C# LR(1)语法分析器代码解析

本文将详细分析两段C#代码,它们共同实现了一个LR(1)语法分析器。

代码1:button4_Click 事件处理函数c#private void button4_Click(object sender, EventArgs e){ step = 0;//单步计数置零 lr = new LR();

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

// 添加第一列    listView1.Columns.Add('状态', 150);    listView1.Columns.Add('项目族信息', 350);

lr.Buildprod(richTextBox1.Text);//调用

for (int i = 0; i < lr.proitemset.Count; i++)//输出    {        ListViewItem li = new ListViewItem();        li.SubItems.Clear();        li.SubItems[0].Text = i.ToString();        string tempstr = '';        for (int j = 0; j < lr.proitemset[i].Container.Count; j++)        {            tempstr += lr.LRobjNum[lr.proitemset[i].Container[j]].Left + '->' + lr.LRobjNum[lr.proitemset[i].Container[j]].Right + '  ';        }        li.SubItems.Add(tempstr);        listView1.Items.Add(li);    }    listView1.GridLines = true;}

这段代码定义了一个名为 button4_Click 的私有方法,该方法在点击名为 button4 的按钮时被调用。

  • 首先,代码初始化了两个变量:step 被设置为 0,表示单步计数清零;lr 被实例化为一个新的 LR 对象,用于进行 LR(1) 语法分析。* 接下来,代码清空了名为 listView1 的列表视图控件,并将其视图模式设置为 View.Details,准备用于显示分析结果。* 然后,代码向 listView1 中添加了两列,分别用于显示 '状态' 和 '项目族信息',并调用 lr 对象的 Buildprod 方法,将名为 richTextBox1 的富文本框中的文本作为参数传入。* Buildprod 方法的主要功能是根据传入的文法规则构建 LR(1) 分析表,其具体实现将在代码2中进行分析。* 最后,代码遍历 lr.proitemset 列表,将每个项目集的信息添加到 listView1 中,并设置 listView1 的网格线可见。

代码2:Buildprod 方法c#public void Buildprod(string str){ LRNode Lr; int i = 0; string left = ''; string right = ''; left += 'S''; right += str[0]; Lr = new LRNode(left, right);//拓广文法开始 LRproNum.Add(Lr); while (i < str.Length) { left = right = '';//还原 int j = i; while (i < str.Length && str[i] != ' ' && str[i] != ' ')//换行符‘ ’ { if (str[i] == ' ') { i++; continue; } if (str[i] == '|') // 遇到“|”可构造一条产生式 { Lr = new LRNode(left, right); LRproNum.Add(Lr); right = ''; //产生式左边相同 右边重新积累 i++; //跳过“|” continue; } if ((i - j) == 0) { if (!exist(Nchar, str[i]))//如果非终结符集合中不存在str[i],加入Nchar 产生式左边 只有非终结符 不必判断终结符 Nchar.Add(str[i]); left += str[i++]; } else if (i - j <= 2) i++; else { if (isFinalsymbol(str[i]) && !exist(Nchar, str[i]))//如果非终结符集合中不存在str[i],加入Nchar isfinalsymbol 非终结符返回T 终结符返回F Nchar.Add(str[i]); else if (!isFinalsymbol(str[i]) && !exist(Echar, str[i]))//产生式右边 需要判断终结符 Echar.Add(str[i]); right += str[i++]; }

    }//while

    i++;//跳过换行符        if (left != '' && right != '')        {            Lr = new LRNode(left, right);//构造每一行最后一个产生式,不存在'|'时就是该行产生式本身            LRproNum.Add(Lr);        }    }//while    Echar.Add('#');

//构造项目  对产生式集合LRproNum中的所有产生式都循环插'.'    LRNode Lobj;    for (i = 0; i < LRproNum.Count; i++)    {        left = '';        right = '';        for (int j = 0; j <= LRproNum[i].Right.Length; j++)//j可以等于length  项目共length+1个        {            left = LRproNum[i].Left;            right = CreObj(LRproNum[i].Right, j);//在第j个位置插入'.'            if (j == LRproNum[i].Right.Length && LRobjNum.Count != 1)            {//在产生式最后的位置插入.  即为归约项目      项目集中1号位置为接受项目                Gy_obj.Add(LRobjNum.Count);//归约项目在项目集中的序号  不用+1  本身就是从0开始的            }            Lobj = new LRNode(left, right);            LRobjNum.Add(Lobj);            left = '';//还原            right = '';        }    }    Creteitemsets();//项目集    RStr_obitemset += '

项目集构建: '; for (int j = 0; j < proitemset.Count; j++) { RStr_obitemset += 'I' + j.ToString() + ':' + ' '; for (i = 0; i < proitemset[j].Container.Count; i++) { RStr_obitemset += LRobjNum[proitemset[j].Container[i]].Left.ToString() + '->' + LRobjNum[proitemset[j].Container[i]].Right.ToString() + ' '; } } //return RStr_obitemset;

C# LR(1)语法分析器代码解析

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

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