00001 package edu.ksu.cis.bandera.specification.assertion.lexer;
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 import java.io.*;
00039 import java.util.*;
00040 import edu.ksu.cis.bandera.specification.assertion.node.*;
00041
00042 public class Lexer
00043 {
00044 protected Token token;
00045 protected State state = State.INITIAL;
00046
00047 private PushbackReader in;
00048 private int line;
00049 private int pos;
00050 private boolean cr;
00051 private boolean eof;
00052 private final StringBuffer text = new StringBuffer();
00053
00054 private static int[][][][] gotoTable;
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 private static int[][] accept;
00128
00129
00130
00131
00132
00133
00134 public static class State
00135 {
00136 public final static State INITIAL = new State(0);
00137
00138 private int id;
00139
00140 private State(int id)
00141 {
00142 this.id = id;
00143 }
00144
00145 public int id()
00146 {
00147 return id;
00148 }
00149 }
00150 public Lexer(PushbackReader in)
00151 {
00152 this.in = in;
00153
00154 if(gotoTable == null)
00155 {
00156 try
00157 {
00158 DataInputStream s = new DataInputStream(
00159 new BufferedInputStream(
00160 Lexer.class.getResourceAsStream("lexer.dat")));
00161
00162
00163 int length = s.readInt();
00164 gotoTable = new int[length][][][];
00165 for(int i = 0; i < gotoTable.length; i++)
00166 {
00167 length = s.readInt();
00168 gotoTable[i] = new int[length][][];
00169 for(int j = 0; j < gotoTable[i].length; j++)
00170 {
00171 length = s.readInt();
00172 gotoTable[i][j] = new int[length][3];
00173 for(int k = 0; k < gotoTable[i][j].length; k++)
00174 {
00175 for(int l = 0; l < 3; l++)
00176 {
00177 gotoTable[i][j][k][l] = s.readInt();
00178 }
00179 }
00180 }
00181 }
00182
00183
00184 length = s.readInt();
00185 accept = new int[length][];
00186 for(int i = 0; i < accept.length; i++)
00187 {
00188 length = s.readInt();
00189 accept[i] = new int[length];
00190 for(int j = 0; j < accept[i].length; j++)
00191 {
00192 accept[i][j] = s.readInt();
00193 }
00194 }
00195
00196 s.close();
00197 }
00198 catch(Exception e)
00199 {
00200 throw new RuntimeException("Unable to read lexer.dat.");
00201 }
00202 }
00203 }
00204 protected void filter() throws LexerException, IOException
00205 {
00206 }
00207 private int getChar() throws IOException
00208 {
00209 if(eof)
00210 {
00211 return -1;
00212 }
00213
00214 int result = in.read();
00215
00216 if(result == -1)
00217 {
00218 eof = true;
00219 }
00220
00221 return result;
00222 }
00223 private String getText(int acceptLength)
00224 {
00225 StringBuffer s = new StringBuffer(acceptLength);
00226 for(int i = 0; i < acceptLength; i++)
00227 {
00228 s.append(text.charAt(i));
00229 }
00230
00231 return s.toString();
00232 }
00233 protected Token getToken() throws IOException, LexerException
00234 {
00235 int dfa_state = 0;
00236
00237 int start_pos = pos;
00238 int start_line = line;
00239
00240 int accept_state = -1;
00241 int accept_token = -1;
00242 int accept_length = -1;
00243 int accept_pos = -1;
00244 int accept_line = -1;
00245
00246 int[][][] gotoTable = this.gotoTable[state.id()];
00247 int[] accept = this.accept[state.id()];
00248 text.setLength(0);
00249
00250 while(true)
00251 {
00252 int c = getChar();
00253
00254 if(c != -1)
00255 {
00256 switch(c)
00257 {
00258 case 10:
00259 if(cr)
00260 {
00261 cr = false;
00262 }
00263 else
00264 {
00265 line++;
00266 pos = 0;
00267 }
00268 break;
00269 case 13:
00270 line++;
00271 pos = 0;
00272 cr = true;
00273 break;
00274 default:
00275 pos++;
00276 cr = false;
00277 break;
00278 };
00279
00280 text.append((char) c);
00281
00282 do
00283 {
00284 int oldState = (dfa_state < -1) ? (-2 -dfa_state) : dfa_state;
00285
00286 dfa_state = -1;
00287
00288 int[][] tmp1 = gotoTable[oldState];
00289 int low = 0;
00290 int high = tmp1.length - 1;
00291
00292 while(low <= high)
00293 {
00294 int middle = (low + high) / 2;
00295 int[] tmp2 = tmp1[middle];
00296
00297 if(c < tmp2[0])
00298 {
00299 high = middle - 1;
00300 }
00301 else if(c > tmp2[1])
00302 {
00303 low = middle + 1;
00304 }
00305 else
00306 {
00307 dfa_state = tmp2[2];
00308 break;
00309 }
00310 }
00311 }while(dfa_state < -1);
00312 }
00313 else
00314 {
00315 dfa_state = -1;
00316 }
00317
00318 if(dfa_state >= 0)
00319 {
00320 if(accept[dfa_state] != -1)
00321 {
00322 accept_state = dfa_state;
00323 accept_token = accept[dfa_state];
00324 accept_length = text.length();
00325 accept_pos = pos;
00326 accept_line = line;
00327 }
00328 }
00329 else
00330 {
00331 if(accept_state != -1)
00332 {
00333 switch(accept_token)
00334 {
00335 case 0:
00336 {
00337 Token token = new0(
00338 getText(accept_length),
00339 start_line + 1,
00340 start_pos + 1);
00341 pushBack(accept_length);
00342 pos = accept_pos;
00343 line = accept_line;
00344 return token;
00345 }
00346 case 1:
00347 {
00348 Token token = new1(
00349 getText(accept_length),
00350 start_line + 1,
00351 start_pos + 1);
00352 pushBack(accept_length);
00353 pos = accept_pos;
00354 line = accept_line;
00355 return token;
00356 }
00357 case 2:
00358 {
00359 Token token = new2(
00360 getText(accept_length),
00361 start_line + 1,
00362 start_pos + 1);
00363 pushBack(accept_length);
00364 pos = accept_pos;
00365 line = accept_line;
00366 return token;
00367 }
00368 case 3:
00369 {
00370 Token token = new3(
00371 getText(accept_length),
00372 start_line + 1,
00373 start_pos + 1);
00374 pushBack(accept_length);
00375 pos = accept_pos;
00376 line = accept_line;
00377 return token;
00378 }
00379 case 4:
00380 {
00381 Token token = new4(
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 5:
00390 {
00391 Token token = new5(
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 6:
00400 {
00401 Token token = new6(
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 7:
00410 {
00411 Token token = new7(
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 8:
00420 {
00421 Token token = new8(
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 9:
00430 {
00431 Token token = new9(
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 10:
00440 {
00441 Token token = new10(
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 11:
00450 {
00451 Token token = new11(
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 12:
00460 {
00461 Token token = new12(
00462 getText(accept_length),
00463 start_line + 1,
00464 start_pos + 1);
00465 pushBack(accept_length);
00466 pos = accept_pos;
00467 line = accept_line;
00468 return token;
00469 }
00470 }
00471 }
00472 else
00473 {
00474 if(text.length() > 0)
00475 {
00476 throw new LexerException(
00477 "[" + (start_line + 1) + "," + (start_pos + 1) + "]" +
00478 " Unknown token: " + text);
00479 }
00480 else
00481 {
00482 EOF token = new EOF(
00483 start_line + 1,
00484 start_pos + 1);
00485 return token;
00486 }
00487 }
00488 }
00489 }
00490 }
00491 Token new0(String text, int line, int pos) { return new TWhiteSpace(text, line, pos); }
00492 Token new1(String text, int line, int pos) { return new TTraditionalComment(text, line, pos); }
00493 Token new10(int line, int pos) { return new TPost(line, pos); }
00494 Token new11(int line, int pos) { return new TLocation(line, pos); }
00495 Token new12(String text, int line, int pos) { return new TId(text, line, pos); }
00496 Token new2(String text, int line, int pos) { return new TDocumentationComment(text, line, pos); }
00497 Token new3(String text, int line, int pos) { return new TEndOfLineComment(text, line, pos); }
00498 Token new4(int line, int pos) { return new TLBracket(line, pos); }
00499 Token new5(int line, int pos) { return new TRBracket(line, pos); }
00500 Token new6(int line, int pos) { return new TColon(line, pos); }
00501 Token new7(int line, int pos) { return new TSemicolon(line, pos); }
00502 Token new8(int line, int pos) { return new TDot(line, pos); }
00503 Token new9(int line, int pos) { return new TPre(line, pos); }
00504 public Token next() throws LexerException, IOException
00505 {
00506 while(token == null)
00507 {
00508 token = getToken();
00509 filter();
00510 }
00511
00512 Token result = token;
00513 token = null;
00514 return result;
00515 }
00516 public Token peek() throws LexerException, IOException
00517 {
00518 while(token == null)
00519 {
00520 token = getToken();
00521 filter();
00522 }
00523
00524 return token;
00525 }
00526 private void pushBack(int acceptLength) throws IOException
00527 {
00528 int length = text.length();
00529 for(int i = length - 1; i >= acceptLength; i--)
00530 {
00531 eof = false;
00532
00533 in.unread(text.charAt(i));
00534 }
00535 }
00536 protected void unread(Token token) throws IOException
00537 {
00538 String text = token.getText();
00539 int length = text.length();
00540
00541 for(int i = length - 1; i >= 0; i--)
00542 {
00543 eof = false;
00544
00545 in.unread(text.charAt(i));
00546 }
00547
00548 pos = token.getPos() - 1;
00549 line = token.getLine() - 1;
00550 }
00551 }