SLR(1)分析器的构建:从代码实现到示例解析
//获取LR0分析表
public Table[][] GET_ANA()
{
if (SLRAna == null)
{
SLRAnaly();
}
return SLRAna;
}
//构造分析表
public void SLRAnaly()
{
//获取Follow集
GetFollow();
//初始化分析表
SLRAna = new Table[proitemset.Count][];
for (int i = 0; i < proitemset.Count; i++)
{
SLRAna[i] = new Table[Echar.Count + 1];
for (int j = 0; j < Echar.Count + 1; j++)
{
SLRAna[i][j] = new Table();
}
}
//填充移进和归约项
for (int i = 0; i < proitemset.Count; i++)
{
foreach (int index in proitemset[i].Container)
{
SLRNode node = SLRobjNum[index];
if (node.Right.IndexOf('.') < node.Right.Length - 1) //移进项
{
char symbol = node.Right[node.Right.IndexOf('.') + 1];
int j = Echar.IndexOf(symbol);
if (j == -1)
{
j = Echar.Count;
}
SLRAna[i][j] = new Table('S', dfa[Pindex++].to);
}
else //归约项
{
foreach (char symbol in Follow(node.Left[0]))
{
int j = Echar.IndexOf(symbol);
if (j == -1)
{
j = Echar.Count;
}
if (!SLRAna[i][j].error)
{
Console.WriteLine('冲突:项目集' + i + '在' + symbol + '上有移进和归约冲突');
Success = false;
return;
}
SLRAna[i][j] = new Table('R', index);
}
}
}
}
//填充接受项
int acceptIndex = proitemset.Count - 1;
SLRAna[acceptIndex][Echar.Count] = new Table('A', 0);
}
//获取非终结符的Follow集
public void GetFollow()
{
//初始化Follow集
foreach (char c in Nchar)
{
follow[c] = new HashSet<char>();
}
follow['S\''] = new HashSet<char> { '#' };
//迭代计算Follow集
bool flag = true;
while (flag)
{
flag = false;
foreach (SLRNode node in SLRproNum)
{
string right = node.Right;
for (int i = 0; i < right.Length; i++)
{
if (isFinalsymbol(right[i]))
{
continue;
}
char A = right[i];
string beta = right.Substring(i + 1);
HashSet<char> betaFirst = First(beta);
int oldCount = follow[A].Count;
if (betaFirst.Contains('#'))
{
follow[A].UnionWith(follow[node.Left[0]]);
}
betaFirst.Remove('#');
follow[A].UnionWith(betaFirst);
int newCount = follow[A].Count;
if (newCount > oldCount)
{
flag = true;
}
}
}
}
}
//获取字符串的First集
public HashSet<char> First(string str)
{
HashSet<char> first = new HashSet<char>();
if (str.Length == 0)
{
first.Add('#');
return first;
}
if (isFinalsymbol(str[0]))
{
first.Add(str[0]);
return first;
}
foreach (SLRNode node in SLRproNum)
{
if (node.Left[0] == str[0])
{
string beta = str.Substring(1);
HashSet<char> betaFirst = First(beta);
int oldCount = first.Count;
if (betaFirst.Contains('#'))
{
first.UnionWith(betaFirst);
first.Remove('#');
first.UnionWith(Follow(node.Left[0]));
}
else
{
first.UnionWith(betaFirst);
}
int newCount = first.Count;
if (newCount > oldCount)
{
break;
}
}
}
return first;
}
//获取非终结符的Follow集
public HashSet<char> Follow(char nonTerminal)
{
return follow[nonTerminal];
}
原文地址: https://www.cveoy.top/t/topic/f0NO 著作权归作者所有。请勿转载和采集!