mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-08-12 20:25:13 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
01e3f45f83 | ||
|
|
091943f265 | ||
|
|
bf98d94f4f | ||
|
|
6bb37dbe27 | ||
|
|
c3585f41ef | ||
|
|
6525abdc83 | ||
|
|
2b63c54f5a | ||
|
|
2da399d15f | ||
|
|
0c77d69721 | ||
|
|
307fcdee00 | ||
|
|
d26d10ad6c | ||
|
|
1b4108da3e | ||
|
|
53bfc7df94 | ||
|
|
a5fb4a88ef | ||
|
|
54df196d49 | ||
|
|
52bb6f0525 | ||
|
|
76dab18af3 |
+1
-1
@@ -1 +1 @@
|
||||
3.5.93
|
||||
3.6
|
||||
|
||||
+1
-1
@@ -46,7 +46,7 @@ jobs:
|
||||
- ./bootstrap
|
||||
- ./configure --enable-gcc-warnings || { cat config.log && false; }
|
||||
- make -j2
|
||||
- make -j2 dist
|
||||
- make -j2 dist-xz
|
||||
# Can help understanding why we get "dirty" tarballs.
|
||||
- git status
|
||||
- dist=$(echo bison*.xz)
|
||||
|
||||
@@ -1,43 +1,18 @@
|
||||
GNU Bison NEWS
|
||||
|
||||
* Noteworthy changes in release 3.5.94 (2020-05-06) [beta]
|
||||
* Noteworthy changes in release 3.6.1 (2020-05-10) [stable]
|
||||
|
||||
Portability issues.
|
||||
** Bug fixes
|
||||
|
||||
* Noteworthy changes in release 3.5.93 (2020-05-03) [beta]
|
||||
GNU readline portability issues.
|
||||
|
||||
Portability issues.
|
||||
|
||||
* Noteworthy changes in release 3.5.92 (2020-05-03) [beta]
|
||||
|
||||
Portability issues.
|
||||
|
||||
More documentation.
|
||||
|
||||
Backward compatibility issues with C++.
|
||||
|
||||
* Noteworthy changes in release 3.5.91 (2020-04-29) [stable]
|
||||
In C++, yy::parser::symbol_name is now a public member, as was intended.
|
||||
|
||||
** New features
|
||||
|
||||
*** Returning the error token
|
||||
In C++, yy::parser::symbol_type now has a public name() member function.
|
||||
|
||||
When the scanner returns an invalid token or the undefined token
|
||||
(YYUNDEF), the parser generates an error message and enters error
|
||||
recovery. Because of that error message, most scanners that find lexical
|
||||
errors generate an error message, and then ignore the invalid input
|
||||
without entering the error-recovery.
|
||||
|
||||
The scanners may now return YYerror, the error token, to enter the
|
||||
error-recovery mode without triggering an additional error message. See
|
||||
the bistromathic for an example.
|
||||
|
||||
*** The bistromathic features internationalization
|
||||
|
||||
Its way to build the error message is more general and is easy to use in
|
||||
other projects.
|
||||
|
||||
* Noteworthy changes in release 3.5.90 (2020-04-18) [beta]
|
||||
* Noteworthy changes in release 3.6 (2020-05-08) [stable]
|
||||
|
||||
** Backward incompatible changes
|
||||
|
||||
@@ -142,6 +117,18 @@ GNU Bison NEWS
|
||||
It makes little sense to use this feature without enabling LAC (lookahead
|
||||
correction).
|
||||
|
||||
*** Returning the error token
|
||||
|
||||
When the scanner returns an invalid token or the undefined token
|
||||
(YYUNDEF), the parser generates an error message and enters error
|
||||
recovery. Because of that error message, most scanners that find lexical
|
||||
errors generate an error message, and then ignore the invalid input
|
||||
without entering the error-recovery.
|
||||
|
||||
The scanners may now return YYerror, the error token, to enter the
|
||||
error-recovery mode without triggering an additional error message. See
|
||||
the bistromathic for an example.
|
||||
|
||||
*** Deep overhaul of the symbol and token kinds
|
||||
|
||||
To avoid the confusion with types in programming languages, we now refer
|
||||
|
||||
@@ -1,4 +1,12 @@
|
||||
* Bison 3.6
|
||||
* Bison 3.7
|
||||
** Bistromathic
|
||||
- Hitting tab on a line with a syntax error is ugly
|
||||
|
||||
- Be robust to existing ~/.inputrc
|
||||
|
||||
- How about not evaluating incomplete lines when the text is not finished
|
||||
(as shells do).
|
||||
|
||||
** Doc
|
||||
*** api.header.include
|
||||
|
||||
@@ -31,7 +39,6 @@ enough.
|
||||
*** calc.at
|
||||
Stop hard-coding "Calc". Adjust local.at (look for FIXME).
|
||||
|
||||
* Bison 3.7
|
||||
** Counter example generation
|
||||
See https://github.com/akimd/bison/pull/15.
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@ gnulib_dir = $(srcdir)/gnulib
|
||||
bootstrap-tools = autoconf,automake,flex,gettext,gnulib
|
||||
|
||||
announcement_Cc_ = \
|
||||
[email protected], [email protected], bison-patches@gnu.org, \
|
||||
[email protected], bison-announce@gnu.org, \
|
||||
[email protected]
|
||||
|
||||
update-copyright: update-b4-copyright update-package-copyright-year
|
||||
|
||||
+2
-4
@@ -36,10 +36,8 @@ AC_DEFINE_UNQUOTED([PACKAGE_COPYRIGHT_YEAR], [$PACKAGE_COPYRIGHT_YEAR],
|
||||
AC_CONFIG_AUX_DIR([build-aux])
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
|
||||
# We use Automake 1.14's %D% and %C%.
|
||||
#
|
||||
# When we move to Automake 1.16, simplify examples/c/reccalc/local.mk.
|
||||
# Our CI runs on Xenial, which has only Automake 1.15.
|
||||
# Our CI build the packages on Bionic, which has only Automake 1.15.
|
||||
#
|
||||
# We want gnits strictness only when rolling a stable release. For
|
||||
# release candidates, we use version strings like 2.4.3_rc1, but gnits
|
||||
@@ -47,7 +45,7 @@ AC_CONFIG_MACRO_DIR([m4])
|
||||
# releases, we want to be able run make dist without being required to
|
||||
# add a bogus NEWS entry. In that case, the version string
|
||||
# automatically contains a dash, which we also let disable gnits.
|
||||
AM_INIT_AUTOMAKE([1.14 dist-xz nostdinc
|
||||
AM_INIT_AUTOMAKE([1.15 dist-lzip dist-xz nostdinc
|
||||
color-tests parallel-tests
|
||||
silent-rules]
|
||||
m4_bmatch(m4_defn([AC_PACKAGE_VERSION]), [[-_]],
|
||||
|
||||
@@ -357,6 +357,29 @@ m4_define([b4_symbol_type_define],
|
||||
Base::clear ();
|
||||
}
|
||||
|
||||
]b4_parse_error_bmatch(
|
||||
[custom\|detailed],
|
||||
[[ /// The user-facing name of this symbol.
|
||||
const char *name () const YY_NOEXCEPT
|
||||
{
|
||||
return ]b4_parser_class[::symbol_name (this->kind ());
|
||||
}]],
|
||||
[simple],
|
||||
[[#if ]b4_api_PREFIX[DEBUG || ]b4_token_table_flag[
|
||||
/// The user-facing name of this symbol.
|
||||
const char *name () const YY_NOEXCEPT
|
||||
{
|
||||
return ]b4_parser_class[::symbol_name (this->kind ());
|
||||
}
|
||||
#endif // #if ]b4_api_PREFIX[DEBUG || ]b4_token_table_flag[
|
||||
]],
|
||||
[verbose],
|
||||
[[ /// The user-facing name of this symbol.
|
||||
std::string name () const YY_NOEXCEPT
|
||||
{
|
||||
return ]b4_parser_class[::symbol_name (this->kind ());
|
||||
}]])[
|
||||
|
||||
/// Backward compatibility (Bison 3.6).
|
||||
symbol_kind_type type_get () const YY_NOEXCEPT;
|
||||
|
||||
|
||||
+99
-92
@@ -241,6 +241,23 @@ m4_define([b4_shared_declarations],
|
||||
/// Report a syntax error.
|
||||
void error (const syntax_error& err);
|
||||
|
||||
]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
|
||||
@@ -317,26 +334,14 @@ m4_define([b4_shared_declarations],
|
||||
static symbol_kind_type yytranslate_ (int t);
|
||||
|
||||
]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);
|
||||
|
||||
/// For a symbol, its name in clear.
|
||||
static const char* const yytname_[];
|
||||
#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);
|
||||
|
||||
/// Convert the symbol name \a n to a form suitable for a diagnostic.
|
||||
[[ /// 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.
|
||||
@@ -474,6 +479,7 @@ m4_define([b4_shared_declarations],
|
||||
};
|
||||
|
||||
]b4_parse_param_vars[
|
||||
]b4_percent_code_get([[yy_bison_internal_hook]])[
|
||||
};
|
||||
|
||||
]b4_token_ctor_if([b4_yytranslate_define([$1])[
|
||||
@@ -607,83 +613,6 @@ m4_if(b4_prefix, [yy], [],
|
||||
#define YYRECOVERING() (!!yyerrstatus_)
|
||||
|
||||
]b4_namespace_open[
|
||||
]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]);
|
||||
}
|
||||
]])[
|
||||
|
||||
/// Build a parser object.
|
||||
]b4_parser_class::b4_parser_class[ (]b4_parse_param_decl[)
|
||||
#if ]b4_api_PREFIX[DEBUG
|
||||
@@ -815,7 +744,7 @@ m4_if(b4_prefix, [yy], [],
|
||||
{
|
||||
symbol_kind_type yykind = yysym.kind ();
|
||||
yyo << (yykind < YYNTOKENS ? "token" : "nterm")
|
||||
<< ' ' << symbol_name (yykind) << " ("]b4_locations_if([
|
||||
<< ' ' << yysym.name () << " ("]b4_locations_if([
|
||||
<< yysym.location << ": "])[;
|
||||
]b4_symbol_actions([printer])[
|
||||
yyo << ')';
|
||||
@@ -1267,8 +1196,86 @@ b4_dollar_popdef])[]dnl
|
||||
{
|
||||
error (]b4_join(b4_locations_if([yyexc.location]),
|
||||
[[yyexc.what ()]])[);
|
||||
}]b4_parse_error_bmatch([custom\|detailed\|verbose], [[
|
||||
}
|
||||
|
||||
]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([custom\|detailed\|verbose], [[
|
||||
// ]b4_parser_class[::context.
|
||||
]b4_parser_class[::context::context (const ]b4_parser_class[& yyparser, const symbol_type& yyla)
|
||||
: yyparser_ (yyparser)
|
||||
|
||||
@@ -1979,7 +1979,7 @@ yyerrorlab:
|
||||
yyerrlab1:
|
||||
yyerrstatus = 3; /* Each real token shifted decrements this. */
|
||||
|
||||
// Pop stack until we find a state that shifts the error token.
|
||||
/* Pop stack until we find a state that shifts the error token. */
|
||||
for (;;)
|
||||
{
|
||||
yyn = yypact[yystate];
|
||||
|
||||
+35
-6
@@ -7666,11 +7666,11 @@ recovery.
|
||||
In either case, the rest of the action is not executed.
|
||||
@end deffn
|
||||
|
||||
@deffn {Macro} YYEMPTY
|
||||
@deffn {Value} YYEMPTY
|
||||
Value stored in @code{yychar} when there is no lookahead token.
|
||||
@end deffn
|
||||
|
||||
@deffn {Macro} YYEOF
|
||||
@deffn {Value} YYEOF
|
||||
Value stored in @code{yychar} when the lookahead is the end of the input
|
||||
stream.
|
||||
@end deffn
|
||||
@@ -12154,6 +12154,8 @@ values, which is always less than @code{YYNTOKENS}.
|
||||
|
||||
@deftypemethod {parser} {const char *} symbol_name (@code{symbol_kind_t} @var{symbol}) @code{const}
|
||||
The name of the symbol whose kind is @var{symbol}, possibly translated.
|
||||
|
||||
Returns a @code{std::string} when @code{parse.error} is @code{verbose}.
|
||||
@end deftypemethod
|
||||
|
||||
A custom syntax error function looks as follows. This implementation is
|
||||
@@ -12286,6 +12288,12 @@ applicable) location.
|
||||
The kind of this symbol.
|
||||
@end deftypemethod
|
||||
|
||||
@deftypemethod {symbol_type} {const char *} name () @code{const}
|
||||
The name of the kind of this symbol.
|
||||
|
||||
Returns a @code{std::string} when @code{parse.error} is @code{verbose}.
|
||||
@end deftypemethod
|
||||
|
||||
@sp 1
|
||||
|
||||
For each token kind, Bison generates named constructors as follows.
|
||||
@@ -14700,6 +14708,14 @@ is given a nonzero value, the parser will output information on input
|
||||
symbols and parser action. @xref{Tracing}.
|
||||
@end deffn
|
||||
|
||||
@deffn {Value} YYEMPTY
|
||||
The pseudo token kind when there is no lookahead token.
|
||||
@end deffn
|
||||
|
||||
@deffn {Value} YYEOF
|
||||
The token kind denoting is the end of the input stream.
|
||||
@end deffn
|
||||
|
||||
@deffn {Macro} yyerrok
|
||||
Macro to cause parser to recover immediately to its normal mode
|
||||
after a syntax error. @xref{Error Recovery}.
|
||||
@@ -14856,6 +14872,10 @@ should not be confused with the @emph{symbol kinds}, used internally by the
|
||||
parser.
|
||||
@end deffn
|
||||
|
||||
@deffn {Value} YYUNDEF
|
||||
The token kind denoting an unknown token.
|
||||
@end deffn
|
||||
|
||||
|
||||
@node Glossary
|
||||
@appendix Glossary
|
||||
@@ -14942,12 +14962,21 @@ A continuous flow of data between devices or programs.
|
||||
@item Kind
|
||||
``Token'' and ``symbol'' are each overloaded to mean either a grammar symbol
|
||||
(kind) or all parse info (kind, value, location) associated with occurrences
|
||||
of that grammar symbol from the input. To disambiguate, we use ``token
|
||||
kind'' and ``symbol kind'' to mean both grammar symbols and the types that
|
||||
represent them in a base programming language (C, C++, etc.). However, we
|
||||
use ``token'' and ``symbol'' without the word ``kind'' to mean parsed
|
||||
of that grammar symbol from the input. To disambiguate,
|
||||
|
||||
@itemize
|
||||
@item
|
||||
we use ``token kind'' and ``symbol kind'' to mean both grammar symbols and
|
||||
the values that represent them in a base programming language (C, C++,
|
||||
etc.). The names of the types of these values are typically
|
||||
@code{token_kind_t}, or @code{token_kind_type}, or @code{TokenKind},
|
||||
depending on the programming language.
|
||||
|
||||
@item
|
||||
we use ``token'' and ``symbol'' without the word ``kind'' to mean parsed
|
||||
occurrences, and we append the word ``type'' to refer to the types that
|
||||
represent them in a base programming language.
|
||||
@end itemize
|
||||
|
||||
In summary: When you see ``kind'', interpret ``symbol'' or ``token'' to mean
|
||||
a @emph{grammar symbol}. When you don't see ``kind'' (including when you
|
||||
|
||||
+4
-4
@@ -131,7 +131,7 @@ dist_man_MANS = $(top_srcdir)/%D%/bison.1
|
||||
EXTRA_DIST += $(dist_man_MANS:.1=.x)
|
||||
MAINTAINERCLEANFILES += $(dist_man_MANS)
|
||||
|
||||
# Differences to ignore when comparing the man page (the date).
|
||||
# Differences to ignore when comparing man pages (the date).
|
||||
remove_time_stamp = \
|
||||
sed 's/^\(\.TH[^"]*"[^"]*"[^"]*\)"[^"]*"/\1/'
|
||||
|
||||
@@ -144,15 +144,15 @@ endif
|
||||
# have the real thing, so if there's a .git directory, fail hard.
|
||||
#
|
||||
# We shouldn't need this, but on some OS the timestamps in the tarball
|
||||
# leaves us no choice. See
|
||||
# leave us no choice. See
|
||||
# https://lists.gnu.org/r/bug-bison/2020-05/msg00055.html.
|
||||
$(top_srcdir)/%D%/bison.1: $(MAN_DEPS)
|
||||
$(AM_V_GEN)if $(HELP2MAN) --version >/dev/null 2>&1; then \
|
||||
$(HELP2MAN) \
|
||||
--include=$(top_srcdir)/%D%/bison.x \
|
||||
--output=$@.tmp tests/bison && \
|
||||
$(remove_time_stamp) $@ >$@a.tmp 2>/dev/null && \
|
||||
$(remove_time_stamp) $@.tmp >$@b.tmp 2>/dev/null && \
|
||||
{ $(remove_time_stamp) $@ >$@a.tmp || true; } && \
|
||||
$(remove_time_stamp) $@.tmp >$@b.tmp && \
|
||||
if diff $@a.tmp $@b.tmp >/dev/null 2>&1; then \
|
||||
touch $@; \
|
||||
else \
|
||||
|
||||
@@ -32,10 +32,10 @@ The calculator with precedence directives and location tracking. It uses
|
||||
Flex to generate the scanner.
|
||||
|
||||
## reccalc - recursive calculator with Flex and Bison
|
||||
The example builds on top of the previous one to provide a reentrant parser.
|
||||
Such parsers can be called concurrently in different threads, or even
|
||||
recursively. To demonstrate this feature, expressions in parentheses are
|
||||
tokenized as strings, and then recursively parsed from the parser. So
|
||||
This example builds on top of the previous one to provide a reentrant
|
||||
parser. Such parsers can be called concurrently in different threads, or
|
||||
even recursively. To demonstrate this feature, expressions in parentheses
|
||||
are tokenized as strings, and then recursively parsed from the parser. So
|
||||
`(((1)+(2))*((3)+(4)))` uses eight parsers, with a depth of four.
|
||||
|
||||
## pushcalc - calculator implemented with a push parser
|
||||
|
||||
@@ -14,6 +14,9 @@ This example demonstrates best practices when using Bison.
|
||||
- It supports debug traces with semantic values.
|
||||
- It uses named references instead of the traditional $1, $2, etc.
|
||||
|
||||
To customize the interaction with bistromathic, see the GNU Readline user
|
||||
manual (see `info rluserman`).
|
||||
|
||||
<!---
|
||||
Local Variables:
|
||||
fill-column: 76
|
||||
|
||||
@@ -15,6 +15,10 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# Users may customize the behavior of readline, which might break our
|
||||
# expected results.
|
||||
INPUTRC=/dev/null
|
||||
export INPUTRC
|
||||
|
||||
# Beware of portability issues of readline when not feeding it from a
|
||||
# terminal.
|
||||
@@ -41,10 +45,11 @@ echo >perfect '> 0
|
||||
echo >ok '0'
|
||||
echo '0' | prog >effective
|
||||
|
||||
if diff perfect effective >/dev/null 2>&1; then
|
||||
echo "checking for readline output"
|
||||
if diff perfect effective; then
|
||||
# Alles ist gut.
|
||||
strip_prompt=false
|
||||
elif diff ok effective >/dev/null 2>&1; then
|
||||
elif diff ok effective; then
|
||||
strip_prompt=true
|
||||
else
|
||||
skip "this is not the GNU Readline we expect"
|
||||
@@ -257,14 +262,22 @@ err: Cleanup: popping nterm input (1.1-4: )' -p
|
||||
# From now on, the differences between versions of GNU Readline are
|
||||
# too painful to try to cope with.
|
||||
if $strip_prompt; then
|
||||
echo "SKIP: this is not the GNU Readline we expect"
|
||||
if $exit; then
|
||||
exit 0
|
||||
else
|
||||
exit 1
|
||||
fi
|
||||
echo "SKIP: this is not the GNU Readline we expect"
|
||||
exit $status
|
||||
fi
|
||||
|
||||
# On Windows10/MSYS2 the ^G coming from <tab> completion is not
|
||||
# emitted the same way
|
||||
# (https://lists.gnu.org/r/bug-bison/2020-05/msg00076.html).
|
||||
echo "checking for kernel name"
|
||||
case `uname -s` in
|
||||
(MSYS*)
|
||||
echo "SKIP: this is Windows/MSYS"
|
||||
exit $status
|
||||
;;
|
||||
esac
|
||||
|
||||
|
||||
# Check completion after an operator.
|
||||
sed -e 's/\\t/ /g' >input <<EOF
|
||||
(1+\t\t
|
||||
|
||||
+9
-2
@@ -34,6 +34,13 @@ cwd=$(pwd)
|
||||
# See bistromathic.test.
|
||||
strip_prompt=false
|
||||
|
||||
# If diff supports --strip-trailing-cr, use it, to avoid EOL issues
|
||||
# when testing Java programs on Windows.
|
||||
echo "checking for diff --strip-trailing-cr"
|
||||
if diff --strip-trailing-cr "$1" "$1"; then
|
||||
diff_opts=--strip-trailing-cr
|
||||
fi
|
||||
|
||||
# The exercised program.
|
||||
abs_medir=$cwd/examples/$medir
|
||||
if test -x "$abs_medir/$me"; then
|
||||
@@ -129,7 +136,7 @@ run ()
|
||||
} >eff
|
||||
|
||||
if test $sta_eff -eq $sta_exp; then
|
||||
if diff eff exp >/dev/null 2>&1; then
|
||||
if diff $diff_opts eff exp >/dev/null 2>&1; then
|
||||
echo "$me: PASS: $number"
|
||||
else
|
||||
echo "$me: FAIL: $number"
|
||||
@@ -140,7 +147,7 @@ run ()
|
||||
echo "$me: effective output:"
|
||||
sed -e 's/^/ /' eff
|
||||
echo "$me: diff:"
|
||||
diff -u exp eff | sed -e 's/^/ /'
|
||||
diff $diff_opts -u exp eff | sed -e 's/^/ /'
|
||||
status=1
|
||||
fi
|
||||
else
|
||||
|
||||
+5
-3
@@ -1,4 +1,4 @@
|
||||
/* A Bison parser, made by GNU Bison 3.5.93. */
|
||||
/* A Bison parser, made by GNU Bison 3.6. */
|
||||
|
||||
/* Bison implementation for Yacc-like parsers in C
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
#define YYBISON 1
|
||||
|
||||
/* Bison version. */
|
||||
#define YYBISON_VERSION "3.5.93"
|
||||
#define YYBISON_VERSION "3.6"
|
||||
|
||||
/* Skeleton name. */
|
||||
#define YYSKELETON_NAME "yacc.c"
|
||||
@@ -1632,6 +1632,8 @@ yypcontext_expected_tokens (const yypcontext_t *yyctx,
|
||||
yyarg[yycount++] = yysym;
|
||||
}
|
||||
}
|
||||
if (yyarg && yycount == 0 && 0 < yyargn)
|
||||
yyarg[0] = YYSYMBOL_YYEMPTY;
|
||||
return yycount;
|
||||
}
|
||||
|
||||
@@ -2703,7 +2705,7 @@ yyerrorlab:
|
||||
yyerrlab1:
|
||||
yyerrstatus = 3; /* Each real token shifted decrements this. */
|
||||
|
||||
// Pop stack until we find a state that shifts the error token.
|
||||
/* Pop stack until we find a state that shifts the error token. */
|
||||
for (;;)
|
||||
{
|
||||
yyn = yypact[yystate];
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
/* A Bison parser, made by GNU Bison 3.5.93. */
|
||||
/* A Bison parser, made by GNU Bison 3.6. */
|
||||
|
||||
/* Bison interface for Yacc-like parsers in C
|
||||
|
||||
|
||||
+18
-11
@@ -109,11 +109,6 @@ AT_DATA_GRAMMAR([list.yy],
|
||||
%define parse.assert
|
||||
%debug
|
||||
|
||||
%code top
|
||||
{
|
||||
// Get access to stack_symbol_type for the tests.
|
||||
# define private public
|
||||
}
|
||||
%code provides
|
||||
{
|
||||
]AT_YYLEX_DECLARE[
|
||||
@@ -136,6 +131,14 @@ AT_DATA_GRAMMAR([list.yy],
|
||||
%code requires { #include <vector> }
|
||||
%code { int yylex (yy::parser::semantic_type* lvalp); }
|
||||
|
||||
// A hack which relies on internal hooks to check stack_symbol_type,
|
||||
// which is private.
|
||||
%code yy_bison_internal_hook {
|
||||
public:
|
||||
typedef stack_symbol_type yy_stack_symbol_type;
|
||||
typedef stack_type yy_stack_type;
|
||||
}
|
||||
|
||||
%%
|
||||
exp: "int" { $$.push_back ($1); }
|
||||
%%
|
||||
@@ -157,6 +160,9 @@ int main()
|
||||
// symbol_type: construction, accessor.
|
||||
{
|
||||
parser::symbol_type s = parser::make_INT (12);
|
||||
assert_eq (s.kind (), parser::symbol_kind::S_INT);
|
||||
assert_eq (parser::symbol_name (s.kind ()), "\"int\"");
|
||||
assert_eq (s.name (), "\"int\"");
|
||||
assert_eq (s.value.as<int> (), 12);
|
||||
}
|
||||
|
||||
@@ -180,12 +186,13 @@ int main()
|
||||
}
|
||||
|
||||
// stack_symbol_type: construction, accessor.
|
||||
typedef parser::yy_stack_symbol_type stack_symbol_type;
|
||||
{
|
||||
#if 201103L <= YY_CPLUSPLUS
|
||||
auto ss = parser::stack_symbol_type(1, parser::make_INT(123));
|
||||
auto ss = stack_symbol_type (1, parser::make_INT(123));
|
||||
#else
|
||||
parser::symbol_type s = parser::make_INT (123);
|
||||
parser::stack_symbol_type ss(1, s);
|
||||
stack_symbol_type ss(1, s);
|
||||
#endif
|
||||
assert_eq (ss.value.as<int> (), 123);
|
||||
}
|
||||
@@ -194,17 +201,17 @@ int main()
|
||||
// Sufficiently many so that it will be resized.
|
||||
// Probably 3 times (starting at 200).
|
||||
{
|
||||
parser::stack_type st;
|
||||
parser::yy_stack_type st;
|
||||
const int mucho = 1700;
|
||||
const int int_reduction_state = 1; // Read list.output to find it.
|
||||
for (int i = 0; i < mucho; ++i)
|
||||
{
|
||||
#if 201103L <= YY_CPLUSPLUS
|
||||
st.push(parser::stack_symbol_type{int_reduction_state,
|
||||
parser::make_INT (i)});
|
||||
st.push(stack_symbol_type{int_reduction_state,
|
||||
parser::make_INT (i)});
|
||||
#else
|
||||
parser::symbol_type s = parser::make_INT (i);
|
||||
parser::stack_symbol_type ss (int_reduction_state, s);
|
||||
stack_symbol_type ss (int_reduction_state, s);
|
||||
st.push (ss);
|
||||
#endif
|
||||
}
|
||||
|
||||
+1
-1
@@ -500,7 +500,7 @@ m4_define([AT_DATA_SOURCE_PROLOGUE],
|
||||
# The prologue that should be included in any grammar whose parser is
|
||||
# meant to be compiled.
|
||||
m4_define([AT_DATA_GRAMMAR_PROLOGUE],
|
||||
[[%code top {
|
||||
[[%code top { /* -*- ]AT_LANG[ -*- */
|
||||
]AT_DATA_SOURCE_PROLOGUE[]dnl
|
||||
[}
|
||||
]])
|
||||
|
||||
Reference in New Issue
Block a user