SLR(1) 文法分析:解析与代码实现
SLR(1) 文法分析:解析与代码实现
本文将对给定的文法进行 SLR(1) 分析,并解决代码实现中遇到的归约状态添加错误问题。
文法:
E->E+T|TT->T*F|FF->(E)|d
目标:
- 构建 SLR(1) 分析表* 实现代码进行文法分析* 解决代码中归约状态添加错误的问题
问题分析
在提供的代码中,SLRAnaly() 函数负责构建 SLR(1) 分析表,但其中对归约状态的处理存在错误。
错误原因:
原代码只处理了归约项目对应的非终结符 Follow 集中的 '#',而忽略了其他终结符。
解决方法:
对于每个含有归约项目的项目集,找到对应非终结符的 Follow 集,并将 Follow 集中所有终结符对应的分析表项设置为相应的归约状态。
代码修改
以下是修改后的 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];
// 初始化,赋予 ERROR 属性 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; // 项目集1必定是接受项目
// 处理归约状态 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) { int CID = FindID(Echar, c); SLRAna[Gy_itemset[i]][CID] = new Table('r', Find_pro(item)); } }
// 处理移进和跳转状态 for (int i = 0; i < Pindex; i++) { if (isFinalsymbol(dfa[i].symbol)) // 非终结符,添加状态 N { int CID = FindID(Nchar, dfa[i].symbol); SLRAna[dfa[i].from][CID + Echar.Count] = new Table('N', dfa[i].to); } else // 终结符,添加状态 S { int CID = FindID(Echar, dfa[i].symbol); SLRAna[dfa[i].from][CID] = new Table('S', dfa[i].to); }
原文地址: https://www.cveoy.top/t/topic/f0LB 著作权归作者所有。请勿转载和采集!