SLR(1)语法分析:文法、分析表构建及错误分析
SLR(1)语法分析:文法、分析表构建及错误分析
本文将以文法 E->E+T|T, T->T*F|F, F->(E)|d 为例,详细介绍如何进行 SLR(1) 语法分析,并对代码实现中添加归约状态时可能出现的错误进行分析和修正。
1. 文法分析
给定文法:
E -> E + T | TT -> T * F | FF -> ( E ) | d
2. 项目集族和 DFA 构建
(限于篇幅,此处省略项目集族和 DFA 的详细构建过程,建议参考编译原理相关教材)
3. SLR(1) 分析表构建
构建 SLR(1) 分析表是语法分析的核心步骤,以下代码展示了如何根据项目集族和 DFA 信息构建分析表: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;
// 项目集 1 必定是接受项目,构建 [1][#]:acc 的情况 tnode = new Table('A', 0); SLRAna[1][FindID(Echar, '#')] = tnode;
// 遍历所有含有归约项目的集合 for (int i = 0; i < Gy_itemset.Count; i++) { // 遍历集合中的所有项目 foreach (int item in proitemset[Gy_itemset[i]].Container) { SLRNode node = SLRobjNum[item]; char left = node.Left[0]; List<char> follow = GetFollow(left); // 对 Follow 集中的每个终结符添加归约状态 foreach (char c in follow) { int CID = FindID(Echar, c); SLRAna[Gy_itemset[i]][CID] = new Table('r', Find_pro(node)); // 如果 Follow 集中包含 '#',需要对所有终结符添加归约状态 if (c == '#') { foreach (char e in Echar) { int EID = FindID(Echar, e); SLRAna[Gy_itemset[i]][EID] = new Table('r', Find_pro(node)); } } } } }
// 添加移进状态 for (int i = 0; i < Pindex; i++) { if (isFinalsymbol(dfa[i].symbol)) { int CID = FindID(Nchar, dfa[i].symbol); SLRAna[dfa[i].from][CID + Echar.Count] = new Table('N', dfa[i].to); } else { int CID = FindID(Echar, dfa[i].symbol); SLRAna[dfa[i].from][CID] = new Table('S', dfa[i].to); }
原文地址: https://www.cveoy.top/t/topic/f0KP 著作权归作者所有。请勿转载和采集!