X-Git-Url: https://www.kengrimes.com/gitweb/?p=henge%2Fapc.git;a=blobdiff_plain;f=src%2Fparser.y;h=e1fe89651eb15c4f9f1878f5f5351b602ffe4e86;hp=85c6c506c7325a0c0d3b237bdc846a3d57d2e526;hb=fc6b15eee27f77e01ed4a24bc11e7bfa5a812342;hpb=c6453f4b6219125bf45a61cde2f44bd7a3154e17 diff --git a/src/parser.y b/src/parser.y index 85c6c50..e1fe896 100644 --- a/src/parser.y +++ b/src/parser.y @@ -1,175 +1,183 @@ /* Asset Package Compiler */ -%code requires{ - #include + +%code requires { #include + #include "ir.h" #include "apc.h" + typedef struct class_state_t yycstate; + struct frame_spec_t { apc_facing d; int w, h; }; +} +%code provides { + yycstate* yycstate_new(void); + void yycstate_delete(yycstate*); } -%{ +%code { #include #include #include - - extern int lexer_init(); //? - extern int lexer(); //? - extern void pop_cdat(void); - extern void push_cdat(uint8_t*); - extern void insert_vdat(void); - extern void insert_refid(int); - extern void insert_set_name(uint8_t*); - extern void insert_set_namelist(uint8_t*); - extern void insert_link_name(uint8_t*); - extern void insert_map(int, uint8_t*, int, int, uint8_t*); - extern void insert_mlink(uint8_t*, int); - extern void insert_vlink(uint8_t*, int); - extern void insert_framesheet(uint_t* int, int, int,int, uint8_t*); + #include + #include "ir.h" - #define yylex lexer - - - void yyerror(); -%} + struct class_state_t { + ir_class *csp; + ir_class class_stack[]; + }; + + extern long sys_pagesize; + extern int lexer(); + 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 */ + #define yyclass(CS) (*(CS->csp)) + #define yyclassld(CS) (ir_classld_from_class(yyclass(CS))) + #define DEFAULT_VARIANT "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 { - int ref; - int val; - uint8_t *str; - struct name* name; - void *voidp; + 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; } - - //operators -%token CLOPEN // ( -%token CLCLOSE // ) -%token MOPEN // ~ -%token HB -%token ROOT -%token SS -%token LINK //# -%token SCLOSE -%token CHILD -//terminals -%token NUM -%token PATH -%token REF -%token HEIGHT -%token WIDTH -%token D -%token NAME -//nonterminals -%type ref_id - /* Syntax Directed Translation Scheme of the APC grammar */ - -/* Rules */ +/* Operators */ +%token CLOPEN //( +%token CLCLOSE //) +%token MAP //~ +%token AUDIO //AUDIO +%token SS //SS +%token LINK //# +/* Terminals */ +%token NUM +%token PATH +%token REF +%token FACING +%token NAME +/* Types */ +%type data_spec +%type set_spec +%type set_ld set_link +%type frame_spec %% -cdat_buf: -class_block -; - -class: -NAME CLOPEN {push_cdat($1);} class_block CLCLOSE {pop_cdat();}; +/* Syntax Directed Translation Scheme of the APC grammar */ +progn: + class_list +| class_list statement_list +| statement_list ; class_list: -class_list class + class_list class | class ; -class_block: -class_list -| class_list statement_list -| statement_list +class: + NAME CLOPEN { yyclass_push(cs,ir_class_addchild(yyclass(cs), $1)); } + progn + CLCLOSE { yyclass_pop(cs); } +| CLCLOSE { yyclass_pop(cs); } ; statement_list: -statement_list statement -| statement + statement_list statement +| statement ; statement: -vdat_statement -| map_statement -| ref_statement -| olink + 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); } ; -ref_statement: -set_namelist ref_id {insert_set_refid($2);}; +data_spec: + SS NAME frame_spec { $$ = ir_framesheet($2,$3.d,$3.w,$3.h); } +| SS frame_spec { $$ = ir_framesheet(DEFAULT_VARIANT,$2.d,$2.w,$2.h); } +| MAP NAME frame_spec { $$ = ir_mapsheet($2,$3.d,$3.w,$3.h); } +| MAP frame_spec { $$ = ir_mapsheet(DEFAULT_VARIANT,$2.d,$2.w,$2.h); } +| AUDIO NAME { $$ = ir_audio($2); } +| 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); } ; -link_namelist: -link_namelist NAME {insert_link_name($2);}; -| NAME {}; +set_spec: + set_spec NAME { $$ = ir_set_addchild($1,$2); } +| NAME { $$ = ir_class_addset(yyclass(cs),$1); } ; - -set_namelist: -set_namelist NAME {insert_set_name($2);}; -| NAME {insert_set_namelist($1);}; -; - -map_statement: -set_namelist MOPEN map -| set_namelist MOPEN mlink -; - -map: -NAME NUM NUM PATH {insert_map(0, $1, $2, $3, 0, $4);}; -| NAME PATH {insert_map($1, 0, 0, 0, 0, $2);}; -| NAME D PATH {insert_map($1, $2, 0, 0, 0, $3);}; -| NAME D NUM NUM PATH {insert_map($1, $2, $3, $4, 0, $5);}; -| NAME NUM NUM ref_id PATH {insert_map($1, 0, $2, $3, $4, $5);}; -| NAME ref_id PATH {insert_map($1, 0, 0, 0, $2, $3);}; -| NAME D ref_id PATH {insert_map($1, $2, 0, 0, $3, $4);}; -| NAME D NUM NUM ref_id PATH {insert_map($1, $2, $3, $4, $5, $6);}; +set_link: + set_link NAME { $$ = ir_setld_addchild($1,$2); } +| NAME { $$ = ir_setld_from_classld(yyclassld(cs),$1); } ; -//shift list_namelist name > reduce mlink -mlink: -MOPEN LINK NAME LINK link_namelist PATH {insert_mlink($3, 0); }; -| MOPEN LINK link_namelist PATH {insert_mlink(NULL, 0); }; -| MOPEN LINK ref_id PATH {insert_mlink(NULL, $3); }; -| MOPEN LINK NAME LINK ref_id PATH {insert_mlink($3,$5); }; +set_ld: + set_link { $$ = $1; } +| REF { $$ = ir_setld_from_ref($1); } ; -//shift list_namelist name > reduce vlink -vlink: -LINK NAME LINK link_namelist PATH {insert_vlink($2, 0); }; -| LINK link_namelist PATH {insert_vlink(NULL, 0);}; -| LINK REF PATH {insert_vlink(NULL, $2);};//vdat of ref -| LINK NAME LINK REF PATH {insert_vlink($2, $4);};//modelname of ref +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}; } +| %empty { $$ = (struct frame_spec_t) {SFACE,0,0}; } ; +%% -olink: -set_namelist MOPEN REF -; - -ref_id: -LINK REF {$$ = $2;}; -; - +static +void yyerror +( 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)); + fprintf(stderr, "]\n\t"); + fprintf(stderr, "%s\n", s); +} -vdat_statement: -set_namelist SS spritesheet_statement -| set_namelist SS vlink -; +yycstate* yycstate_new +( void ) +{ yycstate* class_state; + class_state = (yycstate*) malloc((size_t) sys_pagesize); + if(class_state == NULL) + { yyerror(class_state, "Memory allocation error."); + return NULL; + } + class_state->csp = class_state->class_stack; + *(class_state->csp) = ir_class_root(); + return class_state; +} -spritesheet_statement: -NAME D HEIGHT WIDTH PATH {insert_framesheet($1, $2, $3, $4, 0, $5);}; -| NAME D PATH {insert_framesheet($1, $2, 0, 0, 0, $3);}; -| NAME HEIGHT WIDTH PATH {insert_framesheet($1, 0, $2, $3, 0, $4);}; -| NAME PATH {insert_framesheet($1, 0, 0, 0, 0, $2);}; -| NAME D HEIGHT WIDTH ref_id PATH {insert_framesheet($1, $2, $3, $4, $5, $6);}; -| NAME D ref_id PATH {insert_framesheet($1, $2, 0, 0, $3, $4);}; -| NAME HEIGHT WIDTH ref_id PATH {insert_framesheet($1, 0, $2, $3, $4, $5);}; -| NAME ref_id PATH {insert_framesheet($1, 0, 0, 0, $2, $3);}; -; +static inline +ir_class yyclass_pop +( yycstate* cs ) +{ cs->csp--; + return *(cs->csp + 1); +} -%% +static inline +ir_class yyclass_push +( yycstate* cs, + ir_class class +) +{ return *++(cs->csp) = class; } -void -yyerror (char const *s) -{ fprintf(stderr, "%s\n", s); -} +void yycstate_delete +( yycstate* class_state ) +{ free(class_state); }