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