Mar*_*n B 1 grammar parsing antlr antlr4
请考虑以下语法。我在运算符优先级方面遇到问题,例如:res = 2 * a + b具有与res = 2 *(a + b)类似的解析树。我知道问题出在哪里,但是我想到没有相互左递归的“美丽”解决方案。你能帮我一下吗。语法与自定义访问者一起使用。
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]+;
Run Code Online (Sandbox Code Playgroud)
来自权威的ANTLR 4参考 5.4,处理优先级,左递归和关联性:
expr : expr '*' expr // match subexpressions joined with '*' operator
| expr '+' expr // match subexpressions joined with '+' operator
| INT // matches simple integer atom
;
Run Code Online (Sandbox Code Playgroud)
问题在于该规则对于某些输入短语是不明确的。...
这是一个运算符优先级的问题,传统语法根本无法指定优先级。大多数语法工具(例如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] ;
Run Code Online (Sandbox Code Playgroud)
档案input.txt:
res = 2 * a + b
res = 2 * ( a + b )
Run Code Online (Sandbox Code Playgroud)
执行方式:
$ 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 )
Run Code Online (Sandbox Code Playgroud)
和
$ grun Question question -gui input.txt
Run Code Online (Sandbox Code Playgroud)