错误分析结论:在 SLR1 分析表中没有正确地添加归约状态,对应状态对每个终结符都添加同样的动作。

错误部分:

在 SLRAnaly() 函数中,对于归约状态的处理,只考虑了每个归约状态的 Follow 集,而没有考虑到每个归约状态对应的所有产生式的 First 集。因此,在分析表中对于每个终结符,归约状态都添加了相同的动作。

修改后的代码:

  1. 在 SLRAnaly() 函数中,修改对于归约状态的处理,考虑到每个归约状态对应的所有产生式的 First 集:
for (int i = 0; i < Gy_itemset.Count; i++)
{
    List<int> container = proitemset[Gy_itemset[i]].Container;
    foreach (int index in container)
    {
        SLRNode item = SLRobjNum[index];
        List<char> first = GetFirst(item.Right, item.Pos + 1);
        foreach (char c in first)
        {
            int CID = FindID(Echar, c);
            SLRAna[Gy_itemset[i]][CID] = new Table('r', index);
        }
    }
}
  1. 在 GetFirst() 函数中,添加参数 pos,表示从产生式的第 pos 个字符开始求 First 集:
public List<char> GetFirst(string str, int pos)
{
    List<char> first = new List<char>();
    if (pos >= str.Length)
    {
        first.Add('#');
        return first;
    }
    char c = str[pos];
    if (isFinalsymbol(c))
        first.Add(c);
    else
    {
        foreach (SLRNode node in SLRproNum)
        {
            if (node.Left[0] == c)
            {
                if (node.Right[0] == c)
                    continue;
                else if (isFinalsymbol(node.Right[0]))
                    first.Add(node.Right[0]);
                else
                {
                    List<char> subFirst = GetFirst(node.Right, 0);
                    if (subFirst.Contains('#'))
                    {
                        subFirst.Remove('#');
                        first.AddRange(subFirst);
                        first.AddRange(GetFirst(node.Right, 1));
                    }
                    else
                    {
                        first.AddRange(subFirst);
                    }
                }
            }
        }
    }
    first = first.Distinct().ToList();
    return first;
}

通过以上修改,可以确保 SLR1 分析表中每个归约状态都能正确地根据其 First 集和 Follow 集添加动作,避免了同一个状态对所有终结符都添加相同动作的问题。

SLR1 分析表构建错误分析及代码修正 - 归约状态处理问题

原文地址: https://www.cveoy.top/t/topic/f0MS 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录