【问题标题】:How does the arity.jar arithmetic library evaluates an operation String?arity.jar 算术库如何评估操作字符串?
【发布时间】:2014-06-18 13:33:03
【问题描述】:

大家好,我最近遇到了 Arity 库 -> source can be found here 并发现它使用 .eval() 方法将字符串评估为算术运算,查看源代码我发现了 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();
    }

该方法调用Compiler编译对象的.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() 构造函数,这是一个异常并且没有返回应有的 double,也许我有一些段落,但我不明白最后一个 throw new Function.eval() 实现中的 0 的 ArityException。

那么它到底是如何工作的呢?

【问题讨论】:

    标签: java eval


    【解决方案1】:

    你错过了simpleCodeGen的声明:

    private final SimpleCodeGen simpleCodeGen = new SimpleCodeGen(exception);
    

    这意味着compileSimple(...) 实际上返回一个CompiledFunction,它扩展了ContextFunctionFunction

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

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

    在没有 IDE 的情况下进行代码分析并仅观察代码可能会很棘手。使用调试器并单步执行会很容易地向您展示程序流程。

    【讨论】:

    • 感谢您的解释!
    猜你喜欢
    • 2019-10-04
    • 2020-03-17
    • 1970-01-01
    • 2018-05-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-16
    • 1970-01-01
    相关资源
    最近更新 更多