mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-09 12:23:04 +00:00
api.header.include: document it, and fix its default value
While defining api.header.include worked as expected, its default value was incorrectly defined. As a result, by default, the generated parsers still duplicated the content of the generated header instead of including it. * data/skeletons/yacc.c (api.header.include): Fix its default value. * tests/output.at: Check it. * doc/bison.texi (%define Summary): Document api.header.include. While at it, move the definition of api.namespace at the proper place.
This commit is contained in:
20
NEWS
20
NEWS
@@ -7,6 +7,26 @@ GNU Bison NEWS
|
|||||||
When installed to be relocatable (via configure --enable-relocatable),
|
When installed to be relocatable (via configure --enable-relocatable),
|
||||||
bison will now also look for a relocated m4.
|
bison will now also look for a relocated m4.
|
||||||
|
|
||||||
|
** Bug fixes
|
||||||
|
|
||||||
|
*** Include the generated header (yacc.c)
|
||||||
|
|
||||||
|
Historically, when --defines was used, bison generated a header and pasted
|
||||||
|
an exact copy of it into the generated parser implementation file. Since
|
||||||
|
Bison 3.4 it is possible to specify that the header should be `#include`d,
|
||||||
|
and how. For instance
|
||||||
|
|
||||||
|
%define api.header.include {"parse.h"}
|
||||||
|
|
||||||
|
or
|
||||||
|
|
||||||
|
%define api.header.include {<parser/parse.h>}
|
||||||
|
|
||||||
|
Now api.header.include defaults to `"header-basename"`, as was intended in
|
||||||
|
Bison 3.4, where `header-basename` is the basename of the generated
|
||||||
|
header. This is disabled when the generated header is `y.tab.h`, to
|
||||||
|
comply with Automake's ylwrap.
|
||||||
|
|
||||||
** New features
|
** New features
|
||||||
|
|
||||||
*** File prefix mapping
|
*** File prefix mapping
|
||||||
|
|||||||
8
TODO
8
TODO
@@ -15,16 +15,11 @@ list_get_end (gl_list_t list)
|
|||||||
** Bistromathic
|
** Bistromathic
|
||||||
- Hitting tab on a line with a syntax error is ugly
|
- Hitting tab on a line with a syntax error is ugly
|
||||||
|
|
||||||
- Be robust to existing ~/.inputrc
|
|
||||||
|
|
||||||
- How about not evaluating incomplete lines when the text is not finished
|
- How about not evaluating incomplete lines when the text is not finished
|
||||||
(as shells do).
|
(as shells do).
|
||||||
|
|
||||||
- Caret diagnostics
|
- Caret diagnostics
|
||||||
|
|
||||||
** Doc
|
|
||||||
*** api.header.include
|
|
||||||
|
|
||||||
** Questions
|
** Questions
|
||||||
*** Java
|
*** Java
|
||||||
- Should i18n be part of the Lexer? Currently it's a static method of
|
- Should i18n be part of the Lexer? Currently it's a static method of
|
||||||
@@ -54,9 +49,6 @@ enough.
|
|||||||
*** calc.at
|
*** calc.at
|
||||||
Stop hard-coding "Calc". Adjust local.at (look for FIXME).
|
Stop hard-coding "Calc". Adjust local.at (look for FIXME).
|
||||||
|
|
||||||
** Counter example generation
|
|
||||||
See https://github.com/akimd/bison/pull/15.
|
|
||||||
|
|
||||||
** Clean up
|
** Clean up
|
||||||
Rename endtoken as eoftoken.
|
Rename endtoken as eoftoken.
|
||||||
|
|
||||||
|
|||||||
@@ -335,7 +335,7 @@ m4_define([b4_header_include_if],
|
|||||||
[$2])],
|
[$2])],
|
||||||
[$2])])
|
[$2])])
|
||||||
|
|
||||||
m4_if(b4_spec_header_file, [[y.tab.h]],
|
m4_if(b4_spec_header_file, [y.tab.h], [],
|
||||||
[b4_percent_define_default([[api.header.include]],
|
[b4_percent_define_default([[api.header.include]],
|
||||||
[["@basename(]b4_spec_header_file[@)"]])])
|
[["@basename(]b4_spec_header_file[@)"]])])
|
||||||
|
|
||||||
|
|||||||
@@ -5922,44 +5922,58 @@ Unaccepted @var{variable}s produce an error. Some of the accepted
|
|||||||
@var{variable}s are described below.
|
@var{variable}s are described below.
|
||||||
|
|
||||||
|
|
||||||
@c ================================================== api.namespace
|
@c ================================================== api.header.include
|
||||||
@deffn Directive {%define api.namespace} @{@var{namespace}@}
|
@deffn Directive {%define api.header.include} @{"header.h"@}
|
||||||
|
@deffnx Directive {%define api.header.include} @{<header.h>@}
|
||||||
@itemize
|
@itemize
|
||||||
@item Languages(s): C++
|
@item Languages(s): C (@file{yacc.c})
|
||||||
|
|
||||||
@item Purpose: Specify the namespace for the parser class.
|
@item Purpose: Specify how the generated parser should include the generated header.
|
||||||
For example, if you specify:
|
|
||||||
|
Historically, when option @option{-D}/@option{--defines} was used,
|
||||||
|
@command{bison} generated a header and pasted an exact copy of it into the
|
||||||
|
generated parser implementation file. Since Bison 3.6, it is
|
||||||
|
@code{#include}d as @samp{"@var{basename}.h"}, instead of duplicated, unless
|
||||||
|
@var{file} is @samp{y.tab}, see below.
|
||||||
|
|
||||||
|
The @code{api.header.include} variable allows to control how the generated
|
||||||
|
parser @code{#include}s the generated header. For instance:
|
||||||
|
|
||||||
@example
|
@example
|
||||||
%define api.namespace @{foo::bar@}
|
%define api.header.include @{"parse.h"@}
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
Bison uses @code{foo::bar} verbatim in references such as:
|
@noindent
|
||||||
|
or
|
||||||
|
|
||||||
@example
|
@example
|
||||||
foo::bar::parser::semantic_type
|
%define api.header.include @{<parser/parse.h>@}
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
However, to open a namespace, Bison removes any leading @code{::} and then
|
Using @code{api.header.include} does not change the name of the generated
|
||||||
splits on any remaining occurrences:
|
header, only how it is included.
|
||||||
|
|
||||||
@example
|
To work around limitations of Automake's @command{ylwrap} (which runs
|
||||||
namespace foo @{ namespace bar @{
|
@command{bison} with @option{--yacc}), @code{api.header.include} is
|
||||||
class position;
|
@emph{not} predefined when the output file is @file{y.tab.c}. Define it to
|
||||||
class location;
|
avoid the duplication.
|
||||||
@} @}
|
|
||||||
@end example
|
|
||||||
|
|
||||||
@item Accepted Values:
|
@item Accepted Values:
|
||||||
Any absolute or relative C++ namespace reference without a trailing
|
An argument for @code{#include}.
|
||||||
@code{"::"}. For example, @code{"foo"} or @code{"::foo::bar"}.
|
|
||||||
|
|
||||||
@item Default Value:
|
@item Default Value:
|
||||||
@code{yy}, unless you used the obsolete @samp{%name-prefix "@var{prefix}"}
|
@samp{"@var{header-basename}"}, unless the header file is @file{y.tab.h},
|
||||||
directive.
|
where @var{header-basename} is the name of the generated header, without
|
||||||
|
directory part. For instance with @command{bison -d calc/parse.y},
|
||||||
|
@code{api.header.include} defaults to @samp{"parse.h"}, not
|
||||||
|
@samp{"calc/parse.h"}.
|
||||||
|
|
||||||
|
@item History:
|
||||||
|
Introduced in Bison 3.4. Defaults to @samp{"@var{basename}.h"} since Bison
|
||||||
|
3.7, unless the header file is @file{y.tab.h}.
|
||||||
@end itemize
|
@end itemize
|
||||||
@end deffn
|
@end deffn
|
||||||
@c api.namespace
|
@c api.header.include
|
||||||
|
|
||||||
|
|
||||||
@c ================================================== api.location.file
|
@c ================================================== api.location.file
|
||||||
@@ -6043,6 +6057,46 @@ Introduced in Bison 2.7 for C++ and Java, in Bison 3.4 for C.
|
|||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
|
|
||||||
|
@c ================================================== api.namespace
|
||||||
|
@deffn Directive {%define api.namespace} @{@var{namespace}@}
|
||||||
|
@itemize
|
||||||
|
@item Languages(s): C++
|
||||||
|
|
||||||
|
@item Purpose: Specify the namespace for the parser class.
|
||||||
|
For example, if you specify:
|
||||||
|
|
||||||
|
@example
|
||||||
|
%define api.namespace @{foo::bar@}
|
||||||
|
@end example
|
||||||
|
|
||||||
|
Bison uses @code{foo::bar} verbatim in references such as:
|
||||||
|
|
||||||
|
@example
|
||||||
|
foo::bar::parser::semantic_type
|
||||||
|
@end example
|
||||||
|
|
||||||
|
However, to open a namespace, Bison removes any leading @code{::} and then
|
||||||
|
splits on any remaining occurrences:
|
||||||
|
|
||||||
|
@example
|
||||||
|
namespace foo @{ namespace bar @{
|
||||||
|
class position;
|
||||||
|
class location;
|
||||||
|
@} @}
|
||||||
|
@end example
|
||||||
|
|
||||||
|
@item Accepted Values:
|
||||||
|
Any absolute or relative C++ namespace reference without a trailing
|
||||||
|
@code{"::"}. For example, @code{"foo"} or @code{"::foo::bar"}.
|
||||||
|
|
||||||
|
@item Default Value:
|
||||||
|
@code{yy}, unless you used the obsolete @samp{%name-prefix "@var{prefix}"}
|
||||||
|
directive.
|
||||||
|
@end itemize
|
||||||
|
@end deffn
|
||||||
|
@c api.namespace
|
||||||
|
|
||||||
|
|
||||||
@c ================================================== api.parser.class
|
@c ================================================== api.parser.class
|
||||||
@deffn Directive {%define api.parser.class} @{@var{name}@}
|
@deffn Directive {%define api.parser.class} @{@var{name}@}
|
||||||
@itemize @bullet
|
@itemize @bullet
|
||||||
|
|||||||
@@ -30,9 +30,10 @@ m4_define([AT_CHECK_FILES],
|
|||||||
[], [$1
|
[], [$1
|
||||||
])])
|
])])
|
||||||
|
|
||||||
# AT_CHECK_OUTPUT(INPUT-FILE, [DIRECTIVES], [FLAGS], EXPECTED-FILES, [STATUS],
|
# AT_CHECK_OUTPUT($1 = INPUT-FILE, $2 = [DIRECTIVES], $3 = [FLAGS],
|
||||||
# [ADDITIONAL-TESTS], [PRE-TESTS])
|
# $4 = EXPECTED-FILES, $5 = [STATUS],
|
||||||
# -----------------------------------------------------------------------------
|
# $6 = [ADDITIONAL-TESTS], $7 = [PRE-TESTS])
|
||||||
|
# -----------------------------------------------------------------
|
||||||
m4_define([AT_CHECK_OUTPUT],
|
m4_define([AT_CHECK_OUTPUT],
|
||||||
[AT_SETUP([[Output files: ]$2 $3])[
|
[AT_SETUP([[Output files: ]$2 $3])[
|
||||||
]$7[
|
]$7[
|
||||||
@@ -73,8 +74,19 @@ AT_CHECK_OUTPUT([foo.y], [], [-dv >&-],
|
|||||||
[], [],
|
[], [],
|
||||||
[AT_CHECK([[case "$PREBISON" in *valgrind*) exit 77;; esac]])])
|
[AT_CHECK([[case "$PREBISON" in *valgrind*) exit 77;; esac]])])
|
||||||
|
|
||||||
|
|
||||||
|
# Check how api.header.include.
|
||||||
AT_CHECK_OUTPUT([foo.y], [], [-dv -o foo.c],
|
AT_CHECK_OUTPUT([foo.y], [], [-dv -o foo.c],
|
||||||
[foo.c foo.h foo.output])
|
[foo.c foo.h foo.output], [],
|
||||||
|
[AT_CHECK([grep '#include "foo.h"' foo.c], [0], [ignore])])
|
||||||
|
AT_CHECK_OUTPUT([foo.y], [], [-dv -y],
|
||||||
|
[y.output y.tab.c y.tab.h], [],
|
||||||
|
[AT_CHECK([grep '#include "y.tab.h"' y.tab.c], [1], [ignore])])
|
||||||
|
AT_CHECK_OUTPUT([foo.y], [%define api.header.include {"./foo.h"}], [-dv -y],
|
||||||
|
[y.output y.tab.c y.tab.h], [],
|
||||||
|
[AT_CHECK([grep '#include "./foo.h"' y.tab.c], [0], [ignore])])
|
||||||
|
|
||||||
|
|
||||||
AT_CHECK_OUTPUT([foo.y], [], [-dv -o foo.tab.c],
|
AT_CHECK_OUTPUT([foo.y], [], [-dv -o foo.tab.c],
|
||||||
[foo.output foo.tab.c foo.tab.h])
|
[foo.output foo.tab.c foo.tab.h])
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user