X-Git-Url: https://git.draconx.ca/gitweb/cdecl99.git/blobdiff_plain/a118e977106144aa753045c59e9f5278facc48d7..da87235fd91665373a44dbc75b1750deaaf81abe:/src/parse.y diff --git a/src/parse.y b/src/parse.y index 3a17b99..6f3b304 100644 --- a/src/parse.y +++ b/src/parse.y @@ -32,7 +32,6 @@ #include #include "scan.h" -#include "cdecl.h" #include "cdecl-internal.h" #include "errmsg.h" @@ -66,10 +65,14 @@ #define ALLOC_ITEM_DECLSPEC(ptr) ALLOC_ITEM(ptr, declspec, next) #define ALLOC_ITEM_DECL(ptr) ALLOC_ITEM(ptr, decl, next) -#define ALLOC_FUNCTION(ptr, parameters_, variadic_) do { \ +#define ALLOC_FUNCTION_(ptr, parameters_) do { \ ALLOC_ITEM_DECLARATOR(ptr); \ (ptr)->type = CDECL_DECL_FUNCTION; \ (ptr)->u.function.parameters = parameters_; \ +} while (0) + +#define ALLOC_FUNCTION(ptr, parameters_, variadic_) do { \ + ALLOC_FUNCTION_(ptr, parameters_); \ (ptr)->u.function.variadic = variadic_; \ } while (0) @@ -104,18 +107,13 @@ * name strings can be used directly in error messages and there is no * need for any string processing. */ -#define yytnamerr(a, b) ( (a) ? yytnamerr_copy(a, b) \ - : strlen(b) ) - -static size_t yytnamerr_copy(char *dst, const char *src) -{ - return cdecl__strlcpy(dst, src, strlen(src)+1); -} +#define yytnamerr(a, b) ( (a) ? cdecl__strlcpy(a, b, -1) : strlen(b) ) %} %code requires { #include #include +#include "cdecl.h" } %code provides { @@ -125,7 +123,7 @@ const char *cdecl__token_name(unsigned token); } %union { - uintmax_t uintval; + cdecl_uintmax uintval; unsigned spectype; bool boolval; struct cdecl_declspec *declspec; @@ -226,11 +224,29 @@ static struct cdecl_declspec *join_specs3(struct cdecl_declspec *a, return b; } +/* + * Reverse the order of a "struct cdecl" list, and return the new first + * element of the list (i.e., the last element of the original list). + */ +static struct cdecl *reverse_decls(struct cdecl *decl) +{ + struct cdecl *prev, *next; + + for (prev = NULL; decl; decl = next) { + next = decl->next; + decl->next = prev; + prev = decl; + } + + return prev; +} + /* * Alter an abstract declarator (type name) to declare an identifier instead, * used by the English parser rules to reduce "identifier as type" sequences. */ -static struct cdecl *insert_identifier(struct cdecl *decl, struct parse_item *ident) +static struct cdecl * +insert_identifier(struct cdecl *decl, struct parse_item *ident) { struct cdecl_declarator *d, **p = &decl->declarators; @@ -256,7 +272,7 @@ static struct cdecl_declarator *nulldecl(void) %destructor { free_decl($$); } /* Magic tokens */ -%token T_LEX_ERROR +%token T_LEX_ERROR "@@@" %token T_IDENT "identifier" %token T_UINT "integer constant" @@ -343,7 +359,7 @@ cdecl: english | declaration semi: | T_SEMICOLON declaration: declspecs declarators semi { - $$ = $2; + $$ = reverse_decls($2); $$->specifiers = $1; }; @@ -382,9 +398,9 @@ qualifiers: { $$ = NULL; } | qualifiers qualifier { $$->next = $1; } -declarators: declarator_wrap | declarator_wrap T_COMMA declarators { - $$ = $1; - $$->next = $3; +declarators: declarator_wrap | declarators T_COMMA declarator_wrap { + $$ = $3; + $$->next = $1; } declarator_wrap: declarator { @@ -452,21 +468,23 @@ parameter: declspecs declarator { varargs: { $$ = false; } | T_COMMA T_ELLIPSIS { $$ = true; } -parameter_type_list: parameter varargs { - ALLOC_FUNCTION($$, $1, $2); -} | parameter T_COMMA parameter_type_list { - $$ = $3; - $1->next = $$->u.function.parameters; - $$->u.function.parameters = $1; +parameter_type_list: parameter { + ALLOC_FUNCTION_($$, $1); +} | parameter_type_list T_COMMA parameter { + $$ = $1; + $3->next = $$->u.function.parameters; + $$->u.function.parameters = $3; } -parens: T_LPAREN parameter_type_list T_RPAREN { +parens: T_LPAREN parameter_type_list varargs T_RPAREN { + $2->u.function.parameters = reverse_decls($2->u.function.parameters); + $2->u.function.variadic = $3; $$ = $2; } | T_LPAREN declarator_ish T_RPAREN { struct cdecl *fake_params; ALLOC_DECL(fake_params, NULL, $2); - ALLOC_FUNCTION($$, fake_params, false); + ALLOC_FUNCTION_($$, fake_params); } pointer: T_ASTERISK qualifiers direct_declarator { @@ -546,16 +564,18 @@ english_declarator: { english_function: T_FUNCTION T_RETURNING { ALLOC_FUNCTION($$, NULL, false); -} | T_FUNCTION T_LPAREN english_parameter_list T_RPAREN T_RETURNING { +} | T_FUNCTION T_LPAREN english_parameter_list varargs T_RPAREN T_RETURNING { + $3->u.function.parameters = reverse_decls($3->u.function.parameters); + $3->u.function.variadic = $4; $$ = $3; } -english_parameter_list: english_parameter varargs { - ALLOC_FUNCTION($$, $1, $2); -} | english_parameter T_COMMA english_parameter_list { - $$ = $3; - $1->next = $$->u.function.parameters; - $$->u.function.parameters = $1; +english_parameter_list: english_parameter { + ALLOC_FUNCTION_($$, $1); +} | english_parameter_list T_COMMA english_parameter { + $$ = $1; + $3->next = $$->u.function.parameters; + $$->u.function.parameters = $3; } typedef_name_qual: T_IDENT qualifiers {