SLR(1)分析器中GetFollow()函数的实现
// 获取非终结符的Follow集
public Dictionary<char, HashSet<char>> GetFollow(List<char> Nchar, List<char> Echar, List<SLRNode> SLRproNum, List<SLRNode> SLRobjNum)
{
Dictionary<char, HashSet<char>> follow = new Dictionary<char, HashSet<char>>();
// 将'#'加入开始符的Follow集
HashSet<char> start_follow = new HashSet<char>();
start_follow.Add('#');
follow.Add(SLRproNum[0].Left[0], start_follow);
// 循环直到所有非终结符的Follow集都不再改变
bool change = true;
while (change)
{
change = false;
for (int i = 0; i < SLRproNum.Count; i++)
{
string right = SLRproNum[i].Right;
for (int j = 0; j < right.Length; j++)
{
if (!Nchar.Contains(right[j]))
continue;
if (j == right.Length - 1)
{//如果该非终结符在产生式末尾
HashSet<char> set = follow[SLRproNum[i].Left[0]];
HashSet<char> old_set = new HashSet<char>(set);
set.UnionWith(old_set);
if (set.Count != old_set.Count)
change = true;
}
else
{//如果该非终结符不在产生式末尾
HashSet<char> set = new HashSet<char>();
for (int k = j + 1; k < right.Length; k++)
{
if (Echar.Contains(right[k]))
{
set.Add(right[k]);
break;
}
HashSet<char> first = First(right[k].ToString(), SLRobjNum);
if (first.Contains('#'))
{
first.Remove('#');
set.UnionWith(first);
continue;
}
else
{
set.UnionWith(first);
break;
}
}
HashSet<char> old_set = new HashSet<char>(follow[right[j]]);
follow[right[j]].UnionWith(set);
if (follow[right[j]].Count != old_set.Count)
change = true;
}
}
}
}
return follow;
}
// 获取符号串的First集
public HashSet<char> First(string str, List<SLRNode> SLRobjNum)
{
HashSet<char> set = new HashSet<char>();
if (str == '')
{
set.Add('#');
return set;
}
if (!isFinalsymbol(str[0]))
{
for (int i = 0; i < SLRobjNum.Count; i++)
{
if (SLRobjNum[i].Left[0] == str[0])
{
if (SLRobjNum[i].Right == '#')
set.UnionWith(First(str.Substring(1), SLRobjNum));
else
set.UnionWith(First(SLRobjNum[i].Right + str.Substring(1), SLRobjNum));
}
}
}
else
{
set.Add(str[0]);
}
return set;
}
这段代码实现了SLR(1)分析器中的GetFollow()函数,用于计算文法中非终结符的Follow集。函数接受四个参数:
Nchar: 非终结符集合Echar: 终结符集合SLRproNum: 产生式集合SLRobjNum: 项目集合
函数首先将'#'加入开始符的Follow集中,然后循环遍历所有产生式,根据Follow集的定义逐步计算每个非终结符的Follow集,直到所有非终结符的Follow集都不再改变为止。
函数中还包含一个辅助函数First(),用于计算符号串的First集。
这段代码清晰易懂,注释详细,可以帮助理解SLR(1)分析器中Follow集的计算方法。
原文地址: https://www.cveoy.top/t/topic/f0NM 著作权归作者所有。请勿转载和采集!