0
votes

When running ANTLR3 on the following code, I get the message - warning(200): MYGRAMMAR.g:40:36: Decision can match input such as "QMARK" using multiple alternatives: 3, 4 As a result, alternative(s) 4 were disabled for that input.

The warning message is pointing me to postfixExpr. Is there a way to fix this?

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

1 Answers

0
votes

I think one problem is that PLUS_PLUS as well as MINUS_MINUS will never be matched as they are defined after the respective PLUS or MINUS token. therefore the lexer will always output two PLUS tokens instead of one PLUS_PLUS token.

In order to avaoid something like this you have to define your PLUS_PLUS or MINUS_MINUS token before the PLUS or MINUS token as the lexer processes them in the order they are defined and won't look any further once it found a way to match the current input.

The same problem applies to QMARK_COLON as it is defined after QMARK (this only is a problem because there is another token type COLON to match the following colon).

See if fixing the ambiguities resolves the error message.