glr.cc: support syntax_error exceptions

Kindly requested by Аскар Сафин (Askar Safin).
http://lists.gnu.org/archive/html/bug-bison/2018-12/msg00033.html

* data/skeletons/glr.c (b4_glr_cc_if): New.
Use it.
(yygetToken): Catch syntax_errors.
* data/skeletons/glr.cc (YY_EXCEPTIONS): New.
* tests/c++.at: Check it.
This commit is contained in:
Akim Demaille
2018-12-30 12:07:30 +01:00
parent 6653c912da
commit 90a8537e62
5 changed files with 63 additions and 6 deletions

5
NEWS
View File

@@ -147,6 +147,11 @@ GNU Bison NEWS
return parser::token::PAIR; return parser::token::PAIR;
} }
*** C++: Syntax error exceptions in GLR
The glr.cc skeleton now supports syntax_error exceptions thrown from user
actions, or from the scanner.
*** More POSIX Yacc compatibility warnings *** More POSIX Yacc compatibility warnings
More Bison specific directives are now reported with -y or -Wyacc. This More Bison specific directives are now reported with -y or -Wyacc. This

10
TODO
View File

@@ -7,6 +7,11 @@ Several features are not available in all the backends.
- token constructors: Java and C - token constructors: Java and C
* Short term * Short term
** glr.c: too many definitions of YYLLOC_DEFAULT
See test 241.
241. headers.at:187: testing Sane headers: %locations c++ %glr-parser ...
** consistency ** consistency
token vs terminal token vs terminal
@@ -108,6 +113,11 @@ since it is no longer bound to a particular parser, it's just a
as lr0.cc, why upper case? as lr0.cc, why upper case?
* Various * Various
** Rewrite glr.cc in C++
As a matter of fact, it would be very interesting to see how much we can
share between lalr1.cc and glr.cc. Most of the skeletons should be common.
It would be a very nice source of inspiration for the other languages.
** YYERRCODE ** YYERRCODE
Defined to 256, but not used, not documented. Probably the token Defined to 256, but not used, not documented. Probably the token
number for the error token, which POSIX wants to be 256, but which number for the error token, which POSIX wants to be 256, but which

View File

@@ -23,6 +23,10 @@
m4_if(b4_skeleton, ["glr.c"], m4_if(b4_skeleton, ["glr.c"],
[m4_include(b4_skeletonsdir/[c.m4])]) [m4_include(b4_skeletonsdir/[c.m4])])
m4_define([b4_glr_cc_if],
[m4_if(b4_skeleton, ["glr.cc"], [$1], [$2])])
## ---------------- ## ## ---------------- ##
## Default values. ## ## Default values. ##
## ---------------- ## ## ---------------- ##
@@ -193,7 +197,7 @@ m4_if(b4_skeleton, ["glr.c"],
# ----------------- # # ----------------- #
# glr.cc produces its own header. # glr.cc produces its own header.
m4_if(b4_skeleton, ["glr.c"], b4_glr_cc_if([],
[b4_defines_if( [b4_defines_if(
[b4_output_begin([b4_spec_defines_file]) [b4_output_begin([b4_spec_defines_file])
b4_copyright([Skeleton interface for Bison GLR parsers in C], b4_copyright([Skeleton interface for Bison GLR parsers in C],
@@ -769,8 +773,23 @@ yygetToken (int *yycharp][]b4_pure_if([, yyGLRStack* yystackp])[]b4_user_formals
]b4_parse_param_use()dnl ]b4_parse_param_use()dnl
[ if (*yycharp == YYEMPTY) [ if (*yycharp == YYEMPTY)
{ {
YYDPRINTF ((stderr, "Reading a token: ")); YYDPRINTF ((stderr, "Reading a token: "));]b4_glr_cc_if([[
*yycharp = ]b4_lex[; #if YY_EXCEPTIONS
try
{
#endif // YY_EXCEPTIONS
*yycharp = ]b4_lex[;
#if YY_EXCEPTIONS
}
catch (const ]b4_namespace_ref[::]b4_parser_class_name[::syntax_error& yyexc)
{]b4_locations_if([
yylloc = yyexc.location;])[
yyerror (]b4_lyyerror_args[yyexc.what ());
// Map to the undef token.
*yycharp = YYMAXUTOK + 1;
}
#endif // YY_EXCEPTIONS]], [[
*yycharp = ]b4_lex[;]])[
} }
if (*yycharp <= YYEOF) if (*yycharp <= YYEOF)
{ {
@@ -842,12 +861,26 @@ yyuserAction (yyRuleNum yyn, int yyrhslen, yyGLRStackItem* yyvsp,
/* Default location. */ /* Default location. */
YYLLOC_DEFAULT ((*yylocp), (yyvsp - yyrhslen), yyrhslen); YYLLOC_DEFAULT ((*yylocp), (yyvsp - yyrhslen), yyrhslen);
yystackp->yyerror_range[1].yystate.yyloc = *yylocp; yystackp->yyerror_range[1].yystate.yyloc = *yylocp;
]])[ ]])[]b4_glr_cc_if([[
#if YY_EXCEPTIONS
typedef ]b4_namespace_ref[::]b4_parser_class_name[::syntax_error syntax_error;
try
{
#endif // YY_EXCEPTIONS]])[
switch (yyn) switch (yyn)
{ {
]b4_user_actions[ ]b4_user_actions[
default: break; default: break;
}]b4_glr_cc_if([[
#if YY_EXCEPTIONS
}
catch (const syntax_error& yyexc)
{]b4_locations_if([
*yylocp = yyexc.location;])[
yyerror (]b4_yyerror_args[yyexc.what ());
YYERROR;
} }
#endif // YY_EXCEPTIONS]])[
return yyok; return yyok;
# undef yyerrok # undef yyerrok

View File

@@ -163,8 +163,7 @@ m4_pushdef([b4_parse_param], m4_defn([b4_parse_param_orig]))dnl
} }
]b4_parser_class_name::~b4_parser_class_name[ () ]b4_parser_class_name::~b4_parser_class_name[ ()
{ {}
}
int int
]b4_parser_class_name[::operator() () ]b4_parser_class_name[::operator() ()
@@ -257,6 +256,15 @@ b4_percent_code_get([[requires]])[
]b4_null_define[ ]b4_null_define[
// 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_YYDEBUG_define[ ]b4_YYDEBUG_define[
]b4_namespace_open[ ]b4_namespace_open[

View File

@@ -1020,6 +1020,7 @@ AT_CLEANUP
]) ])
AT_TEST([%skeleton "lalr1.cc"]) AT_TEST([%skeleton "lalr1.cc"])
AT_TEST([%skeleton "glr.cc"])
m4_popdef([AT_TEST]) m4_popdef([AT_TEST])