%{ /* This routine parses the vidf grammar and creates a data structure holding the parameters. */ #include #include #include #include "symtab.h" #include "SDDAS_types.h" extern symtab *GLOBAL_VIDF; static symtab *p; static int symsize; static int symtype; static int counter; typedef union { SDDAS_FLOAT *dval_ptr; SDDAS_INT *lval_ptr; SDDAS_CHAR **str_ptr; } arrayType; static arrayType tmp_array; void *vidf_get_list_head (symtab *p); /* Need to define this because of HPSA on porky! */ #define YYMAXDEPTH 20000 int v_lex (); int v_error (char *); %} %union { SDDAS_FLOAT dval; SDDAS_INT ival; SDDAS_CHAR cval; SDDAS_CHAR *sval; void *pval; symtab *sym; } /* All these are ivals since they tell the type of line */ %token Y_VIDF %token Y_STRUCT %token Y_CHAR %token Y_INT %token Y_FLOAT %token Y_STRING /* these are actual values */ %token Y_NAME %token Y_FLOAT_NUM %token Y_INT_NUM %token Y_QUOTED_STRING %type array_size %type array %type declarator %type initializer %type type_specifier %type struct_specifier %type struct_decl_list %type declaration_list %type declaration %type vidfdef %type type %% vidfdef: Y_VIDF declarator '{' declaration_list '}' { $$ = (symtab *) malloc (sizeof (symtab)); $$->symtype = $1; free ($2); $$->symname = strdup ("VIDF"); $$->ptr = vidf_get_list_head ((symtab *) $4); ((symtab *)$4)->parent = $$; $$->next = $$->prev = NULL; GLOBAL_VIDF = $$; } ; declarator: Y_NAME ; declaration_list: declaration { $$ = $1; } | declaration_list declaration { $1->next = $2; $2->prev = $1; $$ = $2; } ; declaration : type_specifier declarator '[' array_size ']' '=' '{' array '}' ';' { $1->symname = $2; $1->ptr = tmp_array.lval_ptr; $1->array_length = $4; $$ = $1; if (counter > 0) { yyerror ("WARNING: array size does not match the number of elements (too big)!"); } } declaration: type_specifier declarator '=' initializer ';' { $1->symname = $2; $1->ptr = $4; if ($1->symsize == 0) $1->symsize = strlen ((SDDAS_CHAR *) $1->ptr); $$ = $1; } | struct_specifier ';' { $$ = $1; } ; type_specifier: type { p = (symtab *) malloc ((size_t) sizeof (symtab)); p->symtype = $1; p->symsize = symsize; p->array_length = 1; p->next = p->prev = p->parent = NULL; $$ = p; } ; struct_specifier: Y_STRUCT declarator '{' struct_decl_list '}' { $$ = (symtab *) malloc (sizeof (symtab)); $$->symtype = $1; $$->symname = (char *)$2; $$->ptr = vidf_get_list_head ((symtab *)$4); ((symtab *)$4)->parent = $$; $$->next = $$->prev = NULL; } ; struct_decl_list: declaration { $$ = $1; } | struct_decl_list declaration { $1->next = $2; $2->prev = $1; $$ = $2;} ; type: Y_INT { symsize = sizeof (SDDAS_INT); symtype = $1; $$ = $1; } | Y_CHAR { symsize = sizeof (SDDAS_CHAR); symtype = $1; $$ = $1; } | Y_FLOAT { symsize = sizeof (SDDAS_FLOAT); symtype = $1; $$ = $1; } | Y_STRING { symsize = 0; symtype = $1; $$ = $1; } ; initializer: Y_QUOTED_STRING { $$ = (void *) $1; } | Y_FLOAT_NUM { memcpy ($$, $1, sizeof (SDDAS_FLOAT)); } | Y_INT_NUM { memcpy ($$, $1, sizeof (SDDAS_INT)); } ; array_size : Y_INT_NUM { counter = *((int *) $1); free ($1); switch (symtype) { case Y_STRING : tmp_array.lval_ptr = (SDDAS_INT *) malloc (counter * sizeof (SDDAS_CHAR *)); break; case Y_INT : tmp_array.lval_ptr = (SDDAS_INT *) malloc (counter * sizeof (SDDAS_INT)); break; case Y_FLOAT : tmp_array.dval_ptr = (SDDAS_FLOAT *) malloc (counter * sizeof (SDDAS_FLOAT)); break; } $$ = counter; /* set the array size to be a number for use above */ } ; array : initializer ',' array { counter--; if (counter < 0) { yyerror ("WARNING: array size does not match the number of elements (too small)!"); } else { switch (symtype) { case Y_STRING : tmp_array.str_ptr [counter] = (SDDAS_CHAR *) $1; break; case Y_INT : tmp_array.lval_ptr [counter] = *((SDDAS_INT *)$1); free ($1); break; case Y_FLOAT : tmp_array.dval_ptr [counter] = *((SDDAS_FLOAT *)$1); free ($1); break; } } } | initializer { counter--; if (counter < 0) { yyerror ("WARNING: array size does not match the number of elements (too small)!"); } else { switch (symtype) { case Y_STRING : tmp_array.str_ptr [counter] = (SDDAS_CHAR *) $1; $$ = (void *) tmp_array.str_ptr; /* free ($1); */ break; case Y_INT : tmp_array.lval_ptr [counter] = *((SDDAS_INT *)$1); free ($1); $$ = (void *) tmp_array.lval_ptr; break; case Y_FLOAT : tmp_array.dval_ptr [counter] = *((SDDAS_FLOAT *)$1); free ($1); $$ = (void *) tmp_array.dval_ptr; break; } /* switch */ } } ; %% extern FILE *yyin; /* Given a pointer into a list, return a pointer to the head of the list */ void *vidf_get_list_head (symtab *p) { while (p->prev != NULL) p = p->prev; return ((void *) p); }