X-Git-Url: https://git.draconx.ca/gitweb/cdecl99.git/blobdiff_plain/f7cfa924116d4dd36b107fa534fff2b5e5e4fa13..c4d0ba7251867ee9bdb8466357cba5a9fa352b76:/src/parse.y diff --git a/src/parse.y b/src/parse.y index 11ae6bb..263129c 100644 --- a/src/parse.y +++ b/src/parse.y @@ -1,7 +1,7 @@ %code top { /* * Parser for C declarations. - * Copyright © 2011-2012, 2021 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 @@ -34,6 +34,7 @@ #include "scan.h" #include "cdecl.h" #include "cdecl-internal.h" +#include "errmsg.h" #define FAIL(msg) do { \ yyerror(&yylloc, NULL, NULL, msg); \ @@ -42,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 { \ @@ -58,8 +61,8 @@ %code provides { void cdecl__free(struct cdecl *); -void cdecl__yyerror(YYLTYPE *, void *, struct cdecl **, const char *); int cdecl__yyparse(void *scanner, struct cdecl **out); +const char *cdecl__token_name(unsigned token); } %union { @@ -138,6 +141,15 @@ 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($$); } @@ -336,7 +348,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, @@ -563,7 +575,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, @@ -580,14 +592,16 @@ english_vla: T_IDENT | { } %% -void -yyerror(YYLTYPE *loc, yyscan_t scanner, struct cdecl **out, const char *err) -{ - if (strstr(err, "T_LEX_ERROR")) - return; - cdecl__set_error(&(const struct cdecl_error){ - .code = CDECL_ENOPARSE, - .str = err, - }); +/* + * Expose the token string table to the rest of the library, in order to + * produce strings that match parser keywords. + * + * In order for this to work properly, the Bison output must be postprocessed + * by fix-yytname.awk to remove pointless quotation marks from the keyword + * strings. + */ +const char *cdecl__token_name(unsigned token) +{ + return yytname[YYTRANSLATE(token)]; }