构造分析表的过程是遍历每个状态对于每个状态中的每个终结符和非终结符分别判断是否存在移进项或者归约项如果存在则在对应的分析表项中填入相应的移进或者归约动作。最终得到的分析表是一个二维字典其中第一维表示状态编号第二维表示终结符和非终结符。已知上述构造SLR分析表原理请在下列代码环境中实现SLRAnaly函数及相关调用函数实现构建SLR分析表功能。class SLR 产生式结点类
首先需要确定分析表的结构,根据题目中的代码,可以使用一个二维数组SLRAna来表示分析表,其中第一维表示状态编号,第二维表示终结符和非终结符。每个分析表项是一个Table对象,包含三个属性:error表示是否为ERROR,type表示动作类型(移进或归约),id表示移进或归约的状态编号。
在SLRAnaly函数中,需要遍历每个状态,对于每个终结符和非终结符,分别判断是否存在移进项或者归约项。对于移进项,需要根据DFA中的转移关系确定下一个状态编号,并在对应的分析表项中填入移进动作。对于归约项,需要在Gy_obj中查找是否存在该状态编号,如果存在则填入归约动作,否则填入ERROR。
具体实现代码如下:
public void SLRAnaly() { 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 < proitemset.Count; i++)
{
for (int j = 0; j < Echar.Count + Nchar.Count; j++)
{
char symbol = j < Echar.Count ? Echar[j] : Nchar[j - Echar.Count];
int next = GetNextState(i, symbol);
if (next != -1)
{
SLRAna[i][j] = new Table('S', next);
}
else
{
int reduce = GetReduceState(i, symbol);
if (reduce != -1)
{
if (exist(Gy_obj, reduce))
{
int index = Gy_obj.IndexOf(reduce);
SLRAna[i][j] = new Table('R', index + 1);
}
else
{
SLRAna[i][j] = new Table();
SLRAna[i][j].error = true;
}
}
}
}
}
}
其中,GetNextState函数用于根据DFA中的转移关系确定下一个状态编号,如果不存在转移关系,则返回-1。具体实现代码如下:
public int GetNextState(int state, char symbol) { for (int i = 0; i < Pindex; i++) { if (dfa[i].from == state && dfa[i].symbol == symbol) { return dfa[i].to; } } return -1; }
GetReduceState函数用于在归约项目集中查找是否存在该状态编号,如果存在则返回状态编号,否则返回-1。具体实现代码如下:
public int GetReduceState(int state, char symbol) { for (int i = 0; i < proitemset[state].Container.Count; i++) { int index = proitemset[state].Container[i]; if (SLRobjNum[index].Right.EndsWith(symbol.ToString() + ".")) { return index; } } return -1;
原文地址: https://www.cveoy.top/t/topic/hrgt 著作权归作者所有。请勿转载和采集!