考虑下面的语法。 我有问题,与运营商的优先级,例如:解析度= 2 * A + B也有类似的分析树作为解析度= 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]+;
从权威ANTLR 4参考 ,5.4处理优先级,左递归,和结合性:
expr : expr '*' expr // match subexpressions joined with '*' operator
| expr '+' expr // match subexpressions joined with '+' operator
| INT // matches simple integer atom
;
问题是,这条规则是不明确的一些输入短语。 ...
这是运算符优先级的问题,传统的语法根本没有办法来指定优先级。 大多数语法工具,如野牛,使用额外的符号来指定运算符优先级。
相反,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