SLR(1)分析法详解与代码实现:解决文法E->E+T|T T->T*F|F F->(E)|d的分析表构建问题
SLR(1)分析法详解与代码实现:解决文法E->E+T|T T->T*F|F F->(E)|d的分析表构建问题
在学习编译原理SLR(1)分析法的过程中,构建分析表是至关重要的一步。很多初学者经常在添加归约状态时遇到问题,本文将针对这一问题进行详细分析,并提供C#代码实现。
问题描述
给定文法:
E->E+T|TT->T*F|FF->(E)|d
构建SLR(1)分析表时,发现添加的归约状态与正确答案不符。
错误分析
错误的原因是在添加归约状态时,将归约状态添加到了终结符对应的列,而不是非终结符的Follow集对应的列。
代码实现与优化
以下代码实现了SLR(1)分析表的构建,并对添加归约状态的部分进行了优化:
1. SLRAnaly()函数c#public void SLRAnaly(){ Table tnode = new Table();
SLRAna = new Table[proitemset.Count][]; for (int i = 0; i < proitemset.Count; i++) SLRAna[i] = new Table[Echar.Count + Nchar.Count];
// 初始化分析表 for (int i = 0; i < proitemset.Count; i++) for (int j = 0; j < Echar.Count + Nchar.Count; j++) SLRAna[i][j] = tnode;
// 添加接受状态 tnode = new Table('A', 0); SLRAna[1][FindID(Echar, '#')] = tnode;
// 添加归约状态 for (int i = 0; i < Gy_itemset.Count; i++) { SLRNode item = SLRobjNum[proitemset[Gy_itemset[i]].Container[0]]; char left = item.Left[0]; List<char> follow = GetFollow(left); foreach (char c in follow) { // 只在终结符对应的列添加归约状态 if (isFinalsymbol(c)) { int CID = FindID(Echar, c); SLRAna[Gy_itemset[i]][CID] = new Table('r', Find_pro(item)); } } }
// 添加移进状态和GOTO状态 for (int i = 0; i < Pindex; i++) { if (isFinalsymbol(dfa[i].symbol)) { int CID = FindID(Echar, dfa[i].symbol); SLRAna[dfa[i].from][CID] = new Table('S', dfa[i].to); } else { int CID = FindID(Nchar, dfa[i].symbol); SLRAna[dfa[i].from][CID + Echar.Count] = new Table('N', dfa[i].to); } }}
2. GetFollow()函数c#public List
总结
通过以上代码的修改,就可以正确地构建SLR(1)分析表。在学习SLR(1)分析法的过程中,一定要注意添加归约状态的位置,并仔细处理空串的情况,避免出现错误
原文地址: https://www.cveoy.top/t/topic/f0Ly 著作权归作者所有。请勿转载和采集!