Question

I'm trying to learn to use ANTLR, and seem to have come across an error while following this "tutorial": https://theantlrguy.atlassian.net/wiki/display/ANTLR3/Five+minute+introduction+to+ANTLR+3

Essentially, I create the file SimpleCalc.g:

grammar SimpleCalc;
 
options {
    language = Python;
}
 
tokens {
    PLUS    = '+' ;
    MINUS   = '-' ;
    MULT    = '*' ;
    DIV = '/' ;
}
 
@header {
import sys
import traceback
 
from SimpleCalcLexer import SimpleCalcLexer
}
 
@main {
def main(argv, otherArg=None):
  char_stream = ANTLRFileStream(sys.argv[1])
  lexer = SimpleCalcLexer(char_stream)
  tokens = CommonTokenStream(lexer)
  parser = SimpleCalcParser(tokens);
 
  try:
        parser.expr()
  except RecognitionException:
    traceback.print_stack()
}
 
/*------------------------------------------------------------------
 * PARSER RULES
 *------------------------------------------------------------------*/
 
expr    : term ( ( PLUS | MINUS )  term )* ;
 
term    : factor ( ( MULT | DIV ) factor )* ;
 
factor  : NUMBER ;
 
 
/*------------------------------------------------------------------
 * LEXER RULES
 *------------------------------------------------------------------*/
 
NUMBER  : (DIGIT)+ ;
 
WHITESPACE : ( '\t' | ' ' | '\r' | '\n'| '\u000C' )+    { $channel = HIDDEN; } ;
 
fragment DIGIT  : '0'..'9' ;

When I run the ANTLR tools

 java -classpath antlr-3.1.3.jar antlr.Tool SimpleCalc.g

I receive errors, starting with the first line:

ANTLR Parser Generator   Version 2.7.7 (20060906)   1989-2005
SimpleCalc.g:2:1: unexpected token: grammar
error: Token stream error reading grammar(s):
SimpleCalc.g:15:1: unexpected char: '@'
SimpleCalc.g:2:1: rule grammar trapped:
SimpleCalc.g:2:1: unexpected token: grammar
TokenStreamException: unexpected char: '@'

This leads me to believe that I'm doing something stupid, but I'm not sure what.

Was it helpful?

Solution

You're using the wrong Tool class to generate the lexer and parser. Most ANTLR 3.x versions still have dependencies with the older v2.7 version, which is therefor included in v3.x. The Tool class from v2.7 is called antlr.Tool, while the v3.x version is called org.antlr.Tool. The latter is the one you should be using:

java -classpath antlr-3.1.3.jar org.antlr.Tool SimpleCalc.g

EDIT

Here's a little demo based on the grammar from the Wiki, but then with a bit of Python code added to it that evaluates the expression:

grammar SimpleCalc;

options {
  language=Python;
}

@header {
import sys
import traceback

from SimpleCalcLexer import SimpleCalcLexer
}

@main {
def main(argv, otherArg=None):
  char_stream = ANTLRStringStream(sys.argv[1])
  lexer = SimpleCalcLexer(char_stream)
  tokens = CommonTokenStream(lexer)
  parser = SimpleCalcParser(tokens);

  try:
    print parser.eval()
  except RecognitionException:
    traceback.print_stack()
}

eval returns [value]
 : add EOF {$value = $add.value}
 ;

add returns [value]
 : m1=mult {$value = $m1.value} ( '+' m2=mult {$value += $m2.value}
                                | '-' m2=mult {$value -= $m2.value}
                                )* 
 ;

mult returns [value]
 : a1=atom {$value = $a1.value} ( '*' a2=atom {$value *= $a2.value}
                                | '/' a2=atom {$value /= $a2.value}
                                )* 
 ;

atom returns [value]
 : NUMBER      {$value = float($NUMBER.text)}
 | '(' add ')' {$value = $add.value}
 ;

NUMBER         : DIGIT+ ('.' DIGIT*)?;
WHITESPACE     : ('\t' | ' ' | '\r' | '\n')+ {$channel = HIDDEN;};
fragment DIGIT : '0'..'9' ;

Generating a lexer/parser and evaluating an expression:

java -cp antlr-3.1.3.jar org.antlr.Tool SimpleCalc.g
python SimpleCalcParser.py "5 * (8 + 2)"

produces the output:

50.0
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top