debug print formatting
[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 { apc_facing d; 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 }
35 %define parse.error verbose
36 %define parse.lac full
37 %define lr.type ielr
38 %define api.pure full
39 %define api.push-pull push
40 %parse-param {yycstate* cs}
41 %union {
42 long long ref;
43 int val;
44 apc_facing face;
45 uint8_t* str;
46 ir_class class;
47 ir_set set;
48 ir_setld ld;
49 ir_setdata data;
50 struct frame_spec_t frame_spec;
51 }
52 /* Operators */
53 %token CLOPEN //(
54 %token CLCLOSE //)
55 %token MAP //~
56 %token AUDIO //AUDIO
57 %token SS //SS
58 %token LINK //#
59 /* Terminals */
60 %token <val> NUM
61 %token <str> PATH
62 %token <ref> REF
63 %token <face> FACING
64 %token <str> NAME
65 /* Types */
66 %type<data> data_spec
67 %type<set> set_spec
68 %type<ld> set_ld set_link
69 %type<frame_spec> frame_spec
70 %%
71 /* Syntax Directed Translation Scheme of the APC grammar */
72 progn:
73 class_list
74 | class_list statement_list
75 | statement_list
76 ;
77
78 class_list:
79 class_list class
80 | class
81 ;
82
83 class:
84 NAME CLOPEN { yyclass_push(cs,ir_class_addchild(yyclass(cs), $1)); }
85 progn
86 CLCLOSE { yyclass_pop(cs); }
87 ;
88
89 statement_list:
90 statement_list statement
91 | statement
92 ;
93
94 statement:
95 set_spec data_spec REF PATH { ir_data_assign_path($2,$4); ir_set_assign_data($1,$2); ir_set_assign_ref($1,$3); }
96 | set_spec data_spec PATH { ir_data_assign_path($2,$3); ir_set_assign_data($1,$2); }
97 | set_spec REF PATH { ir_set_assign_ref($1,$2); }
98 ;
99
100 data_spec:
101 SS NAME frame_spec { $$ = ir_framesheet($2,$3.d,$3.w,$3.h); }
102 | MAP NAME frame_spec { $$ = ir_mapsheet($2,$3.d,$3.w,$3.h); }
103 | AUDIO NAME { $$ = ir_audio($2); }
104 | LINK set_ld { $$ = ir_link(OLINK, $2, NULL); }
105 | LINK set_ld MAP { $$ = ir_link(MLINK, $2,NULL); }
106 | LINK set_ld MAP NAME { $$ = ir_link(MLINK, $2,$4); }
107 | LINK set_ld SS { $$ = ir_link(VLINK, $2,NULL); }
108 | LINK set_ld SS NAME { $$ = ir_link(VLINK, $2,$4); }
109 | LINK set_ld AUDIO { $$ = ir_link(ALINK, $2,NULL); }
110 | LINK set_ld AUDIO NAME { $$ = ir_link(ALINK, $2,$4); }
111 ;
112
113 set_spec:
114 set_spec NAME { $$ = ir_set_addchild($1,$2); }
115 | NAME { $$ = ir_class_addset(yyclass(cs),$1); }
116 ;
117
118 set_link:
119 set_link NAME { $$ = ir_setld_addchild($1,$2); }
120 | NAME { $$ = ir_setld_from_classld(yyclassld(cs),$1); }
121 ;
122
123 set_ld:
124 set_link { $$ = $1; }
125 | REF { $$ = ir_setld_from_ref($1); }
126 ;
127
128 frame_spec:
129 NUM NUM { $$ = (struct frame_spec_t) {SFACE,$1,$2}; }
130 | FACING { $$ = (struct frame_spec_t) {$1,0,0}; }
131 | FACING NUM NUM { $$ = (struct frame_spec_t) {$1,$2,$3}; }
132 | %empty { $$ = (struct frame_spec_t) {SFACE,0,0}; }
133 ;
134
135 %%
136
137 static
138 void yyerror
139 ( yycstate* cs,
140 char const *s
141 )
142 { ir_class* iter;
143 fprintf(stderr, "[class->");
144 for (iter = cs->class_stack; iter < cs->csp; iter++)
145 fprintf(stderr, "%s/", ir_class_name(*iter));
146 fprintf(stderr, "]\n\t");
147 fprintf(stderr, "%s\n", s);
148 }
149
150 yycstate* yycstate_new
151 ( void )
152 { yycstate* class_state;
153 class_state = (yycstate*) malloc((size_t) sys_pagesize);
154 if(class_state == NULL)
155 { yyerror(class_state, "Memory allocation error.");
156 return NULL;
157 }
158 class_state->csp = class_state->class_stack;
159 *(class_state->csp) = ir_class_root();
160 return class_state;
161 }
162
163 static inline
164 ir_class yyclass_pop
165 ( yycstate* cs )
166 { cs->csp--;
167 return *(cs->csp + 1);
168 }
169
170 static inline
171 ir_class yyclass_push
172 ( yycstate* cs,
173 ir_class class
174 )
175 { return *++(cs->csp) = class; }
176
177 void yycstate_delete
178 ( yycstate* class_state )
179 { free(class_state); }