public class SLRNode public string Left; public string Right; public SLRNodestring Left string Right thisLeft = Left;
SLR分析表的构造需要使用follow集进行判断,具体过程如下:
-
对于每个非终结符,求出它的follow集合。
-
对于每个项目集合,对于每个终结符和非终结符,分别判断是否需要进行移进或归约操作:
- 如果该符号是终结符,则查找该项目集合中是否存在一个项目的后继符号是该终结符,如果存在,则将该符号和对应的状态加入分析表中。
- 如果该符号是非终结符,则查找该符号的follow集合中是否包含该项目集合中的某个终结符,如果存在,则将该符号和对应的状态加入分析表中。
- 对于含有归约项目的项目集合,将其对应的状态加入分析表中,表示进行归约操作。
下面是SLR分析表的构造代码:
public void SLRAnaly() { Table tnode = new Table();
LRAna = new Table[proitemset.Count][];
for (int i = 0; i < proitemset.Count; i++)
LRAna[i] = new Table[Echar.Count + Nchar.Count];
for (int i = 0; i < proitemset.Count; i++)//初始化 赋予ERROR属性
for (int j = 0; j < Echar.Count + Nchar.Count; j++)//为终结符加r状态
LRAna[i][j] = tnode;
tnode = new Table('A', 0);
LRAna[1][FindID(Echar, '#')] = tnode;//项目集1必定是接受项目 构建[1][#]:acc的情况 先直接赋值好 dfa里没有
for (int i = 0; i < Gy_itemset.Count; i++)
{
int proNum = Find_pro(LRobjNum[proitemset[Gy_itemset[i]].Container[0]]);
foreach (char c in Follow[Nchar[proNum]])//对于非终结符的follow集中的每个终结符
{
int j = FindID(Echar, c);
if (j != -1)//如果该终结符在Echar中存在
{
tnode = new Table('r', proNum);//归约项目 找到原产生式序号 添加状态r
LRAna[Gy_itemset[i]][j] = tnode;
}
}
}
for (int i = 0; i < Pindex; i++)
{
if (isFinalsymbol(dfa[i].symbol))//symbol为非终结符 添加状态N
{
int CID = FindID(Nchar, dfa[i].symbol);
foreach (char c in Follow[Nchar[CID]])//对于非终结符的follow集中的每个终结符
{
int j = FindID(Echar, c);
if (j != -1)//如果该终结符在Echar中存在
{
tnode = new Table('N', dfa[i].to);
LRAna[dfa[i].from][j + Echar.Count] = tnode;
}
}
}
else //不是归约项目 添加状态S
{
int CID = FindID(Echar, dfa[i].symbol);
tnode = new Table('S', dfa[i].to);
LRAna[dfa[i].from][CID] = tnode;
}
}
}
需要注意的是,在SLR分析表的构造中,需要使用follow集,因此需要在文法分析时同时求出每个非终结符的follow集。这里我们假设已经求出了Follow集,可以将其保存在一个名为Follow的List
完整代码如下:
public class SLRNode { public string Left; public string Right; public SLRNode(string Left, string Right) { this.Left = Left; this.Right = Right; } }
//项目集类
public class SLRitemsets
{
public List
//DFA结点 public struct DFA { public int from; public char symbol; public int to; public DFA(int from, char symbol, int to) { this.from = from; this.symbol = symbol; this.to = to; } }
//分析表 结点 public class Table { public bool error;//是否为ERROR public char type;//结点类型 public int id;//数值 public Table() { this.error = true; } public Table(char type, int id) { this.type = type; this.id = id; this.error = false; } }
public class Analyze
{
public DFA[] dfa = new DFA[100];
public int Pindex = 0; //dfa数组指针
public Table[][] LRAna;//分析表
public bool Success = false;
public List
public string RStr = "";
public string RStr_obitemset = "";//输出返回
public string RStr_DFA = "";
public string RStr_ANA = "";
public Analyze(List<SLRNode> pro, List<char> n, List<char> e)
{
this.SLRproNum = pro;
this.Nchar = n;
this.Echar = e;
this.Follow = new List<char>[Nchar.Count];
for (int i = 0; i < Nchar.Count; i++)
Follow[i] = new List<char>();
}
public void SLRAnaly()
{
Table tnode = new Table();
LRAna = new Table[proitemset.Count][];
for (int i = 0; i < proitemset.Count; i++)
LRAna[i] = new Table[Echar.Count + Nchar.Count];
for (int i = 0; i < proitemset.Count; i++)//初始化 赋予ERROR属性
for (int j = 0; j < Echar.Count + Nchar.Count; j++)//为终结符加r状态
LRAna[i][j] = tnode;
tnode = new Table('A', 0);
LRAna[1][FindID(Echar, '#')] = tnode;//项目集1必定是接受项目 构建[1][#]:acc的情况 先直接赋值好 dfa里没有
for (int i = 0; i < Gy_itemset.Count; i++)
{
int proNum = Find_pro(LRobjNum[proitemset[Gy_itemset[i]].Container[0]]);
foreach (char c in Follow[Nchar[proNum]])//对于非终结符的follow集中的每个终结符
{
int j = FindID(Echar, c);
if (j != -1)//如果该终结符在Echar中存在
{
tnode = new Table('r', proNum);//归约项目 找到原产生式序号 添加状态r
LRAna[Gy_itemset[i]][j] = tnode;
}
}
}
for (int i = 0; i < Pindex; i++)
{
if (isFinalsymbol(dfa[i].symbol))//symbol为非终结符 添加状态N
{
int CID = FindID(Nchar, dfa[i].symbol);
foreach (char c in Follow[Nchar[CID]])//对于非终结符的follow集中的每个终结符
{
int j = FindID(Echar, c);
if (j != -1)//如果该终结符在Echar中存在
{
tnode = new Table('N', dfa[i].to);
LRAna[dfa[i].from][j + Echar.Count] = tnode;
}
}
}
else //不是归约项目 添加状态S
{
int CID = FindID(Echar, dfa[i].symbol);
tnode = new Table('S', dfa[i].to);
LRAna[dfa[i].from][CID] = tnode;
}
}
}
public void SLR()
{
RStr = "";
RStr_obitemset = "";
RStr_DFA = "";
RStr_ANA = "";
SLRproNum.Insert(0, new SLRNode("", Nchar[0].ToString()));//添加新的开始产生式
SLRobjNum.Insert(0, new SLRNode(SLRproNum[0].Left, "." + SLRproNum[0].Right));//添加新的开始项目
SLR_Closure(0);//构造项目集合
for (int i = 0; i < proitemset.Count; i++)//求出每个非终结符的follow集合
{
SLR_Follow(Nchar[i]);
}
SLR_DFA();//构造DFA
SLRAnaly();//构造分析表
Success = true;
}
public void SLR_Closure(int p)
{
bool flag = true;
while (flag)
{
flag = false;
for (int i = 0; i < proitemset[p].Container.Count; i++)
{
int proNum = proitemset[p].Container[i];
in
原文地址: https://www.cveoy.top/t/topic/hiyW 著作权归作者所有。请勿转载和采集!