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