]> git.draconx.ca Git - cdecl99.git/blobdiff - src/parse.y
Rework library error reporting.
[cdecl99.git] / src / parse.y
index 5bcd9a947c6e587e44fc4d403ab319798b3be41d..bf2a596b1a4a037fee49fe36cd724454e11d8f27 100644 (file)
@@ -1,7 +1,7 @@
 %code top {
 /*
  *  Parser for C declarations.
- *  Copyright © 2011 Nick Bowler
+ *  Copyright © 2011-2012, 2021 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
@@ -19,7 +19,7 @@
 }
 
 %name-prefix "cdecl__yy"
-%parse-param {yyscan_t scanner}
+%parse-param {void *scanner}
 %parse-param {struct cdecl **out}
 %lex-param {yyscan_t scanner}
 %define api.pure
@@ -32,8 +32,8 @@
 #include <stdbool.h>
 
 #include "scan.h"
-#include "error.h"
 #include "cdecl.h"
+#include "cdecl-internal.h"
 
 #define FAIL(msg) do { \
        yyerror(&yylloc, NULL, NULL, msg); \
 
 #define ALLOC(ptr, size) do { \
        (ptr) = malloc(size); \
-       if (!(ptr)) \
-               FAIL("failed to allocate memory"); \
+       if (!(ptr)) { \
+               cdecl__err(CDECL_ENOMEM); \
+               YYERROR; \
+       } \
 } while (0)
 
 #define ALLOC_STRUCT(ptr, type, ...) do { \
 }
 
 %code provides {
-void cdecl__yyerror(YYLTYPE *, void *, struct cdecl **, const char *);
+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;
@@ -132,10 +135,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($$); }            <strval>
@@ -204,7 +216,7 @@ void cdecl_free(struct cdecl *decl)
 
 %type <strval>     vla_ident
 %type <boolval>    varargs
-%type <uintval>    declspec_simple typespec_simple qualifier_simple
+%type <spectype>   declspec_simple typespec_simple qualifier_simple
 %type <declspec>   declspec_notype declspec_noid typespec_noid typespec
 %type <declspec>   qualifier qualifiers
 %type <declspec>   declspecs declspecs_noid
@@ -334,7 +346,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,
@@ -561,7 +573,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,
@@ -576,17 +588,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;
-
-       cdecl__set_error(&(const struct cdecl_error){
-               .code = CDECL_ENOPARSE,
-               .str  = err,
-       });
-}