Compare commits

...
33 Commits
Author SHA1 Message Date
Akim Demaille 9beba1919c version 3.8.2
* NEWS: Record release date.
2021-09-25 10:43:40 +02:00
Akim Demaille 80ebbe7330 tests: Apple clang issues warning on C++11 features
$ cat /tmp/foo.cc
using foo = int;
foo f;
$ clang++ -Wc++11-extensions -c /tmp/foo.cc
/tmp/foo.cc:1:13: warning: alias declarations are a C++11 extension [-Wc++11-extensions]
using foo = int;
            ^
1 warning generated.
$ clang++ --version
Apple clang version 11.0.0 (clang-1100.0.33.17)
Target: x86_64-apple-darwin18.7.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin

* tests/local.at (AT_COMPILE_CXX): Make sure -std=c++11 is passed when
running glr2.cc.  It may be overridden by another flag in CXXFLAGS
afterwards.
2021-09-25 10:42:46 +02:00
Akim Demaille 028df02a9f avoid using atoi
* cfg.mk: Disable sc_indent as auto indent is too invasive for now.
Enable sc_prohibit_atoi_atof, except where we don't care.
* src/location.c, src/muscle-tab.c: Use strtol instead of atoi.
2021-09-25 08:03:22 +02:00
Akim Demaille 71dfc86d58 news: update 2021-09-24 05:38:58 +02:00
Akim Demaille 5c1069c7d8 gnulib: update
To get

commit 7818455627c5e54813ac89924b8b67d0bc869146
Author: Bruno Haible <[email protected]>
Date:   Fri Sep 17 22:22:50 2021 +0200

    threadlib: Avoid crashes in thread-related functions on Cygwin 3.2.0.

    Reported by Brian Inglis via Akim Demaille in
    <https://lists.gnu.org/archive/html/bug-gnulib/2021-09/msg00063.html>.

    * m4/threadlib.m4 (gl_WEAK_SYMBOLS): Force a "guessing no" result on
    Cygwin.
2021-09-18 16:25:57 +02:00
Akim Demaille 3fc3ef658e c++: use YY_NOEXCEPT where it helps
Suggested by Don Macpherson.
<https://github.com/akimd/bison/issues/80>

* data/skeletons/c++.m4, data/skeletons/glr2.cc,
* data/skeletons/lalr1.cc, data/skeletons/stack.hh: Use YY_NOEXCEPT
where it helps constructors.
2021-09-18 08:07:22 +02:00
Akim Demaille dd6e78360a gnulib: update 2021-09-13 08:36:37 +02:00
Akim Demaille eeb5d6f11b glr2.cc: semantic_option: use a symbol
* data/skeletons/c++.m4 (basic_symbol): Add assignment operators.
* data/skeletons/glr2.cc (semantic_option): Replace yytoken, yyvalue
and yylocation by yyla.
2021-09-13 06:20:40 +02:00
Akim Demaille 70441b5ab1 glr2.cc: don't publish move ctor to lalr1.cc
These operators were introduced in "c++: add move assignments to the
symbol type" (fdaedc780a) for glr2.cc.

* data/skeletons/c++.m4: Define them for glr2.cc only.
2021-09-13 06:18:57 +02:00
Akim Demaille 7538d8dc1a glr2.cc: simplify semantic_option
* data/skeletons/glr2.cc (semantic_option): Simplify the rule-based
constructor.  This shows that it should be easy to use a symbol_kind,
instead of the kind/value/location triple.
2021-09-12 20:04:54 +02:00
Akim Demaille b07b5ce423 glr2.cc: we require C++11
* data/skeletons/glr2.cc: So no need for C++98 compatibility.
2021-09-12 20:04:54 +02:00
Akim Demaille 157e91dcc6 glr2.cc: introduse b4_glr2_cc_if
* data/skeletons/bison.m4 (b4_glr2_cc_if): Intro.
* data/skeletons/c++.m4: use.
2021-09-12 20:04:44 +02:00
Akim Demaille b820718adf glr2.cc: don't pass %parse-param to destroy
I regret that %destructor and %printer give access to the %parse-param
in lalr1.cc, since that prevents them from being implemented as a
simple destructor and operator<<.  Let's not repeat the mistake in
glr2.cc.  In addition, fixes a name conflict we have currently in
tests 566 568 570 657:

     calc.cc:1395:85: error: declaration shadows a field of 'calc::parser' [-Werror,-Wshadow]
     void glr_state::destroy (char const* yymsg, calc::parser& yyparser, semantic_value *result, int *count, int *nerrs)
                                                                                         ^
     calc.hh:441:21: note: previous declaration is here
         semantic_value *result;
                         ^

With this commit, the whole test suite passes for glr2.cc.

* data/skeletons/glr2.cc (glr_state::destroy): Don't take the user
arguments.
2021-09-12 14:00:55 +02:00
Akim Demaille 6e6e11795c glr2.cc: kill trailing white spaces
Fixes several calc tests.

Tests 566 568 570 657 still fail because of a name clash when using
%parse-param:

    calc.cc:1395:85: error: declaration shadows a field of 'calc::parser' [-Werror,-Wshadow]
    void glr_state::destroy (char const* yymsg, calc::parser& yyparser, semantic_value *result, int *count, int *nerrs)
                                                                                        ^
    calc.hh:441:21: note: previous declaration is here
        semantic_value *result;
                        ^

* data/skeletons/glr2.cc: Fix indentation/trailing spaces.
2021-09-12 14:00:55 +02:00
Akim Demaille 6bfdf22c50 glr2.cc: check linking conflicts
* tests/headers.at (Several Headers): Link two glr2.cc parsers.
2021-09-12 14:00:55 +02:00
Akim Demaille d432079f8a glr2.cc: move strong_index_alias into the unnamed namespace
* data/skeletons/glr2.cc: here.
2021-09-12 14:00:55 +02:00
Akim Demaille b6ac175a1c glr2.cc: use only symbol_kind_type, not yysymbol_kind_t
* data/skeletons/glr2.cc: here.
And prefer the unnamed namespace to static.
2021-09-12 14:00:55 +02:00
Akim Demaille 5f90ef59a4 glr2.cc: prefer using, and remove useless type aliases
* data/skeletons/glr2.cc: here.
2021-09-12 14:00:55 +02:00
Akim Demaille 10ee04479f glr2.cc: put glr_state_set and glr_stack_item in unnamed namespace
* data/skeletons/glr2.cc: here.
2021-09-12 14:00:55 +02:00
Akim Demaille c09524cf8f glr2.cc: move state_stack into the unnamed namespace
* data/skeletons/glr2.cc: here.
Prefer `using` to `typedef`, this is C++11.
Use the type alias we introduced.
2021-09-12 14:00:55 +02:00
Akim Demaille 28152fc10a glr2.cc: style: clarify control flow
* data/skeletons/glr2.cc (yypreference): Be more functional-style.
2021-09-12 14:00:55 +02:00
Akim Demaille 9babd05a90 glr2.cc: move glr_stack and glr_state into the parser class
In order to be able to link several glr2.cc parser together, we cannot
have glr_stack and glr_state be in no namespace.  Putting them in the
unnamed namespace is not doable, since we need to fwd declare them in
the parser.  Putting them in the specified namespace is not enough
either, since some users would like to be able to put several parsers
in the same name, only differing by the class name.

* data/skeletons/glr2.cc (glr_state, glr_stack): Move into yy::parser.
2021-09-12 14:00:55 +02:00
Akim Demaille 3e94b12ddd glr2.cc: put create_state_set_index in unnamed namespace
* data/skeletons/glr2.cc: here.
2021-09-12 14:00:55 +02:00
Akim Demaille 7cb6de2533 glr2.cc: prefer unnamed namespace to 'static'
* data/skeletons/glr2.cc: here.
2021-09-12 14:00:55 +02:00
Akim Demaille 4ec4309cce glr2.cc: put semantic_option into an unnamed namespace
If we link several glr2.cc parsers together, we get linking failures
because of duplicate symbols.

* data/skeletons/glr2.cc (semantic_option::indexIn)
(semantic_option::next): Remove the useless overloads.
2021-09-12 14:00:50 +02:00
Akim Demaille ca96df89b2 glr2.cc: don't publish YY_EXCEPTIONS
We don't need them in the header file.

* data/skeletons/glr2.cc (YY_EXCEPTIONS): Define only in the
implementation file.
* tests/headers.at (Several Parsers): Also check glr2.cc.
2021-09-12 12:03:58 +02:00
Akim Demaille 2142e59155 c++: demonstrate custom error messages in the examples
Let's use c++/glr to demonstrate custom error messages in C++ (not
just in glr2.cc).

* examples/c++/glr/c++-types.yy (report_syntax_error): New.
* examples/c++/glr/c++-types.test: Adjust.
* examples/c/bistromathic/parse.y: Comment changes.
* tests/local.at (AT_YYERROR_DEFINE(c++)): Use a nicer way to print
the lookakead's name.
2021-09-12 12:03:58 +02:00
Akim Demaille a75072476e glr2.cc: custom error messages
Reported by Tom Shields <[email protected]>.
<https://lists.gnu.org/r/bug-bison/2021-08/msg00003.html>

* data/skeletons/glr2.cc (context): New.
Use it to generate the error messages.
Add support for custom error messages.
* tests/calc.at: Check support for custom error messages.
2021-09-12 12:03:58 +02:00
Akim Demaille 7c47598d4f glr2.cc: start the transition to using symbol_type
Currently glr2.cc uses three variables/struct members to denote the
symbols' kind (or state), value and location.  lalr1.cc has two types
for "complete" symbols: symbol_type and stack_symbol_type.  Let's use
that model in glr2.cc too.

For a start use yyla (a symbol_type) to denote the lookahead, instead
of the triple yytoken, yylval and yylloc.  This will make easier the
introduction of the "context" subclass, used in parse.error=custom.

It simplifies the code in several places.  For instance from:

    symbol_kind_type yytoken_current = this->yytoken;]b4_variant_if([[
    value_type yylval_current;
    ]b4_symbol_variant([this->yytoken],
                       [yylval_current], [move], [this->yylval])], [[
    value_type yylval_current = this->yylval;]])[]b4_locations_if([
    location_type yylloc_current = this->yylloc;])[

to:

    symbol_type yyla_current = std::move (this->yyla);

* data/skeletons/glr2.cc (yytoken, yylval, yylloc): Replace by...
(yyla): this.
Adjust all dependencies.
(yyloc_default): Remove, unused.
* tests/c++.at, tests/glr-regression.at, tests/types.at: C++11 is
required for glr2.cc.
Adjust to changes in glr2.cc.
2021-09-12 12:03:58 +02:00
Akim Demaille fdaedc780a c++: add move assignments to the symbol type
This will be used in glr2.cc, which requires C++11.

* data/skeletons/c++.m4 (basic_symbol, by_kind): Add move assignment.
2021-09-12 12:03:58 +02:00
Akim Demaille 85f5e3b9d5 c++: avoid using the obsolete names
* data/skeletons/c++.m4: Don't define obsolete identifiers in the case
of glr2.cc.  Let's not start with technical debt.
* data/skeletons/glr2.cc, data/skeletons/lalr1.cc,
* data/skeletons/variant.hh: Use token_kind_type, not token_type.
* tests/c++.at, tests/local.at: Use value_type, not semantic_type.
2021-09-12 12:03:58 +02:00
Akim Demaille c3a4686a03 regen 2021-09-12 12:03:58 +02:00
Akim Demaille 9cdfd86cbb maint: post-release administrivia
* NEWS: Add header line for next release.
* .prev-version: Record previous version.
* cfg.mk (old_NEWS_hash): Auto-update.
2021-09-11 08:55:22 +02:00
28 changed files with 2745 additions and 2527 deletions
+1 -1
View File
@@ -1 +1 @@
3.8
3.8.1
+7
View File
@@ -1,5 +1,12 @@
GNU Bison NEWS
* Noteworthy changes in release 3.8.2 (2021-09-25) [stable]
Fixed portability issues of bison on Cygwin.
Improvements in glr2.cc: add support for custom error messages (`%define
parse.error custom`), allow linking several parsers together.
* Noteworthy changes in release 3.8.1 (2021-09-11) [stable]
The generation of prototypes for yylex and yyerror in Yacc mode is
+2 -1
View File
@@ -42,7 +42,7 @@ url_dir_list = \
# Tests not to run as part of "make distcheck".
local-checks-to-skip = \
sc_immutable_NEWS \
sc_prohibit_atoi_atof
sc_indent
# The local directory containing the checked-out copy of gnulib used in
# this release. Used solely to get a date for the "announcement" target.
@@ -164,6 +164,7 @@ $(call exclude,
prohibit_always-defined_macros=^data/skeletons/yacc.c$$ \
prohibit_always-defined_macros+=?|^src/(parse-gram.c|system.h)$$ \
prohibit_always-defined_macros+=?|^tests/regression.at$$ \
prohibit_atoi_atof=^(doc|etc|examples|tests)/ \
prohibit_doubled_word=^tests/named-refs.at$$ \
prohibit_magic_number_exit=^doc/bison.texi$$ \
prohibit_magic_number_exit+=?|^tests/(conflicts|regression).at$$ \
+5 -1
View File
@@ -409,8 +409,12 @@ b4_define_flag_if([yacc]) # Whether POSIX Yacc is emulated.
# b4_glr_cc_if([IF-TRUE], [IF-FALSE])
# -----------------------------------
m4_define([b4_glr_cc_if],
[m4_if(m4_bregexp(b4_skeleton, [^"glr.cc"$]), [0], $@)])
[m4_if(b4_skeleton, ["glr.cc"], $@)])
# b4_glr2_cc_if([IF-TRUE], [IF-FALSE])
# ------------------------------------
m4_define([b4_glr2_cc_if],
[m4_if(b4_skeleton, ["glr2.cc"], $@)])
## --------- ##
## Symbols. ##
+86 -30
View File
@@ -227,6 +227,8 @@ m4_define([b4_value_type_declare],
# Define the public types: token, semantic value, location, and so forth.
# Depending on %define token_lex, may be output in the header or source file.
m4_define([b4_public_types_declare],
[b4_glr2_cc_if(
[b4_value_type_declare],
[[#ifdef ]b4_api_PREFIX[STYPE
# ifdef __GNUC__
# pragma GCC message "bison: do not #define ]b4_api_PREFIX[STYPE in C++, use %define api.value.type"
@@ -236,7 +238,8 @@ m4_define([b4_public_types_declare],
]b4_value_type_declare[
#endif
/// Backward compatibility (Bison 3.8).
typedef value_type semantic_type;]b4_locations_if([
typedef value_type semantic_type;
]])[]b4_locations_if([
/// Symbol locations.
typedef b4_percent_define_get([[api.location.type]],
[[location]]) location_type;])[
@@ -262,16 +265,16 @@ m4_define([b4_public_types_declare],
/// Token kinds.
struct token
{
]b4_token_enums[
]b4_token_enums[]b4_glr2_cc_if([], [[
/// Backward compatibility alias (Bison 3.6).
typedef token_kind_type yytokentype;
typedef token_kind_type yytokentype;]])[
};
/// Token kind, as returned by yylex.
typedef token::yytokentype token_kind_type;
typedef token::token_kind_type token_kind_type;]b4_glr2_cc_if([], [[
/// Backward compatibility alias (Bison 3.6).
typedef token_kind_type token_type;
typedef token_kind_type token_type;]])[
/// Symbol kinds.
struct symbol_kind
@@ -305,7 +308,7 @@ m4_define([b4_symbol_type_define],
typedef Base super_type;
/// Default constructor.
basic_symbol ()
basic_symbol () YY_NOEXCEPT
: value ()]b4_locations_if([
, location ()])[
{}
@@ -343,6 +346,30 @@ m4_define([b4_symbol_type_define],
clear ();
}
]b4_glr2_cc_if([[
/// Copy assignment.
basic_symbol& operator= (const basic_symbol& that)
{
Base::operator= (that);]b4_variant_if([[
]b4_symbol_variant([this->kind ()], [value], [copy],
[that.value])], [[
value = that.value]])[;]b4_locations_if([[
location = that.location;]])[
return *this;
}
/// Move assignment.
basic_symbol& operator= (basic_symbol&& that)
{
Base::operator= (std::move (that));]b4_variant_if([[
]b4_symbol_variant([this->kind ()], [value], [move],
[std::move (that.value)])], [[
value = std::move (that.value)]])[;]b4_locations_if([[
location = std::move (that.location);]])[
return *this;
}
]])[
/// Destroy contents, and record that is empty.
void clear () YY_NOEXCEPT
{]b4_variant_if([[
@@ -383,10 +410,10 @@ m4_define([b4_symbol_type_define],
std::string name () const YY_NOEXCEPT
{
return ]b4_parser_class[::symbol_name (this->kind ());
}]])[
}]])[]b4_glr2_cc_if([], [[
/// Backward compatibility (Bison 3.6).
symbol_kind_type type_get () const YY_NOEXCEPT;
symbol_kind_type type_get () const YY_NOEXCEPT;]])[
/// Whether empty.
bool empty () const YY_NOEXCEPT;
@@ -410,22 +437,30 @@ m4_define([b4_symbol_type_define],
/// Type access provider for token (enum) based symbols.
struct by_kind
{
/// Default constructor.
by_kind ();
#if 201103L <= YY_CPLUSPLUS
/// Move constructor.
by_kind (by_kind&& that);
#endif
/// Copy constructor.
by_kind (const by_kind& that);
/// The symbol kind as needed by the constructor.
typedef token_kind_type kind_type;
/// Default constructor.
by_kind () YY_NOEXCEPT;
#if 201103L <= YY_CPLUSPLUS
/// Move constructor.
by_kind (by_kind&& that) YY_NOEXCEPT;
#endif
/// Copy constructor.
by_kind (const by_kind& that) YY_NOEXCEPT;
/// Constructor from (external) token numbers.
by_kind (kind_type t);
by_kind (kind_type t) YY_NOEXCEPT;
]b4_glr2_cc_if([[
/// Copy assignment.
by_kind& operator= (const by_kind& that);
/// Move assignment.
by_kind& operator= (by_kind&& that);
]])[
/// Record that this symbol is empty.
void clear () YY_NOEXCEPT;
@@ -435,18 +470,18 @@ m4_define([b4_symbol_type_define],
/// The (internal) type number (corresponding to \a type).
/// \a empty when empty.
symbol_kind_type kind () const YY_NOEXCEPT;
symbol_kind_type kind () const YY_NOEXCEPT;]b4_glr2_cc_if([], [[
/// Backward compatibility (Bison 3.6).
symbol_kind_type type_get () const YY_NOEXCEPT;
symbol_kind_type type_get () const YY_NOEXCEPT;]])[
/// The symbol kind.
/// \a ]b4_symbol_prefix[YYEMPTY when empty.
symbol_kind_type kind_;
};
};]b4_glr2_cc_if([], [[
/// Backward compatibility for a private implementation detail (Bison 3.6).
typedef by_kind by_type;
typedef by_kind by_type;]])[
/// "External" symbols: returned by the scanner.
struct symbol_type : basic_symbol<by_kind>
@@ -455,7 +490,7 @@ m4_define([b4_symbol_type_define],
typedef basic_symbol<by_kind> super_type;
/// Empty symbol.
symbol_type () {}
symbol_type () YY_NOEXCEPT {}
/// Constructor for valueless symbols, and symbols from each type.
]b4_type_foreach([_b4_symbol_constructor_define])dnl
@@ -501,12 +536,14 @@ m4_define([b4_public_types_define],
(void) v;
]b4_symbol_variant([this->kind ()], [value], [YY_MOVE_OR_COPY], [YY_MOVE (v)])])[}]])[
]b4_glr2_cc_if([], [[
template <typename Base>
]b4_parser_class[::symbol_kind_type
]b4_parser_class[::basic_symbol<Base>::type_get () const YY_NOEXCEPT
{
return this->kind ();
}
]])[
template <typename Base>
bool
@@ -527,26 +564,43 @@ m4_define([b4_public_types_define],
}
// by_kind.
]b4_inline([$1])b4_parser_class[::by_kind::by_kind ()
]b4_inline([$1])b4_parser_class[::by_kind::by_kind () YY_NOEXCEPT
: kind_ (]b4_symbol(empty, kind)[)
{}
#if 201103L <= YY_CPLUSPLUS
]b4_inline([$1])b4_parser_class[::by_kind::by_kind (by_kind&& that)
]b4_inline([$1])b4_parser_class[::by_kind::by_kind (by_kind&& that) YY_NOEXCEPT
: kind_ (that.kind_)
{
that.clear ();
}
#endif
]b4_inline([$1])b4_parser_class[::by_kind::by_kind (const by_kind& that)
]b4_inline([$1])b4_parser_class[::by_kind::by_kind (const by_kind& that) YY_NOEXCEPT
: kind_ (that.kind_)
{}
]b4_inline([$1])b4_parser_class[::by_kind::by_kind (token_kind_type t)
]b4_inline([$1])b4_parser_class[::by_kind::by_kind (token_kind_type t) YY_NOEXCEPT
: kind_ (yytranslate_ (t))
{}
]b4_glr2_cc_if([[
]b4_inline([$1])]b4_parser_class[::by_kind&
b4_parser_class[::by_kind::by_kind::operator= (const by_kind& that)
{
kind_ = that.kind_;
return *this;
}
]b4_inline([$1])]b4_parser_class[::by_kind&
b4_parser_class[::by_kind::by_kind::operator= (by_kind&& that)
{
kind_ = that.kind_;
that.clear ();
return *this;
}
]])[
]b4_inline([$1])[void
]b4_parser_class[::by_kind::clear () YY_NOEXCEPT
{
@@ -566,11 +620,13 @@ m4_define([b4_public_types_define],
return kind_;
}
]b4_glr2_cc_if([], [[
]b4_inline([$1])[]b4_parser_class[::symbol_kind_type
]b4_parser_class[::by_kind::type_get () const YY_NOEXCEPT
{
return this->kind ();
}
]])[
]])
@@ -587,7 +643,7 @@ m4_define([b4_token_constructor_define], [])
# sometimes in the cc file.
m4_define([b4_yytranslate_define],
[ b4_inline([$1])b4_parser_class[::symbol_kind_type
]b4_parser_class[::yytranslate_ (int t)
]b4_parser_class[::yytranslate_ (int t) YY_NOEXCEPT
{
]b4_api_token_raw_if(
[[ return static_cast<symbol_kind_type> (t);]],
+2501 -2438
View File
File diff suppressed because it is too large Load Diff
+11 -11
View File
@@ -325,19 +325,19 @@ m4_define([b4_shared_declarations],
/// Whether the given \c yypact_ value indicates a defaulted state.
/// \param yyvalue the value to check
static bool yy_pact_value_is_default_ (int yyvalue);
static bool yy_pact_value_is_default_ (int yyvalue) YY_NOEXCEPT;
/// Whether the given \c yytable_ value indicates a syntax error.
/// \param yyvalue the value to check
static bool yy_table_value_is_error_ (int yyvalue);
static bool yy_table_value_is_error_ (int yyvalue) YY_NOEXCEPT;
static const ]b4_int_type(b4_pact_ninf, b4_pact_ninf)[ yypact_ninf_;
static const ]b4_int_type(b4_table_ninf, b4_table_ninf)[ yytable_ninf_;
/// Convert a scanner token kind \a t to a symbol kind.
/// In theory \a t should be a token_kind_type, but character literals
/// are valid, yet not members of the token_type enum.
static symbol_kind_type yytranslate_ (int t);
/// are valid, yet not members of the token_kind_type enum.
static symbol_kind_type yytranslate_ (int t) YY_NOEXCEPT;
]b4_parse_error_bmatch(
[simple],
@@ -474,7 +474,7 @@ m4_define([b4_shared_declarations],
void yypush_ (const char* m, state_type s, YY_MOVE_REF (symbol_type) sym);
/// Pop \a n symbols from the stack.
void yypop_ (int n = 1);
void yypop_ (int n = 1) YY_NOEXCEPT;
/// Constants.
enum
@@ -637,9 +637,9 @@ m4_if(b4_prefix, [yy], [],
]b4_parser_class[::syntax_error::~syntax_error () YY_NOEXCEPT YY_NOTHROW
{}
/*---------------.
| symbol kinds. |
`---------------*/
/*---------.
| symbol. |
`---------*/
]b4_token_ctor_if([], [b4_public_types_define([cc])])[
@@ -779,7 +779,7 @@ m4_if(b4_prefix, [yy], [],
}
void
]b4_parser_class[::yypop_ (int n)
]b4_parser_class[::yypop_ (int n) YY_NOEXCEPT
{
yystack_.pop (n);
}
@@ -822,13 +822,13 @@ m4_if(b4_prefix, [yy], [],
}
bool
]b4_parser_class[::yy_pact_value_is_default_ (int yyvalue)
]b4_parser_class[::yy_pact_value_is_default_ (int yyvalue) YY_NOEXCEPT
{
return yyvalue == yypact_ninf_;
}
bool
]b4_parser_class[::yy_table_value_is_error_ (int yyvalue)
]b4_parser_class[::yy_table_value_is_error_ (int yyvalue) YY_NOEXCEPT
{
return yyvalue == yytable_ninf_;
}
+2 -2
View File
@@ -37,7 +37,7 @@ m4_define([b4_stack_define],
typedef typename S::size_type size_type;
typedef typename std::ptrdiff_t index_type;
stack (size_type n = 200)
stack (size_type n = 200) YY_NOEXCEPT
: seq_ (n)
{}
@@ -116,7 +116,7 @@ m4_define([b4_stack_define],
class slice
{
public:
slice (const stack& stack, index_type range)
slice (const stack& stack, index_type range) YY_NOEXCEPT
: stack_ (stack)
, range_ (range)
{}
+2 -2
View File
@@ -470,7 +470,7 @@ m4_define([_b4_symbol_constructor_define],
b4_symbol_if([$1], [has_type],
[b4_symbol([$1], [type]) v]),
b4_locations_if([location_type l]))[)
: super_type (]b4_join([token_type (tok)],
: super_type (]b4_join([token_kind_type (tok)],
b4_symbol_if([$1], [has_type], [std::move (v)]),
b4_locations_if([std::move (l)]))[)
#else
@@ -479,7 +479,7 @@ m4_define([_b4_symbol_constructor_define],
b4_symbol_if([$1], [has_type],
[const b4_symbol([$1], [type])& v]),
b4_locations_if([const location_type& l]))[)
: super_type (]b4_join([token_type (tok)],
: super_type (]b4_join([token_kind_type (tok)],
b4_symbol_if([$1], [has_type], [v]),
b4_locations_if([l]))[)
#endif
+9
View File
@@ -39,6 +39,15 @@ examples.
Extracted from the documentation: [A Complete C++
Example](https://www.gnu.org/software/bison/manual/html_node/A-Complete-C_002b_002b-Example.html).
## glr
This example demonstrates the use of GLR parsers to handle (local)
ambiguities in the C++ language. See the node "Merging GLR Parses" in
Bison's documentation.
It uses (Bison) variants to store objects as semantic values. It also
demonstrates custom error messages in C++.
<!---
Local Variables:
+3
View File
@@ -4,6 +4,9 @@ This example demonstrates the use of GLR parsers to handle (local)
ambiguities in the C++ language. See the node "Merging GLR Parses" in
Bison's documentation.
It uses (Bison) variants to store objects as semantic values. It also
demonstrates custom error messages in C++.
<!---
Local Variables:
fill-column: 76
+1 -1
View File
@@ -47,4 +47,4 @@ run 0 "\
5.0-13: <OR>(<init-declare>(T, y, +(z, q)), =(<cast>(y, T), +(z, q)))
7.0-15: <error>
9.0-5: +(z, q)
err: 7.5: syntax error, unexpected identifier, expecting = or + or )"
err: 7.5: syntax error on token identifier (expected = or + or ))"
+40 -3
View File
@@ -27,8 +27,8 @@
%locations
%debug
// Nice error messages with details.
%define parse.error detailed
// Custom error messages.
%define parse.error custom
%code requires
{
@@ -44,9 +44,11 @@
#include <fstream>
#include <cstring>
// Merge two semantic values.
static Node
stmt_merge (const Node& x0, const Node& x1);
// Fetch a token.
static yy::parser::symbol_type
yylex ();
}
@@ -100,13 +102,41 @@ declarator
std::istream* input = nullptr;
yy::parser::location_type loc;
// An error reporting function.
/*---------.
| Parser. |
`---------*/
// Generate a custom error message.
void
yy::parser::report_syntax_error (const context& ctx) const
{
std::cerr << ctx.location () << ": syntax error";
if (!ctx.lookahead ().empty ())
std::cerr << " on token " << ctx.lookahead ().name ();
{
enum { TOKENMAX = 10 };
symbol_kind_type expected[TOKENMAX];
int n = ctx.expected_tokens (expected, TOKENMAX);
if (0 < n)
{
for (int i = 0; i < n; ++i)
std::cerr << (i == 0 ? " (expected " : " or ")
<< symbol_name (expected[i]);
std::cerr << ')';
}
}
std::cerr << '\n';
}
// Report the error to the user.
void
yy::parser::error (const location_type& l, const std::string& m)
{
std::cerr << l << ": " << m << '\n';
}
// Fetch the next token.
static yy::parser::symbol_type
yylex ()
{
@@ -168,12 +198,19 @@ yylex ()
}
}
// Merge two semantic values as an AST including both alternatives.
static Node
stmt_merge (const Node& x0, const Node& x1)
{
return Nterm ("<OR>", x0, x1);
}
/*-------.
| Main. |
`-------*/
// Parse `file` using parser `parse`.
int
process (yy::parser& parse, const std::string& file)
{
+3 -2
View File
@@ -465,8 +465,9 @@ yyreport_syntax_error (const yypcontext_t *ctx, const user_context *uctx)
}
// Called by yyparse on error.
void yyerror (const YYLTYPE *loc, const user_context *uctx, char const *format, ...)
// Called by yyparse on errors to report the error to the user.
void
yyerror (const YYLTYPE *loc, const user_context *uctx, char const *format, ...)
{
if (uctx->silent)
return;
+1 -1
Submodule gnulib updated: 964ce0a92b...7818455627
+1
View File
@@ -362,6 +362,7 @@
/stat-w32.c
/stat-w32.h
/stat.c
/stdalign.in.h
/stdbool.h
/stdbool.in.h
/stddef.h
+1
View File
@@ -200,6 +200,7 @@
/stat-time.m4
/stat.m4
/std-gnu11.m4
/stdalign.m4
/stdbool.m4
/stddef_h.m4
/stdint.m4
+11 -5
View File
@@ -512,22 +512,28 @@ location_empty (location loc)
&& !loc.end.file && !loc.end.line && !loc.end.column;
}
static inline int
str_to_int (const char *s)
{
long l = strtol (s, NULL, 10);
return l < 0 ? -1 : l <= INT_MAX ? l : INT_MAX;
}
void
boundary_set_from_string (boundary *bound, char *str)
{
/* Must search in reverse since the file name field may contain '.'
or ':'. */
/* Search backwards: the file name may contain '.' or ':'. */
char *at = strrchr (str, '@');
if (at)
{
*at = '\0';
bound->byte = atoi (at+1);
bound->byte = str_to_int (at + 1);
}
{
char *dot = strrchr (str, '.');
aver (dot);
*dot = '\0';
bound->column = atoi (dot+1);
bound->column = str_to_int (dot + 1);
if (!at)
bound->byte = bound->column;
}
@@ -535,7 +541,7 @@ boundary_set_from_string (boundary *bound, char *str)
char *colon = strrchr (str, ':');
aver (colon);
*colon = '\0';
bound->line = atoi (colon+1);
bound->line = str_to_int (colon + 1);
}
bound->file = uniqstr_new (str);
}
+3 -2
View File
@@ -146,8 +146,9 @@ location_cmp (location a, location b)
/* Whether this is the empty location. */
bool location_empty (location loc);
/* STR must be formatted as 'file:line.column@byte' or 'file:line.column',
it will be modified. */
/* STR must be formatted as 'file:line.column@byte' or 'file:line.column'.
It may be '<command line>:3.-1@-1', with -1 to denote no-column/no-byte.
STR will be modified. */
void boundary_set_from_string (boundary *bound, char *str);
#endif /* ! defined LOCATION_H_ */
+2 -1
View File
@@ -517,8 +517,9 @@ muscle_percent_define_insert (char const *var, location variable_loc,
char const *current_value = muscle_find_const (name);
if (current_value)
{
long l = strtol (muscle_find_const (how_name), NULL, 10);
muscle_percent_define_how how_old
= atoi (muscle_find_const (how_name));
= 0 <= l && l <= INT_MAX ? l : INT_MAX;
if (how_old == MUSCLE_PERCENT_DEFINE_F)
goto end;
/* If assigning the same value, make it a warning. */
+3 -3
View File
@@ -1,4 +1,4 @@
/* A Bison parser, made by GNU Bison 3.8. */
/* A Bison parser, made by GNU Bison 3.8.1. */
/* Bison implementation for Yacc-like parsers in C
@@ -46,10 +46,10 @@
USER NAME SPACE" below. */
/* Identify Bison output, and Bison version. */
#define YYBISON 30800
#define YYBISON 30801
/* Bison version string. */
#define YYBISON_VERSION "3.8"
#define YYBISON_VERSION "3.8.1"
/* Skeleton name. */
#define YYSKELETON_NAME "yacc.c"
+1 -1
View File
@@ -1,4 +1,4 @@
/* A Bison parser, made by GNU Bison 3.8. */
/* A Bison parser, made by GNU Bison 3.8.1. */
/* Bison interface for Yacc-like parsers in C
+3 -2
View File
@@ -969,7 +969,7 @@ AT_DATA_GRAMMAR([[input.yy]],
%code
{
#include <cstdlib>
int yylex (yy::parser::semantic_type *);
int yylex (yy::parser::value_type *);
}
%define parse.error verbose
@@ -1013,7 +1013,7 @@ AT_DATA_SOURCE([scan.cc],
// 'a': valid item, 's': syntax error, 'l': lexical error.
int
yylex (yy::parser::semantic_type *lval)
yylex (yy::parser::value_type *lval)
{
switch (int res = getchar ())
{
@@ -1031,6 +1031,7 @@ yylex (yy::parser::semantic_type *lval)
AT_BISON_CHECK([[-o input.cc input.yy]])
AT_FOR_EACH_CXX([
AT_GLR2_CC_IF([AT_REQUIRE_CXX_STD(11, [echo "$at_std not supported"; continue])])
AT_LANG_COMPILE([[input]], [[input.cc scan.cc]])
# Leave enough valid tokens to make sure we recovered from the
+5
View File
@@ -1398,6 +1398,7 @@ AT_CHECK_CALC_GLR([%define api.pure %locations])
AT_CHECK_CALC_GLR([%define parse.error verbose %locations])
AT_CHECK_CALC_GLR([%define parse.error custom %locations %header %name-prefix "calc" %verbose])
AT_CHECK_CALC_GLR([%define parse.error custom %locations %header %name-prefix "calc" %verbose %define api.pure])
AT_CHECK_CALC_GLR([%define parse.error detailed %locations %header %name-prefix "calc" %verbose])
AT_CHECK_CALC_GLR([%define parse.error verbose %locations %header %name-prefix "calc" %verbose])
@@ -1480,7 +1481,11 @@ AT_CHECK_CALC_GLR_CC([%define parse.error verbose %define api.prefix {calc} %ver
AT_CHECK_CALC_GLR_CC([%debug])
# parse.error.
AT_CHECK_CALC_GLR_CC([%define parse.error detailed %debug %name-prefix "calc" %verbose])
AT_CHECK_CALC_GLR_CC([%define parse.error verbose %debug %name-prefix "calc" %verbose])
AT_CHECK_CALC([%skeleton "glr2.cc" %define parse.error custom %debug %name-prefix "calc" %verbose]) # Only glr2.cc.
AT_CHECK_CALC_GLR_CC([%define parse.error verbose %debug %name-prefix "calc" %define api.token.prefix {TOK_} %verbose])
AT_CHECK_CALC_GLR_CC([%locations %header %define parse.error verbose %debug %name-prefix "calc" %verbose %parse-param {semantic_value *result}{int *count}{int *nerrs}])
+15 -11
View File
@@ -42,13 +42,12 @@ yyparse ()
# --------------------------
m4_define([AT_PRINT_LOOKAHEAD_DECLARE],
[AT_GLR2_CC_IF(
[[ static void
print_lookahead (int yytoken, ]AT_YYSTYPE[ *yylvalp, ]AT_YYLTYPE[ *yyllocp,
char const *reduction);
[[static void
print_lookahead (yy::parser::symbol_type yylookahead, char const *reduction);
#define PRINT_LOOKAHEAD(Msg) \
print_lookahead (yytoken, &yylval, &yylloc, Msg)
print_lookahead (yyla, Msg)
]],
[[ static void
[[static void
print_lookahead (int yychr, ]AT_YYSTYPE[ *yylvalp, ]AT_YYLTYPE[ *yyllocp,
char const *reduction);
#define PRINT_LOOKAHEAD(Msg) \
@@ -60,8 +59,7 @@ m4_define([AT_PRINT_LOOKAHEAD_DECLARE],
m4_define([AT_PRINT_LOOKAHEAD_DEFINE],
[AT_GLR2_CC_IF(
[[static void
print_lookahead (int yytoken, ]AT_YYSTYPE[ *yylvalp, ]AT_YYLTYPE[ *yyllocp,
char const *reduction)
print_lookahead (yy::parser::symbol_type yylookahead, char const *reduction)
]],
[[static void
print_lookahead (int yychr, ]AT_YYSTYPE[ *yylvalp, ]AT_YYLTYPE[ *yyllocp,
@@ -80,11 +78,12 @@ print_lookahead (int yychr, ]AT_YYSTYPE[ *yylvalp, ]AT_YYLTYPE[ *yyllocp,
// | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 117 | : '?';
// | ~~~~~
int yytoken = yylookahead.kind ();
int yychr
= yytoken == yy::parser::symbol_kind::S_YYEMPTY ? -2
: yytoken == yy::parser::symbol_kind::S_YYEOF ? 0
: yytoken == yy::parser::yytranslate_ ('a') ? 'a'
: yytoken == yy::parser::yytranslate_ ('b') ? 'b'
: yytoken == yy::parser::symbol_kind::S_3_a_ ? 'a'
: yytoken == yy::parser::symbol_kind::S_4_b_ ? 'b'
: '?';
]])[
printf ("%s:\n yychar=", reduction);
@@ -94,12 +93,17 @@ print_lookahead (int yychr, ]AT_YYSTYPE[ *yylvalp, ]AT_YYLTYPE[ *yyllocp,
printf ("YYEOF");
else
{
printf ("'%c', yylval='", yychr);
printf ("'%c', yylval='", yychr);]AT_GLR2_CC_IF([[
if (yylookahead.value.value > ' ')
printf ("%c", yylookahead.value.value);
printf ("', yylloc=(%d,%d),(%d,%d)",
yylookahead.location.]AT_FIRST_LINE[, yylookahead.location.]AT_FIRST_COLUMN[,
yylookahead.location.]AT_LAST_LINE[, yylookahead.location.]AT_LAST_COLUMN[);]], [[
if (yylvalp->value > ' ')
printf ("%c", yylvalp->value);
printf ("', yylloc=(%d,%d),(%d,%d)",
yyllocp->]AT_FIRST_LINE[, yyllocp->]AT_FIRST_COLUMN[,
yyllocp->]AT_LAST_LINE[, yyllocp->]AT_LAST_COLUMN[);
yyllocp->]AT_LAST_LINE[, yyllocp->]AT_LAST_COLUMN[);]])[
}
printf ("\n");
}
+15 -2
View File
@@ -241,6 +241,8 @@ exp:
| 'x' '9' { printf ("x9\n"); }
| 'x' 'a' { printf ("xa\n"); }
| 'x' 'b' { printf ("xb\n"); }
| 'x' 'c' { printf ("xc\n"); }
| 'x' 'd' { printf ("xd\n"); }
;
%%
@@ -279,6 +281,8 @@ extern "C"
#include "x9.hh"
#include "xa.hh"
#include "xb.hh"
#include "xc.hh"
#include "xd.hh"
#define RUN(S) \
do { \
@@ -305,6 +309,10 @@ main (void)
RUN(pa.parse());
xb_::parser pb;
RUN(pb.parse());
xc_::parser pc;
RUN(pc.parse());
xd_::parser pd;
RUN(pd.parse());
return 0;
}
]])# main.cc
@@ -320,7 +328,8 @@ AT_TEST([x8], [%define api.pure %define api.push-pull both])
AT_TEST([x9], [%locations %code requires {#include "location.hh"} %define api.location.type {::x5_::location} %debug %language "c++"])
AT_TEST([xa], [%locations %code requires {#include "location.hh"} %define api.location.type {::x5_::location} %language "c++" %define api.value.type variant])
AT_TEST([xb], [%locations %define api.location.file none %language "c++" %define api.value.type variant])
#AT_TEST([x5], [%locations %language "c++" %glr-parser])
AT_TEST([xc], [%locations %code requires {#include "location.hh"} %define api.location.type {::x5_::location} %skeleton "glr2.cc"])
AT_TEST([xd], [%locations %define api.location.file none %skeleton "glr2.cc"])
# Check that api.prefix works properly:
#
@@ -377,7 +386,11 @@ AT_PERL_CHECK([[-n -0777 -e '
# Do this late, so that other checks have been performed.
AT_SKIP_IF_CANNOT_LINK_C_AND_CXX
AT_COMPILE_CXX([parser], [[x[1-9a-b].o -DCC_IS_CXX=$CC_IS_CXX main.cc]])
# The header generated by glr2.cc requires C++11. Push the options to
# prepare AT_COMPILE_CXX.
AT_BISON_OPTION_PUSHDEFS([%skeleton "glr2.cc"])
AT_COMPILE_CXX([parser], [[x[1-9a-d].o -DCC_IS_CXX=$CC_IS_CXX main.cc]])
AT_BISON_OPTION_POPDEFS
AT_PARSER_CHECK([parser], [0], [[expout]])
m4_popdef([AT_TEST])
+10 -7
View File
@@ -378,7 +378,7 @@ m4_pushdef([AT_TOKEN],
m4_pushdef([AT_YYSTYPE],
[AT_CXX_IF([AT_NAMESPACE[::]AT_PARSER_CLASS[::semantic_type]],
[AT_CXX_IF([AT_NAMESPACE[::]AT_PARSER_CLASS[::value_type]],
[AT_API_PREFIX[STYPE]])])
m4_pushdef([AT_YYLTYPE],
[AT_CXX_IF([AT_NAMESPACE[::]AT_PARSER_CLASS[::location_type]],
@@ -823,11 +823,8 @@ void
++*nerrs;]])[]AT_LOCATION_IF([[
std::cerr << ctx.location () << ": ";]])[
std::cerr << "syntax error";
{
symbol_kind_type la = ctx.token ();
if (la != symbol_kind::S_YYEMPTY)
std::cerr << " on token [" << symbol_name (la) << ']';
}
if (!ctx.lookahead ().empty ())
std::cerr << " on token [" << ctx.lookahead ().name () << ']';
{
enum { TOKENMAX = 10 };
symbol_kind_type expected[TOKENMAX];
@@ -1361,13 +1358,19 @@ AT_CHECK(m4_join([ ],
# If OUTPUT does not contain '.', assume that we are linking too,
# otherwise pass "-c"; this is a hack. The default SOURCES is OUTPUT
# with trailing ".o" removed, and ".cc" appended.
#
# glr2.cc require C++11.
m4_define([AT_COMPILE_CXX],
[AT_KEYWORDS([c++])
AT_SKIP_IF([[! $BISON_CXX_WORKS]])
m4_ifdef([AT_GLR2_CC_IF],
[AT_GLR2_CC_IF([AT_SKIP_IF([[test x"$CXX11_CXXFLAGS" == x]])])])
AT_CHECK(m4_join([ ],
[$CXX $CXXFLAGS $CPPFLAGS $3],
[$CXX],
[$CPPFLAGS],
[m4_ifdef([AT_GLR2_CC_IF], [AT_GLR2_CC_IF([$CXX11_CXXFLAGS])])],
[$CXXFLAGS],
[$3],
[m4_bmatch([$1], [[.]], [-c], [$LDFLAGS])],
[-o $1],
[m4_default([$2], [m4_bpatsubst([$1], [\.o$]).cc])],
+1
View File
@@ -105,6 +105,7 @@ start: $3;
]])
AT_LANG_FOR_EACH_STD([
AT_GLR2_CC_IF([AT_REQUIRE_CXX_STD(11, [echo "$at_std not supported"; continue])])
$7
AT_FULL_COMPILE([[test]])
AT_PARSER_CHECK([[test]], 0, [[$6