2012-01-01 9 views
1

私は未知のツール用に開発された既存の文法をAntlrに移植しようとしています。 文法には、TEXTやTEXT_WITHOUT_Aのようなトークンが2つあるユースケースがあります。 文法の中には、aを除いたテキストのみを許可するものがありますが、残りはテキストを使用するとOKです。Antlrでトークンを別のトークンのサブセットに変換する方法

私の最初の試みでは、次の文法が生成されましたが、問題は、txtが実際にそのスーパーセットである場合、Antlrはより具体的な文法規則(txtwa)に一致します。私が 'sometextwth'のようなものを入力すると、Antlrはテキスト(txt)の規則に従わない。予想される入力はtxtであり、提供された入力は一致するが、Antlrは入力がtxtwaと一致していると判断する文法のその時点では期待されていないが、txtを使わないことを選択する。

/*------------------------------------------------------------------ 
* PARSER RULES 
*------------------------------------------------------------------*/ 
expr : ( txt)* ; 
txt : TEXT ; 
txtwa : LETTERS_MINUS_A; 
term : factor ((MULT | DIV) factor)*; 
factor : NUMBER; 

/*------------------------------------------------------------------ 
* LEXER RULES 
*------------------------------------------------------------------*/ 


NUMBER    : (DIGIT)+ ; 

WHITESPACE  : ('\t' | ' ' | '\r' | '\n' | '\u000C')+ {$channel = HIDDEN;} ; 

fragment LETTER_MINUS_A : ('b'..'z' | 'B'..'Z'); 

fragment LETTER : ('a'..'z' | 'A'..'Z'); 


fragment DIGIT  : '0'..'9' ; 



LETTERS_MINUS_A 
    : LETTER_MINUS_A (LETTER_MINUS_A)*;  

TEXT : LETTER (LETTER)* ; 

私はbtwを動作させることなく(txt | txtwa)自由にtxtを使用したいと思います。 私はここで何が欠けていますか?

答えて

1

レクサーは、特定の時間にパーサーが必要とするものを考慮しないことを認識する必要があります。単に、レクサールールを上から下に通るトークンを構築しようとします。あなたがTEXTLETTERS_MINUS_Aを定義しているので

は、LETTERS_MINUS_Aは常に代わりにしか'a'年代と'A'年代が含まれていますTEXT、で作成されます。

これは、ANTLRがどのように機能するかを示しています。

でき単にLETTERS_MINUS_Aルールを捨てて、このような何かをされて実行します。

txt 
: TEXT 
; 

txtwa 
: TEXT 
    { 
    if($TEXT.text.contains("a") || $TEXT.text.contains("A")) { 
     throw new Exception("Eeek, I saw an `[aA]`!"); 
    } 
    } 
; 
+1

私はTXTとtxtwaが独自に使用されているオリジナルの文法のセクションを持っています。私は単純にtxtとtxtwaが必要です.txtwaはtxtより小さい文字です。私は両方を使用する必要があります。 – mahonya

+0

@sarikan、私の提案はまだテキストとtextwaのルールの両方を使用しています... –

+1

あなたは正しい答えを与えました。それはあなたがパーサールールセクションを使用しているのを見落としただけです。ありがとう、これは本当に助けになった。 – mahonya

関連する問題