001: package antlr.preprocessor;
002:
003: /* ANTLR Translator Generator
004: * Project led by Terence Parr at http://www.cs.usfca.edu
005: * Software rights: http://www.antlr.org/license.html
006: */
007:
008: import antlr.collections.impl.IndexedVector;
009:
010: import java.util.Hashtable;
011: import java.util.Enumeration;
012: import java.io.*;
013:
014: import antlr.*;
015: import antlr.preprocessor.Grammar;
016:
017: public class Hierarchy {
018: protected Grammar LexerRoot = null;
019: protected Grammar ParserRoot = null;
020: protected Grammar TreeParserRoot = null;
021: protected Hashtable symbols; // table of grammars
022: protected Hashtable files; // table of grammar files read in
023: protected antlr.Tool antlrTool;
024:
025: public Hierarchy(antlr.Tool tool) {
026: this .antlrTool = tool;
027: LexerRoot = new Grammar(tool, "Lexer", null, null);
028: ParserRoot = new Grammar(tool, "Parser", null, null);
029: TreeParserRoot = new Grammar(tool, "TreeParser", null, null);
030: symbols = new Hashtable(10);
031: files = new Hashtable(10);
032:
033: LexerRoot.setPredefined(true);
034: ParserRoot.setPredefined(true);
035: TreeParserRoot.setPredefined(true);
036:
037: symbols.put(LexerRoot.getName(), LexerRoot);
038: symbols.put(ParserRoot.getName(), ParserRoot);
039: symbols.put(TreeParserRoot.getName(), TreeParserRoot);
040: }
041:
042: public void addGrammar(Grammar gr) {
043: gr.setHierarchy(this );
044: // add grammar to hierarchy
045: symbols.put(gr.getName(), gr);
046: // add grammar to file.
047: GrammarFile f = getFile(gr.getFileName());
048: f.addGrammar(gr);
049: }
050:
051: public void addGrammarFile(GrammarFile gf) {
052: files.put(gf.getName(), gf);
053: }
054:
055: public void expandGrammarsInFile(String fileName) {
056: GrammarFile f = getFile(fileName);
057: for (Enumeration e = f.getGrammars().elements(); e
058: .hasMoreElements();) {
059: Grammar g = (Grammar) e.nextElement();
060: g.expandInPlace();
061: }
062: }
063:
064: public Grammar findRoot(Grammar g) {
065: if (g.getSuperGrammarName() == null) { // at root
066: return g;
067: }
068: // return root of super.
069: Grammar sg = g.getSuperGrammar();
070: if (sg == null)
071: return g; // return this grammar if super missing
072: return findRoot(sg);
073: }
074:
075: public GrammarFile getFile(String fileName) {
076: return (GrammarFile) files.get(fileName);
077: }
078:
079: public Grammar getGrammar(String gr) {
080: return (Grammar) symbols.get(gr);
081: }
082:
083: public static String optionsToString(IndexedVector options) {
084: String s = "options {" + System.getProperty("line.separator");
085: for (Enumeration e = options.elements(); e.hasMoreElements();) {
086: s += (Option) e.nextElement()
087: + System.getProperty("line.separator");
088: }
089: s += "}" + System.getProperty("line.separator")
090: + System.getProperty("line.separator");
091: return s;
092: }
093:
094: public void readGrammarFile(String file)
095: throws FileNotFoundException {
096: Reader grStream = new BufferedReader(new FileReader(file));
097: addGrammarFile(new GrammarFile(antlrTool, file));
098:
099: // Create the simplified grammar lexer/parser
100: PreprocessorLexer ppLexer = new PreprocessorLexer(grStream);
101: ppLexer.setFilename(file);
102: Preprocessor pp = new Preprocessor(ppLexer);
103: pp.setTool(antlrTool);
104: pp.setFilename(file);
105:
106: // populate the hierarchy with class(es) read in
107: try {
108: pp.grammarFile(this , file);
109: } catch (TokenStreamException io) {
110: antlrTool
111: .toolError("Token stream error reading grammar(s):\n"
112: + io);
113: } catch (ANTLRException se) {
114: antlrTool.toolError("error reading grammar(s):\n" + se);
115: }
116: }
117:
118: /** Return true if hierarchy is complete, false if not */
119: public boolean verifyThatHierarchyIsComplete() {
120: boolean complete = true;
121: // Make a pass to ensure all grammars are defined
122: for (Enumeration e = symbols.elements(); e.hasMoreElements();) {
123: Grammar c = (Grammar) e.nextElement();
124: if (c.getSuperGrammarName() == null) {
125: continue; // at root: ignore predefined roots
126: }
127: Grammar super G = c.getSuperGrammar();
128: if (super G == null) {
129: antlrTool.toolError("grammar "
130: + c.getSuperGrammarName() + " not defined");
131: complete = false;
132: symbols.remove(c.getName()); // super not defined, kill sub
133: }
134: }
135:
136: if (!complete)
137: return false;
138:
139: // Make another pass to set the 'type' field of each grammar
140: // This makes it easy later to ask a grammar what its type
141: // is w/o having to search hierarchy.
142: for (Enumeration e = symbols.elements(); e.hasMoreElements();) {
143: Grammar c = (Grammar) e.nextElement();
144: if (c.getSuperGrammarName() == null) {
145: continue; // ignore predefined roots
146: }
147: c.setType(findRoot(c).getName());
148: }
149:
150: return true;
151: }
152:
153: public antlr.Tool getTool() {
154: return antlrTool;
155: }
156:
157: public void setTool(antlr.Tool antlrTool) {
158: this.antlrTool = antlrTool;
159: }
160: }
|