]> git.saurik.com Git - bison.git/blobdiff - tests/actions.at
gnulib: update
[bison.git] / tests / actions.at
index 6dd5a58026fcbdfe5abc1f37c9d740c467c37e43..7d876709f001dbaf52922e7e73f0251329a4fe8a 100644 (file)
@@ -1,6 +1,6 @@
 e# Executing Actions.                               -*- Autotest -*-
 
-# Copyright (C) 2001-2013 Free Software Foundation, Inc.
+# Copyright (C) 2001-2015 Free Software Foundation, Inc.
 
 # This program is free software: you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -64,6 +64,47 @@ AT_PARSER_CHECK([./input], 0,
 
 AT_CLEANUP
 
+## ----------------------- ##
+## Implicitly empty rule.  ##
+## ----------------------- ##
+
+AT_SETUP([Implicitly empty rule])
+
+AT_DATA_GRAMMAR([[1.y]],
+[[%%
+exp: a b;
+a: /* empty. */ {};
+// A mid-rule action does not count as an empty rule.
+b: {} {};
+]])
+
+AT_BISON_CHECK([-fcaret -Wempty-rule 1.y], [0], [],
+[[1.y:11.17-18: warning: empty rule without %empty [-Wempty-rule]
+ a: /* empty. */ {};
+                 ^^
+]])
+
+AT_DATA_GRAMMAR([[2.y]],
+[[%%
+exp: a b c;
+a: /* empty. */ {};
+b: %empty       {};
+c: /* empty. */ {};
+]])
+
+AT_BISON_CHECK([-fcaret 2.y], [0], [],
+[[2.y:11.17-18: warning: empty rule without %empty [-Wempty-rule]
+ a: /* empty. */ {};
+                 ^^
+2.y:13.17-18: warning: empty rule without %empty [-Wempty-rule]
+ c: /* empty. */ {};
+                 ^^
+]])
+
+AT_BISON_CHECK([-fcaret -Wno-empty-rule 2.y], [0])
+
+AT_CLEANUP
+
 ## ------------------------ ##
 ## Invalid uses of %empty.  ##
 ## ------------------------ ##
@@ -73,14 +114,17 @@ AT_SETUP([Invalid uses of %empty])
 AT_DATA_GRAMMAR([[one.y]],
 [[%%
 exp:
-  %empty %empty {}
+  %empty {} %empty
 ;
 ]])
 
 AT_BISON_CHECK([-fcaret one.y], [1], [],
-[[one.y:11.10-15: error: only one %empty allowed per rule
-   %empty %empty {}
-          ^^^^^^
+[[one.y:11.13-18: error: only one %empty allowed per rule
+   %empty {} %empty
+             ^^^^^^
+one.y:11.3-8: previous declaration
+   %empty {} %empty
+   ^^^^^^
 ]])
 
 AT_DATA_GRAMMAR([[two.y]],
@@ -242,8 +286,8 @@ m4_popdef([AT_TEST])
 ## Location Print.  ##
 ## ---------------- ##
 
-# AT_TEST(SKELETON-NAME, DIRECTIVES, [MORE-DIRECTIVES], [LOCATION = 1.1])
-# -----------------------------------------------------------------------
+# AT_TEST(SKELETON-NAME, DIRECTIVES, [MORE-DIRECTIVES])
+# -----------------------------------------------------
 # Check that the initial location is correct.
 m4_pushdef([AT_TEST],
 [AT_SETUP([Location print: $1 $2])
@@ -261,7 +305,7 @@ AT_DATA_GRAMMAR([[input.y]],
 ]AT_YYLEX_DECLARE[
 }
 %%
-exp: /* empty */;
+exp: %empty;
 %%
 ]AT_YYERROR_DEFINE[
 ]AT_YYLEX_DEFINE[
@@ -431,7 +475,7 @@ AT_DATA_GRAMMAR([[input.y]],
 
 /* Display the symbol type Symbol.  */
 #define V(Symbol, Value, Location, Sep) \
-   fprintf (stderr, #Symbol " (%d@%d-%d)" Sep, Value, RANGE(Location))
+   fprintf (stderr, #Symbol " (%d@%d-%d)%s", Value, RANGE(Location), Sep)
 }
 
 $5
@@ -446,15 +490,17 @@ AT_LALR1_CC_IF([typedef yy::location YYLTYPE;])[
 ]AT_LALR1_CC_IF([], [AT_YYERROR_DECLARE])
 [}
 
-]m4_ifval([$6], [%type <ival> '(' 'x' 'y' ')' ';' thing line input END])[
+]m4_ifval([$6],
+[%type <ival> '(' 'x' 'y' ')' ';' thing line input
+              '!' raise check-spontaneous-errors END])[
 
 /* FIXME: This %printer isn't actually tested.  */
 %printer
   {
-    ]AT_LALR1_CC_IF([debug_stream () << $$;],
-                    [fprintf (yyoutput, "%d", $$)])[;
+    ]AT_LALR1_CC_IF([yyo << $$;],
+                    [fprintf (yyo, "%d", $$)])[;
   }
-  input line thing 'x' 'y'
+  '(' 'x' 'y' ')' ';' thing line input '!' raise check-spontaneous-errors END
 
 %destructor
   { fprintf (stderr, "Freeing nterm input (%d@%d-%d)\n", $$, RANGE (@$)); }
@@ -468,6 +514,14 @@ AT_LALR1_CC_IF([typedef yy::location YYLTYPE;])[
   { fprintf (stderr, "Freeing nterm thing (%d@%d-%d)\n", $$, RANGE (@$)); }
   thing
 
+%destructor
+  { fprintf (stderr, "Freeing raise thing (%d@%d-%d)\n", $$, RANGE (@$)); }
+  raise
+
+%destructor
+  { fprintf (stderr, "Freeing check-spontaneous-errors thing (%d@%d-%d)\n", $$, RANGE (@$)); }
+  check-spontaneous-errors
+
 %destructor
   { fprintf (stderr, "Freeing token 'x' (%d@%d-%d)\n", $$, RANGE (@$)); }
   'x'
@@ -484,13 +538,13 @@ AT_LALR1_CC_IF([typedef yy::location YYLTYPE;])[
 %%
 /*
    This grammar is made to exercise error recovery.
-   "Lines" starting with `(' support error recovery, with
+   "Lines" starting with '(' support error recovery, with
    ')' as synchronizing token.  Lines starting with 'x' can never
    be recovered from if in error.
 */
 
 input:
-  /* Nothing. */
+  %empty
     {
       $$ = 0;
       V(input, $$, @$, ": /* Nothing */\n");
@@ -503,6 +557,38 @@ input:
       V(line,  $1, @1, " ");
       V(input, $2, @2, "\n");
     }
+| '!' check-spontaneous-errors
+  {
+    $$ = $2;
+  }
+;
+
+check-spontaneous-errors:
+  raise         { abort(); $$ = $1; }
+| '(' raise ')' { abort(); $$ = $2; }
+| error
+  {
+    $$ = 5;
+    V(check-spontaneous-errors, $$, @$, ": ");
+    fprintf (stderr, "error (@%d-%d)\n", RANGE(@1));
+  }
+;
+
+raise:
+  %empty
+  {
+    $$ = 4;
+    V(raise, $$, @$, ": %empty\n");
+    YYERROR;
+  }
+| '!' '!'
+  {
+    $$ = 5;
+    V(raise, $$, @$, ": ");
+    V(!, $1, @2, " ");
+    V(!, $2, @2, "\n");
+    YYERROR;
+  }
 ;
 
 line:
@@ -552,7 +638,7 @@ thing:
 ;
 %%
 /* Alias to ARGV[1]. */
-const char *source = YY_NULL;
+const char *source = YY_NULLPTR;
 
 ]AT_YYERROR_DEFINE[
 
@@ -561,11 +647,11 @@ static
 {
   static unsigned int counter = 0;
 
-  int c = ]AT_VAL[]m4_ifval([$6], [.ival])[ = counter++;
+  unsigned int c = ]AT_VAL[]m4_ifval([$6], [.ival])[ = counter++;
   /* As in BASIC, line numbers go from 10 to 10.  */
   ]AT_LOC_FIRST_LINE[ = ]AT_LOC_FIRST_COLUMN[ = 10 * c;
   ]AT_LOC_LAST_LINE[ = ]AT_LOC_LAST_COLUMN[ = ]AT_LOC_FIRST_LINE[ + 9;
-  assert (0 <= c && c <= strlen (source));
+  assert (c <= strlen (source));
   if (source[c])
     fprintf (stderr, "sending: '%c'", source[c]);
   else
@@ -589,7 +675,7 @@ main (int argc, const char *argv[])
 {
   int status;
   yydebug = !!getenv ("YYDEBUG");
-  assert (argc == 2);
+  assert (argc == 2); (void) argc;
   source = argv[1];
   status = yyparse ();
   switch (status)
@@ -624,6 +710,38 @@ Freeing nterm input (2@0-29)
 Successful parse.
 ]])
 
+# Check the location of empty reductions raising an error
+# -------------------------------------------------------
+# Here, the error is after token "!@0-9", so the error is raised from
+# @9-9, and the error recovery detects that it starts from @9-9 and
+# ends where starts the next token: END@10-19.
+#
+# So error recovery reports error@9-19.
+AT_PARSER_CHECK([./input '!'], 0, [],
+[[sending: '!' (0@0-9)
+sending: END (1@10-19)
+raise (4@9-9): %empty
+check-spontaneous-errors (5@9-19): error (@9-19)
+Freeing token END (1@10-19)
+Freeing nterm input (5@0-19)
+Successful parse.
+]])
+
+# Check the location of not empty reductions raising an error
+# -----------------------------------------------------------
+# This time the error is raised from a rule with 2 rhs symbols: @10-29.
+# It is recovered @10-29.
+AT_PARSER_CHECK([[./input '!!!']], 0, [],
+[[sending: '!' (0@0-9)
+sending: '!' (1@10-19)
+sending: '!' (2@20-29)
+raise (5@10-29): ! (1@20-29) ! (2@20-29)
+check-spontaneous-errors (5@10-29): error (@10-29)
+sending: END (3@30-39)
+Freeing token END (3@30-39)
+Freeing nterm input (5@0-29)
+Successful parse.
+]])
 
 # Check locations in error recovery
 # ---------------------------------
@@ -647,7 +765,7 @@ Successful parse.
 
 # Syntax errors caught by the parser
 # ----------------------------------
-# Exercise the discarding of stack top and input until `error'
+# Exercise the discarding of stack top and input until 'error'
 # can be reduced.
 #
 #     '(', 'x', 'x', 'x', 'x', 'x', ')',
@@ -804,13 +922,13 @@ AT_CLEANUP
 
 
 AT_CHECK_PRINTER_AND_DESTRUCTOR([])
-AT_CHECK_PRINTER_AND_DESTRUCTOR([], [with union])
+AT_CHECK_PRINTER_AND_DESTRUCTOR([], [ with union])
 
 AT_CHECK_PRINTER_AND_DESTRUCTOR([%defines %skeleton "lalr1.cc"])
-AT_CHECK_PRINTER_AND_DESTRUCTOR([%defines %skeleton "lalr1.cc"], [with union])
+AT_CHECK_PRINTER_AND_DESTRUCTOR([%defines %skeleton "lalr1.cc"], [ with union])
 
 AT_CHECK_PRINTER_AND_DESTRUCTOR([%glr-parser])
-AT_CHECK_PRINTER_AND_DESTRUCTOR([%glr-parser], [with union])
+AT_CHECK_PRINTER_AND_DESTRUCTOR([%glr-parser], [ with union])
 
 
 
@@ -1243,7 +1361,7 @@ AT_SETUP([Default %printer and %destructor are not for $accept])
 #   - The %printer and %destructor code generated for $accept would always be
 #     dead code because $accept is currently never shifted onto the stack.
 #   - $$ for $accept would always be of type YYSTYPE because it's not possible
-#     to declare `%type <field> $accept'.  (Also true for $undefined.)
+#     to declare '%type <field> $accept'.  (Also true for $undefined.)
 #   - Thus, the compiler might complain that the user code assumes the wrong
 #     type for $$ since the code might assume the type associated with a
 #     specific union field, which is especially reasonable in C++ since that
@@ -1486,10 +1604,13 @@ AT_DATA_GRAMMAR([[input.y]],
 
 ]AT_SKEL_CC_IF([[
 # include <iostream>
-  static void
-  report (std::ostream& yyo, int ival, float fval)
+  namespace
   {
-    yyo << "ival: " << ival << ", fval: " <<  fval;
+    void
+    report (std::ostream& yyo, int ival, float fval)
+    {
+      yyo << "ival: " << ival << ", fval: " <<  fval;
+    }
   }
 ]], [[
 # include <stdio.h>
@@ -1563,115 +1684,6 @@ AT_TEST([glr.cc])
 
 m4_popdef([AT_TEST])
 
-## ----------------------------------------------- ##
-## Fix user actions without a trailing semicolon.  ##
-## ----------------------------------------------- ##
-
-AT_SETUP([[Fix user actions without a trailing semicolon]])
-
-# This feature is undocumented, but we accidentally broke it in 2.3a,
-# and there was a complaint at:
-# <http://lists.gnu.org/archive/html/bug-bison/2008-11/msg00001.html>.
-AT_BISON_OPTION_PUSHDEFS
-AT_DATA([input.y],
-[[%%
-start: test2 test1 test0 testc;
-
-test2
-: 'a' { semi;                   /* TEST:N:2 */ }
-| 'b' { if (0) {no_semi}        /* TEST:N:2 */ }
-| 'c' { if (0) {semi;}          /* TEST:N:2 */ }
-| 'd' { semi;   no_semi         /* TEST:Y:2 */ }
-| 'e' { semi(); no_semi()       /* TEST:Y:2 */ }
-| 'f' { semi[]; no_semi[]       /* TEST:Y:2 */ }
-| 'g' { semi++; no_semi++       /* TEST:Y:2 */ }
-| 'h' { {no_semi} no_semi       /* TEST:Y:2 */ }
-| 'i' { {semi;}   no_semi       /* TEST:Y:2 */ }
-;
-test1
-  : 'a' { semi;                 // TEST:N:1 ;
-} | 'b' { if (0) {no_semi}      // TEST:N:1 ;
-} | 'c' { if (0) {semi;}        // TEST:N:1 ;
-} | 'd' { semi;   no_semi       // TEST:Y:1 ;
-} | 'e' { semi(); no_semi()     // TEST:Y:1 ;
-} | 'f' { semi[]; no_semi[]     // TEST:Y:1 ;
-} | 'g' { semi++; no_semi++     // TEST:Y:1 ;
-} | 'h' { {no_semi} no_semi     // TEST:Y:1 ;
-} | 'i' { {semi;}   no_semi     // TEST:Y:1 ;
-} ;
-test0
-  : 'a' { semi;                 // TEST:N:1 {}
-} | 'b' { if (0) {no_semi}      // TEST:N:1 {}
-} | 'c' { if (0) {semi;}        // TEST:N:1 {}
-} | 'd' { semi;   no_semi       // TEST:Y:1 {}
-} | 'e' { semi(); no_semi()     // TEST:Y:1 {}
-} | 'f' { semi[]; no_semi[]     // TEST:Y:1 {}
-} | 'g' { semi++; no_semi++     // TEST:Y:1 {}
-} | 'h' { {no_semi} no_semi     // TEST:Y:1 {}
-} | 'i' { {semi;}   no_semi     // TEST:Y:1 {}
-} ;
-
-testc
-: 'a' {
-#define TEST_MACRO_N \
-[]"broken\" $ @ $$ @$ [];\
-string;"}
-| 'b' {
-no_semi
-#define TEST_MACRO_N \
-[]"broken\" $ @ $$ @$ [];\
-string;"}
-]])
-AT_BISON_OPTION_POPDEFS
-
-AT_BISON_CHECK([[-o input.c input.y]], [0], [],
-[[input.y:8.48: warning: a ';' might be needed at the end of action code [-Wdeprecated]
-input.y:8.48:     future versions of Bison will not add the ';'
-input.y:9.48: warning: a ';' might be needed at the end of action code [-Wdeprecated]
-input.y:9.48:     future versions of Bison will not add the ';'
-input.y:10.48: warning: a ';' might be needed at the end of action code [-Wdeprecated]
-input.y:10.48:     future versions of Bison will not add the ';'
-input.y:11.48: warning: a ';' might be needed at the end of action code [-Wdeprecated]
-input.y:11.48:     future versions of Bison will not add the ';'
-input.y:12.48: warning: a ';' might be needed at the end of action code [-Wdeprecated]
-input.y:12.48:     future versions of Bison will not add the ';'
-input.y:13.48: warning: a ';' might be needed at the end of action code [-Wdeprecated]
-input.y:13.48:     future versions of Bison will not add the ';'
-input.y:20.1: warning: a ';' might be needed at the end of action code [-Wdeprecated]
-input.y:20.1:     future versions of Bison will not add the ';'
-input.y:21.1: warning: a ';' might be needed at the end of action code [-Wdeprecated]
-input.y:21.1:     future versions of Bison will not add the ';'
-input.y:22.1: warning: a ';' might be needed at the end of action code [-Wdeprecated]
-input.y:22.1:     future versions of Bison will not add the ';'
-input.y:23.1: warning: a ';' might be needed at the end of action code [-Wdeprecated]
-input.y:23.1:     future versions of Bison will not add the ';'
-input.y:24.1: warning: a ';' might be needed at the end of action code [-Wdeprecated]
-input.y:24.1:     future versions of Bison will not add the ';'
-input.y:25.1: warning: a ';' might be needed at the end of action code [-Wdeprecated]
-input.y:25.1:     future versions of Bison will not add the ';'
-input.y:31.1: warning: a ';' might be needed at the end of action code [-Wdeprecated]
-input.y:31.1:     future versions of Bison will not add the ';'
-input.y:32.1: warning: a ';' might be needed at the end of action code [-Wdeprecated]
-input.y:32.1:     future versions of Bison will not add the ';'
-input.y:33.1: warning: a ';' might be needed at the end of action code [-Wdeprecated]
-input.y:33.1:     future versions of Bison will not add the ';'
-input.y:34.1: warning: a ';' might be needed at the end of action code [-Wdeprecated]
-input.y:34.1:     future versions of Bison will not add the ';'
-input.y:35.1: warning: a ';' might be needed at the end of action code [-Wdeprecated]
-input.y:35.1:     future versions of Bison will not add the ';'
-input.y:36.1: warning: a ';' might be needed at the end of action code [-Wdeprecated]
-input.y:36.1:     future versions of Bison will not add the ';'
-]])
-
-AT_MATCHES_CHECK([input.c], [[/\* TEST:N:2 \*/ \}$]],       [[3]])
-AT_MATCHES_CHECK([input.c], [[/\* TEST:Y:2 \*/ ;\}$]],      [[6]])
-AT_MATCHES_CHECK([input.c], [[// TEST:N:1 [;{}]*\n\}$]],    [[6]])
-AT_MATCHES_CHECK([input.c], [[// TEST:Y:1 [;{}]*\n;\}$]],  [[12]])
-AT_MATCHES_CHECK([input.c], [[#define TEST_MACRO_N \\\n\[\]"broken\\" \$ \@ \$\$ \@\$ \[\];\\\nstring;"\}]], [[2]])
-
-AT_CLEANUP
-
-
 ## -------------------------------------------------- ##
 ## Destroying lookahead assigned by semantic action.  ##
 ## -------------------------------------------------- ##
@@ -1706,7 +1718,7 @@ AT_DATA_GRAMMAR([input.y],
 // that has set yychar might not always return normally.  Instead,
 // skeletons must translate before every use of yytoken.
 start: 'a' accept { USE($1); } ;
-accept: /*empty*/ {
+accept: %empty {
   assert (yychar == YYEMPTY);
   yychar = 'b';
   YYACCEPT;