LL(1) 语法分析器:构建 Select 集合的优化算法
private void GetSelect(Dictionary<string, List<string>> production1, Dictionary<string, List<string>> firsts1, Dictionary<string, List<string>> follows1)
{
// 对每个非终结符进行处理
foreach (var nonterm in nonterminals)
{
// 对该非终结符的每个产生式进行处理
foreach (var prod in production1[nonterm])
{
// 获取该产生式的第一个符号
string firstSymbol = prod[0];
// 如果第一个符号是终结符,则直接将其加入select集合中
if (IsTerminal(firstSymbol))
{
// 如果是空串,则将该非终结符的follow集合中的所有元素加入select集合中
if (firstSymbol == "#" )
{
foreach (var follow in follows1[nonterm])
{
selects[nonterm][prod].Add(follow);
}
}
else
{
selects[nonterm][prod].Add(firstSymbol);
}
}
// 如果第一个符号是非终结符,则将该非终结符的first集合中的所有元素加入select集合中
else
{
foreach (var first in firsts1[firstSymbol])
{
// 如果是空串,则继续往后查找符号
if (first == "#" )
{
bool canBeEmpty = true;
int i = 1;
// 循环查找直到找到一个非空串或者所有符号都可以为空串
while (canBeEmpty && i < prod.Count)
{
string symbol = prod[i];
canBeEmpty = false;
// 如果该符号是终结符,则将其加入select集合中
if (IsTerminal(symbol))
{
if (symbol != "#" )
{
selects[nonterm][prod].Add(symbol);
}
}
// 如果该符号是非终结符,则将其first集合中的所有元素加入select集合中
else
{
foreach (var f in firsts1[symbol])
{
if (f == "#" )
{
canBeEmpty = true;
}
else
{
selects[nonterm][prod].Add(f);
}
}
}
i++;
}
// 如果所有符号都可以为空串,则将该非终结符的follow集合中的所有元素加入select集合中
if (canBeEmpty)
{
foreach (var follow in follows1[nonterm])
{
selects[nonterm][prod].Add(follow);
}
}
}
else
{
selects[nonterm][prod].Add(first);
}
}
}
}
}
}
原文地址: http://www.cveoy.top/t/topic/oyax 著作权归作者所有。请勿转载和采集!