Antlr4 perentheses和算术

时间:2014-12-02 14:44:57

标签: antlr4

我正在解析一种类似SQL的语言,我需要优先处理算术。

事情可能是这样的:

(a + b) - c 
(a + b) / 1000
a + (b - c)
a + (SELECT...)
(SELECT... ) + (SELECT ...)
 etc..

我正在使用antlr4侦听器模式,因此我无法找到为这些算术子句构建表示树的方法。

语法部分:

arithmetic_select_clause:
        result_column arithmeticExpression result_column            # ArithmeticSelect
    |   result_column arithmeticExpression arithmetic_select_clause # ArithmeticSelect
    |   arithmetic_select_clause arithmeticExpression result_column # ArithmeticSelect
    |   '(' arithmetic_select_clause ')'                            # ArithmeticSelectParentheses
;


arithmeticExpression :  '+'     # arithmeticsAdd
            |           '-'     # arithmeticsSubtract
            |           '*'     # arithmeticsMultiply
            |           '/'     # arithmeticsDivide
            |           '%'     # arithmeticsModulus
;

我可以使用antlr listenres创建一个树,但我无法处理优先级。

请帮助

1 个答案:

答案 0 :(得分:2)

ANTLR可以帮助您,但您需要遵循一些规则来实现这一目标。 arithmeticExpression规则需要包含两个操作数并直接递归,以便ANTLR可以弄清楚如何重写它。

以下是您可以做的一个示例:

expression : '(' expression ')'
           | expression op=('*'|'/'|'%') expression
           | expression op=('+'|'-')     expression
           | result_column
           | arithmetic_select_clause
           ;

此规则是左递归的,但ANTLR会重写它以消除左递归。 Relevant docs

注意如何排序优先级。每个级别都有其替代品。同一优先级运算符在一个级别上。

此外,对于处理数学表达式,使用访问者比使用者更容易。 ANTLR可以为您生成基类。以这种方式以优先顺序遍历/处理解析树会更容易。