KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > antlr > preprocessor > Grammar


1 package antlr.preprocessor;
2
3 /* ANTLR Translator Generator
4  * Project led by Terence Parr at http://www.jGuru.com
5  * Software rights: http://www.antlr.org/RIGHTS.html
6  *
7  * $Id: //depot/code/org.antlr/main/main/antlr/preprocessor/Grammar.java#5 $
8  */

9
10 import antlr.collections.impl.IndexedVector;
11
12 import java.util.Hashtable JavaDoc;
13 import java.util.Enumeration JavaDoc;
14 import java.io.IOException JavaDoc;
15
16 class Grammar {
17     protected String JavaDoc name;
18     protected String JavaDoc fileName; // where does it come from?
19
protected String JavaDoc superGrammar; // null if no super class
20
protected String JavaDoc type; // lexer? parser? tree parser?
21
protected IndexedVector rules; // text of rules as they were read in
22
protected IndexedVector options;// rule options
23
protected String JavaDoc tokenSection; // the tokens{} stuff
24
protected String JavaDoc preambleAction;// action right before grammar
25
protected String JavaDoc memberAction; // action inside grammar
26
protected Hierarchy hier; // hierarchy of grammars
27
protected boolean predefined = false; // one of the predefined grammars?
28
protected boolean alreadyExpanded = false;
29     protected boolean specifiedVocabulary = false; // found importVocab option?
30

31     protected String JavaDoc importVocab = null;
32     protected String JavaDoc exportVocab = null;
33     protected antlr.Tool antlrTool;
34
35     public Grammar(antlr.Tool tool, String JavaDoc name, String JavaDoc superGrammar, IndexedVector rules) {
36         this.name = name;
37         this.superGrammar = superGrammar;
38         this.rules = rules;
39         this.antlrTool = tool;
40     }
41
42     public void addOption(Option o) {
43         if (options == null) { // if not already there, create it
44
options = new IndexedVector();
45         }
46         options.appendElement(o.getName(), o);
47     }
48
49     public void addRule(Rule r) {
50         rules.appendElement(r.getName(), r);
51     }
52
53     /** Copy all nonoverridden rules, vocabulary, and options into this grammar from
54      * supergrammar chain. The change is made in place; e.g., this grammar's vector
55      * of rules gets bigger. This has side-effects: all grammars on path to
56      * root of hierarchy are expanded also.
57      */

58     public void expandInPlace() {
59         // if this grammar already expanded, just return
60
if (alreadyExpanded) {
61             return;
62         }
63
64         // Expand super grammar first (unless it's a predefined or subgrammar of predefined)
65
Grammar superG = getSuperGrammar();
66         if (superG == null)
67             return; // error (didn't provide superclass)
68
if (exportVocab == null) {
69             // if no exportVocab for this grammar, make it same as grammar name
70
exportVocab = getName();
71         }
72         if (superG.isPredefined())
73             return; // can't expand Lexer, Parser, ...
74
superG.expandInPlace();
75
76         // expand current grammar now.
77
alreadyExpanded = true;
78         // track whether a grammar file needed to have a grammar expanded
79
GrammarFile gf = hier.getFile(getFileName());
80         gf.setExpanded(true);
81
82         // Copy rules from supergrammar into this grammar
83
IndexedVector inhRules = superG.getRules();
84         for (Enumeration JavaDoc e = inhRules.elements(); e.hasMoreElements();) {
85             Rule r = (Rule)e.nextElement();
86             inherit(r, superG);
87         }
88
89         // Copy options from supergrammar into this grammar
90
// Modify tokdef options so that they point to dir of enclosing grammar
91
IndexedVector inhOptions = superG.getOptions();
92         if (inhOptions != null) {
93             for (Enumeration JavaDoc e = inhOptions.elements(); e.hasMoreElements();) {
94                 Option o = (Option)e.nextElement();
95                 inherit(o, superG);
96             }
97         }
98
99         // add an option to load the superGrammar's output vocab
100
if ((options != null && options.getElement("importVocab") == null) || options == null) {
101             // no importVocab found, add one that grabs superG's output vocab
102
Option inputV = new Option("importVocab", superG.exportVocab + ";", this);
103             addOption(inputV);
104             // copy output vocab file to current dir
105
String JavaDoc originatingGrFileName = superG.getFileName();
106             String JavaDoc path = antlrTool.pathToFile(originatingGrFileName);
107             String JavaDoc superExportVocabFileName = path + superG.exportVocab +
108                 antlr.CodeGenerator.TokenTypesFileSuffix +
109                 antlr.CodeGenerator.TokenTypesFileExt;
110             String JavaDoc newImportVocabFileName = antlrTool.fileMinusPath(superExportVocabFileName);
111             if (path.equals("." + System.getProperty("file.separator"))) {
112                 // don't copy tokdef file onto itself (must be current directory)
113
// System.out.println("importVocab file same dir; leaving as " + superExportVocabFileName);
114
}
115             else {
116                 try {
117                     antlrTool.copyFile(superExportVocabFileName, newImportVocabFileName);
118                 }
119                 catch (IOException JavaDoc io) {
120                     antlrTool.toolError("cannot find/copy importVocab file " + superExportVocabFileName);
121                     return;
122                 }
123             }
124         }
125
126         // copy member action from supergrammar into this grammar
127
inherit(superG.memberAction, superG);
128     }
129
130     public String JavaDoc getFileName() {
131         return fileName;
132     }
133
134     public String JavaDoc getName() {
135         return name;
136     }
137
138     public IndexedVector getOptions() {
139         return options;
140     }
141
142     public IndexedVector getRules() {
143         return rules;
144     }
145
146     public Grammar getSuperGrammar() {
147         if (superGrammar == null) return null;
148         Grammar g = (Grammar)hier.getGrammar(superGrammar);
149         return g;
150     }
151
152     public String JavaDoc getSuperGrammarName() {
153         return superGrammar;
154     }
155
156     public String JavaDoc getType() {
157         return type;
158     }
159
160     public void inherit(Option o, Grammar superG) {
161         // do NOT inherit importVocab/exportVocab options under any circumstances
162
if (o.getName().equals("importVocab") ||
163             o.getName().equals("exportVocab")) {
164             return;
165         }
166
167         Option overriddenOption = null;
168         if (options != null) { // do we even have options?
169
overriddenOption = (Option)options.getElement(o.getName());
170         }
171         // if overridden, do not add to this grammar
172
if (overriddenOption == null) { // not overridden
173
addOption(o); // copy option into this grammar--not overridden
174
}
175     }
176
177     public void inherit(Rule r, Grammar superG) {
178         // if overridden, do not add to this grammar
179
Rule overriddenRule = (Rule)rules.getElement(r.getName());
180         if (overriddenRule != null) {
181             // rule is overridden in this grammar.
182
if (!overriddenRule.sameSignature(r)) {
183                 // warn if different sig
184
antlrTool.warning("rule " + getName() + "." + overriddenRule.getName() +
185                                    " has different signature than " +
186                                    superG.getName() + "." + overriddenRule.getName());
187             }
188         }
189         else { // not overridden, copy rule into this
190
addRule(r);
191         }
192     }
193
194     public void inherit(String JavaDoc memberAction, Grammar superG) {
195         if (this.memberAction != null) return; // do nothing if already have member action
196
if (memberAction != null) { // don't have one here, use supergrammar's action
197
this.memberAction = memberAction;
198         }
199     }
200
201     public boolean isPredefined() {
202         return predefined;
203     }
204
205     public void setFileName(String JavaDoc f) {
206         fileName = f;
207     }
208
209     public void setHierarchy(Hierarchy hier) {
210         this.hier = hier;
211     }
212
213     public void setMemberAction(String JavaDoc a) {
214         memberAction = a;
215     }
216
217     public void setOptions(IndexedVector options) {
218         this.options = options;
219     }
220
221     public void setPreambleAction(String JavaDoc a) {
222         preambleAction = a;
223     }
224
225     public void setPredefined(boolean b) {
226         predefined = b;
227     }
228
229     public void setTokenSection(String JavaDoc tk) {
230         tokenSection = tk;
231     }
232
233     public void setType(String JavaDoc t) {
234         type = t;
235     }
236
237     public String JavaDoc toString() {
238         String JavaDoc s = "";
239         if (preambleAction != null) {
240             s += preambleAction;
241         }
242         if (superGrammar == null) {
243             return "class " + name + ";";
244         }
245         String JavaDoc sup = "";
246         s += "class " + name + " extends " + type + sup + ";" +
247             System.getProperty("line.separator") +
248             System.getProperty("line.separator");
249         if (options != null) {
250             s += Hierarchy.optionsToString(options);
251         }
252         if (tokenSection != null) {
253             s += tokenSection + "\n";
254         }
255         if (memberAction != null) {
256             s += memberAction + System.getProperty("line.separator");
257         }
258         for (int i = 0; i < rules.size(); i++) {
259             Rule r = (Rule)rules.elementAt(i);
260             if (!getName().equals(r.enclosingGrammar.getName())) {
261                 s += "// inherited from grammar " + r.enclosingGrammar.getName() + System.getProperty("line.separator");
262             }
263             s += r +
264                 System.getProperty("line.separator") +
265                 System.getProperty("line.separator");
266         }
267         return s;
268     }
269 }
270
Popular Tags