%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
}
%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
%locations
%{
+#include <config.h>
#include <assert.h>
#include <stdbool.h>
#include "scan.h"
#include "cdecl.h"
+#include "cdecl-internal.h"
+#include "errmsg.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__errmsg(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;
}
}
-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>
%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
*out = $1;
};
-declaration: declspecs declarators T_SEMICOLON {
+semi: | T_SEMICOLON
+
+declaration: declspecs declarators semi {
$$ = $2;
for (struct cdecl *i = $$; i; i = i->next)
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,
.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,
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);
-}