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() >= 3 && 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() - 3) % 3) == 0)
050 && varValue.substring(0, 2).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() >= 3 && 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] = (String) patterns.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 < 0 && index1 > 0)
155 index = index1;
156 else if(index > 0 && 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+1 < 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+1 < 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] = (PatternPart) patterns.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 = (HashSet) iter.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 = (FSMState) iter.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 = (FSMState) iter.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 = (FSMState) iter.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 = (FSMState) iter.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 = (FSMState) iter.next();
574 state.put(ch, currentState, FSMState.CHILD_STATE);
575 }
576 }
577
578 for(int i=0;i<nextStates.size();i++) {
579 FSMState from = (FSMState) nextStates.get(i);
580 for(int j=0;j<nextStates.size();j++) {
581 FSMState to = (FSMState) nextStates.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 = (FSMState) iter.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 = (FSMState) iter.next();
685 state.put(ch, currentState, FSMState.CHILD_STATE);
686 }
687 }
688
689 for(int i=0;i<nextStates.size();i++) {
690 FSMState from = (FSMState) nextStates.get(i);
691 for(int j=0;j<nextStates.size();j++) {
692 FSMState to = (FSMState) nextStates.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 = (FSMState) iter.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 }
|