Pregunta

Estoy tratando de aprender a usar Antlr, y parece que se ha encontrado con un error al seguir este "tutorial": https://theantlrguy.atlassian.net/WIKI / PANTALLA / ANTLR3 / CINCO + MINUTOS + INTRODUCCIÓN + A + ANTLR + 3

esencialmente, creo el archivo 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' ;

cuando ejecuto las herramientas de antlr

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

Recibo errores, comenzando con la primera línea:

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: '@'

Esto me lleva a creer que estoy haciendo algo estúpido, pero no estoy seguro de qué.

¿Fue útil?

Solución

Está usando la clase incorrecta Tool para generar el lexer y el analizador.La mayoría de las versiones ANTLR 3.x aún tienen dependencias con la versión V2.7 anterior, que se incluye en V3.x.La clase Tool de V2.7 se llama antlr.Tool, mientras que la versión v3.x se llama org.antlr.Tool.Este último es el que debe estar usando:

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

Editar

Aquí hay una pequeña demostración basada en la gramática de la wiki, pero luego con un poco de código de Python que evalúa la expresión:

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' ;

Generando un lexer / analizador y evaluando una expresión:

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

Produce la salida:

50.0

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top