Lex保留了单词规则与查找表

时间:2012-09-22 01:36:03

标签: lex flex-lexer

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

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

似乎lex只是使用你的描述来构建一次处理一个字符的状态机。增加状态机的大小必然会使它变得比使用一个规则用于标识符然后进行多次字符串比较更慢。

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

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

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

编辑:Here是另一个引用,声称lex在被要求匹配多个长文字字符串时会产生效率低下的扫描程序。它也没有理由。

1 个答案:

答案 0 :(得分:2)

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

主要的业绩损失是由于回溯。这可以通过(除其他事项外)使用catch-all规则来避免,该规则将匹配以“以”开头“起始”令牌的令牌。例如,如果您有一个由[a-zA-Z_]组成的保留字列表,然后是一个匹配格式[a-zA-Z _] [a-zA-Z_0-9] *的标识符的规则,匹配标识符的规则将捕获任何以保留字的名称开头的标识符,而不必备份并尝试再次匹配。

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

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