SLR(1)分析法详解及代码实现(解决分析表构建错误)
SLR(1)分析法详解及代码实现(解决分析表构建错误)
在编译原理中,SLR(1)分析法是一种常用的自底向上语法分析方法,用于判断输入串是否符合给定的语法规则。本文将详细介绍SLR(1)分析法的原理,并针对代码实现过程中经常出现的分析表构建错误进行深入分析,给出具体的代码修改方案。
问题描述
给定文法:
E->E+T|TT->T*F|FF->(E)|d
对上述文法进行SLR(1)分析,正确的分析表如下:
| 状态 | + | * | ( | ) | d | # | E | T | F ||---|---|---|---|---|---|---|---|---|---|| 0 | | | S4 | | S5 | | 1 | 2 | 3 || 1 | r6 | r6 | | r6 | r6 | r6 | | | || 2 | | | S4 | | S5 | | | 7 | 3 || 3 | r5 | r5 | | r5 | r5 | r5 | | | || 4 | | | S4 | | S5 | | | 8 | 3 || 5 | r4 | r4 | | r4 | r4 | r4 | | | || 6 | S6 | | | S11 | | | | | || 7 | r2 | S7 | | r2 | r2 | r2 | | | || 8 | r3 | r3 | | r3 | r3 | r3 | | | || 9 | r1 | S7 | | r1 | r1 | r1 | | | || 10 | | | S4 | | S5 | | | | 11 || 11 | r5 | r5 | | r5 | r5 | r5 | | | |
但是,我的代码生成的分析表却如下:
| 状态 | + | * | ( | ) | d | # | E | T | F ||---|---|---|---|---|---|---|---|---|---|| 0 | | | S4 | | S5 | | 1 | 2 | 3 || 1 | | | | | | | | | || 2 | | | S4 | | S5 | | | 7 | 3 || 3 | | | | | | | | | || 4 | | | S4 | | S5 | | | 8 | 3 || 5 | | | | | | | | | || 6 | S6 | | | S11 | | | | | || 7 | | S7 | | | | | | | || 8 | | | | | | | | | || 9 | | S7 | | | | | | | || 10 | | | S4 | | S5 | | | | 11 || 11 | | | | | | | | | |
错误分析
经过分析,错误出现在分析表中归约项目的处理上。在SLR(1)分析表中,对于每个归约项目,应该将其左部符号的Follow集中的所有终结符对应的表项都设置为该归约项目对应的产生式。
然而,在代码中,只对左部符号的Follow集中的第一个终结符进行了处理,而没有对其它终结符进行处理。
代码修改
需要修改 SLRAnaly() 函数中归约项目的处理部分,具体修改如下:c#foreach (char c in follow){ int CID = FindID(Echar, c); SLRAna[i][CID] = new Table('r', Find_pro(item)); // 将所有Follow集中的终结符对应的表项设置为归约项目
if (c == '#') // 特殊处理 Follow集中包含 '#' 的情况 { foreach (char e in Echar) { int EID = FindID(Echar, e); SLRAna[i][EID] = new Table('r', Find_pro(item)); }
原文地址: https://www.cveoy.top/t/topic/f0J1 著作权归作者所有。请勿转载和采集!