2016-09-14 35 views
2

我有一个词法分析器为传递给词法分析器的宏字符串的动态列表创建MACRO标记。我用了一个语义谓词在最高层的词法规则来实现此功能:语义词法分析器谓词性能

MACRO: { macros != null && tryMacro() }? .; 

如有宏字符串输入序列匹配凡tryMacro()只检查。

这种方法的表现很糟糕,一些研究后,我试图改变词法规则为以下内容:

MACRO: . { macros != null && tryMacro() }?; 

这严重地提高性能,但我真的不明白为什么。 :)因为'。'匹配任何字符,语义谓词规则应该像以前一样被调用多次,不是吗?有人可以提供这种行为的解释吗?

+1

这个问题是众所周知的。我在我的ANLTR4 C++目标博客文章中描述过:http://www.soft-gems.net/index.php/tools/49-the-antlr4-c-target-is-here。规则左侧的谓词可防止为其生成的DFA不被缓存,但会导致它们被一次又一次地评估。如果你有许多交易者,这是尤其糟糕的,例如许多关键字(词法分析器规则都是隐藏的根上下文的一种)。 –

回答

1

我进一步调试了一下,结果发现规则的重新排序改变了词法分析器的行为,导致宏在解析过程中不被接受。感知性能提高的原因是因为语义谓词在词法分析器在执行其预测时放弃规则之前仅进行过几次评估。所以规则的改变实际上是无效的,而不是性能改进。

我终于通过将宏处理移动到解析器来解决性能问题。

2

原因很简单:如果你在开始时使用谓词,词法分析器将评估它以决定是否应该应用MACRO规则。如果你把它放在最后,它只会在MACRO规则可能匹配时执行检查。

由于MACRO非常通用的,我想你把它放在规则的结束,并且由于它priority rules一定会得到尝试最后。它只能匹配单个字符标记,所以更精确的规则将是优先的。

如果MACRO规则被更优先的规则所取代,则不会被考虑,并且您的谓词不会被调用。