mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-09 04:13:03 +00:00
lalr1.cc: support compilation with disabled support for exceptions
Reported by Brooks Moses <bmoses@google.com> http://lists.gnu.org/archive/html/bison-patches/2018-02/msg00000.html * data/lalr1.cc (YY_EXCEPTIONS): New. Use it to disable try/catch clauses. * doc/bison.texi (C++ Parser Interface): Document it. * configure.ac (CXXFLAGS_NO_EXCEPTIONS): New. * tests/atlocal.in: Receive it. * tests/local.at (AT_FULL_COMPILE, AT_LANG_COMPILE): Accept a new argument, extra compiler flags. * tests/calc.at: Run the C++ calculator with exception support disabled.
This commit is contained in:
7
NEWS
7
NEWS
@@ -74,6 +74,13 @@ GNU Bison NEWS
|
||||
input: '0' | exp
|
||||
^^^
|
||||
|
||||
*** C++: Generated parsers can be compiled with -fno-exceptions (lalr1.cc)
|
||||
|
||||
When compiled with exceptions disabled, the generated parsers no longer
|
||||
uses try/catch clauses.
|
||||
|
||||
Currently only GCC and Clang are supported.
|
||||
|
||||
** Bug fixes
|
||||
|
||||
*** GLR: Predicates support broken by #line directives
|
||||
|
||||
1
THANKS
1
THANKS
@@ -25,6 +25,7 @@ Bert Deknuydt Bert.Deknuydt@esat.kuleuven.ac.be
|
||||
Bill Allombert Bill.Allombert@math.u-bordeaux1.fr
|
||||
Bob Rossi bob@brasko.net
|
||||
Brandon Lucia blucia@gmail.com
|
||||
Brooks Moses bmoses@google.com
|
||||
Bruce Lilly blilly@erols.com
|
||||
Bruno Haible bruno@clisp.org
|
||||
Charles-Henri de Boysson de-boy_c@epita.fr
|
||||
|
||||
@@ -153,6 +153,7 @@ if test "$enable_gcc_warnings" = yes; then
|
||||
# ... possiby in std=c++11 mode.
|
||||
gl_WARN_ADD([-Wno-zero-as-null-pointer-constant], [FLEX_SCANNER_CXXFLAGS])
|
||||
CXXFLAGS=$save_CXXFLAGS
|
||||
gl_WARN_ADD([-fno-exceptions], [CXXFLAGS_NO_EXCEPTIONS])
|
||||
AC_LANG_POP([C++])
|
||||
fi
|
||||
|
||||
|
||||
@@ -424,6 +424,15 @@ m4_if(b4_prefix, [yy], [],
|
||||
# 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
|
||||
|
||||
]b4_locations_if([dnl
|
||||
[#define YYRHSLOC(Rhs, K) ((Rhs)[K].location)
|
||||
]b4_yylloc_default_define])[
|
||||
@@ -717,7 +726,9 @@ m4_if(b4_prefix, [yy], [],
|
||||
/// The return value of parse ().
|
||||
int yyresult;
|
||||
|
||||
#if YY_EXCEPTIONS
|
||||
try
|
||||
#endif // YY_EXCEPTIONS
|
||||
{
|
||||
YYCDEBUG << "Starting parse\n";
|
||||
|
||||
@@ -755,17 +766,21 @@ b4_dollar_popdef])[]dnl
|
||||
if (yyla.empty ())
|
||||
{
|
||||
YYCDEBUG << "Reading a token: ";
|
||||
#if YY_EXCEPTIONS
|
||||
try
|
||||
#endif // YY_EXCEPTIONS
|
||||
{]b4_token_ctor_if([[
|
||||
symbol_type yylookahead (]b4_lex[);
|
||||
yyla.move (yylookahead);]], [[
|
||||
yyla.type = yytranslate_ (]b4_lex[);]])[
|
||||
}
|
||||
#if YY_EXCEPTIONS
|
||||
catch (const syntax_error& yyexc)
|
||||
{
|
||||
error (yyexc);
|
||||
goto yyerrlab1;
|
||||
}
|
||||
#endif // YY_EXCEPTIONS
|
||||
}
|
||||
YY_SYMBOL_PRINT ("Next token is", yyla);
|
||||
|
||||
@@ -835,7 +850,9 @@ b4_dollar_popdef])[]dnl
|
||||
|
||||
// Perform the reduction.
|
||||
YY_REDUCE_PRINT (yyn);
|
||||
#if YY_EXCEPTIONS
|
||||
try
|
||||
#endif // YY_EXCEPTIONS
|
||||
{
|
||||
switch (yyn)
|
||||
{
|
||||
@@ -844,11 +861,13 @@ b4_dollar_popdef])[]dnl
|
||||
break;
|
||||
}
|
||||
}
|
||||
#if YY_EXCEPTIONS
|
||||
catch (const syntax_error& yyexc)
|
||||
{
|
||||
error (yyexc);
|
||||
YYERROR;
|
||||
}
|
||||
#endif // YY_EXCEPTIONS
|
||||
YY_SYMBOL_PRINT ("-> $$ =", yylhs);
|
||||
yypop_ (yylen);
|
||||
yylen = 0;
|
||||
@@ -973,6 +992,7 @@ b4_dollar_popdef])[]dnl
|
||||
|
||||
return yyresult;
|
||||
}
|
||||
#if YY_EXCEPTIONS
|
||||
catch (...)
|
||||
{
|
||||
YYCDEBUG << "Exception caught: cleaning lookahead and stack\n";
|
||||
@@ -988,6 +1008,7 @@ b4_dollar_popdef])[]dnl
|
||||
}
|
||||
throw;
|
||||
}
|
||||
#endif // YY_EXCEPTIONS
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -10885,13 +10885,12 @@ use @code{yy::parser::token::FOO}. The scanner can use
|
||||
|
||||
@defcv {Type} {parser} {syntax_error}
|
||||
This class derives from @code{std::runtime_error}. Throw instances of it
|
||||
from the scanner or from the user actions to raise parse errors. This is
|
||||
equivalent with first
|
||||
invoking @code{error} to report the location and message of the syntax
|
||||
error, and then to invoke @code{YYERROR} to enter the error-recovery mode.
|
||||
But contrary to @code{YYERROR} which can only be invoked from user actions
|
||||
(i.e., written in the action itself), the exception can be thrown from
|
||||
function invoked from the user action.
|
||||
from the scanner or from the actions to raise parse errors. This is
|
||||
equivalent with first invoking @code{error} to report the location and
|
||||
message of the syntax error, and then to invoke @code{YYERROR} to enter the
|
||||
error-recovery mode. But contrary to @code{YYERROR} which can only be
|
||||
invoked from user actions (i.e., written in the action itself), the
|
||||
exception can be thrown from function invoked from the user action.
|
||||
@end defcv
|
||||
|
||||
@deftypemethod {parser} {} parser (@var{type1} @var{arg1}, ...)
|
||||
@@ -10911,6 +10910,10 @@ Run the syntactic analysis, and return 0 on success, 1 otherwise.
|
||||
The whole function is wrapped in a @code{try}/@code{catch} block, so that
|
||||
when an exception is thrown, the @code{%destructor}s are called to release
|
||||
the lookahead symbol, and the symbols pushed on the stack.
|
||||
|
||||
Exception related code in the generated parser is protected by CPP guards
|
||||
(@code{#if}) and disabled when exceptions are not supported (i.e., passing
|
||||
@code{-fno-exceptions} to the C++ compiler).
|
||||
@end deftypemethod
|
||||
|
||||
@deftypemethod {parser} {std::ostream&} debug_stream ()
|
||||
|
||||
@@ -50,6 +50,9 @@ CXXFLAGS="$NO_WERROR_CXXFLAGS @WERROR_CXXFLAGS@"
|
||||
# If 'exit 77'; skip all C++ tests; otherwise ':'.
|
||||
BISON_CXX_WORKS='@BISON_CXX_WORKS@'
|
||||
|
||||
# Compiler flags to disable exception support.
|
||||
CXXFLAGS_NO_EXCEPTIONS='@CXXFLAGS_NO_EXCEPTIONS@'
|
||||
|
||||
# Be sure that the C++ compiler is not broken because of gnulib. This
|
||||
# cannot be checked in configure (gnulib is not parameterized yet),
|
||||
# and checking this in every C++ test in AC_COMPILE_CXX is too costly.
|
||||
|
||||
@@ -481,20 +481,20 @@ m4_define([AT_CHECK_SPACES],
|
||||
])
|
||||
|
||||
|
||||
# AT_CHECK_CALC([BISON-OPTIONS])
|
||||
# ------------------------------
|
||||
# AT_CHECK_CALC([BISON-OPTIONS], [COMPILER-OPTIONS])
|
||||
# --------------------------------------------------
|
||||
# Start a testing chunk which compiles 'calc' grammar with
|
||||
# BISON-OPTIONS, and performs several tests over the parser.
|
||||
m4_define([AT_CHECK_CALC],
|
||||
[m4_ifval([$2], [m4_fatal([$0: expected a single argument])])
|
||||
[m4_ifval([$3], [m4_fatal([$0: expected at most two arguments])])
|
||||
|
||||
# We use integers to avoid dependencies upon the precision of doubles.
|
||||
AT_SETUP([Calculator $1])
|
||||
AT_SETUP([Calculator $1 $2])
|
||||
|
||||
AT_BISON_OPTION_PUSHDEFS([$1])
|
||||
|
||||
AT_DATA_CALC_Y([$1])
|
||||
AT_FULL_COMPILE([calc], AT_DEFINES_IF([[lex], [main]]))
|
||||
AT_FULL_COMPILE([calc], AT_DEFINES_IF([[lex], [main]]), [], [$2])
|
||||
AT_CHECK_SPACES(m4_join([ ],
|
||||
[calc.AT_SKEL_CC_IF([cc], [c])],
|
||||
[AT_DEFINES_IF([calc.AT_SKEL_CC_IF([hh], [h])])]))
|
||||
@@ -677,10 +677,11 @@ AT_CHECK_CALC([%skeleton "lalr1.cc" %defines])
|
||||
# Start a testing chunk which compiles 'calc' grammar with
|
||||
# the C++ skeleton, and performs several tests over the parser.
|
||||
m4_define([AT_CHECK_CALC_LALR1_CC],
|
||||
[AT_CHECK_CALC([%language "C++"] $@)])
|
||||
[AT_CHECK_CALC([%language "C++" $1], [$2])])
|
||||
|
||||
AT_CHECK_CALC_LALR1_CC([])
|
||||
AT_CHECK_CALC_LALR1_CC([%locations])
|
||||
AT_CHECK_CALC_LALR1_CC([%locations], [$CXXFLAGS_NO_EXCEPTIONS])
|
||||
AT_CHECK_CALC_LALR1_CC([%locations %define api.location.type {Span}])
|
||||
AT_CHECK_CALC_LALR1_CC([%defines %locations %define parse.error verbose %name-prefix "calc" %verbose %yacc])
|
||||
|
||||
|
||||
@@ -740,8 +740,8 @@ m4_define([AT_QUELL_VALGRIND],
|
||||
## ------------------------ ##
|
||||
|
||||
|
||||
# AT_COMPILE(OUTPUT, [SOURCES = OUTPUT.c])
|
||||
# ----------------------------------------
|
||||
# AT_COMPILE(OUTPUT, [SOURCES = OUTPUT.c], [EXTRA-COMPILER-FLAGS])
|
||||
# ----------------------------------------------------------------
|
||||
# Compile SOURCES into OUTPUT.
|
||||
#
|
||||
# If OUTPUT does not contain '.', assume that we are linking too,
|
||||
@@ -758,8 +758,8 @@ AT_CHECK(m4_join([ ],
|
||||
0, [ignore], [ignore])])
|
||||
|
||||
|
||||
# AT_COMPILE_CXX(OUTPUT, [SOURCES = OUTPUT.cc])
|
||||
# ---------------------------------------------
|
||||
# AT_COMPILE_CXX(OUTPUT, [SOURCES = OUTPUT.cc], [EXTRA-COMPILER-FLAGS])
|
||||
# ---------------------------------------------------------------------
|
||||
# Compile SOURCES into OUTPUT. If the C++ compiler does not work,
|
||||
# ignore the test.
|
||||
#
|
||||
@@ -770,7 +770,7 @@ m4_define([AT_COMPILE_CXX],
|
||||
[AT_KEYWORDS(c++)
|
||||
AT_CHECK([$BISON_CXX_WORKS], 0, ignore, ignore)
|
||||
AT_CHECK(m4_join([ ],
|
||||
[$CXX $CXXFLAGS $CPPFLAGS],
|
||||
[$CXX $CXXFLAGS $CPPFLAGS $3],
|
||||
[m4_bmatch([$1], [[.]], [-c], [$LDFLAGS])],
|
||||
[-o $1],
|
||||
[m4_default([$2], [m4_bpatsubst([$1], [\.o$]).cc])],
|
||||
@@ -790,21 +790,21 @@ AT_CHECK([[$SHELL ../../../javacomp.sh ]$1],
|
||||
[[0]], [ignore], [ignore])])
|
||||
|
||||
|
||||
# AT_LANG_COMPILE(OUTPUT, [SOURCES = OUTPUT.c]
|
||||
# --------------------------------------------
|
||||
# AT_LANG_COMPILE(OUTPUT, [SOURCES = OUTPUT.c], [EXTRA-COMPILER-FLAGS])
|
||||
# ---------------------------------------------------------------------
|
||||
# Compile SOURCES into OUTPUT. Skip if compiler does not work.
|
||||
#
|
||||
# If OUTPUT does not contain '.', assume that we are linking too,
|
||||
# otherwise pass "-c"; this is a hack. The default SOURCES is OUTPUT
|
||||
# with trailing .o removed, and ".c"/".cc" appended.
|
||||
m4_define([AT_LANG_COMPILE], [AT_LANG_DISPATCH([$0], $@)])
|
||||
m4_define([AT_LANG_COMPILE(c)], [AT_COMPILE([$1], [$2])])
|
||||
m4_define([AT_LANG_COMPILE(c++)], [AT_COMPILE_CXX([$1], [$2])])
|
||||
m4_define([AT_LANG_COMPILE(java)], [AT_JAVA_COMPILE([$1.java], [$2])])
|
||||
m4_define([AT_LANG_COMPILE(c)], [AT_COMPILE([$1], [$2], [$3])])
|
||||
m4_define([AT_LANG_COMPILE(c++)], [AT_COMPILE_CXX([$1], [$2], [$3])])
|
||||
m4_define([AT_LANG_COMPILE(java)], [AT_JAVA_COMPILE([$1.java], [$2], [$3])])
|
||||
|
||||
|
||||
# AT_FULL_COMPILE(OUTPUT, [OTHER1], [OTHER2])
|
||||
# -------------------------------------------
|
||||
# AT_FULL_COMPILE(OUTPUT, [OTHER1], [OTHER2], [EXTRA-COMPILER-FLAGS)
|
||||
# ------------------------------------------------------------------
|
||||
# Compile OUTPUT.y to OUTPUT.c, OUTPUT.cc, or OUTPUT.java, and then
|
||||
# compile it to OUTPUT or OUTPUT.class. If OTHER is specified, compile
|
||||
# OUTPUT-OTHER.c, OUTPUT-OTHER.cc, or OUTPUT-OTHER.java to OUTPUT or
|
||||
@@ -817,7 +817,8 @@ m4_define([AT_FULL_COMPILE(c)],
|
||||
m4_join([ ],
|
||||
[$1.c],
|
||||
m4_ifval($2, [[$1-$2.c]]),
|
||||
m4_ifval($3, [[$1-$3.c]])))])
|
||||
m4_ifval($3, [[$1-$3.c]])),
|
||||
[$4])])
|
||||
|
||||
m4_define([AT_FULL_COMPILE(c++)],
|
||||
[AT_BISON_CHECK([-o $1.cc $1.y])
|
||||
@@ -825,7 +826,8 @@ m4_define([AT_FULL_COMPILE(c++)],
|
||||
m4_join([ ],
|
||||
[$1.cc],
|
||||
m4_ifval($2, [[$1-$2.cc]]),
|
||||
m4_ifval($3, [[$1-$3.cc]])))])
|
||||
m4_ifval($3, [[$1-$3.cc]])),
|
||||
[$4])])
|
||||
|
||||
m4_define([AT_FULL_COMPILE(java)],
|
||||
[AT_BISON_CHECK([-o $1.java $1.y])
|
||||
@@ -833,7 +835,8 @@ m4_define([AT_FULL_COMPILE(java)],
|
||||
m4_join([ ],
|
||||
[$1.java],
|
||||
m4_ifval($2, [[$1-$2.java]]),
|
||||
m4_ifval($3, [[$1-$3.java]])))])
|
||||
m4_ifval($3, [[$1-$3.java]])),
|
||||
[$4])])
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user