2011-11-11 13 views
2

EBNF形式のスカラからANTLRへの接尾辞、接尾辞および接頭辞の規則を変換しようとしていますが、infixExpression規則の左回帰に関するエラーが表示されています。Antlr left recursive

問題のルールは以下のとおりです。

public symbolOrID 
: ID 
| Symbol 
; 

public postfixExpression 
: infixExpression symbolOrID? -> ^(R__PostfixExpression infixExpression symbolOrID?) 
; 

public infixExpression 
: prefixExpression 
| infixExpression (symbolOrID infixExpression)? -> ^(R__InfixExpression infixExpression symbolOrID? infixExpression?) 
; 

public prefixExpression 
: prefixCharacter? simpleExpression -> ^(R__PrefixExpression prefixCharacter? simpleExpression) 
; 

public prefixCharacter 
: '-' | '+' | '~' | '!' | '#' 
; 

public simpleExpression 
: constant 
; 

私はinfixExpressionルールを変更した場合:

public infixExpression 
: prefixExpression (symbolOrID infixExpression)? -> ^(R__InfixExpression prefixExpression symbolOrID? infixExpression?) 
; 

そして、それは代わりに文句:

warning(200): Hydra.g3:108:26: Decision can match input such as "{ID, Symbol} {'!'..'#', '+', '-', '~'} String" using multiple alternatives: 1, 2 
As a result, alternative(s) 2 were disabled for that input 
warning(200): Hydra.g3:108:26: Decision can match input such as "{ID, Symbol} {'!'..'#', '+', '-', '~'} Number" using multiple alternatives: 1, 2 
As a result, alternative(s) 2 were disabled for that input 
warning(200): Hydra.g3:108:26: Decision can match input such as "{ID, Symbol} {'!'..'#', '+', '-', '~'} Boolean" using multiple alternatives: 1, 2 
As a result, alternative(s) 2 were disabled for that input 
warning(200): Hydra.g3:108:26: Decision can match input such as "{ID, Symbol} {'!'..'#', '+', '-', '~'} Regex" using multiple alternatives: 1, 2 
As a result, alternative(s) 2 were disabled for that input 
warning(200): Hydra.g3:108:26: Decision can match input such as "{ID, Symbol} {'!'..'#', '+', '-', '~'} Null" using multiple alternatives: 1, 2 
As a result, alternative(s) 2 were disabled for that input 

最後に、方法があります条件付きでAST内にノードを作成して、ルールの左部分だけが真である場合にはそれを追加しないようにするのレベルですか?例:現在作成されたASTは、この式のためで解析されexpresionは、a || bある場合

conditional_and_expression 
    conditional_or_expression 
    null_coalescing_expression 

:のように

conditional_or_expression: 
    conditional_and_expression ('||' conditional_or_expression)? 
; 

は、私のような階層構造を次の文法を作成して言うことができます

conditional_and_expression 
    conditional_or_expression 

conditional_or_expressionの部分を取得するにはどうすれば入手できますか? JavaCCので

、あなただけ例えば、ノードアリティを設定することができます。:#ConditionalOrExpression(>1)

EDIT:それは、中置式が今修正properyで、少し遅れての最後の夜でした!

最終編集:私はそれが最終的に動作するようになった方法は、以下のルールだった:

public symbolOrID 
: ID 
| Symbol 
; 

public postfixExpression 
: infixExpression (symbolOrID^)? 
; 

public infixExpression 
: (prefixExpression symbolOrID)=> prefixExpression symbolOrID^ infixExpression 
| prefixExpression 
; 

public prefixExpression 
: prefixCharacter^ simpleExpression 
| simpleExpression 
; 

public prefixCharacter 
: '-' | '+' | '~' | '!' | '#' 
; 

public simpleExpression 
: constant 
; 
+1

ルールは左再帰されていません。あなたはあなたの質問を編集し、あなたが言及したエラーを示す変更なしで、私または他の誰かが実行できる完全な文法を提供できますか?そして、私はあなたが "条件付きでノードを作る"ことが何を意味するのか分かりません。そして、あなたは 'infixExpression'ルールを2回投稿しました(あなたはそれについて何も変更しませんでした...)。 –

+0

残念ながら、これは言語にとっては非常に重要ですが初期の段階ですので、文法の秘密の詳細を徹底的に守らなければなりません。それが実装されたら、私はオープンソースを公開しようとしていますが、 – Darkzaelus

答えて

1

Darkzaelusは書いた:

を私が変換しようとしていますEBNF形式のスカラからANTLRへの接尾辞、接尾辞、接頭辞の規則がありますが、左回帰に関するエラーが表示されます

私のコメントで述べたように、投稿したルールには再帰がありません。

Darkzaelusは書いた:

をそれだけでconditional_or_expressionの一部を取得するので、私はそれを得ることができる方法は?

conditional_and_expression 
      \ 
    conditional_or_expression 

のみ(パースツリーがないAST、示されている)そのように表示されている:木は、その場合には、私はあなたがANTLRWorks'インタプリタやデバッガを使用していると仮定してい

、 。あなたが適切ASTにあなたのorExpressionを変換する場合、式a || bはなります:たとえば

|| 
/\ 
a b 

(すなわち||ルートとして、子ノードとしてab

、次の文法を取ります:

grammar T; 

options { 
    output=AST; 
} 

parse 
    : expr EOF -> expr 
    ; 

expr 
    : or_expr 
    ; 

or_expr 
    : and_expr ('||'^ and_expr)* 
    ; 

and_expr 
    : add_expr ('&&'^ add_expr)* 
    ; 

add_expr 
    : atom (('+' | '-')^ atom)* 
    ; 

atom 
    : NUMBER 
    | '(' expr ')' -> expr 
    ; 

NUMBER : '0'..'9'+; 

あなたが今ANTLRWork、上記の文法から生成されたパーザと12+34を解析した場合S(またはEclipse ANTLR IDE)は、次の構文解析ツリーが表示されます:

enter image description here

をが、これはパーサが作成ない ASTです。 ASTは、実際には次のようになります。

enter image description here

(すなわちor_exprand_expr "層" はありませんそこにある)

Darkzaelusが書いた:

残念なことに、これはかなり大変ですしかし、私は文法の秘密の完全な詳細を守ることを余儀なくされています。

問題はありませんが、重要な情報を保留すると、人々があなたの質問に正しく答えることができないことを認識しなければなりません。あなたは全体の文法を投稿する必要がありますが、あなたがしたい場合は、実際にあなたが言及エラー(複数可)を引き起こす左再帰、あなたが必見ポスト(部分)文法では役立ちません。私がそれを再現できないなら、それは存在しません! :)

+0

バート、あなたに '.g3'のコピーを送ることができるでしょうか?問題が解決したら、答えを更新できますか? – Darkzaelus

+0

@Darkzaelusですが、答えはここの質問と同期していません。エラーが再現できるような方法で文法を減らすことができない場合、私はお手伝いできません。申し訳ありません。そして、私は1対1のコンサルティングのためにオープンしていますが、無料ではありません:)(私の時間単価を知りたい場合は、私の回線を落としてください:私の電子メールは私のプロフィールにあります)。 –

+0

バートは、残念ながら約30分前に文法を修正しました!私はルートに印を付けるためにあなたのトリックを使用したのと同じようにあなたの答えに印をつけます。あなたの助けと良い答えをありがとう – Darkzaelus

0

この生産は:

infixExpr ::= PrefixExpr 
      | InfixExpr id [nl] InfixExpr 

が実際に

infixExpr ::= PrefixExpr 
      | PrefixExpr id [nl] InfixExpr 

のように書き換えることができます、私はこれは単に文法エラーです賭けます。それが大丈夫であるという例を見てみましょう。最初の文法で(部分的に)何かを減らしてから、もう1つを試してみましょう。

InfixExpr id [nl] InfixExpr      
// Apply the second reduction to the first InfixExpr 
InfixExpr id [nl] InfixExpr id [nl] InfixExpr 
// Apply the first reduction to the (new) first InfixExpr 
PrefixExpr id [nl] InfixExpr id [nl] InfixExpr 
// Apply the first reduction to the new first InfixExpr 
PrefixExpr id [nl] PrefixExpr id [nl] InfixExpr 
// Apply the first reduction to the new first InfixExpr 
PrefixExpr id [nl] PrefixExpr id [nl] PrefixExpr 

のが第二の文法でそれを削減してみましょう:

PrefixExpr id [nl] InfixExpr      
// Apply the second reduction to the first InfixExpr 
PrefixExpr id [nl] PrefixExpr id [nl] InfixExpr 
// Apply the first reduction to the new first InfixExpr 
PrefixExpr id [nl] PrefixExpr id [nl] PrefixExpr 

見ての通り、あなたはどちらの場合も同等のASTで終わります。あなたが投稿