-1

I have a string like

String str="(0 & (0 || 1))";

I want to process this as boolean output.For example

(0||1)= 1
(0 & 1)=0

so my final output should be 0 as per the string "(0 & (0 || 1))";

How do you process this?

I tried with the below code:

String str="(1 & (1 & 1))";

    str=str.replaceAll("1","true");

    str=str.replaceAll("0", "false");

    System.out.println(str);

    Boolean boolean2 = Boolean.parseBoolean(str);

    String sr=String.valueOf(str);

    System.out.println(boolean2);
  • You can't do this with regexes since even parsing the parentheses is not possible. Simply tokenize the input and build a parse tree, then write an evaluator function. – perreal Jun 20 '14 at 10:20
  • can u please explain(in code) how to do this?I tried a number of process using tokenizer too StringTokenizer str1=new StringTokenizer(str); while (str1.hasMoreElements()) { if(!(str1.nextElement().equals("(0"))){ Object object = (Object) str1.nextElement(); System.out.println(object); } } but I am not getting it – user3628323 Jun 20 '14 at 10:22
  • 1
    Please include the code you have tried *in your question*. –  Jun 20 '14 at 10:51
  • @LutzHorn: done :please check – user3628323 Jun 20 '14 at 11:03
  • Wrong way,you can't parse this kind of String to a boolean value.Impossible to achieve this way!!! – Am_I_Helpful Jun 20 '14 at 11:23
  • @shekharsuman:how can I do that can u please explain me.It would be really grateful – user3628323 Jun 20 '14 at 11:28
  • possible duplicate of [boolean expression parser in java](http://stackoverflow.com/questions/12203003/boolean-expression-parser-in-java) – Thomas Uhrig Jun 20 '14 at 11:46
  • This *can* be done. It is either hard or requires scripting support, but answering "impossible" is not entirely honest. – tucuxi Jun 20 '14 at 11:47

2 Answers2

1

Java does not have an eval() statement that can take a string of code and compile and interpret it within a program. You could, using Java, write such a command (you have access to the java parser, can write your own classloader, ...), but why bother whenyou already have built-in scripting support in the language.

The usual way to interpret expressions is to write a parser for your expression language and interpret the resulting parse tree (if you do not understand words like "parser" and "parse tree" this is not the easiest route for you). When done correctly, this is the fastest approach.

However, you can also rely on the built-in scripting support:

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

public class T {

    public static String interpret(String js) {
        try {
            ScriptEngineManager mgr = new ScriptEngineManager();
            ScriptEngine engine = mgr.getEngineByName("JavaScript");
            return engine.eval(js).toString();
        } catch (ScriptException e) {
            // Shouldn't happen unless somebody breaks the script
            throw new RuntimeException(e);
        }
    }

    public static void main(String args[]) {
        String str=args[0];
        str = str.replaceAll("1", "true");
        str = str.replaceAll("0", "false");
        str = str.replaceAll(" [&] ", "&&");
        str = str.replaceAll(" [|] ", "||");        
        System.out.println(interpret(str));
    }
}

Notice that this is somewhat slow and generally considered cheating if the exercise expected you to use a parser. Additionally, since JS is a full-fledged language, it is a lot less safe than having a custom-built, restricted parser: you have to go to great lengths to sanitize the JS to prevent people from entering "evil expressions" that can tie up your system or do other nasty stuff.

The output is, for

javac T.java && java T "(0 & (0 || 1))"

(notice that the first argument to the program is the expression to parse)

false
tucuxi
  • 17,561
  • 2
  • 43
  • 74
  • Absolutely Brilliant!! – Mustafa sabir Jun 20 '14 at 11:56
  • @tucuxi: I am begineer to this scriptEngine....but the ouput is not correct I guesss as the desired ouput should be false. can u please tell how it works and how it gave true? – user3628323 Jun 21 '14 at 07:14
  • @tucuxi: What is ScriptEnginemanager is it a jar or waht? How can I get it imported to my workspace? – user3628323 Jun 21 '14 at 07:41
  • @tucuxi:I am getting the below error while I tried to run the above program Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 50 at com.T.main(T.java:20) – user3628323 Jun 21 '14 at 08:46
  • ScriptEngine is included within the standard Java edition. It is probably a jar, but a system one installed with Java itself. Fixed the output: it was, indeed, false. I copied & pasted the wrong thing on the first edit. If you do not show me your input, I cannot comment on your exception, except by saying that "it works for me". Add a System.out.println("this is my string: '" + str + "'") before all those replaceAlls and reply here. – tucuxi Jun 21 '14 at 11:15
  • @tucuxi: my input string is "(0 & (0 || 1))".....The same code when I am trying to execute with only one change as String str="(0 & (0 || 1))"; I get nullpointer exception at ScriptEngine engine = mgr.getEngineByName("JavaScript"); can u please help me out – user3628323 Jun 23 '14 at 09:21
  • What version of Java are you using? (output of `java -version`). You need 1.6 or higher. – tucuxi Jun 23 '14 at 09:51
  • @tucuxi : using java version 7 – user3628323 Jun 24 '14 at 11:23
  • Please include full output of java -version – tucuxi Jun 24 '14 at 11:34
1

Well, basically there are 2 ways that comes to my mind to solve this issue:

  1. Create a custom parser for your expressions. Things like ANTLR or JavaCC may help you, but you can even create your own lexer/parser, there are tons of docs and books about that - but it's not that trivial.
  2. A bit easier is to call an engine that can evaluate that expression for you. Here's an example how to do it in JavaScript, which is within your JDK by default:

    String str = "(true && (false || true))";
    
    ScriptEngine engine = new ScriptEngineManager().getEngineByName("JavaScript");
    System.out.println(engine.eval(str));
    
rlegendi
  • 10,466
  • 3
  • 38
  • 50