1
2
3
4
5 package edu.asu.cri.MirkE.util;
6
7
8 import java.util.Stack;
9 import java.util.Iterator;
10
11 class Parser {
12
13 private boolean DEBUGING_ON = true;
14
15 /***
16 *
17 * @author jafaleon
18 *
19 * class ParsedString
20 * is to hold the Strings objects to be parsed, so
21 * all the needed data is in one object.
22 */
23 class ParsedString{
24
25 /***The current position to be parsed. */
26 public int currentPosition;
27 /*** The source String, the data to be analysed*/
28 public String source;
29 /*** The last lexem recognised*/
30 public String resultLexem;
31 /*** the code of the symbol.*/
32 public int symbolValue;
33
34 /*** boolean tracer, must desapear.*/
35 private boolean addedResult = false;
36
37 /***
38 *
39 * @return the current position of the scanner
40 */
41 public int getCurrentPosition(){
42 return currentPosition;
43 }
44
45 /***
46 *
47 * @return the last recognised lexem.
48 */
49 public String getResultLexem(){
50 return resultLexem;
51 }
52
53 /***
54 * Make a fresh start to recognise a new lexem.
55 *
56 */
57 public void newResult(){
58 resultLexem = "";
59 symbolValue = -1;
60 }
61
62 /***
63 *
64 * @param symbolValue the new one.
65 */
66 public void setSymbolValue(int symbolValue){
67 this.symbolValue = symbolValue;
68 }
69
70 /***
71 *
72 * @return the last recognised symbol.
73 */
74 public int getSymbolValue(){
75 return symbolValue;
76 }
77
78 /***
79 * add the last character to the final result.
80 *
81 */
82 public void addResult(){
83 if(addedResult) return;
84 resultLexem = resultLexem + source.substring(currentPosition-1, currentPosition);
85 addedResult = true;
86 }
87
88 /***
89 * Constructor with full params, not jet used.
90 * @param position
91 * @param source
92 * @param result
93 * @param valor
94 */
95 public ParsedString(int position, String source, String result, int valor){
96 this.currentPosition = position;
97 this.source = source;
98 this.resultLexem = result;
99 this.symbolValue = valor;
100 }
101
102 /***
103 * Constructor with the string to be parsed.
104 * @param source
105 */
106 public ParsedString(String source){
107 this.currentPosition = 0;
108 this.source = source;
109 this.resultLexem = "";
110 this.symbolValue = 0;
111 }
112
113 /***
114 * return next char from the source String.
115 * @return
116 */
117 public Character nextChar(){
118 currentPosition++;
119 if(currentPosition>source.length()){
120 return null;
121 }else{
122 addedResult = false;
123 return new Character(source.charAt(currentPosition -1));
124 }
125 }
126
127 /***
128 * this method is here to accept String representing
129 * numbers starting with a dot, like: .25 => addZero => 0.25
130 *
131 */
132 public void addZero(){
133 resultLexem = "0" + resultLexem;
134 }
135
136 /***
137 * A returning state that mus go back one position.
138 * This method goes back the one position on the parsed string.
139 *
140 */
141 public void backOnePosition(){
142 addedResult = false;
143 resultLexem = resultLexem.substring(0, resultLexem.length()-1);
144 currentPosition--;
145 }
146
147 /***
148 * Same that backOnePosition, but for two positions.
149 *
150 */
151 public void backTwoPositions(){
152 backOnePosition();
153 backOnePosition();
154 }
155
156 /***
157 * Have been reached the EOF?
158 * @return true if true.
159 */
160 public boolean isFinish(){
161 return currentPosition>= source.length();
162 }
163
164 /***
165 *
166 * @return get the part of the string that has been allready parsed.
167 */
168 public String getParsedString(){
169 return source.substring(0, currentPosition - resultLexem.length());
170 }
171 }
172
173
174
175
176
177
178
179
180 public static final int PLUS = 0;
181 public static final int MINUS = 1;
182 public static final int DIGIT = 2;
183 public static final int LETTER = 3;
184 public static final int MULTI = 4;
185 public static final int POWER = 5;
186 public static final int DIV = 6;
187 public static final int DOT = 7;
188 public static final int LFPAR = 8;
189 public static final int RGPAR = 9;
190 public static final int EXP = 10;
191 public static final int WHITE_SPACE = 11;
192 public static final int ERROR = 12;
193 public static final int NUMBER = 13;
194 public static final int NAME = 14;
195 public static final int EOF = 15;
196
197
198
199
200 public static final int ST_ERROR = -1;
201 public static final int ST_INITIAL = 0;
202 public static final int ST_NUMBER = 1;
203 public static final int ST_NAME = 2;
204 public static final int ST_REAL = 3;
205 public static final int ST_DOT = 4;
206
207 public static final int ST_EXP = 5;
208 public static final int ST_SIG_EXP = 6;
209 public static final int ST_DOT_REAL = 7;
210 public static final int MAX_TA_ST = ST_DOT_REAL;
211
212
213
214 public static final int RT_ERROR = 8;
215 public static final int MIN_RT_STATE= RT_ERROR;
216
217 public static final int RT_NUMBER = 9;
218 public static final int MIN_BACK_1_TO_ENTRY = RT_NUMBER;
219
220 public static final int RT_NAME = 10;
221 public static final int MAX_BACK_1_TO_ENTRY = RT_NAME;
222
223 public static final int RT_NUMBER_EXP = 11;
224 public static final int MIN_BACK_2_TO_ENTRY = RT_NUMBER_EXP;
225 public static final int MAX_BACK_2_TO_ENTRY = RT_NUMBER_EXP;
226
227
228 public static final int RT_MULTI = 12;
229 public static final int RT_POWER = 13;
230 public static final int RT_DIV = 14;
231 public static final int RT_LFPAR = 15;
232 public static final int RT_RGPAR = 16;
233 public static final int RT_PLUS = 17;
234 public static final int RT_MINUS = 18;
235 public static final int MAX_RT_STATE= RT_MINUS;
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254 private static int[][] TA={
255 { RT_PLUS, RT_MINUS, ST_NUMBER, ST_NAME, RT_MULTI, RT_POWER, RT_DIV, ST_DOT, RT_LFPAR, RT_RGPAR, ST_NAME, ST_INITIAL, RT_ERROR},
256 { RT_NUMBER, RT_NUMBER, ST_NUMBER, RT_NUMBER, RT_NUMBER, RT_NUMBER, RT_NUMBER, ST_REAL, RT_NUMBER, RT_NUMBER, ST_EXP, RT_NUMBER, RT_NUMBER},
257 { RT_NAME, RT_NAME, RT_NAME, ST_NAME, RT_NAME, RT_NAME, RT_NAME, RT_NAME, RT_NAME, RT_NAME, ST_NAME, RT_NAME, RT_NAME},
258 { RT_NUMBER, RT_NUMBER, ST_REAL , RT_NUMBER, RT_NUMBER, RT_NUMBER, RT_NUMBER, RT_NUMBER, RT_NUMBER, RT_NUMBER, ST_EXP, RT_NUMBER, RT_NUMBER},
259 { RT_ERROR, RT_ERROR, ST_DOT_REAL, RT_ERROR, RT_ERROR, RT_ERROR, RT_ERROR, RT_ERROR, RT_ERROR, RT_ERROR, RT_ERROR, RT_ERROR, RT_ERROR},
260 { ST_SIG_EXP, ST_SIG_EXP, ST_SIG_EXP, RT_NUMBER_EXP, RT_NUMBER_EXP, RT_NUMBER_EXP, RT_NUMBER_EXP, RT_NUMBER_EXP, RT_NUMBER_EXP, RT_NUMBER_EXP, RT_NUMBER_EXP, RT_NUMBER_EXP, RT_NUMBER_EXP},
261 { RT_NUMBER, RT_NUMBER, ST_SIG_EXP, RT_NUMBER, RT_NUMBER, RT_NUMBER, RT_NUMBER, RT_NUMBER, RT_NUMBER, RT_NUMBER, RT_NUMBER, RT_NUMBER, RT_NUMBER}
262 };
263
264 /***
265 * Method for transforming the characters into scanner's symbols.
266 * probably a better name can be found, if so, don't esitate to change.
267 * @param character
268 * @return
269 */
270 public int token(Character character){
271 if(character == null) return ERROR;
272
273 if(character.equals(new Character(new String("+").charAt(0)))) return PLUS;
274 if(character.equals(new Character(new String("-").charAt(0)))) return MINUS;
275 if(character.equals(new Character(new String("*").charAt(0)))) return MULTI;
276 if(character.equals(new Character(new String("/").charAt(0)))) return DIV;
277 if(character.equals(new Character(new String("^").charAt(0)))) return POWER;
278 if(character.equals(new Character(new String(".").charAt(0)))) return DOT;
279 if(character.equals(new Character(new String("(").charAt(0)))) return LFPAR;
280 if(character.equals(new Character(new String(")").charAt(0)))) return RGPAR;
281 if(character.equals(new Character(new String("e").charAt(0)))) return EXP;
282 if(character.equals(new Character(new String("E").charAt(0)))) return EXP;
283 if(Character.isDigit(character.charValue())) return DIGIT;
284 if(Character.isLetter(character.charValue())) return LETTER;
285 if(Character.isWhitespace(character.charValue())) return WHITE_SPACE;
286 return ERROR;
287 }
288
289 /***
290 * simple check for the current state.
291 * @param state
292 * @return
293 */
294 public boolean isReturnState(int state){
295 return (state >= MIN_RT_STATE) && (state <= MAX_RT_STATE);
296 }
297
298 /***
299 * Advance to next state using TA matrix.
300 * @param state the previous state.
301 * @param inChar the readed character.
302 * @param parsedString
303 * @return the new state.
304 */
305 public int nextState(int state, Character inChar, ParsedString parsedString){
306 int localState = ST_ERROR;
307 if(state <=MAX_TA_ST){
308 localState = TA[state][token(inChar)];
309 if(localState==ST_DOT_REAL){
310 parsedString.addZero();
311 localState = ST_REAL;
312 }
313 }
314 return localState;
315 }
316
317 /***
318 * Method to transform the retourning state to a symbol.
319 *
320 */
321 public int fromStateToToken(int state){
322 switch(state){
323 case RT_NUMBER: return NUMBER;
324 case RT_NAME: return NAME;
325 case RT_MULTI: return MULTI;
326 case RT_POWER: return POWER;
327 case RT_DIV: return DIV;
328 case RT_PLUS: return PLUS;
329 case RT_MINUS: return MINUS;
330 case RT_LFPAR: return LFPAR;
331 case RT_RGPAR: return RGPAR;
332 default: return ERROR;
333 }
334 }
335
336
337 public boolean isBackOneToEntryState(int state){
338 return (state >= MIN_BACK_1_TO_ENTRY) && (state <= MAX_BACK_1_TO_ENTRY);
339 }
340
341 public boolean isBackTwoToEntryState(int state){
342 return (state >= MIN_BACK_2_TO_ENTRY) && (state <= MAX_BACK_2_TO_ENTRY);
343 }
344
345 /***
346 * method to get the next lexem it returns the hole parsedString,
347 * I know is not very academic, promised to improve in next version.
348 * @param parsedString
349 * @return
350 */
351 public ParsedString unpackFromString(ParsedString parsedString){
352 parsedString.newResult();
353 int state = ST_INITIAL;
354 Character character = null;
355 while(!isReturnState(state)){
356 character = parsedString.nextChar();
357 if((state == ST_INITIAL) && (character == null)){
358 parsedString.setSymbolValue(EOF);
359 return parsedString;
360 }
361 parsedString.addResult();
362 state = nextState(state, character, parsedString);
363 }
364 if((isBackTwoToEntryState(state)) && (token(character)!=ERROR)){
365 parsedString.backTwoPositions();
366 parsedString.setSymbolValue(fromStateToToken(state));
367 }else if((isBackOneToEntryState(state)) && (token(character)!=ERROR)){
368 parsedString.backOnePosition();
369 parsedString.setSymbolValue(fromStateToToken(state));
370 }
371 parsedString.setSymbolValue(fromStateToToken(state));
372 return parsedString;
373 }
374
375
376
377
378
379
380
381
382
383 private Stack yy_stack = new Stack();
384
385 private int yy_state;
386 private int yy_action;
387 private int yy_symbol;
388
389 public static final String _ST_PARSE_COMPLETED = "Process completed";
390 public static final String _ST_PARSE_ERROR = "Parse error, string not accepted ";
391
392
393 public static final int ST_YY_ERROR = -1;
394 public static final int MIN_ST = 0;
395 public static final int ST_00 = 0;
396 public static final int ST_01 = 1;
397 public static final int ST_02 = 2;
398 public static final int ST_03 = 3;
399 public static final int ST_04 = 4;
400 public static final int ST_05 = 5;
401 public static final int ST_06 = 6;
402 public static final int ST_07 = 7;
403 public static final int ST_08 = 8;
404 public static final int ST_09 = 9;
405 public static final int ST_10 = 10;
406 public static final int ST_11 = 11;
407 public static final int ST_12 = 12;
408 public static final int ST_13 = 13;
409 public static final int ST_14 = 14;
410 public static final int ST_15 = 15;
411 public static final int ST_16 = 16;
412 public static final int ST_17 = 17;
413 public static final int ST_18 = 18;
414 public static final int ST_19 = 19;
415 public static final int ST_20 = 20;
416 public static final int ST_21 = 21;
417 public static final int ST_22 = 22;
418 public static final int ST_23 = 23;
419 public static final int ST_24 = 24;
420 public static final int ST_25 = 25;
421 public static final int MAX_ST = ST_25;
422
423 public static final int YY_ACC = 26;
424
425
426
427 public static final int MIN_SH = 100;
428 public static final int SH_01 = 101;
429 public static final int SH_02 = 102;
430 public static final int SH_03 = 103;
431 public static final int SH_04 = 104;
432 public static final int SH_05 = 105;
433 public static final int SH_06 = 106;
434 public static final int SH_07 = 107;
435 public static final int SH_08 = 108;
436 public static final int SH_09 = 109;
437 public static final int SH_10 = 110;
438 public static final int SH_11 = 111;
439 public static final int SH_12 = 112;
440 public static final int SH_13 = 113;
441 public static final int SH_14 = 114;
442 public static final int SH_15 = 115;
443 public static final int SH_16 = 116;
444 public static final int SH_17 = 117;
445 public static final int SH_18 = 118;
446 public static final int SH_19 = 119;
447 public static final int SH_20 = 120;
448 public static final int SH_21 = 121;
449 public static final int SH_22 = 122;
450 public static final int SH_23 = 123;
451 public static final int SH_24 = 124;
452 public static final int SH_25 = 125;
453 public static final int MAX_SH = SH_25;
454
455
456 public static final int MIN_RE = 200;
457 public static final int RE_01 = 201;
458 public static final int RE_02 = 202;
459 public static final int RE_03 = 203;
460 public static final int RE_04 = 204;
461 public static final int RE_05 = 205;
462 public static final int RE_06 = 206;
463 public static final int RE_07 = 207;
464 public static final int RE_08 = 208;
465 public static final int RE_09 = 209;
466 public static final int RE_10 = 210;
467 public static final int RE_11 = 211;
468 public static final int RE_12 = 212;
469 public static final int RE_13 = 213;
470 public static final int RE_14 = 214;
471 public static final int MAX_RE = RE_14;
472
473
474 public static final int MIN_TE = 300;
475 public static final int TE_PLUS = 300;
476 public static final int TE_MINUS = 301;
477 public static final int TE_MULTI = 302;
478
479 public static final int TE_LFPAR = 303;
480 public static final int TE_RGPAR = 304;
481 public static final int TE_POWER = 305;
482 public static final int TE_NAME = 306;
483 public static final int TE_NUMBER = 307;
484 public static final int TE_EOF = 308;
485 public static final int MAX_TE = TE_EOF;
486
487 public static final String _ST_TE_EOF = "$";
488
489
490 public static final int MIN_NT = 400;
491 public static final int NT_E = 400;
492 public static final int NT_T = 401;
493 public static final int NT_F = 402;
494 public static final int NT_N = 403;
495 public static final int NT_U = 404;
496 public static final int MAX_NT = NT_U;
497
498
499 /***
500 *
501 * @author jafaleon
502 *class to represent the production rules of the grammar.
503 */
504 class Production{
505 /*** The non terminal of the LHS*/
506 private int leftHandSide;
507 /*** the various suymbols of the RHS*/
508 private int[] rightHandSide;
509 /*** a String to keep the written expresion of teh production.*/
510 private String representation;
511
512 /***
513 * Constructor
514 * @param leftHandSide the non terminal of the LHS
515 * @param rightHandSide the matrix of the RHS
516 * @param representation the String representing this production
517 */
518 public Production(int leftHandSide, int[] rightHandSide, String representation){
519 this.leftHandSide = leftHandSide;
520 this.rightHandSide = rightHandSide;
521 this.representation = representation;
522 }
523
524 /***
525 *
526 * @return the RHS
527 */
528 public int[] getRightHandSide(){
529 return rightHandSide;
530 }
531
532 /***
533 *
534 * @return the LHS
535 */
536 public int getLeftHandSide(){
537 return leftHandSide;
538 }
539
540 /***
541 *
542 * @return the length of the RHS
543 */
544 public int getLength(){
545 return rightHandSide.length;
546 }
547
548 /***
549 * get the nth elemnt of the RHS
550 * @param index
551 * @return
552 */
553 public int getElementAt(int index){
554 if(index<getLength()){
555 return rightHandSide[index];
556 }
557 return -1;
558 }
559
560 /***
561 *
562 */
563 public String toString(){
564 return representation;
565 }
566 }
567
568
569
570 private static int[] production_01 = {NT_E, TE_PLUS, NT_T};
571 private Production PR_01= new Production(NT_E, production_01, "E -> E + T");
572
573 private static int[] production_02 = {NT_E, TE_MINUS, NT_T};
574 private Production PR_02= new Production(NT_E, production_02, "E -> E - T");
575
576 private static int[] production_03 = {NT_T};
577 private Production PR_03= new Production(NT_E, production_03, "E -> T");
578
579 private static int[] production_04 = {NT_T, TE_MULTI, NT_F};
580 private Production PR_04= new Production(NT_T, production_04, "T -> T * F");
581
582
583
584
585 private static int[] production_05 = {NT_F};
586 private Production PR_05= new Production(NT_T, production_05, "T -> F");
587
588 private static int[] production_06 = {TE_LFPAR, NT_E, TE_RGPAR};
589 private Production PR_06= new Production(NT_F, production_06, "F -> (E)");
590
591 private static int[] production_07 = {NT_U};
592 private Production PR_07= new Production(NT_F, production_07, "F -> U");
593
594 private static int[] production_08 = {NT_N};
595 private Production PR_08= new Production(NT_F, production_08, "F -> N");
596
597 private static int[] production_09 = {NT_N, TE_MULTI, NT_U};
598 private Production PR_09= new Production(NT_F, production_09, "F -> N * U");
599
600 private static int[] production_10 = {TE_NAME};
601 private Production PR_10= new Production(NT_U, production_10, "U -> name");
602
603 private static int[] production_11 = {TE_NAME, TE_POWER, NT_N};
604 private Production PR_11= new Production(NT_U, production_11, "U -> name ^ N");
605
606
607 private static int[] production_12 = {TE_PLUS, TE_NUMBER};
608 private Production PR_12= new Production(NT_N, production_12, "N -> + number");
609
610 private static int[] production_13 = {TE_MINUS, TE_NUMBER};
611 private Production PR_13= new Production(NT_N, production_13, "N -> - number");
612
613 private static int[] production_14 = {TE_NUMBER};
614 private Production PR_14= new Production(NT_N, production_14, "N -> number");
615
616
617 /***
618 * a vector with the production rules for easy access.
619 */
620 private Production[] productions = {
621 PR_01, PR_02, PR_03, PR_04, PR_05, PR_06, PR_07,
622 PR_08, PR_09, PR_10, PR_11, PR_12, PR_13, PR_14
623 };
624
625
626
627 private static int[][] yy_action_table={
628
629 {SH_08, SH_09, -1, SH_04, -1, -1, SH_07, SH_25, -1},
630 {SH_10, SH_11, -1, -1, -1, -1, -1, -1, YY_ACC},
631 {RE_03, RE_03, SH_12, -1, RE_03, -1, -1, -1, RE_03},
632 {RE_05, RE_05, RE_05, -1, RE_05, -1, -1, -1, RE_05},
633 {SH_08, SH_09, -1, SH_04, -1, -1, SH_07, SH_25, -1},
634 {RE_07, RE_07, RE_07, -1, RE_07, -1, -1, -1, RE_07},
635 {RE_08, RE_08, SH_15, -1, RE_08, -1, -1, -1, RE_08},
636 {RE_10, RE_10, RE_10, -1, RE_10, SH_16, -1, -1, RE_10},
637 { -1, -1, -1, -1, -1, -1, -1, SH_17, -1},
638 { -1, -1, -1, -1, -1, -1, -1, SH_18, -1},
639 {SH_08, SH_09, -1, SH_04, -1, -1, SH_07, SH_25, -1},
640 {SH_08, SH_09, -1, SH_04, -1, -1, SH_07, SH_25, -1},
641 {SH_08, SH_09, -1, SH_04, -1, -1, SH_07, SH_25, -1},
642 {SH_10, SH_11, -1, -1, SH_22, -1, -1, -1, -1},
643 {RE_03, RE_03, SH_12, -1, RE_03, -1, -1, -1, RE_03},
644 { -1, -1, -1, -1, -1, -1, SH_07, SH_25, -1},
645 {SH_08, SH_09, -1, -1, -1, -1, -1, SH_25, -1},
646 {RE_12, RE_12, RE_12, -1, -1, -1, -1, -1, RE_12},
647 {RE_13, RE_13, RE_13, -1, -1, -1, -1, -1, RE_13},
648 {RE_01, RE_01, SH_12, -1, RE_01, -1, -1, -1, RE_01},
649 {RE_02, RE_02, SH_12, -1, RE_02, -1, -1, -1, RE_02},
650 {RE_04, RE_04, RE_04, -1, RE_04, -1, -1, -1, RE_04},
651 {RE_06, RE_06, RE_06, -1, RE_06, -1, -1, -1, RE_06},
652 {RE_09, RE_09, RE_09, -1, RE_09, -1, -1, -1, RE_09},
653 {RE_11, RE_11, RE_11, -1, RE_11, -1, -1, -1, RE_11},
654 {RE_14, RE_14, RE_14, -1, RE_14, -1, -1, -1, RE_14},
655 };
656
657
658 private static int[][] yy_goto_table={
659
660 {ST_01, ST_02, ST_03, ST_06, ST_05},
661 { -1, -1, -1, -1, -1},
662 { -1, -1, -1, -1, -1},
663 { -1, -1, -1, -1, -1},
664 {ST_13, ST_14, ST_03, ST_06, ST_05},
665 { -1, -1, -1, -1, -1},
666 { -1, -1, -1, -1, -1},
667 { -1, -1, -1, -1, -1},
668 { -1, -1, -1, -1, -1},
669 { -1, -1, -1, -1, -1},
670 { -1, ST_19, ST_03, ST_06, ST_05},
671 { -1, ST_20, ST_03, ST_06, ST_05},
672 { -1, -1, ST_21, ST_06, ST_05},
673 { -1, -1, -1, -1, -1},
674 { -1, -1, -1, -1, -1},
675 { -1, -1, -1, -1, ST_23},
676 { -1, -1, -1, ST_24, -1}
677 };
678
679 /***
680 *
681 * @author jafaleon
682 * class to represent a token in the classic meaning.
683 */
684 class LexToken{
685 /*** the text*/
686 private String lexem;
687 /*** the represented symbol.*/
688 private int symbol;
689
690 /***
691 * Constructor with both params.
692 * @param lexem
693 * @param symbol
694 */
695 public LexToken(String lexem, int symbol){
696 this.lexem = lexem;
697 this.symbol = symbol;
698 }
699
700 /***
701 *
702 * @return
703 */
704 public String getLexem(){
705 return lexem;
706 }
707
708 /***
709 *
710 * @return
711 */
712 public int getSymbol(){
713 return symbol;
714 }
715 }
716
717 /***
718 *
719 * @author jafaleon
720 * a class to represents the elemnts of the SLR parsing stack
721 */
722 class StackElement{
723
724 /*** the token*/
725 private LexToken token;
726 /*** the state */
727 private int state;
728
729 /***
730 * constructor with all the elements.
731 * @param token
732 * @param state
733 */
734 public StackElement(LexToken token, int state){
735 this.token = token;
736 this.state = state;
737 }
738
739 /***
740 *
741 * @return the token
742 */
743 public LexToken getToken(){
744 return token;
745 }
746
747 /***
748 *
749 * @return the state of the automaton when the token was pushed into the stack.
750 */
751 public int getState(){
752 return state;
753 }
754 }
755
756 /***
757 * Method to convert from lexems to terminals.
758 * @param lexem
759 * @return
760 */
761 public static int yy_fromLexemToSymbol(int lexem){
762 switch(lexem){
763 case PLUS: return TE_PLUS;
764 case MINUS: return TE_MINUS;
765 case MULTI: return TE_MULTI;
766 case POWER: return TE_POWER;
767
768 case LFPAR: return TE_LFPAR;
769 case RGPAR: return TE_RGPAR;
770 case NUMBER: return TE_NUMBER;
771 case NAME: return TE_NAME;
772 case EOF: return TE_EOF;
773 }
774 return MAX_TE + 1;
775 }
776
777 /***
778 *
779 * @param token
780 * @return
781 */
782 public boolean yy_isTerminal(int token){
783 return ((token>=MIN_TE) && (token<=(MAX_TE)));
784 }
785
786 /***
787 *
788 * @param token
789 * @return
790 */
791 public boolean yy_isNonTerminal(int token){
792 return ((token>=MIN_NT) && (token<=(MAX_NT)));
793 }
794
795 /***
796 *
797 * @param action
798 * @return
799 */
800 public boolean yy_isReduceAction(int action){
801 return ((action>=MIN_RE) && (action<=(MAX_RE)));
802 }
803
804 /***
805 *
806 * @param action
807 * @return
808 */
809 public boolean yy_isShiftAction(int action){
810 return ((action>=MIN_SH) && (action<=(MAX_SH)));
811 }
812
813 public boolean yy_isLegalState(int state){
814 return ((state >= MIN_ST) && (state <= MAX_ST));
815 }
816
817 /***
818 * The string should have been verified before!
819 */
820 public void yy_error(){
821 System.out.println("Internal error parsing expresion .\nPlease report to MirkE");
822 }
823
824
825 /***
826 * method for the shit actions:
827 * a state plus a lexem (=> StackElement) to be pushed into the stack.
828 * @param symbol
829 * @param action
830 * @param posicion
831 * @return
832 */
833 public ParsedString yy_shiftAction(int symbol, int action, ParsedString posicion){
834 yy_state = action - MIN_SH + MIN_ST;
835 StackElement stackElement =
836 new StackElement(new LexToken(posicion.getResultLexem(), symbol), yy_state);
837 yy_stack.push(stackElement);
838 posicion = unpackFromString(posicion);
839 yy_symbol = yy_fromLexemToSymbol(posicion.getSymbolValue());
840 return posicion;
841 }
842
843 /***
844 * method for reduce action, all semantics will go here.
845 * A option is to include a method in each Production to do
846 * the appripiate job wen necessary.
847 *
848 * @param symbol
849 * @param action
850 */
851 public void yy_reduceAction(int symbol, int action){
852 StackElement stackElement;
853 Production production = productions[action - MIN_RE-1];
854 for(int i = production.getLength()-1; i >= 0; i--){
855 stackElement = (StackElement) yy_stack.pop();
856 if(stackElement.getToken().getSymbol()!=
857 production.getElementAt(i)){
858 yy_state = ST_YY_ERROR;
859 return;
860 }
861 }
862 stackElement = (StackElement) yy_stack.peek();
863 yy_state = stackElement.getState();
864 int lhs = production.getLeftHandSide();
865 yy_state = yy_goto_table[yy_state][lhs-MIN_NT];
866 yy_stack.push(new StackElement(new LexToken(production.toString(), lhs), yy_state));
867 }
868
869 /***
870 * Find what is next to do in the parsing process.
871 * @param actualState
872 * @param actualSymbol
873 * @return
874 */
875 public int yy_nextAction(int actualState, int actualSymbol){
876 if(yy_isLegalState(actualState) && yy_isTerminal(actualSymbol)){
877 int localSymbol = actualSymbol - MIN_TE;
878 return yy_action_table[actualState][localSymbol];
879 }
880 return ST_YY_ERROR;
881 }
882
883 /***
884 * Convert to a String each terminal for messaging facilities.
885 * @param terminal
886 * @return
887 */
888 public String yy_fromTerminalToString(int terminal){
889 switch(terminal){
890 case TE_PLUS: return "<+>";
891 case TE_MINUS: return "<->";
892 case TE_MULTI: return "<*>";
893 case TE_POWER: return "<^>";
894
895 case TE_LFPAR: return "<(>";
896 case TE_RGPAR: return "<)>";
897 case TE_NUMBER: return "<a number>";
898 case TE_NAME: return "<unit name>";
899 case TE_EOF: return "<EOF>";
900 }
901 return "< >";
902 }
903
904 /***
905 * When an error has occured get the espected symbols for that state. It's very useful
906 * for giving a precise error message to the user.
907 * @param state
908 * @return
909 */
910 public String yy_getFollowSet(int state){
911 String string = "";
912 int terminal;
913 for(int colIndex = 0; colIndex < (MAX_TE - MIN_TE); colIndex++){
914 terminal = yy_action_table[state][colIndex];
915 if(terminal != ST_YY_ERROR){
916 string = string + yy_fromTerminalToString(colIndex + MIN_TE) +" ";
917 }
918 }
919 return string;
920 }
921
922 /***
923 * Main method of the parser, is here that everything is controlled.
924 * @param posicion
925 */
926 public void yy_parse(ParsedString posicion){
927 yy_stack.push(new StackElement(new LexToken(_ST_TE_EOF, TE_EOF), ST_00));
928
929 yy_state = ST_00;
930 posicion = unpackFromString(posicion);
931 yy_symbol = yy_fromLexemToSymbol(posicion.getSymbolValue());
932
933 while((yy_state!=YY_ACC) &&
934 (yy_state!=ST_YY_ERROR)){
935
936 yy_action = yy_nextAction(yy_state, yy_symbol);
937
938 if(yy_isShiftAction(yy_action)){
939 posicion = yy_shiftAction(yy_symbol, yy_action, posicion);
940 }else if(yy_isReduceAction(yy_action)){
941 yy_reduceAction(yy_symbol, yy_action);
942 }else if (yy_action == YY_ACC){
943 yy_state = YY_ACC;
944 break;
945 }else{
946 yy_state = ST_YY_ERROR;
947 }
948 }
949 if(yy_state==YY_ACC){
950 System.out.println(_ST_PARSE_COMPLETED);
951 }
952 if(yy_state==ST_YY_ERROR){
953 System.out.println(_ST_PARSE_ERROR +
954 "at pos (" + posicion.getCurrentPosition()+
955 ") with text: " + posicion.getResultLexem()+
956 "\nFound: " + yy_fromTerminalToString(yy_fromLexemToSymbol(posicion.getSymbolValue()))+
957 "\nEspected symbols: "+yy_getFollowSet(((StackElement) yy_stack.peek()).getState()));
958 }if(DEBUGING_ON){
959 System.out.println("State of the parser: "+ yy_state +
960 "\nState of the scanner: " + posicion.getSymbolValue()+
961 "\nParsed String: "+ posicion.getParsedString()+
962 "\nSLR stack contents:");
963 StackElement stackElement;
964 int count =0;
965 for(Iterator iterator = yy_stack.iterator(); iterator.hasNext();){
966 stackElement = (StackElement) iterator.next();
967 System.out.println(" => Element " + count++ +" state: " + stackElement.getState());
968 }
969 int terminal = yy_fromLexemToSymbol(posicion.getSymbolValue());
970
971 System.out.println("Found: " + yy_fromTerminalToString(terminal));
972 System.out.println("\nEspected symbols: "+yy_getFollowSet(((StackElement) yy_stack.peek()).getState()));
973 }
974 }
975
976
977
978
979
980
981
982
983
984
985
986 public Parser(){
987
988 String cadena = " m^(-0.2055)";
989 System.out.println(cadena);
990 ParsedString posicion = new ParsedString(cadena);
991 while(posicion.getSymbolValue()!=EOF){
992 posicion = unpackFromString(posicion);
993 }
994 posicion = new ParsedString(cadena);
995 yy_parse(posicion);
996 }
997
998
999
1000
1001
1002
1003
1004
1005 public static void main(String[] args) {
1006 Parser cadena = new Parser();
1007 }
1008 }