LL(1) 文法非终结符 FOLLOW 集计算算法解析
该代码实现了计算 LL(1) 文法中非终结符的 FOLLOW 集的功能。实现过程如下:
-
判断该非终结符的 FOLLOW 集是否已经被计算出,如果已经计算出,则直接返回。
-
将结束符号 '#' 加入起始符号 'intial' 的 FOLLOW 集。
-
遍历产生式,对于每个产生式,找到该非终结符在产生式中的位置,然后根据位置进行处理。
-
如果该非终结符在产生式末尾,则将产生式左边非终结符的 FOLLOW 集加入该非终结符的 FOLLOW 集中。
-
如果该非终结符不在产生式末尾(即后面还跟着其他符号),则需要根据后面的符号进行处理。
-
如果后面是终结符,则直接将其加入该非终结符的 FOLLOW 集中。
-
如果后面是非终结符,则将该非终结符的 FIRST 集加入该非终结符的 FOLLOW 集中,若该非终结符能够推出空,还需将产生式左边的 FOLLOW 集加入。
-
循环结束后,该非终结符的 FOLLOW 集就被计算出来了,并存储在 'follows' 字典中。
void GetFollow(string symbol)
{
// 如果该非终结符的 FOLLOW 集已经被计算出,则直接返回
if (follows.ContainsKey(symbol))
{
return;
}
var grammar = LL1Item.getproduction();
var is_reach = LL1Item.getisreach();
follows.Add(symbol, new List<string>());
// 将结束符号 # 加入起始符号 intial 的 FOLLOW 集
if (symbol == LL1Item.intinal)
{
follows[symbol].Add('#');
}
// 遍历产生式,计算 FOLLOW 集
foreach (string key in LL1Item.nofinal)
{
foreach (var prod in grammar[key])
{
for (int i = 0; i < prod.Length; i++)
{
if (prod[i].ToString() == symbol)
{
// 如果该非终结符在产生式末尾,则将产生式左边非终结符的 FOLLOW 集加入该非终结符的 FOLLOW 集中
if (i == prod.Length - 1)
{
if (key != symbol)
{
GetFollow(key);
foreach (var f in follows[key])
{
if(!follows[symbol].Contains(f))
follows[symbol].Add(f);
}
}
}
// 如果该非终结符不在产生式末尾(即后面还跟着其他符号)
else
{
// 如果后面是终结符,则直接将其加入该非终结符的 FOLLOW 集中
if (IsTerminal(prod[i + 1])&& !follows[symbol].Contains(prod[i + 1].ToString()))
{
follows[symbol].Add(prod[i + 1].ToString());
}
// 如果后面是非终结符,则将该非终结符的 FIRST 集加入该非终结符的 FOLLOW 集中,若该非终结符能够推出空,还需将产生式左边的 FOLLOW 集加入
else
{
foreach (var f in first.getfirsts()[prod[i + 1].ToString()])
{
if (f != '#')
{
if (!follows[symbol].Contains(f))
follows[symbol].Add(f);
}
}
if (first.getfirsts()[prod[i + 1].ToString()].Contains('#') && key != symbol)
{
GetFollow(key);
foreach (var f in follows[key])
{
if (!follows[symbol].Contains(f))
follows[symbol].Add(f);
}
}
}
}
}
}
}
}
}
该代码中,'follows' 字典存储了每个非终结符的 FOLLOW 集,'grammar' 字典存储了所有产生式,'first' 对象用于获取每个非终结符的 FIRST 集。
该代码的核心是递归调用 'GetFollow' 函数,通过遍历产生式,逐步计算每个非终结符的 FOLLOW 集。该算法的时间复杂度为 O(n*m),其中 n 为非终结符数量,m 为产生式数量。
**注意:**该代码仅供参考,实际应用中需要根据具体的 LL(1) 文法进行调整。
原文地址: https://www.cveoy.top/t/topic/oy0G 著作权归作者所有。请勿转载和采集!