KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > ppg > spec > CUPSpec


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     // maps nonterminal to its index in the vector of productions
16
private Hashtable ntProds;
17     private String JavaDoc start;
18     private final int NT_NOT_FOUND = -1;
19     
20     public CUPSpec (String JavaDoc pkg, Vector imp, Vector codeParts, Vector syms,
21                     Vector precedence, String JavaDoc 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 JavaDoc 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 JavaDoc(i));
47         }
48     }
49     
50     public CUPSpec coalesce() {
51         // cannot have a parent by definition
52
return this;
53     }
54     
55     /**
56      * Provides a copy of the production that was present in the original
57      * grammar, but is equal (minus semantic actions) to the given production set.
58      * Thus, we transfer the semantic actions without having to re-specify them.
59      */

60     public Production findProduction (Production p) {
61         // find the nonterminal which would contain this production
62
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((Vector) source.clone());
82
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 JavaDoc clone() {
103         String JavaDoc 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 JavaDoc) 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         /*for (int i=0; i < code.size(); i++) {
116             newCode.addElement( ((Code) code.elementAt(i)).clone());
117         }*/

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 JavaDoc 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         /*
140         return new CUPSpec(newPkgName,
141                            (Vector) imports.clone(),
142                            (Vector) code.clone(),
143                            (Vector) symbols.clone(),
144                            (Vector) prec.clone(),
145                            newStart,
146                            (Vector) productions.clone());
147         */

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 JavaDoc 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         //TODO: error if symbol being dropped was not found
166
/*
167         if (!dropped)
168             throw new PPGError("file", -1, "symbol "+gs+" not found.");
169         */

170     }
171     
172     public void dropProductions(Production p) {
173         Nonterminal nt = p.getLHS();
174         int pos = errorNotFound(findNonterminal(nt), nt);
175         // should be a valid index from which we can drop productions
176
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         // should be a valid index from which we can drop productions
183
Production prod = (Production) productions.elementAt(pos);
184         prod.drop((Production) prod.clone());
185     }
186     
187     public void dropAllProductions(String JavaDoc nt) {
188         int pos = findNonterminal(nt);
189         // a terminal will not be in the hash
190
if (pos == NT_NOT_FOUND)
191             return;
192         // remove the whole lhs ::= rhs entry from the list of productions
193
productions.removeElementAt(pos);
194         // now we need to rehash since positions changed
195
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             // add a hash mapping for this entry
203
ntProds.put(nt.getName(), new Integer JavaDoc(productions.size()));
204             // just append to our list
205
productions.addElement(p);
206         } else {
207             // attach to specific nonterminal in our list of productions
208
Production prod = (Production) productions.elementAt(pos);
209             prod.add(p);
210             //productions.setElementAt(prod, pos);
211
}
212     }
213
214     /**
215      * Returns int which is the position of the nonterminal in the production
216      * list, or exits if it is not found
217      */

218     private int findNonterminal(Nonterminal nt) {
219         return findNonterminal(nt.getName());
220     }
221     
222     private int findNonterminal(String JavaDoc nt) {
223         Integer JavaDoc pos = (Integer JavaDoc) 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             // index not found, hence we have no such terminal
233
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         // import
247
for (int i=0; i < imports.size(); i++) {
248             cw.write("import " + (String JavaDoc) imports.elementAt(i) + ";");
249             cw.newline();
250         }
251         if (imports.size() > 0)
252             cw.newline();
253
254         // code
255
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         // symbols
266
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         // precedence
273
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         // start
280
if (start != null) {
281             cw.write("start with " + start + ";");
282             cw.newline(); cw.newline();
283         }
284         
285         // productions
286
for (int i=0; i < productions.size(); i++) {
287             ((Production) productions.elementAt(i)).unparse(cw);
288         }
289         cw.newline();
290         cw.end();
291         
292         //Write out to stdout in a naive manner
293
/*
294         try {
295             export(System.out);
296         } catch (Exception e) {
297             System.out.println(HEADER+"Exception: "+e.getMessage());
298             return;
299         }
300         */

301     }
302     
303     /**
304      * Write out the CUP specification to the stream
305      */

306     public void export(PrintStream out) throws Exception JavaDoc {
307         // package
308
out.println("package " + packageName + ";");
309         out.println();
310         
311         // import
312
for (int i=0; i < imports.size(); i++)
313             out.println("import " + (String JavaDoc) imports.elementAt(i) + ";");
314         out.println();
315
316         // code
317
/*
318         for (int i=0; i < code.size(); i++)
319             out.println( ((Code) code.elementAt(i)).toString() );
320         */

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         // symbols
332
for (int i=0; i < symbols.size(); i++)
333             out.println( ((SymbolList) symbols.elementAt(i)).toString() );
334         out.println();
335         
336         // precedence
337
for (int i=0; i < prec.size(); i++)
338             out.println( ((Precedence) prec.elementAt(i)).toString() );
339         out.println();
340         
341         // start
342
out.println("start with " + start + ";");
343         out.println();
344         
345         // productions
346
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