From: Akim Demaille Date: Tue, 31 Jul 2012 09:50:18 +0000 (+0200) Subject: Merge branch 'maint' X-Git-Tag: v2.7.90~368 X-Git-Url: https://git.saurik.com/bison.git/commitdiff_plain/cb9ec4fada480554cf47810fee736997d64e7427?ds=inline;hp=-c Merge branch 'maint' * maint: use obstack_printf scanner: restore a missing start condition gnulib: update maint: post-release administrivia version 2.6.1 gnulib: update maint: fix some syntax-check issues tests: do not depend on __cplusplus to decide for C++ or C output Conflicts: NEWS bootstrap.conf cfg.mk lib/.gitignore --- cb9ec4fada480554cf47810fee736997d64e7427 diff --combined NEWS index fa1b948f,f940d8ed..bd47608b --- a/NEWS +++ b/NEWS @@@ -2,145 -2,9 +2,148 @@@ GNU Bison NEW * Noteworthy changes in release ?.? (????-??-??) [?] +** Incompatible changes + +*** Obsolete features + + Support for YYFAIL is removed, as announced since Bison 2.4.2. + Support for yystype and yyltype (instead of YYSTYPE and YYLTYPE) + is removed, as announced in Bison 1.875. + +** Warnings + +*** Warning categories are now displayed + + For instance: + + foo.y:4.6: warning: type clash on default action: != [-Wother] + +*** Useless semantic types + + Bison now warns about useless (uninhabited) semantic types. Since + semantic types are not declared to Bison (they are defined in the opaque + %union structure), it is %printer/%destructor directives about useless + types that trigger the warning: + + %token term + %type nterm + %printer {} + %destructor {} + %% + nterm: term { $$ = $1; }; + + 3.28-34: warning: type is used, but is not associated to any symbol + 4.28-34: warning: type is used, but is not associated to any symbol + +*** Undeclared symbols + + Bison used to raise an error for %printer and %destructor directives for + undefined symbols. + + %printer {} symbol1 + %destructor {} symbol2 + %% + exp: "a"; + + This is now only a warning. + +*** Useless destructors or printers + + Bison now warns about useless destructors or printers. In the following + example, the printer for , and the destructor for are + useless: all symbols of (token1) already have a printer, and all + symbols of type (token2) already have a destructor. + + %token token1 + token2 + token3 + token4 + %printer {} token1 + %destructor {} token2 + +** Additional yylex/yyparse arguments + + The new directive %param declares additional arguments to both yylex and + yyparse. The %lex-param, %parse-param, and %param directives support one + or more arguments. Instead of + + %lex-param {arg1_type *arg1} + %lex-param {arg2_type *arg2} + %parse-param {arg1_type *arg1} + %parse-param {arg2_type *arg2} + + one may now declare + + %param {arg1_type *arg1} {arg2_type *arg2} + +** Java skeleton improvements + + The constants for token names were moved to the Lexer interface. + Also, it is possible to add code to the parser's constructors using + "%code init" and "%define init_throws". + +** C++ skeletons improvements + +*** parser header (%defines) is no longer mandatory (lalr1.cc) + + In which case, if needed, the support classes are defined in the generated + parser, instead of additional files (location.hh, position.hh and + stack.hh). + +*** locations are no longer mandatory (lalr1.cc, glr.cc) + + Both lalr1.cc and glr.cc no longer require %location. + +*** syntax_error exception (lalr1.cc) + + The C++ parser features a syntax_error exception, which can be + thrown from the scanner or from user rules to raise syntax errors. + This facilitates reporting errors caught in sub-functions (e.g., + rejecting too large integral literals from a conversion function + used by the scanner, or rejecting invalid combinations from a + factory invoked by the user actions). + +** Variable api.tokens.prefix + + The variable api.tokens.prefix changes the way tokens are identified in + the generated files. This is especially useful to avoid collisions + with identifiers in the target language. For instance + + %token FILE for ERROR + %define api.tokens.prefix "TOK_" + %% + start: FILE for ERROR; + + will generate the definition of the symbols TOK_FILE, TOK_for, and + TOK_ERROR in the generated sources. In particular, the scanner must + use these prefixed token names, although the grammar itself still + uses the short names (as in the sample rule given above). + +** Variable api.namespace + + The "namespace" variable is renamed "api.namespace". Backward + compatibility is ensured, but upgrading is recommended. + +** Variable parse.error + + The variable error controls the verbosity of error messages. The + use of the %error-verbose directive is deprecated in favor of + %define parse.error "verbose". + +** Semantic predicates + + The new, experimental, semantic-predicate feature allows actions of + the form %?{ BOOLEAN-EXPRESSION }, which cause syntax errors (as for + YYERROR) if the expression evaluates to 0, and are evaluated immediately + in GLR parsers, rather than being deferred. The result is that they + allow the programmer to prune possible parses based on the values of + run-time expressions. + +* Noteworthy changes in release ?.? (????-??-??) [?] + + + * Noteworthy changes in release 2.6.1 (2012-07-30) [stable] + Bison no longer executes user-specified M4 code when processing a grammar. ** Future Changes @@@ -179,7 -43,7 +182,7 @@@ * Noteworthy changes in release 2.6 (2012-07-19) [stable] -** Future Changes +** Future changes: The next major release of Bison will drop support for the following deprecated features. Please report disagreements to bug-bison@gnu.org. @@@ -1980,8 -1844,7 +1983,8 @@@ along with this program. If not, see < LocalWords: namespaces strerror const autoconfiguration Dconst Autoconf's FDL LocalWords: Automake TMPDIR LESSEQ ylwrap endif yydebug YYTOKEN YYLSP ival hh LocalWords: extern YYTOKENTYPE TOKENTYPE yytokentype tokentype STYPE lval pdf - LocalWords: lang yyoutput dvi html ps POSIX lvalp llocp + LocalWords: lang yyoutput dvi html ps POSIX lvalp llocp Wother nterm arg init + LocalWords: TOK Local Variables: mode: outline diff --combined bootstrap.conf index 486268d7,165d5e7d..e90cf12d --- a/bootstrap.conf +++ b/bootstrap.conf @@@ -23,19 -23,18 +23,22 @@@ gnulib_modules= error extensions fdl fopen-safer getopt-gnu gettext git-version-gen gitlog-to-changelog gpl-3.0 hash inttypes isnan javacomp-script - javaexec-script ldexpl malloc-gnu mbschr mbsrchr + javaexec-script ldexpl malloc-gnu - mbswidth obstack perror progname + mbswidth + obstack + obstack-printf + perror progname quote quotearg readme-release realloc-posix spawn-pipe stdbool stpcpy strdup-posix strerror strtoul strverscmp unistd unistd-safer unlocked-io update-copyright unsetenv verify warnings - xalloc xalloc-die xmemdup0 xstrndup + xalloc + xalloc-die + xconcat-filename + xmemdup0 + xstrndup fprintf-posix printf-posix snprintf-posix sprintf-posix vsnprintf-posix vsprintf-posix @@@ -45,9 -44,9 +48,9 @@@ XGETTEXT_OPTIONS=$XGETTEXT_OPTIONS'\\\ --from-code=UTF-8\\\ --flag=asprintf:2:c-format\\\ - --flag=complain:1:c-format --flag=complain_at:2:c-format\\\ - --flag=fatal:1:c-format --flag=fatal_at:2:c-format\\\ - --flag=warn:1:c-format --flag=warn_at:2:c-format\\\ + --flag=complain:2:c-format\\\ + --flag=complain_at:3:c-format\\\ + --flag=complain_at_indent:4:c-format\\\ --flag=unexpected_end:2:c-format\\\ ' XGETTEXT_OPTIONS_RUNTIME=$XGETTEXT_OPTIONS'\\\ @@@ -75,9 -74,6 +78,9 @@@ gnulib_tool_option_extras='--symlink -- bootstrap_post_import_hook() { + # Massage lib/gnulib.mk before using it later in the bootstrapping process. + etc/prefix-gnulib-mk --lib-name=$gnulib_name lib/$gnulib_mk + # Ensure that ChangeLog exists, for automake. test -f ChangeLog || touch ChangeLog } diff --combined cfg.mk index f1caf313,53855aef..af1e09e8 --- a/cfg.mk +++ b/cfg.mk @@@ -36,9 -36,15 +36,9 @@@ url_dir_list = ftp://$(gnu_rel_host)/gnu/bison # Tests not to run as part of "make distcheck". -# Exclude changelog-check here so that there's less churn in ChangeLog -# files -- otherwise, you'd need to have the upcoming version number -# at the top of the file for each `make distcheck' run. -local-checks-to-skip = \ - changelog-check \ +local-checks-to-skip = \ sc_immutable_NEWS \ - sc_prohibit_always_true_header_tests \ - sc_prohibit_atoi_atof \ - sc_prohibit_strcmp + sc_prohibit_atoi_atof # The local directory containing the checked-out copy of gnulib used in # this release. Used solely to get a date for the "announcement" target. @@@ -59,14 -65,16 +59,16 @@@ exclude = $(call exclude, \ bindtextdomain=^lib/main.c$$ \ program_name=^lib/main.c$$ \ - prohibit_always-defined_macros=^data/yacc.c|^djgpp/ \ + prohibit_always-defined_macros=^data/yacc.c$$|^djgpp/ \ prohibit_always-defined_macros+=?|^lib/timevar.c$$ \ prohibit_always-defined_macros+=?|^src/(parse-gram.c|system.h)$$ \ prohibit_always-defined_macros+=?|^tests/regression.at$$ \ prohibit_defined_have_decl_tests=?|^lib/timevar.c$$ \ - prohibit_empty_lines_at_EOF=^src/parse-gram.[ch]$$ \ + prohibit_empty_lines_at_EOF=^src/parse-gram.h$$ \ + prohibit_magic_number_exit=^doc/bison.texi$$ \ + prohibit_magic_number_exit+=?|^tests/(conflicts|regression).at$$ \ + prohibit_strcmp=^doc/bison\.texi$$ \ require_config_h_first=^(lib/yyerror|data/(glr|yacc))\.c$$ \ space_tab=^tests/(input|c\+\+)\.at$$ \ - trailing_blank=^src/parse-gram.[ch]$$ \ unmarked_diagnostics=^(djgpp/|doc/bison.texi$$) \ ) diff --combined lib/.gitignore index 8e0e2096,964d7f45..a448e841 --- a/lib/.gitignore +++ b/lib/.gitignore @@@ -35,6 -35,6 +35,8 @@@ /close.c /closeout.c /closeout.h ++/concat-filename.c ++/concat-filename.h /config.charset /config.h /config.in.h @@@ -62,6 -62,6 +64,7 @@@ /fd-hook.h /fd-safer-flag.c /fd-safer.c ++/filename.h /float+.h /float.c /float.h @@@ -109,7 -109,9 +112,7 @@@ /mbchar.c /mbchar.h /mbrtowc.c -/mbschr.c /mbsinit.c -/mbsrchr.c /mbswidth.c /mbswidth.h /mbuiter.h @@@ -123,6 -125,6 +126,7 @@@ /nonblocking.h /obstack.c /obstack.h ++/obstack_printf.c /open.c /pathmax.h /perror.c @@@ -223,6 -225,6 +227,7 @@@ /sys_socket.in.h /sys_stat.h /sys_stat.in.h ++/sys_types.in.h /sys_wait.h /sys_wait.in.h /sysexits.in.h @@@ -259,14 -261,11 +264,10 @@@ /xalloc-die.c /xalloc-oversized.h /xalloc.h ++/xconcat-filename.c /xmalloc.c ++/xmemdup0.c ++/xmemdup0.h /xsize.h /xstrndup.c /xstrndup.h --/xmemdup0.c --/xmemdup0.h --/sys_types.in.h - /concat-filename.c - /concat-filename.h - /filename.h - /xconcat-filename.c -/obstack_printf.c diff --combined m4/.gitignore index 875400a9,797ed6df..c6a84ce8 --- a/m4/.gitignore +++ b/m4/.gitignore @@@ -51,7 -51,6 +51,7 @@@ /inline.m4 /intdiv0.m4 /intl.m4 +/intl.m4~ /intldir.m4 /intlmacosx.m4 /intmax.m4 @@@ -103,7 -102,6 +103,7 @@@ /perror.m4 /pipe2.m4 /po.m4 +/po.m4~ /posix_spawn.m4 /printf-frexp.m4 /printf-frexpl.m4 @@@ -181,3 -179,4 +181,4 @@@ /xalloc.m4 /xsize.m4 /xstrndup.m4 + /obstack-printf.m4 diff --combined src/conflicts.c index ccd50ebf,ba0b6ed3..dad65683 --- a/src/conflicts.c +++ b/src/conflicts.c @@@ -1,7 -1,7 +1,7 @@@ /* Find and resolve or report lookahead conflicts for bison, - Copyright (C) 1984, 1989, 1992, 2000-2007, 2009-2012 Free Software - Foundation, Inc. + Copyright (C) 1984, 1989, 1992, 2000-2012 Free Software Foundation, + Inc. This file is part of Bison, the GNU Compiler Compiler. @@@ -64,75 -64,75 +64,75 @@@ enum conflict_resolutio static inline void log_resolution (rule *r, symbol_number token, - enum conflict_resolution resolution) + enum conflict_resolution resolution) { if (report_flag & report_solved_conflicts) { /* The description of the resolution. */ switch (resolution) - { - case shift_resolution: - case right_resolution: - obstack_printf (&solved_conflicts_obstack, - _(" Conflict between rule %d and token %s" - " resolved as shift"), - r->number, - symbols[token]->tag); - break; - - case reduce_resolution: - case left_resolution: - obstack_printf (&solved_conflicts_obstack, - _(" Conflict between rule %d and token %s" - " resolved as reduce"), - r->number, - symbols[token]->tag); - break; - - case nonassoc_resolution: - obstack_printf (&solved_conflicts_obstack, - _(" Conflict between rule %d and token %s" - " resolved as an error"), - r->number, - symbols[token]->tag); - break; - } + { + case shift_resolution: + case right_resolution: - obstack_fgrow2 (&solved_conflicts_obstack, ++ obstack_printf (&solved_conflicts_obstack, + _(" Conflict between rule %d and token %s" + " resolved as shift"), + r->number, + symbols[token]->tag); + break; + + case reduce_resolution: + case left_resolution: - obstack_fgrow2 (&solved_conflicts_obstack, ++ obstack_printf (&solved_conflicts_obstack, + _(" Conflict between rule %d and token %s" + " resolved as reduce"), + r->number, + symbols[token]->tag); + break; + + case nonassoc_resolution: - obstack_fgrow2 (&solved_conflicts_obstack, ++ obstack_printf (&solved_conflicts_obstack, + _(" Conflict between rule %d and token %s" + " resolved as an error"), + r->number, + symbols[token]->tag); + break; + } /* The reason. */ switch (resolution) - { - case shift_resolution: - obstack_printf (&solved_conflicts_obstack, - " (%s < %s)", - r->prec->tag, - symbols[token]->tag); - break; - - case reduce_resolution: - obstack_printf (&solved_conflicts_obstack, - " (%s < %s)", - symbols[token]->tag, - r->prec->tag); - break; - - case left_resolution: - obstack_printf (&solved_conflicts_obstack, - " (%%left %s)", - symbols[token]->tag); - break; - - case right_resolution: - obstack_printf (&solved_conflicts_obstack, - " (%%right %s)", - symbols[token]->tag); - break; - - case nonassoc_resolution: - obstack_printf (&solved_conflicts_obstack, - " (%%nonassoc %s)", - symbols[token]->tag); - break; - } + { + case shift_resolution: - obstack_fgrow2 (&solved_conflicts_obstack, ++ obstack_printf (&solved_conflicts_obstack, + " (%s < %s)", + r->prec->tag, + symbols[token]->tag); + break; + + case reduce_resolution: - obstack_fgrow2 (&solved_conflicts_obstack, ++ obstack_printf (&solved_conflicts_obstack, + " (%s < %s)", + symbols[token]->tag, + r->prec->tag); + break; + + case left_resolution: - obstack_fgrow1 (&solved_conflicts_obstack, ++ obstack_printf (&solved_conflicts_obstack, + " (%%left %s)", + symbols[token]->tag); + break; + + case right_resolution: - obstack_fgrow1 (&solved_conflicts_obstack, ++ obstack_printf (&solved_conflicts_obstack, + " (%%right %s)", + symbols[token]->tag); + break; + + case nonassoc_resolution: - obstack_fgrow1 (&solved_conflicts_obstack, ++ obstack_printf (&solved_conflicts_obstack, + " (%%nonassoc %s)", + symbols[token]->tag); + break; + } obstack_sgrow (&solved_conflicts_obstack, ".\n"); } @@@ -145,7 -145,7 +145,7 @@@ { case shift_resolution: case right_resolution: - obstack_fgrow2 (&solved_conflicts_xml_obstack, + obstack_printf (&solved_conflicts_xml_obstack, " ", r->number, @@@ -154,7 -154,7 +154,7 @@@ case reduce_resolution: case left_resolution: - obstack_fgrow2 (&solved_conflicts_xml_obstack, + obstack_printf (&solved_conflicts_xml_obstack, " ", r->number, @@@ -162,7 -162,7 +162,7 @@@ break; case nonassoc_resolution: - obstack_fgrow2 (&solved_conflicts_xml_obstack, + obstack_printf (&solved_conflicts_xml_obstack, " ", r->number, @@@ -174,33 -174,33 +174,33 @@@ switch (resolution) { case shift_resolution: - obstack_fgrow2 (&solved_conflicts_xml_obstack, + obstack_printf (&solved_conflicts_xml_obstack, "%s < %s", xml_escape_n (0, r->prec->tag), xml_escape_n (1, symbols[token]->tag)); break; case reduce_resolution: - obstack_fgrow2 (&solved_conflicts_xml_obstack, + obstack_printf (&solved_conflicts_xml_obstack, "%s < %s", xml_escape_n (0, symbols[token]->tag), xml_escape_n (1, r->prec->tag)); break; case left_resolution: - obstack_fgrow1 (&solved_conflicts_xml_obstack, + obstack_printf (&solved_conflicts_xml_obstack, "%%left %s", xml_escape (symbols[token]->tag)); break; case right_resolution: - obstack_fgrow1 (&solved_conflicts_xml_obstack, + obstack_printf (&solved_conflicts_xml_obstack, "%%right %s", xml_escape (symbols[token]->tag)); break; case nonassoc_resolution: - obstack_fgrow1 (&solved_conflicts_xml_obstack, + obstack_printf (&solved_conflicts_xml_obstack, "%%nonassoc %s", xml_escape (symbols[token]->tag)); break; @@@ -226,7 -226,7 +226,7 @@@ flush_shift (state *s, int token bitset_reset (lookahead_set, token); for (i = 0; i < trans->num; i++) if (!TRANSITION_IS_DISABLED (trans, i) - && TRANSITION_SYMBOL (trans, i) == token) + && TRANSITION_SYMBOL (trans, i) == token) TRANSITION_DISABLE (trans, i); } @@@ -268,56 -268,51 +268,56 @@@ resolve_sr_conflict (state *s, int rule for (i = 0; i < ntokens; i++) if (bitset_test (lookahead_tokens, i) - && bitset_test (lookahead_set, i) - && symbols[i]->prec) + && bitset_test (lookahead_set, i) + && symbols[i]->prec) { - /* Shift-reduce conflict occurs for token number i - and it has a precedence. - The precedence of shifting is that of token i. */ - if (symbols[i]->prec < redprec) - { - log_resolution (redrule, i, reduce_resolution); - flush_shift (s, i); - } - else if (symbols[i]->prec > redprec) - { - log_resolution (redrule, i, shift_resolution); - flush_reduce (lookahead_tokens, i); - } - else - /* Matching precedence levels. - For left association, keep only the reduction. - For right association, keep only the shift. - For nonassociation, keep neither. */ - - switch (symbols[i]->assoc) - { - default: - abort (); - - case right_assoc: - log_resolution (redrule, i, right_resolution); - flush_reduce (lookahead_tokens, i); - break; - - case left_assoc: - log_resolution (redrule, i, left_resolution); - flush_shift (s, i); - break; - - case non_assoc: - log_resolution (redrule, i, nonassoc_resolution); - flush_shift (s, i); - flush_reduce (lookahead_tokens, i); - /* Record an explicit error for this token. */ - errors[(*nerrs)++] = symbols[i]; - break; - } + /* Shift-reduce conflict occurs for token number i + and it has a precedence. + The precedence of shifting is that of token i. */ + if (symbols[i]->prec < redprec) + { + log_resolution (redrule, i, reduce_resolution); + flush_shift (s, i); + } + else if (symbols[i]->prec > redprec) + { + log_resolution (redrule, i, shift_resolution); + flush_reduce (lookahead_tokens, i); + } + else + /* Matching precedence levels. + For non-defined associativity, keep both: unexpected + associativity conflict. + For left associativity, keep only the reduction. + For right associativity, keep only the shift. + For nonassociativity, keep neither. */ + + switch (symbols[i]->assoc) + { + case undef_assoc: + abort (); + + case precedence_assoc: + break; + + case right_assoc: + log_resolution (redrule, i, right_resolution); + flush_reduce (lookahead_tokens, i); + break; + + case left_assoc: + log_resolution (redrule, i, left_resolution); + flush_shift (s, i); + break; + + case non_assoc: + log_resolution (redrule, i, nonassoc_resolution); + flush_shift (s, i); + flush_reduce (lookahead_tokens, i); + /* Record an explicit error for this token. */ + errors[(*nerrs)++] = symbols[i]; + break; + } } } @@@ -350,7 -345,7 +350,7 @@@ set_conflicts (state *s, symbol **error precedence. */ for (i = 0; i < reds->num; ++i) if (reds->rules[i]->prec && reds->rules[i]->prec->prec - && !bitset_disjoint_p (reds->lookahead_tokens[i], lookahead_set)) + && !bitset_disjoint_p (reds->lookahead_tokens[i], lookahead_set)) resolve_sr_conflict (s, i, errors, &nerrs); if (nerrs) @@@ -375,7 -370,7 +375,7 @@@ for (i = 0; i < reds->num; ++i) { if (!bitset_disjoint_p (reds->lookahead_tokens[i], lookahead_set)) - conflicts[s->number] = 1; + conflicts[s->number] = 1; bitset_or (lookahead_set, lookahead_set, reds->lookahead_tokens[i]); } } @@@ -404,9 -399,9 +404,9 @@@ conflicts_solve (void set_conflicts (states[i], errors); /* For uniformity of the code, make sure all the states have a valid - `errs' member. */ + `errs' member. */ if (!states[i]->errs) - states[i]->errs = errs_new (0, 0); + states[i]->errs = errs_new (0, 0); } free (errors); @@@ -475,11 -470,11 +475,11 @@@ count_rr_conflicts (state *s, bool one_ int count = 0; int j; for (j = 0; j < reds->num; ++j) - if (bitset_test (reds->lookahead_tokens[j], i)) - count++; + if (bitset_test (reds->lookahead_tokens[j], i)) + count++; if (count >= 2) - rrc_count += one_per_token ? 1 : count-1; + rrc_count += one_per_token ? 1 : count-1; } return rrc_count; @@@ -495,7 -490,7 +495,7 @@@ conflict_report (FILE *out, int src_num { if (src_num && rrc_num) fprintf (out, _("conflicts: %d shift/reduce, %d reduce/reduce\n"), - src_num, rrc_num); + src_num, rrc_num); else if (src_num) fprintf (out, _("conflicts: %d shift/reduce\n"), src_num); else if (rrc_num) @@@ -516,12 -511,12 +516,12 @@@ conflicts_output (FILE *out { state *s = states[i]; if (conflicts[i]) - { - fprintf (out, _("State %d "), i); - conflict_report (out, count_sr_conflicts (s), - count_rr_conflicts (s, true)); - printed_sth = true; - } + { + fprintf (out, _("State %d "), i); + conflict_report (out, count_sr_conflicts (s), + count_rr_conflicts (s, true)); + printed_sth = true; + } } if (printed_sth) fputs ("\n\n", out); @@@ -531,7 -526,7 +531,7 @@@ | Total the number of S/R and R/R conflicts. Unlike the | | code in conflicts_output, however, count EACH pair of | | reductions for the same state and lookahead as one | -| conflict. | +| conflict. | `--------------------------------------------------------*/ int @@@ -545,8 -540,8 +545,8 @@@ conflicts_total_count (void for (i = 0; i < nstates; i++) if (conflicts[i]) { - count += count_sr_conflicts (states[i]); - count += count_rr_conflicts (states[i], false); + count += count_sr_conflicts (states[i]); + count += count_rr_conflicts (states[i], false); } return count; } @@@ -576,15 -571,15 +576,15 @@@ conflicts_print (void for (i = 0; i < nstates; i++) if (conflicts[i]) - { - src_total += count_sr_conflicts (states[i]); - rrc_total += count_rr_conflicts (states[i], true); - } + { + src_total += count_sr_conflicts (states[i]); + rrc_total += count_rr_conflicts (states[i], true); + } } if (! glr_parser && rrc_total > 0 && expected_rr_conflicts != -1) { - warn (_("%%expect-rr applies only to GLR parsers")); + complain (Wother, _("%%expect-rr applies only to GLR parsers")); expected_rr_conflicts = -1; } @@@ -601,9 -596,9 +601,9 @@@ /* Report the total number of conflicts on STDERR. */ if (expected_sr_conflicts == -1 && expected_rr_conflicts == -1) { - if (!(warnings_flag & warnings_conflicts_sr)) + if (!(warnings_flag & Wconflicts_sr)) src_total = 0; - if (!(warnings_flag & warnings_conflicts_rr)) + if (!(warnings_flag & Wconflicts_rr)) rrc_total = 0; } if (src_total | rrc_total) @@@ -611,22 -606,22 +611,22 @@@ if (expected_sr_conflicts == -1 && expected_rr_conflicts == -1) set_warning_issued (); if (! yacc_flag) - fprintf (stderr, "%s: ", current_file); + fprintf (stderr, "%s: ", current_file); conflict_report (stderr, src_total, rrc_total); } if (expected_sr_conflicts != -1 || expected_rr_conflicts != -1) { if (! src_ok) - complain (ngettext ("expected %d shift/reduce conflict", - "expected %d shift/reduce conflicts", - src_expected), - src_expected); + complain (complaint, ngettext ("expected %d shift/reduce conflict", + "expected %d shift/reduce conflicts", + src_expected), + src_expected); if (! rrc_ok) - complain (ngettext ("expected %d reduce/reduce conflict", - "expected %d reduce/reduce conflicts", - rrc_expected), - rrc_expected); + complain (complaint, ngettext ("expected %d reduce/reduce conflict", + "expected %d reduce/reduce conflicts", + rrc_expected), + rrc_expected); } } diff --combined src/muscle-tab.c index 1168a9c3,bd1fd174..bb54bed7 --- a/src/muscle-tab.c +++ b/src/muscle-tab.c @@@ -50,7 -50,7 +50,7 @@@ hash_compare_muscles (void const *x, vo { muscle_entry const *m1 = x; muscle_entry const *m2 = y; - return strcmp (m1->key, m2->key) == 0; + return STREQ (m1->key, m2->key); } static size_t @@@ -80,7 -80,7 +80,7 @@@ muscle_init (void obstack_init (&muscle_obstack); muscle_table = hash_initialize (HT_INITIAL_CAPACITY, NULL, hash_muscle, - hash_compare_muscles, muscle_entry_free); + hash_compare_muscles, muscle_entry_free); /* Version and input file. */ MUSCLE_INSERT_STRING ("version", VERSION); @@@ -177,7 -177,7 +177,7 @@@ static voi muscle_syncline_grow (char const *key, location loc) { char *extension = NULL; - obstack_fgrow1 (&muscle_obstack, "]b4_syncline(%d, ", loc.start.line); + obstack_printf (&muscle_obstack, "]b4_syncline(%d, ", loc.start.line); obstack_quote (&muscle_obstack, quotearg_style (c_quoting_style, loc.start.file)); obstack_sgrow (&muscle_obstack, ")["); @@@ -202,7 -202,7 +202,7 @@@ muscle_code_grow (const char *key, cons void muscle_pair_list_grow (const char *muscle, - const char *a1, const char *a2) + const char *a1, const char *a2) { char *pair; obstack_sgrow (&muscle_obstack, "["); @@@ -268,12 -268,12 +268,12 @@@ muscle_boundary_grow (char const *key, char *extension; obstack_sgrow (&muscle_obstack, "[["); obstack_escape (&muscle_obstack, bound.file); - obstack_1grow (&muscle_obstack, ':'); + obstack_1grow (&muscle_obstack, ':'); - obstack_fgrow1 (&muscle_obstack, "%d", bound.line); + obstack_printf (&muscle_obstack, "%d", bound.line); - obstack_1grow (&muscle_obstack, '.'); + obstack_1grow (&muscle_obstack, '.'); - obstack_fgrow1 (&muscle_obstack, "%d", bound.column); + obstack_printf (&muscle_obstack, "%d", bound.column); obstack_sgrow (&muscle_obstack, "]]"); - obstack_1grow (&muscle_obstack, '\0'); + obstack_1grow (&muscle_obstack, '\0'); extension = obstack_finish (&muscle_obstack); muscle_grow (key, extension, ""); obstack_free (&muscle_obstack, extension); @@@ -396,42 -396,25 +396,42 @@@ muscle_user_name_list_grow (char const muscle_grow (key, "]]", ""); } +/** If the \a variable name is obsolete, return the name to use, + * otherwise \a variable. */ +static +char const * +muscle_percent_variable_update (char const *variable) +{ + typedef struct + { + const char *obsolete; + const char *updated; + } conversion_type; + const conversion_type conversion[] = + { + { "api.push_pull", "api.push-pull", }, + { "lr.keep_unreachable_states", "lr.keep-unreachable-states", }, + { "namespace", "api.namespace", }, + }; + int i; + for (i = 0; i < sizeof conversion / sizeof *conversion; ++i) + if (STREQ (conversion[i].obsolete, variable)) + return conversion[i].updated; + return variable; +} + void muscle_percent_define_insert (char const *variable, location variable_loc, char const *value, muscle_percent_define_how how) { - char *variable_tr = NULL; char const *name; char const *loc_name; char const *syncline_name; char const *how_name; /* Permit certain names with underscores for backward compatibility. */ - if (0 == strcmp (variable, "api.push_pull") - || 0 == strcmp (variable, "lr.keep_unreachable_states")) - { - variable_tr = strdup (variable); - tr (variable_tr, '_', '-'); - variable = variable_tr; - } + variable = muscle_percent_variable_update (variable); name = UNIQSTR_CONCAT ("percent_define(", variable, ")"); loc_name = UNIQSTR_CONCAT ("percent_define_loc(", variable, ")"); @@@ -446,11 -429,14 +446,11 @@@ muscle_percent_define_how how_old = atoi (muscle_find_const (how_name)); if (how_old == MUSCLE_PERCENT_DEFINE_F) - { - free (variable_tr); - return; - } - complain_at (variable_loc, _("%%define variable %s redefined"), + return; + complain_at (variable_loc, complaint, _("%%define variable %s redefined"), quote (variable)); - complain_at (muscle_percent_define_get_loc (variable), - _("previous definition")); + location loc = muscle_percent_define_get_loc (variable); + complain_at (loc, complaint, _("previous definition")); } MUSCLE_INSERT_STRING (name, value); @@@ -461,30 -447,8 +461,30 @@@ muscle_user_name_list_grow ("percent_define_user_variables", variable, variable_loc); MUSCLE_INSERT_INT (how_name, how); +} + +/* This is used for backward compatibility, e.g., "%define api.pure" + supersedes "%pure-parser". */ +void +muscle_percent_define_ensure (char const *variable, location loc, + bool value) +{ + char const *val = value ? "" : "false"; + char const *name; + name = UNIQSTR_CONCAT ("percent_define(", variable, ")"); - free (variable_tr); + /* %pure-parser is deprecated in favor of `%define api.pure', so use + `%define api.pure' in a backward-compatible manner here. First, + don't complain if %pure-parser is specified multiple times. */ + if (!muscle_find_const (name)) + muscle_percent_define_insert (variable, loc, val, + MUSCLE_PERCENT_DEFINE_GRAMMAR_FILE); + /* In all cases, use api.pure now so that the backend doesn't complain if + the skeleton ignores api.pure, but do warn now if there's a previous + conflicting definition from an actual %define. */ + if (muscle_percent_define_flag_if (variable) != value) + muscle_percent_define_insert (variable, loc, val, + MUSCLE_PERCENT_DEFINE_GRAMMAR_FILE); } char * @@@ -511,7 -475,7 +511,7 @@@ muscle_percent_define_get_loc (char con char const *loc_name; loc_name = UNIQSTR_CONCAT ("percent_define_loc(", variable, ")"); if (!muscle_find_const (loc_name)) - fatal(_("%s: undefined %%define variable %s"), + complain (fatal, _("%s: undefined %%define variable %s"), "muscle_percent_define_get_loc", quote (variable)); return location_decode (loc_name); } @@@ -525,7 -489,7 +525,7 @@@ muscle_percent_define_get_syncline (cha UNIQSTR_CONCAT ("percent_define_syncline(", variable, ")"); syncline = muscle_find_const (syncline_name); if (!syncline) - fatal(_("%s: undefined %%define variable %s"), + complain (fatal, _("%s: undefined %%define variable %s"), "muscle_percent_define_get_syncline", quote (variable)); return syncline; } @@@ -563,23 -527,22 +563,23 @@@ muscle_percent_define_flag_if (char con if (muscle_percent_define_ifdef (variable)) { char *value = muscle_percent_define_get (variable); - if (value[0] == '\0' || 0 == strcmp (value, "true")) + if (value[0] == '\0' || STREQ (value, "true")) result = true; - else if (0 == strcmp (value, "false")) + else if (STREQ (value, "false")) result = false; else if (!muscle_find_const (invalid_boolean_name)) { muscle_insert (invalid_boolean_name, ""); - complain_at(muscle_percent_define_get_loc (variable), - _("invalid value for %%define Boolean variable %s"), - quote (variable)); + location loc = muscle_percent_define_get_loc (variable); + complain_at (loc, complaint, + _("invalid value for %%define Boolean variable %s"), + quote (variable)); } free (value); } else - fatal(_("%s: undefined %%define variable %s"), - "muscle_percent_define_flag", quote (variable)); + complain (fatal, _("%s: undefined %%define variable %s"), + "muscle_percent_define_flag", quote (variable)); return result; } @@@ -623,18 -586,17 +623,18 @@@ muscle_percent_define_check_values (cha { for (++values; *values; ++values) { - if (0 == strcmp (value, *values)) + if (STREQ (value, *values)) break; } if (!*values) { location loc = muscle_percent_define_get_loc (*variablep); - complain_at(loc, - _("invalid value for %%define variable %s: %s"), - quote (*variablep), quote_n (1, value)); + complain_at (loc, complaint, + _("invalid value for %%define variable %s: %s"), + quote (*variablep), quote_n (1, value)); for (values = variablep + 1; *values; ++values) - complain_at (loc, _("accepted value: %s"), quote (*values)); + complain_at (loc, complaint, _("accepted value: %s"), + quote (*values)); } else { @@@ -644,8 -606,8 +644,8 @@@ free (value); } else - fatal (_("%s: undefined %%define variable %s"), - "muscle_percent_define_check_values", quote (*variablep)); + complain (fatal, _("%s: undefined %%define variable %s"), + "muscle_percent_define_check_values", quote (*variablep)); } } diff --combined src/muscle-tab.h index 1f33f8c1,696103f3..ac852978 --- a/src/muscle-tab.h +++ b/src/muscle-tab.h @@@ -1,6 -1,7 +1,6 @@@ /* Muscle table manager for Bison, - Copyright (C) 2001-2003, 2006-2007, 2009-2012 Free Software - Foundation, Inc. + Copyright (C) 2001-2003, 2006-2012 Free Software Foundation, Inc. This file is part of Bison, the GNU Compiler Compiler. @@@ -36,25 -37,24 +36,25 @@@ extern struct obstack muscle_obstack #define MUSCLE_INSERT_BOOL(Key, Value) \ do { \ - int v = Value; \ - MUSCLE_INSERT_INT (Key, v); \ + int v__ = Value; \ + MUSCLE_INSERT_INT (Key, v__); \ } while (0) #define MUSCLE_INSERT_INT(Key, Value) \ do { \ - obstack_fgrow1 (&muscle_obstack, "%d", Value); \ + obstack_printf (&muscle_obstack, "%d", Value); \ obstack_1grow (&muscle_obstack, 0); \ muscle_insert (Key, obstack_finish (&muscle_obstack)); \ } while (0) #define MUSCLE_INSERT_LONG_INT(Key, Value) \ do { \ - obstack_fgrow1 (&muscle_obstack, "%ld", Value); \ + obstack_printf (&muscle_obstack, "%ld", Value); \ obstack_1grow (&muscle_obstack, 0); \ muscle_insert (Key, obstack_finish (&muscle_obstack)); \ } while (0) +/* Key -> Value, but don't apply escaping to Value. */ #define MUSCLE_INSERT_STRING_RAW(Key, Value) \ do { \ obstack_sgrow (&muscle_obstack, Value); \ @@@ -62,7 -62,6 +62,7 @@@ muscle_insert (Key, obstack_finish (&muscle_obstack)); \ } while (0) +/* Key -> Value, applying M4 escaping to Value. */ #define MUSCLE_INSERT_STRING(Key, Value) \ do { \ obstack_escape (&muscle_obstack, Value); \ @@@ -124,13 -123,6 +124,13 @@@ void muscle_percent_define_insert (cha char const *value, muscle_percent_define_how how); +/* Make sure that VARIABLE is set to the boolean VALUE. Warn on mismatches + only, but accept repeated declaration. Used for backward compatibility + between old directives such as %pure-parser, and the recommended use of + variables (%define api.pure). */ +void muscle_percent_define_ensure (char const *variable, location variable_loc, + bool value); + /* Mimic b4_percent_define_get in ../data/bison.m4 exactly. That is, if the %define variable VARIABLE is defined, return its value. Otherwise, return the empty string. Also, record Bison's usage of VARIABLE by defining diff --combined src/output.c index c227be22,e77a2d1a..24bb83cd --- a/src/output.c +++ b/src/output.c @@@ -21,9 -21,8 +21,9 @@@ #include #include "system.h" +#include #include -#include +#include #include #include #include @@@ -42,6 -41,8 +42,6 @@@ #include "symtab.h" #include "tables.h" -# define ARRAY_CARDINALITY(Array) (sizeof (Array) / sizeof *(Array)) - static struct obstack format_obstack; @@@ -53,51 -54,51 +53,51 @@@ `-------------------------------------------------------------------*/ -#define GENERATE_MUSCLE_INSERT_TABLE(Name, Type) \ - \ -static void \ -Name (char const *name, \ - Type *table_data, \ - Type first, \ - int begin, \ - int end) \ -{ \ - Type min = first; \ - Type max = first; \ - long int lmin; \ - long int lmax; \ - int i; \ - int j = 1; \ - \ - obstack_printf (&format_obstack, "%6d", first); \ - for (i = begin; i < end; ++i) \ - { \ - obstack_1grow (&format_obstack, ','); \ - if (j >= 10) \ - { \ - obstack_sgrow (&format_obstack, "\n "); \ - j = 1; \ - } \ - else \ - ++j; \ - obstack_printf (&format_obstack, "%6d", table_data[i]); \ - if (table_data[i] < min) \ - min = table_data[i]; \ - if (max < table_data[i]) \ - max = table_data[i]; \ - } \ - obstack_1grow (&format_obstack, 0); \ - muscle_insert (name, obstack_finish (&format_obstack)); \ - \ - lmin = min; \ - lmax = max; \ - /* Build `NAME_min' and `NAME_max' in the obstack. */ \ - obstack_printf (&format_obstack, "%s_min", name); \ - obstack_1grow (&format_obstack, 0); \ - MUSCLE_INSERT_LONG_INT (obstack_finish (&format_obstack), lmin); \ - obstack_printf (&format_obstack, "%s_max", name); \ - obstack_1grow (&format_obstack, 0); \ - MUSCLE_INSERT_LONG_INT (obstack_finish (&format_obstack), lmax); \ +#define GENERATE_MUSCLE_INSERT_TABLE(Name, Type) \ + \ +static void \ +Name (char const *name, \ + Type *table_data, \ + Type first, \ + int begin, \ + int end) \ +{ \ + Type min = first; \ + Type max = first; \ + long int lmin; \ + long int lmax; \ + int i; \ + int j = 1; \ + \ - obstack_fgrow1 (&format_obstack, "%6d", first); \ ++ obstack_printf (&format_obstack, "%6d", first); \ + for (i = begin; i < end; ++i) \ + { \ + obstack_1grow (&format_obstack, ','); \ + if (j >= 10) \ + { \ + obstack_sgrow (&format_obstack, "\n "); \ + j = 1; \ + } \ + else \ + ++j; \ - obstack_fgrow1 (&format_obstack, "%6d", table_data[i]); \ ++ obstack_printf (&format_obstack, "%6d", table_data[i]); \ + if (table_data[i] < min) \ + min = table_data[i]; \ + if (max < table_data[i]) \ + max = table_data[i]; \ + } \ + obstack_1grow (&format_obstack, 0); \ + muscle_insert (name, obstack_finish (&format_obstack)); \ + \ + lmin = min; \ + lmax = max; \ + /* Build `NAME_min' and `NAME_max' in the obstack. */ \ - obstack_fgrow1 (&format_obstack, "%s_min", name); \ ++ obstack_printf (&format_obstack, "%s_min", name); \ + obstack_1grow (&format_obstack, 0); \ + MUSCLE_INSERT_LONG_INT (obstack_finish (&format_obstack), lmin); \ - obstack_fgrow1 (&format_obstack, "%s_max", name); \ ++ obstack_printf (&format_obstack, "%s_max", name); \ + obstack_1grow (&format_obstack, 0); \ + MUSCLE_INSERT_LONG_INT (obstack_finish (&format_obstack), lmax); \ } GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_unsigned_int_table, unsigned int) @@@ -105,6 -106,7 +105,6 @@@ GENERATE_MUSCLE_INSERT_TABLE(muscle_ins GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_base_table, base_number) GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_rule_number_table, rule_number) GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_symbol_number_table, symbol_number) -GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_item_number_table, item_number) GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_state_number_table, state_number) @@@ -152,14 -154,13 +152,14 @@@ prepare_symbols (void { MUSCLE_INSERT_INT ("tokens_number", ntokens); MUSCLE_INSERT_INT ("nterms_number", nvars); + MUSCLE_INSERT_INT ("symbols_number", nsyms); MUSCLE_INSERT_INT ("undef_token_number", undeftoken->number); MUSCLE_INSERT_INT ("user_token_number_max", max_user_token_number); muscle_insert_symbol_number_table ("translate", - token_translations, - token_translations[0], - 1, max_user_token_number + 1); + token_translations, + token_translations[0], + 1, max_user_token_number + 1); /* tname -- token names. */ { @@@ -171,23 -172,23 +171,23 @@@ set_quoting_flags (qo, QA_SPLIT_TRIGRAPHS); for (i = 0; i < nsyms; i++) { - char *cp = quotearg_alloc (symbols[i]->tag, -1, qo); - /* Width of the next token, including the two quotes, the - comma and the space. */ - int width = strlen (cp) + 2; - - if (j + width > 75) - { - obstack_sgrow (&format_obstack, "\n "); - j = 1; - } - - if (i) - obstack_1grow (&format_obstack, ' '); - obstack_escape (&format_obstack, cp); + char *cp = quotearg_alloc (symbols[i]->tag, -1, qo); + /* Width of the next token, including the two quotes, the + comma and the space. */ + int width = strlen (cp) + 2; + + if (j + width > 75) + { + obstack_sgrow (&format_obstack, "\n "); + j = 1; + } + + if (i) + obstack_1grow (&format_obstack, ' '); + obstack_escape (&format_obstack, cp); free (cp); - obstack_1grow (&format_obstack, ','); - j += width; + obstack_1grow (&format_obstack, ','); + j += width; } free (qo); obstack_sgrow (&format_obstack, " ]b4_null["); @@@ -204,60 -205,71 +204,60 @@@ for (i = 0; i < ntokens; ++i) values[i] = symbols[i]->user_token_number; muscle_insert_int_table ("toknum", values, - values[0], 1, ntokens); + values[0], 1, ntokens); free (values); } } -/*-------------------------------------------------------------. -| Prepare the muscles related to the rules: rhs, prhs, r1, r2, | -| rline, dprec, merger. | -`-------------------------------------------------------------*/ +/*----------------------------------------------------------------. +| Prepare the muscles related to the rules: r1, r2, rline, dprec, | +| merger, immediate. | +`----------------------------------------------------------------*/ static void prepare_rules (void) { - rule_number r; - unsigned int i = 0; - item_number *rhs = xnmalloc (nritems, sizeof *rhs); - unsigned int *prhs = xnmalloc (nrules, sizeof *prhs); unsigned int *rline = xnmalloc (nrules, sizeof *rline); symbol_number *r1 = xnmalloc (nrules, sizeof *r1); unsigned int *r2 = xnmalloc (nrules, sizeof *r2); int *dprec = xnmalloc (nrules, sizeof *dprec); int *merger = xnmalloc (nrules, sizeof *merger); + int *immediate = xnmalloc (nrules, sizeof *immediate); + rule_number r; for (r = 0; r < nrules; ++r) { - item_number *rhsp = NULL; - /* Index of rule R in RHS. */ - prhs[r] = i; - /* RHS of the rule R. */ - for (rhsp = rules[r].rhs; *rhsp >= 0; ++rhsp) - rhs[i++] = *rhsp; /* LHS of the rule R. */ r1[r] = rules[r].lhs->number; /* Length of rule R's RHS. */ - r2[r] = i - prhs[r]; - /* Separator in RHS. */ - rhs[i++] = -1; + r2[r] = rule_rhs_length(&rules[r]); /* Line where rule was defined. */ rline[r] = rules[r].location.start.line; /* Dynamic precedence (GLR). */ dprec[r] = rules[r].dprec; /* Merger-function index (GLR). */ merger[r] = rules[r].merger; + /* Immediate reduction flags (GLR). */ + immediate[r] = rules[r].is_predicate; } - aver (i == nritems); - muscle_insert_item_number_table ("rhs", rhs, ritem[0], 1, nritems); - muscle_insert_unsigned_int_table ("prhs", prhs, 0, 0, nrules); muscle_insert_unsigned_int_table ("rline", rline, 0, 0, nrules); muscle_insert_symbol_number_table ("r1", r1, 0, 0, nrules); muscle_insert_unsigned_int_table ("r2", r2, 0, 0, nrules); muscle_insert_int_table ("dprec", dprec, 0, 0, nrules); muscle_insert_int_table ("merger", merger, 0, 0, nrules); + muscle_insert_int_table ("immediate", immediate, 0, 0, nrules); MUSCLE_INSERT_INT ("rules_number", nrules); MUSCLE_INSERT_INT ("max_left_semantic_context", max_left_semantic_context); - free (rhs); - free (prhs); free (rline); free (r1); free (r2); free (dprec); free (merger); + free (immediate); } /*--------------------------------------------. @@@ -272,7 -284,7 +272,7 @@@ prepare_states (void for (i = 0; i < nstates; ++i) values[i] = states[i]->accessing_symbol; muscle_insert_symbol_number_table ("stos", values, - 0, 1, nstates); + 0, 1, nstates); free (values); MUSCLE_INSERT_INT ("last", high); @@@ -281,73 -293,6 +281,73 @@@ } +/*-------------------------------------------------------. +| Compare two symbols by type-name, and then by number. | +`-------------------------------------------------------*/ + +static int +symbol_type_name_cmp (const symbol **lhs, const symbol **rhs) +{ + int res = UNIQSTR_CMP((*lhs)->type_name, (*rhs)->type_name); + if (res) + return res; + return (*lhs)->number - (*rhs)->number; +} + + +/*----------------------------------------------------------------. +| Return a (malloc'ed) table of the symbols sorted by type-name. | +`----------------------------------------------------------------*/ + +static symbol ** +symbols_by_type_name (void) +{ + typedef int (*qcmp_type) (const void *, const void *); + symbol **res = xmemdup (symbols, nsyms * sizeof *res); + qsort (res, nsyms, sizeof *res, (qcmp_type) &symbol_type_name_cmp); + return res; +} + + +/*------------------------------------------------------------------. +| Define b4_type_names, which is a list of (lists of the numbers of | +| symbols with same type-name). | +`------------------------------------------------------------------*/ + +static void +type_names_output (FILE *out) +{ + int i; + symbol **syms = symbols_by_type_name (); + fputs ("m4_define([b4_type_names],\n[", out); + for (i = 0; i < nsyms; /* nothing */) + { + // The index of the first symbol of the current type-name. + int i0 = i; + fputs (i ? ",\n[" : "[", out); + for (; i < nsyms && syms[i]->type_name == syms[i0]->type_name; ++i) + fprintf (out, "%s%d", i != i0 ? ", " : "", syms[i]->number); + fputs ("]", out); + } + fputs ("])\n\n", out); + free (syms); +} + + +/*-------------------------------------. +| The list of all the symbol numbers. | +`-------------------------------------*/ + +static void +symbol_numbers_output (FILE *out) +{ + int i; + fputs ("m4_define([b4_symbol_numbers],\n[", out); + for (i = 0; i < nsyms; ++i) + fprintf (out, "%s[%d]", i ? ", " : "", i); + fputs ("])\n\n", out); +} + /*---------------------------------. | Output the user actions to OUT. | @@@ -362,18 -307,17 +362,18 @@@ user_actions_output (FILE *out for (r = 0; r < nrules; ++r) if (rules[r].action) { - fprintf (out, "b4_case(%d, [b4_syncline(%d, ", r + 1, - rules[r].action_location.start.line); - string_output (out, rules[r].action_location.start.file); - fprintf (out, ")\n[ %s]])\n\n", rules[r].action); + fprintf (out, "b4_%scase(%d, [b4_syncline(%d, ", + rules[r].is_predicate ? "predicate_" : "", + r + 1, rules[r].action_location.start.line); + string_output (out, rules[r].action_location.start.file); + fprintf (out, ")\n[ %s]])\n\n", rules[r].action); } fputs ("])\n\n", out); } -/*--------------------------------------. -| Output the merge functions to OUT. | -`--------------------------------------*/ +/*------------------------------------. +| Output the merge functions to OUT. | +`------------------------------------*/ static void merger_output (FILE *out) @@@ -385,97 -329,105 +385,97 @@@ for (n = 1, p = merge_functions; p != NULL; n += 1, p = p->next) { if (p->type[0] == '\0') - fprintf (out, " case %d: *yy0 = %s (*yy0, *yy1); break;\n", - n, p->name); + fprintf (out, " case %d: *yy0 = %s (*yy0, *yy1); break;\n", + n, p->name); else - fprintf (out, " case %d: yy0->%s = %s (*yy0, *yy1); break;\n", - n, p->type, p->name); + fprintf (out, " case %d: yy0->%s = %s (*yy0, *yy1); break;\n", + n, p->type, p->name); } fputs ("]])\n\n", out); } -/*--------------------------------------. -| Output the tokens definition to OUT. | -`--------------------------------------*/ + +/*---------------------------------------------. +| Prepare the muscles for symbol definitions. | +`---------------------------------------------*/ static void -token_definitions_output (FILE *out) +prepare_symbol_definitions (void) { int i; - char const *sep = ""; - - fputs ("m4_define([b4_tokens], \n[", out); - for (i = 0; i < ntokens; ++i) + for (i = 0; i < nsyms; ++i) { symbol *sym = symbols[i]; - int number = sym->user_token_number; - - /* At this stage, if there are literal string aliases, they are - part of SYMBOLS, so we should not find their aliased symbols - here. */ - aver (number != USER_NUMBER_HAS_STRING_ALIAS); - - /* Skip error token. */ - if (sym == errtoken) - continue; - - /* If this string has an alias, then it is necessarily the alias - which is to be output. */ - if (sym->alias) - sym = sym->alias; - - /* Don't output literal chars or strings (when defined only as a - string). Note that must be done after the alias resolution: - think about `%token 'f' "f"'. */ - if (sym->tag[0] == '\'' || sym->tag[0] == '\"') - continue; - - /* Don't #define nonliteral tokens whose names contain periods, - dashes or '$' (as does the default value of the EOF token). */ - if (mbschr (sym->tag, '.') - || mbschr (sym->tag, '-') - || mbschr (sym->tag, '$')) - continue; - - fprintf (out, "%s[[[%s]], %d]", - sep, sym->tag, number); - sep = ",\n"; - } - fputs ("])\n\n", out); -} + const char *key; + const char *value; +#define SET_KEY(Entry) \ - obstack_fgrow2 (&format_obstack, "symbol(%d, %s)", \ ++ obstack_printf (&format_obstack, "symbol(%d, %s)", \ + i, Entry); \ + obstack_1grow (&format_obstack, 0); \ + key = obstack_finish (&format_obstack); -/*---------------------------------------------------. -| Output the symbol destructors or printers to OUT. | -`---------------------------------------------------*/ +#define SET_KEY2(Entry, Suffix) \ - obstack_fgrow3 (&format_obstack, "symbol(%d, %s_%s)", \ ++ obstack_printf (&format_obstack, "symbol(%d, %s_%s)", \ + i, Entry, Suffix); \ + obstack_1grow (&format_obstack, 0); \ + key = obstack_finish (&format_obstack); -static void -symbol_code_props_output (FILE *out, char const *what, - code_props const *(*get)(symbol const *)) -{ - int i; - char const *sep = ""; + // Whether the symbol has an identifier. + value = symbol_id_get (sym); + SET_KEY("has_id"); + MUSCLE_INSERT_INT (key, !!value); - fputs ("m4_define([b4_symbol_", out); - fputs (what, out); - fputs ("], \n[", out); - for (i = 0; i < nsyms; ++i) - { - symbol *sym = symbols[i]; - char const *code = (*get) (sym)->code; - if (code) - { - location loc = (*get) (sym)->location; - /* Filename, lineno, - Symbol-name, Symbol-number, - code, optional typename. */ - fprintf (out, "%s[", sep); - sep = ",\n"; - string_output (out, loc.start.file); - fprintf (out, ", %d, ", loc.start.line); - quoted_output (out, sym->tag); - fprintf (out, ", %d, [[%s]]", sym->number, code); - if (sym->type_name) - { - fputs (", ", out); - quoted_output (out, sym->type_name); - } - fputc (']', out); - } + // Its identifier. + SET_KEY("id"); + MUSCLE_INSERT_STRING (key, value ? value : ""); + + // Its tag. Typically for documentation purpose. + SET_KEY("tag"); + MUSCLE_INSERT_STRING (key, sym->tag); + + SET_KEY("user_number"); + MUSCLE_INSERT_INT (key, sym->user_token_number); + + SET_KEY("is_token"); + MUSCLE_INSERT_INT (key, + i < ntokens && sym != errtoken && sym != undeftoken); + + SET_KEY("number"); + MUSCLE_INSERT_INT (key, sym->number); + + SET_KEY("has_type"); + MUSCLE_INSERT_INT (key, !!sym->type_name); + + SET_KEY("type"); + MUSCLE_INSERT_STRING (key, sym->type_name ? sym->type_name : ""); + + { + int j; + for (j = 0; j < CODE_PROPS_SIZE; ++j) + { + /* "printer", not "%printer". */ + char const *pname = code_props_type_string (j) + 1; + code_props const *p = symbol_code_props_get (sym, j); + SET_KEY2("has", pname); + MUSCLE_INSERT_INT (key, !!p->code); + + if (p->code) + { + SET_KEY2(pname, "file"); + MUSCLE_INSERT_STRING (key, p->location.start.file); + + SET_KEY2(pname, "line"); + MUSCLE_INSERT_INT (key, p->location.start.line); + + SET_KEY(pname); + MUSCLE_INSERT_STRING_RAW (key, p->code); + } + } + } +#undef SET_KEY2 +#undef SET_KEY } - fputs ("])\n\n", out); } @@@ -486,30 -438,30 +486,30 @@@ prepare_actions (void lookahead token type. */ muscle_insert_rule_number_table ("defact", yydefact, - yydefact[0], 1, nstates); + yydefact[0], 1, nstates); /* Figure out what to do after reducing with each rule, depending on the saved state from before the beginning of parsing the data that matched this rule. */ muscle_insert_state_number_table ("defgoto", yydefgoto, - yydefgoto[0], 1, nsyms - ntokens); + yydefgoto[0], 1, nsyms - ntokens); /* Output PACT. */ muscle_insert_base_table ("pact", base, - base[0], 1, nstates); + base[0], 1, nstates); MUSCLE_INSERT_INT ("pact_ninf", base_ninf); /* Output PGOTO. */ muscle_insert_base_table ("pgoto", base, - base[nstates], nstates + 1, nvectors); + base[nstates], nstates + 1, nvectors); muscle_insert_base_table ("table", table, - table[0], 1, high + 1); + table[0], 1, high + 1); MUSCLE_INSERT_INT ("table_ninf", table_ninf); muscle_insert_base_table ("check", check, - check[0], 1, high + 1); + check[0], 1, high + 1); /* GLR parsing slightly modifies YYTABLE and YYCHECK (and thus YYPACT) so that in states with unresolved conflicts, the default @@@ -521,12 -473,11 +521,12 @@@ that case. Nevertheless, it seems even better to be able to use the GLR skeletons even without the non-deterministic tables. */ muscle_insert_unsigned_int_table ("conflict_list_heads", conflict_table, - conflict_table[0], 1, high + 1); + conflict_table[0], 1, high + 1); muscle_insert_unsigned_int_table ("conflicting_rules", conflict_list, - 0, 1, conflict_list_cnt); + 0, 1, conflict_list_cnt); } + /*--------------------------------------------. | Output the definitions of all the muscles. | `--------------------------------------------*/ @@@ -535,11 -486,13 +535,11 @@@ static voi muscles_output (FILE *out) { fputs ("m4_init()\n", out); - - user_actions_output (out); merger_output (out); - token_definitions_output (out); - symbol_code_props_output (out, "destructors", &symbol_destructor_get); - symbol_code_props_output (out, "printers", &symbol_printer_get); - + symbol_numbers_output (out); + type_names_output (out); + user_actions_output (out); + // Must be last. muscles_m4_output (out); } @@@ -550,28 -503,48 +550,28 @@@ static void output_skeleton (void) { - FILE *in; int filter_fd[2]; - char const *argv[10]; pid_t pid; /* Compute the names of the package data dir and skeleton files. */ - char const m4sugar[] = "m4sugar/m4sugar.m4"; - char const m4bison[] = "bison.m4"; - char *full_m4sugar; - char *full_m4bison; - char *full_skeleton; - char const *p; - char const *m4 = (p = getenv ("M4")) ? p : M4; - char const *pkgdatadir = compute_pkgdatadir (); - size_t skeleton_size = strlen (skeleton) + 1; - size_t pkgdatadirlen = strlen (pkgdatadir); - while (pkgdatadirlen && pkgdatadir[pkgdatadirlen - 1] == '/') - pkgdatadirlen--; - full_skeleton = xmalloc (pkgdatadirlen + 1 - + (skeleton_size < sizeof m4sugar - ? sizeof m4sugar : skeleton_size)); - memcpy (full_skeleton, pkgdatadir, pkgdatadirlen); - full_skeleton[pkgdatadirlen] = '/'; - strcpy (full_skeleton + pkgdatadirlen + 1, m4sugar); - full_m4sugar = xstrdup (full_skeleton); - strcpy (full_skeleton + pkgdatadirlen + 1, m4bison); - full_m4bison = xstrdup (full_skeleton); - if (mbschr (skeleton, '/')) - strcpy (full_skeleton, skeleton); - else - strcpy (full_skeleton + pkgdatadirlen + 1, skeleton); + char const *m4 = (m4 = getenv ("M4")) ? m4 : M4; + char const *datadir = pkgdatadir (); + char *m4sugar = xconcatenated_filename (datadir, "m4sugar/m4sugar.m4", NULL); + char *m4bison = xconcatenated_filename (datadir, "bison.m4", NULL); + char *skel = (IS_PATH_WITH_DIR (skeleton) + ? xstrdup (skeleton) + : xconcatenated_filename (datadir, skeleton, NULL)); /* Test whether m4sugar.m4 is readable, to check for proper installation. A faulty installation can cause deadlock, so a cheap sanity check is worthwhile. */ - xfclose (xfopen (full_m4sugar, "r")); + xfclose (xfopen (m4sugar, "r")); /* Create an m4 subprocess connected to us via two pipes. */ if (trace_flag & trace_tools) fprintf (stderr, "running: %s %s - %s %s\n", - m4, full_m4sugar, full_m4bison, full_skeleton); + m4, m4sugar, m4bison, skel); /* Some future version of GNU M4 (most likely 1.6) may treat the -dV in a position-dependent manner. Keep it as the first argument so that all @@@ -581,7 -554,6 +581,7 @@@ for details. */ { + char const *argv[10]; int i = 0; argv[i++] = m4; @@@ -598,44 -570,47 +598,44 @@@ argv[i++] = M4_GNU_OPTION; argv[i++] = "-I"; - argv[i++] = pkgdatadir; + argv[i++] = datadir; if (trace_flag & trace_m4) argv[i++] = "-dV"; - argv[i++] = full_m4sugar; + argv[i++] = m4sugar; argv[i++] = "-"; - argv[i++] = full_m4bison; - argv[i++] = full_skeleton; + argv[i++] = m4bison; + argv[i++] = skel; argv[i++] = NULL; aver (i <= ARRAY_CARDINALITY (argv)); + + /* The ugly cast is because gnulib gets the const-ness wrong. */ + pid = create_pipe_bidi ("m4", m4, (char **)(void*)argv, false, true, + true, filter_fd); } - /* The ugly cast is because gnulib gets the const-ness wrong. */ - pid = create_pipe_bidi ("m4", m4, (char **)(void*)argv, false, true, - true, filter_fd); - free (full_m4sugar); - free (full_m4bison); - free (full_skeleton); + free (m4sugar); + free (m4bison); + free (skel); if (trace_flag & trace_muscles) muscles_output (stderr); { - FILE *out = fdopen (filter_fd[1], "w"); - if (! out) - error (EXIT_FAILURE, get_errno (), - "fdopen"); + FILE *out = xfdopen (filter_fd[1], "w"); muscles_output (out); xfclose (out); } /* Read and process m4's output. */ timevar_push (TV_M4); - in = fdopen (filter_fd[0], "r"); - if (! in) - error (EXIT_FAILURE, get_errno (), - "fdopen"); - scan_skel (in); - /* scan_skel should have read all of M4's output. Otherwise, when we - close the pipe, we risk letting M4 report a broken-pipe to the - Bison user. */ - aver (feof (in)); - xfclose (in); + { + FILE *in = xfdopen (filter_fd[0], "r"); + scan_skel (in); + /* scan_skel should have read all of M4's output. Otherwise, when we + close the pipe, we risk letting M4 report a broken-pipe to the + Bison user. */ + aver (feof (in)); + xfclose (in); + } wait_subprocess (pid, "m4", false, false, true, true, NULL); timevar_pop (TV_M4); } @@@ -643,14 -618,21 +643,14 @@@ static void prepare (void) { - /* BISON_USE_PUSH_FOR_PULL is for the test suite and should not be documented - for the user. */ - char const *use_push_for_pull_env = getenv ("BISON_USE_PUSH_FOR_PULL"); - bool use_push_for_pull_flag = false; - if (use_push_for_pull_env != NULL - && use_push_for_pull_env[0] != '\0' - && 0 != strcmp (use_push_for_pull_env, "0")) - use_push_for_pull_flag = true; + /* BISON_USE_PUSH_FOR_PULL is for the test suite and should not be + documented for the user. */ + char const *cp = getenv ("BISON_USE_PUSH_FOR_PULL"); + bool use_push_for_pull_flag = cp && *cp && strtol (cp, 0, 10); /* Flags. */ - MUSCLE_INSERT_BOOL ("debug_flag", debug_flag); MUSCLE_INSERT_BOOL ("defines_flag", defines_flag); - MUSCLE_INSERT_BOOL ("error_verbose_flag", error_verbose); MUSCLE_INSERT_BOOL ("glr_flag", glr_parser); - MUSCLE_INSERT_BOOL ("locations_flag", locations_flag); MUSCLE_INSERT_BOOL ("nondeterministic_flag", nondeterministic_parser); MUSCLE_INSERT_BOOL ("synclines_flag", !no_lines_flag); MUSCLE_INSERT_BOOL ("tag_seen_flag", tag_seen); @@@ -686,7 -668,7 +686,7 @@@ /* b4_pkgdatadir is used inside m4_include in the skeletons, so digraphs would never be expanded. Hopefully no one has M4-special characters in his Bison installation path. */ - MUSCLE_INSERT_STRING_RAW ("pkgdatadir", compute_pkgdatadir ()); + MUSCLE_INSERT_STRING_RAW ("pkgdatadir", pkgdatadir ()); } } @@@ -704,7 -686,6 +704,7 @@@ output (void prepare_rules (); prepare_states (); prepare_actions (); + prepare_symbol_definitions (); prepare (); @@@ -715,8 -696,8 +715,8 @@@ } char const * -compute_pkgdatadir (void) +pkgdatadir (void) { - char const *pkgdatadir = getenv ("BISON_PKGDATADIR"); - return pkgdatadir ? pkgdatadir : PKGDATADIR; + char const *cp = getenv ("BISON_PKGDATADIR"); + return cp ? cp : PKGDATADIR; } diff --combined src/print_graph.c index 61d36512,f5695a7a..d37afb2c --- a/src/print_graph.c +++ b/src/print_graph.c @@@ -54,7 -54,7 +54,7 @@@ print_core (struct obstack *oout, stat snritems = nitemset; } - obstack_fgrow1 (oout, "%d", s->number); + obstack_printf (oout, "%d", s->number); for (i = 0; i < snritems; i++) { item_number *sp; @@@ -64,43 -64,43 +64,43 @@@ sp1 = sp = ritem + sitems[i]; while (*sp >= 0) - sp++; + sp++; r = item_number_as_rule_number (*sp); - obstack_fgrow1 (oout, "\n%s -> ", rules[r].lhs->tag); + obstack_printf (oout, "\n%s -> ", rules[r].lhs->tag); for (sp = rules[r].rhs; sp < sp1; sp++) - obstack_fgrow1 (oout, "%s ", symbols[*sp]->tag); - obstack_printf (oout, "%s ", symbols[*sp]->tag); ++ obstack_printf (oout, "%s ", symbols[*sp]->tag); obstack_1grow (oout, '.'); for (/* Nothing */; *sp >= 0; ++sp) - obstack_fgrow1 (oout, " %s", symbols[*sp]->tag); - obstack_printf (oout, " %s", symbols[*sp]->tag); ++ obstack_printf (oout, " %s", symbols[*sp]->tag); /* Experimental feature: display the lookahead tokens. */ if (report_flag & report_lookahead_tokens && item_number_is_rule_number (*sp1)) - { - /* Find the reduction we are handling. */ - reductions *reds = s->reductions; - int redno = state_reduction_find (s, &rules[r]); - - /* Print them if there are. */ - if (reds->lookahead_tokens && redno != -1) - { - bitset_iterator biter; - int k; - char const *sep = ""; - obstack_sgrow (oout, "["); - BITSET_FOR_EACH (biter, reds->lookahead_tokens[redno], k, 0) - { - obstack_printf (oout, "%s%s", sep, symbols[k]->tag); - sep = ", "; - } - obstack_sgrow (oout, "]"); - } - } + { + /* Find the reduction we are handling. */ + reductions *reds = s->reductions; + int redno = state_reduction_find (s, &rules[r]); + + /* Print them if there are. */ + if (reds->lookahead_tokens && redno != -1) + { + bitset_iterator biter; + int k; + char const *sep = ""; + obstack_sgrow (oout, "["); + BITSET_FOR_EACH (biter, reds->lookahead_tokens[redno], k, 0) + { - obstack_fgrow2 (oout, "%s%s", sep, symbols[k]->tag); ++ obstack_printf (oout, "%s%s", sep, symbols[k]->tag); + sep = ", "; + } + obstack_sgrow (oout, "]"); + } + } } } @@@ -123,21 -123,21 +123,21 @@@ print_actions (state const *s, FILE *fg for (i = 0; i < trans->num; i++) if (!TRANSITION_IS_DISABLED (trans, i)) { - state *s1 = trans->states[i]; - symbol_number sym = s1->accessing_symbol; - - /* Shifts are solid, gotos are dashed, and error is dotted. */ - char const *style = - (TRANSITION_IS_ERROR (trans, i) ? "dotted" - : TRANSITION_IS_SHIFT (trans, i) ? "solid" - : "dashed"); - - if (TRANSITION_IS_ERROR (trans, i) - && strcmp (symbols[sym]->tag, "error") != 0) - abort (); - output_edge (s->number, s1->number, - TRANSITION_IS_ERROR (trans, i) ? NULL : symbols[sym]->tag, - style, fgraph); + state *s1 = trans->states[i]; + symbol_number sym = s1->accessing_symbol; + + /* Shifts are solid, gotos are dashed, and error is dotted. */ + char const *style = + (TRANSITION_IS_ERROR (trans, i) ? "dotted" + : TRANSITION_IS_SHIFT (trans, i) ? "solid" + : "dashed"); + + if (TRANSITION_IS_ERROR (trans, i) + && STRNEQ (symbols[sym]->tag, "error")) + abort (); + output_edge (s->number, s1->number, + TRANSITION_IS_ERROR (trans, i) ? NULL : symbols[sym]->tag, + style, fgraph); } } diff --combined src/scan-code.l index 2fe880ed,fa593beb..83501475 --- a/src/scan-code.l +++ b/src/scan-code.l @@@ -27,14 -27,13 +27,14 @@@ #define code_wrap() 1 #define FLEX_PREFIX(Id) code_ ## Id -#include "flex-scanner.h" +#include -#include "complain.h" -#include "reader.h" -#include "getargs.h" -#include "scan-code.h" -#include "symlist.h" +#include +#include +#include +#include +#include +#include #include #include @@@ -51,7 -50,7 +51,7 @@@ static char *fetch_type_name (char *cp location dollar_loc); static void handle_action_dollar (symbol_list *rule, char *cp, - location dollar_loc); + location dollar_loc); static void handle_action_at (symbol_list *rule, char *cp, location at_loc); /* A string to be pushed to obstack after dollar/at has been handled. */ @@@ -79,17 -78,17 +79,17 @@@ static bool untyped_var_seen /* POSIX says that a tag must be both an id and a C union member, but historically almost any character is allowed in a tag. We disallow NUL and newline, as this simplifies our implementation. */ -tag [^\0\n>]+ +tag [^\0\n>]+ /* Zero or more instances of backslash-newline. Following GCC, allow white space between the backslash and the newline. */ -splice (\\[ \f\t\v]*\n)* +splice (\\[ \f\t\v]*\n)* /* C style identifier. Must start with letter. Will be used for named symbol references. Shall be kept synchronized with scan-gram.l "letter" and "id". */ -letter [.abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_] -id {letter}({letter}|[-0-9])* +letter [.abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_] +id {letter}({letter}|[-0-9])* ref -?[0-9]+|{id}|"["{id}"]"|"$" %% @@@ -119,8 -118,8 +119,8 @@@ is expected to return only once. This initialization is therefore done once per action to translate. */ aver (sc_context == SC_SYMBOL_ACTION - || sc_context == SC_RULE_ACTION - || sc_context == INITIAL); + || sc_context == SC_RULE_ACTION + || sc_context == INITIAL); BEGIN sc_context; %} @@@ -140,8 -139,8 +140,8 @@@ { - "\n" STRING_GROW; BEGIN sc_context; - {splice} STRING_GROW; + "\n" STRING_GROW; BEGIN sc_context; + {splice} STRING_GROW; } @@@ -151,17 -150,17 +151,17 @@@ { - {splice}|\\{splice}. STRING_GROW; + {splice}|\\{splice}. STRING_GROW; } { - "'" STRING_GROW; BEGIN sc_context; + "'" STRING_GROW; BEGIN sc_context; } { - "\"" STRING_GROW; BEGIN sc_context; + "\"" STRING_GROW; BEGIN sc_context; } @@@ -186,7 -185,7 +186,7 @@@ BEGIN SC_LINE_COMMENT; } [$@] { - warn_at (*loc, _("stray '%s'"), yytext); + complain_at (*loc, Wother, _("stray '%s'"), yytext); obstack_escape (&obstack_for_string, yytext); need_semicolon = true; } @@@ -225,10 -224,8 +225,10 @@@ if (outer_brace && !yacc_flag && language_prio == default_prio && skeleton_prio == default_prio && need_semicolon && ! in_cpp) { - warn_at (*loc, _("a ';' might be needed at the end of action code")); - warn_at (*loc, _("future versions of Bison will not add the ';'")); + complain_at (*loc, Wother, + _("a ';' might be needed at the end of action code")); + complain_at (*loc, Wother, + _("future versions of Bison will not add the ';'")); obstack_1grow (&obstack_for_string, ';'); } @@@ -245,7 -242,20 +245,7 @@@ {splice} STRING_GROW; [\n\r] STRING_GROW; if (in_cpp) in_cpp = need_semicolon = false; [ \t\f] STRING_GROW; - - /* YYFAIL is undocumented and was formally deprecated in Bison - 2.4.2. */ - YYFAIL { - STRING_GROW; need_semicolon = true; - warn_at (*loc, _("use of YYFAIL, which is deprecated and will be" - " removed")); - } - - /* The sole purpose of this is to make sure identifiers that merely - contain YYFAIL don't produce the above warning. */ - [A-Za-z_][0-9A-Za-z_]* STRING_GROW; need_semicolon = true; - - . STRING_GROW; need_semicolon = true; + . STRING_GROW; need_semicolon = true; } @@@ -260,7 -270,7 +260,7 @@@ } "@$" { obstack_sgrow (&obstack_for_string, "]b4_at_dollar["); - locations_flag = true; + muscle_percent_define_ensure("locations", the_location, true); } } @@@ -273,7 -283,7 +273,7 @@@ /* By default, grow the string obstack with the input. */ .|\n STRING_GROW; - /* End of processing. */ + /* End of processing. */ <> STRING_FINISH; return last_string; } @@@ -335,9 -345,9 +335,9 @@@ variant_table_grow (void if (variant_count > variant_table_size) { while (variant_count > variant_table_size) - variant_table_size = 2 * variant_table_size + 3; + variant_table_size = 2 * variant_table_size + 3; variant_table = xnrealloc (variant_table, variant_table_size, - sizeof *variant_table); + sizeof *variant_table); } return &variant_table[variant_count - 1]; } @@@ -367,7 -377,7 +367,7 @@@ find_prefix_end (const char *prefix, ch static variant * variant_add (uniqstr id, location id_loc, unsigned symbol_index, - char *cp, char *cp_end, bool explicit_bracketing) + char *cp, char *cp_end, bool explicit_bracketing) { char *prefix_end; @@@ -389,7 -399,7 +389,7 @@@ } static const char * -get_at_spec (unsigned symbol_index) +get_at_spec(unsigned symbol_index) { static char at_buf[20]; if (symbol_index == 0) @@@ -414,62 -424,60 +414,62 @@@ show_sub_messages (const char* cp, boo if (var->err == 0) { if (is_warning) - warn_at_indent (var->loc, &indent, _("refers to: %c%s at %s"), - dollar_or_at, var->id, at_spec); + complain_at_indent (var->loc, Wother, &indent, + _("refers to: %c%s at %s"), dollar_or_at, + var->id, at_spec); else - complain_at_indent (var->loc, &indent, _("refers to: %c%s at %s"), - dollar_or_at, var->id, at_spec); + complain_at_indent (var->loc, complaint, &indent, + _("refers to: %c%s at %s"), dollar_or_at, + var->id, at_spec); } else - { - static struct obstack msg_buf; - const char *tail = explicit_bracketing ? "" : - cp + strlen (var->id); - const char *id = var->hidden_by ? var->hidden_by->id : - var->id; - location id_loc = var->hidden_by ? var->hidden_by->loc : - var->loc; - - /* Create the explanation message. */ - obstack_init (&msg_buf); - - obstack_printf (&msg_buf, _("possibly meant: %c"), dollar_or_at); - if (contains_dot_or_dash (id)) - obstack_printf (&msg_buf, "[%s]", id); - else - obstack_sgrow (&msg_buf, id); - obstack_sgrow (&msg_buf, tail); - - if (var->err & VARIANT_HIDDEN) - { - obstack_printf (&msg_buf, _(", hiding %c"), dollar_or_at); - if (contains_dot_or_dash (var->id)) - obstack_printf (&msg_buf, "[%s]", var->id); - else - obstack_sgrow (&msg_buf, var->id); - obstack_sgrow (&msg_buf, tail); - } - - obstack_printf (&msg_buf, _(" at %s"), at_spec); - - if (var->err & VARIANT_NOT_VISIBLE_FROM_MIDRULE) + { + static struct obstack msg_buf; + const char *tail = explicit_bracketing ? "" : + cp + strlen (var->id); + const char *id = var->hidden_by ? var->hidden_by->id : + var->id; + location id_loc = var->hidden_by ? var->hidden_by->loc : + var->loc; + + /* Create the explanation message. */ + obstack_init (&msg_buf); + - obstack_fgrow1 (&msg_buf, _("possibly meant: %c"), dollar_or_at); ++ obstack_printf (&msg_buf, _("possibly meant: %c"), dollar_or_at); + if (contains_dot_or_dash (id)) - obstack_fgrow1 (&msg_buf, "[%s]", id); ++ obstack_printf (&msg_buf, "[%s]", id); + else + obstack_sgrow (&msg_buf, id); + obstack_sgrow (&msg_buf, tail); + + if (var->err & VARIANT_HIDDEN) + { - obstack_fgrow1 (&msg_buf, _(", hiding %c"), dollar_or_at); ++ obstack_printf (&msg_buf, _(", hiding %c"), dollar_or_at); + if (contains_dot_or_dash (var->id)) - obstack_fgrow1 (&msg_buf, "[%s]", var->id); ++ obstack_printf (&msg_buf, "[%s]", var->id); + else + obstack_sgrow (&msg_buf, var->id); + obstack_sgrow (&msg_buf, tail); + } + - obstack_fgrow1 (&msg_buf, _(" at %s"), at_spec); ++ obstack_printf (&msg_buf, _(" at %s"), at_spec); + + if (var->err & VARIANT_NOT_VISIBLE_FROM_MIDRULE) { const char *format = _(", cannot be accessed from mid-rule action at $%d"); - obstack_fgrow1 (&msg_buf, format, midrule_rhs_index); + obstack_printf (&msg_buf, format, midrule_rhs_index); } - obstack_1grow (&msg_buf, '\0'); + obstack_1grow (&msg_buf, '\0'); if (is_warning) - warn_at_indent (id_loc, &indent, "%s", - (char *) obstack_finish (&msg_buf)); + complain_at_indent (id_loc, Wother, &indent, "%s", + (char *) obstack_finish (&msg_buf)); else - complain_at_indent (id_loc, &indent, "%s", + complain_at_indent (id_loc, complaint, &indent, "%s", (char *) obstack_finish (&msg_buf)); - obstack_free (&msg_buf, 0); - } + obstack_free (&msg_buf, 0); + } } } @@@ -489,8 -497,8 +489,8 @@@ accesses. */ static long int parse_ref (char *cp, symbol_list *rule, int rule_length, - int midrule_rhs_index, char *text, location text_loc, - char dollar_or_at) + int midrule_rhs_index, char *text, location text_loc, + char dollar_or_at) { symbol_list *l; char *cp_end; @@@ -506,13 -514,13 +506,13 @@@ { long int num = strtol (cp, &cp, 10); if (1 - INT_MAX + rule_length <= num && num <= rule_length) - return num; + return num; else - { - complain_at (text_loc, _("integer out of range: %s"), + { + complain_at (text_loc, complaint, _("integer out of range: %s"), quote (text)); - return INVALID_REF; - } + return INVALID_REF; + } } if ('[' == *cp) @@@ -520,7 -528,7 +520,7 @@@ /* Ignore the brackets. */ char *p; for (p = ++cp; *p != ']'; ++p) - continue; + continue; cp_end = p; explicit_bracketing = true; @@@ -530,13 -538,13 +530,13 @@@ /* Take all characters of the name. */ char* p; for (p = cp; *p; ++p) - if (is_dot_or_dash (*p)) - { - ref_tail_fields = p; - break; - } + if (is_dot_or_dash (*p)) + { + ref_tail_fields = p; + break; + } for (p = cp; *p; ++p) - continue; + continue; cp_end = p; explicit_bracketing = false; @@@ -549,17 -557,17 +549,17 @@@ for (symbol_index = 0, l = rule; !symbol_list_null (l); ++symbol_index, l = l->next) { - variant *var; - if (l->content_type != SYMLIST_SYMBOL) - continue; + variant *var; + if (l->content_type != SYMLIST_SYMBOL) + continue; - var = variant_add (l->content.sym->tag, l->sym_loc, + var = variant_add (l->content.sym->tag, l->sym_loc, symbol_index, cp, cp_end, explicit_bracketing); - if (var && l->named_ref) - var->hidden_by = l->named_ref; + if (var && l->named_ref) + var->hidden_by = l->named_ref; - if (l->named_ref) - variant_add (l->named_ref->id, l->named_ref->loc, + if (l->named_ref) + variant_add (l->named_ref->id, l->named_ref->loc, symbol_index, cp, cp_end, explicit_bracketing); } } @@@ -572,7 -580,7 +572,7 @@@ /* Check visibility from mid-rule actions. */ if (midrule_rhs_index != 0 - && (symbol_index == 0 || midrule_rhs_index < symbol_index)) + && (symbol_index == 0 || midrule_rhs_index < symbol_index)) var->err |= VARIANT_NOT_VISIBLE_FROM_MIDRULE; /* Check correct bracketing. */ @@@ -598,8 -606,8 +598,8 @@@ cp_end - cp : ref_tail_fields - cp; unsigned indent = 0; - complain_at_indent (text_loc, &indent, _("invalid reference: %s"), - quote (text)); + complain_at_indent (text_loc, complaint, &indent, + _("invalid reference: %s"), quote (text)); indent += SUB_INDENT; if (len == 0) { @@@ -609,21 -617,20 +609,21 @@@ const char *format = _("syntax error after '%c', expecting integer, letter," " '_', '[', or '$'"); - complain_at_indent (sym_loc, &indent, format, dollar_or_at); + complain_at_indent (sym_loc, complaint, &indent, format, + dollar_or_at); } else if (midrule_rhs_index) { const char *format = _("symbol not found in production before $%d: %.*s"); - complain_at_indent (rule->location, &indent, format, + complain_at_indent (rule->location, complaint, &indent, format, midrule_rhs_index, len, cp); } else { const char *format = _("symbol not found in production: %.*s"); - complain_at_indent (rule->location, &indent, format, + complain_at_indent (rule->location, complaint, &indent, format, len, cp); } @@@ -637,8 -644,8 +637,8 @@@ unsigned indent = 0; if (variant_count > 1) { - warn_at_indent (text_loc, &indent, _("misleading reference: %s"), - quote (text)); + complain_at_indent (text_loc, Wother, &indent, + _("misleading reference: %s"), quote (text)); show_sub_messages (cp, explicit_bracketing, midrule_rhs_index, dollar_or_at, true, indent + SUB_INDENT); } @@@ -652,8 -659,8 +652,8 @@@ default: { unsigned indent = 0; - complain_at_indent (text_loc, &indent, _("ambiguous reference: %s"), - quote (text)); + complain_at_indent (text_loc, complaint, &indent, + _("ambiguous reference: %s"), quote (text)); show_sub_messages (cp, explicit_bracketing, midrule_rhs_index, dollar_or_at, false, indent + SUB_INDENT); return INVALID_REF; @@@ -683,14 -690,13 +683,14 @@@ fetch_type_name (char *cp, char const * { *type_name = ++cp; while (*cp != '>') - ++cp; + ++cp; /* The '>' symbol will be later replaced by '\0'. Original - 'text' is needed for error messages. */ + 'text' is needed for error messages. */ ++cp; if (untyped_var_seen) - complain_at (dollar_loc, _("explicit type given in untyped grammar")); + complain_at (dollar_loc, complaint, + _("explicit type given in untyped grammar")); tag_seen = true; } return cp; @@@ -728,7 -734,7 +728,7 @@@ handle_action_dollar (symbol_list *rule cp = fetch_type_name (cp, &type_name, dollar_loc); n = parse_ref (cp, effective_rule, effective_rule_length, - rule->midrule_parent_rhs_index, text, dollar_loc, '$'); + rule->midrule_parent_rhs_index, text, dollar_loc, '$'); /* End type_name. */ if (type_name) @@@ -741,21 -747,20 +741,21 @@@ case LHS_REF: if (!type_name) - type_name = symbol_list_n_type_name_get (rule, dollar_loc, 0); + type_name = symbol_list_n_type_name_get (rule, dollar_loc, 0); if (!type_name) { if (union_seen | tag_seen) { if (rule->midrule_parent_rule) - complain_at (dollar_loc, + complain_at (dollar_loc, complaint, _("$$ for the midrule at $%d of %s" " has no declared type"), rule->midrule_parent_rhs_index, quote (effective_rule->content.sym->tag)); else - complain_at (dollar_loc, _("$$ of %s has no declared type"), + complain_at (dollar_loc, complaint, + _("$$ of %s has no declared type"), quote (rule->content.sym->tag)); } else @@@ -770,27 -775,26 +770,27 @@@ default: if (max_left_semantic_context < 1 - n) - max_left_semantic_context = 1 - n; + max_left_semantic_context = 1 - n; if (!type_name && 0 < n) - type_name = - symbol_list_n_type_name_get (effective_rule, dollar_loc, n); + type_name = + symbol_list_n_type_name_get (effective_rule, dollar_loc, n); if (!type_name) { if (union_seen | tag_seen) - complain_at (dollar_loc, _("$%s of %s has no declared type"), - cp, quote (effective_rule->content.sym->tag)); + complain_at (dollar_loc, complaint, + _("$%s of %s has no declared type"), cp, + quote (effective_rule->content.sym->tag)); else untyped_var_seen = true; } - obstack_fgrow2 (&obstack_for_string, + obstack_printf (&obstack_for_string, - "]b4_rhs_value(%d, %d, ", effective_rule_length, n); + "]b4_rhs_value(%d, %d, ", effective_rule_length, n); obstack_quote (&obstack_for_string, type_name); obstack_sgrow (&obstack_for_string, ")["); if (n > 0) - symbol_list_n_get (effective_rule, n)->action_props.is_value_used = - true; + symbol_list_n_get (effective_rule, n)->action_props.is_value_used = + true; break; } } @@@ -820,10 -824,10 +820,10 @@@ handle_action_at (symbol_list *rule, ch effective_rule_length = symbol_list_length (rule->next); } - locations_flag = true; + muscle_percent_define_ensure("locations", at_loc, true); n = parse_ref (cp, effective_rule, effective_rule_length, - rule->midrule_parent_rhs_index, text, at_loc, '@'); + rule->midrule_parent_rhs_index, text, at_loc, '@'); switch (n) { case INVALID_REF: @@@ -834,8 -838,8 +834,8 @@@ break; default: - obstack_fgrow2 (&obstack_for_string, "]b4_rhs_location(%d, %d)[", + obstack_printf (&obstack_for_string, "]b4_rhs_location(%d, %d)[", - effective_rule_length, n); + effective_rule_length, n); break; } } @@@ -878,40 -882,43 +878,40 @@@ code_props_none_init (code_props *self *self = code_props_none; } -code_props const code_props_none = CODE_PROPS_NONE_INIT; +code_props code_props_none = CODE_PROPS_NONE_INIT; void code_props_plain_init (code_props *self, char const *code, - location code_loc) + location code_loc) { + code_props_none_init (self); self->kind = CODE_PROPS_PLAIN; self->code = code; self->location = code_loc; - self->is_value_used = false; - self->rule = NULL; - self->named_ref = NULL; } void code_props_symbol_action_init (code_props *self, char const *code, location code_loc) { + code_props_none_init (self); self->kind = CODE_PROPS_SYMBOL_ACTION; self->code = code; self->location = code_loc; - self->is_value_used = false; - self->rule = NULL; - self->named_ref = NULL; } void code_props_rule_action_init (code_props *self, char const *code, location code_loc, symbol_list *rule, - named_ref *name) + named_ref *name, bool is_predicate) { + code_props_none_init (self); self->kind = CODE_PROPS_RULE_ACTION; self->code = code; self->location = code_loc; - self->is_value_used = false; self->rule = rule; self->named_ref = name; + self->is_predicate = is_predicate; } void diff --combined src/scan-skel.l index b79e5832,ed61b5c8..32bfe737 --- a/src/scan-skel.l +++ b/src/scan-skel.l @@@ -1,6 -1,6 +1,6 @@@ /* Scan Bison Skeletons. -*- C -*- - Copyright (C) 2001-2007, 2009-2012 Free Software Foundation, Inc. + Copyright (C) 2001-2012 Free Software Foundation, Inc. This file is part of Bison, the GNU Compiler Compiler. @@@ -27,16 -27,16 +27,16 @@@ #define skel_wrap() 1 #define FLEX_PREFIX(Id) skel_ ## Id -#include "flex-scanner.h" +#include #include #include #include -#include "complain.h" -#include "getargs.h" -#include "files.h" -#include "scan-skel.h" +#include +#include +#include +#include #define YY_DECL static int skel_lex (void) YY_DECL; @@@ -87,11 -87,11 +87,11 @@@ static void fail_for_invalid_at (char c } /* This pattern must not match more than the previous @ patterns. */ -@[^@{}`(\n]* fail_for_invalid_at (yytext); -\n out_lineno++; ECHO; -[^@\n]+ ECHO; +@[^@{}`(\n]* fail_for_invalid_at (yytext); +\n out_lineno++; ECHO; +[^@\n]+ ECHO; - <> { + <> { if (outname) { free (outname); @@@ -137,14 -137,13 +137,14 @@@ { [ \t\r\n] continue; - . { yyless (0); BEGIN SC_AT_DIRECTIVE_ARGS; } + . { yyless (0); BEGIN SC_AT_DIRECTIVE_ARGS; } } { <> { - fatal (_("unclosed %s directive in skeleton"), at_directive_argv[0]); + complain (fatal, _("unclosed %s directive in skeleton"), + at_directive_argv[0]); } } @@@ -181,98 -180,94 +181,98 @@@ at_directive_perform (int at_directive_ char *at_directive_argv[], char **outnamep, int *out_linenop) { - if (0 == strcmp (at_directive_argv[0], "@basename")) + if (STREQ (at_directive_argv[0], "@basename")) { if (at_directive_argc > 2) fail_for_at_directive_too_many_args (at_directive_argv[0]); fputs (last_component (at_directive_argv[1]), yyout); } - else if (0 == strcmp (at_directive_argv[0], "@warn") - || 0 == strcmp (at_directive_argv[0], "@complain") - || 0 == strcmp (at_directive_argv[0], "@fatal")) + else if (STREQ (at_directive_argv[0], "@warn") + || STREQ (at_directive_argv[0], "@complain") + || STREQ (at_directive_argv[0], "@fatal")) { - void (*func)(char const *, ...); + warnings complaint_flag; switch (at_directive_argv[0][1]) { - case 'w': func = warn; break; - case 'c': func = complain; break; - case 'f': func = fatal; break; - default: aver (false); break; + case 'w': complaint_flag = Wother; break; + case 'c': complaint_flag = complaint; break; + case 'f': complaint_flag = fatal; break; + default: aver (false); break; } switch (at_directive_argc) { case 2: - func (_(at_directive_argv[1])); + complain (complaint_flag, "%s", _(at_directive_argv[1])); break; case 3: - func (_(at_directive_argv[1]), at_directive_argv[2]); + complain (complaint_flag, _(at_directive_argv[1]), + at_directive_argv[2]); break; case 4: - func (_(at_directive_argv[1]), at_directive_argv[2], - at_directive_argv[3]); + complain (complaint_flag, _(at_directive_argv[1]), + at_directive_argv[2], at_directive_argv[3]); break; case 5: - func (_(at_directive_argv[1]), at_directive_argv[2], - at_directive_argv[3], at_directive_argv[4]); + complain (complaint_flag, _(at_directive_argv[1]), + at_directive_argv[2], at_directive_argv[3], + at_directive_argv[4]); break; case 6: - func (_(at_directive_argv[1]), at_directive_argv[2], - at_directive_argv[3], at_directive_argv[4], - at_directive_argv[5]); + complain (complaint_flag, _(at_directive_argv[1]), + at_directive_argv[2], at_directive_argv[3], + at_directive_argv[4], at_directive_argv[5]); break; default: fail_for_at_directive_too_many_args (at_directive_argv[0]); break; } } - else if (0 == strcmp (at_directive_argv[0], "@warn_at") - || 0 == strcmp (at_directive_argv[0], "@complain_at") - || 0 == strcmp (at_directive_argv[0], "@fatal_at")) + else if (STREQ (at_directive_argv[0], "@warn_at") + || STREQ (at_directive_argv[0], "@complain_at") + || STREQ (at_directive_argv[0], "@fatal_at")) { - void (*func)(location, char const *, ...); + warnings complaint_flag; location loc; if (at_directive_argc < 4) fail_for_at_directive_too_few_args (at_directive_argv[0]); switch (at_directive_argv[0][1]) { - case 'w': func = warn_at; break; - case 'c': func = complain_at; break; - case 'f': func = fatal_at; break; - default: aver (false); break; + case 'w': complaint_flag = Wother; break; + case 'c': complaint_flag = complaint; break; + case 'f': complaint_flag = fatal; break; + default: aver (false); break; } boundary_set_from_string (&loc.start, at_directive_argv[1]); boundary_set_from_string (&loc.end, at_directive_argv[2]); switch (at_directive_argc) { case 4: - func (loc, _(at_directive_argv[3])); + complain_at (loc, complaint_flag, "%s", _(at_directive_argv[3])); break; case 5: - func (loc, _(at_directive_argv[3]), at_directive_argv[4]); + complain_at (loc, complaint_flag, _(at_directive_argv[3]), + at_directive_argv[4]); break; case 6: - func (loc, _(at_directive_argv[3]), at_directive_argv[4], - at_directive_argv[5]); + complain_at (loc, complaint_flag, _(at_directive_argv[3]), + at_directive_argv[4], at_directive_argv[5]); break; case 7: - func (loc, _(at_directive_argv[3]), at_directive_argv[4], - at_directive_argv[5], at_directive_argv[6]); + complain_at (loc, complaint_flag, _(at_directive_argv[3]), + at_directive_argv[4], at_directive_argv[5], + at_directive_argv[6]); break; case 8: - func (loc, _(at_directive_argv[3]), at_directive_argv[4], - at_directive_argv[5], at_directive_argv[6], - at_directive_argv[7]); + complain_at (loc, complaint_flag, _(at_directive_argv[3]), + at_directive_argv[4], at_directive_argv[5], + at_directive_argv[6], at_directive_argv[7]); break; default: fail_for_at_directive_too_many_args (at_directive_argv[0]); break; } } - else if (0 == strcmp (at_directive_argv[0], "@output")) + else if (STREQ (at_directive_argv[0], "@output")) { if (at_directive_argc > 2) fail_for_at_directive_too_many_args (at_directive_argv[0]); @@@ -293,19 -288,19 +293,19 @@@ static void fail_for_at_directive_too_few_args (char const *at_directive_name) { - fatal (_("too few arguments for %s directive in skeleton"), + complain (fatal, _("too few arguments for %s directive in skeleton"), at_directive_name); } static void fail_for_at_directive_too_many_args (char const *at_directive_name) { - fatal (_("too many arguments for %s directive in skeleton"), - at_directive_name); + complain (fatal, _("too many arguments for %s directive in skeleton"), + at_directive_name); } static void fail_for_invalid_at (char const *at) { - fatal ("invalid @ in skeleton: %s", at); + complain (fatal, "invalid @ in skeleton: %s", at); } diff --combined src/system.h index 1d0af8fa,1ae6a6b4..a56c058a --- a/src/system.h +++ b/src/system.h @@@ -16,65 -16,52 +16,65 @@@ along with this program. If not, see . */ #ifndef BISON_SYSTEM_H -# define BISON_SYSTEM_H +#define BISON_SYSTEM_H /* flex 2.5.31 gratutiously defines macros like INT8_MIN. But this runs afoul of pre-C99 compilers that have or , which are included below if available. It also runs afoul of pre-C99 compilers that define these macros in . */ -# if ! defined __STDC_VERSION__ || __STDC_VERSION__ < 199901 -# undef INT8_MIN -# undef INT16_MIN -# undef INT32_MIN -# undef INT8_MAX -# undef INT16_MAX -# undef UINT8_MAX -# undef INT32_MAX -# undef UINT16_MAX -# undef UINT32_MAX -# endif - -# include -# include -# include -# include - -# if HAVE_SYS_TYPES_H -# include -# endif - -# include -# include - -# ifndef UINTPTR_MAX +#if ! defined __STDC_VERSION__ || __STDC_VERSION__ < 199901 +# undef INT8_MIN +# undef INT16_MIN +# undef INT32_MIN +# undef INT8_MAX +# undef INT16_MAX +# undef UINT8_MAX +# undef INT32_MAX +# undef UINT16_MAX +# undef UINT32_MAX +#endif + +#include +#include +#include +#include + +#define ARRAY_CARDINALITY(Array) (sizeof (Array) / sizeof *(Array)) +#define STREQ(L, R) (strcmp(L, R) == 0) +#define STRNEQ(L, R) (!STREQ(L, R)) + +/* Just like strncmp, but the second argument must be a literal string + and you don't specify the length. */ +#define STRNCMP_LIT(S, Literal) \ + strncmp (S, "" Literal "", sizeof (Literal) - 1) + +/* Whether Literal is a prefix of S. */ +#define STRPREFIX_LIT(Literal, S) \ + (STRNCMP_LIT (S, Literal) == 0) + +#if HAVE_SYS_TYPES_H +# include +#endif + +#include +#include + +#ifndef UINTPTR_MAX /* This isn't perfect, but it's good enough for Bison, which needs only to hash pointers. */ typedef size_t uintptr_t; -# endif +#endif // Version mismatch. -# define EX_MISMATCH 63 +#define EX_MISMATCH 63 /*---------. | Gnulib. | `---------*/ -# include -# include -# include +#include +#include +#include /*-----------------. @@@ -93,49 -80,49 +93,49 @@@ and safer logic than it would for users. Due to the overhead of M4, suppressing Code is unlikely to offer any significant improvement in Bison's performance anyway. */ -# define PACIFY_CC(Code) Code +#define PACIFY_CC(Code) Code -# ifndef __attribute__ +#ifndef __attribute__ /* This feature is available in gcc versions 2.5 and later. */ -# if (! defined __GNUC__ || __GNUC__ < 2 \ +# if (! defined __GNUC__ || __GNUC__ < 2 \ || (__GNUC__ == 2 && __GNUC_MINOR__ < 5)) -# define __attribute__(Spec) /* empty */ -# endif +# define __attribute__(Spec) /* empty */ # endif +#endif /* The __-protected variants of `format' and `printf' attributes are accepted by gcc versions 2.6.4 (effectively 2.7) and later. */ -# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7) -# define __format__ format -# define __printf__ printf -# endif +#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7) +# define __format__ format +# define __printf__ printf +#endif -# ifndef ATTRIBUTE_NORETURN -# define ATTRIBUTE_NORETURN __attribute__ ((__noreturn__)) -# endif +#ifndef ATTRIBUTE_NORETURN +# define ATTRIBUTE_NORETURN __attribute__ ((__noreturn__)) +#endif -# ifndef ATTRIBUTE_UNUSED -# define ATTRIBUTE_UNUSED __attribute__ ((__unused__)) -# endif +#ifndef ATTRIBUTE_UNUSED +# define ATTRIBUTE_UNUSED __attribute__ ((__unused__)) +#endif -# define FUNCTION_PRINT() fprintf (stderr, "%s: ", __func__) +#define FUNCTION_PRINT() fprintf (stderr, "%s: ", __func__) /*------. | NLS. | `------*/ -# include +#include -# include -# define _(Msgid) gettext (Msgid) -# define N_(Msgid) (Msgid) +#include +#define _(Msgid) gettext (Msgid) +#define N_(Msgid) (Msgid) /*-----------. | Booleans. | `-----------*/ -# include +#include @@@ -161,50 -148,21 +161,21 @@@ For now, we use assert but we call it aver throughout Bison in case we later wish to try another scheme. */ -# include -# define aver assert +#include +#define aver assert /*-----------. | Obstacks. | `-----------*/ -# define obstack_chunk_alloc xmalloc -# define obstack_chunk_free free -# include +#define obstack_chunk_alloc xmalloc +#define obstack_chunk_free free +#include -# define obstack_sgrow(Obs, Str) \ +#define obstack_sgrow(Obs, Str) \ obstack_grow (Obs, Str, strlen (Str)) - #define obstack_fgrow1(Obs, Format, Arg1) \ - do { \ - char buf[4096]; \ - sprintf (buf, Format, Arg1); \ - obstack_grow (Obs, buf, strlen (buf)); \ - } while (0) - - #define obstack_fgrow2(Obs, Format, Arg1, Arg2) \ - do { \ - char buf[4096]; \ - sprintf (buf, Format, Arg1, Arg2); \ - obstack_grow (Obs, buf, strlen (buf)); \ - } while (0) - - #define obstack_fgrow3(Obs, Format, Arg1, Arg2, Arg3) \ - do { \ - char buf[4096]; \ - sprintf (buf, Format, Arg1, Arg2, Arg3); \ - obstack_grow (Obs, buf, strlen (buf)); \ - } while (0) - - #define obstack_fgrow4(Obs, Format, Arg1, Arg2, Arg3, Arg4) \ - do { \ - char buf[4096]; \ - sprintf (buf, Format, Arg1, Arg2, Arg3, Arg4); \ - obstack_grow (Obs, buf, strlen (buf)); \ - } while (0) - - /* Output Str escaped for our postprocessing (i.e., escape M4 special characters). @@@ -212,15 -170,15 +183,15 @@@ # define obstack_escape(Obs, Str) \ do { \ - char const *p; \ - for (p = Str; *p; p++) \ - switch (*p) \ + char const *p__; \ + for (p__ = Str; *p__; p__++) \ + switch (*p__) \ { \ case '$': obstack_sgrow (Obs, "$]["); break; \ case '@': obstack_sgrow (Obs, "@@" ); break; \ case '[': obstack_sgrow (Obs, "@{" ); break; \ case ']': obstack_sgrow (Obs, "@}" ); break; \ - default: obstack_1grow (Obs, *p ); break; \ + default: obstack_1grow (Obs, *p__ ); break; \ } \ } while (0) @@@ -253,13 -211,13 +224,13 @@@ | Extensions to use for the output files. | `-----------------------------------------*/ -# ifndef OUTPUT_EXT -# define OUTPUT_EXT ".output" -# endif +#ifndef OUTPUT_EXT +# define OUTPUT_EXT ".output" +#endif -# ifndef TAB_EXT -# define TAB_EXT ".tab" -# endif +#ifndef TAB_EXT +# define TAB_EXT ".tab" +#endif @@@ -267,15 -225,15 +238,15 @@@ | Free a linked list. | `---------------------*/ -# define LIST_FREE(Type, List) \ - do { \ - Type *_node, *_next; \ - for (_node = List; _node; _node = _next) \ - { \ - _next = _node->next; \ - free (_node); \ - } \ - } while (0) +#define LIST_FREE(Type, List) \ +do { \ + Type *_node, *_next; \ + for (_node = List; _node; _node = _next) \ + { \ + _next = _node->next; \ + free (_node); \ + } \ +} while (0) /*---------------------------------------------. diff --combined tests/actions.at index 16711ddd,1ec8ef9a..269bcce5 --- a/tests/actions.at +++ b/tests/actions.at @@@ -1,4 -1,4 +1,4 @@@ -# Executing Actions. -*- Autotest -*- +e# Executing Actions. -*- Autotest -*- # Copyright (C) 2001-2012 Free Software Foundation, Inc. @@@ -30,7 -30,7 +30,7 @@@ AT_SETUP([Mid-rule actions] AT_BISON_OPTION_PUSHDEFS AT_DATA_GRAMMAR([[input.y]], -[[%error-verbose +[[%define parse.error verbose %debug %{ ]AT_YYERROR_DECLARE[ @@@ -80,7 -80,7 +80,7 @@@ AT_SETUP([Exotic Dollars] AT_BISON_OPTION_PUSHDEFS AT_DATA_GRAMMAR([[input.y]], -[[%error-verbose +[[%define parse.error verbose %debug %{ ]AT_YYERROR_DECLARE[ @@@ -136,7 -136,7 +136,7 @@@ AT_PARSER_CHECK([./input], 0 AT_DATA_GRAMMAR([[input.y]], [[ %{ -#include +# include ]AT_YYERROR_DECLARE[ ]AT_YYLEX_DECLARE[ typedef struct { int val; } stype; @@@ -264,7 -264,7 +264,7 @@@ input V(input, $$, @$, ": /* Nothing */\n"); } | line input /* Right recursive to load the stack so that popping at - END can be exercised. */ + END can be exercised. */ { $$ = 2; V(input, $$, @$, ": "); @@@ -561,7 -561,7 +561,7 @@@ m4_define([AT_CHECK_PRINTER_AND_DESTRUC $3 _AT_CHECK_PRINTER_AND_DESTRUCTOR($[1], $[2], $[3], $[4], -[%error-verbose +[%define parse.error verbose %debug %verbose %locations @@@ -592,7 -592,7 +592,7 @@@ AT_CHECK_PRINTER_AND_DESTRUCTOR([%glr-p AT_SETUP([Default tagless %printer and %destructor]) AT_BISON_OPTION_PUSHDEFS([%locations]) AT_DATA_GRAMMAR([[input.y]], -[[%error-verbose +[[%define parse.error verbose %debug %locations %initial-action { @@@ -646,10 -646,7 +646,10 @@@ main (void } ]]) -AT_BISON_CHECK([-o input.c input.y]) +AT_BISON_CHECK([-o input.c input.y], [], [], +[[input.y:27.3-5: warning: useless %destructor for type <*> [-Wother] +input.y:27.3-5: warning: useless %printer for type <*> [-Wother] +]]) AT_COMPILE([input]) AT_PARSER_CHECK([./input], 1, [[<> destructor for 'd' @ 4. @@@ -697,7 -694,7 +697,7 @@@ AT_CLEANU AT_SETUP([Default tagged and per-type %printer and %destructor]) AT_BISON_OPTION_PUSHDEFS AT_DATA_GRAMMAR([[input.y]], -[[%error-verbose +[[%define parse.error verbose %debug %{ @@@ -761,10 -758,7 +761,10 @@@ main (void } ]]) -AT_BISON_CHECK([-o input.c input.y]) +AT_BISON_CHECK([-o input.c input.y], [], [], +[[input.y:22.3-4: warning: useless %destructor for type <> [-Wother] +input.y:22.3-4: warning: useless %printer for type <> [-Wother] +]]) AT_COMPILE([input]) AT_PARSER_CHECK([./input], 1, [[<*>//e destructor. @@@ -823,16 -817,16 +823,16 @@@ AT_CLEANU AT_SETUP([Default %printer and %destructor for user-defined end token]) -# _AT_CHECK_DEFAULT_PRINTER_AND_DESTRUCTOR_FOR_END_TOKEN(TYPED) -# ------------------------------------------------------------- -m4_define([_AT_CHECK_DEFAULT_PRINTER_AND_DESTRUCTOR_FOR_END_TOKEN], +# AT_TEST(TYPED) +# -------------- +m4_pushdef([AT_TEST], [m4_if($1, 0, [m4_pushdef([kind], []) m4_pushdef([not_kind], [*])], [m4_pushdef([kind], [*]) m4_pushdef([not_kind], [])]) AT_BISON_OPTION_PUSHDEFS([%locations]) AT_DATA_GRAMMAR([[input]]$1[[.y]], -[[%error-verbose +[[%define parse.error verbose %debug %locations %initial-action { @@@ -897,17 -891,8 +897,17 @@@ main (void ]]) AT_BISON_OPTION_POPDEFS -AT_BISON_CHECK([-o input$1.c input$1.y]) +AT_BISON_CHECK([-o input$1.c input$1.y], [], [], +[m4_if([$1], [0], +[[input0.y:27.3-5: warning: useless %destructor for type <*> [-Wother] +input0.y:27.3-5: warning: useless %printer for type <*> [-Wother] +]], +[[input1.y:27.3-4: warning: useless %destructor for type <> [-Wother] +input1.y:27.3-4: warning: useless %printer for type <> [-Wother] +]])]) + AT_COMPILE([input$1]) + AT_PARSER_CHECK([./input$1], 0, [[<]]kind[[> for 'E' @ 1. <]]kind[[> for 'S' @ 1. @@@ -930,10 -915,8 +930,10 @@@ m4_popdef([kind] m4_popdef([not_kind]) ]) -_AT_CHECK_DEFAULT_PRINTER_AND_DESTRUCTOR_FOR_END_TOKEN(0) -_AT_CHECK_DEFAULT_PRINTER_AND_DESTRUCTOR_FOR_END_TOKEN(1) +AT_TEST(0) +AT_TEST(1) + +m4_popdef([AT_TEST]) AT_CLEANUP @@@ -993,10 -976,7 +993,10 @@@ main (void ]]) AT_BISON_OPTION_POPDEFS -AT_BISON_CHECK([-o input.c input.y]) +AT_BISON_CHECK([-o input.c input.y], [], [], +[[input.y:21.6-8: warning: useless %destructor for type <*> [-Wother] +input.y:21.6-8: warning: useless %printer for type <*> [-Wother] +]]) AT_COMPILE([input]) AT_PARSER_CHECK([./input], [1], [], [[Starting parse @@@ -1095,10 -1075,7 +1095,10 @@@ main (void ]]) AT_BISON_OPTION_POPDEFS -AT_BISON_CHECK([-o input.c input.y]) +AT_BISON_CHECK([-o input.c input.y], [], [], +[[input.y:22.3-4: warning: useless %destructor for type <> [-Wother] +input.y:22.3-4: warning: useless %printer for type <> [-Wother] +]]) AT_COMPILE([input]) AT_CLEANUP @@@ -1155,10 -1132,8 +1155,10 @@@ main (void AT_BISON_OPTION_POPDEFS AT_BISON_CHECK([-o input.c input.y], 0,, -[[input.y:33.3-23: warning: unset value: $$ -input.y:30.3-35.37: warning: unused value: $3 +[[input.y:24.70-72: warning: useless %destructor for type <*> [-Wother] +input.y:24.70-72: warning: useless %printer for type <*> [-Wother] +input.y:33.3-23: warning: unset value: $$ [-Wother] +input.y:30.3-35.37: warning: unused value: $3 [-Wother] ]]) AT_COMPILE([input]) @@@ -1273,16 -1248,15 +1273,14 @@@ AT_CHECK_ACTION_LOCATIONS([[%printer]] m4_pushdef([AT_TEST], [AT_SETUP([[Qualified $$ in actions: $1]]) -AT_BISON_OPTION_PUSHDEFS([%locations %skeleton "$1"]) +AT_BISON_OPTION_PUSHDEFS([%skeleton "$1"]) AT_DATA_GRAMMAR([[input.y]], [[%skeleton "$1" -%defines // FIXME: Mandated by lalr1.cc in Bison 2.6. -%locations // FIXME: Mandated by lalr1.cc in Bison 2.6. +%defines // FIXME: Mandated by glr.cc. %debug %code requires { - # include - typedef struct sem_type { int ival; @@@ -1291,20 -1265,21 +1289,21 @@@ # define YYSTYPE sem_type - #ifdef __cplusplus + ]AT_SKEL_CC_IF([[ # include static void report (std::ostream& yyo, int ival, float fval) { yyo << "ival: " << ival << ", fval: " << fval; } - #else + ]], [[ + # include static void report (FILE* yyo, int ival, float fval) { fprintf (yyo, "ival: %d, fval: %1.1f", ival, fval); } - #endif + ]])[ } %code @@@ -1320,6 -1295,17 +1319,6 @@@ %printer { report (yyo, $$, $$ ); } ; %printer { report (yyo, $$, $$); } <>; -]AT_SKEL_CC_IF([[ -/* The lalr1.cc skeleton, for backward compatibility, defines - a constructor for position that initializes the filename. The - glr.cc skeleton does not (and in fact cannot: location/position - are stored in a union, from which objects with constructors are - excluded in C++). */ -%initial-action { - @$.initialize (); -} -]])[ - %initial-action { $$ = 42; @@@ -1354,7 -1340,10 +1353,7 @@@ AT_FULL_COMPILE([[input]] AT_PARSER_CHECK([./input], 0, [], [stderr]) # Don't be too picky on the traces, GLR is not exactly the same. Keep # only the lines from the printer. -# -# Don't care about locations. FIXME: remove their removal when Bison -# supports C++ without locations. -AT_CHECK([[sed -ne 's/([-0-9.]*: /(/;/ival:/p' stderr]], 0, +AT_CHECK([[sed -ne '/ival:/p' stderr]], 0, [[Reading a token: Next token is token UNTYPED (ival: 10, fval: 0.1) Shifting token UNTYPED (ival: 10, fval: 0.1) Reading a token: Next token is token INT (ival: 20, fval: 0.2) @@@ -1392,37 -1381,37 +1391,37 @@@ 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 */ } +: '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 ; + : '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 {} + : '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 @@@ -1439,42 -1428,42 +1438,42 @@@ 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 -input.y:8.48: warning: future versions of Bison will not add the ';' -input.y:9.48: warning: a ';' might be needed at the end of action code -input.y:9.48: warning: future versions of Bison will not add the ';' -input.y:10.48: warning: a ';' might be needed at the end of action code -input.y:10.48: warning: future versions of Bison will not add the ';' -input.y:11.48: warning: a ';' might be needed at the end of action code -input.y:11.48: warning: future versions of Bison will not add the ';' -input.y:12.48: warning: a ';' might be needed at the end of action code -input.y:12.48: warning: future versions of Bison will not add the ';' -input.y:13.48: warning: a ';' might be needed at the end of action code -input.y:13.48: warning: future versions of Bison will not add the ';' -input.y:20.1: warning: a ';' might be needed at the end of action code -input.y:20.1: warning: future versions of Bison will not add the ';' -input.y:21.1: warning: a ';' might be needed at the end of action code -input.y:21.1: warning: future versions of Bison will not add the ';' -input.y:22.1: warning: a ';' might be needed at the end of action code -input.y:22.1: warning: future versions of Bison will not add the ';' -input.y:23.1: warning: a ';' might be needed at the end of action code -input.y:23.1: warning: future versions of Bison will not add the ';' -input.y:24.1: warning: a ';' might be needed at the end of action code -input.y:24.1: warning: future versions of Bison will not add the ';' -input.y:25.1: warning: a ';' might be needed at the end of action code -input.y:25.1: warning: future versions of Bison will not add the ';' -input.y:31.1: warning: a ';' might be needed at the end of action code -input.y:31.1: warning: future versions of Bison will not add the ';' -input.y:32.1: warning: a ';' might be needed at the end of action code -input.y:32.1: warning: future versions of Bison will not add the ';' -input.y:33.1: warning: a ';' might be needed at the end of action code -input.y:33.1: warning: future versions of Bison will not add the ';' -input.y:34.1: warning: a ';' might be needed at the end of action code -input.y:34.1: warning: future versions of Bison will not add the ';' -input.y:35.1: warning: a ';' might be needed at the end of action code -input.y:35.1: warning: future versions of Bison will not add the ';' -input.y:36.1: warning: a ';' might be needed at the end of action code -input.y:36.1: warning: future versions of Bison will not add the ';' +[[input.y:8.48: warning: a ';' might be needed at the end of action code [-Wother] +input.y:8.48: warning: future versions of Bison will not add the ';' [-Wother] +input.y:9.48: warning: a ';' might be needed at the end of action code [-Wother] +input.y:9.48: warning: future versions of Bison will not add the ';' [-Wother] +input.y:10.48: warning: a ';' might be needed at the end of action code [-Wother] +input.y:10.48: warning: future versions of Bison will not add the ';' [-Wother] +input.y:11.48: warning: a ';' might be needed at the end of action code [-Wother] +input.y:11.48: warning: future versions of Bison will not add the ';' [-Wother] +input.y:12.48: warning: a ';' might be needed at the end of action code [-Wother] +input.y:12.48: warning: future versions of Bison will not add the ';' [-Wother] +input.y:13.48: warning: a ';' might be needed at the end of action code [-Wother] +input.y:13.48: warning: future versions of Bison will not add the ';' [-Wother] +input.y:20.1: warning: a ';' might be needed at the end of action code [-Wother] +input.y:20.1: warning: future versions of Bison will not add the ';' [-Wother] +input.y:21.1: warning: a ';' might be needed at the end of action code [-Wother] +input.y:21.1: warning: future versions of Bison will not add the ';' [-Wother] +input.y:22.1: warning: a ';' might be needed at the end of action code [-Wother] +input.y:22.1: warning: future versions of Bison will not add the ';' [-Wother] +input.y:23.1: warning: a ';' might be needed at the end of action code [-Wother] +input.y:23.1: warning: future versions of Bison will not add the ';' [-Wother] +input.y:24.1: warning: a ';' might be needed at the end of action code [-Wother] +input.y:24.1: warning: future versions of Bison will not add the ';' [-Wother] +input.y:25.1: warning: a ';' might be needed at the end of action code [-Wother] +input.y:25.1: warning: future versions of Bison will not add the ';' [-Wother] +input.y:31.1: warning: a ';' might be needed at the end of action code [-Wother] +input.y:31.1: warning: future versions of Bison will not add the ';' [-Wother] +input.y:32.1: warning: a ';' might be needed at the end of action code [-Wother] +input.y:32.1: warning: future versions of Bison will not add the ';' [-Wother] +input.y:33.1: warning: a ';' might be needed at the end of action code [-Wother] +input.y:33.1: warning: future versions of Bison will not add the ';' [-Wother] +input.y:34.1: warning: a ';' might be needed at the end of action code [-Wother] +input.y:34.1: warning: future versions of Bison will not add the ';' [-Wother] +input.y:35.1: warning: a ';' might be needed at the end of action code [-Wother] +input.y:35.1: warning: future versions of Bison will not add the ';' [-Wother] +input.y:36.1: warning: a ';' might be needed at the end of action code [-Wother] +input.y:36.1: warning: future versions of Bison will not add the ';' [-Wother] ]]) AT_MATCHES_CHECK([input.c], [[/\* TEST:N:2 \*/ \}$]], [[3]])