我正在尝试学习使用ANTLR,并且在遵循此“教程”时似乎遇到了错误: https://theantlrguy.atlassian.net/wiki/display/ANTLR3/Five+minute+introduction+to+ANTLR+3
基本上,我创建了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' ;
当我运行ANTLR工具时
java -classpath antlr-3.1.3.jar antlr.Tool SimpleCalc.g
我收到错误,从第一行开始:
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: '@'
这让我相信我做的事情很愚蠢,但我不确定是什么。
答案 0 :(得分:3)
您正在使用错误的Tool
类来生成词法分析器和解析器。大多数ANTLR 3.x版本仍然与旧的v2.7版本具有相关性,因此包含在v3.x中。 v2.7中的Tool
类称为antlr.Tool
,而v3.x版本称为org.antlr.Tool
。后者是你应该使用的那个:
java -classpath antlr-3.1.3.jar org.antlr.Tool SimpleCalc.g
这是一个基于Wiki语法的小演示,但随后添加了一些Python代码来评估表达式:
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' ;
生成词法分析器/解析器并评估表达式:
java -cp antlr-3.1.3.jar org.antlr.Tool SimpleCalc.g
python SimpleCalcParser.py "5 * (8 + 2)"
产生输出:
50.0