X-Git-Url: https://git.m6w6.name/?p=m6w6%2Fext-psi;a=blobdiff_plain;f=idl%2Fparser.y;fp=idl%2Fparser.y;h=9d71e63560b7ac8e9009e8fd8c83cfd85db75a1b;hp=74433f995ee35fff1625748bd5d0316ee2cc86ba;hb=5917ec1de81d919ac670af18166a41238aa1d3f6;hpb=6ed7825ca4ddea88b00968e20cbaeeb1e8eb3de4 diff --git a/idl/parser.y b/idl/parser.y index 74433f9..9d71e63 100644 --- a/idl/parser.y +++ b/idl/parser.y @@ -2,9 +2,22 @@ #include #include #include +#include #include "lexer.h" #include "parser.h" #include "types.h" + +static void syntax_error(const char *fn, size_t ln, const char *msg, ...) { + fprintf(stderr, "WARNING: Syntax error on line %zu in '%s'%s", ln, fn, msg ? ": ": "\n"); + if (msg) { + va_list argv; + + va_start(argv, msg); + vfprintf(stderr, msg, argv); + va_end(argv); + } +} + } %name PSI_Parser @@ -12,25 +25,42 @@ %token_type {PSI_Token *} %token_destructor {free($$);} %extra_argument {PSI_Lexer *L} +/* TOKEN is defined inside syntax_error */ %syntax_error { - printf("ERROR: Syntax error on line %zu in '%s': '%s...'\n", L->line, L->fn, L->tok); - exit(1); + syntax_error(L->fn, L->line, "Unexpected token '%s'.\n", TOKEN->text); } - file ::= blocks. blocks ::= block. blocks ::= blocks block. -block ::= decl(decl_). { - L->decl.list = realloc(L->decl.list, ++L->decl.count * sizeof(*L->decl.list)); - L->decl.list[L->decl.count-1] = decl_; +block ::= COMMENT. + +block ::= LIB(T) QUOTED_STRING(libname) EOS. { + if (L->lib) { + syntax_error(L->fn, T->line, "Extra 'lib %s' statement has no effect.\n", libname->text); + } else { + L->lib = strndup(libname->text + 1, libname->size - 2); + } + free(libname); + free(T); } -block ::= impl(impl_). { - L->impl.list = realloc(L->impl.list, ++L->impl.count * sizeof(*L->impl.list)); - L->impl.list[L->impl.count-1] = impl_; + +block ::= decl(decl). { + L->decls = add_decl(L->decls, decl); +} +block ::= impl(impl). { + L->impls = add_impl(L->impls, impl); +} +block ::= decl_typedef(def). { + L->defs = add_decl_typedef(L->defs, def); +} + +%type decl_typedef {decl_typedef*} +decl_typedef(def) ::= TYPEDEF NAME(ALIAS) decl_type(type) EOS. { + def = init_decl_typedef(ALIAS->text, type); + free(ALIAS); } -block ::= COMMENT. %type decl {decl*} decl(decl) ::= decl_arg(func) LPAREN decl_args(args) RPAREN EOS. { @@ -92,9 +122,37 @@ decl_type(type_) ::= UINT8(T). { type_ = init_decl_type(T->type, T->text); free(T); } +decl_type(type_) ::= SINT16(T). { + type_ = init_decl_type(T->type, T->text); + free(T); +} +decl_type(type_) ::= UINT16(T). { + type_ = init_decl_type(T->type, T->text); + free(T); +} +decl_type(type_) ::= SINT32(T). { + type_ = init_decl_type(T->type, T->text); + free(T); +} +decl_type(type_) ::= UINT32(T). { + type_ = init_decl_type(T->type, T->text); + free(T); +} +decl_type(type_) ::= SINT64(T). { + type_ = init_decl_type(T->type, T->text); + free(T); +} +decl_type(type_) ::= UINT64(T). { + type_ = init_decl_type(T->type, T->text); + free(T); +} +decl_type(type_) ::= NAME(T). { + type_ = init_decl_type(T->type, T->text); + free(T); +} %type impl {impl*} -impl(impl) ::= impl_func(func) LCURLY impl_stmts(stmts) RCURLY. { +impl(impl) ::= impl_func(func) LBRACE impl_stmts(stmts) RBRACE. { impl = init_impl(func, stmts); } @@ -103,6 +161,10 @@ impl_func(func) ::= FUNCTION NSNAME(NAME) LPAREN impl_args(args) RPAREN COLON im func = init_impl_func(NAME->text, args, type); free(NAME); } +impl_func(func) ::= FUNCTION NSNAME(NAME) LPAREN RPAREN COLON impl_type(type). { + func = init_impl_func(NAME->text, NULL, type); + free(NAME); +} %type impl_def_val {impl_def_val*} impl_def_val(def) ::= NULL. { @@ -166,13 +228,14 @@ let_stmt(let) ::= LET decl_var(var) EQUALS let_value(val) EOS. { %type let_value {let_value*} let_value(val) ::= let_func(func) LPAREN impl_var(var) RPAREN. { - val = init_let_value(func, var); + val = init_let_value(func, var, 0); } -let_value(val) ::= let_reference_null_pointer. { - val = init_let_value(NULL, NULL); +let_value(val) ::= REFERENCE NULL. { + val = init_let_value(NULL, NULL, 1); +} +let_value(val) ::= NULL. { + val = init_let_value(NULL, NULL, 0); } - -let_reference_null_pointer ::= REFERENCE NULL. %type let_func {let_func*} let_func(func) ::= STRVAL(T). {