1 package antlr.preprocessor;
2
3 import antlr.collections.impl.IndexedVector;
4 import java.util.Hashtable;
5 import java.util.Enumeration;
6 import java.io.IOException;
7
8 class Grammar {
9 protected String name;
10 protected String fileName; protected String superGrammar; protected String type; protected IndexedVector rules; protected IndexedVector options; protected String preambleAction; protected String memberAction; protected Hierarchy hier; protected boolean predefined=false; protected boolean alreadyExpanded = false;
20 protected boolean specifiedVocabulary=false;
22 public Grammar(String name, String superGrammar, IndexedVector rules) {
23 this.name = name;
24 this.superGrammar = superGrammar;
25 this.rules = rules;
26 }
27 public void addOption(Option o) {
28 if ( options==null ) { options = new IndexedVector();
30 }
31 options.appendElement(o.getName(), o);
32 }
33 public void addRule(Rule r) {
34 rules.appendElement(r.getName(), r);
35 }
36 * supergrammar chain. The change is made in place; e.g., this grammar's vector
38 * of rules gets bigger. This has side-effects: all grammars on path to
39 * root of hierarchy are expanded also.
40 */
41 public void expandInPlace() {
42 if ( alreadyExpanded ) {
44 return;
45 }
46
47 Grammar superG = getSuperGrammar();
49 if ( superG == null ) return; if ( superG.isPredefined() ) return; superG.expandInPlace();
52
53 alreadyExpanded = true;
55 GrammarFile gf = hier.getFile(getFileName());
57 gf.setExpanded(true);
58
59 IndexedVector inhRules = superG.getRules();
61 for (Enumeration e = inhRules.elements() ; e.hasMoreElements() ;) {
62 Rule r = (Rule)e.nextElement();
63 inherit(r, superG);
64 }
65
66 IndexedVector inhOptions = superG.getOptions();
69 if ( inhOptions==null ) return;
70 for (Enumeration e = inhOptions.elements() ; e.hasMoreElements() ;) {
71 Option o = (Option)e.nextElement();
72 inherit(o, superG);
73 }
74
75 inherit(superG.memberAction, superG);
77
78 if ( !specifiedVocabulary ) {
80 antlr.Tool.warning("you probably want a tokdef option in the supergrammar");
81 }
82 */
83
84 }
85 public String getFileName() { return fileName; }
86 public String getName() {
87 return name;
88 }
89 public IndexedVector getOptions() { return options; }
90 public IndexedVector getRules() { return rules; }
91 public Grammar getSuperGrammar() {
92 if ( superGrammar==null ) return null;
93 Grammar g = (Grammar)hier.getGrammar(superGrammar);
94 return g;
95 }
96 public String getSuperGrammarName() {
97 return superGrammar;
98 }
99 public String getType() {
100 return type;
101 }
102 public void inherit(Option o, Grammar superG) {
103 Option overriddenOption = null;
104 if ( options!=null ) { overriddenOption = (Option)options.getElement(o.getName());
106 }
107 if ( overriddenOption==null ) {
109 if ( o.getName().equals("tokdef") ) {
110 String rhs = antlr.Tool.stripFrontBack(o.getRHS(), "\"", "\"");
112
113 String originatingGrFileName = o.getEnclosingGrammar().getFileName();
115 String path = antlr.Tool.pathToFile(originatingGrFileName);
116 String originalTokdefFileName = path+rhs;
117 String newTokdefFileName = antlr.Tool.fileMinusPath(rhs);
118 try {
119 antlr.Tool.copyFile(originalTokdefFileName, newTokdefFileName);
120 }
121 catch (IOException io) {
122 antlr.Tool.toolError("cannot find tokdef file "+originalTokdefFileName);
123 return;
124 }
125
126 o.setRHS("\""+newTokdefFileName+"\";");
129
130 if ( rhs.charAt(0)!=System.getProperty("file.separator").charAt(0) ) {
132 // does not begin with /, must not be absolute path
133 // prefix the file (or relative path) with the path to
134 // the associated grammar file
135 String originatingGrFileName = o.getEnclosingGrammar().getFileName();
136 String path = antlr.Tool.pathToFile(originatingGrFileName);
137 if ( path.equals("."+System.getProperty("file.separator")) ) {
138 path = ""; // don't bother putting "./" on front
139 }
140 o.setRHS("\""+path+rhs);
141 }
142 */
143 }
144 addOption(o); }
146 }
147 public void inherit(Rule r, Grammar superG) {
148 Rule overriddenRule = (Rule)rules.getElement(r.getName());
150 if ( overriddenRule!=null ) {
151 if ( !overriddenRule.sameSignature(r) ) {
153 antlr.Tool.warning("rule "+getName()+"."+overriddenRule.getName()+
155 " has different signature than "+
156 superG.getName()+"."+overriddenRule.getName());
157 }
158 }
159 else { addRule(r);
161 }
162 }
163 public void inherit(String memberAction, Grammar superG) {
164 if ( this.memberAction!=null ) return; if ( memberAction != null ) { this.memberAction = memberAction;
167 }
168 }
169 public boolean isPredefined() { return predefined; }
170 public void setFileName(String f) { fileName=f; }
171 public void setHierarchy(Hierarchy hier) { this.hier = hier; }
172 public void setMemberAction(String a) {memberAction=a;}
173 public void setOptions(IndexedVector options) {
174 this.options = options;
175 }
176 public void setPreambleAction(String a) {preambleAction=a;}
177 public void setPredefined(boolean b) { predefined=b; }
178 public void setType(String t) {
179 type = t;
180 }
181 public String toString() {
182 String s="";
183 if ( preambleAction!=null ) {
184 s += preambleAction;
185 }
186 if ( superGrammar==null ) {
187 return "class "+name+";";
188 }
189 String sup="("+superGrammar+")";
191 if ( superGrammar.equals("Parser") ||
192 superGrammar.equals("Lexer") ||
193 superGrammar.equals("TreeParser") ) {
194 sup = "";
195 }
196 */
197 String sup = "";
198 s+="class "+name+" extends "+type+sup+";"+
199 System.getProperty("line.separator")+
200 System.getProperty("line.separator");
201 if ( options!=null ) {
202 s += Hierarchy.optionsToString(options);
203 }
204 if ( memberAction!=null ) {
205 s += memberAction+System.getProperty("line.separator");
206 }
207 for (int i=0; i<rules.size(); i++) {
208 Rule r = (Rule)rules.elementAt(i);
209 if ( !getName().equals(r.enclosingGrammar.getName()) ) {
210 s += "// inherited from grammar "+r.enclosingGrammar.getName()+System.getProperty("line.separator");
211 }
212 s += r+
213 System.getProperty("line.separator")+
214 System.getProperty("line.separator");
215 }
216 return s;
217 }
218 }
219