mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-08-09 02:35:15 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9beba1919c | ||
|
|
80ebbe7330 | ||
|
|
028df02a9f | ||
|
|
71dfc86d58 | ||
|
|
5c1069c7d8 | ||
|
|
3fc3ef658e | ||
|
|
dd6e78360a | ||
|
|
eeb5d6f11b | ||
|
|
70441b5ab1 | ||
|
|
7538d8dc1a | ||
|
|
b07b5ce423 | ||
|
|
157e91dcc6 | ||
|
|
b820718adf | ||
|
|
6e6e11795c | ||
|
|
6bfdf22c50 | ||
|
|
d432079f8a | ||
|
|
b6ac175a1c | ||
|
|
5f90ef59a4 | ||
|
|
10ee04479f | ||
|
|
c09524cf8f | ||
|
|
28152fc10a | ||
|
|
9babd05a90 | ||
|
|
3e94b12ddd | ||
|
|
7cb6de2533 | ||
|
|
4ec4309cce | ||
|
|
ca96df89b2 | ||
|
|
2142e59155 | ||
|
|
a75072476e | ||
|
|
7c47598d4f | ||
|
|
fdaedc780a | ||
|
|
85f5e3b9d5 | ||
|
|
c3a4686a03 | ||
|
|
9cdfd86cbb |
+1
-1
@@ -1 +1 @@
|
||||
3.8
|
||||
3.8.1
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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$$ \
|
||||
|
||||
@@ -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
@@ -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
File diff suppressed because it is too large
Load Diff
+11
-11
@@ -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_;
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
{}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 ))"
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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
@@ -362,6 +362,7 @@
|
||||
/stat-w32.c
|
||||
/stat-w32.h
|
||||
/stat.c
|
||||
/stdalign.in.h
|
||||
/stdbool.h
|
||||
/stdbool.in.h
|
||||
/stddef.h
|
||||
|
||||
@@ -200,6 +200,7 @@
|
||||
/stat-time.m4
|
||||
/stat.m4
|
||||
/std-gnu11.m4
|
||||
/stdalign.m4
|
||||
/stdbool.m4
|
||||
/stddef_h.m4
|
||||
/stdint.m4
|
||||
|
||||
+11
-5
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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])],
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user