source: trunk/yao/share/antlr-2.7.7/antlr/preprocessor/Grammar.java @ 1

Last change on this file since 1 was 1, checked in by lnalod, 15 years ago

Initial import of YAO sources

File size: 9.6 KB
Line 
1package antlr.preprocessor;
2
3/* ANTLR Translator Generator
4 * Project led by Terence Parr at http://www.cs.usfca.edu
5 * Software rights: http://www.antlr.org/license.html
6 *
7 * $Id: //depot/code/org.antlr/release/antlr-2.7.7/antlr/preprocessor/Grammar.java#2 $
8 */
9
10import antlr.collections.impl.IndexedVector;
11
12import java.util.Hashtable;
13import java.util.Enumeration;
14import java.io.IOException;
15
16class Grammar {
17    protected String name;
18    protected String fileName;          // where does it come from?
19    protected String superGrammar;      // null if no super class
20    protected String 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 tokenSection;      // the tokens{} stuff
24    protected String preambleAction;// action right before grammar
25    protected String 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        /** if not derived from another grammar, might still specify a non-ANTLR
32         *  class to derive from like this "class T extends Parser(MyParserClass);"
33         */
34        protected String superClass = null;
35
36    protected String importVocab = null;
37    protected String exportVocab = null;
38    protected antlr.Tool antlrTool;
39
40    public Grammar(antlr.Tool tool, String name, String superGrammar, IndexedVector rules) {
41        this.name = name;
42        this.superGrammar = superGrammar;
43        this.rules = rules;
44        this.antlrTool = tool;
45    }
46
47    public void addOption(Option o) {
48        if (options == null) {  // if not already there, create it
49            options = new IndexedVector();
50        }
51        options.appendElement(o.getName(), o);
52    }
53
54    public void addRule(Rule r) {
55        rules.appendElement(r.getName(), r);
56    }
57
58    /** Copy all nonoverridden rules, vocabulary, and options into this grammar from
59     *  supergrammar chain.  The change is made in place; e.g., this grammar's vector
60     *  of rules gets bigger.  This has side-effects: all grammars on path to
61     *  root of hierarchy are expanded also.
62     */
63    public void expandInPlace() {
64        // if this grammar already expanded, just return
65        if (alreadyExpanded) {
66            return;
67        }
68
69        // Expand super grammar first (unless it's a predefined or subgrammar of predefined)
70        Grammar superG = getSuperGrammar();
71        if (superG == null)
72            return; // error (didn't provide superclass)
73        if (exportVocab == null) {
74            // if no exportVocab for this grammar, make it same as grammar name
75            exportVocab = getName();
76        }
77        if (superG.isPredefined())
78            return; // can't expand Lexer, Parser, ...
79        superG.expandInPlace();
80
81        // expand current grammar now.
82        alreadyExpanded = true;
83        // track whether a grammar file needed to have a grammar expanded
84        GrammarFile gf = hier.getFile(getFileName());
85        gf.setExpanded(true);
86
87        // Copy rules from supergrammar into this grammar
88        IndexedVector inhRules = superG.getRules();
89        for (Enumeration e = inhRules.elements(); e.hasMoreElements();) {
90            Rule r = (Rule)e.nextElement();
91            inherit(r, superG);
92        }
93
94        // Copy options from supergrammar into this grammar
95        // Modify tokdef options so that they point to dir of enclosing grammar
96        IndexedVector inhOptions = superG.getOptions();
97        if (inhOptions != null) {
98            for (Enumeration e = inhOptions.elements(); e.hasMoreElements();) {
99                Option o = (Option)e.nextElement();
100                inherit(o, superG);
101            }
102        }
103
104        // add an option to load the superGrammar's output vocab
105        if ((options != null && options.getElement("importVocab") == null) || options == null) {
106            // no importVocab found, add one that grabs superG's output vocab
107            Option inputV = new Option("importVocab", superG.exportVocab + ";", this);
108            addOption(inputV);
109            // copy output vocab file to current dir
110            String originatingGrFileName = superG.getFileName();
111            String path = antlrTool.pathToFile(originatingGrFileName);
112            String superExportVocabFileName = path + superG.exportVocab +
113                antlr.CodeGenerator.TokenTypesFileSuffix +
114                antlr.CodeGenerator.TokenTypesFileExt;
115            String newImportVocabFileName = antlrTool.fileMinusPath(superExportVocabFileName);
116            if (path.equals("." + System.getProperty("file.separator"))) {
117                // don't copy tokdef file onto itself (must be current directory)
118                // System.out.println("importVocab file same dir; leaving as " + superExportVocabFileName);
119            }
120            else {
121                try {
122                    antlrTool.copyFile(superExportVocabFileName, newImportVocabFileName);
123                }
124                catch (IOException io) {
125                    antlrTool.toolError("cannot find/copy importVocab file " + superExportVocabFileName);
126                    return;
127                }
128            }
129        }
130
131        // copy member action from supergrammar into this grammar
132        inherit(superG.memberAction, superG);
133    }
134
135    public String getFileName() {
136        return fileName;
137    }
138
139    public String getName() {
140        return name;
141    }
142
143    public IndexedVector getOptions() {
144        return options;
145    }
146
147    public IndexedVector getRules() {
148        return rules;
149    }
150
151    public Grammar getSuperGrammar() {
152        if (superGrammar == null) return null;
153        Grammar g = (Grammar)hier.getGrammar(superGrammar);
154        return g;
155    }
156
157    public String getSuperGrammarName() {
158        return superGrammar;
159    }
160
161    public String getType() {
162        return type;
163    }
164
165    public void inherit(Option o, Grammar superG) {
166        // do NOT inherit importVocab/exportVocab options under any circumstances
167        if (o.getName().equals("importVocab") ||
168            o.getName().equals("exportVocab")) {
169            return;
170        }
171
172        Option overriddenOption = null;
173        if (options != null) {  // do we even have options?
174            overriddenOption = (Option)options.getElement(o.getName());
175        }
176        // if overridden, do not add to this grammar
177        if (overriddenOption == null) { // not overridden
178            addOption(o);       // copy option into this grammar--not overridden
179        }
180    }
181
182    public void inherit(Rule r, Grammar superG) {
183        // if overridden, do not add to this grammar
184        Rule overriddenRule = (Rule)rules.getElement(r.getName());
185        if (overriddenRule != null) {
186            // rule is overridden in this grammar.
187            if (!overriddenRule.sameSignature(r)) {
188                // warn if different sig
189                antlrTool.warning("rule " + getName() + "." + overriddenRule.getName() +
190                                   " has different signature than " +
191                                   superG.getName() + "." + overriddenRule.getName());
192            }
193        }
194        else {  // not overridden, copy rule into this
195            addRule(r);
196        }
197    }
198
199    public void inherit(String memberAction, Grammar superG) {
200        if (this.memberAction != null) return;  // do nothing if already have member action
201        if (memberAction != null) { // don't have one here, use supergrammar's action
202            this.memberAction = memberAction;
203        }
204    }
205
206    public boolean isPredefined() {
207        return predefined;
208    }
209
210    public void setFileName(String f) {
211        fileName = f;
212    }
213
214    public void setHierarchy(Hierarchy hier) {
215        this.hier = hier;
216    }
217
218    public void setMemberAction(String a) {
219        memberAction = a;
220    }
221
222    public void setOptions(IndexedVector options) {
223        this.options = options;
224    }
225
226    public void setPreambleAction(String a) {
227        preambleAction = a;
228    }
229
230    public void setPredefined(boolean b) {
231        predefined = b;
232    }
233
234    public void setTokenSection(String tk) {
235        tokenSection = tk;
236    }
237
238    public void setType(String t) {
239        type = t;
240    }
241
242    public String toString() {
243        StringBuffer s = new StringBuffer(10000);
244        if (preambleAction != null) {
245            s.append(preambleAction);
246        }
247        if (superGrammar == null) {
248                        return "class " + name + ";";
249        }
250                if ( superClass!=null ) {
251                        // replace with specified superclass not actual grammar
252                        // user must make sure that the superclass derives from super grammar class
253                        s.append("class " + name + " extends " + superClass + ";");
254                }
255                else {
256                        s.append("class " + name + " extends " + type + ";");
257                }
258                s.append(
259                        System.getProperty("line.separator") +
260            System.getProperty("line.separator"));
261        if (options != null) {
262            s.append(Hierarchy.optionsToString(options));
263        }
264        if (tokenSection != null) {
265            s.append(tokenSection + "\n");
266        }
267        if (memberAction != null) {
268            s.append(memberAction + System.getProperty("line.separator"));
269        }
270        for (int i = 0; i < rules.size(); i++) {
271            Rule r = (Rule)rules.elementAt(i);
272            if (!getName().equals(r.enclosingGrammar.getName())) {
273                s.append("// inherited from grammar " + r.enclosingGrammar.getName() + System.getProperty("line.separator"));
274            }
275            s.append(r +
276                System.getProperty("line.separator") +
277                System.getProperty("line.separator"));
278        }
279        return s.toString();
280    }
281}
Note: See TracBrowser for help on using the repository browser.