1 #include "astgenvisitor1.h"
2 #include "ast.h"
3 #include "strutils.h"
4
5 #include <assert.h>
6 #include <ctype.h> // for isupper
7
8 using std::vector;
9 using std::string;
10
astgenvisitor1(const char * filename,const char * visitorFilename)11 astgenvisitor1::astgenvisitor1(const char* filename, const char* visitorFilename)
12 : m_out(filename)
13 , m_filename(filename)
14 , m_visitorFilename(visitorFilename)
15 {
16 }
17
~astgenvisitor1()18 astgenvisitor1::~astgenvisitor1()
19 {
20 }
21
visit_lhs_IDENT_SEPARATOR(const lhs_IDENT_SEPARATOR * plhs_IDENT_SEPARATOR)22 void astgenvisitor1::visit_lhs_IDENT_SEPARATOR(const lhs_IDENT_SEPARATOR *plhs_IDENT_SEPARATOR)
23 {
24 m_rulename = *plhs_IDENT_SEPARATOR->m_IDENT;
25 }
26
visit_grammar_grammar_production(const grammar_grammar_production * pgrammar_grammar_production)27 void astgenvisitor1::visit_grammar_grammar_production(const grammar_grammar_production *pgrammar_grammar_production)
28 {
29 if (pgrammar_grammar_production->m_grammar.get() == 0) // start of the AST
30 {
31 m_out << "#ifndef " << strToIdentifier(m_filename) << "_HPP_GUARD_\n";
32 m_out << "#define " << strToIdentifier(m_filename) << "_HPP_GUARD_\n";
33 m_out << "#include <string>\n";
34 m_out << "#include <list>\n";
35 m_out << "#include \"" << m_visitorFilename << "\"\n\n";
36 m_out << "class node\n";
37 m_out << "{\n";
38 m_out << " public:\n";
39 m_out << " virtual ~node() {}\n";
40 m_out << " virtual void accept( Visitor * ) const = 0;\n";
41 m_out << "};\n\n";
42 }
43 else
44 {
45 pgrammar_grammar_production->m_grammar->accept(this);
46 }
47 pgrammar_grammar_production->m_production->accept(this);
48
49 }
50
visit_grammar_grammar_COMMENT(const grammar_grammar_COMMENT * pgrammar_grammar_COMMENT)51 void astgenvisitor1::visit_grammar_grammar_COMMENT(const grammar_grammar_COMMENT *pgrammar_grammar_COMMENT)
52 {
53 return;
54 /*
55 if (pgrammar_grammar_COMMENT->m_grammar.get() != 0)
56 {
57 pgrammar_grammar_COMMENT->m_grammar->accept(this);
58 }
59 */
60 }
61
visit_expression_base_OPT(const expression_base_OPT * pexpression_base_OPT)62 void astgenvisitor1::visit_expression_base_OPT(const expression_base_OPT *pexpression_base_OPT)
63 {
64 // not yet implemented
65 assert(0);
66 pexpression_base_OPT->m_base->accept(this);
67 }
68
visit_production_lhs_expressionListList_TERMINATOR(const production_lhs_expressionListList_TERMINATOR * pproduction_lhs_expressionListList_TERMINATOR)69 void astgenvisitor1::visit_production_lhs_expressionListList_TERMINATOR(const production_lhs_expressionListList_TERMINATOR *pproduction_lhs_expressionListList_TERMINATOR)
70 {
71
72 pproduction_lhs_expressionListList_TERMINATOR->m_lhs->accept(this);
73 // m_rulename is now set (by astgenvisitor1::visit_lhs_IDENT_SEPARATOR
74 if (!beginsWithStr(m_rulename))
75 {
76 if (pproduction_lhs_expressionListList_TERMINATOR->m_expressionListList.get() != 0)
77 {
78 if (pproduction_lhs_expressionListList_TERMINATOR->m_expressionListList->size() > 1)
79 {
80 if (!endsWithList(m_rulename))
81 {
82 // First time we'll collect up the class names so we
83 // can use them in the base class.
84 vector<string> names;
85 for (vector<vector<expression*>*>::const_iterator i = pproduction_lhs_expressionListList_TERMINATOR->m_expressionListList->begin();
86 i != pproduction_lhs_expressionListList_TERMINATOR->m_expressionListList->end();
87 ++i)
88 {
89 if (*i)
90 {
91 vector<string> dummy;
92 string name = create_class_name(i, dummy);
93 names.push_back(name);
94 }
95 }
96
97 // Now write out the base class
98 if (!isSpecialRule(m_rulename))
99 {
100 m_out << "class " << m_rulename << ": public node\n";
101 m_out << "{\n";
102 m_out << "\tpublic:\n";
103 /*
104 m_out << "\t\tenum clsType {\n";
105 for (vector<string>::const_iterator i = names.begin();
106 i != names.end(); ++i)
107 m_out << "\t\t\t" << *i << "Type,\n";
108 m_out << "\t\t};\n\n";
109 m_out << "\t\t" << m_rulename << "(const clsType t)\n";
110 m_out << "\t\t\t: type(t) {}\n";
111 */
112 m_out << "\t\t" << m_rulename << "()\n";
113 m_out << "\t\t\t{}\n";
114 m_out << "\t\tvirtual ~" << m_rulename << "() {}\n\n";
115 /*
116 m_out << "\t\tclsType type;\n\n";
117 for (vector<string>::const_iterator i = names.begin();
118 i != names.end(); ++i)
119 {
120 m_out << "\t\tvirtual " << *i << "* get" << *i << "()\n";
121 m_out << "\t\t{\n";
122 m_out << "\t\t\treturn 0;\n";
123 m_out << "\t\t}\n";
124 }
125 */
126 m_out << "};\n\n";
127 }
128
129 // Second time we'll actually write out the classes.
130 for (vector<vector<expression*>*>::const_iterator i = pproduction_lhs_expressionListList_TERMINATOR->m_expressionListList->begin();
131 i != pproduction_lhs_expressionListList_TERMINATOR->m_expressionListList->end();
132 ++i)
133 {
134 if (*i)
135 {
136 write_class(i, m_rulename);
137 }
138 }
139 }
140 else
141 {
142 vector<vector<expression*>*>::const_iterator i = pproduction_lhs_expressionListList_TERMINATOR->m_expressionListList->begin();
143 if ((*i)->size() > 0 && *(*i)->begin())
144 {
145 (*(*i)->begin())->accept(this); // fills out m_ident
146 if (beginsWithStr(m_ident))
147 addListType(m_rulename, "std::string");
148 else
149 addListType(m_rulename, m_ident);
150 }
151 }
152
153 }
154 else
155 {
156 write_class(pproduction_lhs_expressionListList_TERMINATOR->m_expressionListList->begin(), "node");
157 }
158 }
159 }
160 }
161
write_argument(const vector<string>::const_iterator & i,int arg_num)162 void astgenvisitor1::write_argument(const vector<string>::const_iterator& i, int arg_num)
163 {
164 if (isAllCaps(*i) || beginsWithStr(*i))
165 {
166 m_out << "\t\t\tstd::string* pNew" << *i << arg_num;
167 }
168 else if (endsWithList(*i))
169 {
170 string listType = getListType(*i);
171 m_out << "\t\t\tstd::list< " << listType << "* >* pNew" <<
172 *i << arg_num;
173 }
174 else
175 {
176 m_out << "\t\t\t" << *i << "* pNew" << *i << arg_num;
177 }
178 }
179
create_class_name(const vector<vector<expression * > * >::const_iterator i,vector<string> & idents)180 string astgenvisitor1::create_class_name(const vector<vector<expression*>*>::const_iterator i, vector<string>& idents)
181 {
182 // first build up the classname and gather the idents
183 string classname = m_rulename;
184 for (vector<expression*>::const_iterator j = (*i)->begin();
185 j != (*i)->end();
186 ++j)
187 {
188 m_literal.erase();
189 m_ident.erase();
190 (*j)->accept(this);
191 if (m_ident.length() > 0)
192 {
193 classname += "_" + m_ident;
194 idents.push_back(m_ident);
195 }
196 }
197 if ((*i)->size() == 0)
198 {
199 classname += "_empty";
200 }
201
202 return classname;
203 }
204
write_class(const vector<vector<expression * > * >::const_iterator i,const string & baseclass)205 void astgenvisitor1::write_class(const vector<vector<expression*>*>::const_iterator i, const string& baseclass)
206 {
207 // first build up the classname and gather the idents
208 vector<string> idents;
209 string classname;
210 if (baseclass == "node")
211 {
212 // we don't care about the class name, but we need idents to be filled in.
213 create_class_name(i, idents);
214 classname = m_rulename;
215 }
216 else
217 classname = create_class_name(i, idents);
218
219 m_out << "class " << classname << " : public " << baseclass << "\n";
220 m_out << "{\n";
221
222 // next build up the constructor
223 m_out << "\tpublic:\n";
224 m_out << "\t\t" << classname << "(\n";
225 int arg_num = 1;
226 if (idents.size() > 0)
227 {
228 vector<string>::const_iterator i = idents.begin();
229 while (i != idents.end())
230 {
231 write_argument(i, arg_num);
232 ++i;
233 ++arg_num;
234 if (i != idents.end())
235 m_out << ",\n";
236 else
237 m_out << "\n";
238 }
239 }
240 m_out << "\t\t)\n";
241
242 // now do the initialization list
243 vector<string>::const_iterator j = idents.begin();
244 arg_num = 1;
245 char sep = ':';
246 if (baseclass != "node")
247 {
248 m_out << "\t\t\t: " << baseclass << "(" /*<< classname << "Type*/ ")\n";
249 sep = ',';
250 }
251 while (j != idents.end())
252 {
253 m_out << "\t\t\t" << sep << " m_p" << *j << arg_num << "(pNew" << *j << arg_num << ")\n";
254 sep = ',';
255 ++j;
256 ++arg_num;
257 }
258 m_out << "\t\t{}\n\n";
259
260 // write out the destructor
261 m_out << "\t\tvirtual ~" << classname << "();\n\n";
262
263 // write the accept function
264 m_out << "\t\tvoid accept( Visitor* v ) const\n";
265 m_out << "\t\t{\n";
266 if (baseclass == "node")
267 m_out << "\t\t\tv->visit_" << m_rulename << "( this );\n";
268 else
269 m_out << "\t\t\tv->visit_" << classname << "( this );\n";
270 m_out << "\t\t}\n\n";
271
272 // write the getpointer function
273 /*
274 m_out << "\t\tvirtual " << classname << "* get" << classname << "()\n";
275 m_out << "\t\t{\n";
276 m_out << "\t\t\treturn this;\n";
277 m_out << "\t\t}\n\n";
278 */
279
280 // write the member variables
281 arg_num = 1;
282 for (vector<string>::const_iterator i = idents.begin(); i!= idents.end(); ++i, ++arg_num)
283 {
284 if (isAllCaps(*i) || beginsWithStr(*i))
285 {
286 m_out << "\t\tstd::string* m_p" << *i << arg_num << ";\n";
287 }
288 else if (endsWithList(*i))
289 {
290 m_out << "\t\tstd::list< " << getListType(*i) << "* >* m_p" <<
291 *i << arg_num << ";\n";
292 }
293 else
294 {
295 m_out << "\t\t" << *i << "* m_p" << *i << arg_num << ";\n";
296 }
297 }
298
299 // finish off the class
300 m_out << "};\n\n";
301
302 }
303
visit_expression_base_PLUS(const expression_base_PLUS * pexpression_base_PLUS)304 void astgenvisitor1::visit_expression_base_PLUS(const expression_base_PLUS *pexpression_base_PLUS)
305 {
306 // not yet implemented
307 assert(0);
308 pexpression_base_PLUS->m_base->accept(this);
309 }
310
visit_expression_base(const expression_base * pexpression_base)311 void astgenvisitor1::visit_expression_base(const expression_base *pexpression_base)
312 {
313 pexpression_base->m_base->accept(this);
314 }
315
visit_base_LITERAL(const base_LITERAL * pbase_LITERAL)316 void astgenvisitor1::visit_base_LITERAL(const base_LITERAL *pbase_LITERAL)
317 {
318 m_literal = *pbase_LITERAL->m_LITERAL;
319 }
320
visit_expression_base_STAR(const expression_base_STAR * pexpression_base_STAR)321 void astgenvisitor1::visit_expression_base_STAR(const expression_base_STAR *pexpression_base_STAR)
322 {
323 // not yet implemented
324 assert(0);
325 pexpression_base_STAR->m_base->accept(this);
326 }
327
visit_base_LPAREN_expressionList_RPAREN(const base_LPAREN_expressionList_RPAREN * pbase_LPAREN_expressionList_RPAREN)328 void astgenvisitor1::visit_base_LPAREN_expressionList_RPAREN(const base_LPAREN_expressionList_RPAREN *pbase_LPAREN_expressionList_RPAREN)
329 {
330 // not yet implemented
331 assert(0);
332 if (pbase_LPAREN_expressionList_RPAREN->m_expressionList.get() != 0)
333 {
334 for (vector<expression*>::const_iterator i = pbase_LPAREN_expressionList_RPAREN->m_expressionList->begin();
335 i != pbase_LPAREN_expressionList_RPAREN->m_expressionList->end();
336 ++i)
337 {
338 (*i)->accept(this);
339 }
340 }
341 }
342
visit_expression_COMMENT(const expression_COMMENT * pexpression_COMMENT)343 void astgenvisitor1::visit_expression_COMMENT(const expression_COMMENT *pexpression_COMMENT)
344 {
345 // not yet implemented
346 assert(0);
347 (void)pexpression_COMMENT->m_COMMENT;
348 }
349
visit_alternation_expression_OR_expression(const alternation_expression_OR_expression * palternation_expression_OR_expression)350 void astgenvisitor1::visit_alternation_expression_OR_expression(const alternation_expression_OR_expression *palternation_expression_OR_expression)
351 {
352 // not yet implemented
353 assert(0);
354 palternation_expression_OR_expression->m_expression1->accept(this);
355 palternation_expression_OR_expression->m_expression2->accept(this);
356 }
357
visit_base_IDENT(const base_IDENT * pbase_IDENT)358 void astgenvisitor1::visit_base_IDENT(const base_IDENT *pbase_IDENT)
359 {
360 m_ident = *pbase_IDENT->m_IDENT;
361 }
362
visit_base_LPAREN_alternation_RPAREN(const base_LPAREN_alternation_RPAREN * pbase_LPAREN_alternation_RPAREN)363 void astgenvisitor1::visit_base_LPAREN_alternation_RPAREN(const base_LPAREN_alternation_RPAREN *pbase_LPAREN_alternation_RPAREN)
364 {
365 // not yet implemented
366 assert(0);
367 pbase_LPAREN_alternation_RPAREN->m_alternation->accept(this);
368 }
369
visit_alternation_alternation_OR_expression(const alternation_alternation_OR_expression * palternation_alternation_OR_expression)370 void astgenvisitor1::visit_alternation_alternation_OR_expression(const alternation_alternation_OR_expression *palternation_alternation_OR_expression)
371 {
372 // not yet implemented
373 assert(0);
374 palternation_alternation_OR_expression->m_alternation->accept(this);
375 palternation_alternation_OR_expression->m_expression->accept(this);
376 }
377
378
379