[antlr-interest] Expression parser expecting token at EOF

Aaron crackajaxx at gmail.com
Tue Mar 14 11:48:07 PST 2006


I apologize if this is the wrong forum for this message, but I'm still
new here (so punt me the right direction if need be).  I've written a
parser for what I think is a relatively simple grammar for
expressions.  I'm using antlr 2.7.5 with C# as the language.

I noticed that when I provided the input "test" to the expression
element that it would fail when attempting to do a lookahead(1).  So I
narrowed the problem down to the variant element that is listed in the
grammer and reduced the variant element to only allow one expression
for ease of reading.

I wrote a small C# wrapper around this that calls variant() on the parser.

The sample works for the inputs "test(20)" and "test[20]", but fails for "test".
The problem appears to be in the output code to "variantAtoms" which
performs a switch(LA(1)) and then requires a token to be present or it
throws NoViableAltException and my execution is done.

Ironically, if I enter "test)" it works.  variantAtom has a case
statement for RPAREN and for the life of me I can't understand where
in the tree it would expect to see RPAREN as the next token.

Thanks in advance...

----------

class KExprParser extends Parser;
options
{
    buildAST = true;
}

tokens
{
    UNARY_MINUS; UNARY_PLUS;
}

expression
    :    assignmentExpression
    ;

assignmentExpression
    :    logicalOrExpression
    ;

logicalOrExpression
    :    logicalAndExpression ("or"^ logicalAndExpression)*
    ;

logicalAndExpression
    :    eqExpression ("and"^ eqExpression)*
    ;

eqExpression
    :    relationalExpression (EQ^ relationalExpression)*
    ;

relationalExpression
    :    additiveExpression ( ( LTNE^ | GTNE^ | LTEQ^ | GTEQ^ )
additiveExpression)*
    ;

additiveExpression
    :    multiplicativeExpression ((PLUS^ | MINUS^) multiplicativeExpression)*
    ;

multiplicativeExpression
    :    unaryExpression ((STAR^ | DIV^ | MOD^ ) unaryExpression)*
    ;

unaryExpression
    :    MINUS^ {#MINUS.setType(UNARY_MINUS);} unaryExpression
    |    PLUS^  {#PLUS.setType(UNARY_PLUS);} unaryExpression
    |    unaryExpressionNotPlusMinus
    ;

unaryExpressionNotPlusMinus
    :    ("not"^) unaryExpression
    |    primaryExpression
    ;

primaryExpression
    :    variant
    |    NUMBER
    |    "true"^
    |    "false"^
    |    LPAREN! assignmentExpression RPAREN!
    ;

variant
    :    IDENT variantAtoms
    ;

variantAtoms
    :
    |    LBRACKET! NUMBER RBRACKET!
    |    LPAREN! expression RPAREN!
    ;

class KExprLexer extends Lexer;

options
{
    caseSensitive = false;
    testLiterals = false;
    k = 2;
}

WS
    :    (' ' | '\t' | '\n' | '\r')
    { _ttype = Token.SKIP ; }
    ;

LBRACKET    :    '[' ;
RBRACKET    :    ']' ;

LPAREN    :    '('    ;
RPAREN    :    ')' ;
STAR    :    '*' ;
DIV        :    '/' ;
PLUS    :   '+' ;
MINUS   :   '-' ;
MOD        :    '%' ;
COLON    :    ':' ;
QUESTION    :    '?' ;
COMMA    :    ',' ;

ATSIGN    :    '@' ;

GTNE    :   ">" ;
GTEQ    :   ">=" ;
LTNE    :   "<" ;
LTEQ    :    "<=" ;
EQ      :   "=" ;

STRING_LITERAL
    :    '"' (~'"')* '"'
    |    '\'' (~'\'')* '\''
    ;

IDENT
    options {testLiterals=true;}
    :    ('a' .. 'z') ('a' .. 'z' | '0' .. '9' | '_' | '.')*
    ;

NUMBER
    :    ('0'..'9')+ ('.' (('0'..'9')+)?)?
    ;


More information about the antlr-interest mailing list