2017-02-01 18 views
1

これはANTLR4で私の文法である:私はのようなものを入力するとANTLR4の曖昧さ回避

grammar Hello; 
r : WORD ID ; 
ID : [a-z]+ ; 
WORD : [a-z]+ ;  
WS : [ \t\r\n]+ -> skip ; 

は:

line 1 missing WORD at 'hello' 

hello buddy 

私は、次のエラーメッセージが表示されましたしかし、文法を変更すると、

grammar Hello; 
r : WORD ID ; 
ID : [a-z]+ ; 
WORD : [1-9]+ ;  
WS : [ \t\r\n]+ -> skip ; 

ここで、WORDは数字ですが、すべて正常です。 最初の文法では、同じ正規表現を持つ2つの終端ノードがあるため、パーサーは実際の単語の対応関係を知らないことを強く疑う。 私はそれを間違って考えていますか?そうでない場合、同じ正規表現を持つ複数の端末を保持して、この問題をどのように解決しますか?

答えて

0

同じパターンに一致する端末を2つ持つことはできません。あなたの文法は実際には2回[a-z]+を一致させる必要がある場合

は、その後、

r : WORD WORD ; 

のような生産を使用して、差別は、パーサ/ツリートラバーサルのレベルで行われます。

WORDまたはIDのいずれかを固定リストに制限することができます。可能なすべての単語を端末として宣言し、それを使用して例を定義します。どのようなWORDすることができます。

0

ここで、WORDは数字ですが、すべて正常です。

そうでもない:レクサーは二つの規則でいくつかの入力を一致させることができます

$ alias 
alias grun='java org.antlr.v4.gui.TestRig' 
$ grun Hello r -tokens data.txt 
[@0,0:4='hello',<ID>,1:0] 
[@1,6:10='buddy',<ID>,1:6] 
[@2,12:11='<EOF>',<EOF>,2:0] 
line 1:0 missing WORD at 'hello' 

は、あいまいさがあり、それが最初のルールを選択します。 hello buddy入力すると、レクサーは、最初の文法を持つ2つのIDトークン

  • を生成し、それがあいまいだとIDが第二の文法を持つ最初の
  • が来るので、入力のみID WS ID
で一致させることができます

あなたはそうのような字句解析ルールで述語を明確にすることができます

grammar Question; 

/* Ambiguous input */ 

file 
    : HELLO ID 
    ; 

HELLO 
    : [a-z]+ {getText().equals("hello")}? ; 
ID : [a-z]+ ; 
WS : [ \t\r\n]+ -> skip ; 

実行:

$ grun Question file -tokens data.txt 
[@0,0:4='hello',<HELLO>,1:0] 
[@1,6:10='buddy',<ID>,1:6] 
[@2,12:11='<EOF>',<EOF>,2:0] 

The Definitive ANTLR Referenceの意味論的述語の詳細。