bison-patches
[Top][All Lists]
Advanced

[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"])




reply via email to

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