1 package ppg.spec; 2 3 import java.io.*; 4 import java.util.*; 5 import ppg.*; 6 import ppg.atoms.*; 7 import ppg.cmds.*; 8 import ppg.code.*; 9 import ppg.lex.*; 10 import ppg.parse.*; 11 import ppg.util.*; 12 13 public class PPGSpec extends Spec 14 { 15 private String include; 16 private Vector commands, code; 17 private Spec parent; 18 private Vector startSyms; 19 20 39 40 public PPGSpec (String incFile, String pkg, Vector imp, 41 Vector codeParts, Vector syms, 42 Vector precedence, Vector startList, Vector cmds) 43 { 44 super(); 45 include = incFile; 46 packageName = pkg; 47 imports = imp; 48 code = codeParts; 49 symbols = syms; 50 prec = precedence; 51 startSyms = startList; 52 commands = cmds; 53 parent = null; 54 } 55 56 public boolean isMultiStartSymbol() { 57 return (startSyms.size() > 1); 58 } 59 60 92 93 public void patchMultiStartSymbols (CUPSpec cupSpec) { 94 if (!isMultiStartSymbol()) { 95 cupSpec.setStart((String ) startSyms.elementAt(0)); 96 return; 97 } 98 99 String parseCode = ""; 101 String currSymbolName = "ppg_curr_sym"; 103 parseCode += "Symbol " + currSymbolName + ";\n\n"; 104 105 Vector tokens = new Vector(); 107 for (int i=0; i < startSyms.size(); i+=2) { 108 tokens.addElement(new String ("JLGEN_TOKEN_"+String.valueOf(i/2))); 109 } 110 111 String startSym, method, token; 112 for (int i=0; i < startSyms.size(); i += 2) { 113 startSym = (String ) startSyms.elementAt(i); 114 method = (String ) startSyms.elementAt(i+1); 115 token = (String ) tokens.elementAt(i/2); parseCode += "public Symbol "+ method + " () throws Exception {\n"+ 117 "\t"+currSymbolName+" = "+"new Symbol("+ 118 PPG.SYMBOL_CLASS_NAME+"."+token+")"+";\n"+"\t"+ 119 "return parse();\n}\n\n"; 120 } 121 cupSpec.parserCode.append(parseCode); 123 124 125 126 String scanCodeAdd = "\n// scan code generated by PPG\n"+ 128 "if (" + currSymbolName + "!= null) {\n"+ 129 "\tSymbol result = "+currSymbolName+";\n"+ 130 "\t"+currSymbolName+" = null"+";\n"+ 131 "\treturn result;\n"+ 132 "}\n"+ 133 "// end scan code generated by PPG\n\n"; 134 if (cupSpec.scanCode != null) 136 cupSpec.scanCode.prepend(scanCodeAdd); 137 else 138 cupSpec.scanCode = new ScanCode(scanCodeAdd); 139 140 141 142 String newStartSym = "multi_start_symbool"; 144 145 cupSpec.setStart(newStartSym); 147 Nonterminal startNT = new Nonterminal(newStartSym, null); 148 Vector newSymbols = new Vector(); 149 newSymbols.addElement(newStartSym); 150 151 SymbolList sl = new SymbolList(SymbolList.NONTERMINAL, null, newSymbols); 153 Vector addedSymbols = new Vector(); addedSymbols.addElement(sl); 154 cupSpec.addSymbols(addedSymbols); 155 156 SymbolList tokenList = new SymbolList(SymbolList.TERMINAL, "Symbol", tokens); 158 Vector addedTokens = new Vector(); addedTokens.addElement(tokenList); 159 cupSpec.addSymbols(addedTokens); 160 161 Vector rhs = new Vector(); 162 163 Vector rhsPart; 165 for (int i=0; i < startSyms.size(); i += 2) { 166 rhsPart = new Vector(); 167 startSym = (String ) startSyms.elementAt(i); 168 token = (String ) tokens.elementAt(i/2); rhsPart.addElement(new Nonterminal(token, null)); 173 rhsPart.addElement(new Nonterminal(startSym, "s")); 174 rhsPart.addElement(new SemanticAction("RESULT = s;")); 175 rhs.addElement(rhsPart); 176 } 177 179 Production p = new Production(startNT, rhs); 181 cupSpec.addProductions(p); 182 } 183 184 185 188 public void parseChain (String basePath) { 189 InputStream is; 190 File file = null; 191 String simpleName = include; 192 try { 193 is = ClassLoader.getSystemResourceAsStream(include); 195 if (is != null) { 196 PPG.DEBUG("found " + include + " as a resource"); 197 } 198 else { 199 String fullPath = ((basePath == "") ? 201 "" : basePath + System.getProperty("file.separator")) + 202 include; 203 PPG.DEBUG("looking for " + fullPath + " as a file"); 204 file = new File(fullPath); 205 is = new FileInputStream(file); 206 simpleName = file.getName(); 207 } 208 209 Lexer lex = new Lexer(is, simpleName); 210 Parser parser = new Parser(simpleName, lex); 211 212 PPG.DEBUG("parsing "+simpleName); 213 parser.parse(); 214 parent = (Spec)parser.getProgramNode(); 215 is.close(); 216 217 } catch (FileNotFoundException e) { 218 System.out.println(PPG.HEADER + simpleName + " not found."); 219 System.exit(1); 220 } catch (Exception e) { 221 System.out.println(PPG.HEADER+"Exception: "+e.getMessage()); 222 System.exit(1); 223 } 224 parent.setChild(this); 225 226 String parentDir = null; 227 if (file != null) { 228 parentDir = file.getParent(); 229 } 230 parent.parseChain(parentDir == null ? "" : parentDir); 231 } 232 233 public CUPSpec coalesce() throws PPGError { 234 CUPSpec combined = parent.coalesce(); 236 237 CUPSpec newSpec = (CUPSpec) combined.clone(); 239 240 newSpec.setPkgName(packageName); 242 243 newSpec.addImports(imports); 245 246 252 if (prec == null) { 254 newSpec.prec.removeAllElements(); 255 } else if (prec.size() == 0) { 256 } else { 258 newSpec.prec.removeAllElements(); 260 newSpec.prec.addAll(prec); 261 } 262 263 newSpec.replaceCode(code); 265 266 newSpec.addSymbols(symbols); 268 269 if (child == null) 271 patchMultiStartSymbols(newSpec); 272 273 processTransferL(combined, newSpec); 276 processDrop(combined, newSpec); 277 processOverride(combined, newSpec); 278 processTransferR(combined, newSpec); 279 processExtend(combined, newSpec); 280 processNew(combined, newSpec); 281 282 newSpec.removeEmptyProductions(); 284 285 return newSpec; 286 } 287 288 private void processDrop (CUPSpec combined, CUPSpec newSpec) throws PPGError { 289 Command cmd; 291 DropCmd drop; 292 for (int i=0; i < commands.size(); i++) { 293 cmd = (Command) commands.elementAt(i); 294 if (cmd instanceof DropCmd) { 295 drop = (DropCmd) cmd; 296 if (drop.isProdDrop()) { 297 newSpec.dropProductions(drop.getProduction()); 299 } else { 300 Vector symbols = drop.getSymbols(); 301 String sym; 302 for (int j=0; j < symbols.size(); j++) { 303 sym = (String ) symbols.elementAt(j); 304 newSpec.dropSymbol(sym); 306 newSpec.dropAllProductions(sym); 308 } 309 } 310 } 311 } 312 } 313 314 private void processOverride (CUPSpec combined, CUPSpec newSpec) { 315 Command cmd; 317 OverrideCmd override; 318 for (int i=0; i < commands.size(); i++) { 319 cmd = (Command) commands.elementAt(i); 320 if (cmd instanceof OverrideCmd) { 321 override = (OverrideCmd) cmd; 322 newSpec.dropProductions(override.getLHS()); 323 newSpec.addProductions(override.getProduction()); 324 } 325 } 326 } 327 328 private void processExtend (CUPSpec combined, CUPSpec newSpec) { 329 Command cmd; 331 ExtendCmd extend; 332 for (int i=0; i < commands.size(); i++) { 333 cmd = (Command) commands.elementAt(i); 334 if (cmd instanceof ExtendCmd) { 335 extend = (ExtendCmd) cmd; 336 newSpec.addProductions(extend.getProduction()); 337 } 338 } 339 } 340 341 private void processTransferL (CUPSpec combined, CUPSpec newSpec) { 342 Command cmd; 344 TransferCmd transfer; 345 Production prod; 346 Nonterminal source; 347 Vector prodList; 348 for (int i=0; i < commands.size(); i++) { 349 cmd = (Command) commands.elementAt(i); 350 if (cmd instanceof TransferCmd) { 351 transfer = (TransferCmd) cmd; 352 source = transfer.getSource(); 353 prodList = transfer.getTransferList(); 354 355 prod = (Production) prodList.elementAt(0); 357 prod = (Production) prod.clone(); 358 for (int j=1; j < prodList.size(); j++) { 359 Production prodNew = (Production) prodList.elementAt(j); 360 prod.union( (Production) prodNew.clone() ); 361 } 363 364 prod.setLHS(transfer.getSource()); 365 newSpec.dropProductions(prod); 366 } 367 } 368 } 369 370 private void processTransferR (CUPSpec combined, CUPSpec newSpec) { 371 Command cmd; 373 TransferCmd transfer; 374 Production prod, prodTransfer; 375 Vector prodList; 376 Nonterminal target; 377 for (int i=0; i < commands.size(); i++) { 378 cmd = (Command) commands.elementAt(i); 379 if (cmd instanceof TransferCmd) { 380 transfer = (TransferCmd) cmd; 381 prodList = transfer.getTransferList(); 382 for (int j=0; j < prodList.size(); j++) { 383 prod = (Production) prodList.elementAt(j); 384 target = prod.getLHS(); 385 prod.setLHS(transfer.getSource()); 387 prodTransfer = combined.findProduction(prod); 388 prodTransfer.setLHS(target); 391 newSpec.addProductions(prodTransfer); 392 } 394 } 395 } 396 } 397 398 private void processNew (CUPSpec combined, CUPSpec newSpec) { 399 NewProdCmd newProd; 401 Command cmd; 402 for (int i=0; i < commands.size(); i++) { 403 cmd = (Command) commands.elementAt(i); 404 if (cmd instanceof NewProdCmd) { 405 newProd = (NewProdCmd) cmd; 406 newSpec.addProductions(newProd.getProduction()); 407 } 408 } 409 } 410 411 414 public void unparse (CodeWriter cw) { 415 cw.begin(0); 416 if (include != null) { 417 cw.write(include+"\n"); 418 } 419 if (commands != null) { 420 for (int i=0; i < commands.size(); i++) { 421 ((Command)commands.elementAt(i)).unparse(cw); 422 } 423 } 424 cw.end(); 425 } 426 } 427 | Popular Tags |