19 AtomicType* atomic_type;
20 Namespace* _namespace;
25 extern int yylex(YYSTYPE* yylval);
26 void yyerror(const char* s);
29 static Class* currentClass = 0;
30 static Function* currentFunction = 0;
31 static Type* currentType = 0;
32 static ClassMember::Visbility currentVisibility;
34 class ParseError : public std::exception
37 ParseError(const std::string& message) throw()
39 std::ostringstream msg;
40 msg << "Parse error in line " << yylineno << ": "
42 this->message = msg.str();
44 virtual ~ParseError() throw()
46 const char* what() const throw()
48 return message.c_str();
61 %token <atomic_type> T_ATOMIC_TYPE
62 %token <_namespace> T_NAMESPACE;
82 %type <_class> class_declaration
83 %type <function> function_declaration
84 %type <function> constructor_declaration;
85 %type <function> destructor_declaration;
87 %type <atomic_type> type_identifier
95 compilation_unit: compilation_unit_part
96 | compilation_unit compilation_unit_part
99 compilation_unit_part: class_declaration
100 { unit->types.push_back($1); }
101 | function_declaration
102 { unit->functions.push_back($1); }
105 class_declaration: T_CLASS T_ID '{'
107 currentClass = new Class();
108 currentClass->name = $2;
110 currentVisibility = ClassMember::PROTECTED;
118 class_body: /* empty */
119 | visibility_change class_body
120 | constructor_declaration
122 $1->visibility = currentVisibility;
123 currentClass->members.push_back($1);
126 | destructor_declaration
128 $1->visibility = currentVisibility;
129 currentClass->members.push_back($1);
132 | function_declaration
134 $1->visibility = currentVisibility;
135 currentClass->members.push_back($1);
138 | variable_declaration class_body
141 visibility_change: T_PUBLIC ':'
142 { currentVisibility = ClassMember::PUBLIC; }
144 { currentVisibility = ClassMember::PROTECTED; }
146 { currentVisibility = ClassMember::PRIVATE; }
149 constructor_declaration: T_ID '('
151 currentFunction = new Function();
152 currentFunction->type = Function::CONSTRUCTOR;
157 $$ = currentFunction;
161 destructor_declaration: '~' T_ID '(' ')' ';'
163 currentFunction = new Function();
164 currentFunction->type = Function::DESTRUCTOR;
166 $$ = currentFunction;
170 variable_declaration: type T_ID ';'
172 function_declaration: type T_ID '('
174 currentFunction = new Function();
175 currentFunction->type = Function::FUNCTION;
176 currentFunction->return_type = *($1);
178 currentFunction->name = $2;
183 $$ = currentFunction;
187 param_list: /* empty */
191 param_list2: parameter
192 | parameter ',' param_list2
198 parameter.type = *($1);
200 currentFunction->parameters.push_back(parameter);
205 parameter.type = *($1);
207 parameter.name = *($2);
209 currentFunction->parameters.push_back(parameter);
214 currentType = new Type();
216 prefix_type_modifiers atomic_type postfix_type_modifiers
222 prefix_type_modifiers: /* empty */
223 | T_UNSIGNED prefix_type_modifiers
224 | T_SIGNED prefix_type_modifiers
225 | T_STATIC prefix_type_modifiers
226 | T_CONST prefix_type_modifiers
229 postfix_type_modifiers: /* empty */
230 | T_CONST postfix_type_modifiers
231 { currentType->_const = true; }
232 | '*' postfix_type_modifiers
233 { currentType->pointer++; }
234 | '&' postfix_type_modifiers
235 { currentType->ref++; }
238 atomic_type: T_VOID { currentType->atomic_type = &BasicType::VOID; }
239 | T_BOOL { currentType->atomic_type = &BasicType::BOOL; }
240 | T_CHAR { currentType->atomic_type = &BasicType::CHAR; }
241 | T_SHORT { currentType->atomic_type = &BasicType::SHORT; }
242 | T_INT { currentType->atomic_type = &BasicType::INT; }
243 | T_LONG { currentType->atomic_type = &BasicType::LONG; }
244 | T_FLOAT { currentType->atomic_type = &BasicType::FLOAT; }
245 | T_DOUBLE { currentType->atomic_type = &BasicType::DOUBLE; }
246 | type_identifier { currentType->atomic_type = $1; }
249 type_identifier: T_ATOMIC_TYPE
251 // search for type in current compilation unit...
254 | T_NAMESPACE "::" type_identifier
263 void yyerror(const char* error)
265 throw ParseError(error);