SLR1分析表构建的步骤:

  1. 对每个项目集I,找出该集合中所有的LR(0)项,对每个终结符a和非终结符A,求出GOTO(I,a)。如果GOTO(I,a)不为空,则在分析表中将M[I,a]设置为Sj,其中j是GOTO(I,a)的编号。
  2. 对于每个项目[A → α•,a],如果a是终结符,则将M[I,a]设置为“shift j”,其中j是从I到GOTO(I,a)的转换。如果a是#,并且[A → α•]在第一个项目集中,则将M[I,#]设置为“accept”。
  3. 对于每个项目[A → α•,a],如果a是终结符,并且[A → α•]在I中,则将M[I,a]设置为“reduce A → α”。
  4. 如果有任何M[I,a]和M[I,b]都不为空,且它们都不是同一种类型,则发生冲突。此时,文法不是SLR(1)文法。

对于给定代码,存在以下问题:

  1. 代码中的SLRAna数组在GET_ANA函数中返回,但是在SLRAnaly函数中没有进行赋值。因此,代码无法编译通过。
  2. 在SLRAnaly函数中,对于每个非终结符,应该在SLRAna数组中添加状态N,而不是在终结符的位置上添加状态N。
  3. 在SLRAnaly函数中,对于每个项目[A → α•,a],如果a是终结符,并且[A → α•]在I中,则将M[I,a]设置为“reduce A → α”。但是在代码中,使用了SLRNode对象的Find_pro方法来查找规约的产生式,这可能会导致错误。

修改后的代码如下:

public Table[][] GET_ANA() { SLRAnaly(); RStr_ANA += "\r\nSLR0分析表:\r\n "; int i; for (i = 0; i < Echar.Count; i++) { RStr_ANA += Echar[i].ToString() + " "; } for (i = 0; i < Nchar.Count; i++) { RStr_ANA += Nchar[i].ToString() + " "; } RStr_ANA += "\r\n"; for (i = 0; i < proitemset.Count; i++) { RStr_ANA += i.ToString() + " "; for (int j = 0; j < Echar.Count + Nchar.Count; j++) {

        if (SLRAna[i][j].error)
        {
            RStr_ANA += "  " + "    ";
        }
        else if (i == 1 && j == Echar.Count - 1)
        {
            RStr_ANA += "AC" + "    ";
        }
        else if (SLRAna[i][j].type != 'N')
        {
            RStr_ANA += SLRAna[i][j].type.ToString() + SLRAna[i][j].id.ToString() + "    ";
        }
        else
            RStr_ANA += SLRAna[i][j].id.ToString() + "    ";
    }
    RStr_ANA += "\r\n";
}

return SLRAna;

}

public void SLRAnaly() { Table tnode = new Table();

SLRAna = new Table[proitemset.Count][];
for (int i = 0; i < proitemset.Count; i++)
    SLRAna[i] = new Table[Echar.Count + Nchar.Count];

for (int i = 0; i < proitemset.Count; i++)//初始化 赋予ERROR属性
    for (int j = 0; j < Echar.Count + Nchar.Count; j++)//为终结符加r状态 
        SLRAna[i][j] = tnode;

tnode = new Table('A', 0);
SLRAna[1][FindID(Echar, '#')] = tnode;//项目集1必定是接受项目   构建[1][#]:acc的情况 先直接赋值好 dfa里没有

for (int i = 0; i < Gy_itemset.Count; i++)
{
    SLRNode item = SLRobjNum[proitemset[Gy_itemset[i]].Container[0]];
    char left = item.Left[0];
    List<char> follow = GetFollow(left);
    foreach (char c in follow)
    {
        int CID = FindID(Echar, c);
        SLRAna[Gy_itemset[i]][CID] = new Table('r', proitemset[Gy_itemset[i]].Container[0]);

    }
}

for (int i = 0; i < Pindex; i++)
{
    if (isFinalsymbol(dfa[i].symbol))//symbol为非终结符  添加状态N
    {
        int CID = FindID(Nchar, dfa[i].symbol);
        SLRAna[dfa[i].from][CID + Echar.Count] = new Table('N', dfa[i].to);
    }
    else //不是归约项目 添加状态S
    {
        int CID = FindID(Echar, dfa[i].symbol);
        SLRAna[dfa[i].from][CID] = new Table('S', dfa[i].to);
    }
}

}

public List GetFollow(char c) { List follow = new List(); if (c == 'E') follow.Add('#'); foreach (SLRNode node in SLRproNum) { int index = node.Right.IndexOf(c); if (index != -1 && index < node.Right.Length - 1) { char next = node.Right[index + 1]; if (isFinalsymbol(next)) follow.Add(next); else { List first = GetFirst(next); if (first.Contains('#')) { first.Remove('#'); follow.AddRange(first); follow.AddRange(GetFollow(node.Left[0])); } else { follow.AddRange(first); } } } else if (index != -1 && index == node.Right.Length - 1) { follow.AddRange(GetFollow(node.Left[0])); } } follow = follow.Distinct().ToList(); return follow; }

public List GetFirst(char c) { List first = new List(); 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 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分析表构建的步骤依据上述步骤分析下列代码的正误并给出结论和修改后的代码。public Table GET_ANA SLRAnaly; RStr_ANA += rnSLR0分析表rn ; int i; for i = 0; i EcharCount; i++

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

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