简体   繁体   中英

Get variables from javascript expression (Rhino)

I'm using Rhino to evaluate js expressions, by putting all the possible variable values in the scope and evaluating an anonymous function. However the expressions are fairly simple and I would like to put only the values used in the expression, for performance.

Code sample:

    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);

I want to get all the tokens from the expressions that are variable names.

For instance, if the expression is

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

it will return V1ND .

Rhino 1.7 R3 introduced an AST package which can be used to find names:

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);
  }
}

Output:

[V1ND, abs, Math]

However, I'm not sure this will help much with efficiency unless the expressions are amenable to caching. You would be parsing the code twice and if you need to disambiguate a variable abs from the function on Math further inspection will be required.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM