LR(0)分析表代码解析与SLR(1)文法分析表构造
LR(0)分析表代码解析与SLR(1)文法分析表构造
本文分析了一段用于构造LR(0)分析表的C#代码,并讲解了如何将其修改为支持SLR(1)文法的分析表构造。
一、LR(0)分析表代码解析
以下是代码中几个关键类的定义:c#// LR(0)项目public class LRNode{ public string Left; // 产生式左部 public string Right; // 产生式右部 public LRNode(string Left, string Right) { this.Left = Left; this.Right = Right; }}
// 项目集public class LRitemsets{ public List
// DFA节点public struct DFA{ public int from; public char symbol; public int to; public DFA(int from, char symbol, int to) { this.from = from; this.symbol = symbol; this.to = to; }}
// 分析表节点public class Table{ public bool error; // 是否为ERROR public char type; // 节点类型 public int id; // 数值 public Table() { this.error = true; } public Table(char type, int id) { this.type = type; this.id = id; this.error = false; }}
其中,Closure 函数用于计算项目的闭包:c#public List
二、修改为SLR(1)文法
-
修改
SLRNode类和SLRitemsets类c#public class SLRNode{ public string Left; public string Right; public HashSetFollow; // 添加Follow集合 public SLRNode(string Left, string Right) { this.Left = Left; this.Right = Right; Follow = new HashSet (); // 初始化Follow集合 }} -
修改
Closure函数c#public ListClosure(List I){ for (int index = 0; index < I.Count; index++) { for (int i = 0; i < SLRobjNum[I[index]].Right.Length - 1; i++) { if (SLRobjNum[I[index]].Right[i] == '.' && isFinalsymbol(SLRobjNum[I[index]].Right[i + 1])) { for (int j = 0; j < SLRobjNum.Count; j++) { if (isnexist(I, j)) continue; if (SLRobjNum[j].Left == SLRobjNum[I[index]].Right[i + 1].ToString() && SLRobjNum[j].Right[0] == '.') { I.Add(j); // 将Follow集合添加到新的项目中 foreach (char c in SLRproNum.Find(x => x.Left == SLRobjNum[j].Left).Follow) { SLRobjNum[j].Follow.Add(c); } } } } } } return I;} -
修改
GET_ANA函数c#public Table[][] GET_ANA(){ SLRAnaly(); // ... (其余代码保持不变) return SLRAna; } -
添加
SLRAnaly函数c#public void SLRAnaly(){ // 构造SLR(1)项目集族 // ... (代码内容参考LR(0)分析表构造方法,并加入Follow集的计算和使用)}
三、总结
通过以上步骤,就可以将LR(0)分析表的构造代码修改为支持SLR(1)文法的分析表构造。需要注意的是,SLR(1)分析表构造过程中需要计算和使用非终结符的Follow集,具体的计算方法可以参考编译原理相关资料
原文地址: https://www.cveoy.top/t/topic/f0NU 著作权归作者所有。请勿转载和采集!