删除警告而不是使用回溯选项

时间:2013-02-28 03:13:33

标签: antlr antlr3

我不知道如何在不使用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';

有没有办法修复语法,这样就不会发生警告?我们假设我想根据具体情况选择两种选择。

提前谢谢!

1 个答案:

答案 0 :(得分: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现在将被解析为multiplyingExpressionA div sum B

multiplyingExpression
       /    \    
    'div'   unaryExpression
    /            / \ 
   A         'sum'  B
相关问题