X-Git-Url: https://www.kengrimes.com/gitweb/?p=henge%2Fapc.git;a=blobdiff_plain;f=src%2Fparser.y;h=2c74db709d4d58208bdcadb15920cdb57d33f6de;hp=537b2300c493f16c0257af74d1d9ac0f6177e985;hb=HEAD;hpb=91df32369f5391048ef9ef6566ea17c97174f5d9 diff --git a/src/parser.y b/src/parser.y index 537b230..2c74db7 100644 --- a/src/parser.y +++ b/src/parser.y @@ -1,58 +1,55 @@ /* Asset Package Compiler */ -%code requires { +%code requires { #include + #include "ir.h" + #include "apc.h" typedef struct class_state_t yycstate; - + struct frame_spec_t { facinglist list; int w, h; }; +} +%code provides { yycstate* yycstate_new(void); - void yycstate_delete(yycstate*); + void yycstate_delete(yycstate*); } - -%{ +%code { #include #include #include #include #include "ir.h" - + struct class_state_t { ir_class *csp; - size_t class_stack_size; - ir_class *class_stack; - + ir_class class_stack[]; }; - struct frame_spec_t { enum facing d; int w, h; }; - extern long sys_pagesize; extern int lexer(); - static void yyerror(char const*); + static void yyerror(yycstate*, char const*); + static inline ir_class yyclass_push(yycstate*, ir_class); + static inline ir_class yyclass_pop(yycstate*); /* Stack-based class handler */ - static ir_class class_stack_init(void); - #define class_stack_pop() (*--csp) - static ir_class class_stack_push(ir_class); - - #define yylex lexer - #define yyclass (*csp) - #define yyclassld (ir_classld_from_class(yyclass)) - - -%} + #define yyclass(CS) (*(CS->csp)) + #define yyclassld(CS) (ir_classld_from_class(yyclass(CS))) + #define DEFAULT_VARIANT (uint8_t*)"default" +} %define parse.error verbose +%define parse.lac full %define lr.type ielr %define api.pure full %define api.push-pull push %parse-param {yycstate* cs} %union { - long long ref; - int val; - enum facing face; - uint8_t* str; - ir_class class; - ir_set set; - ir_setld ld; - ir_setdata data; + uint32_t ref; + int val; + apc_facing face; + uint8_t* str; + ir_class class; + ir_set set; + ir_setld ld; + ir_setdata data; struct frame_spec_t frame_spec; + facinglist facinglist; } /* Operators */ %token CLOPEN //( @@ -68,17 +65,17 @@ %token FACING %token NAME /* Types */ -%type data_spec -%type set_spec -%type set_ld set_link -%type frame_spec -/* Init */ -%initial-action { class_stack_init(); } +%type data_spec +%type set_spec +%type set_ld set_link +%type frame_spec +%type facing_list %% /* Syntax Directed Translation Scheme of the APC grammar */ progn: class_list | class_list statement_list +| statement_list class_list | statement_list ; @@ -88,9 +85,9 @@ class_list: ; class: - NAME CLOPEN { class_stack_push(ir_class_addchild(yyclass, $1)); } + NAME CLOPEN { yyclass_push(cs,ir_class_addchild(yyclass(cs), $1)); } progn - CLCLOSE { class_stack_pop(); } + CLCLOSE { yyclass_pop(cs); } ; statement_list: @@ -98,33 +95,35 @@ statement_list: | statement ; -statement: + statement: set_spec data_spec REF PATH { ir_data_assign_path($2,$4); ir_set_assign_data($1,$2); ir_set_assign_ref($1,$3); } | set_spec data_spec PATH { ir_data_assign_path($2,$3); ir_set_assign_data($1,$2); } | set_spec REF PATH { ir_set_assign_ref($1,$2); } ; data_spec: - SS NAME frame_spec { $$ = ir_framesheet($2,$3.d,$3.w,$3.h); } -| MAP NAME frame_spec { $$ = ir_mapsheet($2,$3.d,$3.w,$3.h); } + SS NAME frame_spec { $$ = ir_framesheet($2,$3.list,$3.w,$3.h); } +| SS frame_spec { $$ = ir_framesheet(DEFAULT_VARIANT,$2.list,$2.w,$2.h); } +| MAP NAME frame_spec { $$ = ir_mapsheet($2,$3.list,$3.w,$3.h); } +| MAP frame_spec { $$ = ir_mapsheet(DEFAULT_VARIANT,$2.list,$2.w,$2.h); } | AUDIO NAME { $$ = ir_audio($2); } -| LINK set_ld { $$ = ir_link_odat($2); } -| LINK set_ld MAP { $$ = ir_link_mdat($2,NULL); } -| LINK set_ld MAP NAME { $$ = ir_link_mdat($2,$4); } -| LINK set_ld SS { $$ = ir_link_vdat($2,NULL); } -| LINK set_ld SS NAME { $$ = ir_link_vdat($2,$4); } -| LINK set_ld AUDIO { $$ = ir_link_adat($2,NULL); } -| LINK set_ld AUDIO NAME { $$ = ir_link_adat($2,$4); } +| LINK set_ld { $$ = ir_link(OLINK, $2, NULL); } +| LINK set_ld MAP { $$ = ir_link(MLINK, $2,NULL); } +| LINK set_ld MAP NAME { $$ = ir_link(MLINK, $2,$4); } +| LINK set_ld SS { $$ = ir_link(VLINK, $2,NULL); } +| LINK set_ld SS NAME { $$ = ir_link(VLINK, $2,$4); } +| LINK set_ld AUDIO { $$ = ir_link(ALINK, $2,NULL); } +| LINK set_ld AUDIO NAME { $$ = ir_link(ALINK, $2,$4); } ; set_spec: - set_spec NAME { $$ = ir_set_addchild($1,$2); } -| NAME { $$ = ir_class_addset(yyclass,$1); } + set_spec NAME { $$ = ir_set_addchild($1,$2); } +| NAME { $$ = ir_class_addset(yyclass(cs),$1); } ; set_link: set_link NAME { $$ = ir_setld_addchild($1,$2); } -| NAME { $$ = ir_setld_from_classld(yyclassld,$1) } +| NAME { $$ = ir_setld_from_classld(yyclassld(cs),$1); } ; set_ld: @@ -132,92 +131,59 @@ set_ld: | REF { $$ = ir_setld_from_ref($1); } ; +facing_list: + facing_list FACING { $$ = ir_facinglist_push($1,$2); } +| FACING { $$ = ir_facinglist($1); } + frame_spec: - NUM NUM { $$ = (struct frame_spec_t) {SFACE,$1,$2}; } -| FACING { $$ = (struct frame_spec_t) {$1,0,0}; } -| FACING NUM NUM { $$ = (struct frame_spec_t) {$1,$2,$3}; } + NUM NUM { $$ = (struct frame_spec_t) {NULL,$1,$2}; } +| facing_list { $$ = (struct frame_spec_t) {$1,0,0}; } +| facing_list NUM NUM { $$ = (struct frame_spec_t) {$1,$2,$3}; } +| %empty { $$ = (struct frame_spec_t) {NULL,0,0}; } ; %% -#define ERR_ALLOC "memory allocation error\n" - -/* print to stderr */ static void yyerror -( char const *s ) -{ fprintf(stderr, "%s\n", s); } - -/* Initialize the class stack - If the class_stack hasn't been allocated yet, allocates a page for pointers - to be stored in. Initializes class stack pointer, and inserts the root class - from IR - Returns the root class given by IR. -*/ -static -ir_class class_stack_init -( void ) -{ if (class_stack == NULL) - { class_stack_size = (size_t) sys_pagesize; - class_stack = (ir_class*) malloc(class_stack_size); - if (class_stack == NULL) - { yyerror(ERR_MEM); - exit(1); - } - } - csp = class_stack; - return class_stack_push(ir_class_root()); +( yycstate* cs, + char const *s +) +{ ir_class* iter; + fprintf(stderr, "[class->"); + for (iter = cs->class_stack; iter <= cs->csp; iter++) + fprintf(stderr, "%s/", ir_class_name(*iter)); + if (strstr(s,"unexpected CLCLOSE") != NULL) + yyclass_pop(cs); + fprintf(stderr, "]\n\t"); + fprintf(stderr, "%s\n", s); } -/* Add a Class to the Stack - Allocated in page-sized chunks, potentially infinite depth is supported. - Returns the input class. -*/ -static -ir_class class_stack_push -#define class_size (sizeof(*class_stack)) -( ir_class class ) -{ size_t class_stack_len = csp - class_stack; - ir_class* new_class_stack; - if ((class_stack_len * class_size + class_size) > class_stack_size) - { class_stack_size += (size_t) sys_pagesize; - new_class_stack = (ir_class*) realloc(class_stack, class_stack_size); - if (new_class_stack == NULL) - { free(class_stack); //realloc failure does not free class_stack - yyerror("realloc " ERR_MEM); - exit(1); - } - class_stack = new_class_stack; - csp = class_stack + class_stack_len; - } - return (*csp++ = class); -} - -yycstate* -yycstate_new +yycstate* yycstate_new ( void ) { yycstate* class_state; - class_state = (yycstate*) malloc((size_t) sys_pagesize); - if(class_state == NULL) - { yyerror(ERR_MEM); - exit(1); + { yyerror(class_state, "Memory allocation error."); + return NULL; } - - class_state.class_stack = class_stack; - class_state.csp = class_state.class_stack; - class_state.class_stack_size = (size_t) sys_pagesize; - class_stack_push(ir_class_root()); - + class_state->csp = class_state->class_stack; + *(class_state->csp) = ir_class_root(); return class_state; - } -void -yycstate_delete +static inline +ir_class yyclass_pop +( yycstate* cs ) +{ return *cs->csp--; } + +static inline +ir_class yyclass_push +( yycstate* cs, + ir_class class +) +{ return *++(cs->csp) = class; } + +void yycstate_delete ( yycstate* class_state ) -{ - free(class_state); - -} +{ free(class_state); }