/* * $Id: grammar.y,v 1.12 2000-04-17 07:21:24 krueger Exp $ */ %{ #include #include #include #include #include #include #include #include #include "modgen.h" #include "stype.h" int sectnum = 1; int iseof = 0; extern moddef module_def; extern int yylineno; extern int do_create_makefile; extern int init_modgen(moddef *module_def, char *filename); extern int write_intro(moddefv module); extern void write_mod_init(moddefv module, FILE *fp); extern void enter_id(FILE *fp, char *name, char *value, int lineno, char *file); procdef procedure_decl; void yyerror(char * fmt) { if(!iseof) printf("%s at line %d\n", fmt, yylineno); } %} /* %expect 22 */ %pure_parser %token MCOLONCOLON %token MEQUAL /* special symbols */ %token MMODULE_CMD %token MVERSION_CMD %token MINFO_CMD %token MINFOFILE_CMD %token MHELP_CMD %token MHELPFILE_CMD %token MCXXSRC_CMD %token MPROC_CMD %token SECTEND %token SECT2END %token SECT3END /*%token PROCEND*/ %token PROCDECLTOK %token EXAMPLETOK %token STATICTOK /* BISON Declarations */ %token VARNAMETOK /*%token MSTRINGTOK */ %token MSTRINGTOK %token NAME %token FILENAME %token MCCODETOK %token MCODETOK %token CODEPART %token PROCCMD %token ANYTOK %token VARTYPETOK %token NUMTOK %token BOOLTOK %type '=' %type identifier %nonassoc '=' %% goal: part1 sect2 sect2end code { if(trace)printf("Finish modules\n"); return 0; } ; part1: initmod sect1 sect1end { if(do_create_makefile)mod_create_makefile(&module_def); if(write_intro(&module_def)) { return(myyyerror("Error while creating files\n")); } } | sect1 sect1end { write_mod_init(&module_def, module_def.fmtfp); if(do_create_makefile)mod_create_makefile(&module_def); if(write_intro(&module_def)) { return(myyyerror("Error while creating files\n")); } } | sect1end { write_mod_init(&module_def, module_def.fmtfp); if(do_create_makefile)mod_create_makefile(&module_def); if(write_intro(&module_def)) { return(myyyerror("Error while creating files\n")); } }; initmod: MCCODETOK { fprintf(module_def.fmtfp, "%s", $1); fprintf(module_def.fmtfp, "#line %d \"%s\"\n", yylineno, module_def.filename); free($1); write_mod_init(&module_def, module_def.fmtfp); } sect1: expr ';' | sect1 expr ';' ; sect1end: SECTEND { memset(&procedure_decl, 0, sizeof(procdef)); if(debug>2)printf("End of section %d\n", sectnum-1); } ; expr: NAME '=' MSTRINGTOK { var_token vt; int rc = 0; void (*write_cmd)(moddefv module, var_token type = VAR_NONE, idtyp t, void *arg1 = NULL, void *arg2 = NULL); switch(sectnum) { case 1: /* pass 1: */ if( (vt=checkvar($1, VAR_STRING, &write_cmd)) ) { if(write_cmd!=0) write_cmd(&module_def, vt, STRING_CMD, $1, $3.string); if(vt==VAR_VERSION) make_version($3.string, &module_def); } else { rc=myyyerror("Line %d: Unknown variable '%s' in section %d\n", yylineno, $1, sectnum); } break; case 2: /* pass 2: procedure declaration */ if( (vt=checkvar($1, VAR_STRING, &write_cmd)) ) { proc_set_var(&procedure_decl, VAR_STRING, vt, $1, $3.string); } else { rc=myyyerror("Line %d: Unknown variable '%s' in section %d\n", yylineno, $1, sectnum); } break; default: break; } free($1); free($3.string); if(rc)return(rc); } | NAME '=' FILENAME { var_token vt; void (*write_cmd)(moddefv module, var_token type = VAR_NONE, idtyp t, void *arg1 = NULL, void *arg2 = NULL); switch(sectnum) { case 1: /* pass 1: */ Add2files(&module_def, $3); break; case 2: /* pass 2: procedure declaration */ if( (vt=checkvar($1, VAR_FILE, &write_cmd)) ) { proc_set_var(&procedure_decl, VAR_FILE, vt, $1, $3); } break; default: break; } free($1); free($3); } | NAME '=' files { var_token vt; void (*write_cmd)(moddefv module, var_token type = VAR_NONE, idtyp t, void *arg1 = NULL, void *arg2 = NULL); switch(sectnum) { case 1: /* pass 1: */ break; case 2: /* pass 2: procedure declaration */ if( (vt=checkvar($1, VAR_FILES, &write_cmd)) ) { proc_set_var(&procedure_decl, VAR_FILES, vt, $1, &$3); } break; default: break; } free($1); //free($3); } | NAME '=' NUMTOK { var_token vt; void (*write_cmd)(moddefv module, var_token type = VAR_NONE, idtyp t, void *arg1 = NULL, void *arg2 = NULL); switch(sectnum) { case 1: /* pass 1: */ break; case 2: /* pass 2: procedure declaration */ if( (vt=checkvar($1, VAR_NUM, &write_cmd)) ) { proc_set_var(&procedure_decl, VAR_NUM, vt, $1, &$3); } break; default: break; } free($1); } | NAME '=' BOOLTOK { var_token vt; int rc = 0; void (*write_cmd)(moddefv module, var_token type = VAR_NONE, idtyp t, void *arg1 = NULL, void *arg2 = NULL); switch(sectnum) { case 1: /* pass 1: */ if( (vt=checkvar($1, VAR_BOOL, &write_cmd)) ) { proc_set_default_var(VAR_BOOL, vt, $1, &$3); } else { rc=myyyerror("Line %d: Unknown variable '%s' in section %d\n", yylineno, $1, sectnum); } break; case 2: /* pass 2: procedure declaration */ if( (vt=checkvar($1, VAR_BOOL, &write_cmd)) ) { proc_set_var(&procedure_decl, VAR_BOOL, vt, $1, &$3); } else { rc=myyyerror("Line %d: Unknown variable '%s' in section %d\n", yylineno, $1, sectnum); } break; default: break; } free($1); if(rc)return(rc); } ; files: FILENAME ',' FILENAME { if(debug>2)printf(">>>>>>>>files '%s' , '%s'\n", $1, $3); Add2files(&module_def, $1); Add2files(&module_def, $3); free($1); free($3); } ; sect2: procdef | sect2 procdef ; sect2end: SECT2END { write_finish_functions(&module_def, &procedure_decl); if(debug>2)printf("End of section %d\n", sectnum-1); } ; /* */ procdef: procdecl proccode { if(debug>2)printf("PROCDEF:\n"); } | procdecl proccode procdeclexample { if(debug>2)printf("PROCDEF mit example:\n"); fflush(module_def.fmtfp); } ; procdecl: procdecl2 '{' { setup_proc(&module_def, &procedure_decl); } | procdecl2 procdeclhelp '{' { setup_proc(&module_def, &procedure_decl); } ; procdecl1: PROCDECLTOK NAME { init_proc(&procedure_decl, $2, NULL, yylineno, LANG_SINGULAR); free($2); if(write_singular_procedures(&module_def, &procedure_decl)) return(myyyerror("Error while creating bin-file\n")); } | STATICTOK PROCDECLTOK NAME { init_proc(&procedure_decl, $3, NULL, yylineno, LANG_SINGULAR); procedure_decl.is_static = TRUE; free($3); if(write_singular_procedures(&module_def, &procedure_decl)) return(myyyerror("Error while creating bin-file\n")); }; procdecl2: procdecl1 '(' sgtypelist ')' | funcdecl1 | funcdecl1 '(' ')' | funcdecl1 '(' typelist ')' | procdecl1 { write_singular_parameter(&module_def, yylineno, "list", "#"); procedure_decl.lineno_other = yylineno; } | procdecl1 '(' ')' { write_singular_parameter(&module_def, yylineno, "list", "#"); procedure_decl.lineno_other = yylineno; } ; funcdecl1: NAME { if(debug>2)printf("funcdecl1-1\n"); init_proc(&procedure_decl, $1, NULL, yylineno); free($1); } | VARTYPETOK NAME { if(debug>2)printf("funcdecl1-2\n"); init_proc(&procedure_decl, $2, &$1, yylineno); free($2); } | STATICTOK NAME { if(debug>2)printf("funcdecl1-3\n"); init_proc(&procedure_decl, $2, NULL, yylineno); free($2); procedure_decl.is_static = TRUE; } | STATICTOK VARTYPETOK NAME { if(debug>2)printf("funcdecl1-4\n"); init_proc(&procedure_decl, $3, &$2, yylineno); free($3); procedure_decl.is_static = TRUE; }; procdeclhelp: MSTRINGTOK { procedure_decl.help_string = $1.string; procedure_decl.lineno_other = $1.lineno; if(debug>2)printf("\t\thelp at %d\n", yylineno); write_help(&module_def, &procedure_decl); } ; proccode: proccodeline MCODETOK { write_function_errorhandling(&module_def, &procedure_decl); }; proccodeline: CODEPART { write_codeline(&module_def, &procedure_decl, $1, yylineno-1); } | proccodeline CODEPART { write_codeline(&module_def, &procedure_decl, $2); } | proccodeline proccmd { }; procdeclexample: examplestart '{' examplecodeline MCODETOK { write_example(&module_def, &procedure_decl); } ; examplestart: EXAMPLETOK { if(procedure_decl.procname == NULL) { return(myyyerror("example without proc-declaration at line %d\n", yylineno)); } if(debug>2)printf("Example at %d\n", yylineno); procedure_decl.lineno_other = yylineno; }; examplecodeline: CODEPART { int len = strlen($1); procedure_decl.example_len = len; procedure_decl.example_string = (char *)malloc(len+1); memset(procedure_decl.example_string, 0, len+1); memcpy(procedure_decl.example_string, $1, len); } | examplecodeline CODEPART { long len = strlen($2); long newlen = procedure_decl.example_len + len; procedure_decl.example_string = (char *)realloc((void *)procedure_decl.example_string, newlen+1); memset(procedure_decl.example_string+procedure_decl.example_len, 0, len+1); memcpy(procedure_decl.example_string+procedure_decl.example_len, $2, len); procedure_decl.example_len = newlen; //strncat(procedure_decl.example_string, $2, strlen($2)); //procedure_decl.example_string[procedure_decl.example_len] = '\0'; }; proccmd: '%' NAME ';' { cmd_token vt; void (*write_cmd)(moddefv module, procdefv pi, void *arg = NULL); switch(vt=checkcmd($2, &write_cmd, CMDT_SINGLE, 0)) { case CMD_NONE: return(myyyerror("Line %d: Unknown command '%s' in section %d\n", yylineno, $2, sectnum)); break; case CMD_BADSYNTAX: return(myyyerror("Line %d: bad syntax of command '%s' in section %d\n", yylineno, $2, sectnum)); break; default: write_cmd(&module_def, &procedure_decl); } free($2); } | '%' NAME '(' ')' ';' { cmd_token vt; void (*write_cmd)(moddefv module, procdefv pi, void *arg = NULL); switch(vt=checkcmd($2, &write_cmd, CMDT_0, 1)) { case CMD_NONE: return(myyyerror("Line %d: Unknown command '%s' in section %d\n", yylineno, $2, sectnum)); break; case CMD_BADSYNTAX: return(myyyerror("Line %d: bad syntax of command '%s' in section %d\n", yylineno, $2, sectnum)); break; default: write_cmd(&module_def, &procedure_decl, procedure_decl.procname); } free($2); } | '%' NAME '(' NAME ')' ';' { cmd_token vt; void (*write_cmd)(moddefv module, procdefv pi, void *arg = NULL); switch(vt=checkcmd($2, &write_cmd, CMDT_ANY, 1)) { case CMD_NONE: return(myyyerror("Line %d: Unknown command '%s' in section %d\n", yylineno, $2, sectnum)); break; case CMD_BADSYNTAX: return(myyyerror("Line %d: bad syntax of command '%s' in section %d\n", yylineno, $2, sectnum)); break; default: write_cmd(&module_def, &procedure_decl, $4); } free($2); free($4); } | '%' NAME '(' identifier '(' arglist ')' ')' ';' { cmd_token vt; void (*write_cmd)(moddefv module, procdefv pi, void *arg = NULL); switch(vt=checkcmd($2, &write_cmd, CMDT_ANY, 1)) { case CMD_NONE: return(myyyerror("Line %d: Unknown command '%s' in section %d\n", yylineno, $2, sectnum)); break; case CMD_BADSYNTAX: return(myyyerror("Line %d: bad syntax of command '%s' in section %d\n", yylineno, $2, sectnum)); break; default: write_cmd(&module_def, &procedure_decl, $4); } free($2); } | '%' NAME MEQUAL ANYTOK { cmd_token vt; void (*write_cmd)(moddefv module, procdefv pi, void *arg = NULL); switch(vt=checkcmd($2, &write_cmd, CMDT_EQ, 0)) { case CMD_NONE: return(myyyerror("Line %d: Unknown command '%s' in section %d\n", yylineno, $2, sectnum)); break; case CMD_BADSYNTAX: return(myyyerror("Line %d: bad syntax of command '%s' in section %d\n", yylineno, $2, sectnum)); break; default: write_cmd(&module_def, &procedure_decl, $4); } free($2); }; identifier: NAME { if(debug>2)printf("### ID ### Name %s\n", $1); $$ = $1; } | identifier MCOLONCOLON NAME { int len = strlen($$) + strlen($3) + 2; if(debug>2)printf("### ID ### Name %s\n", $3); $$ = (char *)realloc($$, len); strcat($$, "::"); strcat($$, $3); }; arglist: NAME { if(debug>2)printf("### ARGS %s\n", $1); } | arglist ',' NAME { if(debug>2)printf("### ARGS %s\n", $3); }; sgtypelist: VARTYPETOK NAME { if(debug>2)printf("\tsgtypelist %s %s\n", $1.name, $2); write_singular_parameter(&module_def, yylineno, $1.name, $2); free($1.name); free($2); } | VARTYPETOK '#' { if(debug>2)printf("\tsgtypelist %s %s\n", $1.name, $2); write_singular_parameter(&module_def, yylineno, $1.name, "#"); free($1.name); } | sgtypelist ',' VARTYPETOK NAME { if(debug>2)printf("\tsgtypelist next %s %s\n", $3.name, $4); write_singular_parameter(&module_def, yylineno, $3.name, $4); free($3.name); free($4); } | sgtypelist ',' VARTYPETOK '#' { if(debug>2)printf("\tsgtypelist next %s %s\n", $3.name, $4); write_singular_parameter(&module_def, yylineno, $3.name, "#"); free($3.name); } ; typelist: VARTYPETOK { AddParam(&procedure_decl, &$1); free($1.name); } | VARTYPETOK NAME { if(check_reseverd($2)) return(myyyerror("Line %d: variablename '%s' is reserved\n", yylineno, $2)); AddParam(&procedure_decl, &$1, $2); free($1.name); free($2); } | typelist ',' VARTYPETOK { AddParam(&procedure_decl, &$3); free($3.name); } | typelist ',' VARTYPETOK NAME { if(check_reseverd($4)) return(myyyerror("Line %d: variablename '%s' is reserved\n", yylineno, $4)); AddParam(&procedure_decl, &$3, $4); free($3.name); free($4); } ; code: codeline SECT3END { fprintf(module_def.modfp, "%s", $1); } ; codeline: CODEPART { fprintf(module_def.modfp, "#line %d \"%s\"\n", yylineno, module_def.filename); } | codeline CODEPART { } ; %%