Details
-
Type:
New Feature
-
Status:
Resolved
-
Priority:
Minor
-
Resolution: Fixed
-
Affects Version/s: None
-
Fix Version/s: 2.5.12
-
Component/s: None
-
Labels:None
-
Environment:Running on Windows and Mac OS X under Java JDK 1.5+
-
Number of attachments :
Description
I originally posted this feature request on <user@janino.codehaus.org> and was asked to also submit it here (jira.codehaus.org). I've pasted the contents of the email response to my request (from Arno Unkrig). It also contains the original feature request:
---- email contents begin ----
Hi Gary,
thank you for your precise feature request!
Yes, what you want is possible, but the API is not as slick as the one
that you propose. I WILL integrate the feature into the JANINO API, but
before I do that, I want to introduce the ad-hoc solution to you, to
make sure that it does exactly what you need.
Please let me know your thoughts about it...
Also, if you want to make life easier for me, register on
jira.codehaus.org and submit this feature request there!
CU
Arno
Gary Nunes schrieb:
> Perhaps this is possible and I just don't know how to do it. In that case
> this request is for an example of how to do it (instead of a request to
> provide the means to do it).
>
>
> Given an expression to be evaluated, e.g.,
> a + b + c
>
> where, in general, it is not known in advance what parameter names appear in
> the expression (perhaps the expression is provided interactively by a user)
> I would like to be able to query Janino regarding information about the
> parameters used in the expression. Something like
> String[] parameters = ExpressionEvaluator.getParameters("a + b + c");
>
> which, in the case of the above expression would return (as a String array):
> "a", "b", "c"
>
> The information would be used to display the set of parameters in a form
> that the user could manipulate to provide parameter values (e.g., as a
> JTable of parameter name + value columns).
>
> After providing the values the user might press a button that then caused
> the execution of an ExpressionEvaluator construct followed by an evaluate,
> e.g.,
> ExpressionEvaluator ee = new ExpressionEvaluator(
> "a + b + c",
> int.class,
> parameters,
> new Class[] { int.class, int.class, int.class }
> );
>
> Integer res = (Integer) ee.evaluate(getParameterValuesFromTable());
>
>
> I hope I've managed to convey what I'm looking for.
>
> Any advice?
>
>
> Regards,
> Gary Nunes
>
>
> ---------------------------------------------------------------------
> To unsubscribe from this list please visit:
>
> http://xircles.codehaus.org/manage_email
>
>
>
import java.io.*;
import org.codehaus.janino.*;
import org.codehaus.janino.Java.*;
import org.codehaus.janino.util.Traverser;
public class Checker {
/**
- An example how you can "check" your JANINO expression before you execute it: This program
- reports on all "ambiguous names" in a JAVA expression, and throws a RuntimeException
- when it detects a mthod invocation.
* - E.g., in the expression "a.b + c", "a" and "c" are "ambiguous names" which you should
- map with parameters.
*/
public static void main(String[] args) throws Exception {
Parser parser = new Parser(new Scanner(null, new StringReader(args[0])));
Java.ReturnStatement returnStatement = new Java.ReturnStatement(null, parser.parseExpression().toRvalueOrPE());
new Traverser() {
public void traverseAmbiguousName(AmbiguousName an) { System.out.println("Need a parameter \"" + an.identifiers[0] + "\""); super.traverseAmbiguousName(an); }
public void traverseMethodInvocation(MethodInvocation mi) { throw new RuntimeException("Method invocation forbidden"); }
}.traverseReturnStatement(returnStatement);
}
}
---- email contents end ----
I hope this satisfies your request.
I will also try your ad-hoc solution and let you know if it how it works.
Regards,
Gary
Gary Nunes, 2007-07-18:
Arno,
I've tried the Checker class that you provided above and it mostly meets my
needs. There are two problems, one of which I think I can deal with and one,
perhaps not.
First, note that although I used "a + b + c" as my example expression in my
feature request the expressions will, in fact, tend to be more complicated.
For example:
"b0 * P^b1 * (S * (1 - R))^b3 * (S * (1 - R))"
for which Checker returns the output:
Need a parameter "b0"
Need a parameter "P"
Need a parameter "b1"
Need a parameter "S"
Need a parameter "R"
Need a parameter "b3"
Need a parameter "S"
Need a parameter "R"
This illustrates the first problem. Checker returns the same identifier more
than once (e.g., "S" and "R"). This problem I can deal with by removing
duplicates as I collect the identifiers.
The second problem is illustrated by noting that Java has no intrinsic power
operator ("^" in the formula above) so the formula must actually be
expressed as:
"b0 * pow(P, b1) * pow(S * (1 -R), b3) * (S * (1 - R))"
for which Checker returns (since method invocation is forbidden):
Need a parameter "b0"
RuntimeException: Method invocation forbidden ...
when I would actually like it to return the same identifiers (minus perhaps
the duplicates) as the first test above.
More generally, expressions input by users may contain method invocations of
all kinds (built-in and user defined). I'm not sure I know enough about how
Janino works to resolve this second problem.
Regards,
Gary