2012-01-26 7 views
5

利用可能なソースコードはhttps://gist.github.com/1684022をご覧ください。ANTLRレクサールールのあいまい性を解決する適切な方法はありますか?

ID : ('a'..'z' | 'A'..'Z') ('0'..'9' | 'a'..'z' | 'A'..'Z' | ' ')*; 

PITCH 
    : (('A'|'a') '#'?) 
    | (('B'|'b') '#'?) 
    | (('C'|'c') '#'?); 

もちろん、文字は「」あいまいさのようになります。

私は定義された2つのトークンを持っています。

私はさらに定義:

note : PITCH; 
name : ID; 
main : name ':' note '\n'? 

を今、私が入力したとします。パーサへの入力として "A A" を、私は常にエラーを取得します。どちらのパーサはIDまたはPITCHが最初に定義されているかどうかに応じて、PITCHまたはIDを期待:

mismatched input 'A' expecting ID 

意図したとおりに、それが動作するようにこれを解決する適切な方法は何ですか?説明されているように


、それは構文解析がどのように動作するかを直感的に理にかなっているものの、ANTLRは「正しいこと」を行いません。つまり、mainルールではname/IDが最初に来るはずですが、レクサーはこれを知らないように見え、PITCHとして「A」を識別します。これは「最長一致」/「最初に来る」ルールに従うからです。より合理的な "ルールは何を言う"ルール。

IDとPITCHの両方を一致させることで偽装/ハックする唯一の解決策ですが、後でdasblinkenlightと同じように再結合しますか?ここで

+0

はい。スペースはその質問とは何が関係していますか? – Ana

+1

見て、バート。私がANTLRを理解しているかどうかに関わらず、あなたが打ち続けるポイントは無関係です。私は解決策を探そうとしていますが、あなたは1つの答えと4つのコメントを提供しましたが、いずれも解決策ではなく、私の投稿や私の理解に関する解説です。あなたがANTLRを理解していて、自分の問題を私が理解しているよりもよく理解すれば、真の解決策を投稿してください。 – Ana

答えて

4

は、私はそれを動作させるために、この文法をファクタし直すだろうかです:

ID : (('a'..'z' | 'A'..'Z') ('0'..'9' | 'a'..'z' | 'A'..'Z' | ' ')+) 
    | ('d'..'z' | 'D'..'Z'); 

PITCH : 'a'..'c' | 'A'..'C'; 

SHARP : '#'; 

note : PITCH SHARP?; 

name : ID | PITCH; 

main : name ':' note '\n'? EOF 

これは、パーサーに「再会」GET 1文字の音名から長い名前を分離します。また、「シャープな」トークンは独自の名前を取得し、オプションのトークンとしてパーサーで認識されます。

+0

ありがとう、dasblinkenlight。感謝します。きれいな道があることを望んでいたが、これは行うだろう。 – Ana

+0

@Anaこれは、キーワードを識別子として使用するためのANTLRの標準的なアプローチです。あなたの場合、 'PITCH'は「キーワード」の役割を果たしますが、識別子は識別子のままです。 – dasblinkenlight

関連する問題