1

backtrack=true;を使用せずにこの問題を解決する方法がわかりません。

私のサンプル文法:

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

parse : expression 
      ;
expression : binaryExpression 
           | tupleExpression 
           ;

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

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

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

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

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

sumExpression : 'sum'|'div'|'inter' expression
              ;

tupleExpression : ('<' expression '>' (',' '<' expression '>')*)
                ;

literalExpression : INT
                  ;              

id : IDENTIFIER
   ;

// 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';

警告が発生しないように文法を修正する方法はありますか?場合に応じて両方の選択肢を選択したいとします。

前もって感謝します!

4

1 に答える 1

3

ご了承ください:

sumExpression : 'sum'|'div'|'inter' expression
              ;

次のように解釈されます:

sumExpression : 'sum'   /* nothing */
              | 'div'   /* nothing */
              | 'inter' expression
              ;

|優先順位が低いためです。あなたはおそらく欲しい:

sumExpression : ('sum'|'div'|'inter') expression
              ;

場合に応じて両方の選択肢を選択したいとします。

それは不可能です。パーサーに両方(またはそれ以上)の選択肢を選択させることはできず、1つしか選択できません。

なぜ文法が曖昧なのかご存知だと思いますか?そうでない場合は、次の理由があります。入力A div Bは2つの方法で解析できます。

代替案1

unaryExpression 'div' unaryExpression
      |                     |
      A                     B

代替案2

id sumExpression
 |       |   \
 A     'div'  B

あなたが望んでいるように見えます'sum''div'そして'inter'ある種の単項演算子であり、その場合、あなたはそれらをあなたのunaryExpressionルールにマージすることができます:

unaryExpression : '!' unaryExpression
                | '-' unaryExpression
                | 'sum' unaryExpression
                | 'div' unaryExpression
                | 'inter' unaryExpression
                | primitiveElement
                ; 

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

そうすれば、あいまいさはありません。これで、およびとしてA div B解析されることに注意してください。multiplyingExpressionA div sum B

multiplyingExpression
       /    \    
    'div'   unaryExpression
    /            / \ 
   A         'sum'  B
于 2013-02-28T07:21:21.720 に答える