00001 package edu.ksu.cis.bandera.bui.session.parser;
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 edu.ksu.cis.bandera.bui.session.lexer.*;
00039 import edu.ksu.cis.bandera.bui.session.node.*;
00040 import edu.ksu.cis.bandera.bui.session.analysis.*;
00041 import java.util.*;
00042
00043 import java.io.DataInputStream;
00044 import java.io.BufferedInputStream;
00045 import java.io.IOException;
00046
00047 public class Parser
00048 {
00049 public final Analysis ignoredTokens = new AnalysisAdapter();
00050
00051 protected Node node;
00052
00053 private final Lexer lexer;
00054 private final ListIterator stack = new LinkedList().listIterator();
00055 private int last_shift;
00056 private int last_pos;
00057 private int last_line;
00058 private final TokenIndex converter = new TokenIndex();
00059 private final int[] action = new int[2];
00060
00061 private final static int SHIFT = 0;
00062 private final static int REDUCE = 1;
00063 private final static int ACCEPT = 2;
00064 private final static int ERROR = 3;
00065
00066 private static int[][][] actionTable;
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088 private static int[][][] gotoTable;
00089
00090
00091
00092
00093
00094
00095
00096
00097 private static String[] errorMessages;
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108 private static int[] errors;
00109
00110
00111
00112 public Parser(Lexer lexer)
00113 {
00114 this.lexer = lexer;
00115
00116 if(actionTable == null)
00117 {
00118 try
00119 {
00120 DataInputStream s = new DataInputStream(
00121 new BufferedInputStream(
00122 Parser.class.getResourceAsStream("parser.dat")));
00123
00124
00125 int length = s.readInt();
00126 actionTable = new int[length][][];
00127 for(int i = 0; i < actionTable.length; i++)
00128 {
00129 length = s.readInt();
00130 actionTable[i] = new int[length][3];
00131 for(int j = 0; j < actionTable[i].length; j++)
00132 {
00133 for(int k = 0; k < 3; k++)
00134 {
00135 actionTable[i][j][k] = s.readInt();
00136 }
00137 }
00138 }
00139
00140
00141 length = s.readInt();
00142 gotoTable = new int[length][][];
00143 for(int i = 0; i < gotoTable.length; i++)
00144 {
00145 length = s.readInt();
00146 gotoTable[i] = new int[length][2];
00147 for(int j = 0; j < gotoTable[i].length; j++)
00148 {
00149 for(int k = 0; k < 2; k++)
00150 {
00151 gotoTable[i][j][k] = s.readInt();
00152 }
00153 }
00154 }
00155
00156
00157 length = s.readInt();
00158 errorMessages = new String[length];
00159 for(int i = 0; i < errorMessages.length; i++)
00160 {
00161 length = s.readInt();
00162 StringBuffer buffer = new StringBuffer();
00163
00164 for(int j = 0; j < length; j++)
00165 {
00166 buffer.append(s.readChar());
00167 }
00168 errorMessages[i] = buffer.toString();
00169 }
00170
00171
00172 length = s.readInt();
00173 errors = new int[length];
00174 for(int i = 0; i < errors.length; i++)
00175 {
00176 errors[i] = s.readInt();
00177 }
00178
00179 s.close();
00180 }
00181 catch(Exception e)
00182 {
00183 throw new RuntimeException("Unable to read parser.dat.");
00184 }
00185 }
00186 }
00187 protected void filter() throws ParserException, LexerException, IOException
00188 {
00189 }
00190 private int goTo(int index)
00191 {
00192 int state = state();
00193 int low = 1;
00194 int high = gotoTable[index].length - 1;
00195 int value = gotoTable[index][0][1];
00196
00197 while(low <= high)
00198 {
00199 int middle = (low + high) / 2;
00200
00201 if(state < gotoTable[index][middle][0])
00202 {
00203 high = middle - 1;
00204 }
00205 else if(state > gotoTable[index][middle][0])
00206 {
00207 low = middle + 1;
00208 }
00209 else
00210 {
00211 value = gotoTable[index][middle][1];
00212 break;
00213 }
00214 }
00215
00216 return value;
00217 }
00218 private int index(Switchable token)
00219 {
00220 converter.index = -1;
00221 token.apply(converter);
00222 return converter.index;
00223 }
00224 Node new0()
00225 {
00226 XPSession node1 = null;
00227 AUnit node = new AUnit(node1);
00228 return node;
00229 }
00230 Node new1()
00231 {
00232 XPSession node1 = (XPSession) pop();
00233 AUnit node = new AUnit(node1);
00234 return node;
00235 }
00236 Node new10()
00237 {
00238 TStringLiteral node3 = (TStringLiteral) pop();
00239 TPlus node2 = (TPlus) pop();
00240 PStrings node1 = (PStrings) pop();
00241 AStringsStrings node = new AStringsStrings(node1, node2, node3);
00242 return node;
00243 }
00244 Node new2()
00245 {
00246 PSession node2 = (PSession) pop();
00247 XPSession node1 = (XPSession) pop();
00248 X1PSession node = new X1PSession(node1, node2);
00249 return node;
00250 }
00251 Node new3()
00252 {
00253 PSession node1 = (PSession) pop();
00254 X2PSession node = new X2PSession(node1);
00255 return node;
00256 }
00257 Node new4()
00258 {
00259 TRBrace node5 = (TRBrace) pop();
00260 XPResource node4 = null;
00261 TLBrace node3 = (TLBrace) pop();
00262 TId node2 = (TId) pop();
00263 TSession node1 = (TSession) pop();
00264 ASession node = new ASession(node1, node2, node3, node4, node5);
00265 return node;
00266 }
00267 Node new5()
00268 {
00269 TRBrace node5 = (TRBrace) pop();
00270 XPResource node4 = (XPResource) pop();
00271 TLBrace node3 = (TLBrace) pop();
00272 TId node2 = (TId) pop();
00273 TSession node1 = (TSession) pop();
00274 ASession node = new ASession(node1, node2, node3, node4, node5);
00275 return node;
00276 }
00277 Node new6()
00278 {
00279 PResource node2 = (PResource) pop();
00280 XPResource node1 = (XPResource) pop();
00281 X1PResource node = new X1PResource(node1, node2);
00282 return node;
00283 }
00284 Node new7()
00285 {
00286 PResource node1 = (PResource) pop();
00287 X2PResource node = new X2PResource(node1);
00288 return node;
00289 }
00290 Node new8()
00291 {
00292 PStrings node3 = (PStrings) pop();
00293 TEqual node2 = (TEqual) pop();
00294 TId node1 = (TId) pop();
00295 AStringResource node = new AStringResource(node1, node2, node3);
00296 return node;
00297 }
00298 Node new9()
00299 {
00300 TStringLiteral node1 = (TStringLiteral) pop();
00301 AStringStrings node = new AStringStrings(node1);
00302 return node;
00303 }
00304 public Start parse() throws ParserException, LexerException, IOException
00305 {
00306 push(0, null, false);
00307
00308 List ign = null;
00309 while(true)
00310 {
00311 while(index(lexer.peek()) == -1)
00312 {
00313 if(ign == null)
00314 {
00315 ign = new TypedLinkedList(NodeCast.instance);
00316 }
00317
00318 ign.add(lexer.next());
00319 }
00320
00321 if(ign != null)
00322 {
00323 ignoredTokens.setIn(lexer.peek(), ign);
00324 ign = null;
00325 }
00326
00327 last_pos = lexer.peek().getPos();
00328 last_line = lexer.peek().getLine();
00329
00330 int index = index(lexer.peek());
00331 action[0] = actionTable[state()][0][1];
00332 action[1] = actionTable[state()][0][2];
00333
00334 int low = 1;
00335 int high = actionTable[state()].length - 1;
00336
00337 while(low <= high)
00338 {
00339 int middle = (low + high) / 2;
00340
00341 if(index < actionTable[state()][middle][0])
00342 {
00343 high = middle - 1;
00344 }
00345 else if(index > actionTable[state()][middle][0])
00346 {
00347 low = middle + 1;
00348 }
00349 else
00350 {
00351 action[0] = actionTable[state()][middle][1];
00352 action[1] = actionTable[state()][middle][2];
00353 break;
00354 }
00355 }
00356
00357 switch(action[0])
00358 {
00359 case SHIFT:
00360 push(action[1], lexer.next(), true);
00361 last_shift = action[1];
00362 break;
00363 case REDUCE:
00364 switch(action[1])
00365 {
00366 case 0: { Node node = new0(); push(goTo(0), node, true); } break;
00367 case 1: { Node node = new1(); push(goTo(0), node, true); } break;
00368 case 2: { Node node = new2(); push(goTo(4), node, false); } break;
00369 case 3: { Node node = new3(); push(goTo(4), node, false); } break;
00370 case 4: { Node node = new4(); push(goTo(1), node, true); } break;
00371 case 5: { Node node = new5(); push(goTo(1), node, true); } break;
00372 case 6: { Node node = new6(); push(goTo(5), node, false); } break;
00373 case 7: { Node node = new7(); push(goTo(5), node, false); } break;
00374 case 8: { Node node = new8(); push(goTo(2), node, true); } break;
00375 case 9: { Node node = new9(); push(goTo(3), node, true); } break;
00376 case 10: { Node node = new10(); push(goTo(3), node, true); } break;
00377 }
00378 break;
00379 case ACCEPT:
00380 {
00381 EOF node2 = (EOF) lexer.next();
00382 PUnit node1 = (PUnit) pop();
00383 Start node = new Start(node1, node2);
00384 return node;
00385 }
00386 case ERROR:
00387 throw new ParserException(
00388 "[" + last_line + "," + last_pos + "] " +
00389 errorMessages[errors[action[1]]]);
00390 }
00391 }
00392 }
00393 private Node pop()
00394 {
00395 return (Node) ((State) stack.previous()).node;
00396 }
00397 private void push(int state, Node node, boolean filter) throws ParserException, LexerException, IOException
00398 {
00399 this.node = node;
00400
00401 if(filter)
00402 {
00403 filter();
00404 }
00405
00406 if(!stack.hasNext())
00407 {
00408 stack.add(new State(state, this.node));
00409 return;
00410 }
00411
00412 State s = (State) stack.next();
00413 s.state = state;
00414 s.node = this.node;
00415 }
00416 private int state()
00417 {
00418 State s = (State) stack.previous();
00419 stack.next();
00420 return s.state;
00421 }
00422 }