1 package fri.patterns.interpreter.parsergenerator.parsertables; 2 3 import java.util.*; 4 import java.io.*; 5 import java.lang.reflect.*; 6 import fri.patterns.interpreter.parsergenerator.ParserTables; 7 import fri.patterns.interpreter.parsergenerator.Token; 8 import fri.patterns.interpreter.parsergenerator.syntax.*; 9 10 21 22 public abstract class AbstractParserTables implements 23 ParserTables, 24 Serializable 25 { 26 27 protected Syntax syntax; 28 29 30 protected List gotoTable; 31 32 33 protected List parseTable; 34 35 36 protected transient List symbols = new ArrayList(); 37 38 39 protected transient List terminals = new ArrayList(); 40 41 42 protected List terminalsWithoutEpsilon = new ArrayList(); 43 44 45 protected transient List nonterminals = new ArrayList(); 46 47 48 public transient static int CELLWIDTH = 0; 49 50 51 52 protected AbstractParserTables() { 53 } 54 55 61 public Integer getGotoState(Integer currentState, String symbol) { 62 Integer state = null; 63 Map map = (Map) gotoTable.get(currentState.intValue()); 64 if (map != null) 65 state = (Integer ) map.get(symbol); 66 return state == null ? ParserTables.ERROR : state; 67 } 68 69 75 public Integer getParseAction(Integer currentState, String terminal) { 76 Integer action = null; 77 Map map = (Map) parseTable.get(currentState.intValue()); 78 if (map != null) 79 action = (Integer ) map.get(terminal); 80 return action == null ? ParserTables.ERROR : action; 81 } 82 83 84 public List getTerminals() { 85 return terminalsWithoutEpsilon; 86 } 87 88 89 public Syntax getSyntax() { 90 return syntax; 91 } 92 93 94 public Map getExpected(Integer state) { 95 return (Map) parseTable.get(state.intValue()); 96 } 97 98 99 100 106 public static AbstractParserTables construct(Class parserType, Syntax syntax) 107 throws Exception 108 { 109 Constructor constr; 110 if (syntax == null) { constr = parserType.getConstructor(new Class [0]); 112 return (AbstractParserTables)constr.newInstance(new Object [0]); 113 } 114 else { try { constr = parserType.getConstructor(new Class [] { syntax.getClass() }); 117 } 118 catch (Exception e) { constr = parserType.getConstructor(new Class [] { Object .class }); 120 } 121 return (AbstractParserTables)constr.newInstance(new Object [] { syntax }); 122 } 123 } 124 125 126 127 128 130 131 132 public void dump(PrintStream out) { 133 dumpSyntax(out); 134 dumpTables(out); 135 } 136 137 public void dumpTables(PrintStream out) { 138 dumpGoto(out); 139 dumpParseAction(out); 140 } 141 142 public void dumpSyntax(PrintStream out) { 143 for (int i = 0; i < syntax.size(); i++) 144 out.println(dumpRule(syntax.getRule(i), i)); 145 out.println(); 146 } 147 148 protected String dumpRule(Rule rule, int i) { 149 StringBuffer sb = new StringBuffer ("(Rule "+i+") "+rule.getNonterminal()+" : "); 150 for (int j = 0; j < rule.rightSize(); j++) 151 sb.append(rule.getRightSymbol(j)+" "); 152 return sb.toString(); 153 } 154 155 protected void dumpGoto(PrintStream out) { 156 if (symbols.size() > 0) 157 dumpTable("GOTO TABLE", symbols, gotoTable, out); 158 } 159 160 protected void dumpParseAction(PrintStream out) { 161 if (terminals.size() > 0) 162 dumpTable("PARSE-ACTION TABLE", terminals, parseTable, out); 163 } 164 165 166 protected void dumpTable(String title, List head, List table, PrintStream out) { 167 out.println(title); 168 out.println(dummy(title.length(), "=")); 169 170 if (CELLWIDTH <= 0) { 172 for (Iterator it = head.iterator(); it.hasNext(); ) { 173 String s = (String ) it.next(); 174 if (s.length() > CELLWIDTH && it.hasNext()) CELLWIDTH = s.length() + 1; 176 } 177 } 178 179 dumpCell(" | ", CELLWIDTH, false, out); 181 for (Iterator it = head.iterator(); it.hasNext(); ) { 182 String s = (String ) it.next(); 183 if (Token.isEpsilon(s)) 184 s = "<EOF>"; 185 dumpCell(s, CELLWIDTH, ! it.hasNext(), out); 186 } 187 188 out.println(); 189 out.println(dummy(CELLWIDTH * (head.size() + 1), "_")); 190 191 int i = 0; 192 for (Iterator it = table.iterator(); it.hasNext(); i++) { 193 Map h = (Map) it.next(); 194 195 dumpCell(Integer.toString(i)+" | ", CELLWIDTH, false, out); 196 for (Iterator it2 = head.iterator(); it2.hasNext(); ) { 197 String symbol = (String ) it2.next(); 198 199 Integer intg = h != null ? (Integer ) h.get(symbol) : null; 200 String digit = intg == null ? "-" : intg.equals(ParserTables.SHIFT) ? "SH" : intg.equals(ParserTables.ACCEPT) ? "AC" : intg.toString(); 201 202 dumpCell(digit, CELLWIDTH, ! it2.hasNext(), out); 203 } 204 out.println(); 205 } 206 207 out.println(); 208 } 209 210 private void dumpCell(String digit, int width, boolean isLast, PrintStream out) { 211 StringBuffer tab = new StringBuffer (" "); 212 for (int i = 0; i < width - 1 - digit.length(); i++) 213 tab.append(' '); 214 215 String s = tab+digit; 216 if (!isLast && s.length() > width && width > 2) 217 s = s.substring(0, width); 218 219 out.print(s); 220 } 221 222 private String dummy(int width, String ch) { 223 StringBuffer sb = new StringBuffer (); 224 for (int i = 0; i < width; i++) 225 sb.append(ch); 226 return sb.toString(); 227 } 228 229 230 231 public void report(PrintStream out) { 232 out.println("rules: "+syntax.size()); 233 out.println("terminals: "+terminals.size()); 234 out.println("nonterminals: "+nonterminals.size()); 235 } 236 237 238 239 240 242 243 private transient Writer f = null; 244 245 private void fwrite(String line) 246 throws IOException 247 { 248 f.write(line, 0, line.length()); 249 } 250 251 260 public String toSourceFile(String parserClassName) 261 throws IOException 262 { 263 if (parserClassName.endsWith("ParserTables") == false) 264 parserClassName = parserClassName+"ParserTables"; 265 266 String fileName = parserClassName.replace('.', File.separatorChar)+".java"; 267 System.err.println("Writing Java Source to "+fileName); 268 269 File file = new File(fileName); 270 String path = file.getParent(); 271 if (path != null && new File(path).exists() == false) 272 new File(path).mkdirs(); 273 274 f = new BufferedWriter(new FileWriter(file)); 276 277 if (path != null) { 279 if (path.endsWith(File.separator)) 280 path = path.substring(0, path.length() - 1); 281 282 fwrite("package "+path.replace(File.separatorChar, '.')+";\n\n"); 283 284 parserClassName = parserClassName.substring(parserClassName.lastIndexOf(".") + 1); 285 } 286 287 fwrite("import java.util.*;\n"); 288 fwrite("import fri.patterns.interpreter.parsergenerator.syntax.*;\n"); 289 fwrite("import fri.patterns.interpreter.parsergenerator.parsertables.AbstractParserTables;\n\n"); 290 fwrite("/**\n"); 291 fwrite(" * DO NOT EDIT - ParserTables generated\n"); 292 fwrite(" * at "+new Date()+"\n"); 293 fwrite(" * by fri.patterns.interpreter.parsergenerator.parsertables.AbstractParserTables.\n"); 294 fwrite(" */\n\n"); 295 fwrite("public final class "+parserClassName+" extends AbstractParserTables\n"); 296 fwrite("{\n"); 297 298 fwrite(" public "+parserClassName+"() {\n"); 300 301 fwrite(" syntax = new Syntax("+syntax.size()+");\n"); 302 fwrite(" Rule s;\n"); 303 fwrite("\n"); 304 for (int i = 0; i < syntax.size(); i++) { 305 Rule s = syntax.getRule(i); 306 fwrite(" syntax.addRule(s = new Rule(\""+s.getNonterminal()+"\", "+s.rightSize()+")); // rule "+i+"\n"); 307 for (int j = 0; j < s.rightSize(); j++) 308 fwrite(" s.addRightSymbol(\""+sub(s.getRightSymbol(j))+"\");\n"); 309 fwrite("\n"); 310 } 311 fwrite("\n"); 312 313 fwrite(" loadGotoTable();\n"); 315 fwrite(" loadParseActionTable();\n"); 316 fwrite("\n"); 317 318 fwrite(" terminalsWithoutEpsilon = new ArrayList("+terminalsWithoutEpsilon.size()+");\n"); 320 for (int i = 0; i < terminalsWithoutEpsilon.size(); i++) 321 fwrite(" terminalsWithoutEpsilon.add(\""+sub(terminalsWithoutEpsilon.get(i))+"\");\n"); 322 323 fwrite(" }\n"); 324 326 327 fwrite(" private void loadGotoTable() {\n"); 329 fwrite(" gotoTable = new ArrayList("+gotoTable.size()+");\n"); 330 fwrite("\n"); 331 for (int i = 0; i < gotoTable.size(); i++) { 332 Map g = (Map) gotoTable.get(i); 333 if (g == null) 334 fwrite(" gotoTable.add(null); // state "+i); 335 else 336 fwrite(" loadGoto_"+i+"();"); 337 fwrite("\n"); 338 } 339 fwrite(" }\n"); 340 341 for (int i = 0; i < gotoTable.size(); i++) { 343 Map g = (Map) gotoTable.get(i); 344 if (g != null) { 345 fwrite(" private void loadGoto_"+i+"() {\n"); 346 fwrite(" Hashtable g = new Hashtable("+g.size()+", 1);\n"); 347 fwrite(" gotoTable.add(g);\n"); 348 for (Iterator it = g.keySet().iterator(); it.hasNext(); ) { 349 String key = (String ) it.next(); 350 Object value = g.get(key); 351 fwrite(" g.put(\""+sub(key)+"\", new Integer("+value+"));\n"); 352 } 353 fwrite(" }\n"); 354 } 355 } 356 357 fwrite(" private void loadParseActionTable() {\n"); 359 fwrite(" parseTable = new ArrayList("+parseTable.size()+");\n"); 360 fwrite("\n"); 361 for (int i = 0; i < parseTable.size(); i++) { 362 Map p = (Map) parseTable.get(i); 363 if (p == null) 364 fwrite(" parseTable.add(null); // state "+i); 365 else 366 fwrite(" loadParseAction_"+i+"();"); 367 fwrite("\n"); 368 } 369 fwrite(" }\n"); 370 371 for (int i = 0; i < parseTable.size(); i++) { 373 Map p = (Map) parseTable.get(i); 374 if (p != null) { 375 fwrite(" private void loadParseAction_"+i+"() {\n"); 376 fwrite(" Hashtable p = new Hashtable("+p.size()+", 1);\n"); 377 fwrite(" parseTable.add(p);\n"); 378 for (Iterator it = p.keySet().iterator(); it.hasNext(); ) { 379 String key = (String ) it.next(); 380 Object value = p.get(key); 381 fwrite(" p.put(\""+sub(key)+"\", new Integer("+value+"));\n"); 382 } 383 fwrite(" }\n"); 384 } 385 } 386 387 fwrite("}"); 388 389 f.flush(); 391 f.close(); 392 f = null; 393 394 return fileName; 395 } 396 397 398 private String sub(Object o) { 399 return SyntaxUtil.maskQuoteAndBackslash((String ) o); 400 } 401 402 } | Popular Tags |