SLR(1)分析表构建步骤及代码错误分析
SLR(1)分析表构建步骤详解
SLR(1)分析表是编译原理中重要的概念,用于语法分析。以下是其构建步骤:
- 求出文法的所有项目集: 根据文法规则和增广文法,使用闭包和转移操作,构造出所有项目集 (Canonical Collection)。2. 求闭包: 对于每个项目集,计算其闭包,即包含自身和所有可能通过ε产生式到达的状态。3. 寻找后继状态: 对于每个项目集中的每个项目,找到其后继状态。即将 '·' 后面的符号移动到 '·' 前面,形成新的项目。4. 判断项目集是否存在: 对新的项目集,求出其闭包,并判断是否已存在于已有的项目集中。5. 添加新项目集: 若不存在,则将其加入项目集中,并加入待处理的项目集列表中。6. 处理移进和规约操作: 对于每个项目集,分别处理移进(shift)和规约(reduce)操作,并填写到 SLR(1) 分析表中。
代码错误分析
以下代码段存在错误:c#// ... (省略部分代码)
public void SLRAnaly(){ // ... (省略部分代码)
for (int i = 0; i < Pindex; i++) { if (isFinalsymbol(dfa[i].symbol))//symbol为终结符 添加状态N { int CID = FindID(Echar, dfa[i].symbol); SLRAna[dfa[i].from][CID] = new Table('S', dfa[i].to); } else //不是归约项目 添加状态S { int CID = FindID(Nchar, dfa[i].symbol); SLRAna[dfa[i].from][CID + Echar.Count] = new Table('N', dfa[i].to); } }}
public List
else if (index != -1 && index == node.Right.Length - 1) { follow.AddRange(GetFirst(node.Left[0])); }}
// ... (省略部分代码)
错误分析:
- SLRAna() 方法中: 对于终结符,应该添加状态 'S' (shift),对于非终结符,应该添加状态 'N' (goto)。代码中逻辑相反。2. GetFollow() 方法中: 当产生式右部最后一个符号是非终结符时,应该将该非终结符的 Follow 集加入当前符号的 Follow 集,而不是加入 First 集。
修改后的代码:
**SLRAnaly() 方法:**c#public void SLRAnaly(){ // ... (省略部分代码)
for (int i = 0; i < Pindex; i++) { if (isFinalsymbol(dfa[i].symbol)) // symbol为终结符 添加状态S { int CID = FindID(Echar, dfa[i].symbol); SLRAna[dfa[i].from][CID] = new Table('S', dfa[i].to); } else // symbol为非终结符 添加状态N { int CID = FindID(Nchar, dfa[i].symbol); SLRAna[dfa[i].from][CID + Echar.Count] = new Table('N', dfa[i].to); } }}
**GetFollow() 方法:**c#public List
else if (index != -1 && index == node.Right.Length - 1) { follow.AddRange(GetFollow(node.Left[0])); // 加入Follow集 }}
通过以上修改,代码逻辑更正,能够正确构建 SLR(1) 分析表。
原文地址: https://www.cveoy.top/t/topic/f0MC 著作权归作者所有。请勿转载和采集!