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
This commit is contained in:
Adrian Vogelsgesang
2020-02-20 01:08:34 +01:00
committed by Akim Demaille
parent 879530cb95
commit c2cca46795
3 changed files with 42 additions and 6 deletions

View File

@@ -243,7 +243,7 @@ m4_define([b4_shared_declarations],
, yyla (yyla) , yyla (yyla)
{} {}
]b4_locations_if([[ ]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 /* 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 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. /// Generate an error message.
/// \param yyctx the context in which the error occurred. /// \param yyctx the context in which the error occurred.
virtual std::string yysyntax_error_ (const context& yyctx) const; 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. /// Compute post-reduction state.
/// \param yystate the current state /// \param yystate the current state
@@ -1071,11 +1075,15 @@ b4_dollar_popdef])[]dnl
{ {
++yynerrs_;]b4_parse_error_case( ++yynerrs_;]b4_parse_error_case(
[simple], [[ [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); context yyctx (*this, yyla);
std::string msg = yysyntax_error_ (yyctx);]])[ std::string msg = yysyntax_error_ (yyctx);
error (]b4_join(b4_locations_if([yyla.location]), [[YY_MOVE (msg)]])[); error (]b4_join(b4_locations_if([yyla.location]), [[YY_MOVE (msg)]])[);]])[
} }
]b4_locations_if([[ ]b4_locations_if([[

View File

@@ -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 verbose])
AT_CHECK_CALC_LALR1_CC([%locations %define parse.lac full %define parse.error detailed]) 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. # # GLR C++ Calculator. #

View File

@@ -733,10 +733,35 @@ void
++global_nerrs; ++global_nerrs;
++*nerrs;]])[ ++*nerrs;]])[
std::cerr << ]AT_LOCATION_IF([l << ": " << ])[m << '\n'; 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. # Same as in C.
m4_copy([AT_YYLEX_DEFINE(c)], [AT_YYLEX_DEFINE(c++)]) m4_copy([AT_YYLEX_DEFINE(c)], [AT_YYLEX_DEFINE(c++)])