Compare commits

...
56 Commits
Author SHA1 Message Date
Akim Demaille 5d501ee728 version 3.7.3
* NEWS: Record release date.
2020-10-13 07:01:24 +02:00
Akim Demaille bc5e4541da build: don't link bison against libreadline
Reported by Paul Smith <[email protected]>.
https://lists.gnu.org/r/bug-bison/2020-10/msg00001.html

* src/local.mk (src_bison_LDADD): here.
2020-10-13 06:57:33 +02:00
Akim Demaille 567d1eaa19 gnulib: update 2020-10-13 06:46:06 +02:00
Akim Demaille c08e0863be glr.cc: fix: use symbol_name
* data/skeletons/glr.cc: here.
2020-09-27 09:22:02 +02:00
Akim Demaille 541943ee04 build: fix a concurrent build issue in examples
Reported by Thomas Deutschmann <[email protected]>.
https://lists.gnu.org/r/bug-bison/2020-09/msg00010.html

* examples/c/lexcalc/local.mk: scan.o depends on parse.[ch].
2020-09-06 10:08:22 +02:00
Akim Demaille dcdd119f69 maint: post-release administrivia
* NEWS: Add header line for next release.
* .prev-version: Record previous version.
* cfg.mk (old_NEWS_hash): Auto-update.
2020-09-05 18:31:25 +02:00
Akim Demaille a0bc06b703 version 3.7.2
* NEWS: Record release date.
2020-09-05 18:06:16 +02:00
Akim Demaille 5e33dfe59d build: disable syntax-check warning
error_message_uppercase
etc/bench.pl.in-419-static int yylex (@{[is_pure (@directive) ? "YYSTYPE *yylvalp" : "void"]});

* cfg.mk: here.
2020-09-05 17:59:56 +02:00
Akim Demaille 2a4e9a358f gnulib: update 2020-09-05 17:44:38 +02:00
Akim Demaille f7b642cff7 build: fix incorrect dependencies
Commit af000bab11 ("doc: work around
Texinfo 6.7 bug"), published in 3.4.91, added a dependency on the
"all" target.

This is a super bad idea, since "make all" will run this
target *before* "all", which builds bison.  It turns out that this new
dependency actually needed bison to be built.  So all the regular
process (i) build $(BUILT_SOURCES) and then (ii) build bison, was
wrecked since some of the $(BUILT_SOURCES) depended on bison...

It was "easy" to see in the logs of "make V=1" because we were
building bison files (such as src/files.o) *before* displaying the
banner for "all-recursive".  With this fix, we finally get again the
proper sequence:

    rm -f examples/c/reccalc/scan.stamp examples/c/reccalc/scan.stamp.tmp
    /opt/local/libexec/gnubin/mkdir -p examples/c/reccalc
    touch examples/c/reccalc/scan.stamp.tmp
    flex   -oexamples/c/reccalc/scan.c --header=examples/c/reccalc/scan.h ./examples/c/reccalc/scan.l
    mv examples/c/reccalc/scan.stamp.tmp examples/c/reccalc/scan.stamp
    rm -f lib/fcntl.h-t lib/fcntl.h && \
    { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
      ...
    } > lib/fcntl.h-t && \
    mv lib/fcntl.h-t lib/fcntl.h
    ...
    mv -f lib/alloca.h-t lib/alloca.h
    make  all-recursive

Reported by Mingli Yu <[email protected]>.
https://github.com/akimd/bison/issues/31
https://lists.gnu.org/r/bison-patches/2020-05/msg00055.html

Reported by Claudio Calvelli <[email protected]>.
https://lists.gnu.org/r/bug-bison/2020-09/msg00001.html
https://bugs.gentoo.org/716516

* doc/local.mk (all): Rename as...
(all-local): this.
So that we don't compete with BUILT_SOURCES.
2020-09-05 17:42:20 +02:00
Akim Demaille 3da17724ad doc: updates
* NEWS, TODO: here.
2020-09-02 21:37:23 +02:00
Akim Demaille 68e3e442f9 gnulib: update 2020-08-30 17:32:43 +02:00
Akim Demaille e432619d11 tests: beware of sed portability issues
Reported by David Laxer <[email protected]>.
https://lists.gnu.org/r/bug-bison/2020-08/msg00027.html

* tests/output.at: Don't use + with sed.
While at it, fix a quotation problem hidden by the use of '#'.
2020-08-30 17:16:18 +02:00
Akim Demaille a1b7fef045 c: always use YYMALLOC/YYFREE
Reported by Kovalex <[email protected]>.
https://lists.gnu.org/r/bug-bison/2020-08/msg00015.html

* data/skeletons/yacc.c: Don't make direct calls to malloc/free.
* tests/calc.at: Check it.
2020-08-30 10:05:18 +02:00
Akim Demaille 067e35a8be build: beware of POSIX mode
Reported by Dennis Clarke.
https://lists.gnu.org/r/bug-bison/2020-08/msg00013.html

* examples/d/local.mk, examples/java/calc/local.mk,
* examples/java/simple/local.mk: Pass bison's options before its
argument, in case we're in POSIX mode.
2020-08-30 09:38:05 +02:00
Akim Demaille 0522047c96 doc: history of api.prefix
Reported by Matthew Fernandez <[email protected]>.
https://lists.gnu.org/r/help-bison/2020-08/msg00015.html

* doc/bison.texi (api.prefix): We move to {} in 3.0.
2020-08-30 09:29:00 +02:00
Akim Demaille 3724b50ef9 CI: intel moved the script for ICC
* .travis.yml: Adjust.
2020-08-11 07:18:48 +02:00
Akim Demaille b801b7b670 fix: unterminated \-escape
An assertion failed when the last character is a '\' and we're in a
character or a string.
Reported by Agency for Defense Development.
https://lists.gnu.org/r/bug-bison/2020-08/msg00009.html

* src/scan-gram.l: Catch unterminated escapes.
* tests/input.at (Unexpected end of file): New.
2020-08-08 07:53:33 +02:00
Akim Demaille b7aab2dbad fix: crash when redefining the EOF token
Reported by Agency for Defense Development.
https://lists.gnu.org/r/bug-bison/2020-08/msg00008.html

On an empty such as

    %token FOO
           BAR
           FOO 0
    %%
    input: %empty

we crash because when we find FOO 0, we decrement ntokens (since FOO
was discovered to be EOF, which is already known to be a token, so we
increment ntokens for it, and need to cancel this).  This "works well"
when EOF is properly defined in one go, but here it is first defined
and later only assign token code 0.  In the meanwhile BAR was given
the token number that we just decremented.

To fix this, assign symbol numbers after parsing, not during parsing,
so that we also saw all the explicit token codes.  To maintain the
current numbers (I'd like to keep no difference in the output, not
just equivalence), we need to make sure the symbols are numbered in
the same order: that of appearance in the source file.  So we need the
locations to be correct, which was almost the case, except for nterms
that appeared several times as LHS (i.e., several times as "foo:
...").  Fixing the use of location_of_lhs sufficed (it appears it was
intended for this use, but its implementation was unfinished: it was
always set to "false" only).

* src/symtab.c (symbol_location_as_lhs_set): Update location_of_lhs.
(symbol_code_set): Remove broken hack that decremented ntokens.
(symbol_class_set, dummy_symbol_get): Don't set number, ntokens and
nnterms.
(symbol_check_defined): Do it.
(symbols): Don't count nsyms here.
Actually, don't count nsyms at all: let it be done in...
* src/reader.c (check_and_convert_grammar): here.  Define nsyms from
ntokens and nnterms after parsing.
* tests/input.at (EOF redeclared): New.

* examples/c/bistromathic/bistromathic.test: Adjust the traces: in
"%nterm <double> exp %% input: ...", exp used to be numbered before
input.
2020-08-07 07:30:06 +02:00
Akim Demaille 89e42ffb4b style: fix missing space before paren
* cfg.mk (_space_before_paren_exempt): Be less laxist.
* src/output.c, src/reader.c: Fix space before paren issues.
Pacify the warnings where applicable.
2020-08-07 07:30:06 +02:00
Akim Demaille 6aae4a7378 style: fix comments and more debug trace
* src/location.c, src/symtab.h, src/symtab.c: here.
2020-08-07 07:30:06 +02:00
Akim Demaille 7d4a4300c2 style: more uses of const
* src/symtab.c: here.
2020-08-07 07:30:06 +02:00
Akim Demaille 31d4ec28bd bench: fix support for pure parser
* etc/bench.pl.in (is_pure): New.
(generate_grammar_calc): Use code provides where needed.
Use is_pure to call yylex properly.
Coding style fixes.
2020-08-07 07:29:16 +02:00
Akim Demaille 0a5bfb4fda portability: multiple typedefs
Older versions of GCC (4.1.2 here) don't like repeated typedefs.

      CC       src/bison-parse-simulation.o
    src/parse-simulation.c:61: error: redefinition of typedef 'parse_state'
    src/parse-simulation.h:74: error: previous declaration of 'parse_state' was here
    make: *** [Makefile:7876: src/bison-parse-simulation.o] Error 1

Reported by Nelson H. F. Beebe.

* src/parse-simulation.c (parse_state): Don't typedef,
parse-simulation.h did it already.
2020-08-03 07:30:35 +02:00
Akim Demaille 12d0b15679 style: revert "avoid warnings with GCC 4.6"
This reverts commit d0bec3175f (which
should have read "We have a clash...", not "With have a clash...").
Now that `max()` was renamed `max_int()`, we can use `max` again, as
elsewhere in the code.

* src/counterexample.c (visited_hasher): Alpha reconversion.
2020-08-02 10:20:23 +02:00
Akim Demaille cb7dcb011e maint: post-release administrivia
* NEWS: Add header line for next release.
* .prev-version: Record previous version.
* cfg.mk (old_NEWS_hash): Auto-update.
2020-08-02 09:32:34 +02:00
Akim Demaille 71579c7219 version 3.7.1
* NEWS: Record release date.
2020-08-02 09:10:02 +02:00
Akim Demaille 2f8a874215 portability: we use termios.h and sys/ioctl.h
Reported by Maarten De Braekeleer.
https://lists.gnu.org/r/bison-patches/2020-07/msg00079.html

* bootstrap.conf (gnulib_modules): Add termios and sys_ioctl.
2020-08-02 08:36:49 +02:00
Maarten De BraekeleerandAkim Demaille ad6f600bb1 portability: rename accept to acceptsymbol because of MSVC
MSVC already defines this symbol.

* src/symtab.h, src/symtab.c (accept): Rename as...
(acceptsymbol): this.
Adjust dependencies.
2020-08-02 08:32:57 +02:00
Akim Demaille de4f41eab7 regen 2020-08-02 08:32:57 +02:00
Maarten De BraekeleerandAkim Demaille e73f086b0d portability: use CHAR_LITERAL instead of CHAR because MSVC defines CHAR
* src/parse-gram.y, src/scan-gram.l: here.
2020-08-02 08:32:57 +02:00
Maarten De BraekeleerandAkim Demaille 8cf098415e portability: use INT_LITERAL instead of INT because MSVC defines INT
It is defined as a typedef, not a macro.
https://lists.gnu.org/r/bison-patches/2020-08/msg00001.html

* src/parse-gram.y, src/scan-gram.l: here.
2020-08-02 08:32:30 +02:00
Akim Demaille 977e19840d portability: beware of max () with MSVC
Reported by Maarten De Braekeleer.
https://lists.gnu.org/r/bison-patches/2020-07/msg00080.html

We don't want to use gnulib's min and max macros, since we use
function calls in min/max arguments.

* src/location.c (max_int, min_int): Move to...
* src/system.h: here.
* src/counterexample.c, src/derivation.c: Use max_int instead of max.
2020-08-02 08:19:35 +02:00
Akim Demaille d975c2f76e libtextstyle: be sure to have ostream_printf and hyperlink support
Older versions of libtextstyle do not support them, rule them out.

Reported by Lars Wendler
https://lists.gnu.org/r/bug-bison/2020-07/msg00030.html

and by Arnold Robbins
https://lists.gnu.org/r/bug-bison/2020-07/msg00041.html and
https://lists.gnu.org/mailman/private/gawk-devel/2020-July/003988.html

and by Nelson H. F. Beebe
https://lists.gnu.org/mailman/private/gawk-devel/2020-July/003993.html

With support from Bruno Haible in gnulib
https://lists.gnu.org/r/bug-gnulib/2020-08/msg00000.html
thread starting at
https://lists.gnu.org/r/bug-gnulib/2020-07/msg00148.html

* configure.ac: Require libtextstyle 0.20.5.
* gnulib: Update.
2020-08-02 08:19:35 +02:00
Akim Demaille 0676801b8c CI: comment changes 2020-08-01 10:02:44 +02:00
Akim Demaille 82aa96e9b1 regen 2020-08-01 08:54:46 +02:00
Akim Demaille cb65553449 diagnostics: better location for type redeclarations
From

    foo.y:1.7-11: error: %type redeclaration for bar
        1 | %type <foo> bar bar
          |       ^~~~~
    foo.y:1.7-11: note: previous declaration
        1 | %type <foo> bar bar
          |       ^~~~~

to

    foo.y:1.17-19: error: %type redeclaration for bar
        1 | %type <foo> bar bar
          |                 ^~~
    foo.y:1.13-15: note: previous declaration
        1 | %type <foo> bar bar
          |             ^~~

* src/symlist.h, src/symlist.c (symbol_list_type_set): There's no need
for the tag's location, use that of the symbol.
* src/parse-gram.y: Adjust.
* tests/input.at: Adjust.
2020-08-01 08:54:46 +02:00
Akim Demaille f47a1bd622 todo: updates for D 2020-07-30 07:14:57 +02:00
Akim Demaille 205d372c68 cex: style: comment changes
* src/parse-simulation.c: here.
2020-07-29 20:00:59 +02:00
Akim Demaille 07a1243b40 cex: style: prefer "res" for the returned value
* src/derivation.c (derivation_new): here.
2020-07-29 20:00:59 +02:00
Akim Demaille ece343d2c2 cex: style: prefer FOO_print to print_FOO
* src/state-item.h, src/state-item.c (print_state_item): Rename as...
(state_item_print): this.
* src/counterexample.c (print_counterexample): Rename as...
(counterexample_print): this.
2020-07-29 20:00:27 +02:00
Akim Demaille be95a4fe29 scanner: don't crash on strings containing a NUL byte
We crash if the input contains a string containing a NUL byte.
Reported by Suhwan Song.
https://lists.gnu.org/r/bug-bison/2020-07/msg00051.html

* src/flex-scanner.h (STRING_FREE): Avoid accidental use of
last_string.
* src/scan-gram.l: Don't call STRING_FREE without calling
STRING_FINISH first.
* tests/input.at (Invalid inputs): Check that case.
2020-07-28 19:01:48 +02:00
Akim Demaille 6accee7716 doc: refer to cex from sections dealing with conflicts
The documentation about -Wcex should be put forward.

* doc/bison.texi: Refer to -Wcex from the sections about conflicts.
2020-07-28 07:45:07 +02:00
Akim Demaille e63f22703e doc: factor ifnottex/iftex examples
* doc/bison.texi: Factor the common bits out of ifnottex/iftex.
2020-07-28 07:45:07 +02:00
Akim Demaille fa390dc311 doc: fix colors
The original Texinfo macros introducing colors were made for
diagnostics, which are printed in bold.  So by copy-paste accident the
styles we introduced for counterexamples were also in bold.  They
should not.

* doc/bison.texi: Separate the styling of diagnostics from the styling
for counterexamples.
Don't use bold in the latter case.
2020-07-28 07:45:07 +02:00
Akim Demaille 17fdf5eca2 doc: fixes
* doc/bison.texi: Fix spello.
Fix missing colors, and factor.
2020-07-28 07:45:07 +02:00
Akim Demaille 72b3c1a673 maint: post-release administrivia
* NEWS: Add header line for next release.
* .prev-version: Record previous version.
* cfg.mk (old_NEWS_hash): Auto-update.
2020-07-23 20:15:38 +02:00
Akim Demaille 6675d36e25 version 3.7
* NEWS: Record release date.
2020-07-23 19:58:16 +02:00
Akim Demaille d0bec3175f style: avoid warnings with GCC 4.6
With have a clash with the "max" function.

    src/counterexample.c: In function 'visited_hasher':
    src/counterexample.c:720:48: error: declaration of 'max' shadows a global declaration [-Werror=shadow]
    src/counterexample.c:116:12: error: shadowed declaration is here [-Werror=shadow]

* src/counterexample.c (visited_hasher): Alpha conversion.
2020-07-23 19:55:24 +02:00
Akim Demaille 79e68b6c4d doc: fix definition of -Wall
* doc/bison.texi (Diagnostics): here.
2020-07-23 09:17:18 +02:00
Akim Demaille 5cb74cacd8 gnulib: update
* bootstrap.conf: We need stpncpy.
2020-07-23 06:56:25 +02:00
Akim Demaille 9c8e6e05b6 tests: fixes
Fix 6b78e50cef, "cex: make "rerun with
'-Wcex'" a note instead of a warning"

* tests/conflicts.at (-W versus %expect and %expect-rr): Fix
expectations.
2020-07-23 06:33:30 +02:00
Akim Demaille 431774d1f6 cex: update NEWS for 3.7
* NEWS: Update to the current style of cex display.
2020-07-22 07:36:02 +02:00
Akim Demaille 7d5474e979 doc: catch up with the current display of cex
Unfortunately I found no way to use the ↳ glyph in Texinfo, so I used
@arrow{} instead, which has a different width, so we have to have all
the examples doubled, once for TeX, another for the rest of the world.

* doc/bison.texi: Use the current display in the examples.
* doc/calc.y, doc/ids.y, doc/if-then-else.y, doc/sequence.y: New.
2020-07-22 07:36:02 +02:00
Akim Demaille 6b78e50cef cex: make "rerun with '-Wcex'" a note instead of a warning
Currently the suggestion to rerun is a -Wother warning:

    warning: 2 shift/reduce conflicts [-Wconflicts-sr]
    warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]

Instead, let's attach it as a subnote of the diagnostic (in the
current case, -Wconflicts-sr):

    warning: 2 shift/reduce conflicts [-Wconflicts-sr]
    note: rerun with option '-Wcounterexamples' to generate conflict counterexamples

* src/conflicts.c (conflicts_print): Do that.
Adjust the test suite.
2020-07-21 18:57:56 +02:00
Akim Demaille 28769d608e maint: post-release administrivia
* NEWS: Add header line for next release.
* .prev-version: Record previous version.
* cfg.mk (old_NEWS_hash): Auto-update.
2020-07-20 07:58:03 +02:00
58 changed files with 1320 additions and 465 deletions
+1 -1
View File
@@ -1 +1 @@
3.6.92
3.7.2
+4 -1
View File
@@ -50,6 +50,7 @@ jobs:
- make -j2 dist-xz
# Can help understanding why we get "dirty" tarballs.
- git status
- git diff
- dist=$(echo bison*.xz)
# Unfortunately we cannot deterministically know the name of the tarball without the full
@@ -119,6 +120,8 @@ jobs:
- CXX='clang++-10 -fsanitize=address -stdlib=libc++'
- PART=2
# See https://github.com/simd-everywhere/simde/blob/master/.travis.yml
# and https://software.intel.com/content/www/us/en/develop/documentation/get-started-with-intel-oneapi-render-linux/top/configure-your-system.html.
- name: "ICC"
stage: check
os: linux
@@ -127,7 +130,7 @@ jobs:
- CC=icc
- CXX=icpc
install:
- source /opt/intel/inteloneapi/compiler/latest/env/vars.sh
- source /opt/intel/oneapi/compiler/latest/env/vars.sh
addons:
apt:
sources:
+153 -53
View File
@@ -1,36 +1,56 @@
GNU Bison NEWS
* Noteworthy changes in release 3.6.93 (2020-07-20) [beta]
* Noteworthy changes in release 3.7.3 (2020-10-13) [stable]
** Bug fixes
Portability issues.
Fix concurrent build issues.
The bison executable is no longer linked uselessly against libreadline.
* Noteworthy changes in release 3.6.92 (2020-07-19) [beta]
Fix incorrect use of yytname in glr.cc.
Changes in the display of counterexamples.
* Noteworthy changes in release 3.7.2 (2020-09-05) [stable]
** Documentation
This release of Bison fixes all known bugs reported for Bison in MITRE's
Common Vulnerabilities and Exposures (CVE) system. These vulnerabilities
are only about bison-the-program itself, not the generated code.
*** Examples
Although these bugs are typically irrelevant to how Bison is used, they
are worth fixing if only to give users peace of mind.
The bistromathic demonstrates %param and how to quote sources in the error
messages:
> 123 456
1.5-7: syntax error: expected end of file or + or - or * or / or ^ before number
1 | 123 456
| ^~~
* Noteworthy changes in release 3.6.91 (2020-07-09) [beta]
There is no known vulnerability in the generated parsers.
** Bug fixes
Portability issues.
Fix concurrent build issues (introduced in Bison 3.5).
Push parsers always use YYMALLOC/YYFREE (no direct calls to malloc/free).
Fix portability issues of the test suite, and of bison itself.
Some unlikely crashes found by fuzzing have been fixed. This is only
about bison itself, not the generated parsers.
* Noteworthy changes in release 3.6.90 (2020-07-04) [beta]
* Noteworthy changes in release 3.7.1 (2020-08-02) [stable]
** Bug fixes
Crash when a token alias contains a NUL byte.
Portability issues with libtextstyle.
Portability issues of Bison itself with MSVC.
** Changes
Improvements and fixes in the documentation.
More precise location about symbol type redefinitions.
* Noteworthy changes in release 3.7 (2020-07-23) [stable]
** Deprecated features
@@ -48,52 +68,114 @@ Changes in the display of counterexamples.
Contributed by Vincent Imbimbo.
When given `--report=counterexamples` or `-Wcounterexamples`, bison will
now output counterexamples for conflicts in the grammar. These are
strings in the grammar which can be parsed in two ways due to the
conflict. For example:
When given `-Wcounterexamples`/`-Wcex`, bison will now output
counterexamples for conflicts.
Shift/reduce conflict on token "/":
Example exp "+" exp • "/" exp
**** Unifying Counterexamples
Unifying counterexamples are strings which can be parsed in two ways due
to the conflict. For example on a grammar that contains the usual
"dangling else" ambiguity:
$ bison else.y
else.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
else.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
$ bison else.y -Wcex
else.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
else.y: warning: shift/reduce conflict on token "else" [-Wcounterexamples]
Example: "if" exp "then" "if" exp "then" exp • "else" exp
Shift derivation
exp
↳ exp "+" exp
exp • "/" exp
Example exp "+" exp • "/" exp
"if" exp "then" exp
↳ "if" exp "then" exp • "else" exp
Example: "if" exp "then" "if" exp "then" exp • "else" exp
Reduce derivation
exp
exp "/" exp
↳ exp "+" exp •
"if" exp "then" exp "else" exp
"if" exp "then" exp •
When Bison is installed with text styling enabled, the example is actually
shown twice, with colors highlighting the ambiguity.
When text styling is enabled, colors are used in the examples and the
derivations to highlight the structure of both analyses. In this case,
This is a shift/reduce conflict caused by none of the operators having
precedence, so the example can be parsed in the two ways shown. When
bison cannot find an example that can be derived in two ways, it instead
generates two examples that are the same up until the dot:
"if" exp "then" [ "if" exp "then" exp • ] "else" exp
First example expr • ID ',' ID $end
Shift derivation
$accept
↳ s $end
↳ a ID
↳ expr
↳ expr • ID ','
Second example expr • ID $end
Reduce derivation
$accept
↳ s $end
↳ a ID
↳ expr •
vs.
"if" exp "then" [ "if" exp "then" exp • "else" exp ]
The counterexamples are "focused", in two different ways. First, they do
not clutter the output with all the derivations from the start symbol,
rather they start on the "conflicted nonterminal". They go straight to the
point. Second, they don't "expand" nonterminal symbols uselessly.
**** Nonunifying Counterexamples
In the case of the dangling else, Bison found an example that can be
parsed in two ways (therefore proving that the grammar is ambiguous).
When it cannot find such an example, it instead generates two examples
that are the same up until the dot:
$ bison foo.y
foo.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
foo.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
foo.y:4.4-7: warning: rule useless in parser due to conflicts [-Wother]
4 | a: expr
| ^~~~
$ bison -Wcex foo.y
foo.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
foo.y: warning: shift/reduce conflict on token ID [-Wcounterexamples]
First example: expr • ID ',' ID $end
Shift derivation
$accept
↳ s $end
↳ a ID
↳ expr
↳ expr • ID ','
Second example: expr • ID $end
Reduce derivation
$accept
↳ s $end
↳ a ID
↳ expr •
foo.y:4.4-7: warning: rule useless in parser due to conflicts [-Wother]
4 | a: expr
| ^~~~
In these cases, the parser usually doesn't have enough lookahead to
differentiate the two given examples.
The counterexamples are "focused" in two different ways. First, they do
not clutter the output with all the derivations from the start symbol,
rather they start on the "conflicted nonterminal". They go straight to the
point. Second, they don't "expand" nonterminal symbols uselessly.
**** Reports
Counterexamples are also included in the report when given
`--report=counterexamples`/`-rcex` (or `--report=all`), with more
technical details:
State 7
1 exp: "if" exp "then" exp • [$end, "then", "else"]
2 | "if" exp "then" exp • "else" exp
"else" shift, and go to state 8
"else" [reduce using rule 1 (exp)]
$default reduce using rule 1 (exp)
shift/reduce conflict on token "else":
1 exp: "if" exp "then" exp •
2 exp: "if" exp "then" exp • "else" exp
Example: "if" exp "then" "if" exp "then" exp • "else" exp
Shift derivation
exp
↳ "if" exp "then" exp
↳ "if" exp "then" exp • "else" exp
Example: "if" exp "then" "if" exp "then" exp • "else" exp
Reduce derivation
exp
↳ "if" exp "then" exp "else" exp
↳ "if" exp "then" exp •
*** File prefix mapping
@@ -107,6 +189,11 @@ Changes in the display of counterexamples.
** Changes
*** Diagnostics
When text styling is enabled and the terminal supports it, the warnings
now include hyperlinks to the documentation.
*** Relocatable installation
When installed to be relocatable (via `configure --enable-relocatable`),
@@ -147,6 +234,18 @@ Changes in the display of counterexamples.
Now the parser state can be examined when parsing is finished. The parser
state is reset when starting a new parse.
** Documentation
*** Examples
The bistromathic demonstrates %param and how to quote sources in the error
messages:
> 123 456
1.5-7: syntax error: expected end of file or + or - or * or / or ^ before number
1 | 123 456
| ^~~
** Bug fixes
*** Include the generated header (yacc.c)
@@ -488,7 +587,8 @@ Changes in the display of counterexamples.
\005) with incorrect styling. Fixes for similar issues with unexpectedly
short lines (e.g., the file was changed between parsing and diagnosing).
Several unlikely crashes found by fuzzing have been fixed.
Some unlikely crashes found by fuzzing have been fixed. This is only
about bison itself, not the generated parsers.
* Noteworthy changes in release 3.5.2 (2020-02-13) [stable]
@@ -4412,7 +4512,7 @@ LocalWords: yysymbol yytnamerr yyreport ctx ARGMAX yysyntax stderr LPAREN
LocalWords: symrec yypcontext TOKENMAX yyexpected YYEMPTY yypstate YYEOF
LocalWords: autocompletion bistromathic submessages Cayuela lexcalc hoc
LocalWords: yytoken YYUNDEF YYerror basename Automake's UTF ifdef ffile
LocalWords: gotos readline Imbimbo Wcounterexamples
LocalWords: gotos readline Imbimbo Wcounterexamples Wcex Nonunifying rcex
Local Variables:
ispell-dictionary: "american"
+12 -3
View File
@@ -42,9 +42,11 @@ installing it. In that case, do not use `src/bison`: it would use the
As an experimental feature, diagnostics are now colored, controlled by the
`--color` and `--style` options.
To use them, install the libtextstyle library before configuring Bison. It
is available from https://alpha.gnu.org/gnu/gettext/, for instance
https://alpha.gnu.org/pub/gnu/gettext/libtextstyle-0.20.5.tar.gz.
To use them, install the libtextstyle library, 0.20.5 or newer, before
configuring Bison. It is available from https://alpha.gnu.org/gnu/gettext/,
for instance https://alpha.gnu.org/gnu/gettext/libtextstyle-0.20.5.tar.gz,
or as part of Gettext 0.21 or newer, for instance
https://ftp.gnu.org/gnu/gettext/gettext-0.21.tar.gz.
The option --color supports the following arguments:
- always, yes: Enable colors.
@@ -61,6 +63,13 @@ To customize the styles, create a CSS file, say `bison-bw.css`, similar to
then invoke bison with `--style=bison-bw.css`, or set the `BISON_STYLE`
environment variable to `bison-bw.css`.
In some diagnostics, bison uses libtextstyle to emit special escapes to
generate clickable hyperlinks. The environment variable
`NO_TERM_HYPERLINKS` can be used to suppress them. This may be useful for
terminal emulators which produce garbage output when they receive the escape
sequence for a hyperlink. Currently (as of 2020), this affects some versions
of emacs, guake, konsole, lxterminal, rxvt, yakuake.
## Relocatability
If you pass `--enable-relocatable` to `configure`, Bison is relocatable.
+3
View File
@@ -106,9 +106,11 @@ Keith Browne [email protected]
Ken Moffat [email protected]
Kiyoshi Kanazawa [email protected]
Lars Maier [email protected]
Lars Wendler [email protected]
László Várady [email protected]
Laurent Mascherpa [email protected]
Lie Yan [email protected]
Maarten De Braekeleer [email protected]
Magnus Fromreide [email protected]
Marc Autret [email protected]
Marc Mendiola [email protected]
@@ -185,6 +187,7 @@ Simon Sobisch [email protected]
Stefano Lattarini [email protected]
Stephen Cameron [email protected]
Steve Murphy [email protected]
Suhwan Song [email protected]
Sum Wu [email protected]
Théophile Ranquet [email protected]
Thiru Ramakrishnan [email protected]
+306 -16
View File
@@ -1,4 +1,12 @@
* Bison 3.7
* Soon
** gnulib
Bruno notes:
> I haven't looked deeply, but it strikes me that gnulib/lib/bitset/array.c
> does not make use of the 'ffsl' function, nor or the 'integer_length_l'
> function. Maybe because in Bison, all bitsets are so dense that it does
> not give a performance advantage?
** Cex
*** Improve gnulib
Don't do this (counterexample.c):
@@ -48,13 +56,6 @@ Unless we play it dumb (little structure).
- promote YYEOF rather than EOF.
*** D
- is there a way to attach yysymbol_name to the enum itself? As we did
in Java.
- It would be better to have TokenKind as return value. Can we use
reflection to support both output types?
** YYerror
https://git.savannah.gnu.org/gitweb/?p=gettext.git;a=blob;f=gettext-runtime/intl/plural.y;h=a712255af4f2f739c93336d4ff6556d932a426a5;hb=HEAD
@@ -67,7 +68,7 @@ Stop hard-coding "Calc". Adjust local.at (look for FIXME).
** A dev warning for b4_
Maybe we should check for m4_ and b4_ leaking out of the m4 processing, as
Autoconf does. It would have caught overquotation issues.
Autoconf does. It would have caught over-quotation issues.
** doc
I feel it's ugly to use the GNU style to declare functions in the doc. It
@@ -88,7 +89,7 @@ push parsers on top of pull parser. Which is currently not relevant, since
push parsers are measurably slower.
** %define parse.error formatted
How about pushing bistromathics' yyreport_syntax_error as another standard
How about pushing Bistromathic's yyreport_syntax_error as another standard
way to generate the error message, and leave to the user the task of
providing the message formats? Currently in bistro, it reads:
@@ -202,18 +203,282 @@ The "automaton" and "set" categories are not so useful. We should probably
introduce lr(0) and lalr, just the way we have ielr categories. The
"closure" function is too verbose, it should probably have its own category.
"set" can still be used for summariring the important sets. That would make
"set" can still be used for summarizing 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
name they have in GCC, clang, etc. Likewise for the complain_* series of
functions.
*** ritem
states/nstates, rules/nrules, ..., ritem/nritems
Fix the latter.
* D programming language
There's a number of features that are missing, here sorted in _suggested_
order of implementation.
When copying code from other skeletons, keep the comments exactly as they
are. Keep the same variable names. If you change the wording in one place,
do it in the others too. In other words: make sure to keep the
maintenance *simple* by avoiding any gratuitous difference.
** Rename the D example
Move the current content of examples/d into examples/d/simple.
** Create a second example
Duplicate examples/d/simple into examples/d/calc.
** Add location tracking to d/calc
Look at the examples in the other languages to see how to do that.
** yysymbol_name
The SymbolKind is an enum. For a given SymbolKind we want to get its string
representation. Currently it's a separate table in the parser that does
that:
/* Symbol kinds. */
public enum SymbolKind
{
S_YYEMPTY = -2, /* No symbol. */
S_YYEOF = 0, /* "end of file" */
S_YYerror = 1, /* error */
S_YYUNDEF = 2, /* "invalid token" */
S_EQ = 3, /* "=" */
...
S_input = 14, /* input */
S_line = 15, /* line */
S_exp = 16, /* exp */
};
...
/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
First, the terminals, then, starting at \a yyntokens_, nonterminals. */
private static immutable string[] yytname_ =
[
"\"end of file\"", "error", "\"invalid token\"", "\"=\"", "\"+\"",
"\"-\"", "\"*\"", "\"/\"", "\"(\"", "\")\"", "\"end of line\"",
"\"number\"", "UNARY", "$accept", "input", "line", "exp", null
];
...
So to get a symbol kind, one runs `yytname_[yykind]`.
Is there a way to attach this conversion to string to SymbolKind? In Java
for instance, we have:
public enum SymbolKind
{
S_YYEOF(0), /* "end of file" */
S_YYerror(1), /* error */
S_YYUNDEF(2), /* "invalid token" */
...
S_input(16), /* input */
S_line(17), /* line */
S_exp(18); /* exp */
private final int yycode_;
SymbolKind (int n) {
this.yycode_ = n;
}
...
/* YYNAMES_[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
First, the terminals, then, starting at \a YYNTOKENS_, nonterminals. */
private static final String[] yynames_ = yynames_init();
private static final String[] yynames_init()
{
return new String[]
{
i18n("end of file"), i18n("error"), i18n("invalid token"), "!", "+", "-", "*",
"/", "^", "(", ")", "=", i18n("end of line"), i18n("number"), "NEG",
"$accept", "input", "line", "exp", null
};
}
/* The user-facing name of this symbol. */
public final String getName() {
return yynames_[yycode_];
}
};
which allows to write more naturally `yykind.getName()` rather than
`yytname_[yykind]`. Is there something comparable in (idiomatic) D?
** Change the return value of yylex
Historically people were allowed to return any int from the scanner (which
is convenient and allows `return '+'` from the scanner). Akim tends to see
this as an error, we should restrict the return values to TokenKind (not to
be confused with SymbolKind).
In the case of D, without the history, we have the choice to support or not
`int`. If we want to _keep_ `int`, is there a way, say via introspection,
to support both signatures of yylex? If we don't keep `int`, just move to
TokenKind.
** Documentation
Write documentation about D support in doc/bison.texi. Imitate the Java
documentation. You should be more succinct IMHO.
** Complete Symbols
The current interface from the scanner to the parser is somewhat clumsy: the
token kind is returned by yylex, but the value and location are stored in
the scanner. This reflects the fact that the implementation of the parser
uses three variables to deal with each parsed symbol: its kind, its value,
its location.
So today the scanner of examples/d/calc.d (no locations) looks like:
if (input.front.isNumber)
{
import std.conv : parse;
semanticVal_.ival = input.parse!int;
return TokenKind.NUM;
}
and the generated parser:
/* Read a lookahead token. */
if (yychar == TokenKind.YYEMPTY)
{
yychar = yylex ();
yylval = yylexer.semanticVal;
}
The parser class should feature a `Symbol` type which binds together kind,
value and location, and the scanner should be able to return an instance of
that type. Something like
if (input.front.isNumber)
{
import std.conv : parse;
return parser.Symbol (TokenKind.NUM, input.parse!int);
}
** Token Constructors
In the previous example it is possible to mix incorrectly kinds and values,
and for instance:
return parser.Symbol (TokenKind.NUM, "Hello, World!\n");
attaches a string value to NUM kind (wrong, of course). When
api.token.constructor is set, in C++, Bison generated "token constructors":
parser.make_NUM. parser.make_PLUS, parser.make_STRING, etc. The previous
example becomes
return parser.make_NUM ("Hello, World!\n");
which would easily be caught by the type checker.
** Lookahead Correction
Add support for LAC to the D skeleton. It should not be too hard: look how
this is done in lalr1.cc, and mock it.
** Push Parser
Add support for push parser. Do not start a nice skeleton, just enhance the
current one to support push parsers. This is going to be a tougher nut to
crack.
First, you need to understand well how the push parser is expected to work.
To this end:
- read the doc
- look at examples/c/pushcalc
- create an example of a Java push parser.
- have a look at the generated parser in Java, which has the advantage of
being already based on a parser object, instead of just a function.
The C case is harder to read, but it may help too. Keep in mind that
because there's no object to maintain state, the C push parser uses some
struct (yypstate) to preserve this state. We don't need this in D, the
parser object will suffice.
I think working directly on the skeleton to add push-parser support is not
the simplest path. I suggest that you (1) transform a generated parser into
a push parser by hand, and then (2) transform lalr1.d to generate such a
parser.
Use `git commit` frequently to make sure you keep track of your progress.
*** (1.a) Prepare pull parser by hand
Copy again one of the D examples into say examples/d/pushcalc. Also
check-in the generated parser to facilitate experimentation.
- find local variables of yyparse should become members of the parser object
(so that we preserve state from one call to the next).
- do it in your generated D parser. We don't need an equivalent for
yypstate, because we already have it: that the parser object itself.
- have your *pull*-parser (i.e., the good old yy::parser::parse()) work
properly this way. Write and run tests. That's one of the reasons I
suggest using examples/d/calc as a starting point: it already has tests,
you can/should add more.
At this point you have a pull-parser which you prepared to turn into a
push-parser.
*** (1.b) Turn pull parser into push parser by hand
- look again at how push parsers are implemented in Java/C to see what needs
to change in yyparse so that the control is inverted: parse() will
be *given* the tokens, instead of having to call yylex itself. When I say
"look at C", I think your best option are (i) yacc.c (look for b4_push_if)
and (ii) examples/c/pushcalc.
- rename parse() as push_parse(Symbol yyla) (or push_parse(TokenKind, Value,
Location)) that takes the symbol as argument. That's the push parser we
are looking for.
- define a new parse() function which has the same signature as the usual
pull-parser, that repeatedly calls the push_parse function. Something
like this:
int parse ()
{
int status = 0;
do {
status = this->push_parse (yylex());
} while (status == YYPUSH_MORE);
return status;
}
- show me that parser, so that we can validate the approach.
*** (2) Port that into the skeleton
- once we agree on the API of the push parser, implement it into lalr1.d.
You will probaby need help on this regard, but imitation, again, should
help.
- have example/d/pushcalc work properly and pass tests
- add tests in the "real" test suite. Do that in tests/calc.at. I can
help.
- document
** GLR Parser
This is very ambitious. That's the final boss. There are currently no
"clean" implementation to get inspiration from.
glr.c is very clean but:
- is low-level C
- is a different skeleton from yacc.c
glr.cc is (currently) an ugly hack: a C++ shell around glr.c. Valentin
Tolmer is currently rewriting glr.cc to be clean C++, but he is not
finished. There will be a lot a common code between lalr1.cc and glr.cc, so
eventually I would like them to be fused into a single skeleton, supporting
both deterministic and generalized parsing.
It would be great for D to also support this.
The basic ideas of GLR are explained here:
https://www.codeproject.com/Articles/5259825/GLR-Parsing-in-Csharp-How-to-Use-The-Most-Powerful
* Better error messages
The users are not provided with enough tools to forge their error messages.
See for instance "Is there an option to change the message produced by
@@ -231,7 +496,7 @@ and older C++ compilers. Currently the code defaults to defining it to
define it to the same type as the C ptrdiff_t type.
* Completion
Several features are not available in all the backends.
Several features are not available in all the back-ends.
- lac: D, Java (easy)
- push parsers: glr.c, glr.cc, lalr1.cc (not very difficult)
@@ -301,7 +566,7 @@ opposite side we have some use of \l, which is graphviz-specific, in what
should be generic code.
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
print{,-xml} counterpart. We would very much like to re-use the pretty format
of states from .output for the graphs, etc.
Since graphviz dies on medium-to-big grammars, maybe consider an other tool?
@@ -579,14 +844,39 @@ to bison. If you're interested, I'll work on a patch.
Equip the parser with a means to create the (visual) parse tree.
-----
# LocalWords: Cex gnulib gl Bistromathic TokenKinds yylex enum YYEOF EOF
# LocalWords: YYerror gettext af hb YYERRCODE undef calc FIXME dev yyerror
# LocalWords: Autoconf YYUNDEFTOK lexemes parsers Bistromathic's yyreport
# LocalWords: const argc yacc yyclearin lookahead destructor Rici incluent
# LocalWords: yydestruct yydiscardin catégories d'avertissements sr activé
# LocalWords: conflits défaut rr l'alias chaîne n'est attaché un symbole
# LocalWords: obsolète règle vide midrule valeurs de intermédiaire ou avec
# LocalWords: définies inutilisées priorité associativité inutiles POSIX
# LocalWords: incompatibilités tous les autres avertissements sauf dans rp
# LocalWords: désactiver CATEGORIE traiter comme des erreurs glr Akim bool
# LocalWords: Demaille arith lalr goto struct pathlen nullable ntokens lr
# LocalWords: nterm bitsetv ielr ritem nstates nrules nritems yysymbol EQ
# LocalWords: SymbolKind YYEMPTY YYUNDEF YYTNAME NUM yyntokens yytname sed
# LocalWords: nonterminals yykind yycode YYNAMES yynames init getName conv
# LocalWords: TokenKind semanticVal ival yychar yylval yylexer Tolmer hoc
# LocalWords: Sobisch YYPTRDIFF ptrdiff Autotest YYPRINT toknum yytoknum
# LocalWords: sym Wother stderr FP fixits xgettext fdiagnostics Graphviz
# LocalWords: graphviz VCG bitset xml bw maint yytoken YYABORT deps
# LocalWords: YYACCEPT yytranslate nonnegative destructors yyerrlab repo
# LocalWords: backends stmt expr yy Mardle baz qux Vadim Maslow CPP cpp
# LocalWords: yydebug gcc UCHAR EBCDIC gung PDP NUL Pre Florian Krohm utf
# LocalWords: YYACT YYLLOC YYLSP yyval yyvsp yylen yyloc yylsp endif
# LocalWords: ispell american
Local Variables:
mode: outline
coding: utf-8
fill-column: 76
ispell-dictionary: "american"
End:
-----
Copyright (C) 2001-2004, 2006, 2008-2015, 2018-2020 Free Software
Foundation, Inc.
+3 -1
View File
@@ -44,7 +44,9 @@ gnulib_modules='
realloc-posix
relocatable-prog relocatable-script
rename
spawn-pipe stdbool stpcpy strdup-posix strerror strverscmp
spawn-pipe stdbool stpcpy stpncpy strdup-posix strerror strverscmp
sys_ioctl
termios
timevar
unicodeio unistd unistd-safer unlink unlocked-io
update-copyright unsetenv verify
+2 -1
View File
@@ -126,7 +126,7 @@ _sed_rm_comments_q = $(subst ','\'',$(_sed_remove_comments))
_space_before_paren_exempt =? \\n\\$$
_space_before_paren_exempt = \
(^ *\#|(LA)?LR\([01]\)|percent_(code|define)|b4_syncline|m4_(define|init)|symbol)
(^ *\#|(LA)?LR\([01]\)|percent_(code|define)|b4_syncline|m4_(define|init))
# Ensure that there is a space before each open parenthesis in C code.
sc_space_before_open_paren:
@if $(VC_LIST_EXCEPT) | grep -l '\.[ch]$$' > /dev/null; then \
@@ -156,6 +156,7 @@ exclude = \
$(call exclude, \
bindtextdomain=^lib/main.c$$ \
cast_of_argument_to_free=^src/muscle-tab.c$$ \
error_message_uppercase=etc/bench.pl.in$$ \
po_check=^tests|(^po/POTFILES.in|.md)$$ \
preprocessor_indentation=^data/|^lib/|^src/parse-gram.[ch]$$ \
program_name=^lib/main.c$$ \
+3
View File
@@ -60,6 +60,9 @@ AC_PROG_CXX
# Gnulib (early checks).
gl_EARLY
# We want ostream_printf and hyperlink support.
gl_LIBTEXTSTYLE_OPTIONAL([0.20.5])
# Gnulib uses '#pragma GCC diagnostic push' to silence some
# warnings, but older gcc doesn't support this.
AC_CACHE_CHECK([whether pragma GCC diagnostic push works],
+1 -1
View File
@@ -172,7 +172,7 @@ m4_pushdef([b4_parse_param], m4_defn([b4_parse_param_orig]))dnl
const location_type* yylocationp]])[) const
{
*yycdebug_ << (yykind < YYNTOKENS ? "token" : "nterm")
<< ' ' << yytname[yykind] << " ("]b4_locations_if([[
<< ' ' << yysymbol_name (yykind) << " ("]b4_locations_if([[
<< *yylocationp << ": "]])[;
yy_symbol_value_print_ (yykind, yyvaluep]b4_locations_if([[, yylocationp]])[);
*yycdebug_ << ')';
+2 -2
View File
@@ -1486,7 +1486,7 @@ yypstate_new (void)
yypstate *yyps;]b4_pure_if([], [[
if (yypstate_allocated)
return YY_NULLPTR;]])[
yyps = YY_CAST (yypstate *, malloc (sizeof *yyps));
yyps = YY_CAST (yypstate *, YYMALLOC (sizeof *yyps));
if (!yyps)
return YY_NULLPTR;]b4_pure_if([], [[
yypstate_allocated = 1;]])[
@@ -1515,7 +1515,7 @@ yypstate_delete (yypstate *yyps)
#endif]b4_lac_if([[
if (yyes != yyesa)
YYSTACK_FREE (yyes);]])[
free (yyps);]b4_pure_if([], [[
YYFREE (yyps);]b4_pure_if([], [[
yypstate_allocated = 0;]])[
}
}
+286 -87
View File
@@ -57,44 +57,57 @@
\gdef\colorPurple{%
\setcolor{\rgbPurple}%
}
\gdef\colorOff{%
\setcolor{\maincolor}%
}
\gdef\rgbError{0.80 0 0}
\gdef\colorError{%
\gdef\diagError{%
\setcolor{\rgbError}%
}
\gdef\rgbNotice{0 0 0.80}
\gdef\colorNotice{%
\gdef\diagNotice{%
\setcolor{\rgbNotice}%
}
\gdef\colorOff{%
\gdef\rgbWarning{0.50 0 0.50}
\gdef\diagWarning{%
\setcolor{\rgbWarning}%
}
\gdef\diagOff{%
\setcolor{\maincolor}%
}
@end tex
@ifnottex
@macro colorGreen
@inlineraw{html, <b style="color:green">}
@inlineraw{html, <span style="color:green">}
@end macro
@macro colorYellow
@inlineraw{html, <b style="color:#ff8000">}
@inlineraw{html, <span style="color:#ff8000">}
@end macro
@macro colorRed
@inlineraw{html, <b style="color:red">}
@inlineraw{html, <span style="color:red">}
@end macro
@macro colorBlue
@inlineraw{html, <b style="color:blue">}
@inlineraw{html, <span style="color:blue">}
@end macro
@macro colorPurple
@inlineraw{html, <b style="color:darkviolet">}
@end macro
@macro colorError
@inlineraw{html, <b style="color:red">}
@end macro
@macro colorNotice
@inlineraw{html, <b style="color:darkcyan">}
@inlineraw{html, <span style="color:darkviolet">}
@end macro
@macro colorOff
@inlineraw{html, </span>}
@end macro
@macro diagError
@inlineraw{html, <b style="color:red">}
@end macro
@macro diagNotice
@inlineraw{html, <b style="color:darkcyan">}
@end macro
@macro diagWarning
@inlineraw{html, <b style="color:darkviolet">}
@end macro
@macro diagOff
@inlineraw{html, </b>}
@end macro
@end ifnottex
@@ -120,15 +133,15 @@
@end macro
@macro dwarning{text}
@purple{\text\}
@diagWarning{}\text\@diagOff{}
@end macro
@macro derror{text}
@colorError{}\text\@colorOff{}
@diagError{}\text\@diagOff{}
@end macro
@macro dnotice{text}
@colorNotice{}\text\@colorOff{}
@diagNotice{}\text\@diagOff{}
@end macro
@finalout
@@ -6283,7 +6296,10 @@ Introduced in Bison 3.3 to replace @code{parser_class_name}.
@item Default Value: @code{YY} for Java, @code{yy} otherwise.
@item History: introduced in Bison 2.6
@item History:
introduced in Bison 2.6, with its argument in double quotes. Uses braces
since Bison 3.0 (double quotes are still supported for backward
compatibility).
@end itemize
@end deffn
@@ -8302,7 +8318,53 @@ write an unambiguous grammar, but that is very hard to do in this case.)
This particular ambiguity was first encountered in the specifications of
Algol 60 and is called the ``dangling @code{else}'' ambiguity.
To avoid warnings from Bison about predictable, legitimate shift/reduce
To assist the grammar author in understanding the nature of each conflict,
Bison can be asked to generate ``counterexamples''. In the present case it
actually even proves that the grammar is ambiguous by exhibiting a string
with two different parses:
@macro danglingElseCex
@group
@ifnottex
Example: @yellow{"if" expr "then"} @blue{"if" expr "then" stmt} @red{•} @blue{"else" stmt}
Shift derivation
@yellow{if_stmt}
@yellow{↳ "if" expr "then"} @green{stmt}
@green{↳} @blue{if_stmt}
@blue{↳ "if" expr "then" stmt} @red{•} @blue{"else" stmt}
Example: @yellow{"if" expr "then"} @blue{"if" expr "then" stmt} @red{•} @yellow{"else" stmt}
Reduce derivation
@yellow{if_stmt}
@yellow{↳ "if" expr "then"} @green{stmt} @yellow{"else" stmt}
@green{↳} @blue{if_stmt}
@blue{↳ "if" expr "then" stmt} @red{•}
@end ifnottex
@iftex
Example: @yellow{"if" expr "then"} @blue{"if" expr "then" stmt} @red{•} @blue{"else" stmt}
Shift derivation
@yellow{if_stmt}
@yellow{@arrow{} "if" expr "then"} @green{stmt}
@green{@arrow{}} @blue{if_stmt}
@blue{@arrow{} "if" expr "then" stmt} @red{•} @blue{"else" stmt}
Example: @yellow{"if" expr "then"} @blue{"if" expr "then" stmt} @red{•} @yellow{"else" stmt}
Reduce derivation
@yellow{if_stmt}
@yellow{@arrow{} "if" expr "then"} @green{stmt} @yellow{"else" stmt}
@green{@arrow{}} @blue{if_stmt}
@blue{@arrow{} "if" expr "then" stmt} @red{•}
@end iftex
@end group
@end macro
@example
@danglingElseCex
@end example
@noindent
@xref{Counterexamples}, for more details.
@sp 1
To avoid warnings from Bison about predictable, @emph{legitimate} shift/reduce
conflicts, you can use the @code{%expect @var{n}} declaration.
There will be no warning as long as the number of shift/reduce conflicts
is exactly @var{n}, and Bison will report an error if there is a
@@ -8693,7 +8755,8 @@ maybeword:
@end example
@noindent
The error is an ambiguity: there is more than one way to parse a single
The error is an ambiguity: as counterexample generation would demonstrate
(@pxref{Counterexamples}), there is more than one way to parse a single
@code{word} into a @code{sequence}. It could be reduced to a
@code{maybeword} and then into a @code{sequence} via the second rule.
Alternatively, nothing-at-all could be reduced into a @code{sequence}
@@ -8890,12 +8953,14 @@ name_list:
It would seem that this grammar can be parsed with only a single token of
lookahead: when a @code{param_spec} is being read, an @code{"id"} is a
@code{name} if a comma or colon follows, or a @code{type} if another
@code{"id"} follows. In other words, this grammar is LR(1).
@code{"id"} follows. In other words, this grammar is LR(1). Yet Bison
finds one reduce/reduce conflict, for which counterexample generation
(@pxref{Counterexamples}) would find a @emph{nonunifying} example.
@cindex LR
@cindex LALR
However, for historical reasons, Bison cannot by default handle all
LR(1) grammars.
This is because Bison does not handle all LR(1) grammars @emph{by default},
for historical reasons.
In this grammar, two contexts, that after an @code{"id"} at the beginning
of a @code{param_spec} and likewise at the beginning of a
@code{return_spec}, are similar enough that Bison assumes they are the
@@ -9870,6 +9935,9 @@ and understand the parser run-time traces (@pxref{Tracing}).
@node Counterexamples
@section Generation of Counterexamples
@cindex cex
@cindex counterexamples
@cindex conflict counterexamples
Solving conflicts is probably the most delicate part of the design of an LR
parser, as demonstrated by the number of sections devoted to them in this
@@ -9886,13 +9954,14 @@ That task is made much easier thanks to the generation of counterexamples,
initially developed by Chinawat Isradisaikul and Andrew Myers
@pcite{Isradisaikul 2015}.
As a first example, see the example grammar of @ref{Shift/Reduce}, which
features on shift/reduce conflict:
As a first example, see the grammar of @ref{Shift/Reduce}, which features
one shift/reduce conflict:
@c see doc/if-then-else.y
@example
$ @kbd{bison if-then-else.y}
if-then-else.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
if-then-else.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
if-then-else.y: @dwarning{warning}: 1 shift/reduce conflict [@dwarning{-Wconflicts-sr}]
if-then-else.y: @dnotice{note}: rerun with option '-Wcounterexamples' to generate conflict counterexamples
@end example
@noindent
@@ -9900,41 +9969,21 @@ Let's rerun @command{bison} with the option
@option{-Wcex}/@option{-Wcounterexamples}@inlinefmt{info, (the following
output is actually in color)}:
@ifhtml
@example
Shift/reduce conflict on token "else":
@group
Example @yellow{"if" expr "then"} @blue{"if" expr "then" stmt} @red{•} @blue{"else" stmt}
Shift derivation @yellow{if_stmt @arrow{} [ "if" expr "then"} @green{stmt @arrow{} [} @blue{if_stmt @arrow{} [ "if" expr "then" stmt} @red{•} @blue{"else" stmt ]} @green{]} @yellow{]}
Example @yellow{"if" expr "then"} @blue{"if" expr "then" stmt} @red{•} @yellow{"else" stmt}
Reduce derivation @yellow{if_stmt @arrow{} [ "if" expr "then"} @green{stmt @arrow{} [} @blue{if_stmt @arrow{} [ "if" expr "then" stmt} @red{•} @blue{]} @green{]} @yellow{"else" stmt ]}
@end group
if-then-else.y: @dwarning{warning}: 1 shift/reduce conflict [@dwarning{-Wconflicts-sr}]
if-then-else.y: @dwarning{warning}: shift/reduce conflict on token "else" [@dwarning{-Wcounterexamples}]
@danglingElseCex
@end example
@end ifhtml
@ifnothtml
@smallexample
Shift/reduce conflict on token "else":
@group
Example
@yellow{"if" expr "then"} @blue{"if" expr "then" stmt} @red{•} @blue{"else" stmt}
Shift derivation
@yellow{if_stmt @arrow{} [ "if" expr "then"} @green{stmt @arrow{} [} @blue{if_stmt @arrow{} [ "if" expr "then" stmt} @red{•} @blue{"else" stmt ]} @green{]} @yellow{]}
Example
@yellow{"if" expr "then"} @blue{"if" expr "then" stmt} @red{•} @yellow{"else" stmt}
Reduce derivation
@yellow{if_stmt @arrow{} [ "if" expr "then"} @green{stmt @arrow{} [} @blue{if_stmt @arrow{} [ "if" expr "then" stmt} @red{•} @blue{]} @green{]} @yellow{"else" stmt ]}
@end group
@end smallexample
@end ifnothtml
This shows two different derivations for one single expression. That
demonstrates that the grammar is ambiguous.
This shows two different derivations for one single expression, which proves
that the grammar is ambiguous.
@sp 1
As a more delicate example, consider the example grammar of
@ref{Reduce/Reduce}, which features a reduce/reduce conflict:
@c doc/sequence.y
@example
%%
sequence:
@@ -9951,30 +10000,103 @@ maybeword:
Bison generates the following counterexamples:
@example
@group
$ @kbd{bison -Wcex sequence.y}
sequence.y: @dwarning{warning}: 1 shift/reduce conflict [@dwarning{-Wconflicts-sr}]
sequence.y: @dwarning{warning}: 2 reduce/reduce conflicts [@dwarning{-Wconflicts-rr}]
Shift/reduce conflict on token "word":
Example @red{•} @green{"word"}
Shift derivation @yellow{sequence @arrow{} [} @green{maybeword @arrow{} [} @red{•} @green{"word" ]} @yellow{]}
Example @red{•} @yellow{"word"}
Reduce derivation @yellow{sequence @arrow{} [} @green{sequence @arrow{} [} @red{•} @green{]} @yellow{"word" ]}
Reduce/reduce conflict on tokens $end, "word":
Example @red{•}
First derivation @yellow{sequence @arrow{} [} @red{•} @yellow{]}
Example @red{•}
Second derivation @yellow{sequence @arrow{} [} @green{maybeword @arrow{} [} @red{•} @green{]} @yellow{]}
Shift/reduce conflict on token "word":
Example @red{•} @green{"word"}
Shift derivation @yellow{sequence @arrow{} [} @green{maybeword @arrow{} [} @red{•} @green{"word" ]} @yellow{]}
Example @red{•} @yellow{"word"}
Reduce derivation @yellow{sequence @arrow{} [} @green{sequence @arrow{} [} @blue{maybeword @arrow{} [} @red{•} @blue{]} @green{]} @yellow{"word" ]}
@end group
@ifnottex
@group
sequence.y: @dwarning{warning}: shift/reduce conflict on token "word" [@dwarning{-Wcounterexamples}]
Example: @red{•} @green{"word"}
Shift derivation
@yellow{sequence}
@yellow{↳} @green{maybeword}
@green{↳} @red{•} @green{"word"}
Example: @red{•} @yellow{"word"}
Reduce derivation
@yellow{sequence}
@yellow{↳} @green{sequence} @yellow{"word"}
@green{↳} @red{•}
@end group
@group
sequence.y: @dwarning{warning}: reduce/reduce conflict on tokens $end, "word" [@dwarning{-Wcounterexamples}]
Example: @red{•}
First reduce derivation
@yellow{sequence}
@yellow{↳} @red{•}
Example: @red{•}
Second reduce derivation
@yellow{sequence}
@yellow{↳} @green{maybeword}
@green{↳} @red{•}
@end group
@group
sequence.y: @dwarning{warning}: shift/reduce conflict on token "word" [@dwarning{-Wcounterexamples}]
Example: @red{•} @green{"word"}
Shift derivation
@yellow{sequence}
@yellow{↳} @green{maybeword}
@green{↳} @red{•} @green{"word"}
Example: @red{•} @yellow{"word"}
Reduce derivation
@yellow{sequence}
@yellow{↳} @green{sequence} @yellow{"word"}
@green{↳} @blue{maybeword}
@blue{↳} @red{•}
@end group
@group
sequence.y:8.3-45: @dwarning{warning}: rule useless in parser due to conflicts [@dwarning{-Wother}]
8 | @dwarning{%empty @{ printf ("empty maybeword\n"); @}}
| @dwarning{^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}
@end group
@end ifnottex
@iftex
@group
sequence.y: @dwarning{warning}: shift/reduce conflict on token "word" [@dwarning{-Wcounterexamples}]
Example: @red{•} @green{"word"}
Shift derivation
@yellow{sequence}
@yellow{@arrow{}} @green{maybeword}
@green{@arrow{}} @red{•} @green{"word"}
Example: @red{•} @yellow{"word"}
Reduce derivation
@yellow{sequence}
@yellow{@arrow{}} @green{sequence} @yellow{"word"}
@green{@arrow{}} @red{•}
@end group
@group
sequence.y: @dwarning{warning}: reduce/reduce conflict on tokens $end, "word" [@dwarning{-Wcounterexamples}]
Example: @red{•}
First reduce derivation
@yellow{sequence}
@yellow{@arrow{}} @red{•}
Example: @red{•}
Second reduce derivation
@yellow{sequence}
@yellow{@arrow{}} @green{maybeword}
@green{@arrow{}} @red{•}
@end group
@group
sequence.y: @dwarning{warning}: shift/reduce conflict on token "word" [@dwarning{-Wcounterexamples}]
Example: @red{•} @green{"word"}
Shift derivation
@yellow{sequence}
@yellow{@arrow{}} @green{maybeword}
@green{@arrow{}} @red{•} @green{"word"}
Example: @red{•} @yellow{"word"}
Reduce derivation
@yellow{sequence}
@yellow{@arrow{}} @green{sequence} @yellow{"word"}
@green{@arrow{}} @blue{maybeword}
@blue{@arrow{}} @red{•}
@end group
@group
sequence.y:8.3-45: @dwarning{warning}: rule useless in parser due to conflicts [@dwarning{-Wother}]
8 | @dwarning{%empty @{ printf ("empty maybeword\n"); @}}
| @dwarning{^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}
@end group
@end iftex
@end example
Each of these three conflicts, again, prove that the grammar is ambiguous.
@@ -9989,6 +10111,7 @@ that are the same up until the dot. Most notably, this will happen when
your grammar requires a stronger parser (more lookahead, LR instead of
LALR). The following example isn't LR(1):
@c doc/ids.y
@example
%token ID
%%
@@ -9999,13 +10122,54 @@ expr: %empty | expr ID ','
@command{bison} reports:
@smallexample
Shift/reduce conflict on token ID:
First example @purple{expr} @red{•} @purple{ID ','} @green{ID} @yellow{$end}
Shift derivation @yellow{$accept @arrow{} [} @green{s @arrow{} [} @blue{a @arrow{} [} @purple{expr @arrow{} [ expr} @red{•} @purple{ID ',' ]} @blue{]} @green{ID ]} @yellow{$end ]}
Second example @blue{expr} @red{•} @green{ID} @yellow{$end}
Reduce derivation @yellow{$accept @arrow{} [} @green{s @arrow{} [} @blue{a @arrow{} [ expr} @red{•} @blue{]} @green{ID ]} @yellow{$end ]}
@end smallexample
@example
ids.y: @dwarning{warning}: 1 shift/reduce conflict [@dwarning{-Wconflicts-sr}]
ids.y: @dwarning{warning}: shift/reduce conflict on token ID [@dwarning{-Wcounterexamples}]
@ifnottex
@group
First example: @purple{expr} @red{•} @purple{ID ','} @green{ID} @yellow{$end}
Shift derivation
@yellow{$accept}
@yellow{↳} @green{s} @yellow{$end}
@green{↳} @blue{a} @green{ID}
@blue{↳} @purple{expr}
@purple{↳ expr} @red{•} @purple{ID ','}
Second example: @blue{expr} @red{•} @green{ID} @yellow{$end}
Reduce derivation
@yellow{$accept}
@yellow{↳} @green{s} @yellow{$end}
@green{↳} @blue{a} @green{ID}
@blue{↳ expr} @red{•}
@end group
@group
ids.y:4.4-7: @dwarning{warning}: rule useless in parser due to conflicts [@dwarning{-Wother}]
4 | a: expr
| ^~~~
@end group
@end ifnottex
@iftex
@group
First example: @purple{expr} @red{•} @purple{ID ','} @green{ID} @yellow{$end}
Shift derivation
@yellow{$accept}
@yellow{@arrow{}} @green{s} @yellow{$end}
@green{@arrow{}} @blue{a} @green{ID}
@blue{@arrow{}} @purple{expr}
@purple{@arrow{} expr} @red{•} @purple{ID ','}
Second example: @blue{expr} @red{•} @green{ID} @yellow{$end}
Reduce derivation
@yellow{$accept}
@yellow{@arrow{}} @green{s} @yellow{$end}
@green{@arrow{}} @blue{a} @green{ID}
@blue{@arrow{} expr} @red{•}
@end group
@group
ids.y:4.4-7: @dwarning{warning}: rule useless in parser due to conflicts [@dwarning{-Wother}]
4 | a: expr
| ^~~~
@end group
@end iftex
@end example
This conflict is caused by the parser not having enough information to know
the difference between these two examples. The parser would need an
@@ -10041,6 +10205,7 @@ by default. As a consequence, the verbose output file is called
The following grammar file, @file{calc.y}, will be used in the sequel:
@c doc/calc.y
@example
@group
%union
@@ -10084,7 +10249,7 @@ calc.y:19.1-7: @dwarning{warning}: nonterminal useless in grammar: useless [@dwa
19 | @dwarning{useless: STR;}
| @dwarning{^~~~~~~}
calc.y: @dwarning{warning}: 7 shift/reduce conflicts [@dwarning{-Wconflicts-sr}]
calc.y: @dwarning{warning}: rerun with option '-Wcounterexamples' to generate conflict counterexamples [@dwarning{-Wother}]
calc.y: @dnotice{note}: rerun with option '-Wcounterexamples' to generate conflict counterexamples
@end smallexample
Going back to the calc example, when given @option{--report=state},
@@ -10396,15 +10561,44 @@ When given @option{--report=counterexamples}, @command{bison} will generate
counterexamples within the report, augmented with the corresponding items
(@pxref{Counterexamples}).
@ifnottex
@example
Shift/reduce conflict on token '/':
shift/reduce conflict on token '/':
1 exp: exp '+' exp •
4 exp: exp • '/' exp
Example @yellow{exp '+'} @green{exp} @red{•} @green{'/' exp}
Shift derivation @yellow{exp @arrow{} [ exp '+'} @green{exp @arrow{} [ exp} @red{•} @green{'/' exp ]} @yellow{]}
Example @green{exp '+' exp} @red{•} @yellow{'/' exp}
Reduce derivation @yellow{exp @arrow{} [} @green{exp @arrow{} [ exp '+' exp} @red{•} @green{]} @yellow{'/' exp ]}
@group
Example: exp '+' exp • '/' exp
Shift derivation
exp
↳ exp '+' exp
↳ exp • '/' exp
Example: exp '+' exp • '/' exp
Reduce derivation
exp
↳ exp '/' exp
↳ exp '+' exp •
@end group
@end example
@end ifnottex
@iftex
@example
shift/reduce conflict on token '/':
1 exp: exp '+' exp •
4 exp: exp • '/' exp
@group
Example: exp '+' exp • '/' exp
Shift derivation
exp
@arrow{} exp '+' exp
@arrow{} exp • '/' exp
Example: exp '+' exp • '/' exp
Reduce derivation
exp
@arrow{} exp '/' exp
@arrow{} exp '+' exp •
@end group
@end example
@end iftex
This shows two separate derivations in the grammar for the same @code{exp}:
@samp{e1 + e2 / e3}. The derivations show how your rules would parse the
@@ -11414,7 +11608,8 @@ releases of Bison may move warnings from this category to new, more specific
categories.
@item @anchor{Wall}all
All the warnings except @code{dangling-alias} and @code{yacc}.
All the warnings except @code{counterexamples}, @code{dangling-alias} and
@code{yacc}.
@item @anchor{Wnone}none
Turn off all the warnings.
@@ -15458,6 +15653,10 @@ permitted. @xref{Language and Grammar}.
A sequence of tokens and/or nonterminals, with one dot, that demonstrates a
conflict. The dot marks the place where the conflict occurs.
@cindex unifying counterexample
@cindex counterexample, unifying
@cindex nonunifying counterexample
@cindex counterexample, nonunifying
A @emph{unifying} counterexample is a single string that has two different
parses; its existence proves that the grammar is ambiguous. When a unifying
counterexample cannot be found in reasonable time, a @emph{nonunifying}
@@ -15854,7 +16053,7 @@ London, Department of Computer Science, TR-00-12 (December 2000).
@c LocalWords: TokenKind Automake's rtti Wcounterexamples Chinawat PLDI
@c LocalWords: Isradisaikul tcite pcite rgbGreen colorGreen rgbYellow Wcex
@c LocalWords: colorYellow rgbRed colorRed rgbBlue colorBlue rgbPurple
@c LocalWords: colorPurple ifhtml ifnothtml situ rcex
@c LocalWords: colorPurple ifhtml ifnothtml situ rcex MERCHANTABILITY Wnone
@c Local Variables:
@c ispell-dictionary: "american"
+23
View File
@@ -0,0 +1,23 @@
%union
{
int ival;
const char *sval;
}
%token <ival> NUM
%nterm <ival> exp
%token <sval> STR
%nterm <sval> useless
%left '+' '-'
%left '*'
%%
exp:
exp '+' exp
| exp '-' exp
| exp '*' exp
| exp '/' exp
| NUM
;
useless: STR;
+5
View File
@@ -0,0 +1,5 @@
%token ID
%%
s: a ID
a: expr
expr: %empty | expr ID ','
+13
View File
@@ -0,0 +1,13 @@
%%
stmt:
expr
| if_stmt
;
if_stmt:
"if" expr "then" stmt
| "if" expr "then" stmt "else" stmt
;
expr:
"identifier"
+1 -1
View File
@@ -57,7 +57,7 @@ MAINTAINERCLEANFILES = $(CROSS_OPTIONS_TEXI)
# Fix Info's @code in @deftype
# https://lists.gnu.org/archive/html/help-texinfo/2019-11/msg00004.html
all: $(srcdir)/$(%C%_bison).info.bak
all-local: $(srcdir)/$(%C%_bison).info.bak
$(srcdir)/$(%C%_bison).info.bak: $(srcdir)/$(%C%_bison).info
$(AM_V_GEN) $(PERL) -pi.bak -0777 \
-e 's{(^ --.*\n(?: {10}.*\n)*)}' \
+10
View File
@@ -0,0 +1,10 @@
%%
sequence:
%empty
| maybeword
| sequence "word"
;
maybeword:
%empty
| "word"
;
+41 -29
View File
@@ -185,13 +185,13 @@ my $verbose = 1;
=over 4
=item C<verbose($level, $message)>
=item C<verbose ($level, $message)>
Report the C<$message> is C<$level> E<lt>= C<$verbose>.
=cut
sub verbose($$)
sub verbose ($$)
{
my ($level, $message) = @_;
print STDERR $message
@@ -201,13 +201,13 @@ sub verbose($$)
######################################################################
=item C<directives($bench, @directive)>
=item C<directives ($bench, @directive)>
Format the list of directives for Bison for bench named C<$bench>.
=cut
sub directives($@)
sub directives ($@)
{
my ($bench, @directive) = @_;
my $res = "/* Directives for bench '$bench'. */\n";
@@ -218,6 +218,27 @@ sub directives($@)
######################################################################
=item C<is_pure (@directive)>
Whether api.pure is set.
=cut
sub is_pure (@)
{
my (@directive) = @_;
for my $dir (@directive)
{
if ($dir =~ /\A%define api.pure/)
{
return 1;
}
}
return 0;
}
######################################################################
=item C<generate_grammar_triangular ($base, $max, @directive)>
Create a large triangular grammar which looks like :
@@ -389,18 +410,14 @@ sub generate_grammar_calc ($$@)
%define api.value.type union
$directives
%{
%code provides {
static int power (int base, int exponent);
/* yyerror receives the location if:
- %location & %pure & %glr
- %location & %pure & %yacc & %parse-param. */
static void yyerror (const char *s);
#if YYPURE
static int yylex (YYSTYPE* yylvalp);
#else
static int yylex (void);
#endif
%}
static int yylex (@{[is_pure (@directive) ? "YYSTYPE *yylvalp" : "void"]});
}
/* Bison Declarations */
%token
@@ -467,12 +484,7 @@ yyerror (const char *s)
}
static int
#if YYPURE
# define yylval (*yylvalp)
yylex (YYSTYPE* yylvalp)
#else
yylex (void)
#endif
yylex (@{[is_pure (@directive) ? "YYSTYPE *yylvalp" : "void"]})
{
int c;
@@ -498,7 +510,7 @@ yylex (void)
case '5': case '6': case '7': case '8': case '9':
{
int nchars = 0;
int n = sscanf (input - 1, "%d%n", &yylval.NUM, &nchars);
int n = sscanf (input - 1, "%d%n", &@{[is_pure (@directive) ? "yylvalp->" : "yylval."]}NUM, &nchars);
assert (n == 1);
input += nchars - 1;
return NUM;
@@ -506,7 +518,7 @@ yylex (void)
default:
yyerror ("error: invalid character");
return yylex ();
return yylex (@{[is_pure (@directive) ? "yylvalp" : ""]});
}
}
EOF
@@ -592,10 +604,10 @@ $directives
// Prototype of the yylex function providing subsequent tokens.
static
#if USE_TOKEN_CTOR
yy::parser::symbol_type yylex();
yy::parser::symbol_type yylex ();
#else
yy::parser::token_type yylex(yy::parser::semantic_type* yylvalp,
yy::parser::location_type* yyllocp);
yy::parser::token_type yylex (yy::parser::semantic_type *yylvalp,
yy::parser::location_type *yyllocp);
#endif
// Conversion to string.
@@ -618,8 +630,8 @@ EOF
print $out <<'EOF';
%token <std::string> TEXT
%token <int> NUMBER
%printer { std::cerr << "Number: " << $$; } <int>
%printer { std::cerr << "Text: " << $$; } <std::string>
%printer { yyo << "Number: " << $$; } <int>
%printer { yyo << "Text: " << $$; } <std::string>
%type <std::string> text result
%%
@@ -641,8 +653,8 @@ EOF
%union {int ival; std::string* sval;}
%token <sval> TEXT
%token <ival> NUMBER
%printer { std::cerr << "Number: " << $$; } <ival>
%printer { std::cerr << "Text: " << *$$; } <sval>
%printer { yyo << "Number: " << $$; } <ival>
%printer { yyo << "Text: " << *$$; } <sval>
%type <sval> text result
%%
@@ -664,10 +676,10 @@ EOF
static
#if USE_TOKEN_CTOR
yy::parser::symbol_type yylex()
yy::parser::symbol_type yylex ()
#else
yy::parser::token_type yylex(yy::parser::semantic_type* yylvalp,
yy::parser::location_type* yyllocp)
yy::parser::token_type yylex (yy::parser::semantic_type *yylvalp,
yy::parser::location_type *yyllocp)
#endif
{
typedef yy::parser::location_type location_type;
+10 -10
View File
@@ -251,29 +251,29 @@ err: Next token is token ) (1.4: )
err: Shifting token ) (1.4: )
err: Entering state 20
err: Stack now 0 2 10 20
err: Reducing stack by rule 15 (line 151):
err: Reducing stack by rule XX (line XXX):
err: $1 = token ( (1.1: )
err: $2 = token error (1.2-3: )
err: $3 = token ) (1.4: )
err: -> $$ = nterm exp (1.1-4: 666)
err: Entering state 7
err: Stack now 0 7
err: Entering state 8
err: Stack now 0 8
err: Return for a new token:
err: Reading a token
err: Now at end of input.
err: LAC: initial context established for end of file
err: LAC: checking lookahead end of file: R2 G8 S19
err: Reducing stack by rule 2 (line 126):
err: LAC: checking lookahead end of file: R2 G7 S14
err: Reducing stack by rule XX (line XXX):
err: $1 = nterm exp (1.1-4: 666)
err: -> $$ = nterm input (1.1-4: )
err: Entering state 8
err: Stack now 0 8
err: Entering state 7
err: Stack now 0 7
err: Now at end of input.
err: Shifting token end of file (1.5: )
err: LAC: initial context discarded due to shift
err: Entering state 19
err: Stack now 0 8 19
err: Stack now 0 8 19
err: Entering state 14
err: Stack now 0 7 14
err: Stack now 0 7 14
err: Cleanup: popping token end of file (1.5: )
err: Cleanup: popping nterm input (1.1-4: )' -p
+7
View File
@@ -31,6 +31,13 @@ endif FLEX_WORKS
%D%/parse.c: $(dependencies)
# 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%/lexcalc$(DASH)scan.o: %D%/parse.c
# Likewise, but for Automake before 1.16.
%D%/examples_c_lexcalc_lexcalc$(DASH)scan.o: %D%/parse.c
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
+1 -1
View File
@@ -27,7 +27,7 @@ EXTRA_DIST += %D%/calc.test
%D%/calc.d: %D%/calc.y $(dependencies)
$(AM_V_GEN)$(MKDIR_P) %D%
$(AM_V_at)$(BISON) $(srcdir)/%D%/calc.y -o $@
$(AM_V_at)$(BISON) -o $@ $(srcdir)/%D%/calc.y
%D%/calc: %D%/calc.d
$(AM_V_GEN) $(DC) $(DCFLAGS) -of$@ %D%/calc.d
+1 -1
View File
@@ -27,7 +27,7 @@ EXTRA_DIST += %D%/Calc.test
%D%/Calc.java: %D%/Calc.y $(dependencies)
$(AM_V_GEN)$(MKDIR_P) %D%
$(AM_V_at)$(BISON) $(srcdir)/%D%/Calc.y -o $@
$(AM_V_at)$(BISON) -o $@ $(srcdir)/%D%/Calc.y
%D%/Calc.class: %D%/Calc.java
$(AM_V_GEN) $(SHELL) $(top_builddir)/javacomp.sh %D%/Calc.java
+1 -1
View File
@@ -27,7 +27,7 @@ EXTRA_DIST += %D%/Calc.test
%D%/Calc.java: %D%/Calc.y $(dependencies)
$(AM_V_GEN)$(MKDIR_P) %D%
$(AM_V_at)$(BISON) $(srcdir)/%D%/Calc.y -o $@
$(AM_V_at)$(BISON) -o $@ $(srcdir)/%D%/Calc.y
%D%/Calc.class: %D%/Calc.java
$(AM_V_GEN) $(SHELL) $(top_builddir)/javacomp.sh %D%/Calc.java
+1 -1
Submodule gnulib updated: cf6d5db127...160d5e7d9a
+3 -2
View File
@@ -192,8 +192,6 @@
/localcharset.h
/locale.h
/locale.in.h
/localtime-buffer.c
/localtime-buffer.h
/lstat.c
/malloc.c
/malloca.c
@@ -338,8 +336,11 @@
/sys_types.in.h
/sys_wait.in.h
/sysexits.in.h
/termios.h
/termios.in.h
/textstyle.h
/textstyle.in.h
/thread-optim.h
/time.h
/time.in.h
/timespec.c
+4 -1
View File
@@ -97,7 +97,6 @@
/locale-ja.m4
/locale-zh.m4
/locale_h.m4
/localtime-buffer.m4
/lock.m4
/longlong.m4
/lstat.m4
@@ -117,6 +116,7 @@
/msvc-inval.m4
/msvc-nothrow.m4
/multiarch.m4
/musl.m4
/nls.m4
/nocrash.m4
/non-recursive-gnulib-prefix-hack.m4
@@ -128,6 +128,7 @@
/open.m4
/pathmax.m4
/perror.m4
/pid_t.m4
/pipe2.m4
/po.m4
/posix_spawn.m4
@@ -184,6 +185,7 @@
/strndup.m4
/strnlen.m4
/strverscmp.m4
/sys_ioctl_h.m4
/sys_resource_h.m4
/sys_socket_h.m4
/sys_stat_h.m4
@@ -191,6 +193,7 @@
/sys_times_h.m4
/sys_types_h.m4
/sys_wait_h.m4
/termios_h.m4
/threadlib.m4
/time_h.m4
/timespec.m4
+12 -8
View File
@@ -686,7 +686,8 @@ conflicts_print (void)
expected_rr_conflicts = -1;
}
bool has_unexpected_conflicts = false;
// The warning flags used to emit a diagnostic, if we did.
warnings unexpected_conflicts_warning = Wnone;
/* The following two blocks scream for factoring, but i18n support
would make it ugly. */
{
@@ -703,7 +704,8 @@ conflicts_print (void)
complain (NULL, complaint,
_("shift/reduce conflicts: %d found, %d expected"),
total, expected);
has_unexpected_conflicts = true;
if (total)
unexpected_conflicts_warning = complaint;
}
}
else if (total)
@@ -713,7 +715,7 @@ conflicts_print (void)
"%d shift/reduce conflicts",
total),
total);
has_unexpected_conflicts = true;
unexpected_conflicts_warning = Wconflicts_sr;
}
}
@@ -731,7 +733,8 @@ conflicts_print (void)
complain (NULL, complaint,
_("reduce/reduce conflicts: %d found, %d expected"),
total, expected);
has_unexpected_conflicts = true;
if (total)
unexpected_conflicts_warning = complaint;
}
}
else if (total)
@@ -741,15 +744,16 @@ conflicts_print (void)
"%d reduce/reduce conflicts",
total),
total);
has_unexpected_conflicts = true;
unexpected_conflicts_warning = Wconflicts_rr;
}
}
if (warning_is_enabled (Wcounterexamples))
report_counterexamples ();
else if (has_unexpected_conflicts)
complain (NULL, Wother,
_("rerun with option '-Wcounterexamples' to generate conflict counterexamples"));
else if (unexpected_conflicts_warning != Wnone)
subcomplain (NULL, unexpected_conflicts_warning,
_("rerun with option '-Wcounterexamples'"
" to generate conflict counterexamples"));
}
void
+9 -14
View File
@@ -113,13 +113,8 @@ free_counterexample (counterexample *cex)
free (cex);
}
static int max (int a, int b)
{
return a < b ? b : a;
}
static void
print_counterexample (const counterexample *cex, FILE *out, const char *prefix)
counterexample_print (const counterexample *cex, FILE *out, const char *prefix)
{
const bool flat = getenv ("YYFLAT");
const char *example1_label
@@ -131,8 +126,8 @@ print_counterexample (const counterexample *cex, FILE *out, const char *prefix)
const char *deriv2_label
= cex->shift_reduce ? _("Reduce derivation") : _("Second reduce derivation");
const int width =
max (max (mbswidth (example1_label, 0), mbswidth (example2_label, 0)),
max (mbswidth (deriv1_label, 0), mbswidth (deriv2_label, 0)));
max_int (max_int (mbswidth (example1_label, 0), mbswidth (example2_label, 0)),
max_int (mbswidth (deriv1_label, 0), mbswidth (deriv2_label, 0)));
if (flat)
fprintf (out, " %s%s%*s ", prefix,
example1_label, width - mbswidth (example1_label, 0), "");
@@ -526,7 +521,7 @@ nonunifying_shift_path (state_item_list reduce_path, state_item *shift_conflict)
for (gl_list_iterator_t it = gl_list_iterator (result);
state_item_list_next (&it, &sip);
)
print_state_item (sip, stderr, "");
state_item_print (sip, stderr, "");
}
return result;
}
@@ -1267,7 +1262,7 @@ counterexample_report (state_item_number itm1, state_item_number itm2,
: example_from_path (shift_reduce, itm2, shortest_path, next_sym);
gl_list_free (shortest_path);
print_counterexample (cex, out, prefix);
counterexample_print (cex, out, prefix);
free_counterexample (cex);
}
@@ -1290,8 +1285,8 @@ counterexample_report_shift_reduce (state_item_number itm1, state_item_number it
// In the report, print the items.
if (out != stderr || trace_flag & trace_cex)
{
print_state_item (&state_items[itm1], out, prefix);
print_state_item (&state_items[itm2], out, prefix);
state_item_print (&state_items[itm1], out, prefix);
state_item_print (&state_items[itm2], out, prefix);
}
counterexample_report (itm1, itm2, next_sym, true, out, prefix);
}
@@ -1334,8 +1329,8 @@ counterexample_report_reduce_reduce (state_item_number itm1, state_item_number i
// In the report, print the items.
if (out != stderr || trace_flag & trace_cex)
{
print_state_item (&state_items[itm1], out, prefix);
print_state_item (&state_items[itm2], out, prefix);
state_item_print (&state_items[itm1], out, prefix);
state_item_print (&state_items[itm2], out, prefix);
}
counterexample_report (itm1, itm2, bitset_first (conflict_syms),
false, out, prefix);
+10 -17
View File
@@ -76,12 +76,12 @@ void derivation_list_free (derivation_list dl)
derivation *
derivation_new (symbol_number sym, derivation_list children)
{
derivation *deriv = xmalloc (sizeof (derivation));
deriv->sym = sym;
deriv->children = children;
deriv->reference_count = 0;
deriv->color = -1;
return deriv;
derivation *res = xmalloc (sizeof *res);
res->sym = sym;
res->children = children;
res->reference_count = 0;
res->color = -1;
return res;
}
void
@@ -135,12 +135,6 @@ derivation_size (const derivation *deriv)
}
static int
max (int a, int b)
{
return a < b ? b : a;
}
// Longest distance from root to leaf.
static int
derivation_depth (const derivation *deriv)
@@ -154,7 +148,7 @@ derivation_depth (const derivation *deriv)
for (gl_list_iterator_t it = gl_list_iterator (deriv->children);
derivation_list_next (&it, &child);
)
res = max (res, derivation_depth (child));
res = max_int (res, derivation_depth (child));
return res + 1;
}
else
@@ -193,9 +187,8 @@ all_spaces (const char *s)
//
// This function implements this.
//
// When COND is true, put S on OUT, preceeded by *PADDING white
// spaces. Otherwise add the width to *PADDING. Return the width of
// S.
// When COND is true, put S on OUT, preceded by *PADDING white spaces.
// Otherwise add the width to *PADDING. Return the width of S.
static int
fputs_if (bool cond, FILE *out, int *padding, const char *s)
{
@@ -238,7 +231,7 @@ derivation_width (const derivation *deriv)
// No separator at the beginning.
children_width -= derivation_separator_width;
}
return max (self_width, children_width);
return max_int (self_width, children_width);
}
else if (deriv == &d_dot)
{
+9 -1
View File
@@ -112,7 +112,15 @@ static struct obstack obstack_for_string;
# define STRING_1GROW(Char) \
obstack_1grow (&obstack_for_string, Char)
# define STRING_FREE() \
# ifdef NDEBUG
# define STRING_FREE() \
obstack_free (&obstack_for_string, last_string)
# else
# define STRING_FREE() \
do { \
obstack_free (&obstack_for_string, last_string); \
last_string = NULL; \
} while (0)
# endif
#endif
+1 -1
View File
@@ -423,7 +423,7 @@ ielr_item_has_lookahead (state *s, symbol_number lhs, size_t item,
check all predecessors' goto follows for the LHS. */
if (item_number_is_rule_number (ritem[s->items[item] - 2]))
{
aver (lhs != accept->content->number);
aver (lhs != acceptsymbol->content->number);
for (state **predecessor = predecessors[s->number];
*predecessor;
++predecessor)
-1
View File
@@ -143,7 +143,6 @@ src_bison_LDADD = \
$(LIB_SETLOCALE_NULL) \
$(LIBICONV) \
$(LIBINTL) \
$(LIBREADLINE) \
$(LIBTEXTSTYLE)
+3 -13
View File
@@ -40,18 +40,6 @@
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)
@@ -167,7 +155,9 @@ int
location_print (location loc, FILE *out)
{
int res = 0;
if (trace_flag & trace_locations)
if (location_empty (loc))
res += fprintf (out, "(empty location)");
else if (trace_flag & trace_locations)
{
res += boundary_print (&loc.start, out);
res += fprintf (out, "-");
+1 -1
View File
@@ -256,7 +256,7 @@ shortest_path_from_start (state_item_number target, symbol_number next_sym)
gl_list_iterator_t it = gl_list_iterator (res);
const void *sip;
while (gl_list_iterator_next (&it, &sip, NULL))
print_state_item ((state_item *) sip, stdout, "");
state_item_print ((state_item *) sip, stdout, "");
}
return res;
}
+4 -4
View File
@@ -249,7 +249,7 @@ prepare_symbol_names (char const *muscle_name)
if (i)
obstack_1grow (&format_obstack, ' ');
if (translatable)
obstack_sgrow (&format_obstack, "]b4_symbol_translate([");
obstack_sgrow (&format_obstack, "]b4_symbol_translate""([");
obstack_escape (&format_obstack, cp);
if (translatable)
obstack_sgrow (&format_obstack, "])[");
@@ -554,7 +554,7 @@ prepare_symbol_definitions (void)
/* Map "orig NUM" to new numbers. See data/README. */
for (symbol_number i = ntokens; i < nsyms + nuseless_nonterminals; ++i)
{
obstack_printf (&format_obstack, "symbol(orig %d, number)", i);
obstack_printf (&format_obstack, "symbol""(orig %d, number)", i);
const char *key = obstack_finish0 (&format_obstack);
MUSCLE_INSERT_INT (key, nterm_map ? nterm_map[i - ntokens] : i);
}
@@ -565,12 +565,12 @@ prepare_symbol_definitions (void)
const char *key;
#define SET_KEY(Entry) \
obstack_printf (&format_obstack, "symbol(%d, %s)", \
obstack_printf (&format_obstack, "symbol""(%d, %s)", \
i, Entry); \
key = obstack_finish0 (&format_obstack);
#define SET_KEY2(Entry, Suffix) \
obstack_printf (&format_obstack, "symbol(%d, %s_%s)", \
obstack_printf (&format_obstack, "symbol""(%d, %s_%s)", \
i, Entry, Suffix); \
key = obstack_finish0 (&format_obstack);
+22 -23
View File
@@ -1,4 +1,4 @@
/* A Bison parser, made by GNU Bison 3.6.90. */
/* A Bison parser, made by GNU Bison 3.7.14-eb26-dirty. */
/* Bison implementation for Yacc-like parsers in C
@@ -49,7 +49,7 @@
#define YYBISON 1
/* Bison version. */
#define YYBISON_VERSION "3.6.90"
#define YYBISON_VERSION "3.7.14-eb26-dirty"
/* Skeleton name. */
#define YYSKELETON_NAME "yacc.c"
@@ -149,7 +149,7 @@ enum yysymbol_kind_t
YYSYMBOL_BRACED_CODE = 41, /* "{...}" */
YYSYMBOL_BRACED_PREDICATE = 42, /* "%?{...}" */
YYSYMBOL_BRACKETED_ID = 43, /* "[identifier]" */
YYSYMBOL_CHAR = 44, /* "character literal" */
YYSYMBOL_CHAR_LITERAL = 44, /* "character literal" */
YYSYMBOL_COLON = 45, /* ":" */
YYSYMBOL_EPILOGUE = 46, /* "epilogue" */
YYSYMBOL_EQUAL = 47, /* "=" */
@@ -162,7 +162,7 @@ enum yysymbol_kind_t
YYSYMBOL_TAG = 54, /* "<tag>" */
YYSYMBOL_TAG_ANY = 55, /* "<*>" */
YYSYMBOL_TAG_NONE = 56, /* "<>" */
YYSYMBOL_INT = 57, /* "integer literal" */
YYSYMBOL_INT_LITERAL = 57, /* "integer literal" */
YYSYMBOL_PERCENT_PARAM = 58, /* "%param" */
YYSYMBOL_PERCENT_UNION = 59, /* "%union" */
YYSYMBOL_PERCENT_EMPTY = 60, /* "%empty" */
@@ -1115,8 +1115,8 @@ tron (yyo);
{ fprintf (yyo, "[%s]", ((*yyvaluep).BRACKETED_ID)); }
break;
case YYSYMBOL_CHAR: /* "character literal" */
{ fputs (char_name (((*yyvaluep).CHAR)), yyo); }
case YYSYMBOL_CHAR_LITERAL: /* "character literal" */
{ fputs (char_name (((*yyvaluep).CHAR_LITERAL)), yyo); }
break;
case YYSYMBOL_EPILOGUE: /* "epilogue" */
@@ -1139,8 +1139,8 @@ tron (yyo);
{ fprintf (yyo, "<%s>", ((*yyvaluep).TAG)); }
break;
case YYSYMBOL_INT: /* "integer literal" */
{ fprintf (yyo, "%d", ((*yyvaluep).INT)); }
case YYSYMBOL_INT_LITERAL: /* "integer literal" */
{ fprintf (yyo, "%d", ((*yyvaluep).INT_LITERAL)); }
break;
case YYSYMBOL_PERCENT_PARAM: /* "%param" */
@@ -2087,11 +2087,11 @@ yyreduce:
break;
case 12: /* prologue_declaration: "%expect" "integer literal" */
{ expected_sr_conflicts = (yyvsp[0].INT); }
{ expected_sr_conflicts = (yyvsp[0].INT_LITERAL); }
break;
case 13: /* prologue_declaration: "%expect-rr" "integer literal" */
{ expected_rr_conflicts = (yyvsp[0].INT); }
{ expected_rr_conflicts = (yyvsp[0].INT_LITERAL); }
break;
case 14: /* prologue_declaration: "%file-prefix" "string" */
@@ -2339,13 +2339,13 @@ yyreduce:
case 67: /* token_decls: "<tag>" token_decl.1 */
{
(yyval.token_decls) = symbol_list_type_set ((yyvsp[0].yykind_80), (yyvsp[-1].TAG), (yylsp[-1]));
(yyval.token_decls) = symbol_list_type_set ((yyvsp[0].yykind_80), (yyvsp[-1].TAG));
}
break;
case 68: /* token_decls: token_decls "<tag>" token_decl.1 */
{
(yyval.token_decls) = symbol_list_append ((yyvsp[-2].token_decls), symbol_list_type_set ((yyvsp[0].yykind_80), (yyvsp[-1].TAG), (yylsp[-1])));
(yyval.token_decls) = symbol_list_append ((yyvsp[-2].token_decls), symbol_list_type_set ((yyvsp[0].yykind_80), (yyvsp[-1].TAG)));
}
break;
@@ -2396,13 +2396,13 @@ yyreduce:
case 78: /* token_decls_for_prec: "<tag>" token_decl_for_prec.1 */
{
(yyval.token_decls_for_prec) = symbol_list_type_set ((yyvsp[0].yykind_85), (yyvsp[-1].TAG), (yylsp[-1]));
(yyval.token_decls_for_prec) = symbol_list_type_set ((yyvsp[0].yykind_85), (yyvsp[-1].TAG));
}
break;
case 79: /* token_decls_for_prec: token_decls_for_prec "<tag>" token_decl_for_prec.1 */
{
(yyval.token_decls_for_prec) = symbol_list_append ((yyvsp[-2].token_decls_for_prec), symbol_list_type_set ((yyvsp[0].yykind_85), (yyvsp[-1].TAG), (yylsp[-1])));
(yyval.token_decls_for_prec) = symbol_list_append ((yyvsp[-2].token_decls_for_prec), symbol_list_type_set ((yyvsp[0].yykind_85), (yyvsp[-1].TAG)));
}
break;
@@ -2431,13 +2431,13 @@ yyreduce:
case 85: /* symbol_decls: "<tag>" symbol_decl.1 */
{
(yyval.symbol_decls) = symbol_list_type_set ((yyvsp[0].yykind_88), (yyvsp[-1].TAG), (yylsp[-1]));
(yyval.symbol_decls) = symbol_list_type_set ((yyvsp[0].yykind_88), (yyvsp[-1].TAG));
}
break;
case 86: /* symbol_decls: symbol_decls "<tag>" symbol_decl.1 */
{
(yyval.symbol_decls) = symbol_list_append ((yyvsp[-2].symbol_decls), symbol_list_type_set ((yyvsp[0].yykind_88), (yyvsp[-1].TAG), (yylsp[-1])));
(yyval.symbol_decls) = symbol_list_append ((yyvsp[-2].symbol_decls), symbol_list_type_set ((yyvsp[0].yykind_88), (yyvsp[-1].TAG)));
}
break;
@@ -2506,7 +2506,7 @@ yyreduce:
break;
case 105: /* rhs: rhs "%dprec" "integer literal" */
{ grammar_current_rule_dprec_set ((yyvsp[0].INT), (yylsp[0])); }
{ grammar_current_rule_dprec_set ((yyvsp[0].INT_LITERAL), (yylsp[0])); }
break;
case 106: /* rhs: rhs "%merge" "<tag>" */
@@ -2514,11 +2514,11 @@ yyreduce:
break;
case 107: /* rhs: rhs "%expect" "integer literal" */
{ grammar_current_rule_expect_sr ((yyvsp[0].INT), (yylsp[0])); }
{ grammar_current_rule_expect_sr ((yyvsp[0].INT_LITERAL), (yylsp[0])); }
break;
case 108: /* rhs: rhs "%expect-rr" "integer literal" */
{ grammar_current_rule_expect_rr ((yyvsp[0].INT), (yylsp[0])); }
{ grammar_current_rule_expect_rr ((yyvsp[0].INT_LITERAL), (yylsp[0])); }
break;
case 109: /* named_ref.opt: %empty */
@@ -2566,9 +2566,9 @@ yyreduce:
location loc = muscle_percent_define_get_loc (var);
subcomplain (&loc, complaint, _("definition of %s"), var);
}
(yyval.id) = symbol_get (char_name ((yyvsp[0].CHAR)), (yylsp[0]));
(yyval.id) = symbol_get (char_name ((yyvsp[0].CHAR_LITERAL)), (yylsp[0]));
symbol_class_set ((yyval.id), token_sym, (yylsp[0]), false);
symbol_code_set ((yyval.id), (yyvsp[0].CHAR), (yylsp[0]));
symbol_code_set ((yyval.id), (yyvsp[0].CHAR_LITERAL), (yylsp[0]));
}
break;
@@ -3147,8 +3147,7 @@ char_name (char c)
}
}
static
void
static void
current_lhs (symbol *sym, location loc, named_ref *ref)
{
current_lhs_symbol = sym;
+5 -5
View File
@@ -1,4 +1,4 @@
/* A Bison parser, made by GNU Bison 3.6.90. */
/* A Bison parser, made by GNU Bison 3.7.14-eb26-dirty. */
/* Bison interface for Yacc-like parsers in C
@@ -123,7 +123,7 @@ extern int gram_debug;
BRACED_CODE = 41, /* "{...}" */
BRACED_PREDICATE = 42, /* "%?{...}" */
BRACKETED_ID = 43, /* "[identifier]" */
CHAR = 44, /* "character literal" */
CHAR_LITERAL = 44, /* "character literal" */
COLON = 45, /* ":" */
EPILOGUE = 46, /* "epilogue" */
EQUAL = 47, /* "=" */
@@ -136,7 +136,7 @@ extern int gram_debug;
TAG = 54, /* "<tag>" */
TAG_ANY = 55, /* "<*>" */
TAG_NONE = 56, /* "<>" */
INT = 57, /* "integer literal" */
INT_LITERAL = 57, /* "integer literal" */
PERCENT_PARAM = 58, /* "%param" */
PERCENT_UNION = 59, /* "%union" */
PERCENT_EMPTY = 60 /* "%empty" */
@@ -156,7 +156,7 @@ union GRAM_STYPE
char* EPILOGUE; /* "epilogue" */
char* PROLOGUE; /* "%{...%}" */
code_props_type code_props_type; /* code_props_type */
int INT; /* "integer literal" */
int INT_LITERAL; /* "integer literal" */
int yykind_82; /* int.opt */
named_ref* yykind_95; /* named_ref.opt */
param_type PERCENT_PARAM; /* "%param" */
@@ -188,7 +188,7 @@ union GRAM_STYPE
uniqstr yykind_74; /* tag.opt */
uniqstr tag; /* tag */
uniqstr variable; /* variable */
unsigned char CHAR; /* "character literal" */
unsigned char CHAR_LITERAL; /* "character literal" */
value_type value; /* value */
+17 -18
View File
@@ -214,7 +214,7 @@
BRACED_CODE "{...}"
BRACED_PREDICATE "%?{...}"
BRACKETED_ID _("[identifier]")
CHAR _("character literal")
CHAR_LITERAL _("character literal")
COLON ":"
EPILOGUE _("epilogue")
EQUAL "="
@@ -232,7 +232,7 @@
%code pre-printer {tron (yyo);}
%code post-printer {troff (yyo);}
%type <unsigned char> CHAR
%type <unsigned char> CHAR_LITERAL
%printer { fputs (char_name ($$), yyo); } <unsigned char>
%type <char*> "{...}" "%?{...}" "%{...%}" EPILOGUE STRING TSTRING
@@ -249,7 +249,7 @@
%printer { fprintf (yyo, "%%%s", $$); } PERCENT_FLAG
%printer { fprintf (yyo, "<%s>", $$); } TAG tag
%token <int> INT _("integer literal")
%token <int> INT_LITERAL _("integer literal")
%printer { fprintf (yyo, "%d", $$); } <int>
%type <symbol*> id id_colon string_as_id symbol token_decl token_decl_for_prec
@@ -342,8 +342,8 @@ prologue_declaration:
| "%defines" { defines_flag = true; }
| "%defines" STRING { handle_defines ($2); }
| "%error-verbose" { handle_error_verbose (&@$, $1); }
| "%expect" INT { expected_sr_conflicts = $2; }
| "%expect-rr" INT { expected_rr_conflicts = $2; }
| "%expect" INT_LITERAL { expected_sr_conflicts = $2; }
| "%expect-rr" INT_LITERAL { expected_rr_conflicts = $2; }
| "%file-prefix" STRING { handle_file_prefix (&@$, &@1, $1, $2); }
| "%glr-parser"
{
@@ -532,11 +532,11 @@ token_decls:
}
| TAG token_decl.1[syms]
{
$$ = symbol_list_type_set ($syms, $TAG, @TAG);
$$ = symbol_list_type_set ($syms, $TAG);
}
| token_decls TAG token_decl.1[syms]
{
$$ = symbol_list_append ($1, symbol_list_type_set ($syms, $TAG, @TAG));
$$ = symbol_list_append ($1, symbol_list_type_set ($syms, $TAG));
}
;
@@ -561,7 +561,7 @@ token_decl:
%type <int> int.opt;
int.opt:
%empty { $$ = -1; }
| INT
| INT_LITERAL
;
%type <symbol*> alias;
@@ -592,11 +592,11 @@ token_decls_for_prec:
}
| TAG token_decl_for_prec.1[syms]
{
$$ = symbol_list_type_set ($syms, $TAG, @TAG);
$$ = symbol_list_type_set ($syms, $TAG);
}
| token_decls_for_prec TAG token_decl_for_prec.1[syms]
{
$$ = symbol_list_append ($1, symbol_list_type_set ($syms, $TAG, @TAG));
$$ = symbol_list_append ($1, symbol_list_type_set ($syms, $TAG));
}
;
@@ -632,11 +632,11 @@ symbol_decls:
}
| TAG symbol_decl.1[syms]
{
$$ = symbol_list_type_set ($syms, $TAG, @TAG);
$$ = symbol_list_type_set ($syms, $TAG);
}
| symbol_decls TAG symbol_decl.1[syms]
{
$$ = symbol_list_append ($1, symbol_list_type_set ($syms, $TAG, @TAG));
$$ = symbol_list_append ($1, symbol_list_type_set ($syms, $TAG));
}
;
@@ -703,13 +703,13 @@ rhs:
{ grammar_current_rule_empty_set (@2); }
| rhs "%prec" symbol
{ grammar_current_rule_prec_set ($3, @3); }
| rhs "%dprec" INT
| rhs "%dprec" INT_LITERAL
{ grammar_current_rule_dprec_set ($3, @3); }
| rhs "%merge" TAG
{ grammar_current_rule_merge_set ($3, @3); }
| rhs "%expect" INT
| rhs "%expect" INT_LITERAL
{ grammar_current_rule_expect_sr ($3, @3); }
| rhs "%expect-rr" INT
| rhs "%expect-rr" INT_LITERAL
{ grammar_current_rule_expect_rr ($3, @3); }
;
@@ -765,7 +765,7 @@ value:
id:
ID
{ $$ = symbol_from_uniqstr ($1, @1); }
| CHAR
| CHAR_LITERAL
{
const char *var = "api.token.raw";
if (current_class == nterm_sym)
@@ -1158,8 +1158,7 @@ char_name (char c)
}
}
static
void
static void
current_lhs (symbol *sym, location loc, named_ref *ref)
{
current_lhs_symbol = sym;
+15 -19
View File
@@ -28,19 +28,19 @@
#include "lssi.h"
#include "nullable.h"
typedef struct parse_state
struct parse_state
{
// path of state-items the parser has traversed
// Path of state-items the parser has traversed.
struct si_chunk
{
// elements newly added in this chunk
// Elements newly added in this chunk.
state_item_list contents;
// properties of the linked list this chunk represents
// Properties of the linked list this chunk represents.
const state_item *head_elt;
const state_item *tail_elt;
size_t total_size;
} state_items;
// list of derivations of the symbols
// List of derivations of the symbols.
struct deriv_chunk
{
derivation_list contents;
@@ -50,18 +50,15 @@ typedef struct parse_state
} derivs;
struct parse_state *parent;
int reference_count;
// incremented during productions,
// decremented during reductions
// Incremented during productions, decremented during reductions.
int depth;
// whether the contents of the chunks should be
// prepended or appended to the list the chunks
// represent
// Whether the contents of the chunks should be prepended or
// appended to the list the chunks represent.
bool prepend;
// causes chunk contents to be freed when the
// reference count is one. Used when only the chunk metadata
// will be needed.
// Causes chunk contents to be freed when the reference count is
// one. Used when only the chunk metadata will be needed.
bool free_contents_early;
} parse_state;
};
static void
@@ -438,9 +435,8 @@ simulate_transition (parse_state *ps)
// symbols into account.
parse_state_list result = parse_state_list_new ();
state_item_number si_next = si->trans;
// check for disabled transition, shouldn't happen
// as any state_items that lead to these should be
// disabled.
// Check for disabled transition, shouldn't happen as any
// state_items that lead to these should be disabled.
if (si_next < 0)
return result;
parse_state *next_ps = copy_parse_state (false, ps);
@@ -594,8 +590,8 @@ print_parse_state (parse_state *ps)
FILE *out = stderr;
fprintf (out, "(size %zu depth %d rc %d)\n",
ps->state_items.total_size, ps->depth, ps->reference_count);
print_state_item (ps->state_items.head_elt, out, "");
print_state_item (ps->state_items.tail_elt, out, "");
state_item_print (ps->state_items.head_elt, out, "");
state_item_print (ps->state_items.tail_elt, out, "");
if (ps->derivs.total_size > 0)
derivation_print (ps->derivs.head_elt, out, "");
putc ('\n', out);
+8 -5
View File
@@ -406,8 +406,8 @@ grammar_midrule_action (void)
action. Create the MIDRULE. */
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_type_set (dummy,
current_rule->action_props.type, current_rule->action_props.location);
symbol_list *midrule = symbol_list_sym_new (dummy, dummy_loc);
/* Remember named_ref of previous action. */
@@ -804,7 +804,7 @@ check_and_convert_grammar (void)
$accept: %start $end. */
{
symbol_list *p = symbol_list_sym_new (accept, empty_loc);
symbol_list *p = symbol_list_sym_new (acceptsymbol, empty_loc);
p->rhs_loc = grammar->rhs_loc;
p->next = symbol_list_sym_new (startsymbol, empty_loc);
p->next->next = symbol_list_sym_new (eoftoken, empty_loc);
@@ -815,8 +815,11 @@ check_and_convert_grammar (void)
grammar = p;
}
aver (nsyms <= SYMBOL_NUMBER_MAXIMUM);
aver (nsyms == ntokens + nnterms);
if (SYMBOL_NUMBER_MAXIMUM - nnterms < ntokens)
complain (NULL, fatal, "too many symbols in input grammar (limit is %d)",
SYMBOL_NUMBER_MAXIMUM);
nsyms = ntokens + nnterms;
/* Assign the symbols their symbol numbers. */
symbols_pack ();
+4 -4
View File
@@ -160,9 +160,9 @@ inaccessable_symbols (void)
bitset Pp = bitset_create (nrules, BITSET_FIXED);
/* If the start symbol isn't useful, then nothing will be useful. */
if (bitset_test (N, accept->content->number - ntokens))
if (bitset_test (N, acceptsymbol->content->number - ntokens))
{
bitset_set (V, accept->content->number);
bitset_set (V, acceptsymbol->content->number);
while (1)
{
@@ -301,7 +301,7 @@ nonterminals_reduce (void)
for (item_number *rhsp = rules[r].rhs; 0 <= *rhsp; ++rhsp)
if (ISVAR (*rhsp))
*rhsp = symbol_number_as_item_number (nterm_map[*rhsp - ntokens]);
accept->content->number = nterm_map[accept->content->number - ntokens];
acceptsymbol->content->number = nterm_map[acceptsymbol->content->number - ntokens];
}
nsyms -= nuseless_nonterminals;
@@ -381,7 +381,7 @@ reduce_grammar (void)
{
reduce_print ();
if (!bitset_test (N, accept->content->number - ntokens))
if (!bitset_test (N, acceptsymbol->content->number - ntokens))
complain (&startsymbol_loc, fatal,
_("start symbol %s does not derive any sentence"),
startsymbol->tag);
+21 -12
View File
@@ -322,8 +322,8 @@ eqopt ({sp}=)?
BEGIN SC_AFTER_IDENTIFIER;
}
{int} RETURN_VALUE (INT, scan_integer (yytext, 10, *loc));
{xint} RETURN_VALUE (INT, scan_integer (yytext, 16, *loc));
{int} RETURN_VALUE (INT_LITERAL, scan_integer (yytext, 10, *loc));
{xint} RETURN_VALUE (INT_LITERAL, scan_integer (yytext, 16, *loc));
/* Identifiers may not start with a digit. Yet, don't silently
accept "1FOO" as "1 FOO". */
@@ -403,6 +403,7 @@ eqopt ({sp}=)?
{
\0 {
complain (loc, complaint, _("invalid null character"));
STRING_FINISH ();
STRING_FREE ();
return GRAM_error;
}
@@ -566,6 +567,8 @@ eqopt ({sp}=)?
_("POSIX Yacc does not support string literals"));
RETURN_VALUE (STRING, last_string);
}
<<EOF>> unexpected_eof (token_start, "\"");
"\n" unexpected_newline (token_start, "\"");
}
<SC_ESCAPED_TSTRING>
@@ -579,13 +582,10 @@ eqopt ({sp}=)?
_("POSIX Yacc does not support string literals"));
RETURN_VALUE (TSTRING, last_string);
}
<<EOF>> unexpected_eof (token_start, "\")");
"\n" unexpected_newline (token_start, "\")");
}
<SC_ESCAPED_STRING,SC_ESCAPED_TSTRING>
{
<<EOF>> unexpected_eof (token_start, "\"");
"\n" unexpected_newline (token_start, "\"");
}
/*----------------------------------------------------------.
@@ -599,7 +599,6 @@ eqopt ({sp}=)?
STRING_FINISH ();
BEGIN INITIAL;
loc->start = token_start;
val->CHAR = last_string[0];
if (last_string[0] == '\0')
{
@@ -615,8 +614,9 @@ eqopt ({sp}=)?
}
else
{
val->CHAR_LITERAL = last_string[0];
STRING_FREE ();
return CHAR;
return CHAR_LITERAL;
}
}
{eol} unexpected_newline (token_start, "'");
@@ -691,6 +691,15 @@ eqopt ({sp}=)?
p);
STRING_1GROW ('?');
}
"\\" {
// None of the other rules matched: the last character of this
// file is "\". But Flex does not support "\\<<EOF>>".
unexpected_eof (token_start,
YY_START == SC_ESCAPED_CHARACTER ? "?'"
: YY_START == SC_ESCAPED_STRING ? "?\""
: "?\")");
}
}
/*--------------------------------------------.
@@ -933,9 +942,9 @@ convert_ucn_to_byte (char const *ucn)
}
/*---------------------------------------------------------------------.
| Handle '#line INT( "FILE")?\n'. ARGS has already skipped '#line '. |
`---------------------------------------------------------------------*/
/*----------------------------------------------------------------------------.
| Handle '#line INT_LITERAL( "FILE")?\n'. ARGS has already skipped '#line '. |
`----------------------------------------------------------------------------*/
static void
handle_syncline (char *args, location loc)
+3 -3
View File
@@ -475,7 +475,7 @@ prune_disabled_paths (void)
}
void
print_state_item (const state_item *si, FILE *out, const char *prefix)
state_item_print (const state_item *si, FILE *out, const char *prefix)
{
fputs (prefix, out);
item_print (si->item, NULL, out);
@@ -506,7 +506,7 @@ state_items_report (void)
if (si->trans >= 0)
{
fputs (" -> ", stdout);
print_state_item (&state_items[si->trans], stdout, "");
state_item_print (&state_items[si->trans], stdout, "");
}
bitset sets[2] = { si->prods, si->revs };
@@ -521,7 +521,7 @@ state_items_report (void)
BITSET_FOR_EACH (biter, b, sin, 0)
{
fputs (txt[seti], stdout);
print_state_item (&state_items[sin], stdout, "");
state_item_print (&state_items[sin], stdout, "");
}
}
}
+2 -1
View File
@@ -90,9 +90,10 @@ state_item_index_lookup (state_number s, state_item_number off)
}
void state_items_init (void);
void print_state_item (const state_item *si, FILE *out, const char *prefix);
void state_items_free (void);
void state_item_print (const state_item *si, FILE *out, const char *prefix);
bool production_allowed (const state_item *si, const state_item *next);
// Iterating on a state_item_list.
+2 -2
View File
@@ -83,10 +83,10 @@ symbol_list_type_new (uniqstr type_name, location loc)
symbol_list *
symbol_list_type_set (symbol_list *syms, uniqstr type_name, location loc)
symbol_list_type_set (symbol_list *syms, uniqstr type_name)
{
for (symbol_list *l = syms; l; l = l->next)
symbol_type_set (l->content.sym, type_name, loc);
symbol_type_set (l->content.sym, type_name, l->sym_loc);
return syms;
}
+1 -2
View File
@@ -110,8 +110,7 @@ symbol_list *symbol_list_type_new (uniqstr type_name, location loc);
/** Assign the type \c type_name to all the members of \c syms.
** \returns \c syms */
symbol_list *symbol_list_type_set (symbol_list *syms,
uniqstr type_name, location loc);
symbol_list *symbol_list_type_set (symbol_list *syms, uniqstr type_name);
/** Print this list.
+33 -36
View File
@@ -59,7 +59,7 @@ static semantic_type **semantic_types_sorted = NULL;
symbol *errtoken = NULL;
symbol *undeftoken = NULL;
symbol *eoftoken = NULL;
symbol *accept = NULL;
symbol *acceptsymbol = NULL;
symbol *startsymbol = NULL;
location startsymbol_loc;
@@ -137,11 +137,6 @@ symbol_new (uniqstr tag, location loc)
res->alias = NULL;
res->content = sym_content_new (res);
res->is_alias = false;
if (nsyms == SYMBOL_NUMBER_MAXIMUM)
complain (NULL, fatal, _("too many symbols in input grammar (limit is %d)"),
SYMBOL_NUMBER_MAXIMUM);
nsyms++;
return res;
}
@@ -182,11 +177,11 @@ symbol_free (void *ptr)
*/
static void
symbols_sort (symbol **first, symbol **second)
symbols_sort (const symbol **first, const symbol **second)
{
if (0 < location_cmp ((*first)->location, (*second)->location))
{
symbol* tmp = *first;
const symbol* tmp = *first;
*first = *second;
*second = tmp;
}
@@ -243,7 +238,11 @@ semantic_type_new (uniqstr tag, const location *loc)
| Print a symbol. |
`-----------------*/
#define SYMBOL_ATTR_PRINT(Attr) \
#define SYMBOL_INT_ATTR_PRINT(Attr) \
if (s->content) \
fprintf (f, " %s = %d", #Attr, s->content->Attr)
#define SYMBOL_STR_ATTR_PRINT(Attr) \
if (s->content && s->content->Attr) \
fprintf (f, " %s { %s }", #Attr, s->content->Attr)
@@ -264,7 +263,11 @@ symbol_print (symbol const *s, FILE *f)
: c == nterm_sym ? "nterm"
: NULL, /* abort. */
s->tag);
SYMBOL_ATTR_PRINT (type_name);
putc (' ', f);
location_print (s->location, f);
SYMBOL_INT_ATTR_PRINT (code);
SYMBOL_INT_ATTR_PRINT (number);
SYMBOL_STR_ATTR_PRINT (type_name);
SYMBOL_CODE_PRINT (destructor);
SYMBOL_CODE_PRINT (printer);
}
@@ -371,7 +374,7 @@ symbol_from_uniqstr_fuzzy (const uniqstr key)
}
static void
complain_symbol_undeclared (symbol *sym)
complain_symbol_undeclared (const symbol *sym)
{
assert (sym->content->status != declared);
const symbol *best = symbol_from_uniqstr_fuzzy (sym->tag);
@@ -398,7 +401,10 @@ void
symbol_location_as_lhs_set (symbol *sym, location loc)
{
if (!sym->location_of_lhs)
sym->location = loc;
{
sym->location = loc;
sym->location_of_lhs = true;
}
}
@@ -548,10 +554,6 @@ symbol_class_set (symbol *sym, symbol_class class, location loc, bool declaring)
if (class == token_sym && s->class == pct_type_sym)
complain_pct_type_on_token (&sym->location);
if (class == nterm_sym && s->class != nterm_sym)
s->number = nnterms++;
else if (class == token_sym && s->number == NUMBER_UNDEFINED)
s->number = ntokens++;
s->class = class;
if (declaring)
@@ -573,9 +575,9 @@ symbol_class_set (symbol *sym, symbol_class class, location loc, bool declaring)
}
/*------------------------------------------------.
| Set the USER_TOKEN_NUMBER associated with SYM. |
`------------------------------------------------*/
/*----------------------------.
| Set the token code of SYM. |
`----------------------------*/
void
symbol_code_set (symbol *sym, int code, location loc)
@@ -598,10 +600,6 @@ symbol_code_set (symbol *sym, int code, location loc)
if (code == 0 && !eoftoken)
{
eoftoken = sym->content->symbol;
/* It is always mapped to 0, so it was already counted in
NTOKENS. */
if (eoftoken->content->number != NUMBER_UNDEFINED)
--ntokens;
eoftoken->content->number = 0;
}
}
@@ -621,9 +619,11 @@ symbol_check_defined (symbol *sym)
{
complain_symbol_undeclared (sym);
s->class = nterm_sym;
s->number = nnterms++;
}
if (s->number == NUMBER_UNDEFINED)
s->number = s->class == token_sym ? ntokens++ : nnterms++;
if (s->class == token_sym
&& sym->tag[0] == '"'
&& !sym->is_alias)
@@ -742,7 +742,7 @@ symbol_pack (symbol *sym)
}
static void
complain_code_redeclared (int num, symbol *first, symbol *second)
complain_code_redeclared (int num, const symbol *first, const symbol *second)
{
symbols_sort (&first, &second);
complain (&second->location, complaint,
@@ -758,13 +758,11 @@ complain_code_redeclared (int num, symbol *first, symbol *second)
`-------------------------------------------------*/
static void
symbol_translation (symbol *sym)
symbol_translation (const symbol *sym)
{
/* Nonterminal? */
if (sym->content->class == token_sym
&& !sym->is_alias)
if (sym->content->class == token_sym && !sym->is_alias)
{
/* A token which translation has already been set?*/
/* A token whose translation has already been set? */
if (token_translations[sym->content->code]
!= undeftoken->content->number)
complain_code_redeclared
@@ -849,10 +847,10 @@ symbols_new (void)
hash_symbol_comparator,
symbol_free);
/* Construct the accept symbol. */
accept = symbol_get ("$accept", empty_loc);
accept->content->class = nterm_sym;
accept->content->number = nnterms++;
/* Construct the acceptsymbol symbol. */
acceptsymbol = symbol_get ("$accept", empty_loc);
acceptsymbol->content->class = nterm_sym;
acceptsymbol->content->number = nnterms++;
/* Construct the YYerror/"error" token */
errtoken = symbol_get ("YYerror", empty_loc);
@@ -969,7 +967,6 @@ dummy_symbol_get (location loc)
assure (len < sizeof buf);
symbol *sym = symbol_get (buf, loc);
sym->content->class = nterm_sym;
sym->content->number = nnterms++;
return sym;
}
@@ -1002,7 +999,7 @@ symbol_cmp (void const *a, void const *b)
}
/* Store in *SORTED an array of pointers to the symbols contained in
TABLE, sorted (alphabetically) by tag. */
TABLE, sorted by order of appearance (i.e., by location). */
static void
table_sort (struct hash_table *table, symbol ***sorted)
+2 -2
View File
@@ -227,7 +227,7 @@ void symbol_precedence_set (symbol *sym, int prec, assoc a, location loc);
void symbol_class_set (symbol *sym, symbol_class class, location loc,
bool declaring);
/** Set the \c code associated with \c sym. */
/** Set the token \c code of \c sym, specified by the user at \c loc. */
void symbol_code_set (symbol *sym, int code, location loc);
@@ -245,7 +245,7 @@ extern symbol *eoftoken;
/** The genuine start symbol.
$accept: start-symbol $end */
extern symbol *accept;
extern symbol *acceptsymbol;
/** The user start symbol. */
extern symbol *startsymbol;
+16
View File
@@ -131,6 +131,22 @@ typedef size_t uintptr_t;
# include <stdbool.h>
/*-----------.
| Integers. |
`-----------*/
static inline int
min_int (int a, int b)
{
return a < b ? a : b;
}
static inline int
max_int (int a, int b)
{
return a >= b ? a : b;
}
/*-------------.
| Assertions. |
+6
View File
@@ -915,6 +915,12 @@ AT_BISON_OPTION_PUSHDEFS([$1])
AT_DATA_CALC_Y([$1])
AT_FULL_COMPILE(AT_JAVA_IF([[Calc]], [[calc]]), AT_DEFINES_IF([[lex], [main]], [[], []]), [$2], [-Wno-deprecated])
AT_YACC_IF(
[# No direct calls to malloc/free.
AT_CHECK([[$EGREP '(malloc|free) *\(' calc.[ch] | $EGREP -v 'INFRINGES ON USER NAME SPACE']],
[1])])
AT_PUSH_IF([AT_JAVA_IF(
[# Verify that this is a push parser.
AT_CHECK_JAVA_GREP([[Calc.java]],
+27 -17
View File
@@ -726,7 +726,7 @@ AT_BISON_OPTION_POPDEFS
AT_BISON_CHECK([[-Dlr.type=canonical-lr -o input.c input.y]],
[[0]], [[]],
[[input.y: warning: 2 shift/reduce conflicts [-Wconflicts-sr]
input.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
input.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
]])
AT_COMPILE([[input]])
AT_PARSER_CHECK([[input]], [[1]], [[]],
@@ -737,7 +737,7 @@ AT_PARSER_CHECK([[input]], [[1]], [[]],
AT_BISON_CHECK([[-Dlr.type=canonical-lr -Dparse.lac=full \
-o input.c input.y]], [[0]], [[]],
[[input.y: warning: 2 shift/reduce conflicts [-Wconflicts-sr]
input.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
input.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
]])
AT_COMPILE([[input]])
AT_PARSER_CHECK([[input]], [[1]], [[]],
@@ -748,7 +748,7 @@ AT_PARSER_CHECK([[input]], [[1]], [[]],
AT_BISON_CHECK([[-Dlr.type=ielr -Dparse.lac=full -o input.c input.y]],
[[0]], [[]],
[[input.y: warning: 2 shift/reduce conflicts [-Wconflicts-sr]
input.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
input.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
]])
AT_COMPILE([[input]])
AT_PARSER_CHECK([[input]], [[1]], [[]],
@@ -773,7 +773,7 @@ exp: exp OP exp | NUM;
AT_BISON_CHECK([-o input.c --report=all input.y], 0, [],
[[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
input.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
input.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
]])
# Check the contents of the report.
@@ -1032,7 +1032,7 @@ cond:
AT_BISON_CHECK([-o input.c input.y], 0, [],
[[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
input.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
input.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
input.y:12.3-18: warning: rule useless in parser due to conflicts [-Wother]
]])
@@ -1137,7 +1137,7 @@ id : '0';
AT_BISON_CHECK([-o input.c --report=all input.y], 0, [],
[[input.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
input.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
input.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
input.y:4.6-8: warning: rule useless in parser due to conflicts [-Wother]
]])
@@ -1272,7 +1272,7 @@ exp: exp OP exp | NUM;
AT_BISON_CHECK([-o input.c input.y], 1, [],
[[input.y: error: shift/reduce conflicts: 1 found, 0 expected
input.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
input.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
]])
AT_CLEANUP
@@ -1309,7 +1309,7 @@ exp: exp OP exp | NUM;
AT_BISON_CHECK([-o input.c input.y], 1, [],
[[input.y: error: shift/reduce conflicts: 1 found, 2 expected
input.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
input.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
]])
AT_CLEANUP
@@ -1329,7 +1329,7 @@ a: 'a';
AT_BISON_CHECK([-o input.c input.y], 1, [],
[[input.y: error: reduce/reduce conflicts: 1 found, 0 expected
input.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
input.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
]])
AT_CLEANUP
@@ -1530,7 +1530,7 @@ e: e '+' e
AT_BISON_CHECK([-Wall -o input.c input.y], 0, [],
[[input.y: warning: 4 shift/reduce conflicts [-Wconflicts-sr]
input.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
input.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
input.y:1.1-5: warning: useless precedence and associativity for '+' [-Wprecedence]
input.y:2.1-5: warning: useless precedence and associativity for '*' [-Wprecedence]
]])
@@ -1638,7 +1638,7 @@ reported_conflicts:
AT_BISON_CHECK([[--report=all input.y]], 0, [],
[[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
input.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
input.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
input.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
input.y:12.5-20: warning: rule useless in parser due to conflicts [-Wother]
input.y:20.5-20: warning: rule useless in parser due to conflicts [-Wother]
input.y:21.4: warning: rule useless in parser due to conflicts [-Wother]
@@ -1838,7 +1838,7 @@ AT_CHECK([[cat input.y >> input-keep.y]])
AT_BISON_CHECK([[input-keep.y]], 0, [],
[[input-keep.y: warning: 2 shift/reduce conflicts [-Wconflicts-sr]
input-keep.y: warning: 2 reduce/reduce conflicts [-Wconflicts-rr]
input-keep.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
input-keep.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
input-keep.y:22.4: warning: rule useless in parser due to conflicts [-Wother]
input-keep.y:26.16: warning: rule useless in parser due to conflicts [-Wother]
input-keep.y:32.5-7: warning: rule useless in parser due to conflicts [-Wother]
@@ -2038,7 +2038,7 @@ exp: 'a' | 'a';
AT_BISON_CHECK([[2.y]], [[0]], [],
[[2.y: warning: %expect-rr applies only to GLR parsers [-Wother]
2.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
2.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
2.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
2.y:3.12-14: warning: rule useless in parser due to conflicts [-Wother]
]])
@@ -2075,15 +2075,14 @@ B: ;
AT_BISON_CHECK([[sr-rr.y]], [[0]], [[]],
[[sr-rr.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
sr-rr.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
sr-rr.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
sr-rr.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
]])
AT_BISON_CHECK([[-Wno-conflicts-sr sr-rr.y]], [[0]], [[]],
[[sr-rr.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
sr-rr.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
sr-rr.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
]])
AT_BISON_CHECK([[-Wno-conflicts-rr sr-rr.y]], [[0]], [[]],
[[sr-rr.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
sr-rr.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
]])
[
@@ -2140,19 +2139,30 @@ for gram in sr-rr sr rr; do
]AT_BISON_CHECK([[-Werror $file]])[
else
{
issue_note=false
if test -z "$sr_exp_i" && test "$sr_count" -ne 0; then
echo "warning: $sr_count shift/reduce conflicts"
issue_note=true
elif test "$sr_exp_i" -ne "$sr_count"; then
echo "error: shift/reduce conflicts: $sr_count found, $sr_exp_i expected"
if test "$sr_count" -ne 0; then
issue_note=true
fi
fi
if test -z "$rr_exp_i" && test "$rr_count" -ne 0; then
echo "warning: $rr_count reduce/reduce conflicts"
issue_note=true
elif test "$rr_exp_i" -ne "$rr_count"; then
echo "error: reduce/reduce conflicts: $rr_count found, $rr_exp_i expected"
if test "$rr_count" -ne 0; then
issue_note=true
fi
fi
if $issue_note; then
echo "note: rerun with option '-Wcounterexamples' to generate conflict counterexamples"
fi
} | sed -e "s/^/$file: /" > experr
]AT_BISON_CHECK([[-Wnone $file]], [[1]], [[]], [[experr]])[
echo "$file: error: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Werror=other]" >> experr
]AT_BISON_CHECK([[-Werror $file]], [[1]], [[]], [[experr]])[
fi
done
+2 -2
View File
@@ -434,7 +434,7 @@ input.y:323.10: warning: empty rule without %empty [-Wempty-rule]
]AT_COND_CASE([[canonical LR]],
[[input.y: warning: 265 shift/reduce conflicts [-Wconflicts-sr]]],
[[input.y: warning: 65 shift/reduce conflicts [-Wconflicts-sr]]])[
input.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
input.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
input.y:39.1-5: warning: useless associativity for FUNC_CALL, use %precedence [-Wprecedence]
input.y:44.1-5: warning: useless associativity for YNUMBER, use %precedence [-Wprecedence]
input.y:44.1-5: warning: useless associativity for YSTRING, use %precedence [-Wprecedence]
@@ -1419,7 +1419,7 @@ input.y:591.18: warning: empty rule without %empty [-Wempty-rule]
input.y: warning: 144 reduce/reduce conflicts [-Wconflicts-rr]]],
[[input.y: warning: 78 shift/reduce conflicts [-Wconflicts-sr]
input.y: warning: 10 reduce/reduce conflicts [-Wconflicts-rr]]])[
input.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
input.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
input.y:72.1-5: warning: useless associativity for HQUA, use %precedence [-Wprecedence]
input.y:53.1-6: warning: useless associativity for HASSIGN, use %precedence [-Wprecedence]
input.y:54.1-5: warning: useless associativity for HORELSE, use %precedence [-Wprecedence]
+17 -17
View File
@@ -89,7 +89,7 @@ AT_BISON_OPTION_POPDEFS
AT_BISON_CHECK([[-o glr-regr1.c -rall glr-regr1.y]], 0, [],
[[glr-regr1.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
glr-regr1.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
glr-regr1.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
]])
AT_COMPILE([glr-regr1])
AT_PARSER_CHECK([[glr-regr1 BPBPB]], 0,
@@ -214,7 +214,7 @@ AT_BISON_OPTION_POPDEFS
AT_BISON_CHECK([[-o glr-regr2a.c -rall glr-regr2a.y]], 0, [],
[[glr-regr2a.y: warning: 2 shift/reduce conflicts [-Wconflicts-sr]
glr-regr2a.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
glr-regr2a.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
]])
AT_COMPILE([glr-regr2a])
@@ -350,7 +350,7 @@ AT_BISON_OPTION_POPDEFS
AT_BISON_CHECK([[-o glr-regr3.c -rall glr-regr3.y]], 0, [],
[[glr-regr3.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
glr-regr3.y: warning: 2 reduce/reduce conflicts [-Wconflicts-rr]
glr-regr3.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
glr-regr3.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
]])
AT_COMPILE([glr-regr3])
@@ -447,7 +447,7 @@ AT_BISON_OPTION_POPDEFS
AT_BISON_CHECK([[-o glr-regr4.c -rall glr-regr4.y]], 0, [],
[[glr-regr4.y: warning: 2 reduce/reduce conflicts [-Wconflicts-rr]
glr-regr4.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
glr-regr4.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
]])
AT_COMPILE([glr-regr4])
@@ -505,7 +505,7 @@ AT_BISON_OPTION_POPDEFS
AT_BISON_CHECK([[-o glr-regr5.c -rall glr-regr5.y]], 0, [],
[[glr-regr5.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
glr-regr5.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
glr-regr5.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
]])
AT_COMPILE([glr-regr5])
@@ -555,7 +555,7 @@ AT_BISON_OPTION_POPDEFS
AT_BISON_CHECK([[-o glr-regr6.c -rall glr-regr6.y]], 0, [],
[[glr-regr6.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
glr-regr6.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
glr-regr6.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
]])
AT_COMPILE([glr-regr6])
@@ -646,7 +646,7 @@ AT_BISON_OPTION_POPDEFS
AT_BISON_CHECK([[-o glr-regr7.c -rall glr-regr7.y]], 0, [],
[[glr-regr7.y: warning: 2 reduce/reduce conflicts [-Wconflicts-rr]
glr-regr7.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
glr-regr7.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
]])
AT_COMPILE([glr-regr7])
@@ -737,7 +737,7 @@ AT_BISON_OPTION_POPDEFS
AT_BISON_CHECK([[-o glr-regr8.c -rall glr-regr8.y]], 0, [],
[[glr-regr8.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
glr-regr8.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
glr-regr8.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
]])
AT_COMPILE([glr-regr8])
@@ -819,7 +819,7 @@ AT_BISON_OPTION_POPDEFS
AT_BISON_CHECK([[-o glr-regr9.c -rall glr-regr9.y]], 0, [],
[[glr-regr9.y: warning: 2 reduce/reduce conflicts [-Wconflicts-rr]
glr-regr9.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
glr-regr9.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
]])
AT_COMPILE([glr-regr9])
@@ -877,7 +877,7 @@ AT_BISON_OPTION_POPDEFS
AT_BISON_CHECK([[-o glr-regr10.c -rall glr-regr10.y]], 0, [],
[[glr-regr10.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
glr-regr10.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
glr-regr10.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
]])
AT_COMPILE([glr-regr10])
@@ -937,7 +937,7 @@ AT_BISON_OPTION_POPDEFS
AT_BISON_CHECK([[-o glr-regr11.c -rall glr-regr11.y]], 0, [],
[[glr-regr11.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
glr-regr11.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
glr-regr11.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
]])
AT_COMPILE([glr-regr11])
@@ -1060,7 +1060,7 @@ AT_BISON_OPTION_POPDEFS
AT_BISON_CHECK([[-o glr-regr12.c -rall glr-regr12.y]], 0, [],
[[glr-regr12.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
glr-regr12.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
glr-regr12.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
glr-regr12.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
]])
AT_COMPILE([glr-regr12])
@@ -1392,7 +1392,7 @@ AT_BISON_OPTION_POPDEFS
AT_BISON_CHECK([[-o glr-regr14.c -rall glr-regr14.y]], 0, [],
[[glr-regr14.y: warning: 5 reduce/reduce conflicts [-Wconflicts-rr]
glr-regr14.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
glr-regr14.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
]])
AT_COMPILE([glr-regr14])
@@ -1487,7 +1487,7 @@ AT_BISON_OPTION_POPDEFS
AT_BISON_CHECK([[-o glr-regr15.c -rall glr-regr15.y]], 0, [],
[[glr-regr15.y: warning: 2 reduce/reduce conflicts [-Wconflicts-rr]
glr-regr15.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
glr-regr15.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
]])
AT_COMPILE([glr-regr15])
@@ -1549,7 +1549,7 @@ AT_BISON_OPTION_POPDEFS
AT_BISON_CHECK([[-o glr-regr16.c -rall glr-regr16.y]], 0, [],
[[glr-regr16.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
glr-regr16.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
glr-regr16.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
]])
AT_COMPILE([glr-regr16])
@@ -1625,7 +1625,7 @@ AT_BISON_OPTION_POPDEFS
AT_BISON_CHECK([[-o glr-regr17.c -rall glr-regr17.y]], 0, [],
[[glr-regr17.y: warning: 3 reduce/reduce conflicts [-Wconflicts-rr]
glr-regr17.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
glr-regr17.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
]])
AT_COMPILE([glr-regr17])
@@ -1719,7 +1719,7 @@ d: /* nada. */;
AT_BISON_CHECK([[-o input.c input.y]], 0, [],
[[input.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
input.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
input.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
]])
AT_COMPILE([input])
+166 -20
View File
@@ -1,4 +1,4 @@
# Checking the Bison scanner. -*- Autotest -*-
# Checking the Bison reader. -*- Autotest -*-
# Copyright (C) 2002-2015, 2018-2020 Free Software Foundation, Inc.
@@ -78,10 +78,13 @@ AT_CLEANUP
## Invalid inputs. ##
## ---------------- ##
# The truly bad guys no human would write, but easily uncovered by
# fuzzers.
AT_SETUP([Invalid inputs])
AT_DATA([input.y],
[[\000\001\002\377?
"\000"
%%
?
default: 'a' }
@@ -92,21 +95,50 @@ default: 'a' }
]])
AT_PERL_REQUIRE([[-pi -e 's/\\(\d{3})/chr(oct($1))/ge' input.y]])
AT_BISON_CHECK([input.y], [1], [],
AT_BISON_CHECK([-fcaret input.y], [1], [], [stderr])
# Autotest's diffing, when there are NUL bytes, just reports "binary
# files differ". So don't leave NUL bytes.
AT_PERL_CHECK([[-p -e 's{([\0\377])}{sprintf "\\x%02x", ord($1)}ge' stderr]], [],
[[input.y:1.1-2: error: invalid characters: '\0\001\002\377?'
input.y:3.1: error: invalid character: '?'
input.y:4.14: error: invalid character: '}'
input.y:5.1: error: invalid character: '%'
input.y:5.2: error: invalid character: '&'
input.y:6.1-17: error: invalid directive: '%a-does-not-exist'
input.y:7.1: error: invalid character: '%'
input.y:7.2: error: invalid character: '-'
input.y:8.1-9.0: error: missing '%}' at end of file
1 | \x00\xff?
| ^~
input.y:2.2: error: invalid null character
2 | "\x00"
| ^
input.y:4.1: error: invalid character: '?'
4 | ?
| ^
input.y:5.14: error: invalid character: '}'
5 | default: 'a' }
| ^
input.y:6.1: error: invalid character: '%'
6 | %&
| ^
input.y:6.2: error: invalid character: '&'
6 | %&
| ^
input.y:7.1-17: error: invalid directive: '%a-does-not-exist'
7 | %a-does-not-exist
| ^~~~~~~~~~~~~~~~~
input.y:8.1: error: invalid character: '%'
8 | %-
| ^
input.y:8.2: error: invalid character: '-'
8 | %-
| ^
input.y:9.1-10.0: error: missing '%}' at end of file
9 | %{
| ^~
]])
AT_CLEANUP
## ------------------------ ##
## Invalid inputs with {}. ##
## ------------------------ ##
AT_SETUP([Invalid inputs with {}])
# We used to SEGV here. See
@@ -788,6 +820,33 @@ input.y:3.8-10: note: previous declaration
AT_CLEANUP
## ---------------- ##
## EOF redeclared. ##
## ---------------- ##
AT_SETUP([EOF redeclared])
# We used to crash when redefining a token after having defined EOF.
# See https://lists.gnu.org/r/bug-bison/2020-08/msg00008.html.
AT_DATA([[input.y]],
[[%token FOO BAR FOO 0
%%
input: %empty
]])
AT_BISON_CHECK([-fcaret input.y], [0], [],
[[input.y:1.16-18: warning: symbol FOO redeclared [-Wother]
1 | %token FOO BAR FOO 0
| ^~~
input.y:1.8-10: note: previous declaration
1 | %token FOO BAR FOO 0
| ^~~
]])
AT_CLEANUP
## --------------------------- ##
## Symbol class redefinition. ##
## --------------------------- ##
@@ -1224,12 +1283,12 @@ AT_TEST([[%token foo "foo"
%%
exp: foo;
]],
[[input.y:3.7-11: error: %type redeclaration for foo
[[input.y:3.13-15: error: %type redeclaration for foo
3 | %type <baz> foo
| ^~~~~
input.y:2.7-11: note: previous declaration
| ^~~
input.y:2.13-17: note: previous declaration
2 | %type <bar> "foo"
| ^~~~~
| ^~~~~
]])
AT_TEST([[%token foo "foo"
@@ -1336,11 +1395,6 @@ AT_CLEANUP
AT_SETUP([Torturing the Scanner])
AT_BISON_OPTION_PUSHDEFS
AT_DATA([input.y], [])
AT_BISON_CHECK([input.y], [1], [],
[[input.y:1.1: error: unexpected end of file
]])
AT_DATA([input.y],
[{}
@@ -2447,6 +2501,99 @@ input.y:5.19: error: invalid character after \-escape: \001
AT_CLEANUP
## ------------------------ ##
## Unexpected end of file. ##
## ------------------------ ##
AT_SETUP([[Unexpected end of file]])
AT_DATA([input.y], [])
AT_BISON_CHECK([-fcaret input.y], [1], [],
[[input.y:1.1: error: unexpected end of file
]])
AT_DATA_NO_FINAL_EOL([char.y],
[[%token FOO ']])
AT_BISON_CHECK([-fcaret char.y], [1], [],
[[char.y:1.12: error: missing "'" at end of file
1 | %token FOO '
| ^
char.y:1.12: error: empty character literal
1 | %token FOO '
| ^
]])
AT_DATA_NO_FINAL_EOL([escape-in-char.y],
[[%token FOO '\]])
AT_BISON_CHECK([-fcaret escape-in-char.y], [1], [],
[[escape-in-char.y:1.12-13: error: missing '?\'' at end of file
1 | %token FOO '\
| ^~
escape-in-char.y:1.14: error: unexpected end of file
1 | %token FOO '\
| ^
]])
AT_DATA_NO_FINAL_EOL([string.y],
[[%token FOO "]])
AT_BISON_CHECK([-fcaret string.y], [1], [],
[[string.y:1.12: error: missing '"' at end of file
1 | %token FOO "
| ^
string.y:1.13: error: unexpected end of file
1 | %token FOO "
| ^
]])
AT_DATA_NO_FINAL_EOL([escape-in-string.y],
[[%token FOO "\]])
AT_BISON_CHECK([-fcaret escape-in-string.y], [1], [],
[[escape-in-string.y:1.12-13: error: missing '?"' at end of file
1 | %token FOO "\
| ^~
escape-in-string.y:1.14: error: unexpected end of file
1 | %token FOO "\
| ^
]])
AT_DATA_NO_FINAL_EOL([tstring.y],
[[%token FOO _("]])
AT_BISON_CHECK([-fcaret tstring.y], [1], [],
[[tstring.y:1.12-14: error: missing '")' at end of file
1 | %token FOO _("
| ^~~
tstring.y:1.15: error: unexpected end of file
1 | %token FOO _("
| ^
]])
AT_DATA_NO_FINAL_EOL([escape-in-tstring.y],
[[%token FOO _("\]])
AT_BISON_CHECK([-fcaret escape-in-tstring.y], [1], [],
[[escape-in-tstring.y:1.12-15: error: missing '?")' at end of file
1 | %token FOO _("\
| ^~~~
escape-in-tstring.y:1.16: error: unexpected end of file
1 | %token FOO _("\
| ^
]])
AT_CLEANUP
## ------------------------- ##
## LAC: Errors for %define. ##
## ------------------------- ##
@@ -2887,7 +3034,6 @@ input.y:13.1-14: note: previous definition
input.y:14.16-29: warning: %define variable 'parse.error' redefined [-Wother]
input.y:13.16-29: note: previous definition
input.y: error: reduce/reduce conflicts: 0 found, 42 expected
input.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
input.y: warning: fix-its can be applied. Rerun with option '--update'. [-Wother]
]])
+1
View File
@@ -390,6 +390,7 @@ AT_LOCATION_TYPE_SPAN_IF(
AT_GLR_IF([AT_KEYWORDS([glr])])
AT_PUSH_IF([AT_KEYWORDS([push])])
])# _AT_BISON_OPTION_PUSHDEFS
+2 -2
View File
@@ -759,7 +759,7 @@ AT_TEST([x1],
])
# Check the CPP guard and Doxyen comments.
AT_CHECK([sed -ne 's/#line [0-9]\+ "/#line "/p;/INCLUDED/p;/\\file/{p;n;p;}' out/include/ast/loc.hh], [],
AT_CHECK([[sed -ne 's/#line [0-9][0-9]* "/#line "/p;/INCLUDED/p;/\\file/{p;n;p;}' out/include/ast/loc.hh]], [],
[[ ** \file bar/include/ast/loc.hh
** Define the x1::location class.
#ifndef YY_YY_BAR_INCLUDE_AST_LOC_HH_INCLUDED
@@ -771,7 +771,7 @@ AT_CHECK([sed -ne 's/#line [0-9]\+ "/#line "/p;/INCLUDED/p;/\\file/{p;n;p;}' out
#endif // !YY_YY_BAR_INCLUDE_AST_LOC_HH_INCLUDED
]])
AT_CHECK([sed -ne 's/^#line [0-9]\+ "/#line "/p;/INCLUDED/p;/\\file/{p;n;p;}' out/x1.hh], [],
AT_CHECK([[sed -ne 's/^#line [0-9][0-9]* "/#line "/p;/INCLUDED/p;/\\file/{p;n;p;}' out/x1.hh]], [],
[[ ** \file bar/x1.hh
** Define the x1::parser class.
#ifndef YY_YY_BAR_X1_HH_INCLUDED
+1 -1
View File
@@ -1300,7 +1300,7 @@ dnl INPUT
dnl BISON-STDERR
[AT_COND_CASE([[LALR]],
[[input.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
input.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
input.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
]], [])],
dnl TABLES
+1 -1
View File
@@ -285,7 +285,7 @@ term: 'n'
AT_BISON_CHECK([[-fcaret input.y]], [], [],
[[input.y: warning: 5 reduce/reduce conflicts [-Wconflicts-rr]
input.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
input.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
input.y:2.14-17: warning: rule useless in parser due to conflicts [-Wother]
2 | expr: term | term | term | term | term | term
| ^~~~