SLR(1)分析法详解:解决文法分析难题
SLR(1)分析法详解:解决文法分析难题
本文将介绍如何使用SLR(1)分析法对给定文法进行分析,并解决分析表构建过程中遇到的问题。
文法描述
给定文法如下:
E->E+T|TT->T*F|FF->(E)|d
问题描述
在使用SLR(1)分析法构建分析表时,正确答案包含S和r两种状态,而我的答案中仅包含S状态,无r状态。
正确答案:
| 状态 | + | * | ( | ) | d | # | E ||---|---|---|---|---|---|---|---|| 4 | | | S4 | | S5 | | 8 || 5 | r6 | r6 | | r6 | | r6 | || 6 | | | S4 | | S5 | | || 7 | | | S4 | | S5 | | || 8 | S6 | | | S11 | | | || 9 | r1 | S7 | | r1 | | r1 | || 10 | r3 | r3 | | r3 | | r3 | || 11 | r5 | r5 | | r5 | | r5 | |
我的答案:
| 状态 | + | * | ( | ) | d | # | E ||---|---|---|---|---|---|---|---|| 4 | | | S4 | | S5 | | 8 || 5 | | | | | | | || 6 | | | S4 | | S5 | | || 7 | | | S4 | | S5 | | || 8 | S6 | | | S11 | | | || 9 | | S7 | | | | | || 10 | | | | | | | || 11 | | | | | | | |
**代码:**c#public class SLRNode{ public string Left; public string Right; public SLRNode(string Left, string Right) { this.Left = Left; this.Right = Right; }}// ... 其他代码 ...public void SLRAnaly(){ // ... 其他代码 ...
for (int i = 0; i < proitemset.Count; i++)//遍历所有的项目集 { foreach (int index in proitemset[i].Container)//遍历项目集中的所有项目 { SLRNode item = SLRobjNum[index]; if (item.Right == 'd')//归约项目 { int leftIndex = FindID(Nchar, item.Left[0]); List<char> follow = Follow[leftIndex];//获取左部符号的follow集 foreach (char c in follow) { int CID = FindID(Echar, c); SLRAna[i][CID] = new Table('r', Find_pro(item)); if (c == '#') { foreach (char e in Echar) { int EID = FindID(Echar, e); SLRAna[i][EID] = new Table('r', Find_pro(item)); } } } } } } // ... 其他代码 ...}
错误分析
问题出在SLRAnaly()函数中处理归约项目的部分。代码只考虑了将归约项目的 Follow 集中的符号添加到分析表中,而没有考虑到将归约项目本身添加到对应状态的分析表中。
代码修改
需要修改 SLRAnaly() 函数,在处理归约项目时,不仅要将 Follow 集中的符号添加到分析表中,还要将归约项目本身添加到对应状态的分析表中。
修改后的 SLRAnaly() 函数如下:c#public void SLRAnaly(){ // ... 其他代码 ...
for (int i = 0; i < proitemset.Count; i++)//遍历所有的项目集 { foreach (int index in proitemset[i].Container)//遍历项目集中的所有项目 { SLRNode item = SLRobjNum[index]; if (item.Right == 'd')//归约项目 { // ... 将 Follow 集中的符号添加到分析表中 ...
// 将归约项目本身添加到对应状态的分析表中 int symbolIndex = FindID(Nchar, item.Left[0]) + Echar.Count; SLRAna[i][symbolIndex] = new Table('r', Find_pro(item)); } // ... 其他代码 ... } } // ... 其他代码 ..
原文地址: https://www.cveoy.top/t/topic/f0J8 著作权归作者所有。请勿转载和采集!