LR(0) 分析表构造代码到 SLR(1) 分析表构造代码的修改
将 LR(0) 分析表构造代码修改为 SLR(1) 分析表构造代码
以下代码片段展示了如何将 LR(0) 分析表构造代码修改为 SLR(1) 分析表构造代码。主要改动包括:
- 数据结构修改: 将
LRNode修改为SLRNode,将LRitemsets修改为SLRitemsets,并将分析表LRAna修改为SLRAna。2. 增加 Follow 集: 在类中增加Dictionary<char, HashSet<char>> follow用于存储非终结符的 Follow 集。3. 修改 SLRAnaly 函数: 修改SLRAnaly函数,使其能够构造 SLR(1) 分析表。
以下是修改后的 GET_ANA 和 SLRAnaly 函数代码:C#public Table[][] GET_ANA(){ SLRAnaly(); RStr_ANA += '\r\nSLR(1)分析表:\r\n '; int i; for (i = 0; i < Echar.Count; i++) { RStr_ANA += Echar[i].ToString() + ' '; } for (i = 0; i < Nchar.Count; i++) { RStr_ANA += Nchar[i].ToString() + ' '; } RStr_ANA += '\r\n'; for (i = 0; i < proitemset.Count; i++) { RStr_ANA += i.ToString() + ' '; for (int j = 0; j < Echar.Count + Nchar.Count; j++) {
if (SLRAna[i][j].error) { RStr_ANA += ' ' + ' '; } else if (i == 1 && j == Echar.Count - 1) { RStr_ANA += 'AC' + ' '; } else if (SLRAna[i][j].type != 'N') { RStr_ANA += SLRAna[i][j].type.ToString() + SLRAna[i][j].id.ToString() + ' '; } else RStr_ANA += SLRAna[i][j].id.ToString() + ' '; } RStr_ANA += '\r\n'; }
return SLRAna;}
public void SLRAnaly(){ // 1. 构造 SLR 项目集族 // 2. 构造 DFA // 3. 计算每个项目集的闭包和 goto 集 // 4. 构造 SLR 分析表
// Step 1: 构造 SLR 项目集族 SLRproNum.Clear(); SLRobjNum.Clear(); proitemset.Clear(); Gy_obj.Clear(); Gy_itemset.Clear(); Nchar.Clear(); Echar.Clear();
// 同 LR0 // ...
// Step 2: 构造 DFA dfa = new DFA[100]; Pindex = 0;
// 同 LR0 // ...
// Step 3: 计算每个项目集的闭包和 goto 集 // 同 LR0 // ...
// Step 4: 构造 SLR 分析表 SLRAna = new Table[proitemset.Count][]; for (int i = 0; i < proitemset.Count; i++) { SLRAna[i] = new Table[Echar.Count + Nchar.Count]; for (int j = 0; j < Echar.Count + Nchar.Count; j++) { SLRAna[i][j] = new Table(); } }
// 计算 Follow 集 // ... (此处需要实现计算 Follow 集的算法)
for (int i = 0; i < proitemset.Count; i++) { // 对于每个项目集 for (int j = 0; j < proitemset[i].Container.Count; j++) { // 对于每个项目 int p = proitemset[i].Container[j]; SLRNode node = SLRobjNum[p]; if (node.Right == '') { // 规约项目 foreach (char c in follow[node.Left]) { int k = Echar.IndexOf(c); if (k >= 0) { SLRAna[i][k].type = 'r'; SLRAna[i][k].id = Gy_obj.IndexOf(p); } } } else { // 移进项目 char c = node.Right[0]; int k; if (Echar.Contains(c)) { k = Echar.IndexOf(c); SLRAna[i][k].type = 's'; SLRAna[i][k].id = dfa[Pindex].to; } else { k = Nchar.IndexOf(c); SLRAna[i][k + Echar.Count].type = 'g'; SLRAna[i][k + Echar.Count].id = dfa[Pindex].to; } } } }
// 对于每个含有归约项目的项目集 foreach (int i in Gy_itemset) { foreach (char c in Echar) { int k = Echar.IndexOf(c); SLRAna[i][k].type = 'r'; SLRAna[i][k].id = Gy_obj.IndexOf(proitemset[i].Container[0]); } }
// 对于接受状态 int acc = proitemset.Count - 1; SLRAna[acc][Echar.Count - 1].type = 'A'; Success = true
原文地址: https://www.cveoy.top/t/topic/f0NS 著作权归作者所有。请勿转载和采集!