我有一个词法分析器为传递给词法分析器的动态宏字符串列表创建MACRO令牌。我在顶级词法分析器规则中使用了语义谓词来实现此功能:
MACRO: { macros != null && tryMacro() }? .;
tryMacro()
只检查是否有任何宏字符串与输入序列匹配。
这种方法的表现非常糟糕,经过一些研究后我尝试将词法分析器规则改为:
MACRO: . { macros != null && tryMacro() }?;
这严重改善了性能,但我真的不明白为什么。 :)自'。'匹配任何字符,语义谓词规则应该像以前一样多次调用,不应该吗?有人可以为这种行为提供解释吗?
答案 0 :(得分:2)
原因很简单:如果您将谓词放在开头,那么词法分析器会对其进行评估以确定是否应该应用MACRO
规则。如果您将其放在最后,它只会在MACRO
规则可能匹配时执行检查。
由于MACRO
非常泛型,我认为你把它放在规则的末尾,并且由于priority rules它肯定会被尝试 last 。它只能匹配单个字符标记,因此更精确的规则将是优先的。
如果MACRO
规则被更优先的规则取代,则不会被考虑,并且您的谓词不会被调用。
答案 1 :(得分:1)
我进一步调试了这一点,结果发现规则的重新排序改变了词法分析器的行为,导致在解析过程中不接受宏。感知到性能提升的原因是因为语义谓词仅在词法分子在做出预测时放弃规则之前进行了几次评估。因此,规则的更改实际上是无效的,而不是性能改进。
我终于通过将宏处理移动到解析器来解决性能问题。