我正在阅读明确的ANTLR4参考文献并对其中一个例子提出疑问(第76页):
STRING: '"' (ESC|.)*? '"';
fragment
ESC: '\\"' | '\\\\' ;
规则匹配典型的C ++字符串 - ""
中包含的字符序列,也可以包含\"
。
在我的期望中,规则STRING
应该匹配可能的最小字符串,因为非贪婪的构造。因此,如果它看到\"
它会在规则末尾将\
映射到.
并将"
映射到"
,因为这会导致最小字符串可能。而不是这个,\"
映射到ESC
。我有一个理解问题,因为它不是我所期望的。
这到底发生了什么?是这样的,分开的DFA首先与(ESC|.)
匹配,而另一个DFA使用STRING
构造的已匹配字符串匹配(ESC|.)
吗?我不得不承认我还没有读过这本书。
答案 0 :(得分:7)
ANTLR 4词法分子通常以最长匹配胜利行为进行操作,而不考虑替代词出现在语法中的顺序。如果两个词法分析器规则匹配相同的最长输入序列,则只有这些规则的相对顺序进行比较才能确定如何分配令牌类型。
一旦词法分析器到达非贪婪的可选项或闭包,规则中的行为就会发生变化。从那时起到规则的结尾,该规则中的所有备选方案都将被视为有序,而具有最低备选方案的路径将获胜。这种看似奇怪的行为实际上是由于the way we order alternatives in the underlying ATN representation导致的非贪婪处理。当词法分析器处于此模式并到达块(ESC|.)
时,排序约束要求它尽可能使用ESC
。