Domanda

Sto cercando di imparare a usare ANLLR e sembra che abbia incontrato un errore durante questo "tutorial": https://theantlrguy.atlassian.net/wiki / display / antlr3 / cinque + minuto + Introduzione + a + antlr + 3

In sostanza, creo il 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' ;
.

Quando eseguo gli strumenti antlr

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

Ricevo errori, a partire dalla prima riga:

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

Questo mi porta a credere che sto facendo qualcosa di stupido, ma non sono sicuro di cosa.

È stato utile?

Soluzione

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
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top