[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH 11/12] yacc.c: pass the parse-params to yyreport_syntax_error
From: |
Akim Demaille |
Subject: |
[PATCH 11/12] yacc.c: pass the parse-params to yyreport_syntax_error |
Date: |
Thu, 16 Jan 2020 07:58:22 +0100 |
Enhance the calculator tests: show that passing arguments to yyerror
works.
* tests/calc.at: Add a new parse-param, nerrs, which counts the number
of syntax errors in a run.
* tests/local.at: Adjust to handle the new 'nerrs' argument, when
present.
The custom error reporting function show sees the user's additional
arguments. Let's experiment with passing them as arguments to
yyreport_syntax_error, but maybe storing them in the context would be
a bettter alternative.
* data/skeletons/yacc.c (yyreport_syntax_error): Handle the
parse-params.
* tests/calc.at, tests/local.at: Adjust.
---
data/skeletons/yacc.c | 8 ++++--
tests/calc.at | 65 +++++++++++++++++++++++--------------------
tests/local.at | 32 ++++++++++++++-------
3 files changed, 62 insertions(+), 43 deletions(-)
diff --git a/data/skeletons/yacc.c b/data/skeletons/yacc.c
index b6485258..f3353b4a 100644
--- a/data/skeletons/yacc.c
+++ b/data/skeletons/yacc.c
@@ -1174,8 +1174,9 @@ yyparse_context_location (const yyparse_context_t *yyctx)
}]])[
/* User defined funtion to report a syntax error. */
-static int
-yyreport_syntax_error (const yyparse_context_t *yyctx);]],
+]b4_function_declare([yyreport_syntax_error], [static int],
+ [[[const yyparse_context_t *yyctx]], [[yyctx]]],
+ b4_parse_param)],
[verbose],
[[# ifndef yystrlen
# if defined __GLIBC__ && defined _STRING_H
@@ -1832,7 +1833,8 @@ yyerrlab:
= {yyssp, yytoken]b4_locations_if([[, &yylloc]])[]b4_lac_if([[,
yyesa, &yyes, &yyes_capacity]])[};]b4_lac_if([[
if (yychar != YYEMPTY)
YY_LAC_ESTABLISH;]])[
- if (yyreport_syntax_error (&yyctx) == 2)
+ if (yyreport_syntax_error (&yyctx]m4_ifset([b4_parse_param],
+ [[, ]b4_args(b4_parse_param)])[) == 2)
goto yyexhaustedlab;
}]],
[simple],
diff --git a/tests/calc.at b/tests/calc.at
index 01eef065..58526d99 100644
--- a/tests/calc.at
+++ b/tests/calc.at
@@ -34,9 +34,9 @@ namespace
{
/* A C++ ]AT_NAME_PREFIX[parse that simulates the C signature. */
int
- ]AT_NAME_PREFIX[parse (]AT_PARAM_IF([semantic_value *result, int *count]))[
+ ]AT_NAME_PREFIX[parse (]AT_PARAM_IF([semantic_value *result, int *count, int
*nerrs]))[
{
- ]AT_NAME_PREFIX[::parser parser]AT_PARAM_IF([ (result, count)])[;
+ ]AT_NAME_PREFIX[::parser parser]AT_PARAM_IF([ (result, count, nerrs)])[;
#if ]AT_API_PREFIX[DEBUG
parser.set_debug_level (1);
#endif
@@ -49,13 +49,16 @@ namespace
semantic_value global_result = 0;
/* Total number of computations. */
int global_count = 0;
+/* Total number of errors. */
+int global_nerrs = 0;
/* A C main function. */
int
main (int argc, const char **argv)
{]AT_PARAM_IF([[
semantic_value result = 0;
- int count = 0;]])[
+ int count = 0;
+ int nerrs = 0;]])[
int status;
/* This used to be alarm (10), but that isn't enough time for a July
@@ -77,12 +80,13 @@ main (int argc, const char **argv)
}
]AT_CXX_IF([], [AT_DEBUG_IF([ ]AT_NAME_PREFIX[debug = 1;])])[
- status = ]AT_NAME_PREFIX[parse (]AT_PARAM_IF([[&result, &count]])[);
+ status = ]AT_NAME_PREFIX[parse (]AT_PARAM_IF([[&result, &count, &nerrs]])[);
if (fclose (input))
perror ("fclose");]AT_PARAM_IF([[
assert (global_result == result); (void) result;
assert (global_count == count); (void) count;
- printf ("final: %d %d\n", global_result, global_count);]])[
+ assert (global_nerrs == nerrs); (void) nerrs;
+ printf ("final: %d %d %d\n", global_result, global_count, global_nerrs);]])[
return status;
}
]])
@@ -399,6 +403,7 @@ void location_print (FILE *o, Span s);
extern FILE *input;
extern semantic_value global_result;
extern int global_count;
+ extern int global_nerrs;
}
%code
@@ -682,35 +687,35 @@ _AT_CHECK_CALC([$1],
2^2^3 = 256
(2^2)^3 = 64],
-[[final: 64 12]],
+[[final: 64 12 0]],
[AT_PUSH_IF([930], [846])])
# Some syntax errors.
_AT_CHECK_CALC_ERROR([$1], [1], [1 2],
- [[final: 0 0]],
+ [[final: 0 0 1]],
[15],
[[1.3: syntax error on token ["number"] (expected: ['=']
['-'] ['+'] ['*'] ['/'] ['^'] ['\n'])]])
_AT_CHECK_CALC_ERROR([$1], [1], [1//2],
- [[final: 0 0]],
+ [[final: 0 0 1]],
[20],
[[1.3: syntax error on token ['/'] (expected: ["number"]
['-'] ['('] ['!'])]])
_AT_CHECK_CALC_ERROR([$1], [1], [error],
- [[final: 0 0]],
+ [[final: 0 0 1]],
[5],
[[1.1: syntax error on token [$undefined] (expected:
["number"] ['-'] ['\n'] ['('] ['!'])]])
_AT_CHECK_CALC_ERROR([$1], [1], [1 = 2 = 3],
- [[final: 0 0]],
+ [[final: 0 0 1]],
[30],
[[1.7: syntax error on token ['='] (expected: ['-'] ['+']
['*'] ['/'] ['^'])]])
_AT_CHECK_CALC_ERROR([$1], [1],
[
+1],
- [[final: 0 0]],
+ [[final: 0 0 1]],
[20],
[[2.1: syntax error on token ['+'] (expected: ["end of
input"] ["number"] ['-'] ['\n'] ['('] ['!'])]])
# Exercise error messages with EOF: work on an empty file.
_AT_CHECK_CALC_ERROR([$1], [1], [/dev/null],
- [[final: 0 0]],
+ [[final: 0 0 1]],
[4],
[[1.1: syntax error on token ["end of input"] (expected:
["number"] ['-'] ['\n'] ['('] ['!'])]])
@@ -732,7 +737,7 @@ _AT_CHECK_CALC_ERROR([$1], [1], [/dev/null],
#
_AT_CHECK_CALC_ERROR([$1], [0],
[() + (1 + 1 + 1 +) + (* * *) + (1 * 2 * *) = 1],
- [[final: 4444 0]],
+ [[final: 4444 0 4]],
[250],
[[1.2: syntax error on token [')'] (expected: ["number"] ['-'] ['('] ['!'])
1.18: syntax error on token [')'] (expected: ["number"] ['-'] ['('] ['!'])
@@ -743,12 +748,12 @@ calc: error: 4444 != 1]])
# The same, but this time exercising explicitly triggered syntax errors.
# POSIX says the lookahead causing the error should not be discarded.
_AT_CHECK_CALC_ERROR([$1], [0], [(!) + (1 2) = 1],
- [[final: 2222 0]],
+ [[final: 2222 0 1]],
[102],
[[1.10: syntax error on token ["number"] (expected: ['='] ['-'] ['+'] ['*']
['/'] ['^'] [')'])
calc: error: 2222 != 1]])
_AT_CHECK_CALC_ERROR([$1], [0], [(- *) + (1 2) = 1],
- [[final: 2222 0]],
+ [[final: 2222 0 2]],
[113],
[[1.4: syntax error on token ['*'] (expected: ["number"] ['-'] ['('] ['!'])
1.12: syntax error on token ["number"] (expected: ['='] ['-'] ['+'] ['*']
['/'] ['^'] [')'])
@@ -757,7 +762,7 @@ calc: error: 2222 != 1]])
# Check that yyerrok works properly: second error is not reported,
# third and fourth are. Parse status is succesful.
_AT_CHECK_CALC_ERROR([$1], [0], [(* *) + (*) + (*)],
- [[final: 3333 0]],
+ [[final: 3333 0 3]],
[113],
[[1.2: syntax error on token ['*'] (expected: ["number"] ['-'] ['('] ['!'])
1.10: syntax error on token ['*'] (expected: ["number"] ['-'] ['('] ['!'])
@@ -809,14 +814,14 @@ AT_CHECK_CALC_LALR([%define parse.error verbose %debug
%locations %defines %defi
AT_CHECK_CALC_LALR([%define api.pure full %define parse.error verbose %debug
%locations %defines %name-prefix "calc" %verbose %yacc])
AT_CHECK_CALC_LALR([%define api.push-pull both %define api.pure full %define
parse.error verbose %debug %locations %defines %define api.prefix {calc}
%verbose %yacc])
-AT_CHECK_CALC_LALR([%define api.pure %define parse.error verbose %debug
%locations %defines %define api.prefix {calc} %verbose %yacc %parse-param
{semantic_value *result}{int *count}])
+AT_CHECK_CALC_LALR([%define api.pure %define parse.error verbose %debug
%locations %defines %define api.prefix {calc} %verbose %yacc %parse-param
{semantic_value *result}{int *count}{int *nerrs}])
-AT_CHECK_CALC_LALR([%no-lines %define api.pure %define parse.error verbose
%debug %locations %defines %define api.prefix {calc} %verbose %yacc
%parse-param {semantic_value *result}{int *count}])
+AT_CHECK_CALC_LALR([%no-lines %define api.pure %define parse.error verbose
%debug %locations %defines %define api.prefix {calc} %verbose %yacc
%parse-param {semantic_value *result}{int *count}{int *nerrs}])
AT_CHECK_CALC_LALR([%define parse.error custom])
AT_CHECK_CALC_LALR([%define parse.error custom %locations %define api.prefix
{calc}])
-AT_CHECK_CALC_LALR([%define parse.error custom %locations %define api.prefix
{calc} %parse-param {semantic_value *result}{int *count}])
+AT_CHECK_CALC_LALR([%define parse.error custom %locations %define api.prefix
{calc} %parse-param {semantic_value *result}{int *count}{int *nerrs}])
# ----------------------- #
# Simple GLR Calculator. #
@@ -854,10 +859,10 @@ AT_CHECK_CALC_GLR([%define parse.error verbose %debug
%locations %defines %defin
AT_CHECK_CALC_GLR([%define api.pure %define parse.error verbose %debug
%locations %defines %name-prefix "calc" %verbose %yacc])
-AT_CHECK_CALC_GLR([%define api.pure %define parse.error verbose %debug
%locations %defines %name-prefix "calc" %verbose %yacc %parse-param
{semantic_value *result}{int *count}])
-AT_CHECK_CALC_GLR([%define api.pure %define parse.error verbose %debug
%locations %defines %define api.prefix {calc} %verbose %yacc %parse-param
{semantic_value *result}{int *count}])
+AT_CHECK_CALC_GLR([%define api.pure %define parse.error verbose %debug
%locations %defines %name-prefix "calc" %verbose %yacc %parse-param
{semantic_value *result}{int *count}{int *nerrs}])
+AT_CHECK_CALC_GLR([%define api.pure %define parse.error verbose %debug
%locations %defines %define api.prefix {calc} %verbose %yacc %parse-param
{semantic_value *result}{int *count}{int *nerrs}])
-AT_CHECK_CALC_GLR([%no-lines %define api.pure %define parse.error verbose
%debug %locations %defines %define api.prefix {calc} %verbose %yacc
%parse-param {semantic_value *result}{int *count}])
+AT_CHECK_CALC_GLR([%no-lines %define api.pure %define parse.error verbose
%debug %locations %defines %define api.prefix {calc} %verbose %yacc
%parse-param {semantic_value *result}{int *count}{int *nerrs}])
# ----------------------------- #
@@ -888,10 +893,10 @@ AT_CHECK_CALC_LALR1_CC([%locations %define parse.error
verbose %debug %name-pref
AT_CHECK_CALC_LALR1_CC([%locations %define parse.error verbose %debug %define
api.prefix {calc} %verbose %yacc])
AT_CHECK_CALC_LALR1_CC([%locations %define parse.error verbose %debug %define
api.prefix {calc} %define api.token.prefix {TOK_} %verbose %yacc])
-AT_CHECK_CALC_LALR1_CC([%defines %locations %define parse.error verbose %debug
%name-prefix "calc" %verbose %yacc %parse-param {semantic_value *result}{int
*count}])
+AT_CHECK_CALC_LALR1_CC([%defines %locations %define parse.error verbose %debug
%name-prefix "calc" %verbose %yacc %parse-param {semantic_value *result}{int
*count}{int *nerrs}])
-AT_CHECK_CALC_LALR1_CC([%define parse.error verbose %debug %define api.prefix
{calc} %verbose %yacc %parse-param {semantic_value *result}{int *count}])
-AT_CHECK_CALC_LALR1_CC([%defines %locations %define parse.error verbose %debug
%define api.prefix {calc} %verbose %yacc %parse-param {semantic_value
*result}{int *count}])
+AT_CHECK_CALC_LALR1_CC([%define parse.error verbose %debug %define api.prefix
{calc} %verbose %yacc %parse-param {semantic_value *result}{int *count}{int
*nerrs}])
+AT_CHECK_CALC_LALR1_CC([%defines %locations %define parse.error verbose %debug
%define api.prefix {calc} %verbose %yacc %parse-param {semantic_value
*result}{int *count}{int *nerrs}])
AT_CHECK_CALC_LALR1_CC([%defines %locations %define api.location.file none])
AT_CHECK_CALC_LALR1_CC([%defines %locations %define api.location.file
"my-location.hh"])
@@ -926,10 +931,10 @@ AT_CHECK_CALC_GLR_CC([%debug])
AT_CHECK_CALC_GLR_CC([%define parse.error verbose %debug %name-prefix "calc"
%verbose %yacc])
AT_CHECK_CALC_GLR_CC([%define parse.error verbose %debug %name-prefix "calc"
%define api.token.prefix {TOK_} %verbose %yacc])
-AT_CHECK_CALC_GLR_CC([%locations %defines %define parse.error verbose %debug
%name-prefix "calc" %verbose %yacc %parse-param {semantic_value *result}{int
*count}])
-AT_CHECK_CALC_GLR_CC([%locations %defines %define parse.error verbose %debug
%define api.prefix {calc} %verbose %yacc %parse-param {semantic_value
*result}{int *count}])
+AT_CHECK_CALC_GLR_CC([%locations %defines %define parse.error verbose %debug
%name-prefix "calc" %verbose %yacc %parse-param {semantic_value *result}{int
*count}{int *nerrs}])
+AT_CHECK_CALC_GLR_CC([%locations %defines %define parse.error verbose %debug
%define api.prefix {calc} %verbose %yacc %parse-param {semantic_value
*result}{int *count}{int *nerrs}])
-AT_CHECK_CALC_GLR_CC([%no-lines %locations %defines %define parse.error
verbose %debug %define api.prefix {calc} %verbose %yacc %parse-param
{semantic_value *result}{int *count}])
+AT_CHECK_CALC_GLR_CC([%no-lines %locations %defines %define parse.error
verbose %debug %define api.prefix {calc} %verbose %yacc %parse-param
{semantic_value *result}{int *count}{int *nerrs}])
# --------------------------- #
@@ -958,8 +963,8 @@ AT_CHECK_CALC_LALR1_D([%debug])
AT_CHECK_CALC_LALR1_D([%define parse.error verbose %debug %verbose])
#AT_CHECK_CALC_LALR1_D([%define parse.error verbose %debug %define
api.token.prefix {TOK_} %verbose])
-#AT_CHECK_CALC_LALR1_D([%locations %define parse.error verbose %debug %verbose
%parse-param {semantic_value *result}{int *count}])
-#AT_CHECK_CALC_LALR1_D([%locations %define parse.error verbose %debug %define
api.prefix {calc} %verbose %parse-param {semantic_value *result}{int *count}])
+#AT_CHECK_CALC_LALR1_D([%locations %define parse.error verbose %debug %verbose
%parse-param {semantic_value *result}{int *count}{int *nerrs}])
+#AT_CHECK_CALC_LALR1_D([%locations %define parse.error verbose %debug %define
api.prefix {calc} %verbose %parse-param {semantic_value *result}{int
*count}{int *nerrs}])
m4_popdef([AT_CALC_MAIN])
m4_popdef([AT_CALC_YYLEX])
diff --git a/tests/local.at b/tests/local.at
index e314b8bf..30062a2e 100644
--- a/tests/local.at
+++ b/tests/local.at
@@ -610,12 +610,16 @@ location_print (FILE *yyo, ]AT_YYLTYPE[ const * const
yylocp)
]AT_ERROR_CUSTOM_IF([[
int
-yyreport_syntax_error (const yyparse_context_t *ctx)
+yyreport_syntax_error (const yyparse_context_t *ctx]AT_PARAM_IF([,
AT_PARSE_PARAMS])[)
{
/* Arguments of yyformat: reported tokens (one for the "unexpected",
one per "expected"). */
int arg[YYNTOKENS];
- int n = yysyntax_error_arguments (ctx, arg, sizeof arg / sizeof *arg);
+ int n = yysyntax_error_arguments (ctx, arg, sizeof arg / sizeof
*arg);]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 == -2)
return 2;
if (n)
@@ -645,7 +649,9 @@ static
AT_YYERROR_SEES_LOC_IF([[
LOCATION_PRINT (stderr, ]AT_LOC[);
fprintf (stderr, ": ");]])[
- fprintf (stderr, "%s\n", msg);
+ fprintf (stderr, "%s\n", msg);]m4_bmatch(m4_defn([AT_PARSE_PARAMS]),
[nerrs],[[
+ ++global_nerrs;
+ ++*nerrs;]])[
}]])])
@@ -711,7 +717,9 @@ m4_define([AT_YYERROR_DEFINE(c++)],
[[/* A C++ error reporting function. */
void
]AT_NAMESPACE[::parser::error (]AT_LOCATION_IF([[const location_type& l,
]])[const std::string& m)
-{
+{]m4_bmatch(m4_defn([AT_PARSE_PARAMS]), [nerrs],[[
+ ++global_nerrs;
+ ++*nerrs;]])[
std::cerr << ]AT_LOCATION_IF([l << ": " << ])[m << '\n';
}]])
@@ -848,15 +856,19 @@ m4_define([AT_JAVA_POSITION_DEFINE],
m4_define([AT_YYERROR_DEFINE(java)],
[AT_LOCATION_IF([[public void yyerror (Calc.Location l, String m)
-{
- if (l == null)
- System.err.println (m);
- else
- System.err.println (l + ": " + m);
+ {]m4_bmatch(m4_defn([AT_PARSE_PARAMS]), [nerrs],[[
+ ++global_nerrs;
+ ++*nerrs;]])[
+ if (l == null)
+ System.err.println (m);
+ else
+ System.err.println (l + ": " + m);
}
]], [[
public void yyerror (String m)
- {
+ {]m4_bmatch(m4_defn([AT_PARSE_PARAMS]), [nerrs],[[
+ ++global_nerrs;
+ ++*nerrs;]])[
System.err.println (m);
}
]])
--
2.24.1
- [PATCH 03/12] yacc.c: style: avoid macros, (continued)
- [PATCH 03/12] yacc.c: style: avoid macros, Akim Demaille, 2020/01/16
- [PATCH 01/12] yacc.c: extract yyerror_message_arguments, Akim Demaille, 2020/01/16
- [PATCH 04/12] yacc.c: add custom error message generation, Akim Demaille, 2020/01/16
- [PATCH 06/12] tests: compute verbose error messages from the custom ones, Akim Demaille, 2020/01/16
- [PATCH 05/12] yacc.c: check custom error messages, Akim Demaille, 2020/01/16
- [PATCH 07/12] yacc.c: isolate yyexpected_tokens, Akim Demaille, 2020/01/16
- [PATCH 08/12] yacc.c: let custom error messages see the location, Akim Demaille, 2020/01/16
- [PATCH 09/12] yacc.c: check custom error messages with parse-params, Akim Demaille, 2020/01/16
- [PATCH 10/12] tests: a clearer test for parse-params, Akim Demaille, 2020/01/16
- [PATCH 12/12] yacc.c: portability to G++ 4.8, Akim Demaille, 2020/01/16
- [PATCH 11/12] yacc.c: pass the parse-params to yyreport_syntax_error,
Akim Demaille <=
- Re: RFC: custom error messages, Christian Schoenebeck, 2020/01/16
- Re: RFC: custom error messages, Akim Demaille, 2020/01/17
- Re: RFC: custom error messages, Christian Schoenebeck, 2020/01/18
Re: RFC: custom error messages, Rici Lake, 2020/01/06
Re: RFC: custom error messages, Adrian Vogelsgesang, 2020/01/08