comments updated
[henge/apc.git] / src / parser.y
index 2ff1638..2c74db7 100644 (file)
@@ -5,7 +5,7 @@
   #include "ir.h"
   #include "apc.h"
   typedef struct class_state_t yycstate;
-  struct frame_spec_t { apc_facing d; int w, h; };
+  struct frame_spec_t { facinglist list; int w, h; };
 }
 %code provides {
   yycstate* yycstate_new(void);
   /* Stack-based class handler */
   #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;
+  uint32_t   ref;
   int        val;
-  apc_facing  face;
+  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    //(
 %token <face> FACING
 %token <str>  NAME
 /* Types */
-%type<data>       data_spec
-%type<set>        set_spec
-%type<ld>         set_ld set_link
-%type<frame_spec> frame_spec
+%type<data>        data_spec
+%type<set>         set_spec
+%type<ld>          set_ld set_link
+%type<frame_spec>  frame_spec
+%type<facinglist>  facing_list
 %%
 /* Syntax Directed Translation Scheme of the APC grammar */
 progn:
   class_list 
 | class_list statement_list
+| statement_list class_list
 | statement_list
 ;
 
@@ -90,15 +95,17 @@ 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(OLINK, $2, NULL); }
 | LINK set_ld MAP        { $$ = ir_link(MLINK, $2,NULL); }
@@ -124,10 +131,15 @@ 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}; }
 ;
 
 %%
@@ -137,7 +149,15 @@ void yyerror
 ( yycstate* cs,
   char const *s
 )
-{ fprintf(stderr, "%s\n", 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);
+}
 
 yycstate* yycstate_new
 ( void )
@@ -155,7 +175,7 @@ yycstate* yycstate_new
 static inline
 ir_class yyclass_pop
 ( yycstate* cs )
-{ return *((cs->csp)--); }
+{ return *cs->csp--; }
 
 static inline
 ir_class yyclass_push