make the parser understandable by IDE
[m6w6/ext-psi] / src / parser_proc.y
1 %include {
2 #include <stddef.h>
3 #include <assert.h>
4 #include <stdlib.h>
5 #include <string.h>
6 #include <stdarg.h>
7
8 #include "parser.h"
9 }
10 %include { void psi_error(int, const char *, int, const char *, ...); }
11 %name PSI_ParserProc
12 %token_prefix PSI_T_
13 %token_type {PSI_Token *}
14 %token_destructor {free($$);}
15 %default_destructor {(void)P;}
16 %extra_argument {PSI_Parser *P}
17 %syntax_error { ++P->errors; if (TOKEN && TOKEN->type != PSI_T_EOF) { psi_error(PSI_WARNING, TOKEN->file, TOKEN->line, "PSI syntax error: Unexpected token '%s'", TOKEN->text); } else { psi_error(PSI_WARNING, P->psi.file.fn, P->line, "PSI syntax error: Unexpected end of input"); } }
18 %nonassoc NAME.
19 %left PLUS MINUS.
20 %left SLASH ASTERISK.
21 %fallback NAME TEMP FREE SET LET RETURN CALLOC CALLBACK ZVAL LIB STRING.
22 %token_class const_type_token BOOL INT FLOAT STRING.
23 %token_class decl_type_token FLOAT DOUBLE INT8 UINT8 INT16 UINT16 INT32 UINT32 INT64 UINT64 NAME.
24 %token_class impl_def_val_token NULL NUMBER TRUE FALSE QUOTED_STRING.
25 %token_class num_exp_token NUMBER NSNAME.
26 %token_class num_exp_op_token PLUS MINUS ASTERISK SLASH.
27 %token_class let_func_token ZVAL OBJVAL ARRVAL PATHVAL STRLEN STRVAL FLOATVAL INTVAL BOOLVAL.
28 %token_class set_func_token TO_OBJECT TO_ARRAY TO_STRING TO_INT TO_FLOAT TO_BOOL ZVAL VOID.
29 %token_class impl_type_token VOID MIXED BOOL INT FLOAT STRING ARRAY OBJECT CALLABLE.
30 %type decl_enum {decl_enum *}
31 %destructor decl_enum {free_decl_enum($$);}
32 %type decl_enum_items {decl_enum_items*}
33 %destructor decl_enum_items {free_decl_enum_items($$);}
34 %type decl_enum_item {decl_enum_item*}
35 %destructor decl_enum_item {free_decl_enum_item($$);}
36 %type decl_struct_args_block {decl_args*}
37 %destructor decl_struct_args_block {free_decl_args($$);}
38 %type decl_struct_args {decl_args*}
39 %destructor decl_struct_args {free_decl_args($$);}
40 %type decl_struct {decl_struct*}
41 %destructor decl_struct {free_decl_struct($$);}
42 %type align_and_size {decl_struct_layout}
43 %type decl_union {decl_union*}
44 %destructor decl_union {free_decl_union($$);}
45 %type const_type {const_type*}
46 %destructor const_type {free_const_type($$);}
47 %type constant {constant*}
48 %destructor constant {free_constant($$);}
49 %type decl_typedef {decl_arg*}
50 %destructor decl_typedef {free_decl_arg($$);}
51 %type decl_typedef_body_ex {decl_arg*}
52 %destructor decl_typedef_body_ex {free_decl_arg($$);}
53 %type decl_typedef_body {decl_arg*}
54 %destructor decl_typedef_body {free_decl_arg($$);}
55 %type decl_typedef_body_fn_args {decl_args *}
56 %destructor decl_typedef_body_fn_args {free_decl_args($$);}
57 %type decl {decl*}
58 %destructor decl {free_decl($$);}
59 %type decl_func {decl_arg*}
60 %destructor decl_func {free_decl_arg($$);}
61 %type decl_abi {decl_abi*}
62 %destructor decl_abi {free_decl_abi($$);}
63 %type decl_var {decl_var*}
64 %destructor decl_var {free_decl_var($$);}
65 %type decl_vars {decl_vars*}
66 %destructor decl_vars {free_decl_vars($$);}
67 %type decl_arg {decl_arg*}
68 %destructor decl_arg {free_decl_arg($$);}
69 %type decl_args {decl_args*}
70 %destructor decl_args {free_decl_args($$);}
71 %type struct_args {decl_args*}
72 %destructor struct_args {free_decl_args($$);}
73 %type struct_arg {decl_arg*}
74 %destructor struct_arg {free_decl_arg($$);}
75 %type struct_layout {decl_struct_layout*}
76 %destructor struct_layout {free_decl_struct_layout($$);}
77 %type decl_type {decl_type*}
78 %destructor decl_type {free_decl_type($$);}
79 %type const_decl_type {decl_type*}
80 %destructor const_decl_type {free_decl_type($$);}
81 %type impl {impl*}
82 %destructor impl {free_impl($$);}
83 %type impl_func {impl_func*}
84 %destructor impl_func {free_impl_func($$);}
85 %type impl_def_val {impl_def_val*}
86 %destructor impl_def_val {free_impl_def_val($$);}
87 %type impl_var {impl_var*}
88 %destructor impl_var {free_impl_var($$);}
89 %type impl_arg {impl_arg*}
90 %destructor impl_arg {free_impl_arg($$);}
91 %type impl_args {impl_args*}
92 %destructor impl_args {free_impl_args($$);}
93 %type impl_vararg {impl_arg*}
94 %destructor impl_vararg {free_impl_arg($$);}
95 %type impl_arg_list {impl_args*}
96 %destructor impl_arg_list {free_impl_args($$);}
97 %type impl_stmts {impl_stmts*}
98 %destructor impl_stmts {free_impl_stmts($$);}
99 %type impl_stmt {impl_stmt*}
100 %destructor impl_stmt {free_impl_stmt($$);}
101 %type num_exp {num_exp*}
102 %destructor num_exp {free_num_exp($$);}
103 %type let_stmt {let_stmt*}
104 %destructor let_stmt {free_let_stmt($$);}
105 %type let_calloc {let_calloc*}
106 %destructor let_calloc {free_let_calloc($$);}
107 %type let_func {let_func*}
108 %destructor let_func {free_let_func($$);}
109 %type callback_arg_list {set_values *}
110 %destructor callback_arg_list {free_set_values($$);}
111 %type callback_args {set_values *}
112 %destructor callback_args {free_set_values($$);}
113 %type let_val {let_val*}
114 %destructor let_val {free_let_val($$);}
115 %type set_stmt {set_stmt*}
116 %destructor set_stmt {free_set_stmt($$);}
117 %type set_value {set_value*}
118 %destructor set_value {free_set_value($$);}
119 %type set_vals {set_value*}
120 %destructor set_vals {free_set_value($$);}
121 %type set_func {set_func*}
122 %destructor set_func {free_set_func($$);}
123 %type return_stmt {return_stmt*}
124 %destructor return_stmt {free_return_stmt($$);}
125 %type free_stmt {free_stmt*}
126 %destructor free_stmt {free_free_stmt($$);}
127 %type free_calls {free_calls*}
128 %destructor free_calls {free_free_calls($$);}
129 %type free_call {free_call*}
130 %destructor free_call {free_free_call($$);}
131 %type impl_type {impl_type*}
132 %destructor impl_type {free_impl_type($$);}
133 %type reference {char}
134 %type indirection {unsigned}
135 %type pointers {unsigned}
136 file ::= blocks.
137 blocks ::= block.
138 blocks ::= blocks block.
139 block ::= EOF.
140 block ::= EOS.
141 block ::= LIB(token) QUOTED_STRING(libname) EOS. {
142 if (P->psi.file.ln) {
143 P->error(P, token, PSI_WARNING, "Extra 'lib %s' statement has no effect", libname->text);
144 } else {
145 P->psi.file.ln = strndup(libname->text + 1, libname->size - 2);
146 }
147 free(libname);
148 free(token);
149 }
150 block ::= decl(decl). {
151 P->decls = add_decl(P->decls, decl);
152 }
153 block ::= impl(impl). {
154 P->impls = add_impl(P->impls, impl);
155 }
156 block ::= decl_typedef(def). {
157 P->defs = add_decl_typedef(P->defs, def);
158 switch (def->type->type) {
159 case PSI_T_STRUCT:
160 if (def->type->real.strct) {
161 P->structs = add_decl_struct(P->structs, def->type->real.strct);
162 }
163 break;
164 case PSI_T_UNION:
165 if (def->type->real.unn) {
166 P->unions = add_decl_union(P->unions, def->type->real.unn);
167 }
168 break;
169 case PSI_T_ENUM:
170 if (def->type->real.enm) {
171 P->enums = add_decl_enum(P->enums, def->type->real.enm);
172 }
173 break;
174 }
175 }
176 block ::= constant(constant). {
177 P->consts = add_constant(P->consts, constant);
178 }
179 block ::= decl_struct(strct). {
180 P->structs = add_decl_struct(P->structs, strct);
181 }
182 block ::= decl_union(u). {
183 P->unions = add_decl_union(P->unions, u);
184 }
185 block ::= decl_enum(e). {
186 P->enums = add_decl_enum(P->enums, e);
187 }
188 optional_name(n) ::= . {
189 n = NULL;
190 }
191 optional_name(n) ::= NAME(N). {
192 n = N;
193 }
194 enum_name(n) ::= ENUM(E) optional_name(N). {
195 if (N) {
196 n = N;
197 free(E);
198 } else {
199 char digest[17];
200 PSI_TokenHash(E, digest);
201 n = PSI_TokenTranslit(PSI_TokenAppend(E, 1, digest), " ", "@");
202 }
203 }
204 decl_enum(e) ::= enum_name(N) LBRACE decl_enum_items(list) RBRACE. {
205 e = init_decl_enum(N->text, list);
206 e->token = N;
207 }
208 decl_enum_items(l) ::= decl_enum_item(i). {
209 l = init_decl_enum_items(i);
210 }
211 decl_enum_items(l) ::= decl_enum_items(l_) COMMA decl_enum_item(i). {
212 l = add_decl_enum_item(l_, i);
213 }
214 decl_enum_item(i) ::= NAME(N) EQUALS num_exp(num). {
215 i = init_decl_enum_item(N->text, num);
216 i->token = N;
217 }
218 decl_enum_item(i) ::= NAME(N). {
219 i = init_decl_enum_item(N->text, NULL);
220 i->token = N;
221 }
222 union_name(n) ::= UNION(U) optional_name(N). {
223 if (N) {
224 n = N;
225 free(U);
226 } else {
227 char digest[17];
228 PSI_TokenHash(U, digest);
229 n = PSI_TokenTranslit(PSI_TokenAppend(U, 1, digest), " ", "@");
230 }
231 }
232 struct_name(n) ::= STRUCT(S) optional_name(N). {
233 if (N) {
234 n = N;
235 free(S);
236 } else {
237 char digest[17];
238 PSI_TokenHash(S, digest);
239 n = PSI_TokenTranslit(PSI_TokenAppend(S, 1, digest), " ", "@");
240 }
241 }
242 decl_struct_args_block(args_) ::= LBRACE struct_args(args) RBRACE. {
243 args_ = args;
244 }
245 decl_struct_args(args_) ::= decl_struct_args_block(args). {
246 args_ = args;
247 }
248 decl_struct_args(args_) ::= EOS. {
249 args_ = init_decl_args(NULL);
250 }
251 decl_struct(strct) ::= STRUCT NAME(N) align_and_size(as) decl_struct_args(args). {
252 strct = init_decl_struct(N->text, args);
253 strct->align = as.pos;
254 strct->size = as.len;
255 strct->token = N;
256 }
257 align_and_size(as) ::= . {
258 as.pos = 0;
259 as.len = 0;
260 }
261 align_and_size(as) ::= COLON COLON LPAREN NUMBER(A) COMMA NUMBER(S) RPAREN. {
262 as.pos = atol(A->text);
263 as.len = atol(S->text);
264 free(A);
265 free(S);
266 }
267 decl_union(u) ::= UNION NAME(N) align_and_size(as) decl_struct_args(args). {
268 u = init_decl_union(N->text, args);
269 u->align = as.pos;
270 u->size = as.len;
271 u->token = N;
272 }
273 const_type(type_) ::= const_type_token(T). {
274 type_ = init_const_type(T->type, T->text);
275 free(T);
276 }
277 constant(constant) ::= CONST const_type(type) NSNAME(T) EQUALS impl_def_val(val) EOS. {
278 constant = init_constant(type, T->text, val);
279 free(T);
280 }
281 decl_typedef(def) ::= TYPEDEF(T) decl_typedef_body(def_) EOS. {
282 def = def_;
283 def->token = T;
284 }
285 decl_typedef_body_ex(def) ::= struct_name(N) align_and_size(as) decl_struct_args_block(args) decl_var(var). {
286 def = init_decl_arg(init_decl_type(PSI_T_STRUCT, N->text), var);
287 def->type->token = PSI_TokenCopy(N);
288 def->type->real.strct = init_decl_struct(N->text, args);
289 def->type->real.strct->token = N;
290 def->type->real.strct->align = as.pos;
291 def->type->real.strct->size = as.len;
292 }
293 decl_typedef_body_ex(def) ::= union_name(N) align_and_size(as) decl_struct_args_block(args) decl_var(var). {
294 def = init_decl_arg(init_decl_type(PSI_T_UNION, N->text), var);
295 def->type->token = PSI_TokenCopy(N);
296 def->type->real.unn = init_decl_union(N->text, args);
297 def->type->real.unn->token = N;
298 def->type->real.unn->align = as.pos;
299 def->type->real.unn->size = as.len;
300 }
301 decl_typedef_body_ex(def) ::= decl_enum(e) NAME(ALIAS). {
302 def = init_decl_arg(init_decl_type(PSI_T_ENUM, e->name), init_decl_var(ALIAS->text, 0, 0));
303 def->var->token = ALIAS;
304 def->type->token = PSI_TokenCopy(e->token);
305 def->type->real.enm = e;
306 }
307 decl_typedef_body(def) ::= decl_typedef_body_ex(def_). {
308 def = def_;
309 }
310 decl_typedef_body_fn_args(args) ::= LPAREN decl_args(args_) RPAREN. {
311 args = args_;
312 }
313 decl_typedef_body(def) ::= decl_func(func_) decl_typedef_body_fn_args(args). {
314 def = init_decl_arg(init_decl_type(PSI_T_FUNCTION, func_->var->name), copy_decl_var(func_->var));
315 def->type->token = PSI_TokenCopy(func_->token);
316 def->type->real.func = init_decl(init_decl_abi("default"), func_, args);
317 }
318 decl_typedef_body(def) ::= decl_arg(arg). {
319 def = arg;
320 }
321 decl(decl) ::= decl_abi(abi) decl_func(func) LPAREN decl_args(args) RPAREN EOS. {
322 decl = init_decl(abi, func, args);
323 }
324 decl_func(func) ::= decl_arg(arg). {
325 func = arg;
326 }
327 decl_func(func) ::= VOID(T) NAME(N). {
328 func = init_decl_arg(
329 init_decl_type(T->type, T->text),
330 init_decl_var(N->text, 0, 0)
331 );
332 func->type->token = T;
333 func->var->token = N;
334 func->token = N;
335 }
336 decl_typedef_body(def) ::= VOID(T) indirection(decl_i) LPAREN indirection(type_i) NAME(N) RPAREN decl_typedef_body_fn_args(args). {
337 decl_arg *func_ = init_decl_arg(
338 init_decl_type(T->type, T->text),
339 init_decl_var(N->text, decl_i, 0)
340 );
341 func_->type->token = T;
342 func_->var->token = N;
343 func_->token = N;
344 def = init_decl_arg(
345 init_decl_type(PSI_T_FUNCTION, func_->var->name),
346 copy_decl_var(func_->var)
347 );
348 def->var->pointer_level = type_i;
349 def->type->token = PSI_TokenCopy(func_->token);
350 def->type->real.func = init_decl(init_decl_abi("default"), func_, args);
351 }
352 decl_typedef_body(def) ::= CONST VOID(T) pointers(decl_i) LPAREN indirection(type_i) NAME(N) RPAREN decl_typedef_body_fn_args(args). {
353 decl_arg *func_ = init_decl_arg(
354 init_decl_type(T->type, T->text),
355 init_decl_var(N->text, decl_i, 0)
356 );
357 func_->type->token = T;
358 func_->var->token = N;
359 func_->token = N;
360 def = init_decl_arg(
361 init_decl_type(PSI_T_FUNCTION, func_->var->name),
362 copy_decl_var(func_->var)
363 );
364 def->var->pointer_level = type_i;
365 def->type->token = PSI_TokenCopy(func_->token);
366 def->type->real.func = init_decl(init_decl_abi("default"), func_, args);
367 }
368 decl_abi(abi) ::= NAME(T). {
369 abi = init_decl_abi(T->text);
370 abi->token = T;
371 }
372 decl_var(var) ::= indirection(p) NAME(T). {
373 var = init_decl_var(T->text, p, 0);
374 var->token = T;
375 }
376 decl_var(var) ::= indirection(p) NAME(T) LBRACKET NUMBER(D) RBRACKET. {
377 var = init_decl_var(T->text, p+1, atol(D->text));
378 var->token = T;
379 free(D);
380 }
381 decl_vars(vars) ::= decl_var(var). {
382 vars = init_decl_vars(var);
383 }
384 decl_vars(vars) ::= decl_vars(vars_) COMMA decl_var(var). {
385 vars = add_decl_var(vars_, var);
386 }
387 decl_arg(arg_) ::= const_decl_type(type) decl_var(var). {
388 arg_ = init_decl_arg(type, var);
389 }
390 decl_typedef_body(def) ::= const_decl_type(type_) indirection(decl_i) LPAREN indirection(type_i) NAME(N) RPAREN decl_typedef_body_fn_args(args). {
391 decl_arg *func_ = init_decl_arg(
392 type_,
393 init_decl_var(N->text, decl_i, 0)
394 );
395 func_->var->token = N;
396 func_->token = N;
397 def = init_decl_arg(
398 init_decl_type(PSI_T_FUNCTION, func_->var->name),
399 copy_decl_var(func_->var)
400 );
401 def->var->pointer_level = type_i;
402 def->type->token = PSI_TokenCopy(func_->token);
403 def->type->real.func = init_decl(init_decl_abi("default"), func_, args);
404 }
405 decl_arg(arg_) ::= VOID(T) pointers(p) NAME(N). {
406 arg_ = init_decl_arg(
407 init_decl_type(T->type, T->text),
408 init_decl_var(N->text, p, 0)
409 );
410 arg_->type->token = T;
411 arg_->var->token = N;
412 arg_->token = N;
413 }
414 decl_arg(arg_) ::= CONST VOID(T) pointers(p) NAME(N). {
415 arg_ = init_decl_arg(
416 init_decl_type(T->type, T->text),
417 init_decl_var(N->text, p, 0)
418 );
419 arg_->type->token = T;
420 arg_->var->token = N;
421 arg_->token = N;
422 }
423 decl_args ::= .
424 decl_args ::= VOID.
425 decl_args(args) ::= decl_arg(arg). {
426 args = init_decl_args(arg);
427 }
428 decl_args(args) ::= decl_args(args_) COMMA decl_arg(arg). {
429 args = add_decl_arg(args_, arg);
430 }
431 decl_args(args) ::= decl_args(args_) COMMA ELLIPSIS. {
432 args = args_;
433 args->varargs = 1;
434 }
435 struct_args(args) ::= struct_arg(arg). {
436 args = init_decl_args(arg);
437 }
438 struct_args(args) ::= struct_args(args_) struct_arg(arg). {
439 args = add_decl_arg(args_, arg);
440 }
441 struct_arg(arg_) ::= decl_typedef_body_ex(def) EOS. {
442 arg_ = def;
443 switch (def->type->type) {
444 case PSI_T_STRUCT:
445 if (def->type->real.strct) {
446 P->structs = add_decl_struct(P->structs, def->type->real.strct);
447 }
448 break;
449 case PSI_T_UNION:
450 if (def->type->real.unn) {
451 P->unions = add_decl_union(P->unions, def->type->real.unn);
452 }
453 break;
454 case PSI_T_ENUM:
455 if (def->type->real.enm) {
456 P->enums = add_decl_enum(P->enums, def->type->real.enm);
457 }
458 break;
459 }
460 }
461 struct_arg(arg) ::= decl_arg(arg_) struct_layout(layout_) EOS. {
462 arg_->layout = layout_;
463 arg = arg_;
464 }
465 struct_layout(layout) ::= . {
466 layout = NULL;
467 }
468 struct_layout(layout) ::= COLON COLON LPAREN NUMBER(POS) COMMA NUMBER(SIZ) RPAREN. {
469 layout = init_decl_struct_layout(atol(POS->text), atol(SIZ->text));
470 free(POS);
471 free(SIZ);
472 }
473 decl_scalar_type(type_) ::= CHAR(C). {
474 type_ = C;
475 }
476 decl_scalar_type(type_) ::= SHORT(S) decl_scalar_type_short(s). {
477 if (s) {
478 type_ = PSI_TokenCat(2, S, s);
479 free(S);
480 free(s);
481 } else {
482 type_ = S;
483 }
484 }
485 decl_scalar_type_short(s) ::= . {
486 s = NULL;
487 }
488 decl_scalar_type_short(s) ::= INT(I). {
489 s = I;
490 }
491 decl_scalar_type(type_) ::= INT(I). {
492 type_ = I;
493 }
494 decl_scalar_type(type_) ::= LONG(L) decl_scalar_type_long(l). {
495 if (l) {
496 type_ = PSI_TokenCat(2, L, l);
497 free(L);
498 free(l);
499 } else {
500 type_ = L;
501 }
502 }
503 decl_scalar_type_long(l) ::= . {
504 l = NULL;
505 }
506 decl_scalar_type_long(l) ::= DOUBLE(D). {
507 l = D;
508 }
509 decl_scalar_type_long(l) ::= LONG(L) decl_scalar_type_long_long(ll). {
510 if (ll) {
511 l = PSI_TokenCat(2, L, ll);
512 free(L);
513 free(ll);
514 } else {
515 l = L;
516 }
517 }
518 decl_scalar_type_long_long(ll) ::= . {
519 ll = NULL;
520 }
521 decl_scalar_type_long_long(ll) ::= INT(I). {
522 ll = I;
523 }
524 decl_type(type_) ::= UNSIGNED(U) decl_scalar_type(N). {
525 PSI_Token *T = PSI_TokenCat(2, U, N);
526 type_ = init_decl_type(T->type, T->text);
527 type_->token = T;
528 free(U);
529 free(N);
530 }
531 decl_type(type_) ::= SIGNED(S) decl_scalar_type(N). {
532 PSI_Token *T = PSI_TokenCat(2, S, N);
533 type_ = init_decl_type(T->type, T->text);
534 type_->token = T;
535 free(S);
536 free(N);
537 }
538 decl_type(type_) ::= UNSIGNED(U). {
539 type_ = init_decl_type(PSI_T_NAME, U->text);
540 type_->token = U;
541 }
542 decl_type(type_) ::= SIGNED(S). {
543 type_ = init_decl_type(PSI_T_NAME, S->text);
544 type_->token = S;
545 }
546 decl_type(type_) ::= decl_scalar_type(N). {
547 type_ = init_decl_type(N->type, N->text);
548 type_->token = N;
549 }
550 decl_type(type_) ::= STRUCT(S) NAME(T). {
551 type_ = init_decl_type(S->type, T->text);
552 type_->token = T;
553 free(S);
554 }
555 decl_type(type_) ::= UNION(U) NAME(T). {
556 type_ = init_decl_type(U->type, T->text);
557 type_->token = T;
558 free(U);
559 }
560 decl_type(type_) ::= ENUM(E) NAME(T). {
561 type_ = init_decl_type(E->type, T->text);
562 type_->token = T;
563 free(E);
564 }
565 decl_type(type_) ::= decl_type_token(T). {
566 type_ = init_decl_type(T->type, T->text);
567 type_->token = T;
568 }
569 const_decl_type(type) ::= decl_type(type_). {
570 type = type_;
571 }
572 const_decl_type(type) ::= CONST decl_type(type_). {
573 type = type_;
574 }
575 impl(impl) ::= impl_func(func) LBRACE impl_stmts(stmts) RBRACE. {
576 impl = init_impl(func, stmts);
577 }
578 impl_func(func) ::= FUNCTION reference(r) NSNAME(NAME) impl_args(args) COLON impl_type(type). {
579 func = init_impl_func(NAME->text, args, type, r);
580 func->token = NAME;
581 }
582 impl_def_val(def) ::= impl_def_val_token(T). {
583 def = init_impl_def_val(T->type, T->text);
584 free(T);
585 }
586 impl_var(var) ::= reference(r) DOLLAR_NAME(T). {
587 var = init_impl_var(T->text, r);
588 var->token = T;
589 }
590 impl_arg(arg) ::= impl_type(type) impl_var(var). {
591 arg = init_impl_arg(type, var, NULL);
592 }
593 impl_arg(arg) ::= impl_type(type) impl_var(var) EQUALS impl_def_val(def). {
594 arg = init_impl_arg(type, var, def);
595 }
596 impl_args(args) ::= LPAREN RPAREN. {
597 args = NULL;
598 }
599 impl_args(args) ::= LPAREN impl_arg_list(args_) RPAREN. {
600 args = args_;
601 }
602 impl_args(args) ::= LPAREN impl_arg_list(args_) COMMA impl_vararg(va) RPAREN. {
603 args = args_;
604 args->vararg.name = va;
605 }
606 impl_vararg(va) ::= impl_type(type) reference(r) ELLIPSIS DOLLAR_NAME(T). {
607 va = init_impl_arg(type, init_impl_var(T->text, r), NULL);
608 free(T);
609 }
610 impl_arg_list(args) ::= impl_arg(arg). {
611 args = init_impl_args(arg);
612 }
613 impl_arg_list(args) ::= impl_arg_list(args_) COMMA impl_arg(arg). {
614 args = add_impl_arg(args_, arg);
615 }
616 impl_stmts(stmts) ::= impl_stmt(stmt). {
617 stmts = init_impl_stmts(stmt);
618 }
619 impl_stmts(stmts) ::= impl_stmts(stmts_) impl_stmt(stmt). {
620 stmts = add_impl_stmt(stmts_, stmt);
621 }
622 impl_stmt(stmt) ::= let_stmt(let). {
623 stmt = init_impl_stmt(PSI_T_LET, let);
624 }
625 impl_stmt(stmt) ::= set_stmt(set). {
626 stmt = init_impl_stmt(PSI_T_SET, set);
627 }
628 impl_stmt(stmt) ::= return_stmt(ret). {
629 stmt = init_impl_stmt(PSI_T_RETURN, ret);
630 }
631 impl_stmt(stmt) ::= free_stmt(free). {
632 stmt = init_impl_stmt(PSI_T_FREE, free);
633 }
634 num_exp(exp) ::= num_exp_token(tok). {
635 exp = init_num_exp(tok->type, tok->text);
636 exp->token = tok;
637 }
638 num_exp(exp) ::= decl_var(var). {
639 exp = init_num_exp(PSI_T_NAME, var);
640 exp->token = PSI_TokenCopy(var->token);
641 }
642 num_exp(exp) ::= num_exp(exp_) num_exp_op_token(operator_) num_exp(operand_). {
643 exp_->operator = operator_->type;
644 exp_->operand = operand_;
645 exp = exp_;
646 free(operator_);
647 }
648 let_stmt(let) ::= LET decl_var(var) EOS. {
649 let = init_let_stmt(var, init_let_val(PSI_LET_NULL, NULL));
650 }
651 let_stmt(let) ::= LET decl_var(var) EQUALS reference(r) let_val(val) EOS. {
652 val->flags.one.is_reference = r ? 1 : 0;
653 let = init_let_stmt(var, val);
654 }
655 let_stmt(let) ::= TEMP decl_var(var) EQUALS decl_var(val) EOS. {
656 let = init_let_stmt(var, init_let_val(PSI_LET_TMP, val));
657 }
658 let_calloc(alloc) ::= num_exp(nmemb) COMMA num_exp(size). {
659 alloc = init_let_calloc(nmemb, size);
660 }
661 let_func(func) ::= let_func_token(T) LPAREN impl_var(var) RPAREN. {
662 func = init_let_func(T->type, T->text, var);
663 free(T);
664 }
665 callback_arg_list ::= .
666 callback_arg_list(args) ::= callback_args(args_). {
667 args = args_;
668 }
669 callback_args(args) ::= set_value(val). {
670 args = init_set_values(val);
671 }
672 callback_args(args) ::= callback_args(args_) COMMA set_value(val). {
673 args = add_set_value(args_, val);
674 }
675 let_val(val) ::= NULL. {
676 val = init_let_val(PSI_LET_NULL, NULL);
677 }
678 let_val(val) ::= num_exp(exp). {
679 val = init_let_val(PSI_LET_NUMEXP, exp);
680 }
681 let_val(val) ::= CALLOC LPAREN let_calloc(alloc) RPAREN. {
682 val = init_let_val(PSI_LET_CALLOC, alloc);
683 }
684 let_val(val) ::= let_func(func). {
685 val = init_let_val(PSI_LET_FUNC, func);
686 }
687 let_val(val) ::= CALLBACK let_func_token(F) LPAREN impl_var(var) LPAREN callback_arg_list(args_) RPAREN RPAREN. {
688 val = init_let_val(PSI_LET_CALLBACK, init_let_callback(
689 init_let_func(F->type, F->text, var), args_));
690 free(F);
691 }
692 set_stmt(set) ::= SET impl_var(var) EQUALS set_value(val) EOS. {
693 set = init_set_stmt(var, val);
694 }
695 set_value(val) ::= set_func(func) LPAREN decl_var(var) RPAREN. {
696 val = init_set_value(func, init_decl_vars(var));
697 }
698 set_value(val) ::= set_func(func) LPAREN decl_var(var) COMMA num_exp(num_) RPAREN. {
699 val = init_set_value(func, init_decl_vars(var));
700 val->num = num_;
701 }
702 set_value(val) ::= set_func(func_) LPAREN decl_var(var) COMMA ELLIPSIS(T) RPAREN. {
703 free_set_func(func_);
704 val = init_set_value(init_set_func(T->type, T->text), init_decl_vars(var));
705 val->func->token = T;
706 }
707 set_value(val) ::= set_func(func_) LPAREN decl_var(var) COMMA set_vals(vals) RPAREN. {
708 val = vals;
709 val->func = func_;
710 val->vars = init_decl_vars(var);
711 }
712 set_value(val) ::= set_func(func_) LPAREN decl_var(var) COMMA num_exp(num_) COMMA set_vals(vals) RPAREN. {
713 val = vals;
714 val->func = func_;
715 val->num = num_;
716 val->vars = init_decl_vars(var);
717 }
718 set_vals(vals) ::= set_value(val). {
719 vals = add_inner_set_value(init_set_value(NULL, NULL), val);
720 }
721 set_vals(vals) ::= set_vals(vals_) COMMA set_value(val). {
722 vals = add_inner_set_value(vals_, val);
723 }
724 set_func(func) ::= set_func_token(T). {
725 func = init_set_func(T->type, T->text);
726 func->token = T;
727 }
728 return_stmt(ret) ::= RETURN(T) set_value(val) EOS. {
729 ret = init_return_stmt(val);
730 ret->token = T;
731 }
732 free_stmt(free) ::= FREE free_calls(calls) EOS. {
733 free = init_free_stmt(calls);
734 }
735 free_calls(calls) ::= free_call(call). {
736 calls = init_free_calls(call);
737 }
738 free_calls(calls) ::= free_calls(calls_) COMMA free_call(call). {
739 calls = add_free_call(calls_, call);
740 }
741 free_call(call) ::= NAME(F) LPAREN decl_vars(vars) RPAREN. {
742 call = init_free_call(F->text, vars);
743 call->token = F;
744 }
745 impl_type(type_) ::= impl_type_token(T). {
746 type_ = init_impl_type(T->type, T->text);
747 free(T);
748 }
749 reference(r) ::= . {
750 r = 0;
751 }
752 reference(r) ::= AMPERSAND. {
753 r = 1;
754 }
755 indirection(i) ::= .{
756 i = 0;
757 }
758 indirection(i) ::= pointers(p). {
759 i = p;
760 }
761 pointers(p) ::= ASTERISK. {
762 p = 1;
763 }
764 pointers(p) ::= pointers(p_) ASTERISK. {
765 p = p_+1;
766 }