[Top][All Lists]

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

[PATCH 3/4] yacc.c: provide a means to include the header in the impleme

From: Akim Demaille
Subject: [PATCH 3/4] yacc.c: provide a means to include the header in the implementation
Date: Sat, 16 Mar 2019 10:02:08 +0100

Currently when --defines is used, we generate a header, and paste an
exact copy of it into the generated parser implementation file.  Let's
provide a means to #include it instead.

We don't do it by default because of the Autotools' ylwrap.  This
program wraps invocations of yacc (that uses a fixed output name:,, y.output) to support a more modern naming
scheme (dir/foo.y -> dir/, dir/, etc.).  It does
that by renaming the generated files, and then by running sed to
propagate these renamings inside the files themselves.

Unfortunately Automake's Makefiles uses Bison as if it were Yacc (with
--yacc or with -o and invoke bison via ylwrap.  As a
consequence, as far as Bison is concerned, the output files are and, so it emits '#include ""'.  So far, so
good.  But now ylwrap processes this '#include ""' into
'#include "dir/"', which is not guaranteed to always work.

So, let's do the Right Thing when the output file is not, in
which case the user should %define api.header.include.  Binding this
behavior to --yacc is tempting, but we recently told people to stop
using --yacc (as it also enables the Yacc warnings), but rather to use

Yacc.c is the only skeleton concerned: all the others do include their

* data/skeletons/yacc.c (b4_header_include_if): New.
(api.header.include): Provide a default value when the output is not
* src/parse-gram.y (api.header.include): Define.
 NEWS                   | 18 ++++++++++++++++++
 data/skeletons/yacc.c  | 28 +++++++++++++++++++++++-----
 examples/c/calc/calc.y |  1 +
 src/parse-gram.y       |  1 +
 4 files changed, 43 insertions(+), 5 deletions(-)

diff --git a/NEWS b/NEWS
index 5352e043..f41a5931 100644
--- a/NEWS
+++ b/NEWS
@@ -15,6 +15,24 @@ GNU Bison NEWS
   When given -fsyntax-only, the diagnostics are reported, but no output is
+*** Include the generated header (yacc.c)
+  Before, when --defines is used, bison generated a header, and pasted an
+  exact copy of it into the generated parser implementation file.  If the
+  header name is not "", it is now #included instead of being
+  duplicated.
+  To use an '#include' even if the header name is "" (which is what
+  happens with --yacc, or when using the Autotools' ylwrap), define
+  api.header.include to the exact argument to pass to #include.  For
+  instance:
+    %define api.header.include {"parse.h"}
+  or
+    %define api.header.include {<parser/parse.h>}
 ** Documentation
   A new example in C shows an simple infix calculator with a hand-written
diff --git a/data/skeletons/yacc.c b/data/skeletons/yacc.c
index fb3cf54a..446b5c84 100644
--- a/data/skeletons/yacc.c
+++ b/data/skeletons/yacc.c
@@ -294,6 +294,25 @@ m4_define([b4_shared_declarations],
+# b4_header_include_if(IF-TRUE, IF-FALSE)
+# ---------------------------------------
+# Run IF-TRUE if we generate an output file and api.header.include
+# is defined.
+          [b4_percent_define_ifdef([[api.header.include]],
+                                   [$1],
+                                   [$2])],
+          [$2])])
+m4_if(b4_spec_defines_file, [[]],
+      [b4_percent_define_default([[api.header.include]],
+                                 [["@basename(]b4_spec_defines_file[@)"]])])
 ## -------------- ##
 ## Output files.  ##
 ## -------------- ##
@@ -354,11 +373,10 @@ m4_if(b4_api_prefix, [yy], [],
 # define YYERROR_VERBOSE ]b4_error_verbose_if([1], [0])[
-[[/* In a future release of Bison, this section will be replaced
-   by #include "@basename(]b4_spec_defines_file[@)".  */
+                      [/* Use api.header.include to #include this header
+   instead of duplicating it here.  */
diff --git a/examples/c/calc/calc.y b/examples/c/calc/calc.y
index f3771f2e..f3a6cb1d 100644
--- a/examples/c/calc/calc.y
+++ b/examples/c/calc/calc.y
@@ -7,6 +7,7 @@
   void yyerror (char const *);
+%define api.header.include {"calc.h"}
 %define api.value.type union /* Generate YYSTYPE from these types:  */
 %token <double> NUM "number"
 %type  <double> expr term fact
diff --git a/src/parse-gram.y b/src/parse-gram.y
index b01c4e83..13598fa0 100644
--- a/src/parse-gram.y
+++ b/src/parse-gram.y
@@ -114,6 +114,7 @@
   #define YYTYPE_UINT8 uint_fast8_t
+%define api.header.include {"parse-gram.h"}
 %define api.prefix {gram_}
 %define api.pure full
 %define api.value.type union

reply via email to

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