/* $Id: h-syn.y,v 1.7 1997/07/30 17:46:16 isis Exp $ */ // $Log: h-syn.y,v $ // Revision 1.7 1997/07/30 17:46:16 isis // Some minor new features and bug fixes // This seems to work fine // // Revision 1.6 1997/06/22 14:48:45 isis // This is the initial version for // the generating functions module // // Revision 1.5 1997/06/01 13:23:11 isis // Parsing of const: // e.g const char const * const a; // Changed the internal represantation of '*' to support const qualifiers // // Revision 1.4 1997/05/25 15:12:26 isis // Bug fixes // mostly with sizeof operator // // Revision 1.3 1997/05/18 16:56:40 isis // Changed the names a bit // to be easier to use // // Revision 1.2 1997/05/18 16:44:09 isis // Break some files to improve re-making // // Revision 1.1.1.1 1997/05/18 12:15:40 isis // This is the initial distribution // of 'c-headers' using CVS // %{ #include #include #include #include #include #include "Cname.h" #include "symbol.h" #include "gc_stl.h" #include "h-fun.h" int lineno=1; int proto_num=0; int simple_num=0,typedef_num=0,struct_num=0,enum_num=0; //The SymbolTable and ErrorHandler SymbolTableClass SymbolTable; ErrorHandlerClass ErrorHandler; //For the unnamed structs/unions/enums.... int unnamed_num=1; //Unique number char unnamed_scope[80]; //Generated name //For all the parameters... int param_num=1; char param_name[80]; //For the declaration : char * const a[] bool const_id=false; //For the enumerations int EnumValue; //It keeps the next to assign value Ctype *EnumCtype; //It keeps the Ctype of the enum //The built-in types TypeEntry *IntType=new TypeEntry("int",sizeof(int),sizeof(int)); TypeEntry *CharType=new TypeEntry("char",sizeof(char),sizeof(char)); TypeEntry *FloatType=new TypeEntry("float",sizeof(float),sizeof(float)); TypeEntry *DoubleType=new TypeEntry("double",sizeof(double),sizeof(double)); TypeEntry *VoidType=new TypeEntry("void",sizeof(void),sizeof(void)); TypeEntry *EllipsisType=new TypeEntry("...",0,0); %} %union { char string[80]; int number; gc_pCname_list* c_name_list; gc_int_list *int_list; gc_type_id_list *c_type_name_list; Cname *c_name; Ctype *c_type; Ctype::Sign ctype_sign; Ctype::Modifier ctype_modifier; Ctype::DefStyle ctype_defstyle; TypeEntry *type_entry_ptr; gc_type_id *c_type_name; gc_Cstar_list *star_list; Cstar *c_star; void *not_implemented; } %type id_name,param_id_name,param_id_decl %type id_decl_list %type optional_id_decl_list %type width_specifier,optional_width %type stars,optional_stars %type star %type int_expr,optional_array_size %type optional_array_specs,array_specs %type type simple_type builtin_type %type sign_modifier %type type_modifier %type simple_declaration,struct_declaration,enum_declaration %type optional_parameter_list,parameter_list %type parameter %type optionalID,optionalID_DEFTYPE,ID_DEFTYPE %type function_declaration %type fun_id_decl %token DEFTYPE %token T_INT T_CHAR T_DOUBLE T_FLOAT T_VOID %token TM_SHORT TM_LONG TM_UNSIGNED TM_SIGNED TM_CONST %token ID STRUCT ENUM INT TYPEDEF THREEDOTS SIZEOF SHL SHR GE LE EQ NEQ %token L_OR L_AND %type ID %type DEFTYPE %type INT %type STRUCT,ENUM %right '?' ':' %left L_OR %left L_AND %left '|' %left '^' %left '&' %left EQ NEQ %left '<' LE '>' GE %left SHL SHR %left '+' '-' %left '*' '/' '%' %right '!' '~' %left '(' ')' '[' ']' %% header: /* Nothing */ | header declaration ';' | header function_declaration {cerr << "Function Body" << endl;} ; declaration: /*Empty*/ | simple_declaration { simple_num++; insert_type_id_list_as_var($1); delete $1; } | typedef_declaration {typedef_num++;} | struct_declaration { struct_num++; insert_type_id_list_as_var($1); delete $1; } | enum_declaration { enum_num++; insert_type_id_list_as_var($1); delete $1; } ; simple_declaration: type id_decl_list { $$=create_type_id_list($1,$2); // delete $1; } | id_decl_list { Ctype ddd(IntType); $$=create_type_id_list(&ddd,$1); } ; function_declaration: type fun_id_decl {$$=NULL;} ; fun_id_decl: id_name '(' optional_parameter_list ')' '{' error '}' {$$=NULL;} ; id_decl_list: id_name { $$=new gc_pCname_list; $$->push_back($1); } | id_decl_list ',' id_name { $1->push_back($3); $$=$1; } ; id_name: optional_stars ID optional_width optional_array_specs { $$=new Cname($1,$2,$3,$4,NULL,const_id); } | width_specifier { $$=new Cname(0,"",$1,NULL,NULL,false); } | optional_stars '(' id_name ')' optional_width optional_array_specs { $$=new Cname($1,"",$5,$6,$3,const_id); } | id_name '(' optional_parameter_list ')' { proto_num++; make_cname_function($1,$3); $$=$1; } ; width_specifier: ':' int_expr {$$=$2;} ; optional_width: /*Empty*/ {$$=0;} | width_specifier {$$=$1;} ; star: '*' {$$=new Cstar;} | TM_CONST '*' {$$=new Cstar(Cstar::CONSTATTR);} ; stars: star {$$=new gc_Cstar_list;$$->push_back($1);} | stars star {$$=$1;$$->push_back($2);} ; optional_stars: /*Empty*/ {$$=NULL;const_id=false;} | stars {$$=$1;const_id=false;} | stars TM_CONST {$$=$1;const_id=true;} | TM_CONST {$$=NULL;const_id=true;} ; array_specs: '[' optional_array_size ']' { $$=new gc_int_list; $$->push_back($2); } | array_specs '[' optional_array_size ']' { $1->push_back($3); $$=$1; } ; optional_array_specs:/*Empty*/ {$$=(gc_int_list*)NULL;} | array_specs {$$=$1;} ; optional_array_size: /*Empty*/ {$$=-1;} | int_expr {$$=$1;} ; int_expr: INT {$$=$1;} | ID {$$=get_value_of_id($1);} | SIZEOF type {$$=get_sizeof_ctype($2);} | SIZEOF '(' type ')' {$$=get_sizeof_ctype($3);} | SIZEOF ID {$$=get_sizeof_id($2);} | SIZEOF '(' ID ')' {$$=get_sizeof_id($3);} | int_expr '+' int_expr {$$=$1+$3;} | int_expr '-' int_expr {$$=$1-$3;} | int_expr '/' int_expr {$$=$1/$3;} | int_expr '*' int_expr {$$=$1*$3;} | int_expr '%' int_expr {$$=$1%$3;} | int_expr SHL int_expr {$$=$1<<$3;} | int_expr SHR int_expr {$$=$1>>$3;} | int_expr '&' int_expr {$$=$1&$3;} | int_expr '|' int_expr {$$=$1|$3;} | int_expr '^' int_expr {$$=$1^$3;} | int_expr '>' int_expr {$$=$1>$3;} | int_expr '<' int_expr {$$=$1<$3;} | int_expr GE int_expr {$$=$1>=$3;} | int_expr LE int_expr {$$=$1<=$3;} | int_expr EQ int_expr {$$=($1==$3);} | int_expr NEQ int_expr {$$=($1!=$3);} | int_expr L_OR int_expr {$$=$1||$3;} | int_expr L_AND int_expr {$$=$1&&$3;} | int_expr '?' int_expr ':' int_expr {$$=$1 ? $3 : $5;} | '(' int_expr ')' {$$=$2;} | '-' int_expr {$$=-$2;} | '!' int_expr {$$=!$2;} | '~' int_expr {$$=~$2;} ; optional_parameter_list:/*Empty*/ {$$=NULL;} | parameter_list {$$=$1;} ; parameter_list: parameter { if($1==NULL) $$=NULL; else { $$=new gc_type_id_list; $$->push_back($1); } } | parameter_list ',' parameter { if($1==NULL) { ErrorHandler.Error("Cannot have arguments after a void declaration"); } if($3==NULL) { ErrorHandler.Error("Bad use of 'void' in argument list (cannot follow arguments)"); } $1->push_back($3); $$=$1; } ; parameter: type param_id_decl { if(IsVoid($1,$2)) $$=NULL; // if($1->type_attr==VoidType && $2->star_list==NULL && $2->next==NULL) $$=NULL; else { $$=new gc_type_id; $$->first=$1; $$->second=$2; } } | THREEDOTS { $$=new gc_type_id; $$->second=new Cname(0,"",0,NULL,NULL,false); $$->first=new Ctype(EllipsisType); } ; param_id_decl: /* Empty */ {$$=new Cname(0,NULL,0,NULL,NULL,false);fix_param_name($$);} | param_id_name {$$=$1;fix_param_name($1);} ; optional_CONST: /* Empty */ {const_id=false;} | TM_CONST {const_id=true;} ; param_id_name: stars optional_CONST optional_array_specs {$$=new Cname($1,NULL,0,$3,NULL,const_id);} | optional_stars ID optional_array_specs {$$=new Cname($1,NULL,0,$3,NULL,const_id);} | array_specs {$$=new Cname(0,NULL,0,$1,NULL,false);} | '(' optional_parameter_list ')' optional_array_specs {$$=new Cname(0,NULL,0,$4,NULL,false);make_cname_function($$,$2);} | '(' param_id_name ')' optional_array_specs {$$=new Cname(0,NULL,0,$4,$2,false);} | param_id_name '(' optional_parameter_list ')' optional_array_specs {make_cname_function($1,$3);$$=$1;} | param_id_name '(' param_id_name ')' { $$=$1; $1->next=$3; } ; simple_type: T_INT {$$=new Ctype(IntType);} | T_CHAR {$$=new Ctype(CharType);} | T_DOUBLE {$$=new Ctype(DoubleType);} | T_FLOAT {$$=new Ctype(FloatType);} | T_VOID {$$=new Ctype(VoidType);} ; sign_modifier: TM_UNSIGNED {$$=Ctype::UNSIGNED;} | TM_SIGNED {$$=Ctype::SIGNED;} ; type_modifier: TM_SHORT {$$=Ctype::SHORT;} | TM_LONG {$$=Ctype::LONG;} | TM_LONG TM_LONG {$$=Ctype::LONGLONG;} ; builtin_type: simple_type {$$=$1;} | sign_modifier simple_type {$$=$2;$$->sign_attr=$1;} | sign_modifier {$$=new Ctype(IntType,Ctype::DEFMOD,$1);} | type_modifier simple_type {$2->mod_attr=$1;$$=$2;} | type_modifier {$$=new Ctype(IntType,$1);} | sign_modifier type_modifier simple_type {$$=$3;$$->sign_attr=$1;$$->mod_attr=$2;} | type_modifier sign_modifier simple_type {$$=$3;$$->sign_attr=$2;$$->mod_attr=$1;} | sign_modifier type_modifier {$$=new Ctype(IntType,$2,$1);} | type_modifier sign_modifier {$$=new Ctype(IntType,$1,$2);} type: builtin_type {$$=$1;} | STRUCT ID_DEFTYPE {$$=find_and_check_type($2,$1);} | ENUM ID_DEFTYPE {$$=find_and_check_type($2,$1);} | DEFTYPE {$$=new Ctype($1,Ctype::DEFMOD,Ctype::DEFSIGN,Ctype::DEFTYPED);} | TM_CONST type {$2->SetLife(Ctype::CONSTLIFE);$$=$2;} ; optionalID_DEFTYPE: optionalID {$$=$1;} | DEFTYPE {strncpy($$,clean_Cname($1->GetCname()),80);} ; ID_DEFTYPE: ID {$$=$1;} | DEFTYPE {strncpy($$,clean_Cname($1->GetCname()),80);} ; struct_declaration: STRUCT optionalID_DEFTYPE { if(!open_forward_complex_type($2,$1)) create_complex_type($2,$1); } '{' struct_declaration_list '}' { SymbolTable.Up(); } optional_id_decl_list { //Let's create a ctype refering to the new struct Ctype *ddd=find_and_check_type($2,$1); fix_struct_size_alignment(ddd,$1); //Insert the declaration list... $$=create_type_id_list(ddd,$8); // delete ddd; } | STRUCT ID_DEFTYPE {forward_create_complex_type($2,$1);$$=NULL;} ; enum_declaration: ENUM optionalID_DEFTYPE { if(!open_forward_complex_type($2,$1)) forward_create_complex_type($2,$1); EnumValue=0; EnumCtype=find_and_check_type($2,$1); } '{' enum_assign_list '}' optional_id_decl_list { Ctype *ddd=find_and_check_type($2,$1); ddd->type_attr->SetSize(ENUM_SIZE); ddd->type_attr->SetAlignment(ENUM_SIZE); $$=create_type_id_list(ddd,$7); // delete ddd; } | ENUM ID_DEFTYPE {forward_create_complex_type($2,$1);$$=NULL;} ; optional_id_decl_list:/*Empty*/ {$$=NULL;} | id_decl_list {$$=$1;} ; optionalID: /* Empty */ { sprintf(unnamed_scope,"$scope$%d",unnamed_num++); $$=unnamed_scope; } | ID {$$=$1;} ; struct_declaration_list: /* Empty */ | declaration ';' struct_declaration_list ; enum_assign_list: enum_assign | enum_assign_list ',' enum_assign ; enum_assign:/*Empty*/ | ID {insert_enum_ent($1,EnumValue++);} | ID '=' int_expr { insert_enum_ent($1,$3);EnumValue=$3+1; } ; typedef_declaration: TYPEDEF simple_declaration { insert_type_id_list_as_type($2); delete $2; } | TYPEDEF struct_declaration { insert_type_id_list_as_type($2); delete $2; } | TYPEDEF enum_declaration { insert_type_id_list_as_type($2); delete $2; } ; %%