7

私は明確な ANTLR4 リファレンスを読んでいて、例の 1 つに関して質問があります (p. 76):

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

この規則は、典型的な C++ 文字列 ( に含まれる char シーケンスで""あり、これも含むことができる) に一致し\"ます。

STRING私の期待では、非貪欲な構造のため、ルールは可能な限り最小の文字列に一致するはずです。したがって、 a が見つかった場合は、ルールの最後でtoおよびtoに\"マップされます。これは、可能な限り最小の文字列になるためです。これの代わりに、 aは にマップされます。それは私が期待したものではないので、理解に問題があります。\.""\"ESC

ここで正確に何が起こりますか?(ESC|.)分離された DFA が最初に一致し、別の DFAがコンストラクトSTRINGの既に一致した文字列を使用して一致するのはこのようなもの(ESC|.)ですか? 私はその本を最後まで読んでいないことを認めなければなりません。

4

1 に答える 1

11

ANTLR 4 lexer は、通常、代替が文法に現れる順序に関係なく、最長一致が勝つ動作で動作します。2 つのレクサールールが同じ最長の入力シーケンスに一致する場合にのみ、それらのルールの相対的な順序が比較され、トークン タイプの割り当て方法が決定されます。

lexer が貪欲でないオプションまたはクロージャに到達するとすぐに、ルール内の動作が変更されます。その時点からルールの最後まで、そのルール内のすべての選択肢は順序付けされたものとして扱われ、選択肢が最も少ないパスが優先されます。この一見奇妙な動作は、基本的な ATN 表現で代替を注文する方法による、貪欲でない処理の実際の原因です。レクサーがこのモードにあり、 block に到達する(ESC|.)と、順序制約により、ESC可能であればそれを使用する必要があります。

于 2013-09-14T02:58:13.453 に答える