入力が2つのレクサールールに一致すると、ANTLRは最長または最初のどちらかを選択します。disambiguateを参照してください。あなたの文法では、in
は決してCONVERT
、UNIT
として解釈され、3つのUNIT
トークンがあるので、ルール
conversion: NUMBER UNIT CONVERT UNIT;
は動作しないことができます。
$ grun Question question -tokens -diagnostics input.txt
[@0,0:0='1',<NUMBER>,1:0]
[@1,1:1=' ',<WS>,channel=1,1:1]
[@2,2:3='in',<UNIT>,1:2]
[@3,4:4=' ',<WS>,channel=1,1:4]
[@4,5:6='in',<UNIT>,1:5]
[@5,7:7=' ',<WS>,channel=1,1:7]
[@6,8:13='meters',<UNIT>,1:8]
[@7,14:14='\n',<NL>,1:14]
[@8,15:14='<EOF>',<EOF>,2:0]
Question last update 0159
line 1:5 missing 'in' at 'in'
line 1:8 mismatched input 'meters' expecting <EOF>
何ができるかが唯一持っていることですID
またはTEXT
トークンと、このように、ラベルとそれらを区別する:
grammar Question;
question
@init {System.out.println("Question last update 0132");}
: conversion NL EOF
;
conversion
: NUMBER unit1=ID convert=ID unit2=ID
{System.out.println("Quantity " + $NUMBER.text + " " + $unit1.text +
" to convert " + $convert.text + " " + $unit2.text);}
;
ID : LETTER (LETTER | DIGIT | '_')* ; // or TEXT : LETTER+ ;
NUMBER : DIGIT+ ;
NL : [\r\n] ;
WS : [ \t] -> channel(HIDDEN) ; // -> skip ;
fragment LETTER : [a-zA-Z] ;
fragment DIGIT : [0-9] ;
実行:
$ grun Question question -tokens -diagnostics input.txt
[@0,0:0='1',<NUMBER>,1:0]
[@1,1:1=' ',<WS>,channel=1,1:1]
[@2,2:3='in',<ID>,1:2]
[@3,4:4=' ',<WS>,channel=1,1:4]
[@4,5:6='in',<ID>,1:5]
[@5,7:7=' ',<WS>,channel=1,1:7]
[@6,8:13='meters',<ID>,1:8]
[@7,14:14='\n',<NL>,1:14]
[@8,15:14='<EOF>',<EOF>,2:0]
Question last update 0132
Quantity 1 in to convert in meters
ラベルは訪問者にルールのコンテキストから入手可能ですので、同じタイプのトークンを区別することは容易です。
例にレクサールールを追加して、より明確にしました。レクサールールのすべてのテキストをキャッチし、訪問者で手動で解析すると、Antlrを使用する目的が無効になります。レクサーの規則を文法規則に移すと、文法は読みにくくなります。 ... ' – Toast