00001 package edu.ksu.cis.bandera.bui.session.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.bui.session.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 private static int[][] accept;
00103
00104
00105
00106
00107
00108
00109 public static class State
00110 {
00111 public final static State INITIAL = new State(0);
00112
00113 private int id;
00114
00115 private State(int id)
00116 {
00117 this.id = id;
00118 }
00119
00120 public int id()
00121 {
00122 return id;
00123 }
00124 }
00125 public Lexer(PushbackReader in)
00126 {
00127 this.in = in;
00128
00129 if(gotoTable == null)
00130 {
00131 try
00132 {
00133 DataInputStream s = new DataInputStream(
00134 new BufferedInputStream(
00135 Lexer.class.getResourceAsStream("lexer.dat")));
00136
00137
00138 int length = s.readInt();
00139 gotoTable = new int[length][][][];
00140 for(int i = 0; i < gotoTable.length; i++)
00141 {
00142 length = s.readInt();
00143 gotoTable[i] = new int[length][][];
00144 for(int j = 0; j < gotoTable[i].length; j++)
00145 {
00146 length = s.readInt();
00147 gotoTable[i][j] = new int[length][3];
00148 for(int k = 0; k < gotoTable[i][j].length; k++)
00149 {
00150 for(int l = 0; l < 3; l++)
00151 {
00152 gotoTable[i][j][k][l] = s.readInt();
00153 }
00154 }
00155 }
00156 }
00157
00158
00159 length = s.readInt();
00160 accept = new int[length][];
00161 for(int i = 0; i < accept.length; i++)
00162 {
00163 length = s.readInt();
00164 accept[i] = new int[length];
00165 for(int j = 0; j < accept[i].length; j++)
00166 {
00167 accept[i][j] = s.readInt();
00168 }
00169 }
00170
00171 s.close();
00172 }
00173 catch(Exception e)
00174 {
00175 throw new RuntimeException("Unable to read lexer.dat.");
00176 }
00177 }
00178 }
00179 protected void filter() throws LexerException, IOException
00180 {
00181 }
00182 private int getChar() throws IOException
00183 {
00184 if(eof)
00185 {
00186 return -1;
00187 }
00188
00189 int result = in.read();
00190
00191 if(result == -1)
00192 {
00193 eof = true;
00194 }
00195
00196 return result;
00197 }
00198 private String getText(int acceptLength)
00199 {
00200 StringBuffer s = new StringBuffer(acceptLength);
00201 for(int i = 0; i < acceptLength; i++)
00202 {
00203 s.append(text.charAt(i));
00204 }
00205
00206 return s.toString();
00207 }
00208 protected Token getToken() throws IOException, LexerException
00209 {
00210 int dfa_state = 0;
00211
00212 int start_pos = pos;
00213 int start_line = line;
00214
00215 int accept_state = -1;
00216 int accept_token = -1;
00217 int accept_length = -1;
00218 int accept_pos = -1;
00219 int accept_line = -1;
00220
00221 int[][][] gotoTable = this.gotoTable[state.id()];
00222 int[] accept = this.accept[state.id()];
00223 text.setLength(0);
00224
00225 while(true)
00226 {
00227 int c = getChar();
00228
00229 if(c != -1)
00230 {
00231 switch(c)
00232 {
00233 case 10:
00234 if(cr)
00235 {
00236 cr = false;
00237 }
00238 else
00239 {
00240 line++;
00241 pos = 0;
00242 }
00243 break;
00244 case 13:
00245 line++;
00246 pos = 0;
00247 cr = true;
00248 break;
00249 default:
00250 pos++;
00251 cr = false;
00252 break;
00253 };
00254
00255 text.append((char) c);
00256
00257 do
00258 {
00259 int oldState = (dfa_state < -1) ? (-2 -dfa_state) : dfa_state;
00260
00261 dfa_state = -1;
00262
00263 int[][] tmp1 = gotoTable[oldState];
00264 int low = 0;
00265 int high = tmp1.length - 1;
00266
00267 while(low <= high)
00268 {
00269 int middle = (low + high) / 2;
00270 int[] tmp2 = tmp1[middle];
00271
00272 if(c < tmp2[0])
00273 {
00274 high = middle - 1;
00275 }
00276 else if(c > tmp2[1])
00277 {
00278 low = middle + 1;
00279 }
00280 else
00281 {
00282 dfa_state = tmp2[2];
00283 break;
00284 }
00285 }
00286 }while(dfa_state < -1);
00287 }
00288 else
00289 {
00290 dfa_state = -1;
00291 }
00292
00293 if(dfa_state >= 0)
00294 {
00295 if(accept[dfa_state] != -1)
00296 {
00297 accept_state = dfa_state;
00298 accept_token = accept[dfa_state];
00299 accept_length = text.length();
00300 accept_pos = pos;
00301 accept_line = line;
00302 }
00303 }
00304 else
00305 {
00306 if(accept_state != -1)
00307 {
00308 switch(accept_token)
00309 {
00310 case 0:
00311 {
00312 Token token = new0(
00313 getText(accept_length),
00314 start_line + 1,
00315 start_pos + 1);
00316 pushBack(accept_length);
00317 pos = accept_pos;
00318 line = accept_line;
00319 return token;
00320 }
00321 case 1:
00322 {
00323 Token token = new1(
00324 start_line + 1,
00325 start_pos + 1);
00326 pushBack(accept_length);
00327 pos = accept_pos;
00328 line = accept_line;
00329 return token;
00330 }
00331 case 2:
00332 {
00333 Token token = new2(
00334 start_line + 1,
00335 start_pos + 1);
00336 pushBack(accept_length);
00337 pos = accept_pos;
00338 line = accept_line;
00339 return token;
00340 }
00341 case 3:
00342 {
00343 Token token = new3(
00344 start_line + 1,
00345 start_pos + 1);
00346 pushBack(accept_length);
00347 pos = accept_pos;
00348 line = accept_line;
00349 return token;
00350 }
00351 case 4:
00352 {
00353 Token token = new4(
00354 start_line + 1,
00355 start_pos + 1);
00356 pushBack(accept_length);
00357 pos = accept_pos;
00358 line = accept_line;
00359 return token;
00360 }
00361 case 5:
00362 {
00363 Token token = new5(
00364 start_line + 1,
00365 start_pos + 1);
00366 pushBack(accept_length);
00367 pos = accept_pos;
00368 line = accept_line;
00369 return token;
00370 }
00371 case 6:
00372 {
00373 Token token = new6(
00374 getText(accept_length),
00375 start_line + 1,
00376 start_pos + 1);
00377 pushBack(accept_length);
00378 pos = accept_pos;
00379 line = accept_line;
00380 return token;
00381 }
00382 case 7:
00383 {
00384 Token token = new7(
00385 getText(accept_length),
00386 start_line + 1,
00387 start_pos + 1);
00388 pushBack(accept_length);
00389 pos = accept_pos;
00390 line = accept_line;
00391 return token;
00392 }
00393 }
00394 }
00395 else
00396 {
00397 if(text.length() > 0)
00398 {
00399 throw new LexerException(
00400 "[" + (start_line + 1) + "," + (start_pos + 1) + "]" +
00401 " Unknown token: " + text);
00402 }
00403 else
00404 {
00405 EOF token = new EOF(
00406 start_line + 1,
00407 start_pos + 1);
00408 return token;
00409 }
00410 }
00411 }
00412 }
00413 }
00414 Token new0(String text, int line, int pos) { return new TWhiteSpace(text, line, pos); }
00415 Token new1(int line, int pos) { return new TLBrace(line, pos); }
00416 Token new2(int line, int pos) { return new TRBrace(line, pos); }
00417 Token new3(int line, int pos) { return new TPlus(line, pos); }
00418 Token new4(int line, int pos) { return new TEqual(line, pos); }
00419 Token new5(int line, int pos) { return new TSession(line, pos); }
00420 Token new6(String text, int line, int pos) { return new TStringLiteral(text, line, pos); }
00421 Token new7(String text, int line, int pos) { return new TId(text, line, pos); }
00422 public Token next() throws LexerException, IOException
00423 {
00424 while(token == null)
00425 {
00426 token = getToken();
00427 filter();
00428 }
00429
00430 Token result = token;
00431 token = null;
00432 return result;
00433 }
00434 public Token peek() throws LexerException, IOException
00435 {
00436 while(token == null)
00437 {
00438 token = getToken();
00439 filter();
00440 }
00441
00442 return token;
00443 }
00444 private void pushBack(int acceptLength) throws IOException
00445 {
00446 int length = text.length();
00447 for(int i = length - 1; i >= acceptLength; i--)
00448 {
00449 eof = false;
00450
00451 in.unread(text.charAt(i));
00452 }
00453 }
00454 protected void unread(Token token) throws IOException
00455 {
00456 String text = token.getText();
00457 int length = text.length();
00458
00459 for(int i = length - 1; i >= 0; i--)
00460 {
00461 eof = false;
00462
00463 in.unread(text.charAt(i));
00464 }
00465
00466 pos = token.getPos() - 1;
00467 line = token.getLine() - 1;
00468 }
00469 }