comments updated
[henge/apc.git] / src / parser.y
1 /* Asset Package Compiler */
2
3 %code requires {
4 #include <unitypes.h>
5 #include "ir.h"
6 #include "apc.h"
7 typedef struct class_state_t yycstate;
8 struct frame_spec_t { facinglist list; int w, h; };
9 }
10 %code provides {
11 yycstate* yycstate_new(void);
12 void yycstate_delete(yycstate*);
13 }
14 %code {
15 #include <stdio.h>
16 #include <string.h>
17 #include <dirent.h>
18 #include <unitypes.h>
19 #include "ir.h"
20
21 struct class_state_t {
22 ir_class *csp;
23 ir_class class_stack[];
24 };
25
26 extern long sys_pagesize;
27 extern int lexer();
28 static void yyerror(yycstate*, char const*);
29 static inline ir_class yyclass_push(yycstate*, ir_class);
30 static inline ir_class yyclass_pop(yycstate*);
31 /* Stack-based class handler */
32 #define yyclass(CS) (*(CS->csp))
33 #define yyclassld(CS) (ir_classld_from_class(yyclass(CS)))
34 #define DEFAULT_VARIANT (uint8_t*)"default"
35 }
36 %define parse.error verbose
37 %define parse.lac full
38 %define lr.type ielr
39 %define api.pure full
40 %define api.push-pull push
41 %parse-param {yycstate* cs}
42 %union {
43 uint32_t ref;
44 int val;
45 apc_facing face;
46 uint8_t* str;
47 ir_class class;
48 ir_set set;
49 ir_setld ld;
50 ir_setdata data;
51 struct frame_spec_t frame_spec;
52 facinglist facinglist;
53 }
54 /* Operators */
55 %token CLOPEN //(
56 %token CLCLOSE //)
57 %token MAP //~
58 %token AUDIO //AUDIO
59 %token SS //SS
60 %token LINK //#
61 /* Terminals */
62 %token <val> NUM
63 %token <str> PATH
64 %token <ref> REF
65 %token <face> FACING
66 %token <str> NAME
67 /* Types */
68 %type<data> data_spec
69 %type<set> set_spec
70 %type<ld> set_ld set_link
71 %type<frame_spec> frame_spec
72 %type<facinglist> facing_list
73 %%
74 /* Syntax Directed Translation Scheme of the APC grammar */
75 progn:
76 class_list
77 | class_list statement_list
78 | statement_list class_list
79 | statement_list
80 ;
81
82 class_list:
83 class_list class
84 | class
85 ;
86
87 class:
88 NAME CLOPEN { yyclass_push(cs,ir_class_addchild(yyclass(cs), $1)); }
89 progn
90 CLCLOSE { yyclass_pop(cs); }
91 ;
92
93 statement_list:
94 statement_list statement
95 | statement
96 ;
97
98 statement:
99 set_spec data_spec REF PATH { ir_data_assign_path($2,$4); ir_set_assign_data($1,$2); ir_set_assign_ref($1,$3); }
100 | set_spec data_spec PATH { ir_data_assign_path($2,$3); ir_set_assign_data($1,$2); }
101 | set_spec REF PATH { ir_set_assign_ref($1,$2); }
102 ;
103
104 data_spec:
105 SS NAME frame_spec { $$ = ir_framesheet($2,$3.list,$3.w,$3.h); }
106 | SS frame_spec { $$ = ir_framesheet(DEFAULT_VARIANT,$2.list,$2.w,$2.h); }
107 | MAP NAME frame_spec { $$ = ir_mapsheet($2,$3.list,$3.w,$3.h); }
108 | MAP frame_spec { $$ = ir_mapsheet(DEFAULT_VARIANT,$2.list,$2.w,$2.h); }
109 | AUDIO NAME { $$ = ir_audio($2); }
110 | LINK set_ld { $$ = ir_link(OLINK, $2, NULL); }
111 | LINK set_ld MAP { $$ = ir_link(MLINK, $2,NULL); }
112 | LINK set_ld MAP NAME { $$ = ir_link(MLINK, $2,$4); }
113 | LINK set_ld SS { $$ = ir_link(VLINK, $2,NULL); }
114 | LINK set_ld SS NAME { $$ = ir_link(VLINK, $2,$4); }
115 | LINK set_ld AUDIO { $$ = ir_link(ALINK, $2,NULL); }
116 | LINK set_ld AUDIO NAME { $$ = ir_link(ALINK, $2,$4); }
117 ;
118
119 set_spec:
120 set_spec NAME { $$ = ir_set_addchild($1,$2); }
121 | NAME { $$ = ir_class_addset(yyclass(cs),$1); }
122 ;
123
124 set_link:
125 set_link NAME { $$ = ir_setld_addchild($1,$2); }
126 | NAME { $$ = ir_setld_from_classld(yyclassld(cs),$1); }
127 ;
128
129 set_ld:
130 set_link { $$ = $1; }
131 | REF { $$ = ir_setld_from_ref($1); }
132 ;
133
134 facing_list:
135 facing_list FACING { $$ = ir_facinglist_push($1,$2); }
136 | FACING { $$ = ir_facinglist($1); }
137
138 frame_spec:
139 NUM NUM { $$ = (struct frame_spec_t) {NULL,$1,$2}; }
140 | facing_list { $$ = (struct frame_spec_t) {$1,0,0}; }
141 | facing_list NUM NUM { $$ = (struct frame_spec_t) {$1,$2,$3}; }
142 | %empty { $$ = (struct frame_spec_t) {NULL,0,0}; }
143 ;
144
145 %%
146
147 static
148 void yyerror
149 ( yycstate* cs,
150 char const *s
151 )
152 { ir_class* iter;
153 fprintf(stderr, "[class->");
154 for (iter = cs->class_stack; iter <= cs->csp; iter++)
155 fprintf(stderr, "%s/", ir_class_name(*iter));
156 if (strstr(s,"unexpected CLCLOSE") != NULL)
157 yyclass_pop(cs);
158 fprintf(stderr, "]\n\t");
159 fprintf(stderr, "%s\n", s);
160 }
161
162 yycstate* yycstate_new
163 ( void )
164 { yycstate* class_state;
165 class_state = (yycstate*) malloc((size_t) sys_pagesize);
166 if(class_state == NULL)
167 { yyerror(class_state, "Memory allocation error.");
168 return NULL;
169 }
170 class_state->csp = class_state->class_stack;
171 *(class_state->csp) = ir_class_root();
172 return class_state;
173 }
174
175 static inline
176 ir_class yyclass_pop
177 ( yycstate* cs )
178 { return *cs->csp--; }
179
180 static inline
181 ir_class yyclass_push
182 ( yycstate* cs,
183 ir_class class
184 )
185 { return *++(cs->csp) = class; }
186
187 void yycstate_delete
188 ( yycstate* class_state )
189 { free(class_state); }