C# 编译原理 - LL(1) 分析表生成 - GetSelect 函数实现
private void GetSelect(Dictionary<string, List<string>> production1, Dictionary<string, List<string>> firsts1, Dictionary<string, List<string>> follows1)
{
foreach (var nofinal in production1.Keys)
{
selects.Add(nofinal,new Dictionary<string, List<string>>());
foreach (var f in production1[nofinal])
{
selects[nofinal].Add(f,new List<string>());
for(int i=0; i < f.Length; i++)
{
if (IsTerminal(f[i]))
{
if (f[i].Equals('#'))
{
foreach (var fol in follows1[nofinal])
selects[nofinal][f].Add(fol);
}
else if (!selects[nofinal][f].Contains(f[i].ToString()))
selects[nofinal][f].Add(f[i].ToString());
break;
}
else
{
int flag = 0;
foreach(var fir in firsts1[f[i].ToString()])
{
if (fir.Equals('#'))
flag = 1;
else
{
if (!selects[nofinal][f].Contains(fir))
selects[nofinal][f].Add(fir);
}
}
if (flag == 0) break;
}
if (i == f.Length - 1)
{
foreach (var fol in follows1[nofinal])
if (!selects[nofinal][f].Contains(fol))
selects[nofinal][f].Add(fol);
}
}
}
}
}
该 GetSelect 函数接受三个字典作为参数:
- production1: 存储产生式,键是非终结符,值为该非终结符的所有产生式列表。
- firsts1: 存储 First 集,键是非终结符,值为该非终结符 First 集中的终结符列表。
- follows1: 存储 Follow 集,键是非终结符,值为该非终结符 Follow 集中的终结符列表。
该函数遍历所有非终结符和其对应的产生式,根据 First 集和 Follow 集计算每个产生式的 Select 集。
具体逻辑如下:
- 遍历所有非终结符和其对应的产生式。
- 遍历每个产生式中的符号,并根据符号类型进行判断:
- 如果符号为终结符,则直接将其加入 Select 集。
- 如果符号为非终结符,则将其 First 集中的终结符加入 Select 集。
- 如果产生式最后是一个非终结符,则还需要将该非终结符的 Follow 集中的终结符加入 Select 集。
最后,该函数将计算好的 Select 集存储在一个字典中,键是非终结符和产生式,值为该产生式的 Select 集。
此函数是构建 LL(1) 分析表的关键步骤,它能有效地帮助我们确定每个非终结符在不同输入符号下的正确产生式。
原文地址: http://www.cveoy.top/t/topic/oyaq 著作权归作者所有。请勿转载和采集!