1 package ppg.spec; 2 3 import java.io.*; 4 import java.util.*; 5 import ppg.*; 6 import ppg.atoms.*; 7 import ppg.code.*; 8 import ppg.lex.*; 9 import ppg.parse.*; 10 import ppg.util.*; 11 12 public class CUPSpec extends Spec 13 { 14 private Vector productions; 15 private Hashtable ntProds; 17 private String start; 18 private final int NT_NOT_FOUND = -1; 19 20 public CUPSpec (String pkg, Vector imp, Vector codeParts, Vector syms, 21 Vector precedence, String startSym, Vector prods) 22 { 23 super(); 24 packageName = pkg; 25 imports = imp; 26 replaceCode(codeParts); 27 symbols = syms; 28 prec = precedence; 29 start = startSym; 30 productions = prods; 31 ntProds = new Hashtable(); 32 hashNonterminals(); 33 } 34 public void setStart (String startSym) { 35 if (startSym != null) 36 start = startSym; 37 } 38 private void hashNonterminals() { 39 ntProds.clear(); 40 if (productions == null) 41 return; 42 43 Production prod; 44 for (int i=0; i < productions.size(); i++) { 45 prod = (Production) productions.elementAt(i); 46 ntProds.put(prod.getLHS().getName(), new Integer (i)); 47 } 48 } 49 50 public CUPSpec coalesce() { 51 return this; 53 } 54 55 60 public Production findProduction (Production p) { 61 Nonterminal nt = p.getLHS(); 63 int pos = errorNotFound(findNonterminal(nt), nt); 64 Production sourceProd = (Production) productions.elementAt(pos); 65 66 Vector sourceRHSList = sourceProd.getRHS(); 67 68 Vector rhs = p.getRHS(); 69 Production result = new Production(nt, new Vector()); 70 71 Vector toMatch, source, clone; 72 for (int i=0; i < rhs.size(); i++) { 73 toMatch = (Vector) rhs.elementAt(i); 74 for (int j=0; j < sourceRHSList.size(); j++) { 75 source = (Vector) sourceRHSList.elementAt(j); 76 if (Production.isSameProduction(toMatch, source)) { 77 clone = new Vector(); 78 for (int k=0; k < source.size(); k++) { 79 clone.addElement( ((GrammarPart)source.elementAt(k)).clone() ); 80 } 81 result.addToRHS(clone); 83 break; 84 } 85 } 86 } 87 88 return result; 89 } 90 91 public void removeEmptyProductions () { 92 Production prod; 93 for (int i=0; i < productions.size(); i++) { 94 prod = (Production) productions.elementAt(i); 95 if (prod.getRHS().size() == 0) { 96 productions.removeElementAt(i); 97 i--; 98 } 99 } 100 } 101 102 public Object clone() { 103 String newPkgName = (packageName == null) ? null : packageName.toString(); 104 105 Vector newImports = new Vector(); 106 for (int i=0; i < imports.size(); i++) { 107 newImports.addElement( ((String ) imports.elementAt(i)).toString()); 108 } 109 110 Vector newCode = new Vector(); 111 if (actionCode != null) newCode.addElement(actionCode); 112 if (initCode != null) newCode.addElement(initCode); 113 if (parserCode != null) newCode.addElement(parserCode); 114 if (scanCode != null) newCode.addElement(scanCode); 115 118 119 Vector newSymbols = new Vector(); 120 for (int i=0; i < symbols.size(); i++) { 121 newSymbols.addElement( ((SymbolList) symbols.elementAt(i)).clone()); 122 } 123 124 Vector newPrec = new Vector(); 125 for (int i=0; i < prec.size(); i++) { 126 newPrec.addElement( ((Precedence) prec.elementAt(i)).clone()); 127 } 128 129 String newStart = (start == null) ? null : start.toString(); 130 131 Vector newProductions = new Vector(); 132 for (int i=0; i < productions.size(); i++) { 133 newProductions.addElement( ((Production) productions.elementAt(i)).clone()); 134 } 135 136 return new CUPSpec(newPkgName, newImports, newCode, newSymbols, 137 newPrec, newStart, newProductions); 138 139 148 } 149 150 public void addSymbols(Vector syms) { 151 if (syms == null) 152 return; 153 154 for (int i=0; i < syms.size(); i++) { 155 symbols.addElement(syms.elementAt(i)); 156 } 157 } 158 159 public void dropSymbol(String gs) throws PPGError { 160 boolean dropped = false; 161 for (int i=0; i < symbols.size(); i++ ) { 162 SymbolList list = (SymbolList) symbols.elementAt(i); 163 dropped = dropped || list.dropSymbol(gs); 164 } 165 170 } 171 172 public void dropProductions(Production p) { 173 Nonterminal nt = p.getLHS(); 174 int pos = errorNotFound(findNonterminal(nt), nt); 175 Production prod = (Production) productions.elementAt(pos); 177 prod.drop(p); 178 } 179 180 public void dropProductions(Nonterminal nt) { 181 int pos = errorNotFound(findNonterminal(nt), nt); 182 Production prod = (Production) productions.elementAt(pos); 184 prod.drop((Production) prod.clone()); 185 } 186 187 public void dropAllProductions(String nt) { 188 int pos = findNonterminal(nt); 189 if (pos == NT_NOT_FOUND) 191 return; 192 productions.removeElementAt(pos); 194 hashNonterminals(); 196 } 197 198 public void addProductions(Production p) { 199 Nonterminal nt = p.getLHS(); 200 int pos = findNonterminal(nt); 201 if (pos == NT_NOT_FOUND) { 202 ntProds.put(nt.getName(), new Integer (productions.size())); 204 productions.addElement(p); 206 } else { 207 Production prod = (Production) productions.elementAt(pos); 209 prod.add(p); 210 } 212 } 213 214 218 private int findNonterminal(Nonterminal nt) { 219 return findNonterminal(nt.getName()); 220 } 221 222 private int findNonterminal(String nt) { 223 Integer pos = (Integer ) ntProds.get(nt); 224 if (pos == null) 225 return NT_NOT_FOUND; 226 else 227 return pos.intValue(); 228 } 229 230 private int errorNotFound(int i, Nonterminal nt) { 231 if (i == NT_NOT_FOUND) { 232 System.err.println(PPG.HEADER + "nonterminal " + nt + " not found."); 234 System.exit(1); 235 } 236 return i; 237 } 238 239 public void unparse(CodeWriter cw) { 240 cw.begin(0); 241 if (packageName != null) { 242 cw.write("package " + packageName + ";"); 243 cw.newline(); cw.newline(); 244 } 245 246 for (int i=0; i < imports.size(); i++) { 248 cw.write("import " + (String ) imports.elementAt(i) + ";"); 249 cw.newline(); 250 } 251 if (imports.size() > 0) 252 cw.newline(); 253 254 if (actionCode != null) 256 cw.write(actionCode.toString()); 257 if (initCode != null) 258 cw.write(initCode.toString()); 259 if (parserCode != null) 260 cw.write(parserCode.toString()); 261 if (scanCode != null) 262 cw.write(scanCode.toString()); 263 cw.newline(); 264 265 for (int i=0; i < symbols.size(); i++) { 267 cw.write( ((SymbolList) symbols.elementAt(i)).toString() ); 268 cw.newline(); 269 } 270 cw.newline(); 271 272 for (int i=0; i < prec.size(); i++) { 274 cw.write( ((Precedence) prec.elementAt(i)).toString() ); 275 cw.newline(); 276 } 277 cw.newline(); 278 279 if (start != null) { 281 cw.write("start with " + start + ";"); 282 cw.newline(); cw.newline(); 283 } 284 285 for (int i=0; i < productions.size(); i++) { 287 ((Production) productions.elementAt(i)).unparse(cw); 288 } 289 cw.newline(); 290 cw.end(); 291 292 301 } 302 303 306 public void export(PrintStream out) throws Exception { 307 out.println("package " + packageName + ";"); 309 out.println(); 310 311 for (int i=0; i < imports.size(); i++) 313 out.println("import " + (String ) imports.elementAt(i) + ";"); 314 out.println(); 315 316 321 if (actionCode != null) 322 out.println(actionCode.toString()); 323 if (initCode != null) 324 out.println(initCode.toString()); 325 if (parserCode != null) 326 out.println(parserCode.toString()); 327 if (scanCode != null) 328 out.println(scanCode.toString()); 329 out.println(); 330 331 for (int i=0; i < symbols.size(); i++) 333 out.println( ((SymbolList) symbols.elementAt(i)).toString() ); 334 out.println(); 335 336 for (int i=0; i < prec.size(); i++) 338 out.println( ((Precedence) prec.elementAt(i)).toString() ); 339 out.println(); 340 341 out.println("start with " + start + ";"); 343 out.println(); 344 345 for (int i=0; i < productions.size(); i++) 347 out.println( ((Production) productions.elementAt(i)).toString() ); 348 out.println(); 349 350 out.flush(); 351 out.close(); 352 } 353 } 354 | Popular Tags |