[antlr-interest] Rookie problem

Marko Simovic markobarko at gmail.com
Fri Apr 4 13:31:13 PDT 2008


wow...thanks a lot Gavin. Not only did that solve my problem but it also
gave me a lot more understanding of how this whole thing works.

Thanks to everyone else as well. this mailing list is great.
Marko

-----Original Message-----
From: Gavin Lambert <antlr at mirality.co.nz>
To: Marko Simovic <markobarko at gmail.com>, antlr-interest at antlr.org
Subject: Re: [antlr-interest] Rookie problem
Date: Fri, 04 Apr 2008 20:58:11 +1300


At 04:00 4/04/2008, Marko Simovic wrote:
>The grammar at the end of this e-mail works fine for variable 
>names without spaces. If i change the 'name' definition to the 
>following:
>
>name: String (' ' String)*;
>
>then the 'if' statement can no longer be recognized. What am i 
>doing wrong?

If that was a complete grammar, then you're missing a whitespace 
rule.  If a character (such as whitespace) isn't referred to by 
any lexer rule then ANTLR will by default output an error and then 
drop the character and move on, which is why your 'if' rule would 
have been "working" originally.

As soon as you add the space to the 'name' rule, space becomes a 
valid input character and it will start generating space tokens, 
which means that for the input "if foo then bar" you'll now get 
'if',' ','foo',' ','then',' ','bar' instead of 
'if',(error),'foo',(error),'then',(error),'bar'.  And since your 
'selection' rule doesn't match spaces, it won't be able to match 
any more.

The normal solution is to add a WS rule and make it hidden; 
however if you do that then no WS tokens will be visible to the 
parser so your 'name' rule won't be able to match spaces 
anyway.  But you shouldn't need to explicitly specify a space, 
assuming that any amount of whitespace is permitted between the 
words in your multi-word names; the simple fact that multiple 
tokens were generated proves that there was something that broke 
the tokens up.

This is just off the cuff (I haven't tested it), but something 
like this ought to work:

grammar test;

String : ('a'..'z' | 'A'..'Z')+;

ConditionOperator : '<' | '>';

WS : (' ' | '\r' | '\n')+ { $channel = HIDDEN; };

name : String+;

condition : name (ConditionOperator name)*;

selection : 'if' condition 'then' condition;

statement : selection;

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.antlr.org/pipermail/antlr-interest/attachments/20080404/a985f835/attachment.html 


More information about the antlr-interest mailing list