Lexerルール
覚え書きです。
$channel=HIDDENとskip()の違い
$channel=HIDDENは、hidden channelトークンと位置づけ、これはパーサに送りません。ただし、hidden channelトークンとして尋ねることはできます。
文字通りトークンをスルーさせる場合はskip()を使用します。
文字通りトークンをスルーさせる場合はskip()を使用します。
grammar A;
stat : (format {
System.out.println("str : " + $format.str);
System.out.println("text : " + $format.text);
} )+
;
format returns [String str]
: 'int' id=ID ';' NEWLINE {$str = $id.text; }
;
ID :('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*
;
WS : ('\t' | ' ')+
{ skip(); }
// { $channel = HIDDEN; }
;
NEWLINE : '\r'? '\n' ;
このとき、入力テキストを次とする。
int foo;
- $channel = HIDDENの場合の出力結果
str : foo text : int foo;
- skip()の場合の出力結果
str : foo text : intfoo;
違いとしては、textの出力にスペースが入るか入らないか。
fragment修飾子
ときには、lexer grammarを読みやすいようにヘルプやルールが必要となります。
ルールの前にfragment修飾子を使用してください。
fragmentをつけるとそれ自体はトークンを作らず、マクロのようになります。
ルールの前にfragment修飾子を使用してください。
fragmentをつけるとそれ自体はトークンを作らず、マクロのようになります。
HexLiteral : '0' ('x'|'X') HexDigit+ ; fragment HexDigit : ('0'..'9'|'a'..'f'|'A'..'F') ;
この場合、HexDigitはそれ自身がトークンではありません。それはHexLiteralから呼び出されるのみできます。
lexer内で使うものに付けるようです。parser側で使われるトークンに付けるとエラーになります。