diff --git a/data/skeletons/yacc.c b/data/skeletons/yacc.c index f26d9b8e..d71d44e1 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); } ]])