我正在阅读明确的ANTLR4引用,并且对其中一个示例有疑问(p。76):

STRING: '"' (ESC|.)*? '"';
fragment
ESC: '\\"' | '\\\\' ;

该规则与典型的C++字符串匹配-""中包含的char序列,也可以包含\"

在我的期望中,由于非贪心的构造,规则STRING应该匹配最小的字符串。因此,如果看到\",它将在规则末尾将\映射到.,将"映射到",因为这将导致尽可能小的字符串。取而代之的是,将\"映射到ESC。我有一个理解上的问题,因为这不是我所期望的。

这里到底发生了什么?就是这样吗,一个单独的DFA首先匹配(ESC|.),另一个DFA使用已经匹配的STRING构造字符串匹配(ESC|.)?我不得不承认我还没有读完这本书。

最佳答案

ANTLR 4词法分析器通常以最长匹配获胜的方式运行,而不考虑语法中替代项出现的顺序。如果两个词法分析器规则匹配相同的最长输入序列,则只有将这些规则的相对顺序进行比较,才能确定 token 类型的分配方式。

一旦词法分析器到达非贪婪的可选内容或闭包,规则内的行为就会发生变化。从那一刻到规则结束,该规则内的所有替代项将被视作有序处理,并且具有最低替代项的路径将获胜。由于the way we order alternatives in the underlying ATN representation,这种看似奇怪的行为实际上是造成非贪婪处理的原因。当词法分析器处于此模式下并到达块(ESC|.)时,排序约束要求它在可能的情况下使用ESC

关于antlr - ANTLRv4 : non-greedy rules,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/18787242/

10-15 09:18