이 예제는 Antlr 3 Python Grammar에 무엇이 잘못 되었습니까?
문제
Antlr을 사용하는 법을 배우려고 하고이 "자습서"를 따르는 동안 오류가 발생한 것 같습니다. https://theantlrguy.atlassian.net/위키 / 디스플레이 / antlr3 / 5 + 분 + 소개 + ~ 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: '@'
.
이것은 내가 어리석은 일을하고 있다고 믿기로 이끌지만, 나는 확실하지 않습니다.
해결책
잘못된 Tool
클래스를 사용하여 렉서와 파서를 생성합니다.대부분의 Antlr 3.x 버전에는 v3.x에 포함 된 이전 v2.7 버전의 의존성이 있습니다.v2.7의 Tool
클래스는 antlr.Tool
라고합니다. v3.x 버전은 org.antlr.Tool
라고합니다.후자는 당신이 사용해야하는 사람입니다 :
java -classpath antlr-3.1.3.jar org.antlr.Tool SimpleCalc.g
.
편집
여기에 Wiki의 문법을 기반으로 한 작은 데모가 있지만 표현식을 평가하는 비트 파이썬 코드가 추가되었습니다.
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
. 제휴하지 않습니다 StackOverflow