Merge branch 'maint'

* maint:
  c++: shorten the assertions that check whether tokens are correct
  c++: don't glue functions together
  lalr1.cc: YY_ASSERT should use api.prefix
  c++: don't use YY_ASSERT at all if parse.assert is disabled
  c++: style: follow the Bison m4 quoting pattern
  yacc.c: provide the Bison version as an integral macro
  regen
  style: make conversion of version string to int public
  %require: accept version numbers with three parts ("3.7.4")
  yacc.c: fix #definition of YYEMPTY
  gnulib: update
  doc: fix incorrect section title
  doc: minor grammar fixes in counterexamples section
This commit is contained in:
Akim Demaille
2020-11-13 07:01:19 +01:00
21 changed files with 314 additions and 165 deletions

27
NEWS
View File

@@ -54,6 +54,33 @@ GNU Bison NEWS
The Java skeleton (lalr1.java) now supports LAC, via the %define variable
parse.lac.
* Noteworthy changes in release ?.? (????-??-??) [?]
** Bug fixes
*** Bug fixes in yacc.c
In Yacc mode, all the tokens are defined twice: once as an enum, and then
as a macro. YYEMPTY was missing its macro.
*** Bug fixes in lalr1.cc
The lalr1.cc skeleton used to emit internal assertions (using YY_ASSERT)
even when the `parse.assert` %define variable is not enabled. It no
longer does.
The private internal macro YY_ASSERT now obeys the `api.prefix` %define
variable.
When there is a very large number of tokens, some assertions could be long
enough to hit arbitrary limits in Visual C++. They have been rewritten to
work around this limitation.
** Changes
The YYBISON macro in generated "regular C parsers" (from the "yacc.c"
skeleton) used to be defined to 1. It is now defined to the version of
Bison as an integer (e.g., 30704 for version 3.7.4).
* Noteworthy changes in release 3.7.3 (2020-10-13) [stable]

View File

@@ -49,7 +49,7 @@ m4_define([m4_shift4], [m4_shift(m4_shift(m4_shift(m4_shift($@))))])
# b4_generated_by
# ---------------
m4_define([b4_generated_by],
[b4_comment([A Bison parser, made by GNU Bison b4_version.])
[b4_comment([A Bison parser, made by GNU Bison b4_version_string.])
])
# b4_copyright(TITLE, [YEARS])
@@ -651,11 +651,11 @@ m4_define([_b4_type_action],
])])
# b4_type_foreach(MACRO)
# ----------------------
# b4_type_foreach(MACRO, [SEP])
# -----------------------------
# Invoke MACRO(SYMBOL-NUMS) for each set of SYMBOL-NUMS for each type set.
m4_define([b4_type_foreach],
[m4_map([$1], m4_defn([b4_type_names]))])
[m4_map_sep([$1], [$2], m4_defn([b4_type_names]))])

View File

@@ -320,8 +320,9 @@ m4_define([b4_symbol_type_define],
/// Copy constructor.
basic_symbol (const basic_symbol& that);]b4_variant_if([[
/// Constructor for valueless symbols, and symbols from each type.
]b4_type_foreach([b4_basic_symbol_constructor_define])], [[
/// Constructors for typed symbols.
]b4_type_foreach([b4_basic_symbol_constructor_define], [
])], [[
/// Constructor for valueless symbols.
basic_symbol (typename Base::kind_type t]b4_locations_if([,
YY_MOVE_REF (location_type) l])[);

View File

@@ -58,11 +58,11 @@ m4_define([b4_cpp_guard_close],
# b4_pull_flag if they use the values of the %define variables api.pure or
# api.push-pull.
m4_define([b4_identification],
[[/* Identify Bison output. */
#define YYBISON 1
[[/* Identify Bison output, and Bison version. */
#define YYBISON ]b4_version[
/* Bison version. */
#define YYBISON_VERSION "]b4_version["
/* Bison version string. */
#define YYBISON_VERSION "]b4_version_string["
/* Skeleton name. */
#define YYSKELETON_NAME ]b4_skeleton[]m4_ifdef([b4_pure_flag], [[
@@ -520,10 +520,11 @@ m4_define([b4_token_define],
# ----------------
# Output the definition of the tokens.
m4_define([b4_token_defines],
[b4_any_token_visible_if([/* Token kinds. */
m4_join([
[[/* Token kinds. */
#define ]b4_symbol([-2], [id])[ -2
]m4_join([
], b4_symbol_map([b4_token_define]))
])])
])
# b4_token_enum(TOKEN-NUM)

View File

@@ -122,12 +122,12 @@ m4_define([b4_location_type_if],
# b4_identification
# -----------------
m4_define([b4_identification],
[/** Version number for the Bison executable that generated this parser. */
public static immutable string yy_bison_version = "b4_version";
[[/** Version number for the Bison executable that generated this parser. */
public static immutable string yy_bison_version = "]b4_version_string[";
/** Name of the skeleton that generated this parser. */
public static immutable string yy_bison_skeleton = b4_skeleton;
])
public static immutable string yy_bison_skeleton = ]b4_skeleton[;
]])
## ------------ ##

View File

@@ -71,12 +71,12 @@ m4_define([b4_lexer_if],
# b4_identification
# -----------------
m4_define([b4_identification],
[ /** Version number for the Bison executable that generated this parser. */
public static final String bisonVersion = "b4_version";
[[ /** Version number for the Bison executable that generated this parser. */
public static final String bisonVersion = "]b4_version_string[";
/** Name of the skeleton that generated this parser. */
public static final String bisonSkeleton = b4_skeleton;
])
public static final String bisonSkeleton = ]b4_skeleton[;
]])
## ------------ ##

View File

@@ -22,7 +22,7 @@ m4_pushdef([b4_copyright_years],
# b4_position_file
# ----------------
# Name of the file containing the position class, if we want this file.
b4_header_if([b4_required_version_if([302], [],
b4_header_if([b4_required_version_if([30200], [],
[m4_define([b4_position_file], [position.hh])])])])

View File

@@ -19,7 +19,7 @@
# b4_stack_file
# -------------
# Name of the file containing the stack class, if we want this file.
b4_header_if([b4_required_version_if([302], [],
b4_header_if([b4_required_version_if([30200], [],
[m4_define([b4_stack_file], [stack.hh])])])

View File

@@ -20,6 +20,13 @@
## variant. ##
## --------- ##
# b4_assert
# ---------
# The name of YY_ASSERT.
m4_define([b4_assert],
[b4_api_PREFIX[]_ASSERT])
# b4_symbol_variant(YYTYPE, YYVAL, ACTION, [ARGS])
# ------------------------------------------------
# Run some ACTION ("build", or "destroy") on YYVAL of symbol type
@@ -71,12 +78,12 @@ m4_map([ b4_symbol_tag_comment], [$@])dnl
# -------------------
# The needed includes for variants support.
m4_define([b4_variant_includes],
[b4_parse_assert_if([[#include <typeinfo>]])[
#ifndef YY_ASSERT
[b4_parse_assert_if([[#include <typeinfo>
#ifndef ]b4_assert[
# include <cassert>
# define YY_ASSERT assert
# define ]b4_assert[ assert
#endif
]])
]])])
@@ -110,8 +117,8 @@ m4_define([b4_value_type_declare],
template <typename T>
semantic_type (YY_RVREF (T) t)]b4_parse_assert_if([
: yytypeid_ (&typeid (T))])[
{
YY_ASSERT (sizeof (T) <= size);
{]b4_parse_assert_if([[
]b4_assert[ (sizeof (T) <= size);]])[
new (yyas_<T> ()) T (YY_MOVE (t));
}
@@ -125,7 +132,7 @@ m4_define([b4_value_type_declare],
/// Destruction, allowed only if empty.
~semantic_type () YY_NOEXCEPT
{]b4_parse_assert_if([
YY_ASSERT (!yytypeid_);
]b4_assert[ (!yytypeid_);
])[}
# if 201103L <= YY_CPLUSPLUS
@@ -133,10 +140,10 @@ m4_define([b4_value_type_declare],
template <typename T, typename... U>
T&
emplace (U&&... u)
{]b4_parse_assert_if([
YY_ASSERT (!yytypeid_);
YY_ASSERT (sizeof (T) <= size);
yytypeid_ = & typeid (T);])[
{]b4_parse_assert_if([[
]b4_assert[ (!yytypeid_);
]b4_assert[ (sizeof (T) <= size);
yytypeid_ = & typeid (T);]])[
return *new (yyas_<T> ()) T (std::forward <U>(u)...);
}
# else
@@ -144,10 +151,10 @@ m4_define([b4_value_type_declare],
template <typename T>
T&
emplace ()
{]b4_parse_assert_if([
YY_ASSERT (!yytypeid_);
YY_ASSERT (sizeof (T) <= size);
yytypeid_ = & typeid (T);])[
{]b4_parse_assert_if([[
]b4_assert[ (!yytypeid_);
]b4_assert[ (sizeof (T) <= size);
yytypeid_ = & typeid (T);]])[
return *new (yyas_<T> ()) T ();
}
@@ -155,10 +162,10 @@ m4_define([b4_value_type_declare],
template <typename T>
T&
emplace (const T& t)
{]b4_parse_assert_if([
YY_ASSERT (!yytypeid_);
YY_ASSERT (sizeof (T) <= size);
yytypeid_ = & typeid (T);])[
{]b4_parse_assert_if([[
]b4_assert[ (!yytypeid_);
]b4_assert[ (sizeof (T) <= size);
yytypeid_ = & typeid (T);]])[
return *new (yyas_<T> ()) T (t);
}
# endif
@@ -185,10 +192,10 @@ m4_define([b4_value_type_declare],
template <typename T>
T&
as () YY_NOEXCEPT
{]b4_parse_assert_if([
YY_ASSERT (yytypeid_);
YY_ASSERT (*yytypeid_ == typeid (T));
YY_ASSERT (sizeof (T) <= size);])[
{]b4_parse_assert_if([[
]b4_assert[ (yytypeid_);
]b4_assert[ (*yytypeid_ == typeid (T));
]b4_assert[ (sizeof (T) <= size);]])[
return *yyas_<T> ();
}
@@ -196,10 +203,10 @@ m4_define([b4_value_type_declare],
template <typename T>
const T&
as () const YY_NOEXCEPT
{]b4_parse_assert_if([
YY_ASSERT (yytypeid_);
YY_ASSERT (*yytypeid_ == typeid (T));
YY_ASSERT (sizeof (T) <= size);])[
{]b4_parse_assert_if([[
]b4_assert[ (yytypeid_);
]b4_assert[ (*yytypeid_ == typeid (T));
]b4_assert[ (sizeof (T) <= size);]])[
return *yyas_<T> ();
}
@@ -214,9 +221,9 @@ m4_define([b4_value_type_declare],
template <typename T>
void
swap (self_type& that) YY_NOEXCEPT
{]b4_parse_assert_if([
YY_ASSERT (yytypeid_);
YY_ASSERT (*yytypeid_ == *that.yytypeid_);])[
{]b4_parse_assert_if([[
]b4_assert[ (yytypeid_);
]b4_assert[ (*yytypeid_ == *that.yytypeid_);]])[
std::swap (as<T> (), that.as<T> ());
}
@@ -388,11 +395,67 @@ m4_define([_b4_token_maker_define],
])])
m4_define([_b4_type_clause],
[b4_symbol_if([$1], [is_token],
[b4_symbol_if([$1], [has_id],
[tok == token::b4_symbol([$1], [id])],
[tok == b4_symbol([$1], [code])])])])
# b4_token_kind(SYMBOL-NUM)
# -------------------------
# Some tokens don't have an ID.
m4_define([b4_token_kind],
[b4_symbol_if([$1], [has_id],
[token::b4_symbol([$1], [id])],
[b4_symbol([$1], [code])])])
# _b4_tok_in(SYMBOL-NUM, ...)
# ---------------------------
# See b4_tok_in below. The SYMBOL-NUMs... are tokens only.
#
# We iterate over the tokens to group them by "range" of token numbers (not
# symbols numbers!).
#
# b4_fst is the start of that range.
# b4_prev is the previous value.
# b4_val is the current value.
# If b4_val is the successor of b4_prev in token numbers, update the latter,
# otherwise emit the code for range b4_fst .. b4_prev.
# $1 is also used as a terminator in the foreach, but it will not be printed.
#
m4_define([_b4_tok_in],
[m4_pushdef([b4_prev], [$1])dnl
m4_pushdef([b4_fst], [$1])dnl
m4_pushdef([b4_sep], [])dnl
m4_foreach([b4_val], m4_dquote(m4_shift($@, $1)),
[m4_if(b4_symbol(b4_val, [code]), m4_eval(b4_symbol(b4_prev, [code]) + 1), [],
[b4_sep[]m4_if(b4_fst, b4_prev,
[tok == b4_token_kind(b4_fst)],
[(b4_token_kind(b4_fst) <= tok && tok <= b4_token_kind(b4_prev))])[]dnl
m4_define([b4_fst], b4_val)dnl
m4_define([b4_sep], [
|| ])])dnl
m4_define([b4_prev], b4_val)])dnl
m4_popdef([b4_sep])dnl
m4_popdef([b4_fst])dnl
m4_popdef([b4_prev])dnl
])
# _b4_filter_tokens(SYMBOL-NUM, ...)
# ----------------------------------
# Expand as the list of tokens amongst SYMBOL-NUM.
m4_define([_b4_filter_tokens],
[m4_pushdef([b4_sep])dnl
m4_foreach([b4_val], [$@],
[b4_symbol_if(b4_val, [is_token], [b4_sep[]b4_val[]m4_define([b4_sep], [,])])])dnl
m4_popdef([b4_sep])dnl
])
# b4_tok_in(SYMBOL-NUM, ...)
# ---------------------------
# A C++ conditional that checks that `tok` is a member of this list of symbol
# numbers.
m4_define([b4_tok_in],
[_$0(_b4_filter_tokens($@))])
# _b4_token_constructor_define(SYMBOL-NUM...)
@@ -410,9 +473,6 @@ m4_define([_b4_token_constructor_define],
: super_type(]b4_join([token_type (tok)],
b4_symbol_if([$1], [has_type], [std::move (v)]),
b4_locations_if([std::move (l)]))[)
{
YY_ASSERT (]m4_join([ || ], m4_map_sep([_b4_type_clause], [, ], [$@]))[);
}
#else
symbol_type (]b4_join(
[int tok],
@@ -422,10 +482,10 @@ m4_define([_b4_token_constructor_define],
: super_type(]b4_join([token_type (tok)],
b4_symbol_if([$1], [has_type], [v]),
b4_locations_if([l]))[)
{
YY_ASSERT (]m4_join([ || ], m4_map_sep([_b4_type_clause], [, ], [$@]))[);
}
#endif
{]b4_parse_assert_if([[
]b4_assert[ (]b4_tok_in($@)[);
]])[}
]])])

View File

@@ -15837,6 +15837,12 @@ Macro to discard a value from the parser stack and fake a lookahead
token. @xref{Action Features}.
@end deffn
@deffn {Macro} YYBISON
The version of Bison as an integer, for instance 30704 for version 3.7.4.
Defined in @file{yacc.c} only. Before version 3.7.4, @code{YYBISON} was
defined to 1.
@end deffn
@deffn {Variable} yychar
External integer variable that contains the integer value of the
lookahead token. (In a pure parser, it is a local variable within

2
gnulib

Submodule gnulib updated: 160d5e7d9a...839ed059f4

View File

@@ -103,6 +103,8 @@ src_bison_SOURCES = \
src/state.h \
src/state-item.c \
src/state-item.h \
src/strversion.c \
src/strversion.h \
src/symlist.c \
src/symlist.h \
src/symtab.c \

View File

@@ -127,9 +127,6 @@ muscle_init (void)
muscle_table = hash_xinitialize (HT_INITIAL_CAPACITY, NULL, hash_muscle,
hash_compare_muscles, muscle_entry_free);
/* Version and input file. */
MUSCLE_INSERT_STRING ("version", VERSION);
}

View File

@@ -42,6 +42,7 @@
#include "scan-skel.h"
#include "symtab.h"
#include "tables.h"
#include "strversion.h"
static struct obstack format_obstack;
@@ -829,6 +830,9 @@ prepare (void)
char const *cp = getenv ("BISON_USE_PUSH_FOR_PULL");
bool use_push_for_pull_flag = cp && *cp && strtol (cp, 0, 10);
/* Versions. */
MUSCLE_INSERT_STRING ("version_string", VERSION);
MUSCLE_INSERT_INT ("version", strversion_to_int (VERSION));
MUSCLE_INSERT_INT ("required_version", required_version);
/* Flags. */

View File

@@ -1,4 +1,4 @@
/* A Bison parser, made by GNU Bison 3.7.2.67-44c6. */
/* A Bison parser, made by GNU Bison 3.7.3.118-d0ea7-dirty. */
/* Bison implementation for Yacc-like parsers in C
@@ -45,11 +45,11 @@
define necessary library symbols; they are noted "INFRINGES ON
USER NAME SPACE" below. */
/* Identify Bison output. */
#define YYBISON 1
/* Identify Bison output, and Bison version. */
#define YYBISON 30703
/* Bison version. */
#define YYBISON_VERSION "3.7.2.67-44c6"
/* Bison version string. */
#define YYBISON_VERSION "3.7.3.118-d0ea7-dirty"
/* Skeleton name. */
#define YYSKELETON_NAME "yacc.c"
@@ -220,8 +220,6 @@ typedef enum yysymbol_kind_t yysymbol_kind_t;
#include "system.h"
#include <c-ctype.h>
#include <errno.h>
#include <intprops.h>
#include <quotearg.h>
#include <vasnprintf.h>
#include <xmemdup0.h>
@@ -235,6 +233,7 @@ typedef enum yysymbol_kind_t yysymbol_kind_t;
#include "reader.h"
#include "scan-code.h"
#include "scan-gram.h"
#include "strversion.h"
/* Pretend to be at least that version, to check features published
in that version while developping it. */
@@ -647,19 +646,19 @@ union yyalloc
/* YYRLINE[YYN] -- Source line where rule number YYN was defined. */
static const yytype_int16 yyrline[] =
{
0, 311, 311, 320, 321, 325, 326, 332, 336, 341,
342, 343, 344, 345, 346, 351, 356, 357, 358, 359,
360, 361, 361, 362, 363, 364, 365, 366, 367, 368,
369, 373, 374, 383, 384, 388, 399, 403, 407, 415,
425, 426, 436, 437, 443, 456, 456, 461, 461, 466,
466, 471, 481, 482, 483, 484, 489, 490, 494, 495,
500, 501, 505, 506, 510, 511, 512, 525, 534, 538,
542, 550, 551, 555, 568, 569, 574, 575, 576, 594,
598, 602, 610, 612, 617, 624, 634, 638, 642, 650,
656, 669, 670, 676, 677, 678, 685, 685, 693, 694,
695, 700, 703, 705, 707, 709, 711, 713, 715, 717,
719, 724, 725, 734, 758, 759, 760, 761, 773, 775,
799, 804, 805, 810, 818, 819
0, 310, 310, 319, 320, 324, 325, 331, 335, 340,
341, 342, 343, 344, 345, 350, 355, 356, 357, 358,
359, 360, 360, 361, 362, 363, 364, 365, 366, 367,
368, 372, 373, 382, 383, 387, 398, 402, 406, 414,
424, 425, 435, 436, 442, 455, 455, 460, 460, 465,
465, 470, 480, 481, 482, 483, 488, 489, 493, 494,
499, 500, 504, 505, 509, 510, 511, 524, 533, 537,
541, 549, 550, 554, 567, 568, 573, 574, 575, 593,
597, 601, 609, 611, 616, 623, 633, 637, 641, 649,
655, 668, 669, 675, 676, 677, 684, 684, 692, 693,
694, 699, 702, 704, 706, 708, 710, 712, 714, 716,
718, 723, 724, 733, 757, 758, 759, 760, 772, 774,
798, 803, 804, 809, 817, 818
};
#endif
@@ -3063,41 +3062,11 @@ handle_pure_parser (location const *loc, char const *directive)
}
/* Convert VERSION into an int (MAJOR * 100 + MINOR). Return -1 on
errors.
Changes of behavior are only on minor version changes, so "3.0.5"
is the same as "3.0": 300. */
static int
str_to_version (char const *version)
{
IGNORE_TYPE_LIMITS_BEGIN
int res = 0;
errno = 0;
char *cp = NULL;
long major = strtol (version, &cp, 10);
if (errno || cp == version || *cp != '.' || major < 0
|| INT_MULTIPLY_WRAPV (major, 100, &res))
return -1;
++cp;
char *cp1 = NULL;
long minor = strtol (cp, &cp1, 10);
if (errno || cp1 == cp || (*cp1 != '\0' && *cp1 != '.')
|| ! (0 <= minor && minor < 100)
|| INT_ADD_WRAPV (minor, res, &res))
return -1;
IGNORE_TYPE_LIMITS_END
return res;
}
static void
handle_require (location const *loc, char const *version_quoted)
{
char *version = unquote (version_quoted);
required_version = str_to_version (version);
required_version = strversion_to_int (version);
if (required_version == -1)
{
complain (loc, complaint, _("invalid version requirement: %s"),

View File

@@ -1,4 +1,4 @@
/* A Bison parser, made by GNU Bison 3.7.2.67-44c6. */
/* A Bison parser, made by GNU Bison 3.7.3.118-d0ea7-dirty. */
/* Bison interface for Yacc-like parsers in C

View File

@@ -42,8 +42,6 @@
#include "system.h"
#include <c-ctype.h>
#include <errno.h>
#include <intprops.h>
#include <quotearg.h>
#include <vasnprintf.h>
#include <xmemdup0.h>
@@ -57,6 +55,7 @@
#include "reader.h"
#include "scan-code.h"
#include "scan-gram.h"
#include "strversion.h"
/* Pretend to be at least that version, to check features published
in that version while developping it. */
@@ -1053,41 +1052,11 @@ handle_pure_parser (location const *loc, char const *directive)
}
/* Convert VERSION into an int (MAJOR * 100 + MINOR). Return -1 on
errors.
Changes of behavior are only on minor version changes, so "3.0.5"
is the same as "3.0": 300. */
static int
str_to_version (char const *version)
{
IGNORE_TYPE_LIMITS_BEGIN
int res = 0;
errno = 0;
char *cp = NULL;
long major = strtol (version, &cp, 10);
if (errno || cp == version || *cp != '.' || major < 0
|| INT_MULTIPLY_WRAPV (major, 100, &res))
return -1;
++cp;
char *cp1 = NULL;
long minor = strtol (cp, &cp1, 10);
if (errno || cp1 == cp || (*cp1 != '\0' && *cp1 != '.')
|| ! (0 <= minor && minor < 100)
|| INT_ADD_WRAPV (minor, res, &res))
return -1;
IGNORE_TYPE_LIMITS_END
return res;
}
static void
handle_require (location const *loc, char const *version_quoted)
{
char *version = unquote (version_quoted);
required_version = str_to_version (version);
required_version = strversion_to_int (version);
if (required_version == -1)
{
complain (loc, complaint, _("invalid version requirement: %s"),

67
src/strversion.c Normal file
View File

@@ -0,0 +1,67 @@
/* Convert version string to int.
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 <config.h>
#include "system.h"
#include "strversion.h"
#include <errno.h>
#include <intprops.h>
int
strversion_to_int (char const *version)
{
IGNORE_TYPE_LIMITS_BEGIN
int res = 0;
errno = 0;
char *cp = NULL;
{
long major = strtol (version, &cp, 10);
if (errno || cp == version || *cp != '.' || major < 0
|| INT_MULTIPLY_WRAPV (major, 10000, &res))
return -1;
}
{
++cp;
char *prev = cp;
long minor = strtol (cp, &cp, 10);
if (errno || cp == prev || (*cp != '\0' && *cp != '.')
|| ! (0 <= minor && minor < 100)
|| INT_MULTIPLY_WRAPV (minor, 100, &minor)
|| INT_ADD_WRAPV (minor, res, &res))
return -1;
}
if (*cp == '.')
{
++cp;
char *prev = cp;
long micro = strtol (cp, &cp, 10);
if (errno || cp == prev || (*cp != '\0' && *cp != '.')
|| ! (0 <= micro && micro < 100)
|| INT_ADD_WRAPV (micro, res, &res))
return -1;
}
IGNORE_TYPE_LIMITS_END
return res;
}

28
src/strversion.h Normal file
View File

@@ -0,0 +1,28 @@
/* Convert version string to int.
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/>. */
#ifndef STRVERSION_H_
# define STRVERSION_H_
/* Convert VERSION into an int (MAJOR * 10000 + MINOR * 100 + MICRO).
E.g., "3.7.4" => 30704, "3.8" => 30800.
Return -1 on errors. */
int strversion_to_int (char const *version);
#endif

View File

@@ -203,17 +203,20 @@ AT_SETUP([Several parsers])
# Generate and compile to *.o. Make sure there is no (allowed) YY*
# nor yy* identifiers in the header after applying api.prefix. Check
# that headers can be compiled by a C++ compiler.
#
# They should all use parse.assert to make sure that we don't even
# conflict of YY_ASSERT.
m4_pushdef([AT_TEST],
[AT_BISON_OPTION_PUSHDEFS([%define api.prefix {$1_} $2])
[AT_BISON_OPTION_PUSHDEFS([%define api.prefix {$1_} %define parse.assert $2])
AT_DATA_GRAMMAR([$1.y],
[[%define api.prefix {$1_}
%define parse.assert
$2
%define parse.error verbose
%union
{
int integer;
}
%{
]AT_VARIANT_IF([],
[%union {int integer;}])[
%code {
#include <stdio.h> /* printf. */
]AT_PUSH_IF([[
#if defined __GNUC__ && (7 == __GNUC__ || 9 == __GNUC__)
@@ -222,8 +225,10 @@ $2
]])[
]AT_YYERROR_DECLARE[
]AT_YYLEX_DECLARE[
%}
}
%%
exp:
'x' '1' { printf ("x1\n"); }
| 'x' '2' { printf ("x2\n"); }
@@ -234,9 +239,12 @@ exp:
| 'x' '7' { printf ("x7\n"); }
| 'x' '8' { printf ("x8\n"); }
| 'x' '9' { printf ("x9\n"); }
| 'x' 'a' { printf ("xa\n"); }
| 'x' 'b' { printf ("xb\n"); }
;
%%
]AT_YYERROR_DEFINE[
]AT_YYLEX_DEFINE(["$1"])[
]])
@@ -269,6 +277,8 @@ extern "C"
#endif
#include "x5.hh"
#include "x9.hh"
#include "xa.hh"
#include "xb.hh"
#define RUN(S) \
do { \
@@ -291,6 +301,10 @@ main (void)
RUN(x8_parse());
x9_::parser p9;
RUN(p9.parse());
xa_::parser pa;
RUN(pa.parse());
xb_::parser pb;
RUN(pb.parse());
return 0;
}
]])# main.cc
@@ -303,7 +317,9 @@ AT_TEST([x5], [%locations %debug %language "c++"])
AT_TEST([x6], [%define api.pure])
AT_TEST([x7], [%define api.push-pull both])
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([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])
# Check that api.prefix works properly:
@@ -339,6 +355,8 @@ AT_PERL_CHECK([[-n -0777 -e '
|YY_NULLPTR
|YY_RVREF
|YY_\w+_INCLUDED
|FILE\ \*yyo # Function argument.
|const\ yylocp # Function argument.
)\b}{}gx;
while (/^(.*YY.*)$/gm)
{
@@ -356,7 +374,7 @@ 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-9].o -DCC_IS_CXX=$CC_IS_CXX main.cc]])
AT_COMPILE_CXX([parser], [[x[1-9a-b].o -DCC_IS_CXX=$CC_IS_CXX main.cc]])
AT_PARSER_CHECK([parser], [0], [[expout]])
m4_popdef([AT_TEST])

View File

@@ -366,7 +366,7 @@ AT_TOKEN_CTOR_IF(
[m4_pushdef([AT_LOC], [[(]AT_NAME_PREFIX[lloc)]])
m4_pushdef([AT_VAL], [[(]AT_NAME_PREFIX[lval)]])
m4_pushdef([AT_YYLEX_FORMALS], [])
m4_pushdef([AT_YYLEX_RETURN], [yy::parser::symbol_type])
m4_pushdef([AT_YYLEX_RETURN], [AT_NAMESPACE::parser::symbol_type])
m4_pushdef([AT_YYLEX_ARGS], [])
m4_pushdef([AT_USE_LEX_ARGS], [])
m4_pushdef([AT_YYLEX_PRE_FORMALS], [])