ANTLR3 - 决策可以使用多个备选方案匹配输入

时间:2017-06-22 20:27:55

标签: antlr antlr3

在以下代码上运行ANTLR3时,我收到消息 - 警告(200):MYGRAMMAR.g:40:36:决策可以匹配输入,例如" QMARK"使用多种选择:3,4 结果,替代(s)4被禁用该输入。

警告消息指向postfixExpr。有办法解决这个问题吗?

grammar MYGRAMMAR;
options {language = C;}

tokens {
  BANG        = '!';
  COLON       = ':';
  FALSE_LITERAL = 'false';
  GREATER     = '>';
  LSHIFT      = '<<';
  MINUS       = '-';
  MINUS_MINUS = '--';
  PLUS        = '+';
  PLUS_PLUS   = '++';
  QMARK       = '?';
  QMARK_COLON = '?:';
  TILDE       = '~';
  TRUE_LITERAL = 'true';
}


condExpr
                    :  shiftExpr  (QMARK  condExpr COLON  condExpr)? ;

shiftExpr
                    :  addExpr  ( shiftOp   addExpr)* ;

addExpr
                    :  qmarkColonExpr  ( addOp  qmarkColonExpr)* ;

qmarkColonExpr
                    :  prefixExpr  ( QMARK_COLON  prefixExpr )? ;

prefixExpr
                    :  ( prefixOrUnaryMinus |  postfixExpr) ;

prefixOrUnaryMinus
                    :  prefixOp  prefixExpr ;

postfixExpr
                    :  primaryExpr ( postfixOp | BANG | QMARK )*;

primaryExpr
                    :   literal ;



shiftOp
                    :  ( LSHIFT  | rShift);

addOp
                    :  (PLUS  | MINUS);

prefixOp
                    :  ( BANG  | MINUS  | TILDE  | PLUS_PLUS  | MINUS_MINUS );

postfixOp
                    :  (PLUS_PLUS  | MINUS_MINUS);

rShift
                    :  (GREATER GREATER)=> a=GREATER b=GREATER {assertNoSpace($a,$b)}? ;

literal
                    :  ( TRUE_LITERAL  | FALSE_LITERAL );

assertNoSpace       [pANTLR3_COMMON_TOKEN t1, pANTLR3_COMMON_TOKEN t2]
                    : { $t1->line == $t2->line && $t1->getCharPositionInLine($t1) + 1 == $t2->getCharPositionInLine($t2) }? ;

1 个答案:

答案 0 :(得分:0)

我认为一个问题是,PLUS_PLUS以及MINUS_MINUS永远不会匹配,因为它们是在相应的PLUSMINUS令牌之后定义的。因此词法分析器将始终输出两个PLUS标记而不是一个PLUS_PLUS标记。

为了获得类似这样的内容,您必须在PLUS_PLUSMINUS_MINUS令牌之前定义PLUSMINUS令牌,因为词法分析器会按顺序处理它们一旦找到匹配当前输入的方法,就会定义并且不会再看了。

同样的问题适用于QMARK_COLON,因为它是在QMARK之后定义的(这只是一个问题,因为还有另一个令牌类型COLON来匹配以下冒号。)

查看修改歧义是否可以解决错误消息。