2016-04-28 19 views
0

次ANTLR v3の文法を考える:間違っAST選択

tokens 
{ 
    OPTION; 
    UNKNOWN; 
} 

statement : my_statement 
      | UNKNOWN_KEYWORD -> ^(UNKNOWN) 
      ; 

my_statement : FIRST SECOND type = THIRD? -> ^(OPTION $type?); 


FIRST : 'my'; 

SECOND : 'keyword'; 

THIRD: 'best'; 

UNKNOWN_KEYWORD : .; 

文字列「私のキーワードthis_is_garbageが」解析されたときに、それはpicked-されている必要がありながら、それはmy_statementにより、ピックアップされていることであるのはなぜUNKNOWN_KEYWORD(返されるASTは^(OPTION $ type?)ですが、^(UNKNOWN)のはずですか?

+0

あなたのパーサールールでは 'THIRD'はオプションですので、ルールは 'my keyword'とちょうどよく似ていて、' this_is_garbage'に進むことさえしませんでした。 –

+0

はい、それはmy_keywordと一致しませんが、AST ^(UNKNOWN)は返されません。これは、ASTを返すように文法を修正できますか? – user5793565

+1

あなたが見ている振る舞いはまさに私がこの文法から期待しているものです:)まあ、 'UNKNOWN_KEYWORD'はどこかで定義されていると仮定します(' UNKNOWN'は1文字です)。 'my_statement'がマッチするので、' statement'の2番目のブランチは試行されません。 –

答えて

2

入力my keyword this_is_garbageは、(仮定スペースが隠されている)は、以下のようにトークン化されるであろう。

FIRST    'my' 
SECOND    'keyword' 
UNKNOWN_KEYWORD 't' 
UNKNOWN_KEYWORD 'h' 
... 
UNKNOWN_KEYWORD 'e' 

即ち、FIRSTトークン、トークンSECOND、次いで15個のUNKNOWN_KEYWORDトークン。

あなたが今statementに一致するようにしようとすると、ルールmy_statementは喜んでトークンストリームで15個のUNKNOWN_KEYWORDトークンを残し、FIRSTSECONDトークンを消費することになります。

あなたが繰り返しこのようなあなたのstatementルールマッチする場合は、:

parse 
: statement+ EOF 
; 

を、あなたは、次の構文解析ツリーで終わるだろう:

enter image description here

またはこのASTを:

enter image description here

そして、あなたは1つの代替にグループにすべてUNKNOWN_KEYWORDのトークンをしたい場合、あなたがする必要があります:

statement : my_statement 
      | UNKNOWN_KEYWORD+ -> ^(UNKNOWN) 
      ; 

注意ごレクサー内部のあなたができないグループUNKNOWN_KEYWORDこと:

UNKNOWN_KEYWORD : .+ ; 

そのため、字句解析器が文字ストリーム全体を1つの単一のUNKNOWN_KEYWORDトークンに盛り上げるようにする。

+0

UNKNOWN_KEYWORDは、意図した動作に合わせるための単一のcharだけでなく、*ループである必要があることもここに追加する必要があります。 –

+0

ええ、おそらく '+'を意味します。 –

+0

真実ですが、正解です。しかし、ループについてのあなたの追加はそうではありません:-) UNKNOWN_KEYWORDは、その前に一致する他のルールがない場合にのみすべてを食べます。文法の終わりにキャッチオールルールを持つことはまったく問題ありません。 –

関連する問題