SLR1分析表构建实现
补充完整的SLRAnaly()函数代码如下:
public void SLRAnaly() { //初始化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(); } }
//填充移进和归约操作
for (int i = 0; i < Pindex; i++)
{
int from = dfa[i].from;
char symbol = dfa[i].symbol;
int to = dfa[i].to;
if (isFinalsymbol(symbol))
{
//移进操作
SLRAna[from][getIndex(Echar, symbol)] = new Table('s', to);
}
else
{
//归约操作
for (int j = 0; j < proitemset[to].Container.Count; j++)
{
int index = proitemset[to].Container[j];
if (SLRobjNum[index].Left != "S'")
{
//非拓广文法的产生式
SLRAna[to][getIndex(Echar, SLRobjNum[index].Right[SLRobjNum[index].Right.Length - 1])] = new Table('r', index);
}
else
{
//拓广文法的产生式
SLRAna[to][getIndex(Echar, '#')] = new Table('a', 0);
}
}
}
}
//填充goto操作
for (int i = 0; i < proitemset.Count; i++)
{
for (int j = 0; j < Nchar.Count; j++)
{
char symbol = Nchar[j];
int value = Goto(i, symbol);
if (value != -1)
{
SLRAna[i][getIndex(Nchar, symbol) + Echar.Count] = new Table('g', value);
}
}
}
}
//获取SLR分析表 public Table[][] GET_ANA() { return SLRAna; }
//获取字符在集合中的下标
public int getIndex(List
//判断字符是否为终结符 public bool isFinalsymbol(char c) { if (c >= 'a' && c <= 'z') { return true; } return false; }
//判断元素是否存在于集合中
public bool exist(List
//在字符串中插入'.' public string CreObj(string str, int index) { string res = ""; for (int i = 0; i < str.Length; i++) { if (i == index) { res += '.'; } res += str[i]; } if (index == str.Length) { res += '.'; } return res; }
//求闭包
public List
//构造项目集
public void Creteitemsets()
{
List
SLRitemsets LR_C = new SLRitemsets();
LR_C.Container = lr_item;//集合----项目集序号的集合
proitemset.Add(LR_C);//集合的集合----存放项目集序号集合 的集合
for (int i = 0; i < proitemset.Count; i++)//整体集合中 第i个项目集
{
proitemset[i].Container.Sort();//排序由小到大 后面用于判断是否存在的比较
int[] flag = new int[proitemset[i].Container.Count];
for (int fi = 0; fi < proitemset[i].Container.Count; fi++)
{
flag[fi] = 0;
}
for (int j = 0; j < proitemset[i].Container.Count; j++)//第i个项目集的第j个项目
{
if (flag[j] == 1)//如果已经访问过 就不再构造 找下一个项目
{
continue;
}
int index = proitemset[i].Container[j];
for (int pi = 0; pi < SLRobjNum[index].Right.Length - 1; pi++)//length-1是避免匹配到.在最后的规约项目
{
if (SLRobjNum[index].Right[pi] == '.')
{
List<int> lr2_club = new List<int>(100);//记录项目的序号
char symbol = SLRobjNum[index].Right[pi + 1];//记录.a转移状态a.的符号a
lr2_club.Add((index + 1));//如果遇到.a形式的项目序号为index 那么项目a.的序号为index+1
for (int m1 = j + 1; m1 < proitemset[i].Container.Count; m1++)
{//在第i个项目集中找到了可以移动的.:.a 重新遍历第i个项目集j项目之
原文地址: https://www.cveoy.top/t/topic/f0LT 著作权归作者所有。请勿转载和采集!