首先,需要将文法G拓广为G’,然后构造LR(0)项目集规范族C和活前缀识别自动机的状态转换函数GO。然后根据上述原理,构造ACTION和GOTO函数,最后填充分析表中的空白格。

在SLRAnaly函数中,需要遍历所有的项目集,对于每个项目集,根据ACTION和GOTO函数填充分析表中的对应位置。具体实现方法如下:

  1. 初始化分析表SLRAna为一个二维数组,大小为[项目集数量+1][终结符数量+非终结符数量+1],其中第一行和第一列留空。
  2. 对于每个项目集i,遍历其中的每个项目j,根据ACTION和GOTO函数计算对应的动作和转移,填充到SLRAna[i+1][a]中,其中a为终结符或非终结符。
  3. 如果某个位置无法填充,则将其标记为出错标志。
  4. 最后,将SLRAna作为SLR类的一个属性返回。

具体实现代码如下:

public Table[][] SLRAnaly() { SLRAna = new Table[proitemset.Count + 1][]; for (int i = 0; i <= proitemset.Count; i++) { SLRAna[i] = new Table[Nchar.Count + Echar.Count + 1]; for (int j = 0; j <= Nchar.Count + Echar.Count; j++) { SLRAna[i][j] = new Table(); } }

for (int i = 0; i < proitemset.Count; i++)
{
    List<int> itemset = proitemset[i].Container;
    for (int j = 0; j < itemset.Count; j++)
    {
        int item = itemset[j];
        SLRNode obj = SLRobjNum[item];
        if (obj.Right == "#")
        {
            SLRAna[i + 1][Echar.Count + 1] = new Table('a', 0);
        }
        else if (obj.Right[obj.Right.IndexOf(".") + 1] == '\0')
        {
            for (int k = 0; k < Gy_obj.Count; k++)
            {
                if (Gy_obj[k] == item)
                {
                    SLRAna[i + 1][Echar.Count + 1] = new Table('r', k + 1);
                    break;
                }
            }
        }
        else
        {
            char symbol = obj.Right[obj.Right.IndexOf(".") + 1];
            if (isFinalsymbol(symbol))
            {
                int next = Goto(itemset, symbol);
                if (next != -1)
                {
                    SLRAna[i + 1][Echar.IndexOf(symbol)] = new Table('s', next + 1);
                }
                else
                {
                    SLRAna[i + 1][Echar.IndexOf(symbol)] = new Table();
                }
            }
            else
            {
                int next = Goto(itemset, symbol);
                if (next != -1)
                {
                    SLRAna[i + 1][Nchar.IndexOf(symbol)] = new Table('g', next + 1);
                }
                else
                {
                    SLRAna[i + 1][Nchar.IndexOf(symbol)] = new Table();
                }
            }
        }
    }
}

for (int i = 1; i <= Nchar.Count + Echar.Count; i++)
{
    if (isFinalsymbol(Echar[i - 1]))
    {
        SLRAna[0][i] = new Table('s', 0);
    }
    else
    {
        SLRAna[0][i] = new Table();
    }
}
SLRAna[0][Echar.Count + 1] = new Table('a', 0);

return SLRAna;

}

在SLRAnaly函数中,调用了一个名为Goto的函数,用于计算项目集在某个符号上的转移。具体实现方法如下:

public int Goto(List itemset, char symbol) { List nextset = new List(); for (int i = 0; i < itemset.Count; i++) { int item = itemset[i]; SLRNode obj = SLRobjNum[item]; if (obj.Right.IndexOf(".") != obj.Right.Length - 1 && obj.Right[obj.Right.IndexOf(".") + 1] == symbol) { nextset.Add(item + 1); } } nextset = Closure(nextset); int index = isexist(nextset); return index; }

在Goto函数中,首先遍历项目集中的每个项目,找到其中“.”后面紧跟着symbol的项目,将其序号加1并加入nextset中。然后对nextset求闭包,并返回其在项目集中的序号。如果不存在相同的项目集,则返回-1。

最后,在主函数中调用SLRAnaly函数,将分析表输出到文件中:

SLR slr = new SLR(); slr.Buildprod(str); Table[][] SLRAna = slr.SLRAnaly(); StreamWriter sw = new StreamWriter("SLRAnalyTable.txt"); for (int i = 0; i <= slr.proitemset.Count; i++) { for (int j = 0; j <= slr.Nchar.Count + slr.Echar.Count; j++) { if (SLRAna[i][j].error) { sw.Write("e\t"); } else if (SLRAna[i][j].type == 's') { sw.Write("s" + SLRAna[i][j].id.ToString() + "\t"); } else if (SLRAna[i][j].type == 'r') { sw.Write("r" + SLRAna[i][j].id.ToString() + "\t"); } else i

SLR语法分析表的构造方法:首先把G拓广为G’对G’构造LR0项目集规范族C和活前缀识别自动机的状态转换函数GO。函数ACTION和GOTO可按如下方法构造:若项目A→αbβ属于IkGOIka= Ija为终结符置ACTIONka为把状态j和符号a移进栈简记为sj;若项目A→α属于Ik那么对任何非终结符aa∈FOLLOWA置ACTIONka为用产生式A→α进行归约简记为rj;其中假定A→α为文法G’

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

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