bison-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 05/12] yacc.c: check custom error messages


From: Akim Demaille
Subject: [PATCH 05/12] yacc.c: check custom error messages
Date: Thu, 16 Jan 2020 07:58:16 +0100

* tests/local.at (AT_ERROR_CUSTOM_IF, AT_ERROR_VERBOSE_IF)
(AT_ERROR_SIMPLE_IF): New.
(AT_YYERROR_DEFINE(c)): Generate yyreport_syntax_error.
* tests/calc.at (_AT_CHECK_CALC_ERROR): Accept custom error messages
as additional test case.
Use it.
Add a new test case for %define parse.error custom.
---
 tests/calc.at      | 68 ++++++++++++++++++++++++++++++++--------------
 tests/local.at     | 50 +++++++++++++++++++++++++++++-----
 tests/testsuite.at |  2 +-
 3 files changed, 92 insertions(+), 28 deletions(-)

diff --git a/tests/calc.at b/tests/calc.at
index 4af06afc..06a74bc3 100644
--- a/tests/calc.at
+++ b/tests/calc.at
@@ -545,10 +545,11 @@ AT_PARSER_CHECK([calc input], 0, [], [stderr])
 ])
 
 
-# _AT_CHECK_CALC_ERROR(BISON-OPTIONS, EXIT-STATUS, INPUT,
-#                      [NUM-STDERR-LINES],
-#                      [VERBOSE-AND-LOCATED-ERROR-MESSAGE])
-# ---------------------------------------------------------
+# _AT_CHECK_CALC_ERROR($1 = BISON-OPTIONS, $2 = EXIT-STATUS, $3 = INPUT,
+#                      $4 = [NUM-STDERR-LINES],
+#                      $5 = [VERBOSE-AND-LOCATED-ERROR-MESSAGE]
+#                      $6 = [CUSTOM-ERROR-MESSAGE])
+# ----------------------------------------------------------------------
 # Run 'calc' on INPUT, and expect a 'syntax error' message.
 #
 # If INPUT starts with a slash, it is used as absolute input file name,
@@ -595,9 +596,15 @@ sed '/^Starting/d
 mv at-stderr stderr
 
 # 2. Create the reference error message.
-AT_DATA([[expout]],
+AT_ERROR_CUSTOM_IF([
+  AT_DATA([[expout]],
+[$6
+])
+],
+  [AT_DATA([[expout]],
 [$5
 ])
+])
 
 # 3. If locations are not used, remove them.
 AT_YYERROR_SEES_LOC_IF([],
@@ -605,7 +612,7 @@ AT_YYERROR_SEES_LOC_IF([],
 mv at-expout expout]])
 
 # 4. If error-verbose is not used, strip the', unexpected....' part.
-m4_bmatch([$1], [%define parse.error verbose], [],
+AT_ERROR_SIMPLE_IF(
 [[sed 's/syntax error, .*$/syntax error/' expout >at-expout
 mv at-expout expout]])
 
@@ -668,21 +675,27 @@ _AT_CHECK_CALC([$1],
 
 # Some syntax errors.
 _AT_CHECK_CALC_ERROR([$1], [1], [1 2], [15],
-                     [1.3: syntax error, unexpected number])
+                     [[1.3: syntax error, unexpected number]],
+                     [[1.3: syntax error on token ["number"] (expected: ['='] 
['-'] ['+'] ['*'] ['/'] ['^'] ['\n'])]])
 _AT_CHECK_CALC_ERROR([$1], [1], [1//2], [20],
-                     [1.3: syntax error, unexpected '/', expecting number or 
'-' or '(' or '!'])
+                     [[1.3: syntax error, unexpected '/', expecting number or 
'-' or '(' or '!']],
+                     [[1.3: syntax error on token ['/'] (expected: ["number"] 
['-'] ['('] ['!'])]])
 _AT_CHECK_CALC_ERROR([$1], [1], [error], [5],
-                     [1.1: syntax error, unexpected $undefined])
+                     [[1.1: syntax error, unexpected $undefined]],
+                     [[1.1: syntax error on token [$undefined] (expected: 
["number"] ['-'] ['\n'] ['('] ['!'])]])
 _AT_CHECK_CALC_ERROR([$1], [1], [1 = 2 = 3], [30],
-                     [1.7: syntax error, unexpected '='])
+                     [[1.7: syntax error, unexpected '=']],
+                     [[1.7: syntax error on token ['='] (expected: ['-'] ['+'] 
['*'] ['/'] ['^'])]])
 _AT_CHECK_CALC_ERROR([$1], [1],
                      [
 +1],
                      [20],
-                     [2.1: syntax error, unexpected '+'])
+                     [[2.1: syntax error, unexpected '+']],
+                     [[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], [4],
-                     [1.1: syntax error, unexpected end of input])
+                     [[1.1: syntax error, unexpected end of input]],
+                     [[1.1: syntax error on token ["end of input"] (expected: 
["number"] ['-'] ['\n'] ['('] ['!'])]])
 
 # Exercise the error token: without it, we die at the first error,
 # hence be sure to
@@ -703,28 +716,41 @@ _AT_CHECK_CALC_ERROR([$1], [1], [/dev/null], [4],
 _AT_CHECK_CALC_ERROR([$1], [0],
                      [() + (1 + 1 + 1 +) + (* * *) + (1 * 2 * *) = 1],
                      [250],
-[1.2: syntax error, unexpected ')', expecting number or '-' or '(' or '!'
+[[1.2: syntax error, unexpected ')', expecting number or '-' or '(' or '!'
 1.18: syntax error, unexpected ')', expecting number or '-' or '(' or '!'
 1.23: syntax error, unexpected '*', expecting number or '-' or '(' or '!'
 1.41: syntax error, unexpected '*', expecting number or '-' or '(' or '!'
-calc: error: 4444 != 1])
+calc: error: 4444 != 1]],
+[[1.2: syntax error on token [')'] (expected: ["number"] ['-'] ['('] ['!'])
+1.18: syntax error on token [')'] (expected: ["number"] ['-'] ['('] ['!'])
+1.23: syntax error on token ['*'] (expected: ["number"] ['-'] ['('] ['!'])
+1.41: syntax error on token ['*'] (expected: ["number"] ['-'] ['('] ['!'])
+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], [102],
-[1.10: syntax error, unexpected number
-calc: error: 2222 != 1])
+[[1.10: syntax error, unexpected number
+calc: error: 2222 != 1]],
+[[1.10: syntax error on token ["number"] (expected: ['='] ['-'] ['+'] ['*'] 
['/'] ['^'] [')'])
+calc: error: 2222 != 1]])
 _AT_CHECK_CALC_ERROR([$1], [0], [(- *) + (1 2) = 1], [113],
-[1.4: syntax error, unexpected '*', expecting number or '-' or '(' or '!'
+[[1.4: syntax error, unexpected '*', expecting number or '-' or '(' or '!'
 1.12: syntax error, unexpected number
-calc: error: 2222 != 1])
+calc: error: 2222 != 1]],
+[[1.4: syntax error on token ['*'] (expected: ["number"] ['-'] ['('] ['!'])
+1.12: syntax error on token ["number"] (expected: ['='] ['-'] ['+'] ['*'] 
['/'] ['^'] [')'])
+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], [(* *) + (*) + (*)], [113],
-[1.2: syntax error, unexpected '*', expecting number or '-' or '(' or '!'
+[[1.2: syntax error, unexpected '*', expecting number or '-' or '(' or '!'
 1.10: syntax error, unexpected '*', expecting number or '-' or '(' or '!'
-1.16: syntax error, unexpected '*', expecting number or '-' or '(' or '!'])
+1.16: syntax error, unexpected '*', expecting number or '-' or '(' or '!']],
+[[1.2: syntax error on token ['*'] (expected: ["number"] ['-'] ['('] ['!'])
+1.10: syntax error on token ['*'] (expected: ["number"] ['-'] ['('] ['!'])
+1.16: syntax error on token ['*'] (expected: ["number"] ['-'] ['('] ['!'])]])
 
 AT_BISON_OPTION_POPDEFS
 
@@ -777,6 +803,8 @@ AT_CHECK_CALC_LALR([%define api.pure %define parse.error 
verbose %debug %locatio
 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([%define parse.error custom])
+
 # ----------------------- #
 # Simple GLR Calculator.  #
 # ----------------------- #
diff --git a/tests/local.at b/tests/local.at
index 2e2dd5bf..38f2fa19 100644
--- a/tests/local.at
+++ b/tests/local.at
@@ -203,7 +203,13 @@ m4_pushdef([AT_AUTOMOVE_IF],
 m4_pushdef([AT_DEFINES_IF],
 [m4_bmatch([$3], [%defines], [$1], [$2])])
 m4_pushdef([AT_DEBUG_IF],
-[m4_bmatch([$3], [%debug\|%define parse.trace], [$1], [$2])])
+           [m4_bmatch([$3], [%debug\|%define parse.trace], [$1], [$2])])
+m4_pushdef([AT_ERROR_CUSTOM_IF],
+           [m4_bmatch([$3], [%define parse\.error custom], [$1], [$2])])
+m4_pushdef([AT_ERROR_VERBOSE_IF],
+           [m4_bmatch([$3], [%define parse\.error verbose], [$1], [$2])])
+m4_pushdef([AT_ERROR_SIMPLE_IF],
+           [AT_ERROR_CUSTOM_IF([$2], [AT_ERROR_VERBOSE_IF([$2], [$1])], [$1])])
 m4_pushdef([AT_CXX_IF],
 [m4_bmatch([$3], [%language "[Cc]\+\+"\|%skeleton "[a-z0-9]+\.cc"], [$1], 
[$2])])
 m4_pushdef([AT_D_IF],
@@ -409,8 +415,12 @@ m4_popdef([AT_LANG])
 m4_popdef([AT_JAVA_IF])
 m4_popdef([AT_GLR_CC_IF])
 m4_popdef([AT_LALR1_CC_IF])
-m4_popdef([AT_DEFINES_IF])
+m4_popdef([AT_ERROR_SIMPLE_IF])
+m4_popdef([AT_ERROR_VERBOSE_IF])
+m4_popdef([AT_ERROR_CUSTOM_IF])
 m4_popdef([AT_DEBUG_IF])
+m4_popdef([AT_DEFINES_IF])
+m4_popdef([AT_AUTOMOVE_IF])
 AT_LOC_POPDEF])dnl
 ])# AT_BISON_OPTION_POPDEFS
 
@@ -552,7 +562,7 @@ m4_define([AT_YYERROR_DECLARE_EXTERN(c)],
 [AT_YYERROR_PROTOTYPE;])
 
 m4_define([AT_YYERROR_DECLARE(c)],
-[#include <stdio.h>
+[[#include <stdio.h>
 ]AT_LOCATION_IF([[
 #if defined ]AT_YYLTYPE[_IS_TRIVIAL && ]AT_YYLTYPE[_IS_TRIVIAL
 static int location_print (FILE *yyo, ]AT_YYLTYPE[ const * const yylocp);
@@ -561,12 +571,11 @@ static int location_print (FILE *yyo, ]AT_YYLTYPE[ const 
* const yylocp);
 # endif
 #endif
 ]])[
-static AT_YYERROR_DECLARE_EXTERN])
+static ]AT_YYERROR_DECLARE_EXTERN])
 
 
 m4_define([AT_YYERROR_DEFINE(c)],
-[[
-]AT_LOCATION_IF([[
+[AT_LOCATION_IF([[
 # if defined ]AT_YYLTYPE[_IS_TRIVIAL && ]AT_YYLTYPE[_IS_TRIVIAL
 /* Print *YYLOCP on YYO. */
 __attribute__((__unused__))
@@ -596,6 +605,33 @@ location_print (FILE *yyo, ]AT_YYLTYPE[ const * const 
yylocp)
 }
 #endif
 ]])[
+
+]AT_ERROR_CUSTOM_IF([[
+int
+yyreport_syntax_error (const yyparse_context_t *ctx)
+{
+  /* 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);
+  if (n == -2)
+    return 2;
+  if (n)
+  {
+    fprintf (stderr, "syntax error on token [%s]", yysymbol_name (arg[0]));
+    if (1 < n)
+      {
+        fprintf (stderr, " (expected:");
+        for (int i = 1; i < n; ++i)
+          fprintf (stderr, " [%s]", yysymbol_name (arg[i]));
+        fprintf (stderr, ")");
+      }
+    fprintf (stderr, "\n");
+  }
+  return 0;
+}
+]])[
+
 /* A C error reporting function.  */
 static
 ]AT_YYERROR_PROTOTYPE[
@@ -606,7 +642,7 @@ AT_YYERROR_SEES_LOC_IF([[
   LOCATION_PRINT (stderr, ]AT_LOC[);
   fprintf (stderr, ": ");]])[
   fprintf (stderr, "%s\n", msg);
-}]])
+}]])])
 
 
 m4_define([AT_YYLEX_DEFINE(c)],
diff --git a/tests/testsuite.at b/tests/testsuite.at
index 2cfbefc5..e2b72b84 100644
--- a/tests/testsuite.at
+++ b/tests/testsuite.at
@@ -26,7 +26,7 @@ m4_include([named-refs.at])
 # Output file names.
 m4_include([output.at])
 
-# Diagnostics.
+# Bison diagnostics.
 m4_include([diagnostics.at])
 
 # Skeleton support.
-- 
2.24.1




reply via email to

[Prev in Thread] Current Thread [Next in Thread]