From: Michael Wallner Date: Wed, 24 Aug 2016 14:22:50 +0000 (+0200) Subject: make the parser understandable by IDE X-Git-Url: https://git.m6w6.name/?p=m6w6%2Fext-psi;a=commitdiff_plain;h=04a60b34fc18ea3a2638893eaf24514177692eeb make the parser understandable by IDE --- diff --git a/Makefile.frag b/Makefile.frag index 38fe137..6bb4061 100644 --- a/Makefile.frag +++ b/Makefile.frag @@ -29,8 +29,9 @@ $(PHP_PSI_SRCDIR)/src/parser_proc.h: $(PHP_PSI_SRCDIR)/src/parser_proc.c $(PHP_PSI_SRCDIR)/src/%.c: $(PHP_PSI_SRCDIR)/src/parser.h $(PHP_PSI_SRCDIR)/src/parser_proc.h touch $@ -$(PHP_PSI_SRCDIR)/src/parser_proc.y: $(PHP_PSI_SRCDIR)/src/parser.h - touch $@ +$(PHP_PSI_SRCDIR)/src/parser_proc.y: $(PHP_PSI_SRCDIR)/src/parser_def.h $(PHP_PSI_SRCDIR)/src/parser.h + cat $(PHP_PSI_SRCDIR)/src/parser_proc.inc >$@ + $(CPP) -P -DGENERATE $< >>$@ $(PHP_PSI_SRCDIR)/src/parser_proc.c: $(PHP_PSI_SRCDIR)/src/parser_proc.y $(LEMON) $(LEMON) -c $< diff --git a/src/parser.h b/src/parser.h index 105e974..c99c266 100644 --- a/src/parser.h +++ b/src/parser.h @@ -957,16 +957,17 @@ static inline void free_let_func(let_func *func) { free(func); } +enum let_val_kind { + PSI_LET_NULL, + PSI_LET_NUMEXP, + PSI_LET_CALLOC, + PSI_LET_CALLBACK, + PSI_LET_FUNC, + PSI_LET_TMP, +}; #define PSI_LET_REFERENCE 0x1; typedef struct let_val { - enum let_val_kind { - PSI_LET_NULL, - PSI_LET_NUMEXP, - PSI_LET_CALLOC, - PSI_LET_CALLBACK, - PSI_LET_FUNC, - PSI_LET_TMP, - } kind; + enum let_val_kind kind; union { num_exp *num; let_calloc *alloc; diff --git a/src/parser_def.h b/src/parser_def.h new file mode 100644 index 0000000..e286bcd --- /dev/null +++ b/src/parser_def.h @@ -0,0 +1,1206 @@ +#define _CONCAT(x,y) x##y +#define CONCAT(x,y) _CONCAT(x,y) +#define COUNTED(x) CONCAT(parse_ ##x## _, __LINE__) + +#ifdef GENERATE +#define DEF(dn, dv) dn dv +#define LET(nt, rule) nt ::= rule. +#define PARSE(nt, rule) nt ::= rule. +#define PARSE_NAMED(nt, nt_name, rule) NAMED(nt, nt_name) ::= rule. +#define PARSE_TYPED(nt, nt_name, rule) TYPED(nt, nt_name) ::= rule. +#define TOKEN(t) t +#define NAMED(t, name) t(name) +#define TYPED(t, name) t(name) +#define TOKEN_TYPE(token, type_) %type token {type_} +#define TOKEN_DTOR(token, dtor) %destructor token {dtor} +#else +#ifndef TEST +#include "parser.h" +#endif +#define DEF(dn, dv) +#define LET(nt, rule) +#define PARSE(nt, rule) \ + static void COUNTED(nt) (PSI_Parser *P rule) +#define PARSE_NAMED(nt, nt_name, rule) \ + static void COUNTED(nt) (PSI_Parser *P NAMED(nt, nt_name) rule) +#define PARSE_TYPED(nt, nt_name, rule) \ + static void COUNTED(nt) (PSI_Parser *P TYPED(nt, nt_name) rule) +#define TOKEN(t) +#define NAMED(t, name) , PSI_Token *name +#define TYPED(t, name) , TOKEN_TYPE_NAME(t) name +#define TOKEN_TYPE_NAME(token) _##token##_type +#define TOKEN_TYPE(token, type) typedef type TOKEN_TYPE_NAME(token); +#define TOKEN_DTOR(token, dtor) +#endif + +DEF(%include, { +void psi_error(int, const char *, int, const char *, ...); +}) + +DEF(%name, PSI_ParserProc) +DEF(%token_prefix, PSI_T_) +DEF(%token_type, {PSI_Token *}) +DEF(%token_destructor, {free($$);}) +DEF(%default_destructor, {(void)P;}) +DEF(%extra_argument, {PSI_Parser *P}) + +/* TOKEN is defined inside syntax_error */ +DEF(%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"); + } +}) + +DEF(%nonassoc, NAME.) +DEF(%left, PLUS MINUS.) +DEF(%left, SLASH ASTERISK.) +DEF(%fallback, NAME TEMP FREE SET LET RETURN CALLOC CALLBACK ZVAL LIB STRING.) + +DEF(%token_class, const_type_token BOOL INT FLOAT STRING.) +DEF(%token_class, decl_type_token FLOAT DOUBLE INT8 UINT8 INT16 UINT16 INT32 UINT32 INT64 UINT64 NAME.) +DEF(%token_class, impl_def_val_token NULL NUMBER TRUE FALSE QUOTED_STRING.) +DEF(%token_class, num_exp_token NUMBER NSNAME.) +DEF(%token_class, num_exp_op_token PLUS MINUS ASTERISK SLASH.) +DEF(%token_class, let_func_token ZVAL OBJVAL ARRVAL PATHVAL STRLEN STRVAL FLOATVAL INTVAL BOOLVAL.) +DEF(%token_class, set_func_token TO_OBJECT TO_ARRAY TO_STRING TO_INT TO_FLOAT TO_BOOL ZVAL VOID.) +DEF(%token_class, impl_type_token VOID MIXED BOOL INT FLOAT STRING ARRAY OBJECT CALLABLE.) + +TOKEN_TYPE(decl_enum, decl_enum *) +TOKEN_DTOR(decl_enum, free_decl_enum($$);) +TOKEN_TYPE(decl_enum_items, decl_enum_items*) +TOKEN_DTOR(decl_enum_items, free_decl_enum_items($$);) +TOKEN_TYPE(decl_enum_item, decl_enum_item*) +TOKEN_DTOR(decl_enum_item, free_decl_enum_item($$);) +TOKEN_TYPE(decl_struct_args_block, decl_args*) +TOKEN_DTOR(decl_struct_args_block, free_decl_args($$);) /* there was a typo */ +TOKEN_TYPE(decl_struct_args, decl_args*) +TOKEN_DTOR(decl_struct_args, free_decl_args($$);) +TOKEN_TYPE(decl_struct, decl_struct*) +TOKEN_DTOR(decl_struct, free_decl_struct($$);) +TOKEN_TYPE(align_and_size, decl_struct_layout) +TOKEN_TYPE(decl_union, decl_union*) +TOKEN_DTOR(decl_union, free_decl_union($$);) +TOKEN_TYPE(const_type, const_type*) +TOKEN_DTOR(const_type, free_const_type($$);) +TOKEN_TYPE(constant, constant*) +TOKEN_DTOR(constant, free_constant($$);) +TOKEN_TYPE(decl_typedef, decl_arg*) +TOKEN_DTOR(decl_typedef, free_decl_arg($$);) +TOKEN_TYPE(decl_typedef_body_ex, decl_arg*) +TOKEN_DTOR(decl_typedef_body_ex, free_decl_arg($$);) +TOKEN_TYPE(decl_typedef_body, decl_arg*) +TOKEN_DTOR(decl_typedef_body, free_decl_arg($$);) +TOKEN_TYPE(decl_typedef_body_fn_args, decl_args *) +TOKEN_DTOR(decl_typedef_body_fn_args, free_decl_args($$);) +TOKEN_TYPE(decl, decl*) +TOKEN_DTOR(decl, free_decl($$);) +TOKEN_TYPE(decl_func, decl_arg*) +TOKEN_DTOR(decl_func, free_decl_arg($$);) +TOKEN_TYPE(decl_abi, decl_abi*) +TOKEN_DTOR(decl_abi, free_decl_abi($$);) +TOKEN_TYPE(decl_var, decl_var*) +TOKEN_DTOR(decl_var, free_decl_var($$);) +TOKEN_TYPE(decl_vars, decl_vars*) +TOKEN_DTOR(decl_vars, free_decl_vars($$);) +TOKEN_TYPE(decl_arg, decl_arg*) +TOKEN_DTOR(decl_arg, free_decl_arg($$);) +TOKEN_TYPE(decl_args, decl_args*) +TOKEN_DTOR(decl_args, free_decl_args($$);) +TOKEN_TYPE(struct_args, decl_args*) +TOKEN_DTOR(struct_args, free_decl_args($$);) +TOKEN_TYPE(struct_arg, decl_arg*) +TOKEN_DTOR(struct_arg, free_decl_arg($$);) +TOKEN_TYPE(struct_layout, decl_struct_layout*) +TOKEN_DTOR(struct_layout, free_decl_struct_layout($$);) +TOKEN_TYPE(decl_type, decl_type*) +TOKEN_DTOR(decl_type, free_decl_type($$);) +TOKEN_TYPE(const_decl_type, decl_type*) +TOKEN_DTOR(const_decl_type, free_decl_type($$);) +TOKEN_TYPE(impl, impl*) +TOKEN_DTOR(impl, free_impl($$);) +TOKEN_TYPE(impl_func, impl_func*) +TOKEN_DTOR(impl_func, free_impl_func($$);) +TOKEN_TYPE(impl_def_val, impl_def_val*) +TOKEN_DTOR(impl_def_val, free_impl_def_val($$);) +TOKEN_TYPE(impl_var, impl_var*) +TOKEN_DTOR(impl_var, free_impl_var($$);) +TOKEN_TYPE(impl_arg, impl_arg*) +TOKEN_DTOR(impl_arg, free_impl_arg($$);) +TOKEN_TYPE(impl_args, impl_args*) +TOKEN_DTOR(impl_args, free_impl_args($$);) +TOKEN_TYPE(impl_vararg, impl_arg*) +TOKEN_DTOR(impl_vararg, free_impl_arg($$);) +TOKEN_TYPE(impl_arg_list, impl_args*) +TOKEN_DTOR(impl_arg_list, free_impl_args($$);) +TOKEN_TYPE(impl_stmts, impl_stmts*) +TOKEN_DTOR(impl_stmts, free_impl_stmts($$);) +TOKEN_TYPE(impl_stmt, impl_stmt*) +TOKEN_DTOR(impl_stmt, free_impl_stmt($$);) +TOKEN_TYPE(num_exp, num_exp*) +TOKEN_DTOR(num_exp, free_num_exp($$);) +TOKEN_TYPE(let_stmt, let_stmt*) +TOKEN_DTOR(let_stmt, free_let_stmt($$);) +TOKEN_TYPE(let_calloc, let_calloc*) +TOKEN_DTOR(let_calloc, free_let_calloc($$);) +TOKEN_TYPE(let_func, let_func*) +TOKEN_DTOR(let_func, free_let_func($$);) +TOKEN_TYPE(callback_arg_list, set_values *) +TOKEN_DTOR(callback_arg_list, free_set_values($$);) +TOKEN_TYPE(callback_args, set_values *) +TOKEN_DTOR(callback_args, free_set_values($$);) +TOKEN_TYPE(let_val, let_val*) +TOKEN_DTOR(let_val, free_let_val($$);) +TOKEN_TYPE(set_stmt, set_stmt*) +TOKEN_DTOR(set_stmt, free_set_stmt($$);) +TOKEN_TYPE(set_value, set_value*) +TOKEN_DTOR(set_value, free_set_value($$);) +TOKEN_TYPE(set_vals, set_value*) +TOKEN_DTOR(set_vals, free_set_value($$);) +TOKEN_TYPE(set_func, set_func*) +TOKEN_DTOR(set_func, free_set_func($$);) +TOKEN_TYPE(return_stmt, return_stmt*) +TOKEN_DTOR(return_stmt, free_return_stmt($$);) +TOKEN_TYPE(free_stmt, free_stmt*) +TOKEN_DTOR(free_stmt, free_free_stmt($$);) +TOKEN_TYPE(free_calls, free_calls*) +TOKEN_DTOR(free_calls, free_free_calls($$);) +TOKEN_TYPE(free_call, free_call*) +TOKEN_DTOR(free_call, free_free_call($$);) +TOKEN_TYPE(impl_type, impl_type*) +TOKEN_DTOR(impl_type, free_impl_type($$);) +TOKEN_TYPE(reference, char) +TOKEN_TYPE(indirection, unsigned) +TOKEN_TYPE(pointers, unsigned) + +LET(file, blocks) +LET(blocks, block) +LET(blocks, blocks block) + +LET(block, EOF) +LET(block, EOS) + +PARSE(block, NAMED(LIB, token) NAMED(QUOTED_STRING, libname) TOKEN(EOS)) { + if (P->psi.file.ln) { + P->error(P, token, PSI_WARNING, "Extra 'lib %s' statement has no effect", libname->text); + } else { + P->psi.file.ln = strndup(libname->text + 1, libname->size - 2); + } + free(libname); + free(token); +} +PARSE(block, TYPED(decl, decl)) { + P->decls = add_decl(P->decls, decl); +} + +PARSE(block, TYPED(impl, impl)) { + P->impls = add_impl(P->impls, impl); +} + +PARSE(block, TYPED(decl_typedef, def)) { + P->defs = add_decl_typedef(P->defs, def); + switch (def->type->type) { + case PSI_T_STRUCT: + if (def->type->real.strct) { + P->structs = add_decl_struct(P->structs, def->type->real.strct); + } + break; + case PSI_T_UNION: + if (def->type->real.unn) { + P->unions = add_decl_union(P->unions, def->type->real.unn); + } + break; + case PSI_T_ENUM: + if (def->type->real.enm) { + P->enums = add_decl_enum(P->enums, def->type->real.enm); + } + break; + } +} + +PARSE(block, TYPED(constant, constant)) { + P->consts = add_constant(P->consts, constant); +} + +PARSE(block, TYPED(decl_struct, strct)) { + P->structs = add_decl_struct(P->structs, strct); +} + +PARSE(block, TYPED(decl_union, u)) { + P->unions = add_decl_union(P->unions, u); +} + +PARSE(block, TYPED(decl_enum, e)) { + P->enums = add_decl_enum(P->enums, e); +} + +PARSE_NAMED(optional_name, n, ) { + n = NULL; +} + +PARSE_NAMED(optional_name, n, + NAMED(NAME, N)) { + n = N; +} + +PARSE_NAMED(enum_name, n, + NAMED(ENUM, E) NAMED(optional_name, N)) { + if (N) { + n = N; + free(E); + } else { + char digest[17]; + + PSI_TokenHash(E, digest); + n = PSI_TokenTranslit(PSI_TokenAppend(E, 1, digest), " ", "@"); + } +} + +PARSE_TYPED(decl_enum, e, + NAMED(enum_name, N) + TOKEN(LBRACE) + TYPED(decl_enum_items, list) + TOKEN(RBRACE)) { + e = init_decl_enum(N->text, list); + e->token = N; +} + +PARSE_TYPED(decl_enum_items, l, + TYPED(decl_enum_item, i)) { + l = init_decl_enum_items(i); +} +PARSE_TYPED(decl_enum_items, l, + TYPED(decl_enum_items, l_) + TOKEN(COMMA) + TYPED(decl_enum_item, i)) { + l = add_decl_enum_item(l_, i); +} + +PARSE_TYPED(decl_enum_item, i, + NAMED(NAME, N) + TOKEN(EQUALS) + TYPED(num_exp, num)) { + i = init_decl_enum_item(N->text, num); + i->token = N; +} +PARSE_TYPED(decl_enum_item, i, + NAMED(NAME, N)) { + i = init_decl_enum_item(N->text, NULL); + i->token = N; +} + +PARSE_NAMED(union_name, n, + NAMED(UNION, U) + NAMED(optional_name, N)) { + if (N) { + n = N; + free(U); + } else { + char digest[17]; + + PSI_TokenHash(U, digest); + n = PSI_TokenTranslit(PSI_TokenAppend(U, 1, digest), " ", "@"); + } +} + +PARSE_NAMED(struct_name, n, + NAMED(STRUCT, S) + NAMED(optional_name, N)) { + if (N) { + n = N; + free(S); + } else { + char digest[17]; + + PSI_TokenHash(S, digest); + n = PSI_TokenTranslit(PSI_TokenAppend(S, 1, digest), " ", "@"); + } +} + +PARSE_TYPED(decl_struct_args_block, args_, + TOKEN(LBRACE) + TYPED(struct_args, args) + TOKEN(RBRACE)) { + args_ = args; +} + +PARSE_TYPED(decl_struct_args, args_, + TYPED(decl_struct_args_block, args)) { + args_ = args; +} +PARSE_TYPED(decl_struct_args, args_, + TOKEN(EOS)) { + args_ = init_decl_args(NULL); +} + +PARSE_TYPED(decl_struct, strct, + TOKEN(STRUCT) + NAMED(NAME, N) + TYPED(align_and_size, as) + TYPED(decl_struct_args, args)) { + strct = init_decl_struct(N->text, args); + strct->align = as.pos; + strct->size = as.len; + strct->token = N; +} + +PARSE_TYPED(align_and_size, as, ) { + as.pos = 0; + as.len = 0; +} +PARSE_TYPED(align_and_size, as, + TOKEN(COLON) + TOKEN(COLON) + TOKEN(LPAREN) + NAMED(NUMBER, A) + TOKEN(COMMA) + NAMED(NUMBER, S) + TOKEN(RPAREN)) { + as.pos = atol(A->text); + as.len = atol(S->text); + free(A); + free(S); +} + +PARSE_TYPED(decl_union, u, + TOKEN(UNION) + NAMED(NAME, N) + TYPED(align_and_size, as) + TYPED(decl_struct_args, args)) { + u = init_decl_union(N->text, args); + u->align = as.pos; + u->size = as.len; + u->token = N; +} + +PARSE_TYPED(const_type, type_, + NAMED(const_type_token, T)) { + type_ = init_const_type(T->type, T->text); + free(T); +} + +PARSE_TYPED(constant, constant, + TOKEN(CONST) + TYPED(const_type, type) + NAMED(NSNAME, T) + TOKEN(EQUALS) + TYPED(impl_def_val, val) + TOKEN(EOS)) { + constant = init_constant(type, T->text, val); + free(T); +} + +PARSE_TYPED(decl_typedef, def, + NAMED(TYPEDEF, T) + TYPED(decl_typedef_body, def_) + TOKEN(EOS)) { + def = def_; + def->token = T; +} + +PARSE_TYPED(decl_typedef_body_ex, def, + NAMED(struct_name, N) + TYPED(align_and_size, as) + TYPED(decl_struct_args_block, args) + TYPED(decl_var, var)) { + def = init_decl_arg(init_decl_type(PSI_T_STRUCT, N->text), var); + def->type->token = PSI_TokenCopy(N); + def->type->real.strct = init_decl_struct(N->text, args); + def->type->real.strct->token = N; + def->type->real.strct->align = as.pos; + def->type->real.strct->size = as.len; +} +PARSE_TYPED(decl_typedef_body_ex, def, + NAMED(union_name, N) + TYPED(align_and_size, as) + TYPED(decl_struct_args_block, args) + TYPED(decl_var, var)) { + def = init_decl_arg(init_decl_type(PSI_T_UNION, N->text), var); + def->type->token = PSI_TokenCopy(N); + def->type->real.unn = init_decl_union(N->text, args); + def->type->real.unn->token = N; + def->type->real.unn->align = as.pos; + def->type->real.unn->size = as.len; +} +PARSE_TYPED(decl_typedef_body_ex, def, + TYPED(decl_enum, e) + NAMED(NAME, ALIAS)) { + def = init_decl_arg(init_decl_type(PSI_T_ENUM, e->name), init_decl_var(ALIAS->text, 0, 0)); + def->var->token = ALIAS; + def->type->token = PSI_TokenCopy(e->token); + def->type->real.enm = e; +} + +PARSE_TYPED(decl_typedef_body, def, + TYPED(decl_typedef_body_ex, def_)) { + def = def_; +} + +PARSE_TYPED(decl_typedef_body_fn_args, args, + TOKEN(LPAREN) + TYPED(decl_args, args_) + TOKEN(RPAREN)) { + args = args_; +} +PARSE_TYPED(decl_typedef_body, def, + TYPED(decl_func, func_) + TYPED(decl_typedef_body_fn_args, args)) { + def = init_decl_arg(init_decl_type(PSI_T_FUNCTION, func_->var->name), copy_decl_var(func_->var)); + def->type->token = PSI_TokenCopy(func_->token); + def->type->real.func = init_decl(init_decl_abi("default"), func_, args); +} +PARSE_TYPED(decl_typedef_body, def, + TYPED(decl_arg, arg)) { + def = arg; +} + +PARSE_TYPED(decl, decl, + TYPED(decl_abi, abi) + TYPED(decl_func, func) + TOKEN(LPAREN) + TYPED(decl_args, args) + TOKEN(RPAREN) + TOKEN(EOS)) { + decl = init_decl(abi, func, args); +} + +PARSE_TYPED(decl_func, func, + TYPED(decl_arg, arg)) { + func = arg; +} +/* special case for void functions */ +PARSE_TYPED(decl_func, func, + NAMED(VOID, T) + NAMED(NAME, N)) { + func = init_decl_arg( + init_decl_type(T->type, T->text), + init_decl_var(N->text, 0, 0) + ); + func->type->token = T; + func->var->token = N; + func->token = N; +} +PARSE_TYPED(decl_typedef_body, def, + NAMED(VOID, T) + TYPED(indirection, decl_i) + TOKEN(LPAREN) + TYPED(indirection, type_i) + NAMED(NAME, N) + TOKEN(RPAREN) + TYPED(decl_typedef_body_fn_args, args)) { + decl_arg *func_ = init_decl_arg( + init_decl_type(T->type, T->text), + init_decl_var(N->text, decl_i, 0) + ); + func_->type->token = T; + func_->var->token = N; + func_->token = N; + + def = init_decl_arg( + init_decl_type(PSI_T_FUNCTION, func_->var->name), + copy_decl_var(func_->var) + ); + def->var->pointer_level = type_i; + def->type->token = PSI_TokenCopy(func_->token); + def->type->real.func = init_decl(init_decl_abi("default"), func_, args); +} +PARSE_TYPED(decl_typedef_body, def, + TOKEN(CONST) + NAMED(VOID, T) + TYPED(pointers, decl_i) + TOKEN(LPAREN) + TYPED(indirection, type_i) + NAMED(NAME, N) + TOKEN(RPAREN) + TYPED(decl_typedef_body_fn_args, args)) { + decl_arg *func_ = init_decl_arg( + init_decl_type(T->type, T->text), + init_decl_var(N->text, decl_i, 0) + ); + func_->type->token = T; + func_->var->token = N; + func_->token = N; + + def = init_decl_arg( + init_decl_type(PSI_T_FUNCTION, func_->var->name), + copy_decl_var(func_->var) + ); + def->var->pointer_level = type_i; + def->type->token = PSI_TokenCopy(func_->token); + def->type->real.func = init_decl(init_decl_abi("default"), func_, args); +} + +PARSE_TYPED(decl_abi, abi, + NAMED(NAME, T)) { + abi = init_decl_abi(T->text); + abi->token = T; +} + +PARSE_TYPED(decl_var, var, + TYPED(indirection, p) + NAMED(NAME, T)) { + var = init_decl_var(T->text, p, 0); + var->token = T; +} +PARSE_TYPED(decl_var, var, + TYPED(indirection, p) + NAMED(NAME, T) + TOKEN(LBRACKET) + NAMED(NUMBER, D) + TOKEN(RBRACKET)) { + var = init_decl_var(T->text, p+1, atol(D->text)); + var->token = T; + free(D); +} + +PARSE_TYPED(decl_vars, vars, + TYPED(decl_var, var)) { + vars = init_decl_vars(var); +} +PARSE_TYPED(decl_vars, vars, + TYPED(decl_vars, vars_) + TOKEN(COMMA) + TYPED(decl_var, var)) { + vars = add_decl_var(vars_, var); +} + +PARSE_TYPED(decl_arg, arg_, + TYPED(const_decl_type, type) + TYPED(decl_var, var)) { + arg_ = init_decl_arg(type, var); +} +PARSE_TYPED(decl_typedef_body, def, + TYPED(const_decl_type, type_) + TYPED(indirection, decl_i) + TOKEN(LPAREN) + TYPED(indirection, type_i) + NAMED(NAME, N) + TOKEN(RPAREN) + TYPED(decl_typedef_body_fn_args, args)) { + decl_arg *func_ = init_decl_arg( + type_, + init_decl_var(N->text, decl_i, 0) + ); + func_->var->token = N; + func_->token = N; + + def = init_decl_arg( + init_decl_type(PSI_T_FUNCTION, func_->var->name), + copy_decl_var(func_->var) + ); + def->var->pointer_level = type_i; + def->type->token = PSI_TokenCopy(func_->token); + def->type->real.func = init_decl(init_decl_abi("default"), func_, args); +} + +/* void pointers need a specific rule */ +PARSE_TYPED(decl_arg, arg_, + NAMED(VOID, T) + TYPED(pointers, p) + NAMED(NAME, N)) { + arg_ = init_decl_arg( + init_decl_type(T->type, T->text), + init_decl_var(N->text, p, 0) + ); + arg_->type->token = T; + arg_->var->token = N; + arg_->token = N; +} +PARSE_TYPED(decl_arg, arg_, + TOKEN(CONST) + NAMED(VOID, T) + TYPED(pointers, p) + NAMED(NAME, N)) { + arg_ = init_decl_arg( + init_decl_type(T->type, T->text), + init_decl_var(N->text, p, 0) + ); + arg_->type->token = T; + arg_->var->token = N; + arg_->token = N; +} + +LET(decl_args, ) +LET(decl_args, VOID) +PARSE_TYPED(decl_args, args, + TYPED(decl_arg, arg)) { + args = init_decl_args(arg); +} +PARSE_TYPED(decl_args, args, + TYPED(decl_args, args_) + TOKEN(COMMA) + TYPED(decl_arg, arg)) { + args = add_decl_arg(args_, arg); +} +PARSE_TYPED(decl_args, args, + TYPED(decl_args, args_) + TOKEN(COMMA) + TOKEN(ELLIPSIS)) { + args = args_; + args->varargs = 1; +} + +PARSE_TYPED(struct_args, args, + TYPED(struct_arg, arg)) { + args = init_decl_args(arg); +} +PARSE_TYPED(struct_args, args, + TYPED(struct_args, args_) + TYPED(struct_arg, arg)) { + args = add_decl_arg(args_, arg); +} + +PARSE_TYPED(struct_arg, arg_, + TYPED(decl_typedef_body_ex, def) + TOKEN(EOS)) { + arg_ = def; + switch (def->type->type) { + case PSI_T_STRUCT: + if (def->type->real.strct) { + P->structs = add_decl_struct(P->structs, def->type->real.strct); + } + break; + case PSI_T_UNION: + if (def->type->real.unn) { + P->unions = add_decl_union(P->unions, def->type->real.unn); + } + break; + case PSI_T_ENUM: + if (def->type->real.enm) { + P->enums = add_decl_enum(P->enums, def->type->real.enm); + } + break; + } +} +PARSE_TYPED(struct_arg, arg, + TYPED(decl_arg, arg_) + TYPED(struct_layout, layout_) + TOKEN(EOS)) { + arg_->layout = layout_; + arg = arg_; +} + +PARSE_TYPED(struct_layout, layout, ) { + layout = NULL; +} +PARSE_TYPED(struct_layout, layout, + TOKEN(COLON) + TOKEN(COLON) + TOKEN(LPAREN) + NAMED(NUMBER, POS) + TOKEN(COMMA) + NAMED(NUMBER, SIZ) + TOKEN(RPAREN)) { + layout = init_decl_struct_layout(atol(POS->text), atol(SIZ->text)); + free(POS); + free(SIZ); +} + +/* un/signed, urgh */ +PARSE_NAMED(decl_scalar_type, type_, + NAMED(CHAR, C)) { + type_ = C; +} +PARSE_NAMED(decl_scalar_type, type_, + NAMED(SHORT, S) + NAMED(decl_scalar_type_short, s)) { + if (s) { + type_ = PSI_TokenCat(2, S, s); + free(S); + free(s); + } else { + type_ = S; + } +} +PARSE_NAMED(decl_scalar_type_short, s, ) { + s = NULL; +} + +PARSE_NAMED(decl_scalar_type_short, s, + NAMED(INT, I)) { + s = I; +} +PARSE_NAMED(decl_scalar_type, type_, + NAMED(INT, I)) { + type_ = I; +} +PARSE_NAMED(decl_scalar_type, type_, + NAMED(LONG, L) + NAMED(decl_scalar_type_long, l)) { + if (l) { + type_ = PSI_TokenCat(2, L, l); + free(L); + free(l); + } else { + type_ = L; + } +} +PARSE_NAMED(decl_scalar_type_long, l, ) { + l = NULL; +} +PARSE_NAMED(decl_scalar_type_long, l, + NAMED(DOUBLE, D)) { + l = D; +} +PARSE_NAMED(decl_scalar_type_long, l, + NAMED(LONG, L) + NAMED(decl_scalar_type_long_long, ll)) { + if (ll) { + l = PSI_TokenCat(2, L, ll); + free(L); + free(ll); + } else { + l = L; + } +} +PARSE_NAMED(decl_scalar_type_long_long, ll, ) { + ll = NULL; +} +PARSE_NAMED(decl_scalar_type_long_long, ll, + NAMED(INT, I)) { + ll = I; +} +PARSE_TYPED(decl_type, type_, + NAMED(UNSIGNED, U) + NAMED(decl_scalar_type, N)) { + PSI_Token *T = PSI_TokenCat(2, U, N); + type_ = init_decl_type(T->type, T->text); + type_->token = T; + free(U); + free(N); +} +PARSE_TYPED(decl_type, type_, + NAMED(SIGNED, S) + NAMED(decl_scalar_type, N)) { + PSI_Token *T = PSI_TokenCat(2, S, N); + type_ = init_decl_type(T->type, T->text); + type_->token = T; + free(S); + free(N); +} +PARSE_TYPED(decl_type, type_, + NAMED(UNSIGNED, U)) { + type_ = init_decl_type(PSI_T_NAME, U->text); + type_->token = U; +} +PARSE_TYPED(decl_type, type_, + NAMED(SIGNED, S)) { + type_ = init_decl_type(PSI_T_NAME, S->text); + type_->token = S; +} +PARSE_TYPED(decl_type, type_, + NAMED(decl_scalar_type, N)) { + type_ = init_decl_type(N->type, N->text); + type_->token = N; +} +/* structs ! */ +PARSE_TYPED(decl_type, type_, + NAMED(STRUCT, S) + NAMED(NAME, T)) { + type_ = init_decl_type(S->type, T->text); + type_->token = T; + free(S); +} +PARSE_TYPED(decl_type, type_, + NAMED(UNION, U) + NAMED(NAME, T)) { + type_ = init_decl_type(U->type, T->text); + type_->token = T; + free(U); +} +PARSE_TYPED(decl_type, type_, + NAMED(ENUM, E) + NAMED(NAME, T)) { + type_ = init_decl_type(E->type, T->text); + type_->token = T; + free(E); +} +PARSE_TYPED(decl_type, type_, + NAMED(decl_type_token, T)) { + type_ = init_decl_type(T->type, T->text); + type_->token = T; +} + + +PARSE_TYPED(const_decl_type, type, + TYPED(decl_type, type_)) { + type = type_; +} +PARSE_TYPED(const_decl_type, type, + TOKEN(CONST) + TYPED(decl_type, type_)) { + type = type_; +} + +PARSE_TYPED(impl, impl, + TYPED(impl_func, func) + TOKEN(LBRACE) + TYPED(impl_stmts, stmts) + TOKEN(RBRACE)) { + impl = init_impl(func, stmts); +} + +PARSE_TYPED(impl_func, func, + TOKEN(FUNCTION) + TYPED(reference, r) + NAMED(NSNAME, NAME) + TYPED(impl_args, args) + TOKEN(COLON) + TYPED(impl_type, type)) { + func = init_impl_func(NAME->text, args, type, r); + func->token = NAME; +} + +PARSE_TYPED(impl_def_val, def, + NAMED(impl_def_val_token, T)) { + def = init_impl_def_val(T->type, T->text); + free(T); +} + +PARSE_TYPED(impl_var, var, + TYPED(reference, r) + NAMED(DOLLAR_NAME, T)) { + var = init_impl_var(T->text, r); + var->token = T; +} + +PARSE_TYPED(impl_arg, arg, + TYPED(impl_type, type) + TYPED(impl_var, var)) { + arg = init_impl_arg(type, var, NULL); +} +PARSE_TYPED(impl_arg, arg, + TYPED(impl_type, type) + TYPED(impl_var, var) + TOKEN(EQUALS) + TYPED(impl_def_val, def)) { + arg = init_impl_arg(type, var, def); +} + +PARSE_TYPED(impl_args, args, + TOKEN(LPAREN) + TOKEN(RPAREN)) { + args = NULL; +} +PARSE_TYPED(impl_args, args, + TOKEN(LPAREN) + TYPED(impl_arg_list, args_) + TOKEN(RPAREN)) { + args = args_; +} +PARSE_TYPED(impl_args, args, + TOKEN(LPAREN) + TYPED(impl_arg_list, args_) + TOKEN(COMMA) + TYPED(impl_vararg, va) + TOKEN(RPAREN)) { + args = args_; + args->vararg.name = va; +} + +PARSE_TYPED(impl_vararg, va, + TYPED(impl_type, type) + TYPED(reference, r) + TOKEN(ELLIPSIS) + NAMED(DOLLAR_NAME, T)) { + va = init_impl_arg(type, init_impl_var(T->text, r), NULL); + free(T); +} + +PARSE_TYPED(impl_arg_list, args, + TYPED(impl_arg, arg)) { + args = init_impl_args(arg); +} +PARSE_TYPED(impl_arg_list, args, + TYPED(impl_arg_list, args_) + TOKEN(COMMA) + TYPED(impl_arg, arg)) { + args = add_impl_arg(args_, arg); +} + +PARSE_TYPED(impl_stmts, stmts, + TYPED(impl_stmt, stmt)) { + stmts = init_impl_stmts(stmt); +} +PARSE_TYPED(impl_stmts, stmts, + TYPED(impl_stmts, stmts_) + TYPED(impl_stmt, stmt)) { + stmts = add_impl_stmt(stmts_, stmt); +} + +PARSE_TYPED(impl_stmt, stmt, + TYPED(let_stmt, let)) { + stmt = init_impl_stmt(PSI_T_LET, let); +} +PARSE_TYPED(impl_stmt, stmt, + TYPED(set_stmt, set)) { + stmt = init_impl_stmt(PSI_T_SET, set); +} +PARSE_TYPED(impl_stmt, stmt, + TYPED(return_stmt, ret)) { + stmt = init_impl_stmt(PSI_T_RETURN, ret); +} +PARSE_TYPED(impl_stmt, stmt, + TYPED(free_stmt, free)) { + stmt = init_impl_stmt(PSI_T_FREE, free); +} + +PARSE_TYPED(num_exp, exp, + NAMED(num_exp_token, tok)) { + exp = init_num_exp(tok->type, tok->text); + exp->token = tok; +} +PARSE_TYPED(num_exp, exp, + TYPED(decl_var, var)) { + exp = init_num_exp(PSI_T_NAME, var); + exp->token = PSI_TokenCopy(var->token); +} +PARSE_TYPED(num_exp, exp, + TYPED(num_exp, exp_) + NAMED(num_exp_op_token, operator_) + TYPED(num_exp, operand_)) { + exp_->operator = operator_->type; + exp_->operand = operand_; + exp = exp_; + free(operator_); +} + +PARSE_TYPED(let_stmt, let, + TOKEN(LET) + TYPED(decl_var, var) + TOKEN(EOS)) { + let = init_let_stmt(var, init_let_val(PSI_LET_NULL, NULL)); +} +PARSE_TYPED(let_stmt, let, + TOKEN(LET) + TYPED(decl_var, var) + TOKEN(EQUALS) + TYPED(reference, r) + TYPED(let_val, val) + TOKEN(EOS)) { + val->flags.one.is_reference = r ? 1 : 0; + let = init_let_stmt(var, val); +} +PARSE_TYPED(let_stmt, let, + TOKEN(TEMP) + TYPED(decl_var, var) + TOKEN(EQUALS) + TYPED(decl_var, val) + TOKEN(EOS)) { + let = init_let_stmt(var, init_let_val(PSI_LET_TMP, val)); +} + +PARSE_TYPED(let_calloc, alloc, + TYPED(num_exp, nmemb) + TOKEN(COMMA) + TYPED(num_exp, size)) { + alloc = init_let_calloc(nmemb, size); +} + +PARSE_TYPED(let_func, func, + NAMED(let_func_token, T) + TOKEN(LPAREN) + TYPED(impl_var, var) + TOKEN(RPAREN)) { + func = init_let_func(T->type, T->text, var); + free(T); +} + +LET(callback_arg_list, ) +PARSE_TYPED(callback_arg_list, args, + TYPED(callback_args, args_)) { + args = args_; +} + +PARSE_TYPED(callback_args, args, + TYPED(set_value, val)) { + args = init_set_values(val); +} +PARSE_TYPED(callback_args, args, + TYPED(callback_args, args_) + TOKEN(COMMA) + TYPED(set_value, val)) { + args = add_set_value(args_, val); +} + +PARSE_TYPED(let_val, val, + TOKEN(NULL)) { + val = init_let_val(PSI_LET_NULL, NULL); +} +PARSE_TYPED(let_val, val, + TYPED(num_exp, exp)) { + val = init_let_val(PSI_LET_NUMEXP, exp); +} +PARSE_TYPED(let_val, val, + TOKEN(CALLOC) + TOKEN(LPAREN) + TYPED(let_calloc, alloc) + TOKEN(RPAREN)) { + val = init_let_val(PSI_LET_CALLOC, alloc); +} +PARSE_TYPED(let_val, val, + TYPED(let_func, func)) { + val = init_let_val(PSI_LET_FUNC, func); +} +PARSE_TYPED(let_val, val, + TOKEN(CALLBACK) + NAMED(let_func_token, F) + TOKEN(LPAREN) + TYPED(impl_var, var) + TOKEN(LPAREN) + TYPED(callback_arg_list, args_) + TOKEN(RPAREN) + TOKEN(RPAREN)) { + val = init_let_val(PSI_LET_CALLBACK, init_let_callback( + init_let_func(F->type, F->text, var), args_)); + free(F); +} + +PARSE_TYPED(set_stmt, set, + TOKEN(SET) + TYPED(impl_var, var) + TOKEN(EQUALS) + TYPED(set_value, val) + TOKEN(EOS)) { + set = init_set_stmt(var, val); +} + +PARSE_TYPED(set_value, val, + TYPED(set_func, func) + TOKEN(LPAREN) + TYPED(decl_var, var) + TOKEN(RPAREN)) { + val = init_set_value(func, init_decl_vars(var)); +} +PARSE_TYPED(set_value, val, + TYPED(set_func, func) + TOKEN(LPAREN) + TYPED(decl_var, var) + TOKEN(COMMA) + TYPED(num_exp, num_) + TOKEN(RPAREN)) { + val = init_set_value(func, init_decl_vars(var)); + val->num = num_; +} +PARSE_TYPED(set_value, val, + TYPED(set_func, func_) + TOKEN(LPAREN) + TYPED(decl_var, var) + TOKEN(COMMA) + NAMED(ELLIPSIS, T) + TOKEN(RPAREN)) { + free_set_func(func_); + val = init_set_value(init_set_func(T->type, T->text), init_decl_vars(var)); + val->func->token = T; +} +PARSE_TYPED(set_value, val, + TYPED(set_func, func_) + TOKEN(LPAREN) + TYPED(decl_var, var) + TOKEN(COMMA) + TYPED(set_vals, vals) + TOKEN(RPAREN)) { + val = vals; + val->func = func_; + val->vars = init_decl_vars(var); +} +PARSE_TYPED(set_value, val, + TYPED(set_func, func_) + TOKEN(LPAREN) + TYPED(decl_var, var) + TOKEN(COMMA) + TYPED(num_exp, num_) + TOKEN(COMMA) + TYPED(set_vals, vals) + TOKEN(RPAREN)) { + val = vals; + val->func = func_; + val->num = num_; + val->vars = init_decl_vars(var); +} + +PARSE_TYPED(set_vals, vals, + TYPED(set_value, val)) { + vals = add_inner_set_value(init_set_value(NULL, NULL), val); +} +PARSE_TYPED(set_vals, vals, + TYPED(set_vals, vals_) + TOKEN(COMMA) + TYPED(set_value, val)) { + vals = add_inner_set_value(vals_, val); +} + +PARSE_TYPED(set_func, func, + NAMED(set_func_token, T)) { + func = init_set_func(T->type, T->text); + func->token = T; +} + +PARSE_TYPED(return_stmt, ret, + NAMED(RETURN, T) + TYPED(set_value, val) + TOKEN(EOS)) { + ret = init_return_stmt(val); + ret->token = T; +} + +PARSE_TYPED(free_stmt, free, + TOKEN(FREE) + TYPED(free_calls, calls) + TOKEN(EOS)) { + free = init_free_stmt(calls); +} + +PARSE_TYPED(free_calls, calls, + TYPED(free_call, call)) { + calls = init_free_calls(call); +} +PARSE_TYPED(free_calls, calls, + TYPED(free_calls, calls_) + TOKEN(COMMA) + TYPED(free_call, call)) { + calls = add_free_call(calls_, call); +} + +PARSE_TYPED(free_call, call, + NAMED(NAME, F) + TOKEN(LPAREN) + TYPED(decl_vars, vars) + TOKEN(RPAREN)) { + call = init_free_call(F->text, vars); + call->token = F; +} + +PARSE_TYPED(impl_type, type_, + NAMED(impl_type_token, T)) { + type_ = init_impl_type(T->type, T->text); + free(T); +} + +PARSE_TYPED(reference, r, ) { + r = 0; +} +PARSE_TYPED(reference, r, + TOKEN(AMPERSAND)) { + r = 1; +} + +PARSE_TYPED(indirection, i, ){ + i = 0; +} +PARSE_TYPED(indirection, i, + TYPED(pointers, p)) { + i = p; +} + +PARSE_TYPED(pointers, p, + TOKEN(ASTERISK)) { + p = 1; +} +PARSE_TYPED(pointers, p, + TYPED(pointers, p_) + TOKEN(ASTERISK)) { + p = p_+1; +} diff --git a/src/parser_proc.h b/src/parser_proc.h index 0ccde26..2acef5a 100644 --- a/src/parser_proc.h +++ b/src/parser_proc.h @@ -13,65 +13,65 @@ #define PSI_T_ZVAL 13 #define PSI_T_LIB 14 #define PSI_T_STRING 15 -#define PSI_T_EOF 16 -#define PSI_T_EOS 17 -#define PSI_T_QUOTED_STRING 18 -#define PSI_T_ENUM 19 -#define PSI_T_LBRACE 20 -#define PSI_T_RBRACE 21 -#define PSI_T_COMMA 22 -#define PSI_T_EQUALS 23 -#define PSI_T_UNION 24 -#define PSI_T_STRUCT 25 -#define PSI_T_COLON 26 -#define PSI_T_LPAREN 27 -#define PSI_T_NUMBER 28 -#define PSI_T_RPAREN 29 -#define PSI_T_BOOL 30 -#define PSI_T_INT 31 -#define PSI_T_FLOAT 32 -#define PSI_T_CONST 33 -#define PSI_T_NSNAME 34 -#define PSI_T_TYPEDEF 35 -#define PSI_T_VOID 36 -#define PSI_T_LBRACKET 37 -#define PSI_T_RBRACKET 38 -#define PSI_T_ELLIPSIS 39 -#define PSI_T_CHAR 40 -#define PSI_T_SHORT 41 -#define PSI_T_LONG 42 -#define PSI_T_DOUBLE 43 -#define PSI_T_UNSIGNED 44 -#define PSI_T_SIGNED 45 -#define PSI_T_INT8 46 -#define PSI_T_UINT8 47 -#define PSI_T_INT16 48 -#define PSI_T_UINT16 49 -#define PSI_T_INT32 50 -#define PSI_T_UINT32 51 -#define PSI_T_INT64 52 -#define PSI_T_UINT64 53 -#define PSI_T_FUNCTION 54 -#define PSI_T_NULL 55 -#define PSI_T_TRUE 56 -#define PSI_T_FALSE 57 -#define PSI_T_DOLLAR_NAME 58 -#define PSI_T_OBJVAL 59 -#define PSI_T_ARRVAL 60 -#define PSI_T_PATHVAL 61 -#define PSI_T_STRLEN 62 -#define PSI_T_STRVAL 63 -#define PSI_T_FLOATVAL 64 -#define PSI_T_INTVAL 65 -#define PSI_T_BOOLVAL 66 -#define PSI_T_TO_OBJECT 67 -#define PSI_T_TO_ARRAY 68 -#define PSI_T_TO_STRING 69 -#define PSI_T_TO_INT 70 -#define PSI_T_TO_FLOAT 71 -#define PSI_T_TO_BOOL 72 -#define PSI_T_MIXED 73 -#define PSI_T_ARRAY 74 -#define PSI_T_OBJECT 75 -#define PSI_T_CALLABLE 76 +#define PSI_T_BOOL 16 +#define PSI_T_INT 17 +#define PSI_T_FLOAT 18 +#define PSI_T_DOUBLE 19 +#define PSI_T_INT8 20 +#define PSI_T_UINT8 21 +#define PSI_T_INT16 22 +#define PSI_T_UINT16 23 +#define PSI_T_INT32 24 +#define PSI_T_UINT32 25 +#define PSI_T_INT64 26 +#define PSI_T_UINT64 27 +#define PSI_T_NULL 28 +#define PSI_T_NUMBER 29 +#define PSI_T_TRUE 30 +#define PSI_T_FALSE 31 +#define PSI_T_QUOTED_STRING 32 +#define PSI_T_NSNAME 33 +#define PSI_T_OBJVAL 34 +#define PSI_T_ARRVAL 35 +#define PSI_T_PATHVAL 36 +#define PSI_T_STRLEN 37 +#define PSI_T_STRVAL 38 +#define PSI_T_FLOATVAL 39 +#define PSI_T_INTVAL 40 +#define PSI_T_BOOLVAL 41 +#define PSI_T_TO_OBJECT 42 +#define PSI_T_TO_ARRAY 43 +#define PSI_T_TO_STRING 44 +#define PSI_T_TO_INT 45 +#define PSI_T_TO_FLOAT 46 +#define PSI_T_TO_BOOL 47 +#define PSI_T_VOID 48 +#define PSI_T_MIXED 49 +#define PSI_T_ARRAY 50 +#define PSI_T_OBJECT 51 +#define PSI_T_CALLABLE 52 +#define PSI_T_EOF 53 +#define PSI_T_EOS 54 +#define PSI_T_ENUM 55 +#define PSI_T_LBRACE 56 +#define PSI_T_RBRACE 57 +#define PSI_T_COMMA 58 +#define PSI_T_EQUALS 59 +#define PSI_T_UNION 60 +#define PSI_T_STRUCT 61 +#define PSI_T_COLON 62 +#define PSI_T_LPAREN 63 +#define PSI_T_RPAREN 64 +#define PSI_T_CONST 65 +#define PSI_T_TYPEDEF 66 +#define PSI_T_LBRACKET 67 +#define PSI_T_RBRACKET 68 +#define PSI_T_ELLIPSIS 69 +#define PSI_T_CHAR 70 +#define PSI_T_SHORT 71 +#define PSI_T_LONG 72 +#define PSI_T_UNSIGNED 73 +#define PSI_T_SIGNED 74 +#define PSI_T_FUNCTION 75 +#define PSI_T_DOLLAR_NAME 76 #define PSI_T_AMPERSAND 77 diff --git a/src/parser_proc.inc b/src/parser_proc.inc new file mode 100644 index 0000000..5d87612 --- /dev/null +++ b/src/parser_proc.inc @@ -0,0 +1,9 @@ +%include { +#include +#include +#include +#include +#include + +#include "parser.h" +} diff --git a/src/parser_proc.y b/src/parser_proc.y index b46053a..4099877 100644 --- a/src/parser_proc.y +++ b/src/parser_proc.y @@ -6,880 +6,761 @@ #include #include "parser.h" - -void psi_error(int, const char *, int, const char *, ...); } - +%include { void psi_error(int, const char *, int, const char *, ...); } %name PSI_ParserProc %token_prefix PSI_T_ %token_type {PSI_Token *} %token_destructor {free($$);} %default_destructor {(void)P;} %extra_argument {PSI_Parser *P} -/* TOKEN is defined inside syntax_error */ -%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"); - } -} - +%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"); } } %nonassoc NAME. %left PLUS MINUS. %left SLASH ASTERISK. %fallback NAME TEMP FREE SET LET RETURN CALLOC CALLBACK ZVAL LIB STRING. - +%token_class const_type_token BOOL INT FLOAT STRING. +%token_class decl_type_token FLOAT DOUBLE INT8 UINT8 INT16 UINT16 INT32 UINT32 INT64 UINT64 NAME. +%token_class impl_def_val_token NULL NUMBER TRUE FALSE QUOTED_STRING. +%token_class num_exp_token NUMBER NSNAME. +%token_class num_exp_op_token PLUS MINUS ASTERISK SLASH. +%token_class let_func_token ZVAL OBJVAL ARRVAL PATHVAL STRLEN STRVAL FLOATVAL INTVAL BOOLVAL. +%token_class set_func_token TO_OBJECT TO_ARRAY TO_STRING TO_INT TO_FLOAT TO_BOOL ZVAL VOID. +%token_class impl_type_token VOID MIXED BOOL INT FLOAT STRING ARRAY OBJECT CALLABLE. +%type decl_enum {decl_enum *} +%destructor decl_enum {free_decl_enum($$);} +%type decl_enum_items {decl_enum_items*} +%destructor decl_enum_items {free_decl_enum_items($$);} +%type decl_enum_item {decl_enum_item*} +%destructor decl_enum_item {free_decl_enum_item($$);} +%type decl_struct_args_block {decl_args*} +%destructor decl_struct_args_block {free_decl_args($$);} +%type decl_struct_args {decl_args*} +%destructor decl_struct_args {free_decl_args($$);} +%type decl_struct {decl_struct*} +%destructor decl_struct {free_decl_struct($$);} +%type align_and_size {decl_struct_layout} +%type decl_union {decl_union*} +%destructor decl_union {free_decl_union($$);} +%type const_type {const_type*} +%destructor const_type {free_const_type($$);} +%type constant {constant*} +%destructor constant {free_constant($$);} +%type decl_typedef {decl_arg*} +%destructor decl_typedef {free_decl_arg($$);} +%type decl_typedef_body_ex {decl_arg*} +%destructor decl_typedef_body_ex {free_decl_arg($$);} +%type decl_typedef_body {decl_arg*} +%destructor decl_typedef_body {free_decl_arg($$);} +%type decl_typedef_body_fn_args {decl_args *} +%destructor decl_typedef_body_fn_args {free_decl_args($$);} +%type decl {decl*} +%destructor decl {free_decl($$);} +%type decl_func {decl_arg*} +%destructor decl_func {free_decl_arg($$);} +%type decl_abi {decl_abi*} +%destructor decl_abi {free_decl_abi($$);} +%type decl_var {decl_var*} +%destructor decl_var {free_decl_var($$);} +%type decl_vars {decl_vars*} +%destructor decl_vars {free_decl_vars($$);} +%type decl_arg {decl_arg*} +%destructor decl_arg {free_decl_arg($$);} +%type decl_args {decl_args*} +%destructor decl_args {free_decl_args($$);} +%type struct_args {decl_args*} +%destructor struct_args {free_decl_args($$);} +%type struct_arg {decl_arg*} +%destructor struct_arg {free_decl_arg($$);} +%type struct_layout {decl_struct_layout*} +%destructor struct_layout {free_decl_struct_layout($$);} +%type decl_type {decl_type*} +%destructor decl_type {free_decl_type($$);} +%type const_decl_type {decl_type*} +%destructor const_decl_type {free_decl_type($$);} +%type impl {impl*} +%destructor impl {free_impl($$);} +%type impl_func {impl_func*} +%destructor impl_func {free_impl_func($$);} +%type impl_def_val {impl_def_val*} +%destructor impl_def_val {free_impl_def_val($$);} +%type impl_var {impl_var*} +%destructor impl_var {free_impl_var($$);} +%type impl_arg {impl_arg*} +%destructor impl_arg {free_impl_arg($$);} +%type impl_args {impl_args*} +%destructor impl_args {free_impl_args($$);} +%type impl_vararg {impl_arg*} +%destructor impl_vararg {free_impl_arg($$);} +%type impl_arg_list {impl_args*} +%destructor impl_arg_list {free_impl_args($$);} +%type impl_stmts {impl_stmts*} +%destructor impl_stmts {free_impl_stmts($$);} +%type impl_stmt {impl_stmt*} +%destructor impl_stmt {free_impl_stmt($$);} +%type num_exp {num_exp*} +%destructor num_exp {free_num_exp($$);} +%type let_stmt {let_stmt*} +%destructor let_stmt {free_let_stmt($$);} +%type let_calloc {let_calloc*} +%destructor let_calloc {free_let_calloc($$);} +%type let_func {let_func*} +%destructor let_func {free_let_func($$);} +%type callback_arg_list {set_values *} +%destructor callback_arg_list {free_set_values($$);} +%type callback_args {set_values *} +%destructor callback_args {free_set_values($$);} +%type let_val {let_val*} +%destructor let_val {free_let_val($$);} +%type set_stmt {set_stmt*} +%destructor set_stmt {free_set_stmt($$);} +%type set_value {set_value*} +%destructor set_value {free_set_value($$);} +%type set_vals {set_value*} +%destructor set_vals {free_set_value($$);} +%type set_func {set_func*} +%destructor set_func {free_set_func($$);} +%type return_stmt {return_stmt*} +%destructor return_stmt {free_return_stmt($$);} +%type free_stmt {free_stmt*} +%destructor free_stmt {free_free_stmt($$);} +%type free_calls {free_calls*} +%destructor free_calls {free_free_calls($$);} +%type free_call {free_call*} +%destructor free_call {free_free_call($$);} +%type impl_type {impl_type*} +%destructor impl_type {free_impl_type($$);} +%type reference {char} +%type indirection {unsigned} +%type pointers {unsigned} file ::= blocks. - blocks ::= block. blocks ::= blocks block. - block ::= EOF. block ::= EOS. - -block ::= LIB(T) QUOTED_STRING(libname) EOS. { - if (P->psi.file.ln) { - P->error(P, T, PSI_WARNING, "Extra 'lib %s' statement has no effect", libname->text); - } else { - P->psi.file.ln = strndup(libname->text + 1, libname->size - 2); - } - free(libname); - free(T); +block ::= LIB(token) QUOTED_STRING(libname) EOS. { + if (P->psi.file.ln) { + P->error(P, token, PSI_WARNING, "Extra 'lib %s' statement has no effect", libname->text); + } else { + P->psi.file.ln = strndup(libname->text + 1, libname->size - 2); + } + free(libname); + free(token); } - block ::= decl(decl). { - P->decls = add_decl(P->decls, decl); + P->decls = add_decl(P->decls, decl); } block ::= impl(impl). { - P->impls = add_impl(P->impls, impl); + P->impls = add_impl(P->impls, impl); } block ::= decl_typedef(def). { - P->defs = add_decl_typedef(P->defs, def); - switch (def->type->type) { - case PSI_T_STRUCT: - if (def->type->real.strct) { - P->structs = add_decl_struct(P->structs, def->type->real.strct); - } - break; - case PSI_T_UNION: - if (def->type->real.unn) { - P->unions = add_decl_union(P->unions, def->type->real.unn); - } - break; - case PSI_T_ENUM: - if (def->type->real.enm) { - P->enums = add_decl_enum(P->enums, def->type->real.enm); - } - break; - } + P->defs = add_decl_typedef(P->defs, def); + switch (def->type->type) { + case PSI_T_STRUCT: + if (def->type->real.strct) { + P->structs = add_decl_struct(P->structs, def->type->real.strct); + } + break; + case PSI_T_UNION: + if (def->type->real.unn) { + P->unions = add_decl_union(P->unions, def->type->real.unn); + } + break; + case PSI_T_ENUM: + if (def->type->real.enm) { + P->enums = add_decl_enum(P->enums, def->type->real.enm); + } + break; + } } block ::= constant(constant). { - P->consts = add_constant(P->consts, constant); + P->consts = add_constant(P->consts, constant); } block ::= decl_struct(strct). { - P->structs = add_decl_struct(P->structs, strct); + P->structs = add_decl_struct(P->structs, strct); } block ::= decl_union(u). { - P->unions = add_decl_union(P->unions, u); + P->unions = add_decl_union(P->unions, u); } block ::= decl_enum(e). { - P->enums = add_decl_enum(P->enums, e); + P->enums = add_decl_enum(P->enums, e); } - -optional_name(n) ::= .{ - n = NULL; +optional_name(n) ::= . { + n = NULL; } optional_name(n) ::= NAME(N). { - n = N; + n = N; } - enum_name(n) ::= ENUM(E) optional_name(N). { - if (N) { - n = N; - free(E); - } else { - char digest[17]; - - PSI_TokenHash(E, digest); - n = PSI_TokenTranslit(PSI_TokenAppend(E, 1, digest), " ", "@"); - } + if (N) { + n = N; + free(E); + } else { + char digest[17]; + PSI_TokenHash(E, digest); + n = PSI_TokenTranslit(PSI_TokenAppend(E, 1, digest), " ", "@"); + } } - -%type decl_enum {decl_enum *} -%destructor decl_enum {free_decl_enum($$);} decl_enum(e) ::= enum_name(N) LBRACE decl_enum_items(list) RBRACE. { - e = init_decl_enum(N->text, list); - e->token = N; + e = init_decl_enum(N->text, list); + e->token = N; } - -%type decl_enum_items {decl_enum_items*} -%destructor decl_enum_items {free_decl_enum_items($$);} decl_enum_items(l) ::= decl_enum_item(i). { - l = init_decl_enum_items(i); + l = init_decl_enum_items(i); } decl_enum_items(l) ::= decl_enum_items(l_) COMMA decl_enum_item(i). { - l = add_decl_enum_item(l_, i); + l = add_decl_enum_item(l_, i); } - -%type decl_enum_item {decl_enum_item*} -%destructor decl_enum_item {free_decl_enum_item($$);} decl_enum_item(i) ::= NAME(N) EQUALS num_exp(num). { - i = init_decl_enum_item(N->text, num); - i->token = N; + i = init_decl_enum_item(N->text, num); + i->token = N; } decl_enum_item(i) ::= NAME(N). { - i = init_decl_enum_item(N->text, NULL); - i->token = N; + i = init_decl_enum_item(N->text, NULL); + i->token = N; } - union_name(n) ::= UNION(U) optional_name(N). { - if (N) { - n = N; - free(U); - } else { - char digest[17]; - - PSI_TokenHash(U, digest); - n = PSI_TokenTranslit(PSI_TokenAppend(U, 1, digest), " ", "@"); - } + if (N) { + n = N; + free(U); + } else { + char digest[17]; + PSI_TokenHash(U, digest); + n = PSI_TokenTranslit(PSI_TokenAppend(U, 1, digest), " ", "@"); + } } - struct_name(n) ::= STRUCT(S) optional_name(N). { - if (N) { - n = N; - free(S); - } else { - char digest[17]; - - PSI_TokenHash(S, digest); - n = PSI_TokenTranslit(PSI_TokenAppend(S, 1, digest), " ", "@"); - } + if (N) { + n = N; + free(S); + } else { + char digest[17]; + PSI_TokenHash(S, digest); + n = PSI_TokenTranslit(PSI_TokenAppend(S, 1, digest), " ", "@"); + } } - -%type decl_struct_args_block {decl_args*} -%destructor decl_struct_args_block {free_decl_args($$);} decl_struct_args_block(args_) ::= LBRACE struct_args(args) RBRACE. { - args_ = args; + args_ = args; } -%type decl_struct_args {decl_args*} -%destructor decl_struct_args {free_decl_args($$);} decl_struct_args(args_) ::= decl_struct_args_block(args). { - args_ = args; + args_ = args; } decl_struct_args(args_) ::= EOS. { - args_ = init_decl_args(NULL); + args_ = init_decl_args(NULL); } - - -%type decl_struct {decl_struct*} -%destructor decl_struct {free_decl_struct($$);} decl_struct(strct) ::= STRUCT NAME(N) align_and_size(as) decl_struct_args(args). { - strct = init_decl_struct(N->text, args); - strct->align = as.a; - strct->size = as.s; - strct->token = N; + strct = init_decl_struct(N->text, args); + strct->align = as.pos; + strct->size = as.len; + strct->token = N; } - -%type align_and_size { struct {size_t a; size_t s; } } align_and_size(as) ::= . { - as.a = 0; - as.s = 0; + as.pos = 0; + as.len = 0; } align_and_size(as) ::= COLON COLON LPAREN NUMBER(A) COMMA NUMBER(S) RPAREN. { - as.a = atol(A->text); - as.s = atol(S->text); - free(A); - free(S); + as.pos = atol(A->text); + as.len = atol(S->text); + free(A); + free(S); } - -%type decl_union {decl_union*} -%destructor decl_union {free_decl_union($$);} decl_union(u) ::= UNION NAME(N) align_and_size(as) decl_struct_args(args). { - u = init_decl_union(N->text, args); - u->align = as.a; - u->size = as.s; - u->token = N; + u = init_decl_union(N->text, args); + u->align = as.pos; + u->size = as.len; + u->token = N; } - -%token_class const_type_token BOOL INT FLOAT STRING. -%type const_type {const_type*} -%destructor const_type {free_const_type($$);} const_type(type_) ::= const_type_token(T). { - type_ = init_const_type(T->type, T->text); - free(T); + type_ = init_const_type(T->type, T->text); + free(T); } -%type constant {constant*} -%destructor constant {free_constant($$);} constant(constant) ::= CONST const_type(type) NSNAME(T) EQUALS impl_def_val(val) EOS. { - constant = init_constant(type, T->text, val); - free(T); -} - -%type decl_typedef {decl_arg*} -%destructor decl_typedef { - free_decl_arg($$);/* - if ($$->type->real.strct) { - free_decl_struct($$->type->real.strct); - } - if ($$->type->real.enm) { - free_decl_enum($$->type->real.enm); - } - if ($$->type->real.func) { - free_decl($$->type->real.func); - }*/ + constant = init_constant(type, T->text, val); + free(T); } decl_typedef(def) ::= TYPEDEF(T) decl_typedef_body(def_) EOS. { - def = def_; - def->token = T; -} -%type decl_typedef_body_ex {decl_arg*} -%destructor decl_typedef_body_ex { - free_decl_arg($$);/* - if ($$->type->real.strct) { - free_decl_struct($$->type->real.strct); - } - if ($$->type->real.enm) { - free_decl_enum($$->type->real.enm); - } - if ($$->type->real.unn) { - free_decl_union($$->type->real.unn); - } - if ($$->type->real.func) { - free_decl($$->type->real.func); - }*/ + def = def_; + def->token = T; } decl_typedef_body_ex(def) ::= struct_name(N) align_and_size(as) decl_struct_args_block(args) decl_var(var). { - def = init_decl_arg(init_decl_type(PSI_T_STRUCT, N->text), var); - def->type->token = PSI_TokenCopy(N); - def->type->real.strct = init_decl_struct(N->text, args); - def->type->real.strct->token = N; - def->type->real.strct->align = as.a; - def->type->real.strct->size = as.s; + def = init_decl_arg(init_decl_type(PSI_T_STRUCT, N->text), var); + def->type->token = PSI_TokenCopy(N); + def->type->real.strct = init_decl_struct(N->text, args); + def->type->real.strct->token = N; + def->type->real.strct->align = as.pos; + def->type->real.strct->size = as.len; } decl_typedef_body_ex(def) ::= union_name(N) align_and_size(as) decl_struct_args_block(args) decl_var(var). { - def = init_decl_arg(init_decl_type(PSI_T_UNION, N->text), var); - def->type->token = PSI_TokenCopy(N); - def->type->real.unn = init_decl_union(N->text, args); - def->type->real.unn->token = N; - def->type->real.unn->align = as.a; - def->type->real.unn->size = as.s; + def = init_decl_arg(init_decl_type(PSI_T_UNION, N->text), var); + def->type->token = PSI_TokenCopy(N); + def->type->real.unn = init_decl_union(N->text, args); + def->type->real.unn->token = N; + def->type->real.unn->align = as.pos; + def->type->real.unn->size = as.len; } decl_typedef_body_ex(def) ::= decl_enum(e) NAME(ALIAS). { - def = init_decl_arg(init_decl_type(PSI_T_ENUM, e->name), init_decl_var(ALIAS->text, 0, 0)); - def->var->token = ALIAS; - def->type->token = PSI_TokenCopy(e->token); - def->type->real.enm = e; -} -%type decl_typedef_body {decl_arg*} -%destructor decl_typedef_body { - free_decl_arg($$);/* - if ($$->type->real.strct) { - free_decl_struct($$->type->real.strct); - } - if ($$->type->real.enm) { - free_decl_enum($$->type->real.enm); - } - if ($$->type->real.unn) { - free_decl_union($$->type->real.unn); - } - if ($$->type->real.func) { - free_decl($$->type->real.func); - }*/ + def = init_decl_arg(init_decl_type(PSI_T_ENUM, e->name), init_decl_var(ALIAS->text, 0, 0)); + def->var->token = ALIAS; + def->type->token = PSI_TokenCopy(e->token); + def->type->real.enm = e; } decl_typedef_body(def) ::= decl_typedef_body_ex(def_). { - def = def_; + def = def_; } -%type decl_typedef_body_fn_args {decl_args *} -%destructor decl_typedef_body_fn_args {free_decl_args($$);} decl_typedef_body_fn_args(args) ::= LPAREN decl_args(args_) RPAREN. { - args = args_; + args = args_; } decl_typedef_body(def) ::= decl_func(func_) decl_typedef_body_fn_args(args). { - def = init_decl_arg(init_decl_type(PSI_T_FUNCTION, func_->var->name), copy_decl_var(func_->var)); - def->type->token = PSI_TokenCopy(func_->token); - def->type->real.func = init_decl(init_decl_abi("default"), func_, args); + def = init_decl_arg(init_decl_type(PSI_T_FUNCTION, func_->var->name), copy_decl_var(func_->var)); + def->type->token = PSI_TokenCopy(func_->token); + def->type->real.func = init_decl(init_decl_abi("default"), func_, args); } decl_typedef_body(def) ::= decl_arg(arg). { - def = arg; + def = arg; } - -%type decl {decl*} -%destructor decl {free_decl($$);} decl(decl) ::= decl_abi(abi) decl_func(func) LPAREN decl_args(args) RPAREN EOS. { - decl = init_decl(abi, func, args); + decl = init_decl(abi, func, args); } - -%type decl_func {decl_arg*} -%destructor decl_func {free_decl_arg($$);} decl_func(func) ::= decl_arg(arg). { - func = arg; + func = arg; } -/* special case for void functions */ decl_func(func) ::= VOID(T) NAME(N). { - func = init_decl_arg( - init_decl_type(T->type, T->text), - init_decl_var(N->text, 0, 0) - ); - func->type->token = T; - func->var->token = N; - func->token = N; + func = init_decl_arg( + init_decl_type(T->type, T->text), + init_decl_var(N->text, 0, 0) + ); + func->type->token = T; + func->var->token = N; + func->token = N; } decl_typedef_body(def) ::= VOID(T) indirection(decl_i) LPAREN indirection(type_i) NAME(N) RPAREN decl_typedef_body_fn_args(args). { - decl_arg *func_ = init_decl_arg( - init_decl_type(T->type, T->text), - init_decl_var(N->text, decl_i, 0) - ); - func_->type->token = T; - func_->var->token = N; - func_->token = N; - - def = init_decl_arg( - init_decl_type(PSI_T_FUNCTION, func_->var->name), - copy_decl_var(func_->var) - ); - def->var->pointer_level = type_i; - def->type->token = PSI_TokenCopy(func_->token); - def->type->real.func = init_decl(init_decl_abi("default"), func_, args); + decl_arg *func_ = init_decl_arg( + init_decl_type(T->type, T->text), + init_decl_var(N->text, decl_i, 0) + ); + func_->type->token = T; + func_->var->token = N; + func_->token = N; + def = init_decl_arg( + init_decl_type(PSI_T_FUNCTION, func_->var->name), + copy_decl_var(func_->var) + ); + def->var->pointer_level = type_i; + def->type->token = PSI_TokenCopy(func_->token); + def->type->real.func = init_decl(init_decl_abi("default"), func_, args); } decl_typedef_body(def) ::= CONST VOID(T) pointers(decl_i) LPAREN indirection(type_i) NAME(N) RPAREN decl_typedef_body_fn_args(args). { - decl_arg *func_ = init_decl_arg( - init_decl_type(T->type, T->text), - init_decl_var(N->text, decl_i, 0) - ); - func_->type->token = T; - func_->var->token = N; - func_->token = N; - - def = init_decl_arg( - init_decl_type(PSI_T_FUNCTION, func_->var->name), - copy_decl_var(func_->var) - ); - def->var->pointer_level = type_i; - def->type->token = PSI_TokenCopy(func_->token); - def->type->real.func = init_decl(init_decl_abi("default"), func_, args); + decl_arg *func_ = init_decl_arg( + init_decl_type(T->type, T->text), + init_decl_var(N->text, decl_i, 0) + ); + func_->type->token = T; + func_->var->token = N; + func_->token = N; + def = init_decl_arg( + init_decl_type(PSI_T_FUNCTION, func_->var->name), + copy_decl_var(func_->var) + ); + def->var->pointer_level = type_i; + def->type->token = PSI_TokenCopy(func_->token); + def->type->real.func = init_decl(init_decl_abi("default"), func_, args); } - -%type decl_abi {decl_abi*} -%destructor decl_abi {free_decl_abi($$);} decl_abi(abi) ::= NAME(T). { - abi = init_decl_abi(T->text); - abi->token = T; + abi = init_decl_abi(T->text); + abi->token = T; } - -%type decl_var {decl_var*} -%destructor decl_var {free_decl_var($$);} decl_var(var) ::= indirection(p) NAME(T). { - var = init_decl_var(T->text, p, 0); - var->token = T; + var = init_decl_var(T->text, p, 0); + var->token = T; } decl_var(var) ::= indirection(p) NAME(T) LBRACKET NUMBER(D) RBRACKET. { - var = init_decl_var(T->text, p+1, atol(D->text)); - var->token = T; - free(D); + var = init_decl_var(T->text, p+1, atol(D->text)); + var->token = T; + free(D); } - -%type decl_vars {decl_vars*} -%destructor decl_vars {free_decl_vars($$);} decl_vars(vars) ::= decl_var(var). { - vars = init_decl_vars(var); + vars = init_decl_vars(var); } decl_vars(vars) ::= decl_vars(vars_) COMMA decl_var(var). { - vars = add_decl_var(vars_, var); + vars = add_decl_var(vars_, var); } - -%type decl_arg {decl_arg*} -%destructor decl_arg {free_decl_arg($$);} decl_arg(arg_) ::= const_decl_type(type) decl_var(var). { - arg_ = init_decl_arg(type, var); + arg_ = init_decl_arg(type, var); } decl_typedef_body(def) ::= const_decl_type(type_) indirection(decl_i) LPAREN indirection(type_i) NAME(N) RPAREN decl_typedef_body_fn_args(args). { - decl_arg *func_ = init_decl_arg( - type_, - init_decl_var(N->text, decl_i, 0) - ); - func_->var->token = N; - func_->token = N; - - def = init_decl_arg( - init_decl_type(PSI_T_FUNCTION, func_->var->name), - copy_decl_var(func_->var) - ); - def->var->pointer_level = type_i; - def->type->token = PSI_TokenCopy(func_->token); - def->type->real.func = init_decl(init_decl_abi("default"), func_, args); + decl_arg *func_ = init_decl_arg( + type_, + init_decl_var(N->text, decl_i, 0) + ); + func_->var->token = N; + func_->token = N; + def = init_decl_arg( + init_decl_type(PSI_T_FUNCTION, func_->var->name), + copy_decl_var(func_->var) + ); + def->var->pointer_level = type_i; + def->type->token = PSI_TokenCopy(func_->token); + def->type->real.func = init_decl(init_decl_abi("default"), func_, args); } - -/* void pointers need a specific rule */ decl_arg(arg_) ::= VOID(T) pointers(p) NAME(N). { - arg_ = init_decl_arg( - init_decl_type(T->type, T->text), - init_decl_var(N->text, p, 0) - ); - arg_->type->token = T; - arg_->var->token = N; - arg_->token = N; + arg_ = init_decl_arg( + init_decl_type(T->type, T->text), + init_decl_var(N->text, p, 0) + ); + arg_->type->token = T; + arg_->var->token = N; + arg_->token = N; } decl_arg(arg_) ::= CONST VOID(T) pointers(p) NAME(N). { - arg_ = init_decl_arg( - init_decl_type(T->type, T->text), - init_decl_var(N->text, p, 0) - ); - arg_->type->token = T; - arg_->var->token = N; - arg_->token = N; + arg_ = init_decl_arg( + init_decl_type(T->type, T->text), + init_decl_var(N->text, p, 0) + ); + arg_->type->token = T; + arg_->var->token = N; + arg_->token = N; } - -%type decl_args {decl_args*} -%destructor decl_args {free_decl_args($$);} decl_args ::= . decl_args ::= VOID. decl_args(args) ::= decl_arg(arg). { - args = init_decl_args(arg); + args = init_decl_args(arg); } decl_args(args) ::= decl_args(args_) COMMA decl_arg(arg). { - args = add_decl_arg(args_, arg); + args = add_decl_arg(args_, arg); } decl_args(args) ::= decl_args(args_) COMMA ELLIPSIS. { - args = args_; - args->varargs = 1; + args = args_; + args->varargs = 1; } -%type struct_args {decl_args*} -%destructor struct_args {free_decl_args($$);} struct_args(args) ::= struct_arg(arg). { - args = init_decl_args(arg); + args = init_decl_args(arg); } struct_args(args) ::= struct_args(args_) struct_arg(arg). { - args = add_decl_arg(args_, arg); -} -%type struct_arg {decl_arg*} -%destructor struct_arg { - free_decl_arg($$); - /* - if ($$->type->real.strct) { - free_decl_struct($$->type->real.strct); - } - if ($$->type->real.enm) { - free_decl_enum($$->type->real.enm); - } - if ($$->type->real.func) { - free_decl($$->type->real.func); - }*/ + args = add_decl_arg(args_, arg); } struct_arg(arg_) ::= decl_typedef_body_ex(def) EOS. { - arg_ = def; - switch (def->type->type) { - case PSI_T_STRUCT: - if (def->type->real.strct) { - P->structs = add_decl_struct(P->structs, def->type->real.strct); - } - break; - case PSI_T_UNION: - if (def->type->real.unn) { - P->unions = add_decl_union(P->unions, def->type->real.unn); - } - break; - case PSI_T_ENUM: - if (def->type->real.enm) { - P->enums = add_decl_enum(P->enums, def->type->real.enm); - } - break; - } + arg_ = def; + switch (def->type->type) { + case PSI_T_STRUCT: + if (def->type->real.strct) { + P->structs = add_decl_struct(P->structs, def->type->real.strct); + } + break; + case PSI_T_UNION: + if (def->type->real.unn) { + P->unions = add_decl_union(P->unions, def->type->real.unn); + } + break; + case PSI_T_ENUM: + if (def->type->real.enm) { + P->enums = add_decl_enum(P->enums, def->type->real.enm); + } + break; + } } struct_arg(arg) ::= decl_arg(arg_) struct_layout(layout_) EOS. { - arg_->layout = layout_; - arg = arg_; + arg_->layout = layout_; + arg = arg_; } - -%type struct_layout {decl_struct_layout*} -%destructor struct_layout {free_decl_struct_layout($$);} struct_layout(layout) ::= . { - layout = NULL; + layout = NULL; } struct_layout(layout) ::= COLON COLON LPAREN NUMBER(POS) COMMA NUMBER(SIZ) RPAREN. { - layout = init_decl_struct_layout(atol(POS->text), atol(SIZ->text)); - free(POS); - free(SIZ); + layout = init_decl_struct_layout(atol(POS->text), atol(SIZ->text)); + free(POS); + free(SIZ); } - -/* un/signed, urgh */ decl_scalar_type(type_) ::= CHAR(C). { - type_ = C; + type_ = C; } decl_scalar_type(type_) ::= SHORT(S) decl_scalar_type_short(s). { - if (s) { - type_ = PSI_TokenCat(2, S, s); - free(S); - free(s); - } else { - type_ = S; - } + if (s) { + type_ = PSI_TokenCat(2, S, s); + free(S); + free(s); + } else { + type_ = S; + } } decl_scalar_type_short(s) ::= . { - s = NULL; + s = NULL; } - decl_scalar_type_short(s) ::= INT(I). { - s = I; + s = I; } decl_scalar_type(type_) ::= INT(I). { - type_ = I; + type_ = I; } decl_scalar_type(type_) ::= LONG(L) decl_scalar_type_long(l). { - if (l) { - type_ = PSI_TokenCat(2, L, l); - free(L); - free(l); - } else { - type_ = L; - } + if (l) { + type_ = PSI_TokenCat(2, L, l); + free(L); + free(l); + } else { + type_ = L; + } } decl_scalar_type_long(l) ::= . { - l = NULL; + l = NULL; } decl_scalar_type_long(l) ::= DOUBLE(D). { - l = D; + l = D; } decl_scalar_type_long(l) ::= LONG(L) decl_scalar_type_long_long(ll). { - if (ll) { - l = PSI_TokenCat(2, L, ll); - free(L); - free(ll); - } else { - l = L; - } + if (ll) { + l = PSI_TokenCat(2, L, ll); + free(L); + free(ll); + } else { + l = L; + } } decl_scalar_type_long_long(ll) ::= . { - ll = NULL; + ll = NULL; } decl_scalar_type_long_long(ll) ::= INT(I). { - ll = I; + ll = I; } decl_type(type_) ::= UNSIGNED(U) decl_scalar_type(N). { - PSI_Token *T = PSI_TokenCat(2, U, N); - type_ = init_decl_type(T->type, T->text); - type_->token = T; - free(U); - free(N); + PSI_Token *T = PSI_TokenCat(2, U, N); + type_ = init_decl_type(T->type, T->text); + type_->token = T; + free(U); + free(N); } decl_type(type_) ::= SIGNED(S) decl_scalar_type(N). { - PSI_Token *T = PSI_TokenCat(2, S, N); - type_ = init_decl_type(T->type, T->text); - type_->token = T; - free(S); - free(N); + PSI_Token *T = PSI_TokenCat(2, S, N); + type_ = init_decl_type(T->type, T->text); + type_->token = T; + free(S); + free(N); } decl_type(type_) ::= UNSIGNED(U). { - type_ = init_decl_type(PSI_T_NAME, U->text); - type_->token = U; + type_ = init_decl_type(PSI_T_NAME, U->text); + type_->token = U; } decl_type(type_) ::= SIGNED(S). { - type_ = init_decl_type(PSI_T_NAME, S->text); - type_->token = S; + type_ = init_decl_type(PSI_T_NAME, S->text); + type_->token = S; } decl_type(type_) ::= decl_scalar_type(N). { - type_ = init_decl_type(N->type, N->text); - type_->token = N; + type_ = init_decl_type(N->type, N->text); + type_->token = N; } -/* structs ! */ decl_type(type_) ::= STRUCT(S) NAME(T). { - type_ = init_decl_type(S->type, T->text); - type_->token = T; - free(S); + type_ = init_decl_type(S->type, T->text); + type_->token = T; + free(S); } decl_type(type_) ::= UNION(U) NAME(T). { - type_ = init_decl_type(U->type, T->text); - type_->token = T; - free(U); + type_ = init_decl_type(U->type, T->text); + type_->token = T; + free(U); } decl_type(type_) ::= ENUM(E) NAME(T). { - type_ = init_decl_type(E->type, T->text); - type_->token = T; - free(E); + type_ = init_decl_type(E->type, T->text); + type_->token = T; + free(E); } -%token_class decl_type_token FLOAT DOUBLE INT8 UINT8 INT16 UINT16 INT32 UINT32 INT64 UINT64 NAME. -%type decl_type {decl_type*} -%destructor decl_type {free_decl_type($$);} decl_type(type_) ::= decl_type_token(T). { - type_ = init_decl_type(T->type, T->text); - type_->token = T; + type_ = init_decl_type(T->type, T->text); + type_->token = T; } - - -%type const_decl_type {decl_type*} -%destructor const_decl_type {free_decl_type($$);} const_decl_type(type) ::= decl_type(type_). { - type = type_; + type = type_; } const_decl_type(type) ::= CONST decl_type(type_). { - type = type_; + type = type_; } - -%type impl {impl*} -%destructor impl {free_impl($$);} impl(impl) ::= impl_func(func) LBRACE impl_stmts(stmts) RBRACE. { - impl = init_impl(func, stmts); + impl = init_impl(func, stmts); } - -%type impl_func {impl_func*} -%destructor impl_func {free_impl_func($$);} impl_func(func) ::= FUNCTION reference(r) NSNAME(NAME) impl_args(args) COLON impl_type(type). { - func = init_impl_func(NAME->text, args, type, r); - func->token = NAME; + func = init_impl_func(NAME->text, args, type, r); + func->token = NAME; } - -%token_class impl_def_val_token NULL NUMBER TRUE FALSE QUOTED_STRING. -%type impl_def_val {impl_def_val*} -%destructor impl_def_val {free_impl_def_val($$);} impl_def_val(def) ::= impl_def_val_token(T). { - def = init_impl_def_val(T->type, T->text); - free(T); + def = init_impl_def_val(T->type, T->text); + free(T); } - -%type impl_var {impl_var*} -%destructor impl_var {free_impl_var($$);} impl_var(var) ::= reference(r) DOLLAR_NAME(T). { - var = init_impl_var(T->text, r); - var->token = T; + var = init_impl_var(T->text, r); + var->token = T; } - -%type impl_arg {impl_arg*} -%destructor impl_arg {free_impl_arg($$);} impl_arg(arg) ::= impl_type(type) impl_var(var). { - arg = init_impl_arg(type, var, NULL); + arg = init_impl_arg(type, var, NULL); } impl_arg(arg) ::= impl_type(type) impl_var(var) EQUALS impl_def_val(def). { - arg = init_impl_arg(type, var, def); + arg = init_impl_arg(type, var, def); } - -%type impl_args {impl_args*} -%destructor impl_args {free_impl_args($$);} impl_args(args) ::= LPAREN RPAREN. { - args = NULL; + args = NULL; } impl_args(args) ::= LPAREN impl_arg_list(args_) RPAREN. { - args = args_; + args = args_; } impl_args(args) ::= LPAREN impl_arg_list(args_) COMMA impl_vararg(va) RPAREN. { - args = args_; - args->vararg.name = va; + args = args_; + args->vararg.name = va; } - -%type impl_vararg {impl_arg*} -%destructor impl_vararg {free_impl_arg($$);} impl_vararg(va) ::= impl_type(type) reference(r) ELLIPSIS DOLLAR_NAME(T). { - va = init_impl_arg(type, init_impl_var(T->text, r), NULL); - free(T); + va = init_impl_arg(type, init_impl_var(T->text, r), NULL); + free(T); } - -%type impl_arg_list {impl_args*} -%destructor impl_arg_list {free_impl_args($$);} impl_arg_list(args) ::= impl_arg(arg). { - args = init_impl_args(arg); + args = init_impl_args(arg); } impl_arg_list(args) ::= impl_arg_list(args_) COMMA impl_arg(arg). { - args = add_impl_arg(args_, arg); + args = add_impl_arg(args_, arg); } - -%type impl_stmts {impl_stmts*} -%destructor impl_stmts {free_impl_stmts($$);} impl_stmts(stmts) ::= impl_stmt(stmt). { - stmts = init_impl_stmts(stmt); + stmts = init_impl_stmts(stmt); } impl_stmts(stmts) ::= impl_stmts(stmts_) impl_stmt(stmt). { - stmts = add_impl_stmt(stmts_, stmt); + stmts = add_impl_stmt(stmts_, stmt); } - -%type impl_stmt {impl_stmt*} -%destructor impl_stmt {free_impl_stmt($$);} impl_stmt(stmt) ::= let_stmt(let). { - stmt = init_impl_stmt(PSI_T_LET, let); + stmt = init_impl_stmt(PSI_T_LET, let); } impl_stmt(stmt) ::= set_stmt(set). { - stmt = init_impl_stmt(PSI_T_SET, set); + stmt = init_impl_stmt(PSI_T_SET, set); } impl_stmt(stmt) ::= return_stmt(ret). { - stmt = init_impl_stmt(PSI_T_RETURN, ret); + stmt = init_impl_stmt(PSI_T_RETURN, ret); } impl_stmt(stmt) ::= free_stmt(free). { - stmt = init_impl_stmt(PSI_T_FREE, free); + stmt = init_impl_stmt(PSI_T_FREE, free); } - -%token_class num_exp_token NUMBER NSNAME. -%token_class num_exp_op_token PLUS MINUS ASTERISK SLASH. -%type num_exp {num_exp*} -%destructor num_exp {free_num_exp($$);} num_exp(exp) ::= num_exp_token(tok). { - exp = init_num_exp(tok->type, tok->text); - exp->token = tok; + exp = init_num_exp(tok->type, tok->text); + exp->token = tok; } num_exp(exp) ::= decl_var(var). { - exp = init_num_exp(PSI_T_NAME, var); - exp->token = PSI_TokenCopy(var->token); + exp = init_num_exp(PSI_T_NAME, var); + exp->token = PSI_TokenCopy(var->token); } num_exp(exp) ::= num_exp(exp_) num_exp_op_token(operator_) num_exp(operand_). { - exp_->operator = operator_->type; - exp_->operand = operand_; - exp = exp_; - free(operator_); + exp_->operator = operator_->type; + exp_->operand = operand_; + exp = exp_; + free(operator_); } - -%type let_stmt {let_stmt*} -%destructor let_stmt {free_let_stmt($$);} let_stmt(let) ::= LET decl_var(var) EOS. { - let = init_let_stmt(var, init_let_val(PSI_LET_NULL, NULL)); + let = init_let_stmt(var, init_let_val(PSI_LET_NULL, NULL)); } let_stmt(let) ::= LET decl_var(var) EQUALS reference(r) let_val(val) EOS. { - val->flags.one.is_reference = r ? 1 : 0; - let = init_let_stmt(var, val); + val->flags.one.is_reference = r ? 1 : 0; + let = init_let_stmt(var, val); } let_stmt(let) ::= TEMP decl_var(var) EQUALS decl_var(val) EOS. { - let = init_let_stmt(var, init_let_val(PSI_LET_TMP, val)); + let = init_let_stmt(var, init_let_val(PSI_LET_TMP, val)); } - -%type let_calloc {let_calloc*} -%destructor let_calloc {free_let_calloc($$);} let_calloc(alloc) ::= num_exp(nmemb) COMMA num_exp(size). { - alloc = init_let_calloc(nmemb, size); + alloc = init_let_calloc(nmemb, size); } -%token_class let_func_token ZVAL OBJVAL ARRVAL PATHVAL STRLEN STRVAL FLOATVAL INTVAL BOOLVAL. -%type let_func {let_func*} -%destructor let_func {free_let_func($$);} let_func(func) ::= let_func_token(T) LPAREN impl_var(var) RPAREN. { - func = init_let_func(T->type, T->text, var); - free(T); + func = init_let_func(T->type, T->text, var); + free(T); } - -%type callback_arg_list {set_values *} -%destructor callback_arg_list {free_set_values($$);} callback_arg_list ::= . callback_arg_list(args) ::= callback_args(args_). { - args = args_; + args = args_; } - -%type callback_args {set_values *} -%destructor callback_args {free_set_values($$);} callback_args(args) ::= set_value(val). { - args = init_set_values(val); + args = init_set_values(val); } callback_args(args) ::= callback_args(args_) COMMA set_value(val). { - args = add_set_value(args_, val); + args = add_set_value(args_, val); } - -%type let_val {let_val*} -%destructor let_val {free_let_val($$);} let_val(val) ::= NULL. { - val = init_let_val(PSI_LET_NULL, NULL); + val = init_let_val(PSI_LET_NULL, NULL); } let_val(val) ::= num_exp(exp). { - val = init_let_val(PSI_LET_NUMEXP, exp); + val = init_let_val(PSI_LET_NUMEXP, exp); } let_val(val) ::= CALLOC LPAREN let_calloc(alloc) RPAREN. { - val = init_let_val(PSI_LET_CALLOC, alloc); + val = init_let_val(PSI_LET_CALLOC, alloc); } let_val(val) ::= let_func(func). { - val = init_let_val(PSI_LET_FUNC, func); + val = init_let_val(PSI_LET_FUNC, func); } let_val(val) ::= CALLBACK let_func_token(F) LPAREN impl_var(var) LPAREN callback_arg_list(args_) RPAREN RPAREN. { - val = init_let_val(PSI_LET_CALLBACK, init_let_callback( - init_let_func(F->type, F->text, var), args_)); - free(F); + val = init_let_val(PSI_LET_CALLBACK, init_let_callback( + init_let_func(F->type, F->text, var), args_)); + free(F); } - -%type set_stmt {set_stmt*} -%destructor set_stmt {free_set_stmt($$);} set_stmt(set) ::= SET impl_var(var) EQUALS set_value(val) EOS. { - set = init_set_stmt(var, val); + set = init_set_stmt(var, val); } - -%type set_value {set_value*} -%destructor set_value {free_set_value($$);} set_value(val) ::= set_func(func) LPAREN decl_var(var) RPAREN. { - val = init_set_value(func, init_decl_vars(var)); + val = init_set_value(func, init_decl_vars(var)); } set_value(val) ::= set_func(func) LPAREN decl_var(var) COMMA num_exp(num_) RPAREN. { - val = init_set_value(func, init_decl_vars(var)); - val->num = num_; + val = init_set_value(func, init_decl_vars(var)); + val->num = num_; } set_value(val) ::= set_func(func_) LPAREN decl_var(var) COMMA ELLIPSIS(T) RPAREN. { - free_set_func(func_); - val = init_set_value(init_set_func(T->type, T->text), init_decl_vars(var)); - val->func->token = T; + free_set_func(func_); + val = init_set_value(init_set_func(T->type, T->text), init_decl_vars(var)); + val->func->token = T; } set_value(val) ::= set_func(func_) LPAREN decl_var(var) COMMA set_vals(vals) RPAREN. { - val = vals; - val->func = func_; - val->vars = init_decl_vars(var); + val = vals; + val->func = func_; + val->vars = init_decl_vars(var); } set_value(val) ::= set_func(func_) LPAREN decl_var(var) COMMA num_exp(num_) COMMA set_vals(vals) RPAREN. { - val = vals; - val->func = func_; - val->num = num_; - val->vars = init_decl_vars(var); + val = vals; + val->func = func_; + val->num = num_; + val->vars = init_decl_vars(var); } -%type set_vals {set_value*} -%destructor set_vals {free_set_value($$);} set_vals(vals) ::= set_value(val). { - vals = add_inner_set_value(init_set_value(NULL, NULL), val); + vals = add_inner_set_value(init_set_value(NULL, NULL), val); } set_vals(vals) ::= set_vals(vals_) COMMA set_value(val). { - vals = add_inner_set_value(vals_, val); + vals = add_inner_set_value(vals_, val); } - -%token_class set_func_token TO_OBJECT TO_ARRAY TO_STRING TO_INT TO_FLOAT TO_BOOL ZVAL VOID. -%type set_func {set_func*} -%destructor set_func {free_set_func($$);} set_func(func) ::= set_func_token(T). { - func = init_set_func(T->type, T->text); - func->token = T; + func = init_set_func(T->type, T->text); + func->token = T; } - -%type return_stmt {return_stmt*} -%destructor return_stmt {free_return_stmt($$);} return_stmt(ret) ::= RETURN(T) set_value(val) EOS. { - ret = init_return_stmt(val); - ret->token = T; + ret = init_return_stmt(val); + ret->token = T; } - -%type free_stmt {free_stmt*} -%destructor free_stmt {free_free_stmt($$);} free_stmt(free) ::= FREE free_calls(calls) EOS. { - free = init_free_stmt(calls); + free = init_free_stmt(calls); } - -%type free_calls {free_calls*} -%destructor free_calls {free_free_calls($$);} free_calls(calls) ::= free_call(call). { - calls = init_free_calls(call); + calls = init_free_calls(call); } free_calls(calls) ::= free_calls(calls_) COMMA free_call(call). { - calls = add_free_call(calls_, call); + calls = add_free_call(calls_, call); } - -%type free_call {free_call*} -%destructor free_call {free_free_call($$);} free_call(call) ::= NAME(F) LPAREN decl_vars(vars) RPAREN. { - call = init_free_call(F->text, vars); - call->token = F; + call = init_free_call(F->text, vars); + call->token = F; } - -%token_class impl_type_token VOID MIXED BOOL INT FLOAT STRING ARRAY OBJECT CALLABLE. -%type impl_type {impl_type*} -%destructor impl_type {free_impl_type($$);} impl_type(type_) ::= impl_type_token(T). { - type_ = init_impl_type(T->type, T->text); - free(T); + type_ = init_impl_type(T->type, T->text); + free(T); +} +reference(r) ::= . { + r = 0; +} +reference(r) ::= AMPERSAND. { + r = 1; +} +indirection(i) ::= .{ + i = 0; +} +indirection(i) ::= pointers(p). { + i = p; +} +pointers(p) ::= ASTERISK. { + p = 1; +} +pointers(p) ::= pointers(p_) ASTERISK. { + p = p_+1; } - -%type reference {char} -reference(r) ::= . {r = 0;} -reference(r) ::= AMPERSAND. {r = 1;} - -%type indirection {unsigned} -indirection(i) ::= . {i = 0;} -indirection(i) ::= pointers(p). {i = p;} - -%type pointers {unsigned} -pointers(p) ::= ASTERISK. {p = 1;} -pointers(p) ::= pointers(P) ASTERISK. {p = P+1;}