arity.jar算术库如何计算操作String?

时间:2014-06-18 13:33:04

标签: java eval

大家好,我最近遇到了Arity图书馆 - > source can be found here 并发现它使用 .eval()方法将String计算为算术运算,查看源代码我发现了Symbols对象的这个方法:

/**
       Evaluates a simple expression (such as "1+1") and returns its value.
       @throws SyntaxException in these cases:
       <ul>
       <li> the expression is not well-formed
       <li> the expression is a definition (such as "a=1+1")
       <li> the expression is an implicit function (such as "x+1")
       </ul>
     */
    public synchronized double eval(String expression) throws SyntaxException {
        return compiler.compileSimple(this, expression).eval();
    }

此方法调用编译器编译对象的.compileSimple:

Function compileSimple(Symbols symbols, String expression) throws SyntaxException {
    rpn.setConsumer(simpleCodeGen.setSymbols(symbols));
    lexer.scan(expression, rpn);
    return simpleCodeGen.getFun();
}

返回一个Function对象,然后在其上调用eval()方法。看看Function.eval()方法我看到了:

/**
       Evaluates an arity-0 function (a function with no arguments).
       @return the value of the function
    */
    public double eval() {
        throw new ArityException(0);
    }

方法eval必须返回一个double类型,并且实现抛出一个具有此实现的ArityException:

public class ArityException extends RuntimeException {
    public ArityException(String mes) {
        super(mes);
    }

    public ArityException(int nArgs) {
        this("Didn't expect " + nArgs + " arguments");
    }
}

但是当抛出ArityException时,它会调用RuntimeException的super()构造函数,这是一个异常,并且没有双重返回,也许我已经弄乱了一些段落,但是我并不了解最后一段在Function.eval()实现中抛出新的ArityException 0。

那它是如何运作的?

1 个答案:

答案 0 :(得分:1)

您错过了simpleCodeGen的声明:

private final SimpleCodeGen simpleCodeGen = new SimpleCodeGen(exception);

这意味着compileSimple(...)实际上会返回CompiledFunction,其ContextFunction延伸Function

CompiledFunction getFun() {
    return new CompiledFunction(0, code.toArray(), consts.getRe(), consts.getIm(), funcs.toArray());
}

所以实际上它是被调用的eval(...)中的ContextFunction函数。那个有一个真正的实现。

在没有IDE的情况下进行代码分析,只是看代码可能会很棘手。使用调试器和单步执行可以很容易地向您显示程序流程。