class LR 产生式结点类 public class LRproNode public string Left; public string Right; public LRproNodestring Left string Right
对于SLR文法,只需要在LRAnaly()函数中对归约项目的处理做出改变即可。
SLR文法在LR0文法的基础上,增加了对于“先行符”的判断,即在归约时,只有当当前状态的“先行符”包含在归约项的“后继符”中时,才能进行归约操作。
因此,需要在LRAnaly()函数中对归约项目的处理进行改变,具体改变如下:
- 在Cre_club()函数中,需要对每个项目集中的归约项的“后继符”进行计算和记录,这里使用一个字典来记录每个归约项的“后继符”:
Dictionary<int, List<char>> follow_dict = new Dictionary<int, List<char>>();
对于每个归约项,计算其“后继符”的方法如下:
if (j == pro_club[i].Container.Count - 1 && LRobjNum[index].Right[pi] == '.')
{
if (!follow_dict.ContainsKey(index))
{
follow_dict[index] = new List<char>();
}
follow_dict[index].AddRange(FOLLOW(LRobjNum[index].Left));
}
其中,FOLLOW()函数用于计算某个非终结符的“后继符”,具体实现可以参考以下代码:
public List<char> FOLLOW(char ch)
{
List<char> follow = new List<char>();
if (ch == 'S')
{
follow.Add('#');
}
for (int i = 0; i < LRproNum.Count; i++)
{
for (int j = 0; j < LRproNum[i].Right.Length; j++)
{
if (LRproNum[i].Right[j] == ch)
{
if (j == LRproNum[i].Right.Length - 1)
{
if (LRproNum[i].Left != ch)
{
follow.AddRange(FOLLOW(LRproNum[i].Left));
}
}
else
{
if (isFinalsymbol(LRproNum[i].Right[j + 1]))
{
follow.Add(LRproNum[i].Right[j + 1]);
}
else
{
follow.AddRange(FIRST(LRproNum[i].Right.Substring(j + 1)));
if (FIRST(LRproNum[i].Right.Substring(j + 1)).Contains('ε'))
{
follow.AddRange(FOLLOW(LRproNum[i].Left));
}
}
}
}
}
}
return follow.Distinct().ToList();
}
- 在LRAnaly()函数中,对归约项目的处理需要进行修改。对于每个归约项,需要判断其“后继符”是否包含当前状态的“先行符”,如果包含,则进行归约操作,否则将该状态的分析表项设置为ERROR。
具体实现如下:
for (int i = 0; i < Gy_club.Count; i++)
{
in
原文地址: https://www.cveoy.top/t/topic/hryH 著作权归作者所有。请勿转载和采集!