1

LALRからANTLRに文法を翻訳していますが、この1つのルールである区分的表現を翻訳するのに問題があります。

添付されているのはサンプル文法です。

grammar Test;
options {
  language = Java;
  output = AST;
}

parse : expression ';'
      ;

expression : binaryExpression
           | piecesExpression
           ;

binaryExpression : addingExpression (('=='|'!='|'<='|'>='|'>'|'<') addingExpression)*
                 ;

addingExpression : multiplyingExpression (('+'|'-') multiplyingExpression)*
                 ;

multiplyingExpression : unaryExpression 
                        (('*'|'/') unaryExpression)*
                      ;

unaryExpression: ('!'|'-')* primitiveElement;   

primitiveElement : literalExpression
                 | id
                 | '(' expression ')'
                 ;  

literalExpression : INT
                  ;              

id : IDENTIFIER
   ;

piecesExpression : 'piecewise' '{' piece expression '}'  ('(' expression ',' expression ')')? expression?
                 ;

piece : expression '->' expression ';' (expression '->' expression ';')*
      ;


// L E X I C A L   R U L E S      

INT : DIGITS ;   

IDENTIFIER : LETTER (LETTER | DIGIT)*;

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

fragment LETTER : ('a'..'z' | 'A'..'Z' | '_') ;
fragment DIGITS: DIGIT+;
fragment DIGIT : '0'..'9';

ANTLRv3.5はpiecesExpressionルールについて不平を言っています。2つの致命的なエラーがあり、バックトラックオプションは使用しません。

推測される結果:

piecewise {t -> s; t -> x; 100}
piecewise {t -> s; t -> x; 100} (0, x+1) 
piecewise {t -> s; t -> x; 100} (0, x+1) y+5

pieceExpressionはどのようにして上記の結果をキャプチャできますか?

前もって感謝します!

4

1 に答える 1

2

ANTLR には、(少なくとも) 2 つのケースでどの代替案を採用するかを決定する際に問題があります。

  1. pieceで始まりますがexpression、内部ではpiecewise{...}、またで終わる必要がありますexpression
  2. piecesExpressionで終わります'(' expression ...が、オプションの末尾もありますexpression(また、順番にprimitiveElement一致'(' expression ...します)

グローバルなバックトラッキングを使用する必要はありませんが、多くのルールを書き直すことなく、(...)=>上記の 2 つの問題を修正するためにいくつかの述語 (以下の例) を追加する必要があります。

これを試して:

piecesExpression
 : 'piecewise' '{' ((expression '->')=> piece)+ expression '}' 
     ( ('(' expression ',')=> '(' expression ',' expression ')' expression?
     |                        expression
     )
 ;

piece
 : expression '->' expression ';'
 ;
于 2013-03-05T11:22:36.583 に答える