7

我正在阅读明确的 ANTLR4 参考,并对其中一个示例(第 76 页)有疑问:

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

该规则匹配一个典型的 C++ 字符串——一个包含在 中的字符序列"",它也可以包含\"

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

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

4

1 回答 1

11

ANTLR 4 词法分析器通常以最长匹配获胜行为运行,而不考虑替代项出现在语法中的顺序。如果两个词法分析器规则匹配相同的最长输入序列,则仅比较这些规则的相对顺序以确定如何分配标记类型。

一旦词法分析器到达非贪婪可选或闭包,规则中的行为就会改变。从那一刻到规则结束,该规则中的所有备选方案都将被视为有序,备选方案最低的路径获胜。由于我们在底层 ATN 表示中订购替代品的方式,这种看似奇怪的行为实际上是造成非贪婪处理的原因。当词法分析器处于此模式并到达 block(ESC|.)时,排序约束要求ESC尽可能使用它。

于 2013-09-14T02:58:13.453 回答