LL(1) 语法分析器:FIRST 集计算算法详解
这段代码实现的是计算一个非终结符的 FIRST 集,是 LL(1) 语法分析器中至关重要的一个步骤。
算法流程:
- 检查缓存: 首先判断该非终结符的 FIRST 集是否已经被计算过。如果已经被计算过 (存储在
firsts字典中),则直接返回,无需重复计算。 - 遍历产生式: 如果该非终结符的 FIRST 集未被计算过,则遍历其所有的产生式。
- 处理产生式首字符: 对于每个产生式的首字符,进行如下判断:
- 终结符: 如果首字符是终结符,则直接将其加入该非终结符的 FIRST 集中。
- 非终结符: 如果首字符是非终结符,则递归调用
GetFirst()函数计算该非终结符的 FIRST 集,并将结果添加到当前非终结符的 FIRST 集中。
- 处理空串: 如果产生式首字符是非终结符且该非终结符可以推导出空串(通过
LL1Item.getisreach()判断),则需要继续处理该产生式的后续字符。- 遍历后续字符: 从产生式的第二个字符开始,继续判断每个字符:
- 终结符: 如果是终结符,则直接将其加入当前非终结符的 FIRST 集中。
- 非终结符: 递归调用
GetFirst()函数计算该非终结符的 FIRST 集,并将结果添加到当前非终结符的 FIRST 集中。 - 空串: 如果所有后续非终结符的 FIRST 集都包含空串,则将空串添加到当前非终结符的 FIRST 集中。
- 遍历后续字符: 从产生式的第二个字符开始,继续判断每个字符:
- 结束循环: 当处理完产生式的所有字符或遇到一个非终结符其 FIRST 集不包含空串时,结束当前产生式的处理。
代码解析:
**代码解释:**
* `firsts`: 一个字典,用于存储每个非终结符的 FIRST 集。
* `production`: 一个字典,存储所有产生式信息,key 为非终结符,value 为对应非终结符的产生式列表。
* `is_reach`: 一个字典,存储每个非终结符是否可以推导出空串的信息,key 为非终结符,value 为布尔值。
* `IsTerminal(char c)`: 一个函数,用于判断字符 `c` 是否为终结符。
**总结:**
FIRST 集的计算是 LL(1) 语法分析器中构建预测分析表的基础。通过准确计算每个非终结符的 FIRST 集,可以确保语法分析过程的正确性和效率。
原文地址: https://www.cveoy.top/t/topic/oy0x 著作权归作者所有。请勿转载和采集!