SLR(1)分析表构建步骤及代码错误分析
SLR(1)分析表构建步骤及代码错误分析
一、SLR(1)分析表构建步骤
- 构造增广文法: 为原语法添加一个新的开始符号和产生式,例如:原开始符号为S,则添加 S' -> S。2. 构造所有LR(0)项目集: 包括初始项目集和通过闭包和转移函数构造的项目集。3. 根据项目集构造DFA: 每个项目集对应DFA中的一个状态,根据项目集间的转移关系连接状态,形成DFA。4. 根据DFA和Follow集构造SLR(1)分析表: - 对于每个状态I和每个终结符a,如果I中存在形如A→α·aβ的项目,且GOTO(I,a)=J,则ACTION[I,a]=Shift j (j为状态J的编号)。 - 对于每个状态I和每个非终结符A,如果I中存在形如A→α·的项目,则对FOLLOW(A)中的每个终结符b,ACTION[I,b]=Reduce A→α。 - 对于包含S'→S·项目的I,ACTION[I,$]=Accept。 - 其他情况ACTION[I,x]为Error。 - GOTO表根据DFA中状态间的非终结符转移关系填写。
二、代码分析
代码实现的是SLR(1)分析表的构建,但在SLRAnaly()函数中存在错误:在为每个非终结符构造ACTION表时,没有考虑到该非终结符的Follow集合中可能包含空串。
具体来说,错误出现在以下代码段:c#foreach (char c in follow){ int CID = FindID(Echar, c); SLRAna[Gy_itemset[i]][CID] = new Table('r', Find_pro(item));}
这段代码遍历非终结符的Follow集,并为Follow集中的每个终结符添加Reduce项。但是,如果Follow集中包含空串,这段代码并不会为其添加Reduce项,导致分析表不完整。
三、修改建议
- 修改
GetFollow()函数: 在计算Follow集时,如果非终结符出现在产生式最右侧,则将空串('#')加入其Follow集。2. 修改GetFirst()函数: 在计算First集时,如果可以推导出空串,则将空串('#')加入First集。3. 修改SLRAnaly()函数: 在为非终结符添加Reduce项时,需要判断其Follow集是否包含空串。如果包含,则需要为其添加额外的Reduce项。
修改后的代码片段如下:c#// 在 GetFollow() 函数中添加对空串的判断if (index != -1 && index == node.Right.Length - 1){ follow.AddRange(GetFollow(node.Left[0])); follow.Add('#'); // 添加空串}
// 在 SLRAnaly() 函数中添加对空串的处理foreach (char c in follow){ int CID = FindID(Echar, c); if (c == '#') { SLRAna[Gy_itemset[i]][FindID(Echar, '$')] = new Table('r', Find_pro(item)); // 为空串添加 Reduce 项 } else { SLRAna[Gy_itemset[i]][CID] = new Table('r', Find_pro(item)); }}
通过以上修改,可以解决代码中存在的错误,并确保生成的SLR(1)分析表完整正确。
原文地址: https://www.cveoy.top/t/topic/f0ME 著作权归作者所有。请勿转载和采集!