[antlr-interest] Problem with Simple Grammar : NoViableAltException

Kirby Bohling kirby.bohling at gmail.com
Sun Mar 27 21:12:42 PDT 2011


Rory,

I'm pretty sure the problem is that DIGIT is a fragment, but you are
using it as part of a parser rule (I would have thought that this
wouldn't be successfully parsed by ANTLR).

My guess is that is at least part of the problem.  You might also want
to split up your lexer and grammar rules, top to bottom.  I generally
put all the parser rules on the top, and all the lexer rules on the
bottom (actually I generally split all my grammars, as it makes it
harder to accidentally mix parser/lexer rules up mentally).

I think that your grammar is ill-defined, and that you don't yet have
figured out what is a token vs. what is a parser rule.  I'd take a
look at the C or Java lexers and see how they handle what is and isn't
a token.  I think once you clearly differentiate between the different
token types you need, the rest would be an easier mental model to
grasp.

My guess is that you want 'name' to be something like an IDENTIFIER in
C, and then have INTEGER, FLOAT, STRING tokens, all of which would be
options for the value rule.  I'd also be fairly careful about using
the created tokens in parser rules ('=' and '_' are both examples in
your grammar below that I'd likely just change over to real tokens to
avoid any problems).

I'm still learning more about ANTLR, and I've screwed this up plenty
of times, so don't read it as harsh criticism.

Kirby


On Sun, Mar 27, 2011 at 10:49 PM, Rory Winston <rory.winston at gmail.com> wrote:
>>
>> Hi all
>>
>> Im having some problems with a simple grammar that I have defined. The
>> grammar is as follows:
>>
>> grammar RvMessage;
>>
>> START_MSG: '{';
>> END_MSG: '}';
>>
>> parse     :     message+ EOF;
>>
>> message : START_MSG field+ END_MSG;
>>
>> field : name '=' value;
>>
>> fragment LOWER: 'a'..'z';
>> fragment UPPER: 'A'..'Z';
>> LETTER: LOWER | UPPER;
>>
>> fragment DIGIT: '0'..'9';
>>
>> name : LETTER (LETTER | DIGIT | '_')*;
>>
>> NEWLINE: ('\r'? '\n')+ { $channel=HIDDEN; };
>>
>> fragment SPACE: ' ' | '\t';
>> WHITESPACE: SPACE+ { $channel = HIDDEN; };
>>
>> fragment NONCONTROL_CHAR: LETTER | DIGIT | SYMBOL | SPACE;
>>
>> fragment SYMBOL: '!' | '#'..'/' | ':'..'@' | '['..'`' | '{'..'~';
>>
>> STRING_LITERAL : '"' NONCONTROL_CHAR* '"';
>> string : STRING_LITERAL;
>> SIGN: '+' | '-';
>>
>> FLOAT: INTEGER '.' DIGIT+;
>> INTEGER: '0' | SIGN? '1'..'9' DIGIT*;
>> int : INTEGER;
>> float : FLOAT;
>>
>> value : (string | int | float | message);
>>
>>
>> And it can parse simple inputs like the following with no problems:
>>
>> {
>> a=1
>> b=2
>> c="dddd"
>> d=3.14159
>> e= { a=1 }
>> f={a=1 b=2 c="1111111111"}
>> g="hello" h="world"
>> }
>>
>>
>> But an input like the following throws it:
>>
>> {
>> foo_bar_1=1
>> }
>>
>> I get NoViableAltException: no viable alternative at input '1'. The issue
>> seems to be variable names (the 'name' rule in my grammar above) that
>> contain a digit - even though I have defined this as part of the generating
>> rule. Can anyone see if there is anything glaringly obvious in my grammar
>> that would prevent the above from working? Im pretty new to Antlr, so any
>> help is much appreciated.
>>
>> Thanks!
>> -- Rory
>>
>>
>>
>
> List: http://www.antlr.org/mailman/listinfo/antlr-interest
> Unsubscribe: http://www.antlr.org/mailman/options/antlr-interest/your-email-address
>


More information about the antlr-interest mailing list