1 2 Previous Next 18 Replies Latest reply: Apr 1, 2009 7:26 PM by 807588 RSS

    Type of java expression passed as string

    807588
      Hello,

      I am in need in some hints on how/if I can evaluate the overall type of a Java expression, but the expression is given as a string. for example
      return 1 + 3.5D; // returns double
      return (random.nextInt(100) > 50 ? true : false); // returns true
      I would need something which will give me the type for the strings representing those expressions
      Class<?> getClass(String expression) {
      ...
      }
      getClass("1 + 3.5D");
      getClass("(random.nextInt(100) > 50 ? true : false)");
      Mabe there is some reflection method available that I don't know about, or mabe some jdk library method (In my app I generate and compile code and thereby have the tools.jar file added to my project).

      Than you in advance.

      Cosmin
        • 1. Re: Type of java expression passed as string
          thomas.behr
          Maybe you want to look into Eclipse's AST. It supports resolving types, however it has to parse the source first.
          • 2. Re: Type of java expression passed as string
            807588
            Do you want to use a string as the class name to call it or something?
            • 3. Re: Type of java expression passed as string
              800282
              You can't do that like you want it. You will first need to evaluate/parse the expression in order to figure out it's return type.
              An easy way to do that would be to use the script-API from Java 1.6:
              import javax.script.*;
              
              public class Main {    
                  public static void main(String[] args) throws Exception {
                      ScriptEngine engine = new ScriptEngineManager().getEngineByName("js");
                      System.out.println(engine.eval("1 + 3.5").getClass().getName()); // can't use a 'D' after a double
                      System.out.println(engine.eval("(Math.random()*100 > 50 ? true : false)").getClass().getName()); // can't use the Random class
                  }
              }
              (Note the comments)

              You might also use a simple StringindexOf(...) to see if there's >=, < , ==, true, false, ... in your expressions, in which case it must be a Boolean return type (but it may be an invalid expression).
              • 4. Re: Type of java expression passed as string
                807588
                A String is a String. If a String happens to look like something which, if compiled, would be a different type, it's still a String.

                Basically, you have to parse it.

                You might also want to look at attaching a scripting language like Groovy or Beanshell.
                • 5. Re: Type of java expression passed as string
                  807588
                  Thank you for your replies.

                  I generate code (a class which implements an "Object evaluate()" method) based on the expression string. The string is any valid Java expression so scripting is somehow not powerfull enough. The string expression is to be taken as it is received.
                  This post relates to this one. I need to do some casts in the generated code. This is why I need to evaluate the type of the result of a string expression.

                  @paulcv it is exactly what I do, I generate and compile code. Unfortunatelly, the code I am currently writing is a result of the need to avoid Groovy.
                  • 6. Re: Type of java expression passed as string
                    807588
                    Reflection tells you about objects that you have, not objects that you would have if code is compiled and executed.

                    If you're actually parsing now, then I don't understand your issue. The result of parsing would be a parse tree whose types are identifiable. This is why if you make a syntax error in a Java program such that the wrong type is used in the wrong place, the compiler will tell you.
                    • 7. Re: Type of java expression passed as string
                      807588
                      I am not parsing anything, I have a template class and just insert appropriate code (including the string expression). And I know that if there are syntax errors I will be notified by the compiler, but the goal si to write error free code.
                      • 8. Re: Type of java expression passed as string
                        doremifasollatido
                        Just a question...why are you using the ternary operator here?
                        return (random.nextInt(100) > 50 ? true : false); // returns true
                        Why not the following?
                        return (random.nextInt(100) > 50);
                        [Of course, the "returns true" comment is wrong approximately 51% of the time.]
                        • 9. Re: Type of java expression passed as string
                          jschellSomeoneStoleMyAlias
                          cosminr wrote:
                          I am not parsing anything, I have a template class and just insert appropriate code (including the string expression). And I know that if there are syntax errors I will be notified by the compiler, but the goal si to write error free code.
                          The VM runs class files. It doesn't run java source code.

                          So you would need to change it into a class file. Easiest way it so use the compiler that comes with the JDK (I don't believe it comes with the JRE install).

                          Otherwise you build or find your own java compiler.
                          • 10. Re: Type of java expression passed as string
                            807588
                            Groovy:
                            import javax.script.*;
                            
                            public class ScriptTest {
                                public static void main(String[] args) throws ScriptException {
                                        ScriptEngineManager man = new ScriptEngineManager();
                                        ScriptEngine engine = man.getEngineByExtension("groovy");
                                        if (engine == null) {
                                            System.out.println("no groovy engine");
                                        } else {
                                            System.out.println("engine found");
                                            engine.put("random", new java.util.Random());
                                            String[] examples = {
                                                "1 + 3.5D",
                                                "(random.nextInt(100) > 50 ? true : false)"
                                            };
                                            for (String s : examples) {
                                                Object result = engine.eval(s);
                                                System.out.format("eval(\"%s\") = %s : %s%n", s, result, result.getClass().getName());
                                            }
                                        }
                                }
                            }
                            • 11. Re: Type of java expression passed as string
                              807588
                              Thank you guys for your replies.

                              @jschell - I do compile the source code, I forgot to mention it. I use "tools.jar" that is found in the "lib" folder of my jdk install dir. Generating classes, compiling them and loading is done, fairly easy. The thing is I have this "evaluate()" method who's implementation I generate. The method returns Object, and
                              all the members involved in the expression are also Objects (not from the class hierarchy point of view, but as Object variables). In order to apply operators on them (+, - , %, !) I need to cast those objects to the appropriate type (remember, this happens in the generated code file). My problem appears when I have recursive expressions.I explain this whole sharade better in this thread.

                              @BigDaddyLoveHandles Thank you for your code sample, I will try it out according to my needs and will let you know about my results.

                              My best regards,

                              Cosmin
                              • 12. Re: Type of java expression passed as string
                                jschellSomeoneStoleMyAlias
                                cosminr wrote:
                                Thank you guys for your replies.

                                @jschell - I do compile the source code, I forgot to mention it. I use "tools.jar" that is found in the "lib" folder of my jdk install dir. Generating classes, compiling them and loading is done, fairly easy. The thing is I have this "evaluate()" method who's implementation I generate. The method returns Object, and
                                all the members involved in the expression are also Objects (not from the class hierarchy point of view, but as Object variables). In order to apply operators on them (+, - , %, !) I need to cast those objects to the appropriate type (remember, this happens in the generated code file). My problem appears when I have recursive expressions.I explain this whole sharade better in this thread.
                                Separation of concerns.
                                1. You are creating java source and compiling it.
                                2. In creating that source you need to evaluate an expression.
                                3. That java source (compiled version) needs to do something when it runs.
                                4. You have a code that puts all of the above together.

                                The first three parts are not dependent on each other. The fourth is only dependent to the extent that it must use the other parts.

                                Best I can tell you are confusing parts 2 and 3. Just because they are similar does not make them the same.
                                • 13. Re: Type of java expression passed as string
                                  807588
                                  I agree with all four points, I belive. Point 3 is a bit abstract so maybe I did not get exactly what you ment. I kind of have everything set (except for problems in some cases with point 2):

                                  1. Creating java source and compiling it - WORKS
                                  2. In creating that source you need to evaluate an expression - True only in some cases.
                                  3. That java source (compiled version) needs to do something when it runs. - Guess that's the point in creating it in the first place, dunno.
                                  4. You have a code that puts all of the above together. Yes, the part where I create the code is all set up.

                                  Regarding point 2: In some cases the evaluate() method splits in two branches:
                                  1. An initialization expression which I generate code for correctly (this is the initial value of the recursion variable and is stored as Object regardless of it's actual type)
                                  2. A recursive expression which needs to cast the recursion variable to the type of the result object of the first evaluation. But at code generation time, I do not have that type so that I can write the cast code. This is why I need to evaluate the initialization expression and get the type of the result so that when generating code for the second branch I can write the cast.

                                  Take a look at this generated class:
                                  import de.prosit.simulation.ExpressionImpl;
                                  import de.prosit.simulation.Binding;
                                  import de.prosit.simulation.BindingCache;
                                  
                                  public class EMC_bool_binding implements ExpressionImpl {
                                  
                                      private boolean firstEvaluation = true;
                                      private Binding m_bool_binding;
                                  
                                      public EMC_bool_binding(final BindingCache bindingCache) {
                                          m_bool_binding = bindingCache.getBinding("bool_binding");
                                  
                                      }
                                  
                                      public Object evaluate() {
                                          if (firstEvaluation) {
                                              firstEvaluation = false;
                                              return true;
                                          } else {
                                              return (new java.util.Random().nextInt(10) > new java.util.Random().nextInt(10)) &&
                                                      (UnknownType) (m_bool_binding.getValue());
                                          }
                                      }
                                  }
                                  I have this recursive binding (stores name and value) named "bool_binding"
                                  An instance of this class (ExpressionImpl) is the evaluation delegate for this binding. When I create this class I know the string expressions for the initialization of the binding ("true") and the recursive expression "( new java.util.Random().nextInt(10) > new java.util.Random().nextInt(10) ) && $bool_binding"). When writing the actual code I replace "$bool_binding" with "(CAST_HERE)(m_bool_binding.getValue())". But I don't know what type to cast to since the value of "$bool_binding" is null (remember I am generating it's value implementation at this point). This is the reason why I need to evaluate the first expression ("true") while generating the code, to get it's type and then print it to the source file.

                                  Hueh...messy explanation

                                  Thank you for your effort.
                                  • 14. Re: Type of java expression passed as string
                                    807588
                                    @doremifasollatido

                                    It was just an example expression, didn't care much about it's logic since I cannot control the expressions that are being passed to my code. any valid java expression is allowed. And yes, the comment is ... I will not give the exact word for it :). It should have been "returns boolean".
                                    1 2 Previous Next