diff --git a/CMakeLists.txt b/CMakeLists.txt
index b9da95c..cf657a6 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -12,6 +12,11 @@ if(CMAKE_BUILD_TYPE STREQUAL "Debug")
add_definitions(-D_DEBUG)
endif()
+# next line needed for compile in C (nor CPP) mode (ucrt headers bug)
+add_definitions(-Dinline=__inline)
+# next line needed for VS2017 only
+add_definitions(-Drestrict=__restrict)
+
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /W3 /MD /Od /Zi /EHsc")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /W3 /GL /Od /Oi /Gy /Zi /EHsc")
diff --git a/VS2017/common_lib/common_lib.vcxproj b/VS2017/common_lib/common_lib.vcxproj
index 141866e..5447a31 100644
--- a/VS2017/common_lib/common_lib.vcxproj
+++ b/VS2017/common_lib/common_lib.vcxproj
@@ -158,9 +158,15 @@
+
+
+
+
+
+
@@ -255,10 +261,12 @@
+
+
@@ -268,6 +276,7 @@
+
diff --git a/VS2017/common_lib/common_lib.vcxproj.filters b/VS2017/common_lib/common_lib.vcxproj.filters
index 63a1b32..836e466 100644
--- a/VS2017/common_lib/common_lib.vcxproj.filters
+++ b/VS2017/common_lib/common_lib.vcxproj.filters
@@ -117,9 +117,27 @@
misc
+
+ misc
+
+
+ misc
+
+
+ misc
+
misc
+
+ misc
+
+
+ misc
+
+
+ misc
+
misc
@@ -455,9 +473,15 @@
misc
+
+ misc
+
misc
+
+ misc
+
misc
@@ -485,7 +509,10 @@
misc
-
+
+ misc
+
+
misc
diff --git a/VS2019/common_lib/common_lib.vcxproj b/VS2019/common_lib/common_lib.vcxproj
index 5df585f..787746b 100644
--- a/VS2019/common_lib/common_lib.vcxproj
+++ b/VS2019/common_lib/common_lib.vcxproj
@@ -167,9 +167,15 @@
+
+
+
+
+
+
@@ -269,10 +275,12 @@
+
+
@@ -282,6 +290,7 @@
+
diff --git a/VS2019/common_lib/common_lib.vcxproj.filters b/VS2019/common_lib/common_lib.vcxproj.filters
index 4e0f056..ed7da81 100644
--- a/VS2019/common_lib/common_lib.vcxproj.filters
+++ b/VS2019/common_lib/common_lib.vcxproj.filters
@@ -117,9 +117,27 @@
misc
+
+ misc
+
+
+ misc
+
+
+ misc
+
misc
+
+ misc
+
+
+ misc
+
+
+ misc
+
misc
@@ -482,9 +500,15 @@
misc
+
+ misc
+
misc
+
+ misc
+
misc
@@ -512,6 +536,9 @@
misc
+
+ misc
+
misc
diff --git a/bison/data/README.md b/bison/data/README.md
index 50fbe52..09886ea 100644
--- a/bison/data/README.md
+++ b/bison/data/README.md
@@ -73,15 +73,29 @@ skeletons. If you are to write a new skeleton, please, implement them for
your language. Overall, be sure to follow the same patterns as the existing
skeletons.
+## Vocabulary
+
+We use "formal arguments", or "formals" for short, to denote the declared
+parameters of a function (e.g., `int argc, const char **argv`). Yes, this
+is somewhat contradictory with `param` in the `%param` directives.
+
+We use "effective arguments", or "args" for short, to denote the values
+passed in function calls (e.g., `argc, argv`).
+
## Symbols
### `b4_symbol(NUM, FIELD)`
In order to unify the handling of the various aspects of symbols (tag, type
name, whether terminal, etc.), bison.exe defines one macro per (token,
field), where field can `has_id`, `id`, etc.: see
-`prepare_symbols_definitions()` in `src/output.c`.
+`prepare_symbol_definitions()` in `src/output.c`.
-The macro `b4_symbol(NUM, FIELD)` gives access to the following FIELDS:
+NUM can be:
+- `empty` to denote the "empty" pseudo-symbol when it exists,
+- `eof`, `error`, or `undef`
+- a symbol number.
+
+FIELD can be:
- `has_id`: 0 or 1
Whether the symbol has an `id`.
@@ -142,11 +156,17 @@ The macro `b4_symbol(NUM, FIELD)` gives access to the following FIELDS:
When api.value.type=union, the generated name for the union member.
yytype_INT etc. for symbols that has_id, otherwise yytype_1 etc.
-- `type`
+- `type`: string
If it has a semantic value, its type tag, or, if variant are used,
its type.
In the case of api.value.type=union, type is the real type (e.g. int).
+- `slot`: string
+ If it has a semantic value, the name of the union member (i.e., bounces to
+ either `type_tag` or `type`). It would be better to fix our mess and
+ always use `type` for the true type of the member, and `type_tag` for the
+ name of the union member.
+
- `has_printer`: 0, 1
- `printer`: string
- `printer_file`: string
@@ -187,7 +207,7 @@ fill-column: 76
ispell-dictionary: "american"
End:
-Copyright (C) 2002, 2008-2015, 2018-2020 Free Software Foundation, Inc.
+Copyright (C) 2002, 2008-2015, 2018-2021 Free Software Foundation, Inc.
This file is part of GNU Bison.
@@ -202,6 +222,6 @@ 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 .
+along with this program. If not, see .
-->
diff --git a/bison/data/bison-default.css b/bison/data/bison-default.css
index 21e672d..aadaba1 100644
--- a/bison/data/bison-default.css
+++ b/bison/data/bison-default.css
@@ -1,5 +1,5 @@
/* Default styling rules for Bison when doing terminal output.
- Copyright (C) 2019-2020 Free Software Foundation, Inc.
+ Copyright (C) 2019-2021 Free Software Foundation, Inc.
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
diff --git a/bison/data/local.mk b/bison/data/local.mk
index 2110645..c51d287 100644
--- a/bison/data/local.mk
+++ b/bison/data/local.mk
@@ -1,4 +1,4 @@
-## Copyright (C) 2002, 2005-2015, 2018-2020 Free Software Foundation,
+## Copyright (C) 2002, 2005-2015, 2018-2021 Free Software Foundation,
## Inc.
## This program is free software: you can redistribute it and/or modify
@@ -12,7 +12,7 @@
## 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 .
+## along with this program. If not, see .
dist_pkgdata_DATA = \
data/README.md \
@@ -28,6 +28,7 @@ dist_skeletons_DATA = \
data/skeletons/c.m4 \
data/skeletons/glr.c \
data/skeletons/glr.cc \
+ data/skeletons/glr2.cc \
data/skeletons/java-skel.m4 \
data/skeletons/java.m4 \
data/skeletons/lalr1.cc \
@@ -40,7 +41,6 @@ dist_skeletons_DATA = \
# Experimental support for the D language.
dist_skeletons_DATA += \
- data/skeletons/README-D.txt \
data/skeletons/d-skel.m4 \
data/skeletons/d.m4 \
data/skeletons/lalr1.d
diff --git a/bison/data/m4sugar/foreach.m4 b/bison/data/m4sugar/foreach.m4
index 7093d0f..2052d44 100644
--- a/bison/data/m4sugar/foreach.m4
+++ b/bison/data/m4sugar/foreach.m4
@@ -4,7 +4,7 @@
# Speeds up GNU M4 1.4.x by avoiding quadratic $@ recursion, but penalizes
# GNU M4 1.6 by requiring more memory and macro expansions.
#
-# Copyright (C) 2008-2017 Free Software Foundation, Inc.
+# Copyright (C) 2008-2017, 2020 Free Software Foundation, Inc.
# This file is part of Autoconf. This program is free
# software; you can redistribute it and/or modify it under the
diff --git a/bison/data/m4sugar/m4sugar.m4 b/bison/data/m4sugar/m4sugar.m4
index bbd6958..b42fc1a 100644
--- a/bison/data/m4sugar/m4sugar.m4
+++ b/bison/data/m4sugar/m4sugar.m4
@@ -3,7 +3,7 @@ divert(-1)# -*- Autoconf -*-
# Base M4 layer.
# Requires GNU M4.
#
-# Copyright (C) 1999-2017 Free Software Foundation, Inc.
+# Copyright (C) 1999-2017, 2020 Free Software Foundation, Inc.
# This file is part of Autoconf. This program is free
# software; you can redistribute it and/or modify it under the
@@ -2412,6 +2412,27 @@ m4_define([m4_normalize],
[m4_strip(m4_flatten([$1]))])
+# m4_validate_w(STRING)
+# ---------------------
+# Expands into m4_normalize(m4_expand([STRING])), but if that is not
+# the same as just m4_normalize([STRING]), issue a warning.
+#
+# This is used in several Autoconf macros that take a
+# whitespace-separated list of symbols as an argument. Ideally that
+# list would not be expanded before use, but several packages used
+# `dnl' to put comments inside those lists, so they must be expanded
+# for compatibility's sake.
+m4_define([m4_validate_w],
+[_m4_validate_w(m4_normalize([$1]), m4_normalize(m4_expand([$1])))])
+
+m4_define([_m4_validate_w],
+[m4_if([$1], [$2], [],
+ [m4_warn([obsolete], [whitespace-separated list contains macros;
+in a future version of Autoconf they will not be expanded]dnl
+m4_if(m4_bregexp([$1], [\bdn[l]\b]), -1, [], [
+note: `dn@&t@l' is a macro]))])dnl
+[$2]])
+
# m4_join(SEP, ARG1, ARG2...)
# ---------------------------
diff --git a/bison/data/skeletons/README-D.txt b/bison/data/skeletons/README-D.txt
deleted file mode 100644
index e6068b4..0000000
--- a/bison/data/skeletons/README-D.txt
+++ /dev/null
@@ -1,60 +0,0 @@
-Some usage notes for the D Parser:
-
-- it is a port of the Java parser, so interface is very similar.
-
-- the lexer class needs to implement the interface 'Lexer' (similar to
- java). It typically (depending on options) looks like this:
-
-public interface Lexer
-{
- /**
- * Method to retrieve the beginning position of the last scanned token.
- * @return the position at which the last scanned token starts. */
- @property YYPosition startPos ();
-
- /**
- * Method to retrieve the ending position of the last scanned token.
- * @return the first position beyond the last scanned token. */
- @property YYPosition endPos ();
-
- /**
- * Method to retrieve the semantic value of the last scanned token.
- * @return the semantic value of the last scanned token. */
- @property YYSemanticType semanticVal ();
-
- /**
- * Entry point for the scanner. Returns the token identifier corresponding
- * to the next token and prepares to return the semantic value
- * and beginning/ending positions of the token.
- * @return the token identifier corresponding to the next token. */
- TokenKind yylex ();
-
- /**
- * Entry point for error reporting. Emits an error
- * referring to the given location in a user-defined way.
- *
- * @param loc The location of the element to which the
- * error message is related
- * @param s The string for the error message. */
- void yyerror (YYLocation loc, string s);
-}
-
-- semantic types are handled by D unions (same as for C/C++ parsers)
-
-- the following (non-standard) %defines are supported:
-
- %define package ""
- %define api.parser.class "my_class_name>"
- %define position_type "my_position_type"
- %define location_type "my_location_type"
-
-- the following declarations basically work like in C/C++:
-
- %locations
- %error-verbose
- %parse-param
- %initial-action
- %code
- %union
-
-- %destructor is not yet supported
diff --git a/bison/data/skeletons/bison.m4 b/bison/data/skeletons/bison.m4
index 7ab1cb9..b7bf5c5 100644
--- a/bison/data/skeletons/bison.m4
+++ b/bison/data/skeletons/bison.m4
@@ -2,7 +2,7 @@
# Language-independent M4 Macros for Bison.
-# Copyright (C) 2002, 2004-2015, 2018-2020 Free Software Foundation,
+# Copyright (C) 2002, 2004-2015, 2018-2021 Free Software Foundation,
# Inc.
# This program is free software: you can redistribute it and/or modify
@@ -16,7 +16,7 @@
# 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 .
+# along with this program. If not, see .
@@ -74,7 +74,7 @@ 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 .])
+along with this program. If not, see .])
b4_comment([As a special exception, you may create a larger work that contains
part or all of the Bison parser skeleton and distribute that work
@@ -261,6 +261,13 @@ m4_define([b4_fatal_at],
[b4_error([[fatal]], $@)dnl
m4_exit(1)])
+# b4_canary(MSG)
+# --------------
+# Issue a warning on stderr and in the output. Used in the test suite
+# to catch spurious m4 evaluations.
+m4_define([b4_canary],
+[m4_errprintn([dead canary: $1])DEAD CANARY($1)])
+
## ------------ ##
## Data Types. ##
@@ -332,14 +339,14 @@ number is the opposite. If YYTABLE_NINF, syntax error.]])
$1([check], [b4_check])
$1([stos], [b4_stos],
- [[YYSTOS[STATE-NUM] -- The (internal number of the) accessing
-symbol of state STATE-NUM.]])
+ [[YYSTOS[STATE-NUM] -- The symbol kind of the accessing symbol of
+state STATE-NUM.]])
$1([r1], [b4_r1],
- [[YYR1[YYN] -- Symbol number of symbol that rule YYN derives.]])
+ [[YYR1[RULE-NUM] -- Symbol kind of the left-hand side of rule RULE-NUM.]])
$1([r2], [b4_r2],
- [[YYR2[YYN] -- Number of symbols on the right hand side of rule YYN.]])
+ [[YYR2[RULE-NUM] -- Number of symbols on the right-hand side of rule RULE-NUM.]])
])
@@ -391,9 +398,9 @@ m4_define([b4_$3_if],
# b4_FLAG_if(IF-TRUE, IF-FALSE)
# -----------------------------
# Expand IF-TRUE, if FLAG is true, IF-FALSE otherwise.
-b4_define_flag_if([defines]) # Whether headers are requested.
b4_define_flag_if([glr]) # Whether a GLR parser is requested.
b4_define_flag_if([has_translations]) # Whether some tokens are internationalized.
+b4_define_flag_if([header]) # Whether a header is requested.
b4_define_flag_if([nondeterministic]) # Whether conflicts should be handled.
b4_define_flag_if([token_table]) # Whether yytoken_table is demanded.
b4_define_flag_if([yacc]) # Whether POSIX Yacc is emulated.
@@ -404,6 +411,10 @@ b4_define_flag_if([yacc]) # Whether POSIX Yacc is emulated.
m4_define([b4_glr_cc_if],
[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. ##
@@ -465,17 +476,35 @@ m4_case([$1],
# but are S_YYEMPTY and symbol_kind::S_YYEMPTY in C++.
m4_copy([b4_symbol_kind_base], [b4_symbol_kind])
+
+# b4_symbol_slot(NUM)
+# -------------------
+# The name of union member that contains the value of these symbols.
+# Currently, we are messy, this should actually be type_tag, but type_tag
+# has several meanings.
+m4_define([b4_symbol_slot],
+[m4_case(b4_percent_define_get([[api.value.type]]),
+ [union], [b4_symbol([$1], [type_tag])],
+ [variant], [b4_symbol([$1], [type_tag])],
+ [b4_symbol([$1], [type])])])
+
+
# b4_symbol(NUM, FIELD)
# ---------------------
-# Fetch FIELD of symbol #NUM (or "orig NUM"). Fail if undefined.
+# Fetch FIELD of symbol #NUM (or "orig NUM", or "empty"). Fail if undefined.
#
# If FIELD = id, prepend the token prefix.
m4_define([b4_symbol],
-[m4_case([$2],
- [id], [b4_symbol_token_kind([$1])],
- [kind_base], [b4_symbol_kind_base([$1])],
- [kind], [b4_symbol_kind([$1])],
- [_b4_symbol($@)])])
+[m4_if([$1], [empty], [b4_symbol([-2], [$2])],
+ [$1], [eof], [b4_symbol([0], [$2])],
+ [$1], [error], [b4_symbol([1], [$2])],
+ [$1], [undef], [b4_symbol([2], [$2])],
+ [m4_case([$2],
+ [id], [b4_symbol_token_kind([$1])],
+ [kind_base], [b4_symbol_kind_base([$1])],
+ [kind], [b4_symbol_kind([$1])],
+ [slot], [b4_symbol_slot([$1])],
+ [_b4_symbol($@)])])])
# b4_symbol_if(NUM, FIELD, IF-TRUE, IF-FALSE)
@@ -537,7 +566,7 @@ m4_defn([b4_actions_])[]dnl
break;
}dnl
],
-[YYUSE (m4_default([$2], [yykind]));])dnl
+[b4_use(m4_default([$2], [yykind]));])dnl
m4_popdef([b4_actions_])dnl
])
@@ -953,15 +982,18 @@ m4_define([b4_percent_define_flag_if],
# For example:
#
# b4_percent_define_default([[foo]], [[default value]])
+m4_define([_b4_percent_define_define],
+[m4_define([b4_percent_define(]$1[)], [$2])dnl
+m4_define([b4_percent_define_kind(]$1[)],
+ [m4_default([$3], [keyword])])dnl
+m4_define([b4_percent_define_loc(]$1[)],
+ [[[[:-1.-1]],
+ [[:-1.-1]]]])dnl
+m4_define([b4_percent_define_syncline(]$1[)], [[]])])
+
m4_define([b4_percent_define_default],
[_b4_percent_define_ifdef([$1], [],
- [m4_define([b4_percent_define(]$1[)], [$2])dnl
- m4_define([b4_percent_define_kind(]$1[)],
- [m4_default([$3], [keyword])])dnl
- m4_define([b4_percent_define_loc(]$1[)],
- [[[[:-1.-1]],
- [[:-1.-1]]]])dnl
- m4_define([b4_percent_define_syncline(]$1[)], [[]])])])
+ [_b4_percent_define_define($@)])])
# b4_percent_define_if_define(NAME, [VARIABLE = NAME])
@@ -971,11 +1003,12 @@ m4_define([b4_percent_define_default],
# to '_'.
m4_define([_b4_percent_define_if_define],
[m4_define(m4_bpatsubst([b4_$1_if], [[-.]], [_]),
- [b4_percent_define_flag_if(m4_default([$2], [$1]),
- [$3], [$4])])])
+ [b4_percent_define_default([m4_default([$2], [$1])], [[false]])dnl
+b4_percent_define_flag_if(m4_default([$2], [$1]),
+ [$3], [$4])])])
+
m4_define([b4_percent_define_if_define],
-[b4_percent_define_default([m4_default([$2], [$1])], [[false]])
-_b4_percent_define_if_define([$1], [$2], $[1], $[2])])
+[_b4_percent_define_if_define([$1], [$2], $[1], $[2])])
# b4_percent_define_check_kind(VARIABLE, KIND, [DIAGNOSTIC = complain])
@@ -1081,6 +1114,7 @@ b4_percent_define_if_define([token_ctor], [api.token.constructor])
b4_percent_define_if_define([locations]) # Whether locations are tracked.
b4_percent_define_if_define([parse.assert])
b4_percent_define_if_define([parse.trace])
+b4_percent_define_if_define([posix])
# b4_bison_locations_if([IF-TRUE])
@@ -1110,14 +1144,18 @@ m4_define([b4_parse_error_bmatch],
+# b4_union_if([IF-UNION-ARE-USED], [IF-NOT])
# b4_variant_if([IF-VARIANT-ARE-USED], [IF-NOT])
# ----------------------------------------------
-b4_percent_define_if_define([variant])
+# Depend on whether api.value.type is union, or variant.
+m4_define([b4_union_flag], [[0]])
m4_define([b4_variant_flag], [[0]])
b4_percent_define_ifdef([[api.value.type]],
[m4_case(b4_percent_define_get_kind([[api.value.type]]), [keyword],
- [m4_case(b4_percent_define_get([[api.value.type]]), [variant],
- [m4_define([b4_variant_flag], [[1]])])])])
+ [m4_case(b4_percent_define_get([[api.value.type]]),
+ [union], [m4_define([b4_union_flag], [[1]])],
+ [variant], [m4_define([b4_variant_flag], [[1]])])])])
+b4_define_flag_if([union])
b4_define_flag_if([variant])
diff --git a/bison/data/skeletons/c++-skel.m4 b/bison/data/skeletons/c++-skel.m4
index 6d3becf..f22002b 100644
--- a/bison/data/skeletons/c++-skel.m4
+++ b/bison/data/skeletons/c++-skel.m4
@@ -2,7 +2,7 @@
# C++ skeleton dispatching for Bison.
-# Copyright (C) 2006-2007, 2009-2015, 2018-2020 Free Software
+# Copyright (C) 2006-2007, 2009-2015, 2018-2021 Free Software
# Foundation, Inc.
# This program is free software: you can redistribute it and/or modify
@@ -16,7 +16,7 @@
# 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 .
+# along with this program. If not, see .
b4_glr_if( [m4_define([b4_used_skeleton], [b4_skeletonsdir/[glr.cc]])])
b4_nondeterministic_if([m4_define([b4_used_skeleton], [b4_skeletonsdir/[glr.cc]])])
diff --git a/bison/data/skeletons/c++.m4 b/bison/data/skeletons/c++.m4
index 78c66de..2ae8423 100644
--- a/bison/data/skeletons/c++.m4
+++ b/bison/data/skeletons/c++.m4
@@ -2,7 +2,7 @@
# C++ skeleton for Bison
-# Copyright (C) 2002-2020 Free Software Foundation, Inc.
+# Copyright (C) 2002-2021 Free Software Foundation, Inc.
# 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
@@ -15,7 +15,7 @@
# 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 .
+# along with this program. If not, see .
# Sanity checks, before defaults installed by c.m4.
b4_percent_define_ifdef([[api.value.union.name]],
@@ -109,7 +109,6 @@ b4_percent_define_default([[api.filename.type]], [[const std::string]])
# Make it a warning for those who used betas of Bison 3.0.
b4_percent_define_default([[api.namespace]], m4_defn([b4_prefix]))
-b4_percent_define_default([[global_tokens_and_yystype]], [[false]])
b4_percent_define_default([[define_location_comparison]],
[m4_if(b4_percent_define_get([[filename_type]]),
[std::string], [[true]], [[false]])])
@@ -193,7 +192,7 @@ m4_define([b4_declare_symbol_enum],
[[enum symbol_kind_type
{
YYNTOKENS = ]b4_tokens_number[, ///< Number of tokens.
- ]b4_symbol(-2, kind_base)[ = -2,
+ ]b4_symbol(empty, kind_base)[ = -2,
]b4_symbol_foreach([ b4_symbol_enum])dnl
[ };]])
@@ -207,16 +206,16 @@ m4_define([b4_declare_symbol_enum],
# b4_value_type_declare
# ---------------------
-# Declare semantic_type.
+# Declare value_type.
m4_define([b4_value_type_declare],
[b4_value_type_setup[]dnl
[ /// Symbol semantic values.
]m4_bmatch(b4_percent_define_get_kind([[api.value.type]]),
[code],
-[[ typedef ]b4_percent_define_get([[api.value.type]])[ semantic_type;]],
+[[ typedef ]b4_percent_define_get([[api.value.type]])[ value_type;]],
[m4_bmatch(b4_percent_define_get([[api.value.type]]),
[union\|union-directive],
-[[ union semantic_type
+[[ union value_type
{
]b4_user_union_members[
};]])])dnl
@@ -228,11 +227,19 @@ 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],
-[[#ifndef ]b4_api_PREFIX[STYPE
-]b4_value_type_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"
+# endif
+ typedef ]b4_api_PREFIX[STYPE value_type;
#else
- typedef ]b4_api_PREFIX[STYPE semantic_type;
-#endif]b4_locations_if([
+]b4_value_type_declare[
+#endif
+ /// Backward compatibility (Bison 3.8).
+ typedef value_type semantic_type;
+]])[]b4_locations_if([
/// Symbol locations.
typedef b4_percent_define_get([[api.location.type]],
[[location]]) location_type;])[
@@ -258,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
@@ -301,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 ()])[
{}
@@ -330,7 +337,7 @@ m4_define([b4_symbol_type_define],
/// Constructor for symbols with semantic value.
basic_symbol (typename Base::kind_type t,
- YY_RVREF (semantic_type) v]b4_locations_if([,
+ YY_RVREF (value_type) v]b4_locations_if([,
YY_RVREF (location_type) l])[);
]])[
/// Destroy the symbol.
@@ -339,8 +346,32 @@ 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 ()
+ void clear () YY_NOEXCEPT
{]b4_variant_if([[
// User destructor.
symbol_kind_type yykind = this->kind ();
@@ -379,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;
@@ -391,7 +422,7 @@ m4_define([b4_symbol_type_define],
void move (basic_symbol& s);
/// The semantic value.
- semantic_type value;]b4_locations_if([
+ value_type value;]b4_locations_if([
/// The location.
location_type location;])[
@@ -406,43 +437,51 @@ m4_define([b4_symbol_type_define],
/// Type access provider for token (enum) based symbols.
struct by_kind
{
+ /// The symbol kind as needed by the constructor.
+ typedef token_kind_type kind_type;
+
/// Default constructor.
- by_kind ();
+ by_kind () YY_NOEXCEPT;
#if 201103L <= YY_CPLUSPLUS
/// Move constructor.
- by_kind (by_kind&& that);
+ by_kind (by_kind&& that) YY_NOEXCEPT;
#endif
/// Copy constructor.
- by_kind (const by_kind& that);
-
- /// The symbol kind as needed by the constructor.
- typedef token_kind_type kind_type;
+ 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 ();
+ void clear () YY_NOEXCEPT;
/// Steal the symbol kind from \a that.
void move (by_kind& that);
/// 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
@@ -451,10 +490,10 @@ m4_define([b4_symbol_type_define],
typedef basic_symbol super_type;
/// Empty symbol.
- symbol_type () {}
+ symbol_type () YY_NOEXCEPT {}
/// Constructor for valueless symbols, and symbols from each type.
-]b4_type_foreach([_b4_token_constructor_define])dnl
+]b4_type_foreach([_b4_symbol_constructor_define])dnl
])[};
]])
@@ -488,7 +527,7 @@ m4_define([b4_public_types_define],
template
]b4_parser_class[::basic_symbol::basic_symbol (]b4_join(
[typename Base::kind_type t],
- [YY_RVREF (semantic_type) v],
+ [YY_RVREF (value_type) v],
b4_locations_if([YY_RVREF (location_type) l]))[)
: Base (t)
, value (]b4_variant_if([], [YY_MOVE (v)])[)]b4_locations_if([
@@ -497,18 +536,20 @@ 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
]b4_parser_class[::symbol_kind_type
]b4_parser_class[::basic_symbol::type_get () const YY_NOEXCEPT
{
return this->kind ();
}
+]])[
template
bool
]b4_parser_class[::basic_symbol::empty () const YY_NOEXCEPT
{
- return this->kind () == ]b4_symbol(-2, kind)[;
+ return this->kind () == ]b4_symbol(empty, kind)[;
}
template
@@ -523,30 +564,47 @@ m4_define([b4_public_types_define],
}
// by_kind.
- ]b4_inline([$1])b4_parser_class[::by_kind::by_kind ()
- : kind_ (]b4_symbol(-2, 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 ()
+ ]b4_parser_class[::by_kind::clear () YY_NOEXCEPT
{
- kind_ = ]b4_symbol(-2, kind)[;
+ kind_ = ]b4_symbol(empty, kind)[;
}
]b4_inline([$1])[void
@@ -562,17 +620,19 @@ 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 ();
}
+]])[
]])
# b4_token_constructor_define
# ----------------------------
-# Define symbol constructors for all the value types.
+# Define make_FOO for all the token kinds.
# Use at class-level. Redefined in variant.hh.
m4_define([b4_token_constructor_define], [])
@@ -583,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 (t);]],
@@ -601,7 +661,7 @@ m4_define([b4_yytranslate_define],
if (t <= 0)
return symbol_kind::]b4_symbol_prefix[YYEOF;
else if (t <= code_max)
- return YY_CAST (symbol_kind_type, translate_table[t]);
+ return static_cast (translate_table[t]);
else
return symbol_kind::]b4_symbol_prefix[YYUNDEF;]])[
}
diff --git a/bison/data/skeletons/c-like.m4 b/bison/data/skeletons/c-like.m4
index 1e5ab02..a9bbc2e 100644
--- a/bison/data/skeletons/c-like.m4
+++ b/bison/data/skeletons/c-like.m4
@@ -2,7 +2,7 @@
# Common code for C-like languages (C, C++, Java, etc.)
-# Copyright (C) 2012-2015, 2018-2020 Free Software Foundation, Inc.
+# Copyright (C) 2012-2015, 2018-2021 Free Software Foundation, Inc.
# 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
@@ -15,7 +15,7 @@
# 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 .
+# along with this program. If not, see .
# _b4_comment(TEXT, OPEN, CONTINUE, END)
diff --git a/bison/data/skeletons/c-skel.m4 b/bison/data/skeletons/c-skel.m4
index 68d057c..ac6ddd6 100644
--- a/bison/data/skeletons/c-skel.m4
+++ b/bison/data/skeletons/c-skel.m4
@@ -2,7 +2,7 @@
# C skeleton dispatching for Bison.
-# Copyright (C) 2006-2007, 2009-2015, 2018-2020 Free Software
+# Copyright (C) 2006-2007, 2009-2015, 2018-2021 Free Software
# Foundation, Inc.
# This program is free software: you can redistribute it and/or modify
@@ -16,7 +16,7 @@
# 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 .
+# along with this program. If not, see .
b4_glr_if( [m4_define([b4_used_skeleton], [b4_skeletonsdir/[glr.c]])])
b4_nondeterministic_if([m4_define([b4_used_skeleton], [b4_skeletonsdir/[glr.c]])])
diff --git a/bison/data/skeletons/c.m4 b/bison/data/skeletons/c.m4
index 07148ef..2425b07 100644
--- a/bison/data/skeletons/c.m4
+++ b/bison/data/skeletons/c.m4
@@ -2,7 +2,7 @@
# C M4 Macros for Bison.
-# Copyright (C) 2002, 2004-2015, 2018-2020 Free Software Foundation,
+# Copyright (C) 2002, 2004-2015, 2018-2021 Free Software Foundation,
# Inc.
# This program is free software: you can redistribute it and/or modify
@@ -16,7 +16,7 @@
# 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 .
+# along with this program. If not, see .
m4_include(b4_skeletonsdir/[c-like.m4])
@@ -107,27 +107,32 @@ b4_percent_define_default([[api.symbol.prefix]], [[YYSYMBOL_]])
## Pure/impure interfaces. ##
## ------------------------ ##
-# b4_lex_formals
-# --------------
+# b4_yylex_formals
+# ----------------
# All the yylex formal arguments.
# b4_lex_param arrives quoted twice, but we want to keep only one level.
-m4_define([b4_lex_formals],
-[b4_pure_if([[[[YYSTYPE *yylvalp]], [[&yylval]]][]dnl
-b4_locations_if([, [[YYLTYPE *yyllocp], [&yylloc]]])])dnl
+m4_define([b4_yylex_formals],
+[b4_pure_if([[[b4_api_PREFIX[STYPE *yylvalp]], [[&yylval]]][]dnl
+b4_locations_if([, [b4_api_PREFIX[LTYPE *yyllocp], [&yylloc]]])])dnl
m4_ifdef([b4_lex_param], [, ]b4_lex_param)])
-# b4_lex
-# ------
+# b4_yylex
+# --------
# Call yylex.
-m4_define([b4_lex],
-[b4_function_call([yylex], [int], b4_lex_formals)])
+m4_define([b4_yylex],
+[b4_function_call([yylex], [int], b4_yylex_formals)])
# b4_user_args
# ------------
m4_define([b4_user_args],
-[m4_ifset([b4_parse_param], [, b4_args(b4_parse_param)])])
+[m4_ifset([b4_parse_param], [, b4_user_args_no_comma])])
+
+# b4_user_args_no_comma
+# ---------------------
+m4_define([b4_user_args_no_comma],
+[m4_ifset([b4_parse_param], [b4_args(b4_parse_param)])])
# b4_user_formals
@@ -158,13 +163,20 @@ m4_popdef([$2])dnl
m4_popdef([$1])dnl
])])
+
+# b4_use(EXPR)
+# ------------
+# Pacify the compiler about some maybe unused value.
+m4_define([b4_use],
+[YY_USE ($1)])
+
# b4_parse_param_use([VAL], [LOC])
# --------------------------------
-# 'YYUSE' VAL, LOC if locations are enabled, and all the parse-params.
+# 'YY_USE' VAL, LOC if locations are enabled, and all the parse-params.
m4_define([b4_parse_param_use],
-[m4_ifvaln([$1], [ YYUSE ([$1]);])dnl
-b4_locations_if([m4_ifvaln([$2], [ YYUSE ([$2]);])])dnl
-b4_parse_param_for([Decl], [Formal], [ YYUSE (Formal);
+[m4_ifvaln([$1], [ b4_use([$1]);])dnl
+b4_locations_if([m4_ifvaln([$2], [ b4_use([$2]);])])dnl
+b4_parse_param_for([Decl], [Formal], [ b4_use(Formal);
])dnl
])
@@ -242,6 +254,18 @@ typedef int_least16_t yytype_int16;
typedef short yytype_int16;
#endif
+/* Work around bug in HP-UX 11.23, which defines these macros
+ incorrectly for preprocessor constants. This workaround can likely
+ be removed in 2023, as HPE has promised support for HP-UX 11.23
+ (aka HP-UX 11i v2) only through the end of 2022; see Table 2 of
+ . */
+#ifdef __hpux
+# undef UINT_LEAST8_MAX
+# undef UINT_LEAST16_MAX
+# define UINT_LEAST8_MAX 255
+# define UINT_LEAST16_MAX 65535
+#endif
+
#if defined __UINT_LEAST8_MAX__ && __UINT_LEAST8_MAX__ <= __INT_MAX__
typedef __UINT_LEAST8_TYPE__ yytype_uint8;
#elif (!defined __UINT_LEAST8_MAX__ && defined YY_STDINT_H \
@@ -366,14 +390,16 @@ dnl use C' _Noreturn in C++, to avoid -Wc11-extensions warnings.
&& ((201103 <= __cplusplus && !(__GNUC__ == 4 && __GNUC_MINOR__ == 7)) \
|| (defined _MSC_VER && 1900 <= _MSC_VER)))
# define _Noreturn [[noreturn]]
-# elif (!defined __cplusplus \
- && (201112 <= (defined __STDC_VERSION__ ? __STDC_VERSION__ : 0) \
- || 4 < __GNUC__ + (7 <= __GNUC_MINOR__) \
- || (defined __apple_build_version__ \
- ? 6000000 <= __apple_build_version__ \
- : 3 < __clang_major__ + (5 <= __clang_minor__))))
+# elif ((!defined __cplusplus || defined __clang__) \
+ && (201112 <= (defined __STDC_VERSION__ ? __STDC_VERSION__ : 0) \
+ || (!defined __STRICT_ANSI__ \
+ && (4 < __GNUC__ + (7 <= __GNUC_MINOR__) \
+ || (defined __apple_build_version__ \
+ ? 6000000 <= __apple_build_version__ \
+ : 3 < __clang_major__ + (5 <= __clang_minor__))))))
/* _Noreturn works as-is. */
-# elif 2 < __GNUC__ + (8 <= __GNUC_MINOR__) || 0x5110 <= __SUNPRO_C
+# elif (2 < __GNUC__ + (8 <= __GNUC_MINOR__) || defined __clang__ \
+ || 0x5110 <= __SUNPRO_C)
# define _Noreturn __attribute__ ((__noreturn__))
# elif 1200 <= (defined _MSC_VER ? _MSC_VER : 0)
# define _Noreturn __declspec (noreturn)
@@ -384,17 +410,23 @@ dnl use C' _Noreturn in C++, to avoid -Wc11-extensions warnings.
]])[/* Suppress unused-variable warnings by "using" E. */
#if ! defined lint || defined __GNUC__
-# define YYUSE(E) ((void) (E))
+# define YY_USE(E) ((void) (E))
#else
-# define YYUSE(E) /* empty */
+# define YY_USE(E) /* empty */
#endif
-#if defined __GNUC__ && ! defined __ICC && 407 <= __GNUC__ * 100 + __GNUC_MINOR__
/* Suppress an incorrect diagnostic about yylval being uninitialized. */
-# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
+#if defined __GNUC__ && ! defined __ICC && 406 <= __GNUC__ * 100 + __GNUC_MINOR__
+# if __GNUC__ * 100 + __GNUC_MINOR__ < 407
+# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
+ _Pragma ("GCC diagnostic push") \
+ _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")
+# else
+# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
_Pragma ("GCC diagnostic push") \
_Pragma ("GCC diagnostic ignored \"-Wuninitialized\"") \
_Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"")
+# endif
# define YY_IGNORE_MAYBE_UNINITIALIZED_END \
_Pragma ("GCC diagnostic pop")
#else
@@ -474,7 +506,7 @@ m4_define([b4_null], [YY_NULLPTR])
# -------------------------------------------------------------
# Define "yy" whose contents is CONTENT.
m4_define([b4_integral_parser_table_define],
-[m4_ifvaln([$3], [b4_comment([$3], [ ])])dnl
+[m4_ifvaln([$3], [b4_comment([$3])])dnl
static const b4_int_type_for([$2]) yy$1[[]] =
{
$2
@@ -493,7 +525,7 @@ static const b4_int_type_for([$2]) yy$1[[]] =
m4_define([b4_symbol(-2, id)], [b4_api_PREFIX[][EMPTY]])
m4_define([b4_symbol(-2, tag)], [[No symbol.]])
-m4_if(b4_symbol(0, id), [YYEOF],
+m4_if(b4_symbol(eof, id), [YYEOF],
[m4_define([b4_symbol(0, id)], [b4_api_PREFIX[][EOF]])])
m4_define([b4_symbol(1, id)], [b4_api_PREFIX[][error]])
m4_define([b4_symbol(2, id)], [b4_api_PREFIX[][UNDEF]])
@@ -510,7 +542,7 @@ m4_define([b4_token_define],
# Output the definition of the tokens.
m4_define([b4_token_defines],
[[/* Token kinds. */
-#define ]b4_symbol([-2], [id])[ -2
+#define ]b4_symbol(empty, [id])[ -2
]m4_join([
], b4_symbol_map([b4_token_define]))
])
@@ -538,7 +570,7 @@ m4_define([b4_token_enums],
# define ]b4_api_PREFIX[TOKENTYPE
enum ]b4_api_prefix[tokentype
{
- ]b4_symbol([-2], [id])[ = -2,
+ ]b4_symbol(empty, [id])[ = -2,
]b4_symbol_foreach([b4_token_enum])dnl
[ };
typedef enum ]b4_api_prefix[tokentype ]b4_api_prefix[token_kind_t;
@@ -588,7 +620,7 @@ m4_define([b4_declare_symbol_enum],
[[/* Symbol kind. */
enum yysymbol_kind_t
{
- ]b4_symbol([-2], kind_base)[ = -2,
+ ]b4_symbol(empty, [kind_base])[ = -2,
]b4_symbol_foreach([b4_symbol_enum])dnl
[};
typedef enum yysymbol_kind_t yysymbol_kind_t;
@@ -630,6 +662,14 @@ m4_define([b4_formal],
[$1])
+# b4_function_declare(NAME, RETURN-VALUE, [DECL1, NAME1], ...)
+# ------------------------------------------------------------
+# Declare the function NAME.
+m4_define([b4_function_declare],
+[$2 $1 (b4_formals(m4_shift2($@)));[]dnl
+])
+
+
## --------------------- ##
## Calling C functions. ##
@@ -729,13 +769,6 @@ yy_symbol_value_print (FILE *yyo,
]b4_parse_param_use([yyoutput], [yylocationp])dnl
[ if (!yyvaluep)
return;]
-dnl glr.c does not feature yytoknum.
-m4_if(b4_skeleton, ["yacc.c"],
-[[# ifdef YYPRINT
- if (yykind < YYNTOKENS)
- YYPRINT (yyo, yytoknum[yykind], *yyvaluep);
-# endif
-]])dnl
b4_percent_code_get([[pre-printer]])dnl
YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
b4_symbol_actions([printer])
@@ -756,7 +789,7 @@ yy_symbol_print (FILE *yyo,
YYFPRINTF (yyo, "%s %s (",
yykind < YYNTOKENS ? "token" : "nterm", yysymbol_name (yykind));
-]b4_locations_if([ YY_LOCATION_PRINT (yyo, *yylocationp);
+]b4_locations_if([ YYLOCATION_PRINT (yyo, yylocationp);
YYFPRINTF (yyo, ": ");
])dnl
[ yy_symbol_value_print (yyo, yykind, yyvaluep]dnl
@@ -943,7 +976,7 @@ struct ]b4_api_PREFIX[LTYPE
# b4_declare_yylstype
# -------------------
-# Declarations that might either go into the header (if --defines) or
+# Declarations that might either go into the header (if --header) or
# in the parser body. Declare YYSTYPE/YYLTYPE, and yylval/yylloc.
m4_define([b4_declare_yylstype],
[b4_value_type_define[]b4_locations_if([
@@ -1013,17 +1046,24 @@ m4_define([b4_yylloc_default_define],
#endif
]])
-# b4_yy_location_print_define
-# ---------------------------
-# Define YY_LOCATION_PRINT.
-m4_define([b4_yy_location_print_define],
+# b4_yylocation_print_define
+# --------------------------
+# Define YYLOCATION_PRINT.
+m4_define([b4_yylocation_print_define],
[b4_locations_if([[
-/* YY_LOCATION_PRINT -- Print the location on the stream.
+/* YYLOCATION_PRINT -- Print the location on the stream.
This macro was not mandated originally: define only if we know
we won't break user code: when these are the locations we know. */
-# ifndef YY_LOCATION_PRINT
-# if defined ]b4_api_PREFIX[LTYPE_IS_TRIVIAL && ]b4_api_PREFIX[LTYPE_IS_TRIVIAL
+# ifndef YYLOCATION_PRINT
+
+# if defined YY_LOCATION_PRINT
+
+ /* Temporary convenience wrapper in case some people defined the
+ undocumented and private YY_LOCATION_PRINT macros. */
+# define YYLOCATION_PRINT(File, Loc) YY_LOCATION_PRINT(File, *(Loc))
+
+# elif defined ]b4_api_PREFIX[LTYPE_IS_TRIVIAL && ]b4_api_PREFIX[LTYPE_IS_TRIVIAL
/* Print *YYLOCP on YYO. Private, do not rely on its existence. */
@@ -1051,19 +1091,23 @@ yy_location_print_ (FILE *yyo, YYLTYPE const * const yylocp)
res += YYFPRINTF (yyo, "-%d", end_col);
}
return res;
- }
+}
-# define YY_LOCATION_PRINT(File, Loc) \
- yy_location_print_ (File, &(Loc))
+# define YYLOCATION_PRINT yy_location_print_
+
+ /* Temporary convenience wrapper in case some people defined the
+ undocumented and private YY_LOCATION_PRINT macros. */
+# define YY_LOCATION_PRINT(File, Loc) YYLOCATION_PRINT(File, &(Loc))
# else
-# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
+
+# define YYLOCATION_PRINT(File, Loc) ((void) 0)
+ /* Temporary convenience wrapper in case some people defined the
+ undocumented and private YY_LOCATION_PRINT macros. */
+# define YY_LOCATION_PRINT YYLOCATION_PRINT
+
# endif
-# endif /* !defined YY_LOCATION_PRINT */]],
-[[/* This macro is provided for backward compatibility. */
-# ifndef YY_LOCATION_PRINT
-# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
-# endif]])
+# endif /* !defined YYLOCATION_PRINT */]])
])
# b4_yyloc_default
diff --git a/bison/data/skeletons/d-skel.m4 b/bison/data/skeletons/d-skel.m4
index 89cd511..2a38f02 100644
--- a/bison/data/skeletons/d-skel.m4
+++ b/bison/data/skeletons/d-skel.m4
@@ -2,7 +2,7 @@
# D skeleton dispatching for Bison.
-# Copyright (C) 2018-2020 Free Software Foundation, Inc.
+# Copyright (C) 2018-2021 Free Software Foundation, Inc.
# 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
@@ -15,7 +15,7 @@
# 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 .
+# along with this program. If not, see .
b4_glr_if( [b4_complain([%%glr-parser not supported for D])])
b4_nondeterministic_if([b4_complain([%%nondeterministic-parser not supported for D])])
diff --git a/bison/data/skeletons/d.m4 b/bison/data/skeletons/d.m4
index 0c28351..c0632e4 100644
--- a/bison/data/skeletons/d.m4
+++ b/bison/data/skeletons/d.m4
@@ -2,7 +2,7 @@
# D language support for Bison
-# Copyright (C) 2018-2020 Free Software Foundation, Inc.
+# Copyright (C) 2018-2021 Free Software Foundation, Inc.
# 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
@@ -15,27 +15,36 @@
# 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 .
+# along with this program. If not, see .
-# _b4_comment(TEXT, OPEN, CONTINUE, END)
-# --------------------------------------
-# Put TEXT in comment. Avoid trailing spaces: don't indent empty lines.
-# Avoid adding indentation to the first line, as the indentation comes
-# from OPEN. That's why we don't patsubst([$1], [^\(.\)], [ \1]).
-#
-# Prefix all the output lines with PREFIX.
-m4_define([_b4_comment],
-[$2[]m4_bpatsubst(m4_expand([[$1]]), [
-\(.\)], [
-$3\1])$4])
+m4_include(b4_skeletonsdir/[c-like.m4])
-# b4_comment(TEXT, [PREFIX])
-# --------------------------
-# Put TEXT in comment. Prefix all the output lines with PREFIX.
-m4_define([b4_comment],
-[_b4_comment([$1], [$2/* ], [$2 ], [ */])])
+# b4_symbol_action(SYMBOL-NUM, ACTION)
+# ------------------------------------
+# Run the action ACTION ("destructor" or "printer") for SYMBOL-NUM.
+m4_define([b4_symbol_action],
+[b4_symbol_if([$1], [has_$2],
+[b4_dollar_pushdef([yyval],
+ [$1],
+ [],
+ [yyloc])dnl
+ _b4_symbol_case([$1])[]dnl
+b4_syncline([b4_symbol([$1], [$2_line])], [b4_symbol([$1], [$2_file])])dnl
+b4_symbol([$1], [$2])
+b4_syncline([@oline@], [@ofile@])dnl
+ break;
+
+b4_dollar_popdef[]dnl
+])])
+
+
+# b4_use(EXPR)
+# ------------
+# Pacify the compiler about some maybe unused value.
+m4_define([b4_use],
+[])
# b4_sync_start(LINE, FILE)
@@ -58,6 +67,23 @@ m4_define([b4_percent_define_get3],
[m4_ifval(m4_quote(b4_percent_define_get([$1])),
[$2[]b4_percent_define_get([$1])[]$3], [$4])])
+# b4_percent_define_if_get2(ARG1, ARG2, DEF, NOT)
+# -----------------------------------------------
+# Expand to the value of DEF if ARG1 or ARG2 are %define'ed,
+# otherwise NOT.
+m4_define([b4_percent_define_if_get2],
+ [m4_ifval(m4_quote(b4_percent_define_get([$1])),
+ [$3], [m4_ifval(m4_quote(b4_percent_define_get([$2])),
+ [$3], [$4])])])
+
+# b4_percent_define_class_before_interface(CLASS, INTERFACE)
+# ----------------------------------------------------------
+# Expand to a ', ' if both a class and an interface have been %define'ed
+m4_define([b4_percent_define_class_before_interface],
+ [m4_ifval(m4_quote(b4_percent_define_get([$1])),
+ [m4_ifval(m4_quote(b4_percent_define_get([$2])),
+ [, ])])])
+
# b4_flag_value(BOOLEAN-FLAG)
# ---------------------------
@@ -78,8 +104,10 @@ b4_percent_define_flag_if([api.parser.public], [public ])dnl
b4_percent_define_flag_if([api.parser.abstract], [abstract ])dnl
b4_percent_define_flag_if([api.parser.final], [final ])dnl
[class ]b4_parser_class[]dnl
-b4_percent_define_get3([api.parser.extends], [ extends ])dnl
-b4_percent_define_get3([api.parser.implements], [ implements ])])
+b4_percent_define_if_get2([api.parser.extends], [api.parser.implements], [ : ])dnl
+b4_percent_define_get([api.parser.extends])dnl
+b4_percent_define_class_before_interface([api.parser.extends], [api.parser.implements])dnl
+b4_percent_define_get([api.parser.implements])])
# b4_lexer_if(TRUE, FALSE)
@@ -153,6 +181,7 @@ private static immutable b4_int_type_for([$2])[[]] yy$1_ =
## ------------- ##
m4_define([b4_symbol(-2, id)], [[YYEMPTY]])
+b4_percent_define_default([[api.token.raw]], [[true]])
# b4_token_enum(TOKEN-NAME, TOKEN-NUMBER)
# ---------------------------------------
@@ -167,19 +196,49 @@ m4_define([b4_token_enum],
m4_define([b4_token_enums],
[/* Token kinds. */
public enum TokenKind {
- ]b4_symbol_kind([-2])[ = -2,
+ ]b4_symbol(empty, id)[ = -2,
b4_symbol_foreach([b4_token_enum])dnl
}
])
-
+# b4_symbol_translate(STRING)
+# ---------------------------
+# Used by "bison" in the array of symbol names to mark those that
+# require translation.
+m4_define([b4_symbol_translate],
+[[_($1)]])
+
+
+# _b4_token_constructor_define(SYMBOL-NUM)
+# ----------------------------------------
+# Define Symbol.FOO for SYMBOL-NUM.
+m4_define([_b4_token_constructor_define],
+[b4_token_visible_if([$1],
+[[
+ static auto ]b4_symbol([$1], [id])[(]b4_symbol_if([$1], [has_type],
+[b4_union_if([b4_symbol([$1], [type]],
+[[typeof(YYSemanticType.]b4_symbol([$1], [type])[]])) [val]])dnl
+[]b4_locations_if([b4_symbol_if([$1], [has_type], [[, ]])[Location l]])[)
+ {
+ return Symbol(TokenKind.]b4_symbol([$1], [id])[]b4_symbol_if([$1], [has_type],
+ [[, val]])[]b4_locations_if([[, l]])[);
+ }]])])
+
+# b4_token_constructor_define
+# ---------------------------
+# Define Symbol.FOO for each token kind FOO.
+m4_define([b4_token_constructor_define],
+[[
+ /* Implementation of token constructors for each symbol type visible to
+ * the user. The code generates static methods that have the same names
+ * as the TokenKinds.
+ */]b4_symbol_foreach([_b4_token_constructor_define])dnl
+])
## -------------- ##
## Symbol kinds. ##
## -------------- ##
-b4_percent_define_default([[api.symbol.prefix]], [[S_]])
-
# b4_symbol_kind(NUM)
# -------------------
m4_define([b4_symbol_kind],
@@ -204,16 +263,46 @@ m4_define([b4_symbol_enum],
# to use a signed type, which matters for yytoken.
m4_define([b4_declare_symbol_enum],
[[ /* Symbol kinds. */
- public enum SymbolKind
+ struct SymbolKind
{
- ]b4_symbol(-2, kind_base)[ = -2, /* No symbol. */
+ enum
+ {
+ ]b4_symbol(empty, kind_base)[ = -2, /* No symbol. */
]b4_symbol_foreach([b4_symbol_enum])dnl
-[ };
-]])])
-
+[ }
+
+ private int yycode_;
+ alias yycode_ this;
+
+ this(int code)
+ {
+ yycode_ = code;
+ }
+
+ /* Return YYSTR after stripping away unnecessary quotes and
+ backslashes, so that it's suitable for yyerror. The heuristic is
+ that double-quoting is unnecessary unless the string contains an
+ apostrophe, a comma, or backslash (other than backslash-backslash).
+ YYSTR is taken from yytname. */
+ final void toString(W)(W sink) const
+ if (isOutputRange!(W, char))
+ {
+ immutable string[] yy_sname = @{
+ ]b4_symbol_names[
+ @};]b4_has_translations_if([[
+ /* YYTRANSLATABLE[SYMBOL-NUM] -- Whether YY_SNAME[SYMBOL-NUM] is
+ internationalizable. */
+ immutable ]b4_int_type_for([b4_translatable])[[] yytranslatable = @{
+ ]b4_translatable[
+ @};]])[
+
+ put(sink, yy_sname[yycode_]);
+ }
+ }
+]])
-# b4-case(ID, CODE, [COMMENTS])
+# b4_case(ID, CODE, [COMMENTS])
# -----------------------------
m4_define([b4_case], [ case $1:m4_ifval([$3], [ b4_comment([$3])])
$2
@@ -240,6 +329,109 @@ m4_define([b4_location_type], b4_percent_define_ifdef([[location_type]],[b4_perc
m4_define([b4_position_type], b4_percent_define_ifdef([[position_type]],[b4_percent_define_get([[position_type]])],[YYPosition]))
+## ---------------- ##
+## api.value.type. ##
+## ---------------- ##
+
+
+# ---------------------- #
+# api.value.type=union. #
+# ---------------------- #
+
+# b4_symbol_type_register(SYMBOL-NUM)
+# -----------------------------------
+# Symbol SYMBOL-NUM has a type (for union) instead of a type-tag.
+# Extend the definition of %union's body (b4_union_members) with a
+# field of that type, and extend the symbol's "type" field to point to
+# the field name, instead of the type name.
+m4_define([b4_symbol_type_register],
+[m4_define([b4_symbol($1, type_tag)],
+ [b4_symbol_if([$1], [has_id],
+ [b4_symbol([$1], [id])],
+ [yykind_[]b4_symbol([$1], [number])])])dnl
+m4_append([b4_union_members],
+m4_expand([m4_format([ %-40s %s],
+ m4_expand([b4_symbol([$1], [type]) b4_symbol([$1], [type_tag]);]),
+ [b4_symbol_tag_comment([$1])])]))
+])
+
+
+# b4_type_define_tag(SYMBOL1-NUM, ...)
+# ------------------------------------
+# For the batch of symbols SYMBOL1-NUM... (which all have the same
+# type), enhance the %union definition for each of them, and set
+# there "type" field to the field tag name, instead of the type name.
+m4_define([b4_type_define_tag],
+[b4_symbol_if([$1], [has_type],
+ [m4_map([b4_symbol_type_register], [$@])])
+])
+
+
+# b4_symbol_value_union(VAL, SYMBOL-NUM, [TYPE])
+# ----------------------------------------------
+# Same of b4_symbol_value, but when api.value.type=union.
+m4_define([b4_symbol_value_union],
+[m4_ifval([$3],
+ [(*($3*)(&$1))],
+ [m4_ifval([$2],
+ [b4_symbol_if([$2], [has_type],
+ [($1.b4_symbol([$2], [type_tag]))],
+ [$1])],
+ [$1])])])
+
+
+# b4_value_type_setup_union
+# -------------------------
+# Setup support for api.value.type=union. Symbols are defined with a
+# type instead of a union member name: build the corresponding union,
+# and give the symbols their tag.
+m4_define([b4_value_type_setup_union],
+[m4_define([b4_union_members])
+b4_type_foreach([b4_type_define_tag])
+m4_copy_force([b4_symbol_value_union], [b4_symbol_value])
+])
+
+
+# _b4_value_type_setup_keyword
+# ----------------------------
+# api.value.type is defined with a keyword/string syntax. Check if
+# that is properly defined, and prepare its use.
+m4_define([_b4_value_type_setup_keyword],
+[b4_percent_define_check_values([[[[api.value.type]],
+ [[none]],
+ [[union]],
+ [[union-directive]],
+ [[yystype]]]])dnl
+m4_case(b4_percent_define_get([[api.value.type]]),
+ [union], [b4_value_type_setup_union])])
+
+
+# b4_value_type_setup
+# -------------------
+# Check if api.value.type is properly defined, and possibly prepare
+# its use.
+b4_define_silent([b4_value_type_setup],
+[
+# Define default value.
+b4_percent_define_ifdef([[api.value.type]], [],
+[# %union => api.value.type=union-directive
+m4_ifdef([b4_union_members],
+[m4_define([b4_percent_define_kind(api.value.type)], [keyword])
+m4_define([b4_percent_define(api.value.type)], [union-directive])],
+[# no tag seen => api.value.type={int}
+m4_if(b4_tag_seen_flag, 0,
+[m4_define([b4_percent_define_kind(api.value.type)], [code])
+m4_define([b4_percent_define(api.value.type)], [int])],
+[# otherwise api.value.type=yystype
+m4_define([b4_percent_define_kind(api.value.type)], [keyword])
+m4_define([b4_percent_define(api.value.type)], [yystype])])])])
+
+# Set up.
+m4_bmatch(b4_percent_define_get_kind([[api.value.type]]),
+ [keyword], [_b4_value_type_setup_keyword])
+])
+
+
## ----------------- ##
## Semantic Values. ##
## ----------------- ##
@@ -286,7 +478,7 @@ m4_define([b4_lhs_location],
# Expansion of @POS, where the current rule has RULE-LENGTH symbols
# on RHS.
m4_define([b4_rhs_location],
-[yystack.locationAt ([$1], [$2])])
+[yystack.locationAt (b4_subtract($@))])
# b4_lex_param
@@ -371,3 +563,66 @@ m4_define([b4_var_decls],
], [$@])])
m4_define([b4_var_decl],
[ protected $1;])
+
+
+# b4_public_types_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],
+[[
+alias Symbol = ]b4_parser_class[.Symbol;
+alias Value = ]b4_yystype[;]b4_locations_if([[
+alias Location = ]b4_location_type[;
+alias Position = ]b4_position_type[;]b4_push_if([[
+alias PUSH_MORE = ]b4_parser_class[.YYPUSH_MORE;
+alias ABORT = ]b4_parser_class[.YYABORT;
+alias ACCEPT = ]b4_parser_class[.YYACCEPT;]])[]])[
+]])
+
+
+# b4_basic_symbol_constructor_define
+# ----------------------------------
+# Create Symbol struct constructors for all the visible types.
+m4_define([b4_basic_symbol_constructor_define],
+[b4_token_visible_if([$1],
+[[ this(TokenKind token]b4_symbol_if([$1], [has_type],
+[[, ]b4_union_if([], [[typeof(YYSemanticType.]])b4_symbol([$1], [type])dnl
+[]b4_union_if([], [[) ]])[ val]])[]b4_locations_if([[, Location loc]])[)
+ {
+ kind = yytranslate_(token);]b4_union_if([b4_symbol_if([$1], [has_type], [[
+ static foreach (member; __traits(allMembers, YYSemanticType))
+ {
+ static if (is(typeof(mixin("value_." ~ member)) == ]b4_symbol([$1], [type])[))
+ {
+ mixin("value_." ~ member ~ " = val;");
+ }
+ }]])], [b4_symbol_if([$1], [has_type], [[
+ value_.]b4_symbol([$1], [type])[ = val;]])])[]b4_locations_if([
+ location_ = loc;])[
+ }
+]])])
+
+
+# b4_symbol_type_define
+# ---------------------
+# Define symbol_type, the external type for symbols used for symbol
+# constructors.
+m4_define([b4_symbol_type_define],
+[[
+ /**
+ * A complete symbol
+ */
+ struct Symbol
+ {
+ private SymbolKind kind;
+ private Value value_;]b4_locations_if([[
+ private Location location_;]])[
+
+]b4_type_foreach([b4_basic_symbol_constructor_define])[
+ SymbolKind token() { return kind; }
+ Value value() { return value_; }]b4_locations_if([[
+ Location location() { return location_; }]])[
+]b4_token_ctor_if([b4_token_constructor_define])[
+ }
+]])
diff --git a/bison/data/skeletons/glr.c b/bison/data/skeletons/glr.c
index a50f180..fab3733 100644
--- a/bison/data/skeletons/glr.c
+++ b/bison/data/skeletons/glr.c
@@ -1,8 +1,8 @@
- -*- C -*-
+# -*- C -*-
# GLR skeleton for Bison
-# Copyright (C) 2002-2015, 2018-2020 Free Software Foundation, Inc.
+# Copyright (C) 2002-2015, 2018-2021 Free Software Foundation, Inc.
# 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
@@ -15,7 +15,7 @@
# 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 .
+# along with this program. If not, see .
# If we are loaded by glr.cc, do not override c++.m4 definitions by
@@ -32,7 +32,9 @@ m4_if(b4_skeleton, ["glr.c"],
m4_define_default([b4_stack_depth_max], [10000])
m4_define_default([b4_stack_depth_init], [200])
-
+# Included header.
+b4_percent_define_default([[api.header.include]],
+ [["@basename(]b4_spec_header_file[@)"]])
## ------------------------ ##
## Pure/impure interfaces. ##
@@ -122,7 +124,7 @@ m4_define([b4_rhs_data],
# --------------------------------------------------
# Expansion of $$ or $$, for symbol SYMBOL-NUM.
m4_define([b4_rhs_value],
-[b4_symbol_value([b4_rhs_data([$1], [$2]).yysemantics.yysval], [$3], [$4])])
+[b4_symbol_value([b4_rhs_data([$1], [$2]).yysemantics.yyval], [$3], [$4])])
@@ -145,13 +147,22 @@ m4_define([b4_rhs_location],
[(b4_rhs_data([$1], [$2]).yyloc)])
+# b4_call_merger(MERGER-NUM, MERGER-NAME, SYMBOL-SUM)
+# ---------------------------------------------------
+m4_define([b4_call_merger],
+[b4_case([$1],
+ [ b4_symbol_if([$3], [has_type],
+ [yy0->b4_symbol($3, slot) = $2 (*yy0, *yy1);],
+ [*yy0 = $2 (*yy0, *yy1);])])])
+
+
## -------------- ##
## Declarations. ##
## -------------- ##
# b4_shared_declarations
# ----------------------
-# Declaration that might either go into the header (if --defines)
+# Declaration that might either go into the header (if --header)
# or open coded in the parser body. glr.cc has its own definition.
m4_if(b4_skeleton, ["glr.c"],
[m4_define([b4_shared_declarations],
@@ -185,10 +196,10 @@ int ]b4_prefix[parse (]m4_ifset([b4_parse_param], [b4_formals(b4_parse_param)],
# glr.cc produces its own header.
b4_glr_cc_if([],
-[b4_defines_if(
+[b4_header_if(
[b4_output_begin([b4_spec_header_file])
b4_copyright([Skeleton interface for Bison GLR parsers in C],
- [2002-2015, 2018-2020])[
+ [2002-2015, 2018-2021])[
]b4_cpp_guard_open([b4_spec_mapped_header_file])[
]b4_shared_declarations[
]b4_cpp_guard_close([b4_spec_mapped_header_file])[
@@ -202,7 +213,7 @@ b4_copyright([Skeleton interface for Bison GLR parsers in C],
b4_output_begin([b4_parser_file_name])
b4_copyright([Skeleton implementation for Bison GLR parsers in C],
- [2002-2015, 2018-2020])[
+ [2002-2015, 2018-2021])[
/* C GLR parser skeleton written by Paul Hilfinger. */
]b4_disclaimer[
@@ -215,7 +226,7 @@ b4_copyright([Skeleton implementation for Bison GLR parsers in C],
#define YYLTYPE ]b4_api_PREFIX[LTYPE]])])[
]m4_if(b4_prefix, [yy], [],
[[/* Substitute the variable and function names. */
-#define yyparse ]b4_prefix[parse
+#define ]b4_glr_cc_if([yy_parse_impl], [yyparse])[ ]b4_prefix[]b4_glr_cc_if([_parse_impl], [parse])[
#define yylex ]b4_prefix[lex
#define yyerror ]b4_prefix[error
#define yydebug ]b4_prefix[debug]]b4_pure_if([], [[
@@ -228,8 +239,8 @@ b4_copyright([Skeleton implementation for Bison GLR parsers in C],
]b4_cast_define[
]b4_null_define[
-]b4_defines_if([[#include "@basename(]b4_spec_header_file[@)"]],
- [b4_shared_declarations])[
+]b4_header_if([[#include ]b4_percent_define_get([[api.header.include]])],
+ [b4_shared_declarations])[
]b4_glr_cc_if([b4_glr_cc_setup],
[b4_declare_symbol_enum])[
@@ -431,7 +442,7 @@ int yychar;])[
enum { YYENOMEM = -2 };
-typedef enum { yyok, yyaccept, yyabort, yyerr } YYRESULTTAG;
+typedef enum { yyok, yyaccept, yyabort, yyerr, yynomem } YYRESULTTAG;
#define YYCHK(YYE) \
do { \
@@ -496,10 +507,11 @@ typedef struct yySemanticOption yySemanticOption;
typedef union yyGLRStackItem yyGLRStackItem;
typedef struct yyGLRStack yyGLRStack;
-struct yyGLRState {
+struct yyGLRState
+{
/** Type tag: always true. */
yybool yyisState;
- /** Type tag for yysemantics. If true, yysval applies, otherwise
+ /** Type tag for yysemantics. If true, yyval applies, otherwise
* yyfirstVal applies. */
yybool yyresolved;
/** Number of corresponding LALR(1) machine state. */
@@ -514,24 +526,26 @@ struct yyGLRState {
* yynext. */
yySemanticOption* yyfirstVal;
/** Semantic value for this state. */
- YYSTYPE yysval;
+ YYSTYPE yyval;
} yysemantics;]b4_locations_if([[
/** Source location for this state. */
YYLTYPE yyloc;]])[
};
-struct yyGLRStateSet {
+struct yyGLRStateSet
+{
yyGLRState** yystates;
/** During nondeterministic operation, yylookaheadNeeds tracks which
* stacks have actually needed the current lookahead. During deterministic
* operation, yylookaheadNeeds[0] is not maintained since it would merely
- * duplicate yychar != ]b4_symbol(-2, id)[. */
+ * duplicate yychar != ]b4_symbol(empty, id)[. */
yybool* yylookaheadNeeds;
YYPTRDIFF_T yysize;
YYPTRDIFF_T yycapacity;
};
-struct yySemanticOption {
+struct yySemanticOption
+{
/** Type tag: always false. */
yybool yyisState;
/** Rule number for this reduction */
@@ -637,6 +651,13 @@ yysymbol_name (yysymbol_kind_t yysymbol)
}]])[
#endif
+/** Left-hand-side symbol for rule #YYRULE. */
+static inline yysymbol_kind_t
+yylhsNonterm (yyRuleNum yyrule)
+{
+ return YY_CAST (yysymbol_kind_t, yyr1[yyrule]);
+}
+
#if ]b4_api_PREFIX[DEBUG
# ifndef YYFPRINTF
@@ -662,7 +683,7 @@ yysymbol_name (yysymbol_kind_t yysymbol)
YY_IGNORE_USELESS_CAST_END \
} while (0)
-]b4_yy_location_print_define[
+]b4_yylocation_print_define[
]b4_yy_symbol_print_define[
@@ -676,6 +697,16 @@ yysymbol_name (yysymbol_kind_t yysymbol)
} \
} while (0)
+static inline void
+yy_reduce_print (yybool yynormal, yyGLRStackItem* yyvsp, YYPTRDIFF_T yyk,
+ yyRuleNum yyrule]b4_user_formals[);
+
+# define YY_REDUCE_PRINT(Args) \
+ do { \
+ if (yydebug) \
+ yy_reduce_print Args; \
+ } while (0)
+
/* Nonzero means print parse trace. It is left uninitialized so that
multiple parsers can coexist. */
int yydebug;
@@ -689,6 +720,7 @@ static void yypdumpstack (yyGLRStack* yystackp)
# define YY_DPRINTF(Args) do {} while (yyfalse)
# define YY_SYMBOL_PRINT(Title, Kind, Value, Location)
+# define YY_REDUCE_PRINT(Args)
#endif /* !]b4_api_PREFIX[DEBUG */
@@ -791,9 +823,9 @@ yyfillin (yyGLRStackItem *yyvsp, int yylow0, int yylow1)
#endif
yyvsp[i].yystate.yyresolved = s->yyresolved;
if (s->yyresolved)
- yyvsp[i].yystate.yysemantics.yysval = s->yysemantics.yysval;
+ yyvsp[i].yystate.yysemantics.yyval = s->yysemantics.yyval;
else
- /* The effect of using yysval or yyloc (in an immediate rule) is
+ /* The effect of using yyval or yyloc (in an immediate rule) is
* undefined. */
yyvsp[i].yystate.yysemantics.yyfirstVal = YY_NULLPTR;]b4_locations_if([[
yyvsp[i].yystate.yyloc = s->yyloc;]])[
@@ -809,14 +841,14 @@ yygetToken (int *yycharp][]b4_pure_if([, yyGLRStack* yystackp])[]b4_user_formals
{
yysymbol_kind_t yytoken;
]b4_parse_param_use()dnl
-[ if (*yycharp == ]b4_symbol(-2, id)[)
+[ if (*yycharp == ]b4_symbol(empty, id)[)
{
YY_DPRINTF ((stderr, "Reading a token\n"));]b4_glr_cc_if([[
#if YY_EXCEPTIONS
try
{
#endif // YY_EXCEPTIONS
- *yycharp = ]b4_lex[;
+ *yycharp = ]b4_yylex[;
#if YY_EXCEPTIONS
}
catch (const ]b4_namespace_ref[::]b4_parser_class[::syntax_error& yyexc)
@@ -827,14 +859,14 @@ yygetToken (int *yycharp][]b4_pure_if([, yyGLRStack* yystackp])[]b4_user_formals
// Map errors caught in the scanner to the undefined token,
// so that error handling is started. However, record this
// with this special value of yychar.
- *yycharp = ]b4_symbol(1, id)[;
+ *yycharp = ]b4_symbol(error, id)[;
}
#endif // YY_EXCEPTIONS]], [[
- *yycharp = ]b4_lex[;]])[
+ *yycharp = ]b4_yylex[;]])[
}
- if (*yycharp <= ]b4_symbol(0, [id])[)
+ if (*yycharp <= ]b4_symbol(eof, [id])[)
{
- *yycharp = ]b4_symbol(0, [id])[;
+ *yycharp = ]b4_symbol(eof, [id])[;
yytoken = ]b4_symbol_prefix[YYEOF;
YY_DPRINTF ((stderr, "Now at end of input.\n"));
}
@@ -866,28 +898,31 @@ yyfill (yyGLRStackItem *yyvsp, int *yylow, int yylow1, yybool yynormal)
* and top stack item YYVSP. YYLVALP points to place to put semantic
* value ($$), and yylocp points to place for location information
* (@@$). Returns yyok for normal return, yyaccept for YYACCEPT,
- * yyerr for YYERROR, yyabort for YYABORT. */
+ * yyerr for YYERROR, yyabort for YYABORT, yynomem for YYNOMEM. */
static YYRESULTTAG
-yyuserAction (yyRuleNum yyn, int yyrhslen, yyGLRStackItem* yyvsp,
- yyGLRStack* yystackp,
+yyuserAction (yyRuleNum yyrule, int yyrhslen, yyGLRStackItem* yyvsp,
+ yyGLRStack* yystackp, YYPTRDIFF_T yyk,
YYSTYPE* yyvalp]b4_locuser_formals[)
{
- yybool yynormal YY_ATTRIBUTE_UNUSED = yystackp->yysplitPoint == YY_NULLPTR;
- int yylow;
+ const yybool yynormal YY_ATTRIBUTE_UNUSED = yystackp->yysplitPoint == YY_NULLPTR;
+ int yylow = 1;
]b4_parse_param_use([yyvalp], [yylocp])dnl
-[ YYUSE (yyrhslen);
+[ YY_USE (yyk);
+ YY_USE (yyrhslen);
# undef yyerrok
# define yyerrok (yystackp->yyerrState = 0)
# undef YYACCEPT
# define YYACCEPT return yyaccept
# undef YYABORT
# define YYABORT return yyabort
+# undef YYNOMEM
+# define YYNOMEM return yynomem
# undef YYERROR
# define YYERROR return yyerrok, yyerr
# undef YYRECOVERING
# define YYRECOVERING() (yystackp->yyerrState != 0)
# undef yyclearin
-# define yyclearin (yychar = ]b4_symbol(-2, id)[)
+# define yyclearin (yychar = ]b4_symbol(empty, id)[)
# undef YYFILL
# define YYFILL(N) yyfill (yyvsp, &yylow, (N), yynormal)
# undef YYBACKUP
@@ -895,21 +930,23 @@ yyuserAction (yyRuleNum yyn, int yyrhslen, yyGLRStackItem* yyvsp,
return yyerror (]b4_yyerror_args[YY_("syntax error: cannot back up")), \
yyerrok, yyerr
- yylow = 1;
if (yyrhslen == 0)
*yyvalp = yyval_default;
else
- *yyvalp = yyvsp[YYFILL (1-yyrhslen)].yystate.yysemantics.yysval;]b4_locations_if([[
+ *yyvalp = yyvsp[YYFILL (1-yyrhslen)].yystate.yysemantics.yyval;]b4_locations_if([[
/* Default location. */
YYLLOC_DEFAULT ((*yylocp), (yyvsp - yyrhslen), yyrhslen);
- yystackp->yyerror_range[1].yystate.yyloc = *yylocp;
-]])[]b4_glr_cc_if([[
+ yystackp->yyerror_range[1].yystate.yyloc = *yylocp;]])[
+ /* If yyk == -1, we are running a deferred action on a temporary
+ stack. In that case, YY_REDUCE_PRINT must not play with YYFILL,
+ so pretend the stack is "normal". */
+ YY_REDUCE_PRINT ((yynormal || yyk == -1, yyvsp, yyk, yyrule]b4_user_args[));]b4_glr_cc_if([[
#if YY_EXCEPTIONS
typedef ]b4_namespace_ref[::]b4_parser_class[::syntax_error syntax_error;
try
{
#endif // YY_EXCEPTIONS]])[
- switch (yyn)
+ switch (yyrule)
{
]b4_user_actions[
default: break;
@@ -924,11 +961,13 @@ yyuserAction (yyRuleNum yyn, int yyrhslen, yyGLRStackItem* yyvsp,
YYERROR;
}
#endif // YY_EXCEPTIONS]])[
+ YY_SYMBOL_PRINT ("-> $$ =", yylhsNonterm (yyrule), yyvalp, yylocp);
return yyok;
# undef yyerrok
# undef YYABORT
# undef YYACCEPT
+# undef YYNOMEM
# undef YYERROR
# undef YYBACKUP
# undef yyclearin
@@ -939,8 +978,8 @@ yyuserAction (yyRuleNum yyn, int yyrhslen, yyGLRStackItem* yyvsp,
static void
yyuserMerge (int yyn, YYSTYPE* yy0, YYSTYPE* yy1)
{
- YYUSE (yy0);
- YYUSE (yy1);
+ YY_USE (yy0);
+ YY_USE (yy1);
switch (yyn)
{
@@ -965,7 +1004,7 @@ yydestroyGLRState (char const *yymsg, yyGLRState *yys]b4_user_formals[)
{
if (yys->yyresolved)
yydestruct (yymsg, yy_accessing_symbol (yys->yylrState),
- &yys->yysemantics.yysval]b4_locuser_args([&yys->yyloc])[);
+ &yys->yysemantics.yyval]b4_locuser_args([&yys->yyloc])[);
else
{
#if ]b4_api_PREFIX[DEBUG
@@ -992,13 +1031,6 @@ yydestroyGLRState (char const *yymsg, yyGLRState *yys]b4_user_formals[)
}
}
-/** Left-hand-side symbol for rule #YYRULE. */
-static inline yysymbol_kind_t
-yylhsNonterm (yyRuleNum yyrule)
-{
- return YY_CAST (yysymbol_kind_t, yyr1[yyrule]);
-}
-
#define yypact_value_is_default(Yyn) \
]b4_table_value_equals([[pact]], [[Yyn]], [b4_pact_ninf], [YYPACT_NINF])[
@@ -1032,7 +1064,7 @@ static inline int
yygetLRActions (yy_state_t yystate, yysymbol_kind_t yytoken, const short** yyconflicts)
{
int yyindex = yypact[yystate] + yytoken;
- if (yytoken == ]b4_symbol(1, kind)[)
+ if (yytoken == ]b4_symbol(error, kind)[)
{
// This is the error token.
*yyconflicts = yyconfl;
@@ -1119,7 +1151,7 @@ yyaddDeferredAction (yyGLRStack* yystackp, YYPTRDIFF_T yyk, yyGLRState* yystate,
yynewOption->yyloc = yylloc;])[
}
else
- yynewOption->yyrawchar = ]b4_symbol(-2, id)[;
+ yynewOption->yyrawchar = ]b4_symbol(empty, id)[;
yynewOption->yynext = yystate->yysemantics.yyfirstVal;
yystate->yysemantics.yyfirstVal = yynewOption;
@@ -1340,7 +1372,7 @@ yyglrShift (yyGLRStack* yystackp, YYPTRDIFF_T yyk, yy_state_t yylrState,
yynewState->yyposn = yyposn;
yynewState->yyresolved = yytrue;
yynewState->yypred = yystackp->yytops.yystates[yyk];
- yynewState->yysemantics.yysval = *yyvalp;]b4_locations_if([
+ yynewState->yysemantics.yyval = *yyvalp;]b4_locations_if([
yynewState->yyloc = *yylocp;])[
yystackp->yytops.yystates[yyk] = yynewState;
@@ -1368,14 +1400,7 @@ yyglrShiftDefer (yyGLRStack* yystackp, YYPTRDIFF_T yyk, yy_state_t yylrState,
yyaddDeferredAction (yystackp, yyk, yynewState, yyrhs, yyrule);
}
-#if !]b4_api_PREFIX[DEBUG
-# define YY_REDUCE_PRINT(Args)
-#else
-# define YY_REDUCE_PRINT(Args) \
- do { \
- if (yydebug) \
- yy_reduce_print Args; \
- } while (0)
+#if ]b4_api_PREFIX[DEBUG
/*----------------------------------------------------------------------.
| Report that stack #YYK of *YYSTACKP is going to be reduced by YYRULE. |
@@ -1398,7 +1423,7 @@ yy_reduce_print (yybool yynormal, yyGLRStackItem* yyvsp, YYPTRDIFF_T yyk,
YY_FPRINTF ((stderr, " $%d = ", yyi + 1));
yy_symbol_print (stderr,
yy_accessing_symbol (yyvsp[yyi - yynrhs + 1].yystate.yylrState),
- &yyvsp[yyi - yynrhs + 1].yystate.yysemantics.yysval]b4_locations_if([,
+ &yyvsp[yyi - yynrhs + 1].yystate.yysemantics.yyval]b4_locations_if([,
&]b4_rhs_location(yynrhs, yyi + 1))[]dnl
b4_user_args[);
if (!yyvsp[yyi - yynrhs + 1].yystate.yyresolved)
@@ -1429,8 +1454,7 @@ yydoAction (yyGLRStack* yystackp, YYPTRDIFF_T yyk, yyRuleNum yyrule,
yystackp->yynextFree -= yynrhs;
yystackp->yyspaceLeft += yynrhs;
yystackp->yytops.yystates[0] = & yystackp->yynextFree[-1].yystate;
- YY_REDUCE_PRINT ((yytrue, yyrhs, yyk, yyrule]b4_user_args[));
- return yyuserAction (yyrule, yynrhs, yyrhs, yystackp,
+ return yyuserAction (yyrule, yynrhs, yyrhs, yystackp, yyk,
yyvalp]b4_locuser_args[);
}
else
@@ -1449,9 +1473,8 @@ yydoAction (yyGLRStack* yystackp, YYPTRDIFF_T yyk, yyRuleNum yyrule,
}
yyupdateSplit (yystackp, yys);
yystackp->yytops.yystates[yyk] = yys;
- YY_REDUCE_PRINT ((yyfalse, yyrhsVals + YYMAXRHS + YYMAXLEFT - 1, yyk, yyrule]b4_user_args[));
return yyuserAction (yyrule, yynrhs, yyrhsVals + YYMAXRHS + YYMAXLEFT - 1,
- yystackp, yyvalp]b4_locuser_args[);
+ yystackp, yyk, yyvalp]b4_locuser_args[);
}
}
@@ -1474,21 +1497,20 @@ yyglrReduce (yyGLRStack* yystackp, YYPTRDIFF_T yyk, yyRuleNum yyrule,
if (yyforceEval || yystackp->yysplitPoint == YY_NULLPTR)
{
- YYSTYPE yysval;]b4_locations_if([[
+ YYSTYPE yyval;]b4_locations_if([[
YYLTYPE yyloc;]])[
- YYRESULTTAG yyflag = yydoAction (yystackp, yyk, yyrule, &yysval]b4_locuser_args([&yyloc])[);
+ YYRESULTTAG yyflag = yydoAction (yystackp, yyk, yyrule, &yyval]b4_locuser_args([&yyloc])[);
if (yyflag == yyerr && yystackp->yysplitPoint != YY_NULLPTR)
YY_DPRINTF ((stderr,
"Parse on stack %ld rejected by rule %d (line %d).\n",
- YY_CAST (long, yyk), yyrule - 1, yyrline[yyrule - 1]));
+ YY_CAST (long, yyk), yyrule - 1, yyrline[yyrule]));
if (yyflag != yyok)
return yyflag;
- YY_SYMBOL_PRINT ("-> $$ =", yylhsNonterm (yyrule), &yysval, &yyloc);
yyglrShift (yystackp, yyk,
yyLRgotoState (yystackp->yytops.yystates[yyk]->yylrState,
yylhsNonterm (yyrule)),
- yyposn, &yysval]b4_locations_if([, &yyloc])[);
+ yyposn, &yyval]b4_locations_if([, &yyloc])[);
}
else
{
@@ -1508,7 +1530,7 @@ yyglrReduce (yyGLRStack* yystackp, YYPTRDIFF_T yyk, yyRuleNum yyrule,
YY_DPRINTF ((stderr,
"Reduced stack %ld by rule %d (line %d); action deferred. "
"Now in state %d.\n",
- YY_CAST (long, yyk), yyrule - 1, yyrline[yyrule - 1],
+ YY_CAST (long, yyk), yyrule - 1, yyrline[yyrule],
yynewLRState));
for (yyi = 0; yyi < yystackp->yytops.yysize; yyi += 1)
if (yyi != yyk && yystackp->yytops.yystates[yyi] != YY_NULLPTR)
@@ -1619,12 +1641,12 @@ yymergeOptionSets (yySemanticOption* yyy0, yySemanticOption* yyy1)
else if (yys0->yyresolved)
{
yys1->yyresolved = yytrue;
- yys1->yysemantics.yysval = yys0->yysemantics.yysval;
+ yys1->yysemantics.yyval = yys0->yysemantics.yyval;
}
else if (yys1->yyresolved)
{
yys0->yyresolved = yytrue;
- yys0->yysemantics.yysval = yys1->yysemantics.yysval;
+ yys0->yysemantics.yyval = yys1->yysemantics.yyval;
}
else
{
@@ -1678,8 +1700,8 @@ yypreference (yySemanticOption* y0, yySemanticOption* y1)
return 0;
}
-static YYRESULTTAG yyresolveValue (yyGLRState* yys,
- yyGLRStack* yystackp]b4_user_formals[);
+static YYRESULTTAG
+yyresolveValue (yyGLRState* yys, yyGLRStack* yystackp]b4_user_formals[);
/** Resolve the previous YYN states starting at and including state YYS
@@ -1735,7 +1757,7 @@ yyresolveAction (yySemanticOption* yyopt, yyGLRStack* yystackp,
yylloc = yyopt->yyloc;])[
yyflag = yyuserAction (yyopt->yyrule, yynrhs,
yyrhsVals + YYMAXRHS + YYMAXLEFT - 1,
- yystackp, yyvalp]b4_locuser_args[);
+ yystackp, -1, yyvalp]b4_locuser_args[);
yychar = yychar_current;
yylval = yylval_current;]b4_locations_if([
yylloc = yylloc_current;])[
@@ -1795,8 +1817,8 @@ static YYRESULTTAG
yyreportAmbiguity (yySemanticOption* yyx0,
yySemanticOption* yyx1]b4_pure_formals[)
{
- YYUSE (yyx0);
- YYUSE (yyx1);
+ YY_USE (yyx0);
+ YY_USE (yyx1);
#if ]b4_api_PREFIX[DEBUG
YY_FPRINTF ((stderr, "Ambiguity detected.\n"));
@@ -1870,7 +1892,7 @@ yyresolveValue (yyGLRState* yys, yyGLRStack* yystackp]b4_user_formals[)
yySemanticOption* yybest = yyoptionList;
yySemanticOption** yypp;
yybool yymerge = yyfalse;
- YYSTYPE yysval;
+ YYSTYPE yyval;
YYRESULTTAG yyflag;]b4_locations_if([
YYLTYPE *yylocp = &yys->yyloc;])[
@@ -1914,33 +1936,33 @@ yyresolveValue (yyGLRState* yys, yyGLRStack* yystackp]b4_user_formals[)
{
yySemanticOption* yyp;
int yyprec = yydprec[yybest->yyrule];
- yyflag = yyresolveAction (yybest, yystackp, &yysval]b4_locuser_args[);
+ yyflag = yyresolveAction (yybest, yystackp, &yyval]b4_locuser_args[);
if (yyflag == yyok)
for (yyp = yybest->yynext; yyp != YY_NULLPTR; yyp = yyp->yynext)
{
if (yyprec == yydprec[yyp->yyrule])
{
- YYSTYPE yysval_other;]b4_locations_if([
+ YYSTYPE yyval_other;]b4_locations_if([
YYLTYPE yydummy;])[
- yyflag = yyresolveAction (yyp, yystackp, &yysval_other]b4_locuser_args([&yydummy])[);
+ yyflag = yyresolveAction (yyp, yystackp, &yyval_other]b4_locuser_args([&yydummy])[);
if (yyflag != yyok)
{
yydestruct ("Cleanup: discarding incompletely merged value for",
yy_accessing_symbol (yys->yylrState),
- &yysval]b4_locuser_args[);
+ &yyval]b4_locuser_args[);
break;
}
- yyuserMerge (yymerger[yyp->yyrule], &yysval, &yysval_other);
+ yyuserMerge (yymerger[yyp->yyrule], &yyval, &yyval_other);
}
}
}
else
- yyflag = yyresolveAction (yybest, yystackp, &yysval]b4_locuser_args([yylocp])[);
+ yyflag = yyresolveAction (yybest, yystackp, &yyval]b4_locuser_args([yylocp])[);
if (yyflag == yyok)
{
yys->yyresolved = yytrue;
- yys->yysemantics.yysval = yysval;
+ yys->yysemantics.yyval = yyval;
}
else
yys->yysemantics.yyfirstVal = YY_NULLPTR;
@@ -1965,18 +1987,24 @@ yyresolveStack (yyGLRStack* yystackp]b4_user_formals[)
return yyok;
}
+/** Called when returning to deterministic operation to clean up the extra
+ * stacks. */
static void
yycompressStack (yyGLRStack* yystackp)
{
- yyGLRState* yyp, *yyq, *yyr;
+ /* yyr is the state after the split point. */
+ yyGLRState *yyr;
if (yystackp->yytops.yysize != 1 || yystackp->yysplitPoint == YY_NULLPTR)
return;
- for (yyp = yystackp->yytops.yystates[0], yyq = yyp->yypred, yyr = YY_NULLPTR;
- yyp != yystackp->yysplitPoint;
- yyr = yyp, yyp = yyq, yyq = yyp->yypred)
- yyp->yypred = yyr;
+ {
+ yyGLRState *yyp, *yyq;
+ for (yyp = yystackp->yytops.yystates[0], yyq = yyp->yypred, yyr = YY_NULLPTR;
+ yyp != yystackp->yysplitPoint;
+ yyr = yyp, yyp = yyq, yyq = yyp->yypred)
+ yyp->yypred = yyr;
+ }
yystackp->yyspaceLeft += yystackp->yynextFree - yystackp->yyitems;
yystackp->yynextFree = YY_REINTERPRET_CAST (yyGLRStackItem*, yystackp->yysplitPoint) + 1;
@@ -2110,7 +2138,7 @@ yypcontext_expected_tokens (const yyGLRStack* yystackp,
int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
int yyx;
for (yyx = yyxbegin; yyx < yyxend; ++yyx)
- if (yycheck[yyx + yyn] == yyx && yyx != ]b4_symbol(1, kind)[
+ if (yycheck[yyx + yyn] == yyx && yyx != ]b4_symbol(error, kind)[
&& !yytable_value_is_error (yytable[yyx + yyn]))
{
if (!yyarg)
@@ -2122,7 +2150,7 @@ yypcontext_expected_tokens (const yyGLRStack* yystackp,
}
}
if (yyarg && yycount == 0 && 0 < yyargn)
- yyarg[0] = ]b4_symbol(-2, kind)[;
+ yyarg[0] = ]b4_symbol(empty, kind)[;
return yycount;
}]])[
@@ -2140,19 +2168,19 @@ yypcontext_token (const yyGLRStack *yystackp) YY_ATTRIBUTE_UNUSED;
static yysymbol_kind_t
yypcontext_token (const yyGLRStack *yystackp)
{
- YYUSE (yystackp);
- yysymbol_kind_t yytoken = yychar == ]b4_symbol(-2, id)[ ? ]b4_symbol(-2, kind)[ : YYTRANSLATE (yychar);
+ YY_USE (yystackp);
+ yysymbol_kind_t yytoken = yychar == ]b4_symbol(empty, id)[ ? ]b4_symbol(empty, kind)[ : YYTRANSLATE (yychar);
return yytoken;
}
]b4_locations_if([[/* The location of the lookahead of this context. */
-static YYLTYPE *
+static const YYLTYPE *
yypcontext_location (const yyGLRStack *yystackp) YY_ATTRIBUTE_UNUSED;
-static YYLTYPE *
+static const YYLTYPE *
yypcontext_location (const yyGLRStack *yystackp)
{
- YYUSE (yystackp);
+ YY_USE (yystackp);
return &yylloc;
}]])],
[detailed\|verbose],
@@ -2160,7 +2188,7 @@ yypcontext_location (const yyGLRStack *yystackp)
yy_syntax_error_arguments (const yyGLRStack* yystackp,
yysymbol_kind_t yyarg[], int yyargn)
{
- yysymbol_kind_t yytoken = yychar == ]b4_symbol(-2, id)[ ? ]b4_symbol(-2, kind)[ : YYTRANSLATE (yychar);
+ yysymbol_kind_t yytoken = yychar == ]b4_symbol(empty, id)[ ? ]b4_symbol(empty, kind)[ : YYTRANSLATE (yychar);
/* Actual size of YYARG. */
int yycount = 0;
/* There are many possibilities here to consider:
@@ -2176,12 +2204,7 @@ yy_syntax_error_arguments (const yyGLRStack* yystackp,
- Don't assume there isn't a lookahead just because this state is a
consistent state with a default action. There might have been a
previous inconsistent state, consistent state with a non-default
- action, or user semantic action that manipulated yychar.]b4_lac_if([[
- In the first two cases, it might appear that the current syntax
- error should have been detected in the previous state when yy_lac
- was invoked. However, at that time, there might have been a
- different syntax error that discarded a different initial context
- during error recovery, leaving behind the current lookahead.]], [[
+ action, or user semantic action that manipulated yychar.
- Of course, the expected token list depends on states to have
correct lookahead information, and it depends on the parser not
to perform extra reductions after fetching a lookahead from the
@@ -2189,9 +2212,9 @@ yy_syntax_error_arguments (const yyGLRStack* yystackp,
(from LALR or IELR) and default reductions corrupt the expected
token list. However, the list is correct for canonical LR with
one exception: it will still contain any token that will not be
- accepted due to an error action in a later state.]])[
+ accepted due to an error action in a later state.
*/
- if (yytoken != ]b4_symbol(-2, kind)[)
+ if (yytoken != ]b4_symbol(empty, kind)[)
{
int yyn;
if (yyarg)
@@ -2318,9 +2341,9 @@ yyrecoverSyntaxError (yyGLRStack* yystackp]b4_user_formals[)
{
yysymbol_kind_t yytoken;
int yyj;
- if (yychar == ]b4_symbol(0, [id])[)
+ if (yychar == ]b4_symbol(eof, [id])[)
yyFail (yystackp][]b4_lpure_args[, YY_NULLPTR);
- if (yychar != ]b4_symbol(-2, id)[)
+ if (yychar != ]b4_symbol(empty, id)[)
{]b4_locations_if([[
/* We throw away the lookahead, but the error range
of the shifted error token must take it into account. */
@@ -2332,7 +2355,7 @@ yyrecoverSyntaxError (yyGLRStack* yystackp]b4_user_formals[)
yytoken = YYTRANSLATE (yychar);
yydestruct ("Error: discarding",
yytoken, &yylval]b4_locuser_args([&yylloc])[);
- yychar = ]b4_symbol(-2, id)[;
+ yychar = ]b4_symbol(empty, id)[;
}
yytoken = ]b4_yygetToken_call[;
yyj = yypact[yystackp->yytops.yystates[0]->yylrState];
@@ -2370,8 +2393,8 @@ yyrecoverSyntaxError (yyGLRStack* yystackp]b4_user_formals[)
int yyj = yypact[yys->yylrState];
if (! yypact_value_is_default (yyj))
{
- yyj += ]b4_symbol(1, kind)[;
- if (0 <= yyj && yyj <= YYLAST && yycheck[yyj] == ]b4_symbol(1, kind)[
+ yyj += ]b4_symbol(error, kind)[;
+ if (0 <= yyj && yyj <= YYLAST && yycheck[yyj] == ]b4_symbol(error, kind)[
&& yyisShiftAction (yytable[yyj]))
{
/* Shift the error token. */
@@ -2399,20 +2422,16 @@ yyrecoverSyntaxError (yyGLRStack* yystackp]b4_user_formals[)
yyFail (yystackp][]b4_lpure_args[, YY_NULLPTR);
}
-#define YYCHK1(YYE) \
- do { \
- switch (YYE) { \
- case yyok: \
- break; \
- case yyabort: \
- goto yyabortlab; \
- case yyaccept: \
- goto yyacceptlab; \
- case yyerr: \
- goto yyuser_error; \
- default: \
- goto yybuglab; \
- } \
+#define YYCHK1(YYE) \
+ do { \
+ switch (YYE) { \
+ case yyok: break; \
+ case yyabort: goto yyabortlab; \
+ case yyaccept: goto yyacceptlab; \
+ case yyerr: goto yyuser_error; \
+ case yynomem: goto yyexhaustedlab; \
+ default: goto yybuglab; \
+ } \
} while (0)
/*----------.
@@ -2420,7 +2439,7 @@ yyrecoverSyntaxError (yyGLRStack* yystackp]b4_user_formals[)
`----------*/
int
-yyparse (]m4_ifset([b4_parse_param], [b4_formals(b4_parse_param)], [void])[)
+]b4_glr_cc_if([yy_parse_impl], [yyparse])[ (]m4_ifset([b4_parse_param], [b4_formals(b4_parse_param)], [void])[)
{
int yyresult;
yyGLRStack yystack;
@@ -2429,7 +2448,7 @@ yyparse (]m4_ifset([b4_parse_param], [b4_formals(b4_parse_param)], [void])[)
YY_DPRINTF ((stderr, "Starting parse\n"));
- yychar = ]b4_symbol(-2, id)[;
+ yychar = ]b4_symbol(empty, id)[;
yylval = yyval_default;]b4_locations_if([
yylloc = yyloc_default;])[
]m4_ifdef([b4_initial_action], [
@@ -2483,7 +2502,7 @@ b4_dollar_popdef])[]dnl
if (yyisShiftAction (yyaction))
{
YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
- yychar = ]b4_symbol(-2, id)[;
+ yychar = ]b4_symbol(empty, id)[;
yyposn += 1;
yyglrShift (&yystack, 0, yyaction, yyposn, &yylval]b4_locations_if([, &yylloc])[);
if (0 < yystack.yyerrState)
@@ -2494,7 +2513,7 @@ b4_dollar_popdef])[]dnl
yystack.yyerror_range[1].yystate.yyloc = yylloc;]])[
/* Issue an error message unless the scanner already
did. */
- if (yychar != ]b4_symbol(1, id)[)
+ if (yychar != ]b4_symbol(error, id)[)
yyreportSyntaxError (&yystack]b4_user_args[);
goto yyuser_error;
}
@@ -2510,7 +2529,7 @@ b4_dollar_popdef])[]dnl
YYPTRDIFF_T yys;
for (yys = 0; yys < yystack.yytops.yysize; yys += 1)
- yystackp->yytops.yylookaheadNeeds[yys] = yychar != ]b4_symbol(-2, id)[;
+ yystackp->yytops.yylookaheadNeeds[yys] = yychar != ]b4_symbol(empty, id)[;
/* yyprocessOneStack returns one of three things:
@@ -2548,11 +2567,11 @@ b4_dollar_popdef])[]dnl
/* If any yyglrShift call fails, it will fail after shifting. Thus,
a copy of yylval will already be on stack 0 in the event of a
- failure in the following loop. Thus, yychar is set to ]b4_symbol(-2, id)[
+ failure in the following loop. Thus, yychar is set to ]b4_symbol(empty, id)[
before the loop to make sure the user destructor for yylval isn't
called twice. */
yytoken_to_shift = YYTRANSLATE (yychar);
- yychar = ]b4_symbol(-2, id)[;
+ yychar = ]b4_symbol(empty, id)[;
yyposn += 1;
for (yys = 0; yys < yystack.yytops.yysize; yys += 1)
{
@@ -2565,7 +2584,7 @@ b4_dollar_popdef])[]dnl
YY_SYMBOL_PRINT ("shifting", yytoken_to_shift, &yylval, &yylloc);
yyglrShift (&yystack, yys, yyaction, yyposn,
&yylval]b4_locations_if([, &yylloc])[);
- YY_DPRINTF ((stderr, "Stack %ld now in state #%d\n",
+ YY_DPRINTF ((stderr, "Stack %ld now in state %d\n",
YY_CAST (long, yys),
yystack.yytops.yystates[yys]->yylrState));
}
@@ -2586,7 +2605,7 @@ b4_dollar_popdef])[]dnl
yyacceptlab:
yyresult = 0;
- goto yyreturn;
+ goto yyreturnlab;
yybuglab:
YY_ASSERT (yyfalse);
@@ -2594,15 +2613,15 @@ b4_dollar_popdef])[]dnl
yyabortlab:
yyresult = 1;
- goto yyreturn;
+ goto yyreturnlab;
yyexhaustedlab:
yyerror (]b4_lyyerror_args[YY_("memory exhausted"));
yyresult = 2;
- goto yyreturn;
+ goto yyreturnlab;
- yyreturn:
- if (yychar != ]b4_symbol(-2, id)[)
+ yyreturnlab:
+ if (yychar != ]b4_symbol(empty, id)[)
yydestruct ("Cleanup: discarding lookahead",
YYTRANSLATE (yychar), &yylval]b4_locuser_args([&yylloc])[);
@@ -2640,6 +2659,7 @@ b4_dollar_popdef])[]dnl
/* DEBUGGING ONLY */
#if ]b4_api_PREFIX[DEBUG
+/* Print *YYS and its predecessors. */
static void
yy_yypstack (yyGLRState* yys)
{
@@ -2651,22 +2671,25 @@ yy_yypstack (yyGLRState* yys)
YY_FPRINTF ((stderr, "%d@@%ld", yys->yylrState, YY_CAST (long, yys->yyposn)));
}
+/* Print YYS (possibly NULL) and its predecessors. */
static void
-yypstates (yyGLRState* yyst)
+yypstates (yyGLRState* yys)
{
- if (yyst == YY_NULLPTR)
+ if (yys == YY_NULLPTR)
YY_FPRINTF ((stderr, ""));
else
- yy_yypstack (yyst);
+ yy_yypstack (yys);
YY_FPRINTF ((stderr, "\n"));
}
+/* Print the stack #YYK. */
static void
yypstack (yyGLRStack* yystackp, YYPTRDIFF_T yyk)
{
yypstates (yystackp->yytops.yystates[yyk]);
}
+/* Print all the stacks. */
static void
yypdumpstack (yyGLRStack* yystackp)
{
diff --git a/bison/data/skeletons/glr.cc b/bison/data/skeletons/glr.cc
index 8ba34fc..7181402 100644
--- a/bison/data/skeletons/glr.cc
+++ b/bison/data/skeletons/glr.cc
@@ -1,6 +1,6 @@
# C++ GLR skeleton for Bison
-# Copyright (C) 2002-2015, 2018-2020 Free Software Foundation, Inc.
+# Copyright (C) 2002-2015, 2018-2021 Free Software Foundation, Inc.
# 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
@@ -13,7 +13,7 @@
# 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 .
+# along with this program. If not, see .
# This skeleton produces a C++ class that encapsulates a C glr parser.
@@ -78,7 +78,7 @@ m4_define([b4_yy_symbol_print_define],
static void
yy_symbol_print (FILE *, ]b4_namespace_ref::b4_parser_class[::symbol_kind_type yytoken,
- const ]b4_namespace_ref::b4_parser_class[::semantic_type *yyvaluep]b4_locations_if([[,
+ const ]b4_namespace_ref::b4_parser_class[::value_type *yyvaluep]b4_locations_if([[,
const ]b4_namespace_ref::b4_parser_class[::location_type *yylocationp]])[]b4_user_formals[)
{
]b4_parse_param_use[]dnl
@@ -144,7 +144,7 @@ m4_pushdef([b4_parse_param], m4_defn([b4_parse_param_orig]))dnl
int
]b4_parser_class[::parse ()
{
- return ::yyparse (*this]b4_user_args[);
+ return ::yy_parse_impl (*this]b4_user_args[);
}
#if ]b4_api_PREFIX[DEBUG
@@ -154,21 +154,21 @@ m4_pushdef([b4_parse_param], m4_defn([b4_parse_param_orig]))dnl
void
]b4_parser_class[::yy_symbol_value_print_ (symbol_kind_type yykind,
- const semantic_type* yyvaluep]b4_locations_if([[,
+ const value_type* yyvaluep]b4_locations_if([[,
const location_type* yylocationp]])[) const
{]b4_locations_if([[
- YYUSE (yylocationp);]])[
- YYUSE (yyvaluep);
+ YY_USE (yylocationp);]])[
+ YY_USE (yyvaluep);
std::ostream& yyo = debug_stream ();
std::ostream& yyoutput = yyo;
- YYUSE (yyoutput);
+ YY_USE (yyoutput);
]b4_symbol_actions([printer])[
}
void
]b4_parser_class[::yy_symbol_print_ (symbol_kind_type yykind,
- const semantic_type* yyvaluep]b4_locations_if([[,
+ const value_type* yyvaluep]b4_locations_if([[,
const location_type* yylocationp]])[) const
{
*yycdebug_ << (yykind < YYNTOKENS ? "token" : "nterm")
@@ -221,15 +221,33 @@ m4_define([b4_define_symbol_kind],
# Setup redirections for glr.c: Map the names used in c.m4 to the ones used
# in c++.m4.
m4_define([b4_glr_cc_setup],
-[[#undef ]b4_symbol(-2, [id])[
-#define ]b4_symbol(-2, [id])[ ]b4_namespace_ref[::]b4_parser_class[::token::]b4_symbol(-2, [id])[
-#undef ]b4_symbol(0, [id])[
-#define ]b4_symbol(0, [id])[ ]b4_namespace_ref[::]b4_parser_class[::token::]b4_symbol(0, [id])[
-#undef ]b4_symbol(1, [id])[
-#define ]b4_symbol(1, [id])[ ]b4_namespace_ref[::]b4_parser_class[::token::]b4_symbol(1, [id])[
+[[]b4_attribute_define[
+]b4_null_define[
+
+// This skeleton is based on C, yet compiles it as C++.
+// So expect warnings about C style casts.
+#if defined __clang__ && 306 <= __clang_major__ * 100 + __clang_minor__
+# pragma clang diagnostic ignored "-Wold-style-cast"
+#elif defined __GNUC__ && 406 <= __GNUC__ * 100 + __GNUC_MINOR__
+# pragma GCC diagnostic ignored "-Wold-style-cast"
+#endif
+
+// On MacOS, PTRDIFF_MAX is defined as long long, which Clang's
+// -pedantic reports as being a C++11 extension.
+#if defined __APPLE__ && YY_CPLUSPLUS < 201103L \
+ && defined __clang__ && 4 <= __clang_major__
+# pragma clang diagnostic ignored "-Wc++11-long-long"
+#endif
+
+#undef ]b4_symbol(empty, [id])[
+#define ]b4_symbol(empty, [id])[ ]b4_namespace_ref[::]b4_parser_class[::token::]b4_symbol(empty, [id])[
+#undef ]b4_symbol(eof, [id])[
+#define ]b4_symbol(eof, [id])[ ]b4_namespace_ref[::]b4_parser_class[::token::]b4_symbol(eof, [id])[
+#undef ]b4_symbol(error, [id])[
+#define ]b4_symbol(error, [id])[ ]b4_namespace_ref[::]b4_parser_class[::token::]b4_symbol(error, [id])[
#ifndef ]b4_api_PREFIX[STYPE
-# define ]b4_api_PREFIX[STYPE ]b4_namespace_ref[::]b4_parser_class[::semantic_type
+# define ]b4_api_PREFIX[STYPE ]b4_namespace_ref[::]b4_parser_class[::value_type
#endif
#ifndef ]b4_api_PREFIX[LTYPE
# define ]b4_api_PREFIX[LTYPE ]b4_namespace_ref[::]b4_parser_class[::location_type
@@ -252,9 +270,9 @@ m4_define([b4_undef_symbol_kind],
# -----------------
# Remove redirections for glr.c.
m4_define([b4_glr_cc_cleanup],
-[[#undef ]b4_symbol(-2, [id])[
-#undef ]b4_symbol(0, [id])[
-#undef ]b4_symbol(1, [id])[
+[[#undef ]b4_symbol(empty, [id])[
+#undef ]b4_symbol(eof, [id])[
+#undef ]b4_symbol(error, [id])[
]b4_undef_symbol_kind(-2)dnl
b4_symbol_foreach([b4_undef_symbol_kind])dnl
@@ -263,7 +281,7 @@ b4_symbol_foreach([b4_undef_symbol_kind])dnl
# b4_shared_declarations(hh|cc)
# -----------------------------
-# Declaration that might either go into the header (if --defines, $1 = hh)
+# Declaration that might either go into the header (if --header, $1 = hh)
# or in the implementation file.
m4_define([b4_shared_declarations],
[m4_pushdef([b4_parse_param], m4_defn([b4_parse_param_orig]))dnl
@@ -277,24 +295,6 @@ b4_percent_code_get([[requires]])[
[[# include ]b4_location_include])[
]b4_variant_if([b4_variant_includes])[
-]b4_attribute_define[
-]b4_null_define[
-
-// This skeleton is based on C, yet compiles it as C++.
-// So expect warnings about C style casts.
-#if defined __clang__ && 306 <= __clang_major__ * 100 + __clang_minor__
-# pragma clang diagnostic ignored "-Wold-style-cast"
-#elif defined __GNUC__ && 406 <= __GNUC__ * 100 + __GNUC_MINOR__
-# pragma GCC diagnostic ignored "-Wold-style-cast"
-#endif
-
-// On MacOS, PTRDIFF_MAX is defined as long long, which Clang's
-// -pedantic reports as being a C++11 extension.
-#if defined __APPLE__ && YY_CPLUSPLUS < 201103L \
- && defined __clang__ && 4 <= __clang_major__
-# pragma clang diagnostic ignored "-Wc++11-long-long"
-#endif
-
// Whether we are compiled with exception support.
#ifndef YY_EXCEPTIONS
# if defined __GNUC__ && !defined __EXCEPTIONS
@@ -355,14 +355,14 @@ b4_percent_code_get([[requires]])[
/// \param yyvaluep Its semantic value.]b4_locations_if([[
/// \param yylocationp Its location.]])[
virtual void yy_symbol_value_print_ (symbol_kind_type yykind,
- const semantic_type* yyvaluep]b4_locations_if([[,
+ const value_type* yyvaluep]b4_locations_if([[,
const location_type* yylocationp]])[) const;
/// \brief Report a symbol on the debug stream.
/// \param yykind The symbol kind.
/// \param yyvaluep Its semantic value.]b4_locations_if([[
/// \param yylocationp Its location.]])[
virtual void yy_symbol_print_ (symbol_kind_type yykind,
- const semantic_type* yyvaluep]b4_locations_if([[,
+ const value_type* yyvaluep]b4_locations_if([[,
const location_type* yylocationp]])[) const;
private:
/// Debug stream.
@@ -378,10 +378,10 @@ b4_percent_code_get([[requires]])[
]m4_popdef([b4_parse_param])dnl
])[
-]b4_defines_if(
+]b4_header_if(
[b4_output_begin([b4_spec_header_file])
b4_copyright([Skeleton interface for Bison GLR parsers in C++],
- [2002-2015, 2018-2020])[
+ [2002-2015, 2018-2021])[
// C++ GLR parser skeleton written by Akim Demaille.
]b4_disclaimer[
diff --git a/bison/data/skeletons/glr2.cc b/bison/data/skeletons/glr2.cc
new file mode 100644
index 0000000..757d68d
--- /dev/null
+++ b/bison/data/skeletons/glr2.cc
@@ -0,0 +1,3533 @@
+# C++ GLR skeleton for Bison
+
+# Copyright (C) 2002-2015, 2018-2021 Free Software Foundation, Inc.
+
+# 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 .
+
+m4_include(b4_skeletonsdir/[c++.m4])
+
+# api.value.type=variant is valid.
+m4_define([b4_value_type_setup_variant])
+
+# b4_tname_if(TNAME-NEEDED, TNAME-NOT-NEEDED)
+# -------------------------------------------
+m4_define([b4_tname_if],
+[m4_case(b4_percent_define_get([[parse.error]]),
+ [verbose], [$1],
+ [b4_token_table_if([$1],
+ [$2])])])
+
+b4_bison_locations_if([
+ m4_define([b4_location_constructors])
+ m4_include(b4_skeletonsdir/[location.cc])])
+b4_variant_if([m4_include(b4_skeletonsdir/[variant.hh])])
+
+m4_define([b4_parser_class],
+ [b4_percent_define_get([[api.parser.class]])])
+
+]m4_define([b4_define_symbol_kind],
+[m4_format([#define %-15s %s],
+ b4_symbol($][1, kind_base),
+ b4_namespace_ref[::]b4_parser_class[::symbol_kind::]b4_symbol($1, kind_base))
+])
+
+
+# b4_integral_parser_table_define(TABLE-NAME, CONTENT, COMMENT)
+# -------------------------------------------------------------
+# Define "yy" whose contents is CONTENT. Does not use "static",
+# should be in unnamed namespace.
+m4_define([b4_integral_parser_table_define],
+[m4_ifvaln([$3], [ b4_comment([$3])])dnl
+ const b4_int_type_for([$2]) yy$1[[]] =
+ {
+ $2
+ };dnl
+])
+
+
+## ---------------- ##
+## Default values. ##
+## ---------------- ##
+
+# Stack parameters.
+m4_define_default([b4_stack_depth_max], [10000])
+m4_define_default([b4_stack_depth_init], [200])
+
+
+
+## ------------ ##
+## Interfaces. ##
+## ------------ ##
+
+# b4_user_formals
+# ---------------
+# The possible parse-params formal arguments preceded by a comma.
+#
+# This is not shared with yacc.c in c.m4 because GLR relies on ISO C
+# formal argument declarations.
+m4_define([b4_user_formals],
+[m4_ifset([b4_parse_param], [, b4_formals(b4_parse_param)])])
+
+
+# b4_symbol_kind(NUM)
+# -------------------
+m4_define([b4_symbol_kind],
+[symbol_kind::b4_symbol_kind_base($@)])
+
+
+## ----------------- ##
+## Semantic Values. ##
+## ----------------- ##
+
+
+# b4_lhs_value(SYMBOL-NUM, [TYPE])
+# --------------------------------
+# See README.
+m4_define([b4_lhs_value],
+[b4_symbol_value([(*yyvalp)], [$1], [$2])])
+
+
+# b4_rhs_data(RULE-LENGTH, POS)
+# -----------------------------
+# See README.
+m4_define([b4_rhs_data],
+[(static_cast(yyvsp))@{YYFILL (b4_subtract([$2], [$1]))@}.getState()])
+
+
+# b4_rhs_value(RULE-LENGTH, POS, SYMBOL-NUM, [TYPE])
+# --------------------------------------------------
+# Expansion of $$ or $$, for symbol SYMBOL-NUM.
+m4_define([b4_rhs_value],
+[b4_symbol_value([b4_rhs_data([$1], [$2]).value ()], [$3], [$4])])
+
+
+
+## ----------- ##
+## Locations. ##
+## ----------- ##
+
+# b4_lhs_location()
+# -----------------
+# Expansion of @$.
+m4_define([b4_lhs_location],
+[(*yylocp)])
+
+
+# b4_rhs_location(RULE-LENGTH, NUM)
+# ---------------------------------
+# Expansion of @NUM, where the current rule has RULE-LENGTH symbols
+# on RHS.
+m4_define([b4_rhs_location],
+[(b4_rhs_data([$1], [$2]).yyloc)])
+
+
+# b4_symbol_action(SYMBOL-NUM, KIND)
+# ----------------------------------
+# Run the action KIND (destructor or printer) for SYMBOL-NUM.
+# Same as in C, but using references instead of pointers.
+#
+# Currently we need two different b4_symbol_action: once for the
+# self-contained symbols, and another time for yy_destroy_ and
+# yy_symbol_value_print_, which don't use genuine symbols yet.
+m4_define([b4_symbol_action],
+[b4_symbol_if([$1], [has_$2],
+[m4_pushdef([b4_symbol_value], m4_defn([b4_symbol_value_template]))[]dnl
+b4_dollar_pushdef([yysym.value],
+ [$1],
+ [],
+ [yysym.location])dnl
+ _b4_symbol_case([$1])[]dnl
+b4_syncline([b4_symbol([$1], [$2_line])], [b4_symbol([$1], [$2_file])])dnl
+ b4_symbol([$1], [$2])
+b4_syncline([@oline@], [@ofile@])dnl
+ break;
+
+m4_popdef([b4_symbol_value])[]dnl
+b4_dollar_popdef[]dnl
+])])
+
+
+# b4_symbol_action_for_yyval(SYMBOL-NUM, KIND)
+# --------------------------------------------
+# Run the action KIND (destructor or printer) for SYMBOL-NUM.
+# Same as in C, but using references instead of pointers.
+m4_define([b4_symbol_action_for_yyval],
+[b4_symbol_if([$1], [has_$2],
+[b4_dollar_pushdef([yyval],
+ [$1],
+ [],
+ [yyloc])dnl
+ _b4_symbol_case([$1])[]dnl
+b4_syncline([b4_symbol([$1], [$2_line])], [b4_symbol([$1], [$2_file])])dnl
+ b4_symbol([$1], [$2])
+b4_syncline([@oline@], [@ofile@])dnl
+ break;
+
+b4_dollar_popdef[]dnl
+])])
+
+
+# b4_call_merger(MERGER-NUM, MERGER-NAME, SYMBOL-SUM)
+# ---------------------------------------------------
+m4_define([b4_call_merger],
+[b4_case([$1],
+ [ b4_symbol_if([$3], [has_type],
+ [b4_variant_if([yy0.as< b4_symbol($3, type) > () = $2 (yy0.as< b4_symbol($3, type) >(), yy1.as< b4_symbol($3, type) >());],
+ [yy0.b4_symbol($3, slot) = $2 (yy0, yy1);])],
+ [yy0 = $2 (yy0, yy1);])])])
+
+# b4_yylex
+# --------
+# Call yylex.
+m4_define([b4_yylex],
+[b4_token_ctor_if(
+[b4_function_call([yylex],
+ [symbol_type], m4_ifdef([b4_lex_param], b4_lex_param))],
+[b4_function_call([yylex], [int],
+ [[value_type *], [&this->yyla.value]][]dnl
+b4_locations_if([, [[location_type *], [&this->yyla.location]]])dnl
+m4_ifdef([b4_lex_param], [, ]b4_lex_param))])])
+
+
+# b4_shared_declarations(hh|cc)
+# -----------------------------
+# Declaration that might either go into the header (if --header, $1 = hh)
+# or in the implementation file.
+m4_define([b4_shared_declarations],
+[b4_percent_code_get([[requires]])[
+#include
+#include // ptrdiff_t
+#include // memcpy
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+]b4_cxx_portability[
+]m4_ifdef([b4_location_include],
+ [[# include ]b4_location_include])[
+]b4_variant_if([b4_variant_includes])[
+
+]b4_YYDEBUG_define[
+
+]b4_namespace_open[
+
+]b4_bison_locations_if([m4_ifndef([b4_location_file],
+ [b4_location_define])])[
+
+ /// A Bison parser.
+ class ]b4_parser_class[
+ {
+ public:
+]b4_public_types_declare[
+]b4_symbol_type_define[
+
+ // FIXME: should be private eventually.
+ class glr_stack;
+ class glr_state;
+
+ /// Build a parser object.
+ ]b4_parser_class[ (]b4_parse_param_decl[);
+ ~]b4_parser_class[ ();
+
+ /// Parse. An alias for parse ().
+ /// \returns 0 iff parsing succeeded.
+ int operator() ();
+
+ /// Parse.
+ /// \returns 0 iff parsing succeeded.
+ int parse ();
+
+#if ]b4_api_PREFIX[DEBUG
+ /// The current debugging stream.
+ std::ostream& debug_stream () const;
+ /// Set the current debugging stream.
+ void set_debug_stream (std::ostream &);
+
+ /// Type for debugging levels.
+ using debug_level_type = int;
+ /// The current debugging level.
+ debug_level_type debug_level () const;
+ /// Set the current debugging level.
+ void set_debug_level (debug_level_type l);
+#endif
+
+ /// Report a syntax error.]b4_locations_if([[
+ /// \param loc where the syntax error is found.]])[
+ /// \param msg a description of the syntax error.
+ void error (]b4_locations_if([[const location_type& loc, ]])[const std::string& msg);
+
+]b4_parse_error_bmatch(
+[custom\|detailed],
+[[ /// The user-facing name of the symbol whose (internal) number is
+ /// YYSYMBOL. No bounds checking.
+ static const char *symbol_name (symbol_kind_type yysymbol);]],
+[simple],
+[[#if ]b4_api_PREFIX[DEBUG || ]b4_token_table_flag[
+ /// The user-facing name of the symbol whose (internal) number is
+ /// YYSYMBOL. No bounds checking.
+ static const char *symbol_name (symbol_kind_type yysymbol);
+#endif // #if ]b4_api_PREFIX[DEBUG || ]b4_token_table_flag[
+]],
+[verbose],
+[[ /// The user-facing name of the symbol whose (internal) number is
+ /// YYSYMBOL. No bounds checking.
+ static std::string symbol_name (symbol_kind_type yysymbol);]])[
+
+]b4_token_constructor_define[
+]b4_parse_error_bmatch([custom\|detailed\|verbose], [[
+ class context
+ {
+ public:
+ context (glr_stack& yystack, const symbol_type& yyla);
+ const symbol_type& lookahead () const YY_NOEXCEPT { return yyla_; }
+ symbol_kind_type token () const YY_NOEXCEPT { return yyla_.kind (); }]b4_locations_if([[
+ const location_type& location () const YY_NOEXCEPT { return yyla_.location; }
+]])[
+ /// Put in YYARG at most YYARGN of the expected tokens, and return the
+ /// number of tokens stored in YYARG. If YYARG is null, return the
+ /// number of expected tokens (guaranteed to be less than YYNTOKENS).
+ int expected_tokens (symbol_kind_type yyarg[], int yyargn) const;
+
+ private:
+ glr_stack& yystack_;
+ const symbol_type& yyla_;
+ };
+]])[
+# if ]b4_api_PREFIX[DEBUG
+ public:
+ /// \brief Report a symbol value on the debug stream.
+ /// \param yykind The symbol kind.
+ /// \param yyval Its semantic value.]b4_locations_if([[
+ /// \param yyloc Its location.]])[
+ void yy_symbol_value_print_ (symbol_kind_type yykind,
+ const value_type& yyval]b4_locations_if([[,
+ const location_type& yyloc]])[) const;
+ /// \brief Report a symbol on the debug stream.
+ /// \param yykind The symbol kind.
+ /// \param yyval Its semantic value.]b4_locations_if([[
+ /// \param yyloc Its location.]])[
+ void yy_symbol_print_ (symbol_kind_type yykind,
+ const value_type& yyval]b4_locations_if([[,
+ const location_type& yyloc]])[) const;
+ private:
+ /// Debug stream.
+ std::ostream* yycdebug_;
+#endif
+
+]b4_parse_error_bmatch(
+[custom], [[
+ private:
+ /// Report a syntax error
+ /// \param yyctx the context in which the error occurred.
+ void report_syntax_error (const context& yyctx) const;]],
+[detailed\|verbose], [[
+ private:
+ /// The arguments of the error message.
+ int yy_syntax_error_arguments_ (const context& yyctx,
+ symbol_kind_type yyarg[], int yyargn) const;
+
+ /// Generate an error message.
+ /// \param yyctx the context in which the error occurred.
+ virtual std::string yysyntax_error_ (const context& yyctx) const;]])[
+
+ /// 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_kind_type enum.
+ static symbol_kind_type yytranslate_ (int t) YY_NOEXCEPT;
+
+]b4_parse_error_bmatch(
+[simple],
+[[#if ]b4_api_PREFIX[DEBUG || ]b4_token_table_flag[
+ /// For a symbol, its name in clear.
+ static const char* const yytname_[];
+#endif // #if ]b4_api_PREFIX[DEBUG || ]b4_token_table_flag[
+]],
+[verbose],
+[[ /// Convert the symbol name \a n to a form suitable for a diagnostic.
+ static std::string yytnamerr_ (const char *yystr);
+
+ /// For a symbol, its name in clear.
+ static const char* const yytname_[];
+]])[
+
+ /// \brief Reclaim the memory associated to a symbol.
+ /// \param yymsg Why this token is reclaimed.
+ /// If null, print nothing.
+ /// \param yykind The symbol kind.
+ void yy_destroy_ (const char* yymsg, symbol_kind_type yykind,
+ value_type& yyval]b4_locations_if([[,
+ location_type& yyloc]])[);
+
+]b4_parse_param_vars[
+ // Needs access to yy_destroy_, report_syntax_error, etc.
+ friend glr_stack;
+ };
+
+]b4_token_ctor_if([b4_yytranslate_define([$1])[
+]b4_public_types_define([$1])])[
+]b4_namespace_close[
+
+]b4_percent_code_get([[provides]])[
+]])[
+
+
+## -------------- ##
+## Output files. ##
+## -------------- ##
+
+
+# ------------- #
+# Header file. #
+# ------------- #
+
+]b4_header_if([[
+]b4_output_begin([b4_spec_header_file])[
+]b4_copyright([Skeleton interface for Bison GLR parsers in C++],
+ [2002-2015, 2018-2021])[
+// C++ GLR parser skeleton written by Valentin Tolmer.
+
+]b4_disclaimer[
+]b4_cpp_guard_open([b4_spec_mapped_header_file])[
+]b4_shared_declarations([hh])[
+]b4_cpp_guard_close([b4_spec_mapped_header_file])[
+]b4_output_end])[
+
+
+# --------------------- #
+# Implementation file. #
+# --------------------- #
+
+]b4_output_begin([b4_parser_file_name])[
+]b4_copyright([Skeleton implementation for Bison GLR parsers in C],
+ [2002-2015, 2018-2021])[
+// C++ GLR parser skeleton written by Valentin Tolmer.
+
+]b4_disclaimer[
+]b4_identification[
+
+]b4_percent_code_get([[top]])[
+]m4_if(b4_prefix, [yy], [],
+[[/* Substitute the variable and function names. */
+#define yyparse ]b4_prefix[parse
+#define yylex ]b4_prefix[lex
+#define yyerror ]b4_prefix[error
+#define yydebug ]b4_prefix[debug]])[
+
+]b4_user_pre_prologue[
+
+]b4_null_define[
+
+]b4_header_if([[#include "@basename(]b4_spec_header_file[@)"]],
+ [b4_shared_declarations([cc])])[
+
+namespace
+{
+ /* Default (constant) value used for initialization for null
+ right-hand sides. Unlike the standard yacc.c template, here we set
+ the default value of $$ to a zeroed-out value. Since the default
+ value is undefined, this behavior is technically correct. */
+ ]b4_namespace_ref[::]b4_parser_class[::value_type yyval_default;
+}
+
+]b4_user_post_prologue[
+]b4_percent_code_get[
+
+#include
+#include
+
+#ifndef YY_
+# if defined YYENABLE_NLS && YYENABLE_NLS
+# if ENABLE_NLS
+# include /* INFRINGES ON USER NAME SPACE */
+# define YY_(Msgid) dgettext ("bison-runtime", Msgid)
+# endif
+# endif
+# ifndef YY_
+# define YY_(Msgid) Msgid
+# endif
+#endif
+
+// Whether we are compiled with exception support.
+#ifndef YY_EXCEPTIONS
+# if defined __GNUC__ && !defined __EXCEPTIONS
+# define YY_EXCEPTIONS 0
+# else
+# define YY_EXCEPTIONS 1
+# endif
+#endif
+
+#ifndef YYFREE
+# define YYFREE free
+#endif
+#ifndef YYMALLOC
+# define YYMALLOC malloc
+#endif
+
+#ifndef YYSETJMP
+# include
+# define YYJMP_BUF jmp_buf
+# define YYSETJMP(Env) setjmp (Env)
+/* Pacify Clang and ICC. */
+# define YYLONGJMP(Env, Val) \
+ do { \
+ longjmp (Env, Val); \
+ YYASSERT (0); \
+ } while (false)
+#endif
+
+]b4_attribute_define([noreturn])[
+
+#if defined __GNUC__ && ! defined __ICC && 6 <= __GNUC__
+# define YY_IGNORE_NULL_DEREFERENCE_BEGIN \
+ _Pragma ("GCC diagnostic push") \
+ _Pragma ("GCC diagnostic ignored \"-Wnull-dereference\"")
+# define YY_IGNORE_NULL_DEREFERENCE_END \
+ _Pragma ("GCC diagnostic pop")
+#else
+# define YY_IGNORE_NULL_DEREFERENCE_BEGIN
+# define YY_IGNORE_NULL_DEREFERENCE_END
+#endif
+
+]b4_null_define[
+]b4_cast_define[
+
+// FIXME: Use the same conventions as lalr1.cc.
+]b4_parse_assert_if[
+#ifndef YYASSERT
+# define YYASSERT(Condition) ((void) ((Condition) || (abort (), 0)))
+#endif
+
+#ifdef YYDEBUG
+# define YYDASSERT(Condition) YYASSERT(Condition)
+#else
+# define YYDASSERT(Condition)
+#endif
+
+/* YYFINAL -- State number of the termination state. */
+#define YYFINAL ]b4_final_state_number[
+/* YYLAST -- Last index in YYTABLE. */
+#define YYLAST ]b4_last[
+
+/* YYNTOKENS -- Number of terminals. */
+#define YYNTOKENS ]b4_tokens_number[
+/* YYNNTS -- Number of nonterminals. */
+#define YYNNTS ]b4_nterms_number[
+/* YYNRULES -- Number of rules. */
+#define YYNRULES ]b4_rules_number[
+/* YYNSTATES -- Number of states. */
+#define YYNSTATES ]b4_states_number[
+/* YYMAXRHS -- Maximum number of symbols on right-hand side of rule. */
+#define YYMAXRHS ]b4_r2_max[
+/* YYMAXLEFT -- Maximum number of symbols to the left of a handle
+ accessed by $0, $-1, etc., in any rule. */
+#define YYMAXLEFT ]b4_max_left_semantic_context[
+
+namespace
+{
+#if ]b4_api_PREFIX[DEBUG
+ /* YYRLINE[YYN] -- source line where rule number YYN was defined. */
+ const ]b4_int_type_for([b4_rline])[ yyrline[] =
+ {
+ ]b4_rline[
+ };
+#endif
+
+#define YYPACT_NINF ]b4_pact_ninf[
+#define YYTABLE_NINF ]b4_table_ninf[
+
+]b4_parser_tables_define[
+
+ /* YYDPREC[RULE-NUM] -- Dynamic precedence of rule #RULE-NUM (0 if none). */
+ const ]b4_int_type_for([b4_dprec])[ yydprec[] =
+ {
+ ]b4_dprec[
+ };
+
+ /* YYMERGER[RULE-NUM] -- Index of merging function for rule #RULE-NUM. */
+ const ]b4_int_type_for([b4_merger])[ yymerger[] =
+ {
+ ]b4_merger[
+ };
+
+ /* YYIMMEDIATE[RULE-NUM] -- True iff rule #RULE-NUM is not to be deferred, as
+ in the case of predicates. */
+ const bool yyimmediate[] =
+ {
+ ]b4_immediate[
+ };
+
+ /* YYCONFLP[YYPACT[STATE-NUM]] -- Pointer into YYCONFL of start of
+ list of conflicting reductions corresponding to action entry for
+ state STATE-NUM in yytable. 0 means no conflicts. The list in
+ yyconfl is terminated by a rule number of 0. */
+ const ]b4_int_type_for([b4_conflict_list_heads])[ yyconflp[] =
+ {
+ ]b4_conflict_list_heads[
+ };
+
+ /* YYCONFL[I] -- lists of conflicting rule numbers, each terminated by
+ 0, pointed into by YYCONFLP. */
+ ]dnl Do not use b4_int_type_for here, since there are places where
+ dnl pointers onto yyconfl are taken, whose type is "short*".
+ dnl We probably ought to introduce a type for confl.
+ [const short yyconfl[] =
+ {
+ ]b4_conflicting_rules[
+ };
+} // namespace
+
+
+/* Error token number */
+#define YYTERROR 1
+
+]b4_locations_if([[
+]b4_yylloc_default_define[
+# define YYRHSLOC(Rhs, K) ((Rhs)[K].getState().yyloc)
+]])[
+
+enum YYRESULTTAG { yyok, yyaccept, yyabort, yyerr };
+
+#define YYCHK(YYE) \
+ do { \
+ YYRESULTTAG yychk_flag = YYE; \
+ if (yychk_flag != yyok) \
+ return yychk_flag; \
+ } while (false)
+
+#if ]b4_api_PREFIX[DEBUG
+
+#define YYCDEBUG if (!yydebug) {} else std::cerr
+
+# define YY_SYMBOL_PRINT(Title, Kind, Value, Location) \
+ do { \
+ if (yydebug) \
+ { \
+ std::cerr << Title << ' '; \
+ yyparser.yy_symbol_print_ (Kind, Value]b4_locations_if([, Location])[); \
+ std::cerr << '\n'; \
+ } \
+ } while (false)
+
+# define YY_REDUCE_PRINT(Args) \
+ do { \
+ if (yydebug) \
+ yystateStack.yy_reduce_print Args; \
+ } while (false)
+
+/* Nonzero means print parse trace. It is left uninitialized so that
+ multiple parsers can coexist. */
+int yydebug;
+
+namespace
+{
+ using glr_stack = ]b4_namespace_ref[::]b4_parser_class[::glr_stack;
+ using glr_state = ]b4_namespace_ref[::]b4_parser_class[::glr_state;
+
+ void yypstack (const glr_stack& yystack, size_t yyk)
+ YY_ATTRIBUTE_UNUSED;
+ void yypdumpstack (const glr_stack& yystack)
+ YY_ATTRIBUTE_UNUSED;
+}
+
+#else /* !]b4_api_PREFIX[DEBUG */
+
+# define YYCDEBUG if (true) {} else std::cerr
+# define YY_SYMBOL_PRINT(Title, Kind, Value, Location) {}
+# define YY_REDUCE_PRINT(Args) {}
+
+#endif /* !]b4_api_PREFIX[DEBUG */
+
+/* YYINITDEPTH -- initial size of the parser's stacks. */
+#ifndef YYINITDEPTH
+# define YYINITDEPTH ]b4_stack_depth_init[
+#endif
+
+/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
+ if the built-in stack extension method is used).
+
+ Do not make this value too large; the results are undefined if
+ SIZE_MAX < YYMAXDEPTH * sizeof (GLRStackItem)
+ evaluated with infinite-precision integer arithmetic. */
+
+#ifndef YYMAXDEPTH
+# define YYMAXDEPTH ]b4_stack_depth_max[
+#endif
+
+/* Minimum number of free items on the stack allowed after an
+ allocation. This is to allow allocation and initialization
+ to be completed by functions that call yyexpandGLRStack before the
+ stack is expanded, thus insuring that all necessary pointers get
+ properly redirected to new data. */
+#define YYHEADROOM 2
+
+#ifndef YYSTACKEXPANDABLE
+# define YYSTACKEXPANDABLE 1
+#endif
+
+namespace
+{
+ template
+ class strong_index_alias
+ {
+ public:
+ static strong_index_alias create (std::ptrdiff_t value)
+ {
+ strong_index_alias result;
+ result.value_ = value;
+ return result;
+ }
+
+ std::ptrdiff_t const& get () const { return value_; }
+
+ size_t uget () const { return static_cast (value_); }
+
+ strong_index_alias operator+ (std::ptrdiff_t other) const
+ {
+ return strong_index_alias (get () + other);
+ }
+
+ void operator+= (std::ptrdiff_t other)
+ {
+ value_ += other;
+ }
+
+ strong_index_alias operator- (std::ptrdiff_t other)
+ {
+ return strong_index_alias (get () - other);
+ }
+
+ void operator-= (std::ptrdiff_t other)
+ {
+ value_ -= other;
+ }
+
+ size_t operator- (strong_index_alias other)
+ {
+ return strong_index_alias (get () - other.get ());
+ }
+
+ strong_index_alias& operator++ ()
+ {
+ ++value_;
+ return *this;
+ }
+
+ bool isValid () const
+ {
+ return value_ != INVALID_INDEX;
+ }
+
+ void setInvalid()
+ {
+ value_ = INVALID_INDEX;
+ }
+
+ bool operator== (strong_index_alias other)
+ {
+ return get () == other.get ();
+ }
+
+ bool operator!= (strong_index_alias other)
+ {
+ return get () != other.get ();
+ }
+
+ bool operator< (strong_index_alias other)
+ {
+ return get () < other.get ();
+ }
+
+ private:
+ static const std::ptrdiff_t INVALID_INDEX;
+
+ // WARNING: 0-initialized.
+ std::ptrdiff_t value_;
+ }; // class strong_index_alias
+
+ template
+ const std::ptrdiff_t strong_index_alias::INVALID_INDEX =
+ std::numeric_limits::max ();
+
+ using state_set_index = strong_index_alias;
+
+ state_set_index create_state_set_index (std::ptrdiff_t value)
+ {
+ return state_set_index::create (value);
+ }
+
+ /** State numbers, as in LALR(1) machine */
+ using state_num = int;
+
+ /** Rule numbers, as in LALR(1) machine */
+ using rule_num = int;
+
+ using parser_type = ]b4_namespace_ref[::]b4_parser_class[;
+ using glr_state = parser_type::glr_state;
+ using symbol_kind = parser_type::symbol_kind;
+ using symbol_kind_type = parser_type::symbol_kind_type;
+ using symbol_type = parser_type::symbol_type;
+ using value_type = parser_type::value_type;]b4_locations_if([[
+ using location_type = parser_type::location_type;]])[
+
+ // Forward declarations.
+ class glr_stack_item;
+ class semantic_option;
+} // namespace
+
+namespace
+{
+ /** Accessing symbol of state YYSTATE. */
+ inline symbol_kind_type
+ yy_accessing_symbol (state_num yystate)
+ {
+ return YY_CAST (symbol_kind_type, yystos[yystate]);
+ }
+
+ /** Left-hand-side symbol for rule #YYRULE. */
+ inline symbol_kind_type
+ yylhsNonterm (rule_num yyrule)
+ {
+ return static_cast(yyr1[yyrule]);
+ }
+
+ /** Number of symbols composing the right hand side of rule #RULE. */
+ inline int
+ yyrhsLength (rule_num yyrule)
+ {
+ return yyr2[yyrule];
+ }
+}
+
+namespace ]b4_namespace_ref[
+{
+ class ]b4_parser_class[::glr_state
+ {
+ public:
+ glr_state ()
+ : yyresolved (false)
+ , yylrState (0)
+ , yyposn (0)
+ , yypred (0)
+ , yyfirstVal (0)]b4_locations_if([[
+ , yyloc ()]])[]b4_parse_assert_if([[
+ , magic_ (MAGIC)]])[
+ {}
+
+ /// Build with a semantic value.
+ glr_state (state_num lrState, size_t posn, const value_type& val]b4_locations_if([[, const location_type& loc]])[)
+ : yyresolved (true)
+ , yylrState (lrState)
+ , yyposn (posn)
+ , yypred (0)
+ , yyval (]b4_variant_if([], [[val]])[)]b4_locations_if([[
+ , yyloc (loc)]])[]b4_parse_assert_if([[
+ , magic_ (MAGIC)]])[
+ {]b4_variant_if([[
+ ]b4_symbol_variant([yy_accessing_symbol (lrState)],
+ [yyval], [copy], [val])])[}
+
+ /// Build with a semantic option.
+ glr_state (state_num lrState, size_t posn)
+ : yyresolved (false)
+ , yylrState (lrState)
+ , yyposn (posn)
+ , yypred (0)
+ , yyfirstVal (0)]b4_locations_if([[
+ , yyloc ()]])[]b4_parse_assert_if([[
+ , magic_ (MAGIC)]])[
+ {}
+
+ glr_state (const glr_state& other)
+ : yyresolved (other.yyresolved)
+ , yylrState (other.yylrState)
+ , yyposn (other.yyposn)
+ , yypred (0)]b4_locations_if([[
+ , yyloc (other.yyloc)]])[]b4_parse_assert_if([[
+ , magic_ (MAGIC)]])[
+ {
+ setPred (other.pred ());
+ if (other.yyresolved)]b4_variant_if([[
+ {
+ new (&yyval) value_type ();
+ ]b4_symbol_variant([yy_accessing_symbol (other.yylrState)],
+ [yyval], [copy], [other.value ()])[
+ }]], [[
+ new (&yyval) value_type (other.value ());]])[
+ else
+ {
+ yyfirstVal = 0;
+ setFirstVal (other.firstVal ());
+ }]b4_parse_assert_if([[
+ check_();]])[
+ }
+
+ ~glr_state ()
+ {]b4_parse_assert_if([[
+ check_ ();]])[
+ if (yyresolved)
+ {]b4_variant_if([[
+ symbol_kind_type yykind = yy_accessing_symbol (yylrState);
+ // FIXME: User destructors.
+ // Value type destructor.
+ ]b4_symbol_variant([[yykind]], [[yyval]], [[template destroy]])])[
+ yyval.~value_type ();
+ }]b4_parse_assert_if([[
+ magic_ = 0;]])[
+ }
+
+ glr_state& operator= (const glr_state& other)
+ {]b4_parse_assert_if([[
+ check_ ();
+ other.check_ ();]])[
+ if (!yyresolved && other.yyresolved)
+ new (&yyval) value_type;
+ yyresolved = other.yyresolved;
+ yylrState = other.yylrState;
+ yyposn = other.yyposn;
+ setPred (other.pred ());
+ if (other.yyresolved)]b4_variant_if([[
+ ]b4_symbol_variant([yy_accessing_symbol (other.yylrState)],
+ [yyval], [copy], [other.value ()])], [[
+ value () = other.value ();]])[
+ else
+ setFirstVal (other.firstVal ());]b4_locations_if([[
+ yyloc = other.yyloc;]])[
+ return *this;
+ }
+
+ /** Type tag for the semantic value. If true, yyval applies, otherwise
+ * yyfirstVal applies. */
+ bool yyresolved;
+ /** Number of corresponding LALR(1) machine state. */
+ state_num yylrState;
+ /** Source position of the last token produced by my symbol */
+ size_t yyposn;
+
+ /// Only call pred() and setPred() on objects in yyitems, not temporaries.
+ glr_state* pred ();
+ const glr_state* pred () const;
+ void setPred (const glr_state* state);
+
+ /// Only call firstVal() and setFirstVal() on objects in yyitems, not
+ /// temporaries.
+ semantic_option* firstVal ();
+ const semantic_option* firstVal () const;
+ void setFirstVal (const semantic_option* option);
+
+ value_type& value ()
+ {]b4_parse_assert_if([[
+ check_ ();]])[
+ return yyval;
+ }
+
+ const value_type& value () const
+ {]b4_parse_assert_if([[
+ check_ ();]])[
+ return yyval;
+ }
+
+ void
+ destroy (char const *yymsg, ]b4_namespace_ref[::]b4_parser_class[& yyparser);
+
+ /* DEBUGGING ONLY */
+ #if ]b4_api_PREFIX[DEBUG
+ void yy_yypstack () const
+ {]b4_parse_assert_if([[
+ check_ ();]])[
+ if (pred () != YY_NULLPTR)
+ {
+ pred ()->yy_yypstack ();
+ std::cerr << " -> ";
+ }
+ std::cerr << yylrState << "@@" << yyposn;
+ }
+ #endif
+
+ std::ptrdiff_t indexIn (const glr_stack_item* array) const YY_ATTRIBUTE_UNUSED;
+
+ glr_stack_item* asItem ()
+ {]b4_parse_assert_if([[
+ check_ ();]])[
+ return asItem(this);
+ }
+
+ const glr_stack_item* asItem () const
+ {]b4_parse_assert_if([[
+ check_ ();]])[
+ return asItem (this);
+ }
+
+ private:
+ template
+ static const glr_stack_item* asItem (const T* state)
+ {
+ return reinterpret_cast(state);
+ }
+ template
+ static glr_stack_item* asItem (T* state)
+ {
+ return reinterpret_cast (state);
+ }
+ static const char *as_pointer_ (const glr_state *state)
+ {
+ return reinterpret_cast (state);
+ }
+ static char *as_pointer_ (glr_state *state)
+ {
+ return reinterpret_cast (state);
+ }
+ /** Preceding state in this stack */
+ std::ptrdiff_t yypred;
+ union {
+ /** First in a chain of alternative reductions producing the
+ * nonterminal corresponding to this state, threaded through
+ * yyfirstVal. Value "0" means empty. */
+ std::ptrdiff_t yyfirstVal;
+ /** Semantic value for this state. */
+ value_type yyval;
+ };]b4_locations_if([[
+ // FIXME: Why public?
+ public:
+ /** Source location for this state. */
+ location_type yyloc;]])[
+
+]b4_parse_assert_if([[
+ public:
+ // Check invariants.
+ void check_ () const
+ {
+ YY_IGNORE_NULL_DEREFERENCE_BEGIN
+ YYASSERT (this->magic_ == MAGIC);
+ YY_IGNORE_NULL_DEREFERENCE_END
+ }
+
+ // A magic number to check our pointer arithmetic is sane.
+ enum { MAGIC = 713705 };
+ unsigned int magic_;]])[
+ }; // class ]b4_parser_class[::glr_state
+} // namespace ]b4_namespace_ref[
+
+
+namespace
+{
+ /** A stack of GLRState representing the different heads during
+ * nondeterministic evaluation. */
+ class glr_state_set
+ {
+ public:
+ /** Initialize YYSET to a singleton set containing an empty stack. */
+ glr_state_set ()
+ : yylastDeleted (YY_NULLPTR)
+ {
+ yystates.push_back (YY_NULLPTR);
+ yylookaheadNeeds.push_back (false);
+ }
+
+ // Behave like a vector of states.
+ glr_state*& operator[] (state_set_index index)
+ {
+ return yystates[index.uget()];
+ }
+
+ glr_state* operator[] (state_set_index index) const
+ {
+ return yystates[index.uget()];
+ }
+
+ size_t size () const
+ {
+ return yystates.size ();
+ }
+
+ std::vector::iterator begin ()
+ {
+ return yystates.begin ();
+ }
+
+ std::vector::iterator end ()
+ {
+ return yystates.end ();
+ }
+
+ bool lookaheadNeeds (state_set_index index) const
+ {
+ return yylookaheadNeeds[index.uget ()];
+ }
+
+ bool setLookaheadNeeds (state_set_index index, bool value)
+ {
+ return yylookaheadNeeds[index.uget ()] = value;
+ }
+
+ /** Invalidate stack #YYK. */
+ void
+ yymarkStackDeleted (state_set_index yyk)
+ {
+ size_t k = yyk.uget ();
+ if (yystates[k] != YY_NULLPTR)
+ yylastDeleted = yystates[k];
+ yystates[k] = YY_NULLPTR;
+ }
+
+ /** Undelete the last stack in *this that was marked as deleted. Can
+ only be done once after a deletion, and only when all other stacks have
+ been deleted. */
+ void
+ yyundeleteLastStack ()
+ {
+ if (yylastDeleted == YY_NULLPTR || !yystates.empty ())
+ return;
+ yystates.push_back (yylastDeleted);
+ YYCDEBUG << "Restoring last deleted stack as stack #0.\n";
+ clearLastDeleted ();
+ }
+
+ /** Remove the dead stacks (yystates[i] == YY_NULLPTR) and shift the later
+ * ones. */
+ void
+ yyremoveDeletes ()
+ {
+ size_t newsize = yystates.size ();
+ /* j is the number of live stacks we have seen. */
+ for (size_t i = 0, j = 0; j < newsize; ++i)
+ {
+ if (yystates[i] == YY_NULLPTR)
+ {
+ if (i == j)
+ {
+ YYCDEBUG << "Removing dead stacks.\n";
+ }
+ newsize -= 1;
+ }
+ else
+ {
+ yystates[j] = yystates[i];
+ /* In the current implementation, it's unnecessary to copy
+ yylookaheadNeeds[i] since, after
+ yyremoveDeletes returns, the parser immediately either enters
+ deterministic operation or shifts a token. However, it doesn't
+ hurt, and the code might evolve to need it. */
+ yylookaheadNeeds[j] = yylookaheadNeeds[i];
+ if (j != i)
+ {
+ YYCDEBUG << "Rename stack " << i << " -> " << j << ".\n";
+ }
+ j += 1;
+ }
+ }
+ yystates.resize (newsize);
+ yylookaheadNeeds.resize (newsize);
+ }
+
+
+ state_set_index
+ yysplitStack (state_set_index yyk)
+ {
+ const size_t k = yyk.uget ();
+ yystates.push_back (yystates[k]);
+ yylookaheadNeeds.push_back (yylookaheadNeeds[k]);
+ return create_state_set_index (static_cast (yystates.size () - 1));
+ }
+
+ void clearLastDeleted ()
+ {
+ yylastDeleted = YY_NULLPTR;
+ }
+
+ private:
+
+ std::vector yystates;
+ /** During nondeterministic operation, yylookaheadNeeds tracks which
+ * stacks have actually needed the current lookahead. During deterministic
+ * operation, yylookaheadNeeds[0] is not maintained since it would merely
+ * duplicate !yyla.empty (). */
+ std::vector yylookaheadNeeds;
+
+ /** The last stack we invalidated. */
+ glr_state* yylastDeleted;
+ }; // class glr_state_set
+} // namespace
+
+namespace
+{
+ class semantic_option
+ {
+ public:
+ semantic_option ()
+ : yyrule (0)
+ , yystate (0)
+ , yynext (0)
+ , yyla ()]b4_parse_assert_if([[
+ , magic_ (MAGIC)]])[
+ {}
+
+ semantic_option (rule_num rule)
+ : yyrule (rule)
+ , yystate (0)
+ , yynext (0)
+ , yyla ()]b4_parse_assert_if([[
+ , magic_ (MAGIC)]])[
+ {}
+
+ semantic_option (const semantic_option& that)
+ : yyrule (that.yyrule)
+ , yystate (that.yystate)
+ , yynext (that.yynext)
+ , yyla (that.yyla)]b4_parse_assert_if([[
+ , magic_ (MAGIC)]])[
+ {]b4_parse_assert_if([[
+ that.check_ ();]])[
+ }
+
+ // Needed for the assignment in yynewSemanticOption.
+ semantic_option& operator= (const semantic_option& that)
+ {]b4_parse_assert_if([[
+ check_ ();
+ that.check_ ();]])[
+ yyrule = that.yyrule;
+ yystate = that.yystate;
+ yynext = that.yynext;
+ yyla = that.yyla;
+ return *this;
+ }
+
+ /// Only call state() and setState() on objects in yyitems, not temporaries.
+ glr_state* state();
+ const glr_state* state() const;
+ void setState(const glr_state* s);
+
+ const semantic_option* next () const YY_ATTRIBUTE_UNUSED;
+ semantic_option* next ();
+ void setNext (const semantic_option* s);
+
+ std::ptrdiff_t indexIn (const glr_stack_item* array) const YY_ATTRIBUTE_UNUSED;
+
+ /** True iff YYY0 and YYY1 represent identical options at the top level.
+ * That is, they represent the same rule applied to RHS symbols
+ * that produce the same terminal symbols. */
+ bool
+ isIdenticalTo (const semantic_option& yyy1) const
+ {]b4_parse_assert_if([[
+ check_ ();
+ yyy1.check_ ();]])[
+ if (this->yyrule == yyy1.yyrule)
+ {
+ const glr_state *yys0, *yys1;
+ int yyn;
+ for (yys0 = this->state(),
+ yys1 = yyy1.state(),
+ yyn = yyrhsLength (this->yyrule);
+ yyn > 0;
+ yys0 = yys0->pred(),
+ yys1 = yys1->pred(), yyn -= 1)
+ if (yys0->yyposn != yys1->yyposn)
+ return false;
+ return true;
+ }
+ else
+ return false;
+ }
+
+ /** Assuming identicalOptions (YYY0,YYY1), destructively merge the
+ * alternative semantic values for the RHS-symbols of YYY1 and YYY0. */
+ void
+ mergeWith (semantic_option& yyy1)
+ {]b4_parse_assert_if([[
+ check_ ();
+ yyy1.check_ ();]])[
+ glr_state *yys0 = this->state ();
+ glr_state *yys1 = yyy1.state ();
+ for (int yyn = yyrhsLength (this->yyrule);
+ yyn > 0;
+ yyn -= 1, yys0 = yys0->pred (), yys1 = yys1->pred ())
+ {
+ if (yys0 == yys1)
+ break;
+ else if (yys0->yyresolved)
+ {
+ yys1->yyresolved = true;]b4_variant_if([[
+ YYASSERT (yys1->yylrState == yys0->yylrState);
+ ]b4_symbol_variant([yy_accessing_symbol (yys0->yylrState)],
+ [yys1->value ()], [copy], [yys0->value ()])], [[
+ yys1->value () = yys0->value ();]])[
+ }
+ else if (yys1->yyresolved)
+ {
+ yys0->yyresolved = true;]b4_variant_if([[
+ YYASSERT (yys0->yylrState == yys1->yylrState);
+ ]b4_symbol_variant([yy_accessing_symbol (yys1->yylrState)],
+ [yys0->value ()], [copy], [yys1->value ()])], [[
+ yys0->value () = yys1->value ();]])[
+ }
+ else
+ {
+ semantic_option* yyz0prev = YY_NULLPTR;
+ semantic_option* yyz0 = yys0->firstVal();
+ semantic_option* yyz1 = yys1->firstVal();
+ while (true)
+ {
+ if (yyz1 == yyz0 || yyz1 == YY_NULLPTR)
+ break;
+ else if (yyz0 == YY_NULLPTR)
+ {
+ if (yyz0prev != YY_NULLPTR)
+ yyz0prev->setNext (yyz1);
+ else
+ yys0->setFirstVal (yyz1);
+ break;
+ }
+ else if (yyz0 < yyz1)
+ {
+ semantic_option* yyz = yyz0;
+ if (yyz0prev != YY_NULLPTR)
+ yyz0prev->setNext(yyz1);
+ else
+ yys0->setFirstVal(yyz1);
+ yyz1 = yyz1->next();
+ yyz0->setNext(yyz);
+ }
+ yyz0prev = yyz0;
+ yyz0 = yyz0->next();
+ }
+ yys1->setFirstVal(yys0->firstVal());
+ }
+ }
+ }
+
+#if ]b4_api_PREFIX[DEBUG
+ void yyreportTree (size_t yyindent = 2) const
+ {]b4_parse_assert_if([[
+ check_ ();]])[
+ int yynrhs = yyrhsLength (this->yyrule);
+ const glr_state* yystates[1 + YYMAXRHS];
+ glr_state yyleftmost_state;
+
+ {
+ const glr_state* yys = this->state();
+ for (int yyi = yynrhs; 0 < yyi; yyi -= 1)
+ {
+ yystates[yyi] = yys;
+ yys = yys->pred();
+ }
+ if (yys == YY_NULLPTR)
+ {
+ yyleftmost_state.yyposn = 0;
+ yystates[0] = &yyleftmost_state;
+ }
+ else
+ yystates[0] = yys;
+ }
+
+ std::string yylhs = ]b4_namespace_ref[::]b4_parser_class[::symbol_name (yylhsNonterm (this->yyrule));
+ YYASSERT(this->state());
+ if (this->state()->yyposn < yystates[0]->yyposn + 1)
+ std::cerr << std::string(yyindent, ' ') << yylhs << " -> yyrule - 1 << ", empty>\n";
+ else
+ std::cerr << std::string(yyindent, ' ') << yylhs << " -> yyrule - 1 << ", tokens "
+ << yystates[0]->yyposn + 1 << " .. "
+ << this->state()->yyposn << ">\n";
+ for (int yyi = 1; yyi <= yynrhs; yyi += 1)
+ {
+ if (yystates[yyi]->yyresolved)
+ {
+ std::string yysym = ]b4_namespace_ref[::]b4_parser_class[::symbol_name (yy_accessing_symbol (yystates[yyi]->yylrState));
+ if (yystates[yyi-1]->yyposn+1 > yystates[yyi]->yyposn)
+ std::cerr << std::string(yyindent + 2, ' ') << yysym
+ << " \n";
+ else
+ std::cerr << std::string(yyindent + 2, ' ') << yysym
+ << " yyposn + 1
+ << " .. " << yystates[yyi]->yyposn << ">\n";
+ }
+ else
+ yystates[yyi]->firstVal ()->yyreportTree (yyindent+2);
+ }
+ }
+#endif
+
+ /** Rule number for this reduction */
+ rule_num yyrule;
+
+ private:
+ template
+ static const glr_stack_item* asItem(const T* state)
+ {
+ return reinterpret_cast(state);
+ }
+ template
+ static glr_stack_item* asItem(T* state)
+ {
+ return reinterpret_cast(state);
+ }
+ /** The last RHS state in the list of states to be reduced. */
+ std::ptrdiff_t yystate;
+ /** Next sibling in chain of options. To facilitate merging,
+ * options are chained in decreasing order by address. */
+ std::ptrdiff_t yynext;
+
+ public:
+ /** The lookahead for this reduction. */
+ symbol_type yyla;
+
+]b4_parse_assert_if([[
+ public:
+ // Check invariants.
+ void check_ () const
+ {
+ YY_IGNORE_NULL_DEREFERENCE_BEGIN
+ YYASSERT (this->magic_ == MAGIC);
+ YY_IGNORE_NULL_DEREFERENCE_END
+ }
+
+ // A magic number to check our pointer arithmetic is sane.
+ enum { MAGIC = 0xeff1cace };
+ unsigned int magic_;]])[
+ }; // class semantic_option
+} // namespace
+
+namespace
+{
+ /** Type of the items in the GLR stack.
+ * It can be either a glr_state or a semantic_option. The is_state_ field
+ * indicates which item of the union is valid. */
+ class glr_stack_item
+ {
+ public:
+ glr_stack_item (bool state = true)
+ : is_state_ (state)]b4_parse_assert_if([[
+ , magic_ (MAGIC)]])[
+ {
+ if (is_state_)
+ new (&raw_) glr_state;
+ else
+ new (&raw_) semantic_option;
+ }
+
+ glr_stack_item (const glr_stack_item& other) YY_NOEXCEPT YY_NOTHROW
+ : is_state_ (other.is_state_)]b4_parse_assert_if([[
+ , magic_ (MAGIC)]])[
+ {]b4_parse_assert_if([[
+ other.check_ ();]])[
+ std::memcpy (raw_, other.raw_, union_size);
+ }
+
+ glr_stack_item& operator= (glr_stack_item other)
+ {]b4_parse_assert_if([[
+ check_ ();
+ other.check_ ();]])[
+ std::swap (is_state_, other.is_state_);
+ std::swap (raw_, other.raw_);
+ return *this;
+ }
+
+ ~glr_stack_item ()
+ {]b4_parse_assert_if([[
+ check_ ();]])[
+ if (is_state ())
+ getState ().~glr_state ();
+ else
+ getOption ().~semantic_option ();
+ }
+
+ void setState (const glr_state &state)
+ {]b4_parse_assert_if([[
+ check_ ();
+ state.check_ ();]])[
+ if (this != state.asItem ())
+ {
+ if (is_state_)
+ getState ().~glr_state ();
+ else
+ getOption ().~semantic_option ();
+ new (&raw_) glr_state (state);
+ is_state_ = true;
+ }
+ }
+
+ glr_state& getState ()
+ {]b4_parse_assert_if([[
+ check_ ();]])[
+ YYDASSERT (is_state ());
+ void *yyp = raw_;
+ glr_state& res = *static_cast (yyp);]b4_parse_assert_if([[
+ res.check_ ();]])[
+ return res;
+ }
+
+ const glr_state& getState () const
+ {]b4_parse_assert_if([[
+ check_ ();]])[
+ YYDASSERT (is_state ());
+ const void *yyp = raw_;
+ const glr_state& res = *static_cast (yyp);]b4_parse_assert_if([[
+ res.check_ ();]])[
+ return res;
+ }
+
+ semantic_option& getOption ()
+ {]b4_parse_assert_if([[
+ check_ ();]])[
+ YYDASSERT (!is_state ());
+ void *yyp = raw_;
+ return *static_cast (yyp);
+ }
+ const semantic_option& getOption () const
+ {]b4_parse_assert_if([[
+ check_ ();]])[
+ YYDASSERT (!is_state ());
+ const void *yyp = raw_;
+ return *static_cast (yyp);
+ }
+ bool is_state () const
+ {]b4_parse_assert_if([[
+ check_ ();]])[
+ return is_state_;
+ }
+
+ private:
+ /// The possible contents of raw_. Since they have constructors, they cannot
+ /// be directly included in the union.
+ union contents
+ {
+ char yystate[sizeof (glr_state)];
+ char yyoption[sizeof (semantic_option)];
+ };
+ enum { union_size = sizeof (contents) };
+ union {
+ /// Strongest alignment constraints.
+ long double yyalign_me;
+ /// A buffer large enough to store the contents.
+ char raw_[union_size];
+ };
+ /** Type tag for the union. */
+ bool is_state_;
+]b4_parse_assert_if([[
+ public:
+ // Check invariants.
+ void check_ () const
+ {
+ YYASSERT (this->magic_ == MAGIC);
+ YYASSERT (this->is_state_ == false || this->is_state_ == true);
+ }
+ // A magic number to check our pointer arithmetic is sane.
+ enum { MAGIC = 0xDEAD1ACC }; // 3735886540.
+ const unsigned int magic_;]])[
+ }; // class glr_stack_item
+} // namespace
+
+glr_state* glr_state::pred ()
+{]b4_parse_assert_if([[
+ check_ ();]])[
+ YY_IGNORE_NULL_DEREFERENCE_BEGIN
+ return yypred ? &asItem (as_pointer_ (this) - yypred)->getState () : YY_NULLPTR;
+ YY_IGNORE_NULL_DEREFERENCE_END
+}
+
+const glr_state* glr_state::pred () const
+{]b4_parse_assert_if([[
+ check_ ();]])[
+ YY_IGNORE_NULL_DEREFERENCE_BEGIN
+ return yypred ? &asItem (as_pointer_ (this) - yypred)->getState () : YY_NULLPTR;
+ YY_IGNORE_NULL_DEREFERENCE_END
+}
+
+void glr_state::setPred (const glr_state* state)
+{]b4_parse_assert_if([[
+ check_ ();
+ if (state)
+ state->check_ ();]])[
+ yypred = state ? as_pointer_ (this) - as_pointer_ (state) : 0;
+}
+
+semantic_option* glr_state::firstVal ()
+{]b4_parse_assert_if([[
+ check_ ();]])[
+ return yyfirstVal ? &(asItem(this) - yyfirstVal)->getOption() : YY_NULLPTR;
+}
+
+const semantic_option* glr_state::firstVal () const
+{]b4_parse_assert_if([[
+ check_ ();]])[
+ return yyfirstVal ? &(asItem(this) - yyfirstVal)->getOption() : YY_NULLPTR;
+}
+
+void glr_state::setFirstVal (const semantic_option* option)
+{]b4_parse_assert_if([[
+ check_ ();]])[
+ yyfirstVal = option ? asItem(this) - asItem(option) : 0;
+}
+
+std::ptrdiff_t glr_state::indexIn (const glr_stack_item* array) const
+{]b4_parse_assert_if([[
+ check_ ();]])[
+ return asItem(this) - array;
+}
+
+std::ptrdiff_t semantic_option::indexIn (const glr_stack_item* array) const
+{
+ return asItem(this) - array;
+}
+
+glr_state* semantic_option::state ()
+{
+ YY_IGNORE_NULL_DEREFERENCE_BEGIN
+ return yystate ? &(asItem(this) - yystate)->getState() : YY_NULLPTR;
+ YY_IGNORE_NULL_DEREFERENCE_END
+}
+
+const glr_state* semantic_option::state () const
+{
+ return yystate ? &(asItem(this) - yystate)->getState() : YY_NULLPTR;
+}
+
+void semantic_option::setState (const glr_state* s)
+{
+ yystate = s ? asItem(this) - asItem(s) : 0;
+}
+
+const semantic_option* semantic_option::next () const
+{
+ return yynext ? &(asItem(this) - yynext)->getOption() : YY_NULLPTR;
+}
+
+semantic_option* semantic_option::next ()
+{
+ return yynext ? &(asItem(this) - yynext)->getOption() : YY_NULLPTR;
+}
+
+void semantic_option::setNext (const semantic_option* s)
+{
+ yynext = s ? asItem(this) - asItem(s) : 0;
+}
+
+void glr_state::destroy (char const* yymsg, ]b4_namespace_ref[::]b4_parser_class[& yyparser)
+{]b4_parse_assert_if([[
+ check_ ();]])[
+ if (yyresolved)
+ yyparser.yy_destroy_ (yymsg, yy_accessing_symbol(yylrState),
+ value ()]b4_locations_if([, yyloc])[);
+ else
+ {
+#if ]b4_api_PREFIX[DEBUG
+ YYCDEBUG << yymsg
+ << (firstVal() ? " unresolved " : " incomplete ")
+ << (yy_accessing_symbol (yylrState) < YYNTOKENS ? "token" : "nterm")
+ << ' ' << yyparser.symbol_name (yy_accessing_symbol (yylrState))
+ << " ("]b4_locations_if([[
+ << yyloc << ": "]])[
+ << ")\n";
+#endif
+ if (firstVal() != YY_NULLPTR)
+ {
+ semantic_option& yyoption = *firstVal ();
+ glr_state *yyrh = yyoption.state ();
+ for (int yyn = yyrhsLength (yyoption.yyrule); yyn > 0; yyn -= 1)
+ {
+ yyrh->destroy (yymsg, yyparser);
+ yyrh = yyrh->pred();
+ }
+ }
+ }
+}
+
+
+#undef YYFILL
+#define YYFILL(N) yyfill (yyvsp, yylow, (N), yynormal)
+
+namespace
+{
+ class state_stack
+ {
+ public:
+ using parser_type = ]b4_namespace_ref[::]b4_parser_class[;
+ using symbol_kind = parser_type::symbol_kind;
+ using value_type = parser_type::value_type;]b4_locations_if([[
+ using location_type = parser_type::location_type;]])[
+
+ /** Initialize to a single empty stack, with total maximum
+ * capacity for all stacks of YYSIZE. */
+ state_stack (size_t yysize)
+ : yysplitPoint (YY_NULLPTR)
+ {
+ yyitems.reserve (yysize);
+ }
+
+#if YYSTACKEXPANDABLE
+ /** Returns false if it tried to expand but could not. */
+ bool
+ yyexpandGLRStackIfNeeded ()
+ {
+ return YYHEADROOM <= spaceLeft () || yyexpandGLRStack ();
+ }
+
+ private:
+ /** If *this is expandable, extend it. WARNING: Pointers into the
+ stack from outside should be considered invalid after this call.
+ We always expand when there are 1 or fewer items left AFTER an
+ allocation, so that we can avoid having external pointers exist
+ across an allocation. */
+ bool
+ yyexpandGLRStack ()
+ {
+ const size_t oldsize = yyitems.size();
+ if (YYMAXDEPTH - YYHEADROOM < oldsize)
+ return false;
+ const size_t yynewSize = YYMAXDEPTH < 2 * oldsize ? YYMAXDEPTH : 2 * oldsize;
+ const glr_stack_item *oldbase = &yyitems[0];
+
+ yyitems.reserve (yynewSize);
+ const glr_stack_item *newbase = &yyitems[0];
+
+ // Adjust the pointers. Perform raw pointer arithmetic, as there
+ // is no reason for objects to be aligned on their size.
+ const ptrdiff_t disp
+ = reinterpret_cast (newbase) - reinterpret_cast (oldbase);
+ if (yysplitPoint)
+ const_cast (yysplitPoint)
+ = reinterpret_cast (reinterpret_cast (const_cast (yysplitPoint)) + disp);
+
+ for (std::vector::iterator
+ i = yytops.begin (),
+ yyend = yytops.end ();
+ i != yyend; ++i)
+ if (glr_state_not_null (*i))
+ *i = reinterpret_cast(reinterpret_cast(*i) + disp);
+
+ return true;
+ }
+
+ public:
+#else
+ bool yyexpandGLRStackIfNeeded ()
+ {
+ return YYHEADROOM <= spaceLeft ();
+ }
+#endif
+#undef YYSTACKEXPANDABLE
+
+ static bool glr_state_not_null (glr_state* s)
+ {
+ return s != YY_NULLPTR;
+ }
+
+ bool
+ reduceToOneStack ()
+ {
+ using iterator = std::vector::iterator;
+ const iterator yybegin = yytops.begin();
+ const iterator yyend = yytops.end();
+ const iterator yyit = std::find_if(yybegin, yyend, glr_state_not_null);
+ if (yyit == yyend)
+ return false;
+ for (state_set_index yyk = create_state_set_index(yyit + 1 - yybegin);
+ yyk.uget() != numTops(); ++yyk)
+ yytops.yymarkStackDeleted (yyk);
+ yytops.yyremoveDeletes ();
+ yycompressStack ();
+ return true;
+ }
+
+ /** Called when returning to deterministic operation to clean up the extra
+ * stacks. */
+ void
+ yycompressStack ()
+ {
+ if (yytops.size() != 1 || !isSplit())
+ return;
+
+ // yyr is the state after the split point.
+ glr_state* yyr = YY_NULLPTR;
+ for (glr_state *yyp = firstTop(), *yyq = yyp->pred();
+ yyp != yysplitPoint;
+ yyr = yyp, yyp = yyq, yyq = yyp->pred())
+ yyp->setPred(yyr);
+
+ // This const_cast is okay, since anyway we have access to the mutable
+ // yyitems into which yysplitPoint points.
+ glr_stack_item* nextFreeItem
+ = const_cast (yysplitPoint)->asItem () + 1;
+ yysplitPoint = YY_NULLPTR;
+ yytops.clearLastDeleted ();
+
+ while (yyr != YY_NULLPTR)
+ {
+ nextFreeItem->setState (*yyr);
+ glr_state& nextFreeState = nextFreeItem->getState();
+ yyr = yyr->pred();
+ nextFreeState.setPred(&(nextFreeItem - 1)->getState());
+ setFirstTop (&nextFreeState);
+ ++nextFreeItem;
+ }
+ yyitems.resize(static_cast(nextFreeItem - yyitems.data()));
+ }
+
+ bool isSplit() const {
+ return yysplitPoint != YY_NULLPTR;
+ }
+
+ // Present the interface of a vector of glr_stack_item.
+ std::vector::const_iterator begin () const
+ {
+ return yyitems.begin ();
+ }
+
+ std::vector::const_iterator end () const
+ {
+ return yyitems.end ();
+ }
+
+ size_t size() const
+ {
+ return yyitems.size ();
+ }
+
+ glr_stack_item& operator[] (size_t i)
+ {
+ return yyitems[i];
+ }
+
+ glr_stack_item& stackItemAt (size_t index)
+ {
+ return yyitems[index];
+ }
+
+ size_t numTops () const
+ {
+ return yytops.size ();
+ }
+
+ glr_state* firstTop () const
+ {
+ return yytops[create_state_set_index (0)];
+ }
+
+ glr_state* topAt (state_set_index i) const
+ {
+ return yytops[i];
+ }
+
+ void setFirstTop (glr_state* value)
+ {
+ yytops[create_state_set_index (0)] = value;
+ }
+
+ void setTopAt (state_set_index i, glr_state* value)
+ {
+ yytops[i] = value;
+ }
+
+ void pop_back ()
+ {
+ yyitems.pop_back ();
+ }
+
+ void pop_back (size_t n)
+ {
+ yyitems.resize (yyitems.size () - n);
+ }
+
+ state_set_index
+ yysplitStack (state_set_index yyk)
+ {
+ if (!isSplit ())
+ {
+ YYASSERT (yyk.get () == 0);
+ yysplitPoint = topAt (yyk);
+ }
+ return yytops.yysplitStack (yyk);
+ }
+
+ /** Assuming that YYS is a GLRState somewhere on *this, update the
+ * splitpoint of *this, if needed, so that it is at least as deep as
+ * YYS. */
+ void
+ yyupdateSplit (glr_state& yys)
+ {
+ if (isSplit() && &yys < yysplitPoint)
+ yysplitPoint = &yys;
+ }
+
+ /** Return a fresh GLRState.
+ * Callers should call yyreserveStack afterwards to make sure there is
+ * sufficient headroom. */
+ glr_state& yynewGLRState (const glr_state& newState)
+ {
+ glr_state& state = yyitems[yynewGLRStackItem (true)].getState ();
+#if false && 201103L <= YY_CPLUSPLUS
+ state = std::move (newState);
+#else
+ state = newState;
+#endif
+ return state;
+ }
+
+ /** Return a fresh SemanticOption.
+ * Callers should call yyreserveStack afterwards to make sure there is
+ * sufficient headroom. */
+ semantic_option& yynewSemanticOption (semantic_option newOption)
+ {
+ semantic_option& option = yyitems[yynewGLRStackItem (false)].getOption ();
+ option = std::move (newOption);
+ return option;
+ }
+
+ /* Do nothing if YYNORMAL or if *YYLOW <= YYLOW1. Otherwise, fill in
+ * YYVSP[YYLOW1 .. *YYLOW-1] as in yyfillin and set *YYLOW = YYLOW1.
+ * For convenience, always return YYLOW1. */
+ int
+ yyfill (glr_stack_item *yyvsp, int &yylow, int yylow1, bool yynormal)
+ {
+ if (!yynormal && yylow1 < yylow)
+ {
+ yyfillin (yyvsp, yylow, yylow1);
+ yylow = yylow1;
+ }
+ return yylow1;
+ }
+
+ /** Fill in YYVSP[YYLOW1 .. YYLOW0-1] from the chain of states starting
+ * at YYVSP[YYLOW0].getState().pred(). Leaves YYVSP[YYLOW1].getState().pred()
+ * containing the pointer to the next state in the chain. */
+ void
+ yyfillin (glr_stack_item *yyvsp, int yylow0, int yylow1)
+ {
+ glr_state* s = yyvsp[yylow0].getState().pred();
+ YYASSERT(s != YY_NULLPTR);
+ for (int i = yylow0-1; i >= yylow1; i -= 1, s = s->pred())
+ {
+ glr_state& yys = yyvsp[i].getState();
+#if ]b4_api_PREFIX[DEBUG
+ yys.yylrState = s->yylrState;
+#endif
+ yys.yyresolved = s->yyresolved;
+ if (s->yyresolved)
+ {]b4_variant_if([[
+ new (&yys.value ()) value_type ();
+ ]b4_symbol_variant([yy_accessing_symbol (s->yylrState)],
+ [yys.value ()], [copy], [s->value ()])], [[
+ new (&yys.value ()) value_type (s->value ());]])[
+ }
+ else
+ /* The effect of using yyval or yyloc (in an immediate
+ * rule) is undefined. */
+ yys.setFirstVal (YY_NULLPTR);]b4_locations_if([[
+ yys.yyloc = s->yyloc;]])[
+ yys.setPred(s->pred());
+ }
+ }
+
+#if ]b4_api_PREFIX[DEBUG
+
+ /*----------------------------------------------------------------------.
+ | Report that stack #YYK of *YYSTACKP is going to be reduced by YYRULE. |
+ `----------------------------------------------------------------------*/
+
+ void
+ yy_reduce_print (bool yynormal, glr_stack_item* yyvsp, state_set_index yyk,
+ rule_num yyrule, parser_type& yyparser)
+ {
+ int yynrhs = yyrhsLength (yyrule);]b4_locations_if([
+ int yylow = 1;])[
+ int yyi;
+ std::cerr << "Reducing stack " << yyk.get() << " by rule " << yyrule - 1
+ << " (line " << int (yyrline[yyrule]) << "):\n";
+ if (! yynormal)
+ yyfillin (yyvsp, 1, -yynrhs);
+ /* The symbols being reduced. */
+ for (yyi = 0; yyi < yynrhs; yyi++)
+ {
+ std::cerr << " $" << yyi + 1 << " = ";
+ yyparser.yy_symbol_print_
+ (yy_accessing_symbol (yyvsp[yyi - yynrhs + 1].getState().yylrState),
+ yyvsp[yyi - yynrhs + 1].getState().value ()]b4_locations_if([[,
+ ]b4_rhs_location(yynrhs, yyi + 1)])[);
+ if (!yyvsp[yyi - yynrhs + 1].getState().yyresolved)
+ std::cerr << " (unresolved)";
+ std::cerr << '\n';
+ }
+ }
+
+
+#define YYINDEX(YYX) \
+ ((YYX) == YY_NULLPTR ? -1 : (YYX)->indexIn (yyitems.data ()))
+
+ void
+ dumpStack () const
+ {
+ for (size_t yyi = 0; yyi < size(); ++yyi)
+ {
+ const glr_stack_item& item = yyitems[yyi];
+ std::cerr << std::setw(3) << yyi << ". ";
+ if (item.is_state())
+ {
+ std::cerr << "Res: " << item.getState().yyresolved
+ << ", LR State: " << item.getState().yylrState
+ << ", posn: " << item.getState().yyposn
+ << ", pred: " << YYINDEX(item.getState().pred());
+ if (! item.getState().yyresolved)
+ std::cerr << ", firstVal: "
+ << YYINDEX(item.getState().firstVal());
+ }
+ else
+ {
+ std::cerr << "Option. rule: " << item.getOption().yyrule - 1
+ << ", state: " << YYINDEX(item.getOption().state())
+ << ", next: " << YYINDEX(item.getOption().next());
+ }
+ std::cerr << '\n';
+ }
+ std::cerr << "Tops:";
+ for (state_set_index yyi = create_state_set_index(0); yyi.uget() < numTops(); ++yyi) {
+ std::cerr << yyi.get() << ": " << YYINDEX(topAt(yyi)) << "; ";
+ }
+ std::cerr << '\n';
+ }
+
+#undef YYINDEX
+#endif
+
+ YYRESULTTAG
+ yyreportAmbiguity (const semantic_option& yyx0,
+ const semantic_option& yyx1, parser_type& yyparser]b4_locations_if([, const location_type& yyloc])[)
+ {
+ YY_USE (yyx0);
+ YY_USE (yyx1);
+
+#if ]b4_api_PREFIX[DEBUG
+ std::cerr << "Ambiguity detected.\n"
+ "Option 1,\n";
+ yyx0.yyreportTree ();
+ std::cerr << "\nOption 2,\n";
+ yyx1.yyreportTree ();
+ std::cerr << '\n';
+#endif
+
+ yyparser.error (]b4_locations_if([yyloc, ])[YY_("syntax is ambiguous"));
+ return yyabort;
+ }
+
+#if ]b4_api_PREFIX[DEBUG
+ /* Print YYS (possibly NULL) and its predecessors. */
+ void
+ yypstates (const glr_state* yys) const
+ {
+ if (yys != YY_NULLPTR)
+ yys->yy_yypstack();
+ else
+ std::cerr << "";
+ std::cerr << '\n';
+ }
+#endif
+
+ private:
+ size_t spaceLeft() const
+ {
+ return yyitems.capacity() - yyitems.size();
+ }
+
+ /** Return a fresh GLRStackItem in this. The item is an LR state
+ * if YYIS_STATE, and otherwise a semantic option. Callers should call
+ * yyreserveStack afterwards to make sure there is sufficient
+ * headroom. */
+ size_t
+ yynewGLRStackItem (bool yyis_state)
+ {
+ YYDASSERT(yyitems.size() < yyitems.capacity());
+ yyitems.push_back(glr_stack_item(yyis_state));
+ return yyitems.size() - 1;
+ }
+
+
+ public:
+ std::vector yyitems;
+ // Where the stack splits. Anything below this address is deterministic.
+ const glr_state* yysplitPoint;
+ glr_state_set yytops;
+ }; // class state_stack
+} // namespace
+
+#undef YYFILL
+#define YYFILL(N) yystateStack.yyfill (yyvsp, yylow, (N), yynormal)
+
+namespace ]b4_namespace_ref[
+{
+ class ]b4_parser_class[::glr_stack
+ {
+ public:
+]b4_parse_error_bmatch([custom\|detailed\|verbose], [[
+ // Needs access to yypact_value_is_default, etc.
+ friend context;
+]])[
+
+ glr_stack (size_t yysize, parser_type& yyparser_yyarg]m4_ifset([b4_parse_param], [, b4_parse_param_decl])[)
+ : yyerrState (0)
+ , yystateStack (yysize)
+ , yyerrcnt (0)
+ , yyla ()
+ , yyparser (yyparser_yyarg)]m4_ifset([b4_parse_param], [,b4_parse_param_cons])[
+ {}
+
+ ~glr_stack ()
+ {
+ if (!this->yyla.empty ())
+ yyparser.yy_destroy_ ("Cleanup: discarding lookahead",
+ this->yyla.kind (), this->yyla.value]b4_locations_if([, this->yyla.location])[);
+ popall_ ();
+ }
+
+ int yyerrState;
+]b4_locations_if([[ /* To compute the location of the error token. */
+ glr_stack_item yyerror_range[3];]])[
+ state_stack yystateStack;
+ int yyerrcnt;
+ symbol_type yyla;
+ YYJMP_BUF yyexception_buffer;
+ parser_type& yyparser;
+
+ #define YYCHK1(YYE) \
+ do { \
+ switch (YYE) { \
+ case yyok: \
+ break; \
+ case yyabort: \
+ goto yyabortlab; \
+ case yyaccept: \
+ goto yyacceptlab; \
+ case yyerr: \
+ goto yyuser_error; \
+ default: \
+ goto yybuglab; \
+ } \
+ } while (false)
+
+ int
+ parse ()
+ {
+ int yyresult;
+ size_t yyposn;
+
+ YYCDEBUG << "Starting parse\n";
+
+ this->yyla.clear ();
+]m4_ifdef([b4_initial_action], [
+b4_dollar_pushdef([yyla.value], [], [], [yyla.location])dnl
+ b4_user_initial_action
+b4_dollar_popdef])[]dnl
+[
+ switch (YYSETJMP (this->yyexception_buffer))
+ {
+ case 0: break;
+ case 1: goto yyabortlab;
+ case 2: goto yyexhaustedlab;
+ default: goto yybuglab;
+ }
+ this->yyglrShift (create_state_set_index(0), 0, 0, this->yyla.value]b4_locations_if([, this->yyla.location])[);
+ yyposn = 0;
+
+ while (true)
+ {
+ /* For efficiency, we have two loops, the first of which is
+ specialized to deterministic operation (single stack, no
+ potential ambiguity). */
+ /* Standard mode */
+ while (true)
+ {
+ const state_num yystate = this->firstTopState()->yylrState;
+ YYCDEBUG << "Entering state " << yystate << '\n';
+ if (yystate == YYFINAL)
+ goto yyacceptlab;
+ if (yy_is_defaulted_state (yystate))
+ {
+ const rule_num yyrule = yy_default_action (yystate);
+ if (yyrule == 0)
+ {]b4_locations_if([[
+ this->yyerror_range[1].getState().yyloc = this->yyla.location;]])[
+ this->yyreportSyntaxError ();
+ goto yyuser_error;
+ }
+ YYCHK1 (this->yyglrReduce (create_state_set_index(0), yyrule, true));
+ }
+ else
+ {
+ yyget_token ();
+ const short* yyconflicts;
+ const int yyaction = yygetLRActions (yystate, this->yyla.kind (), yyconflicts);
+ if (*yyconflicts != 0)
+ break;
+ if (yy_is_shift_action (yyaction))
+ {
+ YY_SYMBOL_PRINT ("Shifting", this->yyla.kind (), this->yyla.value, this->yyla.location);
+ yyposn += 1;
+ // FIXME: we should move yylval.
+ this->yyglrShift (create_state_set_index(0), yyaction, yyposn, this->yyla.value]b4_locations_if([, this->yyla.location])[);
+ yyla.clear ();
+ if (0 < this->yyerrState)
+ this->yyerrState -= 1;
+ }
+ else if (yy_is_error_action (yyaction))
+ {]b4_locations_if([[
+ this->yyerror_range[1].getState().yyloc = this->yyla.location;]])[
+ /* Don't issue an error message again for exceptions
+ thrown from the scanner. */
+ if (this->yyla.kind () != ]b4_symbol(error, kind)[)
+ this->yyreportSyntaxError ();
+ goto yyuser_error;
+ }
+ else
+ YYCHK1 (this->yyglrReduce (create_state_set_index(0), -yyaction, true));
+ }
+ }
+
+ while (true)
+ {
+ for (state_set_index yys = create_state_set_index(0); yys.uget() < this->yystateStack.numTops(); ++yys)
+ this->yystateStack.yytops.setLookaheadNeeds(yys, !this->yyla.empty ());
+
+ /* yyprocessOneStack returns one of three things:
+
+ - An error flag. If the caller is yyprocessOneStack, it
+ immediately returns as well. When the caller is finally
+ yyparse, it jumps to an error label via YYCHK1.
+
+ - yyok, but yyprocessOneStack has invoked yymarkStackDeleted
+ (yys), which sets the top state of yys to NULL. Thus,
+ yyparse's following invocation of yyremoveDeletes will remove
+ the stack.
+
+ - yyok, when ready to shift a token.
+
+ Except in the first case, yyparse will invoke yyremoveDeletes and
+ then shift the next token onto all remaining stacks. This
+ synchronization of the shift (that is, after all preceding
+ reductions on all stacks) helps prevent double destructor calls
+ on yylval in the event of memory exhaustion. */
+
+ for (state_set_index yys = create_state_set_index (0); yys.uget () < this->yystateStack.numTops (); ++yys)
+ YYCHK1 (this->yyprocessOneStack (yys, yyposn]b4_locations_if([, &this->yyla.location])[));
+ this->yystateStack.yytops.yyremoveDeletes ();
+ if (this->yystateStack.yytops.size() == 0)
+ {
+ this->yystateStack.yytops.yyundeleteLastStack ();
+ if (this->yystateStack.yytops.size() == 0)
+ this->yyFail (]b4_locations_if([&this->yyla.location, ])[YY_("syntax error"));
+ YYCHK1 (this->yyresolveStack ());
+ YYCDEBUG << "Returning to deterministic operation.\n";]b4_locations_if([[
+ this->yyerror_range[1].getState ().yyloc = this->yyla.location;]])[
+ this->yyreportSyntaxError ();
+ goto yyuser_error;
+ }
+
+ /* If any yyglrShift call fails, it will fail after shifting. Thus,
+ a copy of yylval will already be on stack 0 in the event of a
+ failure in the following loop. Thus, yyla is emptied
+ before the loop to make sure the user destructor for yylval isn't
+ called twice. */
+ symbol_kind_type yytoken_to_shift = this->yyla.kind ();
+ this->yyla.kind_ = ]b4_symbol(empty, kind)[;
+ yyposn += 1;
+ for (state_set_index yys = create_state_set_index (0); yys.uget () < this->yystateStack.numTops (); ++yys)
+ {
+ const state_num yystate = this->topState (yys)->yylrState;
+ const short* yyconflicts;
+ const int yyaction = yygetLRActions (yystate, yytoken_to_shift, yyconflicts);
+ /* Note that yyconflicts were handled by yyprocessOneStack. */
+ YYCDEBUG << "On stack " << yys.get() << ", ";
+ YY_SYMBOL_PRINT ("shifting", yytoken_to_shift, this->yyla.value, this->yyla.location);
+ this->yyglrShift (yys, yyaction, yyposn, this->yyla.value]b4_locations_if([, this->yyla.location])[);
+ YYCDEBUG << "Stack " << yys.get() << " now in state "
+ << this->topState(yys)->yylrState << '\n';
+ }
+]b4_variant_if([[
+ // FIXME: User destructors.
+ // Value type destructor.
+ ]b4_symbol_variant([[yytoken_to_shift]], [[this->yyla.value]], [[template destroy]])])[
+
+ if (this->yystateStack.yytops.size () == 1)
+ {
+ YYCHK1 (this->yyresolveStack ());
+ YYCDEBUG << "Returning to deterministic operation.\n";
+ this->yystateStack.yycompressStack ();
+ break;
+ }
+ }
+ continue;
+ yyuser_error:
+ this->yyrecoverSyntaxError (]b4_locations_if([&this->yyla.location])[);
+ yyposn = this->firstTopState()->yyposn;
+ }
+
+ yyacceptlab:
+ yyresult = 0;
+ goto yyreturn;
+
+ yybuglab:
+ YYASSERT (false);
+ goto yyabortlab;
+
+ yyabortlab:
+ yyresult = 1;
+ goto yyreturn;
+
+ yyexhaustedlab:
+ yyparser.error (]b4_locations_if([this->yyla.location, ])[YY_("memory exhausted"));
+ yyresult = 2;
+ goto yyreturn;
+
+ yyreturn:
+ return yyresult;
+ }
+ #undef YYCHK1
+
+ void yyreserveGlrStack ()
+ {
+ if (!yystateStack.yyexpandGLRStackIfNeeded ())
+ yyMemoryExhausted ();
+ }
+
+ _Noreturn void
+ yyMemoryExhausted ()
+ {
+ YYLONGJMP (yyexception_buffer, 2);
+ }
+
+ _Noreturn void
+ yyFail (]b4_locations_if([location_type* yylocp, ])[const char* yymsg)
+ {
+ if (yymsg != YY_NULLPTR)
+ yyparser.error (]b4_locations_if([*yylocp, ])[yymsg);
+ YYLONGJMP (yyexception_buffer, 1);
+ }
+
+ /* GLRStates */
+
+
+ /** Add a new semantic action that will execute the action for rule
+ * YYRULE on the semantic values in YYRHS to the list of
+ * alternative actions for YYSTATE. Assumes that YYRHS comes from
+ * stack #YYK of *this. */
+ void
+ yyaddDeferredAction (state_set_index yyk, glr_state* yystate,
+ glr_state* yyrhs, rule_num yyrule)
+ {
+ semantic_option& yyopt = yystateStack.yynewSemanticOption (semantic_option (yyrule));
+ yyopt.setState (yyrhs);
+ yyopt.setNext (yystate->firstVal ());
+ if (yystateStack.yytops.lookaheadNeeds (yyk))
+ yyopt.yyla = this->yyla;
+ yystate->setFirstVal (&yyopt);
+
+ yyreserveGlrStack ();
+ }
+
+ #if ]b4_api_PREFIX[DEBUG
+ void yypdumpstack () const
+ {
+ yystateStack.dumpStack();
+ }
+ #endif
+
+ void
+ yyreportSyntaxError ()
+ {
+ if (yyerrState != 0)
+ return;
+]b4_parse_error_case(
+[simple], [[
+ std::string msg = YY_("syntax error");
+ yyparser.error (]b4_join(b4_locations_if([yyla.location]), [[YY_MOVE (msg)]])[);]],
+[custom], [[
+ context yyctx (*this, yyla);
+ yyparser.report_syntax_error (yyctx);]],
+[[
+ context yyctx (*this, yyla);
+ std::string msg = yyparser.yysyntax_error_ (yyctx);
+ yyparser.error (]b4_join(b4_locations_if([yyla.location]), [[YY_MOVE (msg)]])[);]])[
+ yyerrcnt += 1;
+ }
+
+ /* Recover from a syntax error on this, assuming that yytoken,
+ yylval, and yylloc are the syntactic category, semantic value, and location
+ of the lookahead. */
+ void
+ yyrecoverSyntaxError (]b4_locations_if([location_type* yylocp])[)
+ {
+ if (yyerrState == 3)
+ /* We just shifted the error token and (perhaps) took some
+ reductions. Skip tokens until we can proceed. */
+ while (true)
+ {
+ if (this->yyla.kind () == ]b4_symbol(eof, kind)[)
+ yyFail (]b4_locations_if([yylocp, ])[YY_NULLPTR);
+ if (this->yyla.kind () != ]b4_symbol(empty, kind)[)
+ {]b4_locations_if([[
+ /* We throw away the lookahead, but the error range
+ of the shifted error token must take it into account. */
+ glr_state *yys = firstTopState();
+ yyerror_range[1].getState().yyloc = yys->yyloc;
+ yyerror_range[2].getState().yyloc = this->yyla.location;
+ YYLLOC_DEFAULT ((yys->yyloc), yyerror_range, 2);]])[
+ yyparser.yy_destroy_ ("Error: discarding",
+ this->yyla.kind (), this->yyla.value]b4_locations_if([, this->yyla.location])[);]b4_variant_if([[
+ // Value type destructor.
+ ]b4_symbol_variant([[this->yyla.kind ()]], [[this->yyla.value]], [[template destroy]])])[
+ this->yyla.kind_ = ]b4_symbol(empty, kind)[;
+ }
+ yyget_token ();
+ int yyj = yypact[firstTopState()->yylrState];
+ if (yypact_value_is_default (yyj))
+ return;
+ yyj += this->yyla.kind ();
+ if (yyj < 0 || YYLAST < yyj || yycheck[yyj] != this->yyla.kind ())
+ {
+ if (yydefact[firstTopState()->yylrState] != 0)
+ return;
+ }
+ else if (! yytable_value_is_error (yytable[yyj]))
+ return;
+ }
+
+ if (!yystateStack.reduceToOneStack())
+ yyFail (]b4_locations_if([yylocp, ])[YY_NULLPTR);
+
+ /* Now pop stack until we find a state that shifts the error token. */
+ yyerrState = 3;
+ while (firstTopState () != YY_NULLPTR)
+ {
+ glr_state *yys = firstTopState ();
+ int yyj = yypact[yys->yylrState];
+ if (! yypact_value_is_default (yyj))
+ {
+ yyj += YYTERROR;
+ if (0 <= yyj && yyj <= YYLAST && yycheck[yyj] == YYTERROR
+ && yy_is_shift_action (yytable[yyj]))
+ {
+ /* Shift the error token. */]b4_locations_if([[
+ /* First adjust its location.*/
+ location_type yyerrloc;
+ yyerror_range[2].getState().yyloc = this->yyla.location;
+ YYLLOC_DEFAULT (yyerrloc, (yyerror_range), 2);]])[
+ YY_SYMBOL_PRINT ("Shifting", yy_accessing_symbol (yytable[yyj]),
+ this->yyla.value, yyerrloc);
+ yyglrShift (create_state_set_index(0), yytable[yyj],
+ yys->yyposn, yyla.value]b4_locations_if([, yyerrloc])[);
+ yys = firstTopState();
+ break;
+ }
+ }]b4_locations_if([[
+ yyerror_range[1].getState().yyloc = yys->yyloc;]])[
+ if (yys->pred() != YY_NULLPTR)
+ yys->destroy ("Error: popping", yyparser);
+ yystateStack.setFirstTop(yys->pred());
+ yystateStack.pop_back();
+ }
+ if (firstTopState() == YY_NULLPTR)
+ yyFail (]b4_locations_if([yylocp, ])[YY_NULLPTR);
+ }
+
+ YYRESULTTAG
+ yyprocessOneStack (state_set_index yyk,
+ size_t yyposn]b4_locations_if([, location_type* yylocp])[)
+ {
+ while (yystateStack.topAt(yyk) != YY_NULLPTR)
+ {
+ const state_num yystate = topState(yyk)->yylrState;
+ YYCDEBUG << "Stack " << yyk.get()
+ << " Entering state " << yystate << '\n';
+
+ YYASSERT (yystate != YYFINAL);
+
+ if (yy_is_defaulted_state (yystate))
+ {
+ const rule_num yyrule = yy_default_action (yystate);
+ if (yyrule == 0)
+ {
+ YYCDEBUG << "Stack " << yyk.get() << " dies.\n";
+ yystateStack.yytops.yymarkStackDeleted (yyk);
+ return yyok;
+ }
+ const YYRESULTTAG yyflag
+ = yyglrReduce (yyk, yyrule, yyimmediate[yyrule]);
+ if (yyflag == yyerr)
+ {
+ YYCDEBUG << "Stack " << yyk.get() << " dies"
+ " (predicate failure or explicit user error).\n";
+ yystateStack.yytops.yymarkStackDeleted (yyk);
+ return yyok;
+ }
+ if (yyflag != yyok)
+ return yyflag;
+ }
+ else
+ {
+ yystateStack.yytops.setLookaheadNeeds(yyk, true);
+ yyget_token ();
+ const short* yyconflicts;
+ const int yyaction = yygetLRActions (yystate, this->yyla.kind (), yyconflicts);
+
+ for (; *yyconflicts != 0; ++yyconflicts)
+ {
+ state_set_index yynewStack = yystateStack.yysplitStack (yyk);
+ YYCDEBUG << "Splitting off stack " << yynewStack.get()
+ << " from " << yyk.get() << ".\n";
+ YYRESULTTAG yyflag =
+ yyglrReduce (yynewStack, *yyconflicts, yyimmediate[*yyconflicts]);
+ if (yyflag == yyok)
+ YYCHK (yyprocessOneStack (yynewStack,
+ yyposn]b4_locations_if([, yylocp])[));
+ else if (yyflag == yyerr)
+ {
+ YYCDEBUG << "Stack " << yynewStack.get() << " dies.\n";
+ yystateStack.yytops.yymarkStackDeleted (yynewStack);
+ }
+ else
+ return yyflag;
+ }
+
+ if (yy_is_shift_action (yyaction))
+ break;
+ else if (yy_is_error_action (yyaction))
+ {
+ YYCDEBUG << "Stack " << yyk.get() << " dies.\n";
+ yystateStack.yytops.yymarkStackDeleted (yyk);
+ break;
+ }
+ else
+ {
+ YYRESULTTAG yyflag
+ = yyglrReduce (yyk, -yyaction, yyimmediate[-yyaction]);
+ if (yyflag == yyerr)
+ {
+ YYCDEBUG << "Stack " << yyk.get() << " dies"
+ " (predicate failure or explicit user error).\n";
+ yystateStack.yytops.yymarkStackDeleted (yyk);
+ break;
+ }
+ else if (yyflag != yyok)
+ return yyflag;
+ }
+ }
+ }
+ return yyok;
+ }
+
+ /** Perform user action for rule number YYN, with RHS length YYRHSLEN,
+ * and top stack item YYVSP. YYVALP points to place to put semantic
+ * value ($$), and yylocp points to place for location information
+ * (@@$). Returns yyok for normal return, yyaccept for YYACCEPT,
+ * yyerr for YYERROR, yyabort for YYABORT. */
+ YYRESULTTAG
+ yyuserAction (rule_num yyrule, int yyrhslen, glr_stack_item* yyvsp, state_set_index yyk,
+ value_type* yyvalp]b4_locations_if([, location_type* yylocp])[)
+ {
+ bool yynormal YY_ATTRIBUTE_UNUSED = !yystateStack.isSplit();
+ int yylow = 1;
+]b4_parse_param_use([yyvalp], [yylocp])dnl
+[ YY_USE (yyk);
+ YY_USE (yyrhslen);
+ # undef yyerrok
+ # define yyerrok (yyerrState = 0)
+ # undef YYACCEPT
+ # define YYACCEPT return yyaccept
+ # undef YYABORT
+ # define YYABORT return yyabort
+ # undef YYERROR
+ # define YYERROR return yyerrok, yyerr
+ # undef YYRECOVERING
+ # define YYRECOVERING() (yyerrState != 0)
+ # undef yytoken
+ # define yytoken this->yyla.kind_
+ # undef yyclearin
+ # define yyclearin (yytoken = ]b4_symbol(empty, kind)[)
+ # undef YYBACKUP
+ # define YYBACKUP(Token, Value) \
+ return yyparser.error (]b4_locations_if([*yylocp, ])[YY_("syntax error: cannot back up")), \
+ yyerrok, yyerr
+
+]b4_variant_if([[
+ /* Variants are always initialized to an empty instance of the
+ correct type. The default '$$ = $1' action is NOT applied
+ when using variants. */
+ // However we really need to prepare yyvsp now if we want to get
+ // correct locations, so invoke YYFILL for $1 anyway.
+ (void) YYFILL (1-yyrhslen);
+ ]b4_symbol_variant([[yylhsNonterm (yyrule)]], [(*yyvalp)], [emplace])], [[
+ if (yyrhslen == 0)
+ *yyvalp = yyval_default;
+ else
+ *yyvalp = yyvsp[YYFILL (1-yyrhslen)].getState().value ();]])[]b4_locations_if([[
+ /* Default location. */
+ YYLLOC_DEFAULT ((*yylocp), (yyvsp - yyrhslen), yyrhslen);
+ yyerror_range[1].getState().yyloc = *yylocp;
+]])[
+ /* If yyk == -1, we are running a deferred action on a temporary
+ stack. In that case, YY_REDUCE_PRINT must not play with YYFILL,
+ so pretend the stack is "normal". */
+ YY_REDUCE_PRINT ((yynormal || yyk == create_state_set_index (-1), yyvsp, yyk, yyrule, yyparser));
+ #if YY_EXCEPTIONS
+ try
+ {
+ #endif // YY_EXCEPTIONS
+ switch (yyrule)
+ {
+ ]b4_user_actions[
+ default: break;
+ }
+ #if YY_EXCEPTIONS
+ }
+ catch (const syntax_error& yyexc)
+ {
+ YYCDEBUG << "Caught exception: " << yyexc.what() << '\n';]b4_locations_if([
+ *yylocp = yyexc.location;])[
+ yyparser.error (]b4_locations_if([*yylocp, ])[yyexc.what ());
+ YYERROR;
+ }
+ #endif // YY_EXCEPTIONS
+ YY_SYMBOL_PRINT ("-> $$ =", yylhsNonterm (yyrule), *yyvalp, *yylocp);
+
+ return yyok;
+ # undef yyerrok
+ # undef YYABORT
+ # undef YYACCEPT
+ # undef YYERROR
+ # undef YYBACKUP
+ # undef yytoken
+ # undef yyclearin
+ # undef YYRECOVERING
+ }
+
+ YYRESULTTAG
+ yyresolveStack ()
+ {
+ if (yystateStack.isSplit ())
+ {
+ int yyn = 0;
+ for (glr_state* yys = firstTopState ();
+ yys != yystateStack.yysplitPoint;
+ yys = yys->pred ())
+ yyn += 1;
+ YYCHK (yyresolveStates (*firstTopState (), yyn));
+ }
+ return yyok;
+ }
+
+ /** Pop the symbols consumed by reduction #YYRULE from the top of stack
+ * #YYK of *YYSTACKP, and perform the appropriate semantic action on their
+ * semantic values. Assumes that all ambiguities in semantic values
+ * have been previously resolved. Set *YYVALP to the resulting value,
+ * and *YYLOCP to the computed location (if any). Return value is as
+ * for userAction. */
+ YYRESULTTAG
+ yydoAction (state_set_index yyk, rule_num yyrule,
+ value_type* yyvalp]b4_locations_if([, location_type* yylocp])[)
+ {
+ const int yynrhs = yyrhsLength (yyrule);
+
+ if (!yystateStack.isSplit())
+ {
+ /* Standard special case: single stack. */
+ YYASSERT (yyk.get() == 0);
+ glr_stack_item* yyrhs = yystateStack.firstTop()->asItem();
+ const YYRESULTTAG res
+ = yyuserAction (yyrule, yynrhs, yyrhs, yyk, yyvalp]b4_locations_if([, yylocp])[);
+ yystateStack.pop_back(static_cast(yynrhs));
+ yystateStack.setFirstTop(&yystateStack[yystateStack.size() - 1].getState());
+ return res;
+ }
+ else
+ {
+ glr_stack_item yyrhsVals[YYMAXRHS + YYMAXLEFT + 1];
+ glr_state* yys = yystateStack.topAt(yyk);
+ yyrhsVals[YYMAXRHS + YYMAXLEFT].getState().setPred(yys);]b4_locations_if([[
+ if (yynrhs == 0)
+ /* Set default location. */
+ yyrhsVals[YYMAXRHS + YYMAXLEFT - 1].getState().yyloc = yys->yyloc;]])[
+ for (int yyi = 0; yyi < yynrhs; yyi += 1)
+ {
+ yys = yys->pred();
+ YYASSERT (yys != YY_NULLPTR);
+ }
+ yystateStack.yyupdateSplit (*yys);
+ yystateStack.setTopAt(yyk, yys);
+ return yyuserAction (yyrule, yynrhs, yyrhsVals + YYMAXRHS + YYMAXLEFT - 1,
+ yyk,
+ yyvalp]b4_locations_if([, yylocp])[);
+ }
+ }
+
+ /** Pop items off stack #YYK of *YYSTACKP according to grammar rule YYRULE,
+ * and push back on the resulting nonterminal symbol. Perform the
+ * semantic action associated with YYRULE and store its value with the
+ * newly pushed state, if YYFORCEEVAL or if *YYSTACKP is currently
+ * unambiguous. Otherwise, store the deferred semantic action with
+ * the new state. If the new state would have an identical input
+ * position, LR state, and predecessor to an existing state on the stack,
+ * it is identified with that existing state, eliminating stack #YYK from
+ * *YYSTACKP. In this case, the semantic value is
+ * added to the options for the existing state's semantic value.
+ */
+ YYRESULTTAG
+ yyglrReduce (state_set_index yyk, rule_num yyrule, bool yyforceEval)
+ {
+ size_t yyposn = topState(yyk)->yyposn;
+
+ if (yyforceEval || !yystateStack.isSplit())
+ {
+ value_type val;]b4_locations_if([[
+ location_type loc;]])[
+
+ YYRESULTTAG yyflag = yydoAction (yyk, yyrule, &val]b4_locations_if([, &loc])[);
+ if (yyflag == yyerr && yystateStack.isSplit())
+ {]b4_parse_trace_if([[
+ YYCDEBUG << "Parse on stack " << yyk.get ()
+ << " rejected by rule " << yyrule - 1
+ << " (line " << int (yyrline[yyrule]) << ").\n";
+ ]])[}
+ if (yyflag != yyok)
+ return yyflag;
+ yyglrShift (yyk,
+ yyLRgotoState (topState(yyk)->yylrState,
+ yylhsNonterm (yyrule)),
+ yyposn, val]b4_locations_if([, loc])[);]b4_variant_if([[
+ // FIXME: User destructors.
+ // Value type destructor.
+ ]b4_symbol_variant([[yylhsNonterm (yyrule)]], [[val]], [[template destroy]])])[
+ }
+ else
+ {
+ glr_state *yys = yystateStack.topAt(yyk);
+ glr_state *yys0 = yys;
+ for (int yyn = yyrhsLength (yyrule); 0 < yyn; yyn -= 1)
+ {
+ yys = yys->pred();
+ YYASSERT (yys != YY_NULLPTR);
+ }
+ yystateStack.yyupdateSplit (*yys);
+ state_num yynewLRState = yyLRgotoState (yys->yylrState, yylhsNonterm (yyrule));]b4_parse_trace_if([[
+ YYCDEBUG << "Reduced stack " << yyk.get ()
+ << " by rule " << yyrule - 1 << " (line " << int (yyrline[yyrule])
+ << "); action deferred. Now in state " << yynewLRState
+ << ".\n";]])[
+ for (state_set_index yyi = create_state_set_index(0); yyi.uget() < yystateStack.numTops(); ++yyi)
+ if (yyi != yyk && yystateStack.topAt(yyi) != YY_NULLPTR)
+ {
+ const glr_state* yysplit = yystateStack.yysplitPoint;
+ glr_state* yyp = yystateStack.topAt(yyi);
+ while (yyp != yys && yyp != yysplit
+ && yyp->yyposn >= yyposn)
+ {
+ if (yyp->yylrState == yynewLRState
+ && yyp->pred() == yys)
+ {
+ yyaddDeferredAction (yyk, yyp, yys0, yyrule);
+ yystateStack.yytops.yymarkStackDeleted (yyk);
+ YYCDEBUG << "Merging stack " << yyk.get ()
+ << " into stack " << yyi.get () << ".\n";
+ return yyok;
+ }
+ yyp = yyp->pred();
+ }
+ }
+ yystateStack.setTopAt(yyk, yys);
+ yyglrShiftDefer (yyk, yynewLRState, yyposn, yys0, yyrule);
+ }
+ return yyok;
+ }
+
+ /** Shift stack #YYK of *YYSTACKP, to a new state corresponding to LR
+ * state YYLRSTATE, at input position YYPOSN, with the (unresolved)
+ * semantic value of YYRHS under the action for YYRULE. */
+ void
+ yyglrShiftDefer (state_set_index yyk, state_num yylrState,
+ size_t yyposn, glr_state* yyrhs, rule_num yyrule)
+ {
+ glr_state& yynewState = yystateStack.yynewGLRState (
+ glr_state (yylrState, yyposn));
+ yynewState.setPred (yystateStack.topAt (yyk));
+ yystateStack.setTopAt (yyk, &yynewState);
+
+ /* Invokes yyreserveStack. */
+ yyaddDeferredAction (yyk, &yynewState, yyrhs, yyrule);
+ }
+
+ /** Shift to a new state on stack #YYK of *YYSTACKP, corresponding to LR
+ * state YYLRSTATE, at input position YYPOSN, with (resolved) semantic
+ * value YYVAL_ARG and source location YYLOC_ARG. */
+ void
+ yyglrShift (state_set_index yyk, state_num yylrState,
+ size_t yyposn,
+ const value_type& yyval_arg]b4_locations_if([, const location_type& yyloc_arg])[)
+ {
+ glr_state& yynewState = yystateStack.yynewGLRState (
+ glr_state (yylrState, yyposn, yyval_arg]b4_locations_if([, yyloc_arg])[));
+ yynewState.setPred (yystateStack.topAt(yyk));
+ yystateStack.setTopAt (yyk, &yynewState);
+ yyreserveGlrStack ();
+ }
+
+#if ]b4_api_PREFIX[DEBUG
+ void
+ yypstack (state_set_index yyk) const
+ {
+ yystateStack.yypstates (yystateStack.topAt (yyk));
+ }
+#endif
+
+ glr_state* topState(state_set_index i) {
+ return yystateStack.topAt(i);
+ }
+
+ glr_state* firstTopState() {
+ return yystateStack.firstTop();
+ }
+
+ private:
+
+ void popall_ ()
+ {
+ /* If the stack is well-formed, pop the stack until it is empty,
+ destroying its entries as we go. But free the stack regardless
+ of whether it is well-formed. */
+ for (state_set_index k = create_state_set_index(0); k.uget() < yystateStack.numTops(); k += 1)
+ if (yystateStack.topAt(k) != YY_NULLPTR)
+ {
+ while (yystateStack.topAt(k) != YY_NULLPTR)
+ {
+ glr_state* state = topState(k);]b4_locations_if([[
+ yyerror_range[1].getState().yyloc = state->yyloc;]])[
+ if (state->pred() != YY_NULLPTR)
+ state->destroy ("Cleanup: popping", yyparser);
+ yystateStack.setTopAt(k, state->pred());
+ yystateStack.pop_back();
+ }
+ break;
+ }
+ }
+
+ /** Resolve the previous YYN states starting at and including state YYS
+ * on *YYSTACKP. If result != yyok, some states may have been left
+ * unresolved possibly with empty semantic option chains. Regardless
+ * of whether result = yyok, each state has been left with consistent
+ * data so that destroy can be invoked if necessary. */
+ YYRESULTTAG
+ yyresolveStates (glr_state& yys, int yyn)
+ {
+ if (0 < yyn)
+ {
+ YYASSERT (yys.pred() != YY_NULLPTR);
+ YYCHK (yyresolveStates (*yys.pred(), yyn-1));
+ if (! yys.yyresolved)
+ YYCHK (yyresolveValue (yys));
+ }
+ return yyok;
+ }
+
+ static void
+ yyuserMerge (int yyn, value_type& yy0, value_type& yy1)
+ {
+ YY_USE (yy0);
+ YY_USE (yy1);
+
+ switch (yyn)
+ {
+]b4_mergers[
+ default: break;
+ }
+ }
+
+ /** Resolve the ambiguity represented in state YYS in *YYSTACKP,
+ * perform the indicated actions, and set the semantic value of YYS.
+ * If result != yyok, the chain of semantic options in YYS has been
+ * cleared instead or it has been left unmodified except that
+ * redundant options may have been removed. Regardless of whether
+ * result = yyok, YYS has been left with consistent data so that
+ * destroy can be invoked if necessary. */
+ YYRESULTTAG
+ yyresolveValue (glr_state& yys)
+ {
+ semantic_option* yybest = yys.firstVal();
+ YYASSERT(yybest != YY_NULLPTR);
+ bool yymerge = false;
+ YYRESULTTAG yyflag;]b4_locations_if([
+ location_type *yylocp = &yys.yyloc;])[
+
+ semantic_option* yypPrev = yybest;
+ for (semantic_option* yyp = yybest->next();
+ yyp != YY_NULLPTR; )
+ {
+ if (yybest->isIdenticalTo (*yyp))
+ {
+ yybest->mergeWith (*yyp);
+ yypPrev->setNext(yyp->next());
+ yyp = yypPrev->next();
+ }
+ else
+ {
+ switch (yypreference (*yybest, *yyp))
+ {
+ case 0:]b4_locations_if([[
+ yyresolveLocations (yys, 1);]])[
+ return yystateStack.yyreportAmbiguity (*yybest, *yyp, yyparser]b4_locations_if([, *yylocp])[);
+ break;
+ case 1:
+ yymerge = true;
+ break;
+ case 2:
+ break;
+ case 3:
+ yybest = yyp;
+ yymerge = false;
+ break;
+ default:
+ /* This cannot happen so it is not worth a YYASSERT (false),
+ but some compilers complain if the default case is
+ omitted. */
+ break;
+ }
+ yypPrev = yyp;
+ yyp = yyp->next();
+ }
+ }
+
+ value_type val;
+ if (yymerge)
+ {
+ int yyprec = yydprec[yybest->yyrule];
+ yyflag = yyresolveAction (*yybest, &val]b4_locations_if([, yylocp])[);
+ if (yyflag == yyok)
+ for (semantic_option* yyp = yybest->next();
+ yyp != YY_NULLPTR;
+ yyp = yyp->next())
+ {
+ if (yyprec == yydprec[yyp->yyrule])
+ {
+ value_type yyval_other;]b4_locations_if([
+ location_type yydummy;])[
+ yyflag = yyresolveAction (*yyp, &yyval_other]b4_locations_if([, &yydummy])[);
+ if (yyflag != yyok)
+ {
+ yyparser.yy_destroy_ ("Cleanup: discarding incompletely merged value for",
+ yy_accessing_symbol (yys.yylrState),
+ this->yyla.value]b4_locations_if([, *yylocp])[);
+ break;
+ }
+ yyuserMerge (yymerger[yyp->yyrule], val, yyval_other);]b4_variant_if([[
+ // FIXME: User destructors.
+ // Value type destructor.
+ ]b4_symbol_variant([[yy_accessing_symbol (yys.yylrState)]], [[yyval_other]], [[template destroy]])])[
+ }
+ }
+ }
+ else
+ yyflag = yyresolveAction (*yybest, &val]b4_locations_if([, yylocp])[);
+
+ if (yyflag == yyok)
+ {
+ yys.yyresolved = true;
+ YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN]b4_variant_if([[
+ new (&yys.value ()) value_type ();
+ ]b4_symbol_variant([yy_accessing_symbol (yys.yylrState)],
+ [yys.value ()], [copy], [val])], [[
+ new (&yys.value ()) value_type (val);]])[
+
+ YY_IGNORE_MAYBE_UNINITIALIZED_END
+ }
+ else
+ yys.setFirstVal(YY_NULLPTR);
+]b4_variant_if([[
+ // FIXME: User destructors.
+ // Value type destructor.
+ ]b4_symbol_variant([[yy_accessing_symbol (yys.yylrState)]], [[val]], [[template destroy]])])[
+ return yyflag;
+ }
+
+ /** Resolve the states for the RHS of YYOPT on *YYSTACKP, perform its
+ * user action, and return the semantic value and location in *YYVALP
+ * and *YYLOCP. Regardless of whether result = yyok, all RHS states
+ * have been destroyed (assuming the user action destroys all RHS
+ * semantic values if invoked). */
+ YYRESULTTAG
+ yyresolveAction (semantic_option& yyopt, value_type* yyvalp]b4_locations_if([, location_type* yylocp])[)
+ {
+ glr_state* yyoptState = yyopt.state();
+ YYASSERT(yyoptState != YY_NULLPTR);
+ int yynrhs = yyrhsLength (yyopt.yyrule);
+ YYRESULTTAG yyflag = yyresolveStates (*yyoptState, yynrhs);
+ if (yyflag != yyok)
+ {
+ for (glr_state *yys = yyoptState; yynrhs > 0; yys = yys->pred(), yynrhs -= 1)
+ yys->destroy ("Cleanup: popping", yyparser);
+ return yyflag;
+ }
+
+ glr_stack_item yyrhsVals[YYMAXRHS + YYMAXLEFT + 1];
+ yyrhsVals[YYMAXRHS + YYMAXLEFT].getState().setPred(yyopt.state());]b4_locations_if([[
+ if (yynrhs == 0)
+ /* Set default location. */
+ yyrhsVals[YYMAXRHS + YYMAXLEFT - 1].getState().yyloc = yyoptState->yyloc;]])[
+ {
+ symbol_type yyla_current = std::move (this->yyla);
+ this->yyla = std::move (yyopt.yyla);
+ yyflag = yyuserAction (yyopt.yyrule, yynrhs,
+ yyrhsVals + YYMAXRHS + YYMAXLEFT - 1,
+ create_state_set_index (-1),
+ yyvalp]b4_locations_if([, yylocp])[);
+ this->yyla = std::move (yyla_current);
+ }
+ return yyflag;
+ }]b4_locations_if([[
+
+ /** Resolve the locations for each of the YYN1 states in *YYSTACKP,
+ * ending at YYS1. Has no effect on previously resolved states.
+ * The first semantic option of a state is always chosen. */
+ void
+ yyresolveLocations (glr_state &yys1, int yyn1)
+ {
+ if (0 < yyn1)
+ {
+ yyresolveLocations (*yys1.pred(), yyn1 - 1);
+ if (!yys1.yyresolved)
+ {
+ glr_stack_item yyrhsloc[1 + YYMAXRHS];
+ YYASSERT (yys1.firstVal() != YY_NULLPTR);
+ semantic_option& yyoption = *yys1.firstVal();
+ const int yynrhs = yyrhsLength (yyoption.yyrule);
+ if (0 < yynrhs)
+ {
+ yyresolveLocations (*yyoption.state(), yynrhs);
+ const glr_state *yys = yyoption.state();
+ for (int yyn = yynrhs; yyn > 0; yyn -= 1)
+ {
+ yyrhsloc[yyn].getState().yyloc = yys->yyloc;
+ yys = yys->pred();
+ }
+ }
+ else
+ {
+ /* Both yyresolveAction and yyresolveLocations traverse the GSS
+ in reverse rightmost order. It is only necessary to invoke
+ yyresolveLocations on a subforest for which yyresolveAction
+ would have been invoked next had an ambiguity not been
+ detected. Thus the location of the previous state (but not
+ necessarily the previous state itself) is guaranteed to be
+ resolved already. */
+ YY_IGNORE_NULL_DEREFERENCE_BEGIN
+ yyrhsloc[0].getState().yyloc = yyoption.state()->yyloc;
+ YY_IGNORE_NULL_DEREFERENCE_END
+ }
+ YYLLOC_DEFAULT ((yys1.yyloc), yyrhsloc, yynrhs);
+ }
+ }
+ }]])[
+
+ /** If yytoken is empty, fetch the next token. */
+ void
+ yyget_token ()
+ {
+]b4_parse_param_use()dnl
+[ if (this->yyla.empty ())
+ {
+ YYCDEBUG << "Reading a token\n";
+#if YY_EXCEPTIONS
+ try
+#endif // YY_EXCEPTIONS
+ {]b4_token_ctor_if([[
+ symbol_type yylookahead (]b4_yylex[);
+ yyla.move (yylookahead);]], [[
+ yyla.kind_ = yyparser.yytranslate_ (]b4_yylex[);]])[
+ }
+#if YY_EXCEPTIONS
+ catch (const parser_type::syntax_error& yyexc)
+ {
+ YYCDEBUG << "Caught exception: " << yyexc.what () << '\n';]b4_locations_if([
+ this->yyla.location = yyexc.location;])[
+ yyparser.error (]b4_locations_if([this->yyla.location, ])[yyexc.what ());
+ // Map errors caught in the scanner to the error token, so that error
+ // handling is started.
+ this->yyla.kind_ = ]b4_symbol(error, kind)[;
+ }
+ }
+#endif // YY_EXCEPTIONS
+ if (this->yyla.kind () == ]b4_symbol(eof, kind)[)
+ YYCDEBUG << "Now at end of input.\n";
+ else
+ YY_SYMBOL_PRINT ("Next token is", this->yyla.kind (), this->yyla.value, this->yyla.location);
+ }
+
+
+ /* Bison grammar-table manipulation. */
+
+ /** The action to take in YYSTATE on seeing YYTOKEN.
+ * Result R means
+ * R < 0: Reduce on rule -R.
+ * R = 0: Error.
+ * R > 0: Shift to state R.
+ * Set *YYCONFLICTS to a pointer into yyconfl to a 0-terminated list
+ * of conflicting reductions.
+ */
+ static int
+ yygetLRActions (state_num yystate, symbol_kind_type yytoken, const short*& yyconflicts)
+ {
+ int yyindex = yypact[yystate] + yytoken;
+ if (yytoken == ]b4_symbol(error, kind)[)
+ {
+ // This is the error token.
+ yyconflicts = yyconfl;
+ return 0;
+ }
+ else if (yy_is_defaulted_state (yystate)
+ || yyindex < 0 || YYLAST < yyindex || yycheck[yyindex] != yytoken)
+ {
+ yyconflicts = yyconfl;
+ return -yydefact[yystate];
+ }
+ else if (! yytable_value_is_error (yytable[yyindex]))
+ {
+ yyconflicts = yyconfl + yyconflp[yyindex];
+ return yytable[yyindex];
+ }
+ else
+ {
+ yyconflicts = yyconfl + yyconflp[yyindex];
+ return 0;
+ }
+ }
+
+ /** Compute post-reduction state.
+ * \param yystate the current state
+ * \param yysym the nonterminal to push on the stack
+ */
+ static state_num
+ yyLRgotoState (state_num yystate, symbol_kind_type yysym)
+ {
+ const int yyr = yypgoto[yysym - YYNTOKENS] + yystate;
+ if (0 <= yyr && yyr <= YYLAST && yycheck[yyr] == yystate)
+ return yytable[yyr];
+ else
+ return yydefgoto[yysym - YYNTOKENS];
+ }
+
+ static bool
+ yypact_value_is_default (state_num yystate)
+ {
+ return ]b4_table_value_equals([[pact]], [[yystate]], [b4_pact_ninf], [YYPACT_NINF])[;
+ }
+
+ static bool
+ yytable_value_is_error (int yytable_value YY_ATTRIBUTE_UNUSED)
+ {
+ return ]b4_table_value_equals([[table]], [[yytable_value]], [b4_table_ninf], [YYTABLE_NINF])[;
+ }
+
+ static bool
+ yy_is_shift_action (int yyaction) YY_NOEXCEPT
+ {
+ return 0 < yyaction;
+ }
+
+ static bool
+ yy_is_error_action (int yyaction) YY_NOEXCEPT
+ {
+ return yyaction == 0;
+ }
+
+ /** Whether LR state YYSTATE has only a default reduction
+ * (regardless of token). */
+ static bool
+ yy_is_defaulted_state (state_num yystate)
+ {
+ return yypact_value_is_default (yypact[yystate]);
+ }
+
+ /** The default reduction for YYSTATE, assuming it has one. */
+ static rule_num
+ yy_default_action (state_num yystate)
+ {
+ return yydefact[yystate];
+ }
+
+ /* GLRStacks */
+
+ /** Y0 and Y1 represent two possible actions to take in a given
+ * parsing state; return 0 if no combination is possible,
+ * 1 if user-mergeable, 2 if Y0 is preferred, 3 if Y1 is preferred. */
+ static int
+ yypreference (const semantic_option& y0, const semantic_option& y1)
+ {
+ const rule_num r0 = y0.yyrule, r1 = y1.yyrule;
+ const int p0 = yydprec[r0], p1 = yydprec[r1];
+
+ if (p0 == p1)
+ {
+ if (yymerger[r0] == 0 || yymerger[r0] != yymerger[r1])
+ return 0;
+ else
+ return 1;
+ }
+ else if (p0 == 0 || p1 == 0)
+ return 0;
+ else if (p0 < p1)
+ return 3;
+ else if (p1 < p0)
+ return 2;
+ else
+ return 0;
+ }
+
+]b4_parse_param_vars[
+ }; // class ]b4_parser_class[::glr_stack
+} // namespace ]b4_namespace_ref[
+
+
+#if ]b4_api_PREFIX[DEBUG
+namespace
+{
+ void
+ yypstack (const glr_stack& yystack, size_t yyk)
+ {
+ yystack.yypstack (create_state_set_index (static_cast (yyk)));
+ }
+
+ void
+ yypdumpstack (const glr_stack& yystack)
+ {
+ yystack.yypdumpstack ();
+ }
+}
+#endif
+
+]b4_namespace_open[
+ /// Build a parser object.
+ ]b4_parser_class::b4_parser_class[ (]b4_parse_param_decl[)]m4_ifset([b4_parse_param], [
+ :])[
+#if ]b4_api_PREFIX[DEBUG
+ ]m4_ifset([b4_parse_param], [ ], [ :])[yycdebug_ (&std::cerr)]m4_ifset([b4_parse_param], [,])[
+#endif]b4_parse_param_cons[
+ {}
+
+ ]b4_parser_class::~b4_parser_class[ ()
+ {}
+
+ ]b4_parser_class[::syntax_error::~syntax_error () YY_NOEXCEPT YY_NOTHROW
+ {}
+
+ int
+ ]b4_parser_class[::operator() ()
+ {
+ return parse ();
+ }
+
+ int
+ ]b4_parser_class[::parse ()
+ {
+ glr_stack yystack(YYINITDEPTH, *this]b4_user_args[);
+ return yystack.parse ();
+ }
+
+]b4_parse_error_bmatch([custom\|detailed],
+[[ const char *
+ ]b4_parser_class[::symbol_name (symbol_kind_type yysymbol)
+ {
+ static const char *const yy_sname[] =
+ {
+ ]b4_symbol_names[
+ };]b4_has_translations_if([[
+ /* YYTRANSLATABLE[SYMBOL-NUM] -- Whether YY_SNAME[SYMBOL-NUM] is
+ internationalizable. */
+ static ]b4_int_type_for([b4_translatable])[ yytranslatable[] =
+ {
+ ]b4_translatable[
+ };
+ return (yysymbol < YYNTOKENS && yytranslatable[yysymbol]
+ ? _(yy_sname[yysymbol])
+ : yy_sname[yysymbol]);]], [[
+ return yy_sname[yysymbol];]])[
+ }
+]],
+[simple],
+[[#if ]b4_api_PREFIX[DEBUG || ]b4_token_table_flag[
+ const char *
+ ]b4_parser_class[::symbol_name (symbol_kind_type yysymbol)
+ {
+ return yytname_[yysymbol];
+ }
+#endif // #if ]b4_api_PREFIX[DEBUG || ]b4_token_table_flag[
+]],
+[verbose],
+[[ /* Return YYSTR after stripping away unnecessary quotes and
+ backslashes, so that it's suitable for yyerror. The heuristic is
+ that double-quoting is unnecessary unless the string contains an
+ apostrophe, a comma, or backslash (other than backslash-backslash).
+ YYSTR is taken from yytname. */
+ std::string
+ ]b4_parser_class[::yytnamerr_ (const char *yystr)
+ {
+ if (*yystr == '"')
+ {
+ std::string yyr;
+ char const *yyp = yystr;
+
+ for (;;)
+ switch (*++yyp)
+ {
+ case '\'':
+ case ',':
+ goto do_not_strip_quotes;
+
+ case '\\':
+ if (*++yyp != '\\')
+ goto do_not_strip_quotes;
+ else
+ goto append;
+
+ append:
+ default:
+ yyr += *yyp;
+ break;
+
+ case '"':
+ return yyr;
+ }
+ do_not_strip_quotes: ;
+ }
+
+ return yystr;
+ }
+
+ std::string
+ ]b4_parser_class[::symbol_name (symbol_kind_type yysymbol)
+ {
+ return yytnamerr_ (yytname_[yysymbol]);
+ }
+]])[
+
+]b4_parse_error_bmatch([simple\|verbose],
+[[#if ]b4_api_PREFIX[DEBUG]b4_tname_if([[ || 1]])[
+ // YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
+ // First, the terminals, then, starting at \a YYNTOKENS, nonterminals.
+ const char*
+ const ]b4_parser_class[::yytname_[] =
+ {
+ ]b4_tname[
+ };
+#endif
+]])[
+
+]b4_parse_error_bmatch([custom\|detailed\|verbose], [[
+ // ]b4_parser_class[::context.
+ ]b4_parser_class[::context::context (glr_stack& yystack, const symbol_type& yyla)
+ : yystack_ (yystack)
+ , yyla_ (yyla)
+ {}
+
+ int
+ ]b4_parser_class[::context::expected_tokens (symbol_kind_type yyarg[], int yyargn) const
+ {
+ // Actual number of expected tokens
+ int yycount = 0;
+ const int yyn = yypact[yystack_.firstTopState()->yylrState];
+ if (!yystack_.yypact_value_is_default (yyn))
+ {
+ /* Start YYX at -YYN if negative to avoid negative indexes in
+ YYCHECK. In other words, skip the first -YYN actions for this
+ state because they are default actions. */
+ const int yyxbegin = yyn < 0 ? -yyn : 0;
+ /* Stay within bounds of both yycheck and yytname. */
+ const int yychecklim = YYLAST - yyn + 1;
+ const int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
+ for (int yyx = yyxbegin; yyx < yyxend; ++yyx)
+ if (yycheck[yyx + yyn] == yyx && yyx != ]b4_symbol(error, kind)[
+ && !yystack_.yytable_value_is_error (yytable[yyx + yyn]))
+ {
+ if (!yyarg)
+ ++yycount;
+ else if (yycount == yyargn)
+ return 0;
+ else
+ yyarg[yycount++] = YY_CAST (symbol_kind_type, yyx);
+ }
+ }
+ if (yyarg && yycount == 0 && 0 < yyargn)
+ yyarg[0] = ]b4_symbol(empty, kind)[;
+ return yycount;
+ }
+
+]])[
+
+]b4_parse_error_bmatch([detailed\|verbose], [[
+ int
+ ]b4_parser_class[::yy_syntax_error_arguments_ (const context& yyctx,
+ symbol_kind_type yyarg[], int yyargn) const
+ {
+ /* There are many possibilities here to consider:
+ - If this state is a consistent state with a default action, then
+ the only way this function was invoked is if the default action
+ is an error action. In that case, don't check for expected
+ tokens because there are none.
+ - The only way there can be no lookahead present (in yyla) is
+ if this state is a consistent state with a default action.
+ Thus, detecting the absence of a lookahead is sufficient to
+ determine that there is no unexpected or expected token to
+ report. In that case, just report a simple "syntax error".
+ - Don't assume there isn't a lookahead just because this state is
+ a consistent state with a default action. There might have
+ been a previous inconsistent state, consistent state with a
+ non-default action, or user semantic action that manipulated
+ yyla. (However, yyla is currently not documented for users.)
+ */
+
+ if (!yyctx.lookahead ().empty ())
+ {
+ if (yyarg)
+ yyarg[0] = yyctx.token ();
+ int yyn = yyctx.expected_tokens (yyarg ? yyarg + 1 : yyarg, yyargn - 1);
+ return yyn + 1;
+ }
+ return 0;
+ }
+
+ // Generate an error message.
+ std::string
+ ]b4_parser_class[::yysyntax_error_ (const context& yyctx) const
+ {
+ // Its maximum.
+ enum { YYARGS_MAX = 5 };
+ // Arguments of yyformat.
+ symbol_kind_type yyarg[YYARGS_MAX];
+ int yycount = yy_syntax_error_arguments_ (yyctx, yyarg, YYARGS_MAX);
+
+ char const* yyformat = YY_NULLPTR;
+ switch (yycount)
+ {
+#define YYCASE_(N, S) \
+ case N: \
+ yyformat = S; \
+ break
+ default: // Avoid compiler warnings.
+ YYCASE_ (0, YY_("syntax error"));
+ YYCASE_ (1, YY_("syntax error, unexpected %s"));
+ YYCASE_ (2, YY_("syntax error, unexpected %s, expecting %s"));
+ YYCASE_ (3, YY_("syntax error, unexpected %s, expecting %s or %s"));
+ YYCASE_ (4, YY_("syntax error, unexpected %s, expecting %s or %s or %s"));
+ YYCASE_ (5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"));
+#undef YYCASE_
+ }
+
+ std::string yyres;
+ // Argument number.
+ std::ptrdiff_t yyi = 0;
+ for (char const* yyp = yyformat; *yyp; ++yyp)
+ if (yyp[0] == '%' && yyp[1] == 's' && yyi < yycount)
+ {
+ yyres += symbol_name (yyarg[yyi++]);
+ ++yyp;
+ }
+ else
+ yyres += *yyp;
+ return yyres;
+ }]])[
+
+ void
+ ]b4_parser_class[::yy_destroy_ (const char* yymsg, symbol_kind_type yykind,
+ value_type& yyval]b4_locations_if([[,
+ location_type& yyloc]])[)
+ {
+ YY_USE (yyval);]b4_locations_if([[
+ YY_USE (yyloc);]])[
+ if (!yymsg)
+ yymsg = "Deleting";
+ ]b4_parser_class[& yyparser = *this;
+ YY_USE (yyparser);
+ YY_SYMBOL_PRINT (yymsg, yykind, yyval, yyloc);
+
+ YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+ ]m4_do([m4_pushdef([b4_symbol_action], m4_defn([b4_symbol_action_for_yyval]))],
+ [b4_symbol_actions([destructor])],
+ [m4_popdef([b4_symbol_action])])[
+ YY_IGNORE_MAYBE_UNINITIALIZED_END
+ }
+
+#if ]b4_api_PREFIX[DEBUG
+ /*--------------------.
+ | Print this symbol. |
+ `--------------------*/
+
+ void
+ ]b4_parser_class[::yy_symbol_value_print_ (symbol_kind_type yykind,
+ const value_type& yyval]b4_locations_if([[,
+ const location_type& yyloc]])[) const
+ {]b4_locations_if([[
+ YY_USE (yyloc);]])[
+ YY_USE (yyval);
+ std::ostream& yyo = debug_stream ();
+ YY_USE (yyo);
+ ]m4_do([m4_pushdef([b4_symbol_action], m4_defn([b4_symbol_action_for_yyval]))],
+ [b4_symbol_actions([printer])],
+ [m4_popdef([b4_symbol_action])])[
+ }
+
+ void
+ ]b4_parser_class[::yy_symbol_print_ (symbol_kind_type yykind,
+ const value_type& yyval]b4_locations_if([[,
+ const location_type& yyloc]])[) const
+ {
+ *yycdebug_ << (yykind < YYNTOKENS ? "token" : "nterm")
+ << ' ' << symbol_name (yykind) << " ("]b4_locations_if([[
+ << yyloc << ": "]])[;
+ yy_symbol_value_print_ (yykind, yyval]b4_locations_if([[, yyloc]])[);
+ *yycdebug_ << ')';
+ }
+
+ std::ostream&
+ ]b4_parser_class[::debug_stream () const
+ {
+ return *yycdebug_;
+ }
+
+ void
+ ]b4_parser_class[::set_debug_stream (std::ostream& o)
+ {
+ yycdebug_ = &o;
+ }
+
+
+ ]b4_parser_class[::debug_level_type
+ ]b4_parser_class[::debug_level () const
+ {
+ return yydebug;
+ }
+
+ void
+ ]b4_parser_class[::set_debug_level (debug_level_type l)
+ {
+ // Actually, it is yydebug which is really used.
+ yydebug = l;
+ }
+#endif // ]b4_api_PREFIX[DEBUG
+
+]b4_token_ctor_if([], [b4_yytranslate_define([cc])])[
+
+]b4_token_ctor_if([], [[
+ /*---------.
+ | symbol. |
+ `---------*/
+]b4_public_types_define([cc])])[
+]b4_namespace_close[]dnl
+b4_epilogue[]dnl
+b4_output_end
diff --git a/bison/data/skeletons/java-skel.m4 b/bison/data/skeletons/java-skel.m4
index bcc8ebd..11cbc49 100644
--- a/bison/data/skeletons/java-skel.m4
+++ b/bison/data/skeletons/java-skel.m4
@@ -2,7 +2,7 @@
# Java skeleton dispatching for Bison.
-# Copyright (C) 2007, 2009-2015, 2018-2020 Free Software Foundation,
+# Copyright (C) 2007, 2009-2015, 2018-2021 Free Software Foundation,
# Inc.
# This program is free software: you can redistribute it and/or modify
@@ -16,7 +16,7 @@
# 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 .
+# along with this program. If not, see .
b4_glr_if( [b4_complain([%%glr-parser not supported for Java])])
b4_nondeterministic_if([b4_complain([%%nondeterministic-parser not supported for Java])])
diff --git a/bison/data/skeletons/java.m4 b/bison/data/skeletons/java.m4
index 7b4f7b5..8b0828b 100644
--- a/bison/data/skeletons/java.m4
+++ b/bison/data/skeletons/java.m4
@@ -2,7 +2,7 @@
# Java language support for Bison
-# Copyright (C) 2007-2015, 2018-2020 Free Software Foundation, Inc.
+# Copyright (C) 2007-2015, 2018-2021 Free Software Foundation, Inc.
# 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
@@ -15,7 +15,7 @@
# 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 .
+# along with this program. If not, see .
m4_include(b4_skeletonsdir/[c-like.m4])
diff --git a/bison/data/skeletons/lalr1.cc b/bison/data/skeletons/lalr1.cc
index b95f9aa..7cb69d3 100644
--- a/bison/data/skeletons/lalr1.cc
+++ b/bison/data/skeletons/lalr1.cc
@@ -1,6 +1,6 @@
# C++ skeleton for Bison
-# Copyright (C) 2002-2015, 2018-2020 Free Software Foundation, Inc.
+# Copyright (C) 2002-2015, 2018-2021 Free Software Foundation, Inc.
# 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
@@ -13,15 +13,14 @@
# 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 .
+# along with this program. If not, see .
m4_include(b4_skeletonsdir/[c++.m4])
# api.value.type=variant is valid.
m4_define([b4_value_type_setup_variant])
-# Check the value of %define parse.lac, where LAC stands for lookahead
-# correction.
+# parse.lac
b4_percent_define_default([[parse.lac]], [[none]])
b4_percent_define_check_values([[[[parse.lac]], [[full]], [[none]]]])
b4_define_flag_if([lac])
@@ -146,21 +145,21 @@ b4_dollar_popdef[]dnl
])])
-# b4_lex
-# ------
+# b4_yylex
+# --------
# Call yylex.
-m4_define([b4_lex],
+m4_define([b4_yylex],
[b4_token_ctor_if(
[b4_function_call([yylex],
[symbol_type], m4_ifdef([b4_lex_param], b4_lex_param))],
[b4_function_call([yylex], [int],
- [b4_api_PREFIX[STYPE*], [&yyla.value]][]dnl
-b4_locations_if([, [[location*], [&yyla.location]]])dnl
+ [[value_type *], [&yyla.value]][]dnl
+b4_locations_if([, [[location_type *], [&yyla.location]]])dnl
m4_ifdef([b4_lex_param], [, ]b4_lex_param))])])
m4_pushdef([b4_copyright_years],
- [2002-2015, 2018-2020])
+ [2002-2015, 2018-2021])
m4_define([b4_parser_class],
[b4_percent_define_get([[api.parser.class]])])
@@ -174,7 +173,7 @@ b4_variant_if([m4_include(b4_skeletonsdir/[variant.hh])])
# b4_shared_declarations(hh|cc)
# -----------------------------
-# Declaration that might either go into the header (if --defines, $1 = hh)
+# Declaration that might either go into the header (if --header, $1 = hh)
# or in the implementation file.
m4_define([b4_shared_declarations],
[b4_percent_code_get([[requires]])[
@@ -271,9 +270,9 @@ m4_define([b4_shared_declarations],
{
public:
context (const ]b4_parser_class[& yyparser, const symbol_type& yyla);
- const symbol_type& lookahead () const { return yyla_; }
- symbol_kind_type token () const { return yyla_.kind (); }]b4_locations_if([[
- const location_type& location () const { return yyla_.location; }
+ const symbol_type& lookahead () const YY_NOEXCEPT { return yyla_; }
+ symbol_kind_type token () const YY_NOEXCEPT { return yyla_.kind (); }]b4_locations_if([[
+ const location_type& location () const YY_NOEXCEPT { return yyla_.location; }
]])[
/// Put in YYARG at most YYARGN of the expected tokens, and return the
/// number of tokens stored in YYARG. If YYARG is null, return the
@@ -307,11 +306,11 @@ m4_define([b4_shared_declarations],
/// Stored state numbers (used for stacks).
typedef ]b4_int_type(0, m4_eval(b4_states_number - 1))[ state_type;
]b4_parse_error_bmatch(
- [custom], [[
+[custom], [[
/// Report a syntax error
/// \param yyctx the context in which the error occurred.
void report_syntax_error (const context& yyctx) const;]],
- [detailed\|verbose], [[
+[detailed\|verbose], [[
/// The arguments of the error message.
int yy_syntax_error_arguments_ (const context& yyctx,
symbol_kind_type yyarg[], int yyargn) const;
@@ -326,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],
@@ -408,7 +407,7 @@ m4_define([b4_shared_declarations],
void move (by_state& that);
/// The symbol kind (corresponding to \a state).
- /// \a ]b4_symbol(-2, kind)[ when empty.
+ /// \a ]b4_symbol(empty, kind)[ when empty.
symbol_kind_type kind () const YY_NOEXCEPT;
/// The state number used to denote an empty symbol.
@@ -475,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
@@ -494,16 +493,21 @@ m4_define([b4_shared_declarations],
]b4_namespace_close[
]b4_percent_code_get([[provides]])[
-]])
+]])[
+
## -------------- ##
## Output files. ##
## -------------- ##
-b4_defines_if(
-[b4_output_begin([b4_spec_header_file])
-b4_copyright([Skeleton interface for Bison LALR(1) parsers in C++])
-[
+# ------------- #
+# Header file. #
+# ------------- #
+
+]b4_header_if([[
+]b4_output_begin([b4_spec_header_file])[
+]b4_copyright([Skeleton interface for Bison LALR(1) parsers in C++])[
+
/**
** \file ]b4_spec_mapped_header_file[
** Define the ]b4_namespace_ref[::parser class.
@@ -516,10 +520,14 @@ b4_copyright([Skeleton interface for Bison LALR(1) parsers in C++])
]b4_shared_declarations(hh)[
]b4_cpp_guard_close([b4_spec_mapped_header_file])[
]b4_output_end[
-]])
+]])[
+
+# --------------------- #
+# Implementation file. #
+# --------------------- #
-b4_output_begin([b4_parser_file_name])[
+]b4_output_begin([b4_parser_file_name])[
]b4_copyright([Skeleton implementation for Bison LALR(1) parsers in C++])[
]b4_disclaimer[
]b4_percent_code_get([[top]])[]dnl
@@ -530,7 +538,7 @@ m4_if(b4_prefix, [yy], [],
]b4_user_pre_prologue[
-]b4_defines_if([[#include "@basename(]b4_spec_header_file[@)"]],
+]b4_header_if([[#include "@basename(]b4_spec_header_file[@)"]],
[b4_shared_declarations([cc])])[
]b4_user_post_prologue[
@@ -597,7 +605,7 @@ m4_if(b4_prefix, [yy], [],
#else // !]b4_api_PREFIX[DEBUG
# define YYCDEBUG if (false) std::cerr
-# define YY_SYMBOL_PRINT(Title, Symbol) YYUSE (Symbol)
+# define YY_SYMBOL_PRINT(Title, Symbol) YY_USE (Symbol)
# define YY_REDUCE_PRINT(Rule) static_cast (0)
# define YY_STACK_PRINT() static_cast (0)
@@ -629,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])])[
@@ -665,7 +673,7 @@ m4_if(b4_prefix, [yy], [],
]b4_parser_class[::by_state::kind () const YY_NOEXCEPT
{
if (state == empty_state)
- return ]b4_symbol(-2, kind)[;
+ return ]b4_symbol(empty, kind)[;
else
return YY_CAST (symbol_kind_type, yystos_[+state]);
}
@@ -690,7 +698,7 @@ m4_if(b4_prefix, [yy], [],
b4_symbol_variant([that.kind ()],
[value], [move], [YY_MOVE (that.value)])])[
// that is emptied.
- that.kind_ = ]b4_symbol(-2, kind)[;
+ that.kind_ = ]b4_symbol(empty, kind)[;
}
#if YY_CPLUSPLUS < 201103L
@@ -736,7 +744,7 @@ m4_if(b4_prefix, [yy], [],
]b4_parser_class[::yy_print_ (std::ostream& yyo, const basic_symbol& yysym) const
{
std::ostream& yyoutput = yyo;
- YYUSE (yyoutput);
+ YY_USE (yyoutput);
if (yysym.empty ())
yyo << "empty symbol";
else
@@ -771,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);
}
@@ -814,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_;
}
@@ -851,8 +859,8 @@ m4_if(b4_prefix, [yy], [],
/// The return value of parse ().
int yyresult;]b4_lac_if([[
- /// Discard the LAC context in case there still is one left from a
- /// previous invocation.
+ // Discard the LAC context in case there still is one left from a
+ // previous invocation.
yy_lac_discard_ ("init");]])[
#if YY_EXCEPTIONS
@@ -904,9 +912,9 @@ b4_dollar_popdef])[]dnl
try
#endif // YY_EXCEPTIONS
{]b4_token_ctor_if([[
- symbol_type yylookahead (]b4_lex[);
+ symbol_type yylookahead (]b4_yylex[);
yyla.move (yylookahead);]], [[
- yyla.kind_ = yytranslate_ (]b4_lex[);]])[
+ yyla.kind_ = yytranslate_ (]b4_yylex[);]])[
}
#if YY_EXCEPTIONS
catch (const syntax_error& yyexc)
@@ -919,13 +927,13 @@ b4_dollar_popdef])[]dnl
}
YY_SYMBOL_PRINT ("Next token is", yyla);
- if (yyla.kind () == ]b4_symbol(1, kind)[)
+ if (yyla.kind () == ]b4_symbol(error, kind)[)
{
// The scanner already issued an error message, process directly
// to error recovery. But do not keep the error token as
// lookahead, it is too special and may lead us to an endless
// loop in error recovery. */
- yyla.kind_ = ]b4_symbol(2, kind)[;
+ yyla.kind_ = ]b4_symbol(undef, kind)[;
goto yyerrlab1;
}
@@ -935,7 +943,7 @@ b4_dollar_popdef])[]dnl
if (yyn < 0 || yylast_ < yyn || yycheck_[yyn] != yyla.kind ())
{]b4_lac_if([[
if (!yy_lac_establish_ (yyla.kind ()))
- goto yyerrlab;]])[
+ goto yyerrlab;]])[
goto yydefault;
}
@@ -946,7 +954,7 @@ b4_dollar_popdef])[]dnl
if (yy_table_value_is_error_ (yyn))
goto yyerrlab;]b4_lac_if([[
if (!yy_lac_establish_ (yyla.kind ()))
- goto yyerrlab;
+ goto yyerrlab;
]])[
yyn = -yyn;
goto yyreduce;
@@ -979,11 +987,11 @@ b4_dollar_popdef])[]dnl
yylen = yyr2_[yyn];
{
stack_symbol_type yylhs;
- yylhs.state = yy_lr_goto_state_ (yystack_[yylen].state, yyr1_[yyn]);]b4_variant_if([
+ yylhs.state = yy_lr_goto_state_ (yystack_[yylen].state, yyr1_[yyn]);]b4_variant_if([[
/* Variants are always initialized to an empty instance of the
correct type. The default '$$ = $1' action is NOT applied
when using variants. */
- b4_symbol_variant([[yyr1_@{yyn@}]], [yylhs.value], [emplace])], [
+ ]b4_symbol_variant([[yyr1_@{yyn@}]], [yylhs.value], [emplace])], [[
/* If YYLEN is nonzero, implement the default value of the
action: '$$ = $1'. Otherwise, use the top of the stack.
@@ -993,7 +1001,7 @@ b4_dollar_popdef])[]dnl
if (yylen)
yylhs.value = yystack_@{yylen - 1@}.value;
else
- yylhs.value = yystack_@{0@}.value;])[
+ yylhs.value = yystack_@{0@}.value;]])[
]b4_locations_if([dnl
[
// Default location.
@@ -1062,7 +1070,7 @@ b4_dollar_popdef])[]dnl
error, discard it. */
// Return failure if at end of input.
- if (yyla.kind () == ]b4_symbol(0, kind)[)
+ if (yyla.kind () == ]b4_symbol(eof, kind)[)
YYABORT;
else if (!yyla.empty ())
{
@@ -1103,9 +1111,9 @@ b4_dollar_popdef])[]dnl
yyn = yypact_[+yystack_[0].state];
if (!yy_pact_value_is_default_ (yyn))
{
- yyn += ]b4_symbol(1, kind)[;
+ yyn += ]b4_symbol(error, kind)[;
if (0 <= yyn && yyn <= yylast_
- && yycheck_[yyn] == ]b4_symbol(1, kind)[)
+ && yycheck_[yyn] == ]b4_symbol(error, kind)[)
{
yyn = yytable_[yyn];
if (0 < yyn)
@@ -1297,8 +1305,8 @@ b4_dollar_popdef])[]dnl
for (int yyx = 0; yyx < YYNTOKENS; ++yyx)
{
symbol_kind_type yysym = YY_CAST (symbol_kind_type, yyx);
- if (yysym != ]b4_symbol(1, kind)[
- && yysym != ]b4_symbol(2, kind)[
+ if (yysym != ]b4_symbol(error, kind)[
+ && yysym != ]b4_symbol(undef, kind)[
&& yyparser_.yy_lac_check_ (yysym))
{
if (!yyarg)
@@ -1309,18 +1317,18 @@ b4_dollar_popdef])[]dnl
yyarg[yycount++] = yysym;
}
}]], [[
- int yyn = yypact_[+yyparser_.yystack_[0].state];
+ const int yyn = yypact_[+yyparser_.yystack_[0].state];
if (!yy_pact_value_is_default_ (yyn))
{
/* Start YYX at -YYN if negative to avoid negative indexes in
YYCHECK. In other words, skip the first -YYN actions for
this state because they are default actions. */
- int yyxbegin = yyn < 0 ? -yyn : 0;
+ const int yyxbegin = yyn < 0 ? -yyn : 0;
// Stay within bounds of both yycheck and yytname.
- int yychecklim = yylast_ - yyn + 1;
- int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
+ const int yychecklim = yylast_ - yyn + 1;
+ const int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
for (int yyx = yyxbegin; yyx < yyxend; ++yyx)
- if (yycheck_[yyx + yyn] == yyx && yyx != ]b4_symbol(1, kind)[
+ if (yycheck_[yyx + yyn] == yyx && yyx != ]b4_symbol(error, kind)[
&& !yy_table_value_is_error_ (yytable_[yyx + yyn]))
{
if (!yyarg)
@@ -1333,11 +1341,13 @@ b4_dollar_popdef])[]dnl
}
]])[
if (yyarg && yycount == 0 && 0 < yyargn)
- yyarg[0] = ]b4_symbol(-2, kind)[;
+ yyarg[0] = ]b4_symbol(empty, kind)[;
return yycount;
}
-]])b4_lac_if([[
+]])[
+
+]b4_lac_if([[
bool
]b4_parser_class[::yy_lac_check_ (symbol_kind_type yytoken) const
{
@@ -1442,7 +1452,9 @@ b4_dollar_popdef])[]dnl
follows. If no initial context is currently established for the
current lookahead, then check if that lookahead can eventually be
shifted if syntactic actions continue from the current context. */
- if (!yy_lac_established_)
+ if (yy_lac_established_)
+ return true;
+ else
{
#if ]b4_api_PREFIX[DEBUG
YYCDEBUG << "LAC: initial context established for "
@@ -1451,12 +1463,11 @@ b4_dollar_popdef])[]dnl
yy_lac_established_ = true;
return yy_lac_check_ (yytoken);
}
- return true;
}
// Discard any previous initial lookahead context.
void
- ]b4_parser_class[::yy_lac_discard_ (const char* evt)
+ ]b4_parser_class[::yy_lac_discard_ (const char* event)
{
/* Discard any previous initial lookahead context because of Event,
which may be a lookahead change or an invalidation of the currently
@@ -1472,11 +1483,12 @@ b4_dollar_popdef])[]dnl
if (yy_lac_established_)
{
YYCDEBUG << "LAC: initial context discarded due to "
- << evt << '\n';
+ << event << '\n';
yy_lac_established_ = false;
}
- }]])b4_parse_error_bmatch([detailed\|verbose], [[
+ }]])[
+]b4_parse_error_bmatch([detailed\|verbose], [[
int
]b4_parser_class[::yy_syntax_error_arguments_ (const context& yyctx,
symbol_kind_type yyarg[], int yyargn) const
diff --git a/bison/data/skeletons/lalr1.d b/bison/data/skeletons/lalr1.d
index 761125c..9730377 100644
--- a/bison/data/skeletons/lalr1.d
+++ b/bison/data/skeletons/lalr1.d
@@ -1,6 +1,6 @@
# D skeleton for Bison -*- autoconf -*-
-# Copyright (C) 2007-2012, 2019-2020 Free Software Foundation, Inc.
+# Copyright (C) 2007-2012, 2019-2021 Free Software Foundation, Inc.
# 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
@@ -13,14 +13,55 @@
# 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 .
+# along with this program. If not, see .
m4_include(b4_skeletonsdir/[d.m4])
+b4_header_if([b4_complain([%header/%defines does not make sense in D])])
+# parse.lac
+b4_percent_define_default([[parse.lac]], [[none]])
+b4_percent_define_check_values([[[[parse.lac]], [[full]], [[none]]]])
+b4_define_flag_if([lac])
+m4_define([b4_lac_flag],
+ [m4_if(b4_percent_define_get([[parse.lac]]),
+ [none], [[0]], [[1]])])
+
+
+## --------------- ##
+## api.push-pull. ##
+## --------------- ##
+
+b4_percent_define_default([[api.push-pull]], [[pull]])
+b4_percent_define_check_values([[[[api.push-pull]],
+ [[pull]], [[push]], [[both]]]])
+
+# Define m4 conditional macros that encode the value
+# of the api.push-pull flag.
+b4_define_flag_if([pull]) m4_define([b4_pull_flag], [[1]])
+b4_define_flag_if([push]) m4_define([b4_push_flag], [[1]])
+m4_case(b4_percent_define_get([[api.push-pull]]),
+ [pull], [m4_define([b4_push_flag], [[0]])],
+ [push], [m4_define([b4_pull_flag], [[0]])])
+
+# Define a macro to be true when api.push-pull has the value "both".
+m4_define([b4_both_if],[b4_push_if([b4_pull_if([$1],[$2])],[$2])])
+
+# Handle BISON_USE_PUSH_FOR_PULL for the test suite. So that push parsing
+# tests function as written, do not let BISON_USE_PUSH_FOR_PULL modify the
+# behavior of Bison at all when push parsing is already requested.
+b4_define_flag_if([use_push_for_pull])
+b4_use_push_for_pull_if([
+ b4_push_if([m4_define([b4_use_push_for_pull_flag], [[0]])],
+ [m4_define([b4_push_flag], [[1]])])])
+
+
+# Define a macro to encapsulate the parse state variables. This
+# allows them to be defined either in parse() when doing pull parsing,
+# or as class instance variable when doing push parsing.
b4_output_begin([b4_parser_file_name])
b4_copyright([Skeleton implementation for Bison LALR(1) parsers in D],
- [2007-2012, 2019-2020])[
+ [2007-2012, 2019-2021])[
]b4_disclaimer[
]b4_percent_define_ifdef([package], [module b4_percent_define_get([package]);
])[
@@ -33,6 +74,29 @@ version(D_Version2) {
]b4_user_post_prologue[
]b4_percent_code_get([[imports]])[
import std.format;
+import std.conv;
+
+/**
+ * Handle error message internationalisation.
+ */
+static if (!is(typeof(YY_))) {
+ version(YYENABLE_NLS)
+ {
+ version(ENABLE_NLS)
+ {
+ extern(C) char* dgettext(const char*, const char*);
+ string YY_(const char* s)
+ {
+ return to!string(dgettext("bison-runtime", s));
+ }
+ }
+ }
+ static if (!is(typeof(YY_)))
+ {
+ pragma(inline, true)
+ string YY_(string msg) { return msg; }
+ }
+}
/**
* A Bison parser, automatically generated from ]m4_bpatsubst(b4_file_name, [^"\(.*\)"$], [\1])[.
@@ -46,29 +110,13 @@ import std.format;
* parser ]b4_parser_class[.
*/
public interface Lexer
-{]b4_locations_if([[
- /**
- * Method to retrieve the beginning position of the last scanned token.
- * @@return the position at which the last scanned token starts. */
- @@property ]b4_position_type[ startPos ();
-
- /**
- * Method to retrieve the ending position of the last scanned token.
- * @@return the first position beyond the last scanned token. */
- @@property ]b4_position_type[ endPos ();
-
-]])[
- /**
- * Method to retrieve the semantic value of the last scanned token.
- * @@return the semantic value of the last scanned token. */
- @@property ]b4_yystype[ semanticVal ();
-
+{
/**
* Entry point for the scanner. Returns the token identifier corresponding
* to the next token and prepares to return the semantic value
* ]b4_locations_if([and beginning/ending positions ])[of the token.
* @@return the token identifier corresponding to the next token. */
- int yylex ();
+ Symbol yylex ();
/**
* Entry point for error reporting. Emits an error
@@ -77,16 +125,26 @@ public interface Lexer
* @@param loc The location of the element to which the
* error message is related]])[
* @@param s The string for the error message. */
- void yyerror (]b4_locations_if([b4_location_type[ loc, ]])[string s);
+ void yyerror (]b4_locations_if([[const Location loc, ]])[string s);
+]b4_parse_error_bmatch([custom], [[
+ /**
+ * Build and emit a "syntax error" message in a user-defined way.
+ *
+ * @@param ctx The context of the error.
+ */
+ void reportSyntaxError(]b4_parser_class[.Context ctx);
+]])[
}
+]b4_public_types_declare[
+
]b4_locations_if([b4_position_type_if([[
static assert(__traits(compiles,
- (new ]b4_position_type[[1])[0]=(new ]b4_position_type[[1])[0]),
- "struct/class ]b4_position_type[ must be default-constructible "
+ (new Position[1])[0]=(new Position[1])[0]),
+ "struct/class Position must be default-constructible "
"and assignable");
-static assert(__traits(compiles, (new string[1])[0]=(new ]b4_position_type[).toString()),
- "error: struct/class ]b4_position_type[ must have toString method");
+static assert(__traits(compiles, (new string[1])[0]=(new Position).toString()),
+ "error: struct/class Position must have toString method");
]], [[
/**
* A struct denoting a point in the input.*/
@@ -109,59 +167,65 @@ public struct ]b4_position_type[ {
}
}
]])b4_location_type_if([[
-static assert(__traits(compiles, (new ]b4_location_type[((new ]b4_position_type[[1])[0]))) &&
- __traits(compiles, (new ]b4_location_type[((new ]b4_position_type[[1])[0], (new ]b4_position_type[[1])[0]))),
- "error: struct/class ]b4_location_type[ must have "
- "default constructor and constructors this(]b4_position_type[) and this(]b4_position_type[, ]b4_position_type[).");
-static assert(__traits(compiles, (new ]b4_location_type[[1])[0].begin=(new ]b4_location_type[[1])[0].begin) &&
- __traits(compiles, (new ]b4_location_type[[1])[0].begin=(new ]b4_location_type[[1])[0].end) &&
- __traits(compiles, (new ]b4_location_type[[1])[0].end=(new ]b4_location_type[[1])[0].begin) &&
- __traits(compiles, (new ]b4_location_type[[1])[0].end=(new ]b4_location_type[[1])[0].end),
- "error: struct/class ]b4_location_type[ must have assignment-compatible "
+static assert(__traits(compiles, (new Location((new Position[1])[0]))) &&
+ __traits(compiles, (new Location((new Position[1])[0], (new Position[1])[0]))),
+ "error: struct/class Location must have "
+ "default constructor and constructors this(Position) and this(Position, Position).");
+static assert(__traits(compiles, (new Location[1])[0].begin=(new Location[1])[0].begin) &&
+ __traits(compiles, (new Location[1])[0].begin=(new Location[1])[0].end) &&
+ __traits(compiles, (new Location[1])[0].end=(new Location[1])[0].begin) &&
+ __traits(compiles, (new Location[1])[0].end=(new Location[1])[0].end),
+ "error: struct/class Location must have assignment-compatible "
"members/properties 'begin' and 'end'.");
-static assert(__traits(compiles, (new string[1])[0]=(new ]b4_location_type[[1])[0].toString()),
- "error: struct/class ]b4_location_type[ must have toString method.");
+static assert(__traits(compiles, (new string[1])[0]=(new Location[1])[0].toString()),
+ "error: struct/class Location must have toString method.");
-private immutable bool yy_location_is_class = !__traits(compiles, *(new ]b4_location_type[((new ]b4_position_type[[1])[0])));]], [[
+private immutable bool yy_location_is_class = !__traits(compiles, *(new Location((new Position[1])[0])));]], [[
/**
- * A class defining a pair of positions. Positions, defined by the
- * ]b4_position_type[
class, denote a point in the input.
+ * A struct defining a pair of positions. Positions, defined by the
+ * Position
struct, denote a point in the input.
* Locations represent a part of the input through the beginning
* and ending positions. */
-public class ]b4_location_type[
+public struct ]b4_location_type[
{
/** The first, inclusive, position in the range. */
- public ]b4_position_type[ begin;
+ public Position begin;
/** The first position beyond the range. */
- public ]b4_position_type[ end;
+ public Position end;
/**
- * Create a ]b4_location_type[
denoting an empty range located at
+ * Create a Location
denoting an empty range located at
* a given point.
* @@param loc The position at which the range is anchored. */
- public this (]b4_position_type[ loc) {
+ public this(Position loc)
+ {
this.begin = this.end = loc;
}
- public this () {
- }
-
/**
- * Create a ]b4_location_type[
from the endpoints of the range.
+ * Create a Location
from the endpoints of the range.
* @@param begin The first position included in the range.
* @@param end The first position beyond the range. */
- public this (]b4_position_type[ begin, ]b4_position_type[ end)
+ public this(Position begin, Position end)
{
this.begin = begin;
this.end = end;
}
/**
- * A representation of the location. For this to be correct,
- * ]b4_position_type[
should override the toString
- * method. */
- public override string toString () const {
+ * Reset initial location to final location.
+ */
+ public void step()
+ {
+ this.begin = this.end;
+ }
+
+ /**
+ * A representation of the location.
+ */
+ public string toString() const
+ {
auto end_col = 0 < end.column ? end.column - 1 : 0;
auto res = begin.toString ();
if (end.filename && begin.filename != end.filename)
@@ -174,9 +238,9 @@ public class ]b4_location_type[
}
}
-private immutable bool yy_location_is_class = true;
+private immutable bool yy_location_is_class = false;
-]])])m4_ifdef([b4_user_union_members], [private union YYSemanticType
+]])])[]b4_value_type_setup[]m4_ifdef([b4_user_union_members], [private union YYSemanticType
{
b4_user_union_members
};],
@@ -190,18 +254,18 @@ b4_user_union_members
]b4_declare_symbol_enum[
]b4_locations_if([[
- private final ]b4_location_type[ yylloc_from_stack (ref YYStack rhs, int n)
+ private final Location yylloc_from_stack (ref YYStack rhs, int n)
{
static if (yy_location_is_class) {
if (n > 0)
- return new ]b4_location_type[ (rhs.locationAt (n-1).begin, rhs.locationAt (0).end);
+ return new Location (rhs.locationAt (n-1).begin, rhs.locationAt (0).end);
else
- return new ]b4_location_type[ (rhs.locationAt (0).end);
+ return new Location (rhs.locationAt (0).end);
} else {
if (n > 0)
- return ]b4_location_type[ (rhs.locationAt (n-1).begin, rhs.locationAt (0).end);
+ return Location (rhs.locationAt (n-1).begin, rhs.locationAt (0).end);
else
- return ]b4_location_type[ (rhs.locationAt (0).end);
+ return Location (rhs.locationAt (0).end);
}
}]])[
@@ -219,6 +283,9 @@ b4_user_union_members
* Instantiate the Bison-generated parser.
*/
public this] (b4_parse_param_decl([b4_lex_param_decl])[) {
+]b4_percent_code_get([[init]])[]b4_lac_if([[
+ this.yylacStack = new int[];
+ this.yylacEstablished = false;]])[
this (new YYLexer(]b4_lex_param_call[));
}
]])[
@@ -233,6 +300,7 @@ b4_user_union_members
]b4_parse_param_cons[
}
]b4_parse_trace_if([[
+ import std.stdio;
private File yyDebugStream;
/**
@@ -272,14 +340,20 @@ b4_user_union_members
yyDebugStream.writeln (s);
}
]])[
- private final int yylex () {
+ private final ]b4_parser_class[.Symbol yylex () {
return yylexer.yylex ();
}
- protected final void yyerror (]b4_locations_if(ref [b4_location_type[ loc, ]])[string s) {
+ protected final void yyerror (]b4_locations_if([[const Location loc, ]])[string s) {
yylexer.yyerror (]b4_locations_if([loc, ])[s);
}
+ /**
+ * The number of syntax errors so far.
+ */
+ public int numberOfErrors() const { return yynerrs_; }
+ private int yynerrs_ = 0;
+
/**
* Returned by a Bison action in order to stop the parsing process and
* return success (true). */
@@ -289,6 +363,11 @@ b4_user_union_members
* Returned by a Bison action in order to stop the parsing process and
* return failure (false). */
public static immutable int YYABORT = 1;
+]b4_push_if([
+ /**
+ * Returned by a Bison action in order to request a new token.
+ */
+ public static immutable int YYPUSH_MORE = 4;])[
/**
* Returned by a Bison action in order to start error recovery without
@@ -303,10 +382,43 @@ b4_user_union_members
private static immutable int YYREDUCE = 6;
private static immutable int YYERRLAB1 = 7;
private static immutable int YYRETURN = 8;
+]b4_push_if([[ private static immutable int YYGETTOKEN = 9; /* Signify that a new token is expected when doing push-parsing. */]])[
+
]b4_locations_if([
private static immutable YYSemanticType yy_semantic_null;])[
private int yyerrstatus_ = 0;
+ private void yyerrok()
+ {
+ yyerrstatus_ = 0;
+ }
+
+ // Lookahead symbol kind.
+ SymbolKind yytoken = ]b4_symbol(empty, kind)[;
+
+ /* State. */
+ int yyn = 0;
+ int yylen = 0;
+ int yystate = 0;
+
+ YYStack yystack;
+
+ int label = YYNEWSTATE;
+
+ /* Error handling. */
+]b4_locations_if([[
+ /// The location where the error started.
+ Location yyerrloc;
+
+ /// Location of the lookahead.
+ Location yylloc;
+
+ /// @@$.
+ Location yyloc;]])[
+
+ /// Semantic value of the lookahead.
+ Value yylval;
+
/**
* Whether error recovery is being done. In this state, the parser
* reads token until it reaches a known state, and then restarts normal
@@ -316,10 +428,22 @@ b4_user_union_members
return yyerrstatus_ == 0;
}
+ /** Compute post-reduction state.
+ * @@param yystate the current state
+ * @@param yysym the nonterminal to push on the stack
+ */
+ private int yyLRGotoState(int yystate, int yysym) {
+ int yyr = yypgoto_[yysym - yyntokens_] + yystate;
+ if (0 <= yyr && yyr <= yylast_ && yycheck_[yyr] == yystate)
+ return yytable_[yyr];
+ else
+ return yydefgoto_[yysym - yyntokens_];
+ }
+
private int yyaction (int yyn, ref YYStack yystack, int yylen)
{
- ]b4_yystype[ yyval;]b4_locations_if([[
- ]b4_location_type[ yyloc = yylloc_from_stack (yystack, yylen);]])[
+ Value yyval;]b4_locations_if([[
+ Location yyloc = yylloc_from_stack (yystack, yylen);]])[
/* If YYLEN is nonzero, implement the default value of the action:
`$$ = $1'. Otherwise, use the top of the stack.
@@ -342,83 +466,47 @@ b4_user_union_members
}
]b4_parse_trace_if([[
- import std.conv : to;
yy_symbol_print ("-> $$ =", to!SymbolKind (yyr1_[yyn]), yyval]b4_locations_if([, yyloc])[);]])[
yystack.pop (yylen);
yylen = 0;
/* Shift the result of the reduction. */
- yyn = yyr1_[yyn];
- int yystate = yypgoto_[yyn - yyntokens_] + yystack.stateAt (0);
- if (0 <= yystate && yystate <= yylast_
- && yycheck_[yystate] == yystack.stateAt (0))
- yystate = yytable_[yystate];
- else
- yystate = yydefgoto_[yyn - yyntokens_];
-
+ int yystate = yyLRGotoState(yystack.stateAt(0), yyr1_[yyn]);
yystack.push (yystate, yyval]b4_locations_if([, yyloc])[);
return YYNEWSTATE;
}
- /* Return YYSTR after stripping away unnecessary quotes and
- backslashes, so that it's suitable for yyerror. The heuristic is
- that double-quoting is unnecessary unless the string contains an
- apostrophe, a comma, or backslash (other than backslash-backslash).
- YYSTR is taken from yytname. */
- private final string yytnamerr_ (string yystr)
- {
- if (yystr[0] == '"')
- {
- string yyr;
- strip_quotes:
- for (int i = 1; i < yystr.length; i++)
- switch (yystr[i])
- {
- case '\'':
- case ',':
- break strip_quotes;
-
- case '\\':
- if (yystr[++i] != '\\')
- break strip_quotes;
- goto default;
- default:
- yyr ~= yystr[i];
- break;
-
- case '"':
- return yyr;
- }
- }
- else if (yystr == "$end")
- return "end of input";
-
- return yystr;
- }
]b4_parse_trace_if([[
/*--------------------------------.
| Print this symbol on YYOUTPUT. |
`--------------------------------*/
private final void yy_symbol_print (string s, SymbolKind yykind,
- ref ]b4_yystype[ yyvaluep]dnl
-b4_locations_if([, ref ]b4_location_type[ yylocationp])[)
+ ref Value yyval]b4_locations_if([, ref Location yyloc])[)
{
if (0 < yydebug)
{
- string message = s ~ (yykind < yyntokens_ ? " token " : " nterm ")
- ~ yytname_[yykind] ~ " ("]b4_locations_if([
- ~ yylocationp.toString() ~ ": "])[;
- static if (__traits(compiles, message ~= yyvaluep.toString ()))
- message ~= yyvaluep.toString ();
- else
- message ~= format ("%s", &yyvaluep);
- message ~= ")";
- yycdebugln (message);
+ File yyo = yyDebugStream;
+ yyo.write(s);
+ yyo.write(yykind < yyntokens_ ? " token " : " nterm ");
+ yyo.write(format("%s", yykind));
+ yyo.write(" ("]b4_locations_if([ ~ yyloc.toString() ~ ": "])[);
+ ]b4_symbol_actions([printer])[
+ yyo.write(")\n");
}
}
]])[
+]b4_symbol_type_define[
+]b4_push_if([[
+ /**
+ * Push Parse input from external lexer
+ *
+ * @@param yyla current Symbol
+ *
+ * @@return YYACCEPT, YYABORT, YYPUSH_MORE
+ */
+ public int pushParse(Symbol yyla)]], [[
/**
* Parse input from the scanner that was specified at object construction
* time. Return whether the end of the input was reached successfully.
@@ -426,35 +514,21 @@ b4_locations_if([, ref ]b4_location_type[ yylocationp])[)
* @@return true if the parsing succeeds. Note that this does not
* imply that there were no syntax errors.
*/
- public bool parse ()
- {
- // Lookahead token kind.
- int yychar = TokenKind.YYEMPTY;
- // Lookahead symbol kind.
- SymbolKind yytoken = ]b4_symbol(-2, kind)[;
-
- /* State. */
- int yyn = 0;
- int yylen = 0;
- int yystate = 0;
-
- YYStack yystack;
-
- /* Error handling. */
- int yynerrs_ = 0;]b4_locations_if([[
- /// The location where the error started.
- ]b4_location_type[ yyerrloc = null;
-
- /// ]b4_location_type[ of the lookahead.
- ]b4_location_type[ yylloc;
-
- /// @@$.
- ]b4_location_type[ yyloc;]])[
-
- /// Semantic value of the lookahead.
- ]b4_yystype[ yylval;
+ public bool parse()]])[
+ {]b4_push_if([[
+ if (!this.pushParseInitialized)
+ {
+ pushParseInitialize();
+ yyerrstatus_ = 0;
+ }
+ else
+ label = YYGETTOKEN;
- bool yyresult;]b4_parse_trace_if([[
+ bool push_token_consumed = true;
+]], [[ bool yyresult;]b4_lac_if([[
+ // Discard the LAC context in case there still is one left from a
+ // previous invocation.
+ yylacDiscard("init");]])[]b4_parse_trace_if([[
yycdebugln ("Starting parse");]])[
yyerrstatus_ = 0;
@@ -470,7 +544,7 @@ m4_popdef([b4_at_dollar])])dnl
[ /* Initialize the stack. */
yystack.push (yystate, yylval]b4_locations_if([, yylloc])[);
- int label = YYNEWSTATE;
+ label = YYNEWSTATE;]])[
for (;;)
final switch (label)
{
@@ -482,42 +556,50 @@ m4_popdef([b4_at_dollar])])dnl
yystack.print (yyDebugStream);]])[
/* Accept? */
- if (yystate == yyfinal_)
- return true;
+ if (yystate == yyfinal_)]b4_push_if([[
+ {
+ label = YYACCEPT;
+ break;
+ }]], [[
+ return true;]])[
/* Take a decision. First try without lookahead. */
yyn = yypact_[yystate];
- if (yy_pact_value_is_default_ (yyn))
+ if (yyPactValueIsDefault(yyn))
{
label = YYDEFAULT;
break;
- }
+ }]b4_push_if([[
+ goto case;
+
+ case YYGETTOKEN:]])[
/* Read a lookahead token. */
- if (yychar == TokenKind.YYEMPTY)
- {]b4_parse_trace_if([[
- yycdebugln ("Reading a token");]])[
- yychar = yylex ();]b4_locations_if([[
- static if (yy_location_is_class) {
- yylloc = new ]b4_location_type[(yylexer.startPos, yylexer.endPos);
- } else {
- yylloc = ]b4_location_type[(yylexer.startPos, yylexer.endPos);
- }]])
- yylval = yylexer.semanticVal;[
+ if (yytoken == ]b4_symbol(empty, kind)[)
+ {]b4_push_if([[
+ if (!push_token_consumed)
+ return YYPUSH_MORE;]])[]b4_parse_trace_if([[
+ yycdebugln ("Reading a token");]])[]b4_push_if([[
+ yytoken = yyla.token;
+ yylval = yyla.value;]b4_locations_if([[
+ yylloc = yyla.location;]])[
+ push_token_consumed = false;]], [[
+ Symbol yysymbol = yylex();
+ yytoken = yysymbol.token();
+ yylval = yysymbol.value();]b4_locations_if([[
+ yylloc = yysymbol.location();]])[]])[
}
- /* Convert token to internal form. */
- yytoken = yytranslate_ (yychar);]b4_parse_trace_if([[
+ /* Token already converted to internal form. */]b4_parse_trace_if([[
yy_symbol_print ("Next token is", yytoken, yylval]b4_locations_if([, yylloc])[);]])[
- if (yytoken == ]b4_symbol(1, kind)[)
+ if (yytoken == ]b4_symbol(error, kind)[)
{
// The scanner already issued an error message, process directly
// to error recovery. But do not keep the error token as
// lookahead, it is too special and may lead us to an endless
// loop in error recovery. */
- yychar = TokenKind.]b4_symbol(2, id)[;
- yytoken = ]b4_symbol(2, kind)[;]b4_locations_if([[
+ yytoken = ]b4_symbol(undef, kind)[;]b4_locations_if([[
yyerrloc = yylloc;]])[
label = YYERRLAB1;
}
@@ -526,14 +608,19 @@ m4_popdef([b4_at_dollar])])dnl
/* If the proper action on seeing token YYTOKEN is to reduce or to
detect an error, take that action. */
yyn += yytoken;
- if (yyn < 0 || yylast_ < yyn || yycheck_[yyn] != yytoken)
- label = YYDEFAULT;
-
+ if (yyn < 0 || yylast_ < yyn || yycheck_[yyn] != yytoken) {]b4_lac_if([[
+ if (!yylacEstablish(yystack, yytoken))
+ label = YYERRLAB;
+ else]])[
+ label = YYDEFAULT;
+ }
/* <= 0 means reduce or error. */
else if ((yyn = yytable_[yyn]) <= 0)
{
- if (yy_table_value_is_error_ (yyn))
- label = YYERRLAB;
+ if (yyTableValueIsError(yyn))
+ label = YYERRLAB;]b4_lac_if([[
+ else if (!yylacEstablish(yystack, yytoken))
+ label = YYERRLAB;]])[
else
{
yyn = -yyn;
@@ -546,7 +633,7 @@ m4_popdef([b4_at_dollar])])dnl
yy_symbol_print ("Shifting", yytoken, yylval]b4_locations_if([, yylloc])[);]])[
/* Discard the token being shifted. */
- yychar = TokenKind.YYEMPTY;
+ yytoken = ]b4_symbol(empty, kind)[;
/* Count tokens shifted since error; after three, turn off error
* status. */
@@ -554,7 +641,8 @@ m4_popdef([b4_at_dollar])])dnl
--yyerrstatus_;
yystate = yyn;
- yystack.push (yystate, yylval]b4_locations_if([, yylloc])[);
+ yystack.push (yystate, yylval]b4_locations_if([, yylloc])[);]b4_lac_if([[
+ yylacDiscard("shift");]])[
label = YYNEWSTATE;
}
}
@@ -588,9 +676,7 @@ m4_popdef([b4_at_dollar])])dnl
if (yyerrstatus_ == 0)
{
++yynerrs_;
- if (yychar == TokenKind.]b4_symbol(-2, id)[)
- yytoken = ]b4_symbol(-2, kind)[;
- yyerror (]b4_locations_if([yylloc, ])[yysyntax_error (yystate, yytoken));
+ yyreportSyntaxError(new Context(]b4_lac_if([[this, ]])[yystack, yytoken]b4_locations_if([[, yylloc]])[));
}
]b4_locations_if([
yyerrloc = yylloc;])[
@@ -599,14 +685,15 @@ m4_popdef([b4_at_dollar])])dnl
/* If just tried and failed to reuse lookahead token after an
* error, discard it. */
- if (yychar <= TokenKind.]b4_symbol(0, [id])[)
+ /* Return failure if at end of input. */
+ if (yytoken == ]b4_symbol(eof, [kind])[)]b4_push_if([[
{
- /* Return failure if at end of input. */
- if (yychar == TokenKind.]b4_symbol(0, [id])[)
- return false;
- }
+ label = YYABORT;
+ break;
+ }]], [[
+ return false;]])[
else
- yychar = TokenKind.YYEMPTY;
+ yytoken = ]b4_symbol(empty, kind)[;
}
/* Else will try to reuse lookahead token after shifting the error
@@ -637,10 +724,10 @@ m4_popdef([b4_at_dollar])])dnl
for (;;)
{
yyn = yypact_[yystate];
- if (!yy_pact_value_is_default_ (yyn))
+ if (!yyPactValueIsDefault(yyn))
{
- yyn += ]b4_symbol(1, kind)[;
- if (0 <= yyn && yyn <= yylast_ && yycheck_[yyn] == ]b4_symbol(1, kind)[)
+ yyn += ]b4_symbol(error, kind)[;
+ if (0 <= yyn && yyn <= yylast_ && yycheck_[yyn] == ]b4_symbol(error, kind)[)
{
yyn = yytable_[yyn];
if (0 < yyn)
@@ -649,16 +736,23 @@ m4_popdef([b4_at_dollar])])dnl
}
/* Pop the current state because it cannot handle the error token. */
- if (yystack.height == 1)
- return false;
+ if (yystack.height == 1)]b4_push_if([[
+ {
+ label = YYABORT;
+ break;
+ }]],[[
+ return false;]])[
]b4_locations_if([ yyerrloc = yystack.locationAt (0);])[
yystack.pop ();
yystate = yystack.stateAt (0);]b4_parse_trace_if([[
if (0 < yydebug)
yystack.print (yyDebugStream);]])[
- }
-
+ }]b4_push_if([[
+ if (label == YYABORT)
+ /* Leave the switch. */
+ break;
+]])[
]b4_locations_if([
/* Muck with the stack to setup for yylloc. */
yystack.push (0, yy_semantic_null, yylloc);
@@ -666,8 +760,8 @@ m4_popdef([b4_at_dollar])])dnl
yyloc = yylloc_from_stack (yystack, 2);
yystack.pop (2);])[
- /* Shift the error token. */]b4_parse_trace_if([[
- import std.conv : to;
+ /* Shift the error token. */]b4_lac_if([[
+ yylacDiscard("error recovery");]])[]b4_parse_trace_if([[
yy_symbol_print ("Shifting", to!SymbolKind (yystos_[yyn]), yylval]b4_locations_if([, yyloc])[);]])[
yystate = yyn;
yystack.push (yyn, yylval]b4_locations_if([, yyloc])[);
@@ -675,33 +769,136 @@ m4_popdef([b4_at_dollar])])dnl
break;
/* Accept. */
- case YYACCEPT:
+ case YYACCEPT:]b4_push_if([[
+ this.pushParseInitialized = false;]b4_parse_trace_if([[
+ if (0 < yydebug)
+ yystack.print (yyDebugStream);]])[
+ return YYACCEPT;]], [[
yyresult = true;
label = YYRETURN;
- break;
+ break;]])[
/* Abort. */
- case YYABORT:
+ case YYABORT:]b4_push_if([[
+ this.pushParseInitialized = false;]b4_parse_trace_if([[
+ if (0 < yydebug)
+ yystack.print (yyDebugStream);]])[
+ return YYABORT;]], [[
yyresult = false;
label = YYRETURN;
- break;
-
- case YYRETURN:]b4_parse_trace_if([[
+ break;]])[
+]b4_push_if([[]], [[ ][case YYRETURN:]b4_parse_trace_if([[
if (0 < yydebug)
yystack.print (yyDebugStream);]])[
- return yyresult;
+ return yyresult;]])[
}
+ assert(0);
}
+]b4_push_if([[
+ bool pushParseInitialized = false;
+
+ /**
+ * (Re-)Initialize the state of the push parser.
+ */
+ public void pushParseInitialize()
+ {
+
+ /* Lookahead and lookahead in internal form. */
+ this.yytoken = ]b4_symbol(empty, kind)[;
+
+ /* State. */
+ this.yyn = 0;
+ this.yylen = 0;
+ this.yystate = 0;
+ destroy(this.yystack);
+ this.label = YYNEWSTATE;
+]b4_lac_if([[
+ destroy(this.yylacStack);
+ this.yylacEstablished = false;]])[
+
+ /* Error handling. */
+ this.yynerrs_ = 0;
+]b4_locations_if([
+ /* The location where the error started. */
+ this.yyerrloc = Location(Position(), Position());
+ this.yylloc = Location(Position(), Position());])[
+
+ /* Semantic value of the lookahead. */
+ //destroy(this.yylval);
+
+ /* Initialize the stack. */
+ yystack.push(this.yystate, this.yylval]b4_locations_if([, this.yylloc])[);
+
+ this.pushParseInitialized = true;
+ }]])[]b4_both_if([[
+ /**
+ * Parse input from the scanner that was specified at object construction
+ * time. Return whether the end of the input was reached successfully.
+ * This version of parse() is defined only when api.push-push=both.
+ *
+ * @@return true if the parsing succeeds. Note that this does not
+ * imply that there were no syntax errors.
+ */
+ bool parse()
+ {
+ int status = 0;
+ do {
+ status = this.pushParse(yylex());
+ } while (status == YYPUSH_MORE);
+ return status == YYACCEPT;
+ }]])[
+
// Generate an error message.
- private final string yysyntax_error (int yystate, SymbolKind tok)
- {]b4_parse_error_case([verbose], [[
+ private final void yyreportSyntaxError(Context yyctx)
+ {]b4_parse_error_bmatch(
+[custom], [[
+ yylexer.reportSyntaxError(yyctx);]],
+[detailed], [[
+ if (yyctx.getToken() != ]b4_symbol(empty, kind)[)
+ {
+ // FIXME: This method of building the message is not compatible
+ // with internationalization.
+ immutable int argmax = 5;
+ SymbolKind[] yyarg = new SymbolKind[argmax];
+ int yycount = yysyntaxErrorArguments(yyctx, yyarg, argmax);
+ string res, yyformat;
+ switch (yycount)
+ {
+ case 1:
+ yyformat = YY_("syntax error, unexpected %s");
+ res = format(yyformat, yyarg[0]);
+ break;
+ case 2:
+ yyformat = YY_("syntax error, unexpected %s, expecting %s");
+ res = format(yyformat, yyarg[0], yyarg[1]);
+ break;
+ case 3:
+ yyformat = YY_("syntax error, unexpected %s, expecting %s or %s");
+ res = format(yyformat, yyarg[0], yyarg[1], yyarg[2]);
+ break;
+ case 4:
+ yyformat = YY_("syntax error, unexpected %s, expecting %s or %s or %s");
+ res = format(yyformat, yyarg[0], yyarg[1], yyarg[2], yyarg[3]);
+ break;
+ case 5:
+ yyformat = YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s");
+ res = format(yyformat, yyarg[0], yyarg[1], yyarg[2], yyarg[3], yyarg[4]);
+ break;
+ default:
+ res = YY_("syntax error");
+ break;
+ }
+ yyerror(]b4_locations_if([yyctx.getLocation(), ])[res);
+ }]],
+[[simple]], [[
+ yyerror(]b4_locations_if([yyctx.getLocation(), ])[YY_("syntax error"));]])[
+ }
+
+]b4_parse_error_bmatch(
+[detailed], [[
+ private int yysyntaxErrorArguments(Context yyctx, SymbolKind[] yyarg, int yyargn) {
/* There are many possibilities here to consider:
- - Assume YYFAIL is not used. It's too flawed to consider.
- See
-
- for details. YYERROR is fine as it does not invoke this
- function.
- If this state is a consistent state with a default action,
then the only way this function was invoked is if the
default action is an error action. In that case, don't
@@ -726,15 +923,85 @@ m4_popdef([b4_at_dollar])])dnl
list is correct for canonical LR with one exception: it
will still contain any token that will not be accepted due
to an error action in a later state.
- */
- if (tok != ]b4_symbol(-2, kind)[)
+ */
+ int yycount = 0;
+ if (yyctx.getToken() != ]b4_symbol(empty, kind)[)
+ {
+ if (yyarg !is null)
+ yyarg[yycount] = yyctx.getToken();
+ yycount += 1;
+ yycount += yyctx.getExpectedTokens(yyarg, 1, yyargn);
+ }
+ return yycount;
+ }
+]])[
+
+
+ /**
+ * Information needed to get the list of expected tokens and to forge
+ * a syntax error diagnostic.
+ */
+ public static final class Context
+ {]b4_lac_if([[
+ private ]b4_parser_class[ yyparser;]])[
+ private const(YYStack) yystack;
+ private SymbolKind yytoken;]b4_locations_if([[
+ private const(Location) yylocation;]])[
+
+ this(]b4_lac_if([[]b4_parser_class[ parser, ]])[YYStack stack, SymbolKind kind]b4_locations_if([[, Location loc]])[)
+ {]b4_lac_if([[
+ yyparser = parser;]])[
+ yystack = stack;
+ yytoken = kind;]b4_locations_if([[
+ yylocation = loc;]])[
+ }
+
+ final SymbolKind getToken() const
{
- // FIXME: This method of building the message is not compatible
- // with internationalization.
- string res = "syntax error, unexpected ";
- res ~= yytnamerr_ (yytname_[tok]);
- int yyn = yypact_[yystate];
- if (!yy_pact_value_is_default_ (yyn))
+ return yytoken;
+ }]b4_locations_if([[
+
+ final const(Location) getLocation() const
+ {
+ return yylocation;
+ }]])[
+ /**
+ * Put in YYARG at most YYARGN of the expected tokens given the
+ * current YYCTX, and return the number of tokens stored in YYARG. If
+ * YYARG is null, return the number of expected tokens (guaranteed to
+ * be less than YYNTOKENS).
+ */
+ int getExpectedTokens(SymbolKind[] yyarg, int yyargn)]b4_lac_if([[]], [[ const]])[
+ {
+ return getExpectedTokens(yyarg, 0, yyargn);
+ }
+
+ int getExpectedTokens(SymbolKind[] yyarg, int yyoffset, int yyargn)]b4_lac_if([[]], [[ const]])[
+ {
+ int yycount = yyoffset;]b4_lac_if([b4_parse_trace_if([[
+ // Execute LAC once. We don't care if it is successful, we
+ // only do it for the sake of debugging output.
+
+ if (!yyparser.yylacEstablished)
+ yyparser.yylacCheck(yystack, yytoken);
+]])[
+ for (int yyx = 0; yyx < yyntokens_; ++yyx)
+ {
+ SymbolKind yysym = SymbolKind(yyx);
+ if (yysym != ]b4_symbol(error, kind)[
+ && yysym != ]b4_symbol(undef, kind)[
+ && yyparser.yylacCheck(yystack, yysym))
+ {
+ if (yyarg == null)
+ yycount += 1;
+ else if (yycount == yyargn)
+ return 0;
+ else
+ yyarg[yycount++] = yysym;
+ }
+ }]], [[
+ int yyn = yypact_[this.yystack.stateAt(0)];
+ if (!yyPactValueIsDefault(yyn))
{
/* Start YYX at -YYN if negative to avoid negative
indexes in YYCHECK. In other words, skip the first
@@ -744,33 +1011,181 @@ m4_popdef([b4_at_dollar])])dnl
/* Stay within bounds of both yycheck and yytname. */
int yychecklim = yylast_ - yyn + 1;
int yyxend = yychecklim < yyntokens_ ? yychecklim : yyntokens_;
- int count = 0;
- for (int x = yyxbegin; x < yyxend; ++x)
- if (yycheck_[x + yyn] == x && x != ]b4_symbol(1, kind)[
- && !yy_table_value_is_error_ (yytable_[x + yyn]))
- ++count;
- if (count < 5)
+ for (int yyx = yyxbegin; yyx < yyxend; ++yyx)
+ if (yycheck_[yyx + yyn] == yyx && yyx != ]b4_symbol(error, kind)[
+ && !yyTableValueIsError(yytable_[yyx + yyn]))
{
- count = 0;
- for (int x = yyxbegin; x < yyxend; ++x)
- if (yycheck_[x + yyn] == x && x != ]b4_symbol(1, kind)[
- && !yy_table_value_is_error_ (yytable_[x + yyn]))
- {
- res ~= count++ == 0 ? ", expecting " : " or ";
- res ~= yytnamerr_ (yytname_[x]);
- }
+ if (yyarg is null)
+ ++yycount;
+ else if (yycount == yyargn)
+ return 0;
+ else
+ yyarg[yycount++] = SymbolKind(yyx);
}
+ }]])[
+ if (yyarg !is null && yycount == yyoffset && yyoffset < yyargn)
+ yyarg[yyoffset] = ]b4_symbol(empty, kind)[;
+ return yycount - yyoffset;
+ }
+ }
+
+]b4_lac_if([[
+ /** Check the lookahead yytoken.
+ * \returns true iff the token will be eventually shifted.
+ */
+ bool yylacCheck(const YYStack yystack, SymbolKind yytoken)
+ {
+ // Logically, the yylacStack's lifetime is confined to this function.
+ // Clear it, to get rid of potential left-overs from previous call.
+ destroy(yylacStack);
+ // Reduce until we encounter a shift and thereby accept the token.
+]b4_parse_trace_if([[
+ yycdebug("LAC: checking lookahead " ~ format("%s", yytoken) ~ ":");]])[
+ int lacTop = 0;
+ while (true)
+ {
+ int topState = (yylacStack.length == 0
+ ? yystack.stateAt(lacTop)
+ : yylacStack[$ - 1]);
+ int yyrule = yypact_[topState];
+ if (yyPactValueIsDefault(yyrule)
+ || (yyrule += yytoken) < 0 || yylast_ < yyrule
+ || yycheck_[yyrule] != yytoken)
+ {
+ // Use the default action.
+ yyrule = yydefact_[+topState];
+ if (yyrule == 0)
+ {]b4_parse_trace_if([[
+ yycdebugln(" Err");]])[
+ return false;
+ }
}
- return res;
- }]])[
- return "syntax error";
+ else
+ {
+ // Use the action from yytable.
+ yyrule = yytable_[yyrule];
+ if (yyTableValueIsError(yyrule))
+ {]b4_parse_trace_if([[
+ yycdebugln(" Err");]])[
+ return false;
+ }
+ if (0 < yyrule)
+ {]b4_parse_trace_if([[
+ yycdebugln(" S" ~ to!string(yyrule));]])[
+ return true;
+ }
+ yyrule = -yyrule;
+ }
+ // By now we know we have to simulate a reduce.
+]b4_parse_trace_if([[
+ yycdebug(" R" ~ to!string(yyrule - 1));]])[
+ // Pop the corresponding number of values from the stack.
+ {
+ int yylen = yyr2_[yyrule];
+ // First pop from the LAC stack as many tokens as possible.
+ int lacSize = cast (int) yylacStack.length;
+ if (yylen < lacSize)
+ {
+ yylacStack.length -= yylen;
+ yylen = 0;
+ }
+ else if (lacSize != 0)
+ {
+ destroy(yylacStack);
+ yylen -= lacSize;
+ }
+ // Only afterwards look at the main stack.
+ // We simulate popping elements by incrementing lacTop.
+ lacTop += yylen;
+ }
+ // Keep topState in sync with the updated stack.
+ topState = (yylacStack.length == 0
+ ? yystack.stateAt(lacTop)
+ : yylacStack[$ - 1]);
+ // Push the resulting state of the reduction.
+ int state = yyLRGotoState(topState, yyr1_[yyrule]);]b4_parse_trace_if([[
+ yycdebug(" G" ~ to!string(state));]])[
+ yylacStack.length++;
+ yylacStack[$ - 1] = state;
+ }
}
+ /** Establish the initial context if no initial context currently exists.
+ * \returns true iff the token will be eventually shifted.
+ */
+ bool yylacEstablish(YYStack yystack, SymbolKind yytoken)
+ {
+ /* Establish the initial context for the current lookahead if no initial
+ context is currently established.
+
+ We define a context as a snapshot of the parser stacks. We define
+ the initial context for a lookahead as the context in which the
+ parser initially examines that lookahead in order to select a
+ syntactic action. Thus, if the lookahead eventually proves
+ syntactically unacceptable (possibly in a later context reached via a
+ series of reductions), the initial context can be used to determine
+ the exact set of tokens that would be syntactically acceptable in the
+ lookahead's place. Moreover, it is the context after which any
+ further semantic actions would be erroneous because they would be
+ determined by a syntactically unacceptable token.
+
+ yylacEstablish should be invoked when a reduction is about to be
+ performed in an inconsistent state (which, for the purposes of LAC,
+ includes consistent states that don't know they're consistent because
+ their default reductions have been disabled).
+
+ For parse.lac=full, the implementation of yylacEstablish is as
+ follows. If no initial context is currently established for the
+ current lookahead, then check if that lookahead can eventually be
+ shifted if syntactic actions continue from the current context. */
+ if (yylacEstablished)
+ return true;
+ else
+ {]b4_parse_trace_if([[
+ yycdebugln("LAC: initial context established for " ~ format("%s", yytoken));]])[
+ yylacEstablished = true;
+ return yylacCheck(yystack, yytoken);
+ }
+ }
+
+ /** Discard any previous initial lookahead context because of event.
+ * \param event the event which caused the lookahead to be discarded.
+ * Only used for debbuging output. */
+ void yylacDiscard(string event)
+ {
+ /* Discard any previous initial lookahead context because of Event,
+ which may be a lookahead change or an invalidation of the currently
+ established initial context for the current lookahead.
+
+ The most common example of a lookahead change is a shift. An example
+ of both cases is syntax error recovery. That is, a syntax error
+ occurs when the lookahead is syntactically erroneous for the
+ currently established initial context, so error recovery manipulates
+ the parser stacks to try to find a new initial context in which the
+ current lookahead is syntactically acceptable. If it fails to find
+ such a context, it discards the lookahead. */
+ if (yylacEstablished)
+ {]b4_parse_trace_if([[
+ yycdebugln("LAC: initial context discarded due to " ~ event);]])[
+ yylacEstablished = false;
+ }
+ }
+
+ /** The stack for LAC.
+ * Logically, the yylacStack's lifetime is confined to the function
+ * yylacCheck. We just store it as a member of this class to hold
+ * on to the memory and to avoid frequent reallocations.
+ */
+ int[] yylacStack;
+ /** Whether an initial LAC context was established. */
+ bool yylacEstablished;
+]])[
+
/**
* Whether the given yypact_
value indicates a defaulted state.
* @@param yyvalue the value to check
*/
- private static bool yy_pact_value_is_default_ (int yyvalue)
+ private static bool yyPactValueIsDefault(int yyvalue)
{
return yyvalue == yypact_ninf_;
}
@@ -779,7 +1194,7 @@ m4_popdef([b4_at_dollar])])dnl
* Whether the given yytable_
value indicates a syntax error.
* @@param yyvalue the value to check
*/
- private static bool yy_table_value_is_error_ (int yyvalue)
+ private static bool yyTableValueIsError(int yyvalue)
{
return yyvalue == yytable_ninf_;
}
@@ -795,13 +1210,6 @@ m4_popdef([b4_at_dollar])])dnl
]b4_parser_tables_define[
- /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
- First, the terminals, then, starting at \a yyntokens_, nonterminals. */
- private static immutable string[] yytname_ =
- @{
- ]b4_tname[
- @};
-
]b4_parse_trace_if([[
/* YYRLINE[YYN] -- Source line where rule number YYN was defined. */
private static immutable ]b4_int_type_for([b4_rline])[[] yyrline_ =
@@ -822,7 +1230,6 @@ m4_popdef([b4_at_dollar])])dnl
yyrule - 1, yylno));
/* The symbols being reduced. */
- import std.conv : to;
for (int yyi = 0; yyi < yynrhs; yyi++)
yy_symbol_print (format(" $%d =", yyi + 1),
to!SymbolKind (yystos_[yystack.stateAt(yynrhs - (yyi + 1))]),
@@ -831,11 +1238,10 @@ m4_popdef([b4_at_dollar])])dnl
}
]])[
- private static SymbolKind yytranslate_ (int t)
+ private static auto yytranslate_ (int t)
{
]b4_api_token_raw_if(
-[[ import std.conv : to;
- return to!SymbolKind (t);]],
+[[ return SymbolKind(t);]],
[[ /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
immutable ]b4_int_type_for([b4_translate])[[] translate_table =
@{
@@ -846,14 +1252,11 @@ m4_popdef([b4_at_dollar])])dnl
immutable int code_max = ]b4_code_max[;
if (t <= 0)
- return ]b4_symbol(0, kind)[;
+ return ]b4_symbol(eof, kind)[;
else if (t <= code_max)
- {
- import std.conv : to;
- return to!SymbolKind (translate_table[t]);
- }
+ return SymbolKind(translate_table[t]);
else
- return ]b4_symbol(2, kind)[;]])[
+ return ]b4_symbol(undef, kind)[;]])[
}
private static immutable int yylast_ = ]b4_last[;
@@ -863,20 +1266,20 @@ m4_popdef([b4_at_dollar])])dnl
private final struct YYStackElement {
int state;
- ]b4_yystype[ value;]b4_locations_if(
+ Value value;]b4_locations_if(
b4_location_type[[] location;])[
}
private final struct YYStack {
private YYStackElement[] stack = [];
- public final @@property ulong height()
+ public final ulong height()
{
return stack.length;
}
- public final void push (int state, ]b4_yystype[ value]dnl
- b4_locations_if([, ref ]b4_location_type[ loc])[)
+ public final void push (int state, Value value]dnl
+ b4_locations_if([, ref Location loc])[)
{
stack ~= YYStackElement(state, value]b4_locations_if([, loc])[);
}
@@ -891,18 +1294,18 @@ m4_popdef([b4_at_dollar])])dnl
stack.length -= num;
}
- public final int stateAt (int i)
+ public final int stateAt (int i) const
{
return stack[$-i-1].state;
}
]b4_locations_if([[
- public final ref ]b4_location_type[ locationAt (int i)
+ public final ref Location locationAt (int i)
{
return stack[$-i-1].location;
}]])[
- public final ref ]b4_yystype[ valueAt (int i)
+ public final ref Value valueAt (int i)
{
return stack[$-i-1].value;
}
diff --git a/bison/data/skeletons/lalr1.java b/bison/data/skeletons/lalr1.java
index b85c16a..1bbecca 100644
--- a/bison/data/skeletons/lalr1.java
+++ b/bison/data/skeletons/lalr1.java
@@ -1,6 +1,6 @@
-# Java skeleton for Bison -*- autoconf -*-
+# Java skeleton for Bison -*- java -*-
-# Copyright (C) 2007-2015, 2018-2020 Free Software Foundation, Inc.
+# Copyright (C) 2007-2015, 2018-2021 Free Software Foundation, Inc.
# 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
@@ -13,11 +13,11 @@
# 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 .
+# along with this program. If not, see .
m4_include(b4_skeletonsdir/[java.m4])
-b4_defines_if([b4_complain([%defines does not make sense in Java])])
+b4_header_if([b4_complain([%header/%defines does not make sense in Java])])
m4_define([b4_symbol_no_destructor_assert],
[b4_symbol_if([$1], [has_destructor],
@@ -25,7 +25,10 @@
[%destructor does not make sense in Java])])])
b4_symbol_foreach([b4_symbol_no_destructor_assert])
-# Setup some macros for api.push-pull.
+## --------------- ##
+## api.push-pull. ##
+## --------------- ##
+
b4_percent_define_default([[api.push-pull]], [[pull]])
b4_percent_define_check_values([[[[api.push-pull]],
[[pull]], [[push]], [[both]]]])
@@ -52,7 +55,8 @@
# Define a macro to encapsulate the parse state variables. This
# allows them to be defined either in parse() when doing pull parsing,
# or as class instance variable when doing push parsing.
-m4_define([b4_define_state],[[
+m4_define([b4_define_state],
+[[
/* Lookahead token kind. */
int yychar = YYEMPTY_;
/* Lookahead symbol kind. */
@@ -74,17 +78,31 @@
/* Semantic value of the lookahead. */
]b4_yystype[ yylval = null;
-]])[
+]])
+
+# parse.lac
+b4_percent_define_default([[parse.lac]], [[none]])
+b4_percent_define_check_values([[[[parse.lac]], [[full]], [[none]]]])
+b4_define_flag_if([lac])
+m4_define([b4_lac_flag],
+ [m4_if(b4_percent_define_get([[parse.lac]]),
+ [none], [[0]], [[1]])])
+
-]b4_output_begin([b4_parser_file_name])[
+## ------------- ##
+## Parser File. ##
+## ------------- ##
+
+b4_output_begin([b4_parser_file_name])[
]b4_copyright([Skeleton implementation for Bison LALR(1) parsers in Java],
- [2007-2015, 2018-2020])[
+ [2007-2015, 2018-2021])[
]b4_disclaimer[
]b4_percent_define_ifdef([api.package], [package b4_percent_define_get([api.package]);[
]])[
]b4_user_pre_prologue[
]b4_user_post_prologue[
import java.text.MessageFormat;
+import java.util.ArrayList;
]b4_percent_code_get([[imports]])[
/**
* A Bison parser, automatically generated from ]m4_bpatsubst(b4_file_name, [^"\(.*\)"$], [\1])[.
@@ -157,11 +175,11 @@ public static class ]b4_location_type[ {
* ]b4_position_type[
should override the equals
* method.
*/
- public String toString () {
+ public String toString() {
if (begin.equals (end))
- return begin.toString ();
+ return begin.toString();
else
- return begin.toString () + "-" + end.toString ();
+ return begin.toString() + "-" + end.toString();
}
}
@@ -181,8 +199,8 @@ public String toString () {
*/
public interface Lexer {
]b4_token_enums[
- /** Deprecated, use ]b4_symbol(0, id)[ instead. */
- public static final int EOF = ]b4_symbol(0, id)[;
+ /** Deprecated, use ]b4_symbol(eof, id)[ instead. */
+ public static final int EOF = ]b4_symbol(eof, id)[;
]b4_pull_if([b4_locations_if([[
/**
* Method to retrieve the beginning position of the last scanned token.
@@ -226,7 +244,7 @@ public interface Lexer {
*
* @@param ctx The context of the error.
*/
- void reportSyntaxError (][Context ctx);
+ void reportSyntaxError(Context ctx);
]])[
}
@@ -247,10 +265,12 @@ private class YYLexer implements Lexer {
/**
* Instantiates the Bison-generated parser.
*/
- public ]b4_parser_class (b4_parse_param_decl([b4_lex_param_decl])[)]b4_maybe_throws([b4_init_throws])[
+ public ]b4_parser_class[(]b4_parse_param_decl([b4_lex_param_decl])[)]b4_maybe_throws([b4_init_throws])[
{
-]b4_percent_code_get([[init]])[
- this.yylexer = new YYLexer (]b4_lex_param_call[);
+]b4_percent_code_get([[init]])[]b4_lac_if([[
+ this.yylacStack = new ArrayList();
+ this.yylacEstablished = false;]])[
+ this.yylexer = new YYLexer(]b4_lex_param_call[);
]b4_parse_param_cons[
}
]])[
@@ -259,9 +279,11 @@ private class YYLexer implements Lexer {
* Instantiates the Bison-generated parser.
* @@param yylexer The scanner that will supply tokens to the parser.
*/
- ]b4_lexer_if([[protected]], [[public]]) b4_parser_class[ (]b4_parse_param_decl([[Lexer yylexer]])[)]b4_maybe_throws([b4_init_throws])[
+ ]b4_lexer_if([[protected]], [[public]]) b4_parser_class[(]b4_parse_param_decl([[Lexer yylexer]])[)]b4_maybe_throws([b4_init_throws])[
{
-]b4_percent_code_get([[init]])[
+]b4_percent_code_get([[init]])[]b4_lac_if([[
+ this.yylacStack = new ArrayList();
+ this.yylacEstablished = false;]])[
this.yylexer = yylexer;
]b4_parse_param_cons[
}
@@ -272,13 +294,13 @@ private class YYLexer implements Lexer {
/**
* The PrintStream on which the debugging output is printed.
*/
- public final java.io.PrintStream getDebugStream () { return yyDebugStream; }
+ public final java.io.PrintStream getDebugStream() { return yyDebugStream; }
/**
* Set the PrintStream on which the debug output is printed.
* @@param s The stream that is used for debugging output.
*/
- public final void setDebugStream (java.io.PrintStream s) { yyDebugStream = s; }
+ public final void setDebugStream(java.io.PrintStream s) { yyDebugStream = s; }
private int yydebug = 0;
@@ -286,14 +308,14 @@ private class YYLexer implements Lexer {
* Answer the verbosity of the debugging output; 0 means that all kinds of
* output from the parser are suppressed.
*/
- public final int getDebugLevel () { return yydebug; }
+ public final int getDebugLevel() { return yydebug; }
/**
* Set the verbosity of the debugging output; 0 means that all kinds of
* output from the parser are suppressed.
* @@param level The verbosity level for debugging output.
*/
- public final void setDebugLevel (int level) { yydebug = level; }
+ public final void setDebugLevel(int level) { yydebug = level; }
]])[
private int yynerrs = 0;
@@ -301,7 +323,7 @@ private class YYLexer implements Lexer {
/**
* The number of syntax errors so far.
*/
- public final int getNumberOfErrors () { return yynerrs; }
+ public final int getNumberOfErrors() { return yynerrs; }
/**
* Print an error message via the lexer.
@@ -330,9 +352,14 @@ public final void yyerror(]b4_position_type[ pos, String msg) {
yylexer.yyerror(new ]b4_location_type[ (pos), msg);
}]])[
]b4_parse_trace_if([[
- protected final void yycdebug (String s) {
+ protected final void yycdebugNnl(String s) {
+ if (0 < yydebug)
+ yyDebugStream.print(s);
+ }
+
+ protected final void yycdebug(String s) {
if (0 < yydebug)
- yyDebugStream.println (s);
+ yyDebugStream.println(s);
}]])[
private final class YYStack {
@@ -343,65 +370,63 @@ private final class YYStack {
public int size = 16;
public int height = -1;
- public final void push (int state, ]b4_yystype[ value]b4_locations_if([, ]b4_location_type[ loc])[) {
+ public final void push(int state, ]b4_yystype[ value]b4_locations_if([, ]b4_location_type[ loc])[) {
height++;
- if (size == height)
- {
- int[] newStateStack = new int[size * 2];
- System.arraycopy (stateStack, 0, newStateStack, 0, height);
- stateStack = newStateStack;]b4_locations_if([[
- ]b4_location_type[[] newLocStack = new ]b4_location_type[[size * 2];
- System.arraycopy (locStack, 0, newLocStack, 0, height);
- locStack = newLocStack;]])
-
- b4_yystype[[] newValueStack = new ]b4_yystype[[size * 2];
- System.arraycopy (valueStack, 0, newValueStack, 0, height);
- valueStack = newValueStack;
-
- size *= 2;
- }
+ if (size == height) {
+ int[] newStateStack = new int[size * 2];
+ System.arraycopy(stateStack, 0, newStateStack, 0, height);
+ stateStack = newStateStack;]b4_locations_if([[
+ ]b4_location_type[[] newLocStack = new ]b4_location_type[[size * 2];
+ System.arraycopy(locStack, 0, newLocStack, 0, height);
+ locStack = newLocStack;]])
+
+ b4_yystype[[] newValueStack = new ]b4_yystype[[size * 2];
+ System.arraycopy(valueStack, 0, newValueStack, 0, height);
+ valueStack = newValueStack;
+
+ size *= 2;
+ }
stateStack[height] = state;]b4_locations_if([[
locStack[height] = loc;]])[
valueStack[height] = value;
}
- public final void pop () {
- pop (1);
+ public final void pop() {
+ pop(1);
}
- public final void pop (int num) {
+ public final void pop(int num) {
// Avoid memory leaks... garbage collection is a white lie!
if (0 < num) {
- java.util.Arrays.fill (valueStack, height - num + 1, height + 1, null);]b4_locations_if([[
- java.util.Arrays.fill (locStack, height - num + 1, height + 1, null);]])[
+ java.util.Arrays.fill(valueStack, height - num + 1, height + 1, null);]b4_locations_if([[
+ java.util.Arrays.fill(locStack, height - num + 1, height + 1, null);]])[
}
height -= num;
}
- public final int stateAt (int i) {
+ public final int stateAt(int i) {
return stateStack[height - i];
}
]b4_locations_if([[
- public final ]b4_location_type[ locationAt (int i) {
+ public final ]b4_location_type[ locationAt(int i) {
return locStack[height - i];
}
]])[
- public final ]b4_yystype[ valueAt (int i) {
+ public final ]b4_yystype[ valueAt(int i) {
return valueStack[height - i];
}
// Print the state stack on the debug stream.
- public void print (java.io.PrintStream out) {
+ public void print(java.io.PrintStream out) {
out.print ("Stack now");
- for (int i = 0; i <= height; i++)
- {
- out.print (' ');
- out.print (stateStack[i]);
- }
- out.println ();
+ for (int i = 0; i <= height; i++) {
+ out.print(' ');
+ out.print(stateStack[i]);
+ }
+ out.println();
}
}
@@ -458,8 +483,7 @@ public final boolean recovering ()
* @@param yystate the current state
* @@param yysym the nonterminal to push on the stack
*/
- private int yyLRGotoState (int yystate, int yysym)
- {
+ private int yyLRGotoState(int yystate, int yysym) {
int yyr = yypgoto_[yysym - YYNTOKENS_] + yystate;
if (0 <= yyr && yyr <= YYLAST_ && yycheck_[yyr] == yystate)
return yytable_[yyr];
@@ -536,7 +560,12 @@ public int push_parse(int yylextoken, b4_yystype yylexval[]b4_locations_if([, b4
/* @@$. */
]b4_location_type[ yyloc;]])[
]b4_push_if([],[[
-]b4_define_state[]b4_parse_trace_if([[
+]b4_define_state[
+]b4_lac_if([[
+ // Discard the LAC context in case there still is one left from a
+ // previous invocation.
+ yylacDiscard("init");]])[
+]b4_parse_trace_if([[
yycdebug ("Starting parse");]])[
yyerrstatus_ = 0;
yynerrs = 0;
@@ -614,14 +643,14 @@ public int push_parse(int yylextoken, b4_yystype yylexval[]b4_locations_if([, b4
yySymbolPrint("Next token is", yytoken,
yylval]b4_locations_if([, yylloc])[);]])[
- if (yytoken == ]b4_symbol(1, kind)[)
+ if (yytoken == ]b4_symbol(error, kind)[)
{
// The scanner already issued an error message, process directly
// to error recovery. But do not keep the error token as
// lookahead, it is too special and may lead us to an endless
// loop in error recovery. */
- yychar = Lexer.]b4_symbol(2, id)[;
- yytoken = ]b4_symbol(2, kind)[;]b4_locations_if([[
+ yychar = Lexer.]b4_symbol(undef, id)[;
+ yytoken = ]b4_symbol(undef, kind)[;]b4_locations_if([[
yyerrloc = yylloc;]])[
label = YYERRLAB1;
}
@@ -630,19 +659,24 @@ public int push_parse(int yylextoken, b4_yystype yylexval[]b4_locations_if([, b4
/* If the proper action on seeing token YYTOKEN is to reduce or to
detect an error, take that action. */
yyn += yytoken.getCode();
- if (yyn < 0 || YYLAST_ < yyn || yycheck_[yyn] != yytoken.getCode())
+ if (yyn < 0 || YYLAST_ < yyn || yycheck_[yyn] != yytoken.getCode()) {]b4_lac_if([[
+ if (!yylacEstablish(yystack, yytoken)) {
+ label = YYERRLAB;
+ } else]])[
label = YYDEFAULT;
+ }
/* <= 0 means reduce or error. */
else if ((yyn = yytable_[yyn]) <= 0)
{
- if (yyTableValueIsError (yyn))
+ if (yyTableValueIsError(yyn)) {
label = YYERRLAB;
- else
- {
- yyn = -yyn;
- label = YYREDUCE;
- }
+ }]b4_lac_if([[ else if (!yylacEstablish(yystack, yytoken)) {
+ label = YYERRLAB;
+ }]])[ else {
+ yyn = -yyn;
+ label = YYREDUCE;
+ }
}
else
@@ -660,7 +694,8 @@ else if ((yyn = yytable_[yyn]) <= 0)
--yyerrstatus_;
yystate = yyn;
- yystack.push (yystate, yylval]b4_locations_if([, yylloc])[);
+ yystack.push(yystate, yylval]b4_locations_if([, yylloc])[);]b4_lac_if([[
+ yylacDiscard("shift");]])[
label = YYNEWSTATE;
}
}
@@ -683,7 +718,7 @@ else if ((yyn = yytable_[yyn]) <= 0)
case YYREDUCE:
yylen = yyr2_[yyn];
label = yyaction(yyn, yystack, yylen);
- yystate = yystack.stateAt (0);
+ yystate = yystack.stateAt(0);
break;
/*------------------------------------.
@@ -696,7 +731,7 @@ else if ((yyn = yytable_[yyn]) <= 0)
++yynerrs;
if (yychar == YYEMPTY_)
yytoken = null;
- yyreportSyntaxError (new Context (yystack, yytoken]b4_locations_if([[, yylloc]])[));
+ yyreportSyntaxError(new Context(this, yystack, yytoken]b4_locations_if([[, yylloc]])[));
}
]b4_locations_if([[
yyerrloc = yylloc;]])[
@@ -705,10 +740,10 @@ else if ((yyn = yytable_[yyn]) <= 0)
/* If just tried and failed to reuse lookahead token after an
error, discard it. */
- if (yychar <= Lexer.]b4_symbol(0, id)[)
+ if (yychar <= Lexer.]b4_symbol(eof, id)[)
{
/* Return failure if at end of input. */
- if (yychar == Lexer.]b4_symbol(0, id)[)
+ if (yychar == Lexer.]b4_symbol(eof, id)[)
]b4_push_if([{label = YYABORT; break;}], [return false;])[
}
else
@@ -729,7 +764,7 @@ else if ((yyn = yytable_[yyn]) <= 0)
this YYERROR. */
yystack.pop (yylen);
yylen = 0;
- yystate = yystack.stateAt (0);
+ yystate = yystack.stateAt(0);
label = YYERRLAB1;
break;
@@ -745,9 +780,9 @@ else if ((yyn = yytable_[yyn]) <= 0)
yyn = yypact_[yystate];
if (!yyPactValueIsDefault (yyn))
{
- yyn += ]b4_symbol(1, kind)[.getCode();
+ yyn += ]b4_symbol(error, kind)[.getCode();
if (0 <= yyn && yyn <= YYLAST_
- && yycheck_[yyn] == ]b4_symbol(1, kind)[.getCode())
+ && yycheck_[yyn] == ]b4_symbol(error, kind)[.getCode())
{
yyn = yytable_[yyn];
if (0 < yyn)
@@ -763,7 +798,7 @@ else if ((yyn = yytable_[yyn]) <= 0)
]b4_locations_if([[
yyerrloc = yystack.locationAt (0);]])[
yystack.pop ();
- yystate = yystack.stateAt (0);]b4_parse_trace_if([[
+ yystate = yystack.stateAt(0);]b4_parse_trace_if([[
if (0 < yydebug)
yystack.print (yyDebugStream);]])[
}
@@ -779,7 +814,8 @@ else if ((yyn = yytable_[yyn]) <= 0)
yyloc = yylloc (yystack, 2);
yystack.pop (2);]])[
- /* Shift the error token. */]b4_parse_trace_if([[
+ /* Shift the error token. */]b4_lac_if([[
+ yylacDiscard("error recovery");]])[]b4_parse_trace_if([[
yySymbolPrint("Shifting", SymbolKind.get(yystos_[yyn]),
yylval]b4_locations_if([, yyloc])[);]])[
@@ -815,7 +851,9 @@ public void push_parse_initialize ()
this.yyn = 0;
this.yylen = 0;
this.yystate = 0;
- this.yystack = new YYStack ();
+ this.yystack = new YYStack();]b4_lac_if([[
+ this.yylacStack = new ArrayList();
+ this.yylacEstablished = false;]])[
this.label = YYNEWSTATE;
/* Error handling. */
@@ -875,23 +913,22 @@ public boolean parse()]b4_maybe_throws([b4_list2([b4_lex_throws], [b4_throws])])
* Information needed to get the list of expected tokens and to forge
* a syntax error diagnostic.
*/
- public static final class Context
- {
- Context (YYStack stack, SymbolKind token]b4_locations_if([[, ]b4_location_type[ loc]])[)
- {
+ public static final class Context {
+ Context(]b4_parser_class[ parser, YYStack stack, SymbolKind token]b4_locations_if([[, ]b4_location_type[ loc]])[) {
+ yyparser = parser;
yystack = stack;
yytoken = token;]b4_locations_if([[
yylocation = loc;]])[
}
+ private ]b4_parser_class[ yyparser;
private YYStack yystack;
/**
* The symbol kind of the lookahead token.
*/
- public final SymbolKind getToken ()
- {
+ public final SymbolKind getToken() {
return yytoken;
}
@@ -900,8 +937,7 @@ public final SymbolKind getToken ()
/**
* The location of the lookahead.
*/
- public final ]b4_location_type[ getLocation ()
- {
+ public final ]b4_location_type[ getLocation() {
return yylocation;
}
@@ -914,16 +950,34 @@ public final SymbolKind getToken ()
* YYARG is null, return the number of expected tokens (guaranteed to
* be less than YYNTOKENS).
*/
- int getExpectedTokens (SymbolKind yyarg[], int yyargn)
- {
+ int getExpectedTokens(SymbolKind yyarg[], int yyargn) {
return getExpectedTokens (yyarg, 0, yyargn);
}
- int getExpectedTokens (SymbolKind yyarg[], int yyoffset, int yyargn)
- {
- int yycount = yyoffset;
- int yyn = yypact_[this.yystack.stateAt (0)];
- if (!yyPactValueIsDefault (yyn))
+ int getExpectedTokens(SymbolKind yyarg[], int yyoffset, int yyargn) {
+ int yycount = yyoffset;]b4_lac_if([b4_parse_trace_if([[
+ // Execute LAC once. We don't care if it is successful, we
+ // only do it for the sake of debugging output.
+ if (!yyparser.yylacEstablished)
+ yyparser.yylacCheck(yystack, yytoken);
+]])[
+ for (int yyx = 0; yyx < YYNTOKENS_; ++yyx)
+ {
+ SymbolKind yysym = SymbolKind.get(yyx);
+ if (yysym != ]b4_symbol(error, kind)[
+ && yysym != ]b4_symbol(undef, kind)[
+ && yyparser.yylacCheck(yystack, yysym))
+ {
+ if (yyarg == null)
+ yycount += 1;
+ else if (yycount == yyargn)
+ return 0;
+ else
+ yyarg[yycount++] = yysym;
+ }
+ }]], [[
+ int yyn = yypact_[this.yystack.stateAt(0)];
+ if (!yyPactValueIsDefault(yyn))
{
/* Start YYX at -YYN if negative to avoid negative
indexes in YYCHECK. In other words, skip the first
@@ -934,7 +988,7 @@ int getExpectedTokens (SymbolKind yyarg[], int yyoffset, int yyargn)
int yychecklim = YYLAST_ - yyn + 1;
int yyxend = yychecklim < NTOKENS ? yychecklim : NTOKENS;
for (int yyx = yyxbegin; yyx < yyxend; ++yyx)
- if (yycheck_[yyx + yyn] == yyx && yyx != ]b4_symbol(1, kind)[.getCode()
+ if (yycheck_[yyx + yyn] == yyx && yyx != ]b4_symbol(error, kind)[.getCode()
&& !yyTableValueIsError(yytable_[yyx + yyn]))
{
if (yyarg == null)
@@ -944,17 +998,158 @@ else if (yycount == yyargn)
else
yyarg[yycount++] = SymbolKind.get(yyx);
}
- }
+ }]])[
if (yyarg != null && yycount == yyoffset && yyoffset < yyargn)
yyarg[yycount] = null;
return yycount - yyoffset;
}
}
+]b4_lac_if([[
+ /** Check the lookahead yytoken.
+ * \returns true iff the token will be eventually shifted.
+ */
+ boolean yylacCheck(YYStack yystack, SymbolKind yytoken)
+ {
+ // Logically, the yylacStack's lifetime is confined to this function.
+ // Clear it, to get rid of potential left-overs from previous call.
+ yylacStack.clear();
+ // Reduce until we encounter a shift and thereby accept the token.
+ yycdebugNnl("LAC: checking lookahead " + yytoken.getName() + ":");
+ int lacTop = 0;
+ while (true)
+ {
+ int topState = (yylacStack.isEmpty()
+ ? yystack.stateAt(lacTop)
+ : yylacStack.get(yylacStack.size() - 1));
+ int yyrule = yypact_[topState];
+ if (yyPactValueIsDefault(yyrule)
+ || (yyrule += yytoken.getCode()) < 0 || YYLAST_ < yyrule
+ || yycheck_[yyrule] != yytoken.getCode())
+ {
+ // Use the default action.
+ yyrule = yydefact_[+topState];
+ if (yyrule == 0) {
+ yycdebug(" Err");
+ return false;
+ }
+ }
+ else
+ {
+ // Use the action from yytable.
+ yyrule = yytable_[yyrule];
+ if (yyTableValueIsError(yyrule)) {
+ yycdebug(" Err");
+ return false;
+ }
+ if (0 < yyrule) {
+ yycdebug(" S" + yyrule);
+ return true;
+ }
+ yyrule = -yyrule;
+ }
+ // By now we know we have to simulate a reduce.
+ yycdebugNnl(" R" + (yyrule - 1));
+ // Pop the corresponding number of values from the stack.
+ {
+ int yylen = yyr2_[yyrule];
+ // First pop from the LAC stack as many tokens as possible.
+ int lacSize = yylacStack.size();
+ if (yylen < lacSize) {
+ // yylacStack.setSize(lacSize - yylen);
+ for (/* Nothing */; 0 < yylen; yylen -= 1) {
+ yylacStack.remove(yylacStack.size() - 1);
+ }
+ yylen = 0;
+ } else if (lacSize != 0) {
+ yylacStack.clear();
+ yylen -= lacSize;
+ }
+ // Only afterwards look at the main stack.
+ // We simulate popping elements by incrementing lacTop.
+ lacTop += yylen;
+ }
+ // Keep topState in sync with the updated stack.
+ topState = (yylacStack.isEmpty()
+ ? yystack.stateAt(lacTop)
+ : yylacStack.get(yylacStack.size() - 1));
+ // Push the resulting state of the reduction.
+ int state = yyLRGotoState(topState, yyr1_[yyrule]);
+ yycdebugNnl(" G" + state);
+ yylacStack.add(state);
+ }
+ }
+
+ /** Establish the initial context if no initial context currently exists.
+ * \returns true iff the token will be eventually shifted.
+ */
+ boolean yylacEstablish(YYStack yystack, SymbolKind yytoken) {
+ /* Establish the initial context for the current lookahead if no initial
+ context is currently established.
+
+ We define a context as a snapshot of the parser stacks. We define
+ the initial context for a lookahead as the context in which the
+ parser initially examines that lookahead in order to select a
+ syntactic action. Thus, if the lookahead eventually proves
+ syntactically unacceptable (possibly in a later context reached via a
+ series of reductions), the initial context can be used to determine
+ the exact set of tokens that would be syntactically acceptable in the
+ lookahead's place. Moreover, it is the context after which any
+ further semantic actions would be erroneous because they would be
+ determined by a syntactically unacceptable token.
+
+ yylacEstablish should be invoked when a reduction is about to be
+ performed in an inconsistent state (which, for the purposes of LAC,
+ includes consistent states that don't know they're consistent because
+ their default reductions have been disabled).
+
+ For parse.lac=full, the implementation of yylacEstablish is as
+ follows. If no initial context is currently established for the
+ current lookahead, then check if that lookahead can eventually be
+ shifted if syntactic actions continue from the current context. */
+ if (yylacEstablished) {
+ return true;
+ } else {
+ yycdebug("LAC: initial context established for " + yytoken.getName());
+ yylacEstablished = true;
+ return yylacCheck(yystack, yytoken);
+ }
+ }
+
+ /** Discard any previous initial lookahead context because of event.
+ * \param event the event which caused the lookahead to be discarded.
+ * Only used for debbuging output. */
+ void yylacDiscard(String event) {
+ /* Discard any previous initial lookahead context because of Event,
+ which may be a lookahead change or an invalidation of the currently
+ established initial context for the current lookahead.
+
+ The most common example of a lookahead change is a shift. An example
+ of both cases is syntax error recovery. That is, a syntax error
+ occurs when the lookahead is syntactically erroneous for the
+ currently established initial context, so error recovery manipulates
+ the parser stacks to try to find a new initial context in which the
+ current lookahead is syntactically acceptable. If it fails to find
+ such a context, it discards the lookahead. */
+ if (yylacEstablished) {
+ yycdebug("LAC: initial context discarded due to " + event);
+ yylacEstablished = false;
+ }
+ }
+
+ /** The stack for LAC.
+ * Logically, the yylacStack's lifetime is confined to the function
+ * yylacCheck. We just store it as a member of this class to hold
+ * on to the memory and to avoid frequent reallocations.
+ */
+ ArrayList yylacStack;
+ /** Whether an initial LAC context was established. */
+ boolean yylacEstablished;
+]])[
+
]b4_parse_error_bmatch(
[detailed\|verbose], [[
- private int yysyntaxErrorArguments (Context yyctx, SymbolKind[] yyarg, int yyargn)
- {
+ private int yysyntaxErrorArguments(Context yyctx, SymbolKind[] yyarg, int yyargn) {
/* There are many possibilities here to consider:
- If this state is a consistent state with a default action,
then the only way this function was invoked is if the
@@ -1032,8 +1227,7 @@ private void yyreportSyntaxError(Context yyctx) {]b4_parse_error_bmatch(
* Whether the given yypact_
value indicates a defaulted state.
* @@param yyvalue the value to check
*/
- private static boolean yyPactValueIsDefault (int yyvalue)
- {
+ private static boolean yyPactValueIsDefault(int yyvalue) {
return yyvalue == yypact_ninf_;
}
@@ -1042,8 +1236,7 @@ private static boolean yyPactValueIsDefault (int yyvalue)
* value indicates a syntax error.
* @@param yyvalue the value to check
*/
- private static boolean yyTableValueIsError (int yyvalue)
- {
+ private static boolean yyTableValueIsError(int yyvalue) {
return yyvalue == yytable_ninf_;
}
@@ -1072,7 +1265,7 @@ private void yyReducePrint (int yyrule, YYStack yystack)
/* The symbols being reduced. */
for (int yyi = 0; yyi < yynrhs; yyi++)
yySymbolPrint(" $" + (yyi + 1) + " =",
- SymbolKind.get(yystos_[yystack.stateAt (yynrhs - (yyi + 1))]),
+ SymbolKind.get(yystos_[yystack.stateAt(yynrhs - (yyi + 1))]),
]b4_rhs_data(yynrhs, yyi + 1)b4_locations_if([,
b4_rhs_location(yynrhs, yyi + 1)])[);
}]])[
@@ -1089,11 +1282,11 @@ private static final SymbolKind yytranslate_(int t)
// Last valid token kind.
int code_max = ]b4_code_max[;
if (t <= 0)
- return ]b4_symbol(0, kind)[;
+ return ]b4_symbol(eof, kind)[;
else if (t <= code_max)
return SymbolKind.get(yytranslate_table_[t]);
else
- return ]b4_symbol(2, kind)[;
+ return ]b4_symbol(undef, kind)[;
}
]b4_integral_parser_table_define([translate_table], [b4_translate])[
]])[
diff --git a/bison/data/skeletons/location.cc b/bison/data/skeletons/location.cc
index c96381e..3870b2b 100644
--- a/bison/data/skeletons/location.cc
+++ b/bison/data/skeletons/location.cc
@@ -1,6 +1,6 @@
# C++ skeleton for Bison
-# Copyright (C) 2002-2015, 2018-2020 Free Software Foundation, Inc.
+# Copyright (C) 2002-2015, 2018-2021 Free Software Foundation, Inc.
# 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
@@ -13,17 +13,10 @@
# 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 .
+# along with this program. If not, see .
m4_pushdef([b4_copyright_years],
- [2002-2015, 2018-2020])
-
-
-# b4_position_file
-# ----------------
-# Name of the file containing the position class, if we want this file.
-b4_defines_if([b4_required_version_if([30200], [],
- [m4_define([b4_position_file], [position.hh])])])])
+ [2002-2015, 2018-2021])
# b4_location_file
@@ -32,7 +25,7 @@ b4_defines_if([b4_required_version_if([30200], [],
# if we want this file.
b4_percent_define_check_file([b4_location_file],
[[api.location.file]],
- b4_defines_if([[location.hh]]))
+ b4_header_if([[location.hh]]))
# b4_location_include
# -------------------
@@ -54,6 +47,16 @@ m4_ifdef([b4_location_file],
])
+# b4_position_file
+# ----------------
+# Name of the file containing the position class, if we want this file.
+b4_header_if(
+ [b4_required_version_if(
+ [30200], [],
+ [m4_ifdef([b4_location_file],
+ [m4_define([b4_position_file], [position.hh])])])])
+
+
# b4_location_define
# ------------------
diff --git a/bison/data/skeletons/stack.hh b/bison/data/skeletons/stack.hh
index 38bff8b..9891325 100644
--- a/bison/data/skeletons/stack.hh
+++ b/bison/data/skeletons/stack.hh
@@ -1,6 +1,6 @@
# C++ skeleton for Bison
-# Copyright (C) 2002-2015, 2018-2020 Free Software Foundation, Inc.
+# Copyright (C) 2002-2015, 2018-2021 Free Software Foundation, Inc.
# 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
@@ -13,14 +13,14 @@
# 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 .
+# along with this program. If not, see .
# b4_stack_file
# -------------
# Name of the file containing the stack class, if we want this file.
-b4_defines_if([b4_required_version_if([30200], [],
- [m4_define([b4_stack_file], [stack.hh])])])
+b4_header_if([b4_required_version_if([30200], [],
+ [m4_define([b4_stack_file], [stack.hh])])])
# b4_stack_define
@@ -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)
{}
diff --git a/bison/data/skeletons/variant.hh b/bison/data/skeletons/variant.hh
index 2887ba6..2a490e8 100644
--- a/bison/data/skeletons/variant.hh
+++ b/bison/data/skeletons/variant.hh
@@ -1,6 +1,6 @@
# C++ skeleton for Bison
-# Copyright (C) 2002-2015, 2018-2020 Free Software Foundation, Inc.
+# Copyright (C) 2002-2015, 2018-2021 Free Software Foundation, Inc.
# 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
@@ -13,7 +13,7 @@
# 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 .
+# along with this program. If not, see .
## --------- ##
@@ -94,28 +94,28 @@ m4_define([b4_variant_includes],
# b4_value_type_declare
# ---------------------
-# Define semantic_type.
+# Define value_type.
m4_define([b4_value_type_declare],
[[ /// A buffer to store and retrieve objects.
///
/// Sort of a variant, but does not keep track of the nature
/// of the stored data, since that knowledge is available
/// via the current parser state.
- class semantic_type
+ class value_type
{
public:
/// Type of *this.
- typedef semantic_type self_type;
+ typedef value_type self_type;
/// Empty construction.
- semantic_type () YY_NOEXCEPT
- : yybuffer_ ()]b4_parse_assert_if([
+ value_type () YY_NOEXCEPT
+ : yyraw_ ()]b4_parse_assert_if([
, yytypeid_ (YY_NULLPTR)])[
{}
/// Construct and fill.
template
- semantic_type (YY_RVREF (T) t)]b4_parse_assert_if([
+ value_type (YY_RVREF (T) t)]b4_parse_assert_if([
: yytypeid_ (&typeid (T))])[
{]b4_parse_assert_if([[
]b4_assert[ (sizeof (T) <= size);]])[
@@ -124,13 +124,13 @@ m4_define([b4_value_type_declare],
#if 201103L <= YY_CPLUSPLUS
/// Non copyable.
- semantic_type (const self_type&) = delete;
+ value_type (const self_type&) = delete;
/// Non copyable.
self_type& operator= (const self_type&) = delete;
#endif
/// Destruction, allowed only if empty.
- ~semantic_type () YY_NOEXCEPT
+ ~value_type () YY_NOEXCEPT
{]b4_parse_assert_if([
]b4_assert[ (!yytypeid_);
])[}
@@ -274,7 +274,7 @@ m4_define([b4_value_type_declare],
private:
#if YY_CPLUSPLUS < 201103L
/// Non copyable.
- semantic_type (const self_type&);
+ value_type (const self_type&);
/// Non copyable.
self_type& operator= (const self_type&);
#endif
@@ -284,7 +284,7 @@ m4_define([b4_value_type_declare],
T*
yyas_ () YY_NOEXCEPT
{
- void *yyp = yybuffer_.yyraw;
+ void *yyp = yyraw_;
return static_cast (yyp);
}
@@ -293,7 +293,7 @@ m4_define([b4_value_type_declare],
const T*
yyas_ () const YY_NOEXCEPT
{
- const void *yyp = yybuffer_.yyraw;
+ const void *yyp = yyraw_;
return static_cast (yyp);
}
@@ -308,10 +308,10 @@ m4_define([b4_value_type_declare],
union
{
/// Strongest alignment constraints.
- long double yyalign_me;
+ long double yyalign_me_;
/// A buffer large enough to store any of the semantic values.
- char yyraw[size];
- } yybuffer_;]b4_parse_assert_if([
+ char yyraw_[size];
+ };]b4_parse_assert_if([
/// Whether the content is built: if defined, the name of the stored type.
const std::type_info *yytypeid_;])[
@@ -458,11 +458,11 @@ m4_define([b4_tok_in],
-# _b4_token_constructor_define(SYMBOL-NUM...)
-# -------------------------------------------
-# Define a unique make_symbol for all the SYMBOL-NUM (they
+# _b4_symbol_constructor_define(SYMBOL-NUM...)
+# --------------------------------------------
+# Define a symbol_type constructor common to all the SYMBOL-NUM (they
# have the same type). Use at class-level.
-m4_define([_b4_token_constructor_define],
+m4_define([_b4_symbol_constructor_define],
[m4_ifval(_b4_includes_tokens($@),
[[#if 201103L <= YY_CPLUSPLUS
symbol_type (]b4_join(
@@ -470,21 +470,23 @@ m4_define([_b4_token_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)],
- b4_symbol_if([$1], [has_type], [std::move (v)]),
- b4_locations_if([std::move (l)]))[)
+ : super_type (]b4_join([token_kind_type (tok)],
+ b4_symbol_if([$1], [has_type], [std::move (v)]),
+ b4_locations_if([std::move (l)]))[)
#else
symbol_type (]b4_join(
[int tok],
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)],
- b4_symbol_if([$1], [has_type], [v]),
- b4_locations_if([l]))[)
+ : super_type (]b4_join([token_kind_type (tok)],
+ b4_symbol_if([$1], [has_type], [v]),
+ b4_locations_if([l]))[)
#endif
{]b4_parse_assert_if([[
+#if !defined _MSC_VER || defined __clang__
]b4_assert[ (]b4_tok_in($@)[);
+#endif
]])[}
]])])
@@ -517,7 +519,7 @@ m4_define([b4_basic_symbol_constructor_define],
# b4_token_constructor_define
# ---------------------------
-# Define the overloaded versions of make_symbol for all the value types.
+# Define the overloaded versions of make_FOO for all the token kinds.
m4_define([b4_token_constructor_define],
-[ // Implementation of make_symbol for each symbol type.
+[ // Implementation of make_symbol for each token kind.
b4_symbol_foreach([_b4_token_maker_define])])
diff --git a/bison/data/skeletons/yacc.c b/bison/data/skeletons/yacc.c
index c695a03..64b9ac6 100644
--- a/bison/data/skeletons/yacc.c
+++ b/bison/data/skeletons/yacc.c
@@ -1,11 +1,11 @@
# -*- C -*-
# Yacc compatible skeleton for Bison
-# Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2020 Free Software
+# Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software
# Foundation, Inc.
m4_pushdef([b4_copyright_years],
- [1984, 1989-1990, 2000-2015, 2018-2020])
+ [1984, 1989-1990, 2000-2015, 2018-2021])
# 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
@@ -18,10 +18,11 @@ m4_pushdef([b4_copyright_years],
# 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 .
+# along with this program. If not, see .
m4_include(b4_skeletonsdir/[c.m4])
+
## ---------- ##
## api.pure. ##
## ---------- ##
@@ -101,6 +102,16 @@ m4_define([b4_yyerror_arg_loc_if],
[1], [m4_ifset([b4_parse_param], [$1])],
[2], [$1])])])
+# b4_yyerror_formals
+# ------------------
+m4_define([b4_yyerror_formals],
+[b4_pure_if([b4_locations_if([, [[const ]b4_api_PREFIX[LTYPE *yyllocp], [&yylloc]]])[]dnl
+m4_ifdef([b4_parse_param], [, b4_parse_param])[]dnl
+,])dnl
+[[const char *msg], [msg]]])
+
+
+
# b4_yyerror_args
# ---------------
# Arguments passed to yyerror: user args plus yylloc.
@@ -115,6 +126,16 @@ m4_ifset([b4_parse_param], [b4_args(b4_parse_param), ])])
## ----------------- ##
+# b4_accept([SYMBOL-NUM])
+# -----------------------
+# Used in actions of the rules of accept, the initial symbol, to call
+# YYACCEPT. If SYMBOL-NUM is specified, run "yyvalue->SLOT = $2;"
+# before, using the slot of SYMBOL-NUM.
+m4_define([b4_accept],
+[m4_ifval([$1],
+ [b4_symbol_value(yyimpl->yyvalue, [$1]) = b4_rhs_value(2, 1, [$1]); ]) YYACCEPT])
+
+
# b4_lhs_value(SYMBOL-NUM, [TYPE])
# --------------------------------
# See README.
@@ -154,14 +175,61 @@ m4_define([b4_rhs_location],
## Declarations. ##
## -------------- ##
+# _b4_declare_sub_yyparse(START-SYMBOL-NUM, SWITCHING-TOKEN-SYMBOL-NUM)
+# ---------------------------------------------------------------------
+# Define the return type of the parsing function for SYMBOL-NUM, and
+# declare its parsing function.
+m4_define([_b4_declare_sub_yyparse],
+[[
+// Return type when parsing one ]_b4_symbol($1, tag)[.
+typedef struct
+{]b4_symbol_if([$1], [has_type], [[
+ ]_b4_symbol($1, type)[ yyvalue;]])[
+ int yystatus;
+ int yynerrs;
+} ]b4_prefix[parse_]_b4_symbol($1, id)[_t;
+
+// Parse one ]_b4_symbol($1, tag)[.
+]b4_prefix[parse_]_b4_symbol($1, id)[_t ]b4_prefix[parse_]_b4_symbol($1, id)[ (]m4_ifset([b4_parse_param], [b4_formals(b4_parse_param)], [void])[);
+]])
+
+
+# _b4_first_switching_token
+# -------------------------
+m4_define([b4_first], [$1])
+m4_define([b4_second], [$2])
+m4_define([_b4_first_switching_token],
+[b4_second(b4_first(b4_start_symbols))])
+
+
+# _b4_define_sub_yyparse(START-SYMBOL-NUM, SWITCHING-TOKEN-SYMBOL-NUM)
+# --------------------------------------------------------------------
+# Define the parsing function for START-SYMBOL-NUM.
+m4_define([_b4_define_sub_yyparse],
+[[
+]b4_prefix[parse_]_b4_symbol($1, id)[_t
+]b4_prefix[parse_]_b4_symbol($1, id)[ (]m4_ifset([b4_parse_param], [b4_formals(b4_parse_param)], [void])[)
+{
+ ]b4_prefix[parse_]_b4_symbol($1, id)[_t yyres;
+ yy_parse_impl_t yyimpl;
+ yyres.yystatus = yy_parse_impl (]b4_symbol($2, id)[, &yyimpl]m4_ifset([b4_parse_param],
+ [[, ]b4_args(b4_parse_param)])[);]b4_symbol_if([$1], [has_type], [[
+ yyres.yyvalue = yyimpl.yyvalue.]b4_symbol($1, slot)[;]])[
+ yyres.yynerrs = yyimpl.yynerrs;
+ return yyres;
+}
+]])
+
+
# b4_declare_scanner_communication_variables
# ------------------------------------------
# Declare the variables that are global, or local to YYPARSE if
# pure-parser.
m4_define([b4_declare_scanner_communication_variables], [[
-/* Lookahead token kind. */
+]m4_ifdef([b4_start_symbols], [],
+[[/* Lookahead token kind. */
int yychar;
-
+]])[
]b4_pure_if([[
/* The semantic value of the lookahead symbol. */
/* Default value used for initialization, for pacifying older GCCs
@@ -276,11 +344,14 @@ int ]b4_prefix[push_parse (]b4_prefix[pstate *ps]b4_pure_if([[,
void ]b4_prefix[pstate_delete (]b4_prefix[pstate *ps);
]])
+
# _b4_declare_yyparse
# -------------------
# When not the push parser.
m4_define([_b4_declare_yyparse],
-[[int ]b4_prefix[parse (]m4_ifset([b4_parse_param], [b4_formals(b4_parse_param)], [void])[);]])
+[[int ]b4_prefix[parse (]m4_ifset([b4_parse_param], [b4_formals(b4_parse_param)], [void])[);
+]m4_ifdef([b4_start_symbols],
+ [m4_map([_b4_declare_sub_yyparse], m4_defn([b4_start_symbols]))])])
# b4_declare_yyparse
@@ -291,16 +362,32 @@ m4_define([b4_declare_yyparse],
])
+# b4_declare_yyerror_and_yylex
+# ----------------------------
+# Comply with POSIX Yacc.
+#
+m4_define([b4_declare_yyerror_and_yylex],
+[b4_posix_if([[#if !defined ]b4_prefix[error && !defined ]b4_api_PREFIX[ERROR_IS_DECLARED
+]b4_function_declare([b4_prefix[error]], void, b4_yyerror_formals)[
+#endif
+#if !defined ]b4_prefix[lex && !defined ]b4_api_PREFIX[LEX_IS_DECLARED
+]b4_function_declare([b4_prefix[lex]], int, b4_yylex_formals)[
+#endif
+]])dnl
+])
+
+
# b4_shared_declarations
# ----------------------
-# Declaration that might either go into the header (if --defines)
-# or open coded in the parser body.
+# Declarations that might either go into the header (if --header)
+# or into the implementation file.
m4_define([b4_shared_declarations],
[b4_cpp_guard_open([b4_spec_mapped_header_file])[
]b4_declare_yydebug[
]b4_percent_code_get([[requires]])[
]b4_token_enums_defines[
]b4_declare_yylstype[
+]b4_declare_yyerror_and_yylex[
]b4_declare_yyparse[
]b4_percent_code_get([[provides]])[
]b4_cpp_guard_close([b4_spec_mapped_header_file])[]dnl
@@ -330,13 +417,13 @@ m4_if(b4_spec_header_file, [y.tab.h], [],
## -------------- ##
-b4_defines_if([[
+b4_header_if([[
]b4_output_begin([b4_spec_header_file])[
]b4_copyright([Bison interface for Yacc-like parsers in C])[
]b4_disclaimer[
]b4_shared_declarations[
]b4_output_end[
-]])# b4_defines_if
+]])# b4_header_if
b4_output_begin([b4_parser_file_name])[
]b4_copyright([Bison implementation for Yacc-like parsers in C])[
@@ -641,15 +728,6 @@ yysymbol_name (yysymbol_kind_t yysymbol)
}]])[
#endif
-#ifdef YYPRINT
-/* YYTOKNUM[NUM] -- (External) token number corresponding to the
- (internal) symbol number NUM (which must be that of a token). */
-static const ]b4_int_type_for([b4_toknum])[ yytoknum[] =
-{
- ]b4_toknum[
-};
-#endif
-
#define YYPACT_NINF (]b4_pact_ninf[)
#define yypact_value_is_default(Yyn) \
@@ -665,18 +743,19 @@ static const ]b4_int_type_for([b4_toknum])[ yytoknum[] =
enum { YYENOMEM = -2 };
#define yyerrok (yyerrstatus = 0)
-#define yyclearin (yychar = ]b4_symbol(-2, id)[)
+#define yyclearin (yychar = ]b4_symbol(empty, id)[)
#define YYACCEPT goto yyacceptlab
#define YYABORT goto yyabortlab
#define YYERROR goto yyerrorlab
+#define YYNOMEM goto yyexhaustedlab
#define YYRECOVERING() (!!yyerrstatus)
#define YYBACKUP(Token, Value) \
do \
- if (yychar == ]b4_symbol(-2, id)[) \
+ if (yychar == ]b4_symbol(empty, id)[) \
{ \
yychar = (Token); \
yylval = (Value); \
@@ -693,8 +772,8 @@ enum { YYENOMEM = -2 };
while (0)
/* Backward compatibility with an undocumented macro.
- Use ]b4_symbol(1, id)[ or ]b4_symbol(2, id)[. */
-#define YYERRCODE ]b4_symbol(2, id)[
+ Use ]b4_symbol(error, id)[ or ]b4_symbol(undef, id)[. */
+#define YYERRCODE ]b4_symbol(undef, id)[
]b4_locations_if([[
]b4_yylloc_default_define[
#define YYRHSLOC(Rhs, K) ((Rhs)[K])
@@ -714,7 +793,7 @@ do { \
YYFPRINTF Args; \
} while (0)
-]b4_yy_location_print_define[
+]b4_yylocation_print_define[
# define YY_SYMBOL_PRINT(Title, Kind, Value, Location) \
do { \
@@ -925,7 +1004,7 @@ do { \
switch (yy_lac (yyesa, &yyes, &yyes_capacity, yyssp, yytoken)) \
{ \
case YYENOMEM: \
- goto yyexhaustedlab; \
+ YYNOMEM; \
case 1: \
goto yyerrlab; \
} \
@@ -1103,7 +1182,7 @@ yypcontext_expected_tokens (const yypcontext_t *yyctx,
for (yyx = 0; yyx < YYNTOKENS; ++yyx)
{
yysymbol_kind_t yysym = YY_CAST (yysymbol_kind_t, yyx);
- if (yysym != ]b4_symbol(1, kind)[ && yysym != ]b4_symbol_prefix[YYUNDEF)
+ if (yysym != ]b4_symbol(error, kind)[ && yysym != ]b4_symbol_prefix[YYUNDEF)
switch (yy_lac (]b4_push_if([[yyps->yyesa, &yyps->yyes, &yyps->yyes_capacity, yyps->yyssp, yysym]],
[[yyctx->yyesa, yyctx->yyes, yyctx->yyes_capacity, yyctx->yyssp, yysym]])[))
{
@@ -1132,7 +1211,7 @@ yypcontext_expected_tokens (const yypcontext_t *yyctx,
int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
int yyx;
for (yyx = yyxbegin; yyx < yyxend; ++yyx)
- if (yycheck[yyx + yyn] == yyx && yyx != ]b4_symbol(1, kind)[
+ if (yycheck[yyx + yyn] == yyx && yyx != ]b4_symbol(error, kind)[
&& !yytable_value_is_error (yytable[yyx + yyn]))
{
if (!yyarg)
@@ -1144,7 +1223,7 @@ yypcontext_expected_tokens (const yypcontext_t *yyctx,
}
}]])[
if (yyarg && yycount == 0 && 0 < yyargn)
- yyarg[0] = ]b4_symbol(-2, kind)[;
+ yyarg[0] = ]b4_symbol(empty, kind)[;
return yycount;
}
@@ -1307,7 +1386,7 @@ yy_syntax_error_arguments (const yypcontext_t *yyctx,
one exception: it will still contain any token that will not be
accepted due to an error action in a later state.]])[
*/
- if (yyctx->yytoken != ]b4_symbol(-2, kind)[)
+ if (yyctx->yytoken != ]b4_symbol(empty, kind)[)
{
int yyn;]b4_lac_if([[
YYDPRINTF ((stderr, "Constructing syntax error message\n"));]])[
@@ -1453,7 +1532,7 @@ yypull_parse (yypstate *yyps]b4_user_formals[)
int yystatus;
do {
]b4_pure_if([[ YYSTYPE yylval;
- int ]])[yychar = ]b4_lex[;
+ int ]])[yychar = ]b4_yylex[;
yystatus = yypush_parse (yyps]b4_pure_if([[, yychar, &yylval]b4_locations_if([[, &yylloc]])])m4_ifset([b4_parse_param], [, b4_args(b4_parse_param)])[);
} while (yystatus == YYPUSH_MORE);
return yystatus;
@@ -1534,8 +1613,31 @@ yypush_parse (yypstate *yyps]b4_pure_if([[,
| yyparse. |
`----------*/
+]m4_ifdef([b4_start_symbols],
+[[// Extract data from the parser.
+typedef struct
+{
+ YYSTYPE yyvalue;
+ int yynerrs;
+} yy_parse_impl_t;
+
+// Run a full parse, using YYCHAR as switching token.
+static int
+yy_parse_impl (int yychar, yy_parse_impl_t *yyimpl]m4_ifset([b4_parse_param], [, b4_formals(b4_parse_param)])[);
+
+]m4_map([_b4_define_sub_yyparse], m4_defn([b4_start_symbols]))[
+
int
-yyparse (]m4_ifset([b4_parse_param], [b4_formals(b4_parse_param)], [void])[)]])[
+yyparse (]m4_ifset([b4_parse_param], [b4_formals(b4_parse_param)], [void])[)
+{
+ return yy_parse_impl (]b4_symbol(_b4_first_switching_token, id)[, YY_NULLPTR]m4_ifset([b4_parse_param],
+ [[, ]b4_args(b4_parse_param)])[);
+}
+
+static int
+yy_parse_impl (int yychar, yy_parse_impl_t *yyimpl]m4_ifset([b4_parse_param], [, b4_formals(b4_parse_param)])[)]],
+[[int
+yyparse (]m4_ifset([b4_parse_param], [b4_formals(b4_parse_param)], [void])[)]])])[
{]b4_pure_if([b4_declare_scanner_communication_variables
])b4_push_if([b4_pure_if([], [[
int yypushed_char = yychar;
@@ -1550,7 +1652,7 @@ yyparse (]m4_ifset([b4_parse_param], [b4_formals(b4_parse_param)], [void])[)]])[
/* The return value of yyparse. */
int yyresult;
/* Lookahead symbol kind. */
- yysymbol_kind_t yytoken = ]b4_symbol(-2, kind)[;
+ yysymbol_kind_t yytoken = ]b4_symbol(empty, kind)[;
/* The variables used to return semantic value and location from the
action routines. */
YYSTYPE yyval;]b4_locations_if([[
@@ -1573,19 +1675,23 @@ yyparse (]m4_ifset([b4_parse_param], [b4_formals(b4_parse_param)], [void])[)]])[
switch (yyps->yynew)
{
- case 2:
- yypstate_clear (yyps);
- goto case_0;
-
- case_0:
case 0:
yyn = yypact[yystate];
goto yyread_pushed_token;
+
+ case 2:
+ yypstate_clear (yyps);
+ break;
+
+ default:
+ break;
}]])[
YYDPRINTF ((stderr, "Starting parse\n"));
- yychar = ]b4_symbol(-2, id)[; /* Cause a token to be read. */
+]m4_ifdef([b4_start_symbols], [],
+[[ yychar = ]b4_symbol(empty, id)[; /* Cause a token to be read. */
+]])[
]m4_ifdef([b4_initial_action], [
b4_dollar_pushdef([m4_define([b4_dollar_dollar_used])yylval], [], [],
[b4_push_if([b4_pure_if([*])yypushed_loc], [yylloc])])dnl
@@ -1620,7 +1726,7 @@ b4_locations_if([[ yylsp[0] = ]b4_push_if([b4_pure_if([*])yypushed_loc], [yyllo
if (yyss + yystacksize - 1 <= yyssp)
#if !defined yyoverflow && !defined YYSTACK_RELOCATE
- goto yyexhaustedlab;
+ YYNOMEM;
#else
{
/* Get the current used size of the three stacks, in elements. */
@@ -1651,7 +1757,7 @@ b4_locations_if([[ yylsp[0] = ]b4_push_if([b4_pure_if([*])yypushed_loc], [yyllo
# else /* defined YYSTACK_RELOCATE */
/* Extend the stack our own way. */
if (YYMAXDEPTH <= yystacksize)
- goto yyexhaustedlab;
+ YYNOMEM;
yystacksize *= 2;
if (YYMAXDEPTH < yystacksize)
yystacksize = YYMAXDEPTH;
@@ -1662,7 +1768,7 @@ b4_locations_if([[ yylsp[0] = ]b4_push_if([b4_pure_if([*])yypushed_loc], [yyllo
YY_CAST (union yyalloc *,
YYSTACK_ALLOC (YY_CAST (YYSIZE_T, YYSTACK_BYTES (yystacksize))));
if (! yyptr)
- goto yyexhaustedlab;
+ YYNOMEM;
YYSTACK_RELOCATE (yyss_alloc, yyss);
YYSTACK_RELOCATE (yyvs_alloc, yyvs);]b4_locations_if([
YYSTACK_RELOCATE (yyls_alloc, yyls);])[
@@ -1686,8 +1792,9 @@ b4_locations_if([[ yylsp[0] = ]b4_push_if([b4_pure_if([*])yypushed_loc], [yyllo
}
#endif /* !defined yyoverflow && !defined YYSTACK_RELOCATE */
+]m4_ifdef([b4_start_symbols], [], [[
if (yystate == YYFINAL)
- YYACCEPT;
+ YYACCEPT;]])[
goto yybackup;
@@ -1707,7 +1814,7 @@ b4_locations_if([[ yylsp[0] = ]b4_push_if([b4_pure_if([*])yypushed_loc], [yyllo
/* Not known => get a lookahead token if don't already have one. */
/* YYCHAR is either empty, or end-of-input, or a valid lookahead. */
- if (yychar == ]b4_symbol(-2, id)[)
+ if (yychar == ]b4_symbol(empty, id)[)
{]b4_push_if([[
if (!yyps->yynew)
{]b4_use_push_for_pull_if([], [[
@@ -1729,23 +1836,23 @@ yyread_pushed_token:]])[
yylval = *yypushed_val;]b4_locations_if([[
if (yypushed_loc)
yylloc = *yypushed_loc;]])])], [[
- yychar = ]b4_lex[;]])[
+ yychar = ]b4_yylex[;]])[
}
- if (yychar <= ]b4_symbol(0, [id])[)
+ if (yychar <= ]b4_symbol(eof, [id])[)
{
- yychar = ]b4_symbol(0, [id])[;
- yytoken = ]b4_symbol(0, [kind])[;
+ yychar = ]b4_symbol(eof, [id])[;
+ yytoken = ]b4_symbol(eof, [kind])[;
YYDPRINTF ((stderr, "Now at end of input.\n"));
}
- else if (yychar == ]b4_symbol(1, [id])[)
+ else if (yychar == ]b4_symbol(error, [id])[)
{
/* The scanner already issued an error message, process directly
to error recovery. But do not keep the error token as
lookahead, it is too special and may lead us to an endless
loop in error recovery. */
- yychar = ]b4_symbol(2, [id])[;
- yytoken = ]b4_symbol(1, [kind])[;]b4_locations_if([[
+ yychar = ]b4_symbol(undef, [id])[;
+ yytoken = ]b4_symbol(error, [kind])[;]b4_locations_if([[
yyerror_range[1] = yylloc;]])[
goto yyerrlab1;
}
@@ -1768,9 +1875,9 @@ yyread_pushed_token:]])[
if (yyn <= 0)
{
if (yytable_value_is_error (yyn))
- goto yyerrlab;]b4_lac_if([[
+ goto yyerrlab;
+ yyn = -yyn;]b4_lac_if([[
YY_LAC_ESTABLISH;]])[
- yyn = -yyn;
goto yyreduce;
}
@@ -1788,7 +1895,7 @@ yyread_pushed_token:]])[
*++yylsp = yylloc;])[
/* Discard the shifted token. */
- yychar = ]b4_symbol(-2, id)[;]b4_lac_if([[
+ yychar = ]b4_symbol(empty, id)[;]b4_lac_if([[
YY_LAC_DISCARD ("shift");]])[
goto yynewstate;
@@ -1879,7 +1986,7 @@ yyread_pushed_token:]])[
yyerrlab:
/* Make sure we have latest lookahead translation. See comments at
user semantic actions for why this is necessary. */
- yytoken = yychar == ]b4_symbol(-2, id)[ ? ]b4_symbol(-2, kind)[ : YYTRANSLATE (yychar);
+ yytoken = yychar == ]b4_symbol(empty, id)[ ? ]b4_symbol(empty, kind)[ : YYTRANSLATE (yychar);
/* If not already recovering from an error, report this error. */
if (!yyerrstatus)
{
@@ -1889,11 +1996,11 @@ yyread_pushed_token:]])[
[[ {
yypcontext_t yyctx
= {]b4_push_if([[yyps]], [[yyssp]b4_lac_if([[, yyesa, &yyes, &yyes_capacity]])])[, yytoken]b4_locations_if([[, &yylloc]])[};]b4_lac_if([[
- if (yychar != ]b4_symbol(-2, id)[)
+ if (yychar != ]b4_symbol(empty, id)[)
YY_LAC_ESTABLISH;]])[
if (yyreport_syntax_error (&yyctx]m4_ifset([b4_parse_param],
- [[, ]b4_args(b4_parse_param)])[) == 2)
- goto yyexhaustedlab;
+ [[, ]b4_args(b4_parse_param)])[) == 2)
+ YYNOMEM;
}]],
[simple],
[[ yyerror (]b4_yyerror_args[YY_("syntax error"));]],
@@ -1902,7 +2009,7 @@ yyread_pushed_token:]])[
= {]b4_push_if([[yyps]], [[yyssp]b4_lac_if([[, yyesa, &yyes, &yyes_capacity]])])[, yytoken]b4_locations_if([[, &yylloc]])[};
char const *yymsgp = YY_("syntax error");
int yysyntax_error_status;]b4_lac_if([[
- if (yychar != ]b4_symbol(-2, id)[)
+ if (yychar != ]b4_symbol(empty, id)[)
YY_LAC_ESTABLISH;]])[
yysyntax_error_status = yysyntax_error (&yymsg_alloc, &yymsg, &yyctx);
if (yysyntax_error_status == 0)
@@ -1928,7 +2035,7 @@ yyread_pushed_token:]])[
}
yyerror (]b4_yyerror_args[yymsgp);
if (yysyntax_error_status == YYENOMEM)
- goto yyexhaustedlab;
+ YYNOMEM;
}]])[
}
]b4_locations_if([[
@@ -1938,17 +2045,17 @@ yyread_pushed_token:]])[
/* If just tried and failed to reuse lookahead token after an
error, discard it. */
- if (yychar <= ]b4_symbol(0, [id])[)
+ if (yychar <= ]b4_symbol(eof, [id])[)
{
/* Return failure if at end of input. */
- if (yychar == ]b4_symbol(0, [id])[)
+ if (yychar == ]b4_symbol(eof, [id])[)
YYABORT;
}
else
{
yydestruct ("Error: discarding",
yytoken, &yylval]b4_locations_if([, &yylloc])[]b4_user_args[);
- yychar = ]b4_symbol(-2, id)[;
+ yychar = ]b4_symbol(empty, id)[;
}
}
@@ -1965,6 +2072,7 @@ yyread_pushed_token:]])[
label yyerrorlab therefore never appears in user code. */
if (0)
YYERROR;
+ ++yynerrs;
/* Do not reclaim the symbols of the rule whose action triggered
this YYERROR. */
@@ -1987,8 +2095,8 @@ yyread_pushed_token:]])[
yyn = yypact[yystate];
if (!yypact_value_is_default (yyn))
{
- yyn += ]b4_symbol(1, kind)[;
- if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == ]b4_symbol(1, kind)[)
+ yyn += ]b4_symbol(error, kind)[;
+ if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == ]b4_symbol(error, kind)[)
{
yyn = yytable[yyn];
if (0 < yyn)
@@ -2032,7 +2140,7 @@ yyread_pushed_token:]])[
`-------------------------------------*/
yyacceptlab:
yyresult = 0;
- goto yyreturn;
+ goto yyreturnlab;
/*-----------------------------------.
@@ -2040,25 +2148,23 @@ yyread_pushed_token:]])[
`-----------------------------------*/
yyabortlab:
yyresult = 1;
- goto yyreturn;
+ goto yyreturnlab;
-#if ]b4_lac_if([[1]], [b4_parse_error_case([simple], [[!defined yyoverflow]], [[1]])])[
-/*-------------------------------------------------.
-| yyexhaustedlab -- memory exhaustion comes here. |
-`-------------------------------------------------*/
+/*-----------------------------------------------------------.
+| yyexhaustedlab -- YYNOMEM (memory exhaustion) comes here. |
+`-----------------------------------------------------------*/
yyexhaustedlab:
yyerror (]b4_yyerror_args[YY_("memory exhausted"));
yyresult = 2;
- goto yyreturn;
-#endif
+ goto yyreturnlab;
-/*-------------------------------------------------------.
-| yyreturn -- parsing is finished, clean up and return. |
-`-------------------------------------------------------*/
-yyreturn:
- if (yychar != ]b4_symbol(-2, id)[)
+/*----------------------------------------------------------.
+| yyreturnlab -- parsing is finished, clean up and return. |
+`----------------------------------------------------------*/
+yyreturnlab:
+ if (yychar != ]b4_symbol(empty, id)[)
{
/* Make sure we have latest lookahead translation. See comments at
user semantic actions for why this is necessary. */
@@ -2092,7 +2198,9 @@ yypushreturn:]], [[
YYSTACK_FREE (yyes);]])])[
]b4_parse_error_bmatch([detailed\|verbose],
[[ if (yymsg != yymsgbuf)
- YYSTACK_FREE (yymsg);]])[
+ YYSTACK_FREE (yymsg);]])[]m4_ifdef([b4_start_symbols], [[
+ if (yyimpl)
+ yyimpl->yynerrs = yynerrs;]])[
return yyresult;
}
]b4_push_if([b4_parse_state_variable_macros([b4_macro_undef])])[
diff --git a/bison/data/xslt/bison.xsl b/bison/data/xslt/bison.xsl
index d493695..989a343 100644
--- a/bison/data/xslt/bison.xsl
+++ b/bison/data/xslt/bison.xsl
@@ -3,7 +3,7 @@
+ xmlns:bison="https://www.gnu.org/software/bison/">
.
+ along with this program. If not, see .
Written by Wojciech Polak .
-->
+ xmlns:bison="https://www.gnu.org/software/bison/">
diff --git a/bison/data/xslt/xml2text.xsl b/bison/data/xslt/xml2text.xsl
index 6aad152..1fc5731 100644
--- a/bison/data/xslt/xml2text.xsl
+++ b/bison/data/xslt/xml2text.xsl
@@ -3,7 +3,7 @@
+ xmlns:bison="https://www.gnu.org/software/bison/">
diff --git a/bison/data/xslt/xml2xhtml.xsl b/bison/data/xslt/xml2xhtml.xsl
index 5fcfda6..aaa5dba 100644
--- a/bison/data/xslt/xml2xhtml.xsl
+++ b/bison/data/xslt/xml2xhtml.xsl
@@ -3,7 +3,7 @@
@@ -26,7 +26,7 @@
+ xmlns:bison="https://www.gnu.org/software/bison/">
@@ -88,7 +88,7 @@