[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
tests: check calls to yyerror from the user actions
From: |
Akim Demaille |
Subject: |
tests: check calls to yyerror from the user actions |
Date: |
Wed, 12 Feb 2020 00:01:44 +0100 |
commit f3d33c3613d826f19f80a1a1e2ab5651091de0c6
Author: Akim Demaille <address@hidden>
Date: Tue Feb 11 19:59:07 2020 +0100
tests: check calls to yyerror from the user actions
This revealed a number of things I had not realized:
- the Java location tracking was aliasing the same pair of positions
for all the symbols (see previous commit).
- in impure parsers, it's quite easy to use incorrect locations for
diagnostics, since yyerror uses yylloc, which is the location of the
lookahead, not that of the current lhs. So we need something like
{
YYLTYPE old_yylloc = yylloc;
yylloc = @$;
yyerror (]AT_PARAM_IF([result, count, nerrs, ])[buf);
yylloc = old_yylloc;
}
Maybe we should do that little yylloc dance in the skeleton instead
of leaving it to the user? It might be costly... But that's only
for users of the impure parsers, which are asking for trouble
anyway.
- in glr.cc invoking yyerror is somewhat cumbersome: the C++ interface
is not available as we are in yyparse (which in C), and yyerror is
used by glr.cc itself to bind it to the user's parser::error. If we
call yyerror, we need:
yyerror (]AT_LOCATION_IF([[&@$, ]])[yyparser, ]AT_PARAM_IF([result,
count, nerrs, ])[msg);
However calling yy::parser::error is easier, once we know that the
current parser object is available as 'yyparser'. Which also saves
us from having to pass the parse-params ourselves:
yyparser.error (]AT_LOCATION_IF([[@$, ]])[msg);
* tests/calc.at: Invoke yyerror by hand, instead of using fprintf etc.
Adjust expectations.
diff --git a/TODO b/TODO
index 32c7ec38..9af72c24 100644
--- a/TODO
+++ b/TODO
@@ -3,15 +3,6 @@
YYUNDEFTOK is an internal symbol number, as YYTERROR.
But YYERRCODE is an external token number.
-** Tests
-The calc.at test should call yyerror with location:
-
-| exp '=' exp
- {
- if ($1.intValue () != $3.intValue ())
- yyerror (]AT_LOCATION_IF([[@$, ]])["calc: error: " + $1 + " != " + $3);
- }
-
** Java: EOF
We should be able to redefine EOF like we do in C.
diff --git a/tests/calc.at b/tests/calc.at
index 0fd8c266..0487dc1f 100644
--- a/tests/calc.at
+++ b/tests/calc.at
@@ -554,10 +554,28 @@ exp:
NUM
| exp '=' exp
{
- if ($1 != $3)]AT_D_IF([
- stderr.writefln ("calc: error: %d != %d", $1, $3);], [
- fprintf (stderr, "calc: error: %d != %d\n", $1, $3);], [
- ])[
+ if ($1 != $3)]AT_LANG_CASE(
+ [c], [[
+ {
+ char buf[1024];
+ snprintf (buf, sizeof buf, "calc: error: %d != %d", $1,
$3);]AT_YYERROR_ARG_LOC_IF([[
+ yyerror (&@$, ]AT_PARAM_IF([result, count, nerrs, ])[buf);]], [[
+ {
+ YYLTYPE old_yylloc = yylloc;
+ yylloc = @$;
+ yyerror (]AT_PARAM_IF([result, count, nerrs, ])[buf);
+ yylloc = old_yylloc;
+ }
+ ]])[
+ }]],
+ [c++], [[
+ {
+ char buf[1024];
+ snprintf (buf, sizeof buf, "calc: error: %d != %d", $1, $3);
+ ]AT_GLR_IF([[yyparser.]])[error (]AT_LOCATION_IF([[@$, ]])[buf);
+ }]],
+ [d], [[
+ yyerror (]AT_LOCATION_IF([[@$, ]])[format ("calc: error: %d != %d", $1,
$3));]])[
$$ = $1;
}
| exp '+' exp { $$ = $1 + $3; }
@@ -691,7 +709,7 @@ exp:
| exp '=' exp
{
if ($1.intValue () != $3.intValue ())
- yyerror ("calc: error: " + $1 + " != " + $3);
+ yyerror (]AT_LOCATION_IF([[@$, ]])["calc: error: " + $1 + " != " + $3);
}
| exp '+' exp { $$ = $1 + $3; }
| exp '-' exp { $$ = $1 - $3; }
@@ -954,27 +972,28 @@ _AT_CHECK_CALC_ERROR([$1], [1], [/dev/null],
#
_AT_CHECK_CALC_ERROR([$1], [0],
[() + (1 + 1 + 1 +) + (* * *) + (1 * 2 * *) = 1],
- [[final: 4444 0 4]],
+ [[final: 4444 0 5]],
[250],
[AT_JAVA_IF([1.2-1.3], [1.2])[: syntax error on token [')'] (expected:
[number] ['-'] ['('] ['!'])
]AT_JAVA_IF([1.18-1.19], [1.18])[: syntax error on token [')'] (expected:
[number] ['-'] ['('] ['!'])
]AT_JAVA_IF([1.23-1.24], [1.23])[: syntax error on token ['*'] (expected:
[number] ['-'] ['('] ['!'])
]AT_JAVA_IF([1.41-1.42], [1.41])[: syntax error on token ['*'] (expected:
[number] ['-'] ['('] ['!'])
-calc: error: 4444 != 1]])
+]AT_JAVA_IF([1.1-1.47], [1.1-46])[: 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 1]],
+ [[final: 2222 0 2]],
[102],
[AT_JAVA_IF([1.10-1.11], [1.10])[: syntax error on token [number] (expected:
['='] ['-'] ['+'] ['*'] ['/'] ['^'] [')'])
-calc: error: 2222 != 1]])
+]AT_JAVA_IF([1.1-1.16], [1.1-15])[: calc: error: 2222 != 1]])
+
_AT_CHECK_CALC_ERROR([$1], [0], [(- *) + (1 2) = 1],
- [[final: 2222 0 2]],
+ [[final: 2222 0 3]],
[113],
[AT_JAVA_IF([1.4-1.5], [1.4])[: syntax error on token ['*'] (expected:
[number] ['-'] ['('] ['!'])
]AT_JAVA_IF([1.12-1.13], [1.12])[: syntax error on token [number] (expected:
['='] ['-'] ['+'] ['*'] ['/'] ['^'] [')'])
-calc: error: 2222 != 1]])
+]AT_JAVA_IF([1.1-1.18], [1.1-17])[: calc: error: 2222 != 1]])
# Check that yyerrok works properly: second error is not reported,
# third and fourth are. Parse status is succesful.
@@ -1009,7 +1028,7 @@ m4_define([AT_CHECK_CALC_LALR],
AT_CHECK_CALC_LALR([%define parse.trace])
AT_CHECK_CALC_LALR([%defines])
-AT_CHECK_CALC_LALR([%locations])
+AT_CHECK_CALC_LALR([%debug %locations])
AT_CHECK_CALC_LALR([%locations %define api.location.type {Span}])
AT_CHECK_CALC_LALR([%name-prefix "calc"])
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- tests: check calls to yyerror from the user actions,
Akim Demaille <=