问题
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:
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.
来源:https://stackoverflow.com/questions/12108447/get-variables-from-javascript-expression-rhino