From 90a8537e6287f92fb3d5be0258a69247a742f12e Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Sun, 30 Dec 2018 12:07:30 +0100 Subject: [PATCH] glr.cc: support syntax_error exceptions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. --- NEWS | 5 +++++ TODO | 10 ++++++++++ data/skeletons/glr.c | 41 +++++++++++++++++++++++++++++++++++++---- data/skeletons/glr.cc | 12 ++++++++++-- tests/c++.at | 1 + 5 files changed, 63 insertions(+), 6 deletions(-) diff --git a/NEWS b/NEWS index 49cc24c8..1e253c0f 100644 --- a/NEWS +++ b/NEWS @@ -147,6 +147,11 @@ GNU Bison NEWS 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 Bison specific directives are now reported with -y or -Wyacc. This diff --git a/TODO b/TODO index 342d2917..aa3c1c3b 100644 --- a/TODO +++ b/TODO @@ -7,6 +7,11 @@ Several features are not available in all the backends. - token constructors: Java and C * 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 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? * 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 Defined to 256, but not used, not documented. Probably the token number for the error token, which POSIX wants to be 256, but which diff --git a/data/skeletons/glr.c b/data/skeletons/glr.c index 868e96f0..4c97f806 100644 --- a/data/skeletons/glr.c +++ b/data/skeletons/glr.c @@ -23,6 +23,10 @@ m4_if(b4_skeleton, ["glr.c"], [m4_include(b4_skeletonsdir/[c.m4])]) +m4_define([b4_glr_cc_if], + [m4_if(b4_skeleton, ["glr.cc"], [$1], [$2])]) + + ## ---------------- ## ## Default values. ## ## ---------------- ## @@ -193,7 +197,7 @@ m4_if(b4_skeleton, ["glr.c"], # ----------------- # # glr.cc produces its own header. -m4_if(b4_skeleton, ["glr.c"], +b4_glr_cc_if([], [b4_defines_if( [b4_output_begin([b4_spec_defines_file]) 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 [ if (*yycharp == YYEMPTY) { - YYDPRINTF ((stderr, "Reading a token: ")); - *yycharp = ]b4_lex[; + YYDPRINTF ((stderr, "Reading a token: "));]b4_glr_cc_if([[ +#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) { @@ -842,12 +861,26 @@ yyuserAction (yyRuleNum yyn, int yyrhslen, yyGLRStackItem* yyvsp, /* Default location. */ YYLLOC_DEFAULT ((*yylocp), (yyvsp - yyrhslen), yyrhslen); 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) { ]b4_user_actions[ 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; # undef yyerrok diff --git a/data/skeletons/glr.cc b/data/skeletons/glr.cc index c9c4acda..b5b0dba2 100644 --- a/data/skeletons/glr.cc +++ b/data/skeletons/glr.cc @@ -163,8 +163,7 @@ m4_pushdef([b4_parse_param], m4_defn([b4_parse_param_orig]))dnl } ]b4_parser_class_name::~b4_parser_class_name[ () - { - } + {} int ]b4_parser_class_name[::operator() () @@ -257,6 +256,15 @@ b4_percent_code_get([[requires]])[ ]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_namespace_open[ diff --git a/tests/c++.at b/tests/c++.at index 4dd39bc7..c2b892bc 100644 --- a/tests/c++.at +++ b/tests/c++.at @@ -1020,6 +1020,7 @@ AT_CLEANUP ]) AT_TEST([%skeleton "lalr1.cc"]) +AT_TEST([%skeleton "glr.cc"]) m4_popdef([AT_TEST])