commit: 1a93f19e9caca17b44498d9a7ac632210a276905
parent fb554b3685d74dd855bc7af375f9f4608aafe7be
Author: Andrius Štikonas <andrius@stikonas.eu>
Date: Wed, 10 Feb 2021 18:06:40 +0000
Add bison 3.4.1.
Diffstat:
18 files changed, 2495 insertions(+), 12 deletions(-)
diff --git a/.reuse/dep5 b/.reuse/dep5
@@ -8,3 +8,7 @@ Source: https://github.com/fosslinux/live-bootstrap
# Files: src/*
# Copyright: $YEAR $NAME <$CONTACT>
# License: ...
+
+Files: SHA256SUMS.sources
+Copyright: none
+License: MIT
diff --git a/README.md b/README.md
@@ -305,12 +305,23 @@ stage process, first compiling flex using `scan.c` (from `scan.l`) created by
old flex, then recompile `scan.c` using the new version of flex to remove any
buggy artifacts from the old flex.
-#### Part 24: grep 2.4
+#### Part 24: bison 3.4.1
+
+GNU `bison` is a parser generator. With `m4` and `flex` we can now bootstrap it
+following https://gitlab.com/giomasce/bison-bootstrap. It's a 3 stage process:
+
+1) Build bison using a handwritten grammar parser in C.
+2) Use bison from previous stage on a simplified bison grammar file.
+3) Build bison using original grammar file.
+
+Finally we have a fully functional `bison` executable.
+
+#### Part 25: grep 2.4
GNU `grep` is a pattern matching utility. Is is not immediately needed but will
be useful later for autotools.
-#### Part 25: diffutils 2.7
+#### Part 26: diffutils 2.7
`diffutils` is useful for comparing two files. It is not immediately needed but
is required later for autotools.
diff --git a/SHA256SUMS.sources b/SHA256SUMS.sources
@@ -1,15 +1,15 @@
-c6c37e888b136ccefab903c51149f4b7bd659d69d4aea21245f61053a57aa60a tar-1.12.tar.gz
-4d2ce9f314f39c9575f913503b0178d6fb2c92920db8e7b7b176b7bab7980fe6 gzip-1.2.4.tar
-ecb5c6469d732bcf01d6ec1afe9e64f1668caba5bfdb103c28d7f537ba3cdb8a patch-2.5.9.tar.gz
-64b30b41fde2ebf669e6af489883fb1df6a06ac30555a96cfa3c39ecce7267dd make-3.80.tar.gz
+ba03d412998cc54bd0b0f2d6c32100967d3137098affdc2d32e6e7c11b163fe4 bash-2.05b.tar.gz
+7007fc89c216fbfaff5525359b02a7e5b612694df5168c74673f67055f015095 bison-3.4.1.tar.gz
ab5a03176ee106d3f0fa90e381da478ddae405918153cca248e682cd0c4a2269 bzip2-1.0.8.tar.gz
c25b36b8af6e0ad2a875daf4d6196bd0df28a62be7dd252e5f99a4d5d7288d95 coreutils-5.0.tar.bz2
-9f233d8b78e4351fe9dd2d50d83958a0e5af36f54e9818521458a08e058691ba heirloom-devtools-070527.tar.bz2
-ba03d412998cc54bd0b0f2d6c32100967d3137098affdc2d32e6e7c11b163fe4 bash-2.05b.tar.gz
-a116c52d314c8e3365756cb1e14c6b460d6bd28769121f92373a362497359d88 m4-1.4.4.tar.gz
+d5f2489c4056a31528e3ada4adacc23d498532b0af1a980f2f76158162b139d6 diffutils-2.7.tar.gz
bc79b890f35ca38d66ff89a6e3758226131e51ccbd10ef78d5ff150b7bd73689 flex-2.5.11.tar.gz
-1370c9a812b2cf2a7d92802510cca0058cc37e66a7bedd70051f0a34015022a3 musl-1.1.24.tar.gz
e87aae032bf07c26f85ac0ed3250998c37621d95f8bd748b31f15b33c45ee995 flex-2.6.4.tar.gz
a32032bab36208509466654df12f507600dfe0313feebbcd218c32a70bf72a16 grep-2.4.tar.gz
-d5f2489c4056a31528e3ada4adacc23d498532b0af1a980f2f76158162b139d6 diffutils-2.7.tar.gz
+4d2ce9f314f39c9575f913503b0178d6fb2c92920db8e7b7b176b7bab7980fe6 gzip-1.2.4.tar
+9f233d8b78e4351fe9dd2d50d83958a0e5af36f54e9818521458a08e058691ba heirloom-devtools-070527.tar.bz2
093c993767f563a11e41c1cf887f4e9065247129679d4c1e213d0544d16d8303 m4-1.4.7.tar.gz
+64b30b41fde2ebf669e6af489883fb1df6a06ac30555a96cfa3c39ecce7267dd make-3.80.tar.gz
+1370c9a812b2cf2a7d92802510cca0058cc37e66a7bedd70051f0a34015022a3 musl-1.1.24.tar.gz
+ecb5c6469d732bcf01d6ec1afe9e64f1668caba5bfdb103c28d7f537ba3cdb8a patch-2.5.9.tar.gz
+c6c37e888b136ccefab903c51149f4b7bd659d69d4aea21245f61053a57aa60a tar-1.12.tar.gz
diff --git a/rootfs.sh b/rootfs.sh
@@ -178,6 +178,9 @@ get_file https://ftp.gnu.org/gnu/m4/m4-1.4.7.tar.gz
# flex 2.6.4
get_file https://github.com/westes/flex/releases/download/v2.6.4/flex-2.6.4.tar.gz
+# bison 3.4.1
+get_file https://ftp.gnu.org/gnu/bison/bison-3.4.1.tar.gz
+
# grep 2.4
get_file https://ftp.gnu.org/gnu/grep/grep-2.4.tar.gz
diff --git a/sysa/bison-3.4.1/files/config.h b/sysa/bison-3.4.1/files/config.h
@@ -0,0 +1,39 @@
+// SPDX-FileCopyrightText: 2020 Andrius Štikonas <andrius@stikonas.eu>
+
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#define HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME 1
+#define HAVE_DECL_STRERROR_R 1
+#define HAVE_GETTIMEOFDAY 1
+#define HAVE_PIPE 1
+#define HAVE_SNPRINTF 1
+#define HAVE_STDINT_H 1
+#define HAVE_UNISTD_H 1
+#define M4 "/after/bin/m4"
+#define M4_GNU_OPTION ""
+#define PACKAGE "bison"
+#define PACKAGE_BUGREPORT "bug-bison@gnu.org"
+#define PACKAGE_COPYRIGHT_YEAR 2019
+#define PACKAGE_NAME "GNU Bison"
+#define PACKAGE_STRING "GNU Bison 3.4.1"
+#define PACKAGE_URL "http://www.gnu.org/software/bison/"
+#define PACKAGE_VERSION "3.4.1"
+#define VERSION "3.4.1"
+#define PROMOTED_MODE_T mode_t
+#define BOURNE_SHELL "/bin/sh"
+#define _GNU_SOURCE 1
+#define _Noreturn
+#define _GL_ASYNC_SAFE
+#define _GL_EXTERN_INLINE extern inline
+#define _GL_INLINE_HEADER_BEGIN
+#define _GL_INLINE_HEADER_END
+#define _GL_UNUSED
+#define _GL_UNUSED_LABEL
+#define _GL_ATTRIBUTE_PURE
+#define _GL_ATTRIBUTE_CONST
+#define _GL_ATTRIBUTE_MALLOC
+#define _GL_ATTRIBUTE_FORMAT_PRINTF(x, y)
+#define _GL_ARG_NONNULL(x)
+#ifndef _GL_INLINE
+#define _GL_INLINE static inline
+#endif
diff --git a/sysa/bison-3.4.1/files/configmake.h b/sysa/bison-3.4.1/files/configmake.h
@@ -0,0 +1,6 @@
+// SPDX-FileCopyrightText: 2020 Andrius Štikonas <andrius@stikonas.eu>
+
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#define LOCALEDIR "/after/share/locale"
+#define PKGDATADIR "/after/share/bison"
diff --git a/sysa/bison-3.4.1/files/parse-gram.c b/sysa/bison-3.4.1/files/parse-gram.c
@@ -0,0 +1,972 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+/*
+ * This file is based on parse-gram.y from GNU Bison 3.4.1. It
+ * implements a subset of the grammar described by parse-gram.y, just
+ * enough to provide a bootstrapping path for Bison.
+ *
+ * Copyright (c) 2020, Giovanni Mascellani <gio@debian.org>
+ *
+ * The copyright notice of the original file follows. This file is
+ * distributed under the same license and with the same conditions.
+ */
+
+/* Bison Grammar Parser -*- C -*-
+
+ Copyright (C) 2002-2015, 2018-2019 Free Software Foundation, Inc.
+
+ This file is part of Bison, the GNU Compiler Compiler.
+
+ 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
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/*
+ * Since this code is intended to provide a bootstrapping path for GNU
+ * Bison, it is important that it is as easy to understand as
+ * possible. Fortunately Bison's grammar is rather simple. I believe
+ * that if you know how Bison works, you should not find it hard to
+ * follow the logic in this file and compare it with the original
+ * grammar.
+ *
+ * Apart from the code literally copied from the grammar file
+ * (prologues and epilogue), this file basically contains a few
+ * wrappers over the lexer interface (the functions gram_*), basically
+ * adding the feature to give back one lexeme and a lot of functions
+ * parse_* or maybe_parse_*, parsing the corresponding grammar
+ * rule. Functions maybe_parse_* are allowed to fail, and return
+ * accordingly.
+ *
+ * Error checking is very simple and just made of assertions. This is
+ * just boostrapping code, not meant for end users, so it should not
+ * be a problem.
+ */
+
+/* %code top */
+ /* On column 0 to please syntax-check. */
+#include <config.h>
+
+#include <assert.h>
+
+#define YYLTYPE GRAM_LTYPE
+
+#include "parse-gram.h"
+
+/* %code */
+ #include "system.h"
+ #include <errno.h>
+
+ #include "c-ctype.h"
+ #include "complain.h"
+ #include "conflicts.h"
+ #include "files.h"
+ #include "getargs.h"
+ #include "gram.h"
+ #include "named-ref.h"
+ #include "quotearg.h"
+ #include "reader.h"
+ #include "scan-code.h"
+ #include "scan-gram.h"
+ #include "vasnprintf.h"
+ #include "xmemdup0.h"
+
+ static int current_prec = 0;
+ static location current_lhs_loc;
+ static named_ref *current_lhs_named_ref;
+ static symbol *current_lhs_symbol;
+ static symbol_class current_class = unknown_sym;
+
+ /** Set the new current left-hand side symbol, possibly common
+ * to several right-hand side parts of rule.
+ */
+ static void current_lhs (symbol *sym, location loc, named_ref *ref);
+
+ #define YYLLOC_DEFAULT(Current, Rhs, N) \
+ (Current) = lloc_default (Rhs, N)
+ static YYLTYPE lloc_default (YYLTYPE const *, int);
+
+ #define YY_LOCATION_PRINT(File, Loc) \
+ location_print (Loc, File)
+
+ /* Strip initial '{' and final '}' (must be first and last characters).
+ Return the result. */
+ static char *strip_braces (char *code);
+
+ /* Convert CODE by calling code_props_plain_init if PLAIN, otherwise
+ code_props_symbol_action_init. Call
+ gram_scanner_last_string_free to release the latest string from
+ the scanner (should be CODE). */
+ static char const *translate_code (char *code, location loc, bool plain);
+
+ /* Convert CODE by calling code_props_plain_init after having
+ stripped the first and last characters (expected to be '{', and
+ '}'). Call gram_scanner_last_string_free to release the latest
+ string from the scanner (should be CODE). */
+ static char const *translate_code_braceless (char *code, location loc);
+
+ /* Handle a %error-verbose directive. */
+ static void handle_error_verbose (location const *loc, char const *directive);
+
+ /* Handle a %file-prefix directive. */
+ static void handle_file_prefix (location const *loc,
+ location const *dir_loc,
+ char const *directive, char const *value);
+
+ /* Handle a %name-prefix directive. */
+ static void handle_name_prefix (location const *loc,
+ char const *directive, char const *value);
+
+ /* Handle a %pure-parser directive. */
+ static void handle_pure_parser (location const *loc, char const *directive);
+
+ /* Handle a %require directive. */
+ static void handle_require (location const *loc, char const *version);
+
+ /* Handle a %skeleton directive. */
+ static void handle_skeleton (location const *loc, char const *skel);
+
+ /* Handle a %yacc directive. */
+ static void handle_yacc (location const *loc, char const *directive);
+
+ static void gram_error (location const *, char const *);
+
+ /* A string that describes a char (e.g., 'a' -> "'a'"). */
+ static char const *char_name (char);
+
+ #define YYTYPE_INT16 int_fast16_t
+ #define YYTYPE_INT8 int_fast8_t
+ #define YYTYPE_UINT16 uint_fast16_t
+ #define YYTYPE_UINT8 uint_fast8_t
+
+ /* Add style to semantic values in traces. */
+ static void tron (FILE *yyo);
+ static void troff (FILE *yyo);
+
+int gram_debug;
+
+typedef struct {
+ GRAM_STYPE s;
+ GRAM_LTYPE l;
+ int t;
+} gram_lex_ctx;
+
+static int gram_lex_wrap(gram_lex_ctx *ctx, GRAM_STYPE *sx, GRAM_LTYPE *lx) {
+ int type;
+ if (ctx->t == 0) {
+ type = gram_lex(&ctx->s, &ctx->l);
+ } else {
+ type = ctx->t;
+ }
+ /*fprintf(stderr, "%s %d from %s:%d:%d:%d to %s:%d:%d:%d\n",
+ ctx->t == 0 ? "Scanned" : "Rescanned", type,
+ ctx->l.start.file, ctx->l.start.line, ctx->l.start.column, ctx->l.start.byte,
+ ctx->l.end.file, ctx->l.end.line, ctx->l.end.column, ctx->l.end.byte);*/
+ ctx->t = 0;
+ if (sx) *sx = ctx->s;
+ if (lx) *lx = ctx->l;
+ return type;
+}
+
+static int gram_unlex_wrap(gram_lex_ctx *ctx, int t, GRAM_STYPE *s, GRAM_LTYPE *l) {
+ assert(ctx->t == 0);
+ ctx->t = t;
+ ctx->s = *s;
+ ctx->l = *l;
+ /*fprintf(stderr, "Unscanned %d from %s:%d:%d:%d to %s:%d:%d:%d\n",
+ t,
+ ctx->l.start.file, ctx->l.start.line, ctx->l.start.column, ctx->l.start.byte,
+ ctx->l.end.file, ctx->l.end.line, ctx->l.end.column, ctx->l.end.byte);*/
+}
+
+static void gram_get_last_loc(gram_lex_ctx *ctx, GRAM_LTYPE *l) {
+ *l = ctx->l;
+}
+
+static void parse_value(gram_lex_ctx *ctx, GRAM_STYPE *sx, GRAM_LTYPE *lx) {
+ GRAM_STYPE s[2];
+ GRAM_LTYPE l[2];
+ gram_get_last_loc(ctx, &l[0]);
+ int t = gram_lex_wrap(ctx, &s[1], &l[1]);
+ switch (t) {
+ case ID:
+ YYLLOC_DEFAULT(*lx, l, 1);
+ sx->value.kind = muscle_keyword;
+ sx->value.chars = s[1].ID;
+ break;
+ case STRING:
+ YYLLOC_DEFAULT(*lx, l, 1);
+ sx->value.kind = muscle_string;
+ sx->value.chars = s[1].STRING;
+ break;
+ case BRACED_CODE:
+ YYLLOC_DEFAULT(*lx, l, 1);
+ sx->value.kind = muscle_code;
+ sx->value.chars = strip_braces(s[1].BRACED_CODE);
+ break;
+ default:
+ gram_unlex_wrap(ctx, t, &s[1], &l[1]);
+ YYLLOC_DEFAULT(*lx, l, 0);
+ sx->value.kind = muscle_keyword;
+ sx->value.chars = "";
+ break;
+ }
+}
+
+static void parse_int_opt(gram_lex_ctx *ctx, GRAM_STYPE *sx, GRAM_LTYPE *lx) {
+ GRAM_STYPE s[2];
+ GRAM_LTYPE l[2];
+ gram_get_last_loc(ctx, &l[0]);
+ int t = gram_lex_wrap(ctx, &s[1], &l[1]);
+ if (t == INT) {
+ YYLLOC_DEFAULT(*lx, l, 1);
+ sx->int_opt = s[1].INT;
+ } else {
+ gram_unlex_wrap(ctx, t, &s[1], &l[1]);
+ YYLLOC_DEFAULT(*lx, l, 0);
+ sx->int_opt = -1;
+ }
+}
+
+static int maybe_parse_string_as_id(gram_lex_ctx *ctx, GRAM_STYPE *sx, GRAM_LTYPE *lx) {
+ GRAM_STYPE s[2];
+ GRAM_LTYPE l[2];
+ int t = gram_lex_wrap(ctx, &s[1], &l[1]);
+ if (t == STRING) {
+ YYLLOC_DEFAULT(*lx, l, 1);
+ sx->string_as_id = symbol_get(quotearg_style(c_quoting_style, s[1].STRING), l[1]);
+ symbol_class_set(sx->string_as_id, token_sym, l[1], false);
+ return 1;
+ } else {
+ gram_unlex_wrap(ctx, t, &s[1], &l[1]);
+ return 0;
+ }
+}
+
+static void parse_string_as_id(gram_lex_ctx *ctx, GRAM_STYPE *sx, GRAM_LTYPE *lx) {
+ int x = maybe_parse_string_as_id(ctx, sx, lx);
+ assert(x);
+}
+
+static void parse_string_as_id_opt(gram_lex_ctx *ctx, GRAM_STYPE *sx, GRAM_LTYPE *lx) {
+ GRAM_STYPE s[2];
+ GRAM_LTYPE l[2];
+ gram_get_last_loc(ctx, &l[0]);
+ int x = maybe_parse_string_as_id(ctx, &s[1], &l[1]);
+ if (x) {
+ YYLLOC_DEFAULT(*lx, l, 1);
+ sx->string_as_id_opt = s[1].string_as_id;
+ } else {
+ YYLLOC_DEFAULT(*lx, l, 0);
+ sx->string_as_id_opt = NULL;
+ }
+}
+
+static int maybe_parse_id(gram_lex_ctx *ctx, GRAM_STYPE *sx, GRAM_LTYPE *lx) {
+ GRAM_STYPE s[2];
+ GRAM_LTYPE l[2];
+ gram_get_last_loc(ctx, &l[0]);
+ int t = gram_lex_wrap(ctx, &s[1], &l[1]);
+ if (t == ID) {
+ YYLLOC_DEFAULT(*lx, l, 1);
+ sx->id = symbol_from_uniqstr(s[1].ID, l[1]);
+ return 1;
+ } else {
+ gram_unlex_wrap(ctx, t, &s[1], &l[1]);
+ return 0;
+ }
+}
+
+static void parse_id(gram_lex_ctx *ctx, GRAM_STYPE *sx, GRAM_LTYPE *lx) {
+ int x = maybe_parse_id(ctx, sx, lx);
+ assert(x);
+}
+
+static void parse_token_decl(gram_lex_ctx *ctx, GRAM_STYPE *sx, GRAM_LTYPE *lx) {
+ GRAM_STYPE s[4];
+ GRAM_LTYPE l[4];
+ parse_id(ctx, &s[1], &l[1]);
+ parse_int_opt(ctx, &s[2], &l[2]);
+ parse_string_as_id_opt(ctx, &s[3], &l[3]);
+ YYLLOC_DEFAULT(*lx, l, 3);
+ sx->token_decl = s[1].id;
+ symbol_class_set(s[1].id, current_class, l[1], true);
+ if (0 <= s[2].int_opt)
+ symbol_user_token_number_set(s[1].id, s[2].int_opt, l[2]);
+ if (s[3].string_as_id_opt)
+ symbol_make_alias(s[1].id, s[3].string_as_id_opt, l[3]);
+}
+
+static int maybe_parse_token_decl_1(gram_lex_ctx *ctx, GRAM_STYPE *sx, GRAM_LTYPE *lx) {
+ GRAM_STYPE s[3];
+ GRAM_LTYPE l[3];
+ int t = gram_lex_wrap(ctx, &s[1], &l[1]);
+ gram_unlex_wrap(ctx, t, &s[1], &l[1]);
+ if (t != ID) {
+ return 0;
+ }
+ parse_token_decl(ctx, &s[1], &l[1]);
+ YYLLOC_DEFAULT(*lx, l, 1);
+ sx->token_decl_1 = symbol_list_sym_new(s[1].token_decl, l[1]);
+ while (1) {
+ int t = gram_lex_wrap(ctx, &s[1], &l[1]);
+ gram_unlex_wrap(ctx, t, &s[1], &l[1]);
+ if (t != ID) {
+ return 1;
+ }
+ s[1] = *sx;
+ l[1] = *lx;
+ parse_token_decl(ctx, &s[2], &l[2]);
+ YYLLOC_DEFAULT(*lx, l, 2);
+ sx->token_decl_1 = symbol_list_append(s[1].token_decl_1, symbol_list_sym_new(s[2].token_decl, l[2]));
+ }
+}
+
+static void parse_token_decl_1(gram_lex_ctx *ctx, GRAM_STYPE *sx, GRAM_LTYPE *lx) {
+ int x = maybe_parse_token_decl_1(ctx, sx, lx);
+ assert(x);
+}
+
+static void parse_token_decls(gram_lex_ctx *ctx, GRAM_STYPE *sx, GRAM_LTYPE *lx) {
+ GRAM_STYPE s[4];
+ GRAM_LTYPE l[4];
+ int begin_with_tokens = maybe_parse_token_decl_1(ctx, &s[1], &l[1]);
+ if (begin_with_tokens) {
+ YYLLOC_DEFAULT(*lx, l, 1);
+ sx->token_decls = s[1].token_decl_1;
+ } else {
+ int t = gram_lex_wrap(ctx, &s[1], &l[1]);
+ assert(t == TAG);
+ parse_token_decl_1(ctx, &s[2], &l[2]);
+ YYLLOC_DEFAULT(*lx, l, 2);
+ sx->token_decls = symbol_list_type_set(s[2].token_decl_1, s[1].TAG, l[1]);
+ }
+ while (1) {
+ s[1] = *sx;
+ l[1] = *lx;
+ int t = gram_lex_wrap(ctx, &s[2], &l[2]);
+ if (t != TAG) {
+ gram_unlex_wrap(ctx, t, &s[2], &l[2]);
+ return;
+ }
+ parse_token_decl_1(ctx, &s[3], &l[3]);
+ YYLLOC_DEFAULT(*lx, l, 3);
+ sx->token_decls = symbol_list_append(s[1].token_decls, symbol_list_type_set(s[3].token_decl_1, s[2].TAG, l[2]));
+ }
+}
+
+static int maybe_parse_symbol(gram_lex_ctx *ctx, GRAM_STYPE *sx, GRAM_LTYPE *lx) {
+ GRAM_STYPE s[2];
+ GRAM_LTYPE l[2];
+ int x = maybe_parse_string_as_id(ctx, &s[1], &l[1]);
+ if (x) {
+ YYLLOC_DEFAULT(*lx, l, 1);
+ sx->symbol = s[1].string_as_id;
+ return 1;
+ }
+ x = maybe_parse_id(ctx, &s[1], &l[1]);
+ if (x) {
+ YYLLOC_DEFAULT(*lx, l, 1);
+ sx->symbol = s[1].id;
+ return 1;
+ }
+ return 0;
+}
+
+static void parse_symbol(gram_lex_ctx *ctx, GRAM_STYPE *sx, GRAM_LTYPE *lx) {
+ int x = maybe_parse_symbol(ctx, sx, lx);
+ assert(x);
+}
+
+static int maybe_parse_symbol_decl_1(gram_lex_ctx *ctx, GRAM_STYPE *sx, GRAM_LTYPE *lx) {
+ GRAM_STYPE s[3];
+ GRAM_LTYPE l[3];
+ int x = maybe_parse_symbol(ctx, &s[1], &l[1]);
+ if (!x) {
+ return 0;
+ }
+ YYLLOC_DEFAULT(*lx, l, 1);
+ sx->symbol_decl_1 = symbol_list_sym_new(s[1].symbol, l[1]);
+ while (1) {
+ s[1] = *sx;
+ l[1] = *lx;
+ x = maybe_parse_symbol(ctx, &s[2], &l[2]);
+ if (!x) {
+ return 1;
+ }
+ YYLLOC_DEFAULT(*lx, l, 2);
+ sx->symbol_decl_1 = symbol_list_append(s[1].symbol_decl_1, symbol_list_sym_new(s[2].symbol, l[2]));
+ }
+}
+
+static void parse_symbol_decl_1(gram_lex_ctx *ctx, GRAM_STYPE *sx, GRAM_LTYPE *lx) {
+ int x = maybe_parse_symbol_decl_1(ctx, sx, lx);
+ assert(x);
+}
+
+static void parse_symbol_decls(gram_lex_ctx *ctx, GRAM_STYPE *sx, GRAM_LTYPE *lx) {
+ GRAM_STYPE s[4];
+ GRAM_LTYPE l[4];
+ int begin_with_tokens = maybe_parse_symbol_decl_1(ctx, &s[1], &l[1]);
+ if (begin_with_tokens) {
+ YYLLOC_DEFAULT(*lx, l, 1);
+ sx->symbol_decls = s[1].symbol_decl_1;
+ } else {
+ int t = gram_lex_wrap(ctx, &s[1], &l[1]);
+ assert(t == TAG);
+ parse_symbol_decl_1(ctx, &s[2], &l[2]);
+ YYLLOC_DEFAULT(*lx, l, 2);
+ sx->symbol_decls = symbol_list_type_set(s[2].symbol_decl_1, s[1].TAG, l[1]);
+ }
+ while (1) {
+ s[1] = *sx;
+ l[1] = *lx;
+ int t = gram_lex_wrap(ctx, &s[2], &l[2]);
+ if (t != TAG) {
+ gram_unlex_wrap(ctx, t, &s[2], &l[2]);
+ return;
+ }
+ parse_symbol_decl_1(ctx, &s[3], &l[3]);
+ YYLLOC_DEFAULT(*lx, l, 3);
+ sx->symbol_decls = symbol_list_append(s[1].symbol_decls, symbol_list_type_set(s[3].symbol_decl_1, s[2].TAG, l[2]));
+ }
+}
+
+static int maybe_parse_declaration(gram_lex_ctx *ctx, int prologue) {
+ GRAM_STYPE s[4];
+ GRAM_LTYPE l[4];
+ int t[4];
+ t[1] = gram_lex_wrap(ctx, &s[1], &l[1]);
+ if (prologue) {
+ switch (t[1]) {
+ /* Prologue declarations */
+ case PERCENT_DEFINE:
+ t[2] = gram_lex_wrap(ctx, &s[2], &l[2]);
+ assert(t[2] == ID);
+ parse_value(ctx, &s[3], &l[3]);
+ YYLLOC_DEFAULT(l[0], l, 3);
+ muscle_percent_define_insert(s[2].ID, l[0], s[3].value.kind, s[3].value.chars,
+ MUSCLE_PERCENT_DEFINE_GRAMMAR_FILE);
+ return 1;
+ case PERCENT_DEFINES:
+ defines_flag = true;
+ return 1;
+ case PERCENT_EXPECT:
+ t[2] = gram_lex_wrap(ctx, &s[2], &l[2]);
+ assert(t[2] == INT);
+ expected_sr_conflicts = s[2].INT;
+ return 1;
+ case PERCENT_INITIAL_ACTION:
+ t[2] = gram_lex_wrap(ctx, &s[2], &l[2]);
+ assert(t[2] == BRACED_CODE);
+ muscle_code_grow("initial_action", translate_code(s[2].BRACED_CODE, l[2], false), l[2]);
+ code_scanner_last_string_free();
+ return 1;
+ case PERCENT_VERBOSE:
+ report_flag |= report_states;
+ return 1;
+ case SEMICOLON:
+ return 1;
+ }
+ }
+
+ switch (t[1]) {
+ /* Grammar declarations */
+ case PERCENT_CODE:
+ t[2] = gram_lex_wrap(ctx, &s[2], &l[2]);
+ if (t[2] == ID) {
+ t[3] = gram_lex_wrap(ctx, &s[3], &l[3]);
+ assert(t[3] == BRACED_CODE);
+ muscle_percent_code_grow(s[2].ID, l[2], translate_code_braceless(s[3].BRACED_CODE, l[3]), l[3]);
+ code_scanner_last_string_free();
+ } else {
+ assert(t[2] == BRACED_CODE);
+ muscle_code_grow("percent_code()", translate_code_braceless(s[2].BRACED_CODE, l[2]), l[2]);
+ code_scanner_last_string_free();
+ }
+ return 1;
+
+ /* Symbol declarations */
+ case PERCENT_TOKEN:
+ current_class = token_sym;
+ parse_token_decls(ctx, &s[2], &l[2]);
+ current_class = unknown_sym;
+ symbol_list_free(s[2].token_decls);
+ return 1;
+ case PERCENT_TYPE:
+ parse_symbol_decls(ctx, &s[2], &l[2]);
+ symbol_list_free(s[2].symbol_decls);
+ return 1;
+ case PERCENT_PERCENT:
+ return 2;
+ default:
+ gram_unlex_wrap(ctx, t[1], &s[1], &l[1]);
+ return 0;
+ }
+}
+
+static void parse_prologue_declarations(gram_lex_ctx *ctx) {
+ while (1) {
+ int x = maybe_parse_declaration(ctx, 1);
+ assert(x);
+ if (x == 2) {
+ return;
+ }
+ }
+}
+
+static void parse_id_colon(gram_lex_ctx *ctx, GRAM_STYPE *sx, GRAM_LTYPE *lx) {
+ GRAM_STYPE s[2];
+ GRAM_LTYPE l[2];
+ int t = gram_lex_wrap(ctx, &s[1], &l[1]);
+ assert(t == ID_COLON);
+ YYLLOC_DEFAULT(*lx, l, 1);
+ sx->id_colon = symbol_from_uniqstr(s[1].ID_COLON, l[1]);
+}
+
+static void parse_named_ref_opt(gram_lex_ctx *ctx, GRAM_STYPE *sx, GRAM_LTYPE *lx) {
+ GRAM_STYPE s[2];
+ GRAM_LTYPE l[2];
+ gram_get_last_loc(ctx, &l[0]);
+ int t = gram_lex_wrap(ctx, &s[1], &l[1]);
+ if (t == BRACKETED_ID) {
+ YYLLOC_DEFAULT(*lx, l, 1);
+ sx->named_ref_opt = named_ref_new(s[1].BRACKETED_ID, l[1]);
+ } else {
+ gram_unlex_wrap(ctx, t, &s[1], &l[1]);
+ YYLLOC_DEFAULT(*lx, l, 0);
+ sx->named_ref_opt = NULL;
+ }
+}
+
+static void parse_rhs(gram_lex_ctx *ctx, GRAM_STYPE *sx, GRAM_LTYPE *lx) {
+ GRAM_STYPE s[5];
+ GRAM_LTYPE l[5];
+ gram_get_last_loc(ctx, &l[0]);
+ YYLLOC_DEFAULT(*lx, l, 0);
+ grammar_current_rule_begin(current_lhs_symbol, current_lhs_loc, current_lhs_named_ref);
+ while (1) {
+ s[1] = *sx;
+ l[1] = *lx;
+ int x = maybe_parse_symbol(ctx, &s[2], &l[2]);
+ if (x) {
+ parse_named_ref_opt(ctx, &s[3], &l[3]);
+ YYLLOC_DEFAULT(*lx, l, 3);
+ grammar_current_rule_symbol_append(s[2].symbol, l[2], s[3].named_ref_opt);
+ } else {
+ int t = gram_lex_wrap(ctx, &s[2], &l[2]);
+ switch (t) {
+ case BRACED_CODE:
+ /* Probably good */
+ s[3] = s[2];
+ l[3] = l[2];
+ s[2].tag_opt = NULL;
+ l[2] = l[1];
+ parse_named_ref_opt(ctx, &s[4], &l[4]);
+ YYLLOC_DEFAULT(*lx, l, 4);
+ grammar_current_rule_action_append(s[3].BRACED_CODE, l[3], s[4].named_ref_opt, s[2].tag_opt);
+ break;
+ case PERCENT_EMPTY:
+ YYLLOC_DEFAULT(*lx, l, 2);
+ grammar_current_rule_empty_set(l[2]);
+ break;
+ default:
+ gram_unlex_wrap(ctx, t, &s[2], &l[2]);
+ return;
+ }
+ }
+ }
+}
+
+static void parse_rhses_1(gram_lex_ctx *ctx, GRAM_STYPE *sx, GRAM_LTYPE *lx) {
+ GRAM_STYPE s[4];
+ GRAM_LTYPE l[4];
+ parse_rhs(ctx, &s[1], &l[1]);
+ YYLLOC_DEFAULT(*lx, l, 1);
+ grammar_current_rule_end(l[1]);
+ while (1) {
+ s[1] = *sx;
+ l[1] = *lx;
+ int t = gram_lex_wrap(ctx, &s[2], &l[2]);
+ switch (t) {
+ case PIPE:
+ parse_rhs(ctx, &s[3], &l[3]);
+ YYLLOC_DEFAULT(*lx, l, 3);
+ grammar_current_rule_end(l[3]);
+ break;
+ case SEMICOLON:
+ YYLLOC_DEFAULT(*lx, l, 2);
+ break;
+ default:
+ gram_unlex_wrap(ctx, t, &s[2], &l[2]);
+ return;
+ }
+ }
+}
+
+static void parse_rules(gram_lex_ctx *ctx) {
+ GRAM_STYPE s[6];
+ GRAM_LTYPE l[6];
+ parse_id_colon(ctx, &s[1], &l[1]);
+ parse_named_ref_opt(ctx, &s[2], &l[2]);
+ gram_get_last_loc(ctx, &l[3]);
+ current_lhs(s[1].id_colon, l[1], s[2].named_ref_opt);
+ int t = gram_lex_wrap(ctx, &s[4], &l[4]);
+ assert(t == COLON);
+ parse_rhses_1(ctx, &s[5], &l[5]);
+ current_lhs(0, l[1], 0);
+}
+
+static void parse_grammar(gram_lex_ctx *ctx) {
+ while (1) {
+ int x = maybe_parse_declaration(ctx, 0);
+ if (x == 1) {
+ int t = gram_lex_wrap(ctx, NULL, NULL);
+ assert(t == SEMICOLON);
+ } if (x == 2) {
+ return;
+ } else if (x == 0) {
+ parse_rules(ctx);
+ }
+ }
+}
+
+static void parse_epilogue(gram_lex_ctx *ctx) {
+ GRAM_STYPE s;
+ GRAM_LTYPE l;
+ int t = gram_lex_wrap(ctx, &s, &l);
+ assert(t == EPILOGUE);
+ muscle_code_grow("epilogue", translate_code(s.EPILOGUE, l, true), l);
+ code_scanner_last_string_free();
+}
+
+int gram_parse(void) {
+ gram_lex_ctx ctx = {};
+ boundary_set(&ctx.l.start, current_file, 1, 1, 1);
+ boundary_set(&ctx.l.end, current_file, 1, 1, 1);
+ parse_prologue_declarations(&ctx);
+ parse_grammar(&ctx);
+ parse_epilogue(&ctx);
+ assert(gram_lex_wrap(&ctx, NULL, NULL) == 0);
+ return 0;
+}
+
+// Epilogue
+
+/* Return the location of the left-hand side of a rule whose
+ right-hand side is RHS[1] ... RHS[N]. Ignore empty nonterminals in
+ the right-hand side, and return an empty location equal to the end
+ boundary of RHS[0] if the right-hand side is empty. */
+
+static YYLTYPE
+lloc_default (YYLTYPE const *rhs, int n)
+{
+ YYLTYPE loc;
+
+ /* SGI MIPSpro 7.4.1m miscompiles "loc.start = loc.end = rhs[n].end;".
+ The bug is fixed in 7.4.2m, but play it safe for now. */
+ loc.start = rhs[n].end;
+ loc.end = rhs[n].end;
+
+ /* Ignore empty nonterminals the start of the right-hand side.
+ Do not bother to ignore them at the end of the right-hand side,
+ since empty nonterminals have the same end as their predecessors. */
+ for (int i = 1; i <= n; i++)
+ if (! equal_boundaries (rhs[i].start, rhs[i].end))
+ {
+ loc.start = rhs[i].start;
+ break;
+ }
+
+ return loc;
+}
+
+static
+char *strip_braces (char *code)
+{
+ code[strlen (code) - 1] = 0;
+ return code + 1;
+}
+
+static
+char const *
+translate_code (char *code, location loc, bool plain)
+{
+ code_props plain_code;
+ if (plain)
+ code_props_plain_init (&plain_code, code, loc);
+ else
+ code_props_symbol_action_init (&plain_code, code, loc);
+ code_props_translate_code (&plain_code);
+ gram_scanner_last_string_free ();
+ return plain_code.code;
+}
+
+static
+char const *
+translate_code_braceless (char *code, location loc)
+{
+ return translate_code (strip_braces (code), loc, true);
+}
+
+static void
+add_param (param_type type, char *decl, location loc)
+{
+ static char const alphanum[26 + 26 + 1 + 10 + 1] =
+ "abcdefghijklmnopqrstuvwxyz"
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "_"
+ "0123456789";
+
+ char const *name_start = NULL;
+ {
+ char *p;
+ /* Stop on last actual character. */
+ for (p = decl; p[1]; p++)
+ if ((p == decl
+ || ! memchr (alphanum, p[-1], sizeof alphanum - 1))
+ && memchr (alphanum, p[0], sizeof alphanum - 10 - 1))
+ name_start = p;
+
+ /* Strip the surrounding '{' and '}', and any blanks just inside
+ the braces. */
+ --p;
+ while (c_isspace ((unsigned char) *p))
+ --p;
+ p[1] = '\0';
+ ++decl;
+ while (c_isspace ((unsigned char) *decl))
+ ++decl;
+ }
+
+ if (! name_start)
+ complain (&loc, complaint, _("missing identifier in parameter declaration"));
+ else
+ {
+ char *name = xmemdup0 (name_start, strspn (name_start, alphanum));
+ if (type & param_lex)
+ muscle_pair_list_grow ("lex_param", decl, name);
+ if (type & param_parse)
+ muscle_pair_list_grow ("parse_param", decl, name);
+ free (name);
+ }
+
+ gram_scanner_last_string_free ();
+}
+
+
+static void
+handle_error_verbose (location const *loc, char const *directive)
+{
+ bison_directive (loc, directive);
+ muscle_percent_define_insert (directive, *loc, muscle_keyword, "",
+ MUSCLE_PERCENT_DEFINE_GRAMMAR_FILE);
+}
+
+
+static void
+handle_file_prefix (location const *loc,
+ location const *dir_loc,
+ char const *directive, char const *value)
+{
+ bison_directive (loc, directive);
+ bool warned = false;
+
+ if (location_empty (spec_file_prefix_loc))
+ {
+ spec_file_prefix_loc = *loc;
+ spec_file_prefix = value;
+ }
+ else
+ {
+ duplicate_directive (directive, spec_file_prefix_loc, *loc);
+ warned = true;
+ }
+
+ if (!warned
+ && STRNEQ (directive, "%file-prefix"))
+ deprecated_directive (dir_loc, directive, "%file-prefix");
+}
+
+
+static void
+handle_name_prefix (location const *loc,
+ char const *directive, char const *value)
+{
+ bison_directive (loc, directive);
+
+ char buf1[1024];
+ size_t len1 = sizeof (buf1);
+ char *old = asnprintf (buf1, &len1, "%s\"%s\"", directive, value);
+ if (!old)
+ xalloc_die ();
+
+ if (location_empty (spec_name_prefix_loc))
+ {
+ spec_name_prefix = value;
+ spec_name_prefix_loc = *loc;
+
+ char buf2[1024];
+ size_t len2 = sizeof (buf2);
+ char *new = asnprintf (buf2, &len2, "%%define api.prefix {%s}", value);
+ if (!new)
+ xalloc_die ();
+ deprecated_directive (loc, old, new);
+ if (new != buf2)
+ free (new);
+ }
+ else
+ duplicate_directive (old, spec_file_prefix_loc, *loc);
+
+ if (old != buf1)
+ free (old);
+}
+
+
+static void
+handle_pure_parser (location const *loc, char const *directive)
+{
+ bison_directive (loc, directive);
+ deprecated_directive (loc, directive, "%define api.pure");
+ muscle_percent_define_insert ("api.pure", *loc, muscle_keyword, "",
+ MUSCLE_PERCENT_DEFINE_GRAMMAR_FILE);
+}
+
+
+static void
+handle_require (location const *loc, char const *version)
+{
+ /* Changes of behavior are only on minor version changes, so "3.0.5"
+ is the same as "3.0". */
+ errno = 0;
+ char* cp = NULL;
+ unsigned long major = strtoul (version, &cp, 10);
+ if (errno || *cp != '.')
+ {
+ complain (loc, complaint, _("invalid version requirement: %s"),
+ version);
+ return;
+ }
+ ++cp;
+ unsigned long minor = strtoul (cp, NULL, 10);
+ if (errno)
+ {
+ complain (loc, complaint, _("invalid version requirement: %s"),
+ version);
+ return;
+ }
+ required_version = major * 100 + minor;
+ /* Pretend to be at least 3.4, to check features published in 3.4
+ while developping it. */
+ const char* api_version = "3.4";
+ const char* package_version =
+ strverscmp (api_version, PACKAGE_VERSION) > 0
+ ? api_version : PACKAGE_VERSION;
+ if (strverscmp (version, package_version) > 0)
+ {
+ complain (loc, complaint, _("require bison %s, but have %s"),
+ version, package_version);
+ exit (EX_MISMATCH);
+ }
+}
+
+static void
+handle_skeleton (location const *loc, char const *skel)
+{
+ char const *skeleton_user = skel;
+ if (strchr (skeleton_user, '/'))
+ {
+ size_t dir_length = strlen (current_file);
+ while (dir_length && current_file[dir_length - 1] != '/')
+ --dir_length;
+ while (dir_length && current_file[dir_length - 1] == '/')
+ --dir_length;
+ char *skeleton_build =
+ xmalloc (dir_length + 1 + strlen (skeleton_user) + 1);
+ if (dir_length > 0)
+ {
+ memcpy (skeleton_build, current_file, dir_length);
+ skeleton_build[dir_length++] = '/';
+ }
+ strcpy (skeleton_build + dir_length, skeleton_user);
+ skeleton_user = uniqstr_new (skeleton_build);
+ free (skeleton_build);
+ }
+ skeleton_arg (skeleton_user, grammar_prio, *loc);
+}
+
+
+static void
+handle_yacc (location const *loc, char const *directive)
+{
+ bison_directive (loc, directive);
+ bool warned = false;
+
+ if (location_empty (yacc_loc))
+ yacc_loc = *loc;
+ else
+ {
+ duplicate_directive (directive, yacc_loc, *loc);
+ warned = true;
+ }
+
+ if (!warned
+ && STRNEQ (directive, "%fixed-output-files")
+ && STRNEQ (directive, "%yacc"))
+ deprecated_directive (loc, directive, "%fixed-output-files");
+}
+
+
+static void
+gram_error (location const *loc, char const *msg)
+{
+ complain (loc, complaint, "%s", msg);
+}
+
+static char const *
+char_name (char c)
+{
+ if (c == '\'')
+ return "'\\''";
+ else
+ {
+ char buf[4];
+ buf[0] = '\''; buf[1] = c; buf[2] = '\''; buf[3] = '\0';
+ return quotearg_style (escape_quoting_style, buf);
+ }
+}
+
+static
+void
+current_lhs (symbol *sym, location loc, named_ref *ref)
+{
+ current_lhs_symbol = sym;
+ current_lhs_loc = loc;
+ if (sym)
+ symbol_location_as_lhs_set (sym, loc);
+ /* In order to simplify memory management, named references for lhs
+ are always assigned by deep copy into the current symbol_list
+ node. This is because a single named-ref in the grammar may
+ result in several uses when the user factors lhs between several
+ rules using "|". Therefore free the parser's original copy. */
+ free (current_lhs_named_ref);
+ current_lhs_named_ref = ref;
+}
+
+static void tron (FILE *yyo)
+{
+ begin_use_class ("value", yyo);
+}
+
+static void troff (FILE *yyo)
+{
+ end_use_class ("value", yyo);
+}
diff --git a/sysa/bison-3.4.1/files/parse-gram.h b/sysa/bison-3.4.1/files/parse-gram.h
@@ -0,0 +1,160 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+/*
+ * This file is based on parse-gram.y from GNU Bison 3.4.1. It is the
+ * header for an implementation of a subset of the grammar described
+ * by parse-gram.y, just enough to provide a bootstrapping path for
+ * Bison.
+ *
+ * Copyright (c) 2020, Giovanni Mascellani <gio@debian.org>
+ *
+ * The copyright notice of the original file follows. This file is
+ * distributed under the same license and with the same conditions.
+ */
+
+/* Bison Grammar Parser -*- C -*-
+
+ Copyright (C) 2002-2015, 2018-2019 Free Software Foundation, Inc.
+
+ This file is part of Bison, the GNU Compiler Compiler.
+
+ 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
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef PARSE_GRAM_H
+#define PARSE_GRAM_H
+
+/* %code requires */
+
+ #include "symlist.h"
+ #include "symtab.h"
+
+ typedef enum
+ {
+ param_none = 0,
+ param_lex = 1 << 0,
+ param_parse = 1 << 1,
+ param_both = param_lex | param_parse
+ } param_type;
+
+ #include "muscle-tab.h"
+ typedef struct
+ {
+ char const *chars;
+ muscle_kind kind;
+ } value_type;
+
+
+enum gram_tokentype {
+ GRAM_EOF = 0,
+ ID = 300,
+ STRING,
+ BRACED_CODE,
+ INT,
+ PERCENT_DEFINE,
+ PERCENT_DEFINES,
+ PERCENT_VERBOSE,
+ SEMICOLON,
+ PERCENT_TOKEN,
+ PERCENT_TYPE,
+ PERCENT_EMPTY,
+ COLON,
+ PERCENT_EXPECT,
+ PERCENT_PERCENT,
+ PERCENT_INITIAL_ACTION,
+ BRACKETED_ID,
+ PIPE,
+ EPILOGUE,
+ TAG,
+ PERCENT_CODE,
+ ID_COLON,
+
+ PERCENT_NONASSOC,
+ PERCENT_FLAG,
+ PERCENT_DEFAULT_PREC,
+ PERCENT_DESTRUCTOR,
+ PERCENT_DPREC,
+ PERCENT_EXPECT_RR,
+ EQUAL,
+ TAG_ANY,
+ CHAR,
+ BRACED_PREDICATE,
+ PERCENT_START,
+ PERCENT_UNION,
+ PERCENT_ERROR_VERBOSE,
+ PERCENT_NAME_PREFIX,
+ PERCENT_PURE_PARSER,
+ PERCENT_RIGHT,
+ PERCENT_PREC,
+ PERCENT_FILE_PREFIX,
+ PERCENT_YACC,
+ PERCENT_GLR_PARSER,
+ PERCENT_LANGUAGE,
+ PERCENT_LEFT,
+ PERCENT_PARAM,
+ PERCENT_MERGE,
+ PERCENT_NO_DEFAULT_PREC,
+ PERCENT_NO_LINES,
+ PERCENT_NONDETERMINISTIC_PARSER,
+ PERCENT_NTERM,
+ PERCENT_OUTPUT,
+ PERCENT_PRECEDENCE,
+ PRECENT_PRINTER,
+ PERCENT_REQUIRE,
+ PERCENT_SKELETON,
+ PERCENT_TOKEN_TABLE,
+ TAG_NONE,
+ PROLOGUE,
+ PERCENT_PRINTER,
+};
+
+union GRAM_STYPE {
+ value_type value;
+ uniqstr ID;
+ char *STRING;
+ symbol *symbol;
+ named_ref *named_ref_opt;
+ uniqstr tag_opt;
+ char *BRACED_CODE;
+ char *EPILOGUE;
+ symbol *id_colon;
+ uniqstr ID_COLON;
+ int int_opt;
+ int INT;
+ symbol *string_as_id;
+ symbol *string_as_id_opt;
+ symbol *token_decl;
+ symbol_list *token_decl_1;
+ symbol_list *token_decls;
+ symbol_list *symbol_decls;
+ symbol_list *symbol_decl_1;
+ uniqstr BRACKETED_ID;
+ symbol *id;
+ uniqstr TAG;
+
+ uniqstr PERCENT_FLAG;
+ uniqstr PERCENT_FILE_PREFIX;
+ uniqstr PERCENT_NAME_PREFIX;
+ uniqstr PERCENT_YACC;
+ param_type PERCENT_PARAM;
+ uniqstr PERCENT_PURE_PARSER;
+ uniqstr PERCENT_ERROR_VERBOSE;
+ unsigned char CHAR;
+ char *BRACED_PREDICATE;
+ char *PROLOGUE;
+};
+typedef union GRAM_STYPE GRAM_STYPE;
+
+int gram_parse (void);
+
+#endif
diff --git a/sysa/bison-3.4.1/files/parse-gram.y b/sysa/bison-3.4.1/files/parse-gram.y
@@ -0,0 +1,1070 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+/* Bison Grammar Parser -*- C -*-
+
+ Copyright (C) 2002-2015, 2018-2019 Free Software Foundation, Inc.
+
+ This file is part of Bison, the GNU Compiler Compiler.
+
+ 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
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/*
+ * This file is identical to the file parse-gram.y distributed with
+ * GNU Bison 3.4.1, except that all %printer and %destructor
+ * directives were removed (and this comment was added). It thus
+ * accepts the same grammar and produce the same actions, although it
+ * won't clean up things properly and it will have partially impaired
+ * printing.
+ *
+ * It was produced by Giovanni Mascellani <gio@debian.org> on 26th
+ * March 2020. Since the modifications are so trivial, no copyright is
+ * claimed.
+ */
+
+%code requires
+{
+ #include "symlist.h"
+ #include "symtab.h"
+}
+
+%code top
+{
+ /* On column 0 to please syntax-check. */
+#include <config.h>
+}
+
+%code
+{
+ #include "system.h"
+ #include <errno.h>
+
+ #include "c-ctype.h"
+ #include "complain.h"
+ #include "conflicts.h"
+ #include "files.h"
+ #include "getargs.h"
+ #include "gram.h"
+ #include "named-ref.h"
+ #include "quotearg.h"
+ #include "reader.h"
+ #include "scan-code.h"
+ #include "scan-gram.h"
+ #include "vasnprintf.h"
+ #include "xmemdup0.h"
+
+ static int current_prec = 0;
+ static location current_lhs_loc;
+ static named_ref *current_lhs_named_ref;
+ static symbol *current_lhs_symbol;
+ static symbol_class current_class = unknown_sym;
+
+ /** Set the new current left-hand side symbol, possibly common
+ * to several right-hand side parts of rule.
+ */
+ static void current_lhs (symbol *sym, location loc, named_ref *ref);
+
+ #define YYLLOC_DEFAULT(Current, Rhs, N) \
+ (Current) = lloc_default (Rhs, N)
+ static YYLTYPE lloc_default (YYLTYPE const *, int);
+
+ #define YY_LOCATION_PRINT(File, Loc) \
+ location_print (Loc, File)
+
+ /* Strip initial '{' and final '}' (must be first and last characters).
+ Return the result. */
+ static char *strip_braces (char *code);
+
+ /* Convert CODE by calling code_props_plain_init if PLAIN, otherwise
+ code_props_symbol_action_init. Call
+ gram_scanner_last_string_free to release the latest string from
+ the scanner (should be CODE). */
+ static char const *translate_code (char *code, location loc, bool plain);
+
+ /* Convert CODE by calling code_props_plain_init after having
+ stripped the first and last characters (expected to be '{', and
+ '}'). Call gram_scanner_last_string_free to release the latest
+ string from the scanner (should be CODE). */
+ static char const *translate_code_braceless (char *code, location loc);
+
+ /* Handle a %error-verbose directive. */
+ static void handle_error_verbose (location const *loc, char const *directive);
+
+ /* Handle a %file-prefix directive. */
+ static void handle_file_prefix (location const *loc,
+ location const *dir_loc,
+ char const *directive, char const *value);
+
+ /* Handle a %name-prefix directive. */
+ static void handle_name_prefix (location const *loc,
+ char const *directive, char const *value);
+
+ /* Handle a %pure-parser directive. */
+ static void handle_pure_parser (location const *loc, char const *directive);
+
+ /* Handle a %require directive. */
+ static void handle_require (location const *loc, char const *version);
+
+ /* Handle a %skeleton directive. */
+ static void handle_skeleton (location const *loc, char const *skel);
+
+ /* Handle a %yacc directive. */
+ static void handle_yacc (location const *loc, char const *directive);
+
+ static void gram_error (location const *, char const *);
+
+ /* A string that describes a char (e.g., 'a' -> "'a'"). */
+ static char const *char_name (char);
+
+ #define YYTYPE_INT16 int_fast16_t
+ #define YYTYPE_INT8 int_fast8_t
+ #define YYTYPE_UINT16 uint_fast16_t
+ #define YYTYPE_UINT8 uint_fast8_t
+
+ /* Add style to semantic values in traces. */
+ static void tron (FILE *yyo);
+ static void troff (FILE *yyo);
+}
+
+%define api.header.include {"parse-gram.h"}
+%define api.prefix {gram_}
+%define api.pure full
+%define api.value.type union
+%define locations
+%define parse.error verbose
+%define parse.lac full
+%define parse.trace
+%defines
+%expect 0
+%verbose
+
+%initial-action
+{
+ /* Bison's grammar can initial empty locations, hence a default
+ location is needed. */
+ boundary_set (&@$.start, current_file, 1, 1, 1);
+ boundary_set (&@$.end, current_file, 1, 1, 1);
+}
+
+/* Define the tokens together with their human representation. */
+%token GRAM_EOF 0 "end of file"
+%token STRING "string"
+
+%token PERCENT_TOKEN "%token"
+%token PERCENT_NTERM "%nterm"
+
+%token PERCENT_TYPE "%type"
+%token PERCENT_DESTRUCTOR "%destructor"
+%token PERCENT_PRINTER "%printer"
+
+%token PERCENT_LEFT "%left"
+%token PERCENT_RIGHT "%right"
+%token PERCENT_NONASSOC "%nonassoc"
+%token PERCENT_PRECEDENCE "%precedence"
+
+%token PERCENT_PREC "%prec"
+%token PERCENT_DPREC "%dprec"
+%token PERCENT_MERGE "%merge"
+
+/*----------------------.
+| Global Declarations. |
+`----------------------*/
+
+%token
+ PERCENT_CODE "%code"
+ PERCENT_DEFAULT_PREC "%default-prec"
+ PERCENT_DEFINE "%define"
+ PERCENT_DEFINES "%defines"
+ PERCENT_ERROR_VERBOSE "%error-verbose"
+ PERCENT_EXPECT "%expect"
+ PERCENT_EXPECT_RR "%expect-rr"
+ PERCENT_FLAG "%<flag>"
+ PERCENT_FILE_PREFIX "%file-prefix"
+ PERCENT_GLR_PARSER "%glr-parser"
+ PERCENT_INITIAL_ACTION "%initial-action"
+ PERCENT_LANGUAGE "%language"
+ PERCENT_NAME_PREFIX "%name-prefix"
+ PERCENT_NO_DEFAULT_PREC "%no-default-prec"
+ PERCENT_NO_LINES "%no-lines"
+ PERCENT_NONDETERMINISTIC_PARSER
+ "%nondeterministic-parser"
+ PERCENT_OUTPUT "%output"
+ PERCENT_PURE_PARSER "%pure-parser"
+ PERCENT_REQUIRE "%require"
+ PERCENT_SKELETON "%skeleton"
+ PERCENT_START "%start"
+ PERCENT_TOKEN_TABLE "%token-table"
+ PERCENT_VERBOSE "%verbose"
+ PERCENT_YACC "%yacc"
+;
+
+%token BRACED_CODE "{...}"
+%token BRACED_PREDICATE "%?{...}"
+%token BRACKETED_ID "[identifier]"
+%token CHAR "char"
+%token COLON ":"
+%token EPILOGUE "epilogue"
+%token EQUAL "="
+%token ID "identifier"
+%token ID_COLON "identifier:"
+%token PERCENT_PERCENT "%%"
+%token PIPE "|"
+%token PROLOGUE "%{...%}"
+%token SEMICOLON ";"
+%token TAG "<tag>"
+%token TAG_ANY "<*>"
+%token TAG_NONE "<>"
+
+ /* Experimental feature, don't rely on it. */
+%code pre-printer {tron (yyo);}
+%code post-printer {troff (yyo);}
+
+%type <unsigned char> CHAR
+
+%type <char*> "{...}" "%?{...}" "%{...%}" EPILOGUE STRING
+
+%type <uniqstr>
+ BRACKETED_ID ID ID_COLON
+ PERCENT_ERROR_VERBOSE PERCENT_FILE_PREFIX PERCENT_FLAG PERCENT_NAME_PREFIX
+ PERCENT_PURE_PARSER PERCENT_YACC
+ TAG tag tag.opt variable
+
+%token <int> INT "integer"
+
+%type <symbol*> id id_colon string_as_id symbol token_decl token_decl_for_prec
+
+%type <assoc> precedence_declarator
+
+%type <named_ref*> named_ref.opt
+
+/*---------.
+| %param. |
+`---------*/
+%code requires
+{
+ typedef enum
+ {
+ param_none = 0,
+ param_lex = 1 << 0,
+ param_parse = 1 << 1,
+ param_both = param_lex | param_parse
+ } param_type;
+};
+%code
+{
+ /** Add a lex-param and/or a parse-param.
+ *
+ * \param type where to push this formal argument.
+ * \param decl the formal argument. Destroyed.
+ * \param loc the location in the source.
+ */
+ static void add_param (param_type type, char *decl, location loc);
+ static param_type current_param = param_none;
+};
+%token <param_type> PERCENT_PARAM "%param";
+
+
+ /*==========\
+ | Grammar. |
+ \==========*/
+%%
+
+input:
+ prologue_declarations "%%" grammar epilogue.opt
+;
+
+
+ /*------------------------------------.
+ | Declarations: before the first %%. |
+ `------------------------------------*/
+
+prologue_declarations:
+ %empty
+| prologue_declarations prologue_declaration
+;
+
+prologue_declaration:
+ grammar_declaration
+| "%{...%}"
+ {
+ muscle_code_grow (union_seen ? "post_prologue" : "pre_prologue",
+ translate_code ($1, @1, true), @1);
+ code_scanner_last_string_free ();
+ }
+| "%<flag>"
+ {
+ muscle_percent_define_ensure ($1, @1, true);
+ }
+| "%define" variable value
+ {
+ muscle_percent_define_insert ($2, @$, $3.kind, $3.chars,
+ MUSCLE_PERCENT_DEFINE_GRAMMAR_FILE);
+ }
+| "%defines" { defines_flag = true; }
+| "%defines" STRING
+ {
+ defines_flag = true;
+ spec_header_file = xstrdup ($2);
+ }
+| "%error-verbose" { handle_error_verbose (&@$, $1); }
+| "%expect" INT { expected_sr_conflicts = $2; }
+| "%expect-rr" INT { expected_rr_conflicts = $2; }
+| "%file-prefix" STRING { handle_file_prefix (&@$, &@1, $1, $2); }
+| "%glr-parser"
+ {
+ nondeterministic_parser = true;
+ glr_parser = true;
+ }
+| "%initial-action" "{...}"
+ {
+ muscle_code_grow ("initial_action", translate_code ($2, @2, false), @2);
+ code_scanner_last_string_free ();
+ }
+| "%language" STRING { language_argmatch ($2, grammar_prio, @1); }
+| "%name-prefix" STRING { handle_name_prefix (&@$, $1, $2); }
+| "%no-lines" { no_lines_flag = true; }
+| "%nondeterministic-parser" { nondeterministic_parser = true; }
+| "%output" STRING { spec_outfile = $2; }
+| "%param" { current_param = $1; } params { current_param = param_none; }
+| "%pure-parser" { handle_pure_parser (&@$, $1); }
+| "%require" STRING { handle_require (&@2, $2); }
+| "%skeleton" STRING { handle_skeleton (&@2, $2); }
+| "%token-table" { token_table_flag = true; }
+| "%verbose" { report_flag |= report_states; }
+| "%yacc" { handle_yacc (&@$, $1); }
+| error ";" { current_class = unknown_sym; yyerrok; }
+| /*FIXME: Err? What is this horror doing here? */ ";"
+;
+
+params:
+ params "{...}" { add_param (current_param, $2, @2); }
+| "{...}" { add_param (current_param, $1, @1); }
+;
+
+
+/*----------------------.
+| grammar_declaration. |
+`----------------------*/
+
+grammar_declaration:
+ symbol_declaration
+| "%start" symbol
+ {
+ grammar_start_symbol_set ($2, @2);
+ }
+| code_props_type "{...}" generic_symlist
+ {
+ code_props code;
+ code_props_symbol_action_init (&code, $2, @2);
+ code_props_translate_code (&code);
+ {
+ for (symbol_list *list = $3; list; list = list->next)
+ symbol_list_code_props_set (list, $1, &code);
+ symbol_list_free ($3);
+ }
+ }
+| "%default-prec"
+ {
+ default_prec = true;
+ }
+| "%no-default-prec"
+ {
+ default_prec = false;
+ }
+| "%code" "{...}"
+ {
+ /* Do not invoke muscle_percent_code_grow here since it invokes
+ muscle_user_name_list_grow. */
+ muscle_code_grow ("percent_code()",
+ translate_code_braceless ($2, @2), @2);
+ code_scanner_last_string_free ();
+ }
+| "%code" ID "{...}"
+ {
+ muscle_percent_code_grow ($2, @2, translate_code_braceless ($3, @3), @3);
+ code_scanner_last_string_free ();
+ }
+;
+
+%type <code_props_type> code_props_type;
+code_props_type:
+ "%destructor" { $$ = destructor; }
+| "%printer" { $$ = printer; }
+;
+
+/*---------.
+| %union. |
+`---------*/
+
+%token PERCENT_UNION "%union";
+
+union_name:
+ %empty {}
+| ID { muscle_percent_define_insert ("api.value.union.name",
+ @1, muscle_keyword, $1,
+ MUSCLE_PERCENT_DEFINE_GRAMMAR_FILE); }
+;
+
+grammar_declaration:
+ "%union" union_name "{...}"
+ {
+ union_seen = true;
+ muscle_code_grow ("union_members", translate_code_braceless ($3, @3), @3);
+ code_scanner_last_string_free ();
+ }
+;
+
+
+%type <symbol_list*> nterm_decls symbol_decls symbol_decl.1
+ token_decls token_decls_for_prec
+ token_decl.1 token_decl_for_prec.1;
+symbol_declaration:
+ "%nterm" { current_class = nterm_sym; } nterm_decls[syms]
+ {
+ current_class = unknown_sym;
+ symbol_list_free ($syms);
+ }
+| "%token" { current_class = token_sym; } token_decls[syms]
+ {
+ current_class = unknown_sym;
+ symbol_list_free ($syms);
+ }
+| "%type" symbol_decls[syms]
+ {
+ symbol_list_free ($syms);
+ }
+| precedence_declarator token_decls_for_prec[syms]
+ {
+ ++current_prec;
+ for (symbol_list *list = $syms; list; list = list->next)
+ symbol_precedence_set (list->content.sym, current_prec, $1, @1);
+ symbol_list_free ($syms);
+ }
+;
+
+precedence_declarator:
+ "%left" { $$ = left_assoc; }
+| "%right" { $$ = right_assoc; }
+| "%nonassoc" { $$ = non_assoc; }
+| "%precedence" { $$ = precedence_assoc; }
+;
+
+tag.opt:
+ %empty { $$ = NULL; }
+| TAG { $$ = $1; }
+;
+
+%type <symbol_list*> generic_symlist generic_symlist_item;
+generic_symlist:
+ generic_symlist_item
+| generic_symlist generic_symlist_item { $$ = symbol_list_append ($1, $2); }
+;
+
+generic_symlist_item:
+ symbol { $$ = symbol_list_sym_new ($1, @1); }
+| tag { $$ = symbol_list_type_new ($1, @1); }
+;
+
+tag:
+ TAG
+| "<*>" { $$ = uniqstr_new ("*"); }
+| "<>" { $$ = uniqstr_new (""); }
+;
+
+/*-----------------------.
+| nterm_decls (%nterm). |
+`-----------------------*/
+
+// A non empty list of possibly tagged symbols for %nterm.
+//
+// Can easily be defined like symbol_decls but restricted to ID, but
+// using token_decls allows to reudce the number of rules, and also to
+// make nicer error messages on "%nterm 'a'" or '%nterm FOO "foo"'.
+nterm_decls:
+ token_decls
+;
+
+/*-----------------------------------.
+| token_decls (%token, and %nterm). |
+`-----------------------------------*/
+
+// A non empty list of possibly tagged symbols for %token or %nterm.
+token_decls:
+ token_decl.1[syms]
+ {
+ $$ = $syms;
+ }
+| TAG token_decl.1[syms]
+ {
+ $$ = symbol_list_type_set ($syms, $TAG, @TAG);
+ }
+| token_decls TAG token_decl.1[syms]
+ {
+ $$ = symbol_list_append ($1, symbol_list_type_set ($syms, $TAG, @TAG));
+ }
+;
+
+// One or more symbol declarations for %token or %nterm.
+token_decl.1:
+ token_decl { $$ = symbol_list_sym_new ($1, @1); }
+| token_decl.1 token_decl { $$ = symbol_list_append ($1, symbol_list_sym_new ($2, @2)); }
+
+// One symbol declaration for %token or %nterm.
+token_decl:
+ id int.opt[num] string_as_id.opt[alias]
+ {
+ $$ = $id;
+ symbol_class_set ($id, current_class, @id, true);
+ if (0 <= $num)
+ symbol_user_token_number_set ($id, $num, @num);
+ if ($alias)
+ symbol_make_alias ($id, $alias, @alias);
+ }
+;
+
+%type <int> int.opt;
+int.opt:
+ %empty { $$ = -1; }
+| INT
+;
+
+/*-------------------------------------.
+| token_decls_for_prec (%left, etc.). |
+`-------------------------------------*/
+
+// A non empty list of possibly tagged tokens for precedence declaration.
+//
+// Similar to %token (token_decls), but in '%left FOO 1 "foo"', it treats
+// FOO and "foo" as two different symbols instead of aliasing them.
+token_decls_for_prec:
+ token_decl_for_prec.1[syms]
+ {
+ $$ = $syms;
+ }
+| TAG token_decl_for_prec.1[syms]
+ {
+ $$ = symbol_list_type_set ($syms, $TAG, @TAG);
+ }
+| token_decls_for_prec TAG token_decl_for_prec.1[syms]
+ {
+ $$ = symbol_list_append ($1, symbol_list_type_set ($syms, $TAG, @TAG));
+ }
+;
+
+// One or more token declarations for precedence declaration.
+token_decl_for_prec.1:
+ token_decl_for_prec
+ { $$ = symbol_list_sym_new ($1, @1); }
+| token_decl_for_prec.1 token_decl_for_prec
+ { $$ = symbol_list_append ($1, symbol_list_sym_new ($2, @2)); }
+
+// One token declaration for precedence declaration.
+token_decl_for_prec:
+ id int.opt[num]
+ {
+ $$ = $id;
+ symbol_class_set ($id, token_sym, @id, false);
+ if (0 <= $num)
+ symbol_user_token_number_set ($id, $num, @num);
+ }
+| string_as_id
+;
+
+
+/*-----------------------.
+| symbol_decls (%type). |
+`-----------------------*/
+
+// A non empty list of typed symbols.
+symbol_decls:
+ symbol_decl.1[syms]
+ {
+ $$ = $syms;
+ }
+| TAG symbol_decl.1[syms]
+ {
+ $$ = symbol_list_type_set ($syms, $TAG, @TAG);
+ }
+| symbol_decls TAG symbol_decl.1[syms]
+ {
+ $$ = symbol_list_append ($1, symbol_list_type_set ($syms, $TAG, @TAG));
+ }
+;
+
+// One or more token declarations.
+symbol_decl.1:
+ symbol { $$ = symbol_list_sym_new ($1, @1); }
+| symbol_decl.1 symbol { $$ = symbol_list_append ($1, symbol_list_sym_new ($2, @2)); }
+;
+
+ /*------------------------------------------.
+ | The grammar section: between the two %%. |
+ `------------------------------------------*/
+
+grammar:
+ rules_or_grammar_declaration
+| grammar rules_or_grammar_declaration
+;
+
+/* As a Bison extension, one can use the grammar declarations in the
+ body of the grammar. */
+rules_or_grammar_declaration:
+ rules
+| grammar_declaration ";"
+| error ";"
+ {
+ yyerrok;
+ }
+;
+
+rules:
+ id_colon named_ref.opt { current_lhs ($1, @1, $2); } ":" rhses.1
+ {
+ /* Free the current lhs. */
+ current_lhs (0, @1, 0);
+ }
+;
+
+rhses.1:
+ rhs { grammar_current_rule_end (@rhs); }
+| rhses.1 "|" rhs { grammar_current_rule_end (@rhs); }
+| rhses.1 ";"
+;
+
+%token PERCENT_EMPTY "%empty";
+rhs:
+ %empty
+ { grammar_current_rule_begin (current_lhs_symbol, current_lhs_loc,
+ current_lhs_named_ref); }
+| rhs symbol named_ref.opt
+ { grammar_current_rule_symbol_append ($2, @2, $3); }
+| rhs tag.opt "{...}"[act] named_ref.opt[name]
+ { grammar_current_rule_action_append ($act, @act, $name, $[tag.opt]); }
+| rhs "%?{...}"
+ { grammar_current_rule_predicate_append ($2, @2); }
+| rhs "%empty"
+ { grammar_current_rule_empty_set (@2); }
+| rhs "%prec" symbol
+ { grammar_current_rule_prec_set ($3, @3); }
+| rhs "%dprec" INT
+ { grammar_current_rule_dprec_set ($3, @3); }
+| rhs "%merge" TAG
+ { grammar_current_rule_merge_set ($3, @3); }
+| rhs "%expect" INT
+ { grammar_current_rule_expect_sr ($3, @3); }
+| rhs "%expect-rr" INT
+ { grammar_current_rule_expect_rr ($3, @3); }
+;
+
+named_ref.opt:
+ %empty { $$ = NULL; }
+| BRACKETED_ID { $$ = named_ref_new ($1, @1); }
+;
+
+
+/*---------------------.
+| variable and value. |
+`---------------------*/
+
+variable:
+ ID
+;
+
+/* Some content or empty by default. */
+%code requires {
+ #include "muscle-tab.h"
+ typedef struct
+ {
+ char const *chars;
+ muscle_kind kind;
+ } value_type;
+};
+%type <value_type> value;
+
+value:
+ %empty { $$.kind = muscle_keyword; $$.chars = ""; }
+| ID { $$.kind = muscle_keyword; $$.chars = $1; }
+| STRING { $$.kind = muscle_string; $$.chars = $1; }
+| "{...}" { $$.kind = muscle_code; $$.chars = strip_braces ($1); }
+;
+
+
+/*--------------.
+| Identifiers. |
+`--------------*/
+
+/* Identifiers are returned as uniqstr values by the scanner.
+ Depending on their use, we may need to make them genuine symbols. */
+
+id:
+ ID
+ { $$ = symbol_from_uniqstr ($1, @1); }
+| CHAR
+ {
+ if (current_class == nterm_sym)
+ {
+ gram_error (&@1,
+ _("character literals cannot be nonterminals"));
+ YYERROR;
+ }
+ $$ = symbol_get (char_name ($1), @1);
+ symbol_class_set ($$, token_sym, @1, false);
+ symbol_user_token_number_set ($$, $1, @1);
+ }
+;
+
+id_colon:
+ ID_COLON { $$ = symbol_from_uniqstr ($1, @1); }
+;
+
+
+symbol:
+ id
+| string_as_id
+;
+
+/* A string used as an ID: quote it. */
+string_as_id:
+ STRING
+ {
+ $$ = symbol_get (quotearg_style (c_quoting_style, $1), @1);
+ symbol_class_set ($$, token_sym, @1, false);
+ }
+;
+
+%type <symbol*> string_as_id.opt;
+string_as_id.opt:
+ %empty { $$ = NULL; }
+| string_as_id
+;
+
+epilogue.opt:
+ %empty
+| "%%" EPILOGUE
+ {
+ muscle_code_grow ("epilogue", translate_code ($2, @2, true), @2);
+ code_scanner_last_string_free ();
+ }
+;
+
+%%
+
+/* Return the location of the left-hand side of a rule whose
+ right-hand side is RHS[1] ... RHS[N]. Ignore empty nonterminals in
+ the right-hand side, and return an empty location equal to the end
+ boundary of RHS[0] if the right-hand side is empty. */
+
+static YYLTYPE
+lloc_default (YYLTYPE const *rhs, int n)
+{
+ YYLTYPE loc;
+
+ /* SGI MIPSpro 7.4.1m miscompiles "loc.start = loc.end = rhs[n].end;".
+ The bug is fixed in 7.4.2m, but play it safe for now. */
+ loc.start = rhs[n].end;
+ loc.end = rhs[n].end;
+
+ /* Ignore empty nonterminals the start of the right-hand side.
+ Do not bother to ignore them at the end of the right-hand side,
+ since empty nonterminals have the same end as their predecessors. */
+ for (int i = 1; i <= n; i++)
+ if (! equal_boundaries (rhs[i].start, rhs[i].end))
+ {
+ loc.start = rhs[i].start;
+ break;
+ }
+
+ return loc;
+}
+
+static
+char *strip_braces (char *code)
+{
+ code[strlen (code) - 1] = 0;
+ return code + 1;
+}
+
+static
+char const *
+translate_code (char *code, location loc, bool plain)
+{
+ code_props plain_code;
+ if (plain)
+ code_props_plain_init (&plain_code, code, loc);
+ else
+ code_props_symbol_action_init (&plain_code, code, loc);
+ code_props_translate_code (&plain_code);
+ gram_scanner_last_string_free ();
+ return plain_code.code;
+}
+
+static
+char const *
+translate_code_braceless (char *code, location loc)
+{
+ return translate_code (strip_braces (code), loc, true);
+}
+
+static void
+add_param (param_type type, char *decl, location loc)
+{
+ static char const alphanum[26 + 26 + 1 + 10 + 1] =
+ "abcdefghijklmnopqrstuvwxyz"
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "_"
+ "0123456789";
+
+ char const *name_start = NULL;
+ {
+ char *p;
+ /* Stop on last actual character. */
+ for (p = decl; p[1]; p++)
+ if ((p == decl
+ || ! memchr (alphanum, p[-1], sizeof alphanum - 1))
+ && memchr (alphanum, p[0], sizeof alphanum - 10 - 1))
+ name_start = p;
+
+ /* Strip the surrounding '{' and '}', and any blanks just inside
+ the braces. */
+ --p;
+ while (c_isspace ((unsigned char) *p))
+ --p;
+ p[1] = '\0';
+ ++decl;
+ while (c_isspace ((unsigned char) *decl))
+ ++decl;
+ }
+
+ if (! name_start)
+ complain (&loc, complaint, _("missing identifier in parameter declaration"));
+ else
+ {
+ char *name = xmemdup0 (name_start, strspn (name_start, alphanum));
+ if (type & param_lex)
+ muscle_pair_list_grow ("lex_param", decl, name);
+ if (type & param_parse)
+ muscle_pair_list_grow ("parse_param", decl, name);
+ free (name);
+ }
+
+ gram_scanner_last_string_free ();
+}
+
+
+static void
+handle_error_verbose (location const *loc, char const *directive)
+{
+ bison_directive (loc, directive);
+ muscle_percent_define_insert (directive, *loc, muscle_keyword, "",
+ MUSCLE_PERCENT_DEFINE_GRAMMAR_FILE);
+}
+
+
+static void
+handle_file_prefix (location const *loc,
+ location const *dir_loc,
+ char const *directive, char const *value)
+{
+ bison_directive (loc, directive);
+ bool warned = false;
+
+ if (location_empty (spec_file_prefix_loc))
+ {
+ spec_file_prefix_loc = *loc;
+ spec_file_prefix = value;
+ }
+ else
+ {
+ duplicate_directive (directive, spec_file_prefix_loc, *loc);
+ warned = true;
+ }
+
+ if (!warned
+ && STRNEQ (directive, "%file-prefix"))
+ deprecated_directive (dir_loc, directive, "%file-prefix");
+}
+
+
+static void
+handle_name_prefix (location const *loc,
+ char const *directive, char const *value)
+{
+ bison_directive (loc, directive);
+
+ char buf1[1024];
+ size_t len1 = sizeof (buf1);
+ char *old = asnprintf (buf1, &len1, "%s\"%s\"", directive, value);
+ if (!old)
+ xalloc_die ();
+
+ if (location_empty (spec_name_prefix_loc))
+ {
+ spec_name_prefix = value;
+ spec_name_prefix_loc = *loc;
+
+ char buf2[1024];
+ size_t len2 = sizeof (buf2);
+ char *new = asnprintf (buf2, &len2, "%%define api.prefix {%s}", value);
+ if (!new)
+ xalloc_die ();
+ deprecated_directive (loc, old, new);
+ if (new != buf2)
+ free (new);
+ }
+ else
+ duplicate_directive (old, spec_file_prefix_loc, *loc);
+
+ if (old != buf1)
+ free (old);
+}
+
+
+static void
+handle_pure_parser (location const *loc, char const *directive)
+{
+ bison_directive (loc, directive);
+ deprecated_directive (loc, directive, "%define api.pure");
+ muscle_percent_define_insert ("api.pure", *loc, muscle_keyword, "",
+ MUSCLE_PERCENT_DEFINE_GRAMMAR_FILE);
+}
+
+
+static void
+handle_require (location const *loc, char const *version)
+{
+ /* Changes of behavior are only on minor version changes, so "3.0.5"
+ is the same as "3.0". */
+ errno = 0;
+ char* cp = NULL;
+ unsigned long major = strtoul (version, &cp, 10);
+ if (errno || *cp != '.')
+ {
+ complain (loc, complaint, _("invalid version requirement: %s"),
+ version);
+ return;
+ }
+ ++cp;
+ unsigned long minor = strtoul (cp, NULL, 10);
+ if (errno)
+ {
+ complain (loc, complaint, _("invalid version requirement: %s"),
+ version);
+ return;
+ }
+ required_version = major * 100 + minor;
+ /* Pretend to be at least 3.4, to check features published in 3.4
+ while developping it. */
+ const char* api_version = "3.4";
+ const char* package_version =
+ strverscmp (api_version, PACKAGE_VERSION) > 0
+ ? api_version : PACKAGE_VERSION;
+ if (strverscmp (version, package_version) > 0)
+ {
+ complain (loc, complaint, _("require bison %s, but have %s"),
+ version, package_version);
+ exit (EX_MISMATCH);
+ }
+}
+
+static void
+handle_skeleton (location const *loc, char const *skel)
+{
+ char const *skeleton_user = skel;
+ if (strchr (skeleton_user, '/'))
+ {
+ size_t dir_length = strlen (current_file);
+ while (dir_length && current_file[dir_length - 1] != '/')
+ --dir_length;
+ while (dir_length && current_file[dir_length - 1] == '/')
+ --dir_length;
+ char *skeleton_build =
+ xmalloc (dir_length + 1 + strlen (skeleton_user) + 1);
+ if (dir_length > 0)
+ {
+ memcpy (skeleton_build, current_file, dir_length);
+ skeleton_build[dir_length++] = '/';
+ }
+ strcpy (skeleton_build + dir_length, skeleton_user);
+ skeleton_user = uniqstr_new (skeleton_build);
+ free (skeleton_build);
+ }
+ skeleton_arg (skeleton_user, grammar_prio, *loc);
+}
+
+
+static void
+handle_yacc (location const *loc, char const *directive)
+{
+ bison_directive (loc, directive);
+ bool warned = false;
+
+ if (location_empty (yacc_loc))
+ yacc_loc = *loc;
+ else
+ {
+ duplicate_directive (directive, yacc_loc, *loc);
+ warned = true;
+ }
+
+ if (!warned
+ && STRNEQ (directive, "%fixed-output-files")
+ && STRNEQ (directive, "%yacc"))
+ deprecated_directive (loc, directive, "%fixed-output-files");
+}
+
+
+static void
+gram_error (location const *loc, char const *msg)
+{
+ complain (loc, complaint, "%s", msg);
+}
+
+static char const *
+char_name (char c)
+{
+ if (c == '\'')
+ return "'\\''";
+ else
+ {
+ char buf[4];
+ buf[0] = '\''; buf[1] = c; buf[2] = '\''; buf[3] = '\0';
+ return quotearg_style (escape_quoting_style, buf);
+ }
+}
+
+static
+void
+current_lhs (symbol *sym, location loc, named_ref *ref)
+{
+ current_lhs_symbol = sym;
+ current_lhs_loc = loc;
+ if (sym)
+ symbol_location_as_lhs_set (sym, loc);
+ /* In order to simplify memory management, named references for lhs
+ are always assigned by deep copy into the current symbol_list
+ node. This is because a single named-ref in the grammar may
+ result in several uses when the user factors lhs between several
+ rules using "|". Therefore free the parser's original copy. */
+ free (current_lhs_named_ref);
+ current_lhs_named_ref = ref;
+}
+
+static void tron (FILE *yyo)
+{
+ begin_use_class ("value", yyo);
+}
+
+static void troff (FILE *yyo)
+{
+ end_use_class ("value", yyo);
+}
diff --git a/sysa/bison-3.4.1/mk/lib.mk b/sysa/bison-3.4.1/mk/lib.mk
@@ -0,0 +1,10 @@
+# SPDX-FileCopyrightText: 2020 Giovanni Mascellani gio@debian.org
+# SPDX-FileCopyrightText: 2021 Andrius Štikonas <andrius@stikonas.eu>
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+lib.a: allocator.o areadlink.o argmatch.o asnprintf.o basename.o basename-lgpl.o binary-io.o bitrotate.o bitset.o bitsetv.o calloc.o canonicalize-lgpl.o careadlinkat.o c-ctype.o cloexec.o close.o closeout.o close-stream.o concat-filename.o c-strcasecmp.o c-strncasecmp.o dirname.o dirname-lgpl.o dup2.o dup-safer.o dup-safer-flag.o exitfail.o fatal-signal.o fd-hook.o fd-safer.o fd-safer-flag.o fopen.o fopen-safer.o fprintf.o frexp.o frexpl.o fstat.o getdtablesize.o get-errno.o gethrxtime.o getopt.o getprogname.o getrusage.o gettime.o gettimeofday.o gl_array_list.o gl_list.o gl_xlist.o hard-locale.o hash.o isnan.o isnand.o isnanf.o isnanl.o itold.o ldexpl.o localcharset.o localtime-buffer.o lstat.o main.o malloca.o malloc.o math.o mbrtowc.o mbsinit.o mbswidth.o memchr.o msvc-inval.o obstack.o obstack_printf.o open.o path-join.o perror.o pipe2-safer.o pipe-safer.o printf-args.o printf.o printf-frexp.o printf-frexpl.o printf-parse.o progname.o progreloc.o quotearg.o raise.o rawmemchr.o readlink.o realloc.o relocatable.o rename.o rmdir.o setenv.o sig-handler.o signbitd.o signbitf.o signbitl.o spawnattr_destroy.o spawnattr_init.o sprintf.o stat.o stat-time.o stat-w32.o stpcpy.o strchrnul.o strdup.o strerror.o stripslash.o strndup.o strnlen.o strverscmp.o timespec.o timevar.o unistd.o unlink.o unsetenv.o vasnprintf.o wait-process.o wctype-h.o xalloc-die.o xconcat-filename.o xmalloc.o xmemdup0.o xreadlink.o xsize.o xstrndup.o xtime.o yyerror.o error.o bitset/array.o bitset/list.o bitset/stats.o bitset/table.o bitset/vector.o fseterr.o spawn-pipe.o
+ $(AR) r $@ $^
+
+%.o: %.c
+ $(CC) $(CFLAGS) -g -c -I.. -I../lib -o $@ $<
diff --git a/sysa/bison-3.4.1/mk/main.mk b/sysa/bison-3.4.1/mk/main.mk
@@ -0,0 +1,27 @@
+# SPDX-FileCopyrightText: 2020 Giovanni Mascellani gio@debian.org
+# SPDX-FileCopyrightText: 2021 Andrius Štikonas <andrius@stikonas.eu>
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+CC=tcc
+AR="tcc -ar"
+
+all: bison
+
+bison: src.a lib.a
+ $(CC) $(CFLAGS) -g -o $@ $^
+
+%.a: FORCE
+ set -e ;\
+ DIR=$(basename $@ .a) ;\
+ $(MAKE) CC=$(CC) AR=$(AR) CFLAGS=$(CGLAGS) -C $$DIR $@ ;\
+ cp $$DIR/$@ $@
+
+FORCE:
+
+install:
+ install bison $(PREFIX)/bin
+ rm -rf $(PREFIX)/share/bison
+ install -d $(PREFIX)/share/bison
+ mv data/skeletons/ $(PREFIX)/share/bison
+ mv data/m4sugar/ $(PREFIX)/share/bison
diff --git a/sysa/bison-3.4.1/mk/src.mk b/sysa/bison-3.4.1/mk/src.mk
@@ -0,0 +1,23 @@
+# SPDX-FileCopyrightText: 2020 Giovanni Mascellani gio@debian.org
+# SPDX-FileCopyrightText: 2021 Andrius Štikonas <andrius@stikonas.eu>
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+src.a: AnnotationList.o assoc.o closure.o complain.o conflicts.o derives.o files.o fixits.o getargs.o gram.o graphviz.o ielr.o InadequacyList.o lalr.o location.o lr0.o main.o muscle-tab.o named-ref.o nullable.o output.o parse-gram.o print.o print-graph.o print-xml.o reader.o reduce.o relation.o Sbitset.o scan-code.o scan-gram.o scan-skel.o state.o symlist.o symtab.o tables.o uniqstr.o
+ $(AR) r $@ $^
+
+closure.o: parse-gram.h
+parse-gram.h: parse-gram.c
+
+%.o: %.c
+ $(CC) $(CFLAGS) -g -c -I. -I.. -I../lib -o $@ $<
+
+%.c: %.y
+ bison -dv $<
+ mv $(shell echo $@ | sed -e 's/c$$/tab.c/') $@
+ mv $(shell echo $@ | sed -e 's/c$$/tab.h/') $(shell echo $@ | sed -e 's/c$$/h/')
+
+%.c: %.l
+ /bin/sh ../build-aux/ylwrap $< lex.yy.c $@ -- flex
+
+.PRECIOUS: %.c %.o %.h
diff --git a/sysa/bison-3.4.1/patches/fseterr.patch b/sysa/bison-3.4.1/patches/fseterr.patch
@@ -0,0 +1,23 @@
+SPDX-FileCopyrightText: 2020 Giovanni Mascellani <gio@debian.org>
+
+SPDX-License-Identifier: GPL-3.0-or-later
+
+commit b1127f6821cc9c40c5a9ee406bee7564c549d9a3
+Author: Giovanni Mascellani <gio@debian.org>
+Date: Thu Mar 26 18:02:01 2020 +0100
+
+ Compile bison.
+
+diff --git lib/fseterr.c lib/fseterr.c
+index 8cd68e8..0ec7e2c 100644
+--- lib/fseterr.c
++++ lib/fseterr.c
+@@ -53,7 +53,7 @@ fseterr (FILE *fp)
+ #elif defined EPLAN9 /* Plan9 */
+ if (fp->state != 0 /* CLOSED */)
+ fp->state = 5 /* ERR */;
+-#elif 0 /* unknown */
++#elif 1 /* unknown */
+ /* Portable fallback, based on an idea by Rich Felker.
+ Wow! 6 system calls for something that is just a bit operation!
+ Not activated on any system, because there is no way to repair FP when
diff --git a/sysa/bison-3.4.1/patches/missing-includes.patch b/sysa/bison-3.4.1/patches/missing-includes.patch
@@ -0,0 +1,70 @@
+SPDX-FileCopyrightText: 2020 Giovanni Mascellani <gio@debian.org>
+
+SPDX-License-Identifier: GPL-3.0-or-later
+
+commit b1127f6821cc9c40c5a9ee406bee7564c549d9a3
+Author: Giovanni Mascellani <gio@debian.org>
+Date: Thu Mar 26 18:02:01 2020 +0100
+
+ Compile bison.
+
+diff --git src/scan-code.l src/scan-code.l
+index 73a3b2d..f348b20 100644
+--- src/scan-code.l
++++ src/scan-code.l
+@@ -21,6 +21,7 @@
+ %option prefix="code_" outfile="lex.yy.c"
+
+ %{
++#include "config.h"
+ #include <c-ctype.h>
+ #include <get-errno.h>
+ #include <quote.h>
+@@ -31,6 +32,7 @@
+ #include <src/reader.h>
+ #include <src/scan-code.h>
+ #include <src/symlist.h>
++#include "system.h"
+
+ #define FLEX_PREFIX(Id) code_ ## Id
+ #include <src/flex-scanner.h>
+diff --git src/scan-gram.l src/scan-gram.l
+index 66a8caa..efa391a 100644
+--- src/scan-gram.l
++++ src/scan-gram.l
+@@ -21,6 +21,7 @@
+ %option prefix="gram_" outfile="lex.yy.c"
+
+ %{
++#include "config.h"
+ #include <c-ctype.h>
+ #include <mbswidth.h>
+ #include <quote.h>
+@@ -33,6 +34,7 @@
+ #include <src/reader.h>
+ #include <src/scan-gram.h>
+ #include <src/uniqstr.h>
++#include "system.h"
+
+ #define FLEX_PREFIX(Id) gram_ ## Id
+ #include <src/flex-scanner.h>
+diff --git src/scan-skel.l src/scan-skel.l
+index 487e9f5..19f4832 100644
+--- src/scan-skel.l
++++ src/scan-skel.l
+@@ -21,6 +21,7 @@
+ %option prefix="skel_" outfile="lex.yy.c"
+
+ %{
++#include "config.h"
+ #include <dirname.h>
+ #include <error.h>
+ #include <path-join.h>
+@@ -30,6 +31,7 @@
+ #include <src/files.h>
+ #include <src/getargs.h>
+ #include <src/scan-skel.h>
++#include "system.h"
+
+ #define FLEX_PREFIX(Id) skel_ ## Id
+ #include <src/flex-scanner.h>
diff --git a/sysa/bison-3.4.1/stage1.sh b/sysa/bison-3.4.1/stage1.sh
@@ -0,0 +1,21 @@
+# SPDX-FileCopyrightText: 2021 Andrius Štikonas <andrius@stikonas.eu>
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+src_prepare() {
+ default_src_prepare
+
+ mv lib/textstyle.in.h lib/textstyle.h
+
+ # Remove pre-generated flex/bison files
+ rm src/parse-gram.c src/parse-gram.h
+ rm src/scan-code.c
+ rm src/scan-gram.c
+ rm src/scan-skel.c
+
+ # Handwritten bison parser
+ mv parse-gram.c parse-gram.h src/
+
+ cp ../../mk/lib.mk lib/Makefile
+ cp ../../mk/src.mk src/Makefile
+}
diff --git a/sysa/bison-3.4.1/stage2.sh b/sysa/bison-3.4.1/stage2.sh
@@ -0,0 +1,21 @@
+# SPDX-FileCopyrightText: 2021 Andrius Štikonas <andrius@stikonas.eu>
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+src_prepare() {
+ default_src_prepare
+
+ mv lib/textstyle.in.h lib/textstyle.h
+
+ # Remove pre-generated flex/bison files
+ rm src/parse-gram.c src/parse-gram.h
+ rm src/scan-code.c
+ rm src/scan-gram.c
+ rm src/scan-skel.c
+
+ # Simplified bison grammar
+ mv parse-gram.y src/
+
+ cp ../../mk/lib.mk lib/Makefile
+ cp ../../mk/src.mk src/Makefile
+}
diff --git a/sysa/bison-3.4.1/stage3.sh b/sysa/bison-3.4.1/stage3.sh
@@ -0,0 +1,18 @@
+# SPDX-FileCopyrightText: 2021 Andrius Štikonas <andrius@stikonas.eu>
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+src_prepare() {
+ default_src_prepare
+
+ mv lib/textstyle.in.h lib/textstyle.h
+
+ # Remove pre-generated flex/bison files
+ rm src/parse-gram.c src/parse-gram.h
+ rm src/scan-code.c
+ rm src/scan-gram.c
+ rm src/scan-skel.c
+
+ cp ../../mk/lib.mk lib/Makefile
+ cp ../../mk/src.mk src/Makefile
+}
diff --git a/sysa/run.sh b/sysa/run.sh
@@ -25,9 +25,14 @@ build m4-1.4.7
build flex-2.6.4
# Part 24
-build grep-2.4
+build bison-3.4.1 stage1.sh
+build bison-3.4.1 stage2.sh
+build bison-3.4.1 stage3.sh
# Part 25
+build grep-2.4
+
+# Part 26
build diffutils-2.7
echo "Bootstrapping completed."