bison-patches
[Top][All Lists]
Advanced

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

fixits: report duplicate %yacc directives


From: Akim Demaille
Subject: fixits: report duplicate %yacc directives
Date: Wed, 16 Jan 2019 08:46:16 +0100

   commit b6b397b7f0a764f29f8b60f7d9eb7696473aa556
   Author: Akim Demaille <address@hidden>
   Date:   Wed Jan 16 07:45:54 2019 +0100
      fixits: report duplicate %yacc directives
      We should use -ffixit and --update to clean files with duplicate
      directives.  And we should complain only once about duplicate
   obsolete
      directives: keep only the "duplicate" warning.  Let's start with
   %yacc.
      For instance on:
          %fixed-output_files
          %fixed-output-files
          %yacc
          %%
          exp:
      This run of bison:
          $ bison /tmp/foo.y -u
          foo.y:1.1-19: warning: deprecated directive, use
   '%fixed-output-files' [-Wdeprecated]
           %fixed-output_files
           ^~~~~~~~~~~~~~~~~~~
          foo.y:2.1-19: warning: duplicate directive [-Wother]
           %fixed-output-files
           ^~~~~~~~~~~~~~~~~~~
          foo.y:1.1-19: previous declaration
           %fixed-output_files
           ^~~~~~~~~~~~~~~~~~~
          foo.y:3.1-5: warning: duplicate directive [-Wother]
           %yacc
           ^~~~~
          foo.y:1.1-19: previous declaration
           %fixed-output_files
           ^~~~~~~~~~~~~~~~~~~
          bison: file 'foo.y' was updated (backup: 'foo.y~')
      gives:
          %fixed-output-files
          %%
          exp:
      * src/location.h, src/location.c (location_empty): New.
      * src/complain.h, src/complain.c (duplicate_directive): New.
      * src/getargs.h, src/getargs.c (yacc_flag): Instead of a Boolean, be
      the location of the definition.
      Update dependencies.
      * src/scan-gram.l (%yacc, %fixed-output-files): Move the handling of
      its warnings to...
      * src/parse-gram.y (do_yacc): This new function.
      * tests/input.at (Deprecated Directives): Adjust expectations.
   diff --git a/src/complain.c b/src/complain.c
   index 3f8c5118..6b6b2c0b 100644
   --- a/src/complain.c
   +++ b/src/complain.c
   @@ -399,6 +399,19 @@ deprecated_directive (location const *loc, char
   const *old, char const *upd)
       fixits_register (loc, upd);
   }
   +void
   +duplicate_directive (char const *directive,
   +                     location first, location second)
   +{
   +  if (feature_flag & feature_caret)
   +    complain (&second, Wother, _("duplicate directive"));
   +  else
   +    complain (&second, Wother, _("duplicate directive: %s"),
   directive);
   +  unsigned i = SUB_INDENT;
   +  complain_indent (&first, complaint, &i, _("previous declaration"));
   +  fixits_register (&second, "");
   +}
   +
   void
   duplicate_rule_directive (char const *directive,
                             location first, location second)
   diff --git a/src/complain.h b/src/complain.h
   index e5f6d7e6..266992f6 100644
   --- a/src/complain.h
   +++ b/src/complain.h
   @@ -126,6 +126,10 @@ void bison_directive (location const *loc, char
   const *directive);
   void deprecated_directive (location const *loc,
                              char const *obsolete, char const *updated);
   +/** Report a repeated directive.  */
   +void duplicate_directive (char const *directive,
   +                          location first, location second);
   +
   /** Report a repeated directive for a rule.  */
   void duplicate_rule_directive (char const *directive,
                                  location first, location second);
   diff --git a/src/files.c b/src/files.c
   index 7c33b23d..f805524c 100644
   --- a/src/files.c
   +++ b/src/files.c
   @@ -285,7 +285,7 @@ compute_file_name_parts (void)
                         last_component (spec_file_prefix) -
   spec_file_prefix);
             all_but_tab_ext = xstrdup (spec_file_prefix);
           }
   -      else if (yacc_flag)
   +      else if (! location_empty (yacc_loc))
           {
             /* If --yacc, then the output is 'y.tab.c'.  */
             dir_prefix = xstrdup ("");
   @@ -306,7 +306,7 @@ compute_file_name_parts (void)
           all_but_ext = xstrdup (all_but_tab_ext);
         /* Compute the extensions from the grammar file name.  */
   -      if (ext && !yacc_flag)
   +      if (ext && location_empty (yacc_loc))
           compute_exts_from_gf (ext);
       }
   }
   diff --git a/src/getargs.c b/src/getargs.c
   index 83ebcb09..a66e4c66 100644
   --- a/src/getargs.c
   +++ b/src/getargs.c
   @@ -41,7 +41,7 @@ bool graph_flag = false;
   bool xml_flag = false;
   bool no_lines_flag = false;
   bool token_table_flag = false;
   -bool yacc_flag = false; /* for -y */
   +location yacc_loc = EMPTY_LOCATION_INIT;
   bool update_flag = false; /* for -u */
   bool nondeterministic_parser = false;
   @@ -709,7 +709,7 @@ getargs (int argc, char *argv[])
         case 'y':
           warning_argmatch ("error=yacc", 0, 6);
   -        yacc_flag = true;
   +        yacc_loc = command_line_location ();
           break;
         case LOCATIONS_OPTION:
   diff --git a/src/getargs.h b/src/getargs.h
   index f44f2183..c5adb848 100644
   --- a/src/getargs.h
   +++ b/src/getargs.h
   @@ -39,7 +39,7 @@ extern bool graph_flag;                 /* for -g */
   extern bool xml_flag;                   /* for -x */
   extern bool no_lines_flag;              /* for -l */
   extern bool token_table_flag;           /* for -k */
   -extern bool yacc_flag;                  /* for -y */
   +extern location yacc_loc;               /* for -y */
   extern bool update_flag;                /* for -u */
   /* GLR_PARSER is true if the input file says to use the GLR
   diff --git a/src/location.c b/src/location.c
   index 4ec12a70..6876890c 100644
   --- a/src/location.c
   +++ b/src/location.c
   @@ -216,6 +216,13 @@ location_caret (location loc, FILE *out)
     }
   }
   +bool
   +location_empty (location loc)
   +{
   +  return !loc.start.file && !loc.start.line && !loc.start.column
   +    && !loc.end.file && !loc.end.line && !loc.end.column;
   +}
   +
   void
   boundary_set_from_string (boundary *bound, char *loc_str)
   {
   diff --git a/src/location.h b/src/location.h
   index 26d6af61..39e0507d 100644
   --- a/src/location.h
   +++ b/src/location.h
   @@ -126,6 +126,9 @@ location_cmp (location a, location b)
     return res;
   }
   +/* Whether this is the empty location.  */
   +bool location_empty (location loc);
   +
   /* LOC_STR must be formatted as 'file:line.column', it will be
   modified.  */
   void boundary_set_from_string (boundary *bound, char *loc_str);
   diff --git a/src/output.c b/src/output.c
   index 6a9553c5..da600ae5 100644
   --- a/src/output.c
   +++ b/src/output.c
   @@ -665,7 +665,7 @@ prepare (void)
     MUSCLE_INSERT_BOOL ("tag_seen_flag", tag_seen);
     MUSCLE_INSERT_BOOL ("token_table_flag", token_table_flag);
     MUSCLE_INSERT_BOOL ("use_push_for_pull_flag",
   use_push_for_pull_flag);
   -  MUSCLE_INSERT_BOOL ("yacc_flag", yacc_flag);
   +  MUSCLE_INSERT_BOOL ("yacc_flag", !location_empty (yacc_loc));
     /* File names.  */
     if (spec_name_prefix)
   diff --git a/src/parse-gram.y b/src/parse-gram.y
   index e0496d5a..aa1a450f 100644
   --- a/src/parse-gram.y
   +++ b/src/parse-gram.y
   @@ -95,6 +95,9 @@
     /* Handle a %skeleton directive.  */
     static void do_skeleton (location const *loc, char const *skel);
   +  /* Handle a %yacc directive.  */
   +  static void do_yacc (location const *loc, char const *directive);
   +
     static void gram_error (location const *, char const *);
     /* A string that describes a char (e.g., 'a' -> "'a'").  */
   @@ -201,8 +204,9 @@
   %type <uniqstr>
     BRACKETED_ID ID ID_COLON
   -  PERCENT_ERROR_VERBOSE PERCENT_FLAG PERCENT_NAME_PREFIX TAG
   -  tag tag.opt variable
   +  PERCENT_ERROR_VERBOSE PERCENT_FLAG PERCENT_NAME_PREFIX
   +  PERCENT_YACC
   +  TAG tag tag.opt variable
   %printer { fputs ($$, yyo); } <uniqstr>
   %printer { fprintf (yyo, "[%s]", $$); } BRACKETED_ID
   %printer { fprintf (yyo, "%s:", $$); } ID_COLON
   @@ -329,7 +333,7 @@ prologue_declaration:
   | "%skeleton" STRING            { do_skeleton (&@2, $2); }
   | "%token-table"                { token_table_flag = true; }
   | "%verbose"                    { report_flag |= report_states; }
   -| "%yacc"                       { yacc_flag = true; }
   +| "%yacc"                       { do_yacc (&@$, $1); }
   | error ";"                     { current_class = unknown_sym; yyerrok;
   }
   | /*FIXME: Err?  What is this horror doing here? */ ";"
   ;
   @@ -956,6 +960,25 @@ do_skeleton (location const *loc, char const
   *skel)
     skeleton_arg (skeleton_user, grammar_prio, *loc);
   }
   +static void
   +do_yacc (location const *loc, char const *directive)
   +{
   +  bison_directive (loc, directive);
   +  bool warned = false;
   +
   +  if (location_empty (yacc_loc))
   +    yacc_loc = *loc;
   +  else
   +    {
   +      duplicate_directive (directive, yacc_loc, *loc);
   +      warned = true;
   +    }
   +
   +  if (!warned
   +      && STRNEQ (directive, "%fixed-output-files")
   +      && STRNEQ (directive, "%yacc"))
   +    deprecated_directive (loc, directive, "%fixed-output-files");
   +}
   static void
   gram_error (location const *loc, char const *msg)
   diff --git a/src/scan-gram.l b/src/scan-gram.l
   index 2eaa1606..e1536f5c 100644
   --- a/src/scan-gram.l
   +++ b/src/scan-gram.l
   @@ -229,7 +229,7 @@ eqopt    ({sp}=)?
     "%expect"                         return BISON_DIRECTIVE (EXPECT);
     "%expect-rr"                      return BISON_DIRECTIVE (EXPECT_RR);
     "%file-prefix"                    return BISON_DIRECTIVE
   (FILE_PREFIX);
   -  "%fixed-output-files"             return BISON_DIRECTIVE (YACC);
   +  "%fixed-output-files"             RETURN_VALUE (PERCENT_YACC,
   uniqstr_new (yytext));
     "%initial-action"                 return BISON_DIRECTIVE
   (INITIAL_ACTION);
     "%glr-parser"                     return BISON_DIRECTIVE
   (GLR_PARSER);
     "%language"                       return BISON_DIRECTIVE (LANGUAGE);
   @@ -259,7 +259,7 @@ eqopt    ({sp}=)?
     "%type"                           return PERCENT_TYPE;
     "%union"                          return PERCENT_UNION;
     "%verbose"                        return BISON_DIRECTIVE (VERBOSE);
   -  "%yacc"                           return BISON_DIRECTIVE (YACC);
   +  "%yacc"                           RETURN_VALUE (PERCENT_YACC,
   uniqstr_new (yytext));
     /* Deprecated since Bison 3.0 (2013-07-25), but the warning is
        issued only since Bison 3.3. */
   @@ -274,7 +274,7 @@ eqopt    ({sp}=)?
     "%error"[-_]"verbose"             RETURN_VALUE
   (PERCENT_ERROR_VERBOSE, uniqstr_new (yytext));
     "%expect"[-_]"rr"                 DEPRECATED ("%expect-rr");
     "%file-prefix"{eqopt}             DEPRECATED ("%file-prefix");
   -  "%fixed"[-_]"output"[-_]"files"   DEPRECATED
   ("%fixed-output-files");
   +  "%fixed"[-_]"output"[-_]"files"   RETURN_VALUE (PERCENT_YACC,
   uniqstr_new (yytext));
     "%no"[-_]"default"[-_]"prec"      DEPRECATED ("%no-default-prec");
     "%no"[-_]"lines"                  DEPRECATED ("%no-lines");
     "%output"{eqopt}                  DEPRECATED ("%output");
   diff --git a/tests/input.at b/tests/input.at
   index f4a2cbbb..3314d680 100644
   --- a/tests/input.at
   +++ b/tests/input.at
   @@ -2526,8 +2526,12 @@ input.y:14.1-15.2: warning: deprecated
   directive: '%file-prefix\n =', use '%file
   fix-it:"input.y":{14:1-15:3}:"%file-prefix"
   input.y:17.1-19: warning: deprecated directive: '%fixed-output_files',
   use '%fixed-output-files' [-Wdeprecated]
   fix-it:"input.y":{17:1-17:20}:"%fixed-output-files"
   -input.y:18.1-19: warning: deprecated directive: '%fixed_output-files',
   use '%fixed-output-files' [-Wdeprecated]
   -fix-it:"input.y":{18:1-18:20}:"%fixed-output-files"
   +input.y:18.1-19: warning: duplicate directive: %fixed_output-files
   [-Wother]
   +input.y:17.1-19: previous declaration
   +fix-it:"input.y":{18:1-18:20}:""
   +input.y:19.1-19: warning: duplicate directive: %fixed-output-files
   [-Wother]
   +input.y:17.1-19: previous declaration
   +fix-it:"input.y":{19:1-19:20}:""
   input.y:20.1-19: warning: deprecated directive: '%name-prefix= "foo"',
   use '%define api.prefix {foo}' [-Wdeprecated]
   fix-it:"input.y":{20:1-20:20}:"%define api.prefix {foo}"
   input.y:21.1-16: warning: deprecated directive: '%no-default_prec', use
   '%no-default-prec' [-Wdeprecated]
   @@ -2550,12 +2554,12 @@ fix-it:"input.y":{29:1-29:19}:"%define
   api.prefix {bar}"
   input.y: warning: fix-its can be applied.  Rerun with option
   '--update'. [-Wother]
   ]])
   -AT_CHECK([[sed -e '/^fix-it:/d' errors-all >experr]])
   -AT_BISON_CHECK([[input.y]], [[1]], [[]], [experr])
   -
   AT_CHECK([cp errors-all experr])
   AT_BISON_CHECK([[-ffixit input.y]], [[1]], [[]], [experr])
   +AT_CHECK([[sed -e '/^fix-it:/d' errors-all >experr]])
   +AT_BISON_CHECK([[input.y]], [[1]], [[]], [experr])
   +
   # Update the input file.
   AT_CHECK([cp input.y input.y.orig])
   AT_CHECK([sed -e '/fix-it/d' <errors-all >experr])
   @@ -2583,8 +2587,6 @@ AT_CHECK([cat input.y], [],
   %file-prefix
   "bar"
   %fixed-output-files
   -%fixed-output-files
   -%fixed-output-files
   %define api.prefix {foo}
   %no-default-prec
   %no-default-prec
   @@ -2599,10 +2601,10 @@ exp : '0'
   ]])
   AT_BISON_CHECK([[-fcaret input.y]], [[1]], [],
   -[[input.y:27.1-24: error: %define variable 'api.prefix' redefined
   +[[input.y:25.1-24: error: %define variable 'api.prefix' redefined
    %define api.prefix {bar}
    ^~~~~~~~~~~~~~~~~~~~~~~~
   -input.y:19.1-24:     previous definition
   +input.y:17.1-24:     previous definition
    %define api.prefix {foo}
    ^~~~~~~~~~~~~~~~~~~~~~~~
   input.y: warning: fix-its can be applied.  Rerun with option
   '--update'. [-Wother]


reply via email to

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