【问题标题】:Get variables from javascript expression (Rhino)从 javascript 表达式中获取变量 (Rhino)
【发布时间】:2012-08-19 23:04:48
【问题描述】:

我正在使用 Rhino 来评估 js 表达式,方法是将所有可能的变量值放在作用域中并评估一个匿名函数。然而,表达式相当简单,为了性能,我只想输入表达式中使用的值。

代码示例:

    Context cx = Context.enter();

    Scriptable scope = cx.initStandardObjects(null);

    // Build javascript anonymous function
    String script = "(function () {" ;

    for (String key : values.keySet()) {
        ScriptableObject.putProperty(scope, key, values.get(key));
    }
    script += "return " + expression + ";})();";

    Object result = cx.evaluateString(scope, script, "<cmd>", 1, null);

我想从作为变量名的表达式中获取所有标记。

例如,如果表达式是

(V1ND < 0 ? Math.abs(V1ND) : 0)

它将返回V1ND

【问题讨论】:

标签: java javascript rhino


【解决方案1】:

Rhino 1.7 R3 引入了一个AST package,可用于查找姓名:

import java.util.*;
import org.mozilla.javascript.Parser;
import org.mozilla.javascript.ast.*;

public class VarFinder {
  public static void main(String[] args) throws IOException {
    final Set<String> names = new HashSet<String>();
    class Visitor implements NodeVisitor {
      @Override public boolean visit(AstNode node) {
        if (node instanceof Name) {
          names.add(node.getString());
        }
        return true;
      }
    }
    String script = "(V1ND < 0 ? Math.abs(V1ND) : 0)";
    AstNode node = new Parser().parse(script, "<cmd>", 1);
    node.visit(new Visitor());
    System.out.println(names);
  }
}

输出:

[V1ND, abs, Math]

但是,除非表达式适合缓存,否则我不确定这对效率有多大帮助。您将解析代码两次,如果您需要从 Math 上的函数中消除变量 abs 的歧义,则需要进一步检查。

【讨论】:

  • 我去年夏天在 Runcc 库的帮助下解决了这个问题(使用简化的 JS 语法)。但是您的解决方案看起来很棒,我将在未来的重构中使用它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-05-22
  • 1970-01-01
  • 2011-07-25
  • 1970-01-01
  • 2012-07-07
  • 2016-02-01
  • 1970-01-01
相关资源
最近更新 更多