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
              ;

假设我想根据情况选择这两种选择。

这是不可能的:你不能让解析器同时选择两个(或多个)选项,它只能选择一个。

我想你知道为什么语法是模棱两可的吗?如果不是,原因如下:A div B可以通过两种方式解析输入:

备选方案 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现在将被解析为 amultiplyingExpressionA div sum Bas:

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