private void button3_Click(object sender, EventArgs e)//实现SLR(1)分析表
{
    listView2.Clear();

    LR.Table[][] table;
    table = lr.GET_ANA_SLR();
    int xlen = table.GetLength(0);
    int ylen = table[1].Length;

    listView2.Columns.Clear();
    listView2.Items.Clear();
    listView2.View = View.Details;

    listView2.Columns.Add('状态');

    for (int i = 0; i < lr.Echar.Count; i++)//添加表头
    {
        string text = lr.Echar[i].ToString();
        listView2.Columns.Add(text, 58);
    }
    for (int i = 0; i < lr.Nchar.Count; i++)//添加表头
    {
        string text = lr.Nchar[i].ToString();
        listView2.Columns.Add(text, 58);
    }

    for (int i = 0; i < xlen; i++)
    {
        ListViewItem li = new ListViewItem(i.ToString());

        for (int j = 0; j < ylen; j++)
        {
            string st = '';
            if (table[i][j].error)
                st = '-';
            else if (table[i][j].type == 'A')
                st = 'AC';
            else
                st = table[i][j].type.ToString() + table[i][j].id.ToString();
            li.SubItems.Add(st);
        }
        listView2.Items.Add(li);
    }

    listView2.GridLines = true;
}
public Table[][] GET_ANA_SLR()
{
    SLRAnaly();
    RStr_ANA += '
SLR(1)分析表:
    ';
    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 += '
';
    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 += '
';
    }

    return SLRAna;

}

// 构造SLR(1)分析表
public void LRAnaly_SLR()
{
    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++)
    {
        tnode = new Table('r', Find_pro(LRobjNum[proitemset[Gy_itemset[i]].Container[0]]));//归约项目 找到原产生式序号 添加状态r
        for (int j = 0; j < Echar.Count; j++)
        {
            SLRAna[Gy_itemset[i]][j] = tnode;
        }
    }

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

这段代码实现了 SLR(1) 文法分析表的构造。主要步骤如下:

  1. 初始化分析表,所有项都赋予 ERROR 属性;
  2. 构建接受项目 [1][#]:acc
  3. 处理归约项目,找到原产生式序号并添加 r 状态;
  4. 处理移进项目,添加 S 状态;
  5. 处理非终结符,根据 Follow 集合添加 r 状态。 代码中使用了 Table 类来存储分析表中的每个元素,并包含了 typeid 属性,分别表示动作类型和动作编号。Follow 集合存储每个非终结符的 Follow 集。 通过这段代码,我们可以方便地构造 SLR(1) 文法分析表,并进行语法分析。
SLR(1) 文法分析表构造

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

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