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