X-Git-Url: https://git.draconx.ca/gitweb/cdecl99.git/blobdiff_plain/08ac16e49d67a40f0f8127cf43f8a166626615dc..0b2a2978f09f5d9b56d8655dd60eaffbe9006b7a:/src/parse.y diff --git a/src/parse.y b/src/parse.y index 8764159..6faf2d2 100644 --- a/src/parse.y +++ b/src/parse.y @@ -1,7 +1,7 @@ %code top { /* * Parser for C declarations. - * Copyright © 2011 Nick Bowler + * Copyright © 2011-2012, 2021, 2023 Nick Bowler * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,7 +18,8 @@ */ } -%parse-param {yyscan_t scanner} +%name-prefix "cdecl__yy" +%parse-param {void *scanner} %parse-param {struct cdecl **out} %lex-param {yyscan_t scanner} %define api.pure @@ -26,11 +27,14 @@ %locations %{ +#include #include #include #include "scan.h" #include "cdecl.h" +#include "cdecl-internal.h" +#include "errmsg.h" #define FAIL(msg) do { \ yyerror(&yylloc, NULL, NULL, msg); \ @@ -39,8 +43,10 @@ #define ALLOC(ptr, size) do { \ (ptr) = malloc(size); \ - if (!(ptr)) \ - FAIL("failed to allocate memory"); \ + if (!(ptr)) { \ + cdecl__errmsg(CDECL__ENOMEM); \ + YYERROR; \ + } \ } while (0) #define ALLOC_STRUCT(ptr, type, ...) do { \ @@ -54,12 +60,13 @@ } %code provides { -void yyerror(YYLTYPE *, void *, struct cdecl **, const char *); -int yyparse(void *scanner, struct cdecl **out); +void cdecl__free(struct cdecl *); +int cdecl__yyparse(void *scanner, struct cdecl **out); } %union { uintmax_t uintval; + unsigned spectype; _Bool boolval; char *strval; struct cdecl_declspec *declspec; @@ -129,10 +136,19 @@ static void free_decl(struct cdecl *x) } } -void cdecl_free(struct cdecl *decl) +void cdecl__free(struct cdecl *decl) { free_decl(decl); } + +static void +yyerror(YYLTYPE *loc, yyscan_t scanner, struct cdecl **out, const char *err) +{ + if (strstr(err, "T_LEX_ERROR")) + return; + + cdecl__err(CDECL_ENOPARSE, "%s", err); +} %} %destructor { free($$); } @@ -201,7 +217,7 @@ void cdecl_free(struct cdecl *decl) %type vla_ident %type varargs -%type declspec_simple typespec_simple qualifier_simple +%type declspec_simple typespec_simple qualifier_simple %type declspec_notype declspec_noid typespec_noid typespec %type qualifier qualifiers %type declspecs declspecs_noid @@ -232,7 +248,9 @@ input: T_ENGLISH english { *out = $1; }; -declaration: declspecs declarators T_SEMICOLON { +semi: | T_SEMICOLON + +declaration: declspecs declarators semi { $$ = $2; for (struct cdecl *i = $$; i; i = i->next) @@ -329,7 +347,7 @@ vla_ident: T_IDENT | T_ASTERISK { array: T_LBRACKET T_UINT T_RBRACKET { if ($2 == 0) - FAIL("array length must be positive"); + FAIL(_("array length must be positive")); ALLOC_STRUCT($$, struct cdecl_declarator, .type = CDECL_DECL_ARRAY, @@ -449,7 +467,7 @@ type_qual_specs: { $$ = NULL; } | type_qual_spec type_qual_specs { post_specs: qualifiers typespec type_qual_specs { $$ = $2; $$->next = $1; - for (struct cdecl_declspec *s = $1; s; s = s->next) { + for (struct cdecl_declspec *s = $$; s; s = s->next) { if (!s->next) { s->next = $3; break; @@ -556,7 +574,7 @@ english_array: T_VLA T_ARRAY english_vla T_OF { .u.array.vla = $3); } | T_ARRAY T_UINT T_OF { if ($2 == 0) - FAIL("array length must be positive"); + FAIL(_("array length must be positive")); ALLOC_STRUCT($$, struct cdecl_declarator, .type = CDECL_DECL_ARRAY, @@ -571,14 +589,3 @@ english_vla: T_IDENT | { ALLOC($$, sizeof ""); strcpy($$, ""); } - -%% -void -yyerror(YYLTYPE *loc, yyscan_t scanner, struct cdecl **out, - const char *err) -{ - if (strstr(err, "T_LEX_ERROR")) - return; - - fprintf(stderr, "%s\n", err); -}