简体   繁体   中英

Java parse String into Query

we have two-dimensional array of ints:

int[][] XYZ = new int[][]{
              { 0, 0, 0, 0, 0, 0, 0, 0 },
              { 1, 2, 3, 4, 5, 6, 7, 8 },
              { 8, 7, 6, 5, 4, 3, 2, 1 },
              { 2, 2, 2, 2, 2, 2, 2, 2 },
              { 1, 2, 3, 4, 5, 6, 7, 8 }
            }; 

and a String:

String zapytanie = "((XYZ[i][0]==3 && XYZ[i][1]==4) || (XYZ[i][1]==3 || XYZ[i][2]==7))"

Query is generated dynamiccly and passed to String.

what i want to do is parse this String in for without adding external tools/components.

for(int i=0;i<XYZ.length;i++)
                    {
                        //todo  parse here this expression
                    } 

we want to find all rows that match query in the String and return them.

My problem is i do not know how to parse String into Query. Like removing this " " from String zapytanie and execute it.

I'm pretty sure i can not use eval, but still new thing to learn so i tried it :)

first imported

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

Second

            ScriptEngineManager factory = new ScriptEngineManager();
            ScriptEngine engine = factory.getEngineByName("JavaScript");

            for(int i=0;i<XYZ.length;i++)
            {
                engine.eval(zapytanie);
            }

error: ReferenceError: "XYZ" is not defined.

Any idea how to fix that error, and can you tell me other methods to do the task without using javascript here?

I made a post-order tree from my query, but i was wondering is there a faster way, then using this tree:

a is XYZ[i][0], b is XYZ[i][1] and so on.

from zapytanie = ((a=3 and b=4) or (b=3 or c=7))

http://i.imgur.com/T6gjT5W.png

And i do not know how to use this tree smart way

Well one option is to use eval , though I wouldn't recommend using it for anything in real life as it is a huge security hole.

If you cannot use eval then I suppose you need to educate yourself on parsers, specifically Operator-precedence parser I'd say.

I figured it out myself :)

  1. let's say query was ((a<=1 and b=4) or (b=2 and c=7)) . We get the query as a String - from user input.

and a is XYZ[i][0] , b is XYZ[i][1] from the database int[][] array and so on.

  1. First what i did is check if the query is ok - regarding number of left/right brackets. If not then stop here.

  2. i change query from String that equals ((a<=1 and b=4) or (b=2 and c=7)) to Reverse Polish notation so now my String equals a<=1 b=4 and b=2 c=7 and or

  3. RPN is in postorder order. I created a tree from it regarding this order and added elements to JTree. It looks like this: http://i.imgur.com/AK9hw6M.png

  4. I travel my tree in postorder way and parse each of the items.

    If i find operator like and or or i take 2 childs of them and use one of the logic operators regarding operator above, so: && or || .

  5. On the final i have root which have only Boolean value that tells use if this row was ok or not.

    1. if it was ok - then we write down that row.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM