From c2cca4679515e2d24363d7252fcf1b8f09ccff11 Mon Sep 17 00:00:00 2001 From: Adrian Vogelsgesang Date: Thu, 20 Feb 2020 01:08:34 +0100 Subject: [PATCH] c++: add support for parse.error=custom * data/skeletons/lalr1.cc: added support here * tests/calc.at: added test cases * tests/local.at: added yyreport_syntax_error implementation for C++ test cases --- data/skeletons/lalr1.cc | 16 ++++++++++++---- tests/calc.at | 3 +++ tests/local.at | 29 +++++++++++++++++++++++++++-- 3 files changed, 42 insertions(+), 6 deletions(-) diff --git a/data/skeletons/lalr1.cc b/data/skeletons/lalr1.cc index 5928f72c..8896a95d 100644 --- a/data/skeletons/lalr1.cc +++ b/data/skeletons/lalr1.cc @@ -243,7 +243,7 @@ m4_define([b4_shared_declarations], , yyla (yyla) {} ]b4_locations_if([[ - const location_type& get_location () const { return yyla.location; } + const location_type& location () const { 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 @@ -279,6 +279,10 @@ m4_define([b4_shared_declarations], /// Generate an error message. /// \param yyctx the context in which the error occurred. virtual std::string yysyntax_error_ (const context& yyctx) const; +]])b4_parse_error_bmatch([custom], [[ + /// Report a syntax error + /// \param yyctx the context in which the error occurred. + void yyreport_syntax_error (const context& yyctx) const; ]])[ /// Compute post-reduction state. /// \param yystate the current state @@ -1071,11 +1075,15 @@ b4_dollar_popdef])[]dnl { ++yynerrs_;]b4_parse_error_case( [simple], [[ - std::string msg = YY_("syntax error");]], + std::string msg = YY_("syntax error"); + error (]b4_join(b4_locations_if([yyla.location]), [[YY_MOVE (msg)]])[);]], + [custom], [[ + context yyctx (*this, yyla); + yyreport_syntax_error (yyctx);]], [[ context yyctx (*this, yyla); - std::string msg = yysyntax_error_ (yyctx);]])[ - error (]b4_join(b4_locations_if([yyla.location]), [[YY_MOVE (msg)]])[); + std::string msg = yysyntax_error_ (yyctx); + error (]b4_join(b4_locations_if([yyla.location]), [[YY_MOVE (msg)]])[);]])[ } ]b4_locations_if([[ diff --git a/tests/calc.at b/tests/calc.at index 8b215c5b..401c5ffa 100644 --- a/tests/calc.at +++ b/tests/calc.at @@ -1138,6 +1138,9 @@ AT_CHECK_CALC_LALR1_CC([%no-lines %defines %locations %define api.location.file AT_CHECK_CALC_LALR1_CC([%locations %define parse.lac full %define parse.error verbose]) AT_CHECK_CALC_LALR1_CC([%locations %define parse.lac full %define parse.error detailed]) +AT_CHECK_CALC_LALR1_CC([%define parse.error custom]) +AT_CHECK_CALC_LALR1_CC([%define parse.error custom %locations %define api.prefix {calc} %parse-param {semantic_value *result}{int *count}{int *nerrs}]) +AT_CHECK_CALC_LALR1_CC([%define parse.error custom %locations %define api.prefix {calc} %parse-param {semantic_value *result}{int *count}{int *nerrs} %define parse.lac full]) # -------------------- # # GLR C++ Calculator. # diff --git a/tests/local.at b/tests/local.at index 0dffe4cc..d824e36c 100644 --- a/tests/local.at +++ b/tests/local.at @@ -733,10 +733,35 @@ void ++global_nerrs; ++*nerrs;]])[ std::cerr << ]AT_LOCATION_IF([l << ": " << ])[m << '\n'; -}]]) +}]AT_ERROR_CUSTOM_IF([[ +void +]AT_NAMESPACE[::parser::yyreport_syntax_error (const context& ctx) const +{ + /* Arguments of yyformat: reported tokens (one for the "unexpected", + one per "expected"). */ + int arg[yyntokens_]; + int n = ctx.yysyntax_error_arguments (arg, yyntokens_);]AT_PARAM_IF([m4_bpatsubst(m4_defn([AT_PARSE_PARAMS]), + [[^,]+[^A-Za-z_0-9]\([A-Za-z_][A-Za-z_0-9]*\),* *], [ + YYUSE (\1);])])[]m4_bmatch(m4_defn([AT_PARSE_PARAMS]), [nerrs],[[ + ++global_nerrs; + ++*nerrs;]])[ + if (n) + {]AT_LOCATION_IF([[ + std::cerr << ctx.location () << ": ";]])[ + std::cerr << "syntax error on token [" << yysymbol_name (arg[0]) << ']'; + if (1 < n) + { + std::cerr << " (expected:"; + for (int i = 1; i < n; ++i) + std::cerr << " [" << yysymbol_name (arg[i]) << ']'; + std::cerr << ')'; + } + std::cerr << '\n'; + } +}]])]) -# AT_YYERROR_DEFINE(c++)([INPUT], [ACTION]) +# AT_YYLEX_DEFINE(c++)([INPUT], [ACTION]) # ----------------------------------------- # Same as in C. m4_copy([AT_YYLEX_DEFINE(c)], [AT_YYLEX_DEFINE(c++)])