19 AtomicType* atomic_type;
20 Namespace* _namespace;
25 extern int yylex(YYSTYPE* yylval);
26 void yyerror(const char* s);
29 bool search_down = true;
30 Namespace* search_namespace = 0;
31 Namespace* current_namespace = 0;
32 static Class* current_class = 0;
33 static Function* currentFunction = 0;
34 static Type* current_type = 0;
35 static ClassMember::Visbility current_visibility;
37 class ParseError : public std::exception
40 ParseError(const std::string& message) throw()
42 std::ostringstream msg;
43 msg << "Parse error in line " << yylineno << ": "
45 this->message = msg.str();
47 virtual ~ParseError() throw()
49 const char* what() const throw()
51 return message.c_str();
64 %token <atomic_type> T_ATOMIC_TYPE
65 %token <_namespace> T_NAMESPACEREF;
87 %type <_class> class_declaration
88 %type <function> function_declaration
89 %type <function> constructor_declaration;
90 %type <function> destructor_declaration;
92 %type <atomic_type> type_identifier
98 current_namespace = unit;
103 namespace_members: /* empty */
104 | namespace_members namespace_member
107 namespace_declaration:
110 Namespace* newNamespace = new Namespace();
111 newNamespace->name = $2;
113 current_namespace->add_namespace(newNamespace);
114 current_namespace = newNamespace;
116 namespace_members '}'
118 current_namespace = current_namespace->parent;
120 | T_NAMESPACE T_NAMESPACEREF '{'
122 current_namespace = $2;
124 namespace_members '}'
126 current_namespace = current_namespace->parent;
132 { current_namespace->add_type($1); }
133 | function_declaration
134 { current_namespace->functions.push_back($1); }
135 | namespace_declaration
141 current_class = new Class();
142 current_class->name = $2;
144 current_visibility = ClassMember::PROTECTED;
152 class_body: /* empty */
153 | class_body class_body_element
158 | constructor_declaration
160 $1->visibility = current_visibility;
161 current_class->members.push_back($1);
163 | destructor_declaration
165 $1->visibility = current_visibility;
166 current_class->members.push_back($1);
168 | function_declaration
170 $1->visibility = current_visibility;
171 current_class->members.push_back($1);
173 | variable_declaration
178 { current_visibility = ClassMember::PUBLIC; }
180 { current_visibility = ClassMember::PROTECTED; }
182 { current_visibility = ClassMember::PRIVATE; }
185 constructor_declaration:
188 currentFunction = new Function();
189 currentFunction->type = Function::CONSTRUCTOR;
192 parameter_list ')' ';'
194 $$ = currentFunction;
198 destructor_declaration:
199 maybe_virtual '~' T_ID '(' ')' abstract_declaration ';'
201 currentFunction = new Function();
202 currentFunction->type = Function::DESTRUCTOR;
204 $$ = currentFunction;
213 variable_declaration:
217 function_declaration:
218 maybe_virtual type T_ID '('
220 currentFunction = new Function();
221 currentFunction->type = Function::FUNCTION;
222 currentFunction->return_type = *($2);
224 currentFunction->name = $3;
227 parameter_list ')' abstract_declaration ';'
229 $$ = currentFunction;
233 abstract_declaration:
245 | parameters ',' parameter
252 parameter.type = *($1);
254 currentFunction->parameters.push_back(parameter);
259 parameter.type = *($1);
261 parameter.name = *($2);
263 currentFunction->parameters.push_back(parameter);
269 current_type = new Type();
271 prefix_type_modifiers atomic_type postfix_type_modifiers
277 prefix_type_modifiers:
279 | prefix_type_modifiers prefix_type_modifier
282 prefix_type_modifier:
284 { current_type->_unsigned = true; }
286 { current_type->_unsigned = false; }
288 { current_type->_static = true; }
290 { current_type->_const = true; }
293 postfix_type_modifiers:
295 | postfix_type_modifiers postfix_type_modifier
298 postfix_type_modifier:
300 { current_type->_const = true; }
302 { current_type->pointer++; }
304 { current_type->ref++; }
309 { current_type->atomic_type = &BasicType::VOID; }
311 { current_type->atomic_type = &BasicType::BOOL; }
313 { current_type->atomic_type = &BasicType::CHAR; }
315 { current_type->atomic_type = &BasicType::SHORT; }
317 { current_type->atomic_type = &BasicType::INT; }
319 { current_type->atomic_type = &BasicType::LONG; }
321 { current_type->atomic_type = &BasicType::FLOAT; }
323 { current_type->atomic_type = &BasicType::DOUBLE; }
325 { current_type->atomic_type = $1; }
331 // search for type in current compilation unit...
334 | namespace_refs "::" T_ATOMIC_TYPE
337 search_namespace = 0;
345 search_namespace = $1;
348 | namespace_refs "::" T_NAMESPACEREF
350 search_namespace = $3;
356 void yyerror(const char* error)
358 throw ParseError(error);