1

I've got a bit of an interesting challenge

To the point:

I want to allow a user to enter an expression in a text field, and have that string treated as a python expression. There are a number of local variables I would like to make available to this expression.

I do have a solution though it will be cumbersome to implement. I was thinking of keeping a Python class source file, with a function that has a single %s in it. When the user enters his expression, we simply do a string format, and then call Jython's interpreter, to spit out something we can execute. There would have to be a number of variable declaration statements in front of that expression to make sure the variables we want to expose to the user for his expression.

So the user would be presented with a text field, he would enter

x1 + (3.5*x2) ** x3

and we would do our interpreting process to come up with an open delegate object. We then punch the values into this object from a map, and call execute, to get the result of the expression.

Any objections to using Jython, or should I be doing something other than modifying source code? I would like to think that some kind of mutable object akin to C#'s Expression object, where we could do something like

PythonExpression expr = new PythonExpression(userSuppliedText)
expr.setDefaultNamespace();
expr.loadLibraries("numPy", /*other libraries?*/);

//comes from somewhere else in the flow, but effectively we get
Map<String, Double> symbolValuesByName = new HashMap<>(){{
    put("x1", 3.0);
    put("x2", 20.0);
    put("x3", 2.0);
}};

expr.loadSymbols(symbolValuesByName);

Runnable exprDelegate = expr.compile();

//sometime later
exprDelegate.run();

but, I'm hoping for a lot, and it looks like Jython is as good as it gets. Still, modifying source files and then passing them to an interpreter seems really heavy-handed.

Does that sound like a good approach? Do you guys have any other libraries you'd suggest?


Update: NumPy does not work with Jython

I should've discovered this one on my own.

So now my question shifts: Is there any way that from a single JVM process instance (meaning, without ever having to fork) I can compile and run some Python code?

7
  • 1
    Do you need to support actual Python expressions like next(x**2 for x in {2, 3}), or Python-like expressions? Commented Feb 16, 2014 at 5:59
  • 1
    Why a Python expression? What specific things do you need to support in the expression? Commented Feb 16, 2014 at 6:08
  • Powers that be demand python. I suggested matlab or mathmatica, but we want python. Blender: No. If I had access to the parse-tree (or AST) I'd like to do an "assert return type is double" on the expression, but I'm OK with completely ignoring error checking for now. Commented Feb 16, 2014 at 6:12
  • what specifically from python? I think I'm after all productions possible from 'expr' in the python grammar: docs.python.org/2/reference/grammar.html Commented Feb 16, 2014 at 6:17
  • 1
    Are you going to need NumPy? If the alternatives you suggested were Matlab and Mathematica, it sounds like there's a good chance you'll need NumPy, and I don't think that's interoperable with Jython. Commented Feb 16, 2014 at 6:21

1 Answer 1

1

If you simply want to parse the expressions, you ought to be able to put something together with a Java parser generator.

If you want to parse, error check and evaluate the expressions, then you will need a substantial subset of the functionality a full Python interpreter.

  1. I'm not aware of a subset implementation.

  2. If such a subset implementation exists, it is unclear that it would be any easier to embed / call than to use a full Python interpreter ... like Jython.

If the powers that be dictate that "thou shalt use python", then they need to pay for the extra work it is going to cause you ... and the next guy who is going to need to maintain a hybrid system across changes in requirements, and updates to the Java and Python / Jython ecosystems. Factor it into the project estimates.


The other approach would be to parse the full python expression grammar, but limit what your evalutor can handle ... based on what it actually required, and what is implementable in your project's time-frame. Limit the types supported and the operations on the types. Limit the built-in functions supported. Etcetera.


Assuming that you go down the Java calling Jython route, there is a lot of material on how to implement it here: http://www.jython.org/jythonbook/en/1.0/JythonAndJavaIntegration.html

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

Comments

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.