Import byacc-20141006.
authorSascha Wildner <saw@online.de>
Sat, 8 Nov 2014 23:01:41 +0000 (00:01 +0100)
committerSascha Wildner <saw@online.de>
Sat, 8 Nov 2014 23:01:41 +0000 (00:01 +0100)
15 files changed:
contrib/byacc/CHANGES
contrib/byacc/VERSION
contrib/byacc/closure.c
contrib/byacc/defs.h
contrib/byacc/error.c
contrib/byacc/graph.c
contrib/byacc/lalr.c
contrib/byacc/lr0.c
contrib/byacc/main.c
contrib/byacc/mkpar.c
contrib/byacc/output.c
contrib/byacc/reader.c
contrib/byacc/symtab.c
contrib/byacc/verbose.c
contrib/byacc/yacc.1

index 877b227..1f01461 100644 (file)
@@ -1,3 +1,978 @@
+2014-10-06  Thomas E. Dickey  <tom@invisible-island.net>
+
+       * package/debian/source/format:
+       change to native format to work around regression in Debian packaging.
+
+       * VERSION, package/byacc.spec, package/debian/changelog, package/mingw-byacc.spec, package/pkgsrc/Makefile:
+       bump
+
+       * configure: regen
+
+       * main.c:
+       correct parameter for umask - for very old mkstemp's - and use type mode_t
+       to quiet compiler warning
+
+       * configure.in: add configure check for mode_t
+
+       * reader.c:
+       better fix for get_line, by ensuring there is enough space to null-terminate
+       its result (prompted by discussion with Craig Rodrigues).
+
+2014-10-05  Thomas E. Dickey  <tom@invisible-island.net>
+
+       * main.c:
+       make change to umask before calling mkstemp, as suggested in Coverity #56902
+
+       * reader.c:
+       adjust logic in copy_action to avoid potential null-pointer dereference
+       (Coverity #56901)
+
+       * reader.c:
+       adjust logic to avoid potential null-pointer dereference in compile_args
+       (Coverity #63407)
+
+       * reader.c: eliminate strcpy into fixed-size buffer (Coverity #63408)
+
+       * yacc.1: document changes made with respect to %parse-param
+
+       * output.c:
+       add parameters from %parse-param to destructor.  The order of the parameters
+       is intentionally inconsistent with yyparse/yyerror, for "compatibility" with
+       bison.
+
+       * test/btyacc/btyacc_destroy1.tab.c, test/btyacc/btyacc_destroy2.tab.c, test/btyacc/btyacc_destroy3.tab.c:
+       regen
+
+       * output.c:
+       use puts_param_types/puts_param_names to output lex_param data.
+
+       * test/btyacc/ok_syntax1.tab.c, test/btyacc/calc2.tab.c, test/btyacc/calc3.tab.c, test/yacc/ok_syntax1.tab.c, test/yacc/calc2.tab.c, test/yacc/calc3.tab.c, test/btyacc/error.tab.c, test/btyacc/grammar.tab.c, test/btyacc/inherit0.tab.c, test/btyacc/inherit1.tab.c, test/btyacc/inherit2.tab.c, test/btyacc/pure_calc.tab.c, test/btyacc/pure_error.tab.c, test/btyacc/quote_calc-s.tab.c, test/btyacc/quote_calc.tab.c, test/btyacc/quote_calc2-s.tab.c, test/btyacc/quote_calc2.tab.c, test/btyacc/quote_calc3-s.tab.c, test/btyacc/quote_calc3.tab.c, test/btyacc/quote_calc4-s.tab.c, test/btyacc/quote_calc4.tab.c, test/btyacc/varsyntax_calc1.tab.c, test/btyacc/btyacc_calc1.tab.c, test/btyacc/btyacc_demo.tab.c, test/btyacc/calc.tab.c, test/btyacc/calc1.tab.c, test/btyacc/code_calc.code.c, test/btyacc/code_error.code.c, test/btyacc/empty.tab.c, test/btyacc/err_inherit3.tab.c, test/btyacc/err_inherit4.tab.c, test/btyacc/err_syntax10.tab.c, test/btyacc/err_syntax11.tab.c, test/btyacc/err_syntax12.tab.c, test/btyacc/err_syntax18.tab.c, test/btyacc/err_syntax20.tab.c, test/btyacc/rename_debug.c:
+       regen
+
+       * btyaccpar.c: add casts, change types to fix strict compiler warnings
+
+       * test/btyacc/err_syntax17.tab.c, test/btyacc/err_syntax19.tab.c, test/btyacc/err_syntax2.tab.c, test/btyacc/err_syntax21.tab.c, test/btyacc/err_syntax22.tab.c, test/btyacc/err_syntax23.tab.c, test/btyacc/err_syntax24.tab.c, test/btyacc/err_syntax25.tab.c, test/btyacc/err_syntax26.tab.c, test/btyacc/err_syntax27.tab.c, test/btyacc/err_syntax3.tab.c, test/btyacc/err_syntax4.tab.c, test/btyacc/err_syntax5.tab.c, test/btyacc/err_syntax6.tab.c, test/btyacc/err_syntax7.tab.c, test/btyacc/err_syntax7a.tab.c, test/btyacc/err_syntax7b.tab.c, test/btyacc/err_syntax8.tab.c, test/btyacc/err_syntax8a.tab.c, test/btyacc/err_syntax9.tab.c, test/btyacc/err_inherit1.tab.c, test/btyacc/err_inherit2.tab.c, test/btyacc/err_inherit5.tab.c, test/btyacc/err_syntax1.tab.c, test/btyacc/err_syntax13.tab.c, test/btyacc/err_syntax14.tab.c, test/btyacc/err_syntax15.tab.c, test/btyacc/err_syntax16.tab.c:
+       regen
+
+       * output.c: gcc-warning
+
+       * test/btyacc/code_calc.tab.c, test/btyacc/code_error.tab.c: regen
+
+       * output.c: fix limit when merging real/workaround tables
+
+       * output.c:
+       for btyacc, it is possible to have no conflicts - but in that case, the
+       "ctable" was not generated at all, while the skeleton uses the table.
+       The most straightforward (workaround) is generating a dummy table which
+       rejects any state.
+
+       * test/btyacc_destroy3.y, test/btyacc_destroy2.y, test/btyacc_destroy1.y:
+       fix "make check_make"
+
+       * test/yacc/calc3.tab.c, test/yacc/ok_syntax1.tab.c, test/yacc/calc2.tab.c, test/btyacc/btyacc_destroy1.tab.c, test/btyacc/btyacc_destroy2.tab.c:
+       regen
+
+       * reader.c:
+       trim blanks from interim value in copy_param() to handle special case when
+       a space precedes a comma.
+
+       * output.c:
+       use two new functions, puts_param_types and puts_param_names, to improve
+       format of the parse_param list (by trimming space after "*") as well as
+       correcting the output of the comma-separated names (only the last name
+       was output).
+
+       * test/btyacc/ok_syntax1.tab.c, test/btyacc/btyacc_destroy3.tab.c, test/btyacc/calc2.tab.c, test/btyacc/calc3.tab.c:
+       regen
+
+       * reader.c:
+       modify copy_param() to handle resulting comma-separated list.  Before, it
+       only expected a single parameter.
+
+2014-10-04  Thomas E. Dickey  <tom@invisible-island.net>
+
+       * reader.c: split-out save_param() from copy_param()
+
+       * reader.c: trim_blanks() did not always convert spaces - fix.
+
+       * reader.c: fix some minor regressions with error-reporting
+
+       * aclocal.m4: update CF_XOPEN_SOURCE for Unixware change from lynx
+
+       * VERSION, package/byacc.spec, package/debian/changelog, package/mingw-byacc.spec, package/pkgsrc/Makefile:
+       bump
+
+       * reader.c:
+       modify copy_param() to accept multiple parameters, each in curly braces like
+       recent bison, as well as honoring bison's undocumented feature to accept the
+       parameters as a comma-separated list.
+
+       * test/btyacc/btyacc_destroy3.tab.c, test/btyacc/btyacc_destroy1.tab.c, test/btyacc/btyacc_destroy2.tab.c, test/btyacc/btyacc_destroy3.error, test/btyacc/btyacc_destroy3.output, test/btyacc/btyacc_destroy3.tab.h, test/btyacc/btyacc_destroy2.error, test/btyacc/btyacc_destroy2.output, test/btyacc/btyacc_destroy2.tab.h:
+       RCS_BASE
+
+2014-10-03  Thomas E. Dickey  <tom@invisible-island.net>
+
+       * test/btyacc/btyacc_demo2.error, test/btyacc/btyacc_demo2.output, test/btyacc/btyacc_demo2.tab.c, test/btyacc/btyacc_demo2.tab.h, test/btyacc/btyacc_destroy1.error, test/btyacc/btyacc_destroy1.output, test/btyacc/btyacc_destroy1.tab.h, test/btyacc_destroy3.y, test/btyacc_destroy1.y, test/btyacc_destroy2.y:
+       RCS_BASE
+
+2014-10-02  Thomas E. Dickey  <tom@invisible-island.net>
+
+       * main.c, reader.c, defs.h:
+       use calloc in get_line() when allocating line to ensure it is fully initialized,
+       fixes a later uninitialized value in copy_param() (FreeBSD #193499).
+
+2014-09-17  Thomas E. Dickey  <tom@invisible-island.net>
+
+       * closure.c, lalr.c, output.c, defs.h:
+       rephrase odd addressing to fix Coverity #48848, #38950, #38860, not actually
+       a bug.
+
+2014-09-01  Thomas E. Dickey  <tom@invisible-island.net>
+
+       * config.sub: update to 2014-07-28
+
+2014-07-27  Thomas E. Dickey  <tom@invisible-island.net>
+
+       * configure: regen
+
+       * aclocal.m4: modified to support port to Minix3.2
+
+       * package/pkgsrc/Makefile, VERSION, package/byacc.spec, package/debian/changelog, package/mingw-byacc.spec:
+       bump
+
+2014-07-15  Thomas E. Dickey  <tom@invisible-island.net>
+
+       * aclocal.m4: resync with my-autoconf (no change to configure script)
+
+       * VERSION, package/byacc.spec, package/debian/changelog, package/mingw-byacc.spec, package/pkgsrc/Makefile:
+       bump
+
+       * test/run_test.sh:
+       make top-level "make check" work again, by adding another step to filtering
+       the test results.
+
+2014-07-14  Thomas E. Dickey  <tom@invisible-island.net>
+
+       * test/run_test.sh: changes from Garrett Cooper's patch:
+               a) ensure that the script returns an error-code if there are differences
+               b) escape "." character in left side of sed expression for $YACC
+               c) ensure that $ifBTYACC has a value
+
+       * test/btyacc/big_b.output, test/btyacc/big_l.output, test/btyacc/help.output, test/btyacc/no_b_opt.output, test/btyacc/no_output2.output, test/btyacc/no_p_opt.output, test/btyacc/nostdin.output:
+       regen (reminder by Garrett Cooper)
+
+2014-07-14  Garrett.Cooper
+
+       * test/btyacc/err_inherit1.error, test/btyacc/err_inherit2.error, test/btyacc/err_inherit3.error, test/btyacc/err_inherit4.error, test/btyacc/err_inherit5.error, test/btyacc/err_syntax1.error, test/btyacc/err_syntax10.error, test/btyacc/err_syntax11.error, test/btyacc/err_syntax12.error, test/btyacc/err_syntax13.error, test/btyacc/err_syntax14.error, test/btyacc/err_syntax15.error, test/btyacc/err_syntax16.error, test/btyacc/err_syntax17.error, test/btyacc/err_syntax18.error, test/btyacc/err_syntax19.error, test/btyacc/err_syntax2.error, test/btyacc/err_syntax21.error, test/btyacc/err_syntax22.error, test/btyacc/err_syntax23.error, test/btyacc/err_syntax24.error, test/btyacc/err_syntax25.error, test/btyacc/err_syntax26.error, test/btyacc/err_syntax27.error, test/btyacc/err_syntax3.error, test/btyacc/err_syntax4.error, test/btyacc/err_syntax5.error, test/btyacc/err_syntax6.error, test/btyacc/err_syntax7.error, test/btyacc/err_syntax7a.error, test/btyacc/err_syntax7b.error, test/btyacc/err_syntax8.error, test/btyacc/err_syntax8a.error, test/btyacc/err_syntax9.error, test/yacc/err_syntax1.error, test/yacc/err_syntax10.error, test/yacc/err_syntax11.error, test/yacc/err_syntax12.error, test/yacc/err_syntax13.error, test/yacc/err_syntax14.error, test/yacc/err_syntax15.error, test/yacc/err_syntax16.error, test/yacc/err_syntax17.error, test/yacc/err_syntax18.error, test/yacc/err_syntax19.error, test/yacc/err_syntax2.error, test/yacc/err_syntax21.error, test/yacc/err_syntax22.error, test/yacc/err_syntax23.error, test/yacc/err_syntax24.error, test/yacc/err_syntax25.error, test/yacc/err_syntax26.error, test/yacc/err_syntax27.error, test/yacc/err_syntax3.error, test/yacc/err_syntax4.error, test/yacc/err_syntax5.error, test/yacc/err_syntax6.error, test/yacc/err_syntax7.error, test/yacc/err_syntax7a.error, test/yacc/err_syntax7b.error, test/yacc/err_syntax8.error, test/yacc/err_syntax8a.error, test/yacc/err_syntax9.error:
+       regen
+
+2014-05-27  Tom.Shields
+
+       * main.c: remove obsolete -D option from usage message
+
+2014-05-27  Thomas E. Dickey  <tom@invisible-island.net>
+
+       * VERSION, package/byacc.spec, package/debian/changelog, test/yacc/big_b.output, test/yacc/big_l.output, test/yacc/help.output, test/yacc/no_b_opt.output, test/yacc/no_output2.output, test/yacc/no_p_opt.output, test/yacc/nostdin.output:
+       bump
+
+2014-04-22  Thomas E. Dickey  <tom@invisible-island.net>
+
+       * mstring.c:
+       use vsnprintf() to ensure that msprintf's buffer is large enough.
+
+       * main.c, defs.h: add mstring_leaks()
+
+       * configure: regen
+
+       * output.c: fix a complementary warning
+
+       * mstring.c: introduce vsnprintf
+
+       * configure.in, config_h.in: add check for vsnprintf
+
+       * output.c: quiet a type-conversion warning
+
+       * mstring.c: fix a potential memory leak on ENOMEM
+       quiet a couple of type-conversion warnings
+
+       * defs.h: add/use GCC_PRINTFLIKE for msprintf()
+
+2014-04-22  Tom.Shields
+
+       * README.BTYACC:
+       drop "NOTES-btyacc-Changes" and "NOTES-btyacc-Disposition", merging relevant
+       content into README.BTYACC
+
+2014-04-22  Thomas E. Dickey  <tom@invisible-island.net>
+
+       * package/pkgsrc/Makefile, VERSION, package/byacc.spec, package/debian/changelog, package/mingw-byacc.spec:
+       bump
+
+2014-04-19  Thomas E. Dickey  <tom@invisible-island.net>
+
+       * config.sub: 2014-04-03
+
+       * config.guess: 2014-03-23
+
+2014-04-09  Rick.Spates
+
+       * main.c, defs.h: patch to allow DEBUG build with WIN32 system
+
+2014-04-09  Thomas E. Dickey  <tom@invisible-island.net>
+
+       * output.c, reader.c: gcc warnings
+
+       * reader.c: fix const-cast warnings
+
+       * test/btyacc/quote_calc-s.tab.c, test/btyacc/quote_calc.tab.c, test/btyacc/quote_calc3-s.tab.c, test/btyacc/quote_calc4-s.tab.c, test/btyacc/quote_calc4.tab.c, test/btyacc/varsyntax_calc1.tab.c, test/btyacc/grammar.tab.c, test/btyacc/inherit0.tab.c, test/btyacc/inherit1.tab.c, test/btyacc/inherit2.tab.c, test/btyacc/ok_syntax1.tab.c, test/btyacc/pure_calc.tab.c, test/btyacc/pure_error.tab.c, test/btyacc/quote_calc2-s.tab.c, test/btyacc/quote_calc2.tab.c, test/btyacc/quote_calc3.tab.c, test/btyacc/err_syntax18.tab.c, test/btyacc/err_syntax20.tab.c, test/btyacc/code_error.tab.c, test/btyacc/empty.tab.c, test/btyacc/err_inherit3.tab.c, test/btyacc/err_inherit4.tab.c, test/btyacc/err_syntax10.tab.c, test/btyacc/err_syntax11.tab.c, test/btyacc/err_syntax12.tab.c, test/btyacc/error.tab.c, test/btyacc/rename_debug.c, test/btyacc/calc.tab.c, test/btyacc/calc1.tab.c, test/btyacc/calc2.tab.c, test/btyacc/calc3.tab.c, test/btyacc/code_calc.tab.c, output.c:
+       fix a few clang --analyze warnings; one was a case where output_ctable emitted
+       an empty table (which should be an error).
+
+       * reader.c: appease clang --analyze
+
+       * defs.h: mark two functions as no-return.
+
+       * package/debian/changelog: reason for release
+
+       * VERSION, package/byacc.spec, package/debian/changelog, package/mingw-byacc.spec, package/pkgsrc/Makefile:
+       bump
+
+       * makefile.in: use $LINT_OPTS from environment via configure script
+
+       * test/btyacc/ok_syntax1.output, test/btyacc/ok_syntax1.tab.c, test/yacc/ok_syntax1.tab.c, test/ok_syntax1.y, test/yacc/ok_syntax1.output:
+       tweaks to make generated files from ok_syntax1.y compile with check_make rule
+
+       * test/btyacc/rename_debug.c, test/btyacc/rename_debug.error, test/btyacc/rename_debug.h, test/btyacc/rename_debug.i, test/btyacc/rename_debug.output, test/yacc/rename_debug.c:
+       reference output for testing
+
+       * test/run_test.sh:
+       retain the renaming done for code_debug.y so that check_make will work.
+
+       * test/yacc/rename_debug.error, test/yacc/rename_debug.h, test/yacc/rename_debug.i, test/yacc/rename_debug.output:
+       reference output for testing
+
+       * test/btyacc/ok_syntax1.error: RCS_BASE
+
+       * test/yacc/quote_calc4-s.tab.c, test/yacc/varsyntax_calc1.tab.c, test/yacc/code_error.code.c, test/yacc/empty.tab.c, test/yacc/err_syntax10.tab.c, test/yacc/err_syntax11.tab.c, test/yacc/err_syntax12.tab.c, test/yacc/err_syntax18.tab.c, test/yacc/err_syntax20.tab.c, test/yacc/error.tab.c, test/yacc/grammar.tab.c, test/yacc/ok_syntax1.tab.c, test/yacc/pure_calc.tab.c, test/yacc/pure_error.tab.c, test/yacc/quote_calc-s.tab.c, test/yacc/quote_calc.tab.c, test/yacc/quote_calc2-s.tab.c, test/yacc/quote_calc2.tab.c, test/yacc/quote_calc3-s.tab.c, test/yacc/quote_calc3.tab.c, test/yacc/quote_calc4.tab.c, test/yacc/calc.tab.c, test/yacc/calc1.tab.c, test/yacc/calc2.tab.c, test/yacc/calc3.tab.c, test/yacc/code_calc.code.c, yaccpar.c:
+       regen
+
+       * yacc.1:
+       clarify relationship of btyacc features to default configuration.
+
+2014-04-08  Thomas E. Dickey  <tom@invisible-island.net>
+
+       * test/yacc/ok_syntax1.output, test/yacc/ok_syntax1.tab.c, test/yacc/ok_syntax1.tab.h, test/btyacc/ok_syntax1.output, test/btyacc/ok_syntax1.tab.c, test/btyacc/ok_syntax1.tab.h:
+       reference output for testing
+
+       * test/ok_syntax1.y: RCS_BASE
+
+       * test/yacc/ok_syntax1.error: reference output for testing
+
+       * test/yacc/big_b.error, test/yacc/big_b.output, test/yacc/big_l.error, test/yacc/big_l.output, test/btyacc/big_b.error, test/btyacc/big_b.output, test/btyacc/big_l.error, test/btyacc/big_l.output, test/run_test.sh:
+       exercise -L/-B options
+
+       * test/yacc/code_debug.c, test/btyacc/code_debug.c, test/yacc/err_syntax15.tab.c, test/yacc/err_syntax16.tab.c, test/yacc/err_syntax17.tab.c, test/yacc/err_syntax18.tab.c, test/yacc/err_syntax19.tab.c, test/yacc/err_syntax2.tab.c, test/yacc/err_syntax20.tab.c, test/yacc/err_syntax21.tab.c, test/yacc/err_syntax22.tab.c, test/yacc/err_syntax23.tab.c, test/yacc/err_syntax24.tab.c, test/yacc/err_syntax25.tab.c, test/yacc/err_syntax26.tab.c, test/yacc/err_syntax27.tab.c, test/yacc/err_syntax3.tab.c, test/yacc/err_syntax4.tab.c, test/yacc/err_syntax5.tab.c, test/yacc/err_syntax6.tab.c, test/yacc/err_syntax7.tab.c, test/yacc/err_syntax7a.tab.c, test/yacc/err_syntax7b.tab.c, test/yacc/err_syntax8.tab.c, test/yacc/err_syntax8a.tab.c, test/yacc/err_syntax9.tab.c, test/yacc/error.tab.c, test/yacc/grammar.tab.c, test/yacc/pure_calc.tab.c, test/yacc/pure_error.tab.c, test/yacc/quote_calc-s.tab.c, test/yacc/quote_calc.tab.c, test/yacc/quote_calc2-s.tab.c, test/yacc/quote_calc2.tab.c, test/yacc/quote_calc3-s.tab.c, test/yacc/quote_calc3.tab.c, test/yacc/quote_calc4-s.tab.c, test/yacc/quote_calc4.tab.c, test/yacc/varsyntax_calc1.tab.c, test/yacc/calc.tab.c, test/yacc/calc1.tab.c, test/yacc/calc2.tab.c, test/yacc/calc3.tab.c, test/yacc/code_calc.code.c, test/yacc/code_error.code.c, test/yacc/empty.tab.c, test/yacc/err_syntax1.tab.c, test/yacc/err_syntax10.tab.c, test/yacc/err_syntax11.tab.c, test/yacc/err_syntax12.tab.c, test/yacc/err_syntax13.tab.c, test/yacc/err_syntax14.tab.c, test/btyacc/err_syntax13.tab.c, test/btyacc/err_syntax14.tab.c, test/btyacc/err_syntax15.tab.c, test/btyacc/err_syntax16.tab.c, test/btyacc/err_syntax17.tab.c, test/btyacc/err_syntax18.tab.c, test/btyacc/err_syntax19.tab.c, test/btyacc/err_syntax2.tab.c, test/btyacc/err_syntax20.tab.c, test/btyacc/err_syntax21.tab.c, test/btyacc/err_syntax22.tab.c, test/btyacc/err_syntax23.tab.c, test/btyacc/err_syntax24.tab.c, test/btyacc/err_syntax25.tab.c, test/btyacc/err_syntax26.tab.c, test/btyacc/err_syntax27.tab.c, test/btyacc/err_syntax3.tab.c, test/btyacc/err_syntax4.tab.c, test/btyacc/err_syntax5.tab.c, test/btyacc/err_syntax6.tab.c, test/btyacc/err_syntax7.tab.c, test/btyacc/err_syntax7a.tab.c, test/btyacc/err_syntax7b.tab.c, test/btyacc/err_syntax8.tab.c, test/btyacc/err_syntax8a.tab.c, test/btyacc/err_syntax9.tab.c, test/btyacc/error.tab.c, test/btyacc/grammar.tab.c, test/btyacc/inherit0.tab.c, test/btyacc/inherit1.tab.c, test/btyacc/inherit2.tab.c, test/btyacc/pure_error.tab.c, test/btyacc/btyacc_demo.tab.c, test/btyacc/code_error.code.c, test/btyacc/empty.tab.c, test/btyacc/err_inherit1.tab.c, test/btyacc/err_inherit2.tab.c, test/btyacc/err_inherit3.tab.c, test/btyacc/err_inherit4.tab.c, test/btyacc/err_inherit5.tab.c, test/btyacc/err_syntax1.tab.c, test/btyacc/err_syntax10.tab.c, test/btyacc/err_syntax11.tab.c, test/btyacc/err_syntax12.tab.c, test/btyacc/pure_calc.tab.c, test/btyacc/quote_calc-s.tab.c, test/btyacc/quote_calc.tab.c, test/btyacc/quote_calc2-s.tab.c, test/btyacc/quote_calc2.tab.c, test/btyacc/quote_calc3-s.tab.c, test/btyacc/quote_calc3.tab.c, test/btyacc/quote_calc4-s.tab.c, test/btyacc/quote_calc4.tab.c, test/btyacc/varsyntax_calc1.tab.c, test/btyacc/btyacc_calc1.tab.c, test/btyacc/calc.tab.c, test/btyacc/calc1.tab.c, test/btyacc/calc2.tab.c, test/btyacc/calc3.tab.c, test/btyacc/code_calc.code.c, test/run_test.sh, test/yacc/no_b_opt1.output:
+       use a better renaming of the YYPATCH definition (none of the test-cases rely
+       upon it, but redefinition in the "make check_make" rule is a problem).
+
+       * test/btyacc/err_syntax1.tab.c, test/btyacc/err_syntax13.tab.c, test/btyacc/err_syntax2.tab.c, test/btyacc/err_syntax25.tab.c, test/btyacc/err_syntax26.tab.c, test/btyacc/err_syntax27.tab.c, test/btyacc/err_syntax3.tab.c, test/btyacc/err_syntax4.tab.c, test/btyacc/err_syntax5.tab.c, test/btyacc/err_syntax6.tab.c, test/btyacc/err_syntax7.tab.c, test/btyacc/err_syntax7a.tab.c, test/btyacc/err_syntax7b.tab.c, test/btyacc/err_syntax8.tab.c, test/btyacc/err_syntax8a.tab.c, test/btyacc/err_syntax9.tab.c, test/btyacc/varsyntax_calc1.tab.c:
+       undid temporary reordering in reader() by Tom Shields to align with byacc outputs
+
+       * test/run_test.sh: remove a repeated test-case
+
+       * mstring.c: minor reformatting to make coverage analysis simpler
+
+2014-04-07  Thomas E. Dickey  <tom@invisible-island.net>
+
+       * test/run_test.sh: tidy
+
+       * test/yacc/help.error, test/yacc/help.output, test/yacc/no_b_opt.error, test/yacc/no_b_opt.output, test/yacc/no_b_opt1.error, test/yacc/no_b_opt1.output, test/yacc/no_code_c.error, test/yacc/no_code_c.output, test/yacc/no_defines.error, test/yacc/no_defines.output, test/yacc/no_graph.error, test/yacc/no_graph.output, test/yacc/no_include.error, test/yacc/no_include.output, test/yacc/no_opts.error, test/yacc/no_opts.output, test/yacc/no_output.error, test/yacc/no_output.output, test/yacc/no_output1.error, test/yacc/no_output1.output, test/yacc/no_output2.error, test/yacc/no_output2.output, test/yacc/no_p_opt.error, test/yacc/no_p_opt.output, test/yacc/no_p_opt1.error, test/yacc/no_p_opt1.output, test/yacc/no_verbose.error, test/yacc/no_verbose.output, test/yacc/nostdin.error, test/yacc/nostdin.output, test/yacc/test-no_b_opt1.output:
+       reference output for testing
+
+       * test/run_test.sh:
+       add special checks for flags which depend on writable/existing files
+
+       * test/btyacc/no_b_opt1.output, test/btyacc/no_p_opt1.output, test/btyacc/no_b_opt.error, test/btyacc/no_b_opt.output, test/btyacc/no_b_opt1.error, test/btyacc/no_code_c.output, test/btyacc/no_p_opt.error, test/btyacc/no_p_opt.output, test/btyacc/no_p_opt1.error, test/btyacc/no_output2.output, test/btyacc/no_code_c.error, test/btyacc/no_output2.error, test/btyacc/no_include.error, test/btyacc/no_include.output, test/btyacc/no_defines.output, test/btyacc/no_defines.error, test/btyacc/no_verbose.output, test/btyacc/no_graph.output, test/btyacc/no_graph.error, test/btyacc/no_opts.error, test/btyacc/no_opts.output, test/btyacc/no_verbose.error, test/btyacc/nostdin.error, test/btyacc/nostdin.output, test/btyacc/no_output.error, test/btyacc/no_output.output, test/btyacc/no_output1.error, test/btyacc/no_output1.output:
+       reference output for testing
+
+       * main.c:
+       change CREATE_FILE_NAMES() to use local function rather than inline code,
+       to simplify coverage analysis.
+
+       * test/btyacc/err_syntax27.error, test/btyacc/err_syntax27.output, test/btyacc/err_syntax27.tab.c, test/btyacc/err_syntax27.tab.h, test/btyacc/help.error, test/btyacc/help.output, test/yacc/err_syntax27.error, test/yacc/err_syntax27.output, test/yacc/err_syntax27.tab.c, test/yacc/err_syntax27.tab.h:
+       reference output for testing
+
+       * test/err_syntax27.y: testcase for missing_brace()
+
+       * error.c: ifdef'd non-btyacc function
+
+       * lr0.c: ifdef'd debug-code
+
+       * yaccpar.skel: use YYINT's to replace short's as in btyaccpar.skel
+
+       * test/btyacc/code_debug.c, test/btyacc/err_syntax12.tab.c, test/btyacc/err_syntax14.tab.c, test/btyacc/err_syntax15.tab.c, test/btyacc/err_syntax16.tab.c, test/btyacc/err_syntax17.tab.c, test/btyacc/err_syntax18.tab.c, test/btyacc/err_syntax19.tab.c, test/btyacc/err_syntax20.tab.c, test/btyacc/err_syntax21.tab.c, test/btyacc/err_syntax22.tab.c, test/btyacc/err_syntax23.tab.c, test/btyacc/err_syntax24.tab.c, test/btyacc/error.tab.c, test/btyacc/grammar.tab.c, test/btyacc/inherit0.tab.c, test/btyacc/inherit1.tab.c, test/btyacc/inherit2.tab.c, test/btyacc/pure_calc.tab.c, test/btyacc/pure_error.tab.c, test/btyacc/quote_calc-s.tab.c, test/btyacc/quote_calc.tab.c, test/btyacc/quote_calc2-s.tab.c, test/btyacc/quote_calc2.tab.c, test/btyacc/quote_calc3-s.tab.c, test/btyacc/quote_calc3.tab.c, test/btyacc/quote_calc4-s.tab.c, test/btyacc/quote_calc4.tab.c, test/btyacc/varsyntax_calc1.tab.c, test/btyacc/btyacc_calc1.tab.c, test/btyacc/btyacc_demo.tab.c, test/btyacc/calc.tab.c, test/btyacc/calc1.tab.c, test/btyacc/calc2.tab.c, test/btyacc/calc3.tab.c, test/btyacc/code_calc.code.c, test/btyacc/code_error.code.c, test/btyacc/empty.tab.c, test/btyacc/err_inherit1.tab.c, test/btyacc/err_inherit2.tab.c, test/btyacc/err_inherit3.tab.c, test/btyacc/err_inherit4.tab.c, test/btyacc/err_inherit5.tab.c, test/btyacc/err_syntax10.tab.c, test/btyacc/err_syntax11.tab.c, test/yacc/err_syntax11.tab.c, test/yacc/err_syntax12.tab.c, test/yacc/err_syntax18.tab.c, test/yacc/err_syntax20.tab.c, test/yacc/error.tab.c, test/yacc/grammar.tab.c, test/yacc/pure_calc.tab.c, test/yacc/pure_error.tab.c, test/yacc/quote_calc-s.tab.c, test/yacc/quote_calc.tab.c, test/yacc/quote_calc2-s.tab.c, test/yacc/quote_calc2.tab.c, test/yacc/quote_calc3-s.tab.c, test/yacc/quote_calc3.tab.c, test/yacc/quote_calc4-s.tab.c, test/yacc/quote_calc4.tab.c, test/yacc/varsyntax_calc1.tab.c, test/yacc/calc.tab.c, test/yacc/calc1.tab.c, test/yacc/calc2.tab.c, test/yacc/calc3.tab.c, test/yacc/code_calc.code.c, test/yacc/code_debug.c, test/yacc/code_error.code.c, test/yacc/empty.tab.c, test/yacc/err_syntax10.tab.c, output.c, test/yacc/err_syntax1.tab.c, test/yacc/err_syntax13.tab.c, test/yacc/err_syntax14.tab.c, test/yacc/err_syntax15.tab.c, test/yacc/err_syntax16.tab.c, test/yacc/err_syntax17.tab.c, test/yacc/err_syntax19.tab.c, test/yacc/err_syntax2.tab.c, test/yacc/err_syntax21.tab.c, test/yacc/err_syntax22.tab.c, test/yacc/err_syntax23.tab.c, test/yacc/err_syntax24.tab.c, test/yacc/err_syntax25.tab.c, test/yacc/err_syntax26.tab.c, test/yacc/err_syntax3.tab.c, test/yacc/err_syntax4.tab.c, test/yacc/err_syntax5.tab.c, test/yacc/err_syntax6.tab.c, test/yacc/err_syntax7.tab.c, test/yacc/err_syntax7a.tab.c, test/yacc/err_syntax7b.tab.c, test/yacc/err_syntax8.tab.c, test/yacc/err_syntax8a.tab.c, test/yacc/err_syntax9.tab.c, test/run_test.sh:
+       2010/11/26 simplification of output.c using putc_code() and putl_code()
+       omitted an adjustment of the #line value used for code-file.  Fix that.
+       Also, amend 2005/05/04 change to run_test.sh to retain a dummy line for
+       YYPATCH #define's to make test-outputs easier to compare #line's (report
+       by Tom Shields)
+
+2014-04-06  Thomas E. Dickey  <tom@invisible-island.net>
+
+       * reader.c: fix for valgrind
+       (the calloc's are intentional - valgrind reported use of uninitialized memory)
+
+       * lr0.c, output.c: fix for valgrind
+
+       * test/btyacc/code_debug.c, test/btyacc/code_debug.error, test/btyacc/code_debug.h, test/btyacc/code_debug.i, test/btyacc/code_debug.output:
+       RCS_BASE
+
+       * test/yacc/code_debug.c, test/yacc/code_debug.h:
+       exercise the -i option
+
+       * test/yacc/code_debug.i: reference output for testing
+
+       * test/run_test.sh: exercise the -i option
+
+       * test/yacc/code_debug.c: reference output for testing
+
+       * test/run_test.sh: exercise the "-o" option
+
+       * test/yacc/code_debug.error, test/yacc/code_debug.h, test/yacc/code_debug.output:
+       reference output for testing
+
+       * output.c: don't call exit() without giving a chance to cleanup.
+
+       * mstring.c: ifdef'd functions not used in byacc
+
+       * btyaccpar.c: generated from btyaccpar.skel
+
+       * yaccpar.c: generated from yaccpar.skel
+
+       * skel2c:
+       change the generated-by comment to show which version of this script (and
+       which version of the given skeleton file) were used to produce the C-file.
+
+       * configure: regen
+
+       * makefile.in:
+       add rules to generate byacc and btyacc parser skeleton files independently
+
+       * aclocal.m4: CF_PROG_AWK - add to byacc's configure script
+       CF_INTEL_COMPILER
+               cleanup the -no-gcc option which was leftover from testing - prcs does
+               not build with this option.
+       CF_MAKE_DOCS
+               protect $2 from substitution, for luit's "$(manext)"
+       CF_XOPEN_SOURCE
+               for Solaris (tested with gcc/g++ 3.4.3 on Solaris 10 and gcc/g++ 4.5.2
+               on Solaris 11), suppress the followup check for defining _XOPEN_SOURCE
+               because it is not needed, as well as because g++ 4.7.3 (no package,
+               used in Sage for Solaris 10) has some unspecified header breakage which
+               is triggered by the duplicate definition.
+
+       * configure.in:
+       modify so skeleton-source is determined by configure options rather than by
+       having developer rename yaccpar.skel.old to yaccpar.skel
+
+       * descrip.mms: rename skeleton
+
+       * vmsbuild.com:
+       fwiw, renamed the skeleton for consistency with makefile
+
+       * skel2c, skeleton.c: resync skeleton and its generating files
+
+       * yaccpar.skel:
+       renamed yaccpar.skel.old to yaccpar.skel, to allow using makefile suffix rules
+
+       * yaccpar.skel.old: resync skeleton and its generating files
+
+       * test/run_make.sh: improve cleanup after error recovery
+
+       * test/yacc/calc.tab.c, test/yacc/calc1.tab.c, test/yacc/calc2.tab.c, test/yacc/calc3.tab.c, test/yacc/code_calc.code.c, test/yacc/code_error.code.c, test/yacc/empty.tab.c, test/yacc/err_syntax10.tab.c, test/yacc/err_syntax11.tab.c, test/yacc/err_syntax12.tab.c, test/yacc/err_syntax18.tab.c, test/yacc/err_syntax20.tab.c, test/yacc/error.tab.c, test/yacc/grammar.tab.c, test/yacc/pure_calc.tab.c, test/yacc/pure_error.tab.c, test/yacc/quote_calc-s.tab.c, test/yacc/quote_calc.tab.c, test/yacc/quote_calc2-s.tab.c, test/yacc/quote_calc2.tab.c, test/yacc/quote_calc3-s.tab.c, test/yacc/quote_calc3.tab.c, test/yacc/quote_calc4-s.tab.c, test/yacc/quote_calc4.tab.c, test/yacc/varsyntax_calc1.tab.c, output.c, skeleton.c, defs.h:
+       use improvement from Tom Shield's btyacc changes, getting rid of special cases for generating two yyerror calls in skeleton
+
+       * output.c: simplify output_yyerror_decl()
+
+       * test/yacc/pure_error.tab.c, test/yacc/quote_calc-s.tab.c, test/yacc/quote_calc.tab.c, test/yacc/quote_calc2-s.tab.c, test/yacc/quote_calc2.tab.c, test/yacc/quote_calc3-s.tab.c, test/yacc/quote_calc3.tab.c, test/yacc/quote_calc4-s.tab.c, test/yacc/quote_calc4.tab.c, test/yacc/varsyntax_calc1.tab.c, test/yacc/calc.tab.c, test/yacc/calc1.tab.c, test/yacc/calc2.tab.c, test/yacc/calc3.tab.c, test/yacc/code_calc.tab.c, test/yacc/code_error.tab.c, test/yacc/empty.tab.c, test/yacc/err_syntax10.tab.c, test/yacc/err_syntax11.tab.c, test/yacc/err_syntax12.tab.c, test/yacc/err_syntax18.tab.c, test/yacc/err_syntax20.tab.c, test/yacc/error.tab.c, test/yacc/grammar.tab.c, test/yacc/pure_calc.tab.c, output.c:
+       add second "const" to string-table declarations, from Tom Shield's btyacc changes
+
+       * test/btyacc/err_syntax20.tab.c, test/btyacc/error.tab.c, test/btyacc/grammar.tab.c, test/btyacc/inherit0.tab.c, test/btyacc/inherit1.tab.c, test/btyacc/inherit2.tab.c, test/btyacc/pure_calc.tab.c, test/btyacc/pure_error.tab.c, test/btyacc/quote_calc-s.tab.c, test/btyacc/quote_calc.tab.c, test/btyacc/quote_calc2-s.tab.c, test/btyacc/quote_calc2.tab.c, test/btyacc/quote_calc3-s.tab.c, test/btyacc/quote_calc3.tab.c, test/btyacc/quote_calc4-s.tab.c, test/btyacc/quote_calc4.tab.c, test/btyacc/varsyntax_calc1.tab.c, test/btyacc/btyacc_calc1.tab.c, test/btyacc/btyacc_demo.tab.c, test/btyacc/calc.tab.c, test/btyacc/calc1.tab.c, test/btyacc/calc2.tab.c, test/btyacc/calc3.tab.c, test/btyacc/empty.tab.c, test/btyacc/err_inherit3.tab.c, test/btyacc/err_inherit4.tab.c, test/btyacc/err_syntax10.tab.c, test/btyacc/err_syntax11.tab.c, test/btyacc/err_syntax12.tab.c, test/btyacc/err_syntax18.tab.c:
+       discard unnecessary call on write_code_lineno() from Tom Shield's changes
+
+       * test/yacc/error.tab.c, test/yacc/grammar.tab.c, test/yacc/pure_calc.tab.c, test/yacc/pure_error.tab.c, test/yacc/quote_calc-s.tab.c, test/yacc/quote_calc.tab.c, test/yacc/quote_calc2-s.tab.c, test/yacc/quote_calc2.tab.c, test/yacc/quote_calc3-s.tab.c, test/yacc/quote_calc3.tab.c, test/yacc/quote_calc4-s.tab.c, test/yacc/quote_calc4.tab.c, test/yacc/varsyntax_calc1.tab.c, test/yacc/calc.tab.c, test/yacc/calc1.tab.c, test/yacc/calc2.tab.c, test/yacc/calc3.tab.c, test/yacc/code_calc.code.c, test/yacc/code_calc.tab.c, test/yacc/code_error.code.c, test/yacc/code_error.tab.c, test/yacc/empty.tab.c, test/yacc/err_syntax10.tab.c, test/yacc/err_syntax11.tab.c, test/yacc/err_syntax12.tab.c, test/yacc/err_syntax18.tab.c, test/yacc/err_syntax20.tab.c, output.c:
+       use YYINT typedef from Tom Shield's btyacc changes to replace explicit "short"
+
+       * test/yacc/code_calc.code.c, test/yacc/code_error.code.c, output.c:
+       use fix from Tom Shield's btyacc changes: remove redundant extern-declaration for YYPARSE_DECL()
+
+       * test/btyacc/err_syntax18.tab.c, test/btyacc/err_syntax20.tab.c, test/btyacc/error.tab.c, test/btyacc/grammar.tab.c, test/btyacc/inherit0.tab.c, test/btyacc/inherit1.tab.c, test/btyacc/inherit2.tab.c, test/btyacc/pure_calc.tab.c, test/btyacc/pure_error.tab.c, test/btyacc/quote_calc-s.tab.c, test/btyacc/quote_calc.tab.c, test/btyacc/quote_calc2-s.tab.c, test/btyacc/quote_calc2.tab.c, test/btyacc/quote_calc3-s.tab.c, test/btyacc/quote_calc3.tab.c, test/btyacc/quote_calc4-s.tab.c, test/btyacc/quote_calc4.tab.c, test/btyacc/varsyntax_calc1.tab.c, test/btyacc/btyacc_calc1.tab.c, test/btyacc/btyacc_demo.tab.c, test/btyacc/calc.tab.c, test/btyacc/calc1.tab.c, test/btyacc/calc2.tab.c, test/btyacc/calc3.tab.c, test/btyacc/code_calc.code.c, test/btyacc/code_error.code.c, test/btyacc/empty.tab.c, test/btyacc/err_inherit3.tab.c, test/btyacc/err_inherit4.tab.c, test/btyacc/err_syntax10.tab.c, test/btyacc/err_syntax11.tab.c, test/btyacc/err_syntax12.tab.c:
+       discard unnecessary call on write_code_lineno() from Tom Shield's changes
+
+       * output.c, test/yacc/code_calc.code.c, test/yacc/code_error.code.c, test/yacc/code_calc.tab.c, test/yacc/code_error.tab.c:
+       use fix from Tom Shield's btyacc changes: prefix-definitions went to the
+       output (.tab.c) file in a case where they should have gone to the code
+       (.code.c) file.  Remove now-redundant call to output_prefix().
+
+       * main.c: do the same for help-message
+
+       * main.c: use OUTPUT_SUFFIX symbol in an overlooked case
+
+       * test/run_make.sh:
+       modify to avoid use of VPATH, which has no standard implementation
+
+2014-04-05  Thomas E. Dickey  <tom@invisible-island.net>
+
+       * test/btyacc/grammar.tab.c, test/btyacc/inherit0.tab.c, test/btyacc/inherit1.tab.c, test/btyacc/inherit2.tab.c, test/btyacc/pure_calc.tab.c, test/btyacc/pure_error.tab.c, test/btyacc/quote_calc-s.tab.c, test/btyacc/quote_calc.tab.c, test/btyacc/quote_calc2-s.tab.c, test/btyacc/quote_calc2.tab.c, test/btyacc/quote_calc3-s.tab.c, test/btyacc/quote_calc3.tab.c, test/btyacc/quote_calc4-s.tab.c, test/btyacc/quote_calc4.tab.c, test/btyacc/varsyntax_calc1.tab.c, test/btyacc/btyacc_calc1.tab.c, test/btyacc/btyacc_demo.tab.c, test/btyacc/calc.tab.c, test/btyacc/calc1.tab.c, test/btyacc/calc2.tab.c, test/btyacc/calc3.tab.c, test/btyacc/code_calc.code.c, test/btyacc/code_error.code.c, test/btyacc/empty.tab.c, test/btyacc/err_inherit3.tab.c, test/btyacc/err_inherit4.tab.c, test/btyacc/err_syntax10.tab.c, test/btyacc/err_syntax11.tab.c, test/btyacc/err_syntax12.tab.c, test/btyacc/err_syntax18.tab.c, test/btyacc/err_syntax20.tab.c, test/btyacc/error.tab.c:
+       discard a change which merged CountLines() with explicit comparisons against
+       code_file because that adds extra to the #line values
+
+       * test/yacc/pure_calc.tab.c, test/yacc/pure_error.tab.c, test/yacc/quote_calc-s.tab.c, test/yacc/quote_calc.tab.c, test/yacc/quote_calc2-s.tab.c, test/yacc/quote_calc2.tab.c, test/yacc/quote_calc3-s.tab.c, test/yacc/quote_calc3.tab.c, test/yacc/quote_calc4-s.tab.c, test/yacc/quote_calc4.tab.c, test/yacc/calc.tab.c, test/yacc/calc2.tab.c, test/yacc/calc3.tab.c, test/yacc/code_calc.code.c, test/yacc/code_error.code.c, test/yacc/empty.tab.c, test/yacc/err_syntax11.tab.c, test/yacc/err_syntax12.tab.c, test/yacc/err_syntax18.tab.c, test/yacc/error.tab.c, output.c:
+       add Tom Shield's change to allow definition of YYSTYPE_IS_DECLARED symbol to
+       override fallback typedef for YYSTYPE when that symbol is undefined
+
+       * test/btyacc/error.tab.c, test/btyacc/inherit0.tab.c, test/btyacc/pure_calc.tab.c, test/btyacc/pure_error.tab.c, test/btyacc/quote_calc-s.tab.c, test/btyacc/quote_calc.tab.c, test/btyacc/quote_calc2-s.tab.c, test/btyacc/quote_calc2.tab.c, test/btyacc/quote_calc3-s.tab.c, test/btyacc/quote_calc3.tab.c, test/btyacc/quote_calc4-s.tab.c, test/btyacc/quote_calc4.tab.c, test/btyacc/calc.tab.c, test/btyacc/calc2.tab.c, test/btyacc/calc3.tab.c, test/btyacc/code_calc.code.c, test/btyacc/code_error.code.c, test/btyacc/empty.tab.c, test/btyacc/err_syntax11.tab.c, test/btyacc/err_syntax12.tab.c, test/btyacc/err_syntax18.tab.c:
+       minor tweak to coding style - use parenthesis for "defined" operator's parameter
+
+       * test/btyacc/err_syntax11.tab.c, test/btyacc/err_syntax12.tab.c, test/btyacc/err_syntax18.tab.c, test/btyacc/err_syntax20.tab.c, test/btyacc/error.tab.c, test/btyacc/grammar.tab.c, test/btyacc/inherit0.tab.c, test/btyacc/inherit1.tab.c, test/btyacc/inherit2.tab.c, test/btyacc/pure_calc.tab.c, test/btyacc/pure_error.tab.c, test/btyacc/quote_calc-s.tab.c, test/btyacc/quote_calc.tab.c, test/btyacc/quote_calc2-s.tab.c, test/btyacc/quote_calc2.tab.c, test/btyacc/quote_calc3-s.tab.c, test/btyacc/quote_calc3.tab.c, test/btyacc/quote_calc4-s.tab.c, test/btyacc/quote_calc4.tab.c, test/btyacc/varsyntax_calc1.tab.c, test/btyacc/btyacc_calc1.tab.c, test/btyacc/btyacc_demo.tab.c, test/btyacc/calc.tab.c, test/btyacc/calc1.tab.c, test/btyacc/calc2.tab.c, test/btyacc/calc3.tab.c, test/btyacc/code_calc.code.c, test/btyacc/code_error.code.c, test/btyacc/empty.tab.c, test/btyacc/err_inherit3.tab.c, test/btyacc/err_inherit4.tab.c, test/btyacc/err_syntax10.tab.c:
+       regen to make YYMAXTOKEN and YYUNDFTOKEN adjacent
+
+       * test/yacc/err_syntax20.tab.c, test/yacc/grammar.tab.c, test/yacc/quote_calc2-s.tab.c, test/yacc/quote_calc2.tab.c, test/yacc/quote_calc3-s.tab.c, test/yacc/quote_calc3.tab.c, test/yacc/quote_calc4-s.tab.c, test/yacc/quote_calc4.tab.c, test/yacc/varsyntax_calc1.tab.c, test/yacc/calc.tab.c, test/yacc/calc1.tab.c, test/yacc/calc2.tab.c, test/yacc/calc3.tab.c, test/yacc/code_calc.code.c, test/yacc/code_calc.tab.c, test/yacc/code_error.code.c, test/yacc/code_error.tab.c, test/yacc/empty.tab.c, test/yacc/err_syntax10.tab.c, test/yacc/err_syntax11.tab.c, test/yacc/err_syntax12.tab.c:
+       regen after adding the YYUNDFTOKEN symbol
+
+       * output.c:
+       integrate Tom Shield's btyacc changes which introduce the YYUNDFTOKEN symbol
+       (I changed order of output to keep this adjacent to YYMAXTOKEN)
+
+       * reader.c:
+       merge all but one small change from Tom Shield's btyacc changes - that
+       changes the order of code-file in the tests.
+
+       * test/btyacc/btyacc_demo.tab.c: regen
+
+       * test/btyacc_demo.y: fix prototypes
+
+2014-04-04  Thomas E. Dickey  <tom@invisible-island.net>
+
+       * reader.c, defs.h, main.c:
+       more merging of Tom Shield's btyacc changes.  In the merge, I moved the
+       symbol_pval inside the btyacc ifdef's and added some more btyacc ifdefs
+
+2014-04-03  Thomas E. Dickey  <tom@invisible-island.net>
+
+       * reader.c:
+       merge-in 3/4 of btyacc's changes, deferring those which change test-outputs.
+       Tom Shield's changes split-out copy_string() and copy_comment() functions
+       to simplify some logic, as well as adding btyacc-only chunks
+
+       * makefile.in: build mstring.o, needed for changes in reader.c
+
+       * output.c:
+       merge-in all of btyacc's changes which do not change byacc's test-output.
+       Some of the merge uses ifdef-changes which I applied to ongoing resync,
+       e.g., the introduction of PER_STATE.
+
+2014-04-02  Thomas E. Dickey  <tom@invisible-island.net>
+
+       * test/btyacc/pure_calc.tab.c, test/btyacc/pure_error.tab.c: regen
+
+       * output.c: fix typo
+
+       * output.c, reader.c:
+       merge in some chunks of reader and output files which do not affect byacc tests
+
+       * test/yacc/calc2.tab.c, test/yacc/calc3.tab.c: regen
+
+       * test/yacc/err_syntax6.tab.c, test/yacc/err_syntax7.tab.c, test/yacc/err_syntax7a.tab.c, test/yacc/err_syntax7b.tab.c, test/yacc/err_syntax8.tab.c, test/yacc/err_syntax8a.tab.c, test/yacc/err_syntax9.tab.c, test/yacc/error.tab.c, test/yacc/grammar.tab.c, test/yacc/pure_calc.tab.c, test/yacc/pure_error.tab.c, test/yacc/quote_calc-s.tab.c, test/yacc/quote_calc.tab.c, test/yacc/quote_calc2-s.tab.c, test/yacc/quote_calc2.tab.c, test/yacc/quote_calc3-s.tab.c, test/yacc/quote_calc3.tab.c, test/yacc/quote_calc4-s.tab.c, test/yacc/quote_calc4.tab.c, test/yacc/varsyntax_calc1.tab.c, test/yacc/calc.tab.c, test/yacc/calc1.tab.c, test/yacc/calc2.tab.c, test/yacc/calc3.tab.c, test/yacc/code_calc.code.c, test/yacc/code_error.code.c, test/yacc/empty.tab.c, test/yacc/err_syntax1.tab.c, test/yacc/err_syntax10.tab.c, test/yacc/err_syntax11.tab.c, test/yacc/err_syntax12.tab.c, test/yacc/err_syntax13.tab.c, test/yacc/err_syntax14.tab.c, test/yacc/err_syntax15.tab.c, test/yacc/err_syntax16.tab.c, test/yacc/err_syntax17.tab.c, test/yacc/err_syntax18.tab.c, test/yacc/err_syntax19.tab.c, test/yacc/err_syntax2.tab.c, test/yacc/err_syntax20.tab.c, test/yacc/err_syntax21.tab.c, test/yacc/err_syntax22.tab.c, test/yacc/err_syntax23.tab.c, test/yacc/err_syntax24.tab.c, test/yacc/err_syntax25.tab.c, test/yacc/err_syntax26.tab.c, test/yacc/err_syntax3.tab.c, test/yacc/err_syntax4.tab.c, test/yacc/err_syntax5.tab.c, skeleton.c:
+       incorporate YYENOMEM and YYEOF symbols from btyacc
+
+       * output.c: merge chunk from btyacc changes for header-guards
+
+       * btyaccpar.skel: RCS_BASE
+
+       * yaccpar.skel: comment-out yysccsid[], for FreeBSD build-issues
+       remove GCC_UNUSED to reduce name-pollution as well as being simpler
+
+       * main.c:
+       move a btyacc symbol outside ifdef to work around current state of merge
+
+       * defs.h:
+       add USE_HEADER_GUARDS to defer whether to modify byacc's header-output
+
+       * test/run_make.sh:
+       do not try to compile files used for testing syntax-errors, since they are
+       likely to be incomplete
+
+2014-04-02  Tom.Shields
+
+       * main.c: changes for btyacc
+
+2014-04-01  Thomas E. Dickey  <tom@invisible-island.net>
+
+       * reader.c:
+       integrate change by Tom Shields to use bsearch rather than successive
+       calls to matchec()
+
+       * defs.h: typedef __compar_fn_t is unnecessary
+
+       * test/btyacc/err_syntax20.tab.c, test/btyacc/error.tab.c, test/btyacc/grammar.tab.c, test/btyacc/inherit0.tab.c, test/btyacc/inherit1.tab.c, test/btyacc/inherit2.tab.c, test/btyacc/pure_calc.tab.c, test/btyacc/pure_error.tab.c, test/btyacc/quote_calc-s.tab.c, test/btyacc/quote_calc.tab.c, test/btyacc/quote_calc2-s.tab.c, test/btyacc/quote_calc2.tab.c, test/btyacc/quote_calc3-s.tab.c, test/btyacc/quote_calc3.tab.c, test/btyacc/quote_calc4-s.tab.c, test/btyacc/quote_calc4.tab.c, test/btyacc/varsyntax_calc1.tab.c, test/btyacc/btyacc_calc1.tab.c, test/btyacc/btyacc_demo.tab.c, test/btyacc/calc.tab.c, test/btyacc/calc1.tab.c, test/btyacc/calc2.tab.c, test/btyacc/calc3.tab.c, test/btyacc/code_calc.code.c, test/btyacc/code_error.code.c, test/btyacc/empty.tab.c, test/btyacc/err_inherit3.tab.c, test/btyacc/err_inherit4.tab.c, test/btyacc/err_syntax10.tab.c, test/btyacc/err_syntax11.tab.c, test/btyacc/err_syntax12.tab.c, test/btyacc/err_syntax18.tab.c:
+       omit the GCC_UNUSED, as noted by Tom Shields not really essential
+
+2014-04-01  Tom.Shields
+
+       * verbose.c: changes for btyacc, ifdef'd
+
+2014-04-01  Thomas E. Dickey  <tom@invisible-island.net>
+
+       * mkpar.c: eliminate most of the ifdef's using macros
+
+2014-04-01  Tom.Shields
+
+       * mkpar.c: merge btyacc changes (ifdef'd - no change to byacc)
+
+       * error.c:
+       new functions used for reporting errors from the btyacc configuration
+       (I reordered some, and ifdef'd the new ones -TD)
+
+2014-03-31  Thomas E. Dickey  <tom@invisible-island.net>
+
+       * test/btyacc/code_calc.code.c, test/btyacc/code_error.code.c:
+       omit the GCC_UNUSED, as noted by Tom Shields not really essential
+
+       * test/btyacc/empty.tab.c, test/btyacc/err_inherit1.tab.c, test/btyacc/err_inherit2.tab.c, test/btyacc/err_inherit3.tab.c, test/btyacc/err_inherit4.tab.c, test/btyacc/err_inherit5.tab.c, test/btyacc/err_syntax10.tab.c, test/btyacc/err_syntax11.tab.c, test/btyacc/err_syntax12.tab.c, test/btyacc/err_syntax14.tab.c, test/btyacc/err_syntax15.tab.c, test/btyacc/err_syntax16.tab.c, test/btyacc/err_syntax17.tab.c, test/btyacc/err_syntax18.tab.c, test/btyacc/err_syntax19.tab.c, test/btyacc/err_syntax20.tab.c, test/btyacc/err_syntax21.tab.c, test/btyacc/err_syntax22.tab.c, test/btyacc/err_syntax23.tab.c, test/btyacc/err_syntax24.tab.c:
+       regen
+
+2014-03-29  Thomas E. Dickey  <tom@invisible-island.net>
+
+       * test/yacc/err_syntax22.tab.c, test/yacc/err_syntax23.tab.c, test/yacc/err_syntax24.tab.c, test/yacc/err_syntax25.tab.c, test/yacc/err_syntax26.tab.c, test/yacc/err_syntax3.tab.c, test/yacc/err_syntax4.tab.c, test/yacc/err_syntax5.tab.c, test/yacc/err_syntax6.tab.c, test/yacc/err_syntax7.tab.c, test/yacc/err_syntax7a.tab.c, test/yacc/err_syntax7b.tab.c, test/yacc/err_syntax8.tab.c, test/yacc/err_syntax8a.tab.c, test/yacc/err_syntax9.tab.c, test/yacc/error.tab.c, test/yacc/grammar.tab.c, test/yacc/pure_calc.tab.c, test/yacc/pure_error.tab.c, test/yacc/quote_calc-s.tab.c, test/yacc/quote_calc.tab.c, test/yacc/quote_calc2-s.tab.c, test/yacc/quote_calc2.tab.c, test/yacc/quote_calc3-s.tab.c, test/yacc/quote_calc3.tab.c, test/yacc/quote_calc4-s.tab.c, test/yacc/quote_calc4.tab.c, test/yacc/varsyntax_calc1.tab.c, test/yacc/calc.tab.c, test/yacc/calc1.tab.c, test/yacc/calc2.tab.c, test/yacc/calc3.tab.c, test/yacc/code_calc.code.c, test/yacc/code_error.code.c, test/yacc/empty.tab.c, test/yacc/err_syntax1.tab.c, test/yacc/err_syntax10.tab.c, test/yacc/err_syntax11.tab.c, test/yacc/err_syntax12.tab.c, test/yacc/err_syntax13.tab.c, test/yacc/err_syntax14.tab.c, test/yacc/err_syntax15.tab.c, test/yacc/err_syntax16.tab.c, test/yacc/err_syntax17.tab.c, test/yacc/err_syntax18.tab.c, test/yacc/err_syntax19.tab.c, test/yacc/err_syntax2.tab.c, test/yacc/err_syntax20.tab.c, test/yacc/err_syntax21.tab.c, skeleton.c:
+       comment-out yysccsid in the banner because it produces unnecessary compiler
+       warnings.  The suggested alternative (using #pragma ident) in the preceding
+       comment is also obsolete; remove that comment (request by Gleb Smirnoff).
+
+       * test/run_test.sh:
+       for yacc, ignore the inherit testcases, since they are btyacc-specific
+
+2014-03-28  Thomas E. Dickey  <tom@invisible-island.net>
+
+       * test/yacc/varsyntax_calc1.error, test/yacc/varsyntax_calc1.output, test/yacc/varsyntax_calc1.tab.c, test/yacc/varsyntax_calc1.tab.h, test/yacc/err_inherit3.error, test/yacc/err_inherit3.output, test/yacc/err_inherit3.tab.c, test/yacc/err_inherit3.tab.h, test/yacc/err_inherit4.error, test/yacc/err_inherit4.output, test/yacc/err_inherit4.tab.c, test/yacc/err_inherit4.tab.h, test/yacc/err_inherit5.error, test/yacc/err_inherit5.output, test/yacc/err_inherit5.tab.c, test/yacc/err_inherit5.tab.h, test/yacc/inherit0.error, test/yacc/inherit0.output, test/yacc/inherit0.tab.c, test/yacc/inherit0.tab.h, test/yacc/inherit1.error, test/yacc/inherit1.output, test/yacc/inherit1.tab.c, test/yacc/inherit1.tab.h, test/yacc/inherit2.error, test/yacc/inherit2.output, test/yacc/inherit2.tab.c, test/yacc/inherit2.tab.h, test/yacc/empty.error, test/yacc/empty.output, test/yacc/empty.tab.c, test/yacc/empty.tab.h, test/yacc/err_inherit1.error, test/yacc/err_inherit1.output, test/yacc/err_inherit1.tab.c, test/yacc/err_inherit1.tab.h, test/yacc/err_inherit2.error, test/yacc/err_inherit2.output, test/yacc/err_inherit2.tab.c, test/yacc/err_inherit2.tab.h:
+       reference output for testing
+
+       * test/run_lint.sh, test/run_make.sh, test/run_test.sh:
+       moving #define's out of makefile broke check for yacc vs btyacc (fix)
+
+2014-03-28  Tom.Shields
+
+       * test/btyacc/btyacc_demo.tab.c, test/btyacc/err_inherit3.error, test/btyacc/err_inherit3.output, test/btyacc/err_inherit3.tab.c, test/btyacc/err_inherit3.tab.h, test/btyacc/err_inherit2.error, test/btyacc/err_inherit2.output, test/btyacc/err_inherit2.tab.c, test/btyacc/err_inherit2.tab.h, test/btyacc/err_inherit4.error, test/btyacc/err_inherit4.output, test/btyacc/err_inherit4.tab.c, test/btyacc/err_inherit4.tab.h, test/btyacc/err_inherit5.error, test/btyacc/err_inherit5.output, test/btyacc/err_inherit5.tab.c, test/btyacc/err_inherit5.tab.h, test/btyacc/inherit0.error, test/btyacc/inherit0.output, test/btyacc/inherit0.tab.c, test/btyacc/inherit0.tab.h, test/btyacc/inherit1.error, test/btyacc/inherit1.output, test/btyacc/inherit1.tab.c, test/btyacc/inherit1.tab.h, test/btyacc/inherit2.error, test/btyacc/inherit2.output, test/btyacc/inherit2.tab.c, test/btyacc/inherit2.tab.h, test/btyacc/calc.error, test/btyacc/err_inherit1.error, test/btyacc/err_inherit1.output, test/btyacc/err_inherit1.tab.c, test/btyacc/err_inherit1.tab.h:
+       reference output for testing
+
+       * defs.h: new functions/variables for btyacc
+       (I reordered and ifdef'd -TD)
+
+       * test/inherit0.y, test/inherit1.y: testcase for btyacc
+
+2014-03-27  Tom.Shields
+
+       * test/err_inherit5.y, test/err_inherit4.y, test/err_inherit3.y, test/err_inherit2.y, test/err_inherit1.y, test/inherit2.y:
+       testcase for btyacc
+
+2014-03-25  Tom.Shields
+
+       * symtab.c: extra initialization needed for btyacc
+       (I ifdef'd -TD)
+
+       * yacc.1: document -L/-B features from btyacc
+
+2014-03-25  Thomas E. Dickey  <tom@invisible-island.net>
+
+       * yacc.1: typo
+
+       * configure: regen
+
+       * configure.in:
+       modified new options to act like those in my other configure-scripts, e.g.,
+       showing what option is being tested, and the resulting value.  Put the
+       definitions in config.h rather than in the makefile.
+
+2014-03-25  Tom.Shields
+
+       * makefile.in: add/use LINTFLAGS variable
+       make all of the objects (not just skeleton) rebuild if makefile changes
+       modify check-rule to reflect updates to run_test.sh vs subdirectory
+
+       * mstring.c: byacc-btyacc-20140323
+
+2014-03-25  Thomas E. Dickey  <tom@invisible-island.net>
+
+       * test/btyacc/RCS, test/yacc/RCS: PERMIT FILE
+
+       * config_h.in: updated with autoheader-252
+
+2014-03-25  Tom.Shields
+
+       * README.BTYACC: byacc-btyacc-20140323
+
+2014-03-24  Tom.Shields
+
+       * test/btyacc/err_syntax1.output, test/btyacc/err_syntax1.tab.c, test/btyacc/err_syntax1.tab.h, test/btyacc/err_syntax10.error, test/btyacc/err_syntax10.output, test/btyacc/err_syntax10.tab.c, test/btyacc/err_syntax10.tab.h, test/btyacc/err_syntax11.error, test/btyacc/err_syntax11.output, test/btyacc/err_syntax11.tab.c, test/btyacc/err_syntax11.tab.h, test/btyacc/err_syntax12.error, test/btyacc/err_syntax12.output, test/btyacc/err_syntax12.tab.c, test/btyacc/err_syntax12.tab.h, test/btyacc/err_syntax13.error, test/btyacc/err_syntax13.output, test/btyacc/err_syntax13.tab.c, test/btyacc/err_syntax13.tab.h, test/btyacc/err_syntax14.error, test/btyacc/err_syntax14.output, test/btyacc/err_syntax14.tab.c, test/btyacc/err_syntax14.tab.h, test/btyacc/err_syntax15.error, test/btyacc/err_syntax15.output, test/btyacc/err_syntax15.tab.c, test/btyacc/err_syntax15.tab.h, test/btyacc/err_syntax16.error, test/btyacc/err_syntax16.output, test/btyacc/err_syntax16.tab.c, test/btyacc/err_syntax16.tab.h, test/btyacc/err_syntax17.error, test/btyacc/err_syntax17.output, test/btyacc/err_syntax17.tab.c, test/btyacc/err_syntax17.tab.h, test/btyacc/err_syntax18.error, test/btyacc/err_syntax18.output, test/btyacc/err_syntax18.tab.c, test/btyacc/err_syntax18.tab.h, test/btyacc/err_syntax19.error, test/btyacc/err_syntax19.output, test/btyacc/err_syntax19.tab.c, test/btyacc/err_syntax19.tab.h, test/btyacc/err_syntax2.output, test/btyacc/err_syntax2.tab.c, test/btyacc/err_syntax2.tab.h, test/btyacc/err_syntax20.error, test/btyacc/err_syntax20.output, test/btyacc/err_syntax20.tab.c, test/btyacc/err_syntax20.tab.h, test/btyacc/err_syntax21.error, test/btyacc/err_syntax21.output, test/btyacc/err_syntax21.tab.c, test/btyacc/err_syntax21.tab.h, test/btyacc/err_syntax22.error, test/btyacc/err_syntax22.output, test/btyacc/err_syntax22.tab.c, test/btyacc/err_syntax22.tab.h, test/btyacc/err_syntax23.error, test/btyacc/err_syntax23.output, test/btyacc/err_syntax23.tab.c, test/btyacc/err_syntax23.tab.h, test/btyacc/err_syntax24.error, test/btyacc/err_syntax24.output, test/btyacc/err_syntax24.tab.c, test/btyacc/err_syntax24.tab.h, test/btyacc/err_syntax25.error, test/btyacc/err_syntax25.output, test/btyacc/err_syntax25.tab.c, test/btyacc/err_syntax25.tab.h, test/btyacc/err_syntax26.error, test/btyacc/err_syntax26.output, test/btyacc/err_syntax26.tab.c, test/btyacc/err_syntax26.tab.h, test/btyacc/err_syntax3.output, test/btyacc/err_syntax3.tab.c, test/btyacc/err_syntax3.tab.h, test/btyacc/err_syntax4.output, test/btyacc/err_syntax4.tab.c, test/btyacc/err_syntax4.tab.h, test/btyacc/err_syntax5.output, test/btyacc/err_syntax5.tab.c, test/btyacc/err_syntax5.tab.h, test/btyacc/err_syntax6.output, test/btyacc/err_syntax6.tab.c, test/btyacc/err_syntax6.tab.h, test/btyacc/err_syntax7.output, test/btyacc/err_syntax7.tab.c, test/btyacc/err_syntax7.tab.h, test/btyacc/err_syntax7a.output, test/btyacc/err_syntax7a.tab.c, test/btyacc/err_syntax7a.tab.h, test/btyacc/err_syntax7b.output, test/btyacc/err_syntax7b.tab.c, test/btyacc/err_syntax7b.tab.h, test/btyacc/err_syntax8.output, test/btyacc/err_syntax8.tab.c, test/btyacc/err_syntax8.tab.h, test/btyacc/err_syntax8a.output, test/btyacc/err_syntax8a.tab.c, test/btyacc/err_syntax8a.tab.h, test/btyacc/err_syntax9.output, test/btyacc/err_syntax9.tab.c, test/btyacc/err_syntax9.tab.h:
+       reference output for testing
+
+2014-03-24  Thomas E. Dickey  <tom@invisible-island.net>
+
+       * defs.h: fix compiler warnings due to mputc()
+
+2014-03-23  Tom.Shields
+
+       * test/btyacc_demo.y: testcase for btyacc
+
+       * test/btyacc/varsyntax_calc1.error, test/btyacc/varsyntax_calc1.output, test/btyacc/varsyntax_calc1.tab.c, test/btyacc/varsyntax_calc1.tab.h:
+       reference output for testing
+
+       * test/varsyntax_calc1.y, test/btyacc_calc1.y: testcase for btyacc
+
+2014-03-23  Thomas E. Dickey  <tom@invisible-island.net>
+
+       * test/err_syntax26.error, test/err_syntax26.output, test/err_syntax26.tab.c, test/err_syntax26.tab.h, test/yacc/err_syntax26.error, test/yacc/err_syntax26.output, test/yacc/err_syntax26.tab.c, test/yacc/err_syntax26.tab.h:
+       reference output for testing
+
+       * test/err_syntax26.y: testcase for missing_brace()
+
+       * test/err_syntax25.error, test/err_syntax25.output, test/err_syntax25.tab.c, test/err_syntax25.tab.h, test/yacc/err_syntax25.error, test/yacc/err_syntax25.output, test/yacc/err_syntax25.tab.c, test/yacc/err_syntax25.tab.h:
+       reference output for testing
+
+       * test/err_syntax25.y: testcase for over_unionized()
+
+       * test/err_syntax24.error, test/err_syntax24.output, test/err_syntax24.tab.c, test/err_syntax24.tab.h, test/yacc/err_syntax24.error, test/yacc/err_syntax24.output, test/yacc/err_syntax24.tab.c, test/yacc/err_syntax24.tab.h:
+       reference output for testing
+
+       * test/err_syntax24.y: testcase for default_action_warning()
+
+2014-03-23  Tom.Shields
+
+       * test/btyacc/quote_calc3-s.error, test/btyacc/quote_calc4-s.error, test/btyacc/quote_calc4.error, test/btyacc/grammar.dot, test/btyacc/grammar.error, test/btyacc/pure_calc.error, test/btyacc/pure_error.error, test/btyacc/quote_calc-s.error, test/btyacc/quote_calc.error, test/btyacc/quote_calc2-s.error, test/btyacc/quote_calc2.error, test/btyacc/quote_calc3.error, test/btyacc/err_syntax2.error, test/btyacc/err_syntax3.error, test/btyacc/err_syntax4.error, test/btyacc/err_syntax5.error, test/btyacc/err_syntax6.error, test/btyacc/err_syntax7.error, test/btyacc/err_syntax7a.error, test/btyacc/err_syntax7b.error, test/btyacc/err_syntax8.error, test/btyacc/err_syntax8a.error, test/btyacc/err_syntax9.error, test/btyacc/error.error, test/btyacc/calc1.error, test/btyacc/calc2.error, test/btyacc/calc3.error, test/btyacc/code_calc.error, test/btyacc/code_error.error, test/btyacc/empty.error, test/btyacc/err_syntax1.error, test/btyacc/btyacc_calc1.error, test/btyacc/btyacc_demo.error:
+       reference output for testing
+
+2014-03-23  Thomas E. Dickey  <tom@invisible-island.net>
+
+       * test/err_syntax23.error, test/err_syntax23.output, test/err_syntax23.tab.c, test/err_syntax23.tab.h, test/yacc/err_syntax23.error, test/yacc/err_syntax23.output, test/yacc/err_syntax23.tab.c, test/yacc/err_syntax23.tab.h:
+       reference output for testing
+
+       * test/err_syntax23.y: testcase for untyped_lhs()
+
+2014-03-23  Tom.Shields
+
+       * test/run_test.sh:
+       move test-outputs into subdirectories to keep btyacc/yacc results separate
+
+2014-03-23  Thomas E. Dickey  <tom@invisible-island.net>
+
+       * test/err_syntax22.error, test/err_syntax22.output, test/err_syntax22.tab.c, test/err_syntax22.tab.h, test/yacc/err_syntax22.error, test/yacc/err_syntax22.output, test/yacc/err_syntax22.tab.c, test/yacc/err_syntax22.tab.h:
+       reference output for testing
+
+       * test/err_syntax22.y: testcase for untyped_rhs()
+
+       * test/err_syntax21.error, test/err_syntax21.output, test/err_syntax21.tab.c, test/err_syntax21.tab.h, test/yacc/err_syntax21.error, test/yacc/err_syntax21.output, test/yacc/err_syntax21.tab.c, test/yacc/err_syntax21.tab.h, test/err_syntax20.error, test/err_syntax20.output, test/err_syntax20.tab.c, test/err_syntax20.tab.h, test/yacc/err_syntax20.error, test/yacc/err_syntax20.output, test/yacc/err_syntax20.tab.c, test/yacc/err_syntax20.tab.h:
+       reference output for testing
+
+       * test/err_syntax20.y: testcase for undefined_symbol_warning()
+
+       * test/err_syntax21.y: testcase for unknown_rhs()
+
+       * test/err_syntax19.error, test/err_syntax19.output, test/err_syntax19.tab.c, test/err_syntax19.tab.h, test/yacc/err_syntax19.error, test/yacc/err_syntax19.output, test/yacc/err_syntax19.tab.c, test/yacc/err_syntax19.tab.h:
+       reference output for testing
+
+       * test/err_syntax19.y: testcase for dollar_error()
+
+       * test/err_syntax18.error, test/err_syntax18.output, test/err_syntax18.tab.c, test/err_syntax18.tab.h, test/yacc/err_syntax18.error, test/yacc/err_syntax18.output, test/yacc/err_syntax18.tab.c, test/yacc/err_syntax18.tab.h:
+       reference output for testing
+
+       * test/err_syntax18.y: testcase for dollar_warning()
+
+       * test/err_syntax17.error, test/err_syntax17.output, test/err_syntax17.tab.c, test/err_syntax17.tab.h, test/yacc/err_syntax17.error, test/yacc/err_syntax17.output, test/yacc/err_syntax17.tab.c, test/yacc/err_syntax17.tab.h:
+       reference output for testing
+
+       * test/err_syntax17.y: testcase for unterminated_action()
+
+2014-03-22  Thomas E. Dickey  <tom@invisible-island.net>
+
+       * test/err_syntax16.error, test/err_syntax16.output, test/err_syntax16.tab.c, test/err_syntax16.tab.h, test/yacc/err_syntax16.error, test/yacc/err_syntax16.output, test/yacc/err_syntax16.tab.c, test/yacc/err_syntax16.tab.h:
+       reference output for testing
+
+       * test/err_syntax16.y: testcase for terminal_lhs()
+
+       * test/err_syntax15.error, test/err_syntax15.output, test/err_syntax15.tab.c, test/err_syntax15.tab.h, test/yacc/err_syntax15.error, test/yacc/err_syntax15.output, test/yacc/err_syntax15.tab.c, test/yacc/err_syntax15.tab.h:
+       reference output for testing
+
+       * test/err_syntax15.y: testcase for no_grammar()
+
+       * test/err_syntax14.error, test/err_syntax14.output, test/err_syntax14.tab.c, test/err_syntax14.tab.h, test/yacc/err_syntax14.error, test/yacc/err_syntax14.output, test/yacc/err_syntax14.tab.c, test/yacc/err_syntax14.tab.h:
+       reference output for testing
+
+       * test/err_syntax14.y:
+       testcase for restarted_warning() and undefined_goal()
+
+       * test/err_syntax13.error, test/err_syntax13.output, test/err_syntax13.tab.c, test/err_syntax13.tab.h, test/yacc/err_syntax13.error, test/yacc/err_syntax13.output, test/yacc/err_syntax13.tab.c, test/yacc/err_syntax13.tab.h:
+       reference output for testing
+
+       * test/err_syntax13.y: testcase for terminal_start()
+
+       * test/err_syntax12.error, test/err_syntax12.output, test/err_syntax12.tab.c, test/err_syntax12.tab.h, test/yacc/err_syntax12.error, test/yacc/err_syntax12.output, test/yacc/err_syntax12.tab.c, test/yacc/err_syntax12.tab.h:
+       reference output for testing
+
+       * test/err_syntax12.y: testcase for revalued_warning()
+
+       * test/err_syntax11.error, test/err_syntax11.output, test/err_syntax11.tab.c, test/err_syntax11.tab.h, test/yacc/err_syntax11.error, test/yacc/err_syntax11.output, test/yacc/err_syntax11.tab.c, test/yacc/err_syntax11.tab.h:
+       reference output for testing
+
+       * test/err_syntax11.y: testcase for reprec_warning()
+
+       * test/err_syntax10.error, test/err_syntax10.output, test/err_syntax10.tab.c, test/err_syntax10.tab.h, test/yacc/err_syntax10.error, test/yacc/err_syntax10.output, test/yacc/err_syntax10.tab.c, test/yacc/err_syntax10.tab.h:
+       reference output for testing
+
+       * test/err_syntax10.y: testcase for retyped_warning()
+
+2014-03-21  Thomas E. Dickey  <tom@invisible-island.net>
+
+       * test/err_syntax9.error, test/err_syntax9.output, test/err_syntax9.tab.c, test/err_syntax9.tab.h, test/yacc/err_syntax9.error, test/yacc/err_syntax9.output, test/yacc/err_syntax9.tab.c, test/yacc/err_syntax9.tab.h:
+       reference output for testing
+
+       * test/err_syntax9.y: testcase for tokenized_start()
+
+       * test/err_syntax8.error, test/err_syntax8.output, test/err_syntax8.tab.c, test/err_syntax8.tab.h, test/err_syntax8a.error, test/err_syntax8a.output, test/err_syntax8a.tab.c, test/err_syntax8a.tab.h, test/yacc/err_syntax8.error, test/yacc/err_syntax8.output, test/yacc/err_syntax8.tab.c, test/yacc/err_syntax8.tab.h, test/yacc/err_syntax8a.error, test/yacc/err_syntax8a.output, test/yacc/err_syntax8a.tab.c, test/yacc/err_syntax8a.tab.h:
+       reference output for testing
+
+       * test/err_syntax8a.y, test/err_syntax8.y: testcase for used_reserved()
+
+       * test/err_syntax7.error, test/err_syntax7.output, test/err_syntax7.tab.c, test/err_syntax7.tab.h, test/err_syntax7a.error, test/err_syntax7a.output, test/err_syntax7a.tab.c, test/err_syntax7a.tab.h, test/err_syntax7b.error, test/err_syntax7b.output, test/err_syntax7b.tab.c, test/err_syntax7b.tab.h, test/yacc/err_syntax7.error, test/yacc/err_syntax7.output, test/yacc/err_syntax7.tab.c, test/yacc/err_syntax7.tab.h, test/yacc/err_syntax7a.error, test/yacc/err_syntax7a.output, test/yacc/err_syntax7a.tab.c, test/yacc/err_syntax7a.tab.h, test/yacc/err_syntax7b.error, test/yacc/err_syntax7b.output, test/yacc/err_syntax7b.tab.c, test/yacc/err_syntax7b.tab.h:
+       reference output for testing
+
+       * test/err_syntax7b.y, test/err_syntax7a.y, test/err_syntax7.y:
+       testcase for illegal_character()
+
+       * test/err_syntax6.error, test/err_syntax6.output, test/err_syntax6.tab.c, test/err_syntax6.tab.h, test/yacc/err_syntax6.error, test/yacc/err_syntax6.output, test/yacc/err_syntax6.tab.c, test/yacc/err_syntax6.tab.h:
+       reference output for testing
+
+       * test/err_syntax6.y: testcase for illegal_tag()
+
+       * test/err_syntax5.error, test/err_syntax5.output, test/err_syntax5.tab.c, test/err_syntax5.tab.h, test/yacc/err_syntax5.error, test/yacc/err_syntax5.output, test/yacc/err_syntax5.tab.c, test/yacc/err_syntax5.tab.h:
+       reference output for testing
+
+       * test/err_syntax5.y: testcase for unterminated_union()
+
+       * test/err_syntax4.error, test/err_syntax4.output, test/err_syntax4.tab.c, test/err_syntax4.tab.h, test/yacc/err_syntax4.error, test/yacc/err_syntax4.output, test/yacc/err_syntax4.tab.c, test/yacc/err_syntax4.tab.h:
+       reference output for testing
+
+       * test/err_syntax4.y: testcase for unterminated_text()
+
+       * test/err_syntax3.error, test/err_syntax3.output, test/err_syntax3.tab.c, test/err_syntax3.tab.h, test/yacc/err_syntax3.error, test/yacc/err_syntax3.output, test/yacc/err_syntax3.tab.c, test/yacc/err_syntax3.tab.h:
+       reference output for testing
+
+       * test/err_syntax3.y: testcase for unterminated_string()
+
+       * test/err_syntax2.error, test/err_syntax2.output, test/err_syntax2.tab.c, test/err_syntax2.tab.h, test/yacc/err_syntax2.error, test/yacc/err_syntax2.output, test/yacc/err_syntax2.tab.c, test/yacc/err_syntax2.tab.h:
+       reference output for testing
+
+       * test/err_syntax2.y: testcase for unterminated_comment()
+
+       * test/err_syntax1.error, test/yacc/err_syntax1.error:
+       reference output for testing
+
+       * test/err_syntax1.y:
+       test-case with syntax error (and nonprinting character)
+
+       * test/calc.error, test/calc1.error, test/calc2.error, test/calc3.error, test/code_calc.error, test/code_error.error, test/err_syntax1.error, test/error.error, test/grammar.error, test/pure_calc.error, test/pure_error.error, test/quote_calc-s.error, test/quote_calc.error, test/quote_calc2-s.error, test/quote_calc2.error, test/quote_calc3-s.error, test/quote_calc3.error, test/quote_calc4-s.error, test/quote_calc4.error, test/yacc/calc.error, test/yacc/calc1.error, test/yacc/calc2.error, test/yacc/calc3.error, test/yacc/code_calc.error, test/yacc/code_error.error, test/yacc/error.error, test/yacc/grammar.error, test/yacc/pure_calc.error, test/yacc/pure_error.error, test/yacc/quote_calc-s.error, test/yacc/quote_calc.error, test/yacc/quote_calc2-s.error, test/yacc/quote_calc2.error, test/yacc/quote_calc3-s.error, test/yacc/quote_calc3.error, test/yacc/quote_calc4-s.error, test/yacc/quote_calc4.error:
+       reference output for testing
+
+       * test/run_test.sh:
+       save stderr to reference files, to capture shift/reduce messages as well
+       as syntax-error messages
+
+       * test/err_syntax1.output, test/err_syntax1.tab.c, test/err_syntax1.tab.h, test/yacc/err_syntax1.output, test/yacc/err_syntax1.tab.c, test/yacc/err_syntax1.tab.h:
+       reference output for testing
+
+       * test/run_test.sh: generate a ".dot" file for the grammar file
+
+       * test/grammar.dot: RCS_BASE
+
+       * test/yacc/grammar.dot: reference output for testing
+
+2014-03-19  Tom.Shields
+
+       * output.c: rename MAXSHORT to MAXYYINT
+
+2014-03-18  Tom.Shields
+
+       * yaccpar.skel: skeleton with btyacc additions
+
+       * NOTES-btyacc-Changes: byacc-btyacc-20140323
+
+       * test/btyacc/btyacc_calc1.output, test/btyacc/btyacc_calc1.tab.c, test/btyacc/btyacc_calc1.tab.h:
+       reference output for testing
+
+       * test/run_make.sh:
+       move test-outputs into subdirectories to keep btyacc/yacc results separate
+
+       * test/btyacc/pure_calc.tab.c, test/btyacc/pure_calc.tab.h, test/btyacc/pure_error.output, test/btyacc/pure_error.tab.c, test/btyacc/pure_error.tab.h, test/btyacc/quote_calc-s.output, test/btyacc/quote_calc-s.tab.c, test/btyacc/quote_calc-s.tab.h, test/btyacc/quote_calc.output, test/btyacc/quote_calc.tab.c, test/btyacc/quote_calc.tab.h, test/btyacc/quote_calc2-s.output, test/btyacc/quote_calc2-s.tab.c, test/btyacc/quote_calc2-s.tab.h, test/btyacc/quote_calc2.output, test/btyacc/quote_calc2.tab.c, test/btyacc/quote_calc2.tab.h, test/btyacc/quote_calc3-s.output, test/btyacc/quote_calc3-s.tab.c, test/btyacc/quote_calc3-s.tab.h, test/btyacc/quote_calc3.output, test/btyacc/quote_calc3.tab.c, test/btyacc/quote_calc3.tab.h, test/btyacc/quote_calc4-s.output, test/btyacc/quote_calc4-s.tab.c, test/btyacc/quote_calc4-s.tab.h, test/btyacc/quote_calc4.output, test/btyacc/quote_calc4.tab.c, test/btyacc/quote_calc4.tab.h, test/btyacc/calc1.output, test/btyacc/calc1.tab.c, test/btyacc/calc1.tab.h, test/btyacc/calc2.output, test/btyacc/calc2.tab.c, test/btyacc/calc2.tab.h, test/btyacc/calc3.output, test/btyacc/calc3.tab.c, test/btyacc/calc3.tab.h, test/btyacc/code_calc.code.c, test/btyacc/code_calc.output, test/btyacc/code_calc.tab.c, test/btyacc/code_calc.tab.h, test/btyacc/code_error.code.c, test/btyacc/code_error.output, test/btyacc/code_error.tab.c, test/btyacc/code_error.tab.h, test/btyacc/empty.output, test/btyacc/empty.tab.c, test/btyacc/empty.tab.h, test/btyacc/error.output, test/btyacc/error.tab.c, test/btyacc/error.tab.h, test/btyacc/grammar.output, test/btyacc/grammar.tab.c, test/btyacc/grammar.tab.h, test/btyacc/pure_calc.output, test/btyacc/btyacc_demo.output, test/btyacc/btyacc_demo.tab.h, test/btyacc/calc.output, test/btyacc/calc.tab.c, test/btyacc/calc.tab.h:
+       reference output for testing
+
+       * defs.h:
+       several changes to help decouple the use of 'short' as the type of value
+       used in yacc parsers.
+
+       * NOTES-btyacc-Disposition: byacc-btyacc-20140323
+
+2014-03-17  Tom.Shields
+
+       * skel2c, yaccpar.skel, yaccpar.skel.old: RCS_BASE
+
+       * test/run_lint.sh:
+       move test-outputs into subdirectories to keep btyacc/yacc results separate
+
+       * configure.in: add --with-max-table-size and --enable-btyacc options
+
+2014-03-16  Tom.Shields
+
+       * main.c: use Value_t rather than short
+
+2014-03-11  Tom.Shields
+
+       * test/empty.y: testcase for btyacc
+
+2014-03-10  Tom.Shields
+
+       * test/calc3.y, test/calc2.y: fix unused-variable warning
+
+2014-02-18  Tom.Shields
+
+       * lr0.c, graph.c: use Value_t rather than short
+
+       * closure.c: use Value_t rather than short
+       ifdef'd forward-reference prototypes to match ifdef'ing of the actual functions
+
+       * lalr.c: rename MAXSHORT to MAXYYINT
+
+2014-01-01  Thomas E. Dickey  <tom@invisible-island.net>
+
+       * yacc.1: document %token-table, improve presentation of double-quotes
+
+       * VERSION, package/byacc.spec, package/debian/changelog: bump
+
+       * test/yacc/calc.tab.c, test/yacc/calc1.tab.c, test/yacc/calc2.tab.c, test/yacc/calc3.tab.c, test/yacc/code_calc.code.c, test/yacc/code_calc.tab.c, test/yacc/code_error.code.c, test/yacc/code_error.tab.c, test/yacc/error.tab.c, test/yacc/grammar.tab.c, test/yacc/pure_calc.tab.c, test/yacc/pure_error.tab.c, test/yacc/quote_calc-s.tab.c, test/yacc/quote_calc.tab.c, test/yacc/quote_calc2-s.tab.c, test/yacc/quote_calc2.tab.c, test/yacc/quote_calc3-s.tab.c, test/yacc/quote_calc3.tab.c, test/yacc/quote_calc4-s.tab.c, test/yacc/quote_calc4.tab.c:
+       reference output for testing
+
+       * test/calc.tab.c, test/calc1.tab.c, test/calc2.tab.c, test/calc3.tab.c, test/code_calc.code.c, test/code_calc.tab.c, test/code_error.code.c, test/code_error.tab.c, test/error.tab.c, test/ftp.tab.c, test/grammar.tab.c, test/pure_calc.tab.c, test/pure_error.tab.c, test/quote_calc-s.tab.c, test/quote_calc.tab.c, test/quote_calc2-s.tab.c, test/quote_calc2.tab.c, test/quote_calc3-s.tab.c, test/quote_calc3.tab.c, test/quote_calc4-s.tab.c, test/quote_calc4.tab.c:
+       regen
+
+       * output.c, skeleton.c:
+       amend the last change so that yytname is #define'd as needed rather than
+       permanent - to avoid breaking cproto for instance.
+
+2014-01-01  Christos.Zoulas
+
+       * output.c, defs.h, main.c, reader.c, skeleton.c:
+       changes to build ntpd using byacc:
+       - rename yyname[] to yytname[]
+       - add YYTRANSLATE() macro
+       - recognize bison's %token-table declaration
+
+2014-01-01  Thomas E. Dickey  <tom@invisible-island.net>
+
+       * configure: regen
+
+       * yacc.1: s/EE/XE/ to work around groff bug on Debian 6
+
+       * makefile.in: use CF_MAKE_DOCS
+
+       * aclocal.m4: add CF_MAKE_DOCS
+
+       * configure.in: use CF_MAKE_DOCS
+
+2013-12-26  Thomas E. Dickey  <tom@invisible-island.net>
+
+       * config.guess: 2013-11-29
+
+2013-11-19  Thomas E. Dickey  <tom@invisible-island.net>
+
+       * aclocal.m4: resync with my-autoconf (fixes for clang and mingw)
+
+2013-10-25  Thomas E. Dickey  <tom@invisible-island.net>
+
+       * config.sub: 2013-10-01
+
+2013-09-25  Thomas E. Dickey  <tom@invisible-island.net>
+
+       * reader.c: fix two loop-limits found by clang 3.3 --analyze
+
+       * configure: regen
+
+       * aclocal.m4:
+       tweaks to CF_MIXEDCASE_FILENAMES and CF_XOPEN_SOURCE for msys from ncurses
+
+       * package/mingw-byacc.spec: RCS_BASE
+
+       * test/calc.tab.c, test/calc1.tab.c, test/calc2.tab.c, test/calc3.tab.c, test/code_calc.code.c, test/code_error.code.c, test/error.tab.c, test/ftp.tab.c, test/grammar.tab.c, test/pure_calc.tab.c, test/pure_error.tab.c, test/quote_calc-s.tab.c, test/quote_calc.tab.c, test/quote_calc2-s.tab.c, test/quote_calc2.tab.c, test/quote_calc3-s.tab.c, test/quote_calc3.tab.c, test/quote_calc4-s.tab.c, test/quote_calc4.tab.c:
+       regen
+
+       * skeleton.c:
+       Increase default stack-size to match FreeBSD version noted as from
+       "BSD 4.4 Lite Usr.bin Sources".  See
+
+               http://svnweb.freebsd.org/base/vendor/CSRG/dist/usr.bin/yacc/
+               http://svnweb.freebsd.org/base/head/usr.bin/yacc/
+               http://svnweb.freebsd.org/base/vendor/byacc/
+
+       The original 1.9 sources (on which I based development) used 500 for
+       stacksize; the BSD Lite sources (a year or two later) used 10000.
+
+       This is a change to default values; the YYMAXDEPTH and YYSTACKSIZE
+       symbols have "always" been overridable by applications, but rarely
+       needed to do this.  RedHat began using the FreeBSD source in 2000,
+       and switched to this source in 2007 using the 20050813 snapshot.
+
+       RedHat #743343 misattributed the change in default stacksize to
+       a regression in byacc, but did not report the issue upstream.
+
+       * package/debian/changelog, VERSION, package/byacc.spec: bump
+
+2013-09-07  Thomas E. Dickey  <tom@invisible-island.net>
+
+       * config.sub: update to 2013-09-15
+
+       * config.guess: update to 2013-06-10
+
+2013-03-04  Thomas E. Dickey  <tom@invisible-island.net>
+
+       * package/debian/changelog, VERSION, package/byacc.spec: bump
+
+       * aclocal.m4:
+       adapt tweak from Dave Becket to work around long-ago breakage in "new" autoconf.
+
+       * output.c:
+       fix bogus #include if "-i" is given but not "-d" (report by Richard Mitton).
+       also while testing that, found a case where the union_file is unused; added
+       a check for address that.
+
+       * test/ftp.output, test/ftp.tab.c, test/ftp.tab.h: regen
+
+       * test/ftp.y: fix most compiler warnings for "make check_make"
+
+       * test/calc1.tab.c: regen
+
+       * test/calc1.y: fix most compiler warnings for "make check_make"
+
+       * test/calc.tab.c, test/calc1.tab.c, test/calc2.tab.c, test/calc3.tab.c, test/code_calc.code.c, test/code_error.code.c, test/error.tab.c, test/ftp.tab.c, test/grammar.tab.c, test/pure_calc.tab.c, test/pure_error.tab.c, test/quote_calc-s.tab.c, test/quote_calc.tab.c, test/quote_calc2-s.tab.c, test/quote_calc2.tab.c, test/quote_calc3-s.tab.c, test/quote_calc3.tab.c, test/quote_calc4-s.tab.c, test/quote_calc4.tab.c:
+       regen
+
+       * skeleton.c: quiet a gcc conversion-warning in yygrowstack()
+
+       * configure: regen
+
+       * aclocal.m4:
+       another fix for CF_GCC_VERSION to handle Debian's modification of gcc message.
+
+2013-02-10  Thomas E. Dickey  <tom@invisible-island.net>
+
+       * config.sub, config.guess: update to 2013-02-04
+
 2012-10-03  Thomas E. Dickey  <tom@invisible-island.net>
 
        * package/debian/changelog, package/byacc.spec, VERSION: bump
 
        * VERSION, package/debian/changelog, package/byacc.spec: bump
 
+       * test/yacc/calc1.output: reference output for testing
+
        * test/calc1.output, test/calc1.tab.c: regen
 
        * test/calc1.y:
        * test/calc2.tab.c, test/calc3.tab.c, test/code_error.code.c, test/ftp.tab.c, test/pure_calc.tab.c, test/pure_error.tab.c:
        regen
 
+       * test/code_debug.y: RCS_BASE
+
        * test/calc2.y, test/calc3.y, test/code_error.y, test/ftp.y:
        byacc already declares yyerror
 
        * test/quote_calc-s.output, test/quote_calc-s.tab.c, test/quote_calc-s.tab.h, test/quote_calc2-s.output, test/quote_calc2-s.tab.c, test/quote_calc2-s.tab.h, test/quote_calc3-s.output, test/quote_calc3-s.tab.c, test/quote_calc3-s.tab.h, test/quote_calc4-s.output, test/quote_calc4-s.tab.c, test/quote_calc4-s.tab.h:
        RCS_BASE
 
+       * test/yacc/quote_calc-s.output, test/yacc/quote_calc-s.tab.h, test/yacc/quote_calc2-s.output, test/yacc/quote_calc2-s.tab.h, test/yacc/quote_calc3-s.output, test/yacc/quote_calc3-s.tab.h, test/yacc/quote_calc4-s.output, test/yacc/quote_calc4-s.tab.h:
+       reference output for testing
+
        * test/run_test.sh: generate/test with "-s" option applied.
 
 2012-01-13  Thomas E. Dickey  <tom@invisible-island.net>
 
        * main.c: add -s option to usage message.
 
-       * test/quote_calc3.output, test/quote_calc3.tab.c, test/quote_calc4.output, test/quote_calc4.tab.c, test/quote_calc4.tab.h, test/quote_calc3.y, test/quote_calc.tab.h, test/quote_calc.output, test/quote_calc.tab.c, test/quote_calc2.output, test/quote_calc2.tab.c, test/quote_calc2.tab.h, test/quote_calc3.tab.h, test/quote_calc4.y, test/quote_calc.y, test/quote_calc2.y:
+       * test/quote_calc3.output, test/quote_calc3.tab.c, test/quote_calc4.output, test/quote_calc4.tab.c, test/quote_calc4.tab.h:
+       RCS_BASE
+
+       * test/yacc/quote_calc3.output, test/yacc/quote_calc4.output, test/yacc/quote_calc4.tab.h:
+       reference output for testing
+
+       * test/quote_calc3.y, test/quote_calc.tab.h: RCS_BASE
+
+       * test/yacc/quote_calc.tab.h: reference output for testing
+
+       * test/quote_calc.output, test/quote_calc.tab.c, test/quote_calc2.output, test/quote_calc2.tab.c, test/quote_calc2.tab.h, test/quote_calc3.tab.h:
        RCS_BASE
 
+       * test/yacc/quote_calc.output, test/yacc/quote_calc2.output, test/yacc/quote_calc2.tab.h, test/yacc/quote_calc3.tab.h:
+       reference output for testing
+
+       * test/quote_calc4.y, test/quote_calc.y, test/quote_calc2.y: RCS_BASE
+
        * configure: regen
 
        * aclocal.m4: resync with my-autoconf, i.e., fixes for CF_XOPEN_SOURCE
 
 2011-04-01  Thomas E. Dickey  <tom@invisible-island.net>
 
-       * config.sub: 2011-04-01
+       * config.sub: update to 2011-04-01
 
 2011-02-02  Thomas E. Dickey  <tom@invisible-island.net>
 
-       * config.guess: 2011-01-01
+       * config.guess: update to 2011-01-01
 
 2010-12-29  Thomas E. Dickey  <tom@invisible-island.net>
 
 
        * output.c: simplified a little, using putc_code() and putl_code()
 
+       * test/yacc/calc1.tab.h: reference output for testing
+
        * test/calc1.tab.h: regen
 
        * reader.c:
 
 2010-09-28  Thomas E. Dickey  <tom@invisible-island.net>
 
-       * config.guess: 2010-09-24
+       * config.guess: update to 2010-09-24
 
 2010-09-10  Thomas E. Dickey  <tom@invisible-island.net>
 
-       * config.sub: 2010-09-11
+       * config.sub: update to 2010-09-11
 
 2010-06-10  Thomas E. Dickey  <tom@invisible-island.net>
 
        improve %lex-param / %parse-param implementation by allowing for arrays to
        be passed as parameters, e.g., "int regs[26]".
 
-       * test/calc3.tab.c, test/calc3.y, test/calc3.output, test/calc3.tab.h, test/calc2.tab.c, test/calc2.y, test/calc2.tab.h, test/calc2.output:
+       * test/calc3.tab.c, test/calc3.y, test/calc3.output, test/calc3.tab.h:
        RCS_BASE
 
+       * test/yacc/calc3.output, test/yacc/calc3.tab.h:
+       reference output for testing
+
+       * test/calc2.tab.c, test/calc2.y, test/calc2.tab.h: RCS_BASE
+
+       * test/yacc/calc2.tab.h: reference output for testing
+
+       * test/calc2.output: RCS_BASE
+
+       * test/yacc/calc2.output: reference output for testing
+
        * output.c:
        improve %lex-param / %parse-param implementation by allowing for arrays to
        be passed as parameters, e.g., "int regs[26]".
        provide for testing -r and -P options by checking if the ".y" filename
        begins with "code_" or "pure_", respectively.
 
-       * test/code_error.code.c, test/code_error.tab.c, test/code_error.tab.h, test/code_calc.code.c, test/code_calc.tab.c, test/code_calc.tab.h, test/pure_calc.output, test/pure_calc.tab.h, test/pure_error.output, test/pure_error.tab.h, test/code_calc.output, test/code_error.output:
+       * test/code_error.code.c, test/code_error.tab.c, test/code_error.tab.h:
        RCS_BASE
 
+       * test/yacc/code_error.tab.h: reference output for testing
+
+       * test/code_calc.code.c, test/code_calc.tab.c, test/code_calc.tab.h:
+       RCS_BASE
+
+       * test/yacc/code_calc.tab.h: reference output for testing
+
+       * test/pure_calc.output, test/pure_calc.tab.h, test/pure_error.output, test/pure_error.tab.h:
+       RCS_BASE
+
+       * test/yacc/pure_calc.output, test/yacc/pure_calc.tab.h, test/yacc/pure_error.output, test/yacc/pure_error.tab.h:
+       reference output for testing
+
+       * test/code_calc.output, test/code_error.output: RCS_BASE
+
+       * test/yacc/code_calc.output, test/yacc/code_error.output:
+       reference output for testing
+
        * test/error.tab.c, test/ftp.tab.c, test/grammar.tab.c: regen
 
        * test/run_test.sh:
 
 2009-12-31  Thomas E. Dickey  <tom@invisible-island.net>
 
-       * config.guess: 2009-12-30
+       * config.guess: update to 2009-12-30
 
-       * config.sub: 2009-12-31
+       * config.sub: update to 2009-12-31
 
 2009-10-27  Thomas E. Dickey  <tom@invisible-island.net>
 
 
 2009-08-25  Thomas E. Dickey  <tom@invisible-island.net>
 
-       * config.guess, config.sub: 2009-08-19
+       * config.guess, config.sub: update to 2009-08-19
 
 2009-02-21  Thomas E. Dickey  <tom@invisible-island.net>
 
 
 2006-12-22  Thomas E. Dickey  <tom@invisible-island.net>
 
-       * config.guess: 2006/12/22
+       * config.guess: update to 2006/12/22
 
 2006-12-08  Thomas E. Dickey  <tom@invisible-island.net>
 
-       * config.sub: 2006/12/08
+       * config.sub: update to 2006/12/08
 
 2005-08-13  Thomas E. Dickey  <tom@invisible-island.net>
 
 
 2005-06-25  Thomas E. Dickey  <tom@invisible-island.net>
 
-       * config.sub: 2005/6/2
+       * config.sub: update to 2005/6/2
 
-       * config.guess: 2005/5/27
+       * config.guess: update to 2005/5/27
 
 2005-05-05  Thomas E. Dickey  <tom@invisible-island.net>
 
 
 2005-04-16  Thomas E. Dickey  <tom@invisible-island.net>
 
-       * config.sub: 2005/2/10
+       * config.sub: update to 2005/2/10
 
-       * config.guess: 2005/3/24
+       * config.guess: update to 2005/3/24
 
 2005-04-13  Thomas E. Dickey  <tom@invisible-island.net>
 
 
        * test/grammar.output, test/grammar.tab.c, test/grammar.tab.h: RCS_BASE
 
+       * test/yacc/grammar.output, test/yacc/grammar.tab.h:
+       reference output for testing
+
        * makefile.in: turn on "make check" rule
 
-       * test/calc.output, test/run_test.sh, test/calc.tab.h: RCS_BASE
+       * test/calc.output: RCS_BASE
+
+       * test/yacc/calc.output: reference output for testing
+
+       * test/run_test.sh, test/calc.tab.h: RCS_BASE
+
+       * test/yacc/calc.tab.h: reference output for testing
 
        * test/ftp.tab.c: yyparse() is now yyparse(void)
 
 
 1993-02-22  unknown
 
-       * test/ftp.output, test/ftp.tab.c, test/ftp.tab.h, test/error.output, test/error.tab.c, test/error.tab.h:
-       RCS_BASE
+       * test/ftp.output, test/ftp.tab.c, test/ftp.tab.h: RCS_BASE
+
+1993-02-22  Thomas E. Dickey  <tom@invisible-island.net>
+
+       * test/yacc/error.output, test/yacc/error.tab.h:
+       reference output for testing
+
+1993-02-22  unknown
+
+       * test/error.output, test/error.tab.c, test/error.tab.h: RCS_BASE
 
        * skeleton.c, warshall.c, main.c, output.c, reader.c, closure.c, NOTES:
        original version
index a633358..572a8c2 100644 (file)
@@ -1 +1 @@
-20121003
+20141006
index 7573ff5..f5c3f04 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: closure.c,v 1.9 2010/06/09 08:21:47 tom Exp $ */
+/* $Id: closure.c,v 1.11 2014/09/18 00:40:07 tom Exp $ */
 
 #include "defs.h"
 
@@ -6,15 +6,22 @@ Value_t *itemset;
 Value_t *itemsetend;
 unsigned *ruleset;
 
+static unsigned *first_base;
 static unsigned *first_derives;
 static unsigned *EFF;
 
+#ifdef DEBUG
+static void print_closure(int);
+static void print_EFF(void);
+static void print_first_derives(void);
+#endif
+
 static void
 set_EFF(void)
 {
     unsigned *row;
     int symbol;
-    short *sp;
+    Value_t *sp;
     int rowsize;
     int i;
     int rule;
@@ -53,7 +60,7 @@ set_first_derives(void)
     int j;
     unsigned k;
     unsigned cword = 0;
-    short *rp;
+    Value_t *rp;
 
     int rule;
     int i;
@@ -62,7 +69,8 @@ set_first_derives(void)
 
     rulesetsize = WORDSIZE(nrules);
     varsetsize = WORDSIZE(nvars);
-    first_derives = NEW2(nvars * rulesetsize, unsigned) - ntokens * rulesetsize;
+    first_base = NEW2(nvars * rulesetsize, unsigned);
+    first_derives = first_base - ntokens * rulesetsize;
 
     set_EFF();
 
@@ -100,7 +108,7 @@ set_first_derives(void)
 }
 
 void
-closure(short *nucleus, int n)
+closure(Value_t *nucleus, int n)
 {
     unsigned ruleno;
     unsigned word;
@@ -170,22 +178,22 @@ finalize_closure(void)
 {
     FREE(itemset);
     FREE(ruleset);
-    FREE(first_derives + ntokens * WORDSIZE(nrules));
+    FREE(first_base);
 }
 
 #ifdef DEBUG
 
-void
+static void
 print_closure(int n)
 {
-    short *isp;
+    Value_t *isp;
 
     printf("\n\nn = %d\n\n", n);
     for (isp = itemset; isp < itemsetend; isp++)
        printf("   %d\n", *isp);
 }
 
-void
+static void
 print_EFF(void)
 {
     int i, j;
@@ -216,7 +224,7 @@ print_EFF(void)
     }
 }
 
-void
+static void
 print_first_derives(void)
 {
     int i;
index 4d1a407..0124a84 100644 (file)
@@ -1,9 +1,10 @@
-/* $Id: defs.h,v 1.37 2012/05/26 15:23:00 tom Exp $ */
+/* $Id: defs.h,v 1.51 2014/10/02 22:38:13 tom Exp $ */
 
 #ifdef HAVE_CONFIG_H
 #include <config.h>
 #endif
 
+#include <limits.h>
 #include <stdlib.h>
 #include <string.h>
 #include <errno.h>
 
 #define VERSION VSTRING(YYMAJOR, YYMINOR)
 
-/*  machine-dependent definitions                      */
-/*  the following definitions are for the Tahoe                */
-/*  they might have to be changed for other machines   */
+/*  machine-dependent definitions:                     */
 
 /*  MAXCHAR is the largest unsigned character value    */
-/*  MAXSHORT is the largest value of a C short         */
-/*  MINSHORT is the most negative value of a C short   */
 /*  MAXTABLE is the maximum table size                 */
+/*  YYINT is the smallest C integer type that can be   */
+/*     used to address a table of size MAXTABLE        */
+/*  MAXYYINT is the largest value of a YYINT           */
+/*  MINYYINT is the most negative value of a YYINT     */
 /*  BITS_PER_WORD is the number of bits in a C unsigned        */
 /*  WORDSIZE computes the number of words needed to    */
 /*     store n bits                                    */
 /*     from r (0-indexed)                              */
 /*  SETBIT sets the n-th bit starting from r           */
 
-#define        MAXCHAR         255
-#define        MAXSHORT        32767
-#define MINSHORT       -32768
+#define        MAXCHAR         UCHAR_MAX
+#ifndef MAXTABLE
 #define MAXTABLE       32500
-#define BITS_PER_WORD  32
-#define        WORDSIZE(n)     (((n)+(BITS_PER_WORD-1))/BITS_PER_WORD)
-#define        BIT(r, n)       ((((r)[(n)>>5])>>((n)&31))&1)
-#define        SETBIT(r, n)    ((r)[(n)>>5]|=((unsigned)1<<((n)&31)))
+#endif
+#if MAXTABLE <= SHRT_MAX
+#define YYINT          short
+#define MAXYYINT       SHRT_MAX
+#define MINYYINT       SHRT_MIN
+#elif MAXTABLE <= INT_MAX
+#define YYINT          int
+#define MAXYYINT       INT_MAX
+#define MINYYINT       INT_MIN
+#else
+#error "MAXTABLE is too large for this machine architecture!"
+#endif
+
+#define BITS_PER_WORD  ((int) sizeof (unsigned) * CHAR_BIT)
+#define WORDSIZE(n)    (((n)+(BITS_PER_WORD-1))/BITS_PER_WORD)
+#define BIT(r, n)      ((((r)[(n)/BITS_PER_WORD])>>((n)&(BITS_PER_WORD-1)))&1)
+#define SETBIT(r, n)   ((r)[(n)/BITS_PER_WORD]|=((unsigned)1<<((n)&(BITS_PER_WORD-1))))
 
 /*  character names  */
 
 #define PARSE_PARAM 13
 #define LEX_PARAM 14
 #define POSIX_YACC 15
+#define TOKEN_TABLE 16
+
+#if defined(YYBTYACC)
+#define LOCATIONS 17
+#define DESTRUCTOR 18
+#endif
 
 /*  symbol classes  */
 
 #define UNKNOWN 0
 #define TERM 1
 #define NONTERM 2
+#define ACTION 3
+#define ARGUMENT 4
 
 /*  the undefined value  */
 
 #define CALLOC(k,n)    (calloc((size_t)(k),(size_t)(n)))
 #define        FREE(x)         (free((char*)(x)))
 #define MALLOC(n)      (malloc((size_t)(n)))
+#define TCMALLOC(t,n)  ((t*) calloc((size_t)(n), sizeof(t)))
 #define TMALLOC(t,n)   ((t*) malloc((size_t)(n) * sizeof(t)))
 #define        NEW(t)          ((t*)allocate(sizeof(t)))
 #define        NEW2(n,t)       ((t*)allocate(((size_t)(n)*sizeof(t))))
 /* messages */
 #define PLURAL(n) ((n) > 1 ? "s" : "")
 
+/*
+ * Features which depend indirectly on the btyacc configuration, but are not
+ * essential.
+ */
+#if defined(YYBTYACC)
+#define USE_HEADER_GUARDS 1
+#else
+#define USE_HEADER_GUARDS 0
+#endif
+
 typedef char Assoc_t;
 typedef char Class_t;
-typedef short Index_t;
-typedef short Value_t;
+typedef YYINT Index_t;
+typedef YYINT Value_t;
 
 /*  the structure of a symbol table entry  */
 
@@ -163,6 +195,12 @@ struct bucket
     struct bucket *next;
     char *name;
     char *tag;
+#if defined(YYBTYACC)
+    char **argnames;
+    char **argtags;
+    int  args;
+    char *destructor;
+#endif
     Value_t value;
     Index_t index;
     Value_t prec;
@@ -248,6 +286,12 @@ extern int lineno;
 extern int outline;
 extern int exit_code;
 extern int pure_parser;
+extern int token_table;
+#if defined(YYBTYACC)
+extern int locations;
+extern int backtrack;
+extern int destructor;
+#endif
 
 extern const char *const banner[];
 extern const char *const xdecls[];
@@ -259,9 +303,7 @@ extern const char *const hdr_vars[];
 extern const char *const body_1[];
 extern const char *const body_vars[];
 extern const char *const body_2[];
-extern const char *const body_3[];
 extern const char *const trailer[];
-extern const char *const trailer_2[];
 
 extern char *code_file_name;
 extern char *input_file_name;
@@ -279,11 +321,11 @@ extern FILE *union_file;
 extern FILE *verbose_file;
 extern FILE *graph_file;
 
-extern int nitems;
-extern int nrules;
-extern int nsyms;
-extern int ntokens;
-extern int nvars;
+extern Value_t nitems;
+extern Value_t nrules;
+extern Value_t nsyms;
+extern Value_t ntokens;
+extern Value_t nvars;
 extern int ntags;
 
 extern char unionized;
@@ -296,6 +338,12 @@ extern Value_t *symbol_value;
 extern Value_t *symbol_prec;
 extern char *symbol_assoc;
 
+#if defined(YYBTYACC)
+extern Value_t *symbol_pval;
+extern char **symbol_destructor;
+extern char **symbol_type_tag;
+#endif
+
 extern Value_t *ritem;
 extern Value_t *rlhs;
 extern Value_t *rrhs;
@@ -319,6 +367,7 @@ extern reductions **reduction_table;
 extern unsigned *LA;
 extern Value_t *LAruleno;
 extern Value_t *lookaheads;
+extern Value_t *goto_base;
 extern Value_t *goto_map;
 extern Value_t *from_state;
 extern Value_t *to_state;
@@ -344,9 +393,6 @@ extern param *parse_param;
 
 /* global functions */
 
-extern bucket *lookup(const char *);
-extern bucket *make_bucket(const char *);
-
 #ifndef GCC_NORETURN
 #if defined(__dead2)
 #define GCC_NORETURN           __dead2
@@ -365,13 +411,23 @@ extern bucket *make_bucket(const char *);
 #endif
 #endif
 
+#ifndef GCC_PRINTFLIKE
+#define GCC_PRINTFLIKE(fmt,var) /*nothing*/
+#endif
+
 /* closure.c */
 extern void closure(Value_t * nucleus, int n);
 extern void finalize_closure(void);
 extern void set_first_derives(void);
 
 /* error.c */
+extern void arg_number_disagree_warning(int a_lineno, char *a_name);
+extern void arg_type_disagree_warning(int a_lineno, int i, char *a_name);
+extern void at_error(int a_lineno, char *a_line, char *a_cptr) GCC_NORETURN;
+extern void at_warning(int a_lineno, int i);
+extern void bad_formals(void) GCC_NORETURN;
 extern void default_action_warning(void);
+extern void destructor_redeclared_warning(int a_lineno, char *a_line, char *a_cptr);
 extern void dollar_error(int a_lineno, char *a_line, char *a_cptr) GCC_NORETURN;
 extern void dollar_warning(int a_lineno, int i);
 extern void fatal(const char *msg) GCC_NORETURN;
@@ -387,6 +443,7 @@ extern void reprec_warning(char *s);
 extern void restarted_warning(void);
 extern void retyped_warning(char *s);
 extern void revalued_warning(char *s);
+extern void start_requires_args(char *a_name);
 extern void syntax_error(int st_lineno, char *st_line, char *st_cptr) GCC_NORETURN;
 extern void terminal_lhs(int s_lineno) GCC_NORETURN;
 extern void terminal_start(char *s) GCC_NORETURN;
@@ -394,24 +451,25 @@ extern void tokenized_start(char *s) GCC_NORETURN;
 extern void undefined_goal(char *s) GCC_NORETURN;
 extern void undefined_symbol_warning(char *s);
 extern void unexpected_EOF(void) GCC_NORETURN;
+extern void unknown_arg_warning(int d_lineno, const char *dlr_opt, const char *d_arg, const char *d_line, const char *d_cptr);
 extern void unknown_rhs(int i) GCC_NORETURN;
+extern void unsupported_flag_warning(const char *flag, const char *details);
 extern void unterminated_action(int a_lineno, char *a_line, char *a_cptr) GCC_NORETURN;
 extern void unterminated_comment(int c_lineno, char *c_line, char *c_cptr) GCC_NORETURN;
 extern void unterminated_string(int s_lineno, char *s_line, char *s_cptr) GCC_NORETURN;
 extern void unterminated_text(int t_lineno, char *t_line, char *t_cptr) GCC_NORETURN;
 extern void unterminated_union(int u_lineno, char *u_line, char *u_cptr) GCC_NORETURN;
+extern void untyped_arg_warning(int a_lineno, const char *dlr_opt, const char *a_name);
 extern void untyped_lhs(void) GCC_NORETURN;
 extern void untyped_rhs(int i, char *s) GCC_NORETURN;
 extern void used_reserved(char *s) GCC_NORETURN;
+extern void unterminated_arglist(int a_lineno, char *a_line, char *a_cptr) GCC_NORETURN;
+extern void wrong_number_args_warning(const char *which, const char *a_name);
+extern void wrong_type_for_arg_warning(int i, char *a_name);
 
 /* graph.c */
 extern void graph(void);
 
-/* lalr.c */
-extern void create_symbol_table(void);
-extern void free_symbol_table(void);
-extern void free_symbols(void);
-
 /* lalr.c */
 extern void lalr(void);
 
@@ -430,25 +488,59 @@ extern void done(int k) GCC_NORETURN;
 extern void free_parser(void);
 extern void make_parser(void);
 
+/* mstring.c */
+struct mstring
+{
+    char *base, *ptr, *end;
+};
+
+extern void msprintf(struct mstring *, const char *, ...) GCC_PRINTFLIKE(2,3);
+extern int mputchar(struct mstring *, int);
+extern struct mstring *msnew(void);
+extern char *msdone(struct mstring *);
+extern int strnscmp(const char *, const char *);
+extern unsigned int strnshash(const char *);
+
+#define mputc(m, ch)   (((m)->ptr == (m)->end) \
+                        ? mputchar(m,ch) \
+                        : (*(m)->ptr++ = (char) (ch)))
+
 /* output.c */
 extern void output(void);
 
 /* reader.c */
 extern void reader(void);
 
-/* skeleton.c */
+/* skeleton.c (generated by skel2c) */
 extern void write_section(FILE * fp, const char *const section[]);
 
+/* symtab.c */
+extern bucket *make_bucket(const char *);
+extern bucket *lookup(const char *);
+extern void create_symbol_table(void);
+extern void free_symbol_table(void);
+extern void free_symbols(void);
+
 /* verbose.c */
 extern void verbose(void);
 
 /* warshall.c */
 extern void reflexive_transitive_closure(unsigned *R, int n);
 
+#ifdef DEBUG
+    /* closure.c */
+extern void print_closure(int n);
+extern void print_EFF(void);
+extern void print_first_derives(void);
+    /* lr0.c */
+extern void print_derives(void);
+#endif
+
 #ifdef NO_LEAKS
 extern void lr0_leaks(void);
 extern void lalr_leaks(void);
 extern void mkpar_leaks(void);
 extern void output_leaks(void);
+extern void mstring_leaks(void);
 extern void reader_leaks(void);
 #endif
index 3bab31b..a042aec 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: error.c,v 1.9 2011/09/05 23:27:43 tom Exp $ */
+/* $Id: error.c,v 1.11 2014/04/07 22:22:49 tom Exp $ */
 
 /* routines for printing error messages  */
 
@@ -42,9 +42,9 @@ unexpected_EOF(void)
 }
 
 static void
-print_pos(char *st_line, char *st_cptr)
+print_pos(const char *st_line, const char *st_cptr)
 {
-    char *s;
+    const char *s;
 
     if (st_line == 0)
        return;
@@ -286,3 +286,117 @@ undefined_symbol_warning(char *s)
 {
     fprintf(stderr, "%s: w - the symbol %s is undefined\n", myname, s);
 }
+
+#if ! defined(YYBTYACC)
+void
+unsupported_flag_warning(const char *flag, const char *details)
+{
+    fprintf(stderr, "%s: w - %s flag unsupported, %s\n",
+           myname, flag, details);
+}
+#endif
+
+#if defined(YYBTYACC)
+void
+at_warning(int a_lineno, int i)
+{
+    fprintf(stderr, "%s: w - line %d of \"%s\", @%d references beyond the \
+end of the current rule\n", myname, a_lineno, input_file_name, i);
+}
+
+void
+at_error(int a_lineno, char *a_line, char *a_cptr)
+{
+    fprintf(stderr,
+           "%s: e - line %d of \"%s\", illegal @$ or @N reference\n",
+           myname, a_lineno, input_file_name);
+    print_pos(a_line, a_cptr);
+    done(1);
+}
+
+void
+unterminated_arglist(int a_lineno, char *a_line, char *a_cptr)
+{
+    fprintf(stderr,
+           "%s: e - line %d of \"%s\", unterminated argument list\n",
+           myname, a_lineno, input_file_name);
+    print_pos(a_line, a_cptr);
+    done(1);
+}
+
+void
+arg_number_disagree_warning(int a_lineno, char *a_name)
+{
+    fprintf(stderr, "%s: w - line %d of \"%s\", number of arguments of %s "
+           "doesn't agree with previous declaration\n",
+           myname, a_lineno, input_file_name, a_name);
+}
+
+void
+bad_formals(void)
+{
+    fprintf(stderr, "%s: e - line %d of \"%s\", bad formal argument list\n",
+           myname, lineno, input_file_name);
+    print_pos(line, cptr);
+    done(1);
+}
+
+void
+arg_type_disagree_warning(int a_lineno, int i, char *a_name)
+{
+    fprintf(stderr, "%s: w - line %d of \"%s\", type of argument %d "
+           "to %s doesn't agree with previous declaration\n",
+           myname, a_lineno, input_file_name, i, a_name);
+}
+
+void
+unknown_arg_warning(int d_lineno, const char *dlr_opt, const char *d_arg, const char
+                   *d_line, const char *d_cptr)
+{
+    fprintf(stderr, "%s: w - line %d of \"%s\", unknown argument %s%s\n",
+           myname, d_lineno, input_file_name, dlr_opt, d_arg);
+    print_pos(d_line, d_cptr);
+}
+
+void
+untyped_arg_warning(int a_lineno, const char *dlr_opt, const char *a_name)
+{
+    fprintf(stderr, "%s: w - line %d of \"%s\", untyped argument %s%s\n",
+           myname, a_lineno, input_file_name, dlr_opt, a_name);
+}
+
+void
+wrong_number_args_warning(const char *which, const char *a_name)
+{
+    fprintf(stderr,
+           "%s: w - line %d of \"%s\", wrong number of %sarguments for %s\n",
+           myname, lineno, input_file_name, which, a_name);
+    print_pos(line, cptr);
+}
+
+void
+wrong_type_for_arg_warning(int i, char *a_name)
+{
+    fprintf(stderr,
+           "%s: w - line %d of \"%s\", wrong type for default argument %d to %s\n",
+           myname, lineno, input_file_name, i, a_name);
+    print_pos(line, cptr);
+}
+
+void
+start_requires_args(char *a_name)
+{
+    fprintf(stderr,
+           "%s: w - line %d of \"%s\", start symbol %s requires arguments\n",
+           myname, 0, input_file_name, a_name);
+
+}
+
+void
+destructor_redeclared_warning(int a_lineno, char *a_line, char *a_cptr)
+{
+    fprintf(stderr, "%s: w - line %d of \"%s\", destructor redeclared\n",
+           myname, a_lineno, input_file_name);
+    print_pos(a_line, a_cptr);
+}
+#endif
index 2e31231..6070fa2 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: graph.c,v 1.7 2009/10/27 09:25:20 tom Exp $ */
+/* $Id: graph.c,v 1.8 2014/02/19 00:46:57 Tom.Shields Exp $ */
 
 #include "defs.h"
 
@@ -51,10 +51,10 @@ graph(void)
 static void
 graph_state(int stateno)
 {
-    short *isp;
+    Value_t *isp;
     int rule;
-    short *sp;
-    short *sp1;
+    Value_t *sp;
+    Value_t *sp1;
 
     larno = (unsigned)lookaheads[stateno];
     fprintf(graph_file, "\n\tq%d [label=\"%d:\\l", stateno, stateno);
index eb5e309..bf7e6a8 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: lalr.c,v 1.9 2009/10/27 09:49:27 tom Exp $ */
+/* $Id: lalr.c,v 1.11 2014/09/18 00:26:39 tom Exp $ */
 
 #include "defs.h"
 
@@ -34,6 +34,7 @@ Value_t *accessing_symbol;
 core **state_table;
 shifts **shift_table;
 reductions **reduction_table;
+Value_t *goto_base;
 Value_t *goto_map;
 Value_t *from_state;
 Value_t *to_state;
@@ -179,12 +180,16 @@ set_goto_map(void)
     int i;
     int symbol;
     int k;
+    Value_t *temp_base;
     Value_t *temp_map;
     Value_t state2;
     Value_t state1;
 
-    goto_map = NEW2(nvars + 1, Value_t) - ntokens;
-    temp_map = NEW2(nvars + 1, Value_t) - ntokens;
+    goto_base = NEW2(nvars + 1, Value_t);
+    temp_base = NEW2(nvars + 1, Value_t);
+
+    goto_map = goto_base - ntokens;
+    temp_map = temp_base - ntokens;
 
     ngotos = 0;
     for (sp = first_shift; sp; sp = sp->next)
@@ -196,7 +201,7 @@ set_goto_map(void)
            if (ISTOKEN(symbol))
                break;
 
-           if (ngotos == MAXSHORT)
+           if (ngotos == MAXYYINT)
                fatal("too many gotos");
 
            ngotos++;
@@ -237,7 +242,7 @@ set_goto_map(void)
        }
     }
 
-    FREE(temp_map + ntokens);
+    FREE(temp_base);
 }
 
 /*  Map_goto maps a state/symbol pair into its numeric representation. */
index 641f9f8..162d106 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: lr0.c,v 1.13 2012/05/26 00:40:47 tom Exp $ */
+/* $Id: lr0.c,v 1.16 2014/04/07 21:53:50 tom Exp $ */
 
 #include "defs.h"
 
@@ -28,7 +28,7 @@ static shifts *last_shift;
 static reductions *last_reduction;
 
 static int nshifts;
-static short *shift_symbol;
+static Value_t *shift_symbol;
 
 static Value_t *redset;
 static Value_t *shiftset;
@@ -40,16 +40,16 @@ static Value_t *kernel_items;
 static void
 allocate_itemsets(void)
 {
-    short *itemp;
-    short *item_end;
+    Value_t *itemp;
+    Value_t *item_end;
     int symbol;
     int i;
     int count;
     int max;
-    short *symbol_count;
+    Value_t *symbol_count;
 
     count = 0;
-    symbol_count = NEW2(nsyms, short);
+    symbol_count = NEW2(nsyms, Value_t);
 
     item_end = ritem + nitems;
     for (itemp = ritem; itemp < item_end; itemp++)
@@ -62,8 +62,8 @@ allocate_itemsets(void)
        }
     }
 
-    kernel_base = NEW2(nsyms, short *);
-    kernel_items = NEW2(count, short);
+    kernel_base = NEW2(nsyms, Value_t *);
+    kernel_items = NEW2(count, Value_t);
 
     count = 0;
     max = 0;
@@ -76,15 +76,15 @@ allocate_itemsets(void)
     }
 
     shift_symbol = symbol_count;
-    kernel_end = NEW2(nsyms, short *);
+    kernel_end = NEW2(nsyms, Value_t *);
 }
 
 static void
 allocate_storage(void)
 {
     allocate_itemsets();
-    shiftset = NEW2(nsyms, short);
-    redset = NEW2(nrules + 1, short);
+    shiftset = NEW2(nsyms, Value_t);
+    redset = NEW2(nrules + 1, Value_t);
     state_set = NEW2(nitems, core *);
 }
 
@@ -133,7 +133,7 @@ static void
 generate_states(void)
 {
     allocate_storage();
-    itemset = NEW2(nitems, short);
+    itemset = NEW2(nitems, Value_t);
     ruleset = NEW2(WORDSIZE(nrules), unsigned);
     set_first_derives();
     initialize_states();
@@ -158,9 +158,9 @@ static Value_t
 get_state(int symbol)
 {
     int key;
-    short *isp1;
-    short *isp2;
-    short *iend;
+    Value_t *isp1;
+    Value_t *isp2;
+    Value_t *iend;
     core *sp;
     int found;
     int n;
@@ -220,14 +220,14 @@ static void
 initialize_states(void)
 {
     unsigned i;
-    short *start_derives;
+    Value_t *start_derives;
     core *p;
 
     start_derives = derives[start_symbol];
     for (i = 0; start_derives[i] >= 0; ++i)
        continue;
 
-    p = (core *)MALLOC(sizeof(core) + i * sizeof(short));
+    p = (core *)MALLOC(sizeof(core) + i * sizeof(Value_t));
     NO_SPACE(p);
 
     p->next = 0;
@@ -248,8 +248,8 @@ new_itemsets(void)
 {
     Value_t i;
     int shiftcount;
-    short *isp;
-    short *ksp;
+    Value_t *isp;
+    Value_t *ksp;
     Value_t symbol;
 
     for (i = 0; i < nsyms; i++)
@@ -283,22 +283,22 @@ new_state(int symbol)
 {
     unsigned n;
     core *p;
-    short *isp1;
-    short *isp2;
-    short *iend;
+    Value_t *isp1;
+    Value_t *isp2;
+    Value_t *iend;
 
 #ifdef TRACE
     fprintf(stderr, "Entering new_state(%d)\n", symbol);
 #endif
 
-    if (nstates >= MAXSHORT)
+    if (nstates >= MAXYYINT)
        fatal("too many states");
 
     isp1 = kernel_base[symbol];
     iend = kernel_end[symbol];
     n = (unsigned)(iend - isp1);
 
-    p = (core *)allocate((sizeof(core) + (n - 1) * sizeof(short)));
+    p = (core *)allocate((sizeof(core) + (n - 1) * sizeof(Value_t)));
     p->accessing_symbol = (Value_t) symbol;
     p->number = (Value_t) nstates;
     p->nitems = (Value_t) n;
@@ -316,7 +316,7 @@ new_state(int symbol)
 }
 
 /* show_cores is used for debugging */
-
+#ifdef DEBUG
 void
 show_cores(void)
 {
@@ -393,17 +393,18 @@ show_shifts(void)
            printf("\t%d\n", p->shift[i]);
     }
 }
+#endif
 
 static void
 save_shifts(void)
 {
     shifts *p;
-    short *sp1;
-    short *sp2;
-    short *send;
+    Value_t *sp1;
+    Value_t *sp2;
+    Value_t *send;
 
     p = (shifts *)allocate((sizeof(shifts) +
-                             (unsigned)(nshifts - 1) * sizeof(short)));
+                             (unsigned)(nshifts - 1) * sizeof(Value_t)));
 
     p->number = this_state->number;
     p->nshifts = (Value_t) nshifts;
@@ -430,13 +431,13 @@ save_shifts(void)
 static void
 save_reductions(void)
 {
-    short *isp;
-    short *rp1;
-    short *rp2;
+    Value_t *isp;
+    Value_t *rp1;
+    Value_t *rp2;
     int item;
     Value_t count;
     reductions *p;
-    short *rend;
+    Value_t *rend;
 
     count = 0;
     for (isp = itemset; isp < itemsetend; isp++)
@@ -452,7 +453,7 @@ save_reductions(void)
     {
        p = (reductions *)allocate((sizeof(reductions) +
                                      (unsigned)(count - 1) *
-                                   sizeof(short)));
+                                   sizeof(Value_t)));
 
        p->number = this_state->number;
        p->nreds = count;
@@ -482,10 +483,10 @@ set_derives(void)
 {
     Value_t i, k;
     int lhs;
-    short *rules;
+    Value_t *rules;
 
-    derives = NEW2(nsyms, short *);
-    rules = NEW2(nvars + nrules, short);
+    derives = NEW2(nsyms, Value_t *);
+    rules = NEW2(nvars + nrules, Value_t);
 
     k = 0;
     for (lhs = start_symbol; lhs < nsyms; lhs++)
@@ -513,7 +514,7 @@ void
 print_derives(void)
 {
     int i;
-    short *sp;
+    Value_t *sp;
 
     printf("\nDERIVES\n\n");
 
@@ -592,8 +593,11 @@ lr0(void)
 void
 lr0_leaks(void)
 {
-    DO_FREE(derives[start_symbol]);
-    DO_FREE(derives);
+    if (derives)
+    {
+       DO_FREE(derives[start_symbol]);
+       DO_FREE(derives);
+    }
     DO_FREE(nullable);
 }
 #endif
index 816e154..b43cd13 100644 (file)
@@ -1,7 +1,11 @@
-/* $Id: main.c,v 1.40 2012/09/29 13:11:00 Adrian.Bunk Exp $ */
+/* $Id: main.c,v 1.54 2014/10/06 22:40:07 tom Exp $ */
 
 #include <signal.h>
+#ifndef _WIN32
 #include <unistd.h>            /* for _exit() */
+#else
+#include <stdlib.h>            /* for _exit() */
+#endif
 
 #include "defs.h"
 
@@ -73,20 +77,30 @@ FILE *union_file;   /*  a temp file, used to save the union             */
 FILE *verbose_file;    /*  y.output                                        */
 FILE *graph_file;      /*  y.dot                                           */
 
-int nitems;
-int nrules;
-int nsyms;
-int ntokens;
-int nvars;
+Value_t nitems;
+Value_t nrules;
+Value_t nsyms;
+Value_t ntokens;
+Value_t nvars;
 
 Value_t start_symbol;
 char **symbol_name;
 char **symbol_pname;
 Value_t *symbol_value;
-short *symbol_prec;
+Value_t *symbol_prec;
 char *symbol_assoc;
 
 int pure_parser;
+int token_table;
+
+#if defined(YYBTYACC)
+Value_t *symbol_pval;
+char **symbol_destructor;
+char **symbol_type_tag;
+int locations = 0;     /* default to no position processing */
+int backtrack = 0;     /* default is no backtracking */
+#endif
+
 int exit_code;
 
 Value_t *ritem;
@@ -115,6 +129,10 @@ done(int k)
 {
     DO_CLOSE(input_file);
     DO_CLOSE(output_file);
+    if (iflag)
+       DO_CLOSE(externs_file);
+    if (rflag)
+       DO_CLOSE(code_file);
 
     DO_CLOSE(action_file);
     DO_CLOSE(defines_file);
@@ -148,13 +166,11 @@ done(int k)
     lr0_leaks();
     lalr_leaks();
     mkpar_leaks();
+    mstring_leaks();
     output_leaks();
     reader_leaks();
 #endif
 
-    if (rflag)
-       DO_CLOSE(code_file);
-
     exit(k);
 }
 
@@ -190,11 +206,13 @@ usage(void)
        ""
        ,"Options:"
        ,"  -b file_prefix        set filename prefix (default \"y.\")"
-       ,"  -d                    write definitions (y.tab.h)"
+       ,"  -B                    create a backtracking parser"
+       ,"  -d                    write definitions (" DEFINES_SUFFIX ")"
        ,"  -i                    write interface (y.tab.i)"
        ,"  -g                    write a graphical description"
        ,"  -l                    suppress #line directives"
-       ,"  -o output_file        (default \"y.tab.c\")"
+       ,"  -L                    enable position processing, e.g., \"%locations\""
+       ,"  -o output_file        (default \"" OUTPUT_SUFFIX "\")"
        ,"  -p symbol_prefix      set symbol prefix (default \"yy\")"
        ,"  -P                    create a reentrant parser, e.g., \"%pure-parser\""
        ,"  -r                    produce separate code and table files (y.code.c)"
@@ -218,6 +236,14 @@ setflag(int ch)
 {
     switch (ch)
     {
+    case 'B':
+#if defined(YYBTYACC)
+       backtrack = 1;
+#else
+       unsupported_flag_warning("-B", "reconfigure with --enable-btyacc");
+#endif
+       break;
+
     case 'd':
        dflag = 1;
        break;
@@ -234,6 +260,14 @@ setflag(int ch)
        lflag = 1;
        break;
 
+    case 'L':
+#if defined(YYBTYACC)
+       locations = 1;
+#else
+       unsupported_flag_warning("-B", "reconfigure with --enable-btyacc");
+#endif
+       break;
+
     case 'P':
        pure_parser = 1;
        break;
@@ -363,10 +397,18 @@ allocate(size_t n)
 }
 
 #define CREATE_FILE_NAME(dest, suffix) \
-       dest = TMALLOC(char, len + strlen(suffix) + 1); \
-       NO_SPACE(dest); \
-       strcpy(dest, file_prefix); \
-       strcpy(dest + len, suffix)
+       dest = alloc_file_name(len, suffix)
+
+static char *
+alloc_file_name(size_t len, const char *suffix)
+{
+    char *result = TMALLOC(char, len + strlen(suffix) + 1);
+    if (result == 0)
+       no_space();
+    strcpy(result, file_prefix);
+    strcpy(result + len, suffix);
+    return result;
+}
 
 static void
 create_file_names(void)
@@ -383,7 +425,7 @@ create_file_names(void)
     /* compute the file_prefix from the user provided output_file_name */
     if (output_file_name != 0)
     {
-       if (!(prefix = strstr(output_file_name, ".tab.c"))
+       if (!(prefix = strstr(output_file_name, OUTPUT_SUFFIX))
            && (prefix = strstr(output_file_name, ".c")))
        {
            defines_suffix = ".h";
@@ -449,8 +491,8 @@ close_tmpfiles(void)
     {
        MY_TMPFILES *next = my_tmpfiles->next;
 
-       chmod(my_tmpfiles->name, 0644);
-       unlink(my_tmpfiles->name);
+       (void)chmod(my_tmpfiles->name, 0644);
+       (void)unlink(my_tmpfiles->name);
 
        free(my_tmpfiles->name);
        free(my_tmpfiles);
@@ -532,6 +574,8 @@ open_tmpfile(const char *label)
     result = 0;
     if (name != 0)
     {
+       mode_t save_umask = umask(0177);
+
        if ((mark = strrchr(label, '_')) == 0)
            mark = label + strlen(label);
 
@@ -559,6 +603,7 @@ open_tmpfile(const char *label)
                my_tmpfiles = item;
            }
        }
+       (void)umask(save_umask);
     }
 #else
     result = tmpfile();
index b2e36ab..653c202 100644 (file)
@@ -1,7 +1,18 @@
-/* $Id: mkpar.c,v 1.12 2012/05/26 00:42:18 tom Exp $ */
+/* $Id: mkpar.c,v 1.14 2014/04/01 23:05:37 tom Exp $ */
 
 #include "defs.h"
 
+#define NotSuppressed(p)       ((p)->suppressed == 0)
+
+#if defined(YYBTYACC)
+#define MaySuppress(p)         ((backtrack ? ((p)->suppressed <= 1) : (p)->suppressed == 0))
+    /* suppress the preferred action => enable backtracking */
+#define StartBacktrack(p)      if (backtrack && (p) != NULL && NotSuppressed(p)) (p)->suppressed = 1
+#else
+#define MaySuppress(p)         ((p)->suppressed == 0)
+#define StartBacktrack(p)      /*nothing */
+#endif
+
 static action *add_reduce(action *actions, int ruleno, int symbol);
 static action *add_reductions(int stateno, action *actions);
 static action *get_shifts(int stateno);
@@ -190,7 +201,7 @@ unused_rules(void)
     {
        for (p = parser[i]; p; p = p->next)
        {
-           if (p->action_code == REDUCE && p->suppressed == 0)
+           if ((p->action_code == REDUCE) && MaySuppress(p))
                rules_used[p->number] = 1;
        }
     }
@@ -225,17 +236,23 @@ remove_conflicts(void)
        SRcount = 0;
        RRcount = 0;
        symbol = -1;
+#if defined(YYBTYACC)
+       pref = NULL;
+#endif
        for (p = parser[i]; p; p = p->next)
        {
            if (p->symbol != symbol)
            {
+               /* the first parse action for each symbol is the preferred action */
                pref = p;
                symbol = p->symbol;
            }
+           /* following conditions handle multiple, i.e., conflicting, parse actions */
            else if (i == final_state && symbol == 0)
            {
                SRcount++;
                p->suppressed = 1;
+               StartBacktrack(pref);
            }
            else if (pref != 0 && pref->action_code == SHIFT)
            {
@@ -269,12 +286,14 @@ remove_conflicts(void)
                {
                    SRcount++;
                    p->suppressed = 1;
+                   StartBacktrack(pref);
                }
            }
            else
            {
                RRcount++;
                p->suppressed = 1;
+               StartBacktrack(pref);
            }
        }
        SRtotal += SRcount;
@@ -329,9 +348,9 @@ sole_reduction(int stateno)
     ruleno = 0;
     for (p = parser[stateno]; p; p = p->next)
     {
-       if (p->action_code == SHIFT && p->suppressed == 0)
+       if (p->action_code == SHIFT && MaySuppress(p))
            return (0);
-       else if (p->action_code == REDUCE && p->suppressed == 0)
+       else if ((p->action_code == REDUCE) && MaySuppress(p))
        {
            if (ruleno > 0 && p->number != ruleno)
                return (0);
index 331726d..ecd9494 100644 (file)
@@ -1,14 +1,24 @@
-/* $Id: output.c,v 1.44 2012/05/26 01:13:02 tom Exp $ */
+/* $Id: output.c,v 1.74 2014/10/05 23:21:09 tom Exp $ */
 
 #include "defs.h"
 
 #define StaticOrR      (rflag ? "" : "static ")
 #define CountLine(fp)   (!rflag || ((fp) == code_file))
 
+#if defined(YYBTYACC)
+#define PER_STATE 3
+#else
+#define PER_STATE 2
+#endif
+
 static int nvectors;
 static int nentries;
 static Value_t **froms;
 static Value_t **tos;
+#if defined(YYBTYACC)
+static Value_t *conflicts = NULL;
+static Value_t nconflicts = 0;
+#endif
 static Value_t *tally;
 static Value_t *width;
 static Value_t *state_count;
@@ -19,7 +29,7 @@ static int maxtable;
 static Value_t *table;
 static Value_t *check;
 static int lowzero;
-static int high;
+static long high;
 
 static void
 putc_code(FILE * fp, int c)
@@ -43,13 +53,50 @@ puts_code(FILE * fp, const char *s)
     fputs(s, fp);
 }
 
+static void
+puts_param_types(FILE * fp, param * list, int more)
+{
+    param *p;
+
+    if (list != 0)
+    {
+       for (p = list; p; p = p->next)
+       {
+           size_t len_type = strlen(p->type);
+           fprintf(fp, "%s%s%s%s%s", p->type,
+                   (((len_type != 0) && (p->type[len_type - 1] == '*'))
+                    ? ""
+                    : " "),
+                   p->name, p->type2,
+                   ((more || p->next) ? ", " : ""));
+       }
+    }
+    else
+    {
+       if (!more)
+           fprintf(fp, "void");
+    }
+}
+
+static void
+puts_param_names(FILE * fp, param * list, int more)
+{
+    param *p;
+
+    for (p = list; p; p = p->next)
+    {
+       fprintf(fp, "%s%s", p->name,
+               ((more || p->next) ? ", " : ""));
+    }
+}
+
 static void
 write_code_lineno(FILE * fp)
 {
     if (!lflag && (fp == code_file))
     {
        ++outline;
-       fprintf(fp, line_format, outline, code_file_name);
+       fprintf(fp, line_format, outline + 1, code_file_name);
     }
 }
 
@@ -105,6 +152,9 @@ output_prefix(FILE * fp)
        define_prefixed(fp, "yylhs");
        define_prefixed(fp, "yylen");
        define_prefixed(fp, "yydefred");
+#if defined(YYBTYACC)
+       define_prefixed(fp, "yystos");
+#endif
        define_prefixed(fp, "yydgoto");
        define_prefixed(fp, "yysindex");
        define_prefixed(fp, "yyrindex");
@@ -113,6 +163,22 @@ output_prefix(FILE * fp)
        define_prefixed(fp, "yycheck");
        define_prefixed(fp, "yyname");
        define_prefixed(fp, "yyrule");
+#if defined(YYBTYACC)
+       if (locations)
+       {
+           define_prefixed(fp, "yyloc");
+           define_prefixed(fp, "yylloc");
+       }
+       putc_code(fp, '\n');
+       putl_code(fp, "#if YYBTYACC\n");
+
+       define_prefixed(fp, "yycindex");
+       define_prefixed(fp, "yyctable");
+
+       putc_code(fp, '\n');
+       putl_code(fp, "#endif /* YYBTYACC */\n");
+       putc_code(fp, '\n');
+#endif
     }
     if (CountLine(fp))
        ++outline;
@@ -148,7 +214,7 @@ start_int_table(const char *name, int value)
     if (need < 6)
        need = 6;
     fprintf(output_file,
-           "%sconst short %s%s[] = {%*d,",
+           "%sconst YYINT %s%s[] = {%*d,",
            StaticOrR, symbol_prefix, name, need, value);
 }
 
@@ -156,8 +222,8 @@ static void
 start_str_table(const char *name)
 {
     fprintf(output_file,
-           "%sconst char *%s%s[] = {",
-           StaticOrR, "yy", name);
+           "%sconst char *const %s%s[] = {",
+           StaticOrR, symbol_prefix, name);
     output_newline();
 }
 
@@ -168,12 +234,23 @@ end_table(void)
     output_line("};");
 }
 
+static void
+output_YYINT_typedef(FILE * fp)
+{
+    /* generate the type used to index the various parser tables */
+    if (CountLine(fp))
+       ++outline;
+    fprintf(fp, "typedef %s YYINT;\n", CONCAT1("", YYINT));
+}
+
 static void
 output_rule_data(void)
 {
     int i;
     int j;
 
+    output_YYINT_typedef(output_file);
+
     start_int_table("lhs", symbol_value[start_symbol]);
 
     j = 10;
@@ -233,27 +310,123 @@ output_yydefred(void)
     end_table();
 }
 
+#if defined(YYBTYACC)
+static void
+output_accessing_symbols(void)
+{
+    int i, j;
+    int *translate;
+
+    if (nstates != 0)
+    {
+       translate = TMALLOC(int, nstates);
+       NO_SPACE(translate);
+
+       for (i = 0; i < nstates; ++i)
+       {
+           int gsymb = accessing_symbol[i];
+
+           translate[i] = symbol_pval[gsymb];
+       }
+
+       /* yystos[] may be unused, depending on compile-time defines */
+       start_int_table("stos", translate[0]);
+
+       j = 10;
+       for (i = 1; i < nstates; ++i)
+       {
+           if (j < 10)
+               ++j;
+           else
+           {
+               output_newline();
+               j = 1;
+           }
+
+           output_int(translate[i]);
+       }
+
+       end_table();
+       FREE(translate);
+    }
+}
+
+static Value_t
+find_conflict_base(int cbase)
+{
+    int i, j;
+
+    for (i = 0; i < cbase; i++)
+    {
+       for (j = 0; j + cbase < nconflicts; j++)
+       {
+           if (conflicts[i + j] != conflicts[cbase + j])
+               break;
+       }
+       if (j + cbase >= nconflicts)
+           break;
+    }
+    return (Value_t) i;
+}
+#endif
+
 static void
 token_actions(void)
 {
     int i, j;
     Value_t shiftcount, reducecount;
+#if defined(YYBTYACC)
+    Value_t conflictcount = 0;
+    Value_t csym = -1;
+    Value_t cbase = 0;
+#endif
     int max, min;
     Value_t *actionrow, *r, *s;
     action *p;
 
-    actionrow = NEW2(2 * ntokens, Value_t);
+    actionrow = NEW2(PER_STATE * ntokens, Value_t);
     for (i = 0; i < nstates; ++i)
     {
        if (parser[i])
        {
-           for (j = 0; j < 2 * ntokens; ++j)
+           for (j = 0; j < PER_STATE * ntokens; ++j)
                actionrow[j] = 0;
 
            shiftcount = 0;
            reducecount = 0;
+#if defined(YYBTYACC)
+           if (backtrack)
+           {
+               conflictcount = 0;
+               csym = -1;
+               cbase = nconflicts;
+           }
+#endif
            for (p = parser[i]; p; p = p->next)
            {
+#if defined(YYBTYACC)
+               if (backtrack)
+               {
+                   if (csym != -1 && csym != p->symbol)
+                   {
+                       conflictcount++;
+                       conflicts[nconflicts++] = -1;
+                       j = find_conflict_base(cbase);
+                       actionrow[csym + 2 * ntokens] = (Value_t) (j + 1);
+                       if (j == cbase)
+                       {
+                           cbase = nconflicts;
+                       }
+                       else
+                       {
+                           if (conflicts[cbase] == -1)
+                               cbase++;
+                           nconflicts = cbase;
+                       }
+                       csym = -1;
+                   }
+               }
+#endif
                if (p->suppressed == 0)
                {
                    if (p->action_code == SHIFT)
@@ -267,17 +440,65 @@ token_actions(void)
                        actionrow[p->symbol + ntokens] = p->number;
                    }
                }
+#if defined(YYBTYACC)
+               else if (backtrack && p->suppressed == 1)
+               {
+                   csym = p->symbol;
+                   if (p->action_code == SHIFT)
+                   {
+                       conflicts[nconflicts++] = p->number;
+                   }
+                   else if (p->action_code == REDUCE && p->number != defred[i])
+                   {
+                       if (cbase == nconflicts)
+                       {
+                           if (cbase)
+                               cbase--;
+                           else
+                               conflicts[nconflicts++] = -1;
+                       }
+                       conflicts[nconflicts++] = (Value_t) (p->number - 2);
+                   }
+               }
+#endif
+           }
+#if defined(YYBTYACC)
+           if (backtrack && csym != -1)
+           {
+               conflictcount++;
+               conflicts[nconflicts++] = -1;
+               j = find_conflict_base(cbase);
+               actionrow[csym + 2 * ntokens] = (Value_t) (j + 1);
+               if (j == cbase)
+               {
+                   cbase = nconflicts;
+               }
+               else
+               {
+                   if (conflicts[cbase] == -1)
+                       cbase++;
+                   nconflicts = cbase;
+               }
            }
+#endif
 
            tally[i] = shiftcount;
            tally[nstates + i] = reducecount;
+#if defined(YYBTYACC)
+           if (backtrack)
+               tally[2 * nstates + i] = conflictcount;
+#endif
            width[i] = 0;
            width[nstates + i] = 0;
+#if defined(YYBTYACC)
+           if (backtrack)
+               width[2 * nstates + i] = 0;
+#endif
            if (shiftcount > 0)
            {
                froms[i] = r = NEW2(shiftcount, Value_t);
                tos[i] = s = NEW2(shiftcount, Value_t);
-               min = MAXSHORT;
+               min = MAXYYINT;
                max = 0;
                for (j = 0; j < ntokens; ++j)
                {
@@ -297,7 +518,7 @@ token_actions(void)
            {
                froms[nstates + i] = r = NEW2(reducecount, Value_t);
                tos[nstates + i] = s = NEW2(reducecount, Value_t);
-               min = MAXSHORT;
+               min = MAXYYINT;
                max = 0;
                for (j = 0; j < ntokens; ++j)
                {
@@ -313,6 +534,28 @@ token_actions(void)
                }
                width[nstates + i] = (Value_t) (max - min + 1);
            }
+#if defined(YYBTYACC)
+           if (backtrack && conflictcount > 0)
+           {
+               froms[2 * nstates + i] = r = NEW2(conflictcount, Value_t);
+               tos[2 * nstates + i] = s = NEW2(conflictcount, Value_t);
+               min = MAXYYINT;
+               max = 0;
+               for (j = 0; j < ntokens; ++j)
+               {
+                   if (actionrow[2 * ntokens + j])
+                   {
+                       if (min > symbol_value[j])
+                           min = symbol_value[j];
+                       if (max < symbol_value[j])
+                           max = symbol_value[j];
+                       *r++ = symbol_value[j];
+                       *s++ = (Value_t) (actionrow[2 * ntokens + j] - 1);
+                   }
+               }
+               width[2 * nstates + i] = (Value_t) (max - min + 1);
+           }
+#endif
        }
     }
     FREE(actionrow);
@@ -377,7 +620,7 @@ save_column(int symbol, int default_state)
     if (count == 0)
        return;
 
-    symno = symbol_value[symbol] + 2 * nstates;
+    symno = symbol_value[symbol] + PER_STATE * nstates;
 
     froms[symno] = sp1 = sp = NEW2(count, Value_t);
     tos[symno] = sp2 = NEW2(count, Value_t);
@@ -476,6 +719,11 @@ sort_actions(void)
 /*  Matching_vector is poorly designed.  The test could easily be made */
 /*  faster.  Also, it depends on the vectors being in a specific       */
 /*  order.                                                             */
+#if defined(YYBTYACC)
+/*                                                                     */
+/*  Not really any point in checking for matching conflicts -- it is    */
+/*  extremely unlikely to occur, and conflicts are (hopefully) rare.    */
+#endif
 
 static int
 matching_vector(int vector)
@@ -639,9 +887,11 @@ pack_table(void)
            FREE(tos[i]);
     }
 
-    FREE(froms);
-    FREE(tos);
-    FREE(pos);
+    DO_FREE(froms);
+    DO_FREE(tos);
+    DO_FREE(tally);
+    DO_FREE(width);
+    DO_FREE(pos);
 }
 
 static void
@@ -685,10 +935,32 @@ output_base(void)
 
     end_table();
 
-    start_int_table("gindex", base[2 * nstates]);
+#if defined(YYBTYACC)
+    output_line("#if YYBTYACC");
+    start_int_table("cindex", base[2 * nstates]);
 
     j = 10;
-    for (i = 2 * nstates + 1; i < nvectors - 1; i++)
+    for (i = 2 * nstates + 1; i < 3 * nstates; i++)
+    {
+       if (j >= 10)
+       {
+           output_newline();
+           j = 1;
+       }
+       else
+           ++j;
+
+       output_int(base[i]);
+    }
+
+    end_table();
+    output_line("#endif");
+#endif
+
+    start_int_table("gindex", base[PER_STATE * nstates]);
+
+    j = 10;
+    for (i = PER_STATE * nstates + 1; i < nvectors - 1; i++)
     {
        if (j >= 10)
        {
@@ -711,8 +983,15 @@ output_table(void)
     int i;
     int j;
 
+    if (high >= MAXYYINT)
+    {
+       fprintf(stderr, "YYTABLESIZE: %ld\n", high);
+       fprintf(stderr, "Table is longer than %d elements.\n", MAXYYINT);
+       done(1);
+    }
+
     ++outline;
-    fprintf(code_file, "#define YYTABLESIZE %d\n", high);
+    fprintf(code_file, "#define YYTABLESIZE %ld\n", high);
     start_int_table("table", table[0]);
 
     j = 10;
@@ -759,16 +1038,57 @@ output_check(void)
     FREE(check);
 }
 
+#if defined(YYBTYACC)
+static void
+output_ctable(void)
+{
+    int i;
+    int j;
+    int limit = (conflicts != 0) ? nconflicts : 0;
+
+    if (limit < high)
+       limit = (int)high;
+
+    output_line("#if YYBTYACC");
+    start_int_table("ctable", conflicts ? conflicts[0] : -1);
+
+    j = 10;
+    for (i = 1; i < limit; i++)
+    {
+       if (j >= 10)
+       {
+           output_newline();
+           j = 1;
+       }
+       else
+           ++j;
+
+       output_int((conflicts != 0 && i < nconflicts) ? conflicts[i] : -1);
+    }
+
+    if (conflicts)
+       FREE(conflicts);
+
+    end_table();
+    output_line("#endif");
+}
+#endif
+
 static void
 output_actions(void)
 {
-    nvectors = 2 * nstates + nvars;
+    nvectors = PER_STATE * nstates + nvars;
 
     froms = NEW2(nvectors, Value_t *);
     tos = NEW2(nvectors, Value_t *);
     tally = NEW2(nvectors, Value_t);
     width = NEW2(nvectors, Value_t);
 
+#if defined(YYBTYACC)
+    if (backtrack && (SRtotal + RRtotal) != 0)
+       conflicts = NEW2(4 * (SRtotal + RRtotal), Value_t);
+#endif
+
     token_actions();
     FREE(lookaheads);
     FREE(LA);
@@ -776,7 +1096,7 @@ output_actions(void)
     FREE(accessing_symbol);
 
     goto_actions();
-    FREE(goto_map + ntokens);
+    FREE(goto_base);
     FREE(from_state);
     FREE(to_state);
 
@@ -785,6 +1105,9 @@ output_actions(void)
     output_base();
     output_table();
     output_check();
+#if defined(YYBTYACC)
+    output_ctable();
+#endif
 }
 
 static int
@@ -818,6 +1141,24 @@ is_C_identifier(char *name)
     return (1);
 }
 
+#if USE_HEADER_GUARDS
+static void
+start_defines_file(void)
+{
+    fprintf(defines_file, "#ifndef _%s_defines_h_\n", symbol_prefix);
+    fprintf(defines_file, "#define _%s_defines_h_\n\n", symbol_prefix);
+}
+
+static void
+end_defines_file(void)
+{
+    fprintf(defines_file, "\n#endif /* _%s_defines_h_ */\n", symbol_prefix);
+}
+#else
+#define start_defines_file()   /* nothing */
+#define end_defines_file()     /* nothing */
+#endif
+
 static void
 output_defines(FILE * fp)
 {
@@ -861,9 +1202,12 @@ output_defines(FILE * fp)
     {
        if (unionized)
        {
-           rewind(union_file);
-           while ((c = getc(union_file)) != EOF)
-               putc(c, fp);
+           if (union_file != 0)
+           {
+               rewind(union_file);
+               while ((c = getc(union_file)) != EOF)
+                   putc_code(fp, c);
+           }
            fprintf(fp, "extern YYSTYPE %slval;\n", symbol_prefix);
        }
     }
@@ -892,7 +1236,7 @@ output_stored_text(FILE * fp)
 static void
 output_debug(void)
 {
-    int i, j, k, max;
+    int i, j, k, max, maxtok;
     const char **symnam;
     const char *s;
 
@@ -911,30 +1255,69 @@ output_debug(void)
        fprintf(output_file, "#endif\n");
     }
 
-    max = 0;
-    for (i = 2; i < ntokens; ++i)
-       if (symbol_value[i] > max)
-           max = symbol_value[i];
+    maxtok = 0;
+    for (i = 0; i < ntokens; ++i)
+       if (symbol_value[i] > maxtok)
+           maxtok = symbol_value[i];
+
+    /* symbol_value[$accept] = -1         */
+    /* symbol_value[<goal>]  = 0          */
+    /* remaining non-terminals start at 1 */
+    max = maxtok;
+    for (i = ntokens; i < nsyms; ++i)
+       if (((maxtok + 1) + (symbol_value[i] + 1)) > max)
+           max = (maxtok + 1) + (symbol_value[i] + 1);
+
+    ++outline;
+    fprintf(code_file, "#define YYMAXTOKEN %d\n", maxtok);
 
     ++outline;
-    fprintf(code_file, "#define YYMAXTOKEN %d\n", max);
+    fprintf(code_file, "#define YYUNDFTOKEN %d\n", max + 1);
 
-    symnam = TMALLOC(const char *, max + 1);
+    ++outline;
+    fprintf(code_file, "#define YYTRANSLATE(a) ((a) > YYMAXTOKEN ? "
+           "YYUNDFTOKEN : (a))\n");
+
+    symnam = TMALLOC(const char *, max + 2);
     NO_SPACE(symnam);
 
-    /* Note that it is  not necessary to initialize the element         */
+    /* Note that it is not necessary to initialize the element          */
     /* symnam[max].                                                     */
+#if defined(YYBTYACC)
     for (i = 0; i < max; ++i)
        symnam[i] = 0;
+    for (i = nsyms - 1; i >= 0; --i)
+       symnam[symbol_pval[i]] = symbol_name[i];
+    symnam[max + 1] = "illegal-symbol";
+#else
+    for (i = 0; i <= max; ++i)
+       symnam[i] = 0;
     for (i = ntokens - 1; i >= 2; --i)
        symnam[symbol_value[i]] = symbol_name[i];
     symnam[0] = "end-of-file";
+    symnam[max + 1] = "illegal-symbol";
+#endif
 
-    output_line("#if YYDEBUG");
+    /*
+     * bison's yytname[] array is roughly the same as byacc's yyname[] array.
+     * The difference is that byacc does not predefine "$undefined".
+     *
+     * If the grammar declares "%token-table", define symbol "yytname" so
+     * an application such as ntpd can build.
+     */
+    if (token_table)
+    {
+       output_line("#undef yytname");
+       output_line("#define yytname yyname");
+    }
+    else
+    {
+       output_line("#if YYDEBUG");
+    }
 
     start_str_table("name");
     j = 80;
-    for (i = 0; i <= max; ++i)
+    for (i = 0; i <= max + 1; ++i)
     {
        if ((s = symnam[i]) != 0)
        {
@@ -1055,6 +1438,8 @@ output_debug(void)
     end_table();
     FREE(symnam);
 
+    if (token_table)
+       output_line("#if YYDEBUG");
     start_str_table("rule");
     for (i = 2; i < nrules; ++i)
     {
@@ -1109,13 +1494,34 @@ output_debug(void)
     output_line("#endif");
 }
 
+#if defined(YYBTYACC)
+static void
+output_backtracking_parser(FILE * fp)
+{
+    putl_code(fp, "#undef YYBTYACC\n");
+#if defined(YYBTYACC)
+    if (backtrack)
+    {
+       putl_code(fp, "#define YYBTYACC 1\n");
+       putl_code(fp,
+                 "#define YYDEBUGSTR (yytrial ? YYPREFIX \"debug(trial)\" : YYPREFIX \"debug\")\n");
+    }
+    else
+#endif
+    {
+       putl_code(fp, "#define YYBTYACC 0\n");
+       putl_code(fp, "#define YYDEBUGSTR YYPREFIX \"debug\"\n");
+    }
+}
+#endif
+
 static void
 output_pure_parser(FILE * fp)
 {
     putc_code(fp, '\n');
 
     if (fp == code_file)
-       outline += 1;
+       ++outline;
     fprintf(fp, "#define YYPURE %d\n", pure_parser);
     putc_code(fp, '\n');
 }
@@ -1126,12 +1532,35 @@ output_stype(FILE * fp)
     if (!unionized && ntags == 0)
     {
        putc_code(fp, '\n');
-       putl_code(fp, "#ifndef YYSTYPE\n");
+       putl_code(fp, "#if "
+                 "! defined(YYSTYPE) && "
+                 "! defined(YYSTYPE_IS_DECLARED)\n");
+       putl_code(fp, "/* Default: YYSTYPE is the semantic value type. */\n");
        putl_code(fp, "typedef int YYSTYPE;\n");
+       putl_code(fp, "# define YYSTYPE_IS_DECLARED 1\n");
        putl_code(fp, "#endif\n");
     }
 }
 
+#if defined(YYBTYACC)
+static void
+output_ltype(FILE * fp)
+{
+    putc_code(fp, '\n');
+    putl_code(fp, "#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED\n");
+    putl_code(fp, "/* Default: YYLTYPE is the text position type. */\n");
+    putl_code(fp, "typedef struct YYLTYPE\n");
+    putl_code(fp, "{\n");
+    putl_code(fp, "    int first_line;\n");
+    putl_code(fp, "    int first_column;\n");
+    putl_code(fp, "    int last_line;\n");
+    putl_code(fp, "    int last_column;\n");
+    putl_code(fp, "} YYLTYPE;\n");
+    putl_code(fp, "#define YYLTYPE_IS_DECLARED 1\n");
+    putl_code(fp, "#endif\n");
+}
+#endif
+
 static void
 output_trailing_text(void)
 {
@@ -1205,7 +1634,7 @@ output_semantic_actions(void)
 static void
 output_parse_decl(FILE * fp)
 {
-    putl_code(fp, "\n");
+    putc_code(fp, '\n');
     putl_code(fp, "/* compatibility with bison */\n");
     putl_code(fp, "#ifdef YYPARSE_PARAM\n");
     putl_code(fp, "/* compatibility with FreeBSD */\n");
@@ -1218,15 +1647,7 @@ output_parse_decl(FILE * fp)
     putl_code(fp, "#else\n");
 
     puts_code(fp, "# define YYPARSE_DECL() yyparse(");
-    if (!parse_param)
-       puts_code(fp, "void");
-    else
-    {
-       param *p;
-       for (p = parse_param; p; p = p->next)
-           fprintf(fp, "%s %s%s%s", p->type, p->name, p->type2,
-                   p->next ? ", " : "");
-    }
+    puts_param_types(fp, parse_param, 0);
     putl_code(fp, ")\n");
 
     putl_code(fp, "#endif\n");
@@ -1235,19 +1656,47 @@ output_parse_decl(FILE * fp)
 static void
 output_lex_decl(FILE * fp)
 {
-    putl_code(fp, "\n");
+    putc_code(fp, '\n');
     putl_code(fp, "/* Parameters sent to lex. */\n");
     putl_code(fp, "#ifdef YYLEX_PARAM\n");
     if (pure_parser)
     {
        putl_code(fp, "# ifdef YYLEX_PARAM_TYPE\n");
-       putl_code(fp, "#  define YYLEX_DECL() yylex(YYSTYPE *yylval,"
-                 " YYLEX_PARAM_TYPE YYLEX_PARAM)\n");
+#if defined(YYBTYACC)
+       if (locations)
+       {
+           putl_code(fp, "#  define YYLEX_DECL() yylex(YYSTYPE *yylval,"
+                     " YYLTYPE *yylloc,"
+                     " YYLEX_PARAM_TYPE YYLEX_PARAM)\n");
+       }
+       else
+#endif
+       {
+           putl_code(fp, "#  define YYLEX_DECL() yylex(YYSTYPE *yylval,"
+                     " YYLEX_PARAM_TYPE YYLEX_PARAM)\n");
+       }
        putl_code(fp, "# else\n");
-       putl_code(fp, "#  define YYLEX_DECL() yylex(YYSTYPE *yylval,"
-                 " void * YYLEX_PARAM)\n");
+#if defined(YYBTYACC)
+       if (locations)
+       {
+           putl_code(fp, "#  define YYLEX_DECL() yylex(YYSTYPE *yylval,"
+                     " YYLTYPE *yylloc,"
+                     " void * YYLEX_PARAM)\n");
+       }
+       else
+#endif
+       {
+           putl_code(fp, "#  define YYLEX_DECL() yylex(YYSTYPE *yylval,"
+                     " void * YYLEX_PARAM)\n");
+       }
        putl_code(fp, "# endif\n");
-       putl_code(fp, "# define YYLEX yylex(&yylval, YYLEX_PARAM)\n");
+#if defined(YYBTYACC)
+       if (locations)
+           putl_code(fp,
+                     "# define YYLEX yylex(&yylval, &yylloc, YYLEX_PARAM)\n");
+       else
+#endif
+           putl_code(fp, "# define YYLEX yylex(&yylval, YYLEX_PARAM)\n");
     }
     else
     {
@@ -1257,35 +1706,49 @@ output_lex_decl(FILE * fp)
     putl_code(fp, "#else\n");
     if (pure_parser && lex_param)
     {
-       param *p;
-       puts_code(fp, "# define YYLEX_DECL() yylex(YYSTYPE *yylval, ");
-       for (p = lex_param; p; p = p->next)
-           fprintf(fp, "%s %s%s%s", p->type, p->name, p->type2,
-                   p->next ? ", " : "");
+#if defined(YYBTYACC)
+       if (locations)
+           puts_code(fp,
+                     "# define YYLEX_DECL() yylex(YYSTYPE *yylval, YYLTYPE *yylloc, ");
+       else
+#endif
+           puts_code(fp, "# define YYLEX_DECL() yylex(YYSTYPE *yylval, ");
+       puts_param_types(fp, lex_param, 0);
        putl_code(fp, ")\n");
 
-       puts_code(fp, "# define YYLEX yylex(&yylval, ");
-       for (p = lex_param; p; p = p->next)
-           fprintf(fp, "%s%s", p->name, p->next ? ", " : "");
+#if defined(YYBTYACC)
+       if (locations)
+           puts_code(fp, "# define YYLEX yylex(&yylval, &yylloc, ");
+       else
+#endif
+           puts_code(fp, "# define YYLEX yylex(&yylval, ");
+       puts_param_names(fp, lex_param, 0);
        putl_code(fp, ")\n");
     }
     else if (pure_parser)
     {
-       putl_code(fp, "# define YYLEX_DECL() yylex(YYSTYPE *yylval)\n");
-       putl_code(fp, "# define YYLEX yylex(&yylval)\n");
+#if defined(YYBTYACC)
+       if (locations)
+       {
+           putl_code(fp,
+                     "# define YYLEX_DECL() yylex(YYSTYPE *yylval, YYLTYPE *yylloc)\n");
+           putl_code(fp, "# define YYLEX yylex(&yylval, &yylloc)\n");
+       }
+       else
+#endif
+       {
+           putl_code(fp, "# define YYLEX_DECL() yylex(YYSTYPE *yylval)\n");
+           putl_code(fp, "# define YYLEX yylex(&yylval)\n");
+       }
     }
     else if (lex_param)
     {
-       param *p;
        puts_code(fp, "# define YYLEX_DECL() yylex(");
-       for (p = lex_param; p; p = p->next)
-           fprintf(fp, "%s %s%s%s", p->type, p->name, p->type2,
-                   p->next ? ", " : "");
+       puts_param_types(fp, lex_param, 0);
        putl_code(fp, ")\n");
 
        puts_code(fp, "# define YYLEX yylex(");
-       for (p = lex_param; p; p = p->next)
-           fprintf(fp, "%s%s", p->name, p->next ? ", " : "");
+       puts_param_names(fp, lex_param, 0);
        putl_code(fp, ")\n");
     }
     else
@@ -1299,38 +1762,114 @@ output_lex_decl(FILE * fp)
 static void
 output_error_decl(FILE * fp)
 {
-    putl_code(fp, "\n");
+    putc_code(fp, '\n');
     putl_code(fp, "/* Parameters sent to yyerror. */\n");
+    putl_code(fp, "#ifndef YYERROR_DECL\n");
+    puts_code(fp, "#define YYERROR_DECL() yyerror(");
+#if defined(YYBTYACC)
+    if (locations)
+       puts_code(fp, "YYLTYPE loc, ");
+#endif
+    puts_param_types(fp, parse_param, 1);
+    putl_code(fp, "const char *s)\n");
+    putl_code(fp, "#endif\n");
+
+    putl_code(fp, "#ifndef YYERROR_CALL\n");
+
+    puts_code(fp, "#define YYERROR_CALL(msg) yyerror(");
+#if defined(YYBTYACC)
+    if (locations)
+       puts_code(fp, "yylloc, ");
+#endif
+    puts_param_names(fp, parse_param, 1);
+    putl_code(fp, "msg)\n");
+
+    putl_code(fp, "#endif\n");
+}
+
+#if defined(YYBTYACC)
+static void
+output_yydestruct_decl(FILE * fp)
+{
+    putc_code(fp, '\n');
+    putl_code(fp, "#ifndef YYDESTRUCT_DECL\n");
+
+    puts_code(fp,
+             "#define YYDESTRUCT_DECL() "
+             "yydestruct(const char *msg, int psymb, YYSTYPE *val");
+#if defined(YYBTYACC)
+    if (locations)
+       puts_code(fp, ", YYLTYPE *loc");
+#endif
     if (parse_param)
     {
-       param *p;
-
-       putl_code(fp, "#ifndef YYERROR_DECL\n");
-       fprintf(fp, "#define YYERROR_DECL() yyerror(");
-       for (p = parse_param; p; p = p->next)
-           fprintf(fp, "%s %s%s, ", p->type, p->name, p->type2);
-       putl_code(fp, "const char *s)\n");
-       putl_code(fp, "#endif\n");
+       puts_code(fp, ", ");
+       puts_param_types(fp, parse_param, 0);
+    }
+    putl_code(fp, ")\n");
 
-       putl_code(fp, "#ifndef YYERROR_CALL\n");
-       puts_code(fp, "#define YYERROR_CALL(msg) yyerror(");
+    putl_code(fp, "#endif\n");
 
-       for (p = parse_param; p; p = p->next)
-           fprintf(fp, "%s, ", p->name);
+    putl_code(fp, "#ifndef YYDESTRUCT_CALL\n");
 
-       putl_code(fp, "msg)\n");
-       putl_code(fp, "#endif\n");
+    puts_code(fp, "#define YYDESTRUCT_CALL(msg, psymb, val");
+#if defined(YYBTYACC)
+    if (locations)
+       puts_code(fp, ", loc");
+#endif
+    puts_code(fp, ") yydestruct(msg, psymb, val");
+#if defined(YYBTYACC)
+    if (locations)
+       puts_code(fp, ", loc");
+#endif
+    if (parse_param)
+    {
+       puts_code(fp, ", ");
+       puts_param_names(fp, parse_param, 0);
     }
-    else
+    putl_code(fp, ")\n");
+
+    putl_code(fp, "#endif\n");
+}
+
+static void
+output_yydestruct_impl(void)
+{
+    int i;
+    char *s, *destructor_code;
+
+    putc_code(code_file, '\n');
+    putl_code(code_file, "/* Release memory associated with symbol. */\n");
+    putl_code(code_file, "#if ! defined YYDESTRUCT_IS_DECLARED\n");
+    putl_code(code_file, "static void\n");
+    putl_code(code_file, "YYDESTRUCT_DECL()\n");
+    putl_code(code_file, "{\n");
+    putl_code(code_file, "    switch (psymb)\n");
+    putl_code(code_file, "    {\n");
+    for (i = 2; i < nsyms; ++i)
     {
-       putl_code(fp, "#ifndef YYERROR_DECL\n");
-       putl_code(fp, "#define YYERROR_DECL() yyerror(const char *s)\n");
-       putl_code(fp, "#endif\n");
-       putl_code(fp, "#ifndef YYERROR_CALL\n");
-       putl_code(fp, "#define YYERROR_CALL(msg) yyerror(msg)\n");
-       putl_code(fp, "#endif\n");
+       if ((destructor_code = symbol_destructor[i]) != NULL)
+       {
+           ++outline;
+           fprintf(code_file, "\tcase %d:\n", symbol_pval[i]);
+           /* comprehend the number of lines in the destructor code */
+           for (s = destructor_code; (s = strchr(s, '\n')) != NULL; s++)
+               ++outline;
+           puts_code(code_file, destructor_code);
+           putc_code(code_file, '\n');
+           putl_code(code_file, "\tbreak;\n");
+           write_code_lineno(code_file);
+           FREE(destructor_code);
+       }
     }
+    putl_code(code_file, "    }\n");
+    putl_code(code_file, "}\n");
+    putl_code(code_file, "#define YYDESTRUCT_IS_DECLARED 1\n");
+    putl_code(code_file, "#endif\n");
+
+    DO_FREE(symbol_destructor);
 }
+#endif
 
 static void
 free_itemsets(void)
@@ -1371,42 +1910,21 @@ free_reductions(void)
     }
 }
 
-static void
-output_yyerror_call(const char *msg)
-{
-    FILE *fp = code_file;
-
-    puts_code(fp, "    yyerror(");
-    if (parse_param)
-    {
-       param *p;
-       for (p = parse_param; p; p = p->next)
-           fprintf(fp, "%s, ", p->name);
-    }
-    puts_code(fp, "\"");
-    puts_code(fp, msg);
-    putl_code(fp, "\");\n");
-}
-
 static void
 output_externs(FILE * fp, const char *const section[])
 {
-    int c;
     int i;
     const char *s;
 
     for (i = 0; (s = section[i]) != 0; ++i)
     {
-       if (*s && *s != '#')
+       /* prefix non-blank lines that don't start with
+          C pre-processor directives with 'extern ' */
+       if (*s && (*s != '#'))
            fputs("extern\t", fp);
-       while ((c = *s) != 0)
-       {
-           putc(c, fp);
-           ++s;
-       }
        if (fp == code_file)
            ++outline;
-       putc('\n', fp);
+       fprintf(fp, "%s\n", s);
     }
 }
 
@@ -1419,8 +1937,15 @@ output(void)
     free_shifts();
     free_reductions();
 
+#if defined(YYBTYACC)
+    output_backtracking_parser(output_file);
+    if (rflag)
+       output_backtracking_parser(code_file);
+#endif
+
     if (iflag)
     {
+       write_code_lineno(code_file);
        ++outline;
        fprintf(code_file, "#include \"%s\"\n", externs_file_name);
        fp = externs_file;
@@ -1428,14 +1953,25 @@ output(void)
     else
        fp = code_file;
 
-    output_prefix(iflag ? externs_file : output_file);
+    output_prefix(fp);
     output_pure_parser(fp);
     output_stored_text(fp);
     output_stype(fp);
+#if defined(YYBTYACC)
+    if (locations)
+       output_ltype(fp);
+#endif
     output_parse_decl(fp);
     output_lex_decl(fp);
     output_error_decl(fp);
-    write_section(fp, xdecls);
+#if defined(YYBTYACC)
+    if (destructor)
+       output_yydestruct_decl(fp);
+#endif
+    if (iflag || !rflag)
+    {
+       write_section(fp, xdecls);
+    }
 
     if (iflag)
     {
@@ -1446,9 +1982,12 @@ output(void)
 
     if (iflag)
     {
-       ++outline;
-       fprintf(code_file, "#include \"%s\"\n", defines_file_name);
-       if (!dflag)
+       if (dflag)
+       {
+           ++outline;
+           fprintf(code_file, "#include \"%s\"\n", defines_file_name);
+       }
+       else
            output_defines(externs_file);
     }
     else
@@ -1458,17 +1997,24 @@ output(void)
     }
 
     if (dflag)
+    {
+       start_defines_file();
        output_defines(defines_file);
+       end_defines_file();
+    }
 
     output_rule_data();
     output_yydefred();
+#if defined(YYBTYACC)
+    output_accessing_symbols();
+#endif
     output_actions();
     free_parser();
     output_debug();
     if (rflag)
     {
-       output_prefix(code_file);
        write_section(code_file, xdecls);
+       output_YYINT_typedef(code_file);
        write_section(code_file, tables);
     }
     write_section(code_file, global_vars);
@@ -1482,18 +2028,18 @@ output(void)
        write_section(code_file, hdr_vars);
     }
     output_trailing_text();
+#if defined(YYBTYACC)
+    if (destructor)
+       output_yydestruct_impl();
+#endif
     write_section(code_file, body_1);
     if (pure_parser)
     {
        write_section(code_file, body_vars);
     }
     write_section(code_file, body_2);
-    output_yyerror_call("syntax error");
-    write_section(code_file, body_3);
     output_semantic_actions();
     write_section(code_file, trailer);
-    output_yyerror_call("yacc stack overflow");
-    write_section(code_file, trailer_2);
 }
 
 #ifdef NO_LEAKS
index 124b776..d0d7b1a 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: reader.c,v 1.36 2012/05/26 16:05:41 tom Exp $ */
+/* $Id: reader.c,v 1.58 2014/10/06 22:15:08 tom Exp $ */
 
 #include "defs.h"
 
@@ -9,16 +9,28 @@
 
 #define LINESIZE 100
 
-#define L_CURL '{'
-#define R_CURL '}'
+#define L_CURL  '{'
+#define R_CURL  '}'
+#define L_PAREN '('
+#define R_PAREN ')'
+#define L_BRAC  '['
+#define R_BRAC  ']'
+
+/* the maximum number of arguments (inherited attributes) to a non-terminal */
+/* this is a hard limit, but seems more than adequate */
+#define MAXARGS        20
 
 static void start_rule(bucket *bp, int s_lineno);
+#if defined(YYBTYACC)
+static void copy_destructor(void);
+static char *process_destructor_XX(char *code, char *tag);
+#endif
 
 static char *cache;
 static int cinc, cache_size;
 
 int ntags;
-static int tagmax;
+static int tagmax, havetags;
 static char **tag_table;
 
 static char saw_eof;
@@ -45,6 +57,38 @@ char line_format[] = "#line %d \"%s\"\n";
 param *lex_param;
 param *parse_param;
 
+#if defined(YYBTYACC)
+int destructor = 0;    /* =1 if at least one %destructor */
+
+static bucket *default_destructor[3] =
+{0, 0, 0};
+
+#define UNTYPED_DEFAULT 0
+#define TYPED_DEFAULT   1
+#define TYPE_SPECIFIED  2
+
+static bucket *
+lookup_type_destructor(char *tag)
+{
+    const char fmt[] = "%.*s destructor";
+    char name[1024] = "\0";
+    bucket *bp, **bpp = &default_destructor[TYPE_SPECIFIED];
+
+    while ((bp = *bpp) != NULL)
+    {
+       if (bp->tag == tag)
+           return (bp);
+       bpp = &bp->link;
+    }
+
+    sprintf(name, fmt, (int)(sizeof(name) - sizeof(fmt)), tag);
+    *bpp = bp = make_bucket(name);
+    bp->tag = tag;
+
+    return (bp);
+}
+#endif /* defined(YYBTYACC) */
+
 static void
 cachec(int c)
 {
@@ -91,13 +135,10 @@ get_line(void)
     ++lineno;
     for (;;)
     {
-       line[i] = (char)c;
+       line[i++] = (char)c;
        if (c == '\n')
-       {
-           cptr = line;
-           return;
-       }
-       if (++i >= linesize)
+           break;
+       if ((i + 3) >= linesize)
        {
            linesize += LINESIZE;
            line = TREALLOC(char, line, linesize);
@@ -106,12 +147,14 @@ get_line(void)
        c = getc(f);
        if (c == EOF)
        {
-           line[i] = '\n';
+           line[i++] = '\n';
            saw_eof = 1;
-           cptr = line;
-           return;
+           break;
        }
     }
+    line[i] = '\0';
+    cptr = line;
+    return;
 }
 
 static char *
@@ -165,7 +208,7 @@ skip_comment(void)
 }
 
 static int
-nextc(void)
+next_inline(void)
 {
     char *s;
 
@@ -181,27 +224,6 @@ nextc(void)
     {
        switch (*s)
        {
-       case '\n':
-           get_line();
-           if (line == 0)
-               return (EOF);
-           s = cptr;
-           break;
-
-       case ' ':
-       case '\t':
-       case '\f':
-       case '\r':
-       case '\v':
-       case ',':
-       case ';':
-           ++s;
-           break;
-
-       case '\\':
-           cptr = s;
-           return ('%');
-
        case '/':
            if (s[1] == '*')
            {
@@ -227,34 +249,79 @@ nextc(void)
     }
 }
 
-/*
- * Compare keyword to cached token, treating '_' and '-' the same.  Some
- * grammars rely upon this misfeature.
- */
 static int
-matchec(const char *name)
+nextc(void)
 {
-    const char *p = cache;
-    const char *q = name;
-    int code = 0;      /* assume mismatch */
+    int ch;
+    int finish = 0;
 
-    while (*p != '\0' && *q != '\0')
+    do
     {
-       char a = *p++;
-       char b = *q++;
-       if (a == '_')
-           a = '-';
-       if (b == '_')
-           b = '-';
-       if (a != b)
-           break;
-       if (*p == '\0' && *q == '\0')
+       switch (ch = next_inline())
        {
-           code = 1;
+       case '\n':
+           get_line();
+           break;
+       case ' ':
+       case '\t':
+       case '\f':
+       case '\r':
+       case '\v':
+       case ',':
+       case ';':
+           ++cptr;
+           break;
+       case '\\':
+           ch = '%';
+           /* FALLTHRU */
+       default:
+           finish = 1;
            break;
        }
     }
-    return code;
+    while (!finish);
+
+    return ch;
+}
+/* *INDENT-OFF* */
+static struct keyword
+{
+    char name[13];
+    int token;
+}
+keywords[] = {
+    { "binary",      NONASSOC },
+#if defined(YYBTYACC)
+    { "destructor",  DESTRUCTOR },
+#endif
+    { "expect",      EXPECT },
+    { "expect-rr",   EXPECT_RR },
+    { "ident",       IDENT }, 
+    { "left",        LEFT },
+    { "lex-param",   LEX_PARAM },
+#if defined(YYBTYACC)
+    { "locations",   LOCATIONS },
+#endif
+    { "nonassoc",    NONASSOC },
+    { "parse-param", PARSE_PARAM },
+    { "pure-parser", PURE_PARSER },
+    { "right",       RIGHT }, 
+    { "start",       START },
+    { "term",        TOKEN }, 
+    { "token",       TOKEN }, 
+    { "token-table", TOKEN_TABLE }, 
+    { "type",        TYPE },
+    { "union",       UNION },
+    { "yacc",        POSIX_YACC },
+};
+/* *INDENT-ON* */
+
+static int
+compare_keys(const void *a, const void *b)
+{
+    const struct keyword *p = (const struct keyword *)a;
+    const struct keyword *q = (const struct keyword *)b;
+    return strcmp(p->name, q->name);
 }
 
 static int
@@ -262,6 +329,7 @@ keyword(void)
 {
     int c;
     char *t_cptr = cptr;
+    struct keyword *key;
 
     c = *++cptr;
     if (isalpha(c))
@@ -277,12 +345,16 @@ keyword(void)
            }
            else if (isdigit(c)
                     || c == '-'
-                    || c == '_'
                     || c == '.'
                     || c == '$')
            {
                cachec(c);
            }
+           else if (c == '_')
+           {
+               /* treat keywords spelled with '_' as if it were '-' */
+               cachec('-');
+           }
            else
            {
                break;
@@ -291,34 +363,10 @@ keyword(void)
        }
        cachec(NUL);
 
-       if (matchec("token") || matchec("term"))
-           return (TOKEN);
-       if (matchec("type"))
-           return (TYPE);
-       if (matchec("left"))
-           return (LEFT);
-       if (matchec("right"))
-           return (RIGHT);
-       if (matchec("nonassoc") || matchec("binary"))
-           return (NONASSOC);
-       if (matchec("start"))
-           return (START);
-       if (matchec("union"))
-           return (UNION);
-       if (matchec("ident"))
-           return (IDENT);
-       if (matchec("expect"))
-           return (EXPECT);
-       if (matchec("expect-rr"))
-           return (EXPECT_RR);
-       if (matchec("pure-parser"))
-           return (PURE_PARSER);
-       if (matchec("parse-param"))
-           return (PARSE_PARAM);
-       if (matchec("lex-param"))
-           return (LEX_PARAM);
-       if (matchec("yacc"))
-           return (POSIX_YACC);
+       if ((key = bsearch(cache, keywords,
+                          sizeof(keywords) / sizeof(*key),
+                          sizeof(*key), compare_keys)))
+           return key->token;
     }
     else
     {
@@ -337,7 +385,6 @@ keyword(void)
            return (NONASSOC);
     }
     syntax_error(lineno, line, t_cptr);
-    /*NOTREACHED */
 }
 
 static void
@@ -371,11 +418,93 @@ copy_ident(void)
     }
 }
 
+static char *
+copy_string(int quote)
+{
+    struct mstring *temp = msnew();
+    int c;
+    int s_lineno = lineno;
+    char *s_line = dup_line();
+    char *s_cptr = s_line + (cptr - line - 1);
+
+    for (;;)
+    {
+       c = *cptr++;
+       mputc(temp, c);
+       if (c == quote)
+       {
+           FREE(s_line);
+           return msdone(temp);
+       }
+       if (c == '\n')
+           unterminated_string(s_lineno, s_line, s_cptr);
+       if (c == '\\')
+       {
+           c = *cptr++;
+           mputc(temp, c);
+           if (c == '\n')
+           {
+               get_line();
+               if (line == 0)
+                   unterminated_string(s_lineno, s_line, s_cptr);
+           }
+       }
+    }
+}
+
+static char *
+copy_comment(void)
+{
+    struct mstring *temp = msnew();
+    int c;
+
+    c = *cptr;
+    if (c == '/')
+    {
+       mputc(temp, '*');
+       while ((c = *++cptr) != '\n')
+       {
+           mputc(temp, c);
+           if (c == '*' && cptr[1] == '/')
+               mputc(temp, ' ');
+       }
+       mputc(temp, '*');
+       mputc(temp, '/');
+    }
+    else if (c == '*')
+    {
+       int c_lineno = lineno;
+       char *c_line = dup_line();
+       char *c_cptr = c_line + (cptr - line - 1);
+
+       mputc(temp, c);
+       ++cptr;
+       for (;;)
+       {
+           c = *cptr++;
+           mputc(temp, c);
+           if (c == '*' && *cptr == '/')
+           {
+               mputc(temp, '/');
+               ++cptr;
+               FREE(c_line);
+               return msdone(temp);
+           }
+           if (c == '\n')
+           {
+               get_line();
+               if (line == 0)
+                   unterminated_comment(c_lineno, c_line, c_cptr);
+           }
+       }
+    }
+    return msdone(temp);
+}
+
 static void
 copy_text(void)
 {
     int c;
-    int quote;
     FILE *f = text_file;
     int need_newline = 0;
     int t_lineno = lineno;
@@ -396,7 +525,6 @@ copy_text(void)
     switch (c)
     {
     case '\n':
-      next_line:
        putc('\n', f);
        need_newline = 0;
        get_line();
@@ -406,82 +534,21 @@ copy_text(void)
 
     case '\'':
     case '"':
+       putc(c, f);
        {
-           int s_lineno = lineno;
-           char *s_line = dup_line();
-           char *s_cptr = s_line + (cptr - line - 1);
-
-           quote = c;
-           putc(c, f);
-           for (;;)
-           {
-               c = *cptr++;
-               putc(c, f);
-               if (c == quote)
-               {
-                   need_newline = 1;
-                   FREE(s_line);
-                   goto loop;
-               }
-               if (c == '\n')
-                   unterminated_string(s_lineno, s_line, s_cptr);
-               if (c == '\\')
-               {
-                   c = *cptr++;
-                   putc(c, f);
-                   if (c == '\n')
-                   {
-                       get_line();
-                       if (line == 0)
-                           unterminated_string(s_lineno, s_line, s_cptr);
-                   }
-               }
-           }
+           char *s = copy_string(c);
+           fputs(s, f);
+           free(s);
        }
+       need_newline = 1;
+       goto loop;
 
     case '/':
        putc(c, f);
-       need_newline = 1;
-       c = *cptr;
-       if (c == '/')
-       {
-           putc('*', f);
-           while ((c = *++cptr) != '\n')
-           {
-               if (c == '*' && cptr[1] == '/')
-                   fprintf(f, "* ");
-               else
-                   putc(c, f);
-           }
-           fprintf(f, "*/");
-           goto next_line;
-       }
-       if (c == '*')
        {
-           int c_lineno = lineno;
-           char *c_line = dup_line();
-           char *c_cptr = c_line + (cptr - line - 1);
-
-           putc('*', f);
-           ++cptr;
-           for (;;)
-           {
-               c = *cptr++;
-               putc(c, f);
-               if (c == '*' && *cptr == '/')
-               {
-                   putc('/', f);
-                   ++cptr;
-                   FREE(c_line);
-                   goto loop;
-               }
-               if (c == '\n')
-               {
-                   get_line();
-                   if (line == 0)
-                       unterminated_comment(c_lineno, c_line, c_cptr);
-               }
-           }
+           char *s = copy_comment();
+           fputs(s, f);
+           free(s);
        }
        need_newline = 1;
        goto loop;
@@ -525,7 +592,6 @@ static void
 copy_union(void)
 {
     int c;
-    int quote;
     int depth;
     int u_lineno = lineno;
     char *u_line = dup_line();
@@ -553,7 +619,6 @@ copy_union(void)
     switch (c)
     {
     case '\n':
-      next_line:
        get_line();
        if (line == 0)
            unterminated_union(u_lineno, u_line, u_cptr);
@@ -576,81 +641,17 @@ copy_union(void)
     case '\'':
     case '"':
        {
-           int s_lineno = lineno;
-           char *s_line = dup_line();
-           char *s_cptr = s_line + (cptr - line - 1);
-
-           quote = c;
-           for (;;)
-           {
-               c = *cptr++;
-               putc_both(c);
-               if (c == quote)
-               {
-                   FREE(s_line);
-                   goto loop;
-               }
-               if (c == '\n')
-                   unterminated_string(s_lineno, s_line, s_cptr);
-               if (c == '\\')
-               {
-                   c = *cptr++;
-                   putc_both(c);
-                   if (c == '\n')
-                   {
-                       get_line();
-                       if (line == 0)
-                           unterminated_string(s_lineno, s_line, s_cptr);
-                   }
-               }
-           }
+           char *s = copy_string(c);
+           puts_both(s);
+           free(s);
        }
+       goto loop;
 
     case '/':
-       c = *cptr;
-       if (c == '/')
-       {
-           putc_both('*');
-           while ((c = *++cptr) != '\n')
-           {
-               if (c == '*' && cptr[1] == '/')
-               {
-                   puts_both("* ");
-               }
-               else
-               {
-                   putc_both(c);
-               }
-           }
-           puts_both("*/\n");
-           goto next_line;
-       }
-       if (c == '*')
        {
-           int c_lineno = lineno;
-           char *c_line = dup_line();
-           char *c_cptr = c_line + (cptr - line - 1);
-
-           putc_both('*');
-           ++cptr;
-           for (;;)
-           {
-               c = *cptr++;
-               putc_both(c);
-               if (c == '*' && *cptr == '/')
-               {
-                   putc_both('/');
-                   ++cptr;
-                   FREE(c_line);
-                   goto loop;
-               }
-               if (c == '\n')
-               {
-                   get_line();
-                   if (line == 0)
-                       unterminated_comment(c_lineno, c_line, c_cptr);
-               }
-           }
+           char *s = copy_comment();
+           puts_both(s);
+           free(s);
        }
        goto loop;
 
@@ -659,92 +660,109 @@ copy_union(void)
     }
 }
 
+static char *
+after_blanks(char *s)
+{
+    while (*s != '\0' && isspace(UCH(*s)))
+       ++s;
+    return s;
+}
+
 /*
- * Keep a linked list of parameters
+ * Trim leading/trailing blanks, and collapse multiple embedded blanks to a
+ * single space.  Return index to last character in the buffer.
  */
-static void
-copy_param(int k)
+static int
+trim_blanks(char *buffer)
 {
-    char *buf;
-    int c;
-    param *head, *p;
-    int i;
-    int name, type2;
-
-    c = nextc();
-    if (c == EOF)
-       unexpected_EOF();
-    if (c != '{')
-       goto out;
-    cptr++;
+    if (*buffer != '\0')
+    {
+       char *d = buffer;
+       char *s = after_blanks(d);
 
-    c = nextc();
-    if (c == EOF)
-       unexpected_EOF();
-    if (c == '}')
-       goto out;
+       while ((*d++ = *s++) != '\0')
+       {
+           ;
+       }
 
-    buf = TMALLOC(char, linesize);
-    NO_SPACE(buf);
+       --d;
+       while ((--d != buffer) && isspace(UCH(*d)))
+           *d = '\0';
 
-    for (i = 0; (c = *cptr++) != '}'; i++)
-    {
-       if (c == '\0')
-           missing_brace();
-       if (c == EOF)
-           unexpected_EOF();
-       buf[i] = (char)c;
+       for (s = d = buffer; (*d++ = *s++) != '\0';)
+       {
+           if (isspace(UCH(*s)))
+           {
+               *s = ' ';
+               while (isspace(UCH(*s)))
+               {
+                   *s++ = ' ';
+               }
+               --s;
+           }
+       }
     }
 
-    if (i == 0)
-       goto out;
-
-    buf[i--] = '\0';
-    while (i >= 0 && isspace(UCH(buf[i])))
-       buf[i--] = '\0';
+    return (int)strlen(buffer) - 1;
+}
 
-    if (buf[i] == ']')
+/*
+ * Scan forward in the current line-buffer looking for a right-curly bracket.
+ *
+ * Parameters begin with a left-curly bracket, and continue until there are no
+ * more interesting characters after the last right-curly bracket on the
+ * current line.  Bison documents parameters as separated like this:
+ *     {type param1} {type2 param2}
+ * but also accepts commas (although some versions of bison mishandle this)
+ *     {type param1,  type2 param2}
+ */
+static int
+more_curly(void)
+{
+    char *save = cptr;
+    int result = 0;
+    int finish = 0;
+    do
     {
-       int level = 1;
-       while (i >= 0 && level > 0 && buf[i] != '[')
+       switch (next_inline())
        {
-           if (buf[i] == ']')
-               ++level;
-           else if (buf[i] == '[')
-               --level;
-           i--;
+       case 0:
+       case '\n':
+           finish = 1;
+           break;
+       case R_CURL:
+           finish = 1;
+           result = 1;
+           break;
        }
-       if (i <= 0)
-           unexpected_EOF();
-       type2 = i--;
-    }
-    else
-    {
-       type2 = i + 1;
+       ++cptr;
     }
+    while (!finish);
+    cptr = save;
+    return result;
+}
 
-    while (i >= 0 && (isalnum(UCH(buf[i])) ||
-                     UCH(buf[i]) == '_'))
-       i--;
-
-    if (!isspace(UCH(buf[i])) && buf[i] != '*')
-       goto out;
-
-    name = i + 1;
+static void
+save_param(int k, char *buffer, int name, int type2)
+{
+    param *head, *p;
 
     p = TMALLOC(param, 1);
     NO_SPACE(p);
 
-    p->type2 = strdup(buf + type2);
+    p->type2 = strdup(buffer + type2);
     NO_SPACE(p->type2);
+    buffer[type2] = '\0';
+    (void)trim_blanks(p->type2);
 
-    buf[type2] = '\0';
-
-    p->name = strdup(buf + name);
+    p->name = strdup(buffer + name);
     NO_SPACE(p->name);
+    buffer[name] = '\0';
+    (void)trim_blanks(p->name);
 
-    buf[name] = '\0';
-    p->type = buf;
+    p->type = strdup(buffer);
+    NO_SPACE(p->type);
+    (void)trim_blanks(p->type);
 
     if (k == LEX_PARAM)
        head = lex_param;
@@ -765,9 +783,169 @@ copy_param(int k)
            parse_param = p;
     }
     p->next = NULL;
+}
+
+/*
+ * Keep a linked list of parameters.  This may be multi-line, if the trailing
+ * right-curly bracket is absent.
+ */
+static void
+copy_param(int k)
+{
+    int c;
+    int name, type2;
+    int curly = 0;
+    char *buf = 0;
+    int i = -1;
+    size_t buf_size = 0;
+    int st_lineno = lineno;
+    char *comma;
+
+    do
+    {
+       int state = curly;
+       c = next_inline();
+       switch (c)
+       {
+       case EOF:
+           unexpected_EOF();
+           break;
+       case L_CURL:
+           if (curly == 1)
+           {
+               goto oops;
+           }
+           curly = 1;
+           st_lineno = lineno;
+           break;
+       case R_CURL:
+           if (curly != 1)
+           {
+               goto oops;
+           }
+           curly = 2;
+           break;
+       case '\n':
+           if (curly == 0)
+           {
+               goto oops;
+           }
+           break;
+       case '%':
+           if ((curly == 1) && (cptr == line))
+           {
+               lineno = st_lineno;
+               missing_brace();
+           }
+           /* FALLTHRU */
+       case '"':
+       case '\'':
+           goto oops;
+       default:
+           if (curly == 0 && !isspace(UCH(c)))
+           {
+               goto oops;
+           }
+           break;
+       }
+       if (buf == 0)
+       {
+           buf_size = (size_t) linesize;
+           buf = TMALLOC(char, buf_size);
+       }
+       else if (c == '\n')
+       {
+           get_line();
+           if (line == 0)
+               unexpected_EOF();
+           --cptr;
+           buf_size += (size_t) linesize;
+           buf = TREALLOC(char, buf, buf_size);
+       }
+       NO_SPACE(buf);
+       if (curly)
+       {
+           if ((state == 2) && (c == L_CURL))
+           {
+               buf[++i] = ',';
+           }
+           else if ((state == 2) && isspace(UCH(c)))
+           {
+               ;
+           }
+           else if ((c != L_CURL) && (c != R_CURL))
+           {
+               buf[++i] = (char)c;
+           }
+       }
+       cptr++;
+    }
+    while (curly < 2 || more_curly());
+
+    if (i == 0)
+    {
+       if (curly == 1)
+       {
+           lineno = st_lineno;
+           missing_brace();
+       }
+       goto oops;
+    }
+
+    buf[i--] = '\0';
+    i = trim_blanks(buf);
+
+    comma = buf - 1;
+    do
+    {
+       char *parms = (comma + 1);
+       comma = strchr(parms, ',');
+       if (comma != 0)
+           *comma = '\0';
+
+       (void)trim_blanks(parms);
+       i = (int)strlen(parms) - 1;
+       if (i < 0)
+       {
+           goto oops;
+       }
+
+       if (parms[i] == ']')
+       {
+           int level = 1;
+           while (i >= 0 && level > 0 && parms[i] != '[')
+           {
+               if (parms[i] == ']')
+                   ++level;
+               else if (parms[i] == '[')
+                   --level;
+               i--;
+           }
+           if (i <= 0)
+               unexpected_EOF();
+           type2 = i--;
+       }
+       else
+       {
+           type2 = i + 1;
+       }
+
+       while (i > 0 && (isalnum(UCH(parms[i])) || UCH(parms[i]) == '_'))
+           i--;
+
+       if (!isspace(UCH(parms[i])) && parms[i] != '*')
+           goto oops;
+
+       name = i + 1;
+
+       save_param(k, parms, name, type2);
+    }
+    while (comma != 0);
+    FREE(buf);
     return;
 
-  out:
+  oops:
+    FREE(buf);
     syntax_error(lineno, line, cptr);
 }
 
@@ -1013,11 +1191,41 @@ get_number(void)
 }
 
 static char *
-get_tag(void)
+cache_tag(char *tag, size_t len)
 {
-    int c;
     int i;
     char *s;
+
+    for (i = 0; i < ntags; ++i)
+    {
+       if (strncmp(tag, tag_table[i], len) == 0 &&
+           tag_table[i][len] == NUL)
+           return (tag_table[i]);
+    }
+
+    if (ntags >= tagmax)
+    {
+       tagmax += 16;
+       tag_table =
+           (tag_table
+            ? TREALLOC(char *, tag_table, tagmax)
+            : TMALLOC(char *, tagmax));
+       NO_SPACE(tag_table);
+    }
+
+    s = TMALLOC(char, len + 1);
+    NO_SPACE(s);
+
+    strncpy(s, tag, len);
+    s[len] = 0;
+    tag_table[ntags++] = s;
+    return s;
+}
+
+static char *
+get_tag(void)
+{
+    int c;
     int t_lineno = lineno;
     char *t_line = dup_line();
     char *t_cptr = t_line + (cptr - line);
@@ -1045,34 +1253,22 @@ get_tag(void)
        illegal_tag(t_lineno, t_line, t_cptr);
     ++cptr;
 
-    for (i = 0; i < ntags; ++i)
-    {
-       if (strcmp(cache, tag_table[i]) == 0)
-       {
-           FREE(t_line);
-           return (tag_table[i]);
-       }
-    }
-
-    if (ntags >= tagmax)
-    {
-       tagmax += 16;
-       tag_table =
-           (tag_table
-            ? TREALLOC(char *, tag_table, tagmax)
-            : TMALLOC(char *, tagmax));
-       NO_SPACE(tag_table);
-    }
+    FREE(t_line);
+    havetags = 1;
+    return cache_tag(cache, (size_t) cinc);
+}
 
-    s = TMALLOC(char, cinc);
-    NO_SPACE(s);
+#if defined(YYBTYACC)
+static char *
+scan_id(void)
+{
+    char *b = cptr;
 
-    strcpy(s, cache);
-    tag_table[ntags] = s;
-    ++ntags;
-    FREE(t_line);
-    return (s);
+    while (isalnum(*cptr) || *cptr == '_' || *cptr == '$')
+       cptr++;
+    return cache_tag(b, (size_t) (cptr - b));
 }
+#endif
 
 static void
 declare_tokens(int assoc)
@@ -1190,33 +1386,88 @@ declare_expect(int assoc)
     }
 }
 
+#if defined(YYBTYACC)
+static void
+declare_argtypes(bucket *bp)
+{
+    char *tags[MAXARGS];
+    int args = 0, c;
+
+    if (bp->args >= 0)
+       retyped_warning(bp->name);
+    cptr++;                    /* skip open paren */
+    for (;;)
+    {
+       c = nextc();
+       if (c == EOF)
+           unexpected_EOF();
+       if (c != '<')
+           syntax_error(lineno, line, cptr);
+       tags[args++] = get_tag();
+       c = nextc();
+       if (c == R_PAREN)
+           break;
+       if (c == EOF)
+           unexpected_EOF();
+    }
+    cptr++;                    /* skip close paren */
+    bp->args = args;
+    bp->argnames = TMALLOC(char *, args);
+    NO_SPACE(bp->argnames);
+    bp->argtags = CALLOC(sizeof(char *), args + 1);
+    NO_SPACE(bp->argtags);
+    while (--args >= 0)
+    {
+       bp->argtags[args] = tags[args];
+       bp->argnames[args] = NULL;
+    }
+}
+#endif
+
 static void
 declare_types(void)
 {
     int c;
     bucket *bp;
-    char *tag;
+    char *tag = NULL;
 
     c = nextc();
     if (c == EOF)
        unexpected_EOF();
-    if (c != '<')
-       syntax_error(lineno, line, cptr);
-    tag = get_tag();
+    if (c == '<')
+       tag = get_tag();
 
     for (;;)
     {
        c = nextc();
+       if (c == EOF)
+           unexpected_EOF();
        if (isalpha(c) || c == '_' || c == '.' || c == '$')
+       {
            bp = get_name();
+#if defined(YYBTYACC)
+           if (nextc() == L_PAREN)
+               declare_argtypes(bp);
+           else
+               bp->args = 0;
+#endif
+       }
        else if (c == '\'' || c == '"')
+       {
            bp = get_literal();
+#if defined(YYBTYACC)
+           bp->args = 0;
+#endif
+       }
        else
            return;
 
-       if (bp->tag && tag != bp->tag)
-           retyped_warning(bp->name);
-       bp->tag = tag;
+       if (tag)
+       {
+           if (bp->tag && tag != bp->tag)
+               retyped_warning(bp->name);
+           bp->tag = tag;
+       }
     }
 }
 
@@ -1301,6 +1552,21 @@ read_declarations(void)
            copy_param(k);
            break;
 
+       case TOKEN_TABLE:
+           token_table = 1;
+           break;
+
+#if defined(YYBTYACC)
+       case LOCATIONS:
+           locations = 1;
+           break;
+
+       case DESTRUCTOR:
+           destructor = 1;
+           copy_destructor();
+           break;
+#endif
+
        case POSIX_YACC:
            /* noop for bison compatibility. byacc is already designed to be posix
             * yacc compatible. */
@@ -1371,65 +1637,409 @@ expand_rules(void)
     NO_SPACE(rassoc);
 }
 
-static void
-advance_to_start(void)
+/* set immediately prior to where copy_args() could be called, and incremented by
+   the various routines that will rescan the argument list as appropriate */
+static int rescan_lineno;
+#if defined(YYBTYACC)
+
+static char *
+copy_args(int *alen)
 {
-    int c;
-    bucket *bp;
-    char *s_cptr;
-    int s_lineno;
+    struct mstring *s = msnew();
+    int depth = 0, len = 1;
+    char c, quote = 0;
+    int a_lineno = lineno;
+    char *a_line = dup_line();
+    char *a_cptr = a_line + (cptr - line - 1);
 
-    for (;;)
+    while ((c = *cptr++) != R_PAREN || depth || quote)
     {
-       c = nextc();
-       if (c != '%')
-           break;
-       s_cptr = cptr;
-       switch (keyword())
+       if (c == ',' && !quote && !depth)
        {
-       case MARK:
-           no_grammar();
-
-       case TEXT:
-           copy_text();
-           break;
-
-       case START:
-           declare_start();
-           break;
-
-       default:
-           syntax_error(lineno, line, s_cptr);
+           len++;
+           mputc(s, 0);
+           continue;
+       }
+       mputc(s, c);
+       if (c == '\n')
+       {
+           get_line();
+           if (!line)
+           {
+               if (quote)
+                   unterminated_string(a_lineno, a_line, a_cptr);
+               else
+                   unterminated_arglist(a_lineno, a_line, a_cptr);
+           }
+       }
+       else if (quote)
+       {
+           if (c == quote)
+               quote = 0;
+           else if (c == '\\')
+           {
+               if (*cptr != '\n')
+                   mputc(s, *cptr++);
+           }
+       }
+       else
+       {
+           if (c == L_PAREN)
+               depth++;
+           else if (c == R_PAREN)
+               depth--;
+           else if (c == '\"' || c == '\'')
+               quote = c;
        }
     }
+    if (alen)
+       *alen = len;
+    FREE(a_line);
+    return msdone(s);
+}
 
-    c = nextc();
-    if (!isalpha(c) && c != '_' && c != '.' && c != '_')
-       syntax_error(lineno, line, cptr);
-    bp = get_name();
-    if (goal == 0)
+static char *
+parse_id(char *p, char **save)
+{
+    char *b;
+
+    while (isspace(*p))
+       if (*p++ == '\n')
+           rescan_lineno++;
+    if (!isalpha(*p) && *p != '_')
+       return NULL;
+    b = p;
+    while (isalnum(*p) || *p == '_' || *p == '$')
+       p++;
+    if (save)
     {
-       if (bp->class == TERM)
-           terminal_start(bp->name);
-       goal = bp;
+       *save = cache_tag(b, (size_t) (p - b));
     }
+    return p;
+}
 
-    s_lineno = lineno;
-    c = nextc();
-    if (c == EOF)
-       unexpected_EOF();
-    if (c != ':')
-       syntax_error(lineno, line, cptr);
-    start_rule(bp, s_lineno);
-    ++cptr;
+static char *
+parse_int(char *p, int *save)
+{
+    int neg = 0, val = 0;
+
+    while (isspace(*p))
+       if (*p++ == '\n')
+           rescan_lineno++;
+    if (*p == '-')
+    {
+       neg = 1;
+       p++;
+    }
+    if (!isdigit(*p))
+       return NULL;
+    while (isdigit(*p))
+       val = val * 10 + *p++ - '0';
+    if (neg)
+       val = -val;
+    if (save)
+       *save = val;
+    return p;
 }
 
 static void
-start_rule(bucket *bp, int s_lineno)
+parse_arginfo(bucket *a, char *args, int argslen)
 {
-    if (bp->class == TERM)
-       terminal_lhs(s_lineno);
-    bp->class = NONTERM;
+    char *p = args, *tmp;
+    int i, redec = 0;
+
+    if (a->args > 0)
+    {
+       if (a->args != argslen)
+           arg_number_disagree_warning(rescan_lineno, a->name);
+       redec = 1;
+    }
+    else
+    {
+       if ((a->args = argslen) == 0)
+           return;
+       a->argnames = TMALLOC(char *, argslen);
+       NO_SPACE(a->argnames);
+       a->argtags = TMALLOC(char *, argslen);
+       NO_SPACE(a->argtags);
+    }
+    if (!args)
+       return;
+    for (i = 0; i < argslen; i++)
+    {
+       while (isspace(*p))
+           if (*p++ == '\n')
+               rescan_lineno++;
+       if (*p++ != '$')
+           bad_formals();
+       while (isspace(*p))
+           if (*p++ == '\n')
+               rescan_lineno++;
+       if (*p == '<')
+       {
+           havetags = 1;
+           if (!(p = parse_id(p + 1, &tmp)))
+               bad_formals();
+           while (isspace(*p))
+               if (*p++ == '\n')
+                   rescan_lineno++;
+           if (*p++ != '>')
+               bad_formals();
+           if (redec)
+           {
+               if (a->argtags[i] != tmp)
+                   arg_type_disagree_warning(rescan_lineno, i + 1, a->name);
+           }
+           else
+               a->argtags[i] = tmp;
+       }
+       else if (!redec)
+           a->argtags[i] = NULL;
+       if (!(p = parse_id(p, &a->argnames[i])))
+           bad_formals();
+       while (isspace(*p))
+           if (*p++ == '\n')
+               rescan_lineno++;
+       if (*p++)
+           bad_formals();
+    }
+    free(args);
+}
+
+static char *
+compile_arg(char **theptr, char *yyvaltag)
+{
+    char *p = *theptr;
+    struct mstring *c = msnew();
+    int i, j, n;
+    Value_t *offsets = NULL, maxoffset;
+    bucket **rhs;
+
+    maxoffset = 0;
+    n = 0;
+    for (i = nitems - 1; pitem[i]; --i)
+    {
+       n++;
+       if (pitem[i]->class != ARGUMENT)
+           maxoffset++;
+    }
+    if (maxoffset > 0)
+    {
+       offsets = TMALLOC(Value_t, maxoffset + 1);
+       NO_SPACE(offsets);
+
+       for (j = 0, i++; i < nitems; i++)
+           if (pitem[i]->class != ARGUMENT)
+               offsets[++j] = (Value_t) (i - nitems + 1);
+    }
+    rhs = pitem + nitems - 1;
+
+    if (yyvaltag)
+       msprintf(c, "yyval.%s = ", yyvaltag);
+    else
+       msprintf(c, "yyval = ");
+    while (*p)
+    {
+       if (*p == '$')
+       {
+           char *tag = NULL;
+           if (*++p == '<')
+               if (!(p = parse_id(++p, &tag)) || *p++ != '>')
+                   illegal_tag(rescan_lineno, NULL, NULL);
+           if (isdigit(*p) || *p == '-')
+           {
+               int val;
+               if (!(p = parse_int(p, &val)))
+                   dollar_error(rescan_lineno, NULL, NULL);
+               if (val <= 0)
+                   i = val - n;
+               else if (val > maxoffset)
+               {
+                   dollar_warning(rescan_lineno, val);
+                   i = val - maxoffset;
+               }
+               else if (maxoffset > 0)
+               {
+                   i = offsets[val];
+                   if (!tag && !(tag = rhs[i]->tag) && havetags)
+                       untyped_rhs(val, rhs[i]->name);
+               }
+               msprintf(c, "yystack.l_mark[%d]", i);
+               if (tag)
+                   msprintf(c, ".%s", tag);
+               else if (havetags)
+                   unknown_rhs(val);
+           }
+           else if (isalpha(*p) || *p == '_')
+           {
+               char *arg;
+               if (!(p = parse_id(p, &arg)))
+                   dollar_error(rescan_lineno, NULL, NULL);
+               for (i = plhs[nrules]->args - 1; i >= 0; i--)
+                   if (arg == plhs[nrules]->argnames[i])
+                       break;
+               if (i < 0)
+                   unknown_arg_warning(rescan_lineno, "$", arg, NULL, NULL);
+               else if (!tag)
+                   tag = plhs[nrules]->argtags[i];
+               msprintf(c, "yystack.l_mark[%d]", i - plhs[nrules]->args + 1
+                        - n);
+               if (tag)
+                   msprintf(c, ".%s", tag);
+               else if (havetags)
+                   untyped_arg_warning(rescan_lineno, "$", arg);
+           }
+           else
+               dollar_error(rescan_lineno, NULL, NULL);
+       }
+       else if (*p == '@')
+       {
+           at_error(rescan_lineno, NULL, NULL);
+       }
+       else
+       {
+           if (*p == '\n')
+               rescan_lineno++;
+           mputc(c, *p++);
+       }
+    }
+    *theptr = p;
+    if (maxoffset > 0)
+       FREE(offsets);
+    return msdone(c);
+}
+
+#define ARG_CACHE_SIZE 1024
+static struct arg_cache
+{
+    struct arg_cache *next;
+    char *code;
+    int rule;
+}
+ *arg_cache[ARG_CACHE_SIZE];
+
+static int
+lookup_arg_cache(char *code)
+{
+    struct arg_cache *entry;
+
+    entry = arg_cache[strnshash(code) % ARG_CACHE_SIZE];
+    while (entry)
+    {
+       if (!strnscmp(entry->code, code))
+           return entry->rule;
+       entry = entry->next;
+    }
+    return -1;
+}
+
+static void
+insert_arg_cache(char *code, int rule)
+{
+    struct arg_cache *entry = NEW(struct arg_cache);
+    int i;
+
+    NO_SPACE(entry);
+    i = strnshash(code) % ARG_CACHE_SIZE;
+    entry->code = code;
+    entry->rule = rule;
+    entry->next = arg_cache[i];
+    arg_cache[i] = entry;
+}
+
+static void
+clean_arg_cache(void)
+{
+    struct arg_cache *e, *t;
+    int i;
+
+    for (i = 0; i < ARG_CACHE_SIZE; i++)
+    {
+       for (e = arg_cache[i]; (t = e); e = e->next, FREE(t))
+           free(e->code);
+       arg_cache[i] = NULL;
+    }
+}
+#endif
+
+static void
+advance_to_start(void)
+{
+    int c;
+    bucket *bp;
+    char *s_cptr;
+    int s_lineno;
+#if defined(YYBTYACC)
+    char *args = NULL;
+    int argslen = 0;
+#endif
+
+    for (;;)
+    {
+       c = nextc();
+       if (c != '%')
+           break;
+       s_cptr = cptr;
+       switch (keyword())
+       {
+       case MARK:
+           no_grammar();
+
+       case TEXT:
+           copy_text();
+           break;
+
+       case START:
+           declare_start();
+           break;
+
+       default:
+           syntax_error(lineno, line, s_cptr);
+       }
+    }
+
+    c = nextc();
+    if (!isalpha(c) && c != '_' && c != '.' && c != '_')
+       syntax_error(lineno, line, cptr);
+    bp = get_name();
+    if (goal == 0)
+    {
+       if (bp->class == TERM)
+           terminal_start(bp->name);
+       goal = bp;
+    }
+
+    s_lineno = lineno;
+    c = nextc();
+    if (c == EOF)
+       unexpected_EOF();
+    rescan_lineno = lineno;    /* line# for possible inherited args rescan */
+#if defined(YYBTYACC)
+    if (c == L_PAREN)
+    {
+       ++cptr;
+       args = copy_args(&argslen);
+       NO_SPACE(args);
+       c = nextc();
+    }
+#endif
+    if (c != ':')
+       syntax_error(lineno, line, cptr);
+    start_rule(bp, s_lineno);
+#if defined(YYBTYACC)
+    parse_arginfo(bp, args, argslen);
+#endif
+    ++cptr;
+}
+
+static void
+start_rule(bucket *bp, int s_lineno)
+{
+    if (bp->class == TERM)
+       terminal_lhs(s_lineno);
+    bp->class = NONTERM;
+    if (!bp->index)
+       bp->index = nrules;
     if (nrules >= maxrules)
        expand_rules();
     plhs[nrules] = bp;
@@ -1476,9 +2086,13 @@ insert_empty_rule(void)
     last_symbol->next = bp;
     last_symbol = bp;
     bp->tag = plhs[nrules]->tag;
-    bp->class = NONTERM;
+    bp->class = ACTION;
+#if defined(YYBTYACC)
+    bp->args = 0;
+#endif
 
-    if ((nitems += 2) > maxitems)
+    nitems = (Value_t) (nitems + 2);
+    if (nitems > maxitems)
        expand_items();
     bpp = pitem + nitems - 1;
     *bpp-- = bp;
@@ -1495,12 +2109,49 @@ insert_empty_rule(void)
     rassoc[nrules - 1] = TOKEN;
 }
 
+#if defined(YYBTYACC)
+static char *
+insert_arg_rule(char *arg, char *tag)
+{
+    int line_number = rescan_lineno;
+    char *code = compile_arg(&arg, tag);
+    int rule = lookup_arg_cache(code);
+    FILE *f = action_file;
+
+    if (rule < 0)
+    {
+       rule = nrules;
+       insert_arg_cache(code, rule);
+       fprintf(f, "case %d:\n", rule - 2);
+       if (!lflag)
+           fprintf(f, line_format, line_number, input_file_name);
+       fprintf(f, "%s;\n", code);
+       fprintf(f, "break;\n");
+       insert_empty_rule();
+       plhs[rule]->tag = tag;
+       plhs[rule]->class = ARGUMENT;
+    }
+    else
+    {
+       if (++nitems > maxitems)
+           expand_items();
+       pitem[nitems - 1] = plhs[rule];
+       free(code);
+    }
+    return arg + 1;
+}
+#endif
+
 static void
 add_symbol(void)
 {
     int c;
     bucket *bp;
     int s_lineno = lineno;
+#if defined(YYBTYACC)
+    char *args = NULL;
+    int argslen = 0;
+#endif
 
     c = *cptr;
     if (c == '\'' || c == '"')
@@ -1509,64 +2160,451 @@ add_symbol(void)
        bp = get_name();
 
     c = nextc();
+    rescan_lineno = lineno;    /* line# for possible inherited args rescan */
+#if defined(YYBTYACC)
+    if (c == L_PAREN)
+    {
+       ++cptr;
+       args = copy_args(&argslen);
+       NO_SPACE(args);
+       c = nextc();
+    }
+#endif
     if (c == ':')
     {
        end_rule();
        start_rule(bp, s_lineno);
+#if defined(YYBTYACC)
+       parse_arginfo(bp, args, argslen);
+#endif
        ++cptr;
        return;
     }
 
-    if (last_was_action)
-       insert_empty_rule();
-    last_was_action = 0;
+    if (last_was_action)
+       insert_empty_rule();
+    last_was_action = 0;
+
+#if defined(YYBTYACC)
+    if (bp->args < 0)
+       bp->args = argslen;
+    if (argslen == 0 && bp->args > 0 && pitem[nitems - 1] == NULL)
+    {
+       int i;
+       if (plhs[nrules]->args != bp->args)
+           wrong_number_args_warning("default ", bp->name);
+       for (i = bp->args - 1; i >= 0; i--)
+           if (plhs[nrules]->argtags[i] != bp->argtags[i])
+               wrong_type_for_arg_warning(i + 1, bp->name);
+    }
+    else if (bp->args != argslen)
+       wrong_number_args_warning("", bp->name);
+    if (bp->args > 0 && argslen > 0)
+    {
+       char *ap;
+       int i;
+       for (ap = args, i = 0; i < argslen; i++)
+           ap = insert_arg_rule(ap, bp->argtags[i]);
+       free(args);
+    }
+#endif /* defined(YYBTYACC) */
+
+    if (++nitems > maxitems)
+       expand_items();
+    pitem[nitems - 1] = bp;
+}
+
+static void
+copy_action(void)
+{
+    int c;
+    int i, j, n;
+    int depth;
+#if defined(YYBTYACC)
+    int trialaction = 0;
+    int haveyyval = 0;
+#endif
+    char *tag;
+    FILE *f = action_file;
+    int a_lineno = lineno;
+    char *a_line = dup_line();
+    char *a_cptr = a_line + (cptr - line);
+    Value_t *offsets = NULL, maxoffset;
+    bucket **rhs;
+
+    if (last_was_action)
+       insert_empty_rule();
+    last_was_action = 1;
+
+    fprintf(f, "case %d:\n", nrules - 2);
+#if defined(YYBTYACC)
+    if (backtrack)
+    {
+       if (*cptr != L_BRAC)
+           fprintf(f, "  if (!yytrial)\n");
+       else
+           trialaction = 1;
+    }
+#endif
+    if (!lflag)
+       fprintf(f, line_format, lineno, input_file_name);
+    if (*cptr == '=')
+       ++cptr;
+
+    /* avoid putting curly-braces in first column, to ease editing */
+    if (*after_blanks(cptr) == L_CURL)
+    {
+       putc('\t', f);
+       cptr = after_blanks(cptr);
+    }
+
+    maxoffset = 0;
+    n = 0;
+    for (i = nitems - 1; pitem[i]; --i)
+    {
+       ++n;
+       if (pitem[i]->class != ARGUMENT)
+           maxoffset++;
+    }
+    if (maxoffset > 0)
+    {
+       offsets = TMALLOC(Value_t, maxoffset + 1);
+       NO_SPACE(offsets);
+
+       for (j = 0, i++; i < nitems; i++)
+       {
+           if (pitem[i]->class != ARGUMENT)
+           {
+               offsets[++j] = (Value_t) (i - nitems + 1);
+           }
+       }
+    }
+    rhs = pitem + nitems - 1;
+
+    depth = 0;
+  loop:
+    c = *cptr;
+    if (c == '$')
+    {
+       if (cptr[1] == '<')
+       {
+           int d_lineno = lineno;
+           char *d_line = dup_line();
+           char *d_cptr = d_line + (cptr - line);
+
+           ++cptr;
+           tag = get_tag();
+           c = *cptr;
+           if (c == '$')
+           {
+               fprintf(f, "yyval.%s", tag);
+               ++cptr;
+               FREE(d_line);
+               goto loop;
+           }
+           else if (isdigit(c))
+           {
+               i = get_number();
+               if (i == 0)
+                   fprintf(f, "yystack.l_mark[%d].%s", -n, tag);
+               else if (i > maxoffset)
+               {
+                   dollar_warning(d_lineno, i);
+                   fprintf(f, "yystack.l_mark[%d].%s", i - maxoffset, tag);
+               }
+               else if (offsets)
+                   fprintf(f, "yystack.l_mark[%d].%s", offsets[i], tag);
+               FREE(d_line);
+               goto loop;
+           }
+           else if (c == '-' && isdigit(UCH(cptr[1])))
+           {
+               ++cptr;
+               i = -get_number() - n;
+               fprintf(f, "yystack.l_mark[%d].%s", i, tag);
+               FREE(d_line);
+               goto loop;
+           }
+#if defined(YYBTYACC)
+           else if (isalpha(c) || c == '_')
+           {
+               char *arg = scan_id();
+               for (i = plhs[nrules]->args - 1; i >= 0; i--)
+                   if (arg == plhs[nrules]->argnames[i])
+                       break;
+               if (i < 0)
+                   unknown_arg_warning(d_lineno, "$", arg, d_line, d_cptr);
+               fprintf(f, "yystack.l_mark[%d].%s", i - plhs[nrules]->args +
+                       1 - n, tag);
+               FREE(d_line);
+               goto loop;
+           }
+#endif
+           else
+               dollar_error(d_lineno, d_line, d_cptr);
+       }
+       else if (cptr[1] == '$')
+       {
+           if (havetags)
+           {
+               tag = plhs[nrules]->tag;
+               if (tag == 0)
+                   untyped_lhs();
+               fprintf(f, "yyval.%s", tag);
+           }
+           else
+               fprintf(f, "yyval");
+           cptr += 2;
+#if defined(YYBTYACC)
+           haveyyval = 1;
+#endif
+           goto loop;
+       }
+       else if (isdigit(UCH(cptr[1])))
+       {
+           ++cptr;
+           i = get_number();
+           if (havetags && offsets)
+           {
+               if (i <= 0 || i > maxoffset)
+                   unknown_rhs(i);
+               tag = rhs[offsets[i]]->tag;
+               if (tag == 0)
+                   untyped_rhs(i, rhs[offsets[i]]->name);
+               fprintf(f, "yystack.l_mark[%d].%s", offsets[i], tag);
+           }
+           else
+           {
+               if (i == 0)
+                   fprintf(f, "yystack.l_mark[%d]", -n);
+               else if (i > maxoffset)
+               {
+                   dollar_warning(lineno, i);
+                   fprintf(f, "yystack.l_mark[%d]", i - maxoffset);
+               }
+               else if (offsets)
+                   fprintf(f, "yystack.l_mark[%d]", offsets[i]);
+           }
+           goto loop;
+       }
+       else if (cptr[1] == '-')
+       {
+           cptr += 2;
+           i = get_number();
+           if (havetags)
+               unknown_rhs(-i);
+           fprintf(f, "yystack.l_mark[%d]", -i - n);
+           goto loop;
+       }
+#if defined(YYBTYACC)
+       else if (isalpha(cptr[1]) || cptr[1] == '_')
+       {
+           char *arg;
+           ++cptr;
+           arg = scan_id();
+           for (i = plhs[nrules]->args - 1; i >= 0; i--)
+               if (arg == plhs[nrules]->argnames[i])
+                   break;
+           if (i < 0)
+               unknown_arg_warning(lineno, "$", arg, line, cptr);
+           tag = (i < 0 ? NULL : plhs[nrules]->argtags[i]);
+           fprintf(f, "yystack.l_mark[%d]", i - plhs[nrules]->args + 1 - n);
+           if (tag)
+               fprintf(f, ".%s", tag);
+           else if (havetags)
+               untyped_arg_warning(lineno, "$", arg);
+           goto loop;
+       }
+#endif
+    }
+#if defined(YYBTYACC)
+    if (c == '@')
+    {
+       if (!locations)
+       {
+           int l_lineno = lineno;
+           char *l_line = dup_line();
+           char *l_cptr = l_line + (cptr - line);
+           syntax_error(l_lineno, l_line, l_cptr);
+       }
+       if (cptr[1] == '$')
+       {
+           fprintf(f, "yyloc");
+           cptr += 2;
+           goto loop;
+       }
+       else if (isdigit(UCH(cptr[1])))
+       {
+           ++cptr;
+           i = get_number();
+           if (i == 0)
+               fprintf(f, "yystack.p_mark[%d]", -n);
+           else if (i > maxoffset)
+           {
+               at_warning(lineno, i);
+               fprintf(f, "yystack.p_mark[%d]", i - maxoffset);
+           }
+           else if (offsets)
+               fprintf(f, "yystack.p_mark[%d]", offsets[i]);
+           goto loop;
+       }
+    }
+#endif
+    if (isalpha(c) || c == '_' || c == '$')
+    {
+       do
+       {
+           putc(c, f);
+           c = *++cptr;
+       }
+       while (isalnum(c) || c == '_' || c == '$');
+       goto loop;
+    }
+    ++cptr;
+#if defined(YYBTYACC)
+    if (backtrack)
+    {
+       if (trialaction && c == L_BRAC && depth == 0)
+       {
+           ++depth;
+           putc(L_CURL, f);
+           goto loop;
+       }
+       if (trialaction && c == R_BRAC && depth == 1)
+       {
+           --depth;
+           putc(R_CURL, f);
+           c = nextc();
+           if (c == L_BRAC && !haveyyval)
+           {
+               goto loop;
+           }
+           if (c == L_CURL && !haveyyval)
+           {
+               fprintf(f, "  if (!yytrial)\n");
+               if (!lflag)
+                   fprintf(f, line_format, lineno, input_file_name);
+               trialaction = 0;
+               goto loop;
+           }
+           fprintf(f, "\nbreak;\n");
+           FREE(a_line);
+           if (maxoffset > 0)
+               FREE(offsets);
+           return;
+       }
+    }
+#endif
+    putc(c, f);
+    switch (c)
+    {
+    case '\n':
+       get_line();
+       if (line)
+           goto loop;
+       unterminated_action(a_lineno, a_line, a_cptr);
+
+    case ';':
+       if (depth > 0)
+           goto loop;
+       fprintf(f, "\nbreak;\n");
+       free(a_line);
+       if (maxoffset > 0)
+           FREE(offsets);
+       return;
+
+#if defined(YYBTYACC)
+    case L_BRAC:
+       if (backtrack)
+           ++depth;
+       goto loop;
+
+    case R_BRAC:
+       if (backtrack)
+           --depth;
+       goto loop;
+#endif
+
+    case L_CURL:
+       ++depth;
+       goto loop;
+
+    case R_CURL:
+       if (--depth > 0)
+           goto loop;
+#if defined(YYBTYACC)
+       if (backtrack)
+       {
+           c = nextc();
+           if (c == L_BRAC && !haveyyval)
+           {
+               trialaction = 1;
+               goto loop;
+           }
+           if (c == L_CURL && !haveyyval)
+           {
+               fprintf(f, "  if (!yytrial)\n");
+               if (!lflag)
+                   fprintf(f, line_format, lineno, input_file_name);
+               goto loop;
+           }
+       }
+#endif
+       fprintf(f, "\nbreak;\n");
+       free(a_line);
+       if (maxoffset > 0)
+           FREE(offsets);
+       return;
+
+    case '\'':
+    case '"':
+       {
+           char *s = copy_string(c);
+           fputs(s, f);
+           free(s);
+       }
+       goto loop;
 
-    if (++nitems > maxitems)
-       expand_items();
-    pitem[nitems - 1] = bp;
-}
+    case '/':
+       {
+           char *s = copy_comment();
+           fputs(s, f);
+           free(s);
+       }
+       goto loop;
 
-static char *
-after_blanks(char *s)
-{
-    while (*s != '\0' && isspace(UCH(*s)))
-       ++s;
-    return s;
+    default:
+       goto loop;
+    }
 }
 
+#if defined(YYBTYACC)
 static void
-copy_action(void)
+copy_destructor(void)
 {
     int c;
-    int i, n;
     int depth;
-    int quote;
     char *tag;
-    FILE *f = action_file;
-    int a_lineno = lineno;
-    char *a_line = dup_line();
-    char *a_cptr = a_line + (cptr - line);
-
-    if (last_was_action)
-       insert_empty_rule();
-    last_was_action = 1;
+    bucket *bp;
+    struct mstring *destructor_text = msnew();
+    char *code_text;
+    int a_lineno;
+    char *a_line;
+    char *a_cptr;
 
-    fprintf(f, "case %d:\n", nrules - 2);
     if (!lflag)
-       fprintf(f, line_format, lineno, input_file_name);
-    if (*cptr == '=')
-       ++cptr;
+       msprintf(destructor_text, line_format, lineno, input_file_name);
 
-    /* avoid putting curly-braces in first column, to ease editing */
-    if (*after_blanks(cptr) == L_CURL)
-    {
-       putc('\t', f);
-       cptr = after_blanks(cptr);
-    }
+    cptr = after_blanks(cptr);
+    if (*cptr == L_CURL)
+       /* avoid putting curly-braces in first column, to ease editing */
+       mputc(destructor_text, '\t');
+    else
+       syntax_error(lineno, line, cptr);
 
-    n = 0;
-    for (i = nitems - 1; pitem[i]; --i)
-       ++n;
+    a_lineno = lineno;
+    a_line = dup_line();
+    a_cptr = a_line + (cptr - line);
 
     depth = 0;
   loop:
@@ -1584,25 +2622,8 @@ copy_action(void)
            c = *cptr;
            if (c == '$')
            {
-               fprintf(f, "yyval.%s", tag);
-               ++cptr;
-               FREE(d_line);
-               goto loop;
-           }
-           else if (isdigit(c))
-           {
-               i = get_number();
-               if (i > n)
-                   dollar_warning(d_lineno, i);
-               fprintf(f, "yystack.l_mark[%d].%s", i - n, tag);
-               FREE(d_line);
-               goto loop;
-           }
-           else if (c == '-' && isdigit(UCH(cptr[1])))
-           {
+               msprintf(destructor_text, "(*val).%s", tag);
                ++cptr;
-               i = -get_number() - n;
-               fprintf(f, "yystack.l_mark[%d].%s", i, tag);
                FREE(d_line);
                goto loop;
            }
@@ -1611,77 +2632,45 @@ copy_action(void)
        }
        else if (cptr[1] == '$')
        {
-           if (ntags)
-           {
-               tag = plhs[nrules]->tag;
-               if (tag == 0)
-                   untyped_lhs();
-               fprintf(f, "yyval.%s", tag);
-           }
-           else
-               fprintf(f, "yyval");
+           /* process '$$' later; replacement is context dependent */
+           msprintf(destructor_text, "$$");
            cptr += 2;
            goto loop;
        }
-       else if (isdigit(UCH(cptr[1])))
-       {
-           ++cptr;
-           i = get_number();
-           if (ntags)
-           {
-               if (i <= 0 || i > n)
-                   unknown_rhs(i);
-               tag = pitem[nitems + i - n - 1]->tag;
-               if (tag == 0)
-                   untyped_rhs(i, pitem[nitems + i - n - 1]->name);
-               fprintf(f, "yystack.l_mark[%d].%s", i - n, tag);
-           }
-           else
-           {
-               if (i > n)
-                   dollar_warning(lineno, i);
-               fprintf(f, "yystack.l_mark[%d]", i - n);
-           }
-           goto loop;
-       }
-       else if (cptr[1] == '-')
+    }
+    if (c == '@' && cptr[1] == '$')
+    {
+       if (!locations)
        {
-           cptr += 2;
-           i = get_number();
-           if (ntags)
-               unknown_rhs(-i);
-           fprintf(f, "yystack.l_mark[%d]", -i - n);
-           goto loop;
+           int l_lineno = lineno;
+           char *l_line = dup_line();
+           char *l_cptr = l_line + (cptr - line);
+           syntax_error(l_lineno, l_line, l_cptr);
        }
+       msprintf(destructor_text, "(*loc)");
+       cptr += 2;
+       goto loop;
     }
     if (isalpha(c) || c == '_' || c == '$')
     {
        do
        {
-           putc(c, f);
+           mputc(destructor_text, c);
            c = *++cptr;
        }
        while (isalnum(c) || c == '_' || c == '$');
        goto loop;
     }
-    putc(c, f);
     ++cptr;
+    mputc(destructor_text, c);
     switch (c)
     {
     case '\n':
-      next_line:
        get_line();
        if (line)
            goto loop;
        unterminated_action(a_lineno, a_line, a_cptr);
 
-    case ';':
-       if (depth > 0)
-           goto loop;
-       fprintf(f, "\nbreak;\n");
-       free(a_line);
-       return;
-
     case L_CURL:
        ++depth;
        goto loop;
@@ -1689,83 +2678,180 @@ copy_action(void)
     case R_CURL:
        if (--depth > 0)
            goto loop;
-       fprintf(f, "\nbreak;\n");
-       free(a_line);
-       return;
+       goto process_symbols;
 
     case '\'':
     case '"':
        {
-           int s_lineno = lineno;
-           char *s_line = dup_line();
-           char *s_cptr = s_line + (cptr - line - 1);
+           char *s = copy_string(c);
+           msprintf(destructor_text, "%s", s);
+           free(s);
+       }
+       goto loop;
+
+    case '/':
+       {
+           char *s = copy_comment();
+           msprintf(destructor_text, "%s", s);
+           free(s);
+       }
+       goto loop;
 
-           quote = c;
-           for (;;)
-           {
-               c = *cptr++;
-               putc(c, f);
-               if (c == quote)
+    default:
+       goto loop;
+    }
+  process_symbols:
+    code_text = msdone(destructor_text);
+    for (;;)
+    {
+       c = nextc();
+       if (c == EOF)
+           unexpected_EOF();
+       if (c == '<')
+       {
+           if (cptr[1] == '>')
+           {                   /* "no semantic type" default destructor */
+               cptr += 2;
+               if ((bp = default_destructor[UNTYPED_DEFAULT]) == NULL)
                {
-                   FREE(s_line);
-                   goto loop;
+                   static char untyped_default[] = "<>";
+                   bp = make_bucket("untyped default");
+                   bp->tag = untyped_default;
+                   default_destructor[UNTYPED_DEFAULT] = bp;
                }
-               if (c == '\n')
-                   unterminated_string(s_lineno, s_line, s_cptr);
-               if (c == '\\')
+               if (bp->destructor != NULL)
+                   destructor_redeclared_warning(a_lineno, a_line, a_cptr);
+               else
+                   /* replace "$$" with "(*val)" in destructor code */
+                   bp->destructor = process_destructor_XX(code_text, NULL);
+           }
+           else if (cptr[1] == '*' && cptr[2] == '>')
+           {                   /* "no per-symbol or per-type" default destructor */
+               cptr += 3;
+               if ((bp = default_destructor[TYPED_DEFAULT]) == NULL)
                {
-                   c = *cptr++;
-                   putc(c, f);
-                   if (c == '\n')
-                   {
-                       get_line();
-                       if (line == 0)
-                           unterminated_string(s_lineno, s_line, s_cptr);
-                   }
+                   static char typed_default[] = "<*>";
+                   bp = make_bucket("typed default");
+                   bp->tag = typed_default;
+                   default_destructor[TYPED_DEFAULT] = bp;
+               }
+               if (bp->destructor != NULL)
+                   destructor_redeclared_warning(a_lineno, a_line, a_cptr);
+               else
+               {
+                   /* postpone re-processing destructor $$s until end of grammar spec */
+                   bp->destructor = TMALLOC(char, strlen(code_text) + 1);
+                   NO_SPACE(bp->destructor);
+                   strcpy(bp->destructor, code_text);
                }
            }
+           else
+           {                   /* "semantic type" default destructor */
+               tag = get_tag();
+               bp = lookup_type_destructor(tag);
+               if (bp->destructor != NULL)
+                   destructor_redeclared_warning(a_lineno, a_line, a_cptr);
+               else
+                   /* replace "$$" with "(*val).tag" in destructor code */
+                   bp->destructor = process_destructor_XX(code_text, tag);
+           }
+       }
+       else if (isalpha(c) || c == '_' || c == '.' || c == '$')
+       {                       /* "symbol" destructor */
+           bp = get_name();
+           if (bp->destructor != NULL)
+               destructor_redeclared_warning(a_lineno, a_line, a_cptr);
+           else
+           {
+               /* postpone re-processing destructor $$s until end of grammar spec */
+               bp->destructor = TMALLOC(char, strlen(code_text) + 1);
+               NO_SPACE(bp->destructor);
+               strcpy(bp->destructor, code_text);
+           }
        }
+       else
+           break;
+    }
+    free(a_line);
+    free(code_text);
+}
 
-    case '/':
-       c = *cptr;
-       if (c == '/')
+static char *
+process_destructor_XX(char *code, char *tag)
+{
+    int c;
+    int quote;
+    int depth;
+    struct mstring *new_code = msnew();
+    char *codeptr = code;
+
+    depth = 0;
+  loop:                        /* step thru code */
+    c = *codeptr;
+    if (c == '$' && codeptr[1] == '$')
+    {
+       codeptr += 2;
+       if (tag == NULL)
+           msprintf(new_code, "(*val)");
+       else
+           msprintf(new_code, "(*val).%s", tag);
+       goto loop;
+    }
+    if (isalpha(c) || c == '_' || c == '$')
+    {
+       do
+       {
+           mputc(new_code, c);
+           c = *++codeptr;
+       }
+       while (isalnum(c) || c == '_' || c == '$');
+       goto loop;
+    }
+    ++codeptr;
+    mputc(new_code, c);
+    switch (c)
+    {
+    case L_CURL:
+       ++depth;
+       goto loop;
+
+    case R_CURL:
+       if (--depth > 0)
+           goto loop;
+       return msdone(new_code);
+
+    case '\'':
+    case '"':
+       quote = c;
+       for (;;)
        {
-           putc('*', f);
-           while ((c = *++cptr) != '\n')
+           c = *codeptr++;
+           mputc(new_code, c);
+           if (c == quote)
+               goto loop;
+           if (c == '\\')
            {
-               if (c == '*' && cptr[1] == '/')
-                   fprintf(f, "* ");
-               else
-                   putc(c, f);
+               c = *codeptr++;
+               mputc(new_code, c);
            }
-           fprintf(f, "*/\n");
-           goto next_line;
        }
+
+    case '/':
+       c = *codeptr;
        if (c == '*')
        {
-           int c_lineno = lineno;
-           char *c_line = dup_line();
-           char *c_cptr = c_line + (cptr - line - 1);
-
-           putc('*', f);
-           ++cptr;
+           mputc(new_code, c);
+           ++codeptr;
            for (;;)
            {
-               c = *cptr++;
-               putc(c, f);
-               if (c == '*' && *cptr == '/')
+               c = *codeptr++;
+               mputc(new_code, c);
+               if (c == '*' && *codeptr == '/')
                {
-                   putc('/', f);
-                   ++cptr;
-                   FREE(c_line);
+                   mputc(new_code, '/');
+                   ++codeptr;
                    goto loop;
                }
-               if (c == '\n')
-               {
-                   get_line();
-                   if (line == 0)
-                       unterminated_comment(c_lineno, c_line, c_cptr);
-               }
            }
        }
        goto loop;
@@ -1774,6 +2860,7 @@ copy_action(void)
        goto loop;
     }
 }
+#endif /* defined(YYBTYACC) */
 
 static int
 mark_symbol(void)
@@ -1807,7 +2894,6 @@ mark_symbol(void)
     else
     {
        syntax_error(lineno, line, cptr);
-       /*NOTREACHED */
     }
 
     if (rprec[nrules] != UNDEFINED && bp->prec != rprec[nrules])
@@ -1838,7 +2924,11 @@ read_grammar(void)
            || c == '\''
            || c == '"')
            add_symbol();
+#if defined(YYBTYACC)
+       else if (c == L_CURL || c == '=' || (backtrack && c == L_BRAC))
+#else
        else if (c == L_CURL || c == '=')
+#endif
            copy_action();
        else if (c == '|')
        {
@@ -1855,6 +2945,10 @@ read_grammar(void)
            syntax_error(lineno, line, cptr);
     }
     end_rule();
+#if defined(YYBTYACC)
+    if (goal->args > 0)
+       start_requires_args(goal->name);
+#endif
 }
 
 static void
@@ -1958,6 +3052,9 @@ pack_symbols(void)
     bucket *bp;
     bucket **v;
     Value_t i, j, k, n;
+#if defined(YYBTYACC)
+    Value_t max_tok_pval;
+#endif
 
     nsyms = 2;
     ntokens = 1;
@@ -1968,7 +3065,7 @@ pack_symbols(void)
            ++ntokens;
     }
     start_symbol = (Value_t) ntokens;
-    nvars = nsyms - ntokens;
+    nvars = (Value_t) (nsyms - ntokens);
 
     symbol_name = TMALLOC(char *, nsyms);
     NO_SPACE(symbol_name);
@@ -1976,12 +3073,26 @@ pack_symbols(void)
     symbol_value = TMALLOC(Value_t, nsyms);
     NO_SPACE(symbol_value);
 
-    symbol_prec = TMALLOC(short, nsyms);
+    symbol_prec = TMALLOC(Value_t, nsyms);
     NO_SPACE(symbol_prec);
 
     symbol_assoc = TMALLOC(char, nsyms);
     NO_SPACE(symbol_assoc);
 
+#if defined(YYBTYACC)
+    symbol_pval = TMALLOC(Value_t, nsyms);
+    NO_SPACE(symbol_pval);
+
+    if (destructor)
+    {
+       symbol_destructor = CALLOC(sizeof(char *), nsyms);
+       NO_SPACE(symbol_destructor);
+
+       symbol_type_tag = CALLOC(sizeof(char *), nsyms);
+       NO_SPACE(symbol_type_tag);
+    }
+#endif
+
     v = TMALLOC(bucket *, nsyms);
     NO_SPACE(v);
 
@@ -2060,17 +3171,34 @@ pack_symbols(void)
     symbol_value[0] = 0;
     symbol_prec[0] = 0;
     symbol_assoc[0] = TOKEN;
+#if defined(YYBTYACC)
+    symbol_pval[0] = 0;
+    max_tok_pval = 0;
+#endif
     for (i = 1; i < ntokens; ++i)
     {
        symbol_name[i] = v[i]->name;
        symbol_value[i] = v[i]->value;
        symbol_prec[i] = v[i]->prec;
        symbol_assoc[i] = v[i]->assoc;
+#if defined(YYBTYACC)
+       symbol_pval[i] = v[i]->value;
+       if (symbol_pval[i] > max_tok_pval)
+           max_tok_pval = symbol_pval[i];
+       if (destructor)
+       {
+           symbol_destructor[i] = v[i]->destructor;
+           symbol_type_tag[i] = v[i]->tag;
+       }
+#endif
     }
     symbol_name[start_symbol] = name_pool;
     symbol_value[start_symbol] = -1;
     symbol_prec[start_symbol] = 0;
     symbol_assoc[start_symbol] = TOKEN;
+#if defined(YYBTYACC)
+    symbol_pval[start_symbol] = (Value_t) (max_tok_pval + 1);
+#endif
     for (++i; i < nsyms; ++i)
     {
        k = v[i]->index;
@@ -2078,6 +3206,14 @@ pack_symbols(void)
        symbol_value[k] = v[i]->value;
        symbol_prec[k] = v[i]->prec;
        symbol_assoc[k] = v[i]->assoc;
+#if defined(YYBTYACC)
+       symbol_pval[k] = (Value_t) ((max_tok_pval + 1) + v[i]->value + 1);
+       if (destructor)
+       {
+           symbol_destructor[k] = v[i]->destructor;
+           symbol_type_tag[k] = v[i]->tag;
+       }
+#endif
     }
 
     if (gflag)
@@ -2129,6 +3265,21 @@ pack_grammar(void)
     j = 4;
     for (i = 3; i < nrules; ++i)
     {
+#if defined(YYBTYACC)
+       if (plhs[i]->args > 0)
+       {
+           if (plhs[i]->argnames)
+           {
+               FREE(plhs[i]->argnames);
+               plhs[i]->argnames = NULL;
+           }
+           if (plhs[i]->argtags)
+           {
+               FREE(plhs[i]->argtags);
+               plhs[i]->argtags = NULL;
+           }
+       }
+#endif /* defined(YYBTYACC) */
        rlhs[i] = plhs[i]->index;
        rrhs[i] = j;
        assoc = TOKEN;
@@ -2155,6 +3306,9 @@ pack_grammar(void)
 
     FREE(plhs);
     FREE(pitem);
+#if defined(YYBTYACC)
+    clean_arg_cache();
+#endif
 }
 
 static void
@@ -2196,6 +3350,85 @@ print_grammar(void)
     }
 }
 
+#if defined(YYBTYACC)
+static void
+finalize_destructors(void)
+{
+    int i;
+    bucket *bp;
+    char *tag;
+
+    for (i = 2; i < nsyms; ++i)
+    {
+       tag = symbol_type_tag[i];
+       if (symbol_destructor[i] == NULL)
+       {
+           if (tag == NULL)
+           {                   /* use <> destructor, if there is one */
+               if ((bp = default_destructor[UNTYPED_DEFAULT]) != NULL)
+               {
+                   symbol_destructor[i] = TMALLOC(char,
+                                                  strlen(bp->destructor) + 1);
+                   NO_SPACE(symbol_destructor[i]);
+                   strcpy(symbol_destructor[i], bp->destructor);
+               }
+           }
+           else
+           {                   /* use type destructor for this tag, if there is one */
+               bp = lookup_type_destructor(tag);
+               if (bp->destructor != NULL)
+               {
+                   symbol_destructor[i] = TMALLOC(char,
+                                                  strlen(bp->destructor) + 1);
+                   NO_SPACE(symbol_destructor[i]);
+                   strcpy(symbol_destructor[i], bp->destructor);
+               }
+               else
+               {               /* use <*> destructor, if there is one */
+                   if ((bp = default_destructor[TYPED_DEFAULT]) != NULL)
+                       /* replace "$$" with "(*val).tag" in destructor code */
+                       symbol_destructor[i]
+                           = process_destructor_XX(bp->destructor, tag);
+               }
+           }
+       }
+       else
+       {                       /* replace "$$" with "(*val)[.tag]" in destructor code */
+           symbol_destructor[i]
+               = process_destructor_XX(symbol_destructor[i], tag);
+       }
+    }
+    /* 'symbol_type_tag[]' elements are freed by 'free_tags()' */
+    DO_FREE(symbol_type_tag);  /* no longer needed */
+    if ((bp = default_destructor[UNTYPED_DEFAULT]) != NULL)
+    {
+       FREE(bp->name);
+       /* 'bp->tag' is a static value, don't free */
+       FREE(bp->destructor);
+       FREE(bp);
+    }
+    if ((bp = default_destructor[TYPED_DEFAULT]) != NULL)
+    {
+       FREE(bp->name);
+       /* 'bp->tag' is a static value, don't free */
+       FREE(bp->destructor);
+       FREE(bp);
+    }
+    if ((bp = default_destructor[TYPE_SPECIFIED]) != NULL)
+    {
+       bucket *p;
+       for (; bp; bp = p)
+       {
+           p = bp->link;
+           FREE(bp->name);
+           /* 'bp->tag' freed by 'free_tags()' */
+           FREE(bp->destructor);
+           FREE(bp);
+       }
+    }
+}
+#endif /* defined(YYBTYACC) */
+
 void
 reader(void)
 {
@@ -2204,13 +3437,17 @@ reader(void)
     read_declarations();
     read_grammar();
     free_symbol_table();
-    free_tags();
     pack_names();
     check_symbols();
     pack_symbols();
     pack_grammar();
     free_symbols();
     print_grammar();
+#if defined(YYBTYACC)
+    if (destructor)
+       finalize_destructors();
+#endif
+    free_tags();
 }
 
 #ifdef NO_LEAKS
@@ -2247,5 +3484,10 @@ reader_leaks(void)
     DO_FREE(symbol_prec);
     DO_FREE(symbol_assoc);
     DO_FREE(symbol_value);
+#if defined(YYBTYACC)
+    DO_FREE(symbol_pval);
+    DO_FREE(symbol_destructor);
+    DO_FREE(symbol_type_tag);
+#endif
 }
 #endif
index 9839180..e7f6fad 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: symtab.c,v 1.10 2012/05/26 15:16:12 tom Exp $ */
+/* $Id: symtab.c,v 1.11 2014/03/26 00:17:09 Tom.Shields Exp $ */
 
 #include "defs.h"
 
@@ -48,6 +48,12 @@ make_bucket(const char *name)
     bp->prec = 0;
     bp->class = UNKNOWN;
     bp->assoc = TOKEN;
+#if defined(YYBTYACC)
+    bp->args = -1;
+    bp->argnames = 0;
+    bp->argtags = 0;
+    bp->destructor = 0;
+#endif
     strcpy(bp->name, name);
 
     return (bp);
index 3e6ea28..b4e1102 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: verbose.c,v 1.10 2012/05/26 00:45:17 tom Exp $ */
+/* $Id: verbose.c,v 1.11 2014/04/01 23:15:59 Tom.Shields Exp $ */
 
 #include "defs.h"
 
@@ -13,7 +13,7 @@ static void print_shifts(action *p);
 static void print_state(int state);
 static void print_reductions(action *p, int defred2);
 
-static short *null_rules;
+static Value_t *null_rules;
 
 void
 verbose(void)
@@ -23,7 +23,7 @@ verbose(void)
     if (!vflag)
        return;
 
-    null_rules = TMALLOC(short, nrules);
+    null_rules = TMALLOC(Value_t, nrules);
     NO_SPACE(null_rules);
 
     fprintf(verbose_file, "\f\n");
@@ -39,13 +39,33 @@ verbose(void)
     fprintf(verbose_file, "\n\n%d terminals, %d nonterminals\n", ntokens,
            nvars);
     fprintf(verbose_file, "%d grammar rules, %d states\n", nrules - 2, nstates);
+#if defined(YYBTYACC)
+    {                          /* print out the grammar symbol # and parser internal symbol # for each
+                                  symbol as an aide to writing the implementation for YYDESTRUCT_CALL()
+                                  and YYSTYPE_TOSTRING() */
+       int maxtok = 0;
+
+       fputs("\ngrammar parser grammar\n", verbose_file);
+       fputs("symbol# value# symbol\n", verbose_file);
+       for (i = 0; i < ntokens; ++i)
+       {
+           fprintf(verbose_file, " %5d  %5d  %s\n",
+                   i, symbol_value[i], symbol_name[i]);
+           if (symbol_value[i] > maxtok)
+               maxtok = symbol_value[i];
+       }
+       for (i = ntokens; i < nsyms; ++i)
+           fprintf(verbose_file, " %5d  %5d  %s\n",
+                   i, (maxtok + 1) + symbol_value[i] + 1, symbol_name[i]);
+    }
+#endif
 }
 
 static void
 log_unused(void)
 {
     int i;
-    short *p;
+    Value_t *p;
 
     fprintf(verbose_file, "\n\nRules never reduced:\n");
     for (i = 3; i < nrules; ++i)
@@ -155,8 +175,8 @@ print_core(int state)
     int k;
     int rule;
     core *statep;
-    short *sp;
-    short *sp1;
+    Value_t *sp;
+    Value_t *sp1;
 
     statep = state_table[state];
     k = statep->nitems;
@@ -273,6 +293,11 @@ print_shifts(action *p)
            if (p->action_code == SHIFT && p->suppressed == 0)
                fprintf(verbose_file, "\t%s  shift %d\n",
                        symbol_name[p->symbol], p->number);
+#if defined(YYBTYACC)
+           if (backtrack && p->action_code == SHIFT && p->suppressed == 1)
+               fprintf(verbose_file, "\t%s  [trial] shift %d\n",
+                       symbol_name[p->symbol], p->number);
+#endif
        }
     }
 }
@@ -305,6 +330,11 @@ print_reductions(action *p, int defred2)
                if (p->suppressed == 0)
                    fprintf(verbose_file, "\t%s  reduce %d\n",
                            symbol_name[p->symbol], k);
+#if defined(YYBTYACC)
+               if (backtrack && p->suppressed == 1)
+                   fprintf(verbose_file, "\t%s  [trial] reduce %d\n",
+                           symbol_name[p->symbol], k);
+#endif
            }
        }
 
@@ -318,7 +348,7 @@ print_gotos(int stateno)
 {
     int i, k;
     int as;
-    short *to_state2;
+    Value_t *to_state2;
     shifts *sp;
 
     putc('\n', verbose_file);
index 239380a..8076ab0 100644 (file)
@@ -1,4 +1,4 @@
-.\" $Id: yacc.1,v 1.18 2012/01/15 18:12:28 tom Exp $
+.\" $Id: yacc.1,v 1.24 2014/10/06 00:03:48 tom Exp $
 .\"
 .\" .TH YACC 1 "July\ 15,\ 1990"
 .\" .UC 6
@@ -8,20 +8,29 @@
 .sp
 .in +4
 ..
-.de EE
+.de XE
 .in -4
 .fi
 ..
+.\" Escape single quotes in literal strings from groff's Unicode transform.
+.ie \n(.g .ds AQ \(aq
+.el       .ds AQ '
+.ie \n(.g .ds `` \(lq
+.el       .ds `` ``
+.ie \n(.g .ds '' \(rq
+.el       .ds '' ''
 .\" Bulleted paragraph
 .de bP
 .IP \(bu 4
 ..
-.TH YACC 1 "September 7, 2011" "Berkeley Yacc" "User Commands"
+.TH YACC 1 "October 5, 2014" "Berkeley Yacc" "User Commands"
 .SH NAME
 Yacc \- an LALR(1) parser generator
 .SH SYNOPSIS
-.B yacc [ -dgilrtv ] [ \-b
+.B yacc [ -BdgilLPrtvVy ] [ \-b
 .I file_prefix
+.B ] [ \-o
+.I output_file
 .B ] [ \-p
 .I symbol_prefix
 .B ]
@@ -48,6 +57,9 @@ the string denoted by
 The default prefix is the character
 .IR y.
 .TP
+.B \-B
+create a backtracking parser (compile-type configuration for \fBbtyacc\fP).
+.TP
 .B \-d
 The \fB-d\fR option causes the header file
 .BR y.tab.h
@@ -89,11 +101,14 @@ If the \fB-l\fR option is specified,
 will not insert the \fI#line\fP directives.
 \&\fI#line\fP directives specified by the user will be retained.
 .TP
+.B \-L
+enable position processing, e.g., \*(``%locations\*('' (compile-type configuration for \fBbtyacc\fP).
+.TP
 \fB\-o \fP\fIoutput_file\fR
 specify the filename for the parser file.
 If this option is not given, the output filename is
 the file prefix concatenated with the file suffix, e.g., \fBy.tab.c\fP.
-This overrides the \fB-p\fP option.
+This overrides the \fB-b\fP option.
 .TP
 \fB\-p \fP\fIsymbol_prefix\fR
 The
@@ -105,30 +120,31 @@ The default prefix is the string
 .BR yy.
 .TP
 .B \-P
-create a reentrant parser, e.g., "%pure-parser".
+create a reentrant parser, e.g., \*(``%pure-parser\*(''.
 .TP
 .B \-r
 The
 .B \-r
 option causes
 .B yacc
-to produce separate files for code and tables.  The code file
-is named
+to produce separate files for code and tables.
+The code file is named
 .IR y.code.c,
 and the tables file is named
 .IR y.tab.c.
-The prefix "\fIy.\fP" can be overridden using the \fB\-b\fP option.
+The prefix \*(``\fIy.\fP\*('' can be overridden using the \fB\-b\fP option.
 .TP
 .B \-s
-suppress "\fB#define\fP" statements generated for string literals in
-a "\fB%token\fP" statement, to more closely match original \fByacc\fP behavior.
+suppress \*(``\fB#define\fP\*('' statements generated for string literals in
+a \*(``\fB%token\fP\*('' statement,
+to more closely match original \fByacc\fP behavior.
 .IP
 Normally when \fByacc\fP sees a line such as
 .ES
 %token OP_ADD "ADD"
-.EE
+.XE
 .IP
-it notices that the quoted "ADD" is a valid C identifier,
+it notices that the quoted \*(``ADD\*('' is a valid C identifier,
 and generates a #define not only for OP_ADD,
 but for ADD as well,
 e.g.,
@@ -136,12 +152,13 @@ e.g.,
 #define OP_ADD 257
 .br
 #define ADD 258
-.EE
+.XE
 .IP
-The original \fByacc\fP does not generate the second "\fB#define\fP".
-The \fB\-s\fP option suppresses this "\fB#define\fP".
+The original \fByacc\fP does not generate the second \*(``\fB#define\fP\*(''.
+The \fB\-s\fP option suppresses this \*(``\fB#define\fP\*(''.
 .IP
-POSIX (IEEE 1003.1 2004) documents only names and numbers for "\fB%token\fP",
+POSIX (IEEE 1003.1 2004) documents only names and numbers
+for \*(``\fB%token\fP\*('',
 though original \fByacc\fP and bison also accept string literals.
 .TP
 .B \-t
@@ -166,11 +183,56 @@ print the version number to the standard output.
 which bison supports for ostensible POSIX compatibility.
 .SH EXTENSIONS
 .B yacc
-provides some extensions for compatibility with bison and other implementations
-of yacc:
+provides some extensions for
+compatibility with bison and other implementations of yacc.
+The \fB%destructor\fP and \fB%locations\fP features are available
+only if \fByacc\fP has been configured and compiled to support the
+back-tracking (\fBbtyacc\fP) functionality.
+The remaining features are always available:
+.TP
+\fB %destructor\fP { \fIcode\fP } \fIsymbol+\fP
+defines code that is invoked when a symbol is automatically
+discarded during error recovery.
+This code can be used to
+reclaim dynamically allocated memory associated with the corresponding
+semantic value for cases where user actions cannot manage the memory
+explicitly.
+.IP
+On encountering a parse error, the generated parser
+discards symbols on the stack and input tokens until it reaches a state
+that will allow parsing to continue.
+This error recovery approach results in a memory leak
+if the \fBYYSTYPE\fP value is, or contains,
+pointers to dynamically allocated memory.
+.IP
+The bracketed \fIcode\fP is invoked whenever the parser discards one of
+the symbols. Within \fIcode\fP, \*(``\fB$$\fP\*('' or
+\*(``\fB$<tag>$\fP\*('' designates the semantic value associated with the
+discarded symbol, and  \*(``\fB@$\fP\*('' designates its location (see
+\fB%locations\fP directive).
+.IP
+A per-symbol destructor is defined by listing a grammar symbol
+in \fIsymbol+\fP.  A per-type destructor is defined  by listing
+a semantic type tag (e.g., \*(``<some_tag>\*('') in \fIsymbol+\fP; in this
+case, the parser will invoke \fIcode\fP whenever it discards any grammar
+symbol that has that semantic type tag, unless that symbol has its own
+per-symbol destructor.
+.IP
+Two categories of default destructor are supported that are
+invoked when discarding any grammar symbol that has no per-symbol and no
+per-type destructor:
+.RS
+.bP
+the code for \*(``\fB<*>\fP\*('' is used
+for grammar symbols that have an explicitly declared semantic type tag
+(via \*(``\fB%type\fP\*('');
+.bP
+the code for \*(``\fB<>\fP\*('' is used
+for grammar symbols that have no declared semantic type tag.
+.RE
 .TP
 \fB %expect\fP \fInumber\fP
-tell \fByacc\fP the expected number of shift/reduce conflicts.
+tells \fByacc\fP the expected number of shift/reduce conflicts.
 That makes it only report the number if it differs.
 .TP
 \fB %expect-rr\fP \fInumber\fP
@@ -178,6 +240,42 @@ tell \fByacc\fP the expected number of reduce/reduce conflicts.
 That makes it only report the number if it differs.
 This is (unlike bison) allowable in LALR parsers.
 .TP
+\fB %locations\fP
+tells \fByacc\fP to enable  management of position information associated
+with each token, provided by the lexer in the global variable \fByylloc\fP,
+similar to management of semantic value information provided in \fByylval\fP.
+.IP
+As for semantic values, locations can be referenced within actions using
+\fB@$\fP to refer to the location of the left hand side symbol, and \fB@N\fP
+(\fBN\fP an integer) to refer to the location of one of the right hand side
+symbols. Also as for semantic values, when a rule is matched, a default
+action is used the compute the location represented by \fB@$\fP as the
+beginning of the first symbol and the end of the last symbol in the right
+hand side of the rule. This default computation can be overridden by
+explicit assignment to \fB@$\fP in a rule action.
+.IP
+The type of \fByylloc\fP is \fBYYLTYPE\fP, which is defined by default as:
+.ES
+typedef struct YYLTYPE {
+    int first_line;
+    int first_column;
+    int last_line;
+    int last_column;
+} YYLTYPE;
+.XE
+.IP
+\fBYYLTYPE\fP can be redefined by the user
+(\fBYYLTYPE_IS_DEFINED\fP must be defined, to inhibit the default)
+in the declarations section of the specification file.
+As in bison, the macro \fBYYLLOC_DEFAULT\fP is invoked
+each time a rule is matched to calculate a position for the left hand side of
+the rule, before the associated action is executed; this macro can be
+redefined by the user.
+.IP
+This directive adds a \fBYYLTYPE\fP parameter to \fByyerror()\fP.
+If the \fB%pure-parser\fP directive is present,
+a \fBYYLTYPE\fP parameter is added to \fByylex()\fP calls.
+.TP
 \fB %lex-param\fP { \fIargument-declaration\fP }
 By default, the lexer accepts no parameters, e.g., \fByylex()\fP.
 Use this directive to add parameter declarations for your customized lexer.
@@ -190,6 +288,13 @@ Use this directive to add parameter declarations for your customized parser.
 Most variables (other than \fByydebug\fP and \fByynerrs\fP) are
 allocated on the stack within \fByyparse\fP, making the parser reasonably
 reentrant.
+.TP
+\fB %token-table\fP
+Make the parser's names for tokens available in the \fByytname\fP array.
+However,
+.B yacc
+does not predefine \*(``$end\*('', \*(``$error\*(''
+or \*(``$undefined\*('' in this array.
 .SH PORTABILITY
 According to Robert Corbett,
 .ES
@@ -198,17 +303,17 @@ as compatible as possible with AT&T Yacc.  Berkeley Yacc can accept any input
 specification that conforms to the AT&T Yacc documentation.  Specifications
 that take advantage of undocumented features of AT&T Yacc will probably be
 rejected.
-.EE
+.XE
 .PP
 The rationale in
 .ES
 http://pubs.opengroup.org/onlinepubs/9699919799/utilities/yacc.html
-.EE
+.XE
 .PP
 documents some features of AT&T yacc which are no longer required for POSIX
 compliance.
 .PP
-That said, you may be interested in reusing grammary files with some
+That said, you may be interested in reusing grammar files with some
 other implementation which is not strictly compatible with AT&T yacc.
 For instance, there is bison.
 Here are a few differences:
@@ -220,20 +325,37 @@ of an action (as in the original grammar file \fBftp.y\fP):
                = {
                        statcmd();
                }
-.EE
+.XE
 .bP
 \fBYacc\fP and bison emit code in different order, and in particular bison
 makes forward reference to common functions such as yylex, yyparse and
 yyerror without providing prototypes.
 .bP
-Bison's support for "%expect" is broken in more than one release.
+Bison's support for \*(``%expect\*('' is broken in more than one release.
 For best results using bison, delete that directive.
 .bP
 Bison has no equivalent for some of \fByacc\fP's commmand-line options,
 relying on directives embedded in the grammar file.
 .bP
-Bison's "\fB\-y\fP" option does not affect bison's lack of support for
+Bison's \*(``\fB\-y\fP\*('' option does not affect bison's lack of support for
 features of AT&T yacc which were deemed obsolescent.
+.bP
+\fBYacc\fP accepts multiple parameters with \fB%lex-param\fP and \fB%parse-param\fP
+in two forms
+.ES
+{type1 name1} {type2 name2} ...
+{type1 name1,  type2 name2 ...}
+.XE
+.IP
+Bison accepts the latter (though undocumented), but depending on the
+release may generate bad code.
+.bP
+Like bison, \fByacc\fP will add parameters specified via \fB%parse-param\fP
+to \fByyparse\fP, \fByyerror\fP and (if configured for back-tracking)
+to the destructor declared using \fB%destructor\fP.
+Bison puts the additional parameters \fIfirst\fP for
+\fByyparse\fP and \fByyerror\fP but \fIlast\fP for destructors.
+\fBYacc\fP matches this behavior.
 .
 .SH DIAGNOSTICS
 If there are rules that are never reduced, the number of such rules is