%{ /* sd_yacc.y yacc syntactical description of Etak stack definition language, sd. */ typedef char *charptr; #define YYSTYPE charptr %} %start sd %token NAME OTHER INCLUDE DEFINE LINK %% sd: includes defines stacks { printf("Done.\n"); } ; includes: /* none */ | includes include ; include: INCLUDE NAME { include_on = 1; sd_temp_fd = sd_fd; if ((sd_fd = fopen($2,"r"))==NULL) { printf("sd2rpl: couldn't open include %s. Exiting.\n", $2); exit (0); } printf("%s included\n",$2); } ; defines: /* none */ | defines define ; define: DEFINE NAME '{' cards '}' { define_on = 1; /* save the definition for use during replacement by yylex */ sd_defs[sd_defs_index].name = $2; sd_defs[sd_defs_index].text = $4; sd_defs_index++; /* note that later defs of the same name replace older ones, which may be just the behavior we want. */ printf("%s defined\n",$2); } ; cards: /* none */ { if (define_on) { $$ = ""; } } | cards card { if (define_on) { $$ = malloc(strlen($1)+3+strlen($2)); sprintf($$,"%s %s",$1,$2); } } ; card: '#' NAME param_list cases { if (define_on) { $$ = malloc(strlen($2)+4+strlen($3)+strlen($4)); sprintf($$,"# %s %s %s",$2,$3,$4); } else { stacks[stack_index].cards[card_index].name = $2; card_index++; param_list = 0; } printf("card %s used\n",$2); } ; param_list: '(' params ')' { if (define_on) { $$ = malloc(strlen($2)+3); sprintf($$,"(%s)",$2); } else { param_list++; param_number = 0; } } ; params: /* none */ { if (define_on) { $$ = ""; } } | NAME { if (define_on) { $$ = $1; } else { stacks[stack_index].cards[card_index]. params[param_list][param_number] = $1; param_number++; } } | params ','NAME { if (define_on) { $$ = malloc(strlen($1)+3+strlen($3)); sprintf($$,"%s,%s",$1,$3); } else { stacks[stack_index].cards[card_index]. params[param_list][param_number] = $3; param_number++; } } ; cases: /* none */ { if (define_on) { $$ = ""; } } | cases case { if (define_on) { $$ = malloc(strlen($1)+3+strlen($2)); sprintf($$,"%s %s",$1,$2); } } ; case: '(' case_params ')' { if (define_on) { $$ = malloc(strlen($2)+3); sprintf($$,"(%s)",$2); } else { param_list++; param_number = 0; } } ; case_params: case_param { if (define_on) { $$ = $1; } } | case_params ',' case_param { if (define_on) { $$ = malloc(strlen($1)+3+strlen($3)); sprintf($$,"%s,%s",$1,$3); } } ; case_param: /* none */ { if (define_on) { $$ = ""; } } | OTHER { $$ = $1; } | LINK { $$ = $1; } | NAME { $$ = $1; } ; stacks: stack | stacks stack ; stack: '-' NAME ',' NAME cards { stacks[stack_index].name1 = $2; stacks[stack_index].name2 = $4; stack_index++; card_index = 0; printf("stack %s , %s defined \n",$2,$4); } ; %% #include "sd_lex.c" yyerror() { printf("Syntax error on line %d: %s Exiting\n",yylineno,yytext); }