SLR(1)分析表的构建:如何实现FOLLOW集和FIRST集的逻辑判断
SLR(1)分析表的构建:如何实现FOLLOW集和FIRST集的逻辑判断
在SLR(1)分析表的构建过程中,需要对归约项的FOLLOW集和移进项的FIRST集进行逻辑判断,以确定分析表的每个条目。本文将介绍如何使用C#代码实现这些逻辑判断,并提供完整的代码示例。
逻辑判断步骤
- 判断当前产生式是否为规约项目: 如果当前产生式的点号位置等于右部的长度,且左部不是原始文法的增广符号,则该产生式为规约项目。2. 添加FOLLOW集: 对于每个规约项目,将其左部的FOLLOW集添加到
back列表中。3. 添加FIRST集: - 如果当前产生式的点号后面是终结符,则将当前终结符添加到put列表中。 - 如果点号后面是非终结符,则将该非终结符的FIRST集添加到put列表中。4. 判断FOLLOW集和FIRST集的关系: - 如果back和put列表中都有元素,则遍历back列表中的所有元素,并判断每个元素是否包含在put列表中。 - 如果存在back列表中的元素包含在put列表中,则返回false,表示该文法不是SLR(1)文法。 - 如果back列表中的元素个数大于等于2,则需要进一步判断是否存在二义性。5. 判断二义性: - 遍历back列表中的所有元素,除了最后一个元素。 - 对于back列表中每个位置i的元素,遍历其后面的所有元素,并判断是否存在包含关系。 - 如果存在包含关系,则返回false,表示该文法不是SLR(1)文法。6. 返回结果: 如果以上条件都不满足,则返回true,表示该文法是SLR(1)文法。
代码示例c#class SLR{ // ... (其他代码)
// 判断当前产生式是否为规约项目 public bool isGyItem(SLRNode node) { if (node.Right.Length == node.Right.IndexOf('.') + 1 && node.Left != 'S'') return true; return false; }
// ... (其他代码)
// 构造分析表 public void BuildAnaTable() { // ... (其他代码)
// 填充归约项的FOLLOW集 for (int i = 0; i < proitemset.Count; i++) { for (int j = 0; j < proitemset[i].Container.Count; j++) { int index = proitemset[i].Container[j]; if (SLRobjNum[index].Right.IndexOf('.') == SLRobjNum[index].Right.Length - 1)//找到归约项 { // ... (其他代码)
List<char> back = new List<char>(50); // 归约项的FOLLOW集 back.AddRange(FOLLOW(SLRobjNum[index].Left)); List<char> put = new List<char>(50); // 移进项的FIRST集 if (SLRobjNum[index].Right.IndexOf('.') == SLRobjNum[index].Right.Length - 1) // 如果是空产生式 put.AddRange(back); else { char symbol = SLRobjNum[index].Right[SLRobjNum[index].Right.IndexOf('.') + 1]; // 找到'.'后面的符号 if (isFinalsymbol(symbol)) // 如果是终结符 put.Add(symbol); else // 如果是非终结符 put.AddRange(FIRST(SLRobjNum[index].Right.Substring(SLRobjNum[index].Right.IndexOf('.') + 1))); if (put.Contains('#')) // 如果包含空串,也加入归约项的FOLLOW集 put.AddRange(back); }
// 判断FOLLOW集和FIRST集的关系 if (back.Count > 0 && put.Count > 0) { foreach (char b in back) { if (put.Contains(b)) { // 错误处理:该文法不是SLR(1)文法 return; } } }
// 判断二义性 if (back.Count >= 2) { for (int m = 0; m < back.Count - 1; m++) { for (int n = m + 1; n < back.Count; n++) { if (back[m] == back[n]) { // 错误处理:该文法不是SLR(1)文法 return; } } } }
// ... (其他代码) } } }
// ... (其他代码) }
// ... (其他代码
原文地址: https://www.cveoy.top/t/topic/f1TA 著作权归作者所有。请勿转载和采集!