View Javadoc
1   /*
2    * Created on 20-fÈvr.-2005
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  	//Just a debbuging control.
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 	//        S  C  A  N  N  E  R   or   L  E  X  E  R         //
176 	//                                                         //
177 	/////////////////////////////////////////////////////////////
178 	
179 	// Scanner constants for the accepted characters.
180 	public static final int PLUS        =  0; // <+>
181 	public static final int MINUS       =  1; // <->
182 	public static final int DIGIT       =  2; // <[0..9]>
183 	public static final int LETTER      =  3; // <[a..zA..Z]>
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; // [E|e]
191 	public static final int WHITE_SPACE = 11;
192 	public static final int ERROR       = 12; //
193 	public static final int NUMBER      = 13; // [+|-]*[0..9]+
194 	public static final int NAME        = 14; // [a..zA..Z]+
195 	public static final int EOF         = 15;
196 	
197 	
198 
199 	// The prefix ST is for the States of the automaton. Still scanner only
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; //Actualise if changed !!
211 	
212 	// The RT prefix if for the acceptation states. Still scanner only
213 	
214 	public static final int RT_ERROR    =  8;
215 	public static final int MIN_RT_STATE=  RT_ERROR; //Actualize if changed !!!
216 	
217 	public static final int RT_NUMBER   =  9;
218 	public static final int MIN_BACK_1_TO_ENTRY = RT_NUMBER; //Actualize if changed !!!
219 	
220 	public static final int RT_NAME     =  10;
221 	public static final int MAX_BACK_1_TO_ENTRY = RT_NAME; //Actualize if changed !!!
222 	
223 	public static final int RT_NUMBER_EXP = 11;
224 	public static final int MIN_BACK_2_TO_ENTRY = RT_NUMBER_EXP; //Actualize if changed !!!
225 	public static final int MAX_BACK_2_TO_ENTRY = RT_NUMBER_EXP; //Actualize if changed !!!
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; //Actualize if changed !!!
236 	
237 	/*
238 	 * The complete matrix for the TA is
239 	 * N is a non terminal
240 	 * S is a State
241 	 *
242 	 * S\N        |    "+"         "-"        digit       letter            "*"            "^"           "/"           "."            "("             ")"            "e"        Whi-Sp          ERROR
243 	 *------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
244 	 * ST_INITIAL |   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
245 	 * ST_NUMBER  |   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
246 	 * ST_NAME    |   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
247 	 * ST_REAL    |   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
248 	 * ST_DOT     |   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
249 	 * ST_EXP     |   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
250 	 * ST_SIG_EXP |   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
251 	 * ST_DOT_REAL|  // IT GOES BACK TO ST_REAL AFTER INSERTING A ZERO IN THE NUMBER BEFORE THE DOT
252 	 * this scanner accepts numbers starting with a . (dot), like .025? the resultLexem will be 0.025.
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 		//I'm sure there is a better way to do this ...
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 	//           T  H  E     P  A  R  S  E  R                  //
379 	//                                                         //
380 	/////////////////////////////////////////////////////////////
381 	
382 	//All the functions will be prefixed with "yy" for the parser
383 	private Stack yy_stack = new Stack();
384 	//private Stack yy_valStack  = new Stack();
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 	//States to GOTO table prefixed with ST
393 	public static final int ST_YY_ERROR  = -1; // The name is too long to be used :(
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; //Actualize if changed !!!
422 	//accept state
423 	public static final int YY_ACC       = 26;
424 	
425 	
426 	//Shift constants prefixed with SH
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;//Actualize if changed !!!
454 	
455 	//Reduce constants prefixed with RE
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; //Actualize if changed !!!
472 	
473 	//Terminal constatns prefixed with TE
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 	//public static final int TE_DIV    = 303; //"/"
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; //Actualize if changed !!!
486 	
487 	public static final String _ST_TE_EOF = "$";
488 	
489 	//Non terminal constatns prefixed with NT
490 	public static final int MIN_NT = 400;
491 	public static final int NT_E   = 400; //E
492 	public static final int NT_T   = 401; //T
493 	public static final int NT_F   = 402; //F
494 	public static final int NT_N   = 403; //P
495 	public static final int NT_U   = 404; //U
496 	public static final int MAX_NT = NT_U; //Actualize if changed !!!
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 	//Production rules PR you know what
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"); //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"); //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"); //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"); //T -> T * F
581 	
582 	//private static int[] production_05 = {NT_T, TE_DIV, NT_F};
583 	//private Production PR_05= new Production(NT_E, production_05, "T -> T / F"); //T -> T / F
584 	
585 	private static int[] production_05 = {NT_F};
586 	private Production PR_05= new Production(NT_T, production_05, "T -> F"); //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)"); //F -> (E)
590 	
591 	private static int[] production_07 = {NT_U};
592 	private Production PR_07= new Production(NT_F, production_07, "F -> U"); //F -> U
593 	
594 	private static int[] production_08 = {NT_N};
595 	private Production PR_08= new Production(NT_F, production_08, "F -> N"); //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"); //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"); //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"); //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"); //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"); //N -> - number
612 	
613 	private static int[] production_14 = {TE_NUMBER};
614 	private Production PR_14= new Production(NT_N, production_14, "N -> number"); //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 		// "+"   "-"     "*"   "("     ")"   "^"  name   number    EOF    
629 		{SH_08, SH_09,    -1, SH_04,    -1,    -1, SH_07, SH_25,     -1}, //ST 0
630 		{SH_10, SH_11,    -1,    -1,    -1,    -1,    -1,    -1, YY_ACC}, //ST 1
631 		{RE_03, RE_03, SH_12,    -1, RE_03,    -1,    -1,    -1,  RE_03}, //ST 2
632 		{RE_05, RE_05, RE_05,    -1, RE_05,    -1,    -1,    -1,  RE_05}, //ST 3
633 		{SH_08, SH_09,    -1, SH_04,    -1,    -1, SH_07, SH_25,     -1}, //ST 4
634 		{RE_07, RE_07, RE_07,    -1, RE_07,    -1,    -1,    -1,  RE_07}, //ST 5
635 		{RE_08, RE_08, SH_15,    -1, RE_08,    -1,    -1,    -1,  RE_08}, //ST 6
636 		{RE_10, RE_10, RE_10,    -1, RE_10, SH_16,    -1,    -1,  RE_10}, //ST 7
637 		{   -1,    -1,    -1,    -1,    -1,    -1,    -1, SH_17,     -1}, //ST 8
638 		{   -1,    -1,    -1,    -1,    -1,    -1,    -1, SH_18,     -1}, //ST 9
639 		{SH_08, SH_09,    -1, SH_04,    -1,    -1, SH_07, SH_25,     -1}, //ST 10
640 		{SH_08, SH_09,    -1, SH_04,    -1,    -1, SH_07, SH_25,     -1}, //ST 11
641 		{SH_08, SH_09,    -1, SH_04,    -1,    -1, SH_07, SH_25,     -1}, //ST 12
642 		{SH_10, SH_11,    -1,    -1, SH_22,    -1,    -1,    -1,     -1}, //ST 13
643 		{RE_03, RE_03, SH_12,    -1, RE_03,    -1,    -1,    -1,  RE_03}, //ST 14
644 		{   -1,    -1,    -1,    -1,    -1,    -1, SH_07, SH_25,     -1}, //ST 15
645 		{SH_08, SH_09,    -1,    -1,    -1,    -1,    -1, SH_25,     -1}, //ST 16
646 		{RE_12, RE_12, RE_12,    -1,    -1,    -1,    -1,    -1,  RE_12}, //ST 17
647 		{RE_13, RE_13, RE_13,    -1,    -1,    -1,    -1,    -1,  RE_13}, //ST 18
648 		{RE_01, RE_01, SH_12,    -1, RE_01,    -1,    -1,    -1,  RE_01}, //ST 19
649 		{RE_02, RE_02, SH_12,    -1, RE_02,    -1,    -1,    -1,  RE_02}, //ST 20
650 		{RE_04, RE_04, RE_04,    -1, RE_04,    -1,    -1,    -1,  RE_04}, //ST 21
651 		{RE_06, RE_06, RE_06,    -1, RE_06,    -1,    -1,    -1,  RE_06}, //ST 22
652 		{RE_09, RE_09, RE_09,    -1, RE_09,    -1,    -1,    -1,  RE_09}, //ST 23
653 		{RE_11, RE_11, RE_11,    -1, RE_11,    -1,    -1,    -1,  RE_11}, //ST 24
654 		{RE_14, RE_14, RE_14,    -1, RE_14,    -1,    -1,    -1,  RE_14}, //ST 25
655 	};
656 	
657 	
658 	private static int[][] yy_goto_table={
659 		//NT_E  NT_T   NT_F   NT_P   NT_U
660 		{ST_01, ST_02, ST_03, ST_06, ST_05}, //ST 0
661 		{   -1,    -1,    -1,    -1,    -1}, //ST 1
662 		{   -1,    -1,    -1,    -1,    -1}, //ST 2
663 		{   -1,    -1,    -1,    -1,    -1}, //ST 3
664 		{ST_13, ST_14, ST_03, ST_06, ST_05}, //ST 4
665 		{   -1,    -1,    -1,    -1,    -1}, //ST 5
666 		{   -1,    -1,    -1,    -1,    -1}, //ST 6
667 		{   -1,    -1,    -1,    -1,    -1}, //ST 7
668 		{   -1,    -1,    -1,    -1,    -1}, //ST 8
669 		{   -1,    -1,    -1,    -1,    -1}, //ST 9
670 		{   -1, ST_19, ST_03, ST_06, ST_05}, //ST 10
671 		{   -1, ST_20, ST_03, ST_06, ST_05}, //ST 11
672 		{   -1,    -1, ST_21, ST_06, ST_05}, //ST 12
673 		{   -1,    -1,    -1,    -1,    -1}, //ST 13
674 		{   -1,    -1,    -1,    -1,    -1}, //ST 14
675 		{   -1,    -1,    -1,    -1, ST_23}, //ST 15
676 		{   -1,    -1,    -1, ST_24,    -1}  //ST 16
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 			//case DIV:   return TE_DIV;    // </>
768 			case LFPAR:   return TE_LFPAR;  // <(>
769 			case RGPAR:   return TE_RGPAR;  // <)>
770 			case NUMBER:  return TE_NUMBER; // [+|-]*[0..9]+
771 			case NAME:    return TE_NAME;   // [a..zA..Z]+
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]; //This table produce states.
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 			//case TE_DIV:     return  "</>";    // </>
895 			case TE_LFPAR:  return "<(>";  // <(>
896 			case TE_RGPAR:  return "<)>";  // <)>
897 			case TE_NUMBER: return "<a number>"; // [+|-]*[0..9]+
898 			case TE_NAME:   return "<unit name>";   // [a..zA..Z]+
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{//there is an error
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 	 * TODO Remove this constructor when coding will be finish.
979 	 * Constructor for prototyping pourposes only.
980 	 * yy_UNIT_IS_IN_EXpresion(a unit)
981 	 * yy_converto(other unit)
982 	 * yy_getunitExpresion(a unit)
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 	 * TODO Remove this when coding will be finish.
1000 	 * Method main for prototyping pourposses only
1001 	 *
1002 	 * @param args
1003 	 *
1004 	 */
1005 	public static void main(String[] args) {
1006 		Parser cadena = new Parser();		
1007 	}	
1008 }