ANTLR4语法中不同类型的乘法

时间:2014-07-03 09:33:20

标签: math expression antlr4

在输入使用ANTLR4解析的数学表达式时,应允许两种类型的乘法5 * x5x。下面的语法已经接受了这两种情况,但是有一种新的否定规则会产生错误的输出。示例:现在解析表达式x^2 - 5x,就好像它是(x^2) * (-5x)

我应该如何更改语法以便正确解析输入?

编辑:我已更新下面的语法,以便它反映当前状态,我还在此处插入了日志消息以显示我的问题。主要问题是在enterNatural (5)电话会议之前没有enterVariable (x)exitSimpleMultiplication (5x)来电。

EDIT2 :我一直在玩语法很多,并且发现如果我在simplifiedMultiplication中使用规则(而不是令牌)会变得更好。更新了下面发布的语法。

现在,解析5x正在解析但解析2x^2仍未解析(导致(2x)^2,s。日志消息如下)。

我也发布了听众类。

// Parser Rules

expression
    : primary                                            # aPrimary
    | composite                                          # aComposite
    | expression '^' expression                          # exponentiation
    | '-' expression                                     # negation
    | expression '/' expression                          # division
    | expression '*' expression                          # multiplication
    | simpleMultiplication                               # aSimpleMultiplication
    | expression operator=('+' | '-') expression         # additive
    | expression '=' expression                          # equation
    ;

primary
    : NATURAL                                            # natural
    | VARIABLE                                           # variable
    ;

composite
    : '(' expression ')'                                 # parentheses
    | '|' expression '|'                                 # abs
    | function                                           # aFunction
    ;

simpleMultiplication
    : primary primary
    | primary composite
    | composite primary
    | composite composite
    ;

function
    : FUNC '(' expression ')'
    ;

// Lexer Rules

FUNC : 'sqrt' | 'exp' | 'ln' | 'log' | 'abs' ;

ADD  : '+' ;
SUB  : '-' ;

NATURAL : [0-9]+ ;

VARIABLE : 'x' ;

WS  : [ \t\r\n]+ -> skip ;

听众课程:

public class AntlrExpressionListener extends ExpressionsBaseListener {

    private final Deque<Expression> stack = new LinkedList();

    private final Map<String, Expression> identifiers = new HashMap();

    private Variable x;

    /**
     * Returns the parsed expression.
     * 
     * @return 
     */
    Expression getExpression() {
        return stack.pop();
    }

    void add(Reference ref) {
        identifiers.put(ref.name(), ref);
    }

    @Override
    public void exitAdditive(ExpressionsParser.AdditiveContext ctx) {
        Expression rhs = stack.pop();
        Expression lhs = stack.pop();

        if (ctx.operator.getType() == ExpressionsParser.ADD) {
            stack.push(Sum.add(lhs, rhs));
        } else if (ctx.operator.getType() == ExpressionsParser.SUB) {
            stack.push(Sum.subtract(lhs, rhs));
        } else {
            throw new IllegalStateException("Unexpected operation: " + ctx.operator);
        }
    }

    @Override
    public void exitMultiplication(ExpressionsParser.MultiplicationContext ctx) {
        Expression rhs = stack.pop();
        Expression lhs = stack.pop();

        stack.push(new Multiplication(lhs, rhs));
    }

    @Override
    public void exitSimpleMultiplication(ExpressionsParser.SimpleMultiplicationContext ctx) {
        Expression rhs = stack.pop();
        Expression lhs = stack.pop();

        stack.push(new Multiplication(lhs, rhs));
    }

    @Override
    public void exitDivision(ExpressionsParser.DivisionContext ctx) {
        Expression rhs = stack.pop();
        Expression lhs = stack.pop();

        if (lhs instanceof IntegerNumber && rhs instanceof NaturalNumber) {
            stack.push(new Division(lhs, rhs).evaluate());
        } else {
            stack.push(new Division(lhs, rhs));
        }
    }

    @Override
    public void exitExponentiation(ExpressionsParser.ExponentiationContext ctx) {
        Expression rhs = stack.pop();
        Expression lhs = stack.pop();

        stack.push(new Exponentiation(lhs, rhs));
    }

    @Override
    public void exitNegation(ExpressionsParser.NegationContext ctx) {
        Expression arg = stack.pop();

        if (arg instanceof ANumber) {
            stack.push(((ANumber) arg).negate());
        } else {
            stack.push(new Negation(arg));
        }
    }

    @Override
    public void exitEquation(ExpressionsParser.EquationContext ctx) {
        Expression rhs = stack.pop();
        Expression lhs = stack.pop();
        Equality equation = new Equality(lhs, rhs);

        stack.push(Equation.convert(equation, x));
    }

    @Override
    public void exitFunction(ExpressionsParser.FunctionContext ctx) {
        String function = ctx.FUNC().getText();
        Expression arg = stack.pop();

        switch (function) {
            case "exp":
                stack.push(new Exp(arg));
                break;

            case "ln":
                stack.push(new Ln(arg));
                break;

            case "sqrt":
                stack.push(new Sqrt(arg));
                break;

            case "abs":
                stack.push(new Abs(arg));
                break;

            default:
                throw new IllegalStateException("Unexpected function name: " + function);
        }
    }

    @Override
    public void enterNatural(ExpressionsParser.NaturalContext ctx) {
        stack.push(Naturals.getInstance().create(ctx.getText()));
    }

    @Override
    public void enterVariable(ExpressionsParser.VariableContext ctx) {
        x = (Variable) identifiers.get(ctx.getText());

        if (x == null) {
            x = Numbers.variable(ctx.getText());
            identifiers.put(ctx.getText(), x);
        }

        stack.push(x);
    }

    @Override
    public void exitAbs(ExpressionsParser.AbsContext ctx) {
        Expression arg = stack.pop();

        stack.push(new Abs(arg));
    }

    @Override
    public void enterEveryRule(ParserRuleContext ctx) {
        System.out.printf("in:  %s : %s%n", ctx.getText(), ctx.toStringTree());
    }

    @Override
    public void exitEveryRule(ParserRuleContext ctx) {
        System.out.printf("out: %s : %s%n", ctx.getText(), ctx.toStringTree());
    }
}

记录消息:

in:  2x^2-x-1=0 : ([] ([0] ([0 0] ([0 0 0] ([0 0 0 0] ([15 0 0 0 0] ([53 15 0 0 0 0] 2) ([54 15 0 0 0 0] x))) ^ ([20 0 0 0] ([13 20 0 0 0] 2))) - ([29 0 0] ([13 29 0 0] x))) - ([29 0] ([13 29 0] 1))) = ([32] ([13 32] 0)))
in:  2x^2-x-1 : ([0] ([0 0] ([0 0 0] ([0 0 0 0] ([15 0 0 0 0] ([53 15 0 0 0 0] 2) ([54 15 0 0 0 0] x))) ^ ([20 0 0 0] ([13 20 0 0 0] 2))) - ([29 0 0] ([13 29 0 0] x))) - ([29 0] ([13 29 0] 1)))
in:  2x^2-x : ([0 0] ([0 0 0] ([0 0 0 0] ([15 0 0 0 0] ([53 15 0 0 0 0] 2) ([54 15 0 0 0 0] x))) ^ ([20 0 0 0] ([13 20 0 0 0] 2))) - ([29 0 0] ([13 29 0 0] x)))
in:  2x^2 : ([0 0 0] ([0 0 0 0] ([15 0 0 0 0] ([53 15 0 0 0 0] 2) ([54 15 0 0 0 0] x))) ^ ([20 0 0 0] ([13 20 0 0 0] 2)))
in:  2x : ([0 0 0 0] ([15 0 0 0 0] ([53 15 0 0 0 0] 2) ([54 15 0 0 0 0] x)))
in:  2x : ([15 0 0 0 0] ([53 15 0 0 0 0] 2) ([54 15 0 0 0 0] x))
in:  2 : ([53 15 0 0 0 0] 2)
out: 2 : ([53 15 0 0 0 0] 2)
in:  x : ([54 15 0 0 0 0] x)
out: x : ([54 15 0 0 0 0] x)
out: 2x : ([15 0 0 0 0] ([53 15 0 0 0 0] 2) ([54 15 0 0 0 0] x))
out: 2x : ([0 0 0 0] ([15 0 0 0 0] ([53 15 0 0 0 0] 2) ([54 15 0 0 0 0] x)))
in:  2 : ([20 0 0 0] ([13 20 0 0 0] 2))
in:  2 : ([13 20 0 0 0] 2)
out: 2 : ([13 20 0 0 0] 2)
out: 2 : ([20 0 0 0] ([13 20 0 0 0] 2))
out: 2x^2 : ([0 0 0] ([0 0 0 0] ([15 0 0 0 0] ([53 15 0 0 0 0] 2) ([54 15 0 0 0 0] x))) ^ ([20 0 0 0] ([13 20 0 0 0] 2)))
in:  x : ([29 0 0] ([13 29 0 0] x))
in:  x : ([13 29 0 0] x)
out: x : ([13 29 0 0] x)
out: x : ([29 0 0] ([13 29 0 0] x))
out: 2x^2-x : ([0 0] ([0 0 0] ([0 0 0 0] ([15 0 0 0 0] ([53 15 0 0 0 0] 2) ([54 15 0 0 0 0] x))) ^ ([20 0 0 0] ([13 20 0 0 0] 2))) - ([29 0 0] ([13 29 0 0] x)))
in:  1 : ([29 0] ([13 29 0] 1))
in:  1 : ([13 29 0] 1)
out: 1 : ([13 29 0] 1)
out: 1 : ([29 0] ([13 29 0] 1))
out: 2x^2-x-1 : ([0] ([0 0] ([0 0 0] ([0 0 0 0] ([15 0 0 0 0] ([53 15 0 0 0 0] 2) ([54 15 0 0 0 0] x))) ^ ([20 0 0 0] ([13 20 0 0 0] 2))) - ([29 0 0] ([13 29 0 0] x))) - ([29 0] ([13 29 0] 1)))
in:  0 : ([32] ([13 32] 0))
in:  0 : ([13 32] 0)
out: 0 : ([13 32] 0)
out: 0 : ([32] ([13 32] 0))
out: 2x^2-x-1=0 : ([] ([0] ([0 0] ([0 0 0] ([0 0 0 0] ([15 0 0 0 0] ([53 15 0 0 0 0] 2) ([54 15 0 0 0 0] x))) ^ ([20 0 0 0] ([13 20 0 0 0] 2))) - ([29 0 0] ([13 29 0 0] x))) - ([29 0] ([13 29 0] 1))) = ([32] ([13 32] 0)))
(2x)^2 - x - 1 = 0

0 个答案:

没有答案