ParsingFunctions.java
001 package gate.creole.morph;
002 
003 import java.util.ArrayList;
004 import java.util.HashSet;
005 import java.util.Iterator;
006 import java.util.List;
007 import java.util.Set;
008 import java.util.Stack;
009 
010 /**
011  <p>
012  * Title: ParsingFunctions.java
013  </p>
014  <p>
015  * Description: This class implements all static methods, which can be used for
016  * various purposes, like converting rules defined by users into the regular
017  * expressions, finding varilable type from its value type etc.
018  </p>
019  */
020 public class ParsingFunctions {
021 
022 
023   /**
024    * This method takes the value of the variable and tells the user what type
025    * of value is from CharacterRange, CharacterSet, StringSet
026    
027    @param varValue
028    *            value for which to find the variable type
029    @return ERROR_CODE = -4, STRING_SET_CODE = 0, CHARACTER_RANGE_CODE = 1,
030    *         CHARACTER_SET_CODE = 2;
031    */
032   public static int findVariableType(String varValue) {
033     // if the value starts with " it is string set
034     // if the value starts with "[-" it is a character range
035     // if the value starts with "[" it is a character set
036     // otherwise error
037     if (varValue == null) {
038       return Codes.ERROR_CODE;
039     }
040 
041     if (varValue.length() >= && varValue.charAt(0== '\"'
042         && (varValue.lastIndexOf('\"'== (varValue.length() 1))) {
043       // for string set it should be greater than 3 because
044       // it requires at least one character to make the string
045       // first and the last character should be "
046       return Codes.STRING_SET_CODE;
047 
048     else if (varValue.length() >= 6
049         && (((varValue.length() 33== 0)
050         && varValue.substring(02).equals("[-")
051         && varValue.charAt(varValue.length() 1== ']') {
052       // for the character range it should be greater than 6 because
053       // three characters as "[-" and "]"
054       // and finally to define the range character-character
055       return Codes.CHARACTER_RANGE_CODE;
056 
057     else if (varValue.length() >= && varValue.charAt(0== '['
058         && varValue.charAt(varValue.length() 1== ']') {
059       // for the character set it should be greater than 3 characters
060       // because
061       // it requires at least one character
062       // first and the last character should be [ and ] respectively
063       if (varValue.charAt(1== '-') {
064         return Codes.ERROR_CODE;
065       else {
066         return Codes.CHARACTER_SET_CODE;
067       }
068 
069     else {
070       // there are some errors
071       return Codes.ERROR_CODE;
072     }
073 
074   }
075 
076   /**
077    * This method checks for the string if it is a valid integer value
078    
079    @param value
080    *            value to be checked for its type to be integer
081    @return if value is an integer returns true, false otherwise
082    */
083   public static boolean isInteger(String value) {
084     try {
085       Integer.parseInt(value);
086     catch (NumberFormatException nfe) {
087       return false;
088     }
089     return true;
090   }
091 
092   /**
093    * This method checks for the string if it is a valid integer value
094    
095    @param value
096    *            value to be checked for its type to be integer
097    @return if value is an integer returns true, false otherwise
098    */
099   public static boolean isBoolean(String value) {
100     if (value.equals("false"|| value.equals("true")) {
101       return true;
102     else {
103       return false;
104     }
105   }
106 
107   // [abcd]
108   public static final int OR = 0;
109 
110   // (abcd)
111   public static final int AND = 1;
112 
113   // [abcd]+
114   public static final int OR_PLUS = 2;
115 
116   // (abcd)+
117   public static final int AND_PLUS = 3;
118 
119   // [abcd]*
120   public static final int OR_STAR = 4;
121 
122   // (abcd)*
123   public static final int AND_STAR = 5;
124 
125   
126   public static String[] normlizePattern(String line) {
127     List<String> patterns = PatternParser.parsePattern(line);
128     /*String[] pats = new String[patterns.size()];
129     for(int i=0;i<patterns.size();i++) {
130       pats[i] = patterns.get(i);
131     }
132     return pats;*/
133     return patterns.toArray(new String[patterns.size()]);
134   }
135   
136   
137   public static PatternPart[] getPatternParts(String line) {
138     // the first thing we do is replace all variables with their respective
139     // values
140     List<PatternPart> patterns = new ArrayList<PatternPart>();
141     line = line.replaceAll("[\\(]+","(");
142     line = line.replaceAll("[\\)]+",")");
143     line = line.replaceAll("[\\[]+","[");
144     line = line.replaceAll("[\\]]+","]");
145     line = line.replaceAll("(\\()[\\[]+","[");
146     line = line.replaceAll("(\\])[\\)]+","]");
147 
148     while(true) {
149       if(line.trim().length() == 0)
150         break;
151 
152       if(line.charAt(0)!= '(' && line.charAt(0!= '[') {
153         int index = line.indexOf("(");
154         int index1 = line.indexOf("[");
155         if(index < && index1 > 0)
156           index = index1;
157         else if(index > && index1 < 0) {
158           // no need to anything
159         else if(index > index1)
160           index = index1;
161         
162         if(index < 0) {
163           line = "(" + line + ")";
164         else {
165           line = '(' + line.substring(0,index")" + line.substring(index, line.length());
166         }
167       }
168       
169       boolean rdBracket = false;
170       boolean rcBracket = false;
171       
172       int index = line.indexOf('(');
173       if(index >= 0)
174         rdBracket = true;
175       
176       int rcindex = line.indexOf('[');
177       if(rcindex >= 0) {
178         // check which one appears first
179         if(rdBracket) {
180           if(index < rcindex)
181             rcBracket = false;
182           else {
183             rcBracket = true;
184             rdBracket = false;
185             index = rcindex;
186           }
187         else {
188           index = rcindex;
189           rcBracket = true;
190         }
191       }
192       
193       // no bracket found
194       if(!rdBracket && !rcBracket)
195         break;
196       
197       int index1 = -1;
198       if(rdBracket) {
199         index1 = line.indexOf(')');
200         if(index1 < 0)
201           break;
202       }
203       
204       if(rcBracket) {
205         index1 = line.indexOf(']');
206         if(index1 < 0)
207           break;
208       }
209 
210       boolean isPlus = false;
211       boolean isStar = false;
212       
213       if(index1+< line.length()) {
214         isPlus = line.charAt(index1+1== '+';
215         if(!isPlus)
216           isStar = line.charAt(index1+1== '*';
217       }
218       
219       // we check if the character after closing bracket is
220       String string = line.substring(index+1, index1);
221       // by now there shouldn't be any bracket
222       string = string.replaceAll("\\(","");
223       string = string.replaceAll("\\)","");
224       
225       if(!isPlus && !isStar && rcBracket) {
226         // Style 1
227         // [ABCD]
228         PatternPart pp = new PatternPart(string, OR);
229         patterns.add(pp);
230       else if(!isPlus && !isStar && rdBracket) { 
231         // Style 2
232         // (ABC)
233         PatternPart pp = new PatternPart(string, AND);
234         patterns.add(pp);
235       else if(isPlus && rdBracket) {
236         // Style 3
237         // (ABC)+
238         PatternPart pp = new PatternPart(string, AND_PLUS);
239         patterns.add(pp);
240       else if(isPlus && rcBracket){
241         // Style 4
242         // [ABCD]+
243         PatternPart pp = new PatternPart(string, OR_PLUS);
244         patterns.add(pp);
245       else if(isStar && rcBracket){
246         // Style 4
247         // [ABCD]*
248         PatternPart pp = new PatternPart(string, OR_STAR);
249         patterns.add(pp);
250       else {
251         // Style 4
252         // (ABCD)*
253         PatternPart pp = new PatternPart(string, AND_STAR);
254         patterns.add(pp);
255       }
256       
257       if(isPlus || isStar)
258         index1++;
259       
260       if(index1+< line.length())
261         line = line.substring(index1+1, line.length());
262       else
263         line = "";
264     }
265 
266     PatternPart[] parts = new PatternPart[patterns.size()];
267     for(int i=0;i<patterns.size();i++) {
268       parts[i= patterns.get(i);
269     }
270     return parts;
271   }
272 
273   /**
274    * This method is used to find the method definition But it can recognize
275    * only String, boolean and int types for Example: stem(2,"ed","d") ==>
276    * stem(int,java.lang.String,java.lang.String);
277    
278    @param method
279    @return the definition of the method
280    */
281   public static String getMethodName(String method) {
282     // find the first index of '('
283     int index = method.indexOf('(');
284     String methodName = method.substring(0, index"(";
285 
286     // now get the parameter types
287     String[] parameters = method.substring(index + 1, method.length() 1)
288         .split(",");
289 
290     // find the approapriate type
291     for (int i = 0; i < parameters.length; i++) {
292       if (parameters[i].startsWith("\""&& parameters[i].endsWith("\"")) {
293         methodName = methodName + "java.lang.String";
294       else if (ParsingFunctions.isBoolean(parameters[i])) {
295         methodName = methodName + "boolean";
296       else if (ParsingFunctions.isInteger(parameters[i])) {
297         methodName = methodName + "int";
298       }
299       if ((i + 1< parameters.length) {
300         methodName = methodName + ",";
301       }
302     }
303     methodName = methodName + ")";
304     return methodName;
305   }
306 
307   public static final short IRREG_STEM = 0;
308   public static final short NULL_STEM = 1;
309   public static final short SEMIREG_STEM = 2;
310   public static final short STEM = 3;
311   
312   /**
313    * This method is used to find the method definition But it can recognize
314    * only String, boolean and int types for Example: stem(2,"ed","d") ==>
315    * stem(int,java.lang.String,java.lang.String);
316    
317    @param method
318    @return the definition of the method
319    */
320   public static short getMethodIndex(String method) {
321     // find the first index of '('
322     int index = method.indexOf('(');
323     String methodName = method.substring(0, index"(";
324     
325     // now get the parameter types
326     String[] parameters = method.substring(index + 1, method.length() 1)
327         .split(",");
328 
329     // find the approapriate type
330     for (int i = 0; i < parameters.length; i++) {
331       if (parameters[i].startsWith("\""&& parameters[i].endsWith("\"")) {
332         methodName = methodName + "java.lang.String";
333       else if (ParsingFunctions.isBoolean(parameters[i])) {
334         methodName = methodName + "boolean";
335       else if (ParsingFunctions.isInteger(parameters[i])) {
336         methodName = methodName + "int";
337       }
338       if ((i + 1< parameters.length) {
339         methodName = methodName + ",";
340       }
341     }
342     methodName = methodName + ")";
343     if (methodName.startsWith("irreg_stem")) {
344       return IRREG_STEM;
345     else if (methodName.startsWith("null_stem")) {
346       return NULL_STEM;
347     else if(methodName.startsWith("semi_reg_stem")) {
348       return SEMIREG_STEM;
349     else if(methodName.startsWith("stem")) {
350       return STEM;
351     }
352     return -1;
353   }
354 
355   
356   /**
357    * This method finds the actual parameter values
358    
359    @param method
360    *            from which parameters are required to be found
361    @return parameter values
362    */
363   public static String[] getParameterValues(String method) {
364     // now first find the name of the method
365     // their parameters and their types
366     int index = method.indexOf("(");
367 
368     // now get the parameters
369     String[] parameters = method.substring(index + 1, method.length() 1)
370         .split(",");
371 
372     // process each parameter
373     for (int i = 0; i < parameters.length; i++) {
374       // we need to remove " from String
375       if (parameters[i].startsWith("\""&& parameters[i].endsWith("\"")) {
376         parameters[i= parameters[i].substring(1, parameters[i]
377             .length() 1).intern();
378         continue;
379       }
380     }
381     return parameters;
382   }
383   
384   public static Set<Set<FSMState>> createFSMs(String string, int type, Set<Set<FSMState>> initStates, Interpret owner) {
385     Set<Set<FSMState>> result = new HashSet<Set<FSMState>>();
386     // we create different groups for states 
387     Iterator<Set<FSMState>> iter = initStates.iterator();
388     while(iter.hasNext()) {
389       Set<FSMState> states = iter.next();
390       switch (type) {
391       case OR:
392         result.addAll(orFSMs(string, states, owner));
393         break;
394       case OR_PLUS:
395         result.addAll(orPlusFSMs(string, states,owner));
396         break;
397       case AND_PLUS:
398         result.addAll(andPlusFSMs(string, states,owner));
399         break;
400       case OR_STAR:
401         result.addAll(orStarFSMs(string, states,owner));
402         break;
403       case AND_STAR:
404         result.addAll(andStarFSMs(string, states,owner));
405         break;
406       default:
407         if(string.length() 0)
408           result.addAll(andFSMs(string, states,owner));
409         break;
410       }
411     }
412     return result;
413   }
414 
415   
416   @SuppressWarnings("unused")
417   private static FSMState next(char ch, Set<FSMState> states) {
418     Iterator<FSMState> iter = states.iterator();
419     while(iter.hasNext()) {
420       FSMState state = iter.next();
421       FSMState nextState = state.next(ch, FSMState.CHILD_STATE);
422       if(nextState != null)
423         return nextState;
424     }
425     return null;
426   }
427   
428   private static int getIndex(Set<FSMState> states) {
429     Iterator<FSMState> iter = states.iterator();
430     while(iter.hasNext()) {
431       FSMState state = iter.next();
432       return state.getIndex();
433     }
434     return -1;
435   }
436 
437   
438   /**
439    * (abc) -> a -> b -> c ->
440    */
441   public static List<Set<FSMState>> andFSMs(String line, Set<FSMState> initStates, Interpret owner) {
442     // for the first inital State
443     // we need to find out if any of the parent contains referece to it
444     char ch = line.charAt(0);
445 
446     int nextIndex = getIndex(initStates);
447     FSMState currentState = owner.getState(ch, nextIndex + 1);
448     if(currentState == null) {
449       currentState = new FSMState(nextIndex+1);
450       //System.out.println(ch + " \t "+(nextIndex+1));
451       owner.addState(ch, currentState, nextIndex+1);
452     }
453     
454     // currentState contains the first state
455     // this should be added as a child state to all initStates
456     Iterator<FSMState> iter = initStates.iterator();
457     while(iter.hasNext()) {
458       FSMState state = iter.next();
459       state.put(ch, currentState, FSMState.CHILD_STATE);
460     }
461     
462     // and from current state
463     // do the linking of rest of the characters
464     
465     FSMState nextState = currentState;
466     for (int i = 1; i < line.length(); i++) {
467       ch = line.charAt(i);
468       nextState = currentState.next(ch,  FSMState.CHILD_STATE);
469         if(nextState == null){
470           nextState = owner.getState(ch, currentState.getIndex()+1);
471           if(nextState == null) {
472             nextState = new FSMState(currentState.getIndex()+1);
473             //System.out.println(ch + " \t "+(currentState.getIndex()+1));
474             owner.addState(ch, nextState, currentState.getIndex()+1);
475           }
476         currentState.put(ch, nextState,  FSMState.CHILD_STATE);
477         }      
478       currentState = nextState;
479     }
480     List<Set<FSMState>> nextStates = new ArrayList<Set<FSMState>>();
481     Set<FSMState> newSet = new HashSet<FSMState>();
482     newSet.add(nextState);
483     nextStates.add(newSet);
484     return nextStates;
485   }
486 
487   /**
488    * [abc] -> a, 
489    *      -> b, 
490    *      -> c
491    */ 
492   public static List<Set<FSMState>> orFSMs(String line, Set<FSMState> initStates, Interpret owner) {
493     // for each character in the line
494     // we need to find out if any of the initStates contain reference to it
495     // if so that should be assigned to all initStates
496     Set<FSMState> nextStates = new HashSet<FSMState>();
497     for(int i=0;i<line.length();i++) {
498       // for the current character
499       // we need to find out if any of the parent contains referece to it
500       char ch = line.charAt(i);
501       int nextIndex = getIndex(initStates);
502       FSMState currentState = owner.getState(ch, nextIndex + 1);
503       if(currentState == null) {
504         currentState = new FSMState(nextIndex+1);
505         //System.out.println(ch + " \t "+(nextIndex+1));
506         owner.addState(ch, currentState, nextIndex+1);
507       }
508       
509       
510       // currentState should be added as a nextStates
511       nextStates.add(currentState);
512       
513       // currentState contains refenrece for the current character
514       // this should be added as a child state to all initStates
515       Iterator<FSMState> iter = initStates.iterator();
516       while(iter.hasNext()) {
517         FSMState state = iter.next();
518         state.put(ch, currentState, FSMState.CHILD_STATE);
519       }
520       
521     }
522     List<Set<FSMState>> newList = new ArrayList<Set<FSMState>>();
523     newList.add(nextStates);
524     return newList;
525   }
526 
527   /**
528    * [abc]+ 
529    * each element can travel to itself and can travel to next one
530    */
531   public static List<Set<FSMState>> orPlusFSMs(String line, Set<FSMState> initStates, Interpret owner) {
532     // for each character in the line
533     // we need to find out if any of the initStates contain reference to it
534     // if so that should be assigned to all initStates
535     List<FSMState> nextStates = new ArrayList<FSMState>();
536     for(int i=0;i<line.length();i++) {
537       // for the current character
538       // we need to find out if any of the parent contains referece to it
539       char ch = line.charAt(i);
540       int nextIndex = getIndex(initStates);
541       FSMState currentState = owner.getState(ch, nextIndex + 1);
542       if(currentState == null) {
543         currentState = new FSMState(nextIndex+1);
544         //System.out.println(ch + " \t "+(nextIndex+1));
545 
546         owner.addState(ch, currentState, nextIndex+1);
547       }
548       
549       // currentState should be added as a nextStates
550       nextStates.add(currentState);
551       
552       // currentState contains refenrece for the current character
553       // this should be added as a child state to all initStates
554       Iterator<FSMState> iter = initStates.iterator();
555       while(iter.hasNext()) {
556         FSMState state = iter.next();
557         state.put(ch, currentState, FSMState.CHILD_STATE);
558       }
559     }
560 
561     for(int i=0;i<nextStates.size();i++) {
562       FSMState from = nextStates.get(i);
563       for(int j=0;j<nextStates.size();j++) {
564         FSMState to = nextStates.get(j);
565         char ch = line.charAt(j);
566         from.put(ch, to, FSMState.ADJ_STATE);
567       }
568     }
569 
570     Set<FSMState> newSet = new HashSet<FSMState>();
571     newSet.addAll(nextStates);
572     List<Set<FSMState>> newList = new ArrayList<Set<FSMState>>();
573     newList.add(newSet);
574     return newList;
575   }
576 
577   /**
578    * (abc)+ 
579    * -> a -> b -> c -> null 
580    * -> a -> b -> c -> a
581    */
582   public static List<Set<FSMState>> andPlusFSMs(String line, Set<FSMState> initStates, Interpret owner) {
583     // for the first inital State
584     // we need to find out if any of the parent contains referece to it
585     char ch = line.charAt(0);
586     int nextIndex = getIndex(initStates);
587     FSMState currentState = owner.getState(ch, nextIndex + 1);
588     if(currentState == null) {
589       currentState = new FSMState(nextIndex+1);
590       //System.out.println(ch + " \t "+(nextIndex+1));
591 
592       owner.addState(ch, currentState, nextIndex+1);
593     }
594 
595     FSMState firstState = currentState;
596     
597     // currentState contains the first state
598     // this should be added as a child state to all initStates
599     Iterator<FSMState> iter = initStates.iterator();
600     while(iter.hasNext()) {
601       FSMState state = iter.next();
602       state.put(ch, currentState, FSMState.CHILD_STATE);
603     }
604     
605     // and from current state
606     // do the linking of rest of the characters
607     FSMState nextState = currentState;
608     for (int i = 1; i < line.length(); i++) {
609       ch = line.charAt(i);
610       nextState = currentState.next(ch,  FSMState.CHILD_STATE);
611         if(nextState == null){
612           nextState = owner.getState(ch, currentState.getIndex()+1);
613           if(nextState == null) {
614             nextState = new FSMState(currentState.getIndex()+1);
615             //System.out.println(ch + " \t "+(currentState.getIndex()+1));
616             owner.addState(ch, nextState, currentState.getIndex()+1);
617           }
618         currentState.put(ch, nextState,  FSMState.CHILD_STATE);
619         }      
620       currentState = nextState;
621     }
622       
623     nextState.put(line.charAt(0), firstState,  FSMState.ADJ_STATE);
624     List<Set<FSMState>> nextStates = new ArrayList<Set<FSMState>>();
625     Set<FSMState> newSet = new HashSet<FSMState>();
626     newSet.add(nextState);
627     nextStates.add(newSet);
628     return nextStates;
629   }
630 
631   /**
632    * [abc]* 
633    * each element can have reference to adjecent ones and to itself
634    */
635   public static List<Set<FSMState>> orStarFSMs(String line, Set<FSMState> initStates, Interpret owner) {
636     // for each character in the line
637     // we need to find out if any of the initStates contain reference to it
638     // if so that should be assigned to all initStates
639     List<FSMState> nextStates = new ArrayList<FSMState>();
640     for(int i=0;i<line.length();i++) {
641       // for the current character
642       // we need to find out if any of the parent contains referece to it
643       char ch = line.charAt(i);
644       int nextIndex = getIndex(initStates);
645       FSMState currentState = owner.getState(ch, nextIndex + 1);
646       if(currentState == null) {
647         currentState = new FSMState(nextIndex+1);
648         //System.out.println(ch + " \t "+(nextIndex+1));
649 
650         owner.addState(ch, currentState, nextIndex+1);
651       }
652       
653       // currentState should be added as a nextStates
654       nextStates.add(currentState);
655       
656       // currentState contains refenrece for the current character
657       // this should be added as a child state to all initStates
658       Iterator<FSMState> iter = initStates.iterator();
659       while(iter.hasNext()) {
660         FSMState state = iter.next();
661         state.put(ch, currentState, FSMState.CHILD_STATE);
662       }
663     }
664 
665     for(int i=0;i<nextStates.size();i++) {
666       FSMState from = nextStates.get(i);
667       for(int j=0;j<nextStates.size();j++) {
668         FSMState to = nextStates.get(j);
669         char ch = line.charAt(j);
670         from.put(ch, to, FSMState.ADJ_STATE);
671       }
672     }
673 
674     Set<FSMState> newSet = new HashSet<FSMState>();
675     newSet.addAll(nextStates);
676     
677     List<Set<FSMState>> newList = new ArrayList<Set<FSMState>>();
678     newList.add(newSet);
679     newList.add(initStates);
680     return newList;
681   }
682 
683   /**
684    * (abc)*
685    */
686   public static List<Set<FSMState>> andStarFSMs(String line, Set<FSMState> initStates, Interpret owner) {
687     // for the first inital State
688     // we need to find out if any of the parent contains referece to it
689     char ch = line.charAt(0);
690     int nextIndex = getIndex(initStates);
691     FSMState currentState = owner.getState(ch, nextIndex + 1);
692     if(currentState == null) {
693       currentState = new FSMState(nextIndex+1);
694       //System.out.println(ch + " \t "+(nextIndex+1));
695 
696       owner.addState(ch, currentState, nextIndex+1);
697     }
698 
699     FSMState firstState = currentState;
700     
701     // currentState contains the first state
702     // this should be added as a child state to all initStates
703     Iterator<FSMState> iter = initStates.iterator();
704     while(iter.hasNext()) {
705       FSMState state = iter.next();
706       state.put(ch, currentState, FSMState.CHILD_STATE);
707     }
708     
709     // and from current state
710     // do the linking of rest of the characters
711     FSMState nextState = currentState;
712     for (int i = 1; i < line.length(); i++) {
713       ch = line.charAt(i);
714       nextState = currentState.next(ch,  FSMState.CHILD_STATE);
715         if(nextState == null){
716           nextState = owner.getState(ch, currentState.getIndex()+1);
717           if(nextState == null) {
718             nextState = new FSMState(currentState.getIndex()+1);
719             //System.out.println(ch + " \t "+(currentState.getIndex()+1));
720             owner.addState(ch, nextState, currentState.getIndex()+1);
721           }
722         currentState.put(ch, nextState,  FSMState.CHILD_STATE);
723         }      
724       currentState = nextState;
725     }
726     
727     
728     nextState.put(line.charAt(0), firstState,  FSMState.ADJ_STATE);
729     
730     List<Set<FSMState>> nextStates = new ArrayList<Set<FSMState>>();
731     Set<FSMState> newSet = new HashSet<FSMState>();
732     newSet.add(nextState);
733     nextStates.add(newSet);
734     nextStates.add(initStates);
735     return nextStates;
736   }
737 
738   
739   /**
740    * This method convert the expression which has been entered by the user in
741    * the .rul file (i.e. rules defined by the user), into the expression which
742    * are recognized by the regular expression Patterns
743    
744    @param line
745    *            rule defined by the user
746    @param storage
747    *            this method internally requires values of the used variables
748    *            to replace the them with their values in the expression
749    @return newly generated regular expression
750    */
751   public static String convertToRegExp(String line, Storage storage) {
752     // replace all OR with |
753     line = line.replaceAll("( OR )""|");
754     line = line.replaceAll("(\\[\\-)""[");
755 
756     // we will use the stack concept here
757     // for every occurence of '{', or '(' we will add that into the stack
758     // and for every occurence of '}' or ')' we will remove that element
759     // from
760     // the stack
761     // if the value found between the bracket is an integer value
762     // we won't replace those brackets
763     StringBuffer newExpr = new StringBuffer(line);
764     Stack<String> stack = new Stack<String>();
765     Stack<Integer> bracketIndexes = new Stack<Integer>();
766 
767     for (int i = 0; i < newExpr.length(); i++) {
768       if (newExpr.charAt(i== '{') {
769         // add it to the stack
770         stack.add("{");
771         bracketIndexes.add(new Integer(i));
772 
773       else if (newExpr.charAt(i== '(') {
774         // add it to the stack
775         stack.add("(");
776         bracketIndexes.add(new Integer(i));
777 
778       else if (newExpr.charAt(i== '[') {
779         // add it to the stack
780         stack.add("[");
781         bracketIndexes.add(new Integer(i));
782 
783       else if (newExpr.charAt(i== '\"') {
784         // before adding it to the stack, check if this is the closing
785         // one
786         if (stack.isEmpty()
787             || !((stack.get(stack.size() 1))
788                 .equals("\""))) {
789           // yes this is the opening one
790           // add it to the stack
791           stack.add("\"");
792           bracketIndexes.add(new Integer(i));
793         else {
794           // this is the closing one
795           stack.pop();
796           int index = (bracketIndexes.pop()).intValue();
797           newExpr.setCharAt(index, '(');
798           newExpr.setCharAt(i, ')');
799         }
800       else if (newExpr.charAt(i== '}') {
801         // remove the element from the stack
802         // it must be '{', otherwise generate the error
803         String bracket = (stack.pop());
804         int index = (bracketIndexes.pop()).intValue();
805         if (!bracket.equals("{")) {
806           return null;
807         }
808 
809         // now check if the value between these brackets is integer,
810         // that means
811         // we don't need to change the brackets, otherwise change them
812         // to
813         // '(' and ')'
814         if (isInteger(newExpr.substring(index + 1, i))) {
815           // yes it is an integer
816           // continue
817           continue;
818         else {
819           // no it is string
820           newExpr.setCharAt(index, '(');
821           newExpr.setCharAt(i, ')');
822         }
823 
824       else if (newExpr.charAt(i== ')') {
825         // remove the element from the stack
826         // it must be ')', otherwise generate the error
827         String bracket = (stack.pop());
828         bracketIndexes.pop();
829         if (!bracket.equals("(")) {
830           return null;
831         }
832         continue;
833       else if (newExpr.charAt(i== ']') {
834         // remove the element from the stack
835         // it must be '[', otherwise generate the error
836         String bracket = (stack.pop());
837         bracketIndexes.pop();
838         if (!bracket.equals("[")) {
839           return null;
840         }
841       }
842     }
843     // check if all the stacks are empty then and only then the written
844     // expression is true, otherwise it is incorrect
845     if (!stack.empty() || !bracketIndexes.empty()) {
846       return null;
847     }
848     // System.out.println(line+" "+newExpr);
849     // now we need to replace the variables with their values
850     // but how would we know which is the variable
851     // so get the variable list and check if it is available in the
852     // expression
853     String[] varNames = storage.getVarNames();
854     for (int i = 0; i < varNames.length; i++) {
855       // check for the occurance of each varName in the expression
856       int index = -1;
857       String myString = "{[()]} ";
858       while ((index = newExpr.indexOf(varNames[i], index + 1)) != -1) {
859         // System.out.println(index + " "+newExpr.length());
860         // now check for the left and right characters
861         if (index > 0) {
862           if (myString.indexOf(newExpr.charAt(index - 1)) == -1) {
863             index = index + varNames[i].length() 1;
864             // this is not the varilable
865             continue;
866           }
867         }
868         if ((varNames[i].length() + index< newExpr.length()) {
869           if (myString.indexOf(newExpr.charAt(varNames[i].length()
870               + index)) == -1) {
871             index = index + varNames[i].length() 1;
872             // this is not the variable
873             continue;
874           }
875         }
876 
877         // yes it is a variable
878         String replaceWith = "(" (storage.get(varNames[i]))
879             ")";
880         newExpr.replace(index, (varNames[i].length() + index),
881             replaceWith);
882         index = index + replaceWith.length();
883       }
884     }
885     return new String(newExpr);
886   }
887 }