SLR(1) 文法分析表构造
private void button3_Click(object sender, EventArgs e)//实现SLR(1)分析表
{
listView2.Clear();
LR.Table[][] table;
table = lr.GET_ANA_SLR();
int xlen = table.GetLength(0);
int ylen = table[1].Length;
listView2.Columns.Clear();
listView2.Items.Clear();
listView2.View = View.Details;
listView2.Columns.Add('状态');
for (int i = 0; i < lr.Echar.Count; i++)//添加表头
{
string text = lr.Echar[i].ToString();
listView2.Columns.Add(text, 58);
}
for (int i = 0; i < lr.Nchar.Count; i++)//添加表头
{
string text = lr.Nchar[i].ToString();
listView2.Columns.Add(text, 58);
}
for (int i = 0; i < xlen; i++)
{
ListViewItem li = new ListViewItem(i.ToString());
for (int j = 0; j < ylen; j++)
{
string st = '';
if (table[i][j].error)
st = '-';
else if (table[i][j].type == 'A')
st = 'AC';
else
st = table[i][j].type.ToString() + table[i][j].id.ToString();
li.SubItems.Add(st);
}
listView2.Items.Add(li);
}
listView2.GridLines = true;
}
public Table[][] GET_ANA_SLR()
{
SLRAnaly();
RStr_ANA += '
SLR(1)分析表:
';
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 += '
';
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 += '
';
}
return SLRAna;
}
// 构造SLR(1)分析表
public void LRAnaly_SLR()
{
Table tnode = new Table();
SLRAna = new Table[proitemset.Count][];
for (int i = 0; i < proitemset.Count; i++)
SLRAna[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状态
SLRAna[i][j] = tnode;
tnode = new Table('A', 0);
SLRAna[1][FindID(Echar, '#')] = tnode;//项目集1必定是接受项目 构建[1][#]:acc的情况 先直接赋值好 dfa里没有
for (int i = 0; i < Gy_itemset.Count; i++)
{
tnode = new Table('r', Find_pro(LRobjNum[proitemset[Gy_itemset[i]].Container[0]]));//归约项目 找到原产生式序号 添加状态r
for (int j = 0; j < Echar.Count; j++)
{
SLRAna[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 (int item in Follow[CID])
{
tnode = new Table('r', Find_pro(LRobjNum[proitemset[item].Container[0]]));
SLRAna[dfa[i].from][item + Echar.Count] = tnode;
}
}
else //不是归约项目 添加状态S
{
int CID = FindID(Echar, dfa[i].symbol);
tnode = new Table('S', dfa[i].to);
SLRAna[dfa[i].from][CID] = tnode;
}
}
}
这段代码实现了 SLR(1) 文法分析表的构造。主要步骤如下:
- 初始化分析表,所有项都赋予
ERROR属性; - 构建接受项目
[1][#]:acc; - 处理归约项目,找到原产生式序号并添加
r状态; - 处理移进项目,添加
S状态; - 处理非终结符,根据
Follow集合添加r状态。 代码中使用了Table类来存储分析表中的每个元素,并包含了type和id属性,分别表示动作类型和动作编号。Follow集合存储每个非终结符的Follow集。 通过这段代码,我们可以方便地构造 SLR(1) 文法分析表,并进行语法分析。
原文地址: https://www.cveoy.top/t/topic/oItY 著作权归作者所有。请勿转载和采集!