2

网页建议如果您的 lex 程序“有大量保留字,让 lex 简单地匹配一个字符串并在您自己的代码中确定它是变量还是保留字会更有效”。

我的问题是:在哪里更高效,为什么?如果这意味着编译词法分析器更快,我并不真正关心这一点,因为它是从使用词法分析器解析输入的程序中删除的一步。

似乎 lex 只是使用您的描述来构建一个一次处理一个字符的状态机。增加状态机的大小必然会导致它变得比使用一个标识符规则然后进行多个字符串比较慢,这似乎是不合逻辑的。

此外,如果事实证明这有某种逻辑上的理由作为一种优化是有意义的,那么什么会被认为是大量的保留字呢?我有大约 20 条,而其他各种规则大约有 30 条。那会被认为是大量的保留字吗?我应该尝试对其他一些符号使用相同的策略吗?

我试图用谷歌搜索结果,但我发现的唯一相关文章指出了这个策略,好像它是众所周知的,没有给出任何理由。

如果相关,我使用的是 flex 2.5.35。

编辑:是另一个参考,它声称 lex 在被要求匹配几个长文字字符串时会产生效率低下的扫描器。它也没有给出理由。

4

1 回答 1

3

根据flex 手册,“扫描仪的速度与规则的数量无关,或者......规则对于 '*' 和 '|' 等运算符的复杂程度。”

主要的性能损失是由于回溯。这可以通过(除其他外)使用包罗万象的规则来避免,该规则将匹配“以”有问题的令牌“开始”的令牌。例如,如果您有一个由 [a-zA-Z_] 组成的保留字列表,然后是一个匹配 [a-zA-Z_][a-zA-Z_0-9]* 形式的标识符的规则,则匹配标识符的规则将捕获以保留字名称开头的任何标识符,而无需备份并再次尝试匹配。

根据faq, flex 生成一个确定性有限自动机,它“同时并行地进行所有匹配”。如上所述,其结果是扫描仪的速度与规则的数量无关。另一方面,字符串比较在规则数量上是线性的。

因此,保留字规则实际上应该比查找表快得多。

于 2012-09-30T16:13:10.847 回答