4

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.

1

1 Answer 1

6

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.

Sign up to request clarification or add additional context in comments.

1 Comment

I solved it last summer with the help of Runcc library (with a simplified JS grammar). But your solution looks awesome, I will use it for a future refactoring.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.