Compare commits

...
297 Commits
Author SHA1 Message Date
Akim Demaille 10acc148bb version 3.4.90
* NEWS: Record release date.
2019-10-29 21:41:00 +01:00
Akim Demaille 28f1e1546c C++: finish propagating the unsigned->signed conversion in locations
* data/skeletons/location.cc: Remove the u (for unsigned) suffix from
the initial line and column.
* NEWS: AFAICT, only C++ backends have their location types changed.
2019-10-29 09:15:25 +01:00
Akim Demaille c53b379784 style: fix cpp indentation
Reported by syntax-check.

* src/system.h: here.
2019-10-29 09:00:46 +01:00
Akim Demaille fead28d9e3 style: glr.c: comment changes
* data/skeletons/glr.c: here.
2019-10-29 08:59:18 +01:00
Akim Demaille 7e0b50c524 CI: pass -O1 to GCC8 with sanitizers
This build never finishes in the 50min credit given by Travis.  See if
with optimizations it works better.

* .travis.yml: here.
2019-10-26 10:39:01 +02:00
Akim Demaille 8228d96d33 reader: reduce the "scope" of global variables
We have too many global variables, adding structure would help.  For a
start, let's hide some of the variables closer to their usage.

* src/getargs.c, src/files.h (current_file): Move to...
* src/scan-gram.c: here.
* src/scan-gram.h (gram_in, gram__flex_debug): Remove, make them
private to the scanner.
* src/reader.h, src/reader.c (reader): Take a grammar file as argument.
Move the handling of scanner variables to...
* src/scan-gram.l (gram_scanner_open, gram_scanner_close): here.
(gram_scanner_initialize): Remove, replaced by gram_scanner_open.
* src/main.c: Adjust.
2019-10-26 10:39:01 +02:00
Akim Demaille a5fc4e3b44 regen 2019-10-26 10:39:01 +02:00
Akim Demaille 3be912e4af parser: use grammar_file instead of current_file
* src/parse-gram (%initial-action): here.
(handle_skeleton): Don't depend on the current file name to look for
"local" skeletons (subject to changes coming from "#lines"): depend
only on the initial file name, the one given on the command line.
2019-10-26 10:38:39 +02:00
Akim Demaille 4b4e532748 diagnostics: use grammar_file instead of current_file
Currently there are two globals denoting the input file: grammar_file
is the one from the command line, and current_file which might change
because of #line.  Use only the former.

* src/complain.c (error_message): here.
* tests/diagnostics.at: Adjust.
2019-10-26 09:11:40 +02:00
Akim Demaille 6e7d8ba6a7 reader: let symtab deal with the symbols
* src/reader.c (reader): Move the setting up of the builtin symbols to...
* src/symtab.c (symbols_new): here.
2019-10-25 07:48:07 +02:00
Akim Demaille c680300a29 style: remove incorrect comment
Reported by Paul Eggert.

* src/system.h: here.
2019-10-25 07:41:38 +02:00
Akim Demaille 0cbefb71e8 lalr1.cc: fix previous commit: printing of state numbers
* data/skeletons/lalr1.cc: Printing a char prints... a char.
Print ints instead.
2019-10-24 23:02:26 +02:00
Akim Demaille 402332c4b6 lalr1.cc: use computed state types
This skeleton uses a single stack of state structures, so it is less
likely to benefit from a stack size reduction than yacc.c (which uses
several stacks: state number, value and location).  But it will reduce
the size of the LAC stack.

This skeleton was already using int for state numbers, so, contrary to
yacc.c, this brings nothing for large automata.

Overall, it is still nicer to make the skeletons alike.

* data/skeletons/lalr1.cc (state_type): Here.
2019-10-24 18:16:01 +02:00
kaneko yandAkim Demaille aa244fc5fe README: Fix a typo
* README: Fix a typo. Git command name is submodule.
2019-10-24 18:13:17 +02:00
Akim Demaille 719395c9cd examples: fix missing dependencies
Reported by Thomas Petazzoni.
https://lists.gnu.org/archive/html/bug-bison/2019-08/msg00000.html

* examples/c/reccalc/local.mk: Complete dependencies, including for
earlier versions of Automake (for sake of our CI, on top of Ubuntu
Xenial/Bionic, which feature only Automake 1.15).
(%D%/scan.c %D%/scan.h): Upgrade to the full version provided in
Automake's documentation.
2019-10-24 18:01:53 +02:00
Akim Demaille fa9871a2fb diagnostics: simplify location handling
Locations start at line 1.  Don't accept line 0.

* src/location.c (location_print): Don't print locations with line 0.
(location_caret): Simplify.
2019-10-24 18:00:43 +02:00
Akim Demaille 76597d01f3 build: reenable -Wtype-limits
See https://lists.gnu.org/archive/html/bug-bison/2019-10/msg00061.html
to https://lists.gnu.org/archive/html/bug-bison/2019-10/msg00073.html.

Paul Eggert's changes in gnulib do fix the issue for modern GCCs (7,
8, 9) on macOS.  Unfortunately these warnings are back on the
CI (GNU/Linux) with GCC 4.6, 4.7, (not 4.8) and 4.9.

Disable the warning locally.

* configure.ac (warn_common, warn_tests): Remove -Wtype-limits.
* src/system.h (IGNORE_TYPE_LIMITS_BEGIN, IGNORE_TYPE_LIMITS_END): New.
* src/InadequacyList.c, src/parse-gram.c, src/parse-gram.y,
* src/symtab.c: Use it.
2019-10-24 08:50:14 +02:00
Akim Demaille bc5efb558d build: remove dmalloc support
Today sanitizers are a better alternative.

* m4/dmalloc.m4: Remove.
* configure.ac, src/system.h: Adjust.
2019-10-24 07:22:17 +02:00
Akim Demaille 17e21f6158 gitignore: update 2019-10-23 23:09:56 +02:00
Paul Eggert 6ef8513e7c build: update gnulib submodule to latest 2019-10-23 13:44:58 -07:00
Yuichiro KanekoandAkim Demaille 3945beb1d2 style: update comment in reader.c
rrhs and rlhs were removed by b2ed6e5826.

* src/reader.c (packgram): Update comment.
2019-10-23 08:32:06 +02:00
kaneko yandAkim Demaille c86b7815fc yacc.c: fix a typo
* data/skeletons/yacc.c (yysetstate): fix comment.
2019-10-22 19:05:02 +02:00
Akim Demaille 048730c691 style: pacify syntax-check
* doc/.gitignore, src/complain.c, src/getargs.c,
* src/output.c: here.
2019-10-22 10:40:12 +02:00
Akim Demaille ec64a0bc7e main: also free memory on errors
* src/derives.c (derives_free): Beware of NULL.
* src/main.c (main): Let the 'finish' label include memory release.
2019-10-21 17:18:32 +02:00
Akim Demaille d6fe39cd18 gnulib: update
To get bitset_free accept NULL.  See
https://lists.gnu.org/archive/html/bug-gnulib/2019-10/msg00054.html
2019-10-21 17:18:32 +02:00
Akim Demaille d76ea5ce06 style: reduce scope in derives
* src/derives.c: here.
And prefer prefix to postfix increment.
2019-10-21 17:18:32 +02:00
Akim Demaille fdef997432 build: disable -Wtautological-constant-out-of-range-compare
Also see e31f92495c and
https://lists.gnu.org/archive/html/bug-bison/2019-10/msg00061.html

* configure.ac (warn_common): Disable
-Wtautological-constant-out-of-range-compare.
(warn_tests): Restore it.
2019-10-21 10:35:01 +02:00
Akim Demaille 0073b5ea5f CI: formatting changes
* .travis.yml: Use the single line form of lists, when reduced to a
singletons.
2019-10-21 08:53:07 +02:00
Akim Demaille 717be0a0f0 CI: rename jobs
* .travis.yml (compile, test): Rename as...
(dist, check): these, which are more traditional for GNU projects.
2019-10-21 08:53:07 +02:00
Akim Demaille c6e4b260e0 doc: update README
* README: Be clearer that README-hacking _must_ be read.
Convert to Markdown.
2019-10-21 08:53:06 +02:00
Akim Demaille 8b87da8d12 bootstrap: relieve developpers from Gettext version mismatch issues
* .travis.yml (compile): Move the workaround from here...
* bootstrap.conf (bootstrap_epilogue): to there.
2019-10-21 08:38:03 +02:00
Akim Demaille 41b1f828ae tests: beware of GCC9 warnings in push mode
This is really weird: GCC points to the LHS of the assignment...

    260. headers.at:184: testing Sane headers: api.pure api.push-pull=both ...
    tests/headers.at:184: COLUMNS=1000; export COLUMNS;  bison --color=no -fno-caret -d -o input.c input.y
    tests/headers.at:184: $CC $CFLAGS $CPPFLAGS  -c -o input.o input.c
    stderr:
    input.c: In function 'yyparse':
    input.c:1276:16: error: 'yylval' may be used uninitialized in this function [-Werror=maybe-uninitialized]
     1276 |         yylval = *yypushed_val;
          |         ~~~~~~~^~~~~~~~~~~~~~~
    input.c: In function 'yypull_parse':
    input.c:1276:16: error: 'yylval' may be used uninitialized in this function [-Werror=maybe-uninitialized]
     1276 |         yylval = *yypushed_val;
          |         ~~~~~~~^~~~~~~~~~~~~~~
    cc1: all warnings being treated as errors
    stdout:
    tests/headers.at:184: exit code was 1, expected 0

See also d87c8ac79a
and 9645a2b20e.

* tests/headers.at (Several parsers, Several parsers): Disable these
warnings when in push parser.
2019-10-20 23:01:27 +02:00
Akim Demaille 4e0de4df8c CI: try GCC9 and Clang9
The logs show:

    Disallowing sources: llvm-toolchain-bionic-8, ubuntu-toolchain-r-test
    To add unlisted APT sources, follow instructions in
    https://docs.travis-ci.com/user/installing-dependencies#Installing-Packages-with-the-APT-Addon

* .travis.yml: Remove a few apt sources which are ignored in
Bionic (e.g., see
https://github.com/travis-ci/apt-source-safelist/issues/410).
Where needed, use sources/sourceline instead.
Also, don't use -DNDEBUG with older builds.
2019-10-20 17:57:28 +02:00
Akim Demaille 97d6da0c5b parser: clarify version checking
* src/parse-gram.y: Use the same conventions for gnulib as elsewhere:
<header.h>.
(str_to_version): New.
(handle_require): Use it.
Prefer < to >.
2019-10-20 17:57:28 +02:00
Akim Demaille e31f92495c build: disable -Wtype-limits, except in the test suite
The current implementation of lib/intprops.h results in "unsigned < 0"
comparisons, which triggers warnings.  See

https://lists.gnu.org/archive/html/bug-bison/2019-10/msg00061.html

* configure.ac (warn_common): Disable -Wtype-limits.
(warn_tests): Restore it.
2019-10-20 08:55:44 +02:00
Paul Eggert 54c5d5d1b4 c++: port to Sun C++ 5.12
The documentation for Oracle Solaris Studio 12.3 (Sun C++ 5.12
2011/11/16) says it supports C++03.  This compiler rejects the
location.cc use of std::max for some reason; I don’t know why
since I don’t use C++ as a rule.  The simplest workaround is to
open-code ‘max’.
* data/skeletons/location.cc (add_):
Do max by hand rather than relying on std::max.
Don’t include <algorithm.h>; no longer needed.
2019-10-17 12:25:05 -07:00
Paul Eggert 693e69f289 regen 2019-10-17 11:51:20 -07:00
Paul Eggert 5c2c9fcb17 tests: port to Solaris 10 grep
* tests/scanner.at (Token numbers: $1): Use $EGREP, not grep -E.
2019-10-17 11:51:20 -07:00
Paul Eggert 071f43d5b7 tests: port to Solaris 10 sed
As documented in the Autoconf manual, Solaris 10 sed rejects
script labels contianing more than 7 characters.  POSIX requires
support for at least 8 characters, but we might as well be portable
to Solaris 10 which is still supported.
* tests/local.at (AT_SETS_CHECK): Use only the first 7 characters
in sed labels.
2019-10-17 11:51:20 -07:00
Paul Eggert 8a4ec5d4e4 bison: check for int overflow in token numbers
* src/symtab.c: Include intprops.h
(symbol_user_token_number_set): Don’t allow user_token_number ==
INT_MAX because too much other code adds 1 to the user token number.
(symbols_token_translations_init): Complain on integer overflow
instead of indulging in undefined behavior.
2019-10-17 11:51:20 -07:00
Paul Eggert 052215a138 bison: check for int overflow when scanning
* src/scan-gram.l: Include errno.h, for errno.
(scan_integer, handle_syncline): Check for integer overflow.
* tests/input.at (too-large.y): Adjust to match new diagnostics.
2019-10-17 11:51:20 -07:00
Paul Eggert 15c1b913cf bison: check version numbers more carefully
* src/parse-gram.y: Include intprops.h.
(handle_require): Don’t indulge in undefined behavior if the major
or minor number is out of range.  Instead, check that the
resulting value is nonnegative, fits in int, and that the minor
number is less than 100.  Also, check that a number was parsed.
2019-10-17 11:51:20 -07:00
Paul Eggert 83c9051a64 c: port YY_ATTRIBUTE_UNUSED to Sun C 5.12
Sun C 5.12 defines __SUNPRO_C to 0x5120 but diagnoses
‘__attribute__ ((__unused__))’.  Change the ifdefs to use
the same method as Gnulib in this area.
* data/skeletons/c.m4 (YY_ATTRIBUTE): Remove, since
not all attributes were added in the same compiler version.
(YY_ATTRIBUTE_PURE, YY_ATTRIBUTE_UNUSED):
Use specific GCC version for each attribute.
Pay no attention to __SUNPRO_C.
* tests/headers.at (Several parsers): Tighten tests accordingly.
2019-10-17 11:51:20 -07:00
Paul Eggert 7a557ee7fe c: improve port of stdint.h usage to pre-C99
Oracle Solaris Studio 12.3 (Sun C 5.12 2011/11/16) by default does
not conform to C99; it defines __STDC_VERSION__ to be 199409L, so
the Bison code does not include <stdint.h> (not required by C89
amendment 1) even though this compiler does have <stdint.h>.  On
this platform <limits.h> defines INT_LEAST8_MAX (POSIX allows
this) so the skeleton got confused and thought that <stdint.h> had
been included even though it wasn’t.
* data/skeletons/c.m4 (b4_c99_int_type_define) [!__PTRDIFF_MAX__]:
Always include <limits.h>.
(YY_STDINT_H): Define when <stdint.h> was included.
All uses of expressions like ‘defined INT_LEAST8_MAX’ changed to
‘defined YY_STDINT_H’, since Sun C 5.12 <limits.h> defines macros
like INT_LEAST8_MAX but does not declare types like int_least8_t.
2019-10-17 11:51:20 -07:00
Paul Eggert 08dd5e9feb gnulib:update 2019-10-17 11:51:20 -07:00
Paul Eggert 68cc2631a4 autoconf:update 2019-10-17 11:51:20 -07:00
Akim Demaille b47340982b TODO: more updates 2019-10-15 08:40:50 +02:00
Akim Demaille ee35055b49 TODO: update 2019-10-15 07:28:33 +02:00
Akim Demaille e5cbac98b6 yacc: rename types for states
* data/skeletons/yacc.c (yy_state_num): Rename as...
(yy_state_t): this.
(yy_state_fast_t): New.
Use it.
2019-10-15 07:02:26 +02:00
Akim Demaille d563a01709 glr: style changes
* data/skeletons/glr.c (yytnamerr): here.
(yyprocessOneStack): Initialize variables.
2019-10-15 07:02:26 +02:00
Akim Demaille a428a9fa6c yacc: style changes
* data/skeletons/yacc.c: Move call to lac discard to clarify the
shifting of the token.
Like in lalr1.cc.
2019-10-15 07:02:26 +02:00
Akim Demaille 2a0185b693 tests: avoid $(...)
Reported by Paul Eggert.

* tests/local.at (AT_DATA_NO_FINAL_EOL): here.
2019-10-15 07:01:06 +02:00
Akim Demaille ab3621678a tests: use a portable 'truncate' implementation
Suggested by Paul Eggert.
https://lists.gnu.org/archive/html/bison-patches/2019-10/msg00044.html

* tests/local.at (AT_DATA_NO_FINAL_EOL): Use dd instead of perl.
2019-10-14 07:58:36 +02:00
Akim Demaille 8631f35bf9 tests: factor the generation of files without the final eol
AFAICT Autotest 2.69 still does not support AT_DATA without the final
eol.

* tests/local.at (AT_DATA_NO_FINAL_EOL): New.
* tests/input.at: Use it.
2019-10-13 09:55:44 +02:00
Akim Demaille c483b6593f tests: refactor the handling of Perl
Let's make a difference between places where Perl is required for the
test (AT_PERL_REQUIRE), and the places where it's used to run the
test, but it's not not to run the test (AT_PERL_CHECK).

* tests/local.at (AT_REQUIRE): New.
(AT_PERL_CHECK, AT_PERL_REQUIRE): New.
Use them where appropriate.

* tests/local.mk ($(TESTSUITE)): Beware not to start the line with
'-pi' if Perl is empty, as Make understands this as "it's ok to fail".
Which it is not.
2019-10-13 09:22:05 +02:00
Akim Demaille 59cb1f421c d: comment changes
* data/skeletons/lalr1.d: Here.
2019-10-12 12:11:42 +02:00
Akim Demaille d9d37a1196 i18n: don't push too hard for '…'
Suggested by Paul Eggert.

* src/location.c (ellipsis): Clarify comment for translators.
2019-10-12 10:43:53 +02:00
Akim Demaille c3db1394a1 regen 2019-10-11 08:52:04 +02:00
Akim Demaille 2c20ae9b41 glr: display line numbers in traces
Suggested by Lars Maier.

* data/skeletons/glr.c: Also display rule locations when rules are
deferred, and rejected.
2019-10-11 08:38:24 +02:00
Akim Demaille 0c56c195e0 tests: be really robust to Perl missing
My previous tests (with ./configure PERL=false) have been fooled by
configure, that managed to find perl anyway.  This time, I ran this on
a Fedora in Docker, without Perl.

* tests/calc.at, tests/diagnostics.at, tests/headers.at,
* tests/input.at, tests/local.at, tests/named-refs.at,
* tests/output.at, tests/regression.at, tests/skeletons.at,
* tests/synclines.at, tests/torture.at: Don't require Perl.
2019-10-11 06:53:45 +02:00
Akim Demaille 3dd2ae4415 configure: perl is not required
But it's used in various places, including in some tests.

* configure.ac: here.
2019-10-10 21:57:50 +02:00
Akim Demaille d50df39f1a news: update 2019-10-10 21:57:50 +02:00
Akim Demaille 2c66acfec0 diagnostics: prefer "…" to "..." if the locale supports it
* src/location.c (ellipsis, ellipsize): New.
Use them.
2019-10-10 21:57:50 +02:00
Paul Eggert 3f320159e3 c: improve patch for UCHAR_MAX etc. problem
* data/skeletons/c.m4 (b4_c99_int_type_define): Reorder to put the
signed types first, since they’re simpler and this keeps similar
code closer.  For signed types, don’t bother checking whether the
type promotes to int since the type must be signed anyway.  For
unsigned types, protect a test like ‘UCHAR_MAX <= INT_MAX’ with
‘!defined __UINT_LEAST8_MAX__’, as otherwise the logic is wrong
for oddball platforms; and once we do that, there should no need
for ‘defined INT_MAX’ so remove that.
2019-10-10 12:08:42 -07:00
Akim Demaille f41e0cf73c tests: do not depend on config.h
Currently we face test suite failures in different environments,
because of a conflict between the definitions of isnan by gnulib, and
by the C++ library:

    262. headers.at:186: testing Sane headers: %locations %debug c++ ...
    ./headers.at:186: COLUMNS=1000; export COLUMNS;  bison --color=no -fno-caret -d -o input.cc input.y
    ./headers.at:186: $CXX $CXXFLAGS $CPPFLAGS  -c -o input.o input.cc
    stderr:
    In file included from /usr/include/c++/4.8.2/cmath:44:0,
                     from /usr/include/c++/4.8.2/random:38,
                     from /usr/include/c++/4.8.2/bits/stl_algo.h:65,
                     from /usr/include/c++/4.8.2/algorithm:62,
                     from location.hh:41,
                     from input.hh:90,
                     from input.cc:50:
    /u/cs/fac/eggert/src/gnu/bison/lib/math.h: In function 'bool isnan(double)':
    /u/cs/fac/eggert/src/gnu/bison/lib/math.h:2849:1: error: new declaration 'bool isnan(double)'
     _GL_MATH_CXX_REAL_FLOATING_DECL_2 (isnan, isnan, bool)
     ^
    In file included from /usr/include/features.h:375:0,
                     from /usr/include/c++/4.8.2/x86_64-redhat-linux/bits/os_defines.h:39,
                     from /usr/include/c++/4.8.2/x86_64-redhat-linux/bits/c++config.h:2097,
                     from /usr/include/c++/4.8.2/cstdlib:41,
                     from input.hh:48,
                     from input.cc:50:
    /usr/include/bits/mathcalls.h:235:1: error: ambiguates old declaration 'int isnan(double)'
     __MATHDECL_1 (int,isnan,, (_Mdouble_ __value)) __attribute__ ((__const__));
     ^

There might be something to do in gnulib about this, but I believe
that gnulib should not be used in the test suite in the first place.

The test suite should work with other compilers than the one used to
compile the package.  For a start, Bison sources are more
demanding (C99) than the generated parsers.  Last time I tried, tcc
for example, was not able to compile Bison, yet our generated parsers
should compile cleanly with it.

Besides the problem at hand is with the C++ compiler, with is not the
one used to set up gnulib at configuration-time (config.h is mainly
built from probing the C compiler).

We should really not depend on gnulib in tests.

This was introduced in 2001 to check whether including
stdlib.h/string.h is safe thanks to STDC_HEADERS
(2ce1014469).  Today, we assume at least
a C90 compiler, it should be safe enough.

* tests/local.at, tests/testsuite.h: Do not include config.h.
* tests/atlocal.in (conftest.cc): Likewise.
(CPPFLAGS): Do not expose lib/, as because of this we might picked up
gnulib replacement headers for system headers.

* tests/input.at: Use int instead of ptrdiff_t, for easier portability
(some machine on the CI did not find ptrdiff_t).
* tests/c++.at: Add missing include for getchar.
2019-10-10 17:53:48 +02:00
Akim Demaille d6ce0521cf doc: spell check
* doc/bison.texi: Remove the index about yyoutput, it is no longer
documented.
Spell check.
2019-10-10 17:53:48 +02:00
Akim Demaille cf298ebb7d tests: style changes
* tests/actions.at: Prefer printf to fprintf.
Prefer yyo to yyoutput in %printer.
2019-10-10 17:53:48 +02:00
Akim Demaille 734db67004 tests: formatting changes
* tests/actions.at, tests/local.at: here.
2019-10-10 17:53:48 +02:00
Akim Demaille 7d47d51962 tests: add missing includes
* tests/actions.at, tests/c++.at, tests/headers.at,
* tests/regression.at: here.
2019-10-10 17:53:32 +02:00
Akim Demaille 602d562d6f c: don't assume that UCHAR_MAX, etc. are defined
A number of portability issues with GCC 4.6 .. 4.9 (inclusive):

    input.c:184:7: error: "UCHAR_MAX" is not defined [-Werror=undef]
     #elif UCHAR_MAX <= INT_MAX
           ^
    input.c:184:20: error: "INT_MAX" is not defined [-Werror=undef]
     #elif UCHAR_MAX <= INT_MAX
                        ^
    input.c:202:7: error: "USHRT_MAX" is not defined [-Werror=undef]
     #elif USHRT_MAX <= INT_MAX
           ^
    input.c:202:20: error: "INT_MAX" is not defined [-Werror=undef]
     #elif USHRT_MAX <= INT_MAX
                        ^

* data/skeletons/c.m4 (b4_c99_int_type_define): Don't assume they are
defined.
2019-10-10 16:01:43 +02:00
Akim Demaille 825150b085 configure: don't require Flex
Flex should not be required to build Bison or run the test suite (of
course it is needed for maintaining Bison).  Yet the Automake
conditional FLEX_WORKS does not work.

* m4/flex.m4 (_AC_PROG_LEX_YYTEXT_DECL): Since this is called
conditionally, don't define LEX_IS_FLEX here, but rather...
(AC_PROG_LEX): here.
* configure.ac: Be more cautious about possibly undefined variables.
2019-10-09 07:28:26 +02:00
Paul Eggert d4b6c86c7f Move the integer-type selection into c.m4
That way, glr.c can use it too.
* data/skeletons/c.m4 (b4_int_type):
Do not special-case ‘char’; it’s not worth the trouble,
as clang complains about char subscripts.
(b4_c99_int_type, b4_c99_int_type_define): New macros,
taken from yacc.c.
* data/skeletons/glr.c: Use b4_int_type_define.
* data/skeletons/yacc.c (b4_int_type): Remove, since there’s
no longer any need to redefine it.
Use b4_c99_int_type_define rather than its body.
2019-10-07 00:08:19 -07:00
Paul Eggert 5463291a91 Use “least” types for integers in Yacc tables
This changes the Yacc skeleton to use “least” integer types to
keep tables smaller on some platforms, which should lessen cache
pressure.  Since Bison uses the Yacc skeleton, it follows suit.
* data/skeletons/yacc.c: Include limits.h and stdint.h if this
seems to be needed.
(yytype_uint8, yytype_int8, yytype_uint16, yytype_int16):
If available, use GCC predefined macros __INT_MAX__ etc. to select
a “least” type, as this avoids namespace hassles.  Otherwise, if
available fall back on selecting a “least” type via the C99 macros
INT_MAX, INT_LEAST8_MAX, etc.  Otherwise, fall further back on one of
the builtin C99 types signed char, short, and int.  Make sure that
any selected type promotes to int.  Ignore any macros YYTYPE_INT16,
YYTYPE_INT8, YYTYPE_UINT16, YYTYPE_UINT8 defined by the user.
(ptrdiff_t, PTRDIFF_MAX): Simplify in the light of the above.
(yytype_uint8, yytype_uint16): Do not assume that unsigned char
and unsigned short promote to int, as this isn’t true on some
platforms (e.g., TI TMS320C55x).
* src/parse-gram.y (YYTYPE_INT16, YYTYPE_INT8, YYTYPE_UINT16)
(YYTYPE_UINT8): Remove, as these are no longer effective.
2019-10-07 00:08:19 -07:00
Paul Eggert 6373b90fc8 Port better to C++ platforms
* data/skeletons/yacc.c (YYPTRDIFF_T, YYPTRDIFF_MAXIMUM):
Default to long, not int.
(yy_lac_stack_realloc, yy_lac, yytnamerr, yyparse):
Avoid casts to YYPTRDIFF_T that were masking the problem.
2019-10-06 11:59:16 -07:00
Paul Eggert beceb2fa93 Work around GCC 4.8 false alarms without casts
* data/skeletons/yacc.c (yyparse):
Initialize yyes_capacity with a signed expression.
* tests/local.at (AT_YYLEX_DEFINE(c)):
Use enum to avoid cast.
2019-10-06 11:59:16 -07:00
Akim Demaille 58302c6079 regen 2019-10-06 17:48:51 +02:00
Akim Demaille d2a7a28438 tests: make recheck
* tests/local.mk (recheck): New.
2019-10-06 12:15:12 +02:00
Akim Demaille 9e6c5328d3 diagnostics: also show suggested %empty
* src/reader.c (grammar_rule_check_and_complete): Suggest to add %empty.
* tests/actions.at, tests/diagnostics.at: Adjust expectations.
2019-10-06 12:15:12 +02:00
Akim Demaille fec13ce2db diagnostics: sort symbols per location
Because the checking of the grammar is made by phases after the whole
grammar was read, we sometimes have diagnostics that look weird.  In
some case, within one type of checking, the entities are not checked
in the order in which they appear in the file.  For instance, checking
symbols is done on the list of symbols sorted by tag:

    foo.y:1.20-22: warning: symbol BAR is used, but is not defined as a token and has no rules [-Wother]
        1 | %destructor {} QUX BAR
          |                    ^~~
    foo.y:1.16-18: warning: symbol QUX is used, but is not defined as a token and has no rules [-Wother]
        1 | %destructor {} QUX BAR
          |                ^~~

Let's sort them by location instead:

    foo.y:1.16-18: warning: symbol 'QUX' is used, but is not defined as a token and has no rules [-Wother]
        1 | %destructor {} QUX BAR
          |                ^~~
    foo.y:1.20-22: warning: symbol 'BAR' is used, but is not defined as a token and has no rules [-Wother]
        1 | %destructor {} QUX BAR
          |                    ^~~

* src/location.h (location_cmp): Be robust to empty file names.
* src/symtab.c (symbol_cmp): Sort by location.
* tests/input.at: Adjust expectations.
2019-10-06 09:54:25 +02:00
Akim Demaille be3cf406af diagnostics: suggest fixes for undeclared symbols
From

    input.y:1.17-19: warning: symbol baz is used, but is not defined as a token and has no rules [-Wother]
         1 | %printer {} foo baz
           |                 ^~~

to

    input.y:1.17-19: warning: symbol 'baz' is used, but is not defined as a token and has no rules; did you mean 'bar'? [-Wother]
        1 | %printer {} foo baz
          |                 ^~~
          |                 bar

* bootstrap.conf: We need fstrcmp.
* src/symtab.c (symbol_from_uniqstr_fuzzy): New.
(complain_symbol_undeclared): Use it.
* tests/diagnostics.at (Suggestions): New.
* data/bison-default.css (insertion): Rename as...
(fixit-insert): this, as this is what GCC uses.
2019-10-06 09:54:25 +02:00
Akim Demaille 126c4622de style: isolate complain_symbol_undeclared
* src/symtab.c (complain_symbol_undeclared): New.
Use it.
Use quote on the guilty symbol (like GCC does, and we also do
elsewhere).
* tests/input.at: Adjust.
2019-10-06 09:54:25 +02:00
Akim Demaille dd64eaf9db style: simplify the handling of symbol and semantic_type tables
Both are stored in a hash, and back in the days, we used to iterate
over these tables using hash_do_for_each.  However, the order of
traversal was not deterministic, which was a nuisance for
deterministic output (and therefore also a problem for tests).  So at
some point (83b60c97ee) we generated a
sorted list of these symbols, and symbols_do actually iterated on that
list.  But we kept the constraints of using hash_do_for_each, which
requires a lot of ceremonial code, and makes it hard/unnatural to
preserve data between iterations (see the next commit).

Alas, this is C, not C++.

Let's remove this abstraction, and directly iterate on the sorted
tables.

* src/symtab.c (symbols_do): Remove.
Adjust callers to use a simple for-loop instead.
(table_sort): New.
(symbols_check_defined): Use it.
(symbol_check_defined_processor, symbol_pack_processor)
(semantic_type_check_defined_processor, symbol_translation_processor):
Remove.
Simplify the corresponding functions (that no longer need to return a
bool).
2019-10-06 09:54:20 +02:00
Akim Demaille 0b585c49ae diagnostics: display suggested update after the caret-info
This commit adds the suggestion in green, on the line below the
caret-and-tildes.

    foo.y:1.1-14: warning: deprecated directive: '%error-verbose', use '%define parse.error verbose' [-Wdeprecated]
        1 | %error-verbose
          | ^~~~~~~~~~~~~~
          | %define parse.error verbose

The current approach, with location_caret_suggestion, is fragile:
there's a protocol of calls to the complain functions which is strict.
We should rather have a richer structure describing the diagnostics,
including with submessages such as the suggestions, passed in the end
to the routines in charge of formatting and printing them.

* src/location.h, src/location.c (location_caret_suggestion): New.
* src/complain.c (deprecated_directive): Use it.
* tests/diagnostics.at, tests/input.at: Adjust expectations.
2019-10-06 08:07:57 +02:00
Akim Demaille 37c4d0b175 diagnostics: isolate caret_set_column
* src/location.c (caret_info): Add width and skip members.
(caret_set_column): New.
Use it.
2019-10-06 08:07:57 +02:00
Akim Demaille 56bcccbc51 diagnostics: isolate caret_set_file
* src/location.c (caret_set_file): New.
Store the current line's length in caret_info.line_len.
Pay attention to fseek's return value.
Extracted from...
(location_caret): here.
2019-10-06 08:07:57 +02:00
Akim Demaille 17cc7da519 tests: use tput to get the number of columns
* tests/bison.in: here.
2019-10-06 08:07:57 +02:00
Akim Demaille 2713e7c4ff TODO: update
I no longer agree with that item, there are indeed two things to
report: lack of definition, and being useless.  We could have either
one without the other, they are not directly related.
2019-10-06 08:07:57 +02:00
Akim Demaille 32e5a91a91 yacc.c: work around warnings from G++ 4.8
input.c: In function 'int yyparse()':
input.c: error: conversion to 'long int' from 'long unsigned int'
                may change the sign of the result [-Werror=sign-conversion]
   yyes_capacity = sizeof yyesa / sizeof *yyes;
                                ^
cc1plus: all warnings being treated as errors

* data/skeletons/yacc.c: here.
2019-10-06 08:07:40 +02:00
Akim Demaille 5973d763c0 yacc.c: work around warnings from Clang++ 3.3 and 3.4
When we run the test suite with these C++ compilers to compile C code,
we get:

    239. synclines.at:440: testing syncline escapes: yacc.c ...
    ../../tests/synclines.at:440: $CC $CFLAGS $CPPFLAGS \"\\\"\".c -o \"\\\"\" ||
              exit 77
    stderr:
    stdout:
    ../../tests/synclines.at:440: COLUMNS=1000; export COLUMNS;  bison --color=no -fno-caret  -o \"\\\"\".c \"\\\"\".y
    ../../tests/synclines.at:440: $CC $CFLAGS $CPPFLAGS  $LDFLAGS -o \"\\\"\" \"\\\"\".c $LIBS
    stderr:
    "\"".c:1102:41: error: implicit conversion loses integer precision: 'long' to 'int' [-Werror,-Wshorten-64-to-32]
          YYPTRDIFF_T yysize = yyssp - yyss + 1;
                      ~~~~~~   ~~~~~~~~~~~~~^~~
    1 error generated.

    193. conflicts.at:545: testing parse.error=verbose and consistent errors: lr.type=canonical-lr parse.lac=full ...
    input.c:737:75: error: implicit conversion loses integer precision: 'long' to 'int'
                           [-Werror,-Wshorten-64-to-32]
      YYPTRDIFF_T yysize_old = *yytop == yytop_empty ? 0 : *yytop - *yybottom + 1;
                  ~~~~~~~~~~                               ~~~~~~~~~~~~~~~~~~~^~~
    input.c:901:48: error: implicit conversion loses integer precision: 'long' to 'int'
                           [-Werror,-Wshorten-64-to-32]
                YYPTRDIFF_T yysize = yyesp - *yyes + 1;
                            ~~~~~~   ~~~~~~~~~~~~~~^~~

* data/skeletons/yacc.c: Add more casts.
2019-10-06 08:03:43 +02:00
Akim Demaille 4246cd81df tests: avoid a GCC 4.8 warning
GCC 4.8 reports:

    input.y:57:33: error: conversion to 'int' from 'long unsigned int'
                          may alter its value [-Werror=conversion]
       int input_elts = sizeof input / sizeof input[0];
                                     ^

* tests/local.at (AT_YYLEX_DEFINE(c)): Add a cast (sorry, Paul!).
2019-10-05 23:00:05 +02:00
Paul Eggert e69b47cd18 * data/skeletons/glr.c (yysplitStack): Pacify Clang 8. 2019-10-05 03:42:24 -07:00
Paul Eggert 8f5aaa0e04 Avoid quiet conversion of pointer to bool
* src/location.c (caret_set_file):
* src/scan-code.l (contains_dot_or_dash):
Do not quietly convert pointer to bool, as Oracle Developer Studio
12.6 complains and it is arguably confusing style anyway.
2019-10-05 01:19:39 -07:00
Paul Eggert b75b055288 Port ARGMATCH_DEFINE_GROUP calls to C99
* src/complain.c, src/getargs.c: Omit ‘;’ after call
to ARGMATCH_DEFINE_GROUP, as C99 does not allow ‘;’ there.
2019-10-05 01:19:39 -07:00
Paul Eggert 41e84cddc7 Port lexcalc scan.l to Solaris 10
* examples/c/lexcalc/scan.l: Include errno.h.
2019-10-05 01:19:39 -07:00
Akim Demaille 5709f94a91 yacc.c: use casts instead of pragmas when losing integer width
For instance with Clang 4, 8, etc.:

    input.c:1166:12: error: implicit conversion loses integer precision: 'int' to 'yy_state_num' (aka 'signed char') [-Werror,-Wconversion]
      *yyssp = yystate;
             ~ ^~~~~~~

And GCC 8:

    input.c:1166:12: error: implicit conversion loses integer precision: 'int' to 'yy_state_num' (aka 'signed char') [-Werror,-Wimplicit-int-conversion]
      *yyssp = yystate;
             ~ ^~~~~~~

* data/skeletons/yacc.c (YY_CONVERT_INT_BEGIN): Remove.
Adjust callers.
2019-10-05 09:01:56 +02:00
Akim Demaille bc96b757ca yacc.c: fix warnings about undefined macros
For instance with GCC 4.9 and --enable-gcc-warnings:

    25. input.at:1201: testing Torturing the Scanner ...
    ../../tests/input.at:1344: $CC $CFLAGS $CPPFLAGS  -c -o input.o input.c
    stderr:
    input.c:239:18: error: "__STDC_VERSION__" is not defined [-Werror=undef]
     # elif 199901 <= __STDC_VERSION__
                      ^
    input.c:256:18: error: "__STDC_VERSION__" is not defined [-Werror=undef]
     # elif 199901 <= __STDC_VERSION__
                      ^

* data/skeletons/yacc.c: Check that __STDC_VERSION__ is defined before
using it.
2019-10-04 06:58:44 +02:00
Akim Demaille 1133220416 tests: check more state numbers
* tests/torture.at (State number type): Also check 128, 129 and
32768.
2019-10-04 06:58:44 +02:00
Paul Eggert 39eb80bdbc * doc/bison.texi (Table of Symbols): Mention memory exhaustion. 2019-10-03 11:17:18 -07:00
Paul Eggert 361004aabe Simplify mfcalc error handling
* doc/bison.texi (Mfcalc Symbol Table, Mfcalc Lexer):
Don’t abort on memory allocation failure or integer overflow.
Instead, comment that these things aren’t checked for.
2019-10-03 11:17:18 -07:00
Akim Demaille 032a52be6e c++: fix comments suggesting to use %require
* data/skeletons/location.cc, data/skeletons/stack.hh: Here.
2019-10-03 09:27:41 +02:00
Akim Demaille 843ef49bc3 lalr1.cc: simplify uses of size_t
* data/skeletons/stack.hh (stack::index_type): New type.
(stack::size, stack::operator[]): Be about an index_type rather than a
size_type and an int.
2019-10-03 09:27:41 +02:00
Akim Demaille 5df33278b4 c++: fixes for old compilers
On the CI with GCC 6:

    examples/c++/calc++/parser.cc:845:5: error: 'ptrdiff_t' was not declared in this scope
         ptrdiff_t yycount = 0;
         ^~~~~~~~~
    examples/c++/calc++/parser.cc:845:5: note: suggested alternatives:
    /usr/include/x86_64-linux-gnu/c++/6/bits/c++config.h:202:28: note:   'std::ptrdiff_t'
       typedef __PTRDIFF_TYPE__ ptrdiff_t;
                                ^~~~~~~~~

* data/skeletons/lalr1.cc: Qualify ptrdiff_t and size_t with std::.
2019-10-03 09:27:41 +02:00
Akim Demaille d96fff6115 tests: be robust to -DNDEBUG
input.y: In function 'yylex':
input.y:67:7: error: unused variable 'input_elts' [-Werror=unused-variable]
   int input_elts = sizeof input / sizeof input[0];
       ^~~~~~~~~~
cc1: all warnings being treated as errors

* tests/input.at, tests/local.at: Avoid that.
2019-10-03 09:27:40 +02:00
Akim Demaille be92ad1eb4 CI: remove the symlink before creating it
Currently we fail if we rerun a job that succeeded to push the
tarball.
2019-10-03 07:56:42 +02:00
Paul Eggert ff2f02815b Adjust ‘Big horizontal’ test case
* tests/torture.at (Big horizontal): Adjust to recent changes with
integers.  If there are states 0..256, Bison now uses a signed
rather than an unsigned 16-bit integer.
2019-10-02 18:37:35 -07:00
Paul Eggert 67dcef357c regen 2019-10-02 17:11:33 -07:00
Paul Eggert 133edcd248 Prefer signed to unsigned integers
This patch contains more fixes to prefer signed to unsigned
integer types, as modern tools like 'gcc -fsanitize=undefined'
can check for signed integer overflow but not unsigned overflow.
* NEWS: Document the API change.
* boostrap.conf (gnulib_modules): Add intprops.
* data/skeletons/glr.c: Include stddef.h and stdint.h,
since this skeleton can assume C99 or later.
(YYSIZEMAX): Now signed, and the minimum of SIZE_MAX and PTRDIFF_MAX.
(yybool) [!__cplusplus]: Now signed (which is how bool behaves).
(YYTRANSLATE): Avoid use of unsigned, and make the macro
safe even for values greater than UINT_MAX.
(yytnamerr, struct yyGLRState, struct yyGLRStateSet, struct yyGLRStack)
(yyaddDeferredAction, yyinitStateSet, yyinitGLRStack)
(yyexpandGLRStack, yymarkStackDeleted, yyremoveDeletes)
(yyglrShift, yyglrShiftDefer, yy_reduce_print, yydoAction)
(yyglrReduce, yysplitStack, yyreportTree, yycompressStack)
(yyprocessOneStack, yyreportSyntaxError, yyrecoverSyntaxError)
(yyparse, yy_yypstack, yypstack, yypdumpstack):
* tests/input.at (Torturing the Scanner):
Prefer ptrdiff_t to size_t.
* data/skeletons/c++.m4 (b4_yytranslate_define):
* src/AnnotationList.c (AnnotationList__computePredecessorAnnotations):
* src/AnnotationList.h (AnnotationIndex):
* src/InadequacyList.h (InadequacyListNodeCount):
* src/closure.c (closure_new):
* src/complain.c (error_message, complains, complain_indent)
(complain_args, duplicate_directive, duplicate_rule_directive):
* src/gram.c (nritems, ritem_print, grammar_dump):
* src/ielr.c (ielr_compute_ritem_sees_lookahead_set)
(ielr_item_has_lookahead, ielr_compute_annotation_lists)
(ielr_compute_lookaheads):
* src/location.c (columns, boundary_print, location_print):
* src/muscle-tab.c (muscle_percent_define_insert)
(muscle_percent_define_check_values):
* src/output.c (prepare_rules, prepare_actions):
* src/parse-gram.y (id, handle_require):
* src/reader.c (record_merge_function_type, packgram):
* src/reduce.c (nuseless_productions, nuseless_nonterminals)
(inaccessable_symbols):
* src/relation.c (relation_print):
* src/scan-code.l (variant, variant_table_size, variant_count)
(variant_add, get_at_spec, show_sub_message, show_sub_messages)
(parse_ref):
* src/scan-gram.l (<SC_ESCAPED_STRING,SC_ESCAPED_CHARACTER>)
(scan_integer, convert_ucn_to_byte, handle_syncline):
* src/scan-skel.l (at_complain):
* src/symtab.c (complain_symbol_redeclared)
(complain_semantic_type_redeclared, complain_class_redeclared)
(symbol_class_set, complain_user_token_number_redeclared):
* src/tables.c (conflict_tos, conflrow, conflict_table)
(conflict_list, save_row, pack_vector):
* tests/local.at (AT_YYLEX_DEFINE(c)):
Prefer signed to unsigned integer.
* data/skeletons/lalr1.cc (yy_lac_check_):
* tests/actions.at (_AT_CHECK_PRINTER_AND_DESTRUCTOR):
* tests/local.at (AT_YYLEX_DEFINE(c)):
Omit now-unnecessary casts.
* data/skeletons/location.cc (b4_location_define):
* doc/bison.texi (Mfcalc Lexer, C++ position, C++ location):
Prefer int to unsigned for line and column numbers.
Change example to abort explicitly on memory exhaustion,
and fix an off-by-one bug that led to undefined behavior.
* data/skeletons/stack.hh (stack::operator[]):
Also allow ptrdiff_t indexes.
(stack::pop, slice::slice, slice::operator[]):
Index arg is now ptrdiff_t, not int.
(stack::ssize): New method.
(slice::range_): Now ptrdiff_t, not int.
* data/skeletons/yacc.c (b4_state_num_type): Remove.
All uses replaced by b4_int_type.
(YY_CONVERT_INT_BEGIN, YY_CONVERT_INT_END): New macros.
(yylac, yyparse): Use them around conversions that -Wconversion
would give false alarms about. 	Omit unnecessary casts.
(yy_stack_print): Use int rather than unsigned, and omit
a cast that doesn’t seem to be needed here any more.
* examples/c++/variant.yy (yylex):
* examples/c++/variant-11.yy (yylex):
Omit no-longer-needed conversions to unsigned.
* src/InadequacyList.c (InadequacyList__new_conflict):
Don’t assume *node_count is unsigned.
* src/output.c (muscle_insert_unsigned_table):
Remove; no longer used.
2019-10-02 17:11:33 -07:00
Paul EggertandAkim Demaille 4d9ff272cf Prefer signed types for indexes in skeletons
* NEWS: Mention this.
* data/skeletons/c.m4 (b4_int_type):
Prefer char if it will do, and prefer signed types to unsigned if
either will do.
* data/skeletons/glr.c (yy_reduce_print): No need to
convert rule line to unsigned long.
(yyrecoverSyntaxError): Put action into an int to
avoid GCC warning of using a char subscript.
* data/skeletons/lalr1.cc (yy_lac_check_, yysyntax_error_):
Prefer ptrdiff_t to size_t.
* data/skeletons/yacc.c (b4_int_type):
Prefer signed types to unsigned if either will do.
* data/skeletons/yacc.c (b4_declare_parser_state_variables):
(YYSTACK_RELOCATE, YYCOPY, yy_lac_stack_realloc, yy_lac)
(yytnamerr, yysyntax_error, yyparse): Prefer ptrdiff_t to size_t.
(YYPTRDIFF_T, YYPTRDIFF_MAXIMUM): New macros.
(YYSIZE_T): Fix "! defined YYSIZE_T" typo.
(YYSIZE_MAXIMUM): Take the minimum of PTRDIFF_MAX and SIZE_MAX.
(YYSIZEOF): New macro.
(YYSTACK_GAP_MAXIMUM, YYSTACK_BYTES, YYSTACK_RELOCATE)
(yy_lac_stack_realloc, yyparse): Use it.
(YYCOPY, yy_lac_stack_realloc): Cast to YYSIZE_T to pacify GCC.
(yy_reduce_print): Use int instead of unsigned long when int
will do.
(yy_lac_stack_realloc): Prefer long to unsigned long when
either will do.
* tests/regression.at: Adjust to these changes.
2019-10-02 07:10:03 +02:00
Akim Demaille 2ca6b71967 yacc: use the most appropriate integral type for state numbers
Currently we properly use the "best" integral type for tables,
including those storing state numbers.  However the variables for
state numbers used in yyparse (and its dependencies such as
yy_stack_print) still use int16_t invariably.  As a consequence, very
large models overflow these variables.

Let's use the "best" type for these variables too.  It turns out that
we can still use 16 bits for twice larger automata: stick to unsigned
types.

However using 'unsigned' when 16 bits are not enough is troublesome
and generates tons of warnings about signedness issues.  Instead,
let's use 'int'.

Reported by Tom Kramer.
https://lists.gnu.org/archive/html/bug-bison/2019-09/msg00018.html

* data/skeletons/yacc.c (b4_state_num_type): New.
(yy_state_num): Be computed from YYNSTATES.
* tests/linear: New.
* tests/torture.at (State number type): New.
Use it.
2019-09-30 18:31:55 +02:00
Akim Demaille 871c02b327 yacc: introduce a type for states
* data/skeletons/yacc.c (yy_state_num): New.
Use it for arrays of states.
2019-09-30 07:26:17 +02:00
Akim Demaille a57e74a5bf style: prefer symbolic values rather than litterals
Instead of

    #define YYPACT_NINF -130
    #define yypact_value_is_default(Yystate) \
      (!!((Yystate) == (-130)))

generate

    #define YYPACT_NINF (-130)
    #define yypact_value_is_default(Yyn) \
      ((Yyn) == YYPACT_NINF)

* data/skeletons/c.m4 (b4_table_value_equals): Add support for $4.
* data/skeletons/glr.c, data/skeletons/yacc.c: Use it.
Also, use shorter macro argument names, the name of the macro is clear
enough.
2019-09-30 07:25:56 +02:00
Akim Demaille 4971409e39 style: change misleading macro argument name
* data/skeletons/glr.c, data/skeletons/yacc.c
(yypact_value_is_default): It does not take a rule number as argument.
2019-09-30 07:25:48 +02:00
Akim Demaille b772baef24 Merge remote-tracking branch 'upstream/maint'
* upstream/maint:
  c++: add copy ctors for compatibility with the IAR compiler
  CI: show git status
  CI: disable ICC
  tests: pass -jN from Make to the test suite
  quotearg: avoid leaks
  maint: post-release administrivia
2019-09-28 08:09:33 +02:00
Akim Demaille 406e8c7c02 c++: add copy ctors for compatibility with the IAR compiler
Reported by Andreas Damm.
https://savannah.gnu.org/support/?110032

* data/skeletons/lalr1.cc (stack_symbol_type::operator=): New
overload, const, to please the IAR C++ compiler (version ca 2013).
2019-09-27 08:40:52 +02:00
Akim Demaille 97c4169f23 CI: show git status 2019-09-23 06:06:35 +02:00
Akim Demaille 8add45dbd9 CI: disable ICC
It seems that Intel changed something in their license management.
https://github.com/nemequ/icc-travis/issues/15
2019-09-23 06:06:26 +02:00
Akim Demaille b3e9c20227 tests: pass -jN from Make to the test suite
I am sooooo tired of typing "make -j5 TESTSUITEFLAGS=-j5"...
Should have done this years ago.

* cfg.mk (TESTSUITEFLAGS): here.
2019-09-23 06:05:39 +02:00
Akim Demaille b2c381cd25 quotearg: avoid leaks
Reported by Tomasz Kłoczko.
https://lists.gnu.org/archive/html/bug-bison/2019-09/msg00008.html

* src/main.c (main): Free quotearg's memory later.
2019-09-22 18:15:36 +02:00
Akim Demaille 67bff62e31 diagnostics: get the screen width from the terminal
* bootstrap.conf: We need winsz-ioctl and winsz-termios.
* src/location.c (columns): Use winsize to get the number of
columns.
Code taken from the GNU Coreutils.
* src/location.h, src/location.c (caret_init): New.
* src/complain.c (complain_init): Call it.
* tests/bison.in: Export COLUMNS so that users of tests/bison can
enjoy proper line truncation.
2019-09-22 09:12:08 +02:00
Akim Demaille 5f45cb05f1 diagnostics: don't print ellipsis on the caret line
From

    9 | ...TUVWXYZ  ABCDEFGHIJKLMNOPQRSTUVWXYZ  ABCDEFGHIJKL
      | ...         ^~~~~~~~~~~~~~~~~~~~~~~~~~

to

    9 | ...TUVWXYZ  ABCDEFGHIJKLMNOPQRSTUVWXYZ  ABCDEFGHI...
      |             ^~~~~~~~~~~~~~~~~~~~~~~~~~

* src/location.c (location_caret): here.
* tests/diagnostics.at: Adjust expectations.
2019-09-22 09:12:08 +02:00
Akim Demaille b61b0eb9ac diagnostics: also show truncation at the end of line with "..."
From

    9 | ...TUVWXYZ  ABCDEFGHIJKLMNOPQRSTUVWXYZ  ABCDEFGHIJKL
      | ...         ^~~~~~~~~~~~~~~~~~~~~~~~~~

to

    9 | ...TUVWXYZ  ABCDEFGHIJKLMNOPQRSTUVWXYZ  ABCDEFGHI...
      | ...         ^~~~~~~~~~~~~~~~~~~~~~~~~~

* src/location.c (location_caret): here.
* tests/diagnostics.at: Adjust expectations.
2019-09-22 09:12:08 +02:00
Akim Demaille 69277e109a diagnostics: check that quoted lines are truncated
* tests/diagnostics.at (Screen width: 60 columns, Screen width: 80
columns, Screen width: 200 columns): New tests.
2019-09-22 09:12:08 +02:00
Akim Demaille f716484627 diagnostics: truncate quoted sources to fit the screen
* src/location.c (min_int, columns): New.
(location_caret): Compute the line width.  Based on it, compute how
many columns must be skipped before the quoted location and truncated
after, to fit the sceen width.
* tests/local.at (AT_QUELL_VALGRIND): Transform into...
(AT_SET_ENV_IF, AT_SET_ENV): these.
Define COLUMNS to protect the test suite from the user's environment.
2019-09-22 09:12:08 +02:00
Akim Demaille 945b917da2 diagnostics: learn how to count column number with multibyte chars
So far diagnostics were cheating: in addition to the 'column' field of
locations (based on actual screen width per multibyte characters and
on tabulation expansion), the scanner sets the 'byte' field.
Diagnostics used this byte count to decide where to insert (color)
style.

We want to be able to truncate the quoted lines when there are too
wide to fit the screen.  This requires that the diagnostics learn how
to count columns, the byte-in-boundary trick no longer works.

Bytes are still used for fix-its.

* bootstrap.conf: We need mbfile for mbf_getc.
* src/location.c (caret_info): We need an mbfile.
(caret_set_file): Initialize it.
(caret_getc): Convert to mbfile.
(location_caret): Instead of relying on the byte position to decide
where to insert the color style, count the current column using
boundary_compute.
2019-09-22 09:12:08 +02:00
Akim Demaille 1ef407d923 diagnostics: style: rename member for clariy
* src/location.c (caret_info): Now that we no longer have a 'file'
member (see previous commit), rename 'source' as 'file'.
2019-09-22 09:12:08 +02:00
Akim Demaille 576b863e91 diagnostics: style: use a boundary to track the caret_info
* src/location.c (caret_info): Replace file and line with pos, a
boundary.  This will allow us to use features of the boundary type,
such as boundary_compute.
2019-09-22 09:12:08 +02:00
Akim Demaille 2274c34e91 diagnostics: extract boundary_compute from location_compute
The handling of the contributions of the tabulations in the columns is
burried inside location_compute.  We will soon be willing to use the
boundary part of the computation (to compute the current column number
each time we read a multibyte char).

* src/location.c (boundary_compute): New, extracted from...
(location_compute): here.
2019-09-22 09:12:08 +02:00
Akim Demaille fccab9bc40 diagnostics: style: add caret_set_file
To make the following commits easier to read.

* src/location.c (caret_set_file): New.
2019-09-22 09:12:08 +02:00
Akim Demaille 488607534a diagnostics: style: minor changes
* src/location.c (location_caret): Factor two branches of an if.
2019-09-22 09:12:08 +02:00
Akim Demaille 4db572dd21 CI: show git status 2019-09-22 09:12:08 +02:00
Akim Demaille 8faf075fd7 git: update ignores 2019-09-22 09:12:08 +02:00
Akim Demaille 453639dfac git: update ignores 2019-09-22 07:48:10 +02:00
Akim Demaille 4901ee115b quotearg: avoid leaks
Reported by Tomasz Kłoczko.
https://lists.gnu.org/archive/html/bug-bison/2019-09/msg00008.html

* src/main.c (main): Free quotearg's memory later.
2019-09-21 15:01:45 +02:00
Akim Demaille 6c7b2dfe51 tests: pass -jN from Make to the test suite
I am sooooo tired of typing "make -j5 TESTSUITEFLAGS=-j5"...
Should have done this years ago.

* cfg.mk (TESTSUITEFLAGS): here.
2019-09-14 10:19:13 +02:00
Akim Demaille a3e201de02 java: handle eof in yytranslate
* data/skeletons/lalr1.java (yytranslate_): Handle eof here, as is done
in lalr1.cc.
* tests/javapush.at: Adjust.
2019-09-14 10:09:08 +02:00
Akim Demaille 5e95bb6251 d: handle eof in yytranslate
This changes the traces from

    Reading a token:
    Now at end of input.

to

    Reading a token:
    Next token is token $end (7FFEE56E6474)

which is ok.  Actually it is even better, as it gives the location
when locations are enabled, and is clearer when rules explicitly use
the EOF token.

* data/skeletons/lalr1.d (yytranslate_): Handle eof here, as is done
in lalr1.cc.
2019-09-14 10:09:08 +02:00
Akim Demaille 569125a6bf regen 2019-09-14 10:09:08 +02:00
Akim Demaille 8ac28ba1f0 parser: use api.token.raw
* src/parse-gram.y: Here.
2019-09-14 10:09:08 +02:00
Akim Demaille 3ca713abd0 api.token.raw: document it
* doc/bison.texi: here.
2019-09-14 10:09:08 +02:00
Akim Demaille 8c18e3f18c api.token.raw: cannot be used with character literals
* src/parse-gram.y (CHAR): api.token.raw and character literals are
mutually exclusive.
* tests/input.at (Character literals and api.token.raw): New.
2019-09-14 10:09:08 +02:00
Akim Demaille 1e5e274972 api.token.raw: apply to the other skeletons
* data/skeletons/c++.m4, data/skeletons/glr.c,
* data/skeletons/lalr1.c, data/skeletons/lalr1.java:
Add support for api.token.raw.

* tests/scanner.at: Check them.
2019-09-14 09:55:17 +02:00
Akim Demaille b1679f8346 api.token.raw: check it
* tests/local.at (AT_TOKEN_RAW_IF): New.
* tests/local.mk: New.
Use it.
2019-09-14 09:55:17 +02:00
Akim Demaille 9861bcc540 api.token.raw: implement
Bison used to feature %raw, documented as follows:

    @item %raw
    The output file @file{@var{name}.h} normally defines the tokens with
    Yacc-compatible token numbers.  If this option is specified, the
    internal Bison numbers are used instead.  (Yacc-compatible numbers start
    at 257 except for single character tokens; Bison assigns token numbers
    sequentially for all tokens starting at 3.)

Unfortunately, as far as I can tell, it never worked: token numbers
are indeed changed in the generated tables (from external token number
to internal), yet the code was still applying the mapping from
external token numbers to internal token numbers.

This commit reintroduces the feature as it was expected to be.

* data/skeletons/bison.m4 (b4_token_format): When api.token.raw is
enabled, use the internal token number.
* data/skeletons/yacc.c (yytranslate): Don't emit if api.token.raw is
enabled.
(YYTRANSLATE): Adjust.
2019-09-14 09:55:17 +02:00
Akim Demaille d94d83e10b style: tidy yacc.c
* data/skeletons/yacc.c: Include 'c.m4' first.
Then sort the handling of %define variables.
* tests/input.at: Adjust.
2019-09-14 09:55:17 +02:00
Akim Demaille 2f6e377953 CI: disable ICC
It seems that Intel changed something in their license management.
https://github.com/nemequ/icc-travis/issues/15
2019-09-14 09:55:17 +02:00
Akim Demaille 32dff87c1d diagnostics: fix use of complain_indent
* src/symtab.c (symbol_class_set): Here.
* tests/diagnostics.at, tests/input.at, tests/regression.at: Adjust
expectations.
2019-09-14 09:47:49 +02:00
Akim Demaille 19da501e06 input: stop treating lone CRs as end-of-lines
We used to treat lone CRs (\r, aka ^M) as regular NLs (\n), probably
to please Classic MacOS.  As of today, it makes more sense to treat \r
like a plain white space character.

https://lists.gnu.org/archive/html/bison-patches/2019-09/msg00027.html

* src/scan-gram.l (no_cr_read): Remove.  Instead, use...
(eol): this new abbreviation denoting end-of-line.
* src/location.c (caret_getc): New.
(location_caret): Use it.
* tests/diagnostics.at (Carriage return): Adjust expectations.
(CR NL): New.
2019-09-14 09:23:47 +02:00
Akim Demaille 5e4133175d Merge tag 'v3.4.2' into HEAD
bison 3.4.2

* tag 'v3.4.2': (24 commits)
  version 3.4.2
  CI: always uninstall icc
  news: more bug fixes thanks to Marc Schönefeld
  diagnostics: beware of unexpected EOF when quoting the source file
  gnulib: update
  build: fix distcheck
  tests: add noexcept to please GCC 9
  news: update
  fix: don't die when EOF token is defined twice
  tests: check token redeclaration
  yacc.c: beware of GCC's -Wmaybe-uninitialized
  glr.c: initialize vector of bools
  gnulib: update
  check for memory exhaustion
  diagnostics: avoid global variables
  diagnostics: fix invalid error message indentation
  git: ignore files generated in gnulib-po
  c++: avoid duplicate definition of YYUSE
  gnulib: update
  CI: more compilers
  ...
2019-09-12 19:12:24 +02:00
Akim Demaille 0b093ac4d9 maint: post-release administrivia
* NEWS: Add header line for next release.
* .prev-version: Record previous version.
* cfg.mk (old_NEWS_hash): Auto-update.
2019-09-12 18:09:26 +02:00
Akim Demaille 69b22b49d4 version 3.4.2
* NEWS: Record release date.
2019-09-12 17:41:12 +02:00
Akim Demaille ec11f08fb3 CI: always uninstall icc 2019-09-12 13:16:30 +02:00
Akim Demaille 67444a6f0d news: more bug fixes thanks to Marc Schönefeld 2019-09-12 09:07:48 +02:00
Akim Demaille 4eed3a0f0c diagnostics: beware of unexpected EOF when quoting the source file
When the input file contains lone CRs (aka, ^M, \r), the locations see
a new line.  Diagnostics look only at \n as end-of-line, so sometimes
there is an offset in diagnostics.  Worse yet: sometimes we loop
endlessly waiting for \n to come from a continuous stream of EOF.

Fix that:
- check for EOF
- beware not to call end_use_class if begin_use_class was not
  called (which would abort).  This could happen if the actual
  line is shorter that the expected one.

Prompted by a (private) report from Marc Schönefeld.

* src/location.c (location_caret): here.
* tests/diagnostics.at (Carriage return): New.
2019-09-12 07:02:46 +02:00
Akim Demaille 84a6621c78 gnulib: update
Contains the creation of the xhash module.
https://lists.gnu.org/archive/html/bug-gnulib/2019-09/msg00046.html

* src/muscle-tab.c, src/state.c, src/symtab.c, src/uniqstr.c:
Use hash_xinitialize.
2019-09-11 09:07:27 +02:00
Akim Demaille 06a273625b build: fix distcheck
* configure.ac (gl_LIBOBJS): Adjust so that the generated files are
indeed the expected ones.
2019-09-11 08:27:27 +02:00
Akim Demaille d120a07e6b diagnostics: beware of unexpected EOF when quoting the source file
When the input file contains lone CRs (aka, ^M, \r), the locations see
a new line.  Diagnostics look only at \n as end-of-line, so sometimes
there is an offset in diagnostics.  Worse yet: sometimes we loop
endlessly waiting for \n to come from a continuous stream of EOF.

Fix that:
- check for EOF
- beware not to call end_use_class if begin_use_class was not
  called (which would abort).  This could happen if the actual
  line is shorter that the expected one.

Prompted by a (private) report from Marc Schönefeld.

* src/location.c (location_caret): here.
* tests/diagnostics.at (Carriage return): New.
2019-09-10 19:15:18 +02:00
Akim Demaille 741a58a504 gnulib: update
Contains the creation of the xhash module.
https://lists.gnu.org/archive/html/bug-gnulib/2019-09/msg00046.html

* src/muscle-tab.c, src/state.c, src/symtab.c, src/uniqstr.c:
Use hash_xinitialize.
2019-09-10 19:06:13 +02:00
Akim Demaille d80815ac23 build: fix distcheck
* configure.ac (gl_LIBOBJS): Adjust so that the generated files are
indeed the expected ones.
2019-09-10 19:06:13 +02:00
Akim Demaille 0b417c3479 tests: add noexcept to please GCC 9
bison/tests/c++.at:552: bison --color=no -fno-caret  -o list.cc list.y
    bison/tests/c++.at:552: $CXX $CXXFLAGS $CPPFLAGS  $LDFLAGS -o list list.cc $LIBS
    stderr:
    gcc9/c++/ext/new_allocator.h: In instantiation of 'void __gnu_cxx::new_allocator<_Tp>::construct(_Up*, _Args&& ...) [with _Up = string; _Args = {string}; _Tp = string]':
    gcc9/c++/bits/alloc_traits.h:482:2:   required from 'static void std::allocator_traits<std::allocator<_CharT> >::construct(std::allocator_traits<std::allocator<_CharT> >::allocator_type&, _Up*, _Args&& ...) [with _Up = string; _Args = {string}; _Tp = string; std::allocator_traits<std::allocator<_CharT> >::allocator_type = std::allocator<string>]'
    gcc9/c++/bits/stl_uninitialized.h:888:67:   required from 'void std::__relocate_object_a(_Tp*, _Up*, _Allocator&) [with _Tp = string; _Up = string; _Allocator = std::allocator<string>]'
    gcc9/c++/bits/stl_uninitialized.h:920:47:   required from '_ForwardIterator std::__relocate_a_1(_InputIterator, _InputIterator, _ForwardIterator, _Allocator&) [with _InputIterator = string*; _ForwardIterator = string*; _Allocator = std::allocator<string>]'
    gcc9/c++/bits/stl_uninitialized.h:942:37:   required from '_ForwardIterator std::__relocate_a(_InputIterator, _InputIterator, _ForwardIterator, _Allocator&) [with _InputIterator = string*; _ForwardIterator = string*; _Allocator = std::allocator<string>]'
    gcc9/c++/bits/stl_vector.h:430:35:   required from 'static constexpr bool std::vector<_Tp, _Alloc>::_S_nothrow_relocate(std::true_type) [with _Tp = string; _Alloc = std::allocator<string>; std::true_type = std::integral_constant<bool, true>]'
    gcc9/c++/bits/stl_vector.h:446:28:   required from 'void std::vector<_Tp, _Alloc>::_M_realloc_insert(std::vector<_Tp, _Alloc>::iterator, _Args&& ...) [with _Args = {const string&}; _Tp = string; _Alloc = std::allocator<string>; std::vector<_Tp, _Alloc>::iterator = __gnu_cxx::__normal_iterator<string*, std::vector<string> >; typename std::_Vector_base<_Tp, _Alloc>::pointer = string*]'
    gcc9/c++/bits/stl_vector.h:1195:4:   required from 'void std::vector<_Tp, _Alloc>::push_back(const value_type&) [with _Tp = string; _Alloc = std::allocator<string>; std::vector<_Tp, _Alloc>::value_type = string]'
    list.y:126:110:   required from here
    gcc9/c++/bits/vector.tcc:459:44:   in 'constexpr' expansion of 'std::vector<string>::_S_use_relocate()'
    list.y:41:7: error: but 'string::string(string&&)' does not throw; perhaps it should be declared 'noexcept' [-Werror=noexcept]
       41 |       string (string&& s)
          |       ^~~~~~

* tests/c++.at (Variants): Add noexcept where appropriate.
2019-09-08 12:04:36 +02:00
Akim Demaille f6fd9be688 tests: add noexcept to please GCC 9
bison/tests/c++.at:552: bison --color=no -fno-caret  -o list.cc list.y
    bison/tests/c++.at:552: $CXX $CXXFLAGS $CPPFLAGS  $LDFLAGS -o list list.cc $LIBS
    stderr:
    gcc9/c++/ext/new_allocator.h: In instantiation of 'void __gnu_cxx::new_allocator<_Tp>::construct(_Up*, _Args&& ...) [with _Up = string; _Args = {string}; _Tp = string]':
    gcc9/c++/bits/alloc_traits.h:482:2:   required from 'static void std::allocator_traits<std::allocator<_CharT> >::construct(std::allocator_traits<std::allocator<_CharT> >::allocator_type&, _Up*, _Args&& ...) [with _Up = string; _Args = {string}; _Tp = string; std::allocator_traits<std::allocator<_CharT> >::allocator_type = std::allocator<string>]'
    gcc9/c++/bits/stl_uninitialized.h:888:67:   required from 'void std::__relocate_object_a(_Tp*, _Up*, _Allocator&) [with _Tp = string; _Up = string; _Allocator = std::allocator<string>]'
    gcc9/c++/bits/stl_uninitialized.h:920:47:   required from '_ForwardIterator std::__relocate_a_1(_InputIterator, _InputIterator, _ForwardIterator, _Allocator&) [with _InputIterator = string*; _ForwardIterator = string*; _Allocator = std::allocator<string>]'
    gcc9/c++/bits/stl_uninitialized.h:942:37:   required from '_ForwardIterator std::__relocate_a(_InputIterator, _InputIterator, _ForwardIterator, _Allocator&) [with _InputIterator = string*; _ForwardIterator = string*; _Allocator = std::allocator<string>]'
    gcc9/c++/bits/stl_vector.h:430:35:   required from 'static constexpr bool std::vector<_Tp, _Alloc>::_S_nothrow_relocate(std::true_type) [with _Tp = string; _Alloc = std::allocator<string>; std::true_type = std::integral_constant<bool, true>]'
    gcc9/c++/bits/stl_vector.h:446:28:   required from 'void std::vector<_Tp, _Alloc>::_M_realloc_insert(std::vector<_Tp, _Alloc>::iterator, _Args&& ...) [with _Args = {const string&}; _Tp = string; _Alloc = std::allocator<string>; std::vector<_Tp, _Alloc>::iterator = __gnu_cxx::__normal_iterator<string*, std::vector<string> >; typename std::_Vector_base<_Tp, _Alloc>::pointer = string*]'
    gcc9/c++/bits/stl_vector.h:1195:4:   required from 'void std::vector<_Tp, _Alloc>::push_back(const value_type&) [with _Tp = string; _Alloc = std::allocator<string>; std::vector<_Tp, _Alloc>::value_type = string]'
    list.y:126:110:   required from here
    gcc9/c++/bits/vector.tcc:459:44:   in 'constexpr' expansion of 'std::vector<string>::_S_use_relocate()'
    list.y:41:7: error: but 'string::string(string&&)' does not throw; perhaps it should be declared 'noexcept' [-Werror=noexcept]
       41 |       string (string&& s)
          |       ^~~~~~

* tests/c++.at (Variants): Add noexcept where appropriate.
2019-09-08 12:02:30 +02:00
Akim Demaille 77dbdd0d59 news: update 2019-09-08 11:38:29 +02:00
Akim Demaille f8db8fe4d7 fix: don't die when EOF token is defined twice
With

    %token EOF 0 EOF 0

we get

    input.y:3.14-16: warning: symbol EOF redeclared [-Wother]
        3 | %token EOF 0 EOF 0
          |              ^~~
    input.y:3.8-10: previous declaration
        3 | %token EOF 0 EOF 0
          |        ^~~
    Assertion failed: (nsyms == ntokens + nvars), function check_and_convert_grammar,
        file /Users/akim/src/gnu/bison/src/reader.c, line 839.

Reported by Marc Schönefeld.

* src/symtab.c (symbol_user_token_number_set): Register only the
first definition of the end of input token.
* tests/input.at (Symbol redeclared): Check that case.
2019-09-08 11:38:29 +02:00
Akim Demaille 375eb71489 tests: check token redeclaration
* src/symtab.c (symbol_class_set): Report previous definitions when
redeclared.
* tests/input.at (Symbol redeclared): New.
2019-09-08 11:38:29 +02:00
Akim Demaille d3a86f7b20 yacc.c: beware of GCC's -Wmaybe-uninitialized
Test 400 (calc.at:773: testing Calculator api.push-pull=both
api.pure=full parse.error=verbose %debug %locations %defines
api.prefix={calc} %verbose %yacc) fails on the CI with GCC 8 on
Bionic:

    400. calc.at:773: testing Calculator api.push-pull=both api.pure=full parse.error=verbose %debug %locations %defines api.prefix={calc} %verbose %yacc  ...
    ../../tests/calc.at:773: bison --color=no -fno-caret -Wno-deprecated -o calc.c calc.y
    ../../tests/calc.at:773: $CC $CFLAGS $CPPFLAGS  $LDFLAGS -o calc calc.c calc-lex.c calc-main.c $LIBS
    stderr:
    calc.y: In function 'int calcpush_parse(calcpstate*, int, const CALCSTYPE*, CALCLTYPE*)':
    calc.y:26:20: error: 'yylval.CALCSTYPE::ival' may be used uninitialized in this function [-Werror=maybe-uninitialized]
     %printer { fprintf (yyo, "%d", $$); } <ival>;
                        ^
    calc.c:1272:9: note: 'yylval.CALCSTYPE::ival' was declared here
     YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
             ^~~~~~
    cc1plus: all warnings being treated as errors
    stdout:
    ../../tests/calc.at:773: exit code was 1, expected 0
    400. calc.at:773: 400. Calculator api.push-pull=both api.pure=full parse.error=verbose %debug %locations %defines api.prefix={calc} %verbose %yacc  (calc.at:773): FAILED (calc.at:773)

* data/skeletons/c.m4 (yy_symbol_value_print): Disable the warning
locally.
2019-09-08 11:38:29 +02:00
Akim Demaille 29c75ef27f glr.c: initialize vector of bools
The CI, with CC='gcc-7 -fsanitize=undefined,address
-fno-omit-frame-pointer', reports:

    calc.cc:1652:50: runtime error: load of value 190, which is not a valid value for type 'bool'
    ../../tests/calc.at:867: cat stderr
    --- expout	2019-09-05 20:30:37.887257545 +0000
    +++ /home/travis/build/bison-3.4.1.72-79a1-dirty/_build/tests/testsuite.dir/at-groups/438/stdout	2019-09-05 20:30:37.887257545 +0000
    @@ -1 +1,2 @@
     syntax error
    +calc.cc:1652:50: runtime error: load of value 190, which is not a valid value for type 'bool'
    438. calc.at:867: 438. Calculator glr.cc  (calc.at:867): FAILED (calc.at:867)

The problem is that yylookaheadNeeds is not initialized in
yyinitStateSet, and when it is copied, the value is not 0 or 1.

* data/skeletons/glr.c (yylookaheadNeeds): Initialize yylookaheadNeeds.
2019-09-08 11:38:29 +02:00
Akim Demaille 628012d830 gnulib: update
Contains a fix for
https://lists.gnu.org/archive/html/bug-bison/2019-08/msg00016.html.
See
https://lists.gnu.org/archive/html/bug-gnulib/2019-09/msg00005.html.
Reported by 江 祖铭 (Zu-Ming Jiang).
2019-09-08 11:38:29 +02:00
Akim Demaille f788ba2ab6 check for memory exhaustion
hash_initialize returns NULL when out of memory.  Check for it, and
die cleanly instead of crashing.

Reported by 江 祖铭 (Zu-Ming Jiang).
https://lists.gnu.org/archive/html/bug-bison/2019-08/msg00015.html

* src/muscle-tab.c, src/state.c, src/symtab.c, src/uniqstr.c:
Check the value returned by hash_initialize.
2019-09-08 11:38:29 +02:00
László VáradyandAkim Demaille 53526f31df diagnostics: avoid global variables
* src/complain.c (indent_ptr): Remove.
(error_message, complains): Take indent as an argument.
Adjust callers.
2019-09-08 11:38:29 +02:00
László VáradyandAkim Demaille e63811dd86 diagnostics: fix invalid error message indentation
https://lists.gnu.org/archive/html/bison-patches/2019-08/msg00007.html

When Bison is started with a flag that suppresses warning messages, the
error_message() function can produce a few gigabytes of indentation
because of a dangling pointer.

* src/complain.c (error_message): Don't reset indent_ptr here, but...
(complain_indent): here.
* tests/diagnostics.at (Indentation with message suppression): Check
this case.
2019-09-08 11:38:29 +02:00
Akim Demaille 47262c36bb git: ignore files generated in gnulib-po
Because of them, the CI generates "-dirty" tarballs.
2019-09-08 11:38:29 +02:00
Akim Demaille 1e452b1553 c++: avoid duplicate definition of YYUSE
Reported by Frank Heckenbach.
https://lists.gnu.org/archive/html/bug-bison/2019-06/msg00009.html

* data/skeletons/lalr1.cc (b4_shared_declarations): Remove the
duplicate definition of YYUSE, the other one coming from
b4_attribute_define.
2019-09-08 09:59:31 +02:00
Akim Demaille ed796869bb gnulib: update
This update brings file from Gettext 0.20, which is not available on
the CI yet.

.travis.yml: Adjust.
Use Bionic now that it's available.
2019-09-08 09:59:31 +02:00
Akim Demaille 12c412f6bb CI: more compilers
* .travis.yml: Bionic is now available, with GCC8.
GCC7 sanitizers work, but they are too longer: cover only part 1.
Redefine part 1 and part 2 so that part 1 is really the core of the
tests: not playing with POSIX and C++ compiler for C code.
2019-09-08 09:01:18 +02:00
Akim Demaille 2663035ea5 CI: fail fast 2019-09-08 09:01:11 +02:00
Akim Demaille de7c66ab41 CI: propagate sftp failures
* .travis.yml (stage: "compile"): here.
2019-09-08 09:00:58 +02:00
Akim Demaille feeacc2d57 CI: avoid useless git costs
Travis answered favorably to my suggestion to provide a means to
disable git clone on some jobs (issue 7542).  See
https://docs.travis-ci.com/user/customizing-the-build/#disabling-git-clone.

* .travis.yml: Disable git globally, enable it for i. the compile job,
and ii. the test job on ICC which needs the install-icc.sh script.
2019-09-08 09:00:49 +02:00
Akim Demaille cc10f9ab24 CI: factor
* .travis.yml (Clang 7 libc++ and ASAN part 2): Reuse bits from "Clang
7 libc++ and ASAN part 1".
2019-09-08 09:00:30 +02:00
Akim Demaille a9499e6ea2 regen 2019-09-08 08:58:55 +02:00
Akim Demaille 09a4bfdab4 gnulib: update
Contains a fix for
https://lists.gnu.org/archive/html/bug-bison/2019-08/msg00016.html.
See
https://lists.gnu.org/archive/html/bug-gnulib/2019-09/msg00005.html.
Reported by 江 祖铭 (Zu-Ming Jiang).
2019-09-08 08:40:17 +02:00
Akim Demaille 7d701f4378 fix: don't die when EOF token is defined twice
With

    %token EOF 0 EOF 0

we get

    input.y:3.14-16: warning: symbol EOF redeclared [-Wother]
        3 | %token EOF 0 EOF 0
          |              ^~~
    input.y:3.8-10: previous declaration
        3 | %token EOF 0 EOF 0
          |        ^~~
    Assertion failed: (nsyms == ntokens + nvars), function check_and_convert_grammar,
        file /Users/akim/src/gnu/bison/src/reader.c, line 839.

Reported by Marc Schönefeld.

* src/symtab.c (symbol_user_token_number_set): Register only the
first definition of the end of input token.
* tests/input.at (Symbol redeclared): Check that case.
2019-09-07 17:09:43 +02:00
Akim Demaille 378963b139 tests: check token redeclaration
* src/symtab.c (symbol_class_set): Report previous definitions when
redeclared.
* tests/input.at (Symbol redeclared): New.
2019-09-07 17:09:43 +02:00
Akim Demaille 2dd882bce5 glr.c: initialize vector of bools
The CI, with CC='gcc-7 -fsanitize=undefined,address
-fno-omit-frame-pointer', reports:

    calc.cc:1652:50: runtime error: load of value 190, which is not a valid value for type 'bool'
    ../../tests/calc.at:867: cat stderr
    --- expout	2019-09-05 20:30:37.887257545 +0000
    +++ /home/travis/build/bison-3.4.1.72-79a1-dirty/_build/tests/testsuite.dir/at-groups/438/stdout	2019-09-05 20:30:37.887257545 +0000
    @@ -1 +1,2 @@
     syntax error
    +calc.cc:1652:50: runtime error: load of value 190, which is not a valid value for type 'bool'
    438. calc.at:867: 438. Calculator glr.cc  (calc.at:867): FAILED (calc.at:867)

The problem is that yylookaheadNeeds is not initialized in
yyinitStateSet, and when it is copied, the value is not 0 or 1.

* data/skeletons/glr.c (yylookaheadNeeds): Initialize yylookaheadNeeds.
2019-09-06 17:27:56 +02:00
Akim Demaille 989503b1ba yacc.c: beware of GCC's -Wmaybe-uninitialized
Test 400 (calc.at:773: testing Calculator api.push-pull=both
api.pure=full parse.error=verbose %debug %locations %defines
api.prefix={calc} %verbose %yacc) fails on the CI with GCC 8 on
Bionic:

    400. calc.at:773: testing Calculator api.push-pull=both api.pure=full parse.error=verbose %debug %locations %defines api.prefix={calc} %verbose %yacc  ...
    ../../tests/calc.at:773: bison --color=no -fno-caret -Wno-deprecated -o calc.c calc.y
    ../../tests/calc.at:773: $CC $CFLAGS $CPPFLAGS  $LDFLAGS -o calc calc.c calc-lex.c calc-main.c $LIBS
    stderr:
    calc.y: In function 'int calcpush_parse(calcpstate*, int, const CALCSTYPE*, CALCLTYPE*)':
    calc.y:26:20: error: 'yylval.CALCSTYPE::ival' may be used uninitialized in this function [-Werror=maybe-uninitialized]
     %printer { fprintf (yyo, "%d", $$); } <ival>;
                        ^
    calc.c:1272:9: note: 'yylval.CALCSTYPE::ival' was declared here
     YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
             ^~~~~~
    cc1plus: all warnings being treated as errors
    stdout:
    ../../tests/calc.at:773: exit code was 1, expected 0
    400. calc.at:773: 400. Calculator api.push-pull=both api.pure=full parse.error=verbose %debug %locations %defines api.prefix={calc} %verbose %yacc  (calc.at:773): FAILED (calc.at:773)

* data/skeletons/c.m4 (yy_symbol_value_print): Disable the warning
locally.
2019-09-06 17:27:55 +02:00
Akim Demaille 61c2c40092 lalr1.cc: fix LAC support
* data/skeletons/lalr1.cc (ctor): Initialize yy_lac_established_.
This is quite painful to write, and ugly to read.
2019-09-06 17:27:55 +02:00
Akim Demaille 3953c61362 style: fix comment
* tests/atlocal.in: here.
2019-09-06 17:27:55 +02:00
Akim Demaille 39e584c018 CI: more compilers
* .travis.yml: Bionic is now available, with GCC8.
GCC7 sanitizers work, but they are too longer: cover only part 1.
Redefine part 1 and part 2 so that part 1 is really the core of the
tests: not playing with POSIX and C++ compiler for C code.
2019-09-06 17:26:00 +02:00
Akim Demaille 611eaffd28 CI: fail fast 2019-09-06 07:21:54 +02:00
Akim Demaille 3f4ad2cd24 gnulib: update
This update brings file from Gettext 0.20, which is not available on
the CI yet.

.travis.yml: Adjust.
Use Bionic now that it's available.
2019-09-04 18:17:38 +02:00
Akim Demaille 989a7aa865 check for memory exhaustion
hash_initialize returns NULL when out of memory.  Check for it, and
die cleanly instead of crashing.

Reported by 江 祖铭 (Zu-Ming Jiang).
https://lists.gnu.org/archive/html/bug-bison/2019-08/msg00015.html

* src/muscle-tab.c, src/state.c, src/symtab.c, src/uniqstr.c:
Check the value returned by hash_initialize.
2019-09-01 17:53:22 +02:00
Akim Demaille 95cbd56882 news: LAC for C++ 2019-08-30 11:16:57 -05:00
Akim Demaille 92124d27c1 d: remove useless imports
* examples/d/calc.y, tests/calc.at: here.
2019-08-29 07:26:33 -05:00
László VáradyandAkim Demaille 6d81b91ae0 diagnostics: avoid global variables
* src/complain.c (indent_ptr): Remove.
(error_message, complains): Take indent as an argument.
Adjust callers.
2019-08-18 09:40:58 -05:00
László VáradyandAkim Demaille 9145bd0b61 diagnostics: fix invalid error message indentation
https://lists.gnu.org/archive/html/bison-patches/2019-08/msg00007.html

When Bison is started with a flag that suppresses warning messages, the
error_message() function can produce a few gigabytes of indentation
because of a dangling pointer.

* src/complain.c (error_message): Don't reset indent_ptr here, but...
(complain_indent): here.
* tests/diagnostics.at (Indentation with message suppression): Check
this case.
2019-08-18 09:40:44 -05:00
Akim Demaille d7cf3f5b18 c++: use resize to shrink a vector
Suggested by Adrian Vogelsgesang.
https://lists.gnu.org/archive/html/bison-patches/2019-08/msg00009.html

* data/skeletons/lalr1.cc (yy_lac_check_): here.
2019-08-18 06:54:56 -05:00
Akim Demaille f49598a1e1 lalr1.cc: check LAC support
* tests/conflicts.at, tests/input.at, tests/regression.at: here.
2019-08-09 06:40:38 -05:00
Adrian VogelsgesangandAkim Demaille 72d4ae5306 lalr1.cc: add LAC support
Implement lookahead correction (LAC) for the C++ skeleton.  LAC is a
mechanism to make sure that we report the correct list of expected
tokens if a syntax error occurs.  So far, LAC was only supported for
the C skeleton "yacc.c".

* data/skeletons/lalr1.cc: Add LAC support.
* doc/bison.texi: Update.
2019-08-09 06:39:59 -05:00
Adrian VogelsgesangandAkim Demaille 996abe62d7 style: readability improvements to yacc.c
* data/skeletons/yacc.c (yysyntax_error): Change the nesting of `m4`
conditions slightly to make it more readable.
The generated C code stays unchanged.
2019-08-09 06:06:02 -05:00
Adrian VogelsgesangandAkim Demaille 0420362ee8 lalr1.cc: reduce "scope"
* data/skeletons/lalr1.cc (yy_lr_goto_state_): Make it static.
2019-08-09 06:06:00 -05:00
Adrian VogelsgesangandAkim Demaille 6f47eea7ab lalr1.cc: fix indentation of table declarations in the header
* data/skeletons/lalr1.cc: Fix indentation of table declarations in
the generated header.
2019-08-09 05:39:30 -05:00
Akim Demaille 99bfdc09cb tests: prepare LAC tests for more languages
* tests/regression.at: Use %expect to avoid warnings.
Set the keywords to facilitate running specific tests.
Use macros such as AT_YYLEX_DECLARE to facilitate tests for other
languages.
Likewise for AT_FULL_COMPILE.
2019-08-09 05:39:30 -05:00
Akim Demaille 52f21717f7 git: ignore files generated in gnulib-po
Because of them, the CI generates "-dirty" tarballs.
2019-08-09 05:38:19 -05:00
Akim Demaille cbdc22af10 diagnostics: use the modern argmatch interface
* src/complain.h (warnings): Remove Werror.
Adjust dependencies.
Sort.
Remove useless comments (see the doc in argmatch group).
* src/complain.c (warnings_args, warnings_types): Remove.
(warning_argmatch): Use argmatch_warning_value.
(warnings_print_categories): Use argmatch_warning_argument.
2019-07-26 07:57:15 +02:00
Akim Demaille 220c593a79 doc: avoid spurious empty lines in the option table
In Texinfo. empty lines in multitable rows generate empty lines in the
output.  Avoid them altogether.

With help from Gavin Smith.
https://lists.gnu.org/archive/html/bug-texinfo/2019-07/msg00000.html

* build-aux/cross-options.pl: Separate rows with empty lines.
So, to be more readable, generate a single line for each row.
Use Perl format to this end.
2019-07-19 07:46:09 +02:00
Akim Demaille e29ac453d0 --fixed-output-files: detach from --yacc
See the previous commit.  This option should be removed, -o suffices.

* src/getargs.c (FIXED_OUTPUT_FILES): New.
Add support for it.
(getargs): Define loc, and use it.
This is safer when we need to pass a pointer to a location.
2019-07-07 15:59:54 +02:00
Akim Demaille 44a56b20ac %fixed-output-files: detach from %yacc
The name fixed-output-files is pretty clear: generate y.tab.c, as Yacc
does.  So let's detach this from %yacc which does more: it requires
POSIX Yacc behavior.

This directive is obsolete since December 29th 2001
8c9a50bee1.  It does not show in the
doc.  I don't want to spend more time on improving its diagnostics, it
could be removed just as well as far as I'm concerned.

* src/scan-gram.l, src/parse-gram.y (%fixed-output-files): Detach from
%yacc.
2019-07-07 15:54:20 +02:00
Akim Demaille f99956b550 style: clarify control flow
* src/getargs.c (language_argmatch): Initialize msg.
Check it instead of relying on a return.
2019-07-07 15:01:45 +02:00
Akim Demaille 1f02348d6c remove MS-DOS support
DJGPP support was dropped in Bison 3.3
(c239e53bab).

AS_FILE_NAME was introduced in
ae40480115.

* src/getargs.c (AS_FILE_NAME): Remove.
2019-07-07 14:38:49 +02:00
Akim Demaille 421ff03018 style: declare options in the same order as in --help
* src/getargs.c (long_options): here.
2019-07-07 14:27:39 +02:00
Akim Demaille 5d3468e0d1 regen 2019-07-07 14:03:37 +02:00
Akim Demaille 40a8dddde1 gnulib: update
Contains a fix for argmatch to get proper man pages.
See https://lists.gnu.org/archive/html/bug-gnulib/2019-07/msg00038.html
2019-07-07 12:22:02 +02:00
Akim Demaille 9bdefd7984 style: comment change
* src/getargs.c: here.
2019-07-07 12:13:30 +02:00
Akim Demaille d233a2e314 doc: remove the --report=look-aheads alias
Years ago we moved from 'look-ahead' to 'lookahead', and that alias
was kept for backward compatibility.  But now that we use argmatch to
generate the documentation, that value clutters the doc.

* src/getargs.c (argmatch_report_args): Remove the
--report=look-aheads alias.
2019-07-07 08:11:35 +02:00
Akim Demaille d90023af5f doc: fix inaccuracies wrt --define and --force-define
The doc says that -Dfoo=bar is the same as %define foo "bar".  It is
not: the quotes are not added (and it makes a difference).

* doc/bison.texi (Tuning the Parser): Fix the definition of -D/-F
* src/getargs.c (usage): Likewise.
2019-07-07 08:11:35 +02:00
Akim Demaille 964c6508b1 doc: put diagnostics related options together
* doc/bison.texi (Diagnostics): New section.
Move --warning, --color and --style there.
* src/getargs.c (usage): Likewise.
2019-07-07 08:11:35 +02:00
Akim Demaille 4e3c6f59cc doc: move -y's documentation into "Tuning the Parser"
Let's clarify --help: use clearer "section" names, as in the doc.
Move --yacc to where it belongs.

* src/getargs.c (usage): Rename "Parser" as "Tuning the Parser", as in
the doc.
Rename "Output" as "Output Files"
Move --yacc to "Tuning the Parser".
* doc/bison.texi: Likewise.
2019-07-07 08:01:37 +02:00
Akim Demaille 801582b410 doc: document colorized diagnostics
* src/getargs.c (argmatch_color_group): New.
(usage): Document --color and --style.
* doc/bison.texi (Bison Options): Split into three subsections.
Document --color and --style.
2019-07-07 08:01:37 +02:00
Akim Demaille 6d35340556 gnulib: use new features of the argmatch module
It can now generate the usage message.

* src/complain.h (feature_fixit_parsable): Rename as...
(feature_fixit): this, for column economy.
Adjust dependencies.
(warning_usage): New.
Use it.
* src/complain.h, src/complain.c, src/getargs.h, src/getargs.c:
Use ARGMATCH_DEFINE_GROUP instead of the older interface.
2019-07-03 07:02:44 +02:00
Akim Demaille 1161649446 preserve the indentation in the ouput
Preserve the actions' initial indentation.  For instance, on

    | %define api.value.type {int}
    | %%
    | exp: exp '/' exp { if ($3)
    |                     $$ = $1 + $3;
    |                   else
    |                     $$ = 0; }

we used to generate

    |     { if (yyvsp[0])
    |                     yyval = yyvsp[-2] + yyvsp[0];
    |                   else
    |                    yyval = 0; }

now we produce

    |                  { if (yyvsp[0])
    |                     yyval = yyvsp[-2] + yyvsp[0];
    |                   else
    |                     yyval = 0; }

See https://lists.gnu.org/archive/html/bison-patches/2019-06/msg00012.html.

* data/skeletons/bison.m4 (b4_symbol_action): Output the code in
column 0, leave indentation matters to the C code.
* src/output.c (user_actions_output): Preserve the incoming
indentation in the output.
(prepare_symbol_definitions): Likewise for %printer/%destructor.
* tests/synclines.at (Output columns): New.
2019-07-02 07:38:52 +02:00
Akim Demaille 13577a809e style: prefer passing locations by pointer
The code is inconsistent: sometimes we pass by value, sometimes by
reference.  Let's stick to the last, more conventional for large
values in C.

* src/scan-code.l: Pass locations by reference.
2019-07-01 07:23:42 +02:00
Akim Demaille afc219a765 c++: avoid duplicate definition of YYUSE
Reported by Frank Heckenbach.
https://lists.gnu.org/archive/html/bug-bison/2019-06/msg00009.html

* data/skeletons/lalr1.cc (b4_shared_declarations): Remove the
duplicate definition of YYUSE, the other one coming from
b4_attribute_define.
2019-06-30 19:19:43 +02:00
Akim Demaille 21aa4b2713 style: comment changes
* examples/c/lexcalc/local.mk, examples/c/reccalc/local.mk:
Here.
2019-06-27 07:57:21 +02:00
Akim Demaille 63f4dca78f tests: restructure for clarity
* tests/calc.at (AT_CALC_MAIN, AT_CALC_LEX): Rewrite on top of
AT_LANG_DISPATCH.
2019-06-23 19:26:13 +02:00
Akim Demaille 0984f70e08 d: track locations
* configure.ac (DCFLAGS): Pass -g.
* data/skeletons/d.m4 (b4_locations_if): Remove, let bison.m4's one do
its job.
* data/skeletons/lalr1.d (position): Leave filename empty by default.
(position::toString): Don't print empty file names.
(location::this): New ctor.
(location::toString): Match the implementations of C/C++.
(yy_semantic_null): Leave undefined, the previous implementation does
not compile.
* tests/calc.at: Improve the implementation for D.
Enable more checks, in particular using locations.
* tests/local.at (AT_YYERROR_DEFINE(d)): Fix its implementation.
2019-06-23 11:20:18 +02:00
Akim Demaille f26bd45da3 d: style changes
* data/skeletons/lalr1.d: Use a more traditional quotation scheme.
Formatting changes.
2019-06-23 11:20:16 +02:00
Akim Demaille a3adc1701b d: put internal details inside the parser
Avoid name clashes, etc.

* data/skeletons/lalr1.d (YYStackElement, YYStack): Move inside the
parser.
2019-06-23 11:19:46 +02:00
Akim Demaille 7ab275214b gnulib: update 2019-06-22 09:03:19 +02:00
Akim Demaille 0428c429a1 remove "experimental" warnings
Sadly enough, AFAIK, there were never answers to the "More user
feedback will help to stabilize it" sentences.  Remove them.

* src/getargs.c: IELR, canonical LR and XML output are here to stay,
and they are no more experimental than some other features.
* doc/bison.texi: Likewise.
Also remove "experimental" warning for Java, LAC, LR tuning options,
and named references.
2019-06-22 08:29:06 +02:00
Akim Demaille 14fb2cc820 CI: propagate sftp failures
* .travis.yml (stage: "compile"): here.
2019-06-22 08:29:06 +02:00
Akim Demaille faf033957c d: honor %define parse.trace
* data/skeletons/lalr1.d: Don't generate debug code if parse.trace is
not enabled.
2019-06-20 06:57:27 +02:00
Akim Demaille 0555e25a41 d: style changes
* data/skeletons/lalr1.d: here.
2019-06-20 06:57:27 +02:00
Akim Demaille cde8c0a0e6 d: prefer delegation to duplication
* data/skeletons/lalr1.d: Delegate the construction of the scanner.
2019-06-20 06:57:27 +02:00
Akim Demaille 5b525e86a5 d: enable #line output
* data/skeletons/d.m4 (b4_sync_start): New.
2019-06-20 06:57:27 +02:00
Akim Demaille df77a98edf d: style changes
* data/skeletons/lalr1.d: here.
* examples/d/calc.y: Remove incorrect support for decimal numbers.
Formatting changes.
2019-06-20 06:57:27 +02:00
Akim Demaille c23fa0fc97 style: reduce scopes in glr.c
* data/skeletons/glr.c: here.
2019-06-20 06:57:27 +02:00
Akim Demaille 08c0571613 java: honor %define parse.trace
* data/skeletons/lalr1.java: Don't generate debug code if parse.trace
is not enabled.
2019-06-20 06:57:27 +02:00
Akim Demaille f2b210a901 java: fix support for api.prefix
* data/skeletons/java.m4: here.
* tests/java.at: Check it.
2019-06-19 19:15:31 +02:00
Akim Demaille 66ac4acc6c java: style changes
* data/skeletons/lalr1.java: Use more conventional function names for
Java.
Prefer < and <= to => and >.
Use the same approach for m4 quotation as in the other skeletons.
Fix indentation issues.

* tests/calc.at, tests/java.at, tests/javapush.at: Fix quotation style.
(main): Use 'args', not 'argv', the former seems more conventional and
is used elsewhere in Bison.
Prefer character literals to integers to denote characters.
* examples/java/Calc.y: Likewise.
2019-06-19 19:15:26 +02:00
Akim Demaille cd0f25df5f CI: avoid useless git costs
Travis answered favorably to my suggestion to provide a means to
disable git clone on some jobs (issue 7542).  See
https://docs.travis-ci.com/user/customizing-the-build/#disabling-git-clone.

* .travis.yml: Disable git globally, enable it for i. the compile job,
and ii. the test job on ICC which needs the install-icc.sh script.
2019-06-15 10:28:50 +02:00
Akim Demaille 0f46038589 style: simplify strings to translate
* src/conflicts.c (log_resolution): Don't translate indentation.
2019-06-12 21:41:16 +02:00
Akim Demaille 1105cf841b style: reduce scopes, propagate const
* src/conflicts.c (conflicts_output): here.
2019-06-12 21:41:16 +02:00
Akim Demaille a298a6d82b style: use clearer types
* src/conflicts.c (conflicts): Array of Booleans.
2019-06-12 06:59:31 +02:00
Akim Demaille 5f33acefd1 tests: prefer %empty
* tests/regression.at: here.
2019-06-11 20:40:36 +02:00
Akim Demaille 849ba01b8b CI: factor
* .travis.yml (Clang 7 libc++ and ASAN part 2): Reuse bits from "Clang
7 libc++ and ASAN part 1".
2019-06-09 11:11:14 +02:00
Akim Demaille 29c9cb3188 lr0: more debug traces
* src/lr0.c (kernel_check): New.
(new_itemsets, save_reductions): Add traces.
2019-06-09 11:11:12 +02:00
Akim Demaille ec4d49e129 traces: add some colors
This is an experiment.  Maybe more styles will be used (in which case
a short-hand function will be useful), maybe it will be just reverted.
* data/bison-default.css (.traces0): New.
* src/lalr.c (lalr): Use it.
2019-06-09 08:36:01 +02:00
Akim Demaille d84b245c63 tests: make sure the default action properly works in C++
See e3fdc37049: in C++ we generate
explicitly the code for the default action instead of simply copying
blindly the semantic value buffer.  This is important when copying
raw memory is not enough, as exemplified by move-only types.

This is currently tested by examples/c++/variant.yy and variant-11.yy.
But it is safer to also have a test in the main test suite.

* tests/local.at (AT_REQUIRE_CXX_STD): Fix.
(AT_BISON_OPTION_PUSHDEFS, AT_BISON_OPTION_POPDEFS): Define/undefine
AT_BISON_OPTIONS.
* tests/c++.at (Default action): New.
2019-06-09 08:36:01 +02:00
Akim Demaille 73797b2552 tests: main: support -s and -p
* tests/local.at (AT_MAIN_DEFINE(c), AT_MAIN_DEFINE(c++)): here.
2019-06-09 08:36:01 +02:00
Akim Demaille dfef525920 tests: remove useless support of '.' in integers
* tests/calc.at: here.
* doc/bison.texi: Avoid uninitialized variables.
2019-06-04 08:36:43 +02:00
Akim Demaille 7f017ae1c9 tests: refactor checks on sets
It will be convenient to check sets elsewhere.

* tests/sets.at (AT_EXTRACT_SETS): Transform into...
* tests/local.at (AT_SETS_CHECK): this.
* tests/sets.at: Adjust.
2019-05-29 08:38:16 +02:00
Akim Demaille 65126716d7 update-test: some file names have dashes in them
* build-aux/update-test (log): Rename as...
(trace): this, to avoid clashes with the log variable.
(getargs): Clarify the type of the arguments.
2019-05-29 08:26:20 +02:00
Akim Demaille 1dcd6068dd tests: take SHELL into account
Reported by Dennis Clarke.
http://lists.gnu.org/archive/html/bug-bison/2019-05/msg00053.html

* examples/local.mk, tests/local.mk: here.
2019-05-26 15:29:37 +02:00
Akim Demaille 02f16dc799 gnulib: update to get gnulib translations
This update contains a fix needed for gnulib-po to work properly.
https://lists.gnu.org/archive/html/bug-gnulib/2019-05/msg00146.html
2019-05-26 09:35:31 +02:00
Akim Demaille aa21c457f2 doc: clarify the purpose of symbol_type constructors
Reported by Frank Heckenbach.
http://lists.gnu.org/archive/html/bug-bison/2019-02/msg00006.html

* doc/bison.texi (Complete Symbols): Here.
2019-05-25 10:28:12 +02:00
Akim Demaille 9f26e6d6b3 thanks: fix an address 2019-05-22 18:09:04 +02:00
Akim Demaille 8d3e782e05 maint: post-release administrivia
* NEWS: Add header line for next release.
* .prev-version: Record previous version.
* cfg.mk (old_NEWS_hash): Auto-update.
2019-05-22 07:45:49 +02:00
Akim Demaille 1c671bad33 version 3.4.1
* NEWS: Record release date.
2019-05-22 07:28:15 +02:00
Akim Demaille 88cd9570b6 NEWS: update 2019-05-22 07:22:51 +02:00
Akim Demaille c423ad17e7 CI: remove useless apt-get update
The apt addons already ran it for us, it is not needed.

* .travis.yml: here.
2019-05-20 09:35:24 +02:00
Akim Demaille 9114b267a8 c++: beware of to_string portability issues
Reported by Bruno Haible.
http://lists.gnu.org/archive/html/bug-bison/2019-05/msg00033.html

* m4/bison-cxx-std.m4 (_BISON_CXXSTD_11_snippet): Check it.
2019-05-20 06:27:55 +02:00
Akim Demaille 70c3f3ade5 doc: avoid Texinfo portability issues
Reported by Bruno Haible.
http://lists.gnu.org/archive/html/bug-bison/2019-05/msg00024.html
Fixed by Karl Berry.
http://lists.gnu.org/archive/html/bug-bison/2019-05/msg00034.html

* doc/bison.texi: Don't specify the langage, rely on the default.
Avoid blank pages.
2019-05-20 06:12:47 +02:00
Akim Demaille 1934304acf examples: don't run those that require f?lex when it's not available
Reported by Bruno Haible.
http://lists.gnu.org/archive/html/bug-bison/2019-05/msg00026.html

* configure.ac (FLEX_WORKS): New.
* examples/c/lexcalc/local.mk, examples/c/reccalc/local.mk: Use it.
2019-05-19 18:41:59 +02:00
Akim Demaille c8e57e8159 diagnostics: don't crash when libtextstyle is installed
Reported by neok m4700.
https://lists.gnu.org/archive/html/bison-patches/2019-05/msg00025.html
https://github.com/akimd/bison/pull/11

* src/complain.c (complain_init_color): style_file_prepare _needs_ a
string as second argument.
2019-05-19 18:16:47 +02:00
Akim Demaille 1e49f5e1e6 CI: avoid useless git costs
The final gain is small: 2h2min instead 2h9min.  But that is still an
improvement.

* .travis.yml (git.depth): Make the clone very shallow.
(git.submodules): Don't clone gnulib in test jobs.
(jobs.include.compile.script): Do it here.
2019-05-19 17:52:28 +02:00
Akim Demaille 49aae94bed fix: copyable instead of copiable
Reported by Frank Heckenbach.
http://lists.gnu.org/archive/html/bug-bison/2019-05/msg00020.html

* data/skeletons/lalr1.cc, doc/bison.texi: here.
2019-05-19 13:53:15 +02:00
Akim Demaille e191bf7b9f maint: post-release administrivia
* NEWS: Add header line for next release.
* .prev-version: Record previous version.
* cfg.mk (old_NEWS_hash): Auto-update.
2019-05-19 11:36:06 +02:00
Akim Demaille f520e150eb version 3.4
* NEWS: Record release date.
2019-05-19 11:19:47 +02:00
Akim Demaille 75db37c564 fix: use copiable, not copyable
Reported by Hans Åberg.
http://lists.gnu.org/archive/html/bug-bison/2019-05/msg00017.html

* data/skeletons/lalr1.cc, doc/bison.texi: here.
2019-05-19 11:17:44 +02:00
Akim Demaille 886b503e4b NEWS: update for 3.4 2019-05-19 11:01:20 +02:00
Akim Demaille a2f0444c6e tests: adjust to GCC9 diagnostics with a margin
* tests/synclines.at (_AT_SYNCLINES_COMPILE): Remove the margin.
2019-05-19 10:53:02 +02:00
Akim Demaille 66100b640f regen 2019-05-19 10:05:18 +02:00
Akim Demaille de5207244b diagnostics: %pure-parser is obsolete
Reported by Uxio Prego.
http://lists.gnu.org/archive/html/bug-bison/2018-12/msg00029.html

* src/scan-gram.l, src/parse-gram.y (PERCENT_PURE_PARSER)
(handle_pure_parser): New.
Issue a deprecation/update notice for %pure-parser.
* doc/bison.texi (Java Bison Interface): Don't mention %pure-parser.
* tests/actions.at, tests/input.at: Adjust.
2019-05-19 10:05:18 +02:00
Akim Demaille cae8132690 diagnostics: clean up convention for colored diagnostics
* data/diagnostics.css: Rename as...
* data/bison-default.css: this.
Add the GPL header.
This is the convention followed by Bruno Haible in gettext.
Adjust dependencies.
* src/complain.c (complain_init_color): Use BISON_STYLE instead of
BISON_DIAGNOSTICS_STYLE.
2019-05-19 09:50:21 +02:00
Akim Demaille a1a847bfb5 CI: use a pipeline: first build the tarball, then check it
Build the tarball in one job, check it in many.
Unfortunately no real gain in overall duration.
With help from Clément Démoulins.

* .travis.yml: here.
Remove all the tricks that were used to be able to boostrap on old
distros.
(before_install): Merge into 'script', because before_install applies
to all the jobs, and we don't want to run it for the 'compile' job.
2019-05-19 09:45:27 +02:00
Akim Demaille 3ac95de01a examples: fix srcdir/builddir issues
* examples/d/local.mk, examples/java/local.mk: here.
2019-05-18 13:22:58 +02:00
Akim Demaille da7af36a13 gnulib: update
In preparation for Bison 3.4, revert to the version before this
commit:

    commit 03752516b21091cf3c4beea7e8b9bcad462d50ed
    Author: John Darrington <[email protected]>
    Date:   Sun May 12 00:42:36 2019 +0200

    version-etc: Ease translation.

    * lib/version-etc.c (version_etc_arn, emit_bug_reporting_address):
    Move URLs and formatting newlines out of translatable string.

because it changes the messages for --version, translated in
gnulib.po.  These changes are not yet available on the translation
project, so we would have a regression in the set of translated
strings.
2019-05-18 09:10:08 +02:00
Akim Demaille 3f25104caf build: do not use $< in plain rules
It works only in implicit rules (or with GNU Make, but not with
Solaris Make).

Reported by Bruno Haible.
http://lists.gnu.org/archive/html/bug-bison/2019-05/msg00009.html
Diagnosed thanks to Kiyoshi Kanazawa.

* examples/c/reccalc/local.mk, examples/d/local.mk,
* examples/java/local.mk: Don't use $< in non implicit rules.
2019-05-13 22:16:23 +02:00
Akim Demaille 6b1933d992 maint: post-release administrivia
* NEWS: Add header line for next release.
* .prev-version: Record previous version.
* cfg.mk (old_NEWS_hash): Auto-update.
2019-05-12 14:25:31 +02:00
Akim Demaille 5163803a63 version 3.3.91
* NEWS: Record release date.
2019-05-12 14:09:10 +02:00
Akim Demaille fee7c78a83 NEWS: update 2019-05-12 14:07:43 +02:00
Akim Demaille 8fc544b03c gnulib: update 2019-05-12 11:39:27 +02:00
Akim Demaille d62d5c4b33 style: remove incorrect comment
* src/getargs.c: here.
It's documented in getargs.h anyway.
2019-05-11 09:19:16 +02:00
Akim Demaille ab3eaff7c4 doc: use colors for diagnostics in TeX too
Thanks to Gavin Smith and Patrice Dumas.
http://lists.gnu.org/archive/html/help-texinfo/2019-04/msg00015.html

* doc/bison.texi (@colorWarning, @colorError, @colorNotice)
(@colorOff): Define for TeX and HTML.
(@dwarning, @derror, @dnotice): Use them.
2019-05-09 19:21:02 +02:00
Akim Demaille 85e83ea968 gnulib: update to fix location tracking in UTF-8 on Solaris
This update contains Bruno Haible's fix for the location tracking
issue reported by Kiyoshi Kanazawa.

https://lists.gnu.org/archive/html/bug-gnulib/2019-05/msg00020.html
https://lists.gnu.org/archive/html/bug-bison/2019-04/msg00020.html
2019-05-08 16:34:31 +02:00
Akim Demaille 0269c6fb03 diagnostics: rename --style=debug as --color=debug
It is more consistent with --color=html, --color=test, etc.

* src/getargs.h, src/getargs.c (style_debug): Rename as...
(color_debug): this.
(getargs_colors): Rename --style=debug as --color=debug.
Adjust dependencies.
2019-05-08 13:36:47 +02:00
Akim Demaille 23e536af49 diagnostics: support --color=html
Based on a message from Bruno Haible.
https://git.savannah.gnu.org/gitweb/?p=gettext.git;a=commitdiff;h=fe18e92743b7226791a5f28d7c786941a1bf8cc9

This does not generate proper HTML: special characters are not escaped
for instance.  This is a hidden feature meant for Bison developers,
not end users.

* src/complain.c (complain_init_color): Support --color=html.
2019-05-08 13:36:47 +02:00
Akim Demaille cd56929097 tests: use %empty instead of comments
* tests/c++.at, tests/glr-regression.at: here.
2019-05-08 09:11:37 +02:00
Akim Demaille 7aa38561f7 fixits: sort them before applying them
An experimental commit introduced a fix-it hint that changes comments
such as "/* empty */" into %empty.  But in some case, because
diagnostics are not necessarily emitted in order, the fixits also come
in disorder, which must never happen, as the fixes are installed in
one pass.

* src/fixits.c (fixits_register): Insert them in order.
2019-05-08 09:10:28 +02:00
Akim Demaille 22a00cfbf2 style: use warning_is_enabled instead of duplicating it
* src/complain.c (deprecated_directive): Here.
2019-05-04 17:50:57 +02:00
Akim Demaille 8c06cb9130 fixits: be sure to preserve the action when adding %empty
Currently we remove the rhs to install %empty instead.

* src/reader.c (grammar_rule_check_and_complete): Insert the missing
%empty in front of the rhs, not in replacement thereof.
* tests/actions.at (Add missing %empty): Check that.
2019-05-03 16:28:28 +02:00
Akim Demaille b5233ba323 tests: don't duplicate the portability prologue
* tests/actions.at, tests/input.at: Don't repeat the prologue, skip it.
* tests/diagnostics.at, tests/local.at: Comment changes.
2019-05-03 16:28:28 +02:00
Akim Demaille 013720f0e7 style: use consistently *_loc for locations
Some members are called foo_location, others are foo_loc.  Stick to
the latter.

* src/gram.h, src/location.h, src/location.c, src/output.c,
* src/parse-gram.y, src/reader.h, src/reader.c, src/reduce.c,
* src/scan-gram.l, src/symlist.h, src/symlist.c, src/symtab.h,
* src/symtab.c:
Use _loc consistently, not _location.
2019-05-03 16:28:28 +02:00
Akim Demaille 365b4d95a4 style: clarify the use of symbol_lists' locations
symbol_list features a 'location' and a 'sym_loc' member.  The former
is expected to be set only for symbol_lists that denote a symbol (not
a type name), and the latter should only denote the location of the
symbol/type name.  Yet both are set, and the name "location" is too
unprecise.

* src/symlist.h, src/symlist.c (symbol_list::location): Rename as
rhs_loc for clarity.  Move it to the "section" of data valid only
for rules.
* src/reader.c, src/scan-code.l: Adjust.
2019-05-03 16:28:28 +02:00
Akim Demaille 5bb44cca81 maint: update gnulib-po/.gitignore 2019-05-03 16:28:28 +02:00
Akim Demaille 15f9f8c853 tests: don't require a D compiler
Reported by Kiyoshi Kanazawa.
http://lists.gnu.org/archive/html/bug-bison/2019-04/msg00018.html

* tests/atlocal.in (BISON_DC_WORKS): New.
* tests/local.at (AT_COMPILE_D): Use it.
2019-04-29 22:27:01 +02:00
Akim Demaille 04676a5085 doc: use svg instead of png
* doc/bison.texi, doc/local.mk: here.
2019-04-29 07:44:19 +02:00
Akim Demaille cf44351dd7 doc: use colors
* doc/bison.texi (dwarning, derror, dnotice): New.
Use them in the diagnostics.
* doc/local.mk (AM_MAKEINFOFLAGS): Pass customization variables.
2019-04-29 07:44:19 +02:00
Akim Demaille 614e0bbe23 maint: post-release administrivia
* NEWS: Add header line for next release.
* .prev-version: Record previous version.
* cfg.mk (old_NEWS_hash): Auto-update.
2019-04-28 12:02:35 +02:00
125 changed files with 5770 additions and 3397 deletions
-3
View File
@@ -1,9 +1,6 @@
/ABOUT-NLS~
*.eps
*.log
*.o
*.pdf
*.png
*.stamp
*.trs
*~
+1 -1
View File
@@ -1 +1 @@
3.3.2
3.4.2
+237 -135
View File
@@ -1,8 +1,7 @@
# Travis defines and exports CC and CXX *after* we have defined our
# environment variables via 'env'. So, do not use 'env' to define
# them. Instead, put their definitions in MATRIX_EVAL, which we eval
# after the definitions from Travis.
# environment variables via 'env'. So, do not use 'env' to define them.
# Instead, put their definitions in MATRIX_EVAL, which we eval after the
# definitions from Travis.
language: cpp
env:
@@ -11,8 +10,65 @@ env:
# See https://github.com/nemequ/icc-travis.
secure: B3manbbi0anCAGDJTdAa9TlodzRHeiYD87FKmFzS877dPm8Cm0BDvtUhKBUpBvP8+nbHOWFGrgDmLugSZjTGU+mAxtuQpamUFHvinu0BIk3qtjlqouwvbtIqUu8iiZ3Uqu+xKeAANKRy0YVZGLlEb9F3N119tJ/Fxp1p9bXL1qph+CZ25OFbUgZ2s4F+/AyHMUxJlNXKFe3Qean65hC6edhU3zoaKzr/g/wtbhRmcyWbkOa1dJqzr2yKotcPvrnApGhDzgMKFtohg/t7xfMADDVv6sGS5XNpt25Z+MUCmLg4Z9eD7u109jvRV1eu/jgVafqsthWEhXbuMiFgFhKBKGCNZ0dACIfKZSkFZI6FdM7ovJ6aNhSlxZ2169Ybd22rN1UTHeCQWySPcVVOg5taLVpqe+E8Xhnv4hBO5NrzElWwCMLxIdPUSwVStYvtDr8ZytHWzfot50vSnFKIFpTOr9hP4+AJMVmmqJfaJo2MLBft/q2xkztrMv3lQSj3m4+ma9kPDwXIu9uCutjlnhc00jNx9qegi5VfpAjxcG1R+pX4T20az6ByHk/7LPQsANkT31RJq/jAeD9LEuMOy8miha83q4QuvbFaqPK3PY0el/O1LZaXqLsV2aQ0uqH8YX0l4r5NzHdhb+3lYgvpMBO5ytr/EWJiEyNYV518050IUDE=
matrix:
# Run in two steps:
# 1. Build the tarball
# On a modern distro, with all the needed dependencies, including the whole git history.
# 2. Check it on various environments.
# Less dependencies, and little git content (we would like to have none, but it's not
# an option on Travis).
stages:
- dist
- check
# The 'check' jobs do not need the repo at all, only the 'dist'
# does. Let's save time, bandwith, energy, and polar bears.
git:
clone: false
# matrix.include and jobs.include are aliases
# (https://docs.travis-ci.com/user/conditional-builds-stages-jobs/).
jobs:
include:
- stage: dist
name: "Make dist"
git:
clone: true
dist: bionic
script:
- sudo apt-get install -qq autoconf automake autopoint flex gettext graphviz help2man m4 texinfo
- autoconf --version
- automake --version
- autopoint --version
- dot -V
- gettext --version
- help2man --version
- makeinfo --version
- m4 --version
# Travis makes a shallow clone, but we need it in full to build the ChangeLog and apply the fixes in git-log-fix.
- git fetch --unshallow || true
- git submodule update --init --recursive
- ./bootstrap
- ./configure --enable-gcc-warnings || { cat config.log && false; }
- make -j2
- make -j2 dist
# Can help understanding why we get "dirty" tarballs.
- git status
- dist=$(echo bison*.xz)
# Unfortunately we cannot deterministically know the name of the tarball without the full
# git history (because git describe --abbrev=4 may use more than 4 characters if there are
# conflicts).
#
# So for the sake of the 'check' jobs (that don't even have the repo at all), also expose this
# tarball on a name that only depends on the Travis build number.
#
# Without -b -, exit status is always 0.
#
# If we rerun a job that was already uploaded, 'ln -s' will fail: remove beforehand.
- sftp -b - [email protected] <<< "put $dist"$'\n'"-rm bison-$TRAVIS_BUILD_NUMBER.tar.xz"$'\n'"ln -s $dist bison-$TRAVIS_BUILD_NUMBER.tar.xz"
## ------- ##
## First. ##
## ------- ##
@@ -20,154 +76,167 @@ matrix:
# Start with three completely different environments, to get
# errors asap.
- name: "GCC 7 -O3"
- name: "GCC 9 -O3"
stage: check
os: linux
dist: xenial
dist: bionic
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- g++-7
# See https://github.com/travis-ci/apt-source-safelist/issues/410.
- sourceline: 'ppa:ubuntu-toolchain-r/test'
packages: g++-9
env:
- MATRIX_EVAL="CC=gcc-7 && CXX=g++-7 && CONFIGUREFLAGS='CPPFLAGS=-DNDEBUG CFLAGS=-O3 CXXFLAGS=-O3'"
- MATRIX_EVAL="CC=gcc-9 && CXX=g++-9 && CONFIGUREFLAGS='CPPFLAGS=-DNDEBUG CFLAGS=-O3 CXXFLAGS=-O3'"
# ASAN is time consuming, and we timeout the 50min granted by
# Travis if we run all the tests in on go. Run in two parts.
- name: "Clang 7 libc++ and ASAN part 1"
# Travis if we run all the tests in one go. Run in two parts.
- name: "Clang 9 libc++ and ASAN part 1"
stage: check
os: linux
dist: xenial
addons:
dist: bionic
addons: &clang9
apt:
sources:
- llvm-toolchain-xenial-7
- ubuntu-toolchain-r-test
# See https://github.com/travis-ci/apt-source-safelist/issues/410.
- sourceline: 'ppa:ubuntu-toolchain-r/test'
- sourceline: 'deb http://apt.llvm.org/bionic/ llvm-toolchain-bionic-9 main'
key_url: 'https://apt.llvm.org/llvm-snapshot.gpg.key'
packages:
- clang-7
- libc++-7-dev
- libc++abi-7-dev
- clang-9
- libc++-9-dev
- libc++abi-9-dev
env:
# Do not use ASAN with ubuntu's libc++: https://bugs.llvm.org/show_bug.cgi?id=17379
- MATRIX_EVAL="PART=1 CC='clang-7 -fsanitize=address' CXX='clang++-7 -fsanitize=address -stdlib=libc++'"
- MATRIX_EVAL="CC='clang-9 -fsanitize=address' CXX='clang++-9 -fsanitize=address -stdlib=libc++'"
- PART=1
- name: "Clang 7 libc++ and ASAN part 2"
- name: "Clang 9 libc++ and ASAN part 2"
stage: check
os: linux
dist: xenial
addons:
apt:
sources:
- llvm-toolchain-xenial-7
- ubuntu-toolchain-r-test
packages:
- clang-7
- libc++-7-dev
- libc++abi-7-dev
dist: bionic
addons: *clang9
env:
# Do not use ASAN with ubuntu's libc++: https://bugs.llvm.org/show_bug.cgi?id=17379
- MATRIX_EVAL="PART=2 CC='clang-7 -fsanitize=address' CXX='clang++-7 -fsanitize=address -stdlib=libc++'"
- MATRIX_EVAL="CC='clang-9 -fsanitize=address' CXX='clang++-9 -fsanitize=address -stdlib=libc++'"
- PART=2
- name: "ICC"
os: linux
dist: xenial
env:
# ICC's warnings are often very wrong (e.g., it thinks foo ?
# "bar" : "baz" is char* instead of const char*), so don't try
# to work around the, and obviously, don't die on them.
- MATRIX_EVAL="CC=icc && CXX=icpc"
- MAKE_ARGS='WERROR_CFLAGS= WERROR_CXXFLAGS='
# Currently no longer works (https://github.com/nemequ/icc-travis/issues/15).
# - name: "ICC"
# stage: check
# # We need the build-aux/install-icc.sh script.
# git:
# clone: true
# submodules: false
# depth: 1
# os: linux
# dist: xenial
# env:
# # ICC's warnings are often very wrong (e.g., it thinks foo ?
# # "bar" : "baz" is char* instead of const char*), so don't try
# # to work around the, and obviously, don't die on them.
# - MATRIX_EVAL="CC=icc && CXX=icpc"
# - MAKE_ARGS='WERROR_CFLAGS= WERROR_CXXFLAGS='
## ----- ##
## GCC. ##
## ----- ##
#- name: "GCC 8 with sanitizers"
# os: linux
# dist: xenial
# addons:
# apt:
# sources:
# - ubuntu-toolchain-r-test
# packages:
# - g++-8
# env:
# # Can't use UBSAN: I get:
# # configure:4951: gcc-8 -fsanitize=undefined,address -fno-omit-frame-pointer conftest.c
# # /usr/bin/ld: unrecognized option '--push-state' (on trusty)
# # /usr/bin/ld: unrecognized option '--push-state--no-as-needed' (on xenial)
# #
# # https://stackoverflow.com/questions/50024731/ suggests using the gold linker.
# - MATRIX_EVAL="CC='gcc-8 -fsanitize=undefined,address -fno-omit-frame-pointer' CXX='g++-8 -fsanitize=undefined,address -fno-omit-frame-pointer'"
- name: "GCC 8 with sanitizers part 1"
os: linux
dist: bionic
addons:
apt:
packages: g++-8
env:
- MATRIX_EVAL="CC='gcc-8 -fsanitize=undefined,address -fno-omit-frame-pointer' CXX='g++-8 -fsanitize=undefined,address -fno-omit-frame-pointer'"
- CONFIGUREFLAGS='CFLAGS=-O1 CXXFLAGS=-O1'
- PART=1
- name: "GCC 8"
stage: check
os: linux
dist: bionic
addons:
apt:
packages: g++-8
env:
- MATRIX_EVAL="CC=gcc-8 && CXX=g++-8"
- name: "GCC 7"
stage: check
os: linux
dist: bionic
addons:
apt:
packages: g++-7
env:
- MATRIX_EVAL="CC=gcc-7 && CXX=g++-7"
- name: "GCC 6"
stage: check
os: linux
dist: xenial
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- g++-6
sources: ubuntu-toolchain-r-test
packages: g++-6
env:
- MATRIX_EVAL="CC=gcc-6 && CXX=g++-6"
- name: "GCC 5"
stage: check
os: linux
dist: xenial
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- g++-5
sources: ubuntu-toolchain-r-test
packages: g++-5
env:
- MATRIX_EVAL="CC=gcc-5 && CXX=g++-5"
- name: "GCC 4.9"
stage: check
os: linux
dist: xenial
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- g++-4.9
sources: ubuntu-toolchain-r-test
packages: g++-4.9
env:
- MATRIX_EVAL="CC=gcc-4.9 && CXX=g++-4.9"
- name: "GCC 4.8"
stage: check
os: linux
dist: xenial
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- g++-4.8
sources: ubuntu-toolchain-r-test
packages: g++-4.8
env:
- MATRIX_EVAL="CC=gcc-4.8 && CXX=g++-4.8"
- name: "GCC 4.7"
stage: check
os: linux
dist: xenial
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- g++-4.7
sources: ubuntu-toolchain-r-test
packages: g++-4.7
env:
- MATRIX_EVAL="CC=gcc-4.7 && CXX=g++-4.7"
- name: "GCC 4.6"
stage: check
os: linux
dist: xenial
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- g++-4.6
sources: ubuntu-toolchain-r-test
packages: g++-4.6
env:
- MATRIX_EVAL="CC=gcc-4.6 && CXX=g++-4.6"
@@ -175,7 +244,35 @@ matrix:
## Clang. ##
## ------- ##
- name: "Clang 6 -O3 and libc++"
- name: "Clang 8 -O3"
stage: check
os: linux
dist: bionic
addons:
apt:
packages:
- clang-8
- libc++-8-dev
- libc++abi-8-dev
env:
- MATRIX_EVAL="CC=clang-8 && CXX='clang++-8 -stdlib=libc++'"
- CONFIGUREFLAGS='CPPFLAGS=-DNDEBUG CFLAGS=-O3 CXXFLAGS=-O3'
- name: "Clang 7"
stage: check
os: linux
dist: bionic
addons:
apt:
packages:
- clang-7
- libc++-7-dev
- libc++abi-7-dev
env:
- MATRIX_EVAL="CC=clang-7 && CXX='clang++-7 -stdlib=libc++'"
- name: "Clang 6 and libc++"
stage: check
os: linux
dist: xenial
addons:
@@ -188,15 +285,14 @@ matrix:
- libc++-dev
env:
- MATRIX_EVAL="CC=clang-6.0 && CXX='clang++-6.0 -stdlib=libc++'"
- CONFIGUREFLAGS='CPPFLAGS=-DNDEBUG CFLAGS=-O3 CXXFLAGS=-O3'
- name: "Clang 5"
stage: check
os: linux
dist: xenial
addons:
apt:
sources:
- llvm-toolchain-xenial-5.0
sources: llvm-toolchain-xenial-5.0
packages:
- clang-5.0
- libc++-dev
@@ -204,30 +300,29 @@ matrix:
- MATRIX_EVAL="CC='clang-5.0' CXX='clang++-5.0'"
- name: "Clang 4"
stage: check
os: linux
dist: xenial
addons:
apt:
sources:
- llvm-toolchain-xenial-4.0
packages:
- clang-4.0
sources: llvm-toolchain-xenial-4.0
packages: clang-4.0
env:
- MATRIX_EVAL="CC=clang-4.0 && CXX=clang++-4.0"
- name: "Clang 3.9"
stage: check
os: linux
dist: xenial
addons:
apt:
sources:
- llvm-toolchain-xenial-3.9
packages:
- clang-3.9
sources: llvm-toolchain-xenial-3.9
packages: clang-3.9
env:
- MATRIX_EVAL="CC=clang-3.9 && CXX=clang++-3.9"
- name: "Clang 3.8"
stage: check
os: linux
dist: xenial
addons:
@@ -235,12 +330,12 @@ matrix:
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-precise-3.8
packages:
- clang-3.8
packages: clang-3.8
env:
- MATRIX_EVAL="CC=clang-3.8 && CXX=clang++-3.8"
- name: "CLang 3.7"
stage: check
os: linux
dist: xenial
addons:
@@ -248,12 +343,12 @@ matrix:
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-precise-3.7
packages:
- clang-3.7
packages: clang-3.7
env:
- MATRIX_EVAL="CC=clang-3.7 && CXX=clang++-3.7"
- name: "Clang 3.6"
stage: check
os: linux
dist: xenial
addons:
@@ -261,12 +356,12 @@ matrix:
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-precise-3.6
packages:
- clang-3.6
packages: clang-3.6
env:
- MATRIX_EVAL="CC=clang-3.6 && CXX=clang++-3.6"
- name: "Clang 3.5"
stage: check
os: linux
dist: xenial
addons:
@@ -274,82 +369,89 @@ matrix:
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-precise-3.5
packages:
- clang-3.5
packages: clang-3.5
env:
- MATRIX_EVAL="CC=clang-3.5 && CXX=clang++-3.5"
- name: "Clang 3.4"
stage: check
os: linux
# Not available on Xenial.
dist: trusty
addons:
apt:
packages:
- clang-3.4
packages: clang-3.4
env:
# No versioned name installed, but beware that Travis installs
# a more modern clang earlier in the default PATH.
- MATRIX_EVAL='CC=/usr/bin/clang && CXX=/usr/bin/clang++ && GETTEXT_VERSION=0.18.3'
- MATRIX_EVAL='CC=/usr/bin/clang && CXX=/usr/bin/clang++'
- name: "Clang 3.3"
stage: check
os: linux
# Not available on Xenial.
dist: trusty
addons:
apt:
packages:
- clang-3.3
packages: clang-3.3
env:
# See comment for 3.4.
- MATRIX_EVAL='CC=/usr/bin/clang && CXX=/usr/bin/clang++ && GETTEXT_VERSION=0.18.3'
- MATRIX_EVAL='CC=/usr/bin/clang && CXX=/usr/bin/clang++'
## From https://docs.gitlab.com/ce/ci/ssh_keys/#ssh-keys-when-using-the-docker-executor.
## Applies to Travis too. Applied to all the 'script's (of all the jobs).
before_script:
- 'which ssh-agent || ( sudo apt-get install openssh-client -y )'
- eval "$(ssh-agent -s)"
# $SSH_PRIVATE_KEY is multiline. Use $'...' to register its value: $'-----BEGIN OPENSSH PRIVATE KEY-----\nXXXXX...\n...==\n-----END OPENSSH PRIVATE KEY-----'.
- echo "$SSH_PRIVATE_KEY" >/tmp/key.id_rsa
- chmod 600 /tmp/key.id_rsa
- ssh-add /tmp/key.id_rsa </dev/null
- mkdir -p ~/.ssh
- chmod 700 ~/.ssh
- echo '|1|bpc51UGxoDZjCPiwRlCStW32trI=|rfh6mLoLZv/vAvOVrpZXI1hTLxg= ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBIR+ckMoJTNXHvAQLHWSfrRnrNJGW2ZR6kr5pBVDGCkz1v1RcQ5rleq0NAt9kS3v4hgnuLiEVnK7KDRzcEH3ikc=' >>~/.ssh/known_hosts
- chmod 600 ~/.ssh/known_hosts
before_install:
# Applies only to the jobs that don't have a 'script', i.e., applies to all the 'check' jobs, but not the 'dist' one.
script:
- eval "$MATRIX_EVAL"
- env
- sudo apt-get update -qq
- sudo apt-get install -qq autoconf automake autopoint doxygen flex gettext graphviz help2man m4 texinfo
# Beware not too leak $SSH_PRIVATE_KEY.
# - env
- sudo apt-get install -qq doxygen flex m4
# Install and activate ICC.
- if [[ $CC == "icc" ]]; then build-aux/install-icc.sh; fi
- if [[ -f ~/.bashrc ]]; then source ~/.bashrc; fi
# Install and activate dmd
# Install and activate dmd.
- mkdir -p ~/dlang && wget https://dlang.org/install.sh -O ~/dlang/install.sh
- source $(source ~/dlang/install.sh dmd -a)
- autoconf --version
- automake --version
- autopoint --version
- $CC --version
- $CXX --version
- dmd --version
- doxygen --version
- flex --version
- gettext --version
- dot -V
- help2man --version
- ld --version
- m4 --version
- makeinfo --version
script:
- git tag -l
# For some reasons, sometimes the checkout does not have any tags,
# so `git describe` fails, so bootstrap fails.
- git describe || git tag v3.0 -m "Fake version 3.0."
- git describe
- if [[ -f ~/.bashrc ]]; then source ~/.bashrc; fi
# Unset this variable, otherwise, Java programs' stderr is cluttered
# with `Picked up _JAVA_OPTIONS: -Xmx2048m -Xms512m`, which makes
# the test suite fail.
- unset _JAVA_OPTIONS
- if [[ $GETTEXT_VERSION ]]; then sed -i -re "s/(AM_GNU_GETTEXT_VERSION).*/\1([$GETTEXT_VERSION])/" configure.ac; fi
- ./bootstrap
# For some reason, gnulib-po/Makefile.in.in is about Gettext 0.19, so it will break here. Override it.
- if [[ $GETTEXT_VERSION ]]; then autopoint --force; fi
- if [[ -f ~/.bashrc ]]; then source ~/.bashrc; fi
- ./configure --enable-gcc-warnings CC="$CC" CXX="$CXX" $CONFIGUREFLAGS || { cat config.log && false; }
# Fail fast from now on.
- set -e
- sftp [email protected]:bison-$TRAVIS_BUILD_NUMBER.tar.xz
- tar xf bison-$TRAVIS_BUILD_NUMBER.tar.xz
- dir=$(tar tf bison-$TRAVIS_BUILD_NUMBER.tar.xz | sed 1q)
- cd $dir
- mkdir _build
- cd _build
- ../configure --enable-gcc-warnings CC="$CC" CXX="$CXX" $CONFIGUREFLAGS || { cat config.log && false; }
- make -j2 $MAKE_ARGS
- if test ${PART-1} = 1; then make check VERBOSE=1 TESTSUITEFLAGS=-j2 || { cat test-suite.log && cat tests/testsuite.log && false; }; fi
- if test ${PART-1} = 1; then make maintainer-check-posix VERBOSE=1 TESTSUITEFLAGS=-j2 || { cat tests/testsuite.log && false; }; fi
- if test ${PART-2} = 2; then make maintainer-check-posix VERBOSE=1 TESTSUITEFLAGS=-j2 || { cat tests/testsuite.log && false; }; fi
- if test ${PART-2} = 2; then make maintainer-check-g++ VERBOSE=1 TESTSUITEFLAGS=-j2 || { cat tests/testsuite.log && false; }; fi
after_script:
- if [[ $CC == "icc" ]]; then uninstall_intel_software; fi
- uninstall_intel_software || true
+145 -10
View File
@@ -1,15 +1,149 @@
GNU Bison NEWS
* Noteworthy changes in release 3.3.90 (2019-04-28) [beta]
* Noteworthy changes in release 3.4.90 (2019-10-29) [beta]
** Backward incompatible changes
Lone carriage-return characters (aka \r or ^M) in the grammar files are no
longer treated as end-of-lines. This changes the diagnostics, and in
particular their locations.
In C++, line numbers and columns are now represented as 'int' not
'unsigned', so that integer overflow on positions is easily checkable via
'gcc -fsanitize=undefined' and the like. This affects the API for
positions.
** Bug fixes
In Java, %define api.prefix was ignored. It now behaves as expected.
** New features
*** Lookahead correction in C++
Contributed by Adrian Vogelsgesang.
The C++ deterministic skeleton (lalr1.cc) now supports LAC, via the
%define variable parse.lac.
*** Variable api.token.raw: Optimized token numbers (all skeletons)
In the generated parsers, tokens have two numbers: the "external" token
number as returned by yylex (which starts at 257), and the "internal"
symbol number (which starts at 3). Each time yylex is called, a table
lookup maps the external token number to the internal symbol number.
When the %define variable api.token.raw is set, tokens are assigned their
internal number, which saves one table lookup per token, and also saves
the generation of the mapping table.
The gain is typically moderate, but in extreme cases (very simple user
actions), a 10% improvement can be observed.
*** Diagnostics with insertion
The diagnostics now display suggestion below the underlined source.
Replacement for undeclared symbols are now also suggested.
$ cat /tmp/foo.y
%%
list: lis '.' |
$ bison -Wall foo.y
foo.y:2.7-9: error: symbol 'lis' is used, but is not defined as a token and has no rules; did you mean 'list'?
2 | list: lis '.' |
| ^~~
| list
foo.y:2.16: warning: empty rule without %empty [-Wempty-rule]
2 | list: lis '.' |
| ^
| %empty
foo.y: warning: fix-its can be applied. Rerun with option '--update'. [-Wother]
*** Diagnostics about long lines
Quoted sources may now be truncated to fit the screen. For instance, on a
30-column wide terminal:
$ cat foo.y
%token FOO FOO FOO
%%
exp: FOO
$ bison foo.y
foo.y:1.34-36: warning: symbol FOO redeclared [-Wother]
1 | … FOO …
| ^~~
foo.y:1.8-10: previous declaration
1 | %token FOO …
| ^~~
foo.y:1.62-64: warning: symbol FOO redeclared [-Wother]
1 | … FOO
| ^~~
foo.y:1.8-10: previous declaration
1 | %token FOO …
| ^~~
*** Debug traces in Java
The Java backend no longer emits code and data for parser tracing if the
%define variable parse.trace is not defined.
*** Generated parsers prefer signed integer types
Bison skeletons now prefer signed to unsigned integer types when either
will do, as the signed types are less error-prone and allow for better
checking with 'gcc -fsanitize=undefined'. Also, the types chosen are now
portable to unusual machines where char, short and int are all the same
width. On non-GNU platforms this may entail including <limits.h> and (if
available) <stdint.h> to define integer types and constants.
*** Generated parsers use better types for states
Stacks now use the best integral type for state numbers, instead of always
using 15 bits. As a result "small" parsers now have a smaller memory
footprint (they use 8 bits), and there is support for large automata (16
bits), and extra large (using int, i.e., typically 31 bits).
* Noteworthy changes in release 3.4.2 (2019-09-12) [stable]
** Bug fixes
In some cases, when warnings are disabled, bison could emit tons of white
spaces as diagnostics.
When running out of memory, bison could crash (found by fuzzing).
When defining twice the EOF token, bison would crash.
New warnings from recent compilers have been addressed in the generated
parsers (yacc.c, glr.c, glr.cc).
When lone carriage-return characters appeared in the input file,
diagnostics could hang forever.
* Noteworthy changes in release 3.4.1 (2019-05-22) [stable]
** Bug fixes
Portability fixes.
* Noteworthy changes in release 3.4 (2019-05-19) [stable]
** Deprecated features
The %pure-parser directive is deprecated in favor of '%define api.pure'
since Bison 2.3b (2008-05-27), but no warning was issued; there is one
now. Note that since Bison 2.7 you are strongly encouraged to use
'%define api.pure full' instead of '%define api.pure'.
** New features
*** Colored diagnostics
As an experimental feature, Bison now generates colored diagnostics,
controlled by the new options --color and --style.
As an experimental feature, diagnostics are now colored, controlled by the
new options --color and --style.
Install the libtextstyle library before configuring Bison to use them.
To use them, install the libtextstyle library before configuring Bison.
It is available from
https://alpha.gnu.org/gnu/gettext/
@@ -25,12 +159,13 @@ GNU Bison NEWS
To customize the styles, create a CSS file similar to
/* black-and-white.css */
/* bison-bw.css */
.warning { }
.error { font-weight: 800; text-decoration: underline; }
.note { }
then invoke bison with --style=black-and-white.css.
then invoke bison with --style=bison-bw.css, or set the BISON_STYLE
environment variable to "bison-bw.css".
*** Disabling output
@@ -869,10 +1004,10 @@ GNU Bison NEWS
bison used to report:
/tmp/foo.yy:2.10-11: error: %printer redeclaration for FOO
foo.yy:2.10-11: error: %printer redeclaration for FOO
%printer {} "foo"
^^
/tmp/foo.yy:3.10-11: previous declaration
foo.yy:3.10-11: previous declaration
%printer {} FOO
^^
@@ -3614,12 +3749,12 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
LocalWords: redeclaration sval fcaret reentrant XSLT xsl Wmaybe yyvsp Tedi
LocalWords: pragmas noreturn untyped Rozenman unexpanded Wojciech Polak
LocalWords: Alexandre MERCHANTABILITY yytype emplace ptr automove lvalues
LocalWords: nonterminal yy args Pragma dereference yyformat rhs docdir
LocalWords: nonterminal yy args Pragma dereference yyformat rhs docdir bw
LocalWords: Redeclarations rpcalc Autoconf YFLAGS Makefiles PROG DECL num
LocalWords: Heimbigner AST src ast Makefile srcdir MinGW xxlex XXSTYPE
LocalWords: XXLTYPE strictfp IDEs ffixit fdiagnostics parseable fixits
LocalWords: Wdeprecated yytext Variadic variadic yyrhs yyphrs RCS README
LocalWords: noexcept constexpr ispell american deprecations
LocalWords: noexcept constexpr ispell american deprecations backend
Local Variables:
ispell-dictionary: "american"
+17 -15
View File
@@ -1,25 +1,25 @@
This package contains the GNU Bison parser generator.
* Installation
** Build from git
# Installation
## Build from git
Here are basic installation instructions for a repository checkout:
$ git submodules update --init
$ git submodule update --init
$ ./bootstrap
then proceed with the usual 'configure && make' steps.
README-hacking contains more information about building and modifying the
software.
Be sure to read README-hacking, which contains all the needed information
about building, modifying and checking Bison.
** Build for tarball
## Build from tarball
See the file INSTALL for generic compilation and installation instructions.
Bison requires GNU m4 1.4.6 or later. See:
https://ftp.gnu.org/gnu/m4/m4-1.4.6.tar.gz
** Relocatability
## Relocatability
If you pass '--enable-relocatable' to 'configure', Bison is relocatable.
A relocatable program can be moved or copied to a different location on the
@@ -29,7 +29,7 @@ invoke them through the symlink.
See "Enabling Relocatability" in the documentation.
** Internationalization
## Internationalization
Bison supports two catalogs: one for Bison itself (i.e., for the
maintainer-side parser generation), and one for the generated parsers (i.e.,
for the user-side parser execution). The requirements between both differ:
@@ -39,7 +39,7 @@ generated parsers could have been localized. See
http://lists.gnu.org/archive/html/bug-bison/2009-08/msg00006.html for more
details.
* Questions
# Questions
See the section FAQ in the documentation (doc/bison.info) for frequently
asked questions. The documentation is also available in PDF and HTML,
provided you have a recent version of Texinfo installed: run "make pdf" or
@@ -48,19 +48,19 @@ provided you have a recent version of Texinfo installed: run "make pdf" or
If you have questions about using Bison and the documentation does not
answer them, please send mail to <[email protected]>.
* Bug reports
# Bug reports
Please send bug reports to <[email protected]>. Be sure to include the
version number from 'bison --version', and a complete, self-contained test
case in each bug report.
* Copyright statements
# Copyright statements
For any copyright year range specified as YYYY-ZZZZ in this package, note
that the range specifies every single year in that closed interval.
-----
<!--
Local Variables:
mode: outline
mode: markdown
fill-column: 76
ispell-dictionary: "american"
End:
@@ -83,5 +83,7 @@ GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
# LocalWords: parsers ngettext Texinfo pdf html YYYY ZZZZ ispell american
# LocalWords: MERCHANTABILITY
LocalWords: parsers ngettext Texinfo pdf html YYYY ZZZZ ispell american
LocalWords: MERCHANTABILITY
-->
+11 -4
View File
@@ -45,8 +45,8 @@ processes tabs in its input.
* Working from the repository
These notes intend to help people working on the checked-out sources.
These requirements do not apply when building from a distribution tarball.
These notes intend to help people working on the checked-out sources. These
requirements do not apply when building from a distribution tarball.
** Requirements
@@ -201,7 +201,6 @@ added the "[-Wother]" part to all the warnings). Part of the update can be
done with a crude tool: tests/update-test. Read it for more information.
** TESTSUITEFLAGS
To run just the testsuite (not the tests related to the examples), run `make
check-local`.
@@ -212,6 +211,10 @@ can be sped up in two ways:
Using -j, in a make-like fashion, for example:
$ make check-local TESTSUITEFLAGS='-j8'
Actually, when using GNU Make, TESTSUITEFLAGS defaults to the -jN passed to
it, so you may simply run
$ make check-local -j8
Running only the tests of a certain category, as specified in the AT files
with AT_KEYWORDS([[category]]). Categories include:
- c++, for c++ parsers
@@ -224,6 +227,10 @@ To run a specific set of tests, use -k (for "keyword"). For example:
$ make check-local TESTSUITEFLAGS='-k c++'
Both can be combined.
$ make check-local TESTSUITEFLAGS='-j8 -k c++'
To rerun the tests that failed:
$ make recheck -j5
** Typical errors
If the test suite shows failures such as the following one
@@ -309,7 +316,7 @@ re-run the tests, run:
./gnulib-tool --symlink --create-test --dir=/tmp/gnutest bitset-tests
cd /tmp/gnutest
./configure CC='gcc-mp-8 -fsanitize=undefined'
./configure -C CC='gcc-mp-8 -fsanitize=undefined' CFLAGS='-ggdb'
make check
* Release Procedure
Symlink
+1
View File
@@ -0,0 +1 @@
README
+15
View File
@@ -10,6 +10,7 @@ Albert Chin-A-Young [email protected]
Alexander Belopolsky [email protected]
Alexandre Duret-Lutz [email protected]
Andre da Costa Barros [email protected]
Andreas Damm [email protected]
Andreas Schwab [email protected]
Andrew Suffield [email protected]
Angelo Borsotti [email protected]
@@ -33,6 +34,7 @@ Bruce Lilly [email protected]
Bruno Haible [email protected]
Charles-Henri de Boysson [email protected]
Christian Burger [email protected]
Clément Démoulins [email protected]
Colin Daley [email protected]
Cris Bailiff [email protected]
Cris van Pelt [email protected]
@@ -66,6 +68,7 @@ Frank Heckenbach [email protected]
Frans Englich [email protected]
Gabriel Rassoul [email protected]
Gary L Peskin [email protected]
Gavin Smith [email protected]
Georg Sauthoff [email protected]
George Neuner [email protected]
Gilles Espinasse [email protected]
@@ -87,15 +90,19 @@ Jonathan Fabrizio [email protected]
Jonathan Nieder [email protected]
Josh Soref [email protected]
Juan Manuel Guerrero [email protected]
Karl Berry [email protected]
Kees Zeelenberg [email protected]
Keith Browne [email protected]
Ken Moffat [email protected]
Kiyoshi Kanazawa [email protected]
Lars Maier [email protected]
László Várady [email protected]
Laurent Mascherpa [email protected]
Lie Yan [email protected]
Magnus Fromreide [email protected]
Marc Autret [email protected]
Marc Mendiola [email protected]
Marc Schönefeld [email protected]
Mark Boyall [email protected]
Martin Jacobs [email protected]
Martin Mokrejs [email protected]
@@ -116,6 +123,7 @@ Mike Sullivan [email protected]
Nate Guerin [email protected]
Neil Booth [email protected]
Nelson H. F. Beebe [email protected]
neok m4700 [email protected]
Nick Bowler [email protected]
Nicolas Bedon [email protected]
Nicolas Burrus [email protected]
@@ -128,6 +136,7 @@ Oliver Mangold [email protected]
Paolo Bonzini [email protected]
Paolo Simone Gasparello [email protected]
Pascal Bart [email protected]
Patrice Dumas [email protected]
Paul Eggert [email protected]
Paul Hilfinger [email protected]
Per Allansson [email protected]
@@ -166,16 +175,20 @@ Sum Wu [email protected]
Théophile Ranquet [email protected]
Thiru Ramakrishnan [email protected]
Thomas Jahns [email protected]
Thomas Petazzoni [email protected]
Tim Josling [email protected]
Tim Landscheidt [email protected]
Tim Van Holder [email protected]
Tobias Frost [email protected]
Todd Freed [email protected]
Tom Kramer [email protected]
Tom Lane [email protected]
Tom Tromey [email protected]
Tomasz Kłoczko [email protected]
Tommy Nordgren [email protected]
Troy A. Johnson [email protected]
Tys Lefering [email protected]
Uxio Prego [email protected]
Valentin Tolmer [email protected]
wcventure [email protected]
Victor Khomenko [email protected]
@@ -190,8 +203,10 @@ Wolfgang Thaller [email protected]
Wolfram Wagner [email protected]
Wwp [email protected]
xolodho [email protected]
Yuichiro Kaneko [email protected]
Zack Weinberg [email protected]
長田偉伸 [email protected]
江 祖铭 [email protected]
Many people are not named here because we lost track of them. We
thank them! Please, help us keeping this list up to date.
+159 -42
View File
@@ -1,25 +1,3 @@
* Bison 3.4
** bad diagnostics
%token <val> NUM
%type <val> expr term fact
%%
res: expr { printf ("%d\n", $1); };
expr: expr '+' term { $$ = $1 + $3; } | term;
term: NUM | { $$ = 0; };
The second warning about fact is... useless.
$ bison /tmp/bar.y
/tmp/bar.y:2.24-27: warning: symbol fact is used, but is not defined as a token and has no rules [-Wother]
%type <val> expr term fact
^~~~
/tmp/bar.y: warning: 1 nonterminal useless in grammar [-Wother]
/tmp/bar.y:2.24-27: warning: nonterminal useless in grammar: fact [-Wother]
%type <val> expr term fact
^~~~
* Bison 3.5
** doc
I feel its ugly to use the GNU style to declare functions in the doc. It
@@ -29,9 +7,6 @@ breaks.
Also, we seem to teach YYPRINT very early on, although it should be
considered deprecated: %printer is superior.
** glr.cc
move glr.c into the yy namespace
** improve syntax errors (UTF-8, internationalization)
Bison depends on the current locale. For instance:
@@ -73,10 +48,15 @@ syntax error, unexpected $end, expecting ↦ or 🎅🐃 or '\n'
While at it, we should stop using "$end" by default, in favor of "end of
file", or "end of input", whatever.
file", or "end of input", whatever. See how lalr1.java does that.
** api.token.raw
Maybe we should exhibit the YYUNDEFTOK token. It could also be assigned a
semantic value so that yyerror could be used to report invalid lexemes.
See also the item "$undefined" below.
* Bison 3.6
** Unit rules
** Unit rules / Injection rules (Akim Demaille)
Maybe we could expand unit rules (or "injections", see
https://homepages.cwi.nl/~daybuild/daily-books/syntax/2-sdf/sdf.html), i.e.,
transform
@@ -95,10 +75,12 @@ Practice' is impossible to find, but according to 'Parsing Techniques: a
Practical Guide', it includes information about this issue. Does anybody
have it?
** Injection rules
See above.
** clean up (Akim Demaille)
Do not work on these items now, as I (Akim) have branches with a lot of
changes in this area (hitting several files), and no desire to have to fix
conflicts. Addressing these items will happen after my branches have been
merged.
** clean up
*** lalr.c
Introduce a goto struct, and use it in place of from_state/to_state.
Rename states1 as path, length as pathlen.
@@ -119,7 +101,20 @@ introduce lr(0) and lalr, just the way we have ielr categories. The
"set" can still be used for summariring the important sets. That would make
tests easy to maintain.
*** complain.*
Rename these guys as "diagnostics.*" (or "diagnose.*"), since that's the
name they have in gcc, clang, etc. Likewise for the complain_* series of
functions.
*** ritem
states/nstates, rules/nrules, ..., ritem/nritems
Fix the latter.
* Modernization
Fix data/skeletons/yacc.c so that it defines YYPTRDIFF_T properly for modern
and older C++ compilers. Currently the code defaults to defining it to
'long' for non-GCC compilers, but it should use the proper C++ magic to
define it to the same type as the C ptrdiff_t type.
* Completion
Several features are not available in all the backends.
@@ -139,8 +134,88 @@ $ ./tests/testsuite -l | grep errors | sed q
38: input.at:1730 errors
* Short term
** Stop indentation in diagnostics
Before Bison 2.7, we printed "flatly" the dependencies in long diagnostics:
input.y:2.7-12: %type redeclaration for exp
input.y:1.7-12: previous declaration
In Bison 2.7, we indented them
input.y:2.7-12: error: %type redeclaration for exp
input.y:1.7-12: previous declaration
Later we quoted the source in the diagnostics, and today we have:
/tmp/foo.y:1.12-14: warning: symbol FOO redeclared [-Wother]
1 | %token FOO FOO
| ^~~
/tmp/foo.y:1.8-10: previous declaration
1 | %token FOO FOO
| ^~~
The indentation is no longer helping. We should probably get rid of it, or
maybe keep it only when -fno-caret. GCC displays this as a "note":
$ g++-mp-9 -Wall /tmp/foo.c -c
/tmp/foo.c:1:10: error: redefinition of 'int foo'
1 | int foo, foo;
| ^~~
/tmp/foo.c:1:5: note: 'int foo' previously declared here
1 | int foo, foo;
| ^~~
Likewise for Clang, contrary to what I believed (because "note:" is written
in black, so it doesn't show in my terminal :-)
$ clang++-mp-8.0 -Wall /tmp/foo.c -c
clang: warning: treating 'c' input as 'c++' when in C++ mode, this behavior is deprecated [-Wdeprecated]
/tmp/foo.c:1:10: error: redefinition of 'foo'
int foo, foo;
^
/tmp/foo.c:1:5: note: previous definition is here
int foo, foo;
^
1 error generated.
See also the item "Complaint submessage indentation" below.
** Better design for diagnostics
The current implementation of diagnostics is adhoc, it grew organically. It
works as a series of calls to several functions, with dependency of the
latter calls on the former. For instance:
complain (&sym->location,
sym->content->status == needed ? complaint : Wother,
_("symbol %s is used, but is not defined as a token"
" and has no rules; did you mean %s?"),
quote_n (0, sym->tag),
quote_n (1, best->tag));
if (feature_flag & feature_caret)
location_caret_suggestion (sym->location, best->tag, stderr);
We should rewrite this in a more FP way:
1. build a rich structure that denotes the (complete) diagnostic.
"Complete" in the sense that it also contains the suggestions, the list
of possible matches, etc.
2. send this to the pretty-printing routine. The diagnostic structure
should be sufficient so that we can generate all the 'format' of
diagnostics, including the fixits.
If properly done, this diagnostic module can be detached from Bison and be
put in gnulib. It could be used, for instance, for errors caught by
xgettext.
There's certainly already something alike in GCC. At least that's the
impression I get from reading the "-fdiagnostics-format=FORMAT" part of this
page:
https://gcc.gnu.org/onlinedocs/gcc/Diagnostic-Message-Formatting-Options.html
** consistency
token vs terminal
token vs terminal, variable vs non terminal.
** C++
Move to int everywhere instead of unsigned? stack_size, etc. The parser
@@ -148,11 +223,10 @@ itself uses int (for yylen for instance), yet stack is based on size_t.
Maybe locations should also move to ints.
** C
Introduce state_type rather than spreading yytype_int16 everywhere?
** glr.c
yyspaceLeft should probably be a pointer diff.
Paul Eggert already covered most of this. But before publishing these
changes, we need to ask our C++ users if they agree with that change, or if
we need some migration path. Could be a %define variable, or simply
%require "3.5".
** Graphviz display code thoughts
The code for the --graph option is over two files: print_graph, and
@@ -173,9 +247,6 @@ Little effort seems to have been given to factoring these files and their
rint{,-xml} counterpart. We would very much like to re-use the pretty format
of states from .output for the graphs, etc.
Also, the underscore in print_graph.[ch] isn't very fitting considering the
dashes in the other filenames.
Since graphviz dies on medium-to-big grammars, maybe consider an other tool?
** push-parser
@@ -233,11 +304,13 @@ since it is no longer bound to a particular parser, it's just a
(standalone symbol).
* Various
** Rewrite glr.cc in C++
** Rewrite glr.cc in C++ (Valentin Tolmer)
As a matter of fact, it would be very interesting to see how much we can
share between lalr1.cc and glr.cc. Most of the skeletons should be common.
It would be a very nice source of inspiration for the other languages.
Valentin Tolmer is working on this.
** YYERRCODE
Defined to 256, but not used, not documented. Probably the token
number for the error token, which POSIX wants to be 256, but which
@@ -307,10 +380,21 @@ other improvements and also made it faster (probably because memory
management is performed once instead of three times). I suggest that
we do the same in yacc.c.
(Some time later): it's also very nice to have three stacks: it's more dense
as we don't lose bits to padding. For instance the typical stack for states
will use 8 bits, while it is likely to consume 32 bits in a struct.
We need trustworthy benchmarks for Bison, for all our backends. Akim has a
few things scattered around; we need to put them in the repo, and make them
more useful.
** yysyntax_error
The code bw glr.c and yacc.c is really alike, we can certainly factor
some parts.
This should be worked on when we also address the expected improvements for
error generation (e.g., i18n).
* Report
@@ -350,7 +434,26 @@ LORIA, INRIA Nancy - Grand Est, Nancy, France
* Extensions
** Multiple start symbols
Would be very useful when parsing closely related languages.
Would be very useful when parsing closely related languages. The idea is to
declare several start symbols, for instance
%start stmt expr
%%
stmt: ...
expr: ...
and to generate parse(), parse_stmt() and parse_expr(). Technically, the
above grammar would be transformed into
%start yy_start
%token YY_START_STMT YY_START_EXPR
%%
yy_start: YY_START_STMT stmt | YY_START_EXPR expr
so that there are no new conflicts in the grammar (as would undoubtedly
happen with yy_start: stmt | expr). Then adjust the skeletons so that this
initial token (YY_START_STMT, YY_START_EXPR) be shifted first in the
corresponding parse function.
** Better error messages
The users are not provided with enough tools to forge their error messages.
@@ -368,6 +471,12 @@ should make this reasonably easy to implement.
Bruce Mardle <[email protected]>
https://lists.gnu.org/archive/html/bison-patches/2015-09/msg00000.html
However, there are many other things to do before having such a feature,
because I don't want a % equivalent to #include (which we all learned to
hate). I want something that builds "modules" of grammars, and assembles
them together, paying attention to keep separate bits separated, in pseudo
name spaces.
** Push parsers
There is demand for push parsers in Java and C++. And GLR I guess.
@@ -394,6 +503,10 @@ must be in the scanner: we must not parse what is in a switched off
part of %if. Akim Demaille thinks it should be in the parser, so as
to avoid falling into another CPP mistake.
(Later): I'm sure there's actually good case for this. People who need that
feature can use m4/cpp on top of Bison. I don't think it is worth the
trouble in Bison itself.
** XML Output
There are couple of available extensions of Bison targeting some XML
output. Some day we should consider including them. One issue is
@@ -413,6 +526,9 @@ XML output for GNU Bison
https://lists.gnu.org/archive/html/bug-bison/2016-06/msg00000.html
http://www.cs.cornell.edu/andru/papers/cupex/
Andrew Myers and Vincent Imbimbo are working on this item, see
https://github.com/akimd/bison/issues/12
* Coding system independence
Paul notes:
@@ -430,7 +546,7 @@ Paul notes:
tokens, either via escapes (e.g., "x\0y") or via a NUL byte in
the source code. This should get fixed.
* Broken options ?
* Broken options?
** %token-table
** Skeleton strategy
Must we keep %token-table?
@@ -442,6 +558,7 @@ It is unfortunate that there is a total order for precedence. It
makes it impossible to have modular precedence information. We should
move to partial orders (sounds like series/parallel orders to me).
This is a prerequisite for modules.
* $undefined
From Hans:
+1 -1
View File
@@ -166,7 +166,7 @@ bootstrap_epilogue() { :; }
# specified directory. Fill in the first %s with the destination
# directory and the second with the domain name.
po_download_command_format=\
"wget --mirror --level=1 -nd -q -A.po -P '%s' \
"wget --mirror --level=1 -nd -nv -A.po -P '%s' \
https://translationproject.org/latest/%s/"
# Prefer a non-empty tarname (4th argument of AC_INIT if given), else
+14 -3
View File
@@ -22,15 +22,16 @@ gnulib_modules='
calloc-posix close closeout config-h c-strcase
configmake
dirname
error extensions fdl fopen-safer
error extensions
fdl fopen-safer fstrcmp
getopt-gnu
gettext-h git-version-gen gitlog-to-changelog
gpl-3.0 hash inttypes isnan javacomp-script
gpl-3.0 intprops inttypes isnan javacomp-script
javaexec-script
ldexpl
libtextstyle-optional
malloc-gnu
mbswidth
mbfile mbswidth
non-recursive-gnulib-prefix-hack
obstack
obstack-printf
@@ -45,9 +46,12 @@ gnulib_modules='
unistd unistd-safer unlink unlocked-io
update-copyright unsetenv verify
warnings
winsz-ioctl
winsz-termios
xalloc
xalloc-die
xconcat-filename
xhash
xlist
xmemdup0
xstrndup
@@ -86,6 +90,13 @@ bootstrap_epilogue()
touch src/parse-gram.[ch]
perl -pi -e "s/\@PACKAGE\@/$package/g" README-release
# Bison currently uses Gettext 0.19, but the gnulib-po module
# imports files from more recent versions of Gettext that are not
# yet available widely enough (e.g., not in bionic, used by the CI).
# Work around this. Don't use autopoint, which sends some other
# files in the past.
cp po/Makefile.in.in gnulib-po
}
# Keep our bootstrap script in sync with gnulib's. If we ever need to
+12 -10
View File
@@ -12,7 +12,7 @@ while (<STDIN>)
{
if (/^\s* # Initial spaces.
(?:(-\w),\s+)? # $1: $short: Possible short option.
(--[-\w]+) # $2: $long: Long option.
(--[-\w]+) # $2: $long: Mandatory long option.
(\[?) # $3: $opt: '[' iff the argument is optional.
(?:=(\S+))? # $4: $arg: Possible argument name.
\s # Spaces.
@@ -32,7 +32,6 @@ while (<STDIN>)
# if $opt, $arg contains the closing ].
substr ($arg, -1) = ''
if $opt eq '[';
$arg =~ s/^=//;
$arg = lc ($arg);
my $dir_arg = $arg;
# If the argument is complete (e.g., for --define[=NAME[=VALUE]]),
@@ -72,12 +71,15 @@ while (<STDIN>)
my $sep = '';
foreach my $long (sort keys %option)
{
# Avoid trailing spaces.
print $sep;
$sep = "\n";
print '@item @option{', $long, "}\n\@tab";
print ' @option{', $option{$long}, '}' if $option{$long};
print "\n\@tab";
print ' @code{', $directive{$long}, '}' if $directive{$long};
print "\n";
# Couldn't find a means to escape @ in the format (for @item, @tab), so
# pass it as a literal to print.
format STDOUT =
@item @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< @tab @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< @tab @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
{
'@', '@option{' . $long . '}',
'@', $option{$long} ? ('@option{' . $option{$long} . '}') : '',
'@', $directive{$long} ? ('@code{' . $directive{$long} . '}') : ''
}
.
write;
}
+13 -12
View File
@@ -1,7 +1,7 @@
#! /usr/bin/env python
# usage:
# update-test _build/8d/tests/testsuite.dir/*.testsuite.log
# update-test _build/8d/tests/testsuite.dir/*/testsuite.log
import argparse
import os
@@ -11,8 +11,8 @@ import re
def getargs():
p = argparse.ArgumentParser(description='Update test cases.')
opt = p.add_argument
opt('tests', metavar='test', nargs='+', type=str, default=None,
help='test files to update')
opt('logs', metavar='log', nargs='+', type=str, default=None,
help='log files to process')
opt('-v', '--verbose', action='store_true',
help='Be verbose')
return p.parse_args()
@@ -21,14 +21,14 @@ args = getargs()
subst = dict()
def log(*args_):
def trace(*args_):
if args.verbose:
print(*args_)
def contents(file):
'''The contents of a file.'''
log(file)
trace(file)
f = open(file)
return f.read()
@@ -60,9 +60,9 @@ def diff_to_re(match):
def update(at_file, logfile):
test = contents(at_file)
if os.path.isfile(logfile):
log("LOG: ", logfile)
trace("LOG: ", logfile)
l = contents(logfile)
log("LOG: ", l)
trace("LOG: ", l)
global subst
subst = {}
re.sub(r'(?:^@@.*\n)((?:^[-+ ].*\n)+)',
@@ -71,7 +71,7 @@ def update(at_file, logfile):
if subst:
# Turn "subst{frm} -> to" into a large RE.
frm = '|'.join([re.escape(x) for x in subst])
log("FROM:", frm)
trace("FROM:", frm)
test = re.sub("(" + frm + ")",
lambda m: subst[m.group(1)],
test, flags=re.MULTILINE)
@@ -81,13 +81,14 @@ def update(at_file, logfile):
def process(logfile):
log = contents(logfile)
# Look for the file to update.
m = re.search(r'^\d+\. (\w+\.at):\d+: ', log, re.MULTILINE)
m = re.search(r'^\d+\. ([-\w]+\.at):\d+: ', log, re.MULTILINE)
if not m:
trace("no diff found:", logfile)
return
at_file = 'tests/' + m.group(1)
print(at_file)
update(at_file, logfile)
for t in args.tests:
log("FILE:", t)
process(t)
for logfile in args.logs:
trace("FILE:", logfile)
process(logfile)
+3
View File
@@ -26,6 +26,9 @@ regen: _version
manual_title = The Yacc-compatible Parser Generator
gendocs_options_ = -I $(abs_top_srcdir)/doc -I $(abs_top_builddir)/doc
# By default, propagate -j from make to Bison's test suite.
TESTSUITEFLAGS = $(filter -j%,$(MAKEFLAGS))
# It's useful to run maintainer-check* targets during development, but we
# don't want to wait on a recompile because of an update to $(VERSION). Thus,
# override the _is-dist-target from GNUmakefile so that maintainer-check*
+24 -8
View File
@@ -36,6 +36,9 @@ AC_CONFIG_MACRO_DIR([m4])
# We use Automake 1.14's %D% and %C%.
#
# When we move to Automake 1.16, simplify examples/c/reccalc/local.mk.
# Our CI runs on Xenial, which has only Automake 1.15.
#
# We want gnits strictness only when rolling a stable release. For
# release candidates, we use version strings like 2.4.3_rc1, but gnits
# doesn't like that, so we let the underscore disable gnits. Between
@@ -94,9 +97,13 @@ AC_ARG_ENABLE([gcc-warnings],
[enable_gcc_warnings=no])
AM_CONDITIONAL([ENABLE_GCC_WARNINGS], [test "$enable_gcc_warnings" = yes])
if test "$enable_gcc_warnings" = yes; then
warn_common='-Wall -Wextra -Wno-sign-compare -Wcast-align
# -Wno-tautological-constant-out-of-range-compare for Clang 3.3 and
# 3.4 on GNU/Linux that choke on intprops.h's INT_MULTIPLY_WRAPV,
# etc.
warn_common='-Wall -Wextra -Wcast-align
-fparse-all-comments -Wdocumentation
-Wformat -Wimplicit-fallthrough -Wnull-dereference
-Wno-sign-compare -Wno-tautological-constant-out-of-range-compare
-Wpointer-arith -Wshadow
-Wwrite-strings'
warn_c='-Wbad-function-cast -Wstrict-prototypes'
@@ -112,6 +119,7 @@ if test "$enable_gcc_warnings" = yes; then
# details for lalr1.cc.
warn_tests='-Wundef -pedantic -Wconversion
-Wdeprecated -Wsign-compare -Wsign-conversion
-Wtautological-constant-out-of-range-compare
-fno-color-diagnostics
-Wno-keyword-macro'
@@ -192,7 +200,7 @@ BISON_CXX_COMPILER_POSIXLY_CORRECT
# D.
AC_CHECK_PROGS([DC], [dmd])
AC_CHECK_PROGS([DCFLAGS], [])
AC_CHECK_PROGS([DCFLAGS], [-g])
AM_CONDITIONAL([ENABLE_D], [test x"$DC" != x])
# Java.
@@ -211,10 +219,11 @@ AC_CONFIG_FILES([src/yacc], [chmod +x src/yacc])
# Checks for programs.
AM_MISSING_PROG([DOT], [dot])
AC_PROG_LEX
$LEX_IS_FLEX || test "X$LEX" = X: || {
if ! "$LEX_IS_FLEX" || test "X$LEX" = X:; then
AC_MSG_WARN([bypassing lex because flex is required])
LEX=:
}
fi
AM_CONDITIONAL([FLEX_WORKS], [$LEX_IS_FLEX])
AM_CONDITIONAL([FLEX_CXX_WORKS],
[$LEX_IS_FLEX && test $bison_cv_cxx_works = yes])
AC_PROG_YACC
@@ -224,9 +233,6 @@ AC_DEFINE_UNQUOTED([M4], ["$M4"], [Define to the GNU M4 executable name.])
AC_DEFINE_UNQUOTED([M4_GNU_OPTION], ["$M4_GNU"], [Define to "-g" if GNU M4
supports -g, otherwise to "".])
AC_PATH_PROG([PERL], [perl])
if test -z "$PERL"; then
AC_MSG_ERROR([perl not found])
fi
AM_MISSING_PROG([HELP2MAN], [help2man])
AC_PATH_PROG([XSLTPROC], [xsltproc])
AC_SUBST([XSLTPROC])
@@ -243,7 +249,6 @@ gl_INIT
# Checks for library functions.
AC_CHECK_FUNCS_ONCE([setlocale])
AM_WITH_DMALLOC
# Gettext.
# We use gnulib, which is only guaranteed to work properly with the
@@ -296,4 +301,15 @@ AC_SUBST([GCC])
AC_CONFIG_FILES([Makefile
po/Makefile.in
doc/yacc.1])
# Fix LIBOBJS to give the Makefile the right file names. Otherwise
# compilation works, but with unexpected file names, so clean rules don't
# remove the actual files and distcheck fails.
AC_CONFIG_COMMANDS_PRE([
case $am__api_version in
1.14*|1.15*) gl_LIBOBJS=`echo "$gl_LIBOBJS" | sed -e 's, lib/, lib/lib_libbison_a-,g'`;;
*) gl_LIBOBJS=`echo "$gl_LIBOBJS" | sed -e 's, lib/, lib/libbison_a-,g'`;;
esac
])
AC_OUTPUT
+31
View File
@@ -0,0 +1,31 @@
/* Default styling rules for Bison when doing terminal output.
Copyright (C) 2019 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>. */
/* This is an experimental feature. The class names may change in the
future. */
/* Diagnostics. */
.warning { color: purple; }
.error { color: red; }
.note { color: cyan; }
.fixit-insert { color: green; }
/* Semantic values in Bison's own parser traces. */
.value { color: green; }
/* "Sections" in traces (--trace). */
.trace0 { color: green; }
-10
View File
@@ -1,10 +0,0 @@
/* CSS style for Bison's diagnostics.
This is an experimental feature. The class names may change in the
future. */
.warning { color: purple; }
.error { color: red; }
.note { color: cyan; }
/* Semantic values in Bison's parser traces. */
.value { color: green; }
+1 -1
View File
@@ -16,7 +16,7 @@
dist_pkgdata_DATA = \
data/README.md \
data/diagnostics.css
data/bison-default.css
skeletonsdir = $(pkgdatadir)/skeletons
dist_skeletons_DATA = \
+3 -2
View File
@@ -449,7 +449,7 @@ m4_define([b4_symbol_action],
[(*yylocationp)])dnl
_b4_symbol_case([$1])[]dnl
b4_syncline([b4_symbol([$1], [$2_line])], [b4_symbol([$1], [$2_file])])dnl
b4_symbol([$1], [$2])
b4_symbol([$1], [$2])
b4_syncline([@oline@], [@ofile@])dnl
break;
@@ -535,7 +535,7 @@ m4_define([b4_token_format],
[b4_token_visible_if([$2],
[m4_quote(m4_format([$1],
[b4_symbol([$2], [id])],
[b4_symbol([$2], [user_number])]))])])
[b4_symbol([$2], b4_api_token_raw_if([[number]], [[user_number]]))]))])])
## ------- ##
@@ -1002,6 +1002,7 @@ m4_define([b4_percent_code_ifdef],
# b4_parse_trace_if([IF-DEBUG-TRACES-ARE-ENABLED], [IF-NOT])
# b4_token_ctor_if([IF-YYLEX-RETURNS-A-TOKEN], [IF-NOT])
# ----------------------------------------------------------
b4_percent_define_if_define([api.token.raw])
b4_percent_define_if_define([token_ctor], [api.token.constructor])
b4_percent_define_if_define([locations]) # Whether locations are tracked.
b4_percent_define_if_define([parse.assert])
+6 -4
View File
@@ -532,7 +532,9 @@ m4_define([b4_yytranslate_define],
]b4_parser_class[::yytranslate_ (]b4_token_ctor_if([token_type],
[int])[ t)
{
// YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to
]b4_api_token_raw_if(
[[ return static_cast<yy::parser::token_number_type> (t);]],
[[ // YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to
// TOKEN-NUM as returned by yylex.
static
const token_number_type
@@ -540,15 +542,15 @@ m4_define([b4_yytranslate_define],
{
]b4_translate[
};
const unsigned user_token_number_max_ = ]b4_user_token_number_max[;
const int user_token_number_max_ = ]b4_user_token_number_max[;
const token_number_type undef_token_ = ]b4_undef_token_number[;
if (static_cast<int> (t) <= yyeof_)
return yyeof_;
else if (static_cast<unsigned> (t) <= user_token_number_max_)
else if (static_cast<int> (t) <= user_token_number_max_)
return translate_table[t];
else
return undef_token_;
return undef_token_;]])[
}
]])
+95 -23
View File
@@ -167,38 +167,110 @@ b4_parse_param_for([Decl], [Formal], [ YYUSE (Formal);
# b4_int_type(MIN, MAX)
# ---------------------
# Return the smallest int type able to handle numbers ranging from
# MIN to MAX (included).
# Return a narrow int type able to handle integers ranging from MIN
# to MAX (included) in portable C code. Assume MIN and MAX fall in
# 'int' range.
m4_define([b4_int_type],
[m4_if(b4_ints_in($@, [0], [255]), [1], [unsigned char],
b4_ints_in($@, [-128], [127]), [1], [signed char],
[m4_if(b4_ints_in($@, [-127], [127]), [1], [signed char],
b4_ints_in($@, [0], [255]), [1], [unsigned char],
b4_ints_in($@, [-32767], [32767]), [1], [short],
b4_ints_in($@, [0], [65535]), [1], [unsigned short],
b4_ints_in($@, [-32768], [32767]), [1], [short],
m4_eval([0 <= $1]), [1], [unsigned],
[int])])
# b4_c99_int_type(MIN, MAX)
# -------------------------
# Like b4_int_type, but for C99.
# b4_c99_int_type_define replaces b4_int_type with this.
m4_define([b4_c99_int_type],
[m4_if(b4_ints_in($@, [-127], [127]), [1], [yytype_int8],
b4_ints_in($@, [0], [255]), [1], [yytype_uint8],
b4_ints_in($@, [-32767], [32767]), [1], [yytype_int16],
b4_ints_in($@, [0], [65535]), [1], [yytype_uint16],
[int])])
# b4_c99_int_type_define
# ----------------------
# Define private types suitable for holding small integers in C99 or later.
m4_define([b4_c99_int_type_define],
[m4_copy_force([b4_c99_int_type], [b4_int_type])dnl
[/* On compilers that do not define __PTRDIFF_MAX__ etc., make sure
<limits.h> and (if available) <stdint.h> are included
so that the code can choose integer types of a good width. */
#ifndef __PTRDIFF_MAX__
# include <limits.h> /* INFRINGES ON USER NAME SPACE */
# if defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__
# include <stdint.h> /* INFRINGES ON USER NAME SPACE */
# define YY_STDINT_H
# endif
#endif
/* Narrow types that promote to a signed type and that can represent a
signed or unsigned integer of at least N bits. In tables they can
save space and decrease cache pressure. Promoting to a signed type
helps avoid bugs in integer arithmetic. */
#ifdef __INT_LEAST8_MAX__
typedef __INT_LEAST8_TYPE__ yytype_int8;
#elif defined YY_STDINT_H
typedef int_least8_t yytype_int8;
#else
typedef signed char yytype_int8;
#endif
#ifdef __INT_LEAST16_MAX__
typedef __INT_LEAST16_TYPE__ yytype_int16;
#elif defined YY_STDINT_H
typedef int_least16_t yytype_int16;
#else
typedef short yytype_int16;
#endif
#if defined __UINT_LEAST8_MAX__ && __UINT_LEAST8_MAX__ <= __INT_MAX__
typedef __UINT_LEAST8_TYPE__ yytype_uint8;
#elif (!defined __UINT_LEAST8_MAX__ && defined YY_STDINT_H \
&& UINT_LEAST8_MAX <= INT_MAX)
typedef uint_least8_t yytype_uint8;
#elif !defined __UINT_LEAST8_MAX__ && UCHAR_MAX <= INT_MAX
typedef unsigned char yytype_uint8;
#else
typedef short yytype_uint8;
#endif
#if defined __UINT_LEAST16_MAX__ && __UINT_LEAST16_MAX__ <= __INT_MAX__
typedef __UINT_LEAST16_TYPE__ yytype_uint16;
#elif (!defined __UINT_LEAST16_MAX__ && defined YY_STDINT_H \
&& UINT_LEAST16_MAX <= INT_MAX)
typedef uint_least16_t yytype_uint16;
#elif !defined __UINT_LEAST16_MAX__ && USHRT_MAX <= INT_MAX
typedef unsigned short yytype_uint16;
#else
typedef int yytype_uint16;
#endif]])
# b4_int_type_for(NAME)
# ---------------------
# Return the smallest int type able to handle numbers ranging from
# Return a narrow int type able to handle numbers ranging from
# 'NAME_min' to 'NAME_max' (included).
m4_define([b4_int_type_for],
[b4_int_type($1_min, $1_max)])
# b4_table_value_equals(TABLE, VALUE, LITERAL)
# --------------------------------------------
# b4_table_value_equals(TABLE, VALUE, LITERAL, SYMBOL)
# ----------------------------------------------------
# Without inducing a comparison warning from the compiler, check if the
# literal value LITERAL equals VALUE from table TABLE, which must have
# TABLE_min and TABLE_max defined.
# TABLE_min and TABLE_max defined. SYMBOL denotes
m4_define([b4_table_value_equals],
[m4_if(m4_eval($3 < m4_indir([b4_]$1[_min])
|| m4_indir([b4_]$1[_max]) < $3), [1],
[[0]],
[(!!(($2) == ($3)))])])
[(($2) == $4)])])
## ----------------- ##
@@ -210,22 +282,20 @@ m4_define([b4_table_value_equals],
# Provide portable compiler "attributes". If "noreturn" is passed, define
# _Noreturn.
m4_define([b4_attribute_define],
[[#ifndef YY_ATTRIBUTE
# if (defined __GNUC__ \
&& (2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__))) \
|| defined __SUNPRO_C && 0x5110 <= __SUNPRO_C
# define YY_ATTRIBUTE(Spec) __attribute__(Spec)
[[#ifndef YY_ATTRIBUTE_PURE
# if defined __GNUC__ && 2 < __GNUC__ + (96 <= __GNUC_MINOR__)
# define YY_ATTRIBUTE_PURE __attribute__ ((__pure__))
# else
# define YY_ATTRIBUTE(Spec) /* empty */
# define YY_ATTRIBUTE_PURE
# endif
#endif
#ifndef YY_ATTRIBUTE_PURE
# define YY_ATTRIBUTE_PURE YY_ATTRIBUTE ((__pure__))
#endif
#ifndef YY_ATTRIBUTE_UNUSED
# define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__))
# if defined __GNUC__ && 2 < __GNUC__ + (7 <= __GNUC_MINOR__)
# define YY_ATTRIBUTE_UNUSED __attribute__ ((__unused__))
# else
# define YY_ATTRIBUTE_UNUSED
# endif
#endif
]m4_bmatch([$1], [\bnoreturn\b], [[/* The _Noreturn keyword of C11. */
@@ -545,7 +615,9 @@ m4_if(b4_skeleton, ["yacc.c"],
# endif
]])dnl
b4_percent_code_get([[pre-printer]])dnl
YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
b4_symbol_actions([printer])
YY_IGNORE_MAYBE_UNINITIALIZED_END
b4_percent_code_get([[post-printer]])dnl
[}
+5 -6
View File
@@ -38,6 +38,11 @@ m4_define([b4_comment],
[_b4_comment([$1], [$2/* ], [$2 ], [ */])])
# b4_sync_start(LINE, FILE)
# -------------------------
m4_define([b4_sync_start], [[#]line $1 $2])
# b4_list2(LIST1, LIST2)
# ----------------------
# Join two lists with a comma if necessary.
@@ -95,12 +100,6 @@ m4_define([b4_location_type_if],
[b4_percent_define_ifdef([[location_type]], [$1], [$2])])
# b4_locations_if(TRUE, FALSE)
# ----------------------------
m4_define([b4_locations_if],
[m4_if(b4_locations_flag, 1, [$1], [$2])])
# b4_identification
# -----------------
m4_define([b4_identification],
+137 -130
View File
@@ -259,10 +259,14 @@ static YYLTYPE yyloc_default][]b4_yyloc_default;])[
]b4_user_post_prologue[
]b4_percent_code_get[]dnl
[#include <stdio.h>
[#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
]b4_c99_int_type_define[
#ifndef YY_
# if defined YYENABLE_NLS && YYENABLE_NLS
# if ENABLE_NLS
@@ -285,7 +289,7 @@ static YYLTYPE yyloc_default][]b4_yyloc_default;])[
# define YYREALLOC realloc
#endif
#define YYSIZEMAX ((size_t) -1)
#define YYSIZEMAX (PTRDIFF_MAX < SIZE_MAX ? PTRDIFF_MAX : (ptrdiff_t) SIZE_MAX)
#ifdef __cplusplus
typedef bool yybool;
@@ -293,7 +297,7 @@ static YYLTYPE yyloc_default][]b4_yyloc_default;])[
# define yyfalse false
#else
/* When we move to stdbool, get rid of the various casts to yybool. */
typedef unsigned char yybool;
typedef signed char yybool;
# define yytrue 1
# define yyfalse 0
#endif
@@ -346,15 +350,17 @@ static YYLTYPE yyloc_default][]b4_yyloc_default;])[
/* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM
as returned by yylex, with out-of-bounds checking. */
#define YYTRANSLATE(YYX) \
((unsigned) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
]b4_api_token_raw_if(dnl
[[#define YYTRANSLATE(YYX) (YYX)]],
[[#define YYTRANSLATE(YYX) \
(0 <= (YYX) && (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM
as returned by yylex. */
static const ]b4_int_type_for([b4_translate])[ yytranslate[] =
{
]b4_translate[
};
};]])[
#if ]b4_api_PREFIX[DEBUG
/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
@@ -373,8 +379,8 @@ static const char *const yytname[] =
};
#endif
#define YYPACT_NINF ]b4_pact_ninf[
#define YYTABLE_NINF ]b4_table_ninf[
#define YYPACT_NINF (]b4_pact_ninf[)
#define YYTABLE_NINF (]b4_table_ninf[)
]b4_parser_tables_define[
@@ -488,7 +494,7 @@ typedef enum { yyok, yyaccept, yyabort, yyerr } YYRESULTTAG;
int yydebug;
struct yyGLRStack;
static void yypstack (struct yyGLRStack* yystackp, size_t yyk)
static void yypstack (struct yyGLRStack* yystackp, ptrdiff_t yyk)
YY_ATTRIBUTE_UNUSED;
static void yypdumpstack (struct yyGLRStack* yystackp)
YY_ATTRIBUTE_UNUSED;
@@ -572,12 +578,12 @@ yystpcpy (char *yydest, const char *yysrc)
backslash-backslash). YYSTR is taken from yytname. If YYRES is
null, do not copy; instead, return the length of what the result
would have been. */
static size_t
static ptrdiff_t
yytnamerr (char *yyres, const char *yystr)
{
if (*yystr == '"')
{
size_t yyn = 0;
ptrdiff_t yyn = 0;
char const *yyp = yystr;
for (;;)
@@ -608,25 +614,25 @@ yytnamerr (char *yyres, const char *yystr)
do_not_strip_quotes: ;
}
if (! yyres)
return strlen (yystr);
return (size_t) (yystpcpy (yyres, yystr) - yyres);
if (yyres)
return yystpcpy (yyres, yystr) - yyres;
else
return (ptrdiff_t) strlen (yystr);
}
# endif
#endif /* !YYERROR_VERBOSE */
/** State numbers, as in LALR(1) machine */
/** State numbers. */
typedef int yyStateNum;
/** Rule numbers, as in LALR(1) machine */
/** Rule numbers. */
typedef int yyRuleNum;
/** Grammar symbol */
/** Grammar symbol. */
typedef int yySymbol;
/** Item references, as in LALR(1) machine */
/** Item references. */
typedef short yyItemNum;
typedef struct yyGLRState yyGLRState;
@@ -646,7 +652,7 @@ struct yyGLRState {
/** Preceding state in this stack */
yyGLRState* yypred;
/** Source position of the last token produced by my symbol */
size_t yyposn;
ptrdiff_t yyposn;
union {
/** First in a chain of alternative reductions producing the
* nonterminal corresponding to this state, threaded through
@@ -666,7 +672,8 @@ struct yyGLRStateSet {
* operation, yylookaheadNeeds[0] is not maintained since it would merely
* duplicate yychar != YYEMPTY. */
yybool* yylookaheadNeeds;
size_t yysize, yycapacity;
ptrdiff_t yysize;
ptrdiff_t yycapacity;
};
struct yySemanticOption {
@@ -706,7 +713,7 @@ struct yyGLRStack {
YYJMP_BUF yyexception_buffer;
yyGLRStackItem* yyitems;
yyGLRStackItem* yynextFree;
size_t yyspaceLeft;
ptrdiff_t yyspaceLeft;
yyGLRState* yysplitPoint;
yyGLRState* yylastDeleted;
yyGLRStateSet yytops;
@@ -965,8 +972,8 @@ yylhsNonterm (yyRuleNum yyrule)
return yyr1[yyrule];
}
#define yypact_value_is_default(Yystate) \
]b4_table_value_equals([[pact]], [[Yystate]], [b4_pact_ninf])[
#define yypact_value_is_default(Yyn) \
]b4_table_value_equals([[pact]], [[Yyn]], [b4_pact_ninf], [YYPACT_NINF])[
/** True iff LR state YYSTATE has only a default reduction (regardless
* of token). */
@@ -983,8 +990,8 @@ yydefaultAction (yyStateNum yystate)
return yydefact[yystate];
}
#define yytable_value_is_error(Yytable_value) \
]b4_table_value_equals([[table]], [[Yytable_value]], [b4_table_ninf])[
#define yytable_value_is_error(Yyn) \
]b4_table_value_equals([[table]], [[Yyn]], [b4_table_ninf], [YYTABLE_NINF])[
/** The action to take in YYSTATE on seeing YYTOKEN.
* Result R means
@@ -1064,7 +1071,7 @@ yynewGLRStackItem (yyGLRStack* yystackp, yybool yyisState)
* alternative actions for YYSTATE. Assumes that YYRHS comes from
* stack #YYK of *YYSTACKP. */
static void
yyaddDeferredAction (yyGLRStack* yystackp, size_t yyk, yyGLRState* yystate,
yyaddDeferredAction (yyGLRStack* yystackp, ptrdiff_t yyk, yyGLRState* yystate,
yyGLRState* yyrhs, yyRuleNum yyrule)
{
yySemanticOption* yynewOption =
@@ -1094,17 +1101,22 @@ yyinitStateSet (yyGLRStateSet* yyset)
{
yyset->yysize = 1;
yyset->yycapacity = 16;
yyset->yystates = (yyGLRState**) YYMALLOC (16 * sizeof yyset->yystates[0]);
yyset->yystates
= (yyGLRState**) YYMALLOC ((size_t) yyset->yycapacity
* sizeof yyset->yystates[0]);
if (! yyset->yystates)
return yyfalse;
yyset->yystates[0] = YY_NULLPTR;
yyset->yylookaheadNeeds =
(yybool*) YYMALLOC (16 * sizeof yyset->yylookaheadNeeds[0]);
yyset->yylookaheadNeeds
= (yybool*) YYMALLOC ((size_t) yyset->yycapacity
* sizeof yyset->yylookaheadNeeds[0]);
if (! yyset->yylookaheadNeeds)
{
YYFREE (yyset->yystates);
return yyfalse;
}
memset (yyset->yylookaheadNeeds,
0, (size_t) yyset->yycapacity * sizeof yyset->yylookaheadNeeds[0]);
return yytrue;
}
@@ -1117,13 +1129,14 @@ static void yyfreeStateSet (yyGLRStateSet* yyset)
/** Initialize *YYSTACKP to a single empty stack, with total maximum
* capacity for all stacks of YYSIZE. */
static yybool
yyinitGLRStack (yyGLRStack* yystackp, size_t yysize)
yyinitGLRStack (yyGLRStack* yystackp, ptrdiff_t yysize)
{
yystackp->yyerrState = 0;
yynerrs = 0;
yystackp->yyspaceLeft = yysize;
yystackp->yyitems =
(yyGLRStackItem*) YYMALLOC (yysize * sizeof yystackp->yynextFree[0]);
(yyGLRStackItem*) YYMALLOC ((size_t) yysize
* sizeof yystackp->yynextFree[0]);
if (!yystackp->yyitems)
return yyfalse;
yystackp->yynextFree = yystackp->yyitems;
@@ -1147,15 +1160,16 @@ yyexpandGLRStack (yyGLRStack* yystackp)
{
yyGLRStackItem* yynewItems;
yyGLRStackItem* yyp0, *yyp1;
size_t yynewSize;
size_t yyn;
size_t yysize = (size_t) (yystackp->yynextFree - yystackp->yyitems);
ptrdiff_t yynewSize;
ptrdiff_t yyn;
ptrdiff_t yysize = yystackp->yynextFree - yystackp->yyitems;
if (YYMAXDEPTH - YYHEADROOM < yysize)
yyMemoryExhausted (yystackp);
yynewSize = 2*yysize;
if (YYMAXDEPTH < yynewSize)
yynewSize = YYMAXDEPTH;
yynewItems = (yyGLRStackItem*) YYMALLOC (yynewSize * sizeof yynewItems[0]);
yynewItems = (yyGLRStackItem*) YYMALLOC ((size_t) yynewSize
* sizeof yynewItems[0]);
if (! yynewItems)
yyMemoryExhausted (yystackp);
for (yyp0 = yystackp->yyitems, yyp1 = yynewItems, yyn = yysize;
@@ -1219,7 +1233,7 @@ yyupdateSplit (yyGLRStack* yystackp, yyGLRState* yys)
/** Invalidate stack #YYK in *YYSTACKP. */
static inline void
yymarkStackDeleted (yyGLRStack* yystackp, size_t yyk)
yymarkStackDeleted (yyGLRStack* yystackp, ptrdiff_t yyk)
{
if (yystackp->yytops.yystates[yyk] != YY_NULLPTR)
yystackp->yylastDeleted = yystackp->yytops.yystates[yyk];
@@ -1243,7 +1257,7 @@ yyundeleteLastStack (yyGLRStack* yystackp)
static inline void
yyremoveDeletes (yyGLRStack* yystackp)
{
size_t yyi, yyj;
ptrdiff_t yyi, yyj;
yyi = yyj = 0;
while (yyj < yystackp->yytops.yysize)
{
@@ -1267,8 +1281,8 @@ yyremoveDeletes (yyGLRStack* yystackp)
yystackp->yytops.yylookaheadNeeds[yyi];
if (yyj != yyi)
{
YYDPRINTF ((stderr, "Rename stack %lu -> %lu.\n",
(unsigned long) yyi, (unsigned long) yyj));
YYDPRINTF ((stderr, "Rename stack %ld -> %ld.\n",
(long) yyi, (long) yyj));
}
yyj += 1;
}
@@ -1280,8 +1294,8 @@ yyremoveDeletes (yyGLRStack* yystackp)
* state YYLRSTATE, at input position YYPOSN, with (resolved) semantic
* value *YYVALP and source location *YYLOCP. */
static inline void
yyglrShift (yyGLRStack* yystackp, size_t yyk, yyStateNum yylrState,
size_t yyposn,
yyglrShift (yyGLRStack* yystackp, ptrdiff_t yyk, yyStateNum yylrState,
ptrdiff_t yyposn,
YYSTYPE* yyvalp]b4_locations_if([, YYLTYPE* yylocp])[)
{
yyGLRState* yynewState = &yynewGLRStackItem (yystackp, yytrue)->yystate;
@@ -1301,8 +1315,8 @@ yyglrShift (yyGLRStack* yystackp, size_t yyk, yyStateNum yylrState,
* state YYLRSTATE, at input position YYPOSN, with the (unresolved)
* semantic value of YYRHS under the action for YYRULE. */
static inline void
yyglrShiftDefer (yyGLRStack* yystackp, size_t yyk, yyStateNum yylrState,
size_t yyposn, yyGLRState* yyrhs, yyRuleNum yyrule)
yyglrShiftDefer (yyGLRStack* yystackp, ptrdiff_t yyk, yyStateNum yylrState,
ptrdiff_t yyposn, yyGLRState* yyrhs, yyRuleNum yyrule)
{
yyGLRState* yynewState = &yynewGLRStackItem (yystackp, yytrue)->yystate;
YYASSERT (yynewState->yyisState);
@@ -1332,15 +1346,14 @@ yyglrShiftDefer (yyGLRStack* yystackp, size_t yyk, yyStateNum yylrState,
`----------------------------------------------------------------------*/
static inline void
yy_reduce_print (yybool yynormal, yyGLRStackItem* yyvsp, size_t yyk,
yy_reduce_print (yybool yynormal, yyGLRStackItem* yyvsp, ptrdiff_t yyk,
yyRuleNum yyrule]b4_user_formals[)
{
int yynrhs = yyrhsLength (yyrule);]b4_locations_if([
int yylow = 1;])[
int yyi;
YYFPRINTF (stderr, "Reducing stack %lu by rule %d (line %lu):\n",
(unsigned long) yyk, yyrule - 1,
(unsigned long) yyrline[yyrule]);
YYFPRINTF (stderr, "Reducing stack %ld by rule %d (line %d):\n",
(long) yyk, yyrule - 1, yyrline[yyrule]);
if (! yynormal)
yyfillin (yyvsp, 1, -yynrhs);
/* The symbols being reduced. */
@@ -1366,7 +1379,7 @@ yy_reduce_print (yybool yynormal, yyGLRStackItem* yyvsp, size_t yyk,
* and *YYLOCP to the computed location (if any). Return value is as
* for userAction. */
static inline YYRESULTTAG
yydoAction (yyGLRStack* yystackp, size_t yyk, yyRuleNum yyrule,
yydoAction (yyGLRStack* yystackp, ptrdiff_t yyk, yyRuleNum yyrule,
YYSTYPE* yyvalp]b4_locuser_formals[)
{
int yynrhs = yyrhsLength (yyrule);
@@ -1377,7 +1390,7 @@ yydoAction (yyGLRStack* yystackp, size_t yyk, yyRuleNum yyrule,
yyGLRStackItem* yyrhs = (yyGLRStackItem*) yystackp->yytops.yystates[yyk];
YYASSERT (yyk == 0);
yystackp->yynextFree -= yynrhs;
yystackp->yyspaceLeft += (size_t) yynrhs;
yystackp->yyspaceLeft += yynrhs;
yystackp->yytops.yystates[0] = & yystackp->yynextFree[-1].yystate;
YY_REDUCE_PRINT ((yytrue, yyrhs, yyk, yyrule]b4_user_args[));
return yyuserAction (yyrule, yynrhs, yyrhs, yystackp,
@@ -1385,11 +1398,10 @@ yydoAction (yyGLRStack* yystackp, size_t yyk, yyRuleNum yyrule,
}
else
{
int yyi;
yyGLRState* yys;
yyGLRStackItem yyrhsVals[YYMAXRHS + YYMAXLEFT + 1];
yys = yyrhsVals[YYMAXRHS + YYMAXLEFT].yystate.yypred
= yystackp->yytops.yystates[yyk];]b4_locations_if([[
yyGLRState* yys = yyrhsVals[YYMAXRHS + YYMAXLEFT].yystate.yypred
= yystackp->yytops.yystates[yyk];
int yyi;]b4_locations_if([[
if (yynrhs == 0)
/* Set default location. */
yyrhsVals[YYMAXRHS + YYMAXLEFT - 1].yystate.yyloc = yys->yyloc;]])[
@@ -1418,10 +1430,10 @@ yydoAction (yyGLRStack* yystackp, size_t yyk, yyRuleNum yyrule,
* added to the options for the existing state's semantic value.
*/
static inline YYRESULTTAG
yyglrReduce (yyGLRStack* yystackp, size_t yyk, yyRuleNum yyrule,
yyglrReduce (yyGLRStack* yystackp, ptrdiff_t yyk, yyRuleNum yyrule,
yybool yyforceEval]b4_user_formals[)
{
size_t yyposn = yystackp->yytops.yystates[yyk]->yyposn;
ptrdiff_t yyposn = yystackp->yytops.yystates[yyk]->yyposn;
if (yyforceEval || yystackp->yysplitPoint == YY_NULLPTR)
{
@@ -1431,8 +1443,9 @@ yyglrReduce (yyGLRStack* yystackp, size_t yyk, yyRuleNum yyrule,
YYRESULTTAG yyflag = yydoAction (yystackp, yyk, yyrule, &yysval]b4_locuser_args([&yyloc])[);
if (yyflag == yyerr && yystackp->yysplitPoint != YY_NULLPTR)
{
YYDPRINTF ((stderr, "Parse on stack %lu rejected by rule #%d.\n",
(unsigned long) yyk, yyrule - 1));
YYDPRINTF ((stderr,
"Parse on stack %ld rejected by rule %d (line %d).\n",
(long) yyk, yyrule - 1, yyrline[yyrule - 1]));
}
if (yyflag != yyok)
return yyflag;
@@ -1444,7 +1457,7 @@ yyglrReduce (yyGLRStack* yystackp, size_t yyk, yyRuleNum yyrule,
}
else
{
size_t yyi;
ptrdiff_t yyi;
int yyn;
yyGLRState* yys, *yys0 = yystackp->yytops.yystates[yyk];
yyStateNum yynewLRState;
@@ -1458,9 +1471,9 @@ yyglrReduce (yyGLRStack* yystackp, size_t yyk, yyRuleNum yyrule,
yyupdateSplit (yystackp, yys);
yynewLRState = yyLRgotoState (yys->yylrState, yylhsNonterm (yyrule));
YYDPRINTF ((stderr,
"Reduced stack %lu by rule #%d; action deferred. "
"Reduced stack %ld by rule %d (line %d); action deferred. "
"Now in state %d.\n",
(unsigned long) yyk, yyrule - 1, yynewLRState));
(long) yyk, yyrule - 1, yyrline[yyrule - 1], yynewLRState));
for (yyi = 0; yyi < yystackp->yytops.yysize; yyi += 1)
if (yyi != yyk && yystackp->yytops.yystates[yyi] != YY_NULLPTR)
{
@@ -1472,9 +1485,8 @@ yyglrReduce (yyGLRStack* yystackp, size_t yyk, yyRuleNum yyrule,
{
yyaddDeferredAction (yystackp, yyk, yyp, yys0, yyrule);
yymarkStackDeleted (yystackp, yyk);
YYDPRINTF ((stderr, "Merging stack %lu into stack %lu.\n",
(unsigned long) yyk,
(unsigned long) yyi));
YYDPRINTF ((stderr, "Merging stack %ld into stack %ld.\n",
(long) yyk, (long) yyi));
return yyok;
}
yyp = yyp->yypred;
@@ -1486,8 +1498,8 @@ yyglrReduce (yyGLRStack* yystackp, size_t yyk, yyRuleNum yyrule,
return yyok;
}
static size_t
yysplitStack (yyGLRStack* yystackp, size_t yyk)
static ptrdiff_t
yysplitStack (yyGLRStack* yystackp, ptrdiff_t yyk)
{
if (yystackp->yysplitPoint == YY_NULLPTR)
{
@@ -1498,15 +1510,16 @@ yysplitStack (yyGLRStack* yystackp, size_t yyk)
{
yyGLRState** yynewStates = YY_NULLPTR;
yybool* yynewLookaheadNeeds;
ptrdiff_t state_size = sizeof yynewStates[0];
ptrdiff_t half_max_capacity = YYSIZEMAX / 2 / state_size;
if (yystackp->yytops.yycapacity
> (YYSIZEMAX / (2 * sizeof yynewStates[0])))
if (half_max_capacity < yystackp->yytops.yycapacity)
yyMemoryExhausted (yystackp);
yystackp->yytops.yycapacity *= 2;
yynewStates =
(yyGLRState**) YYREALLOC (yystackp->yytops.yystates,
(yystackp->yytops.yycapacity
((size_t) yystackp->yytops.yycapacity
* sizeof yynewStates[0]));
if (yynewStates == YY_NULLPTR)
yyMemoryExhausted (yystackp);
@@ -1514,7 +1527,7 @@ yysplitStack (yyGLRStack* yystackp, size_t yyk)
yynewLookaheadNeeds =
(yybool*) YYREALLOC (yystackp->yytops.yylookaheadNeeds,
(yystackp->yytops.yycapacity
((size_t) yystackp->yytops.yycapacity
* sizeof yynewLookaheadNeeds[0]));
if (yynewLookaheadNeeds == YY_NULLPTR)
yyMemoryExhausted (yystackp);
@@ -1716,10 +1729,10 @@ yyreportTree (yySemanticOption* yyx, int yyindent)
yyindent, "", yytokenName (yylhsNonterm (yyx->yyrule)),
yyx->yyrule - 1);
else
YYFPRINTF (stderr, "%*s%s -> <Rule %d, tokens %lu .. %lu>\n",
YYFPRINTF (stderr, "%*s%s -> <Rule %d, tokens %ld .. %ld>\n",
yyindent, "", yytokenName (yylhsNonterm (yyx->yyrule)),
yyx->yyrule - 1, (unsigned long) (yys->yyposn + 1),
(unsigned long) yyx->yystate->yyposn);
yyx->yyrule - 1, (long) (yys->yyposn + 1),
(long) yyx->yystate->yyposn);
for (yyi = 1; yyi <= yynrhs; yyi += 1)
{
if (yystates[yyi]->yyresolved)
@@ -1728,10 +1741,10 @@ yyreportTree (yySemanticOption* yyx, int yyindent)
YYFPRINTF (stderr, "%*s%s <empty>\n", yyindent+2, "",
yytokenName (yystos[yystates[yyi]->yylrState]));
else
YYFPRINTF (stderr, "%*s%s <tokens %lu .. %lu>\n", yyindent+2, "",
YYFPRINTF (stderr, "%*s%s <tokens %ld .. %ld>\n", yyindent+2, "",
yytokenName (yystos[yystates[yyi]->yylrState]),
(unsigned long) (yystates[yyi-1]->yyposn + 1),
(unsigned long) yystates[yyi]->yyposn);
(long) (yystates[yyi-1]->yyposn + 1),
(long) yystates[yyi]->yyposn);
}
else
yyreportTree (yystates[yyi]->yysemantics.yyfirstVal, yyindent+2);
@@ -1926,9 +1939,9 @@ yycompressStack (yyGLRStack* yystackp)
yyr = yyp, yyp = yyq, yyq = yyp->yypred)
yyp->yypred = yyr;
yystackp->yyspaceLeft += (size_t) (yystackp->yynextFree - yystackp->yyitems);
yystackp->yyspaceLeft += yystackp->yynextFree - yystackp->yyitems;
yystackp->yynextFree = ((yyGLRStackItem*) yystackp->yysplitPoint) + 1;
yystackp->yyspaceLeft -= (size_t) (yystackp->yynextFree - yystackp->yyitems);
yystackp->yyspaceLeft -= yystackp->yynextFree - yystackp->yyitems;
yystackp->yysplitPoint = YY_NULLPTR;
yystackp->yylastDeleted = YY_NULLPTR;
@@ -1944,14 +1957,13 @@ yycompressStack (yyGLRStack* yystackp)
}
static YYRESULTTAG
yyprocessOneStack (yyGLRStack* yystackp, size_t yyk,
size_t yyposn]b4_pure_formals[)
yyprocessOneStack (yyGLRStack* yystackp, ptrdiff_t yyk,
ptrdiff_t yyposn]b4_pure_formals[)
{
while (yystackp->yytops.yystates[yyk] != YY_NULLPTR)
{
yyStateNum yystate = yystackp->yytops.yystates[yyk]->yylrState;
YYDPRINTF ((stderr, "Stack %lu Entering state %d\n",
(unsigned long) yyk, yystate));
YYDPRINTF ((stderr, "Stack %ld Entering state %d\n", yyk, yystate));
YYASSERT (yystate != YYFINAL);
@@ -1961,8 +1973,7 @@ yyprocessOneStack (yyGLRStack* yystackp, size_t yyk,
yyRuleNum yyrule = yydefaultAction (yystate);
if (yyrule == 0)
{
YYDPRINTF ((stderr, "Stack %lu dies.\n",
(unsigned long) yyk));
YYDPRINTF ((stderr, "Stack %ld dies.\n", (long) yyk));
yymarkStackDeleted (yystackp, yyk);
return yyok;
}
@@ -1970,9 +1981,9 @@ yyprocessOneStack (yyGLRStack* yystackp, size_t yyk,
if (yyflag == yyerr)
{
YYDPRINTF ((stderr,
"Stack %lu dies "
"Stack %ld dies "
"(predicate failure or explicit user error).\n",
(unsigned long) yyk));
(long) yyk));
yymarkStackDeleted (yystackp, yyk);
return yyok;
}
@@ -1981,21 +1992,17 @@ yyprocessOneStack (yyGLRStack* yystackp, size_t yyk,
}
else
{
yySymbol yytoken;
int yyaction;
yySymbol yytoken = ]b4_yygetToken_call[;
const short* yyconflicts;
const int yyaction = yygetLRActions (yystate, yytoken, &yyconflicts);
yystackp->yytops.yylookaheadNeeds[yyk] = yytrue;
yytoken = ]b4_yygetToken_call[;
yyaction = yygetLRActions (yystate, yytoken, &yyconflicts);
while (*yyconflicts != 0)
{
YYRESULTTAG yyflag;
size_t yynewStack = yysplitStack (yystackp, yyk);
YYDPRINTF ((stderr, "Splitting off stack %lu from %lu.\n",
(unsigned long) yynewStack,
(unsigned long) yyk));
ptrdiff_t yynewStack = yysplitStack (yystackp, yyk);
YYDPRINTF ((stderr, "Splitting off stack %ld from %ld.\n",
(long) yynewStack, (long) yyk));
yyflag = yyglrReduce (yystackp, yynewStack,
*yyconflicts,
yyimmediate[*yyconflicts]]b4_user_args[);
@@ -2004,8 +2011,7 @@ yyprocessOneStack (yyGLRStack* yystackp, size_t yyk,
yyposn]b4_pure_args[));
else if (yyflag == yyerr)
{
YYDPRINTF ((stderr, "Stack %lu dies.\n",
(unsigned long) yynewStack));
YYDPRINTF ((stderr, "Stack %ld dies.\n", (long) yynewStack));
yymarkStackDeleted (yystackp, yynewStack);
}
else
@@ -2017,8 +2023,7 @@ yyprocessOneStack (yyGLRStack* yystackp, size_t yyk,
break;
else if (yyisErrorAction (yyaction))
{
YYDPRINTF ((stderr, "Stack %lu dies.\n",
(unsigned long) yyk));
YYDPRINTF ((stderr, "Stack %ld dies.\n", (long) yyk));
yymarkStackDeleted (yystackp, yyk);
break;
}
@@ -2029,9 +2034,9 @@ yyprocessOneStack (yyGLRStack* yystackp, size_t yyk,
if (yyflag == yyerr)
{
YYDPRINTF ((stderr,
"Stack %lu dies "
"Stack %ld dies "
"(predicate failure or explicit user error).\n",
(unsigned long) yyk));
(long) yyk));
yymarkStackDeleted (yystackp, yyk);
break;
}
@@ -2053,8 +2058,8 @@ yyreportSyntaxError (yyGLRStack* yystackp]b4_user_formals[)
#else
{
yySymbol yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar);
size_t yysize0 = yytnamerr (YY_NULLPTR, yytokenName (yytoken));
size_t yysize = yysize0;
ptrdiff_t yysize0 = yytnamerr (YY_NULLPTR, yytokenName (yytoken));
ptrdiff_t yysize = yysize0;
yybool yysize_overflow = yyfalse;
char* yymsg = YY_NULLPTR;
enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
@@ -2115,10 +2120,11 @@ yyreportSyntaxError (yyGLRStack* yystackp]b4_user_formals[)
}
yyarg[yycount++] = yytokenName (yyx);
{
size_t yysz = yysize + yytnamerr (YY_NULLPTR, yytokenName (yyx));
if (yysz < yysize)
ptrdiff_t yysz = yytnamerr (YY_NULLPTR, yytokenName (yyx));
if (YYSIZEMAX - yysize < yysz)
yysize_overflow = yytrue;
yysize = yysz;
else
yysize += yysz;
}
}
}
@@ -2141,14 +2147,15 @@ yyreportSyntaxError (yyGLRStack* yystackp]b4_user_formals[)
}
{
size_t yysz = yysize + strlen (yyformat);
if (yysz < yysize)
ptrdiff_t yysz = (ptrdiff_t) strlen (yyformat);
if (YYSIZEMAX - yysize < yysz)
yysize_overflow = yytrue;
yysize = yysz;
else
yysize += yysz;
}
if (!yysize_overflow)
yymsg = (char *) YYMALLOC (yysize);
yymsg = (char *) YYMALLOC ((size_t) yysize);
if (yymsg)
{
@@ -2225,7 +2232,7 @@ yyrecoverSyntaxError (yyGLRStack* yystackp]b4_user_formals[)
/* Reduce to one stack. */
{
size_t yyk;
ptrdiff_t yyk;
for (yyk = 0; yyk < yystackp->yytops.yysize; yyk += 1)
if (yystackp->yytops.yystates[yyk] != YY_NULLPTR)
break;
@@ -2249,14 +2256,15 @@ yyrecoverSyntaxError (yyGLRStack* yystackp]b4_user_formals[)
if (0 <= yyj && yyj <= YYLAST && yycheck[yyj] == YYTERROR
&& yyisShiftAction (yytable[yyj]))
{
/* Shift the error token. */]b4_locations_if([[
/* Shift the error token. */
int yyaction = yytable[yyj];]b4_locations_if([[
/* First adjust its location.*/
YYLTYPE yyerrloc;
yystackp->yyerror_range[2].yystate.yyloc = yylloc;
YYLLOC_DEFAULT (yyerrloc, (yystackp->yyerror_range), 2);]])[
YY_SYMBOL_PRINT ("Shifting", yystos[yytable[yyj]],
YY_SYMBOL_PRINT ("Shifting", yystos[yyaction],
&yylval, &yyerrloc);
yyglrShift (yystackp, 0, yytable[yyj],
yyglrShift (yystackp, 0, yyaction,
yys->yyposn, &yylval]b4_locations_if([, &yyerrloc])[);
yys = yystackp->yytops.yystates[0];
break;
@@ -2298,7 +2306,7 @@ yyrecoverSyntaxError (yyGLRStack* yystackp]b4_user_formals[)
int yyresult;
yyGLRStack yystack;
yyGLRStack* const yystackp = &yystack;
size_t yyposn;
ptrdiff_t yyposn;
YYDPRINTF ((stderr, "Starting parse\n"));
@@ -2378,7 +2386,7 @@ b4_dollar_popdef])[]dnl
while (yytrue)
{
yySymbol yytoken_to_shift;
size_t yys;
ptrdiff_t yys;
for (yys = 0; yys < yystack.yytops.yysize; yys += 1)
yystackp->yytops.yylookaheadNeeds[yys] = (yybool) (yychar != YYEMPTY);
@@ -2432,12 +2440,12 @@ b4_dollar_popdef])[]dnl
int yyaction = yygetLRActions (yystate, yytoken_to_shift,
&yyconflicts);
/* Note that yyconflicts were handled by yyprocessOneStack. */
YYDPRINTF ((stderr, "On stack %lu, ", (unsigned long) yys));
YYDPRINTF ((stderr, "On stack %ld, ", (long) yys));
YY_SYMBOL_PRINT ("shifting", yytoken_to_shift, &yylval, &yylloc);
yyglrShift (&yystack, yys, yyaction, yyposn,
&yylval]b4_locations_if([, &yylloc])[);
YYDPRINTF ((stderr, "Stack %lu now in state #%d\n",
(unsigned long) yys,
YYDPRINTF ((stderr, "Stack %ld now in state #%d\n",
(long) yys,
yystack.yytops.yystates[yys]->yylrState));
}
@@ -2485,8 +2493,8 @@ b4_dollar_popdef])[]dnl
yyGLRState** yystates = yystack.yytops.yystates;
if (yystates)
{
size_t yysize = yystack.yytops.yysize;
size_t yyk;
ptrdiff_t yysize = yystack.yytops.yysize;
ptrdiff_t yyk;
for (yyk = 0; yyk < yysize; yyk += 1)
if (yystates[yyk])
{
@@ -2519,8 +2527,7 @@ yy_yypstack (yyGLRState* yys)
yy_yypstack (yys->yypred);
YYFPRINTF (stderr, " -> ");
}
YYFPRINTF (stderr, "%d@@%lu", yys->yylrState,
(unsigned long) yys->yyposn);
YYFPRINTF (stderr, "%d@@%ld", yys->yylrState, (long) yys->yyposn);
}
static void
@@ -2534,7 +2541,7 @@ yypstates (yyGLRState* yyst)
}
static void
yypstack (yyGLRStack* yystackp, size_t yyk)
yypstack (yyGLRStack* yystackp, ptrdiff_t yyk)
{
yypstates (yystackp->yytops.yystates[yyk]);
}
@@ -2547,18 +2554,18 @@ static void
yypdumpstack (yyGLRStack* yystackp)
{
yyGLRStackItem* yyp;
size_t yyi;
ptrdiff_t yyi;
for (yyp = yystackp->yyitems; yyp < yystackp->yynextFree; yyp += 1)
{
YYFPRINTF (stderr, "%3lu. ",
(unsigned long) (yyp - yystackp->yyitems));
YYFPRINTF (stderr, "%3ld. ",
(long) (yyp - yystackp->yyitems));
if (*(yybool *) yyp)
{
YYASSERT (yyp->yystate.yyisState);
YYASSERT (yyp->yyoption.yyisState);
YYFPRINTF (stderr, "Res: %d, LR State: %d, posn: %lu, pred: %ld",
YYFPRINTF (stderr, "Res: %d, LR State: %d, posn: %ld, pred: %ld",
yyp->yystate.yyresolved, yyp->yystate.yylrState,
(unsigned long) yyp->yystate.yyposn,
(long) yyp->yystate.yyposn,
(long) YYINDEX (yyp->yystate.yypred));
if (! yyp->yystate.yyresolved)
YYFPRINTF (stderr, ", firstVal: %ld",
@@ -2578,7 +2585,7 @@ yypdumpstack (yyGLRStack* yystackp)
}
YYFPRINTF (stderr, "Tops:");
for (yyi = 0; yyi < yystackp->yytops.yysize; yyi += 1)
YYFPRINTF (stderr, "%lu: %ld; ", (unsigned long) yyi,
YYFPRINTF (stderr, "%ld: %ld; ", (long) yyi,
(long) YYINDEX (yystackp->yytops.yystates[yyi]));
YYFPRINTF (stderr, "\n");
}
+13 -2
View File
@@ -184,8 +184,19 @@ b4_percent_define_check_kind([[throws]], [code], [deprecated])
m4_define([b4_yystype], [b4_percent_define_get([[api.value.type]])])
b4_percent_define_default([[api.value.type]], [[Object]])
# %name-prefix
m4_define_default([b4_prefix], [[YY]])
# b4_api_prefix, b4_api_PREFIX
# ----------------------------
# Corresponds to %define api.prefix
b4_percent_define_default([[api.prefix]], [[YY]])
m4_define([b4_api_prefix],
[b4_percent_define_get([[api.prefix]])])
m4_define([b4_api_PREFIX],
[m4_toupper(b4_api_prefix)])
# b4_prefix
# ---------
# If the %name-prefix is not given, it is api.prefix.
m4_define_default([b4_prefix], [b4_api_prefix])
b4_percent_define_default([[api.parser.class]], [b4_prefix[]Parser])
m4_define([b4_parser_class], [b4_percent_define_get([[api.parser.class]])])
+246 -37
View File
@@ -20,14 +20,22 @@ m4_include(b4_skeletonsdir/[c++.m4])
# api.value.type=variant is valid.
m4_define([b4_value_type_setup_variant])
# Check the value of %define parse.lac, where LAC stands for lookahead
# correction.
b4_percent_define_default([[parse.lac]], [[none]])
b4_define_flag_if([lac])
m4_define([b4_lac_flag],
[m4_if(b4_percent_define_get([[parse.lac]]),
[none], [[0]], [[1]])])
# b4_integral_parser_table_declare(TABLE-NAME, CONTENT, COMMENT)
# --------------------------------------------------------------
# Declare "parser::yy<TABLE-NAME>_" whose contents is CONTENT.
m4_define([b4_integral_parser_table_declare],
[m4_ifval([$3], [b4_comment([$3], [ ])
[m4_ifval([$3], [b4_comment([$3], [ ])
])dnl
static const b4_int_type_for([$2]) yy$1_[[]];dnl
static const b4_int_type_for([$2]) yy$1_[[]];dnl
])
# b4_integral_parser_table_define(TABLE-NAME, CONTENT, COMMENT)
@@ -220,10 +228,21 @@ m4_define([b4_shared_declarations],
private:
/// This class is not copyable.
]b4_parser_class[ (const ]b4_parser_class[&);
]b4_parser_class[& operator= (const ]b4_parser_class[&);
]b4_parser_class[& operator= (const ]b4_parser_class[&);]b4_lac_if([[
/// State numbers.
typedef int state_type;
/// Check the lookahead yytoken.
/// \returns true iff the token will be eventually shifted.
bool yy_lac_check_ (int yytoken) const;
/// Establish the initial context if no initial context currently exists.
/// \returns true iff the token will be eventually shifted.
bool yy_lac_establish_ (int yytoken);
/// Discard any previous initial lookahead context because of event.
/// \param event the event which caused the lookahead to be discarded.
/// Only used for debbuging output.
void yy_lac_discard_ (const char* event);]])[
/// Stored state numbers (used for stacks).
typedef ]b4_int_type(0, m4_eval(b4_states_number - 1))[ state_type;
/// Generate an error message.
/// \param yystate the state where the error occurred.
@@ -234,7 +253,7 @@ m4_define([b4_shared_declarations],
/// Compute post-reduction state.
/// \param yystate the current state
/// \param yysym the nonterminal to push on the stack
state_type yy_lr_goto_state_ (state_type yystate, int yysym);
static state_type yy_lr_goto_state_ (state_type yystate, int yysym);
/// Whether the given \c yypact_ value indicates a defaulted state.
/// \param yyvalue the value to check
@@ -335,6 +354,10 @@ m4_define([b4_shared_declarations],
/// Assignment, needed by push_back by some old implementations.
/// Moves the contents of that.
stack_symbol_type& operator= (stack_symbol_type& that);
/// Assignment, needed by push_back by other implementations.
/// Needed by some other old implementations.
stack_symbol_type& operator= (const stack_symbol_type& that);
#endif
};
@@ -344,7 +367,16 @@ m4_define([b4_shared_declarations],
typedef stack<stack_symbol_type> stack_type;
/// The stack.
stack_type yystack_;
stack_type yystack_;]b4_lac_if([[
/// The stack for LAC.
/// Logically, the yy_lac_stack's lifetime is confined to the function
/// yy_lac_check_. We just store it as a member of this class to hold
/// on to the memory and to avoid frequent reallocations.
/// Since yy_lac_check_ is const, this member must be mutable.
mutable std::vector<state_type> yylac_stack_;
/// Whether an initial LAC context was established.
bool yy_lac_established_;
]])[
/// Push a new state on the stack.
/// \param m a debug message to display
@@ -459,9 +491,6 @@ m4_if(b4_prefix, [yy], [],
[#define YYRHSLOC(Rhs, K) ((Rhs)[K].location)
]b4_yylloc_default_define])[
// Suppress unused-variable warnings by "using" E.
#define YYUSE(E) ((void) (E))
// Enable debugging if requested.
#if ]b4_api_PREFIX[DEBUG
@@ -551,12 +580,14 @@ m4_if(b4_prefix, [yy], [],
]])[
/// Build a parser object.
]b4_parser_class::b4_parser_class[ (]b4_parse_param_decl[)]m4_ifset([b4_parse_param], [
:])[
]b4_parser_class::b4_parser_class[ (]b4_parse_param_decl[)
#if ]b4_api_PREFIX[DEBUG
]m4_ifset([b4_parse_param], [ ], [ :])[yydebug_ (false),
yycdebug_ (&std::cerr)]m4_ifset([b4_parse_param], [,])[
#endif]b4_parse_param_cons[
: yydebug_ (false),
yycdebug_ (&std::cerr)]b4_lac_if([,], [m4_ifset([b4_parse_param], [,])])[
#else
]b4_lac_if([ :], [m4_ifset([b4_parse_param], [ :])])[
#endif]b4_lac_if([[
yy_lac_established_ (false)]m4_ifset([b4_parse_param], [,])])[]b4_parse_param_cons[
{}
]b4_parser_class::~b4_parser_class[ ()
@@ -630,6 +661,17 @@ m4_if(b4_prefix, [yy], [],
}
#if YY_CPLUSPLUS < 201103L
]b4_parser_class[::stack_symbol_type&
]b4_parser_class[::stack_symbol_type::operator= (const stack_symbol_type& that)
{
state = that.state;
]b4_variant_if([b4_symbol_variant([that.type_get ()],
[value], [copy], [that.value])],
[[value = that.value;]])[]b4_locations_if([
location = that.location;])[
return *this;
}
]b4_parser_class[::stack_symbol_type&
]b4_parser_class[::stack_symbol_type::operator= (stack_symbol_type& that)
{
@@ -761,7 +803,6 @@ m4_if(b4_prefix, [yy], [],
int
]b4_parser_class[::parse ()
{
// State.
int yyn;
/// Length of the RHS of the rule being reduced.
int yylen = 0;
@@ -777,7 +818,11 @@ m4_if(b4_prefix, [yy], [],
stack_symbol_type yyerror_range[3];]])[
/// The return value of parse ().
int yyresult;
int yyresult;]b4_lac_if([[
/// Discard the LAC context in case there still is one left from a
/// previous invocation.
yy_lac_discard_ ("init");]])[
#if YY_EXCEPTIONS
try
@@ -801,7 +846,7 @@ b4_dollar_popdef])[]dnl
| yynewstate -- push a new symbol on the stack. |
`-----------------------------------------------*/
yynewstate:
YYCDEBUG << "Entering state " << yystack_[0].state << '\n';
YYCDEBUG << "Entering state " << int (yystack_[0].state) << '\n';
// Accept?
if (yystack_[0].state == yyfinal_)
@@ -846,14 +891,21 @@ b4_dollar_popdef])[]dnl
to detect an error, take that action. */
yyn += yyla.type_get ();
if (yyn < 0 || yylast_ < yyn || yycheck_[yyn] != yyla.type_get ())
goto yydefault;
{]b4_lac_if([[
if (!yy_lac_establish_ (yyla.type_get ()))
goto yyerrlab;]])[
goto yydefault;
}
// Reduce or error.
yyn = yytable_[yyn];
if (yyn <= 0)
{
if (yy_table_value_is_error_ (yyn))
goto yyerrlab;
goto yyerrlab;]b4_lac_if([[
if (!yy_lac_establish_ (yyla.type_get ()))
goto yyerrlab;
]])[
yyn = -yyn;
goto yyreduce;
}
@@ -863,7 +915,8 @@ b4_dollar_popdef])[]dnl
--yyerrstatus_;
// Shift the lookahead token.
yypush_ ("Shifting", yyn, YY_MOVE (yyla));
yypush_ ("Shifting", static_cast<state_type> (yyn), YY_MOVE (yyla));]b4_lac_if([[
yy_lac_discard_ ("shift");]])[
goto yynewstate;
@@ -1023,8 +1076,9 @@ b4_dollar_popdef])[]dnl
yyerror_range[2].location = yyla.location;
YYLLOC_DEFAULT (error_token.location, yyerror_range, 2);]])[
// Shift the error token.
error_token.state = yyn;
// Shift the error token.]b4_lac_if([[
yy_lac_discard_ ("error recovery");]])[
error_token.state = static_cast<state_type> (yyn);
yypush_ ("Shifting", YY_MOVE (error_token));
}
goto yynewstate;
@@ -1088,8 +1142,147 @@ b4_dollar_popdef])[]dnl
{
error (]b4_join(b4_locations_if([yyexc.location]),
[[yyexc.what ()]])[);
}]b4_lac_if([[
bool
]b4_parser_class[::yy_lac_check_ (int yytoken) const
{
// Logically, the yylac_stack's lifetime is confined to this function.
// Clear it, to get rid of potential left-overs from previous call.
yylac_stack_.clear ();
// Reduce until we encounter a shift and thereby accept the token.
#if ]b4_api_PREFIX[DEBUG
YYCDEBUG << "LAC: checking lookahead " << yytname_[yytoken] << ':';
#endif
std::ptrdiff_t lac_top = 0;
while (true)
{
state_type top_state = (yylac_stack_.empty ()
? yystack_[lac_top].state
: yylac_stack_.back ());
int yyrule = yypact_[top_state];
if (yy_pact_value_is_default_ (yyrule)
|| (yyrule += yytoken) < 0 || yylast_ < yyrule
|| yycheck_[yyrule] != yytoken)
{
// Use the default action.
yyrule = yydefact_[top_state];
if (yyrule == 0)
{
YYCDEBUG << " Err\n";
return false;
}
}
else
{
// Use the action from yytable.
yyrule = yytable_[yyrule];
if (yy_table_value_is_error_ (yyrule))
{
YYCDEBUG << " Err\n";
return false;
}
if (0 < yyrule)
{
YYCDEBUG << " S" << yyrule << '\n';
return true;
}
yyrule = -yyrule;
}
// By now we know we have to simulate a reduce.
YYCDEBUG << " R" << yyrule - 1;
// Pop the corresponding number of values from the stack.
{
std::ptrdiff_t yylen = yyr2_[yyrule];
// First pop from the LAC stack as many tokens as possible.
std::ptrdiff_t lac_size = (std::ptrdiff_t) yylac_stack_.size ();
if (yylen < lac_size)
{
yylac_stack_.resize ((std::size_t) (lac_size - yylen));
yylen = 0;
}
else if (lac_size)
{
yylac_stack_.clear ();
yylen -= lac_size;
}
// Only afterwards look at the main stack.
// We simulate popping elements by incrementing lac_top.
lac_top += yylen;
}
// Keep top_state in sync with the updated stack.
top_state = (yylac_stack_.empty ()
? yystack_[lac_top].state
: yylac_stack_.back ());
// Push the resulting state of the reduction.
state_type state = yy_lr_goto_state_ (top_state, yyr1_[yyrule]);
YYCDEBUG << " G" << state;
yylac_stack_.push_back (state);
}
}
// Establish the initial context if no initial context currently exists.
bool
]b4_parser_class[::yy_lac_establish_ (int yytoken)
{
/* Establish the initial context for the current lookahead if no initial
context is currently established.
We define a context as a snapshot of the parser stacks. We define
the initial context for a lookahead as the context in which the
parser initially examines that lookahead in order to select a
syntactic action. Thus, if the lookahead eventually proves
syntactically unacceptable (possibly in a later context reached via a
series of reductions), the initial context can be used to determine
the exact set of tokens that would be syntactically acceptable in the
lookahead's place. Moreover, it is the context after which any
further semantic actions would be erroneous because they would be
determined by a syntactically unacceptable token.
yy_lac_establish_ should be invoked when a reduction is about to be
performed in an inconsistent state (which, for the purposes of LAC,
includes consistent states that don't know they're consistent because
their default reductions have been disabled).
For parse.lac=full, the implementation of yy_lac_establish_ is as
follows. If no initial context is currently established for the
current lookahead, then check if that lookahead can eventually be
shifted if syntactic actions continue from the current context. */
if (!yy_lac_established_)
{
#if ]b4_api_PREFIX[DEBUG
YYCDEBUG << "LAC: initial context established for "
<< yytname_[yytoken] << '\n';
#endif
yy_lac_established_ = true;
return yy_lac_check_ (yytoken);
}
return true;
}
// Discard any previous initial lookahead context.
void
]b4_parser_class[::yy_lac_discard_ (const char* evt)
{
/* Discard any previous initial lookahead context because of Event,
which may be a lookahead change or an invalidation of the currently
established initial context for the current lookahead.
The most common example of a lookahead change is a shift. An example
of both cases is syntax error recovery. That is, a syntax error
occurs when the lookahead is syntactically erroneous for the
currently established initial context, so error recovery manipulates
the parser stacks to try to find a new initial context in which the
current lookahead is syntactically acceptable. If it fails to find
such a context, it discards the lookahead. */
if (yy_lac_established_)
{
YYCDEBUG << "LAC: initial context discarded due to "
<< evt << '\n';
yy_lac_established_ = false;
}
}]])[
// Generate an error message.
std::string
]b4_parser_class[::yysyntax_error_ (]dnl
@@ -1098,7 +1291,7 @@ b4_error_verbose_if([state_type yystate, const symbol_type& yyla],
{]b4_error_verbose_if([[
// Number of reported tokens (one for the "unexpected", one per
// "expected").
size_t yycount = 0;
std::ptrdiff_t yycount = 0;
// Its maximum.
enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
// Arguments of yyformat.
@@ -1118,24 +1311,40 @@ b4_error_verbose_if([state_type yystate, const symbol_type& yyla],
a consistent state with a default action. There might have
been a previous inconsistent state, consistent state with a
non-default action, or user semantic action that manipulated
yyla. (However, yyla is currently not documented for users.)
yyla. (However, yyla is currently not documented for users.)]b4_lac_if([[
In the first two cases, it might appear that the current syntax
error should have been detected in the previous state when
yy_lac_check was invoked. However, at that time, there might
have been a different syntax error that discarded a different
initial context during error recovery, leaving behind the
current lookahead.]], [[
- Of course, the expected token list depends on states to have
correct lookahead information, and it depends on the parser not
to perform extra reductions after fetching a lookahead from the
scanner and before detecting a syntax error. Thus, state
merging (from LALR or IELR) and default reductions corrupt the
expected token list. However, the list is correct for
canonical LR with one exception: it will still contain any
token that will not be accepted due to an error action in a
later state.
scanner and before detecting a syntax error. Thus, state merging
(from LALR or IELR) and default reductions corrupt the expected
token list. However, the list is correct for canonical LR with
one exception: it will still contain any token that will not be
accepted due to an error action in a later state.]])[
*/
if (!yyla.empty ())
{
int yytoken = yyla.type_get ();
yyarg[yycount++] = yytname_[yytoken];
yyarg[yycount++] = yytname_[yytoken];]b4_lac_if([[
#if ]b4_api_PREFIX[DEBUG
// Execute LAC once. We don't care if it is succesful, we
// only do it for the sake of debugging output.
if (!yy_lac_established_)
yy_lac_check_ (yytoken);
#endif]])[
int yyn = yypact_[yystate];
if (!yy_pact_value_is_default_ (yyn))
{
{]b4_lac_if([[
for (int yyx = 0; yyx < yyntokens_; ++yyx)
if (yyx != yyterror_ && yy_lac_check_(yyx))
{]], [[
/* Start YYX at -YYN if negative to avoid negative indexes in
YYCHECK. In other words, skip the first -YYN actions for
this state because they are default actions. */
@@ -1146,7 +1355,7 @@ b4_error_verbose_if([state_type yystate, const symbol_type& yyla],
for (int yyx = yyxbegin; yyx < yyxend; ++yyx)
if (yycheck_[yyx + yyn] == yyx && yyx != yyterror_
&& !yy_table_value_is_error_ (yytable_[yyx + yyn]))
{
{]])[
if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
{
yycount = 1;
@@ -1177,7 +1386,7 @@ b4_error_verbose_if([state_type yystate, const symbol_type& yyla],
std::string yyres;
// Argument number.
size_t yyi = 0;
std::ptrdiff_t yyi = 0;
for (char const* yyp = yyformat; *yyp; ++yyp)
if (yyp[0] == '%' && yyp[1] == 's' && yyi < yycount)
{
@@ -1218,7 +1427,7 @@ b4_error_verbose_if([state_type yystate, const symbol_type& yyla],
i = yystack_.begin (),
i_end = yystack_.end ();
i != i_end; ++i)
*yycdebug_ << ' ' << i->state;
*yycdebug_ << ' ' << int (i->state);
*yycdebug_ << '\n';
}
@@ -1226,7 +1435,7 @@ b4_error_verbose_if([state_type yystate, const symbol_type& yyla],
void
]b4_parser_class[::yy_reduce_print_ (int yyrule)
{
unsigned yylno = yyrline_[yyrule];
int yylno = yyrline_[yyrule];
int yynrhs = yyr2_[yyrule];
// Print the symbols being reduced, and their result.
*yycdebug_ << "Reducing stack by rule " << yyrule - 1
+146 -135
View File
@@ -1,6 +1,6 @@
# Java skeleton for Bison -*- autoconf -*-
# D skeleton for Bison -*- autoconf -*-
# Copyright (C) 2007-2011, 2019 Free Software Foundation, Inc.
# Copyright (C) 2007-2012, 2019 Free Software Foundation, Inc.
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -18,12 +18,11 @@
m4_include(b4_skeletonsdir/[d.m4])
m4_divert_push(0)dnl
@output(b4_parser_file_name@)@
b4_output_begin([b4_parser_file_name])
b4_copyright([Skeleton implementation for Bison LALR(1) parsers in D],
[2007-2012, 2019])
[2007-2012, 2019])[
b4_percent_define_ifdef([package], [module b4_percent_define_get([package]);
]b4_percent_define_ifdef([package], [module b4_percent_define_get([package]);
])[
version(D_Version2) {
} else {
@@ -81,68 +80,14 @@ public interface Lexer
void yyerror (]b4_locations_if([b4_location_type[ loc, ]])[string s);
}
private final struct YYStackElement{
int state;
]b4_yystype[ value;]b4_locations_if(
b4_location_type[[] location;])[
}
private final struct YYStack {
private YYStackElement[] stack = [];
public final @@property ulong height()
{
return stack.length;
}
public final void push (int state, ]b4_yystype[ value]dnl
b4_locations_if([, ref ]b4_location_type[ loc])[)
{
stack ~= YYStackElement(state, value]b4_locations_if([, loc])[);
}
public final void pop ()
{
pop (1);
}
public final void pop (int num)
{
stack.length -= num;
}
public final int stateAt (int i)
{
return stack[$-i-1].state;
}
]b4_locations_if([[public final ref ]b4_location_type[ locationAt (int i)
{
return stack[$-i-1].location;
}
]])[public final ref ]b4_yystype[ valueAt (int i)
{
return stack[$-i-1].value;
}
// Print the state stack on the debug stream.
public final void print (File stream)
{
stream.write ("Stack now");
for (int i = 0; i < stack.length; i++)
stream.write (" %d", stack[i].state);
stream.writeln ();
}
}
]b4_locations_if(b4_position_type_if([[[
]b4_locations_if([b4_position_type_if([[
static assert(__traits(compiles,
(new ]b4_position_type[[1])[0]=(new ]b4_position_type[[1])[0]),
"struct/class ]b4_position_type[ must be default-constructible "
"and assignable");
static assert(__traits(compiles, (new string[1])[0]=(new ]b4_position_type[).toString()),
"error: struct/class ]b4_position_type[ must have toString method");
]]], [[
]], [[
/**
* A struct denoting a point in the input.*/
public struct ]b4_position_type[ {
@@ -152,15 +97,18 @@ public struct ]b4_position_type[ {
/** The line number within an input file. */
public int line = 1;
/** The name of the input file. */
public string filename = "(unspecified file)";
public string filename = null;
/**
* Return a string representation of the position. */
* A string representation of the position. */
public string toString() const {
return format("%s:%d.%d", filename, line, column);
if (filename)
return format("%s:%d.%d", filename, line, column);
else
return format("%d.%d", line, column);
}
}
]])b4_location_type_if([[[
]])b4_location_type_if([[
static assert(__traits(compiles, (new ]b4_location_type[((new ]b4_position_type[[1])[0]))) &&
__traits(compiles, (new ]b4_location_type[((new ]b4_position_type[[1])[0], (new ]b4_position_type[[1])[0]))),
"error: struct/class ]b4_location_type[ must have "
@@ -174,7 +122,7 @@ static assert(__traits(compiles, (new ]b4_location_type[[1])[0].begin=(new ]b4_l
static assert(__traits(compiles, (new string[1])[0]=(new ]b4_location_type[[1])[0].toString()),
"error: struct/class ]b4_location_type[ must have toString method.");
private immutable bool yy_location_is_class = !__traits(compiles, *(new ]b4_location_type[((new ]b4_position_type[[1])[0])));]]], [[
private immutable bool yy_location_is_class = !__traits(compiles, *(new ]b4_location_type[((new ]b4_position_type[[1])[0])));]], [[
/**
* A class defining a pair of positions. Positions, defined by the
* <code>]b4_position_type[</code> class, denote a point in the input.
@@ -196,6 +144,9 @@ public class ]b4_location_type[
this.begin = this.end = loc;
}
public this () {
}
/**
* Create a <code>]b4_location_type[</code> from the endpoints of the range.
* @@param begin The first position included in the range.
@@ -207,20 +158,25 @@ public class ]b4_location_type[
}
/**
* Return a representation of the location. For this to be correct,
* A representation of the location. For this to be correct,
* <code>]b4_position_type[</code> should override the <code>toString</code>
* method. */
public const string toString () const {
if (begin==end)
return begin.toString ();
else
return begin.toString () ~ "-" ~ end.toString ();
public override string toString () const {
auto end_col = 0 < end.column ? end.column - 1 : 0;
auto res = begin.toString ();
if (end.filename && begin.filename != end.filename)
res ~= "-" ~ format("%s:%d.%d", end.filename, end.line, end_col);
else if (begin.line < end.line)
res ~= "-" ~ format("%d.%d", end.line, end_col);
else if (begin.column < end_col)
res ~= "-" ~ format("%d", end_col);
return res;
}
}
private immutable bool yy_location_is_class = true;
]]))m4_ifdef([b4_user_union_members], [private union YYSemanticType
]])])m4_ifdef([b4_user_union_members], [private union YYSemanticType
{
b4_user_union_members
};],
@@ -261,29 +217,27 @@ b4_user_union_members
]b4_lexer_if([[
/**
* Instantiates the Bison-generated parser.
* Instantiate the Bison-generated parser.
*/
public this] (b4_parse_param_decl([b4_lex_param_decl])[) {
this.yylexer = new YYLexer(]b4_lex_param_call[);
this.yyDebugStream = stderr;
]b4_parse_param_cons[
this (new YYLexer(]b4_lex_param_call[));
}
]])[
/**
* Instantiates the Bison-generated parser.
* Instantiate the Bison-generated parser.
* @@param yylexer The scanner that will supply tokens to the parser.
*/
]b4_lexer_if([[protected]], [[public]]) [this (]b4_parse_param_decl([[Lexer yylexer]])[) {
this.yylexer = yylexer;
this.yyDebugStream = stderr;
this.yylexer = yylexer;]b4_parse_trace_if([[
this.yyDebugStream = stderr;]])[
]b4_parse_param_cons[
}
]b4_parse_trace_if([[
private File yyDebugStream;
/**
* Return the <tt>File</tt> on which the debugging output is
* The <tt>File</tt> on which the debugging output is
* printed.
*/
public File getDebugStream () { return yyDebugStream; }
@@ -309,16 +263,17 @@ b4_user_union_members
*/
public final void setDebugLevel(int level) { yydebug = level; }
protected final void yycdebug (string s) {
if (0 < yydebug)
yyDebugStream.writeln (s);
}
]])[
private final int yylex () {
return yylexer.yylex ();
}
protected final void yyerror (]b4_locations_if(ref [b4_location_type[ loc, ]])[string s) {
yylexer.yyerror (]b4_locations_if([loc, ])[s);
}]
[protected final void yycdebug (string s) {
if (yydebug > 0)
yyDebugStream.writeln (s);
}
/**
@@ -345,11 +300,11 @@ b4_user_union_members
private static immutable int YYERRLAB1 = 7;
private static immutable int YYRETURN = 8;
]b4_locations_if([
private static immutable YYSemanticType yy_semantic_null = cast(YYSemanticType)null;])[
private static immutable YYSemanticType yy_semantic_null;])[
private int yyerrstatus_ = 0;
/**
* Return whether error recovery is being done. In this state, the parser
* Whether error recovery is being done. In this state, the parser
* reads token until it reaches a known state, and then restarts normal
* operation. */
public final bool recovering ()
@@ -373,7 +328,8 @@ b4_user_union_members
else
yyval = yystack.valueAt (0);
yy_reduce_print (yyn, yystack);
]b4_parse_trace_if([[
yy_reduce_print (yyn, yystack);]])[
switch (yyn)
{
@@ -381,7 +337,8 @@ b4_user_union_members
default: break;
}
yy_symbol_print ("-> $$ =", yyr1_[yyn], yyval]b4_locations_if([, yyloc])[);
]b4_parse_trace_if([[
yy_symbol_print ("-> $$ =", yyr1_[yyn], yyval]b4_locations_if([, yyloc])[);]])[
yystack.pop (yylen);
yylen = 0;
@@ -429,12 +386,12 @@ b4_user_union_members
return yyr;
}
}
else if (yystr=="$end")
else if (yystr == "$end")
return "end of input";
return yystr;
}
]b4_parse_trace_if([[
/*--------------------------------.
| Print this symbol on YYOUTPUT. |
`--------------------------------*/
@@ -443,11 +400,11 @@ b4_user_union_members
ref ]b4_yystype[ yyvaluep]dnl
b4_locations_if([, ref ]b4_location_type[ yylocationp])[)
{
if (yydebug > 0) {
if (0 < yydebug) {
string message = s ~ (yytype < yyntokens_ ? " token " : " nterm ")
~ yytname_[yytype] ~ " ("]b4_locations_if([
~ yylocationp.toString() ~ ": "])[;
static if (__traits(compiles, message~=yyvaluep.toString ()))
static if (__traits(compiles, message ~= yyvaluep.toString ()))
message ~= yyvaluep.toString ();
else
message ~= format ("%s", &yyvaluep);
@@ -455,7 +412,7 @@ b4_locations_if([, ref ]b4_location_type[ yylocationp])[)
yycdebug (message);
}
}
]])[
/**
* Parse input from the scanner that was specified at object construction
* time. Return whether the end of the input was reached successfully.
@@ -490,9 +447,9 @@ b4_locations_if([, ref ]b4_location_type[ yylocationp])[)
/// Semantic value of the lookahead.
]b4_yystype[ yylval;
int yyresult;
int yyresult;]b4_parse_trace_if([[
yycdebug ("Starting parse\n");
yycdebug ("Starting parse\n");]])[
yyerrstatus_ = 0;
]m4_ifdef([b4_initial_action], [
@@ -512,10 +469,10 @@ m4_popdef([b4_at_dollar])])dnl
{
/* New state. Unlike in the C/C++ skeletons, the state is already
pushed when we come here. */
case YYNEWSTATE:
case YYNEWSTATE:]b4_parse_trace_if([[
yycdebug (format("Entering state %d\n", yystate));
if (yydebug > 0)
yystack.print (yyDebugStream);
if (0 < yydebug)
yystack.print (yyDebugStream);]])[
/* Accept? */
if (yystate == yyfinal_)
@@ -531,8 +488,8 @@ m4_popdef([b4_at_dollar])])dnl
/* Read a lookahead token. */
if (yychar == yyempty_)
{
yycdebug ("Reading a token: ");
{]b4_parse_trace_if([[
yycdebug ("Reading a token: ");]])[
yychar = yylex ();]b4_locations_if([[
static if (yy_location_is_class) {
yylloc = new ]b4_location_type[(yylexer.startPos, yylexer.endPos);
@@ -543,17 +500,9 @@ m4_popdef([b4_at_dollar])])dnl
}
/* Convert token to internal form. */
if (yychar <= YYTokenType.EOF)
{
yychar = yytoken = YYTokenType.EOF;
yycdebug ("Now at end of input.\n");
}
else
{
yytoken = yytranslate_ (yychar);
yy_symbol_print ("Next token is",
yytoken, yylval]b4_locations_if([, yylloc])[);
}
yytoken = yytranslate_ (yychar);]b4_parse_trace_if([[
yy_symbol_print ("Next token is",
yytoken, yylval]b4_locations_if([, yylloc])[);]])[
/* If the proper action on seeing token YYTOKEN is to reduce or to
detect an error, take that action. */
@@ -574,9 +523,9 @@ m4_popdef([b4_at_dollar])])dnl
}
else
{
/* Shift the lookahead token. */
/* Shift the lookahead token. */]b4_parse_trace_if([[
yy_symbol_print ("Shifting", yytoken,
yylval]b4_locations_if([, yylloc])[);
yylval]b4_locations_if([, yylloc])[);]])[
/* Discard the token being shifted. */
yychar = yyempty_;
@@ -685,9 +634,9 @@ m4_popdef([b4_at_dollar])])dnl
]b4_locations_if([ yyerrloc = yystack.locationAt (0);])[
yystack.pop ();
yystate = yystack.stateAt (0);
if (yydebug > 0)
yystack.print (yyDebugStream);
yystate = yystack.stateAt (0);]b4_parse_trace_if([[
if (0 < yydebug)
yystack.print (yyDebugStream);]])[
}
]b4_locations_if([
@@ -697,9 +646,9 @@ m4_popdef([b4_at_dollar])])dnl
yyloc = yylloc_from_stack (yystack, 2);
yystack.pop (2);])[
/* Shift the error token. */
/* Shift the error token. */]b4_parse_trace_if([[
yy_symbol_print ("Shifting", yystos_[yyn],
yylval]b4_locations_if([, yyloc])[);
yylval]b4_locations_if([, yyloc])[);]])[
yystate = yyn;
yystack.push (yyn, yylval]b4_locations_if([, yyloc])[);
@@ -837,6 +786,7 @@ m4_popdef([b4_at_dollar])])dnl
]b4_tname[
@};
]b4_parse_trace_if([[
/* YYRLINE[YYN] -- Source line where rule number YYN was defined. */
private static immutable ]b4_int_type_for([b4_rline])[[] yyrline_ =
@{
@@ -862,19 +812,25 @@ m4_popdef([b4_at_dollar])])dnl
]b4_rhs_value(yynrhs, yyi + 1)b4_locations_if([,
b4_rhs_location(yynrhs, yyi + 1)])[);
}
/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
private static immutable ]b4_int_type_for([b4_translate])[[] yytranslate_table_ =
@{
]b4_translate[
@};
]])[
private static ]b4_int_type_for([b4_translate])[ yytranslate_ (int t)
{
if (t >= 0 && t <= yyuser_token_number_max_)
return yytranslate_table_[t];
]b4_api_token_raw_if(
[[ import std.conv : to;
return to!byte (t);]],
[[ /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
immutable ]b4_int_type_for([b4_translate])[[] translate_table =
@{
]b4_translate[
@};
if (t <= 0)
return YYTokenType.EOF;
else if (t <= yyuser_token_number_max_)
return translate_table[t];
else
return yyundef_token_;
return yyundef_token_;]])[
}
private static immutable int yylast_ = ]b4_last[;
@@ -888,9 +844,64 @@ m4_popdef([b4_at_dollar])])dnl
private static immutable int yyuser_token_number_max_ = ]b4_user_token_number_max[;
private static immutable int yyundef_token_ = ]b4_undef_token_number[;
]/* User implementation code. */
b4_percent_code_get[]dnl
private final struct YYStackElement {
int state;
]b4_yystype[ value;]b4_locations_if(
b4_location_type[[] location;])[
}
private final struct YYStack {
private YYStackElement[] stack = [];
public final @@property ulong height()
{
return stack.length;
}
public final void push (int state, ]b4_yystype[ value]dnl
b4_locations_if([, ref ]b4_location_type[ loc])[)
{
stack ~= YYStackElement(state, value]b4_locations_if([, loc])[);
}
public final void pop ()
{
pop (1);
}
public final void pop (int num)
{
stack.length -= num;
}
public final int stateAt (int i)
{
return stack[$-i-1].state;
}
]b4_locations_if([[
public final ref ]b4_location_type[ locationAt (int i)
{
return stack[$-i-1].location;
}]])[
public final ref ]b4_yystype[ valueAt (int i)
{
return stack[$-i-1].value;
}
]b4_parse_trace_if([[
// Print the state stack on the debug stream.
public final void print (File stream)
{
stream.write ("Stack now");
for (int i = 0; i < stack.length; i++)
stream.write (" ", stack[i].state);
stream.writeln ();
}]])[
}
/* User implementation code. */
]b4_percent_code_get[
}
b4_epilogue[]dnl
m4_divert_pop(0)dnl
]b4_epilogue[]dnl
b4_output_end
+122 -133
View File
@@ -1,4 +1,4 @@
# Java skeleton for Bison -*- autoconf -*-
# Java skeleton for Bison -*- autoconf -*-
# Copyright (C) 2007-2015, 2018-2019 Free Software Foundation, Inc.
@@ -19,10 +19,6 @@ m4_include(b4_skeletonsdir/[java.m4])
b4_defines_if([b4_complain([%defines does not make sense in Java])])
# We do not depend on %debug in Java, but pacify warnings about
# non-used flags.
b4_parse_trace_if([0], [0])
m4_define([b4_symbol_no_destructor_assert],
[b4_symbol_if([$1], [has_destructor],
[b4_complain_at(m4_unquote(b4_symbol([$1], [destructor_loc])),
@@ -70,19 +66,19 @@ m4_define([b4_define_state],[[
/* Error handling. */
int yynerrs_ = 0;
]b4_locations_if([/* The location where the error started. */
b4_location_type yyerrloc = null;
]b4_locations_if([[/* The location where the error started. */
]b4_location_type[ yyerrloc = null;
/* Location. */
b4_location_type yylloc = new b4_location_type (null, null);])[
]b4_location_type[ yylloc = new ]b4_location_type[ (null, null);]])[
/* Semantic value of the lookahead. */
]b4_yystype[ yylval = null;
]])
]])[
b4_output_begin([b4_parser_file_name])[
]b4_output_begin([b4_parser_file_name])[
]b4_copyright([Skeleton implementation for Bison LALR(1) parsers in Java],
[2007-2015, 2018])[
[2007-2015, 2018-2019])[
]b4_percent_define_ifdef([package], [package b4_percent_define_get([package]);[
]])[
]b4_user_pre_prologue[
@@ -103,7 +99,7 @@ b4_output_begin([b4_parser_file_name])[
private boolean yyErrorVerbose = true;
/**
* Return whether verbose error messages are enabled.
* Whether verbose error messages are enabled.
*/
public final boolean getErrorVerbose() { return yyErrorVerbose; }
@@ -165,12 +161,12 @@ b4_locations_if([[
}
}
]])
]])[
b4_locations_if([[
]b4_locations_if([[
private ]b4_location_type[ yylloc (YYStack rhs, int n)
{
if (n > 0)
if (0 < n)
return new ]b4_location_type[ (rhs.locationAt (n-1).begin, rhs.locationAt (0).end);
else
return new ]b4_location_type[ (rhs.locationAt (0).end);
@@ -220,10 +216,11 @@ b4_locations_if([[
* error message is related]])[
* @@param msg The string for the error message.
*/
void yyerror (]b4_locations_if([b4_location_type[ loc, ]])[String msg);]
void yyerror (]b4_locations_if([b4_location_type[ loc, ]])[String msg);
}
b4_lexer_if([[private class YYLexer implements Lexer {
]b4_lexer_if([[
private class YYLexer implements Lexer {
]b4_percent_code_get([[lexer]])[
}
@@ -231,10 +228,10 @@ b4_locations_if([[
* The object doing lexical analysis for us.
*/
private Lexer yylexer;
]
b4_parse_param_vars
b4_lexer_if([[
]b4_parse_param_vars[
]b4_lexer_if([[
/**
* Instantiates the Bison-generated parser.
*/
@@ -244,24 +241,24 @@ b4_lexer_if([[
this.yylexer = new YYLexer(]b4_lex_param_call[);
]b4_parse_param_cons[
}
]])
]])[
/**
* Instantiates the Bison-generated parser.
* @@param yylexer The scanner that will supply tokens to the parser.
*/
b4_lexer_if([[protected]], [[public]]) b4_parser_class[ (]b4_parse_param_decl([[Lexer yylexer]])[) ]b4_maybe_throws([b4_init_throws])[
]b4_lexer_if([[protected]], [[public]]) b4_parser_class[ (]b4_parse_param_decl([[Lexer yylexer]])[) ]b4_maybe_throws([b4_init_throws])[
{
]b4_percent_code_get([[init]])[
this.yylexer = yylexer;
]b4_parse_param_cons[
}
]b4_parse_trace_if([[
private java.io.PrintStream yyDebugStream = System.err;
/**
* Return the <tt>PrintStream</tt> on which the debugging output is
* printed.
* The <tt>PrintStream</tt> on which the debugging output is printed.
*/
public final java.io.PrintStream getDebugStream () { return yyDebugStream; }
@@ -285,6 +282,7 @@ b4_lexer_if([[
* @@param level The verbosity level for debugging output.
*/
public final void setDebugLevel(int level) { yydebug = level; }
]])[
/**
* Print an error message via the lexer.
@@ -314,12 +312,12 @@ b4_lexer_if([[
public final void yyerror (]b4_position_type[ pos, String msg)
{
yylexer.yyerror (new ]b4_location_type[ (pos), msg);
}]])
[protected final void yycdebug (String s) {
if (yydebug > 0)
}]])[
]b4_parse_trace_if([[
protected final void yycdebug (String s) {
if (0 < yydebug)
yyDebugStream.println (s);
}
}]])[
private final class YYStack {
private int[] stateStack = new int[16];
@@ -360,7 +358,7 @@ b4_lexer_if([[
public final void pop (int num) {
// Avoid memory leaks... garbage collection is a white lie!
if (num > 0) {
if (0 < num) {
java.util.Arrays.fill (valueStack, height - num + 1, height + 1, null);
]b4_locations_if([[java.util.Arrays.fill (locStack, height - num + 1, height + 1, null);]])[
}
@@ -430,10 +428,9 @@ b4_lexer_if([[
private int yyerrstatus_ = 0;
]b4_push_if([dnl
b4_define_state])[
]b4_push_if([b4_define_state])[
/**
* Return whether error recovery is being done. In this state, the parser
* Whether error recovery is being done. In this state, the parser
* reads token until it reaches a known state, and then restarts normal
* operation.
*/
@@ -446,7 +443,7 @@ b4_define_state])[
* @@param yystate the current state
* @@param yysym the nonterminal to push on the stack
*/
private int yy_lr_goto_state_ (int yystate, int yysym)
private int yyLRGotoState (int yystate, int yysym)
{
int yyr = yypgoto_[yysym - yyntokens_] + yystate;
if (0 <= yyr && yyr <= yylast_ && yycheck_[yyr] == yystate)
@@ -457,35 +454,30 @@ b4_define_state])[
private int yyaction (int yyn, YYStack yystack, int yylen) ]b4_maybe_throws([b4_throws])[
{
]b4_yystype[ yyval;
]b4_locations_if([b4_location_type[ yyloc = yylloc (yystack, yylen);]])[
/* If YYLEN is nonzero, implement the default value of the action:
'$$ = $1'. Otherwise, use the top of the stack.
Otherwise, the following line sets YYVAL to garbage.
This behavior is undocumented and Bison
users should not rely upon it. */
if (yylen > 0)
yyval = yystack.valueAt (yylen - 1);
else
yyval = yystack.valueAt (0);
]b4_yystype[ yyval = (0 < yylen) ? yystack.valueAt (yylen - 1) : yystack.valueAt (0);
]b4_locations_if([b4_location_type[ yyloc = yylloc (yystack, yylen);]])[]b4_parse_trace_if([[
yy_reduce_print (yyn, yystack);
yyReducePrint (yyn, yystack);]])[
switch (yyn)
{
]b4_user_actions[
default: break;
}
}]b4_parse_trace_if([[
yy_symbol_print ("-> $$ =", yyr1_[yyn], yyval]b4_locations_if([, yyloc])[);
yySymbolPrint ("-> $$ =", yyr1_[yyn], yyval]b4_locations_if([, yyloc])[);]])[
yystack.pop (yylen);
yylen = 0;
/* Shift the result of the reduction. */
int yystate = yy_lr_goto_state_ (yystack.stateAt (0), yyr1_[yyn]);
int yystate = yyLRGotoState (yystack.stateAt (0), yyr1_[yyn]);
yystack.push (yystate, yyval]b4_locations_if([, yyloc])[);
return YYNEWSTATE;
}
@@ -526,21 +518,20 @@ b4_define_state])[
return yystr;
}
]])[
]b4_parse_trace_if([[
/*--------------------------------.
| Print this symbol on YYOUTPUT. |
`--------------------------------*/
private void yy_symbol_print (String s, int yytype,
]b4_yystype[ yyvaluep]dnl
b4_locations_if([, Object yylocationp])[)
private void yySymbolPrint (String s, int yytype,
]b4_yystype[ yyvaluep]dnl
b4_locations_if([, Object yylocationp])[)
{
if (yydebug > 0)
yycdebug (s + (yytype < yyntokens_ ? " token " : " nterm ")
+ yytname_[yytype] + " ("]b4_locations_if([
+ yylocationp + ": "])[
+ (yyvaluep == null ? "(null)" : yyvaluep.toString ()) + ")");
}
}]])[
]b4_push_if([],[[
/**
@@ -550,7 +541,7 @@ b4_define_state])[
* @@return <tt>true</tt> if the parsing succeeds. Note that this does not
* imply that there were no syntax errors.
*/
public boolean parse () ]b4_maybe_throws([b4_list2([b4_lex_throws], [b4_throws])])[]])[
public boolean parse () ]b4_maybe_throws([b4_list2([b4_lex_throws], [b4_throws])])[]])[
]b4_push_if([
/**
* Push Parse input from external lexer
@@ -567,8 +558,8 @@ b4_define_state])[
]b4_locations_if([/* @@$. */
b4_location_type yyloc;])[
]b4_push_if([],[[
]b4_define_state[
yycdebug ("Starting parse\n");
]b4_define_state[]b4_parse_trace_if([[
yycdebug ("Starting parse\n");]])[
yyerrstatus_ = 0;
/* Initialize the stack. */
@@ -587,8 +578,8 @@ b4_dollar_popdef[]dnl
b4_dollar_pushdef([yylval], [], [], [yylloc])dnl
b4_user_initial_action
b4_dollar_popdef[]dnl
])[
yycdebug ("Starting parse\n");
])[]b4_parse_trace_if([[
yycdebug ("Starting parse\n");]])[
yyerrstatus_ = 0;
} else
label = YYGETTOKEN;
@@ -600,10 +591,10 @@ b4_dollar_popdef[]dnl
{
/* New state. Unlike in the C/C++ skeletons, the state is already
pushed when we come here. */
case YYNEWSTATE:
case YYNEWSTATE:]b4_parse_trace_if([[
yycdebug ("Entering state " + yystate + "\n");
if (yydebug > 0)
yystack.print (yyDebugStream);
if (0 < yydebug)
yystack.print (yyDebugStream);]])[
/* Accept? */
if (yystate == yyfinal_)
@@ -612,7 +603,7 @@ b4_dollar_popdef[]dnl
/* Take a decision. First try without lookahead. */
yyn = yypact_[yystate];
if (yy_pact_value_is_default_ (yyn))
if (yyPactValueIsDefault (yyn))
{
label = YYDEFAULT;
break;
@@ -625,14 +616,13 @@ b4_dollar_popdef[]dnl
{
]b4_push_if([[
if (!push_token_consumed)
return YYPUSH_MORE;
yycdebug ("Reading a token: ");
return YYPUSH_MORE;]b4_parse_trace_if([[
yycdebug ("Reading a token: ");]])[
yychar = yylextoken;
yylval = yylexval;]b4_locations_if([
yylloc = yylexloc;])[
push_token_consumed = false;]])[
]b4_push_if([],[[
yycdebug ("Reading a token: ");
push_token_consumed = false;]], [b4_parse_trace_if([[
yycdebug ("Reading a token: ");]])[
yychar = yylexer.yylex ();
yylval = yylexer.getLVal ();]b4_locations_if([
yylloc = new b4_location_type (yylexer.getStartPos (),
@@ -641,17 +631,9 @@ b4_dollar_popdef[]dnl
}
/* Convert token to internal form. */
if (yychar <= Lexer.EOF)
{
yychar = yytoken = Lexer.EOF;
yycdebug ("Now at end of input.\n");
}
else
{
yytoken = yytranslate_ (yychar);
yy_symbol_print ("Next token is", yytoken,
yylval]b4_locations_if([, yylloc])[);
}
yytoken = yytranslate_ (yychar);]b4_parse_trace_if([[
yySymbolPrint ("Next token is", yytoken,
yylval]b4_locations_if([, yylloc])[);]])[
/* If the proper action on seeing token YYTOKEN is to reduce or to
detect an error, take that action. */
@@ -662,7 +644,7 @@ b4_dollar_popdef[]dnl
/* <= 0 means reduce or error. */
else if ((yyn = yytable_[yyn]) <= 0)
{
if (yy_table_value_is_error_ (yyn))
if (yyTableValueIsError (yyn))
label = YYERRLAB;
else
{
@@ -673,10 +655,10 @@ b4_dollar_popdef[]dnl
else
{
/* Shift the lookahead token. */
yy_symbol_print ("Shifting", yytoken,
yylval]b4_locations_if([, yylloc])[);
/* Shift the lookahead token. */]b4_parse_trace_if([[
yySymbolPrint ("Shifting", yytoken,
yylval]b4_locations_if([, yylloc])[);
]])[
/* Discard the token being shifted. */
yychar = yyempty_;
@@ -727,17 +709,17 @@ b4_dollar_popdef[]dnl
]b4_locations_if([yyerrloc = yylloc;])[
if (yyerrstatus_ == 3)
{
/* If just tried and failed to reuse lookahead token after an
error, discard it. */
/* If just tried and failed to reuse lookahead token after an
error, discard it. */
if (yychar <= Lexer.EOF)
{
/* Return failure if at end of input. */
if (yychar == Lexer.EOF)
]b4_push_if([{label = YYABORT; break;}],[return false;])[
}
else
yychar = yyempty_;
if (yychar <= Lexer.EOF)
{
/* Return failure if at end of input. */
if (yychar == Lexer.EOF)
]b4_push_if([{label = YYABORT; break;}], [return false;])[
}
else
yychar = yyempty_;
}
/* Else will try to reuse lookahead token after shifting the error
@@ -749,7 +731,6 @@ b4_dollar_popdef[]dnl
| errorlab -- error raised explicitly by YYERROR. |
`-------------------------------------------------*/
case YYERROR:
]b4_locations_if([yyerrloc = yystack.locationAt (yylen - 1);])[
/* Do not reclaim the symbols of the rule which action triggered
this YYERROR. */
@@ -768,7 +749,7 @@ b4_dollar_popdef[]dnl
for (;;)
{
yyn = yypact_[yystate];
if (!yy_pact_value_is_default_ (yyn))
if (!yyPactValueIsDefault (yyn))
{
yyn += yyterror_;
if (0 <= yyn && yyn <= yylast_ && yycheck_[yyn] == yyterror_)
@@ -786,9 +767,9 @@ b4_dollar_popdef[]dnl
]b4_locations_if([yyerrloc = yystack.locationAt (0);])[
yystack.pop ();
yystate = yystack.stateAt (0);
if (yydebug > 0)
yystack.print (yyDebugStream);
yystate = yystack.stateAt (0);]b4_parse_trace_if([[
if (0 < yydebug)
yystack.print (yyDebugStream);]])[
}
if (label == YYABORT)
@@ -802,9 +783,9 @@ b4_dollar_popdef[]dnl
yyloc = yylloc (yystack, 2);
yystack.pop (2);])[
/* Shift the error token. */
yy_symbol_print ("Shifting", yystos_[yyn],
yylval]b4_locations_if([, yyloc])[);
/* Shift the error token. */]b4_parse_trace_if([[
yySymbolPrint ("Shifting", yystos_[yyn],
yylval]b4_locations_if([, yyloc])[);]])[
yystate = yyn;
yystack.push (yyn, yylval]b4_locations_if([, yyloc])[);
@@ -870,9 +851,9 @@ b4_dollar_popdef[]dnl
{
return push_parse (yylextoken, yylexval, new b4_location_type (yylexpos));
}
])[]])
])[]])[
b4_both_if([[
]b4_both_if([[
/**
* Parse input from the scanner that was specified at object construction
* time. Return whether the end of the input was reached successfully.
@@ -881,21 +862,21 @@ b4_both_if([[
* @@return <tt>true</tt> if the parsing succeeds. Note that this does not
* imply that there were no syntax errors.
*/
public boolean parse () ]b4_maybe_throws([b4_list2([b4_lex_throws], [b4_throws])])[
{
if (yylexer == null)
throw new NullPointerException("Null Lexer");
int status;
do {
int token = yylexer.yylex();
]b4_yystype[ lval = yylexer.getLVal();
public boolean parse () ]b4_maybe_throws([b4_list2([b4_lex_throws], [b4_throws])])[
{
if (yylexer == null)
throw new NullPointerException("Null Lexer");
int status;
do {
int token = yylexer.yylex();
]b4_yystype[ lval = yylexer.getLVal();
]b4_locations_if([dnl
b4_location_type yyloc = new b4_location_type (yylexer.getStartPos (),
yylexer.getEndPos ());])[
]b4_locations_if([status = push_parse(token,lval,yyloc);],[
status = push_parse(token,lval);])[
} while (status == YYPUSH_MORE);
return (status == YYACCEPT);
b4_location_type yyloc = new b4_location_type (yylexer.getStartPos (),
yylexer.getEndPos ());])[
]b4_locations_if([status = push_parse(token,lval,yyloc);],[
status = push_parse(token,lval);])[
} while (status == YYPUSH_MORE);
return (status == YYACCEPT);
}
]])[
@@ -938,7 +919,7 @@ b4_both_if([[
new StringBuffer ("syntax error, unexpected ");
res.append (yytnamerr_ (yytname_[tok]));
int yyn = yypact_[yystate];
if (!yy_pact_value_is_default_ (yyn))
if (!yyPactValueIsDefault (yyn))
{
/* Start YYX at -YYN if negative to avoid negative
indexes in YYCHECK. In other words, skip the first
@@ -951,14 +932,14 @@ b4_both_if([[
int count = 0;
for (int x = yyxbegin; x < yyxend; ++x)
if (yycheck_[x + yyn] == x && x != yyterror_
&& !yy_table_value_is_error_ (yytable_[x + yyn]))
&& !yyTableValueIsError (yytable_[x + yyn]))
++count;
if (count < 5)
{
count = 0;
for (int x = yyxbegin; x < yyxend; ++x)
if (yycheck_[x + yyn] == x && x != yyterror_
&& !yy_table_value_is_error_ (yytable_[x + yyn]))
&& !yyTableValueIsError (yytable_[x + yyn]))
{
res.append (count++ == 0 ? ", expecting " : " or ");
res.append (yytnamerr_ (yytname_[x]));
@@ -976,7 +957,7 @@ b4_both_if([[
* Whether the given <code>yypact_</code> value indicates a defaulted state.
* @@param yyvalue the value to check
*/
private static boolean yy_pact_value_is_default_ (int yyvalue)
private static boolean yyPactValueIsDefault (int yyvalue)
{
return yyvalue == yypact_ninf_;
}
@@ -986,7 +967,7 @@ b4_both_if([[
* value indicates a syntax error.
* @@param yyvalue the value to check
*/
private static boolean yy_table_value_is_error_ (int yyvalue)
private static boolean yyTableValueIsError (int yyvalue)
{
return yyvalue == yytable_ninf_;
}
@@ -1003,12 +984,13 @@ b4_both_if([[
First, the terminals, then, starting at \a yyntokens_, nonterminals. */
]b4_typed_parser_table_define([String], [tname], [b4_tname])[
]b4_parse_trace_if([[
]b4_integral_parser_table_define([rline], [b4_rline],
[[YYRLINE[YYN] -- Source line where rule number YYN was defined.]])[
// Report on the debug stream that the rule yyrule is going to be reduced.
private void yy_reduce_print (int yyrule, YYStack yystack)
private void yyReducePrint (int yyrule, YYStack yystack)
{
if (yydebug == 0)
return;
@@ -1021,23 +1003,30 @@ b4_both_if([[
/* The symbols being reduced. */
for (int yyi = 0; yyi < yynrhs; yyi++)
yy_symbol_print (" $" + (yyi + 1) + " =",
yystos_[yystack.stateAt(yynrhs - (yyi + 1))],
]b4_rhs_data(yynrhs, yyi + 1)b4_locations_if([,
b4_rhs_location(yynrhs, yyi + 1)])[);
}
yySymbolPrint (" $" + (yyi + 1) + " =",
yystos_[yystack.stateAt(yynrhs - (yyi + 1))],
]b4_rhs_data(yynrhs, yyi + 1)b4_locations_if([,
b4_rhs_location(yynrhs, yyi + 1)])[);
}]])[
/* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM
/* YYTRANSLATE_(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM
as returned by yylex, with out-of-bounds checking. */
]b4_integral_parser_table_define([translate_table], [b4_translate])[
private static final ]b4_int_type_for([b4_translate])[ yytranslate_ (int t)
{
if (t >= 0 && t <= yyuser_token_number_max_)
]b4_api_token_raw_if(dnl
[[ {
return t;
}
]],
[[ {
if (t <= 0)
return Lexer.EOF;
else if (t <= yyuser_token_number_max_)
return yytranslate_table_[t];
else
return yyundef_token_;
}
]b4_integral_parser_table_define([translate_table], [b4_translate])[
]])[
private static final int yylast_ = ]b4_last[;
private static final int yynnts_ = ]b4_nterms_number[;
@@ -1050,8 +1039,8 @@ b4_both_if([[
private static final int yyuser_token_number_max_ = ]b4_user_token_number_max[;
private static final int yyundef_token_ = ]b4_undef_token_number[;
]/* User implementation code. */
b4_percent_code_get[]dnl
/* User implementation code. */
]b4_percent_code_get[]dnl
}
+15 -17
View File
@@ -65,8 +65,8 @@ m4_define([b4_location_define],
public:]m4_ifdef([b4_location_constructors], [[
/// Construct a position.
explicit position (]b4_percent_define_get([[filename_type]])[* f = YY_NULLPTR,
unsigned l = ]b4_location_initial_line[u,
unsigned c = ]b4_location_initial_column[u)
int l = ]b4_location_initial_line[,
int c = ]b4_location_initial_column[)
: filename (f)
, line (l)
, column (c)
@@ -75,8 +75,8 @@ m4_define([b4_location_define],
]])[
/// Initialization.
void initialize (]b4_percent_define_get([[filename_type]])[* fn = YY_NULLPTR,
unsigned l = ]b4_location_initial_line[u,
unsigned c = ]b4_location_initial_column[u)
int l = ]b4_location_initial_line[,
int c = ]b4_location_initial_column[)
{
filename = fn;
line = l;
@@ -90,7 +90,7 @@ m4_define([b4_location_define],
{
if (count)
{
column = ]b4_location_initial_column[u;
column = ]b4_location_initial_column[;
line = add_ (line, count, ]b4_location_initial_line[);
}
}
@@ -105,16 +105,15 @@ m4_define([b4_location_define],
/// File name to which this position refers.
]b4_percent_define_get([[filename_type]])[* filename;
/// Current line number.
unsigned line;
int line;
/// Current column number.
unsigned column;
int column;
private:
/// Compute max (min, lhs+rhs).
static unsigned add_ (unsigned lhs, int rhs, int min)
static int add_ (int lhs, int rhs, int min)
{
return static_cast<unsigned> (std::max (min,
static_cast<int> (lhs) + rhs));
return lhs + rhs < min ? min : lhs + rhs;
}
};
@@ -197,8 +196,8 @@ m4_define([b4_location_define],
/// Construct a 0-width location in \a f, \a l, \a c.
explicit location (]b4_percent_define_get([[filename_type]])[* f,
unsigned l = ]b4_location_initial_line[u,
unsigned c = ]b4_location_initial_column[u)
int l = ]b4_location_initial_line[,
int c = ]b4_location_initial_column[)
: begin (f, l, c)
, end (f, l, c)
{}
@@ -206,8 +205,8 @@ m4_define([b4_location_define],
])[
/// Initialization.
void initialize (]b4_percent_define_get([[filename_type]])[* f = YY_NULLPTR,
unsigned l = ]b4_location_initial_line[u,
unsigned c = ]b4_location_initial_column[u)
int l = ]b4_location_initial_line[,
int c = ]b4_location_initial_column[)
{
begin.initialize (f, l, c);
end = begin;
@@ -305,7 +304,7 @@ m4_define([b4_location_define],
std::basic_ostream<YYChar>&
operator<< (std::basic_ostream<YYChar>& ostr, const location& loc)
{
unsigned end_col = 0 < loc.end.column ? loc.end.column - 1 : 0;
int end_col = 0 < loc.end.column ? loc.end.column - 1 : 0;
ostr << loc.begin;
if (loc.end.filename
&& (!loc.begin.filename
@@ -327,7 +326,7 @@ m4_ifdef([b4_position_file], [[
// used to define is now defined in "]b4_location_file[".
//
// To get rid of this file:
// 1. add 'require "3.2"' (or newer) to your grammar file
// 1. add '%require "3.2"' (or newer) to your grammar file
// 2. remove references to this file from your build system
// 3. if you used to include it, include "]b4_location_file[" instead.
@@ -346,7 +345,6 @@ m4_ifdef([b4_location_file], [[
]b4_cpp_guard_open([b4_location_path])[
# include <algorithm> // std::max
# include <iostream>
# include <string>
+18 -30
View File
@@ -35,6 +35,7 @@ m4_define([b4_stack_define],
typedef typename S::reverse_iterator iterator;
typedef typename S::const_reverse_iterator const_iterator;
typedef typename S::size_type size_type;
typedef typename std::ptrdiff_t index_type;
stack (size_type n = 200)
: seq_ (n)
@@ -43,37 +44,19 @@ m4_define([b4_stack_define],
/// Random access.
///
/// Index 0 returns the topmost element.
T&
operator[] (size_type i)
const T&
operator[] (index_type i) const
{
return seq_[size () - 1 - i];
return seq_[size_type (size () - 1 - i)];
}
/// Random access.
///
/// Index 0 returns the topmost element.
T&
operator[] (int i)
operator[] (index_type i)
{
return operator[] (size_type (i));
}
/// Random access.
///
/// Index 0 returns the topmost element.
const T&
operator[] (size_type i) const
{
return seq_[size () - 1 - i];
}
/// Random access.
///
/// Index 0 returns the topmost element.
const T&
operator[] (int i) const
{
return operator[] (size_type (i));
return seq_[size_type (size () - 1 - i)];
}
/// Steal the contents of \a t.
@@ -88,7 +71,7 @@ m4_define([b4_stack_define],
/// Pop elements from the stack.
void
pop (int n = 1) YY_NOEXCEPT
pop (std::ptrdiff_t n = 1) YY_NOEXCEPT
{
for (; 0 < n; --n)
seq_.pop_back ();
@@ -102,10 +85,15 @@ m4_define([b4_stack_define],
}
/// Number of elements on the stack.
size_type
index_type
size () const YY_NOEXCEPT
{
return seq_.size ();
return index_type (seq_.size ());
}
std::ptrdiff_t
ssize () const YY_NOEXCEPT
{
return (std::ptrdiff_t) size ();
}
/// Iterator on top of the stack (going downwards).
@@ -126,20 +114,20 @@ m4_define([b4_stack_define],
class slice
{
public:
slice (const stack& stack, int range)
slice (const stack& stack, index_type range)
: stack_ (stack)
, range_ (range)
{}
const T&
operator[] (int i) const
operator[] (index_type i) const
{
return stack_[range_ - i];
}
private:
const stack& stack_;
int range_;
index_type range_;
};
private:
@@ -157,7 +145,7 @@ m4_ifdef([b4_stack_file],
// used to define is now defined with the parser itself.
//
// To get rid of this file:
// 1. add 'require "3.2"' (or newer) to your grammar file
// 1. add '%require "3.2"' (or newer) to your grammar file
// 2. remove references to this file from your build system.
]b4_output_end[
]])
+182 -190
View File
@@ -1,4 +1,4 @@
-*- C -*-
# -*- C -*-
# Yacc compatible skeleton for Bison
# Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2019 Free Software
@@ -20,51 +20,11 @@ m4_pushdef([b4_copyright_years],
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# Check the value of %define api.push-pull.
b4_percent_define_default([[api.push-pull]], [[pull]])
b4_percent_define_check_values([[[[api.push-pull]],
[[pull]], [[push]], [[both]]]])
b4_define_flag_if([pull]) m4_define([b4_pull_flag], [[1]])
b4_define_flag_if([push]) m4_define([b4_push_flag], [[1]])
m4_case(b4_percent_define_get([[api.push-pull]]),
[pull], [m4_define([b4_push_flag], [[0]])],
[push], [m4_define([b4_pull_flag], [[0]])])
# Handle BISON_USE_PUSH_FOR_PULL for the test suite. So that push parsing
# tests function as written, do not let BISON_USE_PUSH_FOR_PULL modify the
# behavior of Bison at all when push parsing is already requested.
b4_define_flag_if([use_push_for_pull])
b4_use_push_for_pull_if([
b4_push_if([m4_define([b4_use_push_for_pull_flag], [[0]])],
[m4_define([b4_push_flag], [[1]])])])
# Check the value of %define parse.lac and friends, where LAC stands for
# lookahead correction.
b4_percent_define_default([[parse.lac]], [[none]])
b4_percent_define_default([[parse.lac.es-capacity-initial]], [[20]])
b4_percent_define_default([[parse.lac.memory-trace]], [[failures]])
b4_percent_define_check_values([[[[parse.lac]], [[full]], [[none]]]],
[[[[parse.lac.memory-trace]],
[[failures]], [[full]]]])
b4_define_flag_if([lac])
m4_define([b4_lac_flag],
[m4_if(b4_percent_define_get([[parse.lac]]),
[none], [[0]], [[1]])])
m4_include(b4_skeletonsdir/[c.m4])
## ---------------- ##
## Default values. ##
## ---------------- ##
# Stack parameters.
m4_define_default([b4_stack_depth_max], [10000])
m4_define_default([b4_stack_depth_init], [200])
## ------------------------ ##
## Pure/impure interfaces. ##
## ------------------------ ##
## ---------- ##
## api.pure. ##
## ---------- ##
b4_percent_define_default([[api.pure]], [[false]])
b4_percent_define_check_values([[[[api.pure]],
@@ -84,6 +44,51 @@ m4_define([b4_pure_if],
[2], [$1])])
[m4_fatal([invalid api.pure value: ]$1)])])
## --------------- ##
## api.push-pull. ##
## --------------- ##
b4_percent_define_default([[api.push-pull]], [[pull]])
b4_percent_define_check_values([[[[api.push-pull]],
[[pull]], [[push]], [[both]]]])
b4_define_flag_if([pull]) m4_define([b4_pull_flag], [[1]])
b4_define_flag_if([push]) m4_define([b4_push_flag], [[1]])
m4_case(b4_percent_define_get([[api.push-pull]]),
[pull], [m4_define([b4_push_flag], [[0]])],
[push], [m4_define([b4_pull_flag], [[0]])])
# Handle BISON_USE_PUSH_FOR_PULL for the test suite. So that push parsing
# tests function as written, do not let BISON_USE_PUSH_FOR_PULL modify the
# behavior of Bison at all when push parsing is already requested.
b4_define_flag_if([use_push_for_pull])
b4_use_push_for_pull_if([
b4_push_if([m4_define([b4_use_push_for_pull_flag], [[0]])],
[m4_define([b4_push_flag], [[1]])])])
## ----------- ##
## parse.lac. ##
## ----------- ##
b4_percent_define_default([[parse.lac]], [[none]])
b4_percent_define_default([[parse.lac.es-capacity-initial]], [[20]])
b4_percent_define_default([[parse.lac.memory-trace]], [[failures]])
b4_percent_define_check_values([[[[parse.lac]], [[full]], [[none]]]],
[[[[parse.lac.memory-trace]],
[[failures]], [[full]]]])
b4_define_flag_if([lac])
m4_define([b4_lac_flag],
[m4_if(b4_percent_define_get([[parse.lac]]),
[none], [[0]], [[1]])])
## ---------------- ##
## Default values. ##
## ---------------- ##
# Stack parameters.
m4_define_default([b4_stack_depth_max], [10000])
m4_define_default([b4_stack_depth_init], [200])
# b4_yyerror_arg_loc_if(ARG)
# --------------------------
# Expand ARG iff yyerror is to be given a location as argument.
@@ -101,28 +106,6 @@ m4_ifset([b4_parse_param], [b4_args(b4_parse_param), ])])
## ------------ ##
## Data Types. ##
## ------------ ##
# b4_int_type(MIN, MAX)
# ---------------------
# Return the smallest int type able to handle numbers ranging from
# MIN to MAX (included). Overwrite the version from c.m4, which
# uses only C89 types, so that the user can override the shorter
# types, and so that pre-C89 compilers are handled correctly.
m4_define([b4_int_type],
[m4_if(b4_ints_in($@, [0], [255]), [1], [yytype_uint8],
b4_ints_in($@, [-128], [127]), [1], [yytype_int8],
b4_ints_in($@, [0], [65535]), [1], [yytype_uint16],
b4_ints_in($@, [-32768], [32767]), [1], [yytype_int16],
m4_eval([0 <= $1]), [1], [unsigned],
[int])])
## ----------------- ##
## Semantic Values. ##
## ----------------- ##
@@ -199,7 +182,7 @@ m4_define([b4_declare_parser_state_variables], [b4_pure_if([[
/* Number of syntax errors so far. */
int yynerrs;
]])[
int yystate;
yy_state_fast_t yystate;
/* Number of tokens to shift before error messages enabled. */
int yyerrstatus;
@@ -212,9 +195,9 @@ m4_define([b4_declare_parser_state_variables], [b4_pure_if([[
to reallocate them elsewhere. */
/* The state stack. */
yytype_int16 yyssa[YYINITDEPTH];
yytype_int16 *yyss;
yytype_int16 *yyssp;
yy_state_t yyssa[YYINITDEPTH];
yy_state_t *yyss;
yy_state_t *yyssp;
/* The semantic value stack. */
YYSTYPE yyvsa[YYINITDEPTH];
@@ -229,11 +212,11 @@ m4_define([b4_declare_parser_state_variables], [b4_pure_if([[
/* The locations where the error started and ended. */
YYLTYPE yyerror_range[3];]])[
YYSIZE_T yystacksize;]b4_lac_if([[
YYPTRDIFF_T yystacksize;]b4_lac_if([[
yytype_int16 yyesa@{]b4_percent_define_get([[parse.lac.es-capacity-initial]])[@};
yytype_int16 *yyes;
YYSIZE_T yyes_capacity;]])])
yy_state_t yyesa@{]b4_percent_define_get([[parse.lac.es-capacity-initial]])[@};
yy_state_t *yyes;
YYPTRDIFF_T yyes_capacity;]])])
# _b4_declare_yyparse_push
@@ -386,28 +369,22 @@ m4_if(b4_api_prefix, [yy], [],
# undef short
#endif
#ifdef YYTYPE_UINT8
typedef YYTYPE_UINT8 yytype_uint8;
#else
typedef unsigned char yytype_uint8;
#endif
]b4_c99_int_type_define[
#ifdef YYTYPE_INT8
typedef YYTYPE_INT8 yytype_int8;
#else
typedef signed char yytype_int8;
#endif
#ifdef YYTYPE_UINT16
typedef YYTYPE_UINT16 yytype_uint16;
#else
typedef unsigned short yytype_uint16;
#endif
#ifdef YYTYPE_INT16
typedef YYTYPE_INT16 yytype_int16;
#else
typedef short yytype_int16;
#ifndef YYPTRDIFF_T
# if defined __PTRDIFF_TYPE__ && defined __PTRDIFF_MAX__
# define YYPTRDIFF_T __PTRDIFF_TYPE__
# define YYPTRDIFF_MAXIMUM __PTRDIFF_MAX__
# elif defined PTRDIFF_MAX
# ifndef ptrdiff_t
# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
# endif
# define YYPTRDIFF_T ptrdiff_t
# define YYPTRDIFF_MAXIMUM PTRDIFF_MAX
# else
# define YYPTRDIFF_T long
# define YYPTRDIFF_MAXIMUM LONG_MAX
# endif
#endif
#ifndef YYSIZE_T
@@ -415,7 +392,7 @@ typedef short yytype_int16;
# define YYSIZE_T __SIZE_TYPE__
# elif defined size_t
# define YYSIZE_T size_t
# elif ! defined YYSIZE_T
# elif defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__
# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
# define YYSIZE_T size_t
# else
@@ -423,7 +400,16 @@ typedef short yytype_int16;
# endif
#endif
#define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
#define YYSIZE_MAXIMUM ((YYPTRDIFF_T) (YYPTRDIFF_MAXIMUM < (YYSIZE_T) -1 \
? YYPTRDIFF_MAXIMUM : (YYSIZE_T) -1))
#define YYSIZEOF(X) ((YYPTRDIFF_T) sizeof (X))
/* Stored state numbers (used for stacks). */
typedef ]b4_int_type(0, m4_eval(b4_states_number - 1))[ yy_state_t;
/* State numbers in computations. */
typedef int yy_state_fast_t;
#ifndef YY_
# if defined YYENABLE_NLS && YYENABLE_NLS
@@ -526,22 +512,23 @@ void free (void *); /* INFRINGES ON USER NAME SPACE */
/* A type that is properly aligned for any stack member. */
union yyalloc
{
yytype_int16 yyss_alloc;
yy_state_t yyss_alloc;
YYSTYPE yyvs_alloc;]b4_locations_if([
YYLTYPE yyls_alloc;])[
};
/* The size of the maximum gap between one aligned stack and the next. */
# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
# define YYSTACK_GAP_MAXIMUM (YYSIZEOF (union yyalloc) - 1)
/* The size of an array large to enough to hold all stacks, each with
N elements. */
]b4_locations_if(
[# define YYSTACK_BYTES(N) \
((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE) + sizeof (YYLTYPE)) \
((N) * (YYSIZEOF (yy_state_t) + YYSIZEOF (YYSTYPE) \
+ YYSIZEOF (YYLTYPE)) \
+ 2 * YYSTACK_GAP_MAXIMUM)],
[# define YYSTACK_BYTES(N) \
((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \
((N) * (YYSIZEOF (yy_state_t) + YYSIZEOF (YYSTYPE)) \
+ YYSTACK_GAP_MAXIMUM)])[
# define YYCOPY_NEEDED 1
@@ -554,11 +541,11 @@ union yyalloc
# define YYSTACK_RELOCATE(Stack_alloc, Stack) \
do \
{ \
YYSIZE_T yynewbytes; \
YYPTRDIFF_T yynewbytes; \
YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \
Stack = &yyptr->Stack_alloc; \
yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
yyptr += yynewbytes / sizeof (*yyptr); \
yynewbytes = yystacksize * YYSIZEOF (*Stack) + YYSTACK_GAP_MAXIMUM; \
yyptr += yynewbytes / YYSIZEOF (*yyptr); \
} \
while (0)
@@ -570,12 +557,12 @@ union yyalloc
# ifndef YYCOPY
# if defined __GNUC__ && 1 < __GNUC__
# define YYCOPY(Dst, Src, Count) \
__builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src)))
__builtin_memcpy (Dst, Src, (YYSIZE_T) (Count) * sizeof (*(Src)))
# else
# define YYCOPY(Dst, Src, Count) \
do \
{ \
YYSIZE_T yyi; \
YYPTRDIFF_T yyi; \
for (yyi = 0; yyi < (Count); yyi++) \
(Dst)[yyi] = (Src)[yyi]; \
} \
@@ -601,17 +588,20 @@ union yyalloc
#define YYUNDEFTOK ]b4_undef_token_number[
#define YYMAXUTOK ]b4_user_token_number_max[
/* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM
as returned by yylex, with out-of-bounds checking. */
#define YYTRANSLATE(YYX) \
((unsigned) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
]b4_api_token_raw_if(dnl
[[#define YYTRANSLATE(YYX) (YYX)]],
[[#define YYTRANSLATE(YYX) \
(0 <= (YYX) && (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM
as returned by yylex. */
static const ]b4_int_type_for([b4_translate])[ yytranslate[] =
{
]b4_translate[
};
};]])[
#if ]b4_api_PREFIX[DEBUG
]b4_integral_parser_table_define([rline], [b4_rline],
@@ -636,15 +626,15 @@ static const ]b4_int_type_for([b4_toknum])[ yytoknum[] =
};
# endif
#define YYPACT_NINF ]b4_pact_ninf[
#define YYPACT_NINF (]b4_pact_ninf[)
#define yypact_value_is_default(Yystate) \
]b4_table_value_equals([[pact]], [[Yystate]], [b4_pact_ninf])[
#define yypact_value_is_default(Yyn) \
]b4_table_value_equals([[pact]], [[Yyn]], [b4_pact_ninf], [YYPACT_NINF])[
#define YYTABLE_NINF ]b4_table_ninf[
#define YYTABLE_NINF (]b4_table_ninf[)
#define yytable_value_is_error(Yytable_value) \
]b4_table_value_equals([[table]], [[Yytable_value]], [b4_table_ninf])[
#define yytable_value_is_error(Yyn) \
]b4_table_value_equals([[table]], [[Yyn]], [b4_table_ninf], [YYTABLE_NINF])[
]b4_parser_tables_define[
@@ -722,8 +712,8 @@ do { \
`------------------------------------------------------------------*/
]b4_function_define([yy_stack_print], [static void],
[[yytype_int16 *yybottom], [yybottom]],
[[yytype_int16 *yytop], [yytop]])[
[[yy_state_t *yybottom], [yybottom]],
[[yy_state_t *yytop], [yytop]])[
{
YYFPRINTF (stderr, "Stack now");
for (; yybottom <= yytop; yybottom++)
@@ -746,16 +736,16 @@ do { \
`------------------------------------------------*/
]b4_function_define([yy_reduce_print], [static void],
[[yytype_int16 *yyssp], [yyssp]],
[[yy_state_t *yyssp], [yyssp]],
[[YYSTYPE *yyvsp], [yyvsp]],
b4_locations_if([[[YYLTYPE *yylsp], [yylsp]],
])[[int yyrule], [yyrule]]m4_ifset([b4_parse_param], [,
b4_parse_param]))[
{
unsigned long yylno = yyrline[yyrule];
int yylno = yyrline[yyrule];
int yynrhs = yyr2[yyrule];
int yyi;
YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
YYFPRINTF (stderr, "Reducing stack by rule %d (line %d):\n",
yyrule - 1, yylno);
/* The symbols being reduced. */
for (yyi = 0; yyi < yynrhs; yyi++)
@@ -814,22 +804,22 @@ int yydebug;
using YYSTACK_FREE. Return 0 if successful or if no reallocation is
required. Return 1 if memory is exhausted. */
static int
yy_lac_stack_realloc (YYSIZE_T *yycapacity, YYSIZE_T yyadd,
yy_lac_stack_realloc (YYPTRDIFF_T *yycapacity, YYPTRDIFF_T yyadd,
#if ]b4_api_PREFIX[DEBUG
char const *yydebug_prefix,
char const *yydebug_suffix,
#endif
yytype_int16 **yybottom,
yytype_int16 *yybottom_no_free,
yytype_int16 **yytop, yytype_int16 *yytop_empty)
yy_state_t **yybottom,
yy_state_t *yybottom_no_free,
yy_state_t **yytop, yy_state_t *yytop_empty)
{
YYSIZE_T yysize_old =
(YYSIZE_T) (*yytop == yytop_empty ? 0 : *yytop - *yybottom + 1);
YYSIZE_T yysize_new = yysize_old + yyadd;
YYPTRDIFF_T yysize_old =
*yytop == yytop_empty ? 0 : *yytop - *yybottom + 1;
YYPTRDIFF_T yysize_new = yysize_old + yyadd;
if (*yycapacity < yysize_new)
{
YYSIZE_T yyalloc = 2 * yysize_new;
yytype_int16 *yybottom_new;
YYPTRDIFF_T yyalloc = 2 * yysize_new;
yy_state_t *yybottom_new;
/* Use YYMAXDEPTH for maximum stack size given that the stack
should never need to grow larger than the main state stack
needs to grow without LAC. */
@@ -842,7 +832,8 @@ yy_lac_stack_realloc (YYSIZE_T *yycapacity, YYSIZE_T yyadd,
if (YYMAXDEPTH < yyalloc)
yyalloc = YYMAXDEPTH;
yybottom_new =
(yytype_int16*) YYSTACK_ALLOC (yyalloc * sizeof *yybottom_new);
(yy_state_t *) YYSTACK_ALLOC ((YYSIZE_T)
(yyalloc * YYSIZEOF (*yybottom_new)));
if (!yybottom_new)
{
YYDPRINTF ((stderr, "%srealloc failed%s", yydebug_prefix,
@@ -859,8 +850,8 @@ yy_lac_stack_realloc (YYSIZE_T *yycapacity, YYSIZE_T yyadd,
*yybottom = yybottom_new;
*yycapacity = yyalloc;]m4_if(b4_percent_define_get([[parse.lac.memory-trace]]),
[full], [[
YYDPRINTF ((stderr, "%srealloc to %lu%s", yydebug_prefix,
(unsigned long) yyalloc, yydebug_suffix));]])[
YYDPRINTF ((stderr, "%srealloc to %ld%s", yydebug_prefix,
(long) yyalloc, yydebug_suffix));]])[
}
return 0;
}
@@ -945,11 +936,11 @@ do { \
contents of either array, alter *YYES and *YYES_CAPACITY, and free
any old *YYES other than YYESA. */
static int
yy_lac (yytype_int16 *yyesa, yytype_int16 **yyes,
YYSIZE_T *yyes_capacity, yytype_int16 *yyssp, int yytoken)
yy_lac (yy_state_t *yyesa, yy_state_t **yyes,
YYPTRDIFF_T *yyes_capacity, yy_state_t *yyssp, int yytoken)
{
yytype_int16 *yyes_prev = yyssp;
yytype_int16 *yyesp = yyes_prev;
yy_state_t *yyes_prev = yyssp;
yy_state_t *yyesp = yyes_prev;
YYDPRINTF ((stderr, "LAC: checking lookahead %s:", yytname[yytoken]));
if (yytoken == YYUNDEFTOK)
{
@@ -986,11 +977,11 @@ yy_lac (yytype_int16 *yyesa, yytype_int16 **yyes,
yyrule = -yyrule;
}
{
YYSIZE_T yylen = yyr2[yyrule];
YYPTRDIFF_T yylen = yyr2[yyrule];
YYDPRINTF ((stderr, " R%d", yyrule - 1));
if (yyesp != yyes_prev)
{
YYSIZE_T yysize = (YYSIZE_T) (yyesp - *yyes + 1);
YYPTRDIFF_T yysize = yyesp - *yyes + 1;
if (yylen < yysize)
{
yyesp -= yylen;
@@ -1006,19 +997,18 @@ yy_lac (yytype_int16 *yyesa, yytype_int16 **yyes,
yyesp = yyes_prev -= yylen;
}
{
yytype_int16 yystate;
yy_state_fast_t yystate;
{
const int yylhs = yyr1[yyrule] - YYNTOKENS;
const int yyi = yypgoto[yylhs] + *yyesp;
yystate = ((yytype_int16)
(0 <= yyi && yyi <= YYLAST && yycheck[yyi] == *yyesp
? yytable[yyi]
: yydefgoto[yylhs]));
yystate = (0 <= yyi && yyi <= YYLAST && yycheck[yyi] == *yyesp
? yytable[yyi]
: yydefgoto[yylhs]);
}
if (yyesp == yyes_prev)
{
yyesp = *yyes;
*yyesp = yystate;
*yyesp = (yy_state_t) yystate;
}
else
{
@@ -1031,9 +1021,9 @@ yy_lac (yytype_int16 *yyesa, yytype_int16 **yyes,
YYDPRINTF ((stderr, "\n"));
return 2;
}
*++yyesp = yystate;
*++yyesp = (yy_state_t) yystate;
}
YYDPRINTF ((stderr, " G%d", (int) yystate));
YYDPRINTF ((stderr, " G%d", yystate));
}
}
}]])[
@@ -1043,13 +1033,13 @@ yy_lac (yytype_int16 *yyesa, yytype_int16 **yyes,
# ifndef yystrlen
# if defined __GLIBC__ && defined _STRING_H
# define yystrlen strlen
# define yystrlen(S) ((YYPTRDIFF_T) strlen (S))
# else
/* Return the length of YYSTR. */
]b4_function_define([yystrlen], [static YYSIZE_T],
]b4_function_define([yystrlen], [static YYPTRDIFF_T],
[[const char *yystr], [yystr]])[
{
YYSIZE_T yylen;
YYPTRDIFF_T yylen;
for (yylen = 0; yystr[yylen]; yylen++)
continue;
return yylen;
@@ -1085,12 +1075,12 @@ yy_lac (yytype_int16 *yyesa, yytype_int16 **yyes,
backslash-backslash). YYSTR is taken from yytname. If YYRES is
null, do not copy; instead, return the length of what the result
would have been. */
static YYSIZE_T
static YYPTRDIFF_T
yytnamerr (char *yyres, const char *yystr)
{
if (*yystr == '"')
{
YYSIZE_T yyn = 0;
YYPTRDIFF_T yyn = 0;
char const *yyp = yystr;
for (;;)
@@ -1121,10 +1111,10 @@ yytnamerr (char *yyres, const char *yystr)
do_not_strip_quotes: ;
}
if (! yyres)
if (yyres)
return yystpcpy (yyres, yystr) - yyres;
else
return yystrlen (yystr);
return (YYSIZE_T) (yystpcpy (yyres, yystr) - yyres);
}
# endif
@@ -1139,12 +1129,12 @@ yytnamerr (char *yyres, const char *yystr)
required number of bytes is too large to store]b4_lac_if([[ or if
yy_lac returned 2]])[. */
static int
yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
]b4_lac_if([[yytype_int16 *yyesa, yytype_int16 **yyes,
YYSIZE_T *yyes_capacity, ]])[yytype_int16 *yyssp, int yytoken)
yysyntax_error (YYPTRDIFF_T *yymsg_alloc, char **yymsg,
]b4_lac_if([[yy_state_t *yyesa, yy_state_t **yyes,
YYPTRDIFF_T *yyes_capacity, ]])[yy_state_t *yyssp, int yytoken)
{
YYSIZE_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]);
YYSIZE_T yysize = yysize0;
YYPTRDIFF_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]);
YYPTRDIFF_T yysize = yysize0;
enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
/* Internationalized format string. */
const char *yyformat = YY_NULLPTR;
@@ -1188,15 +1178,8 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
YYDPRINTF ((stderr, "Constructing syntax error message\n"));]])[
yyarg[yycount++] = yytname[yytoken];
if (!yypact_value_is_default (yyn))
{]b4_lac_if([], [[
/* Start YYX at -YYN if negative to avoid negative indexes in
YYCHECK. In other words, skip the first -YYN actions for
this state because they are default actions. */
int yyxbegin = yyn < 0 ? -yyn : 0;
/* Stay within bounds of both yycheck and yytname. */
int yychecklim = YYLAST - yyn + 1;
int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;]])[
int yyx;]b4_lac_if([[
{]b4_lac_if([[
int yyx;
for (yyx = 0; yyx < YYNTOKENS; ++yyx)
if (yyx != YYTERROR && yyx != YYUNDEFTOK)
@@ -1209,6 +1192,14 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
if (yy_lac_status == 1)
continue;
}]], [[
/* Start YYX at -YYN if negative to avoid negative indexes in
YYCHECK. In other words, skip the first -YYN actions for
this state because they are default actions. */
int yyxbegin = yyn < 0 ? -yyn : 0;
/* Stay within bounds of both yycheck and yytname. */
int yychecklim = YYLAST - yyn + 1;
int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
int yyx;
for (yyx = yyxbegin; yyx < yyxend; ++yyx)
if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR
@@ -1222,7 +1213,8 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
}
yyarg[yycount++] = yytname[yyx];
{
YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]);
YYPTRDIFF_T yysize1 = yysize + yytnamerr (YY_NULLPTR,
yytname[yyx]);
if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)
yysize = yysize1;
else
@@ -1253,7 +1245,7 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
}
{
YYSIZE_T yysize1 = yysize + yystrlen (yyformat);
YYPTRDIFF_T yysize1 = yysize + yystrlen (yyformat);
if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)
yysize = yysize1;
else
@@ -1434,7 +1426,7 @@ b4_function_define([[yyparse]], [[int]], b4_parse_param)[
/* Buffer for error messages, and its allocated size. */
char yymsgbuf[128];
char *yymsg = yymsgbuf;
YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
YYPTRDIFF_T yymsg_alloc = sizeof yymsgbuf;
#endif
#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)]b4_locations_if([, yylsp -= (N)])[)
@@ -1455,7 +1447,7 @@ b4_function_define([[yyparse]], [[int]], b4_parse_param)[
yystacksize = YYINITDEPTH;]b4_lac_if([[
yyes = yyesa;
yyes_capacity = sizeof yyesa / sizeof *yyes;
yyes_capacity = ]b4_percent_define_get([[parse.lac.es-capacity-initial]])[;
if (YYMAXDEPTH < yyes_capacity)
yyes_capacity = YYMAXDEPTH;]])[
@@ -1487,12 +1479,12 @@ yynewstate:
/*--------------------------------------------------------------------.
| yynewstate -- set current state (the top of the stack) to yystate. |
| yysetstate -- set current state (the top of the stack) to yystate. |
`--------------------------------------------------------------------*/
yysetstate:
YYDPRINTF ((stderr, "Entering state %d\n", yystate));
YY_ASSERT (0 <= yystate && yystate < YYNSTATES);
*yyssp = (yytype_int16) yystate;
*yyssp = (yy_state_t) yystate;
if (yyss + yystacksize - 1 <= yyssp)
#if !defined yyoverflow && !defined YYSTACK_RELOCATE
@@ -1500,15 +1492,15 @@ yysetstate:
#else
{
/* Get the current used size of the three stacks, in elements. */
YYSIZE_T yysize = (YYSIZE_T) (yyssp - yyss + 1);
YYPTRDIFF_T yysize = yyssp - yyss + 1;
# if defined yyoverflow
{
/* Give user a chance to reallocate the stack. Use copies of
these so that the &'s don't force the real ones into
memory. */
YYSTYPE *yyvs1 = yyvs;
yytype_int16 *yyss1 = yyss;]b4_locations_if([
yy_state_t *yyss1 = yyss;
YYSTYPE *yyvs1 = yyvs;]b4_locations_if([
YYLTYPE *yyls1 = yyls;])[
/* Each stack pointer address is followed by the size of the
@@ -1516,9 +1508,9 @@ yysetstate:
conditional around just the two extra args, but that might
be undefined if yyoverflow is a macro. */
yyoverflow (YY_("memory exhausted"),
&yyss1, yysize * sizeof (*yyssp),
&yyvs1, yysize * sizeof (*yyvsp),]b4_locations_if([
&yyls1, yysize * sizeof (*yylsp),])[
&yyss1, yysize * YYSIZEOF (*yyssp),
&yyvs1, yysize * YYSIZEOF (*yyvsp),]b4_locations_if([
&yyls1, yysize * YYSIZEOF (*yylsp),])[
&yystacksize);
yyss = yyss1;
yyvs = yyvs1;]b4_locations_if([
@@ -1533,9 +1525,10 @@ yysetstate:
yystacksize = YYMAXDEPTH;
{
yytype_int16 *yyss1 = yyss;
yy_state_t *yyss1 = yyss;
union yyalloc *yyptr =
(union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
(union yyalloc *) YYSTACK_ALLOC ((YYSIZE_T)
YYSTACK_BYTES (yystacksize));
if (! yyptr)
goto yyexhaustedlab;
YYSTACK_RELOCATE (yyss_alloc, yyss);
@@ -1551,8 +1544,8 @@ yysetstate:
yyvsp = yyvs + yysize - 1;]b4_locations_if([
yylsp = yyls + yysize - 1;])[
YYDPRINTF ((stderr, "Stack size increased to %lu\n",
(unsigned long) yystacksize));
YYDPRINTF ((stderr, "Stack size increased to %ld\n",
(long) yystacksize));
if (yyss + yystacksize - 1 <= yyssp)
YYABORT;
@@ -1642,16 +1635,15 @@ yyread_pushed_token:]])[
/* Shift the lookahead token. */
YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
/* Discard the shifted token. */
yychar = YYEMPTY;]b4_lac_if([[
YY_LAC_DISCARD ("shift");]])[
yystate = yyn;
YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
*++yyvsp = yylval;
YY_IGNORE_MAYBE_UNINITIALIZED_END]b4_locations_if([
*++yylsp = yylloc;])[
/* Discard the shifted token. */
yychar = YYEMPTY;]b4_lac_if([[
YY_LAC_DISCARD ("shift");]])[
goto yynewstate;
@@ -1766,7 +1758,7 @@ yyerrlab:
{
if (yymsg != yymsgbuf)
YYSTACK_FREE (yymsg);
yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc);
yymsg = (char *) YYSTACK_ALLOC ((YYSIZE_T) yymsg_alloc);
if (!yymsg)
{
yymsg = yymsgbuf;
+2
View File
@@ -31,3 +31,5 @@
/version.texi
/yacc.1
/relocatable.texi
/figs/*.eps
/figs/*.svg
+410 -276
View File
File diff suppressed because it is too large Load Diff
+12 -7
View File
@@ -14,7 +14,12 @@
## You should have received a copy of the GNU General Public License
## along with this program. If not, see <http://www.gnu.org/licenses/>.
AM_MAKEINFOFLAGS = --no-split
AM_MAKEINFOFLAGS = \
--no-split \
--set-customization-variable=SECTION_NAME_IN_TITLE=true \
--set-customization-variable=AVOID_MENU_REDUNDANCY=true \
--set-customization-variable=ICONS=true
info_TEXINFOS = doc/bison.texi
doc_bison_TEXINFOS = \
$(CROSS_OPTIONS_TEXI) \
@@ -28,7 +33,7 @@ doc_bison = doc/bison
$(doc_bison).dvi: $(FIGS_GV:.gv=.eps)
$(doc_bison).info: $(FIGS_GV:.gv=.txt)
$(doc_bison).pdf: $(FIGS_GV:.gv=.pdf)
$(doc_bison).html: $(FIGS_GV:.gv=.png)
$(doc_bison).html: $(FIGS_GV:.gv=.svg)
TEXI2DVI = texi2dvi --build-dir=doc/bison.t2d -I doc
CLEANDIRS += doc/bison.t2d
@@ -137,14 +142,14 @@ endif
## Graphviz examples generation. ##
## ----------------------------- ##
CLEANFILES += $(FIGS_GV:.gv=.eps) $(FIGS_GV:.gv=.pdf) $(FIGS_GV:.gv=.png)
CLEANFILES += $(FIGS_GV:.gv=.eps) $(FIGS_GV:.gv=.pdf) $(FIGS_GV:.gv=.svg)
FIGS_GV = \
doc/figs/example.gv \
doc/figs/example-reduce.gv doc/figs/example-shift.gv
EXTRA_DIST += \
$(FIGS_GV) $(FIGS_GV:.gv=.txt) \
$(FIGS_GV:.gv=.eps) $(FIGS_GV:.gv=.pdf) $(FIGS_GV:.gv=.png)
SUFFIXES += .gv .eps .pdf .png
$(FIGS_GV:.gv=.eps) $(FIGS_GV:.gv=.pdf) $(FIGS_GV:.gv=.svg)
SUFFIXES += .gv .eps .pdf .svg
.gv.eps:
$(AM_V_GEN) $(MKDIR_P) `echo "./$@" | sed -e 's,/[^/]*$$,,'`
@@ -156,9 +161,9 @@ SUFFIXES += .gv .eps .pdf .png
$(AM_V_at) $(DOT) -Gmargin=0 -Tpdf $< >$@.tmp
$(AM_V_at) mv $@.tmp $@
.gv.png:
.gv.svg:
$(AM_V_GEN) $(MKDIR_P) `echo "./$@" | sed -e 's,/[^/]*$$,,'`
$(AM_V_at) $(DOT) -Gmargin=0 -Tpng $< >$@.tmp
$(AM_V_at) $(DOT) -Gmargin=0 -Tsvg $< >$@.tmp
$(AM_V_at) mv $@.tmp $@
## -------------- ##
+1
View File
@@ -0,0 +1 @@
/simple.yy
+1 -1
View File
@@ -117,7 +117,7 @@ namespace yy
static int count = 0;
const int stage = count;
++count;
auto loc = parser::location_type{nullptr, unsigned (stage + 1), unsigned (stage + 1)};
auto loc = parser::location_type{nullptr, stage + 1, stage + 1};
if (stage == 0)
return parser::make_TEXT (make_string_uptr ("I have numbers for you."), std::move (loc));
else if (stage < max)
+1 -1
View File
@@ -117,7 +117,7 @@ namespace yy
static int count = 0;
const int stage = count;
++count;
parser::location_type loc (NULLPTR, unsigned (stage + 1), unsigned (stage + 1));
parser::location_type loc (NULLPTR, stage + 1, stage + 1);
switch (stage)
{
case 0:
+12 -10
View File
@@ -15,19 +15,21 @@
lexcalcdir = $(docdir)/%D%
## ------ ##
## Calc. ##
## ------ ##
## --------- ##
## LexCalc. ##
## --------- ##
if FLEX_WORKS
check_PROGRAMS += %D%/lexcalc
TESTS += %D%/lexcalc.test
nodist_%C%_lexcalc_SOURCES = %D%/parse.y %D%/parse.h %D%/scan.l
# Don't use gnulib's system headers.
%C%_lexcalc_CPPFLAGS = -I$(top_srcdir)/%D% -I$(top_builddir)/%D%
endif FLEX_WORKS
check_PROGRAMS += %D%/lexcalc
TESTS += %D%/lexcalc.test
EXTRA_DIST += %D%/lexcalc.test
nodist_%C%_lexcalc_SOURCES = %D%/parse.y %D%/parse.h %D%/scan.l
%D%/parse.c: $(dependencies)
# Don't use gnulib's system headers.
%C%_lexcalc_CPPFLAGS = -I$(top_srcdir)/%D% -I$(top_builddir)/%D%
EXTRA_DIST += %D%/lexcalc.test
dist_lexcalc_DATA = %D%/parse.y %D%/scan.l %D%/Makefile %D%/README.md
CLEANFILES += %D%/parse.[ch] %D%/scan.c %D%/parse.output
CLEANDIRS += %D%/*.dSYM
+1
View File
@@ -4,6 +4,7 @@
%option nodefault noinput nounput noyywrap
%{
#include <errno.h> /* errno, ERANGE */
#include <limits.h> /* INT_MIN */
#include <stdlib.h> /* strtol */
+2
View File
@@ -0,0 +1,2 @@
/scan.c
/scan.h
+40 -13
View File
@@ -15,15 +15,19 @@
reccalcdir = $(docdir)/%D%
## ------ ##
## Calc. ##
## ------ ##
## --------- ##
## RecCalc. ##
## --------- ##
if FLEX_WORKS
check_PROGRAMS += %D%/reccalc
TESTS += %D%/reccalc.test
nodist_%C%_reccalc_SOURCES = %D%/parse.y %D%/scan.h %D%/scan.c
BUILT_SOURCES += $(nodist_%C%_reccalc_SOURCES)
# Don't use gnulib's system headers.
%C%_reccalc_CPPFLAGS = -I$(top_srcdir)/%D% -I$(top_builddir)/%D%
endif FLEX_WORKS
check_PROGRAMS += %D%/reccalc
TESTS += %D%/reccalc.test
EXTRA_DIST += %D%/reccalc.test %D%/scan.l
nodist_%C%_reccalc_SOURCES = %D%/parse.y %D%/scan.h %D%/scan.c
BUILT_SOURCES += $(nodist_%C%_reccalc_SOURCES)
%D%/parse.c: $(dependencies)
# Tell Make that parse.o depends on scan.h, so that scan.h is built
@@ -32,21 +36,44 @@ BUILT_SOURCES += $(nodist_%C%_reccalc_SOURCES)
# additional dependency.
DASH = -
%D%/reccalc$(DASH)parse.o: %D%/scan.h
# Tell Make scan.o depends on parse.h, except that Make sees only
# parse.c, not parse.h. We can't use BUILT_SOURCES to this end, since
# we use the built bison.
%D%/reccalc$(DASH)scan.o: %D%/parse.c
# Likewise, but for Automake before 1.16.
%D%/examples_c_reccalc_reccalc$(DASH)parse.o: %D%/scan.h
%D%/examples_c_reccalc_reccalc$(DASH)scan.o: %D%/parse.c
## See "info automake 'Multiple Outputs'" for this rule.
%D%/scan.c %D%/scan.h: %D%/scan.stamp
@test -f $@ || rm -f %D%/scan.stamp
@test -f $@ || $(MAKE) $(AM_MAKEFLAGS) %D%/scan.stamp
## Recover from the removal of $@
@if test -f $@; then :; else \
trap 'rm -rf %D%/scan.lock %D%/scan.stamp' 1 2 13 15; \
## mkdir is a portable test-and-set
if mkdir %D%/scan.lock 2>/dev/null; then \
## This code is being executed by the first process.
rm -f %D%/scan.stamp; \
$(MAKE) $(AM_MAKEFLAGS) %D%/scan.stamp; \
result=$$?; rm -rf %D%/scan.lock; exit $$result; \
else \
## This code is being executed by the follower processes.
## Wait until the first process is done.
while test -d %D%/scan.lock; do sleep 1; done; \
## Succeed if and only if the first process succeeded.
test -f %D%/scan.stamp; \
fi; \
fi
%D%/scan.stamp: %D%/scan.l
$(AM_V_LEX)rm -f $@ $@.tmp
$(AM_V_at)$(MKDIR_P) %D%
$(AM_V_at)touch $@.tmp
$(AM_V_at) $(LEX) -o %D%/scan.c --header-file=%D%/scan.h $<
$(AM_V_at)$(LEX) $(AM_LFLAGS) $(LFLAGS) -o%D%/scan.c --header-file=%D%/scan.h $(srcdir)/%D%/scan.l
$(AM_V_at)mv $@.tmp $@
# Don't use gnulib's system headers.
%C%_reccalc_CPPFLAGS = -I$(top_srcdir)/%D% -I$(top_builddir)/%D%
EXTRA_DIST += %D%/reccalc.test %D%/scan.l
dist_reccalc_DATA = %D%/parse.y %D%/scan.l %D%/Makefile %D%/README.md
CLEANFILES += %D%/parse.[ch] %D%/parse.output %D%/scan.[ch] %D%/*.stamp
CLEANDIRS += %D%/*.dSYM
+1 -8
View File
@@ -3,11 +3,6 @@
%define api.parser.class {Calc}
%define parse.error verbose
%code imports {
import std.ascii;
import std.stdio;
}
%union {
int ival;
}
@@ -102,16 +97,14 @@ class CalcLexer(R) : Lexer
// Skip initial spaces
while (!input.empty && input.front != '\n' && isWhite (input.front))
{
input.popFront;
}
// Handle EOF.
if (input.empty)
return YYTokenType.EOF;
// Numbers.
if (input.front == '.' || input.front.isNumber)
if (input.front.isNumber)
{
import std.conv : parse;
semanticVal_.ival = input.parse!int;
+2 -2
View File
@@ -27,10 +27,10 @@ EXTRA_DIST += %D%/calc.test
%D%/calc.d: %D%/calc.y $(dependencies)
$(AM_V_GEN)$(MKDIR_P) %D%
$(AM_V_at)$(BISON) $< -o $@
$(AM_V_at)$(BISON) $(srcdir)/%D%/calc.y -o $@
%D%/calc: %D%/calc.d
$(AM_V_GEN) $(DC) $(DCFLAGS) -of$@ $<
$(AM_V_GEN) $(DC) $(DCFLAGS) -of$@ %D%/calc.d
dist_d_DATA = %D%/calc.y %D%/Makefile %D%/README.md
CLEANFILES += %D%/calc %D%/calc.[do]
+3 -3
View File
@@ -78,9 +78,9 @@ class CalcLexer implements Calc.Lexer {
st = new StreamTokenizer (new InputStreamReader (is));
st.resetSyntax ();
st.eolIsSignificant (true);
st.whitespaceChars (9, 9);
st.whitespaceChars (32, 32);
st.wordChars (48, 57);
st.whitespaceChars ('\t', '\t');
st.whitespaceChars (' ', ' ');
st.wordChars ('0', '9');
}
+2 -2
View File
@@ -27,10 +27,10 @@ EXTRA_DIST += %D%/Calc.test
%D%/Calc.java: %D%/Calc.y $(dependencies)
$(AM_V_GEN)$(MKDIR_P) %D%
$(AM_V_at)$(BISON) $< -o $@
$(AM_V_at)$(BISON) $(srcdir)/%D%/Calc.y -o $@
%D%/Calc.class: %D%/Calc.java
$(AM_V_GEN) $(SHELL) $(top_builddir)/javacomp.sh $<
$(AM_V_GEN) $(SHELL) $(top_builddir)/javacomp.sh %D%/Calc.java
dist_java_DATA = %D%/Calc.y %D%/Makefile %D%/README.md
CLEANFILES += %D%/*.class %D%/Calc.java
+1 -1
View File
@@ -33,7 +33,7 @@
## which guarantees that parse.y is indeed shipped.
dist_noinst_SCRIPTS = %D%/extexi %D%/test
TEST_LOG_COMPILER = $(top_srcdir)/%D%/test
TEST_LOG_COMPILER = $(SHELL) $(top_srcdir)/%D%/test
AM_CXXFLAGS = \
$(WARN_CXXFLAGS) $(WARN_CXXFLAGS_TEST) $(WERROR_CXXFLAGS)
+1 -1
Submodule gnulib updated: 14a920195e...56ca994d47
+20
View File
@@ -0,0 +1,20 @@
/*.gmo
/*.po
/LINGUAS
/Makefile
/Makefile.in
/Makefile.in.in
/Makevars
/Makevars.template
/POTFILES
/POTFILES.in
/Rules-quot
/bison-gnulib.pot
/boldquot.sed
/[email protected]
/[email protected]
/insert-header.sin
/quot.sed
/remove-potcdate.sed
/remove-potcdate.sin
/stamp-po
+30 -6
View File
@@ -16,6 +16,7 @@
/argmatch.c
/argmatch.h
/asnprintf.c
/assure.h
/basename-lgpl.c
/basename.c
/binary-io.c
@@ -38,6 +39,7 @@
/canonicalize-lgpl.c
/careadlinkat.c
/careadlinkat.h
/cdefs.h
/charset.alias
/cloexec.c
/cloexec.h
@@ -51,6 +53,7 @@
/config.h
/config.in.h
/configmake.h
/diffseq.h
/dirname-lgpl.c
/dirname.c
/dirname.h
@@ -89,9 +92,13 @@
/fseterr.c
/fseterr.h
/fstat.c
/fstrcmp.c
/fstrcmp.h
/fsync.c
/getdtablesize.c
/gethrxtime.c
/gethrxtime.h
/getopt-cdefs.h
/getopt-cdefs.in.h
/getopt-core.h
/getopt-ext.h
@@ -129,8 +136,10 @@
/isnanf.c
/isnanl-nolibm.h
/isnanl.c
/iswblank.c
/itold.c
/ldexpl.c
/libc-config.h
/limits.h
/limits.in.h
/localcharset.c
@@ -144,6 +153,10 @@
/math.c
/math.h
/math.in.h
/mbchar.c
/mbchar.h
/mbfile.c
/mbfile.h
/mbrtowc.c
/mbsinit.c
/mbswidth.c
@@ -189,6 +202,9 @@
/relocatable.c
/relocatable.h
/relocwrapper.c
/rename.c
/rmdir.c
/same-inode.h
/sched.h
/sched.in.h
/setenv.c
@@ -264,6 +280,8 @@
/sys_types.in.h
/sys_wait.in.h
/sysexits.in.h
/textstyle.h
/textstyle.in.h
/time.h
/time.in.h
/timespec.c
@@ -300,10 +318,22 @@
/wctype.h
/wctype.in.h
/wcwidth.c
/windows-initguard.h
/windows-mutex.c
/windows-mutex.h
/windows-once.c
/windows-once.h
/windows-recmutex.c
/windows-recmutex.h
/windows-rwlock.c
/windows-rwlock.h
/windows-tls.c
/windows-tls.h
/xalloc-die.c
/xalloc-oversized.h
/xalloc.h
/xconcat-filename.c
/xhash.c
/xmalloc.c
/xmemdup0.c
/xmemdup0.h
@@ -315,9 +345,3 @@
/xstrndup.h
/xtime.c
/xtime.h
/rename.c
/rmdir.c
/same-inode.h
/assure.h
/fsync.c
/textstyle.in.h
+2
View File
@@ -1,3 +1,5 @@
/lock.c
/lock.h
/threadlib.c
/tls.c
/tls.h
+8 -18
View File
@@ -1,5 +1,6 @@
/*~
/00gnulib.m4
/__inline.m4
/absolute-header.m4
/alloca.m4
/asm-underscore.m4
@@ -7,9 +8,7 @@
/calloc.m4
/canonicalize.m4
/clock_time.m4
/close-stream.m4
/close.m4
/closeout.m4
/codeset.m4
/config-h.m4
/configmake.m4
@@ -44,23 +43,14 @@
/getopt.m4
/getprogname.m4
/getrusage.m4
/gettext.m4
/gettime.m4
/gettimeofday.m4
/glibc2.m4
/glibc21.m4
/gnulib-cache.m4
/gnulib-common.m4
/gnulib-comp.m4
/gnulib-tool.m4
/host-cpu-c-abi.m4
/iconv.m4
/include_next.m4
/intdiv0.m4
/intl.m4
/intldir.m4
/intlmacosx.m4
/intmax.m4
/intmax_t.m4
/inttypes-pri.m4
/inttypes.m4
@@ -69,10 +59,12 @@
/isnand.m4
/isnanf.m4
/isnanl.m4
/iswblank.m4
/javacomp.m4
/javaexec.m4
/jm-winsz1.m4
/jm-winsz2.m4
/largefile.m4
/lcmessage.m4
/ldexp.m4
/ldexpl.m4
/lib-ld.m4
@@ -93,6 +85,8 @@
/malloc.m4
/malloca.m4
/math_h.m4
/mbchar.m4
/mbfile.m4
/mbrtowc.m4
/mbsinit.m4
/mbstate_t.m4
@@ -104,25 +98,22 @@
/msvc-inval.m4
/msvc-nothrow.m4
/multiarch.m4
/nls.m4
/nocrash.m4
/non-recursive-gnulib-prefix-hack.m4
/obstack-printf.m4
/obstack.m4
/off_t.m4
/open-cloexec.m4
/open-slash.m4
/open.m4
/pathmax.m4
/perror.m4
/pipe2.m4
/po.m4
/posix_spawn.m4
/printf-frexp.m4
/printf-frexpl.m4
/printf-posix-rpl.m4
/printf-posix.m4
/printf.m4
/progtest.m4
/pthread_rwlock_rdlock.m4
/quote.m4
/quotearg.m4
@@ -177,14 +168,13 @@
/threadlib.m4
/time_h.m4
/timespec.m4
/uintmax_t.m4
/tls.m4
/unistd-safer.m4
/unistd_h.m4
/unlink.m4
/unlocked-io.m4
/vasnprintf.m4
/vfprintf-posix.m4
/visibility.m4
/vsnprintf-posix.m4
/vsnprintf.m4
/vsprintf-posix.m4
+3
View File
@@ -63,6 +63,9 @@ m4_define([_BISON_CXXSTD_11_snippet],
for (int r: std::set<int>{1, 2})
continue;
}
// GCC 4.8.2 on Solaris 11.3 does not support to_string.
auto e = std::to_string(42);
])
m4_define([_BISON_CXXSTD_14_snippet],
-22
View File
@@ -1,22 +0,0 @@
## ----------------------------------- ##
## Check if --with-dmalloc was given. ##
## From Franc,ois Pinard ##
## ----------------------------------- ##
# serial 1
AC_DEFUN([AM_WITH_DMALLOC],
[AC_MSG_CHECKING([if malloc debugging is wanted])
AC_ARG_WITH(dmalloc,
[ --with-dmalloc use dmalloc, as in
http://www.dmalloc.com/dmalloc.tar.gz],
[if test "$withval" = yes; then
AC_MSG_RESULT(yes)
AC_DEFINE([WITH_DMALLOC],1,
[Define if using the dmalloc debugging malloc package])
LIBS="$LIBS -ldmalloc"
LDFLAGS="$LDFLAGS -g"
else
AC_MSG_RESULT(no)
fi], [AC_MSG_RESULT(no)])
])
+4 -3
View File
@@ -15,7 +15,10 @@ AC_DEFUN_ONCE([AC_PROG_LEX],
[AC_CHECK_PROGS([LEX], [flex lex], [:])
if test "x$LEX" != "x:"; then
_AC_PROG_LEX_YYTEXT_DECL
fi])
fi
AC_SUBST([LEX_IS_FLEX],
[`test "$ac_cv_prog_lex_is_flex" = yes && echo true || echo false`])dnl
])
# _AC_PROG_LEX_YYTEXT_DECL
@@ -37,8 +40,6 @@ else
ac_cv_prog_lex_is_flex=no
fi
])
AC_SUBST([LEX_IS_FLEX],
[`test "$ac_cv_prog_lex_is_flex" = yes && echo true || echo false`])dnl
cat >conftest.l <<_ACEOF[
%%
+1 -1
View File
@@ -269,7 +269,7 @@ AnnotationList__computePredecessorAnnotations (
if (item_number_is_rule_number (ritem[s->items[self_item]
- 2]))
{
unsigned rulei;
int rulei;
for (rulei = s->items[self_item];
!item_number_is_rule_number (ritem[rulei]);
++rulei)
+1 -1
View File
@@ -25,7 +25,7 @@
# include "InadequacyList.h"
# include "state.h"
typedef unsigned AnnotationIndex;
typedef int AnnotationIndex;
/**
* A node in a list of annotations on a particular LR(0) state. Each
+7 -2
View File
@@ -22,6 +22,8 @@
#include "InadequacyList.h"
#include <intprops.h>
ContributionIndex const ContributionIndex__none = -1;
ContributionIndex const ContributionIndex__error_action = -2;
@@ -31,8 +33,11 @@ InadequacyList__new_conflict (state *manifesting_state, symbol *token,
InadequacyListNodeCount *node_count)
{
InadequacyList *result = xmalloc (sizeof *result);
result->id = (*node_count)++;
aver (*node_count != 0);
result->id = *node_count;
IGNORE_TYPE_LIMITS_BEGIN
if (INT_ADD_WRAPV (*node_count, 1, node_count))
aver (false);
IGNORE_TYPE_LIMITS_END
result->next = NULL;
result->manifestingState = manifesting_state;
result->contributionCount = bitset_count (actions);
+1 -4
View File
@@ -27,11 +27,8 @@
/**
* A unique ID assigned to every \c InadequacyList node.
*
* This must remain unsigned so that the overflow check in
* \c InadequacyList__new_conflict works properly.
*/
typedef unsigned long long InadequacyListNodeCount;
typedef long long InadequacyListNodeCount;
/**
* For a conflict, each rule in the grammar can have at most one contributing
+1 -1
View File
@@ -170,7 +170,7 @@ set_fderives (void)
void
closure_new (unsigned n)
closure_new (int n)
{
itemset = xnmalloc (n, sizeof *itemset);
+1 -1
View File
@@ -27,7 +27,7 @@
data so that closure can be called. n is the number of elements to
allocate for itemset. */
void closure_new (unsigned n);
void closure_new (int n);
/* Given the kernel (aka core) of a state (a sorted vector of item numbers
+113 -80
View File
@@ -63,8 +63,6 @@ typedef enum
/** For each warning type, its severity. */
static severity warnings_flag[warnings_size];
static unsigned *indent_ptr = NULL;
styled_ostream_t errstream = NULL;
void
@@ -72,7 +70,7 @@ begin_use_class (const char *s, FILE *out)
{
if (out == stderr)
{
if (style_debug)
if (color_debug)
fprintf (out, "<%s>", s);
else
{
@@ -87,7 +85,7 @@ end_use_class (const char *s, FILE *out)
{
if (out == stderr)
{
if (style_debug)
if (color_debug)
fprintf (out, "</%s>", s);
else
{
@@ -109,46 +107,59 @@ flush (FILE *out)
| --warnings's handling. |
`------------------------*/
static const char * const warnings_args[] =
ARGMATCH_DEFINE_GROUP (warning, warnings)
static const argmatch_warning_doc argmatch_warning_docs[] =
{
"none",
"midrule-values",
"yacc",
"conflicts-sr",
"conflicts-rr",
"deprecated",
"empty-rule",
"precedence",
"other",
"all",
"error",
"everything",
0
{ "conflicts-sr", N_("S/R conflicts (enabled by default)") },
{ "conflicts-rr", N_("R/R conflicts (enabled by default)") },
{ "deprecated", N_("obsolete constructs") },
{ "empty-rule", N_("empty rules without %empty") },
{ "midrule-values", N_("unset or unused midrule values") },
{ "precedence", N_("useless precedence and associativity") },
{ "yacc", N_("incompatibilities with POSIX Yacc") },
{ "other", N_("all other warnings (enabled by default)") },
{ "all", N_("all the warnings except 'yacc'") },
{ "no-CATEGORY", N_("turn off warnings in CATEGORY") },
{ "none", N_("turn off all the warnings") },
{ "error[=CATEGORY]", N_("treat warnings as errors") },
{ NULL, NULL }
};
static const warnings warnings_types[] =
static const argmatch_warning_arg argmatch_warning_args[] =
{
Wnone,
Wmidrule_values,
Wyacc,
Wconflicts_sr,
Wconflicts_rr,
Wdeprecated,
Wempty_rule,
Wprecedence,
Wother,
Wall,
Werror,
Weverything
{ "none", Wnone },
{ "midrule-values", Wmidrule_values },
{ "yacc", Wyacc },
{ "conflicts-sr", Wconflicts_sr },
{ "conflicts-rr", Wconflicts_rr },
{ "deprecated", Wdeprecated },
{ "empty-rule", Wempty_rule },
{ "precedence", Wprecedence },
{ "other", Wother },
{ "all", Wall },
{ "everything", Weverything },
{ NULL, Wnone }
};
ARGMATCH_VERIFY (warnings_args, warnings_types);
const argmatch_warning_group_type argmatch_warning_group =
{
argmatch_warning_args,
argmatch_warning_docs,
N_("Warning categories include:"),
NULL
};
void
warning_usage (FILE *out)
{
argmatch_warning_usage (out);
}
void
warning_argmatch (char const *arg, size_t no, size_t err)
{
int value = XARGMATCH ("--warning", arg + no + err,
warnings_args, warnings_types);
int value = *argmatch_warning_value ("--warning", arg + no + err);
/* -Wnone == -Wno-everything, and -Wno-none == -Weverything. */
if (!value)
@@ -187,7 +198,14 @@ warning_argmatch (char const *arg, size_t no, size_t err)
void
warnings_argmatch (char *args)
{
if (args)
if (!args)
warning_argmatch ("all", 0, 0);
else if (STREQ (args, "help"))
{
warning_usage (stdout);
exit (EXIT_SUCCESS);
}
else
for (args = strtok (args, ","); args; args = strtok (NULL, ","))
if (STREQ (args, "error"))
warnings_are_errors = true;
@@ -203,8 +221,6 @@ warnings_argmatch (char *args)
warning_argmatch (args, no, err);
}
else
warning_argmatch ("all", 0, 0);
}
static const char*
@@ -252,30 +268,48 @@ complain_init_color (void)
{
#if HAVE_LIBTEXTSTYLE
if (color_mode == color_yes
|| color_mode == color_html
|| (color_mode == color_tty && isatty (STDERR_FILENO)))
{
style_file_prepare ("BISON_DIAGNOSTICS_STYLE", NULL,
pkgdatadir (),
"diagnostics.css");
style_file_prepare ("BISON_STYLE", "BISON_STYLEDIR", pkgdatadir (),
"bison-default.css");
/* As a fallback, use the default in the current directory. */
struct stat statbuf;
if ((style_file_name == NULL || stat (style_file_name, &statbuf) < 0)
&& stat ("diagnostics.css", &statbuf) == 0)
style_file_name = "diagnostics.css";
&& stat ("bison-default.css", &statbuf) == 0)
style_file_name = "bison-default.css";
}
else
/* No styling. */
style_file_name = NULL;
#endif
/* Workaround clang's warning (starting at Clang 3.5) about the stub
code of html_styled_ostream_create:
| src/complain.c:274:7: error: code will never be executed [-Werror,-Wunreachable-code]
| ? html_styled_ostream_create (file_ostream_create (stderr),
| ^~~~~~~~~~~~~~~~~~~~~~~~~~ */
#if defined __clang__
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wunreachable-code"
#endif
errstream =
styled_ostream_create (STDERR_FILENO, "(stderr)", TTYCTL_AUTO,
style_file_name);
color_mode == color_html
? html_styled_ostream_create (file_ostream_create (stderr),
style_file_name)
: styled_ostream_create (STDERR_FILENO, "(stderr)", TTYCTL_AUTO,
style_file_name);
#if defined __clang__
# pragma clang diagnostic pop
#endif
}
void
complain_init (void)
{
caret_init ();
warnings warnings_default =
Wconflicts_sr | Wconflicts_rr | Wdeprecated | Wother;
@@ -349,16 +383,17 @@ warning_is_enabled (warnings flags)
static void
warnings_print_categories (warnings warn_flags, FILE *out)
{
for (size_t i = 0; warnings_args[i]; ++i)
if (warn_flags & warnings_types[i])
for (int wbit = 0; wbit < warnings_size; ++wbit)
if (warn_flags & (1 << wbit))
{
severity s = warning_severity (warnings_types[i]);
warnings w = 1 << wbit;
severity s = warning_severity (w);
const char* style = severity_style (s);
fputs (" [", out);
begin_use_class (style, out);
fprintf (out, "-W%s%s",
s == severity_error ? "error=" : "",
warnings_args[i]);
argmatch_warning_argument (&w));
end_use_class (style, out);
fputc (']', out);
/* Display only the first match, the second is "-Wall". */
@@ -370,6 +405,7 @@ warnings_print_categories (warnings warn_flags, FILE *out)
*
* \param loc the location, defaulting to the current file,
* or the program name.
* \param indent optional indentation for the error message.
* \param flags the category for this message.
* \param sever to decide the prefix to put before the message
* (e.g., "warning").
@@ -381,26 +417,25 @@ warnings_print_categories (warnings warn_flags, FILE *out)
*/
static
void
error_message (const location *loc, warnings flags, severity sever,
const char *message, va_list args)
error_message (const location *loc, int *indent, warnings flags,
severity sever, const char *message, va_list args)
{
unsigned pos = 0;
int pos = 0;
if (loc)
pos += location_print (*loc, stderr);
else
pos += fprintf (stderr, "%s", current_file ? current_file : program_name);
pos += fprintf (stderr, "%s", grammar_file ? grammar_file : program_name);
pos += fprintf (stderr, ": ");
if (indent_ptr)
if (indent)
{
if (*indent_ptr)
if (*indent)
sever = severity_disabled;
if (!*indent_ptr)
*indent_ptr = pos;
else if (*indent_ptr > pos)
fprintf (stderr, "%*s", *indent_ptr - pos, "");
indent_ptr = NULL;
if (!*indent)
*indent = pos;
else if (*indent > pos)
fprintf (stderr, "%*s", *indent - pos, "");
}
const char* style = severity_style (sever);
@@ -435,8 +470,8 @@ error_message (const location *loc, warnings flags, severity sever,
/** Raise a complaint (fatal error, error or just warning). */
static void
complains (const location *loc, warnings flags, const char *message,
va_list args)
complains (const location *loc, int *indent, warnings flags,
const char *message, va_list args)
{
severity s = warning_severity (flags);
if ((flags & complaint) && complaint_status < status_complaint)
@@ -446,7 +481,7 @@ complains (const location *loc, warnings flags, const char *message,
{
if (severity_error <= s && ! complaint_status)
complaint_status = status_warning_as_error;
error_message (loc, flags, s, message, args);
error_message (loc, indent, flags, s, message, args);
}
if (flags & fatal)
@@ -458,23 +493,22 @@ complain (location const *loc, warnings flags, const char *message, ...)
{
va_list args;
va_start (args, message);
complains (loc, flags, message, args);
complains (loc, NULL, flags, message, args);
va_end (args);
}
void
complain_indent (location const *loc, warnings flags, unsigned *indent,
complain_indent (location const *loc, warnings flags, int *indent,
const char *message, ...)
{
va_list args;
indent_ptr = indent;
va_start (args, message);
complains (loc, flags, message, args);
complains (loc, indent, flags, message, args);
va_end (args);
}
void
complain_args (location const *loc, warnings w, unsigned *indent,
complain_args (location const *loc, warnings w, int *indent,
int argc, char *argv[])
{
switch (argc)
@@ -512,24 +546,23 @@ bison_directive (location const *loc, char const *directive)
void
deprecated_directive (location const *loc, char const *old, char const *upd)
{
if (feature_flag & feature_caret)
complain (loc, Wdeprecated,
_("deprecated directive, use %s"),
quote_n (1, upd));
else
complain (loc, Wdeprecated,
_("deprecated directive: %s, use %s"),
quote (old), quote_n (1, upd));
/* Register updates only if -Wdeprecated is enabled. */
if (warnings_flag[warning_deprecated] != severity_disabled)
fixits_register (loc, upd);
if (warning_is_enabled (Wdeprecated))
{
complain (loc, Wdeprecated,
_("deprecated directive: %s, use %s"),
quote (old), quote_n (1, upd));
if (feature_flag & feature_caret)
location_caret_suggestion (*loc, upd, stderr);
/* Register updates only if -Wdeprecated is enabled. */
fixits_register (loc, upd);
}
}
void
duplicate_directive (char const *directive,
location first, location second)
{
unsigned i = 0;
int i = 0;
if (feature_flag & feature_caret)
complain_indent (&second, Wother, &i, _("duplicate directive"));
else
@@ -543,7 +576,7 @@ void
duplicate_rule_directive (char const *directive,
location first, location second)
{
unsigned i = 0;
int i = 0;
complain_indent (&second, complaint, &i,
_("only one %s allowed per rule"), directive);
i += SUB_INDENT;
+15 -15
View File
@@ -45,14 +45,14 @@ void flush (FILE *out);
/** The bits assigned to each warning type. */
typedef enum
{
warning_midrule_values, /**< Unset or unused midrule values. */
warning_conflicts_rr,
warning_conflicts_sr,
warning_deprecated,
warning_empty_rule,
warning_midrule_values,
warning_other,
warning_precedence,
warning_yacc, /**< POSIXME. */
warning_conflicts_sr, /**< S/R conflicts. */
warning_conflicts_rr, /**< R/R conflicts. */
warning_empty_rule, /**< Implicitly empty rules. */
warning_deprecated, /**< Obsolete constructs. */
warning_precedence, /**< Useless precedence and associativity. */
warning_other, /**< All other warnings. */
warnings_size /**< The number of warnings. Must be last. */
} warning_bit;
@@ -60,6 +60,8 @@ typedef enum
/** Whether -Werror was set. */
extern bool warnings_are_errors;
void warning_usage (FILE *out);
/** Decode a single argument from -W.
*
* \param arg the subarguments to decode.
@@ -100,16 +102,14 @@ typedef enum
{
Wnone = 0, /**< Issue no warnings. */
Wmidrule_values = 1 << warning_midrule_values,
Wyacc = 1 << warning_yacc,
Wconflicts_sr = 1 << warning_conflicts_sr,
Wconflicts_rr = 1 << warning_conflicts_rr,
Wconflicts_sr = 1 << warning_conflicts_sr,
Wdeprecated = 1 << warning_deprecated,
Wempty_rule = 1 << warning_empty_rule,
Wprecedence = 1 << warning_precedence,
Wmidrule_values = 1 << warning_midrule_values,
Wother = 1 << warning_other,
Werror = 1 << 10, /** This bit is no longer used. */
Wprecedence = 1 << warning_precedence,
Wyacc = 1 << warning_yacc,
complaint = 1 << 11, /**< All complaints. */
fatal = 1 << 12, /**< All fatal errors. */
@@ -133,11 +133,11 @@ void complain (location const *loc, warnings flags, char const *message, ...)
__attribute__ ((__format__ (__printf__, 3, 4)));
/** Likewise, but with an \a argc/argv interface. */
void complain_args (location const *loc, warnings w, unsigned *indent,
void complain_args (location const *loc, warnings w, int *indent,
int argc, char *arg[]);
/** Make a complaint with location and some indentation. */
void complain_indent (location const *loc, warnings flags, unsigned *indent,
void complain_indent (location const *loc, warnings flags, int *indent,
char const *message, ...)
__attribute__ ((__format__ (__printf__, 4, 5)));
+29 -25
View File
@@ -38,7 +38,10 @@
/* -1 stands for not specified. */
int expected_sr_conflicts = -1;
int expected_rr_conflicts = -1;
static char *conflicts;
/* CONFLICTS[STATE-NUM] -- Whether that state has unresolved conflicts. */
static bool *conflicts;
static struct obstack solved_conflicts_obstack;
static struct obstack solved_conflicts_xml_obstack;
@@ -73,8 +76,9 @@ log_resolution (rule *r, symbol_number token,
{
case shift_resolution:
case right_resolution:
obstack_sgrow (&solved_conflicts_obstack, " ");
obstack_printf (&solved_conflicts_obstack,
_(" Conflict between rule %d and token %s"
_("Conflict between rule %d and token %s"
" resolved as shift"),
r->number,
symbols[token]->tag);
@@ -82,16 +86,18 @@ log_resolution (rule *r, symbol_number token,
case reduce_resolution:
case left_resolution:
obstack_sgrow (&solved_conflicts_obstack, " ");
obstack_printf (&solved_conflicts_obstack,
_(" Conflict between rule %d and token %s"
_("Conflict between rule %d and token %s"
" resolved as reduce"),
r->number,
symbols[token]->tag);
break;
case nonassoc_resolution:
obstack_sgrow (&solved_conflicts_obstack, " ");
obstack_printf (&solved_conflicts_obstack,
_(" Conflict between rule %d and token %s"
_("Conflict between rule %d and token %s"
" resolved as an error"),
r->number,
symbols[token]->tag);
@@ -376,7 +382,7 @@ set_conflicts (state *s, symbol **errors)
for (int i = 0; i < reds->num; ++i)
{
if (!bitset_disjoint_p (reds->lookahead_tokens[i], lookahead_set))
conflicts[s->number] = 1;
conflicts[s->number] = true;
bitset_or (lookahead_set, lookahead_set, reds->lookahead_tokens[i]);
}
}
@@ -428,7 +434,7 @@ conflicts_update_state_numbers (state_number old_to_new[],
`---------------------------------------------*/
static size_t
count_state_sr_conflicts (state *s)
count_state_sr_conflicts (const state *s)
{
transitions *trans = s->transitions;
reductions *reds = s->reductions;
@@ -476,7 +482,7 @@ count_sr_conflicts (void)
`-----------------------------------------------------------------*/
static size_t
count_state_rr_conflicts (state *s)
count_state_rr_conflicts (const state *s)
{
reductions *reds = s->reductions;
size_t res = 0;
@@ -588,24 +594,22 @@ conflicts_output (FILE *out)
{
bool printed_sth = false;
for (state_number i = 0; i < nstates; ++i)
{
state *s = states[i];
if (conflicts[i])
{
int src = count_state_sr_conflicts (s);
int rrc = count_state_rr_conflicts (s);
fprintf (out, _("State %d "), i);
if (src && rrc)
fprintf (out,
_("conflicts: %d shift/reduce, %d reduce/reduce\n"),
src, rrc);
else if (src)
fprintf (out, _("conflicts: %d shift/reduce\n"), src);
else if (rrc)
fprintf (out, _("conflicts: %d reduce/reduce\n"), rrc);
printed_sth = true;
}
}
if (conflicts[i])
{
const state *s = states[i];
int src = count_state_sr_conflicts (s);
int rrc = count_state_rr_conflicts (s);
fprintf (out, _("State %d "), i);
if (src && rrc)
fprintf (out,
_("conflicts: %d shift/reduce, %d reduce/reduce\n"),
src, rrc);
else if (src)
fprintf (out, _("conflicts: %d shift/reduce\n"), src);
else if (rrc)
fprintf (out, _("conflicts: %d reduce/reduce\n"), rrc);
printed_sth = true;
}
if (printed_sth)
fputs ("\n\n", out);
}
+7 -6
View File
@@ -40,11 +40,9 @@ rule ***derives;
static void
print_derives (void)
{
int i;
fputs ("DERIVES\n", stderr);
for (i = ntokens; i < nsyms; i++)
for (symbol_number i = ntokens; i < nsyms; ++i)
{
fprintf (stderr, " %s derives\n", symbols[i]->tag);
for (rule **rp = derives[i - ntokens]; *rp; ++rp)
@@ -88,7 +86,7 @@ derives_compute (void)
/* Q is the storage for DERIVES[...] (DERIVES[0] = q). */
rule **q = xnmalloc (nvars + nrules, sizeof *q);
for (symbol_number i = ntokens; i < nsyms; i++)
for (symbol_number i = ntokens; i < nsyms; ++i)
{
rule_list *p = dset[i - ntokens];
derives[i - ntokens] = q;
@@ -111,6 +109,9 @@ derives_compute (void)
void
derives_free (void)
{
free (derives[0]);
free (derives);
if (derives)
{
free (derives[0]);
free (derives);
}
}
-1
View File
@@ -68,7 +68,6 @@ static generated_file *generated_files = NULL;
static int generated_files_size = 0;
uniqstr grammar_file = NULL;
uniqstr current_file = NULL;
/* If --output=dir/foo.c was specified,
DIR_PREFIX is 'dir/' and ALL_BUT_EXT and ALL_BUT_TAB_EXT are 'dir/foo'.
-3
View File
@@ -58,9 +58,6 @@ extern char *dir_prefix;
and therefore GCC warns about a name clash. */
extern uniqstr grammar_file;
/* The current file name. Might change with #line. */
extern uniqstr current_file;
/* The computed base for output file names. */
extern char *all_but_ext;
+7 -2
View File
@@ -52,6 +52,11 @@ fixit_new (location const *loc, char const* fix)
return res;
}
static int
fixit_cmp (const fixit *a, const fixit *b)
{
return location_cmp (a->location, b->location);
}
static void
fixit_free (fixit *f)
@@ -85,8 +90,8 @@ fixits_register (location const *loc, char const* fix)
(gl_listelement_dispose_fn) fixit_free,
true);
fixit *f = fixit_new (loc, fix);
gl_list_add_last (fixits, f);
if (feature_flag & feature_fixit_parsable)
gl_sortedlist_add (fixits, (gl_listelement_compar_fn) fixit_cmp, f);
if (feature_flag & feature_fixit)
fixit_print (f, stderr);
}
+272 -217
View File
@@ -45,7 +45,7 @@ bool no_lines_flag = false;
bool token_table_flag = false;
location yacc_loc = EMPTY_LOCATION_INIT;
bool update_flag = false; /* for -u */
bool style_debug = false; /* --style=debug. */
bool color_debug = false;
bool nondeterministic_parser = false;
bool glr_parser = false;
@@ -68,28 +68,28 @@ const char *skeleton = NULL;
int language_prio = default_prio;
struct bison_language const *language = &valid_languages[0];
typedef int* (xargmatch_fn) (const char *context, const char *arg);
/** Decode an option's key.
*
* \param opt option being decoded.
* \param keys array of valid subarguments.
* \param values array of corresponding (int) values.
* \param all the all value.
* \param flags the flags to update
* \param arg the subarguments to decode.
* If null, then activate all the flags.
* \param no length of the potential "no-" prefix.
* Can be 0 or 3. If 3, negate the action of the subargument.
* \param opt option being decoded.
* \param xargmatch matching function.
* \param all the value of the argument 'all'.
* \param flags the flags to update
* \param arg the subarguments to decode.
* If null, then activate all the flags.
* \param no length of the potential "no-" prefix.
* Can be 0 or 3. If 3, negate the action of the subargument.
*
* If VALUE != 0 then KEY sets flags and no-KEY clears them.
* If VALUE == 0 then KEY clears all flags from \c all and no-KEY sets all
* flags from \c all. Thus no-none = all and no-all = none.
*/
static void
flag_argmatch (const char *opt,
const char *const keys[], const int values[],
flag_argmatch (const char *opt, xargmatch_fn xargmatch,
int all, int *flags, char *arg, size_t no)
{
int value = XARGMATCH (opt, arg + no, keys, values);
int value = *xargmatch (opt, arg + no);
/* -rnone == -rno-all, and -rno-none == -rall. */
if (!value)
@@ -104,30 +104,38 @@ flag_argmatch (const char *opt,
*flags |= value;
}
typedef void (usage_fn) (FILE *out);
/** Decode an option's set of keys.
*
* \param opt option being decoded (e.g., --report).
* \param keys array of valid subarguments.
* \param values array of corresponding (int) values.
* \param all the all value.
* \param flags the flags to update
* \param args comma separated list of effective subarguments to decode.
* If 0, then activate all the flags.
* \param opt option being decoded (e.g., --report).
* \param xargmatch matching function.
* \param usage function that implement --help for this option.
* \param all the value of the argument 'all'.
* \param flags the flags to update
* \param args comma separated list of effective subarguments to decode.
* If 0, then activate all the flags.
*/
static void
flags_argmatch (const char *opt,
const char * const keys[], const int values[],
xargmatch_fn xargmatch,
usage_fn usage,
int all, int *flags, char *args)
{
if (args)
if (!args)
*flags |= all;
else if (STREQ (args, "help"))
{
usage (stdout);
exit (EXIT_SUCCESS);
}
else
for (args = strtok (args, ","); args; args = strtok (NULL, ","))
{
size_t no = STRPREFIX_LIT ("no-", args) ? 3 : 0;
flag_argmatch (opt, keys,
values, all, flags, args, no);
flag_argmatch (opt, xargmatch,
all, flags, args, no);
}
else
*flags |= all;
}
@@ -142,116 +150,188 @@ flags_argmatch (const char *opt,
* \arg FlagName_flag the flag to update.
*/
#define FLAGS_ARGMATCH(FlagName, Args, All) \
flags_argmatch ("--" #FlagName, FlagName ## _args, FlagName ## _types, \
flags_argmatch ("--" #FlagName, \
(xargmatch_fn*) argmatch_## FlagName ## _value, \
argmatch_## FlagName ## _usage, \
All, &FlagName ## _flag, Args)
/*---------------------.
| --color's handling. |
`---------------------*/
enum color
{
color_always,
color_never,
color_auto
};
ARGMATCH_DEFINE_GROUP (color, enum color)
static const argmatch_color_doc argmatch_color_docs[] =
{
{ "always", N_("colorize the output") },
{ "never", N_("don't colorize the output") },
{ "auto", N_("colorize if the output device is a tty") },
{ NULL, NULL },
};
static const argmatch_color_arg argmatch_color_args[] =
{
{ "always", color_always },
{ "yes", color_always },
{ "never", color_never },
{ "no", color_never },
{ "auto", color_auto },
{ "tty", color_auto },
{ NULL, color_always },
};
const argmatch_color_group_type argmatch_color_group =
{
argmatch_color_args,
argmatch_color_docs,
/* TRANSLATORS: Use the same translation for WHEN as in the
--color=WHEN help message. */
N_("WHEN can be one of the following:"),
NULL
};
/*----------------------.
| --report's handling. |
`----------------------*/
static const char * const report_args[] =
ARGMATCH_DEFINE_GROUP (report, enum report)
static const argmatch_report_doc argmatch_report_docs[] =
{
/* In a series of synonyms, present the most meaningful first, so
that argmatch_valid be more readable. */
"none",
"state", "states",
"itemset", "itemsets",
"lookahead", "lookaheads", "look-ahead",
"solved",
"all",
0
{ "states", N_("describe the states") },
{ "itemsets", N_("complete the core item sets with their closure") },
{ "lookaheads", N_("explicitly associate lookahead tokens to items") },
{ "solved", N_("describe shift/reduce conflicts solving") },
{ "all", N_("include all the above information") },
{ "none", N_("disable the report") },
{ NULL, NULL },
};
static const int report_types[] =
static const argmatch_report_arg argmatch_report_args[] =
{
report_none,
report_states, report_states,
report_states | report_itemsets, report_states | report_itemsets,
report_states | report_lookahead_tokens,
report_states | report_lookahead_tokens,
report_states | report_lookahead_tokens,
report_states | report_solved_conflicts,
report_all
{ "none", report_none },
{ "states", report_states },
{ "itemsets", report_states | report_itemsets },
{ "lookaheads", report_states | report_lookahead_tokens },
{ "solved", report_states | report_solved_conflicts },
{ "all", report_all },
{ NULL, report_none },
};
ARGMATCH_VERIFY (report_args, report_types);
const argmatch_report_group_type argmatch_report_group =
{
argmatch_report_args,
argmatch_report_docs,
/* TRANSLATORS: Use the same translation for THINGS as in the
--report=THINGS help message. */
N_("THINGS is a list of comma separated words that can include:"),
NULL
};
/*---------------------.
| --trace's handling. |
`---------------------*/
static const char * const trace_args[] =
ARGMATCH_DEFINE_GROUP (trace, enum trace)
static const argmatch_trace_doc argmatch_trace_docs[] =
{
"none - no traces",
"locations - full display of the locations",
"scan - grammar scanner traces",
"parse - grammar parser traces",
"automaton - construction of the automaton",
"bitsets - use of bitsets",
"closure - input/output of closure",
"grammar - reading, reducing the grammar",
"resource - memory consumption (where available)",
"sets - grammar sets: firsts, nullable etc.",
"muscles - m4 definitions passed to the skeleton",
"tools - m4 invocation",
"m4 - m4 traces",
"skeleton - skeleton postprocessing",
"time - time consumption",
"ielr - IELR conversion",
"all - all of the above",
0
/* Meant for developers only, don't translate them. */
{ "none", "no traces" },
{ "locations", "full display of the locations" },
{ "scan", "grammar scanner traces" },
{ "parse", "grammar parser traces" },
{ "automaton", "construction of the automaton" },
{ "bitsets", "use of bitsets" },
{ "closure", "input/output of closure" },
{ "grammar", "reading, reducing the grammar" },
{ "resource", "memory consumption (where available)" },
{ "sets", "grammar sets: firsts, nullable etc." },
{ "muscles", "m4 definitions passed to the skeleton" },
{ "tools", "m4 invocation" },
{ "m4", "m4 traces" },
{ "skeleton", "skeleton postprocessing" },
{ "time", "time consumption" },
{ "ielr", "IELR conversion" },
{ "all", "all of the above" },
{ NULL, NULL},
};
static const int trace_types[] =
static const argmatch_trace_arg argmatch_trace_args[] =
{
trace_none,
trace_locations,
trace_scan,
trace_parse,
trace_automaton,
trace_bitsets,
trace_closure,
trace_grammar,
trace_resource,
trace_sets,
trace_muscles,
trace_tools,
trace_m4,
trace_skeleton,
trace_time,
trace_ielr,
trace_all
{ "none", trace_none },
{ "locations", trace_locations },
{ "scan", trace_scan },
{ "parse", trace_parse },
{ "automaton", trace_automaton },
{ "bitsets", trace_bitsets },
{ "closure", trace_closure },
{ "grammar", trace_grammar },
{ "resource", trace_resource },
{ "sets", trace_sets },
{ "muscles", trace_muscles },
{ "tools", trace_tools },
{ "m4", trace_m4 },
{ "skeleton", trace_skeleton },
{ "time", trace_time },
{ "ielr", trace_ielr },
{ "all", trace_all },
{ NULL, trace_none},
};
ARGMATCH_VERIFY (trace_args, trace_types);
const argmatch_trace_group_type argmatch_trace_group =
{
argmatch_trace_args,
argmatch_trace_docs,
N_("TRACES is a list of comma separated words that can include:"),
NULL
};
/*-----------------------.
| --feature's handling. |
`-----------------------*/
static const char * const feature_args[] =
ARGMATCH_DEFINE_GROUP (feature, enum feature)
static const argmatch_feature_doc argmatch_feature_docs[] =
{
"none",
"caret", "diagnostics-show-caret",
"fixit", "diagnostics-parseable-fixits",
"syntax-only",
"all",
0
{ "caret", N_("show errors with carets") },
{ "fixit", N_("show machine-readable fixes") },
{ "syntax-only", N_("do not generate any file") },
{ "all", N_("all of the above") },
{ "none", N_("disable all of the above") },
{ NULL, NULL }
};
static const int feature_types[] =
static const argmatch_feature_arg argmatch_feature_args[] =
{
feature_none,
feature_caret, feature_caret,
feature_fixit_parsable, feature_fixit_parsable,
feature_syntax_only,
feature_all
{ "none", feature_none },
{ "caret", feature_caret },
{ "diagnostics-show-caret", feature_caret },
{ "fixit", feature_fixit },
{ "diagnostics-parseable-fixits", feature_fixit },
{ "syntax-only", feature_syntax_only },
{ "all", feature_all },
{ NULL, feature_none}
};
ARGMATCH_VERIFY (feature_args, feature_types);
const argmatch_feature_group_type argmatch_feature_group =
{
argmatch_feature_args,
argmatch_feature_docs,
/* TRANSLATORS: Use the same translation for FEATURES as in the
--feature=FEATURES help message. */
N_("FEATURES is a list of comma separated words that can include:"),
NULL
};
/*-------------------------------------------.
| Display the help message and exit STATUS. |
@@ -275,8 +355,7 @@ usage (int status)
printf (_("Usage: %s [OPTION]... FILE\n"), program_name);
fputs (_("\
Generate a deterministic LR or generalized LR (GLR) parser employing\n\
LALR(1), IELR(1), or canonical LR(1) parser tables. IELR(1) and\n\
canonical LR(1) support is experimental.\n\
LALR(1), IELR(1), or canonical LR(1) parser tables.\n\
\n\
"), stdout);
@@ -286,10 +365,10 @@ Mandatory arguments to long options are mandatory for short options too.\n\
fputs (_("\
The same is true for optional arguments.\n\
"), stdout);
putc ('\n', stdout);
fputs (_("\
\n\
Operation modes:\n\
Operation Modes:\n\
-h, --help display this help and exit\n\
-V, --version output version information and exit\n\
--print-localedir output directory containing locale-dependent data\n\
@@ -297,32 +376,48 @@ Operation modes:\n\
--print-datadir output directory containing skeletons and XSLT\n\
and exit\n\
-u, --update apply fixes to the source grammar file and exit\n\
-y, --yacc emulate POSIX Yacc\n\
-W, --warnings[=CATEGORY] report the warnings falling in CATEGORY\n\
-f, --feature[=FEATURES] activate miscellaneous features\n\
\n\
"), stdout);
argmatch_feature_usage (stdout);
putc ('\n', stdout);
fputs (_("\
Parser:\n\
Diagnostics:\n\
-W, --warnings[=CATEGORY] report the warnings falling in CATEGORY\n\
--color[=WHEN] whether to colorize the diagnostics\n\
--style=FILE specify the CSS FILE for colorizer diagnostics\n\
\n\
"), stdout);
warning_usage (stdout);
putc ('\n', stdout);
argmatch_color_usage (stdout);
putc ('\n', stdout);
fputs (_("\
Tuning the Parser:\n\
-L, --language=LANGUAGE specify the output programming language\n\
-S, --skeleton=FILE specify the skeleton to use\n\
-t, --debug instrument the parser for tracing\n\
same as '-Dparse.trace'\n\
--locations enable location support\n\
-D, --define=NAME[=VALUE] similar to '%define NAME \"VALUE\"'\n\
-F, --force-define=NAME[=VALUE] override '%define NAME \"VALUE\"'\n\
-D, --define=NAME[=VALUE] similar to '%define NAME VALUE'\n\
-F, --force-define=NAME[=VALUE] override '%define NAME VALUE'\n\
-p, --name-prefix=PREFIX prepend PREFIX to the external symbols\n\
deprecated by '-Dapi.prefix=PREFIX'\n\
deprecated by '-Dapi.prefix={PREFIX}'\n\
-l, --no-lines don't generate '#line' directives\n\
-k, --token-table include a table of token names\n\
-y, --yacc emulate POSIX Yacc\n\
"), stdout);
putc ('\n', stdout);
/* Keep -d and --defines separate so that ../build-aux/cross-options.pl
* won't assume that -d also takes an argument. */
fputs (_("\
Output:\n\
Output Files:\n\
--defines[=FILE] also produce a header file\n\
-d likewise but cannot specify FILE (for POSIX Yacc)\n\
-r, --report=THINGS also produce details on the automaton\n\
@@ -332,53 +427,12 @@ Output:\n\
-o, --output=FILE leave output to FILE\n\
-g, --graph[=FILE] also output a graph of the automaton\n\
-x, --xml[=FILE] also output an XML report of the automaton\n\
(the XML schema is experimental)\n\
"), stdout);
putc ('\n', stdout);
fputs (_("\
Warning categories include:\n\
'conflicts-sr' S/R conflicts (enabled by default)\n\
'conflicts-rr' R/R conflicts (enabled by default)\n\
'deprecated' obsolete constructs\n\
'empty-rule' empty rules without %empty\n\
'midrule-values' unset or unused midrule values\n\
'precedence' useless precedence and associativity\n\
'yacc' incompatibilities with POSIX Yacc\n\
'other' all other warnings (enabled by default)\n\
'all' all the warnings except 'yacc'\n\
'no-CATEGORY' turn off warnings in CATEGORY\n\
'none' turn off all the warnings\n\
'error[=CATEGORY]' treat warnings as errors\n\
"), stdout);
argmatch_report_usage (stdout);
putc ('\n', stdout);
fputs (_("\
THINGS is a list of comma separated words that can include:\n\
'state' describe the states\n\
'itemset' complete the core item sets with their closure\n\
'lookahead' explicitly associate lookahead tokens to items\n\
'solved' describe shift/reduce conflicts solving\n\
'all' include all the above information\n\
'none' disable the report\n\
"), stdout);
putc ('\n', stdout);
fputs (_("\
FEATURES is a list of comma separated words that can include:\n\
'caret', 'diagnostics-show-caret'\n\
show errors with carets\n\
'fixit', 'diagnostics-parseable-fixits'\n\
show machine-readable fixes\n\
'syntax-only'\n\
do not generate any file\n\
'all'\n\
all of the above\n\
'none'\n\
disable all of the above\n\
"), stdout);
putc ('\n', stdout);
printf (_("Report bugs to <%s>.\n"), PACKAGE_BUGREPORT);
printf (_("%s home page: <%s>.\n"), PACKAGE_NAME, PACKAGE_URL);
fputs (_("General help using GNU software: "
@@ -452,7 +506,7 @@ skeleton_arg (char const *arg, int prio, location loc)
void
language_argmatch (char const *arg, int prio, location loc)
{
char const *msg;
char const *msg = NULL;
if (prio < language_prio)
{
@@ -467,10 +521,9 @@ language_argmatch (char const *arg, int prio, location loc)
}
else if (language_prio == prio)
msg = _("multiple language declarations are invalid");
else
return;
complain (&loc, complaint, msg, quotearg_colon (arg));
if (msg)
complain (&loc, complaint, msg, quotearg_colon (arg));
}
/*----------------------.
@@ -508,6 +561,7 @@ static char const short_options[] =
enum
{
COLOR_OPTION = CHAR_MAX + 1,
FIXED_OUTPUT_FILES_OPTION,
LOCATIONS_OPTION,
PRINT_DATADIR_OPTION,
PRINT_LOCALEDIR_OPTION,
@@ -515,6 +569,7 @@ enum
STYLE_OPTION
};
/* In the same order as in usage(), and in the documentation. */
static struct option const long_options[] =
{
/* Operation modes. */
@@ -523,55 +578,43 @@ static struct option const long_options[] =
{ "print-localedir", no_argument, 0, PRINT_LOCALEDIR_OPTION },
{ "print-datadir", no_argument, 0, PRINT_DATADIR_OPTION },
{ "update", no_argument, 0, 'u' },
{ "warnings", optional_argument, 0, 'W' },
{ "feature", optional_argument, 0, 'f' },
/* Parser. */
{ "name-prefix", required_argument, 0, 'p' },
/* Diagnostics. */
{ "warnings", optional_argument, 0, 'W' },
{ "color", optional_argument, 0, COLOR_OPTION },
{ "style", optional_argument, 0, STYLE_OPTION },
/* Output. */
{ "file-prefix", required_argument, 0, 'b' },
{ "output", required_argument, 0, 'o' },
{ "output-file", required_argument, 0, 'o' },
{ "graph", optional_argument, 0, 'g' },
{ "xml", optional_argument, 0, 'x' },
/* Tuning the Parser. */
{ "language", required_argument, 0, 'L' },
{ "skeleton", required_argument, 0, 'S' },
{ "debug", no_argument, 0, 't' },
{ "locations", no_argument, 0, LOCATIONS_OPTION },
{ "define", required_argument, 0, 'D' },
{ "force-define", required_argument, 0, 'F' },
{ "name-prefix", required_argument, 0, 'p' },
{ "no-lines", no_argument, 0, 'l' },
{ "token-table", no_argument, 0, 'k' },
{ "yacc", no_argument, 0, 'y' },
/* Output Files. */
{ "defines", optional_argument, 0, 'd' },
{ "report", required_argument, 0, 'r' },
{ "report-file", required_argument, 0, REPORT_FILE_OPTION },
{ "verbose", no_argument, 0, 'v' },
{ "file-prefix", required_argument, 0, 'b' },
{ "output", required_argument, 0, 'o' },
{ "graph", optional_argument, 0, 'g' },
{ "xml", optional_argument, 0, 'x' },
/* Hidden. */
{ "trace", optional_argument, 0, 'T' },
{ "color", optional_argument, 0, COLOR_OPTION },
{ "style", optional_argument, 0, STYLE_OPTION },
/* Output. */
{ "defines", optional_argument, 0, 'd' },
{ "feature", optional_argument, 0, 'f' },
/* Operation modes. */
{ "fixed-output-files", no_argument, 0, 'y' },
{ "yacc", no_argument, 0, 'y' },
/* Parser. */
{ "debug", no_argument, 0, 't' },
{ "define", required_argument, 0, 'D' },
{ "force-define", required_argument, 0, 'F' },
{ "locations", no_argument, 0, LOCATIONS_OPTION },
{ "no-lines", no_argument, 0, 'l' },
{ "skeleton", required_argument, 0, 'S' },
{ "language", required_argument, 0, 'L' },
{ "token-table", no_argument, 0, 'k' },
{ "fixed-output-files", no_argument, 0, FIXED_OUTPUT_FILES_OPTION },
{ "output-file", required_argument, 0, 'o' },
{ "trace", optional_argument, 0, 'T' },
{0, 0, 0, 0}
};
/* Under DOS, there is no difference on the case. This can be
troublesome when looking for '.tab' etc. */
#ifdef MSDOS
# define AS_FILE_NAME(File) (strlwr (File), (File))
#else
# define AS_FILE_NAME(File) (File)
#endif
/* Build a location for the current command line argument. */
static
location
@@ -596,14 +639,19 @@ getargs_colors (int argc, char *argv[])
{
const char *arg = argv[i];
if (STRPREFIX_LIT ("--color=", arg))
handle_color_option (arg + strlen ("--color="));
{
const char *color = arg + strlen ("--color=");
if (STREQ (color, "debug"))
color_debug = true;
else
handle_color_option (color);
}
else if (STREQ ("--color", arg))
handle_color_option (NULL);
else if (STRPREFIX_LIT ("--style=", arg))
{
const char *style = arg + strlen ("--style=");
if (STREQ (style, "debug"))
style_debug = true;
else
handle_style_option (style);
handle_style_option (style);
}
}
complain_init_color ();
@@ -618,6 +666,8 @@ getargs (int argc, char *argv[])
int c;
while ((c = getopt_long (argc, argv, short_options, long_options, NULL))
!= -1)
{
location loc = command_line_location ();
switch (c)
{
/* ASCII Sorting for short options (i.e., upper case then
@@ -650,7 +700,7 @@ getargs (int argc, char *argv[])
*end = 0;
}
}
muscle_percent_define_insert (name, command_line_location (),
muscle_percent_define_insert (name, loc,
kind, value ? value : "",
c == 'D' ? MUSCLE_PERCENT_DEFINE_D
: MUSCLE_PERCENT_DEFINE_F);
@@ -658,13 +708,11 @@ getargs (int argc, char *argv[])
break;
case 'L':
language_argmatch (optarg, command_line_prio,
command_line_location ());
language_argmatch (optarg, command_line_prio, loc);
break;
case 'S':
skeleton_arg (AS_FILE_NAME (optarg), command_line_prio,
command_line_location ());
skeleton_arg (optarg, command_line_prio, loc);
break;
case 'T':
@@ -684,7 +732,7 @@ getargs (int argc, char *argv[])
break;
case 'b':
spec_file_prefix = AS_FILE_NAME (optarg);
spec_file_prefix = optarg;
break;
case 'd':
@@ -693,7 +741,7 @@ getargs (int argc, char *argv[])
if (optarg)
{
free (spec_header_file);
spec_header_file = xstrdup (AS_FILE_NAME (optarg));
spec_header_file = xstrdup (optarg);
}
break;
@@ -702,7 +750,7 @@ getargs (int argc, char *argv[])
if (optarg)
{
free (spec_graph_file);
spec_graph_file = xstrdup (AS_FILE_NAME (optarg));
spec_graph_file = xstrdup (optarg);
}
break;
@@ -718,7 +766,7 @@ getargs (int argc, char *argv[])
break;
case 'o':
spec_outfile = AS_FILE_NAME (optarg);
spec_outfile = optarg;
break;
case 'p':
@@ -731,7 +779,7 @@ getargs (int argc, char *argv[])
case 't':
muscle_percent_define_insert ("parse.trace",
command_line_location (),
loc,
muscle_keyword, "",
MUSCLE_PERCENT_DEFINE_D);
break;
@@ -750,22 +798,28 @@ getargs (int argc, char *argv[])
if (optarg)
{
free (spec_xml_file);
spec_xml_file = xstrdup (AS_FILE_NAME (optarg));
spec_xml_file = xstrdup (optarg);
}
break;
case 'y':
warning_argmatch ("yacc", 0, 0);
yacc_loc = command_line_location ();
yacc_loc = loc;
break;
case COLOR_OPTION:
/* Handled in getargs_colors. */
break;
case FIXED_OUTPUT_FILES_OPTION:
complain (&loc, Wdeprecated,
_("deprecated option: %s, use %s"),
quote ("--fixed-output-files"), quote_n (1, "-o y.tab.c"));
spec_outfile = "y.tab.c";
break;
case LOCATIONS_OPTION:
muscle_percent_define_ensure ("locations",
command_line_location (), true);
muscle_percent_define_ensure ("locations", loc, true);
break;
case PRINT_LOCALEDIR_OPTION:
@@ -778,7 +832,7 @@ getargs (int argc, char *argv[])
case REPORT_FILE_OPTION:
free (spec_verbose_file);
spec_verbose_file = xstrdup (AS_FILE_NAME (optarg));
spec_verbose_file = xstrdup (optarg);
break;
case STYLE_OPTION:
@@ -788,6 +842,7 @@ getargs (int argc, char *argv[])
default:
usage (EXIT_FAILURE);
}
}
if (argc - optind != 1)
{
@@ -798,7 +853,7 @@ getargs (int argc, char *argv[])
usage (EXIT_FAILURE);
}
current_file = grammar_file = uniqstr_new (argv[optind]);
grammar_file = uniqstr_new (argv[optind]);
MUSCLE_INSERT_C_STRING ("file_name", grammar_file);
}
+2 -2
View File
@@ -41,7 +41,7 @@ extern bool no_lines_flag; /* for -l */
extern bool token_table_flag; /* for -k */
extern location yacc_loc; /* for -y */
extern bool update_flag; /* for -u */
extern bool style_debug; /* --style=debug. */
extern bool color_debug; /* --color=debug. */
/* GLR_PARSER is true if the input file says to use the GLR
(Generalized LR) parser, and to output some additional information
used by the GLR algorithm. */
@@ -118,7 +118,7 @@ enum feature
{
feature_none = 0, /**< No additional feature. */
feature_caret = 1 << 0, /**< Output errors with carets. */
feature_fixit_parsable = 1 << 1, /**< Issue instructions to fix the sources. */
feature_fixit = 1 << 1, /**< Issue instructions to fix the sources. */
feature_syntax_only = 1 << 2, /**< Don't generate output. */
feature_all = ~0 /**< All above features. */
};
+4 -4
View File
@@ -32,7 +32,7 @@
/* Comments for these variables are in gram.h. */
item_number *ritem = NULL;
unsigned nritems = 0;
int nritems = 0;
rule *rules = NULL;
rule_number nrules = 0;
@@ -165,7 +165,7 @@ void
ritem_print (FILE *out)
{
fputs ("RITEM\n", out);
for (unsigned i = 0; i < nritems; ++i)
for (int i = 0; i < nritems; ++i)
if (ritem[i] >= 0)
fprintf (out, " %s", symbols[ritem[i]]->tag);
else
@@ -280,8 +280,8 @@ grammar_dump (FILE *out, const char *title)
for (rule_number i = 0; i < nrules + nuseless_productions; ++i)
{
rule const *rule_i = &rules[i];
unsigned const rhs_itemno = rule_i->rhs - ritem;
unsigned length = rule_rhs_length (rule_i);
int const rhs_itemno = rule_i->rhs - ritem;
int length = rule_rhs_length (rule_i);
aver (item_number_as_rule_number (rule_i->rhs[length] == i));
fprintf (out, "%3d (%2d, %2d, %2s, %2s) %2d -> (%2u-%2u)",
i,
+2 -2
View File
@@ -115,7 +115,7 @@ extern int nvars;
typedef int item_number;
# define ITEM_NUMBER_MAX INT_MAX
extern item_number *ritem;
extern unsigned nritems;
extern int nritems;
/* There is weird relationship between OT1H item_number and OTOH
symbol_number and rule_number: we store the latter in
@@ -203,7 +203,7 @@ typedef struct
int expected_rr_conflicts;
const char *action;
location action_location;
location action_loc;
} rule;
/* The used rules (size NRULES). */
+4 -4
View File
@@ -78,7 +78,7 @@ static bitset
ielr_compute_ritem_sees_lookahead_set (void)
{
bitset result = bitset_create (nritems, BITSET_FIXED);
unsigned i = nritems-1;
int i = nritems-1;
while (0 < i)
{
--i;
@@ -418,7 +418,7 @@ ielr_item_has_lookahead (state *s, symbol_number lhs, size_t item,
top-level invocation), go get it. */
if (!lhs)
{
unsigned i;
int i;
for (i = s->items[item];
!item_number_is_rule_number (ritem[i]);
++i)
@@ -496,7 +496,7 @@ ielr_compute_annotation_lists (bitsetv follow_kernel_items,
AnnotationIndex *annotation_counts =
xnmalloc (nstates, sizeof *annotation_counts);
ContributionIndex max_contributions = 0;
unsigned total_annotations = 0;
int total_annotations = 0;
*inadequacy_listsp = xnmalloc (nstates, sizeof **inadequacy_listsp);
*annotation_listsp = xnmalloc (nstates, sizeof **annotation_listsp);
@@ -633,7 +633,7 @@ ielr_compute_lookaheads (bitsetv follow_kernel_items, bitsetv always_follows,
{
if (item_number_is_rule_number (ritem[t->items[t_item] - 2]))
{
unsigned rule_item;
int rule_item;
for (rule_item = t->items[t_item];
!item_number_is_rule_number (ritem[rule_item]);
++rule_item)
+15
View File
@@ -550,6 +550,14 @@ lookahead_tokens_print (FILE *out)
void
lalr (void)
{
if (trace_flag & trace_automaton)
{
fputc ('\n', stderr);
begin_use_class ("trace0", stderr);
fprintf (stderr, "lalr: begin");
end_use_class ("trace0", stderr);
fputc ('\n', stderr);
}
initialize_LA ();
set_goto_map ();
initialize_goto_follows ();
@@ -560,6 +568,13 @@ lalr (void)
if (trace_flag & trace_sets)
lookahead_tokens_print (stderr);
if (trace_flag & trace_automaton)
{
begin_use_class ("trace0", stderr);
fprintf (stderr, "lalr: done");
end_use_class ("trace0", stderr);
fputc ('\n', stderr);
}
}
+305 -89
View File
@@ -21,16 +21,67 @@
#include <config.h>
#include "system.h"
#include <mbfile.h>
#include <mbswidth.h>
#include <quotearg.h>
#include <stdio.h> /* fileno */
#include <sys/ioctl.h>
#include <sys/stat.h> /* fstat */
#include <termios.h>
#ifdef WINSIZE_IN_PTEM
# include <sys/stream.h>
# include <sys/ptem.h>
#endif
#include "complain.h"
#include "getargs.h"
#include "location.h"
location const empty_location = EMPTY_LOCATION_INIT;
location const empty_loc = EMPTY_LOCATION_INIT;
static int
min_int (int a, int b)
{
return a < b ? a : b;
}
static int
max_int (int a, int b)
{
return a >= b ? a : b;
}
/* The terminal width. Not less than 40. */
static int
columns (void)
{
const char *cp = getenv ("COLUMNS");
int res = 80;
if (cp && *cp)
{
long l = strtol (cp, NULL, 10);
res = 0 <= l && l <= INT_MAX ? l : INT_MAX;
}
else
{
#ifdef TIOCGWINSZ
struct winsize ws;
if (ioctl (STDERR_FILENO, TIOCGWINSZ, &ws) != -1
&& 0 < ws.ws_col && ws.ws_col == (size_t) ws.ws_col)
res = ws.ws_col;
#endif
}
return max_int (res, 40);
}
/* Available screen width. */
static int screen_width = 80;
/* The ellipsis symbol to use for this locale, and the number of
screen-columns it uses. */
static const char *ellipsis = "...";
static int ellipsize = 3;
/* If BUF is null, add BUFSIZE (which in this case must be less than
INT_MAX) to COLUMN; otherwise, add mbsnwidth (BUF, BUFSIZE, 0) to
@@ -46,11 +97,8 @@ add_column_width (int column, char const *buf, size_t bufsize)
return column <= INT_MAX - width ? column + width : INT_MAX;
}
/* Set *LOC and adjust scanner cursor to account for token TOKEN of
size SIZE. */
void
location_compute (location *loc, boundary *cur, char const *token, size_t size)
static void
boundary_compute (boundary *cur, char const *token, size_t size)
{
int line = cur->line;
int column = cur->column;
@@ -59,8 +107,6 @@ location_compute (location *loc, boundary *cur, char const *token, size_t size)
char const *p = token;
char const *lim = token + size;
loc->start = *cur;
for (p = token; p < lim; ++p)
switch (*p)
{
@@ -82,22 +128,34 @@ location_compute (location *loc, boundary *cur, char const *token, size_t size)
byte += byte < INT_MAX;
break;
}
column = add_column_width (column, p0, p - p0);
cur->line = line;
cur->column = column = add_column_width (column, p0, p - p0);
cur->column = column;
cur->byte = byte;
}
/* Set *LOC and adjust scanner cursor to account for token TOKEN of
size SIZE. */
void
location_compute (location *loc, boundary *cur, char const *token, size_t size)
{
loc->start = *cur;
boundary_compute (cur, token, size);
loc->end = *cur;
if (line == INT_MAX && loc->start.line != INT_MAX)
if (loc->end.line == INT_MAX && loc->start.line != INT_MAX)
complain (loc, Wother, _("line number overflow"));
if (column == INT_MAX && loc->start.column != INT_MAX)
if (loc->end.column == INT_MAX && loc->start.column != INT_MAX)
complain (loc, Wother, _("column number overflow"));
if (byte == INT_MAX && loc->start.byte != INT_MAX)
/* TRANSLATORS: we are counting bytes, and there are too many. */
if (loc->end.byte == INT_MAX && loc->start.byte != INT_MAX)
complain (loc, Wother, _("byte number overflow"));
}
static unsigned
static int
boundary_print (boundary const *b, FILE *out)
{
return fprintf (out, "%s:%d.%d@%d",
@@ -105,10 +163,10 @@ boundary_print (boundary const *b, FILE *out)
b->line, b->column, b->byte);
}
unsigned
int
location_print (location loc, FILE *out)
{
unsigned res = 0;
int res = 0;
if (trace_flag & trace_locations)
{
res += boundary_print (&loc.start, out);
@@ -120,10 +178,10 @@ location_print (location loc, FILE *out)
int end_col = 0 != loc.end.column ? loc.end.column - 1 : 0;
res += fprintf (out, "%s",
quotearg_n_style (3, escape_quoting_style, loc.start.file));
if (0 <= loc.start.line)
if (0 < loc.start.line)
{
res += fprintf (out, ":%d", loc.start.line);
if (0 <= loc.start.column)
if (0 < loc.start.column)
res += fprintf (out, ".%d", loc.start.column);
}
if (loc.start.file != loc.end.file)
@@ -131,14 +189,14 @@ location_print (location loc, FILE *out)
res += fprintf (out, "-%s",
quotearg_n_style (3, escape_quoting_style,
loc.end.file));
if (0 <= loc.end.line)
if (0 < loc.end.line)
{
res += fprintf (out, ":%d", loc.end.line);
if (0 <= end_col)
res += fprintf (out, ".%d", end_col);
}
}
else if (0 <= loc.end.line)
else if (0 < loc.end.line)
{
if (loc.start.line < loc.end.line)
{
@@ -159,128 +217,286 @@ location_print (location loc, FILE *out)
same file all over for each error. */
static struct
{
FILE *source;
/* The last file we tried to open. If non NULL, but SOURCE is NULL,
it means this file is special and should not be quoted. */
uniqstr file;
size_t line;
/* Offset in SOURCE where line LINE starts. */
/* Raw input file. */
FILE *file;
/* Input file as a stream of multibyte characters. */
mb_file_t mbfile;
/* The position within the last file we quoted. If POS.FILE is non
NULL, but FILE is NULL, it means this file is special and should
not be quoted. */
boundary pos;
/* Offset in FILE of the current line (i.e., where line POS.LINE
starts). */
size_t offset;
/* Length of the current line. */
int line_len;
/* Given the initial column to display, the offset (number of
characters to skip at the beginning of the line). */
int skip;
/* Available width to quote the source file. Eight chars are
consumed by the left-margin (with line number). */
int width;
} caret_info;
void
caret_free ()
void caret_init (void)
{
if (caret_info.source)
{
fclose (caret_info.source);
caret_info.source = NULL;
}
screen_width = columns ();
/* TRANSLATORS: This is used when a line is too long, and is
displayed truncated. Use an ellipsis appropriate for your
language, remembering that "" (U+2026 HORIZONTAL ELLIPSIS)
sometimes misdisplays and that "..." (three ASCII periods) is a
safer choice in some locales. */
ellipsis = _("...");
ellipsize = mbswidth (ellipsis, 0);
}
void
location_caret (location loc, const char *style, FILE *out)
caret_free (void)
{
if (loc.start.column == -1 || loc.start.line == -1)
return;
/* If a different source than before, close and let the rest open
the new one. */
if (caret_info.file && caret_info.file != loc.start.file)
if (caret_info.file)
{
caret_free ();
fclose (caret_info.file);
caret_info.file = NULL;
}
if (!caret_info.file)
}
/* Open FILE for quoting, if needed, and if possible. Return whether
the file can quoted. */
static bool
caret_set_file (const char *file)
{
/* If a different file than before, close and let the rest open
the new one. */
if (caret_info.pos.file && caret_info.pos.file != file)
{
caret_info.file = loc.start.file;
if ((caret_info.source = fopen (caret_info.file, "r")))
caret_free ();
caret_info.pos.file = NULL;
}
if (!caret_info.pos.file)
{
caret_info.pos.file = file;
if ((caret_info.file = fopen (caret_info.pos.file, "r")))
{
/* If the file is not regular (imagine #line 1 "/dev/stdin"
in the input file for instance), don't try to quote the
source. Keep caret_info.file set so that we don't try to
open it again, but leave caret_info.source NULL so that
we don't try to quote it. */
file. Keep caret_info.file set so that we don't try to
open it again, but leave caret_info.file NULL so that we
don't try to quote it. */
struct stat buf;
if (fstat (fileno (caret_info.source), &buf) == 0
if (fstat (fileno (caret_info.file), &buf) == 0
&& buf.st_mode & S_IFREG)
{
caret_info.line = 1;
caret_info.offset = 0;
caret_info.pos.line = 1;
mbf_init (caret_info.mbfile, caret_info.file);
}
else
caret_free ();
}
}
if (!caret_info.source)
return;
return !!caret_info.file;
}
/* Getc, but smash \r\n as \n. */
static void
caret_getc_internal (mbchar_t *res)
{
mbf_getc (*res, caret_info.mbfile);
if (mb_iseq (*res, '\r'))
{
mbchar_t c;
mbf_getc (c, caret_info.mbfile);
if (mb_iseq (c, '\n'))
mb_copy (res, &c);
else
mbf_ungetc (c, caret_info.mbfile);
}
}
#define caret_getc(Var) caret_getc_internal(&Var)
/* Move CARET_INFO (which has a valid FILE) to the line number LINE.
Compute and cache that line's length in CARET_INFO.LINE_LEN.
Return whether succesful.*/
static bool
caret_set_line (int line)
{
/* If the line we want to quote is seekable (the same line as the previous
location), just seek it. If it was a previous line, we lost track of it,
so return to the start of file. */
if (caret_info.line <= loc.start.line)
fseek (caret_info.source, caret_info.offset, SEEK_SET);
else
if (line < caret_info.pos.line)
{
caret_info.line = 1;
caret_info.pos.line = 1;
caret_info.offset = 0;
fseek (caret_info.source, caret_info.offset, SEEK_SET);
}
if (fseek (caret_info.file, caret_info.offset, SEEK_SET))
return false;
/* If this is the same line as the previous one, we are done. */
if (line < caret_info.pos.line)
return true;
/* Advance to the line's position, keeping track of the offset. */
while (caret_info.line < loc.start.line)
caret_info.line += getc (caret_info.source) == '\n';
caret_info.offset = ftell (caret_info.source);
while (caret_info.pos.line < line)
{
mbchar_t c;
caret_getc (c);
if (mb_iseof (c))
/* Something is wrong, that line number does not exist. */
return false;
caret_info.pos.line += mb_iseq (c, '\n');
}
caret_info.offset = ftell (caret_info.file);
caret_info.pos.column = 1;
/* Reset mbf's internal state.
FIXME: should be done in mbfile. */
caret_info.mbfile.eof_seen = 0;
/* Find the number of columns of this line. */
while (true)
{
mbchar_t c;
caret_getc (c);
if (mb_iseof (c) || mb_iseq (c, '\n'))
break;
boundary_compute (&caret_info.pos, mb_ptr (c), mb_len (c));
}
caret_info.line_len = caret_info.pos.column;
/* Go back to the beginning of line. */
if (fseek (caret_info.file, caret_info.offset, SEEK_SET))
return false;
/* Reset mbf's internal state.
FIXME: should be done in mbfile. */
caret_info.mbfile.eof_seen = 0;
caret_info.pos.column = 1;
return true;
}
/* Compute CARET_INFO.WIDTH and CARET_INFO.SKIP based on the fact that
the first column to display in the current line is COL. */
static bool
caret_set_column (int col)
{
/* Available width. Eight chars are consumed by the left-margin
(with line number). */
caret_info.width = screen_width - 8;
caret_info.skip = 0;
if (caret_info.width < caret_info.line_len)
{
/* We cannot quote the whole line. Make sure we can see the
beginning of the location. */
caret_info.skip = caret_info.width < col ? col - 10 : 0;
}
/* If we skip the initial part, we insert "..." before. */
if (caret_info.skip)
caret_info.width -= ellipsize;
/* If the end of line does not fit, we also need to truncate the
end, and leave "..." there. */
if (caret_info.width < caret_info.line_len - caret_info.skip)
caret_info.width -= ellipsize;
return true;
}
void
location_caret (location loc, const char *style, FILE *out)
{
if (!loc.start.line)
return;
if (!caret_set_file (loc.start.file))
return;
if (!caret_set_line (loc.start.line))
return;
if (!caret_set_column (loc.start.column))
return;
const int width = caret_info.width;
const int skip = caret_info.skip;
/* Read the actual line. Don't update the offset, so that we keep a pointer
to the start of the line. */
{
int c = getc (caret_info.source);
if (c != EOF)
mbchar_t c;
caret_getc (c);
if (!mb_iseof (c))
{
/* The last column to highlight. Only the first line of
multiline locations are quoted, in which case the ending
column is the end of line. Single point locations (with
equal boundaries) denote the character that they
follow. */
int col_end
= loc.start.line == loc.end.line
? loc.end.column + (loc.start.column == loc.end.column)
: caret_info.line_len;
/* Quote the file (at most the first line in the case of
multiline locations). */
fprintf (out, "%5d | ", loc.start.line);
bool single_line = loc.start.line == loc.end.line;
/* Consider that single point location (with equal boundaries)
actually denote the character that they follow. */
int byte_end = loc.end.byte +
(single_line && loc.start.byte == loc.end.byte);
/* Byte number. */
int byte = 1;
while (c != EOF && c != '\n')
{
if (byte == loc.start.byte)
begin_use_class (style, out);
fputc (c, out);
c = getc (caret_info.source);
++byte;
if (single_line
? byte == byte_end
: c == '\n' || c == EOF)
end_use_class (style, out);
}
putc ('\n', out);
{
/* Print the carets with the same indentation as above. */
fprintf (out, " | %*s", loc.start.column - 1, "");
fprintf (out, "%5d | %s", loc.start.line, skip ? ellipsis : "");
/* Whether we opened the style. If the line is not as
expected (maybe the file was changed since the scanner
ran), we might reach the end before we actually saw the
opening column. */
bool opened = false;
while (!mb_iseof (c) && !mb_iseq (c, '\n'))
{
if (caret_info.pos.column == loc.start.column)
{
begin_use_class (style, out);
opened = true;
}
if (skip < caret_info.pos.column)
mb_putc (c, out);
boundary_compute (&caret_info.pos, mb_ptr (c), mb_len (c));
caret_getc (c);
if (opened
&& (caret_info.pos.column == col_end
|| width < caret_info.pos.column - skip))
{
end_use_class (style, out);
opened = false;
}
if (width < caret_info.pos.column - skip)
{
fputs (ellipsis, out);
break;
}
}
putc ('\n', out);
}
/* Print the carets with the same indentation as above. */
{
fprintf (out, " | %*s",
loc.start.column - 1 - skip + (skip ? ellipsize : 0), "");
begin_use_class (style, out);
putc ('^', out);
/* Underlining a multiline location ends with the first
line. */
int len = single_line
? loc.end.column
: ftell (caret_info.source) - caret_info.offset;
for (int i = loc.start.column + 1; i < len; ++i)
for (int i = loc.start.column - 1 - skip + 1,
i_end = min_int (col_end - 1 - skip, width);
i < i_end; ++i)
putc ('~', out);
end_use_class (style, out);
putc ('\n', out);
}
putc ('\n', out);
}
}
}
void
location_caret_suggestion (location loc, const char *s, FILE *out)
{
const char *style = "fixit-insert";
fprintf (out, " | %*s",
loc.start.column - 1 - caret_info.skip
+ (caret_info.skip ? ellipsize : 0),
"");
begin_use_class (style, out);
fputs (s, out);
end_use_class (style, out);
putc ('\n', out);
}
bool
location_empty (location loc)
{
+23 -10
View File
@@ -33,25 +33,25 @@ typedef struct
/* The name of the file that contains the boundary. */
uniqstr file;
/* If nonnegative, the (origin-1) line that contains the boundary.
/* If positive, the line (starting at 1) that contains the boundary.
If this is INT_MAX, the line number has overflowed.
Meaningless and not displayed if negative.
Meaningless and not displayed if nonpositive.
*/
int line;
/* If nonnegative, the (origin-1) column just after the boundary.
/* If positive, the column (starting at 1) just after the boundary.
This is neither a byte count, nor a character count; it is a
column count. If this is INT_MAX, the column number has
overflowed.
Meaningless and not displayed if negative.
Meaningless and not displayed if nonpositive.
*/
int column;
/* If nonnegative, (origin-0) bytes number in the current line.
/* If nonnegative, the byte number (starting at 0) in the current line.
Never displayed, used when printing error messages with colors to
know where colors start and ends. */
know where colors start and end. */
int byte;
} boundary;
@@ -71,7 +71,12 @@ boundary_set (boundary *p, const char *f, int l, int c, int b)
static inline int
boundary_cmp (boundary a, boundary b)
{
int res = strcmp (a.file, b.file);
/* Locations with no file first. */
int res =
a.file && b.file ? strcmp (a.file, b.file)
: a.file ? 1
: b.file ? -1
: 0;
if (!res)
res = a.line - b.line;
if (!res)
@@ -102,7 +107,7 @@ typedef struct
# define GRAM_LTYPE location
# define EMPTY_LOCATION_INIT {{NULL, 0, 0, 0}, {NULL, 0, 0, 0}}
extern location const empty_location;
extern location const empty_loc;
/* Set *LOC and adjust scanner cursor to account for token TOKEN of
size SIZE. */
@@ -112,15 +117,23 @@ void location_compute (location *loc,
/* Print location to file.
Return number of actually printed characters.
Warning: uses quotearg's slot 3. */
unsigned location_print (location loc, FILE *out);
int location_print (location loc, FILE *out);
/* Prepare the use of location_caret. */
void caret_init (void);
/* Free any allocated resources and close any open file handles that are
left-over by the usage of location_caret. */
void caret_free (void);
/* Output to OUT the line and caret corresponding to location LOC. */
/* Quote the line containing LOC onto OUT. Highlight the part of LOC
with the color STYLE. */
void location_caret (location loc, const char* style, FILE *out);
/* Display a suggestion of replacement for LOC with S. To call after
location_caret. */
void location_caret_suggestion (location loc, const char *s, FILE *out);
/* Return -1, 0, 1, depending whether a is before, equal, or
after b. */
static inline int
+33
View File
@@ -158,6 +158,14 @@ kernel_print (FILE *out)
}
}
/* Make sure the kernel is in sane state. */
static void
kernel_check (void)
{
for (symbol_number i = 0; i < nsyms - 1; ++i)
assert (kernel_base[i] + kernel_size[i] <= kernel_base[i + 1]);
}
static void
allocate_storage (void)
{
@@ -209,9 +217,21 @@ new_itemsets (state *s)
bitset_zero (shift_symbol);
if (trace_flag & trace_automaton)
{
fprintf (stderr, "initial kernel:\n");
kernel_print (stderr);
}
for (size_t i = 0; i < nitemset; ++i)
if (item_number_is_symbol_number (ritem[itemset[i]]))
{
if (trace_flag & trace_automaton)
{
fputs ("working on: ", stderr);
item_print (ritem + itemset[i], NULL, stderr);
fputc ('\n', stderr);
}
symbol_number sym = item_number_as_symbol_number (ritem[itemset[i]]);
bitset_set (shift_symbol, sym);
kernel_base[sym][kernel_size[sym]] = itemset[i] + 1;
@@ -220,9 +240,11 @@ new_itemsets (state *s)
if (trace_flag & trace_automaton)
{
fprintf (stderr, "final kernel:\n");
kernel_print (stderr);
fprintf (stderr, "new_itemsets: end: state = %d\n\n", s->number);
}
kernel_check ();
}
@@ -309,6 +331,17 @@ save_reductions (state *s)
}
}
if (trace_flag & trace_automaton)
{
fprintf (stderr, "reduction[%d] = {\n", s->number);
for (int i = 0; i < count; ++i)
{
rule_print (redset[i], NULL, stderr);
fputc ('\n', stderr);
}
fputs ("}\n", stderr);
}
/* Make a reductions structure and copy the data into it. */
state_reductions_set (s, count, redset);
}
+4 -4
View File
@@ -101,7 +101,7 @@ main (int argc, char *argv[])
the grammar; see gram.h. */
timevar_push (tv_reader);
reader ();
reader (grammar_file);
timevar_pop (tv_reader);
if (complaint_status == status_complaint)
@@ -207,6 +207,8 @@ main (int argc, char *argv[])
timevar_pop (tv_parser);
}
finish:
timevar_push (tv_free);
nullable_free ();
derives_free ();
@@ -223,14 +225,11 @@ main (int argc, char *argv[])
muscle_free ();
code_scanner_free ();
skel_scanner_free ();
quotearg_free ();
timevar_pop (tv_free);
if (trace_flag & trace_bitsets)
bitset_stats_dump (stderr);
finish:
/* Stop timing and print the times. */
timevar_stop (tv_total);
timevar_print (stderr);
@@ -249,6 +248,7 @@ main (int argc, char *argv[])
uniqstrs_free ();
complain_free ();
quotearg_free ();
return complaint_status ? EXIT_FAILURE : EXIT_SUCCESS;
}
+4 -4
View File
@@ -126,8 +126,8 @@ muscle_init (void)
/* Initialize the muscle obstack. */
obstack_init (&muscle_obstack);
muscle_table = hash_initialize (HT_INITIAL_CAPACITY, NULL, hash_muscle,
hash_compare_muscles, muscle_entry_free);
muscle_table = hash_xinitialize (HT_INITIAL_CAPACITY, NULL, hash_muscle,
hash_compare_muscles, muscle_entry_free);
/* Version and input file. */
MUSCLE_INSERT_STRING ("version", VERSION);
@@ -525,7 +525,7 @@ muscle_percent_define_insert (char const *var, location variable_loc,
= atoi (muscle_find_const (how_name));
if (how_old == MUSCLE_PERCENT_DEFINE_F)
goto end;
unsigned i = 0;
int i = 0;
/* If assigning the same value, make it a warning. */
warnings warn = STREQ (value, current_value) ? Wother : complaint;
complain_indent (&variable_loc, warn, &i,
@@ -739,7 +739,7 @@ muscle_percent_define_check_values (char const * const *values)
if (!*values)
{
location loc = muscle_percent_define_get_loc (*variablep);
unsigned i = 0;
int i = 0;
complain_indent (&loc, complaint, &i,
_("invalid value for %%define variable %s: %s"),
quote (*variablep), quote_n (1, value));
+30 -20
View File
@@ -91,7 +91,6 @@ Name (char const *name, Type *table_data, Type first, \
MUSCLE_INSERT_LONG_INT (obstack_finish0 (&format_obstack), lmax); \
}
GENERATE_MUSCLE_INSERT_TABLE (muscle_insert_unsigned_table, unsigned)
GENERATE_MUSCLE_INSERT_TABLE (muscle_insert_int_table, int)
GENERATE_MUSCLE_INSERT_TABLE (muscle_insert_base_table, base_number)
GENERATE_MUSCLE_INSERT_TABLE (muscle_insert_rule_number_table, rule_number)
@@ -214,17 +213,17 @@ prepare_symbols (void)
static void
prepare_rules (void)
{
unsigned *prhs = xnmalloc (nrules, sizeof *prhs);
int *prhs = xnmalloc (nrules, sizeof *prhs);
item_number *rhs = xnmalloc (nritems, sizeof *rhs);
unsigned *rline = xnmalloc (nrules, sizeof *rline);
int *rline = xnmalloc (nrules, sizeof *rline);
symbol_number *r1 = xnmalloc (nrules, sizeof *r1);
unsigned *r2 = xnmalloc (nrules, sizeof *r2);
int *r2 = xnmalloc (nrules, sizeof *r2);
int *dprec = xnmalloc (nrules, sizeof *dprec);
int *merger = xnmalloc (nrules, sizeof *merger);
int *immediate = xnmalloc (nrules, sizeof *immediate);
/* Index in RHS. */
unsigned i = 0;
int i = 0;
for (rule_number r = 0; r < nrules; ++r)
{
/* Index of rule R in RHS. */
@@ -251,10 +250,10 @@ prepare_rules (void)
aver (i == nritems);
muscle_insert_item_number_table ("rhs", rhs, ritem[0], 1, nritems);
muscle_insert_unsigned_table ("prhs", prhs, 0, 0, nrules);
muscle_insert_unsigned_table ("rline", rline, 0, 0, nrules);
muscle_insert_int_table ("prhs", prhs, 0, 0, nrules);
muscle_insert_int_table ("rline", rline, 0, 0, nrules);
muscle_insert_symbol_number_table ("r1", r1, 0, 0, nrules);
muscle_insert_unsigned_table ("r2", r2, 0, 0, nrules);
muscle_insert_int_table ("r2", r2, 0, 0, nrules);
muscle_insert_int_table ("dprec", dprec, 0, 0, nrules);
muscle_insert_int_table ("merger", merger, 0, 0, nrules);
muscle_insert_int_table ("immediate", immediate, 0, 0, nrules);
@@ -359,9 +358,9 @@ symbol_numbers_output (FILE *out)
}
/*---------------------------------.
| Output the user actions to OUT. |
`---------------------------------*/
/*-------------------------------------------.
| Output the user reduction actions to OUT. |
`-------------------------------------------*/
static void
user_actions_output (FILE *out)
@@ -370,11 +369,20 @@ user_actions_output (FILE *out)
for (rule_number r = 0; r < nrules; ++r)
if (rules[r].action)
{
fprintf (out, "%s(%d, [b4_syncline(%d, ",
/* The useless "" is there to pacify syntax-check. */
fprintf (out, "%s""(%d, [",
rules[r].is_predicate ? "b4_predicate_case" : "b4_case",
r + 1, rules[r].action_location.start.line);
string_output (out, rules[r].action_location.start.file);
fprintf (out, ")dnl\n[ %s]])\n\n", rules[r].action);
r + 1);
if (!no_lines_flag)
{
fprintf (out, "b4_syncline(%d, ",
rules[r].action_loc.start.line);
string_output (out, rules[r].action_loc.start.file);
fprintf (out, ")dnl\n");
}
fprintf (out, "[%*s%s]])\n\n",
rules[r].action_loc.start.column - 1, "",
rules[r].action);
}
fputs ("])\n\n", out);
}
@@ -482,7 +490,9 @@ prepare_symbol_definitions (void)
muscle_location_grow (key, p->location);
SET_KEY (pname);
MUSCLE_INSERT_STRING_RAW (key, p->code);
obstack_printf (&muscle_obstack,
"%*s%s", p->location.start.column - 1, "", p->code);
muscle_insert (key, obstack_finish0 (&muscle_obstack));
}
}
#undef SET_KEY2
@@ -532,10 +542,10 @@ prepare_actions (void)
parser, so we could avoid accidents by not writing them out in
that case. Nevertheless, it seems even better to be able to use
the GLR skeletons even without the non-deterministic tables. */
muscle_insert_unsigned_table ("conflict_list_heads", conflict_table,
conflict_table[0], 1, high + 1);
muscle_insert_unsigned_table ("conflicting_rules", conflict_list,
0, 1, conflict_list_cnt);
muscle_insert_int_table ("conflict_list_heads", conflict_table,
conflict_table[0], 1, high + 1);
muscle_insert_int_table ("conflicting_rules", conflict_list,
0, 1, conflict_list_cnt);
}
+653 -592
View File
File diff suppressed because it is too large Load Diff
+68 -67
View File
@@ -1,4 +1,4 @@
/* A Bison parser, made by GNU Bison 3.3.2.153-f5a4-dirty. */
/* A Bison parser, made by GNU Bison 3.4.2.213-aa24. */
/* Bison interface for Yacc-like parsers in C
@@ -78,62 +78,63 @@ extern int gram_debug;
enum gram_tokentype
{
GRAM_EOF = 0,
STRING = 258,
PERCENT_TOKEN = 259,
PERCENT_NTERM = 260,
PERCENT_TYPE = 261,
PERCENT_DESTRUCTOR = 262,
PERCENT_PRINTER = 263,
PERCENT_LEFT = 264,
PERCENT_RIGHT = 265,
PERCENT_NONASSOC = 266,
PERCENT_PRECEDENCE = 267,
PERCENT_PREC = 268,
PERCENT_DPREC = 269,
PERCENT_MERGE = 270,
PERCENT_CODE = 271,
PERCENT_DEFAULT_PREC = 272,
PERCENT_DEFINE = 273,
PERCENT_DEFINES = 274,
PERCENT_ERROR_VERBOSE = 275,
PERCENT_EXPECT = 276,
PERCENT_EXPECT_RR = 277,
PERCENT_FLAG = 278,
PERCENT_FILE_PREFIX = 279,
PERCENT_GLR_PARSER = 280,
PERCENT_INITIAL_ACTION = 281,
PERCENT_LANGUAGE = 282,
PERCENT_NAME_PREFIX = 283,
PERCENT_NO_DEFAULT_PREC = 284,
PERCENT_NO_LINES = 285,
PERCENT_NONDETERMINISTIC_PARSER = 286,
PERCENT_OUTPUT = 287,
PERCENT_REQUIRE = 288,
PERCENT_SKELETON = 289,
PERCENT_START = 290,
PERCENT_TOKEN_TABLE = 291,
PERCENT_VERBOSE = 292,
PERCENT_YACC = 293,
BRACED_CODE = 294,
BRACED_PREDICATE = 295,
BRACKETED_ID = 296,
CHAR = 297,
COLON = 298,
EPILOGUE = 299,
EQUAL = 300,
ID = 301,
ID_COLON = 302,
PERCENT_PERCENT = 303,
PIPE = 304,
PROLOGUE = 305,
SEMICOLON = 306,
TAG = 307,
TAG_ANY = 308,
TAG_NONE = 309,
INT = 310,
PERCENT_PARAM = 311,
PERCENT_UNION = 312,
PERCENT_EMPTY = 313
STRING = 3,
PERCENT_TOKEN = 4,
PERCENT_NTERM = 5,
PERCENT_TYPE = 6,
PERCENT_DESTRUCTOR = 7,
PERCENT_PRINTER = 8,
PERCENT_LEFT = 9,
PERCENT_RIGHT = 10,
PERCENT_NONASSOC = 11,
PERCENT_PRECEDENCE = 12,
PERCENT_PREC = 13,
PERCENT_DPREC = 14,
PERCENT_MERGE = 15,
PERCENT_CODE = 16,
PERCENT_DEFAULT_PREC = 17,
PERCENT_DEFINE = 18,
PERCENT_DEFINES = 19,
PERCENT_ERROR_VERBOSE = 20,
PERCENT_EXPECT = 21,
PERCENT_EXPECT_RR = 22,
PERCENT_FLAG = 23,
PERCENT_FILE_PREFIX = 24,
PERCENT_GLR_PARSER = 25,
PERCENT_INITIAL_ACTION = 26,
PERCENT_LANGUAGE = 27,
PERCENT_NAME_PREFIX = 28,
PERCENT_NO_DEFAULT_PREC = 29,
PERCENT_NO_LINES = 30,
PERCENT_NONDETERMINISTIC_PARSER = 31,
PERCENT_OUTPUT = 32,
PERCENT_PURE_PARSER = 33,
PERCENT_REQUIRE = 34,
PERCENT_SKELETON = 35,
PERCENT_START = 36,
PERCENT_TOKEN_TABLE = 37,
PERCENT_VERBOSE = 38,
PERCENT_YACC = 39,
BRACED_CODE = 40,
BRACED_PREDICATE = 41,
BRACKETED_ID = 42,
CHAR = 43,
COLON = 44,
EPILOGUE = 45,
EQUAL = 46,
ID = 47,
ID_COLON = 48,
PERCENT_PERCENT = 49,
PIPE = 50,
PROLOGUE = 51,
SEMICOLON = 52,
TAG = 53,
TAG_ANY = 54,
TAG_NONE = 55,
INT = 56,
PERCENT_PARAM = 57,
PERCENT_UNION = 58,
PERCENT_EMPTY = 59
};
#endif
@@ -159,9 +160,9 @@ union GRAM_STYPE
/* "integer" */
int INT;
/* int.opt */
int yytype_80;
int yytype_81;
/* named_ref.opt */
named_ref* yytype_92;
named_ref* yytype_93;
/* "%param" */
param_type PERCENT_PARAM;
/* token_decl */
@@ -177,7 +178,7 @@ union GRAM_STYPE
/* string_as_id */
symbol* string_as_id;
/* string_as_id.opt */
symbol* yytype_99;
symbol* yytype_100;
/* generic_symlist */
symbol_list* generic_symlist;
/* generic_symlist_item */
@@ -187,15 +188,15 @@ union GRAM_STYPE
/* token_decls */
symbol_list* token_decls;
/* token_decl.1 */
symbol_list* yytype_78;
symbol_list* yytype_79;
/* token_decls_for_prec */
symbol_list* token_decls_for_prec;
/* token_decl_for_prec.1 */
symbol_list* yytype_82;
symbol_list* yytype_83;
/* symbol_decls */
symbol_list* symbol_decls;
/* symbol_decl.1 */
symbol_list* yytype_85;
symbol_list* yytype_86;
/* "%error-verbose" */
uniqstr PERCENT_ERROR_VERBOSE;
/* "%<flag>" */
@@ -204,8 +205,8 @@ union GRAM_STYPE
uniqstr PERCENT_FILE_PREFIX;
/* "%name-prefix" */
uniqstr PERCENT_NAME_PREFIX;
/* "%yacc" */
uniqstr PERCENT_YACC;
/* "%pure-parser" */
uniqstr PERCENT_PURE_PARSER;
/* "[identifier]" */
uniqstr BRACKETED_ID;
/* "identifier" */
@@ -215,12 +216,12 @@ union GRAM_STYPE
/* "<tag>" */
uniqstr TAG;
/* tag.opt */
uniqstr yytype_72;
uniqstr yytype_73;
/* tag */
uniqstr tag;
/* variable */
uniqstr variable;
/* "char" */
/* "character literal" */
unsigned char CHAR;
/* value */
value_type value;
+95 -56
View File
@@ -32,24 +32,26 @@
%code
{
#include "system.h"
#include <errno.h>
#include "c-ctype.h"
#include <c-ctype.h>
#include <errno.h>
#include <intprops.h>
#include <quotearg.h>
#include <vasnprintf.h>
#include <xmemdup0.h>
#include "complain.h"
#include "conflicts.h"
#include "files.h"
#include "getargs.h"
#include "gram.h"
#include "named-ref.h"
#include "quotearg.h"
#include "reader.h"
#include "scan-code.h"
#include "scan-gram.h"
#include "vasnprintf.h"
#include "xmemdup0.h"
static int current_prec = 0;
static location current_lhs_location;
static location current_lhs_loc;
static named_ref *current_lhs_named_ref;
static symbol *current_lhs_symbol;
static symbol_class current_class = unknown_sym;
@@ -94,6 +96,9 @@
static void handle_name_prefix (location const *loc,
char const *directive, char const *value);
/* Handle a %pure-parser directive. */
static void handle_pure_parser (location const *loc, char const *directive);
/* Handle a %require directive. */
static void handle_require (location const *loc, char const *version);
@@ -101,18 +106,14 @@
static void handle_skeleton (location const *loc, char const *skel);
/* Handle a %yacc directive. */
static void handle_yacc (location const *loc, char const *directive);
static void handle_yacc (location const *loc);
/* Implementation of yyerror. */
static void gram_error (location const *, char const *);
/* A string that describes a char (e.g., 'a' -> "'a'"). */
static char const *char_name (char);
#define YYTYPE_INT16 int_fast16_t
#define YYTYPE_INT8 int_fast8_t
#define YYTYPE_UINT16 uint_fast16_t
#define YYTYPE_UINT8 uint_fast8_t
/* Add style to semantic values in traces. */
static void tron (FILE *yyo);
static void troff (FILE *yyo);
@@ -121,6 +122,7 @@
%define api.header.include {"parse-gram.h"}
%define api.prefix {gram_}
%define api.pure full
%define api.token.raw
%define api.value.type union
%define locations
%define parse.error verbose
@@ -134,8 +136,8 @@
{
/* Bison's grammar can initial empty locations, hence a default
location is needed. */
boundary_set (&@$.start, current_file, 1, 1, 1);
boundary_set (&@$.end, current_file, 1, 1, 1);
boundary_set (&@$.start, grammar_file, 1, 1, 1);
boundary_set (&@$.end, grammar_file, 1, 1, 1);
}
/* Define the tokens together with their human representation. */
@@ -181,6 +183,7 @@
PERCENT_NONDETERMINISTIC_PARSER
"%nondeterministic-parser"
PERCENT_OUTPUT "%output"
PERCENT_PURE_PARSER "%pure-parser"
PERCENT_REQUIRE "%require"
PERCENT_SKELETON "%skeleton"
PERCENT_START "%start"
@@ -192,7 +195,7 @@
%token BRACED_CODE "{...}"
%token BRACED_PREDICATE "%?{...}"
%token BRACKETED_ID "[identifier]"
%token CHAR "char"
%token CHAR "character literal"
%token COLON ":"
%token EPILOGUE "epilogue"
%token EQUAL "="
@@ -219,7 +222,7 @@
%type <uniqstr>
BRACKETED_ID ID ID_COLON
PERCENT_ERROR_VERBOSE PERCENT_FILE_PREFIX PERCENT_FLAG PERCENT_NAME_PREFIX
PERCENT_YACC
PERCENT_PURE_PARSER
TAG tag tag.opt variable
%printer { fputs ($$, yyo); } <uniqstr>
%printer { fprintf (yyo, "[%s]", $$); } BRACKETED_ID
@@ -343,11 +346,12 @@ prologue_declaration:
| "%nondeterministic-parser" { nondeterministic_parser = true; }
| "%output" STRING { spec_outfile = $2; }
| "%param" { current_param = $1; } params { current_param = param_none; }
| "%pure-parser" { handle_pure_parser (&@$, $1); }
| "%require" STRING { handle_require (&@2, $2); }
| "%skeleton" STRING { handle_skeleton (&@2, $2); }
| "%token-table" { token_table_flag = true; }
| "%verbose" { report_flag |= report_states; }
| "%yacc" { handle_yacc (&@$, $1); }
| "%yacc" { handle_yacc (&@$); }
| error ";" { current_class = unknown_sym; yyerrok; }
| /*FIXME: Err? What is this horror doing here? */ ";"
;
@@ -651,7 +655,7 @@ rhses.1:
%token PERCENT_EMPTY "%empty";
rhs:
%empty
{ grammar_current_rule_begin (current_lhs_symbol, current_lhs_location,
{ grammar_current_rule_begin (current_lhs_symbol, current_lhs_loc,
current_lhs_named_ref); }
| rhs symbol named_ref.opt
{ grammar_current_rule_symbol_append ($2, @2, $3); }
@@ -727,12 +731,24 @@ id:
{ $$ = symbol_from_uniqstr ($1, @1); }
| CHAR
{
const char *var = "api.token.raw";
if (current_class == nterm_sym)
{
gram_error (&@1,
_("character literals cannot be nonterminals"));
complain (&@1, complaint,
_("character literals cannot be nonterminals"));
YYERROR;
}
if (muscle_percent_define_ifdef (var))
{
int indent = 0;
complain_indent (&@1, complaint, &indent,
_("character literals cannot be used together"
" with %s"), var);
indent += SUB_INDENT;
location loc = muscle_percent_define_get_loc (var);
complain_indent (&loc, complaint, &indent,
_("definition of %s"), var);
}
$$ = symbol_get (char_name ($1), @1);
symbol_class_set ($$, token_sym, @1, false);
symbol_user_token_number_set ($$, $1, @1);
@@ -910,6 +926,7 @@ handle_file_prefix (location const *loc,
deprecated_directive (dir_loc, directive, "%file-prefix");
}
static void
handle_name_prefix (location const *loc,
char const *directive, char const *value)
@@ -944,36 +961,65 @@ handle_name_prefix (location const *loc,
}
static void
handle_pure_parser (location const *loc, char const *directive)
{
bison_directive (loc, directive);
deprecated_directive (loc, directive, "%define api.pure");
muscle_percent_define_insert ("api.pure", *loc, muscle_keyword, "",
MUSCLE_PERCENT_DEFINE_GRAMMAR_FILE);
}
/* Convert VERSION into an int (MAJOR * 100 + MINOR). Return -1 on
errors.
Changes of behavior are only on minor version changes, so "3.0.5"
is the same as "3.0": 300. */
static int
str_to_version (char const *version)
{
IGNORE_TYPE_LIMITS_BEGIN
int res = 0;
errno = 0;
char *cp = NULL;
long major = strtol (version, &cp, 10);
if (errno || cp == version || *cp != '.' || major < 0
|| INT_MULTIPLY_WRAPV (major, 100, &res))
return -1;
++cp;
char *cp1 = NULL;
long minor = strtol (cp, &cp1, 10);
if (errno || cp1 == cp || (*cp1 != '\0' && *cp1 != '.')
|| ! (0 <= minor && minor < 100)
|| INT_ADD_WRAPV (minor, res, &res))
return -1;
IGNORE_TYPE_LIMITS_END
return res;
}
static void
handle_require (location const *loc, char const *version)
{
/* Changes of behavior are only on minor version changes, so "3.0.5"
is the same as "3.0". */
errno = 0;
char* cp = NULL;
unsigned long major = strtoul (version, &cp, 10);
if (errno || *cp != '.')
required_version = str_to_version (version);
if (required_version == -1)
{
complain (loc, complaint, _("invalid version requirement: %s"),
version);
required_version = 0;
return;
}
++cp;
unsigned long minor = strtoul (cp, NULL, 10);
if (errno)
{
complain (loc, complaint, _("invalid version requirement: %s"),
version);
return;
}
required_version = major * 100 + minor;
/* Pretend to be at least 3.4, to check features published in 3.4
while developping it. */
const char* api_version = "3.4";
const char* package_version =
strverscmp (api_version, PACKAGE_VERSION) > 0
0 < strverscmp (api_version, PACKAGE_VERSION)
? api_version : PACKAGE_VERSION;
if (strverscmp (version, package_version) > 0)
if (0 < strverscmp (version, package_version))
{
complain (loc, complaint, _("require bison %s, but have %s"),
version, package_version);
@@ -987,16 +1033,16 @@ handle_skeleton (location const *loc, char const *skel)
char const *skeleton_user = skel;
if (strchr (skeleton_user, '/'))
{
size_t dir_length = strlen (current_file);
while (dir_length && current_file[dir_length - 1] != '/')
size_t dir_length = strlen (grammar_file);
while (dir_length && grammar_file[dir_length - 1] != '/')
--dir_length;
while (dir_length && current_file[dir_length - 1] == '/')
while (dir_length && grammar_file[dir_length - 1] == '/')
--dir_length;
char *skeleton_build =
xmalloc (dir_length + 1 + strlen (skeleton_user) + 1);
if (dir_length > 0)
{
memcpy (skeleton_build, current_file, dir_length);
memcpy (skeleton_build, grammar_file, dir_length);
skeleton_build[dir_length++] = '/';
}
strcpy (skeleton_build + dir_length, skeleton_user);
@@ -1006,26 +1052,19 @@ handle_skeleton (location const *loc, char const *skel)
skeleton_arg (skeleton_user, grammar_prio, *loc);
}
static void
handle_yacc (location const *loc, char const *directive)
{
bison_directive (loc, directive);
bool warned = false;
static void
handle_yacc (location const *loc)
{
const char *directive = "%yacc";
bison_directive (loc, directive);
if (location_empty (yacc_loc))
yacc_loc = *loc;
else
{
duplicate_directive (directive, yacc_loc, *loc);
warned = true;
}
if (!warned
&& STRNEQ (directive, "%fixed-output-files")
&& STRNEQ (directive, "%yacc"))
deprecated_directive (loc, directive, "%fixed-output-files");
duplicate_directive (directive, yacc_loc, *loc);
}
static void
gram_error (location const *loc, char const *msg)
{
@@ -1050,7 +1089,7 @@ void
current_lhs (symbol *sym, location loc, named_ref *ref)
{
current_lhs_symbol = sym;
current_lhs_location = loc;
current_lhs_loc = loc;
if (sym)
symbol_location_as_lhs_set (sym, loc);
/* In order to simplify memory management, named references for lhs
+50 -66
View File
@@ -62,7 +62,7 @@ grammar_start_symbol_set (symbol *sym, location loc)
{
start_flag = true;
startsymbol = sym;
startsymbol_location = loc;
startsymbol_loc = loc;
}
}
@@ -124,19 +124,19 @@ record_merge_function_type (int merger, uniqstr type, location declaration_loc)
aver (merge_function != NULL && merger_find == merger);
if (merge_function->type != NULL && !UNIQSTR_EQ (merge_function->type, type))
{
unsigned indent = 0;
int indent = 0;
complain_indent (&declaration_loc, complaint, &indent,
_("result type clash on merge function %s: "
"<%s> != <%s>"),
quote (merge_function->name), type,
merge_function->type);
indent += SUB_INDENT;
complain_indent (&merge_function->type_declaration_location, complaint,
complain_indent (&merge_function->type_declaration_loc, complaint,
&indent,
_("previous declaration"));
}
merge_function->type = uniqstr_new (type);
merge_function->type_declaration_location = declaration_loc;
merge_function->type_declaration_loc = declaration_loc;
}
/*--------------------------------------.
@@ -295,7 +295,7 @@ grammar_rule_check_and_complete (symbol_list *r)
char const *rhs_type =
first_rhs->content->type_name ? first_rhs->content->type_name : "";
if (!UNIQSTR_EQ (lhs_type, rhs_type))
complain (&r->location, Wother,
complain (&r->rhs_loc, Wother,
_("type clash on default action: <%s> != <%s>"),
lhs_type, rhs_type);
else
@@ -308,7 +308,7 @@ grammar_rule_check_and_complete (symbol_list *r)
if (is_cxx)
{
code_props_rule_action_init (&r->action_props, "{ $$ = $1; }",
r->location, r,
r->rhs_loc, r,
/* name */ NULL,
/* type */ NULL,
/* is_predicate */ false);
@@ -318,7 +318,7 @@ grammar_rule_check_and_complete (symbol_list *r)
}
/* Warn if there is no default for $$ but we need one. */
else
complain (&r->location, Wother,
complain (&r->rhs_loc, Wother,
_("empty rule for typed nonterminal, and no action"));
}
@@ -335,9 +335,9 @@ grammar_rule_check_and_complete (symbol_list *r)
{
warnings warn_flag = midrule_warning ? Wmidrule_values : Wother;
if (n)
complain (&l->location, warn_flag, _("unused value: $%d"), n);
complain (&l->sym_loc, warn_flag, _("unused value: $%d"), n);
else
complain (&l->location, warn_flag, _("unset value: $$"));
complain (&l->rhs_loc, warn_flag, _("unset value: $$"));
}
}
}
@@ -357,9 +357,12 @@ grammar_rule_check_and_complete (symbol_list *r)
&& !r->percent_empty_loc.start.file
&& warning_is_enabled (Wempty_rule))
{
complain (&r->location, Wempty_rule,
_("empty rule without %%empty"));
fixits_register (&r->location, " %empty ");
complain (&r->rhs_loc, Wempty_rule, _("empty rule without %%empty"));
if (feature_flag & feature_caret)
location_caret_suggestion (r->rhs_loc, "%empty", stderr);
location loc = r->rhs_loc;
loc.end = loc.start;
fixits_register (&loc, " %empty ");
}
/* See comments in grammar_current_rule_prec_set for how POSIX
@@ -369,12 +372,12 @@ grammar_rule_check_and_complete (symbol_list *r)
&& r->ruleprec->tag[0] != '\'' && r->ruleprec->tag[0] != '"'
&& r->ruleprec->content->status != declared
&& !r->ruleprec->content->prec)
complain (&r->location, Wother,
complain (&r->rhs_loc, Wother,
_("token for %%prec is not defined: %s"), r->ruleprec->tag);
/* Check that the (main) action was not typed. */
if (r->action_props.type)
complain (&r->location, Wother,
complain (&r->rhs_loc, Wother,
_("only midrule actions can be typed: %s"), r->action_props.type);
}
@@ -387,8 +390,8 @@ void
grammar_current_rule_end (location loc)
{
/* Put an empty link in the list to mark the end of this rule */
grammar_symbol_append (NULL, grammar_end->location);
current_rule->location = loc;
grammar_symbol_append (NULL, grammar_end->rhs_loc);
current_rule->rhs_loc = loc;
}
@@ -408,11 +411,11 @@ grammar_midrule_action (void)
/* Make a DUMMY nonterminal, whose location is that of the midrule
action. Create the MIDRULE. */
location dummy_location = current_rule->action_props.location;
symbol *dummy = dummy_symbol_get (dummy_location);
location dummy_loc = current_rule->action_props.location;
symbol *dummy = dummy_symbol_get (dummy_loc);
symbol_type_set(dummy,
current_rule->action_props.type, current_rule->action_props.location);
symbol_list *midrule = symbol_list_sym_new (dummy, dummy_location);
symbol_list *midrule = symbol_list_sym_new (dummy, dummy_loc);
/* Remember named_ref of previous action. */
named_ref *action_name = current_rule->action_props.named_ref;
@@ -422,7 +425,7 @@ grammar_midrule_action (void)
++nrules;
++nritems;
/* Attach its location and actions to that of the DUMMY. */
midrule->location = dummy_location;
midrule->rhs_loc = dummy_loc;
code_props_rule_action_init (&midrule->action_props,
current_rule->action_props.code,
current_rule->action_props.location,
@@ -443,14 +446,14 @@ grammar_midrule_action (void)
grammar = midrule;
/* End the dummy's rule. */
midrule->next = symbol_list_sym_new (NULL, dummy_location);
midrule->next = symbol_list_sym_new (NULL, dummy_loc);
midrule->next->next = current_rule;
previous_rule_end = midrule->next;
/* Insert the dummy nonterminal replacing the midrule action into
the current rule. Bind it to its dedicated rule. */
grammar_current_rule_symbol_append (dummy, dummy_location,
grammar_current_rule_symbol_append (dummy, dummy_loc,
action_name);
grammar_end->midrule = midrule;
midrule->midrule_parent_rule = current_rule;
@@ -509,11 +512,11 @@ grammar_current_rule_dprec_set (int dprec, location loc)
"%dprec");
else if (current_rule->dprec != 0)
duplicate_rule_directive ("%dprec",
current_rule->dprec_location, loc);
current_rule->dprec_loc, loc);
else
{
current_rule->dprec = dprec;
current_rule->dprec_location = loc;
current_rule->dprec_loc = loc;
}
}
@@ -528,11 +531,11 @@ grammar_current_rule_merge_set (uniqstr name, location loc)
"%merge");
if (current_rule->merger != 0)
duplicate_rule_directive ("%merge",
current_rule->merger_declaration_location, loc);
current_rule->merger_declaration_loc, loc);
else
{
current_rule->merger = get_merge_function (name);
current_rule->merger_declaration_location = loc;
current_rule->merger_declaration_loc = loc;
}
}
@@ -602,15 +605,14 @@ grammar_current_rule_expect_rr (int count, location loc)
}
/*---------------------------------------------------------------.
| Convert the rules into the representation using RRHS, RLHS and |
| RITEM. |
`---------------------------------------------------------------*/
/*---------------------------------------------.
| Build RULES and RITEM from what was parsed. |
`---------------------------------------------*/
static void
packgram (void)
{
unsigned itemno = 0;
int itemno = 0;
ritem = xnmalloc (nritems + 1, sizeof *ritem);
/* This sentinel is used by build_relations in gram.c. */
*ritem++ = 0;
@@ -622,7 +624,7 @@ packgram (void)
{
symbol_list *lhs = p;
record_merge_function_type (lhs->merger, lhs->content.sym->content->type_name,
lhs->merger_declaration_location);
lhs->merger_declaration_loc);
/* If the midrule's $$ is set or its $n is used, remove the '$' from the
symbol name so that it's a user-defined symbol so that the default
%destructor and %printer apply. */
@@ -647,10 +649,10 @@ packgram (void)
rules[ruleno].dprec = lhs->dprec;
rules[ruleno].merger = lhs->merger;
rules[ruleno].precsym = NULL;
rules[ruleno].location = lhs->location;
rules[ruleno].location = lhs->rhs_loc;
rules[ruleno].useful = true;
rules[ruleno].action = lhs->action_props.code;
rules[ruleno].action_location = lhs->action_props.location;
rules[ruleno].action_loc = lhs->action_props.location;
rules[ruleno].is_predicate = lhs->action_props.is_predicate;
rules[ruleno].expected_sr_conflicts = lhs->expected_sr_conflicts;
rules[ruleno].expected_rr_conflicts = lhs->expected_rr_conflicts;
@@ -698,7 +700,8 @@ packgram (void)
if (trace_flag & trace_sets)
ritem_print (stderr);
}
/*------------------------------------------------------------------.
| Read in the grammar specification and record it in the format |
| described in gram.h. All actions are copied into ACTION_OBSTACK, |
@@ -707,39 +710,20 @@ packgram (void)
`------------------------------------------------------------------*/
void
reader (void)
reader (const char *gram)
{
/* Initialize the symbol table. */
/* Set up symbol_table, semantic_type_table, and the built-in
symbols. */
symbols_new ();
/* Construct the accept symbol. */
accept = symbol_get ("$accept", empty_location);
accept->content->class = nterm_sym;
accept->content->number = nvars++;
/* Construct the error token */
errtoken = symbol_get ("error", empty_location);
errtoken->content->class = token_sym;
errtoken->content->number = ntokens++;
/* Construct a token that represents all undefined literal tokens.
It is always token number 2. */
undeftoken = symbol_get ("$undefined", empty_location);
undeftoken->content->class = token_sym;
undeftoken->content->number = ntokens++;
gram_in = xfopen (grammar_file, "r");
gram__flex_debug = trace_flag & trace_scan;
gram_debug = trace_flag & trace_parse;
gram_scanner_initialize ();
gram_scanner_open (gram);
gram_parse ();
gram_scanner_close ();
prepare_percent_define_front_end_variables ();
if (complaint_status < status_complaint)
check_and_convert_grammar ();
xfclose (gram_in);
}
static void
@@ -801,7 +785,7 @@ check_and_convert_grammar (void)
/* If the user did not define her ENDTOKEN, do it now. */
if (!endtoken)
{
endtoken = symbol_get ("$end", empty_location);
endtoken = symbol_get ("$end", empty_loc);
endtoken->content->class = token_sym;
endtoken->content->number = 0;
/* Value specified by POSIX. */
@@ -823,11 +807,11 @@ check_and_convert_grammar (void)
$accept: %start $end. */
{
symbol_list *p = symbol_list_sym_new (accept, empty_location);
p->location = grammar->location;
p->next = symbol_list_sym_new (startsymbol, empty_location);
p->next->next = symbol_list_sym_new (endtoken, empty_location);
p->next->next->next = symbol_list_sym_new (NULL, empty_location);
symbol_list *p = symbol_list_sym_new (accept, empty_loc);
p->rhs_loc = grammar->rhs_loc;
p->next = symbol_list_sym_new (startsymbol, empty_loc);
p->next->next = symbol_list_sym_new (endtoken, empty_loc);
p->next->next->next = symbol_list_sym_new (NULL, empty_loc);
p->next->next->next->next = grammar;
nrules += 1;
nritems += 3;
+2 -2
View File
@@ -32,7 +32,7 @@ typedef struct merger_list
struct merger_list* next;
uniqstr name;
uniqstr type;
location type_declaration_location;
location type_declaration_loc;
} merger_list;
/* From the parser. */
@@ -60,7 +60,7 @@ void grammar_current_rule_action_append (const char *action, location loc,
named_ref *nref, uniqstr tag);
/* Attach a PREDICATE to the current rule. */
void grammar_current_rule_predicate_append (const char *predicate, location loc);
void reader (void);
void reader (const char *gram);
void free_merger_functions (void);
extern merger_list *merge_functions;
+5 -5
View File
@@ -52,8 +52,8 @@ static bitset V;
'useless', but no warning should be issued). */
static bitset V1;
unsigned nuseless_productions;
unsigned nuseless_nonterminals;
int nuseless_productions;
int nuseless_nonterminals;
#define bitset_swap(Lhs, Rhs) \
do { \
@@ -195,10 +195,10 @@ inaccessable_symbols (void)
bitset_free (P);
P = Pp;
unsigned nuseful_productions = bitset_count (P);
int nuseful_productions = bitset_count (P);
nuseless_productions = nrules - nuseful_productions;
unsigned nuseful_nonterminals = 0;
int nuseful_nonterminals = 0;
for (symbol_number i = ntokens; i < nsyms; ++i)
nuseful_nonterminals += bitset_test (V, i);
nuseless_nonterminals = nvars - nuseful_nonterminals;
@@ -382,7 +382,7 @@ reduce_grammar (void)
reduce_print ();
if (!bitset_test (N, accept->content->number - ntokens))
complain (&startsymbol_location, fatal,
complain (&startsymbol_loc, fatal,
_("start symbol %s does not derive any sentence"),
startsymbol->tag);
+2 -2
View File
@@ -36,7 +36,7 @@ void reduce_free (void);
* reduce_grammar. Size nvars + nuseless_nonterminals. */
extern symbol_number *nterm_map;
extern unsigned nuseless_nonterminals;
extern unsigned nuseless_productions;
extern int nuseless_nonterminals;
extern int nuseless_productions;
#endif /* !REDUCE_H_ */
+3 -3
View File
@@ -33,14 +33,14 @@ relation_print (const char *title,
{
if (title)
fprintf (out, "%s:\n", title);
for (size_t i = 0; i < size; ++i)
for (relation_node i = 0; i < size; ++i)
if (r[i])
{
fputs (" ", out);
if (print)
print (i, out);
else
fprintf (out, "%3lu", (unsigned long) i);
fprintf (out, "%3ld", (long) i);
fputc (':', out);
for (relation_node j = 0; r[i][j] != END_NODE; ++j)
{
@@ -48,7 +48,7 @@ relation_print (const char *title,
if (print)
print (r[i][j], out);
else
fprintf (out, "%3lu", (unsigned long) r[i][j]);
fprintf (out, "%3ld", (long) r[i][j]);
}
fputc ('\n', out);
}
+46 -45
View File
@@ -48,17 +48,18 @@ YY_DECL;
#define YY_USER_ACTION location_compute (loc, &loc->end, yytext, yyleng);
static char *fetch_type_name (char *cp, char const **type_name,
location dollar_loc);
const location *dollar_loc);
static void handle_action_dollar (symbol_list *rule, char *cp,
location dollar_loc);
static void handle_action_at (symbol_list *rule, char *cp, location at_loc);
const location *dollar_loc);
static void handle_action_at (symbol_list *rule, char *cp,
const location *at_loc);
/* A string to be pushed to obstack after dollar/at has been handled. */
static char *ref_tail_fields;
static location the_location;
static location *loc = &the_location;
static location current_loc;
static location *loc = &current_loc;
/* A string representing the most recent translation. */
static char *last_string;
@@ -163,13 +164,13 @@ ref -?[0-9]+|{id}|"["{id}"]"|"$"
{
"$"("<"{tag}">")?{ref} {
ref_tail_fields = NULL;
handle_action_dollar (self->rule, yytext, *loc);
handle_action_dollar (self->rule, yytext, loc);
if (ref_tail_fields)
obstack_sgrow (&obstack_for_string, ref_tail_fields);
}
"@"{ref} {
ref_tail_fields = NULL;
handle_action_at (self->rule, yytext, *loc);
handle_action_at (self->rule, yytext, loc);
if (ref_tail_fields)
obstack_sgrow (&obstack_for_string, ref_tail_fields);
}
@@ -179,7 +180,7 @@ ref -?[0-9]+|{id}|"["{id}"]"|"$"
{
"$"("<"{tag}">")?"$" {
const char *type_name = NULL;
fetch_type_name (yytext + 1, &type_name, *loc)[-1] = 0;
fetch_type_name (yytext + 1, &type_name, loc)[-1] = 0;
obstack_sgrow (&obstack_for_string, "]b4_dollar_dollar(");
obstack_quote (&obstack_for_string, type_name);
obstack_sgrow (&obstack_for_string, ")[");
@@ -187,7 +188,7 @@ ref -?[0-9]+|{id}|"["{id}"]"|"$"
}
"@$" {
obstack_sgrow (&obstack_for_string, "]b4_at_dollar[");
muscle_percent_define_ensure("locations", the_location, true);
muscle_percent_define_ensure("locations", *loc, true);
}
}
@@ -215,14 +216,14 @@ is_dot_or_dash (char ch)
static inline bool
contains_dot_or_dash (const char* p)
{
return strpbrk(p, ".-");
return !!strpbrk (p, ".-");
}
/* Defines a variant of a symbolic name resolution. */
typedef struct
{
/* Index in symbol list. */
unsigned symbol_index;
int symbol_index;
/* Matched symbol id and loc. */
uniqstr id;
@@ -249,8 +250,8 @@ typedef struct
#define VARIANT_NOT_VISIBLE_FROM_MIDRULE (1 << 2)
static variant *variant_table = NULL;
static unsigned variant_table_size = 0;
static unsigned variant_count = 0;
static int variant_table_size = 0;
static int variant_count = 0;
static variant *
variant_table_grow (void)
@@ -285,7 +286,7 @@ find_prefix_end (char const *prefix, char const *cp, char const *end)
}
static variant *
variant_add (uniqstr id, location id_loc, unsigned symbol_index,
variant_add (uniqstr id, location id_loc, int symbol_index,
char const *cp, char const *cp_end, bool explicit_bracketing)
{
char const *prefix_end = find_prefix_end (id, cp, cp_end);
@@ -306,7 +307,7 @@ variant_add (uniqstr id, location id_loc, unsigned symbol_index,
}
static const char *
get_at_spec(unsigned symbol_index)
get_at_spec(int symbol_index)
{
static char at_buf[20];
if (symbol_index == 0)
@@ -320,7 +321,7 @@ static void
show_sub_message (warnings warning,
const char* cp, bool explicit_bracketing,
int midrule_rhs_index, char dollar_or_at,
unsigned indent, const variant *var)
int indent, const variant *var)
{
const char *at_spec = get_at_spec (var->symbol_index);
@@ -384,9 +385,9 @@ static void
show_sub_messages (warnings warning,
const char* cp, bool explicit_bracketing,
int midrule_rhs_index, char dollar_or_at,
unsigned indent)
int indent)
{
for (unsigned i = 0; i < variant_count; ++i)
for (int i = 0; i < variant_count; ++i)
show_sub_message (warning | silent,
cp, explicit_bracketing,
midrule_rhs_index, dollar_or_at,
@@ -406,7 +407,7 @@ show_sub_messages (warnings warning,
accesses. */
static long
parse_ref (char *cp, symbol_list *rule, int rule_length,
int midrule_rhs_index, char *text, location text_loc,
int midrule_rhs_index, char *text, const location *text_loc,
char dollar_or_at)
{
if ('$' == *cp)
@@ -419,7 +420,7 @@ parse_ref (char *cp, symbol_list *rule, int rule_length,
return num;
else
{
complain (&text_loc, complaint, _("integer out of range: %s"),
complain (text_loc, complaint, _("integer out of range: %s"),
quote (text));
return INVALID_REF;
}
@@ -436,7 +437,7 @@ parse_ref (char *cp, symbol_list *rule, int rule_length,
/* Add all relevant variants. */
{
unsigned symbol_index;
int symbol_index;
symbol_list *l;
variant_count = 0;
for (symbol_index = 0, l = rule; !symbol_list_null (l);
@@ -458,12 +459,12 @@ parse_ref (char *cp, symbol_list *rule, int rule_length,
}
/* Check errors. */
unsigned valid_variants = 0;
unsigned valid_variant_index = 0;
for (unsigned i = 0; i < variant_count; ++i)
int valid_variants = 0;
int valid_variant_index = 0;
for (int i = 0; i < variant_count; ++i)
{
variant *var = &variant_table[i];
unsigned symbol_index = var->symbol_index;
int symbol_index = var->symbol_index;
/* Check visibility from midrule actions. */
if (midrule_rhs_index != 0
@@ -489,16 +490,16 @@ parse_ref (char *cp, symbol_list *rule, int rule_length,
{
case 0:
{
unsigned len = (explicit_bracketing || !ref_tail_fields) ?
int len = (explicit_bracketing || !ref_tail_fields) ?
cp_end - cp : ref_tail_fields - cp;
unsigned indent = 0;
int indent = 0;
complain_indent (&text_loc, complaint, &indent,
complain_indent (text_loc, complaint, &indent,
_("invalid reference: %s"), quote (text));
indent += SUB_INDENT;
if (len == 0)
{
location sym_loc = text_loc;
location sym_loc = *text_loc;
sym_loc.start.column += 1;
sym_loc.end = sym_loc.start;
complain_indent (&sym_loc, complaint, &indent,
@@ -507,12 +508,12 @@ parse_ref (char *cp, symbol_list *rule, int rule_length,
dollar_or_at);
}
else if (midrule_rhs_index)
complain_indent (&rule->location, complaint, &indent,
complain_indent (&rule->rhs_loc, complaint, &indent,
_("symbol not found in production before $%d: "
"%.*s"),
midrule_rhs_index, len, cp);
else
complain_indent (&rule->location, complaint, &indent,
complain_indent (&rule->rhs_loc, complaint, &indent,
_("symbol not found in production: %.*s"),
len, cp);
@@ -524,17 +525,17 @@ parse_ref (char *cp, symbol_list *rule, int rule_length,
}
case 1:
{
unsigned indent = 0;
int indent = 0;
if (variant_count > 1)
{
complain_indent (&text_loc, Wother, &indent,
complain_indent (text_loc, Wother, &indent,
_("misleading reference: %s"), quote (text));
show_sub_messages (Wother,
cp, explicit_bracketing, midrule_rhs_index,
dollar_or_at, indent + SUB_INDENT);
}
{
unsigned symbol_index =
int symbol_index =
variant_table[valid_variant_index].symbol_index;
return (symbol_index == midrule_rhs_index) ? LHS_REF : symbol_index;
}
@@ -542,8 +543,8 @@ parse_ref (char *cp, symbol_list *rule, int rule_length,
case 2:
default:
{
unsigned indent = 0;
complain_indent (&text_loc, complaint, &indent,
int indent = 0;
complain_indent (text_loc, complaint, &indent,
_("ambiguous reference: %s"), quote (text));
show_sub_messages (complaint,
cp, explicit_bracketing, midrule_rhs_index,
@@ -566,7 +567,7 @@ int max_left_semantic_context = 0;
static
char *
fetch_type_name (char *cp, char const **type_name,
location dollar_loc)
const location *dollar_loc)
{
if (*cp == '<')
{
@@ -579,7 +580,7 @@ fetch_type_name (char *cp, char const **type_name,
'text' is needed for error messages. */
++cp;
if (untyped_var_seen)
complain (&dollar_loc, complaint,
complain (dollar_loc, complaint,
_("explicit type given in untyped grammar"));
tag_seen = true;
}
@@ -595,7 +596,7 @@ fetch_type_name (char *cp, char const **type_name,
`------------------------------------------------------------------*/
static void
handle_action_dollar (symbol_list *rule, char *text, location dollar_loc)
handle_action_dollar (symbol_list *rule, char *text, const location *dollar_loc)
{
symbol_list *effective_rule;
int effective_rule_length;
@@ -634,13 +635,13 @@ handle_action_dollar (symbol_list *rule, char *text, location dollar_loc)
if (union_seen || tag_seen)
{
if (rule->midrule_parent_rule)
complain (&dollar_loc, complaint,
complain (dollar_loc, complaint,
_("$$ for the midrule at $%d of %s"
" has no declared type"),
rule->midrule_parent_rhs_index,
quote (effective_rule->content.sym->tag));
else
complain (&dollar_loc, complaint,
complain (dollar_loc, complaint,
_("$$ of %s has no declared type"),
quote (rule->content.sym->tag));
}
@@ -666,7 +667,7 @@ handle_action_dollar (symbol_list *rule, char *text, location dollar_loc)
&& (!sym || !sym->content.sym->content->type_name))
{
if (union_seen || tag_seen)
complain (&dollar_loc, complaint,
complain (dollar_loc, complaint,
_("$%s of %s has no declared type"), cp,
quote (effective_rule->content.sym->tag));
else
@@ -689,7 +690,7 @@ handle_action_dollar (symbol_list *rule, char *text, location dollar_loc)
{
if (muscle_percent_define_ifdef ("api.value.automove")
&& sym->action_props.is_value_used)
complain (&dollar_loc, Wother,
complain (dollar_loc, Wother,
_("multiple occurrences of $%d with api.value.automove"),
n);
sym->action_props.is_value_used = true;
@@ -706,7 +707,7 @@ handle_action_dollar (symbol_list *rule, char *text, location dollar_loc)
`------------------------------------------------------*/
static void
handle_action_at (symbol_list *rule, char *text, location at_loc)
handle_action_at (symbol_list *rule, char *text, const location *at_loc)
{
symbol_list *effective_rule;
int effective_rule_length;
@@ -722,7 +723,7 @@ handle_action_at (symbol_list *rule, char *text, location at_loc)
effective_rule_length = symbol_list_length (rule->next);
}
muscle_percent_define_ensure("locations", at_loc, true);
muscle_percent_define_ensure ("locations", *at_loc, true);
int n = parse_ref (text + 1, effective_rule, effective_rule_length,
rule->midrule_parent_rhs_index, text, at_loc, '@');
+6 -9
View File
@@ -21,18 +21,15 @@
#ifndef SCAN_GRAM_H_
# define SCAN_GRAM_H_
/* From the scanner. */
extern FILE *gram_in;
extern int gram__flex_debug;
void gram_scanner_initialize (void);
/* Initialize the scanner to read file GRAM. */
void gram_scanner_open (const char *gram);
/* Close the open files. */
void gram_scanner_close (void);
/* Free all the memory allocated to the scanner. */
void gram_scanner_free (void);
void gram_scanner_last_string_free (void);
/* These are declared by the scanner, but not used. We put them here
to pacify "make syntax-check". */
extern FILE *gram_out;
extern int gram_lineno;
# define GRAM_LEX_DECL int gram_lex (GRAM_STYPE *val, location *loc)
GRAM_LEX_DECL;
+59 -97
View File
@@ -21,6 +21,8 @@
%option prefix="gram_" outfile="lex.yy.c"
%{
#include <errno.h>
#include <c-ctype.h>
#include <mbswidth.h>
#include <quote.h>
@@ -49,9 +51,6 @@ static boundary scanner_cursor;
#define YY_USER_ACTION location_compute (loc, &scanner_cursor, yytext, yyleng);
static size_t no_cr_read (FILE *, char *, size_t);
#define YY_INPUT(buf, result, size) ((result) = no_cr_read (yyin, buf, size))
/* Report that yytext is an extension, and evaluate to its token type. */
#define BISON_DIRECTIVE(Directive) \
(bison_directive (loc, yytext), PERCENT_ ## Directive)
@@ -84,6 +83,9 @@ static size_t no_cr_read (FILE *, char *, size_t);
unput (Msg[i - 1]); \
} while (0)
/* The current file name. Might change with #line. */
static uniqstr current_file = NULL;
/* A string representing the most recently saved token. */
static char *last_string = NULL;
@@ -100,7 +102,7 @@ gram_scanner_last_string_free (void)
}
static void handle_syncline (char *, location);
static unsigned long scan_integer (char const *p, int base, location loc);
static int scan_integer (char const *p, int base, location loc);
static int convert_ucn_to_byte (char const *hex_text);
static void unexpected_eof (boundary, char const *);
static void unexpected_newline (boundary, char const *);
@@ -139,12 +141,14 @@ id {letter}({letter}|[-0-9])*
int [0-9]+
xint 0[xX][0-9abcdefABCDEF]+
eol \n|\r\n
/* UTF-8 Encoded Unicode Code Point, from Flex's documentation. */
mbchar [\x09\x0A\x0D\x20-\x7E]|[\xC2-\xDF][\x80-\xBF]|\xE0[\xA0-\xBF][\x80-\xBF]|[\xE1-\xEC\xEE\xEF]([\x80-\xBF]{2})|\xED[\x80-\x9F][\x80-\xBF]|\xF0[\x\90-\xBF]([\x80-\xBF]{2})|[\xF1-\xF3]([\x80-\xBF]{3})|\xF4[\x80-\x8F]([\x80-\xBF]{2})
/* Zero or more instances of backslash-newline. Following GCC, allow
white space between the backslash and the newline. */
splice (\\[ \f\t\v]*\n)*
splice (\\[ \f\t\v]*{eol})*
/* An equal sign, with optional leading whitespaces. This is used in some
deprecated constructs. */
@@ -161,7 +165,7 @@ eqopt ({sp}=)?
int context_state PACIFY_CC (= 0);
/* Location of most recent identifier, when applicable. */
location id_loc PACIFY_CC (= empty_location);
location id_loc PACIFY_CC (= empty_loc);
/* Where containing code started, when applicable. Its initial
value is relevant only when yylex is invoked in the SC_EPILOGUE
@@ -193,7 +197,7 @@ eqopt ({sp}=)?
"," {
complain (loc, Wother, _("stray ',' treated as white space"));
}
[ \f\n\t\v] |
[ \f\t\v\r]|{eol} |
"//".* continue;
"/*" {
token_start = loc->start;
@@ -201,9 +205,7 @@ eqopt ({sp}=)?
BEGIN SC_YACC_COMMENT;
}
/* #line directives are not documented, and may be withdrawn or
modified in future versions of Bison. */
^"#line "{int}(" \"".*"\"")?"\n" {
^"#line "{int}(" \"".*"\"")?{eol} {
handle_syncline (yytext + sizeof "#line " - 1, *loc);
}
}
@@ -233,7 +235,6 @@ eqopt ({sp}=)?
"%expect" return BISON_DIRECTIVE (EXPECT);
"%expect-rr" return BISON_DIRECTIVE (EXPECT_RR);
"%file-prefix" RETURN_VALUE (PERCENT_FILE_PREFIX, uniqstr_new (yytext));
"%fixed-output-files" RETURN_VALUE (PERCENT_YACC, uniqstr_new (yytext));
"%initial-action" return BISON_DIRECTIVE (INITIAL_ACTION);
"%glr-parser" return BISON_DIRECTIVE (GLR_PARSER);
"%language" return BISON_DIRECTIVE (LANGUAGE);
@@ -252,7 +253,6 @@ eqopt ({sp}=)?
"%prec" return PERCENT_PREC;
"%precedence" return BISON_DIRECTIVE (PRECEDENCE);
"%printer" return BISON_DIRECTIVE (PRINTER);
"%pure-parser" RETURN_PERCENT_FLAG ("api.pure");
"%require" return BISON_DIRECTIVE (REQUIRE);
"%right" return PERCENT_RIGHT;
"%skeleton" return BISON_DIRECTIVE (SKELETON);
@@ -263,7 +263,11 @@ eqopt ({sp}=)?
"%type" return PERCENT_TYPE;
"%union" return PERCENT_UNION;
"%verbose" return BISON_DIRECTIVE (VERBOSE);
"%yacc" RETURN_VALUE (PERCENT_YACC, uniqstr_new (yytext));
"%yacc" return PERCENT_YACC;
/* Deprecated since Bison 2.3b (2008-05-27), but the warning is
issued only since Bison 3.4. */
"%pure"[-_]"parser" RETURN_VALUE (PERCENT_PURE_PARSER, uniqstr_new (yytext));
/* Deprecated since Bison 3.0 (2013-07-25), but the warning is
issued only since Bison 3.3. */
@@ -278,11 +282,10 @@ eqopt ({sp}=)?
"%error"[-_]"verbose" RETURN_VALUE (PERCENT_ERROR_VERBOSE, uniqstr_new (yytext));
"%expect"[-_]"rr" DEPRECATED ("%expect-rr");
"%file-prefix"{eqopt} RETURN_VALUE (PERCENT_FILE_PREFIX, uniqstr_new (yytext));
"%fixed"[-_]"output"[-_]"files" RETURN_VALUE (PERCENT_YACC, uniqstr_new (yytext));
"%fixed"[-_]"output"[-_]"files" DEPRECATED ("%output \"y.tab.c\"");
"%no"[-_]"default"[-_]"prec" DEPRECATED ("%no-default-prec");
"%no"[-_]"lines" DEPRECATED ("%no-lines");
"%output"{eqopt} DEPRECATED ("%output");
"%pure"[-_]"parser" DEPRECATED ("%pure-parser");
"%token"[-_]"table" DEPRECATED ("%token-table");
"%"{id} {
@@ -328,7 +331,7 @@ eqopt ({sp}=)?
}
/* Semantic predicate. */
"%?"[ \f\n\t\v]*"{" {
"%?"([ \f\t\v]|{eol})*"{" {
nesting = 0;
code_start = loc->start;
BEGIN SC_PREDICATE;
@@ -357,7 +360,7 @@ eqopt ({sp}=)?
BEGIN SC_BRACKETED_ID;
}
[^\[%A-Za-z0-9_<>{}\"\'*;|=/, \f\n\t\v]+|. {
[^\[%A-Za-z0-9_<>{}\"\'*;|=/, \f\r\n\t\v]+|. {
complain (loc, complaint, "%s: %s",
ngettext ("invalid character", "invalid characters", yyleng),
quote_mem (yytext, yyleng));
@@ -456,7 +459,7 @@ eqopt ({sp}=)?
complain (loc, complaint, _("an identifier expected"));
}
[^\].A-Za-z0-9_/ \f\n\t\v]+|. {
[^\].A-Za-z0-9_/ \f\r\n\t\v]+|. {
complain (loc, complaint, "%s: %s",
ngettext ("invalid character in bracketed name",
"invalid characters in bracketed name", yyleng),
@@ -489,7 +492,7 @@ eqopt ({sp}=)?
<SC_YACC_COMMENT>
{
"*/" BEGIN context_state;
.|\n continue;
.|{eol} continue;
<<EOF>> unexpected_eof (token_start, "*/"); BEGIN context_state;
}
@@ -511,7 +514,7 @@ eqopt ({sp}=)?
<SC_LINE_COMMENT>
{
"\n" STRING_GROW; BEGIN context_state;
{eol} STRING_GROW; BEGIN context_state;
{splice} STRING_GROW;
<<EOF>> BEGIN context_state;
}
@@ -533,7 +536,7 @@ eqopt ({sp}=)?
RETURN_VALUE (STRING, last_string);
}
<<EOF>> unexpected_eof (token_start, "\"");
"\n" unexpected_newline (token_start, "\"");
{eol} unexpected_newline (token_start, "\"");
}
/*----------------------------------------------------------.
@@ -562,7 +565,7 @@ eqopt ({sp}=)?
BEGIN INITIAL;
return CHAR;
}
"\n" unexpected_newline (token_start, "'");
{eol} unexpected_newline (token_start, "'");
<<EOF>> unexpected_eof (token_start, "'");
}
@@ -602,22 +605,22 @@ eqopt ({sp}=)?
{
\\[0-7]{1,3} {
verify (UCHAR_MAX < ULONG_MAX);
unsigned long c = strtoul (yytext + 1, NULL, 8);
if (!c || UCHAR_MAX < c)
long c = strtol (yytext + 1, NULL, 8);
if (0 < c && c <= UCHAR_MAX)
obstack_1grow (&obstack_for_string, c);
else
complain (loc, complaint, _("invalid number after \\-escape: %s"),
yytext+1);
else
obstack_1grow (&obstack_for_string, c);
}
\\x[0-9abcdefABCDEF]+ {
verify (UCHAR_MAX < ULONG_MAX);
unsigned long c = strtoul (yytext + 2, NULL, 16);
if (!c || UCHAR_MAX < c)
long c = strtol (yytext + 2, NULL, 16);
if (0 < c && c <= UCHAR_MAX)
obstack_1grow (&obstack_for_string, c);
else
complain (loc, complaint, _("invalid number after \\-escape: %s"),
yytext+1);
else
obstack_1grow (&obstack_for_string, c);
}
\\a obstack_1grow (&obstack_for_string, '\a');
@@ -639,7 +642,7 @@ eqopt ({sp}=)?
else
obstack_1grow (&obstack_for_string, c);
}
\\(.|\n) {
\\(.|{eol}) {
char const *p = yytext + 1;
/* Quote only if escaping won't make the character visible. */
if (c_isspace ((unsigned char) *p) && c_isprint ((unsigned char) *p))
@@ -663,14 +666,14 @@ eqopt ({sp}=)?
<SC_CHARACTER>
{
"'" STRING_GROW; BEGIN context_state;
\n unexpected_newline (token_start, "'");
{eol} unexpected_newline (token_start, "'");
<<EOF>> unexpected_eof (token_start, "'");
}
<SC_STRING>
{
"\"" STRING_GROW; BEGIN context_state;
\n unexpected_newline (token_start, "\"");
{eol} unexpected_newline (token_start, "\"");
<<EOF>> unexpected_eof (token_start, "\"");
}
@@ -807,59 +810,12 @@ eqopt ({sp}=)?
%%
/* Read bytes from FP into buffer BUF of size SIZE. Return the
number of bytes read. Remove '\r' from input, treating \r\n
and isolated \r as \n. */
static size_t
no_cr_read (FILE *fp, char *buf, size_t size)
{
size_t bytes_read = fread (buf, 1, size, fp);
if (bytes_read)
{
char *w = memchr (buf, '\r', bytes_read);
if (w)
{
char const *r = ++w;
char const *lim = buf + bytes_read;
for (;;)
{
/* Found an '\r'. Treat it like '\n', but ignore any
'\n' that immediately follows. */
w[-1] = '\n';
if (r == lim)
{
int ch = getc (fp);
if (ch != '\n' && ungetc (ch, fp) != ch)
break;
}
else if (*r == '\n')
r++;
/* Copy until the next '\r'. */
do
{
if (r == lim)
return w - buf;
}
while ((*w++ = *r++) != '\r');
}
return w - buf;
}
}
return bytes_read;
}
/*------------------------------------------------------.
| Scan NUMBER for a base-BASE integer at location LOC. |
`------------------------------------------------------*/
static unsigned long
static int
scan_integer (char const *number, int base, location loc)
{
verify (INT_MAX < ULONG_MAX);
@@ -867,9 +823,10 @@ scan_integer (char const *number, int base, location loc)
complain (&loc, Wyacc,
_("POSIX Yacc does not support hexadecimal literals"));
unsigned long num = strtoul (number, NULL, base);
errno = 0;
long num = strtol (number, NULL, base);
if (INT_MAX < num)
if (! (0 <= num && num <= INT_MAX && errno == 0))
{
complain (&loc, complaint, _("integer out of range: %s"),
quote (number));
@@ -890,7 +847,7 @@ static int
convert_ucn_to_byte (char const *ucn)
{
verify (UCHAR_MAX <= INT_MAX);
unsigned long code = strtoul (ucn + 2, NULL, 16);
long code = strtol (ucn + 2, NULL, 16);
/* FIXME: Currently we assume Unicode-compatible unibyte characters
on ASCII hosts (i.e., Latin-1 on hosts with 8-bit bytes). On
@@ -898,7 +855,7 @@ convert_ucn_to_byte (char const *ucn)
These limitations should be removed once we add support for
multibyte characters. */
if (UCHAR_MAX < code)
if (! (0 <= code && code <= UCHAR_MAX))
return -1;
#if ! ('$' == 0x24 && '@' == 0x40 && '`' == 0x60 && '~' == 0x7e)
@@ -945,8 +902,9 @@ static void
handle_syncline (char *args, location loc)
{
char *file;
unsigned long lineno = strtoul (args, &file, 10);
if (INT_MAX <= lineno)
errno = 0;
long lineno = strtol (args, &file, 10);
if (! (0 <= lineno && lineno <= INT_MAX && errno == 0))
{
complain (&loc, Wother, _("line number overflow"));
lineno = INT_MAX;
@@ -1016,25 +974,29 @@ unexpected_newline (boundary start, char const *token_end)
}
/*-------------------------.
| Initialize the scanner. |
`-------------------------*/
void
gram_scanner_initialize (void)
gram_scanner_open (const char *gram)
{
gram__flex_debug = trace_flag & trace_scan;
gram_debug = trace_flag & trace_parse;
obstack_init (&obstack_for_string);
current_file = gram;
gram_in = xfopen (gram, "r");
}
void
gram_scanner_close ()
{
xfclose (gram_in);
/* Reclaim Flex's buffers. */
yylex_destroy ();
}
/*-----------------------------------------------.
| Free all the memory allocated to the scanner. |
`-----------------------------------------------*/
void
gram_scanner_free (void)
{
obstack_free (&obstack_for_string, 0);
/* Reclaim Flex's buffers. */
yylex_destroy ();
}
+1 -1
View File
@@ -209,7 +209,7 @@ at_basename (int argc, char *argv[], char **out_namep, int *out_linenop)
static void
at_complain (int argc, char *argv[], char **out_namep, int *out_linenop)
{
static unsigned indent;
static int indent;
warnings w = flag (argv[1]);
location loc;
location *locp = NULL;
+5 -5
View File
@@ -359,11 +359,11 @@ state_hasher (void const *s, size_t tablesize)
void
state_hash_new (void)
{
state_table = hash_initialize (HT_INITIAL_CAPACITY,
NULL,
state_hasher,
state_comparator,
NULL);
state_table = hash_xinitialize (HT_INITIAL_CAPACITY,
NULL,
state_hasher,
state_comparator,
NULL);
}
+6 -5
View File
@@ -34,7 +34,7 @@ symbol_list_sym_new (symbol *sym, location loc)
res->content_type = SYMLIST_SYMBOL;
res->content.sym = sym;
res->location = res->sym_loc = loc;
res->sym_loc = loc;
res->named_ref = NULL;
res->midrule = NULL;
@@ -42,13 +42,14 @@ symbol_list_sym_new (symbol *sym, location loc)
res->midrule_parent_rhs_index = 0;
/* Members used for LHS only. */
res->rhs_loc = empty_loc;
res->ruleprec = NULL;
res->percent_empty_loc = empty_location;
res->percent_empty_loc = empty_loc;
code_props_none_init (&res->action_props);
res->dprec = 0;
res->dprec_location = empty_location;
res->dprec_loc = empty_loc;
res->merger = 0;
res->merger_declaration_location = empty_location;
res->merger_declaration_loc = empty_loc;
res->expected_sr_conflicts = -1;
res->expected_rr_conflicts = -1;
@@ -73,7 +74,7 @@ symbol_list_type_new (uniqstr type_name, location loc)
res->content.sem_type->location = loc;
res->content.sem_type->status = undeclared;
res->location = res->sym_loc = loc;
res->sym_loc = loc;
res->named_ref = NULL;
res->next = NULL;
+6 -4
View File
@@ -50,7 +50,6 @@ typedef struct symbol_list
*/
semantic_type *sem_type;
} content;
location location;
/* Named reference. */
named_ref *named_ref;
@@ -74,6 +73,9 @@ typedef struct symbol_list
| when several RHSs are bound to a single lhs via "|"). |
`--------------------------------------------------------------*/
/* Location of the RHS. */
location rhs_loc;
/* Precedence/associativity. */
symbol *ruleprec;
@@ -82,13 +84,13 @@ typedef struct symbol_list
code_props action_props;
/* The location of the first %empty for this rule, or \a
empty_location. */
empty_loc. */
location percent_empty_loc;
int dprec;
location dprec_location;
location dprec_loc;
int merger;
location merger_declaration_location;
location merger_declaration_loc;
/* Counts of the number of expected conflicts for this rule, or -1 if none
given. */
+167 -117
View File
@@ -24,18 +24,27 @@
#include "system.h"
#include <assure.h>
#include <fstrcmp.h>
#include <hash.h>
#include "complain.h"
#include "getargs.h"
#include "gram.h"
#include "intprops.h"
#include "quote.h"
/*-------------------------------------------------------------------.
| Symbols sorted by tag. Allocated by the first invocation of |
| symbols_do, after which no more symbols should be created. |
`-------------------------------------------------------------------*/
static struct hash_table *symbol_table = NULL;
static struct hash_table *semantic_type_table = NULL;
/*----------------------------------------------------------------.
| Symbols sorted by tag. Allocated by table_sort, after which no |
| more symbols should be created. |
`----------------------------------------------------------------*/
static symbol **symbols_sorted = NULL;
static symbol **semantic_types_sorted = NULL;
static semantic_type **semantic_types_sorted = NULL;
/*------------------------.
| Distinguished symbols. |
@@ -46,7 +55,7 @@ symbol *undeftoken = NULL;
symbol *endtoken = NULL;
symbol *accept = NULL;
symbol *startsymbol = NULL;
location startsymbol_location;
location startsymbol_loc;
/* Precedence relation graph. */
static symgraph **prec_nodes;
@@ -149,8 +158,8 @@ symbol_free (void *ptr)
declaration first.
*/
static
void symbols_sort (symbol **first, symbol **second)
static void
symbols_sort (symbol **first, symbol **second)
{
if (0 < location_cmp ((*first)->location, (*second)->location))
{
@@ -162,8 +171,8 @@ void symbols_sort (symbol **first, symbol **second)
/* Likewise, for locations. */
static
void locations_sort (location *first, location *second)
static void
locations_sort (location *first, location *second)
{
if (0 < location_cmp (*first, *second))
{
@@ -198,7 +207,7 @@ semantic_type_new (uniqstr tag, const location *loc)
uniqstr_assert (tag);
res->tag = tag;
res->location = loc ? *loc : empty_location;
res->location = loc ? *loc : empty_loc;
res->status = undeclared;
for (int i = 0; i < CODE_PROPS_SIZE; ++i)
code_props_none_init (&res->props[i]);
@@ -279,7 +288,7 @@ static void
complain_symbol_redeclared (symbol *s, const char *what, location first,
location second)
{
unsigned i = 0;
int i = 0;
locations_sort (&first, &second);
complain_indent (&second, complaint, &i,
_("%s redeclaration for %s"), what, s->tag);
@@ -292,7 +301,7 @@ static void
complain_semantic_type_redeclared (semantic_type *s, const char *what, location first,
location second)
{
unsigned i = 0;
int i = 0;
locations_sort (&first, &second);
complain_indent (&second, complaint, &i,
_("%s redeclaration for <%s>"), what, s->tag);
@@ -304,7 +313,7 @@ complain_semantic_type_redeclared (semantic_type *s, const char *what, location
static void
complain_class_redeclared (symbol *sym, symbol_class class, location second)
{
unsigned i = 0;
int i = 0;
complain_indent (&second, complaint, &i,
class == token_sym
? _("symbol %s redeclared as a token")
@@ -317,6 +326,55 @@ complain_class_redeclared (symbol *sym, symbol_class class, location second)
}
}
static const symbol *
symbol_from_uniqstr_fuzzy (const uniqstr key)
{
aver (symbols_sorted);
#define FSTRCMP_THRESHOLD 0.6
double best_similarity = FSTRCMP_THRESHOLD;
const symbol *res = NULL;
size_t count = hash_get_n_entries (symbol_table);
for (int i = 0; i < count; ++i)
{
symbol *sym = symbols_sorted[i];
if (STRNEQ (key, sym->tag)
&& (sym->content->status == declared
|| sym->content->status == undeclared))
{
double similarity = fstrcmp_bounded (key, sym->tag, best_similarity);
if (best_similarity < similarity)
{
res = sym;
best_similarity = similarity;
}
}
}
return res;
}
static void
complain_symbol_undeclared (symbol *sym)
{
assert (sym->content->status != declared);
const symbol *best = symbol_from_uniqstr_fuzzy (sym->tag);
if (best)
{
complain (&sym->location,
sym->content->status == needed ? complaint : Wother,
_("symbol %s is used, but is not defined as a token"
" and has no rules; did you mean %s?"),
quote_n (0, sym->tag),
quote_n (1, best->tag));
if (feature_flag & feature_caret)
location_caret_suggestion (sym->location, best->tag, stderr);
}
else
complain (&sym->location,
sym->content->status == needed ? complaint : Wother,
_("symbol %s is used, but is not defined as a token"
" and has no rules"),
quote (sym->tag));
}
void
symbol_location_as_lhs_set (symbol *sym, location loc)
@@ -339,12 +397,12 @@ symbol_type_set (symbol *sym, uniqstr type_name, location loc)
tag_seen = true;
if (sym->content->type_name)
complain_symbol_redeclared (sym, "%type",
sym->content->type_location, loc);
sym->content->type_loc, loc);
else
{
uniqstr_assert (type_name);
sym->content->type_name = type_name;
sym->content->type_location = loc;
sym->content->type_loc = loc;
}
}
}
@@ -426,12 +484,12 @@ symbol_precedence_set (symbol *sym, int prec, assoc a, location loc)
sym_content *s = sym->content;
if (s->prec)
complain_symbol_redeclared (sym, assoc_to_string (a),
s->prec_location, loc);
s->prec_loc, loc);
else
{
s->prec = prec;
s->assoc = a;
s->prec_location = loc;
s->prec_loc = loc;
}
}
@@ -462,7 +520,14 @@ symbol_class_set (symbol *sym, symbol_class class, location loc, bool declaring)
if (declaring)
{
if (s->status == declared)
complain (&loc, Wother, _("symbol %s redeclared"), sym->tag);
{
int i = 0;
complain_indent (&loc, Wother, &i,
_("symbol %s redeclared"), sym->tag);
i += SUB_INDENT;
complain_indent (&sym->location, Wother, &i,
_("previous declaration"));
}
else
s->status = declared;
}
@@ -485,11 +550,14 @@ symbol_user_token_number_set (symbol *sym, int user_token_number, location loc)
&& *user_token_numberp != user_token_number)
complain (&loc, complaint, _("redefining user token number of %s"),
sym->tag);
else if (user_token_number == INT_MAX)
complain (&loc, complaint, _("user token number of %s too large"),
sym->tag);
else
{
*user_token_numberp = user_token_number;
/* User defined $end token? */
if (user_token_number == 0)
if (user_token_number == 0 && !endtoken)
{
endtoken = sym->content->symbol;
/* It is always mapped to 0, so it was already counted in
@@ -507,18 +575,13 @@ symbol_user_token_number_set (symbol *sym, int user_token_number, location loc)
| nonterminal. |
`----------------------------------------------------------*/
static inline bool
static void
symbol_check_defined (symbol *sym)
{
sym_content *s = sym->content;
if (s->class == unknown_sym)
{
assert (s->status != declared);
complain (&sym->location,
s->status == needed ? complaint : Wother,
_("symbol %s is used, but is not defined as a token"
" and has no rules"),
sym->tag);
complain_symbol_undeclared (sym);
s->class = nterm_sym;
s->number = nvars++;
}
@@ -534,11 +597,9 @@ symbol_check_defined (symbol *sym)
if (sem_type)
sem_type->status = declared;
}
return true;
}
static inline bool
static void
semantic_type_check_defined (semantic_type *sem_type)
{
/* <*> and <> do not have to be "declared". */
@@ -557,24 +618,8 @@ semantic_type_check_defined (semantic_type *sem_type)
complain (&sem_type->location, Wother,
_("type <%s> is used, but is not associated to any symbol"),
sem_type->tag);
return true;
}
static bool
symbol_check_defined_processor (void *sym, void *null ATTRIBUTE_UNUSED)
{
return symbol_check_defined (sym);
}
static bool
semantic_type_check_defined_processor (void *sem_type,
void *null ATTRIBUTE_UNUSED)
{
return semantic_type_check_defined (sem_type);
}
/*-------------------------------------------------------------------.
| Merge the properties (precedence, associativity, etc.) of SYM, and |
| its string-named alias STR; check consistency. |
@@ -587,10 +632,10 @@ symbol_merge_properties (symbol *sym, symbol *str)
{
if (str->content->type_name)
symbol_type_set (sym,
str->content->type_name, str->content->type_location);
str->content->type_name, str->content->type_loc);
else
symbol_type_set (str,
sym->content->type_name, sym->content->type_location);
sym->content->type_name, sym->content->type_loc);
}
@@ -604,10 +649,10 @@ symbol_merge_properties (symbol *sym, symbol *str)
{
if (str->content->prec)
symbol_precedence_set (sym, str->content->prec, str->content->assoc,
str->content->prec_location);
str->content->prec_loc);
else
symbol_precedence_set (str, sym->content->prec, sym->content->assoc,
sym->content->prec_location);
sym->content->prec_loc);
}
}
@@ -641,7 +686,7 @@ symbol_make_alias (symbol *sym, symbol *str, location loc)
| into FDEFINES. Put in SYMBOLS. |
`-------------------------------------------------------------------*/
static inline bool
static void
symbol_pack (symbol *this)
{
aver (this->content->number != NUMBER_UNDEFINED);
@@ -649,19 +694,12 @@ symbol_pack (symbol *this)
this->content->number += ntokens;
symbols[this->content->number] = this->content->symbol;
return true;
}
static bool
symbol_pack_processor (void *this, void *null ATTRIBUTE_UNUSED)
{
return symbol_pack (this);
}
static void
complain_user_token_number_redeclared (int num, symbol *first, symbol *second)
{
unsigned i = 0;
int i = 0;
symbols_sort (&first, &second);
complain_indent (&second->location, complaint, &i,
_("user token number %d redeclaration for %s"),
@@ -676,7 +714,7 @@ complain_user_token_number_redeclared (int num, symbol *first, symbol *second)
| Put THIS in TOKEN_TRANSLATIONS if it is a token. |
`--------------------------------------------------*/
static inline bool
static void
symbol_translation (symbol *this)
{
/* Nonterminal? */
@@ -693,14 +731,6 @@ symbol_translation (symbol *this)
token_translations[this->content->user_token_number]
= this->content->number;
}
return true;
}
static bool
symbol_translation_processor (void *this, void *null ATTRIBUTE_UNUSED)
{
return symbol_translation (this);
}
@@ -711,9 +741,6 @@ symbol_translation_processor (void *this, void *null ATTRIBUTE_UNUSED)
/* Initial capacity of symbol and semantic type hash table. */
#define HT_INITIAL_CAPACITY 257
static struct hash_table *symbol_table = NULL;
static struct hash_table *semantic_type_table = NULL;
static inline bool
hash_compare_symbol (const symbol *m1, const symbol *m2)
{
@@ -773,16 +800,33 @@ hash_semantic_type_hasher (void const *m, size_t tablesize)
void
symbols_new (void)
{
symbol_table = hash_initialize (HT_INITIAL_CAPACITY,
NULL,
hash_symbol_hasher,
hash_symbol_comparator,
symbol_free);
semantic_type_table = hash_initialize (HT_INITIAL_CAPACITY,
NULL,
hash_semantic_type_hasher,
hash_semantic_type_comparator,
free);
symbol_table = hash_xinitialize (HT_INITIAL_CAPACITY,
NULL,
hash_symbol_hasher,
hash_symbol_comparator,
symbol_free);
/* Construct the accept symbol. */
accept = symbol_get ("$accept", empty_loc);
accept->content->class = nterm_sym;
accept->content->number = nvars++;
/* Construct the error token */
errtoken = symbol_get ("error", empty_loc);
errtoken->content->class = token_sym;
errtoken->content->number = ntokens++;
/* Construct a token that represents all undefined literal tokens.
It is always token number 2. */
undeftoken = symbol_get ("$undefined", empty_loc);
undeftoken->content->class = token_sym;
undeftoken->content->number = ntokens++;
semantic_type_table = hash_xinitialize (HT_INITIAL_CAPACITY,
NULL,
hash_semantic_type_hasher,
hash_semantic_type_comparator,
free);
}
@@ -899,36 +943,25 @@ symbols_free (void)
}
/*---------------------------------------------------------------.
| Look for undefined symbols, report an error, and consider them |
| terminals. |
`---------------------------------------------------------------*/
static int
symbols_cmp (symbol const *a, symbol const *b)
symbol_cmp (void const *a, void const *b)
{
return strcmp (a->tag, b->tag);
return location_cmp ((*(symbol * const *)a)->location,
(*(symbol * const *)b)->location);
}
static int
symbols_cmp_qsort (void const *a, void const *b)
{
return symbols_cmp (*(symbol * const *)a, *(symbol * const *)b);
}
/* Store in *SORTED an array of pointers to the symbols contained in
TABLE, sorted (alphabetically) by tag. */
static void
symbols_do (Hash_processor processor, void *processor_data,
struct hash_table *table, symbol ***sorted)
table_sort (struct hash_table *table, symbol ***sorted)
{
aver (!*sorted);
size_t count = hash_get_n_entries (table);
if (!*sorted)
{
*sorted = xnmalloc (count, sizeof **sorted);
hash_get_entries (table, (void**)*sorted, count);
qsort (*sorted, count, sizeof **sorted, symbols_cmp_qsort);
}
for (size_t i = 0; i < count; ++i)
processor ((*sorted)[i], processor_data);
*sorted = xnmalloc (count + 1, sizeof **sorted);
hash_get_entries (table, (void**)*sorted, count);
qsort (*sorted, count, sizeof **sorted, symbol_cmp);
(*sorted)[count] = NULL;
}
/*--------------------------------------------------------------.
@@ -939,10 +972,20 @@ symbols_do (Hash_processor processor, void *processor_data,
void
symbols_check_defined (void)
{
symbols_do (symbol_check_defined_processor, NULL,
symbol_table, &symbols_sorted);
symbols_do (semantic_type_check_defined_processor, NULL,
semantic_type_table, &semantic_types_sorted);
table_sort (symbol_table, &symbols_sorted);
/* semantic_type, like symbol, starts with a 'tag' field and then a
'location' field. And here we only deal with arrays/hashes of
pointers, sizeof is not an issue.
So instead of implementing table_sort (and symbol_cmp) once for
each type, let's lie a bit to the typing system, and treat
'semantic_type' as if it were 'symbol'. */
table_sort (semantic_type_table, (symbol ***) &semantic_types_sorted);
for (int i = 0; symbols_sorted[i]; ++i)
symbol_check_defined (symbols_sorted[i]);
for (int i = 0; semantic_types_sorted[i]; ++i)
semantic_type_check_defined (semantic_types_sorted[i]);
}
/*------------------------------------------------------------------.
@@ -983,7 +1026,13 @@ symbols_token_translations_init (void)
{
sym_content *this = symbols[i]->content;
if (this->user_token_number == USER_NUMBER_UNDEFINED)
this->user_token_number = ++max_user_token_number;
{
IGNORE_TYPE_LIMITS_BEGIN
if (INT_ADD_WRAPV (max_user_token_number, 1, &max_user_token_number))
complain (NULL, fatal, _("token number too large"));
IGNORE_TYPE_LIMITS_END
this->user_token_number = max_user_token_number;
}
if (this->user_token_number > max_user_token_number)
max_user_token_number = this->user_token_number;
}
@@ -993,10 +1042,10 @@ symbols_token_translations_init (void)
/* Initialize all entries for literal tokens to the internal token
number for $undefined, which represents all invalid inputs. */
for (int i = 0; i < max_user_token_number + 1; i++)
for (int i = 0; i < max_user_token_number + 1; ++i)
token_translations[i] = undeftoken->content->number;
symbols_do (symbol_translation_processor, NULL,
symbol_table, &symbols_sorted);
for (int i = 0; symbols_sorted[i]; ++i)
symbol_translation (symbols_sorted[i]);
}
@@ -1009,7 +1058,8 @@ void
symbols_pack (void)
{
symbols = xcalloc (nsyms, sizeof *symbols);
symbols_do (symbol_pack_processor, NULL, symbol_table, &symbols_sorted);
for (int i = 0; symbols_sorted[i]; ++i)
symbol_pack (symbols_sorted[i]);
/* Aliases leave empty slots in symbols, so remove them. */
{
@@ -1034,11 +1084,11 @@ symbols_pack (void)
symbols_token_translations_init ();
if (startsymbol->content->class == unknown_sym)
complain (&startsymbol_location, fatal,
complain (&startsymbol_loc, fatal,
_("the start symbol %s is undefined"),
startsymbol->tag);
else if (startsymbol->content->class == token_sym)
complain (&startsymbol_location, fatal,
complain (&startsymbol_loc, fatal,
_("the start symbol %s is a token"),
startsymbol->tag);
}
@@ -1209,14 +1259,14 @@ print_precedence_warnings (void)
&& !prec_nodes[i]->succ)
{
if (is_assoc_useless (s))
complain (&s->content->prec_location, Wprecedence,
complain (&s->content->prec_loc, Wprecedence,
_("useless precedence and associativity for %s"), s->tag);
else if (s->content->assoc == precedence_assoc)
complain (&s->content->prec_location, Wprecedence,
complain (&s->content->prec_loc, Wprecedence,
_("useless precedence for %s"), s->tag);
}
else if (is_assoc_useless (s))
complain (&s->content->prec_location, Wprecedence,
complain (&s->content->prec_loc, Wprecedence,
_("useless associativity for %s, use %%precedence"), s->tag);
}
free (used_assoc);
+5 -4
View File
@@ -122,7 +122,7 @@ struct sym_content
uniqstr type_name;
/** Its \c \%type's location. */
location type_location;
location type_loc;
/** Any \c \%destructor (resp. \%printer) declared specificially for this
symbol.
@@ -134,7 +134,7 @@ struct sym_content
code_props props[CODE_PROPS_SIZE];
symbol_number number;
location prec_location;
location prec_loc;
int prec;
assoc assoc;
@@ -246,7 +246,7 @@ extern symbol *accept;
/** The user start symbol. */
extern symbol *startsymbol;
/** The location of the \c \%start declaration. */
extern location startsymbol_location;
extern location startsymbol_loc;
/** Whether a symbol declared with a type tag. */
extern bool tag_seen;
@@ -345,7 +345,8 @@ void semantic_type_code_props_set (semantic_type *type,
| Symbol and semantic type tables. |
`----------------------------------*/
/** Create the symbol and semantic type tables. */
/** Create the symbol and semantic type tables, and the built-in
symbols. */
void symbols_new (void);
/** Free all the memory allocated for symbols and semantic types. */
+13 -10
View File
@@ -74,6 +74,19 @@ typedef size_t uintptr_t;
# include <xalloc.h>
/* See https://lists.gnu.org/archive/html/bug-bison/2019-10/msg00061.html. */
# if defined __GNUC__ && ! defined __clang__ && ! defined __ICC && __GNUC__ < 5
# define IGNORE_TYPE_LIMITS_BEGIN \
_Pragma ("GCC diagnostic push") \
_Pragma ("GCC diagnostic ignored \"-Wtype-limits\"")
# define IGNORE_TYPE_LIMITS_END \
_Pragma ("GCC diagnostic pop")
# else
# define IGNORE_TYPE_LIMITS_BEGIN
# define IGNORE_TYPE_LIMITS_END
# endif
/*-----------------.
| GCC extensions. |
`-----------------*/
@@ -249,14 +262,4 @@ typedef size_t uintptr_t;
} \
} while (0)
/*---------------------------------------------.
| Debugging memory allocation (must be last). |
`---------------------------------------------*/
# if WITH_DMALLOC
# define DMALLOC_FUNC_CHECK
# include <dmalloc.h>
# endif /* WITH_DMALLOC */
#endif /* ! BISON_SYSTEM_H */
+6 -6
View File
@@ -84,7 +84,7 @@ int nvectors;
static base_number **froms;
static base_number **tos;
static unsigned **conflict_tos;
static int **conflict_tos;
static size_t *tally;
static base_number *width;
@@ -115,9 +115,9 @@ base_number base_ninf = 0;
-nstates..table_size (as an upper bound) */
static bitset pos_set = NULL;
static unsigned *conflrow;
unsigned *conflict_table;
unsigned *conflict_list;
static int *conflrow;
int *conflict_table;
int *conflict_list;
int conflict_list_cnt;
static int conflict_list_free;
@@ -391,7 +391,7 @@ save_row (state_number s)
/* Allocate non defaulted actions. */
base_number *sp1 = froms[s] = xnmalloc (count, sizeof *sp1);
base_number *sp2 = tos[s] = xnmalloc (count, sizeof *sp2);
unsigned *sp3 = conflict_tos[s] =
int *sp3 = conflict_tos[s] =
nondeterministic_parser ? xnmalloc (count, sizeof *sp3) : NULL;
/* Store non defaulted actions. */
@@ -646,7 +646,7 @@ pack_vector (vector_number vector)
size_t t = tally[i];
base_number *from = froms[i];
base_number *to = tos[i];
unsigned *conflict_to = conflict_tos[i];
int *conflict_to = conflict_tos[i];
aver (t != 0);
+2 -2
View File
@@ -122,8 +122,8 @@ extern base_number *base;
keep parser tables small. */
extern base_number base_ninf;
extern unsigned *conflict_table;
extern unsigned *conflict_list;
extern int *conflict_table;
extern int *conflict_list;
extern int conflict_list_cnt;
extern base_number *table;
+5 -5
View File
@@ -157,11 +157,11 @@ hash_uniqstr (void const *m, size_t tablesize)
void
uniqstrs_new (void)
{
uniqstrs_table = hash_initialize (HT_INITIAL_CAPACITY,
NULL,
hash_uniqstr,
hash_compare_uniqstr,
free);
uniqstrs_table = hash_xinitialize (HT_INITIAL_CAPACITY,
NULL,
hash_uniqstr,
hash_compare_uniqstr,
free);
}

Some files were not shown because too many files have changed in this diff Show More