[antlr-interest] Resolving ambiguity

Stefan jan_ek at op.pl
Fri May 4 16:28:27 PDT 2007


Gavin Lambert napisał(a):
> At 07:07 5/05/2007, Stefan wrote:
>  >OK, but how do I do it without changing the grammar? How do I make
>  >ANTLR choose the 4th alternative instead of the 2nd, when IDENTIFIER
>  >is a variable?
> 
> You need to use a semantic predicate.  Something along these lines:
> 
> statement
>     :
>     (   function_definition
>     |   {isFunction(LT(1))}? function_call
>     |   variable_definition
>     |   expression
>     ) ';';
> 
> (The exact syntax used to call LT may be different depending on your 
> target language.  But it'll be something along those lines.  There's 
> probably more info on the wiki.)

Thanks! I'm so excited about ANTLR and I finally got it to work! It took 
me quite some time to figure out why my main() java file doesn't see 
lexer and parser classes even though they were in the same directory - 
I've set the CLASSPATH, but forgot to add "." to it.

I believe it should be just like you've written, but I had to write 
input.LT(1), because it wouldn't compile otherwise. Is it a bug? Which 
one is right?

I'm posting the code, maybe somebody will find it useful:

grammar My;

@header
{
     import java.util.HashSet;
}

@members
{
     HashSet<String> functions = new HashSet<String>();
     HashSet<String> variables = new HashSet<String>();
     boolean isFunctionName(Token token)
     {
         return functions.contains(token.getText());
     }
}

WHITESPACE
     :   (' ' | '\t' | '\n' | '\r' | '\f' | '\v')
     {
         $channel = HIDDEN;
     };

fragment
DIGIT   :   '0'..'9';

fragment
NONDIGIT:   'a'..'z' | 'A'..'Z' | '_';

IDENTIFIER
     :   NONDIGIT (DIGIT | NONDIGIT)*;

function_definition
     :   'function' IDENTIFIER
     {
         functions.add($IDENTIFIER.text);
     };

function_call
     :   IDENTIFIER
     {
         System.out.println("Function call: " + $IDENTIFIER.text);
     };

variable_definition
     :   'var' IDENTIFIER
     {
         variables.add($IDENTIFIER.text);
     };

expression
     :   IDENTIFIER
     {
         System.out.println("Expression: " + $IDENTIFIER.text);
     };

statement
     :
     (
         function_definition
         | { isFunctionName(input.LT(1)) }? function_call
         | variable_definition
         | expression
     ) ';';

program :   statement+;
parse   :   program;



Stefan Chrobot


More information about the antlr-interest mailing list