ANTLR的解析器运营商优先(Antlr Parser operator priority)

2019-09-26 06:20发布

考虑下面的语法。 我有问题,与运营商的优先级,例如:解析度= 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]+;

Answer 1:

从权威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



文章来源: Antlr Parser operator priority