LR(0)分析器到SLR(1)分析器的转换:C#代码示例
using System;
using System.Collections.Generic;
using System.Linq;
// ... 其他代码 ...
public List<int> Closure(List<int> I)
{
bool flag = true;
while (flag)
{
flag = false;
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]))
{
char A = SLRobjNum[I[index]].Right[i + 1];
HashSet<char> followA = new HashSet<char>();
if (i + 2 < SLRobjNum[I[index]].Right.Length)
{
followA = First(SLRobjNum[I[index]].Right.Substring(i + 2));
}
else if (follow.ContainsKey(SLRobjNum[I[index]].Left[0]))
{
followA = follow[SLRobjNum[I[index]].Left[0]];
}
for (int j = 0; j < SLRobjNum.Count; j++)
{
if (isnexist(I, j))
continue;
if (SLRobjNum[j].Left == A.ToString() && SLRobjNum[j].Right[0] == '.')
{
foreach (char c in followA)
{
if (SLRobjNum[j].Follow.Add(c))
flag = true;
}
if (!I.Contains(j))
I.Add(j);
}
}
}
}
}
}
return I;
}
public int Goto(List<int> I, char X)
{
List<int> J = new List<int>();
for (int i = 0; i < I.Count; i++)
{
int index = I[i];
if (SLRobjNum[index].Right.Contains('.'))
{
int dotIndex = SLRobjNum[index].Right.IndexOf('.');
if (dotIndex + 1 < SLRobjNum[index].Right.Length && SLRobjNum[index].Right[dotIndex + 1] == X)
{
string tmp = SLRobjNum[index].Right.Remove(dotIndex, 1);
tmp = tmp.Insert(dotIndex + 1, '.');
SLRNode node = new SLRNode(SLRobjNum[index].Left, tmp);
// 将Follow集传递给新的项目
node.Follow = SLRobjNum[index].Follow;
if (!SLRobjNum.Any(n => n.Left == node.Left && n.Right == node.Right && n.Follow.SetEquals(node.Follow)))
{
SLRobjNum.Add(node);
J.Add(SLRobjNum.Count - 1);
}
}
}
}
return isnexist(J) ? -1 : isnexist(J) ? -1 : proitemset.Count;
}
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;
}
// ... 其他代码 ...
代码解释:
- SLRNode类修改: 为
SLRNode类添加一个HashSet<char> Follow字段,用于存储每个项目的Follow集。 - Closure函数修改:
- 在原有逻辑的基础上,使用Follow集判断是否需要将新的项目加入到闭包中。
- 当遇到
.A形式的项目时,获取A的Follow集followA。 - 遍历所有以A开头的项目,如果该项目的Follow集中包含
followA中的任何一个字符,则将该项目加入到闭包中,并将flag设置为true,表示需要继续进行闭包运算。
- Goto函数修改:
- 在创建新的项目时,将原项目的Follow集传递给新的项目。
- 在将新的项目加入到项目集之前,检查该项目是否已经存在于项目集中。
- GET_ANA函数修改:
- 将函数名修改为
GET_ANA,并修改输出的分析表类型为SLR(1)分析表。
- 将函数名修改为
注意:
- 上述代码中省略了部分函数的实现,例如
isFinalsymbol、First、isnexist和SLRAnaly等函数。你需要根据自己的实际情况进行实现。 - 在实际应用中,还需要根据具体的SLR(1)文法进行相应的调整。
希望以上代码和解释能够帮助你理解如何将LR(0)分析器代码转换为SLR(1)分析器代码。
原文地址: https://www.cveoy.top/t/topic/f0NW 著作权归作者所有。请勿转载和采集!