2017-10-31 10 views
1

다음 문법을 고려하십시오. 예를 들어 연산자 우선 순위와 관련된 문제가 있습니다. res = 2 * a + b는 res = 2 * (a + b)와 비슷한 구문 분석 트리를가집니다. 나는 문제가 어디 있는지 알고 있지만, 상호 왼쪽 재귀가없는 "아름다운"해결책은 내 마음에 온다. 좀 도와 주실 래요? 문법은 맞춤 방문자와 함께 사용됩니다. 우선, 왼쪽 재귀 및 연관성을 다루는 The Definitive ANTLR 4 Reference에서Antlr 파서 연산자 우선 순위

grammar Math; 

expression: expression add=('+'|'-') expression # expressionAddExpression 
      | expression mult='*' expression # expressionMultExpression 
      |'(' expression ')' # bracketExpression 
      | number       # numberExpression 
      ; 
    number: INT                 #int 
      | '(' number ')'             #bracketNumber 
      | VARIABLE               #var 

      ; 
    VARIABLE: [A-Za-z][A-Za-z0-9]*; 



INT: [0-9]+; 

답변

4

, 5.4 :

expr : expr '*' expr // match subexpressions joined with '*' operator 
    | expr '+' expr // match subexpressions joined with '+' operator 
    | INT // matches simple integer atom 
    ; 

문제는이 규칙이 일부 입력 문구 모호한 것입니다. ...

이것은 운영자 우선 순위에 대한 질문이며 일반적인 문법 은 단순히 우선 순위를 지정할 방법이 없습니다. Bison과 같은 대부분의 문법 도구는 연산자 우선 순위를 지정하는 데 추가 표기법을 사용합니다.

대신 ANTLR은 대안을 선호하여 애매한 점을 해결하여 암시 적으로 연산자 우선 순위를 지정할 수 있습니다.

단순히 덧셈하기 전에 곱하기를 넣으십시오.

파일 Question.g4 :

grammar Question; 

question 
@init {System.out.println("Question last update 1213");} 
    : line+ EOF 
    ; 

line 
    : expression NL 
     {System.out.println("Expression found : " + $expression.text); } 
    ; 

expression 
    : expression mult='*' expression   # expressionMultExpression 
    | expression add=('+' | '-') expression # expressionAddExpression 
    | VARIABLE '=' expression     # expressionAssign 
    | '(' expression ')'      # parenthesisedExpression 
    | atom         # atomExpression 
    ; 

atom 
    : INT          #int 
    | VARIABLE        #var 
    ; 

VARIABLE : LETTER (LETTER | DIGIT)*; 
INT  : DIGIT+; 

NL  : [\r\n] ; 
WS  : [ \t] -> channel(HIDDEN) ; // -> skip ; 

fragment LETTER : [a-zA-Z] ; 
fragment DIGIT : [0-9] ; 

파일 input.txt :

res = 2 * a + b 
res = 2 * (a + b) 

실행 :

$ grun Question question -tokens -diagnostics input.txt 
[@0,0:2='res',<VARIABLE>,1:0] 
[@1,3:3=' ',<WS>,channel=1,1:3] 
[@2,4:4='=',<'='>,1:4] 
[@3,5:5=' ',<WS>,channel=1,1:5] 
[@4,6:6='2',<INT>,1:6] 
[@5,7:7=' ',<WS>,channel=1,1:7] 
[@6,8:8='*',<'*'>,1:8] 
[@7,9:9=' ',<WS>,channel=1,1:9] 
[@8,10:10='a',<VARIABLE>,1:10] 
... 
[@32,36:35='<EOF>',<EOF>,3:0] 
Question last update 1213 
Expression found : res = 2 * a + b 
Expression found : res = 2 * (a + b) 

$ grun Question question -gui input.txt 

enter image description here

+0

대단히 감사합니다. 나는 antlr 참조의이 섹션에 익숙했지만 예상대로 작동하지 않았습니다. 빌드 스크립트가 깨 졌으므로 규칙의 순서를 변경해도 아무런 차이가 없었습니다. 이제는 완벽하게 작동합니다. –