parser.y (1382B)
1 %code requires { 2 #include "generator.h" 3 #include <stdarg.h> 4 } 5 6 %define api.value.type union 7 %token <char *> n LITERAL COMMENT PROLOGUE EPILOGUE 8 9 %type <record_t *> record 10 %type <list_t *> list items 11 %type <char *> name 12 13 %token EOL COMMA SWITCH EMPTY 14 15 %code provides { 16 int yylex(void); 17 int yyparse(void); 18 void yyrestart(FILE *); 19 int yylex_destroy(void); 20 21 extern list_t records; 22 extern list_t epilogue; 23 extern list_t prologue; 24 } 25 26 %destructor { free($$); } <char *> 27 28 %start document 29 30 %% 31 32 document: prologue grammar epilogue 33 34 prologue: %empty 35 | prologue PROLOGUE { list_append(&prologue, node_new($2)); } 36 ; 37 38 epilogue: SWITCH 39 | epilogue EPILOGUE { list_append(&epilogue, node_new($2)); } 40 ; 41 42 grammar: SWITCH 43 | grammar EOL 44 | grammar record { list_append(&records, node_new((char *)$2)); } 45 ; 46 47 record: name list list list { $$ = record_new($1, $2, $3, $4); } 48 | COMMENT { $$ = record_new($1, NULL, NULL, NULL); } 49 ; 50 51 name: LITERAL EOL { $$ = $1; } 52 ; 53 54 list: EMPTY { $$ = NULL; } 55 | items EOL { $$ = $1; } 56 ; 57 58 items: LITERAL { $$ = list_new($1); } 59 | items COMMA LITERAL { list_append($1, node_new($3)); $$ = $1; } 60 ; 61 62 %% 63 64 void yyerror(char *s, ...) { 65 va_list ap; 66 va_start(ap, s); 67 68 fprintf(stderr, "%d: error: ", yylineno); 69 vfprintf(stderr, s, ap); 70 fprintf(stderr, "\n"); 71 } 72