web-dev-qa-db-ja.com

ANTLR4:空白の処理

私はこのような空白処理を使用する多くのANTLR文法を見てきました:

WS: [ \n\t\r]+ -> skip;
// or
WS: [ \n\t\r]+ -> channel(HIDDEN);

したがって、空白はそれぞれ破棄され、非表示のチャネルに送信されます。

このような文法で:

grammar Not;

start:      expression;
expression: NOT expression
          | (TRUE | FALSE);

NOT:    'not';
TRUE:   'true';
FALSE:  'false';
WS: [ \n\t\r]+ -> skip;

有効な入力は '真ではない'または '偽ではない'ですが、 '真ではない'でもあり、これは望ましい結果ではありません。文法を次のように変更します。

grammar Not;

start:      expression;

expression: NOT WS+ expression
          | (TRUE | FALSE);

NOT:    'not';

TRUE:   'true';
FALSE:  'false';

WS: [ \n\t\r];

問題を修正しますが、各ルールで空白を手動で処理したくありません。

一般に、いくつかの例外を除いて、各トークンの間に空白を入れたいと思います(たとえば、 '!true'の間に空白は必要ありません)。

これを行う簡単な方法はありますか?

19
flux

キーワードではない単語を処理するためにIDENTIFIERレクサールールを追加します。

IDENTIFIER : [a-zA-Z]+;

これで、テキストnottrueは単一のIDENTIFIERトークンになり、パーサーはnot trueの個別のキーワードの代わりに受け入れません。

IDENTIFIERが定義されていることを確認してくださいafter他のキーワード。レクサーは、NOTIDENTIFIERの両方がテキストnotと一致することを検出し、文法に最初に表示されるトークンタイプにトークンタイプを割り当てます。

17
Sam Harwell