1 package fri.patterns.interpreter.parsergenerator; 2 3 import java.util.*; 4 import java.io.*; 5 import fri.patterns.interpreter.parsergenerator.syntax.Rule; 6 7 28 29 public class Parser implements Serializable 30 { 31 private Lexer lexer; 32 private ParserTables tables; 33 private transient Semantic semantic; 34 protected Stack stateStack = new Stack(); 35 protected Stack valueStack = new Stack(); 36 protected Stack rangeStack = new Stack(); 37 private transient Object result; 38 private transient List inputTokens; 39 private transient List rangeList; 40 private transient Token.Range range = new Token.Range(null, null); 41 private transient PrintStream out; 42 private boolean passExpectedToLexer = true; 43 private boolean DEBUG; 45 46 47 51 public Parser(ParserTables tables) { 52 this.tables = tables; 53 } 54 55 56 57 public Object getResult() { 58 return result; 59 } 60 61 66 70 public void setLexer(Lexer lexer) { 71 boolean initLexer = (this.lexer != lexer); this.lexer = lexer; 73 clear(); if (initLexer) 75 lexer.setTerminals(getParserTables().getTerminals()); } 77 78 79 public Lexer getLexer() { 80 return lexer; 81 } 82 83 84 public void setInput(Object input) 85 throws IOException 86 { 87 if (lexer == null) 88 throw new IllegalStateException ("Can not set input when no lexer was defined!"); 89 clear(); lexer.setInput(input); 91 } 92 93 94 public void setSemantic(Semantic semantic) { 95 this.semantic = semantic; 96 } 97 98 99 public Semantic getSemantic() { 100 return semantic; 101 } 102 103 104 public ParserTables getParserTables() { 105 return tables; 106 } 107 108 109 public void setPassExpectedToLexer(boolean passExpectedToLexer) { 110 this.passExpectedToLexer = passExpectedToLexer; 111 } 112 113 114 115 117 private Integer top() { 118 return (Integer ) stateStack.peek(); 119 } 120 121 private void push(Integer state, Object result, Token.Range range) { 122 stateStack.push(state); 123 semanticPush(result, range); 124 } 125 126 private void pop(int pops) { 127 inputTokens = new ArrayList(); 128 rangeList = new ArrayList(); 129 130 for (int i = 0; i < pops; i++) { 131 stateStack.pop(); 132 semanticPop(i, pops); 133 } 134 } 135 136 private void semanticPush(Object result, Token.Range range) { 137 if (semantic != null) { valueStack.push(result); rangeStack.push(range); } 141 } 142 143 private void semanticPop(int popIndex, int countOfPops) { 144 if (semantic != null) { 145 inputTokens.add(0, valueStack.pop()); 147 148 Token.Range currentRange = (Token.Range) rangeStack.pop(); 150 rangeList.add(0, currentRange); 151 152 if (popIndex == 0) this.range = new Token.Range(null, currentRange.end); 155 if (popIndex == countOfPops - 1) this.range = new Token.Range(currentRange.start, this.range.end); 157 } 158 } 159 160 165 protected void reduce(Integer ruleIndex) { 166 if (DEBUG) 167 dump("reduce "+ruleIndex); 168 169 Rule rule = getParserTables().getSyntax().getRule(ruleIndex.intValue()); 170 pop(rule.rightSize()); 172 semanticReduce(rule); 173 174 String nonterminal = rule.getNonterminal(); 175 push(getParserTables().getGotoState(top(), nonterminal), result, range); 176 177 dumpStack(); 178 } 179 180 private void semanticReduce(Rule rule) { 181 if (semantic != null) { 182 result = semantic.doSemantic(rule, inputTokens, rangeList); 183 } 184 } 185 186 190 protected Token shift(Token token) 191 throws IOException 192 { 193 if (DEBUG) 194 dump("shift from token symbol >"+token.symbol+"<"); 195 196 push(getParserTables().getGotoState(top(), token.symbol), token.text, token.range); 197 dumpStack(); 198 199 Token newToken = getNextToken(); 200 if (DEBUG) 201 dump("next token "+newToken.symbol+" >"+newToken.text+"<"); 202 203 return newToken; 204 } 205 206 207 protected Token getNextToken() 208 throws IOException 209 { 210 Map expected = passExpectedToLexer && top().intValue() >= 0 ? getParserTables().getExpected(top()) : null; 211 Token token = lexer.getNextToken(expected); 212 return token; 213 } 214 215 216 218 223 public boolean parse(Lexer lexer) 224 throws IOException 225 { 226 setLexer(lexer); 227 return parse(); 228 } 229 230 236 public boolean parse(Semantic semantic) 237 throws IOException 238 { 239 if (lexer == null) 240 throw new IllegalStateException ("No lexer was defined to scan input!"); 241 setSemantic(semantic); 242 return parse(); 243 } 244 245 251 public boolean parse(Object input) 252 throws IOException 253 { 254 setInput(input); 255 return parse(); 256 } 257 258 264 public boolean parse(Lexer lexer, Semantic semantic) 265 throws IOException 266 { 267 setLexer(lexer); 268 setSemantic(semantic); 269 return parse(); 270 } 271 272 278 public boolean parse(Object input, Semantic semantic) 279 throws IOException 280 { 281 setInput(input); 282 setSemantic(semantic); 283 return parse(); 284 } 285 286 295 public boolean parse() 296 throws IOException 297 { 298 stateStack.push(new Integer (0)); Integer action = ParserTables.SHIFT; Token token = getNextToken(); if (DEBUG) 302 dump("initial token symbol >"+token.symbol+"<, text >"+token.text+"<"); 303 304 while (token.symbol != null && action.equals(ParserTables.ACCEPT) == false && action.equals(ParserTables.ERROR) == false && top().equals(ParserTables.ERROR) == false) { 309 action = getParserTables().getParseAction(top(), token.symbol); 310 311 if (action.intValue() > 0) 312 reduce(action); 313 else 314 if (action.equals(ParserTables.SHIFT)) 315 token = shift(token); 316 317 action = recover(action, token); } 319 320 return detectError(token, top(), action); 321 } 322 323 324 330 protected Integer recover(Integer action, Token token) { 331 return action; 332 } 333 334 335 339 protected boolean detectError(Token token, Integer state, Integer action) { 340 boolean ret = true; 341 342 if (token.symbol == null || action.equals(ParserTables.ERROR)) { 343 if (token.symbol == null) 344 ensureOut().println("ERROR: Unknown symbol: >"+token.text+"<, state "+state); 345 else 346 ensureOut().println("ERROR: Wrong symbol: "+(Token.isEpsilon(token) ? "EOF" : token.symbol+", text: >"+token.text+"<")+", state "+state); 347 348 lexer.dump(out); 349 350 Map h = getParserTables().getExpected(state); 351 if (h != null) { 352 ensureOut().print("Expected was (one of): "); 353 354 for (Iterator it = h.keySet().iterator(); it.hasNext(); ) { 355 String s = (String ) it.next(); 356 ensureOut().print((Token.isEpsilon(s) ? "EOF" : s)+(it.hasNext() ? ", " : "")); 357 } 358 ensureOut().println(); 359 } 360 361 ret = false; 362 } 363 else 364 if (state.equals(ParserTables.ERROR)) { pop(1); 366 ensureOut().println("ERROR: found no possible follow state for "+top()+", text >"+token.text+"<"); 367 lexer.dump(out); 368 ret = false; 369 } 370 else 371 if (Token.isEpsilon(token) == false) { 372 ensureOut().println("ERROR: Input is not finished."); 373 lexer.dump(out); 374 ret = false; 375 } 376 else 377 if (action.equals(ParserTables.ACCEPT) == false) { 378 ensureOut().println("ERROR: Could not achieve ACCEPT. Symbol: "+token.symbol); 379 lexer.dump(out); 380 ret = false; 381 } 382 383 if (ret == false) 384 result = null; 385 386 return ret; 387 } 388 389 390 private void clear() { 391 stateStack.removeAllElements(); 392 valueStack.removeAllElements(); 393 rangeStack.removeAllElements(); 394 range = new Token.Range(null, null); 395 inputTokens = null; 396 result = null; 397 if (lexer != null) 398 lexer.clear(); 399 } 400 401 402 403 private void dumpStack() { 404 if (DEBUG) { 405 ensureOut().print("stack: "); 406 for (int i = 0; i < stateStack.size(); i++) 407 ensureOut().print(stateStack.elementAt(i)+" "); 408 ensureOut().println(); 409 } 410 } 411 412 private void dump(String s) { 413 ensureOut().println(s); 414 } 415 416 private PrintStream ensureOut() { 417 if (out == null) 418 out = System.err; 419 return out; 420 } 421 422 423 public void setPrintStream(PrintStream out) { 424 this.out = (out != null) ? out : System.err; 425 } 426 427 428 public void setDebug(boolean debug) { 429 DEBUG = debug; 430 } 431 432 } 433 | Popular Tags |