bison-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] examples: add new build scenario test case


From: Kaz Kylheku
Subject: [PATCH] examples: add new build scenario test case
Date: Sun, 06 Sep 2020 22:55:47 -0700
User-agent: Roundcube Webmail/0.9.2

* examples/c/buildscenario/Makefile, examples/c/buildscenario/README.md,
* examples/c/buildscenario/buildscenario.test,
* examples/c/buildscenario/local.mk, examples/c/buildscenario/main.c,
* examples/c/buildscenario/parser.h, examples/c/buildscenario/parser.y,
* examples/c/buildscenario/local.mk:
New files.

* examples/c/local.mk: Include the buildscenario test case.
The new COMPILER_IS_GCC conditional is used to define some
compiler warning options only if the compiler is GCC.

* configure.ac (COMPILER_IS_GCC): New Automake conditional
symbol, derived from $GCC being yes.
---
 configure.ac                                |  3 +
 examples/c/buildscenario/Makefile           | 36 +++++++++
 examples/c/buildscenario/README.md          | 69 ++++++++++++++++
 examples/c/buildscenario/buildscenario.test | 19 +++++
 examples/c/buildscenario/local.mk           | 51 ++++++++++++
 examples/c/buildscenario/main.c             | 28 +++++++
 examples/c/buildscenario/parser.h           | 42 ++++++++++
 examples/c/buildscenario/parser.y           | 90 +++++++++++++++++++++
 examples/c/local.mk                         |  1 +
 9 files changed, 339 insertions(+)
 create mode 100644 examples/c/buildscenario/Makefile
 create mode 100644 examples/c/buildscenario/README.md
 create mode 100644 examples/c/buildscenario/buildscenario.test
 create mode 100644 examples/c/buildscenario/local.mk
 create mode 100644 examples/c/buildscenario/main.c
 create mode 100644 examples/c/buildscenario/parser.h
 create mode 100644 examples/c/buildscenario/parser.y

diff --git a/configure.ac b/configure.ac
index 4993a2c6..d5b738f3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -360,4 +360,7 @@ AC_CONFIG_COMMANDS_PRE([
   esac
 ])

+# Whether the compiler is GCC
+AM_CONDITIONAL([COMPILER_IS_GCC], [test "$GCC" = yes])
+
 AC_OUTPUT
diff --git a/examples/c/buildscenario/Makefile b/examples/c/buildscenario/Makefile
new file mode 100644
index 00000000..c48abf88
--- /dev/null
+++ b/examples/c/buildscenario/Makefile
@@ -0,0 +1,36 @@
+# This Makefile is designed to be simple and readable.  It does not
+# aim at portability.  It requires GNU Make.
+BASE = buildscenario
+
+CFLAGS += -W -Wall -ansi -pedantic \
+          -Werror=implicit-function-declaration \
+          -Werror=missing-prototypes \
+          -Werror=strict-prototypes
+BISON = bison --yacc
+ifneq (BISON,byacc)
+BISONFLAGS += -Wno-deprecated -Wno-yacc
+endif
+
+CLEANFILES = $(BASE) main.o y.tab.o y.tab.h y.tab.c y.output
+
+$(BASE): main.o y.tab.o
+       $(CC) -o $@ $^
+
+run: $(BASE)
+       @echo "This program doesn't do anything."
+       ./$<
+
+y.tab.c: parser.y
+       $(BISON) $(BISONFLAGS) -v -d $<
+       # workaround for Bison 3.x: yyparse declared in y.tab.h
+ifneq (BISON,byacc)
+       sed -e /yyparse/d < y.tab.h > y.tab.h.tmp
+       mv y.tab.h.tmp y.tab.h
+endif
+
+main.o: parser.h
+
+y.tab.o: parser.h y.tab.h
+
+clean:
+       -rm -f $(CLEANFILES)
diff --git a/examples/c/buildscenario/README.md b/examples/c/buildscenario/README.md
new file mode 100644
index 00000000..7a1293ff
--- /dev/null
+++ b/examples/c/buildscenario/README.md
@@ -0,0 +1,69 @@
+# buildscenario - a realistic Bison build scenario with historic warts.
+
+This directory contains buildscenario, a program which doesn't do
+anything, but is required to build successfully.
+
+The structure of this program mimics one that is found in a
+real-world program, the TXR language.
+
+It uses %pure-parser and can build not only with Bison, but also with
+Berkeley Yacc, which implements %pure-parse in a manner that remains
+compatible with Bison 2.
+
+The parser.h header defines the scanner and parser type definitions.
+
+If the y.tab.h header is included before parser.h, then parser.h
+provides the complete declaration of the parser structure.
+Otherwise it provides an incomplete declaration only.
+
+C files implementing the parser objects therefore include y.tab.h before
+parser.h. A representation of such files is omitted from this condensed
+sample; they are not exemplified.
+
+Other C files in the application that need to use the parser only
+include parser.h. They receive only an opaque interface. Such modules of the
+program are exemplified by main.c in this example.
+
+The parser structure's body references the YYSTYPE union, which is why it +requires requires y.tab.h. Since y.tab.h defines well-known symbols (the +token macros) it is possible to easily and portably detect whether it has been
+included.
+
+Because the parser is pure, the yyparse function takes a pointer to the parser +structure as one of its parameters. At some point, bison 3.x introduced a
+prototype declaration of yyparse into y.tab.h. This creates a circular
+dependency: parser.h needs y.tab.h for YYSTYPE, but y.tab.h needs the parser +type to be declared for the prototype of yyparse. This is why the Makefile +for buildscenario contains a step to remove the yyparse declaration from
+y.tab.h. This is not necessary with bison 2.x or wit Berkeley Yacc.
+If that filtering step is omitted, buildscenario will not build.
+
+In this program organization, only the parser.y file contains a call to
+yyparse; this illustrates that the declaration of yyparse is not required at +all outside of that file. A wrapper function calls yyparse, from a point in
+the file where the full definition of yyparse is in scope, providing a
+declaration.
+
+The %purse-parser declaration is deprecated in Bison. Moreover, if it
+is used in --yacc mode, there is a warning from Bison about a non-POSIX
+extension being used. The -Wno-yacc and -Wno-deprecated options are
+used to suppress these diagnostics.
+
+<!---
+Local Variables:
+fill-column: 76
+ispell-dictionary: "american"
+End:
+
+Copyright (C) 2019-2020 Free Software Foundation, Inc.
+
+This file is part of Bison, the GNU Compiler Compiler.
+
+Permission is granted to copy, distribute and/or modify this document
+under the terms of the GNU Free Documentation License, Version 1.3 or
+any later version published by the Free Software Foundation; with no
+Invariant Sections, with no Front-Cover Texts, and with no Back-Cover
+Texts.  A copy of the license is included in the "GNU Free
+Documentation License" file as part of this distribution.
+
+--->
diff --git a/examples/c/buildscenario/buildscenario.test b/examples/c/buildscenario/buildscenario.test
new file mode 100644
index 00000000..489054a3
--- /dev/null
+++ b/examples/c/buildscenario/buildscenario.test
@@ -0,0 +1,19 @@
+#! /bin/sh
+
+# Copyright (C) 2019-2020 Free Software Foundation, Inc.
+#
+# 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/>.
+
+> input   # empty input
+run 0 ""  # program produces empty line
diff --git a/examples/c/buildscenario/local.mk b/examples/c/buildscenario/local.mk
new file mode 100644
index 00000000..44d89ce2
--- /dev/null
+++ b/examples/c/buildscenario/local.mk
@@ -0,0 +1,51 @@
+## Copyright (C) 2019-2020 Free Software Foundation, Inc.
+##
+## 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/>.
+
+buildscenariodir = $(docdir)/%D%
+
+check_PROGRAMS += %D%/buildscenario
+
+dist_buildscenario_DATA = %D%/parser.y %D%/parser.h %D%/main.c %D%/Makefile %D%/README.md
+nodist_%C%_buildscenario_SOURCES = %D%/parse.y %D%/main.c %D%/parse.h
+nodist_%C%_buildscenario_OBJECTS = %D%/y.tab.o %D%/main.o
+
+TESTS += %D%/buildscenario.test
+EXTRA_DIST += %D%/buildscenario.test
+
+CLEANDIRS += %D%/*.dSYM
+CLEANFILES += $(%C%_buildscenario_OBJECTS)
+
+%C%_buildscenario_CPPFLAGS =
+%C%_buildscenario_CFLAGS = $(TEST_CFLAGS)
+
+if COMPILER_IS_GCC
+  %C%_buildscenario_CFLAGS += \
+    -W -Wall -ansi -pedantic \
+    -Werror=implicit-function-declaration \
+    -Werror=missing-prototypes \
+    -Werror=strict-prototypes
+endif
+
+%D%/y.tab.c: %D%/parser.y
+       $(BISON) --yacc -Wno-yacc -Wno-deprecated -v -d $<
+       @# workaround for Bison 3.x: yyparse declared in y.tab.h
+       sed -e /yyparse/d < y.tab.h > y.tab.h.tmp
+       mv y.tab.h.tmp %D%/y.tab.h
+       mv y.tab.c %D%/y.tab.c
+       mv y.output %D%/y.output
+
+%D%/main.o: %D%/parser.h
+
+%D%/y.tab.o: %D%/parser.h %D%/y.tab.h
diff --git a/examples/c/buildscenario/main.c b/examples/c/buildscenario/main.c
new file mode 100644
index 00000000..b4a93944
--- /dev/null
+++ b/examples/c/buildscenario/main.c
@@ -0,0 +1,28 @@
+/* Main module of buildscenario.   -*- C -*-
+
+   Copyright (C) 2020 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/>. */
+#include <stdio.h>
+#include "parser.h"
+
+int main(void)
+{
+  parser_t *p = parser_create();
+  parse(p);
+ putchar('\n'); /* test framework requires at least one line of output */
+  return 0;
+}
diff --git a/examples/c/buildscenario/parser.h b/examples/c/buildscenario/parser.h
new file mode 100644
index 00000000..75fc971f
--- /dev/null
+++ b/examples/c/buildscenario/parser.h
@@ -0,0 +1,42 @@
+/* Declrations of buildscenario.   -*- C -*-
+
+   Copyright (C) 2020 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/>. */
+typedef struct yyguts_t scanner_t;
+typedef struct parser parser_t;
+typedef void *yyscan_t;
+
+#ifdef SPACE /* If y.tab.h has been included ... */
+
+struct token {
+  YYSTYPE yy_lval;
+};
+
+struct parser {
+  scanner_t *scanner;
+  struct token tok;
+  void *ast;
+};
+
+int yylex(YYSTYPE *yylval_param, yyscan_t yyscanner);
+
+#endif
+
+void yyerror(scanner_t *scanner, parser_t *, const char *s);
+void parser_func(scanner_t *s, parser_t *p);
+parser_t *parser_create(void);
+int parse(parser_t *);
diff --git a/examples/c/buildscenario/parser.y b/examples/c/buildscenario/parser.y
new file mode 100644
index 00000000..d4247d08
--- /dev/null
+++ b/examples/c/buildscenario/parser.y
@@ -0,0 +1,90 @@
+/* Parser for buildscenario.   -*- C -*-
+
+   Copyright (C) 2020 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/>. */
+
+%{
+
+/*
+ * These headers must be in that order because "parser.h" needs YYSTYPE in + * order to define the parser structure. But parser.h also defines the types + * that are required for Bison's yyparse declaration in y.tab.h to work. + * The solution is the hack in the Makefile to remove the yyparse declaration.
+ */
+#include "y.tab.h"
+#include "parser.h"
+
+/*
+ * Byacc doesn't need the following at all. We need to add it for Bison
+ * because we stripped the yyparse declaration from y.tab.h in the Makefile.
+ */
+#if YYBISON
+int yyparse(scanner_t *, parser_t *);
+#endif
+
+void parser_func(scanner_t *s, parser_t *p)
+{
+  (void) s;
+  (void) p;
+}
+
+%}
+
+%pure-parser
+%parse-param{scanner_t *scnr}
+%parse-param{parser_t *parser}
+%lex-param{yyscan_t scnr}
+
+%union {
+  int val;
+}
+
+%token <val> SPACE
+%type <val> top
+
+%%
+
+top  : SPACE  { $$ = $1; parser->ast = 0; }
+     ;
+
+%%
+
+int yylex(YYSTYPE *yyparam, yyscan_t scanner)
+{
+  yyparam->val = 42;
+  (void) scanner;
+  return SPACE;
+}
+
+parser_t *parser_create(void)
+{
+  return 0;
+}
+
+int parse(parser_t *p)
+{
+  if (0)
+    yyparse(p->scanner, p);
+  return 0;
+}
+
+void yyerror(scanner_t *scanner, parser_t *parser, const char *s)
+{
+  (void) scanner;
+  (void) parser;
+  (void) s;
+}
diff --git a/examples/c/local.mk b/examples/c/local.mk
index 860d6994..506fbdc5 100644
--- a/examples/c/local.mk
+++ b/examples/c/local.mk
@@ -23,3 +23,4 @@ include %D%/mfcalc/local.mk
 include %D%/pushcalc/local.mk
 include %D%/reccalc/local.mk
 include %D%/rpcalc/local.mk
+include %D%/buildscenario/local.mk
--
2.17.1



reply via email to

[Prev in Thread] Current Thread [Next in Thread]