mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-09 12:23:04 +00:00
yacc.c: check custom error messages
* 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.
This commit is contained in:
@@ -545,10 +545,11 @@ AT_PARSER_CHECK([calc input], 0, [], [stderr])
|
|||||||
])
|
])
|
||||||
|
|
||||||
|
|
||||||
# _AT_CHECK_CALC_ERROR(BISON-OPTIONS, EXIT-STATUS, INPUT,
|
# _AT_CHECK_CALC_ERROR($1 = BISON-OPTIONS, $2 = EXIT-STATUS, $3 = INPUT,
|
||||||
# [NUM-STDERR-LINES],
|
# $4 = [NUM-STDERR-LINES],
|
||||||
# [VERBOSE-AND-LOCATED-ERROR-MESSAGE])
|
# $5 = [VERBOSE-AND-LOCATED-ERROR-MESSAGE]
|
||||||
# ---------------------------------------------------------
|
# $6 = [CUSTOM-ERROR-MESSAGE])
|
||||||
|
# ----------------------------------------------------------------------
|
||||||
# Run 'calc' on INPUT, and expect a 'syntax 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,
|
# 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
|
mv at-stderr stderr
|
||||||
|
|
||||||
# 2. Create the reference error message.
|
# 2. Create the reference error message.
|
||||||
AT_DATA([[expout]],
|
AT_ERROR_CUSTOM_IF([
|
||||||
|
AT_DATA([[expout]],
|
||||||
|
[$6
|
||||||
|
])
|
||||||
|
],
|
||||||
|
[AT_DATA([[expout]],
|
||||||
[$5
|
[$5
|
||||||
])
|
])
|
||||||
|
])
|
||||||
|
|
||||||
# 3. If locations are not used, remove them.
|
# 3. If locations are not used, remove them.
|
||||||
AT_YYERROR_SEES_LOC_IF([],
|
AT_YYERROR_SEES_LOC_IF([],
|
||||||
@@ -605,7 +612,7 @@ AT_YYERROR_SEES_LOC_IF([],
|
|||||||
mv at-expout expout]])
|
mv at-expout expout]])
|
||||||
|
|
||||||
# 4. If error-verbose is not used, strip the', unexpected....' part.
|
# 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
|
[[sed 's/syntax error, .*$/syntax error/' expout >at-expout
|
||||||
mv at-expout expout]])
|
mv at-expout expout]])
|
||||||
|
|
||||||
@@ -668,21 +675,27 @@ _AT_CHECK_CALC([$1],
|
|||||||
|
|
||||||
# Some syntax errors.
|
# Some syntax errors.
|
||||||
_AT_CHECK_CALC_ERROR([$1], [1], [1 2], [15],
|
_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],
|
_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],
|
_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],
|
_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],
|
_AT_CHECK_CALC_ERROR([$1], [1],
|
||||||
[
|
[
|
||||||
+1],
|
+1],
|
||||||
[20],
|
[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.
|
# Exercise error messages with EOF: work on an empty file.
|
||||||
_AT_CHECK_CALC_ERROR([$1], [1], [/dev/null], [4],
|
_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,
|
# Exercise the error token: without it, we die at the first error,
|
||||||
# hence be sure to
|
# hence be sure to
|
||||||
@@ -703,28 +716,41 @@ _AT_CHECK_CALC_ERROR([$1], [1], [/dev/null], [4],
|
|||||||
_AT_CHECK_CALC_ERROR([$1], [0],
|
_AT_CHECK_CALC_ERROR([$1], [0],
|
||||||
[() + (1 + 1 + 1 +) + (* * *) + (1 * 2 * *) = 1],
|
[() + (1 + 1 + 1 +) + (* * *) + (1 * 2 * *) = 1],
|
||||||
[250],
|
[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.18: syntax error, unexpected ')', expecting number or '-' or '(' or '!'
|
||||||
1.23: 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 '!'
|
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.
|
# The same, but this time exercising explicitly triggered syntax errors.
|
||||||
# POSIX says the lookahead causing the error should not be discarded.
|
# POSIX says the lookahead causing the error should not be discarded.
|
||||||
_AT_CHECK_CALC_ERROR([$1], [0], [(!) + (1 2) = 1], [102],
|
_AT_CHECK_CALC_ERROR([$1], [0], [(!) + (1 2) = 1], [102],
|
||||||
[1.10: syntax error, unexpected number
|
[[1.10: syntax error, unexpected number
|
||||||
calc: error: 2222 != 1])
|
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],
|
_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
|
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,
|
# Check that yyerrok works properly: second error is not reported,
|
||||||
# third and fourth are. Parse status is succesful.
|
# third and fourth are. Parse status is succesful.
|
||||||
_AT_CHECK_CALC_ERROR([$1], [0], [(* *) + (*) + (*)], [113],
|
_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.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
|
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([%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. #
|
# Simple GLR Calculator. #
|
||||||
# ----------------------- #
|
# ----------------------- #
|
||||||
|
|||||||
@@ -203,7 +203,13 @@ m4_pushdef([AT_AUTOMOVE_IF],
|
|||||||
m4_pushdef([AT_DEFINES_IF],
|
m4_pushdef([AT_DEFINES_IF],
|
||||||
[m4_bmatch([$3], [%defines], [$1], [$2])])
|
[m4_bmatch([$3], [%defines], [$1], [$2])])
|
||||||
m4_pushdef([AT_DEBUG_IF],
|
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_pushdef([AT_CXX_IF],
|
||||||
[m4_bmatch([$3], [%language "[Cc]\+\+"\|%skeleton "[a-z0-9]+\.cc"], [$1], [$2])])
|
[m4_bmatch([$3], [%language "[Cc]\+\+"\|%skeleton "[a-z0-9]+\.cc"], [$1], [$2])])
|
||||||
m4_pushdef([AT_D_IF],
|
m4_pushdef([AT_D_IF],
|
||||||
@@ -409,8 +415,12 @@ m4_popdef([AT_LANG])
|
|||||||
m4_popdef([AT_JAVA_IF])
|
m4_popdef([AT_JAVA_IF])
|
||||||
m4_popdef([AT_GLR_CC_IF])
|
m4_popdef([AT_GLR_CC_IF])
|
||||||
m4_popdef([AT_LALR1_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_DEBUG_IF])
|
||||||
|
m4_popdef([AT_DEFINES_IF])
|
||||||
|
m4_popdef([AT_AUTOMOVE_IF])
|
||||||
AT_LOC_POPDEF])dnl
|
AT_LOC_POPDEF])dnl
|
||||||
])# AT_BISON_OPTION_POPDEFS
|
])# AT_BISON_OPTION_POPDEFS
|
||||||
|
|
||||||
@@ -552,7 +562,7 @@ m4_define([AT_YYERROR_DECLARE_EXTERN(c)],
|
|||||||
[AT_YYERROR_PROTOTYPE;])
|
[AT_YYERROR_PROTOTYPE;])
|
||||||
|
|
||||||
m4_define([AT_YYERROR_DECLARE(c)],
|
m4_define([AT_YYERROR_DECLARE(c)],
|
||||||
[#include <stdio.h>
|
[[#include <stdio.h>
|
||||||
]AT_LOCATION_IF([[
|
]AT_LOCATION_IF([[
|
||||||
#if defined ]AT_YYLTYPE[_IS_TRIVIAL && ]AT_YYLTYPE[_IS_TRIVIAL
|
#if defined ]AT_YYLTYPE[_IS_TRIVIAL && ]AT_YYLTYPE[_IS_TRIVIAL
|
||||||
static int location_print (FILE *yyo, ]AT_YYLTYPE[ const * const yylocp);
|
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
|
||||||
#endif
|
#endif
|
||||||
]])[
|
]])[
|
||||||
static AT_YYERROR_DECLARE_EXTERN])
|
static ]AT_YYERROR_DECLARE_EXTERN])
|
||||||
|
|
||||||
|
|
||||||
m4_define([AT_YYERROR_DEFINE(c)],
|
m4_define([AT_YYERROR_DEFINE(c)],
|
||||||
[[
|
[AT_LOCATION_IF([[
|
||||||
]AT_LOCATION_IF([[
|
|
||||||
# if defined ]AT_YYLTYPE[_IS_TRIVIAL && ]AT_YYLTYPE[_IS_TRIVIAL
|
# if defined ]AT_YYLTYPE[_IS_TRIVIAL && ]AT_YYLTYPE[_IS_TRIVIAL
|
||||||
/* Print *YYLOCP on YYO. */
|
/* Print *YYLOCP on YYO. */
|
||||||
__attribute__((__unused__))
|
__attribute__((__unused__))
|
||||||
@@ -596,6 +605,33 @@ location_print (FILE *yyo, ]AT_YYLTYPE[ const * const yylocp)
|
|||||||
}
|
}
|
||||||
#endif
|
#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. */
|
/* A C error reporting function. */
|
||||||
static
|
static
|
||||||
]AT_YYERROR_PROTOTYPE[
|
]AT_YYERROR_PROTOTYPE[
|
||||||
@@ -606,7 +642,7 @@ AT_YYERROR_SEES_LOC_IF([[
|
|||||||
LOCATION_PRINT (stderr, ]AT_LOC[);
|
LOCATION_PRINT (stderr, ]AT_LOC[);
|
||||||
fprintf (stderr, ": ");]])[
|
fprintf (stderr, ": ");]])[
|
||||||
fprintf (stderr, "%s\n", msg);
|
fprintf (stderr, "%s\n", msg);
|
||||||
}]])
|
}]])])
|
||||||
|
|
||||||
|
|
||||||
m4_define([AT_YYLEX_DEFINE(c)],
|
m4_define([AT_YYLEX_DEFINE(c)],
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ m4_include([named-refs.at])
|
|||||||
# Output file names.
|
# Output file names.
|
||||||
m4_include([output.at])
|
m4_include([output.at])
|
||||||
|
|
||||||
# Diagnostics.
|
# Bison diagnostics.
|
||||||
m4_include([diagnostics.at])
|
m4_include([diagnostics.at])
|
||||||
|
|
||||||
# Skeleton support.
|
# Skeleton support.
|
||||||
|
|||||||
Reference in New Issue
Block a user