%{
+#include <config.h>
#include <iostream>
#include <sstream>
#include <stdexcept>
-#include "tree.h"
-#include "globals.h"
+#include "tree.hpp"
+#include "globals.hpp"
%}
float fval;
Class* _class;
Function* function;
+ Field* field;
Type* type;
AtomicType* atomic_type;
Namespace* _namespace;
void yyerror(const char* s);
extern int yylineno;
-static Class* currentClass = 0;
-static Function* currentFunction = 0;
-static Type* currentType = 0;
-static ClassMember::Visbility currentVisibility;
+bool search_down = true;
+Namespace* search_namespace = 0;
+Namespace* current_namespace = 0;
+static Class* current_class = 0;
+static Function* current_function = 0;
+static Type* current_type = 0;
+static Field* current_field = 0;
+static ClassMember::Visbility current_visibility;
class ParseError : public std::exception
{
ParseError(const std::string& message) throw()
{
std::ostringstream msg;
- msg << "Parse error in line " << yylineno << ": "
+ msg << "Parse error in '" << current_file
+ << "' line " << getCurrentLine() << ": "
<< message;
this->message = msg.str();
}
%token <str> T_STRING
%token <str> T_ID
%token <atomic_type> T_ATOMIC_TYPE
-%token <_namespace> T_NAMESPACE;
+%token <_namespace> T_NAMESPACEREF
%token T_CLASS
%token T_STRUCT
%token T_STATIC
+%token T_SUSPEND
+%token T_CUSTOM
%token T_CONST
%token T_UNSIGNED
%token T_SIGNED
%token T_BOOL
%token T_CHAR
%token T_SHORT
-%token T_INT
%token T_LONG
-%token T_FLOAT
%token T_DOUBLE
%token T_PUBLIC
%token T_PROTECTED
%token T_PRIVATE
+%token T_NAMESPACE
%token T_DDCOL "::"
%type <_class> class_declaration
%type <function> function_declaration
%type <function> constructor_declaration;
%type <function> destructor_declaration;
+%type <field> field_declaration;
%type <type> type
%type <atomic_type> type_identifier
%%
-input: /* empty */
- | compilation_unit
+input:
+ {
+ current_namespace = unit;
+ }
+ namespace_members
+;
+
+namespace_members: /* empty */
+ | namespace_members namespace_member
;
-compilation_unit: compilation_unit_part
- | compilation_unit compilation_unit_part
+namespace_declaration:
+ T_NAMESPACE T_ID '{'
+ {
+ Namespace* newNamespace = new Namespace();
+ newNamespace->name = $2;
+ free($2);
+ current_namespace->add_namespace(newNamespace);
+ current_namespace = newNamespace;
+ }
+ namespace_members '}'
+ {
+ current_namespace = current_namespace->parent;
+ }
+ | T_NAMESPACE T_NAMESPACEREF '{'
+ {
+ current_namespace = $2;
+ }
+ namespace_members '}'
+ {
+ current_namespace = current_namespace->parent;
+ }
;
-compilation_unit_part: class_declaration
- { unit->types.push_back($1); }
+namespace_member:
+ class_declaration
+ { current_namespace->add_type($1); }
| function_declaration
- { unit->functions.push_back($1); }
+ { current_namespace->functions.push_back($1); }
+ | namespace_declaration
+ | field_declaration
+ { current_namespace->fields.push_back($1); }
;
-class_declaration: T_CLASS T_ID '{'
- {
- currentClass = new Class();
- currentClass->name = $2;
- free($2);
- currentVisibility = ClassMember::PROTECTED;
- }
- class_body '}' ';'
- {
- $$ = currentClass;
- }
+class_declaration:
+ T_CLASS T_ID
+ {
+ current_class = new Class();
+ current_class->name = $2;
+ free($2);
+ current_class->docu_comment = last_docucomment;
+ last_docucomment = "";
+ current_visibility = ClassMember::PROTECTED;
+ }
+ superclass_list '{' class_body '}' ';'
+ {
+ $$ = current_class;
+ }
+;
+
+superclass_list:
+ /* empty */
+ | ':' superclasses
+;
+
+superclasses:
+ superclass
+ | superclasses ',' superclass
+;
+
+superclass:
+ superclass_visibility type_identifier
+ {
+ Class* superclass = dynamic_cast<Class*> ($2);
+ if(superclass == 0)
+ throw ParseError("SuperClass is not a Class type");
+ current_class->super_classes.push_back(superclass);
+ superclass->sub_classes.push_back(current_class);
+ }
+;
+
+superclass_visibility:
+ T_PUBLIC
+ | T_PROTECTED
+ | T_PRIVATE
;
class_body: /* empty */
- | visibility_change class_body
+ | class_body class_body_element
+;
+
+class_body_element:
+ visibility_change
| constructor_declaration
{
- $1->visibility = currentVisibility;
- currentClass->members.push_back($1);
+ $1->visibility = current_visibility;
+ current_class->members.push_back($1);
}
- class_body
| destructor_declaration
{
- $1->visibility = currentVisibility;
- currentClass->members.push_back($1);
+ $1->visibility = current_visibility;
+ current_class->members.push_back($1);
}
- class_body
| function_declaration
{
- $1->visibility = currentVisibility;
- currentClass->members.push_back($1);
+ $1->visibility = current_visibility;
+ current_class->members.push_back($1);
+ }
+ | field_declaration
+ {
+ $1->visibility = current_visibility;
+ current_class->members.push_back($1);
}
- class_body
- | variable_declaration class_body
;
-visibility_change: T_PUBLIC ':'
- { currentVisibility = ClassMember::PUBLIC; }
- | T_PROTECTED ':'
- { currentVisibility = ClassMember::PROTECTED; }
- | T_PRIVATE ':'
- { currentVisibility = ClassMember::PRIVATE; }
+visibility_change:
+ T_PUBLIC ':'
+ { current_visibility = ClassMember::PUBLIC; }
+ | T_PROTECTED ':'
+ { current_visibility = ClassMember::PROTECTED; }
+ | T_PRIVATE ':'
+ { current_visibility = ClassMember::PRIVATE; }
;
-constructor_declaration: T_ID '('
+constructor_declaration:
+ T_ID '('
{
- currentFunction = new Function();
- currentFunction->type = Function::CONSTRUCTOR;
+ current_function = new Function();
+ current_function->type = Function::CONSTRUCTOR;
+ current_function->docu_comment = last_docucomment;
+ last_docucomment = "";
free($1);
}
- param_list ')' ';'
+ parameter_list ')' ';'
+ {
+ $$ = current_function;
+ }
+;
+
+destructor_declaration:
+ '~' T_ID '(' ')' abstract_declaration ';'
{
- $$ = currentFunction;
+ current_function = new Function();
+ current_function->type = Function::DESTRUCTOR;
+ current_function->docu_comment = last_docucomment;
+ last_docucomment = "";
+ free($2);
+ $$ = current_function;
}
;
-destructor_declaration: '~' T_ID '(' ')' ';'
+field_declaration:
+ type T_ID
{
- currentFunction = new Function();
- currentFunction->type = Function::DESTRUCTOR;
+ current_field = new Field();
+ current_field->type = $1;
+ current_field->docu_comment = last_docucomment;
+ last_docucomment = "";
+ current_field->name = $2;
free($2);
- $$ = currentFunction;
+ }
+ maybe_const_initialisation ';'
+ {
+ $$ = current_field;
}
;
-variable_declaration: type T_ID ';'
+maybe_const_initialisation:
+ /* empty */
+ | '=' T_INT
+ {
+ if(current_field->type->atomic_type == &BasicType::FLOAT) {
+ current_field->const_float_value = (float) $2;
+ } else {
+ current_field->const_int_value = $2;
+ }
+ current_field->has_const_value = true;
+ }
+ | '=' T_FLOAT
+ {
+ current_field->const_float_value = $2;
+ current_field->has_const_value = true;
+ }
+ | '=' T_STRING
+ {
+ current_field->const_string_value = $2;
+ current_field->has_const_value = true;
+ }
+;
-function_declaration: type T_ID '('
+function_declaration:
+ type T_ID '('
{
- currentFunction = new Function();
- currentFunction->type = Function::FUNCTION;
- currentFunction->return_type = *($1);
+ current_function = new Function();
+ current_function->type = Function::FUNCTION;
+ current_function->return_type = *($1);
delete $1;
- currentFunction->name = $2;
+ current_function->name = $2;
free($2);
+ current_function->docu_comment = last_docucomment;
+ last_docucomment = "";
}
- param_list ')' ';'
+ parameter_list ')' function_attributes abstract_declaration ';'
{
- $$ = currentFunction;
+ $$ = current_function;
}
;
-param_list: /* empty */
- | param_list2
+function_attributes:
+ /* empty */
+ | T_CONST function_attributes
+ | T_CUSTOM function_attributes
+ {
+ current_function->custom = true;
+ }
+ | T_SUSPEND function_attributes
+ {
+ current_function->suspend = true;
+ }
;
-param_list2: parameter
- | parameter ',' param_list2
+abstract_declaration:
+ /* empty */
+ | '=' T_INT
;
-parameter: type
- {
- Parameter parameter;
- parameter.type = *($1);
- delete $1;
- currentFunction->parameters.push_back(parameter);
- }
- | type T_ID
- {
- Parameter parameter;
- parameter.type = *($1);
- delete $1;
- parameter.name = *($2);
- free($2);
- currentFunction->parameters.push_back(parameter);
- }
+parameter_list:
+ /* empty */
+ | parameters
;
-type: {
- currentType = new Type();
- }
- prefix_type_modifiers atomic_type postfix_type_modifiers
- {
- $$ = currentType;
- }
+parameters:
+ parameter
+ | parameters ',' parameter
;
-prefix_type_modifiers: /* empty */
- | T_UNSIGNED prefix_type_modifiers
- | T_SIGNED prefix_type_modifiers
- | T_STATIC prefix_type_modifiers
- | T_CONST prefix_type_modifiers
+parameter:
+ type
+ {
+ Parameter parameter;
+ parameter.type = *($1);
+ delete $1;
+ current_function->parameters.push_back(parameter);
+ }
+ | type T_ID
+ {
+ Parameter parameter;
+ parameter.type = *($1);
+ delete $1;
+ parameter.name = $2;
+ free($2);
+ current_function->parameters.push_back(parameter);
+ }
+;
+
+type:
+ {
+ current_type = new Type();
+ }
+ prefix_type_modifiers atomic_type postfix_type_modifiers
+ {
+ $$ = current_type;
+ }
+;
+
+prefix_type_modifiers:
+ /* empty */
+ | prefix_type_modifiers prefix_type_modifier
;
-postfix_type_modifiers: /* empty */
- | T_CONST postfix_type_modifiers
- { currentType->_const = true; }
- | '*' postfix_type_modifiers
- { currentType->pointer++; }
- | '&' postfix_type_modifiers
- { currentType->ref++; }
+prefix_type_modifier:
+ T_UNSIGNED
+ { current_type->_unsigned = true; }
+ | T_SIGNED
+ { current_type->_unsigned = false; }
+ | T_STATIC
+ { current_type->_static = true; }
+ | T_CONST
+ { current_type->_const = true; }
;
-atomic_type: T_VOID { currentType->atomic_type = &BasicType::VOID; }
- | T_BOOL { currentType->atomic_type = &BasicType::BOOL; }
- | T_CHAR { currentType->atomic_type = &BasicType::CHAR; }
- | T_SHORT { currentType->atomic_type = &BasicType::SHORT; }
- | T_INT { currentType->atomic_type = &BasicType::INT; }
- | T_LONG { currentType->atomic_type = &BasicType::LONG; }
- | T_FLOAT { currentType->atomic_type = &BasicType::FLOAT; }
- | T_DOUBLE { currentType->atomic_type = &BasicType::DOUBLE; }
- | type_identifier { currentType->atomic_type = $1; }
+postfix_type_modifiers:
+ /* empty */
+ | postfix_type_modifiers postfix_type_modifier
;
-type_identifier: T_ATOMIC_TYPE
+postfix_type_modifier:
+ T_CONST
+ { current_type->_const = true; }
+ | '*'
+ { current_type->pointer++; }
+ | '&'
+ { current_type->ref++; }
+;
+
+atomic_type:
+ T_VOID
+ { current_type->atomic_type = &BasicType::VOID; }
+ | T_BOOL
+ { current_type->atomic_type = &BasicType::BOOL; }
+ | T_CHAR
+ { current_type->atomic_type = &BasicType::CHAR; }
+ | T_SHORT
+ { current_type->atomic_type = &BasicType::SHORT; }
+ | T_INT
+ { current_type->atomic_type = &BasicType::INT; }
+ | T_LONG
+ { current_type->atomic_type = &BasicType::LONG; }
+ | T_FLOAT
+ { current_type->atomic_type = &BasicType::FLOAT; }
+ | T_DOUBLE
+ { current_type->atomic_type = &BasicType::DOUBLE; }
+ | type_identifier
+ { current_type->atomic_type = $1; }
+;
+
+type_identifier:
+ T_ATOMIC_TYPE
{
- // search for type in current compilation unit...
$$ = $1;
}
- | T_NAMESPACE "::" type_identifier
+ | namespace_refs "::" T_ATOMIC_TYPE
{
- // hack...
$$ = $3;
+ search_namespace = 0;
+ search_down = true;
+ }
+;
+
+namespace_refs:
+ T_NAMESPACEREF
+ {
+ search_namespace = $1;
+ search_down = false;
+ }
+ | namespace_refs "::" T_NAMESPACEREF
+ {
+ search_namespace = $3;
}
;