00001 package edu.ksu.cis.bandera.specification.lexer;
00002
00003
00004
00005 import java.io.*;
00006 import java.util.*;
00007 import edu.ksu.cis.bandera.specification.node.*;
00008
00009 public class Lexer
00010 {
00011 protected Token token;
00012 protected State state = State.INITIAL;
00013
00014 private PushbackReader in;
00015 private int line;
00016 private int pos;
00017 private boolean cr;
00018 private boolean eof;
00019 private final StringBuffer text = new StringBuffer();
00020
00021 private static int[][][][] gotoTable;
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137 private static int[][] accept;
00138
00139
00140
00141
00142
00143
00144 public static class State
00145 {
00146 public final static State INITIAL = new State(0);
00147
00148 private int id;
00149
00150 private State(int id)
00151 {
00152 this.id = id;
00153 }
00154
00155 public int id()
00156 {
00157 return id;
00158 }
00159 }
00160 public Lexer(PushbackReader in)
00161 {
00162 this.in = in;
00163
00164 if(gotoTable == null)
00165 {
00166 try
00167 {
00168 DataInputStream s = new DataInputStream(
00169 new BufferedInputStream(
00170 Lexer.class.getResourceAsStream("lexer.dat")));
00171
00172
00173 int length = s.readInt();
00174 gotoTable = new int[length][][][];
00175 for(int i = 0; i < gotoTable.length; i++)
00176 {
00177 length = s.readInt();
00178 gotoTable[i] = new int[length][][];
00179 for(int j = 0; j < gotoTable[i].length; j++)
00180 {
00181 length = s.readInt();
00182 gotoTable[i][j] = new int[length][3];
00183 for(int k = 0; k < gotoTable[i][j].length; k++)
00184 {
00185 for(int l = 0; l < 3; l++)
00186 {
00187 gotoTable[i][j][k][l] = s.readInt();
00188 }
00189 }
00190 }
00191 }
00192
00193
00194 length = s.readInt();
00195 accept = new int[length][];
00196 for(int i = 0; i < accept.length; i++)
00197 {
00198 length = s.readInt();
00199 accept[i] = new int[length];
00200 for(int j = 0; j < accept[i].length; j++)
00201 {
00202 accept[i][j] = s.readInt();
00203 }
00204 }
00205
00206 s.close();
00207 }
00208 catch(Exception e)
00209 {
00210 throw new RuntimeException("The file \"lexer.dat\" is either missing or corrupted.");
00211 }
00212 }
00213 }
00214 protected void filter() throws LexerException, IOException
00215 {
00216 }
00217 private int getChar() throws IOException
00218 {
00219 if(eof)
00220 {
00221 return -1;
00222 }
00223
00224 int result = in.read();
00225
00226 if(result == -1)
00227 {
00228 eof = true;
00229 }
00230
00231 return result;
00232 }
00233 private String getText(int acceptLength)
00234 {
00235 StringBuffer s = new StringBuffer(acceptLength);
00236 for(int i = 0; i < acceptLength; i++)
00237 {
00238 s.append(text.charAt(i));
00239 }
00240
00241 return s.toString();
00242 }
00243 protected Token getToken() throws IOException, LexerException
00244 {
00245 int dfa_state = 0;
00246
00247 int start_pos = pos;
00248 int start_line = line;
00249
00250 int accept_state = -1;
00251 int accept_token = -1;
00252 int accept_length = -1;
00253 int accept_pos = -1;
00254 int accept_line = -1;
00255
00256 int[][][] gotoTable = this.gotoTable[state.id()];
00257 int[] accept = this.accept[state.id()];
00258 text.setLength(0);
00259
00260 while(true)
00261 {
00262 int c = getChar();
00263
00264 if(c != -1)
00265 {
00266 switch(c)
00267 {
00268 case 10:
00269 if(cr)
00270 {
00271 cr = false;
00272 }
00273 else
00274 {
00275 line++;
00276 pos = 0;
00277 }
00278 break;
00279 case 13:
00280 line++;
00281 pos = 0;
00282 cr = true;
00283 break;
00284 default:
00285 pos++;
00286 cr = false;
00287 break;
00288 };
00289
00290 text.append((char) c);
00291
00292 do
00293 {
00294 int oldState = (dfa_state < -1) ? (-2 -dfa_state) : dfa_state;
00295
00296 dfa_state = -1;
00297
00298 int[][] tmp1 = gotoTable[oldState];
00299 int low = 0;
00300 int high = tmp1.length - 1;
00301
00302 while(low <= high)
00303 {
00304 int middle = (low + high) / 2;
00305 int[] tmp2 = tmp1[middle];
00306
00307 if(c < tmp2[0])
00308 {
00309 high = middle - 1;
00310 }
00311 else if(c > tmp2[1])
00312 {
00313 low = middle + 1;
00314 }
00315 else
00316 {
00317 dfa_state = tmp2[2];
00318 break;
00319 }
00320 }
00321 }while(dfa_state < -1);
00322 }
00323 else
00324 {
00325 dfa_state = -1;
00326 }
00327
00328 if(dfa_state >= 0)
00329 {
00330 if(accept[dfa_state] != -1)
00331 {
00332 accept_state = dfa_state;
00333 accept_token = accept[dfa_state];
00334 accept_length = text.length();
00335 accept_pos = pos;
00336 accept_line = line;
00337 }
00338 }
00339 else
00340 {
00341 if(accept_state != -1)
00342 {
00343 switch(accept_token)
00344 {
00345 case 0:
00346 {
00347 Token token = new0(
00348 getText(accept_length),
00349 start_line + 1,
00350 start_pos + 1);
00351 pushBack(accept_length);
00352 pos = accept_pos;
00353 line = accept_line;
00354 return token;
00355 }
00356 case 1:
00357 {
00358 Token token = new1(
00359 getText(accept_length),
00360 start_line + 1,
00361 start_pos + 1);
00362 pushBack(accept_length);
00363 pos = accept_pos;
00364 line = accept_line;
00365 return token;
00366 }
00367 case 2:
00368 {
00369 Token token = new2(
00370 getText(accept_length),
00371 start_line + 1,
00372 start_pos + 1);
00373 pushBack(accept_length);
00374 pos = accept_pos;
00375 line = accept_line;
00376 return token;
00377 }
00378 case 3:
00379 {
00380 Token token = new3(
00381 getText(accept_length),
00382 start_line + 1,
00383 start_pos + 1);
00384 pushBack(accept_length);
00385 pos = accept_pos;
00386 line = accept_line;
00387 return token;
00388 }
00389 case 4:
00390 {
00391 Token token = new4(
00392 start_line + 1,
00393 start_pos + 1);
00394 pushBack(accept_length);
00395 pos = accept_pos;
00396 line = accept_line;
00397 return token;
00398 }
00399 case 5:
00400 {
00401 Token token = new5(
00402 start_line + 1,
00403 start_pos + 1);
00404 pushBack(accept_length);
00405 pos = accept_pos;
00406 line = accept_line;
00407 return token;
00408 }
00409 case 6:
00410 {
00411 Token token = new6(
00412 start_line + 1,
00413 start_pos + 1);
00414 pushBack(accept_length);
00415 pos = accept_pos;
00416 line = accept_line;
00417 return token;
00418 }
00419 case 7:
00420 {
00421 Token token = new7(
00422 start_line + 1,
00423 start_pos + 1);
00424 pushBack(accept_length);
00425 pos = accept_pos;
00426 line = accept_line;
00427 return token;
00428 }
00429 case 8:
00430 {
00431 Token token = new8(
00432 start_line + 1,
00433 start_pos + 1);
00434 pushBack(accept_length);
00435 pos = accept_pos;
00436 line = accept_line;
00437 return token;
00438 }
00439 case 9:
00440 {
00441 Token token = new9(
00442 start_line + 1,
00443 start_pos + 1);
00444 pushBack(accept_length);
00445 pos = accept_pos;
00446 line = accept_line;
00447 return token;
00448 }
00449 case 10:
00450 {
00451 Token token = new10(
00452 start_line + 1,
00453 start_pos + 1);
00454 pushBack(accept_length);
00455 pos = accept_pos;
00456 line = accept_line;
00457 return token;
00458 }
00459 case 11:
00460 {
00461 Token token = new11(
00462 start_line + 1,
00463 start_pos + 1);
00464 pushBack(accept_length);
00465 pos = accept_pos;
00466 line = accept_line;
00467 return token;
00468 }
00469 case 12:
00470 {
00471 Token token = new12(
00472 start_line + 1,
00473 start_pos + 1);
00474 pushBack(accept_length);
00475 pos = accept_pos;
00476 line = accept_line;
00477 return token;
00478 }
00479 case 13:
00480 {
00481 Token token = new13(
00482 start_line + 1,
00483 start_pos + 1);
00484 pushBack(accept_length);
00485 pos = accept_pos;
00486 line = accept_line;
00487 return token;
00488 }
00489 case 14:
00490 {
00491 Token token = new14(
00492 start_line + 1,
00493 start_pos + 1);
00494 pushBack(accept_length);
00495 pos = accept_pos;
00496 line = accept_line;
00497 return token;
00498 }
00499 case 15:
00500 {
00501 Token token = new15(
00502 start_line + 1,
00503 start_pos + 1);
00504 pushBack(accept_length);
00505 pos = accept_pos;
00506 line = accept_line;
00507 return token;
00508 }
00509 case 16:
00510 {
00511 Token token = new16(
00512 start_line + 1,
00513 start_pos + 1);
00514 pushBack(accept_length);
00515 pos = accept_pos;
00516 line = accept_line;
00517 return token;
00518 }
00519 case 17:
00520 {
00521 Token token = new17(
00522 start_line + 1,
00523 start_pos + 1);
00524 pushBack(accept_length);
00525 pos = accept_pos;
00526 line = accept_line;
00527 return token;
00528 }
00529 case 18:
00530 {
00531 Token token = new18(
00532 start_line + 1,
00533 start_pos + 1);
00534 pushBack(accept_length);
00535 pos = accept_pos;
00536 line = accept_line;
00537 return token;
00538 }
00539 case 19:
00540 {
00541 Token token = new19(
00542 start_line + 1,
00543 start_pos + 1);
00544 pushBack(accept_length);
00545 pos = accept_pos;
00546 line = accept_line;
00547 return token;
00548 }
00549 case 20:
00550 {
00551 Token token = new20(
00552 start_line + 1,
00553 start_pos + 1);
00554 pushBack(accept_length);
00555 pos = accept_pos;
00556 line = accept_line;
00557 return token;
00558 }
00559 case 21:
00560 {
00561 Token token = new21(
00562 start_line + 1,
00563 start_pos + 1);
00564 pushBack(accept_length);
00565 pos = accept_pos;
00566 line = accept_line;
00567 return token;
00568 }
00569 case 22:
00570 {
00571 Token token = new22(
00572 start_line + 1,
00573 start_pos + 1);
00574 pushBack(accept_length);
00575 pos = accept_pos;
00576 line = accept_line;
00577 return token;
00578 }
00579 case 23:
00580 {
00581 Token token = new23(
00582 start_line + 1,
00583 start_pos + 1);
00584 pushBack(accept_length);
00585 pos = accept_pos;
00586 line = accept_line;
00587 return token;
00588 }
00589 case 24:
00590 {
00591 Token token = new24(
00592 start_line + 1,
00593 start_pos + 1);
00594 pushBack(accept_length);
00595 pos = accept_pos;
00596 line = accept_line;
00597 return token;
00598 }
00599 case 25:
00600 {
00601 Token token = new25(
00602 start_line + 1,
00603 start_pos + 1);
00604 pushBack(accept_length);
00605 pos = accept_pos;
00606 line = accept_line;
00607 return token;
00608 }
00609 case 26:
00610 {
00611 Token token = new26(
00612 start_line + 1,
00613 start_pos + 1);
00614 pushBack(accept_length);
00615 pos = accept_pos;
00616 line = accept_line;
00617 return token;
00618 }
00619 case 27:
00620 {
00621 Token token = new27(
00622 start_line + 1,
00623 start_pos + 1);
00624 pushBack(accept_length);
00625 pos = accept_pos;
00626 line = accept_line;
00627 return token;
00628 }
00629 case 28:
00630 {
00631 Token token = new28(
00632 start_line + 1,
00633 start_pos + 1);
00634 pushBack(accept_length);
00635 pos = accept_pos;
00636 line = accept_line;
00637 return token;
00638 }
00639 case 29:
00640 {
00641 Token token = new29(
00642 start_line + 1,
00643 start_pos + 1);
00644 pushBack(accept_length);
00645 pos = accept_pos;
00646 line = accept_line;
00647 return token;
00648 }
00649 case 30:
00650 {
00651 Token token = new30(
00652 start_line + 1,
00653 start_pos + 1);
00654 pushBack(accept_length);
00655 pos = accept_pos;
00656 line = accept_line;
00657 return token;
00658 }
00659 case 31:
00660 {
00661 Token token = new31(
00662 start_line + 1,
00663 start_pos + 1);
00664 pushBack(accept_length);
00665 pos = accept_pos;
00666 line = accept_line;
00667 return token;
00668 }
00669 case 32:
00670 {
00671 Token token = new32(
00672 getText(accept_length),
00673 start_line + 1,
00674 start_pos + 1);
00675 pushBack(accept_length);
00676 pos = accept_pos;
00677 line = accept_line;
00678 return token;
00679 }
00680 case 33:
00681 {
00682 Token token = new33(
00683 getText(accept_length),
00684 start_line + 1,
00685 start_pos + 1);
00686 pushBack(accept_length);
00687 pos = accept_pos;
00688 line = accept_line;
00689 return token;
00690 }
00691 }
00692 }
00693 else
00694 {
00695 if(text.length() > 0)
00696 {
00697 throw new LexerException(
00698 "[" + (start_line + 1) + "," + (start_pos + 1) + "]" +
00699 " Unknown token: " + text);
00700 }
00701 else
00702 {
00703 EOF token = new EOF(
00704 start_line + 1,
00705 start_pos + 1);
00706 return token;
00707 }
00708 }
00709 }
00710 }
00711 }
00712 Token new0(String text, int line, int pos) { return new TWhiteSpace(text, line, pos); }
00713 Token new1(String text, int line, int pos) { return new TDocumentationComment(text, line, pos); }
00714 Token new10(int line, int pos) { return new TOr(line, pos); }
00715 Token new11(int line, int pos) { return new TNot(line, pos); }
00716 Token new12(int line, int pos) { return new TDot(line, pos); }
00717 Token new13(int line, int pos) { return new TColon(line, pos); }
00718 Token new14(int line, int pos) { return new TSemicolon(line, pos); }
00719 Token new15(int line, int pos) { return new TLBracket(line, pos); }
00720 Token new16(int line, int pos) { return new TRBracket(line, pos); }
00721 Token new17(int line, int pos) { return new TLBrace(line, pos); }
00722 Token new18(int line, int pos) { return new TRBrace(line, pos); }
00723 Token new19(int line, int pos) { return new TLParen(line, pos); }
00724 Token new2(String text, int line, int pos) { return new TTraditionalComment(text, line, pos); }
00725 Token new20(int line, int pos) { return new TRParen(line, pos); }
00726 Token new21(int line, int pos) { return new TComma(line, pos); }
00727 Token new22(int line, int pos) { return new TDoubleQuote(line, pos); }
00728 Token new23(int line, int pos) { return new TStar(line, pos); }
00729 Token new24(int line, int pos) { return new TPlus(line, pos); }
00730 Token new25(int line, int pos) { return new TMinus(line, pos); }
00731 Token new26(int line, int pos) { return new TImport(line, pos); }
00732 Token new27(int line, int pos) { return new TEnable(line, pos); }
00733 Token new28(int line, int pos) { return new TAssertions(line, pos); }
00734 Token new29(int line, int pos) { return new TForall(line, pos); }
00735 Token new3(String text, int line, int pos) { return new TEndOfLineComment(text, line, pos); }
00736 Token new30(int line, int pos) { return new TPredicate(line, pos); }
00737 Token new31(int line, int pos) { return new TAssertion(line, pos); }
00738 Token new32(String text, int line, int pos) { return new TNumber(text, line, pos); }
00739 Token new33(String text, int line, int pos) { return new TId(text, line, pos); }
00740 Token new4(int line, int pos) { return new TLess(line, pos); }
00741 Token new5(int line, int pos) { return new TLessEqual(line, pos); }
00742 Token new6(int line, int pos) { return new TInstance(line, pos); }
00743 Token new7(int line, int pos) { return new TGreater(line, pos); }
00744 Token new8(int line, int pos) { return new TImply(line, pos); }
00745 Token new9(int line, int pos) { return new TAnd(line, pos); }
00746 public Token next() throws LexerException, IOException
00747 {
00748 while(token == null)
00749 {
00750 token = getToken();
00751 filter();
00752 }
00753
00754 Token result = token;
00755 token = null;
00756 return result;
00757 }
00758 public Token peek() throws LexerException, IOException
00759 {
00760 while(token == null)
00761 {
00762 token = getToken();
00763 filter();
00764 }
00765
00766 return token;
00767 }
00768 private void pushBack(int acceptLength) throws IOException
00769 {
00770 int length = text.length();
00771 for(int i = length - 1; i >= acceptLength; i--)
00772 {
00773 eof = false;
00774
00775 in.unread(text.charAt(i));
00776 }
00777 }
00778 protected void unread(Token token) throws IOException
00779 {
00780 String text = token.getText();
00781 int length = text.length();
00782
00783 for(int i = length - 1; i >= 0; i--)
00784 {
00785 eof = false;
00786
00787 in.unread(text.charAt(i));
00788 }
00789
00790 pos = token.getPos() - 1;
00791 line = token.getLine() - 1;
00792 }
00793 }