Frage

Ich versuche den Umgang mit ANTLR zu erlernen und bin beim Befolgen dieses „Tutorials“ offenbar auf einen Fehler gestoßen:https://theantlrguy.atlassian.net/wiki/display/ANTLR3/Five+minute+introduction+to+ANTLR+3

Im Wesentlichen erstelle ich die Datei 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' ;

Wenn ich die ANTLR-Tools ausführe

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

Ich erhalte Fehlermeldungen, beginnend mit der ersten Zeile:

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

Das lässt mich glauben, dass ich etwas Dummes tue, aber ich bin mir nicht sicher, was.

War es hilfreich?

Lösung

Du verwendest das Falsche Tool Klasse zum Generieren des Lexers und Parsers.Die meisten ANTLR 3.x-Versionen weisen noch Abhängigkeiten zur älteren Version v2.7 auf, die daher in v3.x enthalten ist.Der Tool Klasse aus v2.7 wird aufgerufen antlr.Tool, während die v3.x-Version aufgerufen wird org.antlr.Tool.Letzteres sollten Sie verwenden:

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

BEARBEITEN

Hier ist eine kleine Demo, die auf der Grammatik aus dem Wiki basiert, aber dann mit etwas Python-Code ergänzt wurde, der den Ausdruck auswertet:

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

Einen Lexer/Parser generieren und einen Ausdruck auswerten:

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

erzeugt die Ausgabe:

50.0
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top