From 26eb4f0bdcd78ea56c05c49363b9fbe6072c425c Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Mon, 9 Dec 2013 15:40:07 +0100 Subject: [PATCH 1/4] symbol: provide an easy means to compare them in source order * src/symtab.c (symbols_sort): New. (user_token_number_redeclaration): Taken from here. --- src/symtab.c | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/src/symtab.c b/src/symtab.c index 1c2372c1..1b446119 100644 --- a/src/symtab.c +++ b/src/symtab.c @@ -100,6 +100,28 @@ symbol_new (uniqstr tag, location loc) return res; } +/* If needed, swap first and second so that first has the earliest + location (according to location_cmp). + + Many symbol features (e.g., user token numbers) are not assigned + during the parsing, but in a second step, via a traversal of the + symbol table sorted on tag. + + However, error messages make more sense if we keep the first + declaration first. +*/ + +static +void symbols_sort (symbol **first, symbol **second) +{ + if (0 < location_cmp ((*first)->location, (*second)->location)) + { + symbol* tmp = *first; + *first = *second; + *second = tmp; + } +} + char const * code_props_type_string (code_props_type kind) { @@ -587,17 +609,7 @@ static void user_token_number_redeclaration (int num, symbol *first, symbol *second) { unsigned i = 0; - /* User token numbers are not assigned during the parsing, but in a - second step, via a traversal of the symbol table sorted on tag. - - However, error messages make more sense if we keep the first - declaration first. */ - if (location_cmp (first->location, second->location) > 0) - { - symbol* tmp = first; - first = second; - second = tmp; - } + symbols_sort (&first, &second); complain_indent (&second->location, complaint, &i, _("user token number %d redeclaration for %s"), num, second->tag); From 461f1516f8d301f5be532e496f6def0d15e502ed Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Mon, 9 Dec 2013 15:26:52 +0100 Subject: [PATCH 2/4] diagnostics: fix the order of multiple declarations reports On %token FOO "foo" %printer {} "foo" %printer {} FOO we report /tmp/foo.yy:2.10-11: error: %printer redeclaration for FOO %printer {} "foo" ^^ /tmp/foo.yy:3.10-11: previous declaration %printer {} FOO ^^ * src/symtab.c (locations_sort): New. Use it. * tests/input.at (Invalid Aliases): Stress the order of diagnostics. --- NEWS | 21 ++++++++ src/symtab.c | 15 ++++++ tests/input.at | 132 +++++++++++++++++++++++++++++++++++++------------ 3 files changed, 136 insertions(+), 32 deletions(-) diff --git a/NEWS b/NEWS index 39322da8..689c5019 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,27 @@ GNU Bison NEWS * Noteworthy changes in release ?.? (????-??-??) [?] +** Bug fixes + +*** Redeclarations are reported in proper order + + On + + %token FOO "foo" + %printer {} "foo" + %printer {} FOO + + bison used to report: + + /tmp/foo.yy:2.10-11: error: %printer redeclaration for FOO + %printer {} "foo" + ^^ + /tmp/foo.yy:3.10-11: previous declaration + %printer {} FOO + ^^ + + Now, the "previous" declaration is always the first one. + * Noteworthy changes in release 3.0.2 (2013-12-05) [stable] diff --git a/src/symtab.c b/src/symtab.c index 1b446119..acbc58df 100644 --- a/src/symtab.c +++ b/src/symtab.c @@ -122,6 +122,19 @@ void symbols_sort (symbol **first, symbol **second) } } +/* Likewise, for locations. */ + +static +void locations_sort (location *first, location *second) +{ + if (0 < location_cmp (*first, *second)) + { + location tmp = *first; + *first = *second; + *second = tmp; + } +} + char const * code_props_type_string (code_props_type kind) { @@ -232,6 +245,7 @@ symbol_redeclaration (symbol *s, const char *what, location first, location second) { unsigned i = 0; + locations_sort (&first, &second); complain_indent (&second, complaint, &i, _("%s redeclaration for %s"), what, s->tag); i += SUB_INDENT; @@ -244,6 +258,7 @@ semantic_type_redeclaration (semantic_type *s, const char *what, location first, location second) { unsigned i = 0; + locations_sort (&first, &second); complain_indent (&second, complaint, &i, _("%s redeclaration for <%s>"), what, s->tag); i += SUB_INDENT; diff --git a/tests/input.at b/tests/input.at index 4ddf955a..28a0a038 100644 --- a/tests/input.at +++ b/tests/input.at @@ -654,50 +654,118 @@ AT_CLEANUP AT_SETUP([Incompatible Aliases]) -AT_DATA([input.y], -[[%token foo "foo" +m4_pushdef([AT_TEST], +[AT_DATA([input.y], [$1]) +AT_BISON_CHECK([-fcaret input.y], [1], [], [$2]) +]) -%type foo -%printer {bar} foo -%destructor {bar} foo -%left foo - -%type "foo" -%printer {baz} "foo" -%destructor {baz} "foo" -%left "foo" +# Use the string-alias first to check the order between "first +# declaration" and second. +AT_TEST([[%token foo "foo" +%type "foo" +%type foo %% exp: foo; +]], +[[input.y:3.7-11: error: %type redeclaration for foo + %type foo + ^^^^^ +input.y:2.7-11: previous declaration + %type "foo" + ^^^^^ ]]) -AT_BISON_CHECK([-fcaret input.y], [1], [], -[[input.y:8.7-11: error: %type redeclaration for foo - %type "foo" - ^^^^^ -input.y:3.7-11: previous declaration - %type foo - ^^^^^ -input.y:10.13-17: error: %destructor redeclaration for foo - %destructor {baz} "foo" - ^^^^^ -input.y:5.13-17: previous declaration - %destructor {bar} foo - ^^^^^ -input.y:9.10-14: error: %printer redeclaration for foo - %printer {baz} "foo" +AT_TEST([[%token foo "foo" +%printer {bar} "foo" +%printer {baz} foo +%% +exp: foo; +]], +[[input.y:3.10-14: error: %printer redeclaration for foo + %printer {baz} foo ^^^^^ -input.y:4.10-14: previous declaration - %printer {bar} foo +input.y:2.10-14: previous declaration + %printer {bar} "foo" ^^^^^ -input.y:11.1-5: error: %left redeclaration for foo - %left "foo" +]]) + +AT_TEST([[%token foo "foo" +%destructor {bar} "foo" +%destructor {baz} foo +%% +exp: foo; +]], +[[input.y:3.13-17: error: %destructor redeclaration for foo + %destructor {baz} foo + ^^^^^ +input.y:2.13-17: previous declaration + %destructor {bar} "foo" + ^^^^^ +]]) + +AT_TEST([[%token foo "foo" +%left "foo" +%left foo +%% +exp: foo; +]], +[[input.y:3.1-5: error: %left redeclaration for foo + %left foo ^^^^^ -input.y:6.1-5: previous declaration - %left foo +input.y:2.1-5: previous declaration + %left "foo" ^^^^^ ]]) +# This time, declare the alias after its use. + +# Precedence/associativity. +AT_TEST([[%left "foo" +%left foo +%token foo "foo" +%% +exp: foo; +]], +[[input.y:2.1-5: error: %left redeclaration for foo + %left foo + ^^^^^ +input.y:1.1-5: previous declaration + %left "foo" + ^^^^^ +]]) + +# Printer. +AT_TEST([[%printer {} "foo" +%printer {} foo +%token foo "foo" +%% +exp: foo; +]], +[[input.y:2.10-11: error: %printer redeclaration for foo + %printer {} foo + ^^ +input.y:1.10-11: previous declaration + %printer {} "foo" + ^^ +]]) + +# Destructor. +AT_TEST([[%destructor {} "foo" +%destructor {} foo +%token foo "foo" +%% +exp: foo; +]], +[[input.y:2.13-14: error: %destructor redeclaration for foo + %destructor {} foo + ^^ +input.y:1.13-14: previous declaration + %destructor {} "foo" + ^^ +]]) + +m4_popdef([AT_TEST]) AT_CLEANUP From 85d57e27d26ff11a99ee6d82d3b9d34c16f6efce Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Mon, 9 Dec 2013 16:14:15 +0100 Subject: [PATCH 3/4] package: install README and the like in docdir * Makefile.am: here. --- Makefile.am | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Makefile.am b/Makefile.am index 339a3c63..becd1d39 100644 --- a/Makefile.am +++ b/Makefile.am @@ -24,8 +24,10 @@ SUBDIRS = po runtime-po . aclocaldir = @aclocaldir@ aclocal_DATA = m4/bison-i18n.m4 -EXTRA_DIST = .prev-version .version \ - cfg.mk ChangeLog-1998 ChangeLog-2012 PACKAGING +EXTRA_DIST = .prev-version .version cfg.mk PACKAGING \ + ChangeLog-1998 ChangeLog-2012 ChangeLog + +dist_doc_DATA = AUTHORS COPYING NEWS README THANKS TODO ## Running the bison from this tarball. To generate our own parser, ## but also to run the tests. Of course, you ought to keep a sane From b167e7ba0dd66dca7888782363fc97a3e282f8ef Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Mon, 9 Dec 2013 16:29:05 +0100 Subject: [PATCH 4/4] package: install the examples Currently, we do not install the various examples extracted from the documentation. Let's do it, as they are useful starting points. * configure.ac: When --enable-gcc-warnings is set, enable ENABLE_GCC_WARNINGS. * examples/extexi: No longer issue synclines by default. * examples/local.mk: Except if ENABLE_GCC_WARNINGS. * examples/calc++/local.mk, examples/mfcalc/local.mk, * examples/rpcalc/local.mk: Install the example files. --- NEWS | 14 ++++++++++++++ configure.ac | 5 ++++- examples/calc++/local.mk | 32 ++++++++++++++++++++------------ examples/extexi | 21 ++++++++++++++------- examples/local.mk | 5 ++++- examples/mfcalc/local.mk | 7 +++++++ examples/rpcalc/local.mk | 7 +++++++ 7 files changed, 70 insertions(+), 21 deletions(-) diff --git a/NEWS b/NEWS index 689c5019..e6521bf9 100644 --- a/NEWS +++ b/NEWS @@ -24,6 +24,20 @@ GNU Bison NEWS Now, the "previous" declaration is always the first one. +** Documentation + + Bison now installs various files in its docdir (which defaults to + '/usr/local/share/doc/bison'), including the three fully blown examples + extracted from the documentation: + + - rpcalc + Reverse polish calculator, a simple introductory example. + - mfcalc + Multi-function Calc, a calculator with memory and functions and located + error messages. + - calc++ + a calculator in C++ using variant support and token constructors. + * Noteworthy changes in release 3.0.2 (2013-12-05) [stable] ** Bug fixes diff --git a/configure.ac b/configure.ac index f3dcdfd8..2658d73e 100644 --- a/configure.ac +++ b/configure.ac @@ -71,12 +71,15 @@ AC_CACHE_CHECK([whether pragma GCC diagnostic push works], CFLAGS=$save_CFLAGS]) AC_ARG_ENABLE([gcc-warnings], -[ --enable-gcc-warnings turn on lots of GCC warnings (not recommended)], +[ --enable-gcc-warnings turn on lots of GCC warnings (not recommended). + Also, issue synclines from the examples/ to + the corresponding source in the Texinfo doc.], [case $enable_gcc_warnings in yes|no) ;; *) AC_MSG_ERROR([invalid value for --gcc-warnings: $enable_gcc_warnings]);; esac], [enable_gcc_warnings=no]) +AM_CONDITIONAL([ENABLE_GCC_WARNINGS], [test "$enable_gcc_warnings" = yes]) if test "$enable_gcc_warnings" = yes; then warn_common='-Wall-Wextra -Wno-sign-compare -Wcast-align -Wdocumentation -Wformat -Wpointer-arith -Wwrite-strings' diff --git a/examples/calc++/local.mk b/examples/calc++/local.mk index d920e634..018d007a 100644 --- a/examples/calc++/local.mk +++ b/examples/calc++/local.mk @@ -27,11 +27,11 @@ SUFFIXES += .yy .stamp $(AM_V_at)$(YACCCOMPILE) -o $*.cc $< $(AM_V_at)mv -f $@.tmp $@ -$(calc_sources_generated): %D%/calc++-parser.stamp +$(calcxx_sources_generated): %D%/calc++-parser.stamp @test -f $@ || rm -f %D%/calc++-parser.stamp @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) %D%/calc++-parser.stamp CLEANFILES += \ - $(calc_sources_generated) \ + $(calcxx_sources_generated) \ %D%/calc++-parser.output \ %D%/calc++-parser.stamp \ %D%/calc++-scanner.cc @@ -42,31 +42,31 @@ CLEANFILES += \ ## -------------------- ## # Avoid using BUILT_SOURCES which is too global. -$(%C%_calc___OBJECTS): $(calc_sources_generated) +$(%C%_calc___OBJECTS): $(calcxx_sources_generated) -calc_sources_extracted = \ +calcxx_sources_extracted = \ %D%/calc++-driver.cc \ %D%/calc++-driver.hh \ %D%/calc++-scanner.ll \ %D%/calc++.cc -calc_extracted = \ - $(calc_sources_extracted) \ +calcxx_extracted = \ + $(calcxx_sources_extracted) \ %D%/calc++-parser.yy -extracted += $(calc_extracted) -calc_sources_generated = \ +extracted += $(calcxx_extracted) +calcxx_sources_generated = \ %D%/calc++-parser.cc \ %D%/calc++-parser.hh \ %D%/location.hh \ %D%/position.hh \ %D%/stack.hh -calc_sources = \ - $(calc_sources_extracted) \ - $(calc_sources_generated) +calcxx_sources = \ + $(calcxx_sources_extracted) \ + $(calcxx_sources_generated) if FLEX_CXX_WORKS check_PROGRAMS += %D%/calc++ nodist_%C%_calc___SOURCES = \ - $(calc_sources) + $(calcxx_sources) %C%_calc___CPPFLAGS = -I$(top_builddir)/%D% %C%_calc___CXXFLAGS = $(AM_CXXFLAGS) $(FLEX_SCANNER_CXXFLAGS) @@ -74,3 +74,11 @@ dist_TESTS += %D%/calc++.test else EXTRA_DIST += %D%/calc++.test endif + + +## ------------ ## +## Installing. ## +## ------------ ## + +calcxxdir = $(docdir)/examples/calc++ +calcxx_DATA = $(calcxx_extracted) diff --git a/examples/extexi b/examples/extexi index 24a005eb..d4ce653d 100755 --- a/examples/extexi +++ b/examples/extexi @@ -19,7 +19,7 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -# Usage: extexi input-file.texi ... -- [FILES to extract] +# Usage: extexi [OPTION...] input-file.texi ... -- [FILES to extract] # Look for @example environments preceded with lines such as: # @@ -35,6 +35,9 @@ use strict; +# Whether we generate synclines. +my $synclines = 0; + # normalize($block) # ----------------- # Remove Texinfo mark up. @@ -102,7 +105,7 @@ sub process ($) { # Bison supports synclines, but not Flex. $input .= sprintf ("#line %s \"$in\"\n", $. + 1) - if $file =~ /\.[chy]*$/; + if $synclines && $file =~ /\.[chy]*$/; next; } elsif (/^\@end (small)?example$/) @@ -136,15 +139,19 @@ my @input; my $seen_dash = 0; for my $arg (@ARGV) { - if ($arg eq '--') - { - $seen_dash = 1; - } - elsif ($seen_dash) + if ($seen_dash) { use File::Basename; $file_wanted{basename($arg)} = $arg; } + elsif ($arg eq '--') + { + $seen_dash = 1; + } + elsif ($arg eq '--synclines') + { + $synclines = 1; + } else { push @input, $arg; diff --git a/examples/local.mk b/examples/local.mk index 9f7863c1..8274e007 100644 --- a/examples/local.mk +++ b/examples/local.mk @@ -25,7 +25,10 @@ AM_CXXFLAGS = \ doc = $(top_srcdir)/doc/bison.texi extexi = $(top_srcdir)/%D%/extexi -extract = VERSION="$(VERSION)" $(PERL) $(extexi) $(doc) -- +if ENABLE_GCC_WARNINGS +extexiFLAGS = --synclines +endif +extract = VERSION="$(VERSION)" $(PERL) $(extexi) $(extexiFLAGS) $(doc) -- extracted = CLEANFILES += $(extracted) %D%/extracted.stamp %D%/extracted.stamp: $(doc) $(extexi) diff --git a/examples/mfcalc/local.mk b/examples/mfcalc/local.mk index 97ea63b3..361a4a5f 100644 --- a/examples/mfcalc/local.mk +++ b/examples/mfcalc/local.mk @@ -30,3 +30,10 @@ nodist_%C%_mfcalc_SOURCES = $(mfcalc_sources) %C%_mfcalc_CPPFLAGS = -I$(top_builddir)/%D% dist_TESTS += %D%/mfcalc.test + +## ------------ ## +## Installing. ## +## ------------ ## + +mfcalcdir = $(docdir)/examples/mfcalc +mfcalc_DATA = $(mfcalc_extracted) diff --git a/examples/rpcalc/local.mk b/examples/rpcalc/local.mk index 97f35356..125bb3ba 100644 --- a/examples/rpcalc/local.mk +++ b/examples/rpcalc/local.mk @@ -30,3 +30,10 @@ nodist_%C%_rpcalc_SOURCES = $(rpcalc_sources) %C%_rpcalc_CPPFLAGS = -I$(top_builddir)/%D% dist_TESTS += %D%/rpcalc.test + +## ------------ ## +## Installing. ## +## ------------ ## + +rpcalcdir = $(docdir)/examples/rpcalc +rpcalc_DATA = $(rpcalc_extracted)