Compare commits

..
236 Commits
Author SHA1 Message Date
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
Akim Demaille a22588bcb9 version 3.6.93
* NEWS: Record release date.
2020-07-20 07:37:47 +02:00
Akim Demaille b8c5e5609f cex: label all the derivations by their initial action
From

    input.y: warning: reduce/reduce conflict on token $end [-Wcounterexamples]
      Example: A b .
      First derivation
        a
        `-> A b .
      Second derivation
        a
        `-> A b
              `-> b .

to

    input.y: warning: reduce/reduce conflict on token $end [-Wcounterexamples]
      Example: A b .
      First reduce derivation
        a
        `-> A b .
      Second reduce derivation
        a
        `-> A b
              `-> b .

* src/counterexample.c (print_counterexample): here.
Compute the width of the labels to properly align the values.
* tests/conflicts.at, tests/counterexample.at, tests/diagnostics.at,
* tests/report.at: Adjust.
2020-07-20 07:36:38 +02:00
Akim Demaille b81229e1f9 cex: improve readability of the subsections
Now that the derivation is no longer printed on one line, aligning the
example and the derivation is no longer useful.  It can actually be
harmful, as it makes the overall structure less clear.

* src/derivation.h, src/derivation.c (derivation_print_leaves): Remove
the `prefix` argument.
* src/counterexample.c (print_counterexample): Put the example next to
its label.
* tests/conflicts.at, tests/counterexample.at, tests/diagnostics.at,
* tests/report.at: Adjust.
2020-07-20 07:09:31 +02:00
Akim Demaille 815a76f558 cex: don't issue an empty line between counterexamples
Now that we use complain, the "sections" are clearer.

* src/counterexample.c (print_counterexample): Use the empty line only
in reports.
* tests/counterexample.at, tests/diagnostics.at, tests/report.at: Adjust.
2020-07-20 06:45:31 +02:00
Akim Demaille ea138cd1f1 cex: use usual routines for diagnostics about S/R conflicts
See previous commit.  We go from

    input.y: warning: 3 reduce/reduce conflicts [-Wconflicts-rr]
    Shift/reduce conflict on token "⊕":
      Example              exp "+" exp • "⊕" exp
      Shift derivation
        exp
        ↳ exp "+" exp
                  ↳ exp • "⊕" exp

to

    input.y: warning: 3 reduce/reduce conflicts [-Wconflicts-rr]
    input.y: warning: shift/reduce conflict on token "⊕" [-Wcounterexamples]
      Example              exp "+" exp • "⊕" exp
      Shift derivation
        exp
        ↳ exp "+" exp
                  ↳ exp • "⊕" exp

with an hyperlink on -Wcounterexamples.

* src/counterexample.c (counterexample_report_shift_reduce):
Use complain.
* tests/counterexample.at, tests/diagnostics.at, tests/report.at:
Adjust.
2020-07-20 06:45:27 +02:00
Akim Demaille 9922f1f877 cex: use usual routines for diagnostics about R/R conflicts
This is more consistent, and brings benefits: users know that these
diagnostics are attached to -Wcounterexamples, and they can also click
on the hyperlink if permitted by their terminal.

We go from

    warning: 1 reduce/reduce conflict [-Wconflicts-rr]
    Reduce/reduce conflict on token $end:
      Example              A b .
      First derivation     a -> [ A b . ]
      Second derivation    a -> [ A b -> [ b . ] ]

to

    warning: 1 reduce/reduce conflict [-Wconflicts-rr]
    input.y: warning: reduce/reduce conflict on token $end [-Wcounterexamples]
      Example              A b .
      First derivation     a -> [ A b . ]
      Second derivation    a -> [ A b -> [ b . ] ]

with an hyperlink on -Wcounterexamples.

* src/counterexample.c (counterexample_report_reduce_reduce):
Use complain.
* tests/counterexample.at, tests/diagnostics.at, tests/report.at:
Adjust.
2020-07-20 06:45:21 +02:00
Akim Demaille 1438b79e80 diagnostics: use hyperlinks to point to the only documentation
* src/complain.c (begin_hyperlink, end_hyperlink): New.
(warnings_print_categories): Use them.
* tests/local.at (AT_SET_ENV): Disable hyperlinks in the tests, they
contain random id's, and brackets (which is not so nice for M4).
2020-07-19 19:26:47 +02:00
Akim Demaille 01f3e2969b doc: add anchors for warnings
Unfortunately Texinfo somewhat mangles anchors such as `-Werror` into
`g_t_002dWerror`, so let's not include the dash.

* doc/bison.texi (Diagnostics): here.
2020-07-19 17:28:45 +02:00
Akim Demaille 744da03955 glyphs: fix types
The code was written on top of buffers of `char[26]`, and then was
changed to use `char *`, yet was still using `sizeof buf`, which
became `sizeof (char *)` instead of `sizeof (char[26])`.

Reported by Dagobert Michelsen.
https://lists.gnu.org/r/bug-bison/2020-07/msg00023.html

* src/glyphs.h, src/glyphs.c: Get rid of uses of `char *`, use only
glyph_buffer_t.
2020-07-19 17:09:01 +02:00
Akim Demaille b28d67b6b0 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-19 09:45:36 +02:00
Akim Demaille cf890692f1 version 3.6.92
* NEWS: Record release date.
2020-07-19 09:24:57 +02:00
Akim Demaille 6932023f4d style: avoid strncpy
syntax-check seems to dislike strncpy.  The GNU Coreutils replaced
their uses of strncpy with stpncpy.

strlcpy is not an option.
  http://sources.redhat.com/ml/libc-alpha/2002-01/msg00159.html
  http://sources.redhat.com/ml/libc-alpha/2002-01/msg00011.html
  http://lists.gnu.org/archive/html/bug-gnulib/2004-09/msg00181.html

* src/glyphs.c: Use stpncpy.
2020-07-19 09:23:42 +02:00
Akim Demaille fff17fe8fe cex: display derivations as trees
Sometimes, understanding the derivations is difficult, because they
are serialized to fit in one line.  For instance, the example taken
from the NEWS file:

    %token ID
    %%
    s: a ID
    a: expr
    expr: expr ID ',' | "expr"

gave

    First example        expr • ID ',' ID $end
    Shift derivation     $accept → [ s → [ a → [ expr → [ expr • ID ',' ] ] ID ] $end ]
    Second example       expr • ID $end
    Reduce derivation    $accept → [ s → [ a → [ expr • ] ID ] $end ]

Printing as trees, it gives:

    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 •

* src/glyphs.h, src/glyphs.c (down_arrow, empty, derivation_separator):
New.
* src/derivation.c (derivation_print, derivation_print_impl): Rename
as...
(derivation_print_flat, derivation_print_flat_impl): These.
(fputs_if, derivation_depth, derivation_width, derivation_print_tree)
(derivation_print_tree_impl, derivation_print): New.
* src/counterexample.c (print_counterexample): Adjust.
* tests/conflicts.at, tests/counterexample.at, tests/diagnostics.at,
* tests/report.at: Adjust.
2020-07-18 07:54:02 +02:00
Akim Demaille 5544615a59 cex: use the glyphs
* src/derivation.c: here.
* src/gram.h, src/gram.c (print_arrow, print_dot, print_fallback):
Remove.
2020-07-16 07:31:25 +02:00
Akim Demaille 346ba14f15 cex: factor the handling of graphical symbols
* src/glyphs.h, src/glyphs.c: New.
2020-07-16 07:31:24 +02:00
Akim Demaille 4d18195ebc cex: style changes
* src/counterexample.c: here.
2020-07-15 06:41:07 +02:00
Akim Demaille dd3e7b3895 cex: simplify tests
* tests/counterexample.at (AT_BISON_CHECK_CEX): Handle the keyword.
Simplify the signature.
2020-07-15 06:38:36 +02:00
Akim Demaille 64a3b6546a cex: more colors
Provided by Daniela Becker.

* data/bison-default.css: More colors.
2020-07-15 06:38:36 +02:00
Akim Demaille bad07a7f66 style: comments changes
* src/print.c: here.
2020-07-14 14:26:02 +02:00
Akim Demaille 88bd814bf1 doc: update GLR sections
Reported by Christian Schoenebeck.

* doc/bison.texi (GLR Parsers): Minor fixes.
(Compiler Requirements for GLR): Remove, quite useless today.
2020-07-14 06:56:15 +02:00
Akim Demaille 4f9ae5de07 cex: display shifts before reductions
When reporting counterexamples for s/r conflicts, put the shift first.
This is more natural, and displays the default resolution first, which
is also what happens for r/r conflicts where the smallest rule number
is displayed first, and "wins".

* src/counterexample.c (counterexample): Add a shift_reduce member.
(new_counterexample): Adjust.
Swap the derivations when this is a s/r conflict.
(print_counterexample): For s/r conflicts, prefer "Shift derivation"
and "Reduce derivation" rather than "First/Second derivation".

* tests/conflicts.at, tests/counterexample.at, tests/report.at: Adjust.
* NEWS, doc/bison.texi: Ditto.
2020-07-14 06:48:48 +02:00
Akim Demaille 78f72a4516 style: s/lookahead_tokens/lookaheads/g
Currently we use both names.  Let's stick to the short one.

* src/AnnotationList.c, src/conflicts.c, src/counterexample.c,
* src/getargs.c, src/getargs.h, src/graphviz.c, src/ielr.c,
* src/lalr.c, src/print-graph.c, src/print-xml.c, src/print.c,
* src/state-item.c, src/state.c, src/state.h, src/tables.c:
s/lookahead_token/lookahead/gi.
2020-07-14 06:48:48 +02:00
Akim Demaille c04693d651 cex: factor memory allocation
* src/counterexample.c (counterexample_report_state): Allocate once
per conflicted state, instead of once per r/r conflict.
2020-07-14 06:48:48 +02:00
Akim Demaille 12191911ba cex: use state_item_number consistently
* src/counterexample.c, src/state-item.c: here.
(counterexample_report_state): While at it, prefer c2 to j/k, to match
c1.
2020-07-14 06:48:48 +02:00
Akim Demaille d7f27477f4 cex: more consistent memory allocation/copy
* src/counterexample.c, src/parse-simulation.c: It is more usual in
Bison to use sizeof on expressions than on types, especially for
allocation.
Let the compiler do it's job instead of calling memcpy ourselves.
2020-07-14 06:48:48 +02:00
Akim Demaille 5bad15d7ea cex: minor renaming
* src/counterexample.c (has_common_prefix): Rename as...
(have_common_prefix): this.
2020-07-14 06:48:48 +02:00
Akim Demaille cd099edf2d cex: use better type names
There are too many gl_list_t in there, it's hard to understand what is
going on.  Introduce and use more precise types.  I sure can be wrong
in some places, it's hard to tell without proper tool support.

* src/counterexample.c, src/lssi.c, src/lssi.h, src/parse-simulation.c,
* src/parse-simulation.h, src/state-item.c, src/state-item.h
(si_bfs_node_list, search_state_list, ssb_list, lssi_list)
(state_item_list): New.
2020-07-14 06:48:48 +02:00
Akim Demaille 1e12219775 cex: minor style changes
* src/counterexample.h, src/derivation.h, src/derivation.c:
More comments.
Use `out` for FILE*, as elsewhere.
2020-07-14 06:48:48 +02:00
Akim Demaille d8c2af56c1 tests: beware of version numbers from git describe
* tests/report.at: Be robust to version numbers such as
3.6.4.133-fbac-dirty.
2020-07-14 06:48:48 +02:00
Akim Demaille cc11bb037c tests: fix expectations
Broken in ee86ea8839.

* tests/diagnostics.at: here.
2020-07-14 06:48:48 +02:00
Akim Demaille 121dd98508 doc: makeinfo wants @arrow{}, not @arrow
* doc/bison.texi: here.
2020-07-12 08:15:44 +02:00
Akim Demaille 2eddbd0ac4 gnulib: update 2020-07-11 19:11:19 +02:00
Akim Demaille ee86ea8839 cex: prefer → to ::=
It does not make a lot of sense to use ::= in our counterexamples,
that's not something that belongs to the Bison "vocabulary".  Using
the colon makes sense, but it's too discreet.  Let's use the arrow,
which we already use in some reports (HTML and Dot).

* src/gram.h (print_dot_fallback): Generalize into...
(print_fallback): this.
(print_arrow): New.
* src/derivation.c: Use it.

* NEWS, tests/conflicts.at, tests/counterexample.at,
* tests/diagnostics.at, tests/report.at: Adjust.
* doc/bison.texi: Ditto.
Unfortunately the literal `→` is output as `↦`.  So we need to use
@arrow.
2020-07-11 18:43:46 +02:00
Akim Demaille a2ad33dca6 style: cex: prefer the array notation
Prefer `&foos[i]` to `foos + i` when `foos` is an array.  IMHO, it
makes the semantics clearer.

* src/counterexample.c, src/lssi.c, src/parse-simulation.c,
* src/state-item.c: With arrays, prefer the array notation rather than
the pointer one.
2020-07-11 18:07:09 +02:00
Akim Demaille 5b2b7b1ffb style: cex: remove variables that don't make it simpler to read
* src/counterexample.c: With arrays, prefer the array notation rather
than the pointer one.
2020-07-11 18:07:09 +02:00
Akim Demaille dc72b3566d bistromathic: demonstrate caret-diagnostics
* examples/c/bistromathic/parse.y (user_context): We need the current
line.
(yyreport_syntax_error): Quote the guilty line, with squiggles.
* examples/c/bistromathic/bistromathic.test: Adjust.
2020-07-11 18:06:45 +02:00
Akim Demaille c47e1174d4 bistromathic: do not display parse errors on completion
Currently autocompletion on a line with errors leaks the error
messages.  It can be useful to let the user know, but GNU Readline
does not provide us with an nice way to display the error.  So we
actually break into the current line of the user.

So instead, do not show these errors.

* examples/c/bistromathic/parse.y (user_context): New.
Use %param to pass it to the parser and scanner.
Keep quiet when in computing autocompletion.
2020-07-11 18:05:50 +02:00
Akim Demaille 093eeb27e9 bistromathic: don't stupidly reset the location for each token
That quite defeats the whole point of locations...  But anyway, we
should not see these messages at all.

* examples/c/bistromathic/parse.y (expected_tokens): Fix (useless)
location tracking.
2020-07-11 18:05:41 +02:00
Akim Demaille dab23c4a21 bistromathic: promote yytoken_kind_t
* examples/c/bistromathic/parse.y: Use yytoken_kind_t rather than int.
2020-07-11 18:05:35 +02:00
Akim Demaille 38a169bec1 html: capitalize titles
* data/xslt/xml2xhtml.xsl: Use "State 0", not "state 0".
As we do in text reports.
2020-07-11 12:58:45 +02:00
Akim Demaille dc77d6500f html: don't define several times the same anchors
Currently when we output useless rules, they appear before the
grammar, but using the same invocation.  As a result, the anchor is
defined twice, and the wrong one, being first, is honored.

* data/xslt/xml2xhtml.xsl (rule): Take a new 'anchor' parameter to
decide whether being an anchor, or a target.
Let it be true when output the grammar.
* tests/report.at: Adjust.
2020-07-11 12:58:44 +02:00
Akim Demaille 8262c7dc22 html: simplify
* data/xslt/xml2xhtml.xsl: Merge two identical when-clauses.
2020-07-11 12:58:44 +02:00
Akim Demaille 44f28d10ee reports: let html reports catch up with --report and --graph
* data/xslt/xml2xhtml.xsl: Show the symbol types.
* tests/report.at: Adjust.
2020-07-11 12:58:44 +02:00
Akim Demaille 44ad466a32 reports: let xml reports catch up with --report and --graph
The text and Dot reports are expected to be identical when generated
directly (--report, --graph) or indirectly (via XML).  The xml
testsuite had not be run for ages, let it catch up a bit.

* src/print-xml.c: Pass the type of the symbols.
* data/xslt/xml2text.xsl
Catch up with the new layout.
Display the symbol types.
Use '•', not '.'
* tests/local.at: Smash '•' to '.' when matching against the direct
text report.
* tests/report.at: Adjust XML expectations.
2020-07-11 12:58:44 +02:00
Akim Demaille a839f4c461 reports: update html ouput
* data/xslt/xml2xhtml.xsl: Improve indentation.
Use ul/li rather that pre.
2020-07-11 12:58:44 +02:00
Akim Demaille 9a51c6a128 tests: check html
* tests/report.at: here.
2020-07-11 12:58:44 +02:00
Akim Demaille 2608b0cf12 style: factor complex expressions
* src/print-xml.c, src/print.c: Introduce a variable pointing to the
current symbol.
2020-07-11 12:58:44 +02:00
Akim Demaille aa766d1560 maint: make it easier to update expectations
* tests/local.mk (update-tests): New.
2020-07-11 12:58:44 +02:00
Akim Demaille a7ed13b25f 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-09 21:38:23 +02:00
Akim Demaille 2d90916067 version 3.6.91
* NEWS: Record release date.
2020-07-09 21:10:23 +02:00
Akim Demaille 91e5a23ff2 news: update 2020-07-09 20:29:24 +02:00
Akim Demaille d4ae66c371 gnulib: update 2020-07-09 20:26:16 +02:00
Akim Demaille 70fb574717 examples: add license headers
Prompted by Rici Lake.
https://stackoverflow.com/questions/62658368/#comment110853985_62661621
Discussed with Paul Eggert.

* doc/bison.texi, examples/c/bistromathic/parse.y,
* examples/c/lexcalc/parse.y, examples/c/lexcalc/scan.l,
* examples/c/pushcalc/calc.y, examples/c/reccalc/parse.y,
* examples/c/reccalc/scan.l, examples/d/calc.y,
* examples/java/calc/Calc.y, examples/java/simple/Calc.y:
Install the GPL3+ header.
2020-07-08 22:19:37 +02:00
Akim Demaille 0820f16ca8 style: update comments
* src/reader.c: action_obstack was removed in 2002...
* src/parse-gram.y: Better names.
* src/scan-code.h: More comments.
2020-07-05 09:59:45 +02:00
Akim Demaille 49f1e5f428 style: update comments in the skeletons
* data/skeletons/c++.m4, data/skeletons/glr.c, data/skeletons/lalr1.d,
* data/skeletons/lalr1.java, data/skeletons/yacc.c:
Be more accurate about yychar and yytoken.
Don't name local variables as if they were members.
2020-07-05 09:59:25 +02:00
Akim Demaille 238692ad77 doc: more details about symbols in m4
* data/README.md: here.
* README-hacking.md (Vocabulary): More.
2020-07-05 09:18:27 +02:00
Akim Demaille 5f95583da7 regen 2020-07-05 08:18:51 +02:00
Akim Demaille 964fb2aa6f examples: include the generated header
* examples/c/bistromathic/parse.y, examples/c/lexcalc/parse.y,
* examples/c/reccalc/parse.y: here.
Add some comments.

* src/parse-gram.y (api_version): Pull out of handle_require.
Bump to 3.7.
2020-07-05 08:18:51 +02:00
Akim Demaille 7c0d36b760 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-04 12:37:45 +02:00
Akim Demaille b4d18c7fc6 version 3.6.90
* NEWS: Record release date.
2020-07-04 12:14:28 +02:00
Akim Demaille 3e6e51cf5c news: update 2020-07-04 12:12:33 +02:00
Akim Demaille d309bd9f9f package: fix syntax-check errors
* examples/c/bistromathic/bistromathic.test, po/POTFILES.in: here.
2020-07-04 12:10:15 +02:00
Akim Demaille 203f7230ec gnulib: update 2020-07-04 11:43:41 +02:00
Akim Demaille 156e548341 cex: give more details about -Wcex and -rcex
* data/bison-default.css: Cobalt does not seem to be supported.
* doc/bison.texi (Counterexamples): A new section.
(Understanding): Show the counterexamples as it shows in the report:
with its items.
(Bison Options): Document -Wcex and -rcex.
2020-07-04 11:43:35 +02:00
Akim Demaille 526ef45f30 news: update 2020-07-03 07:07:28 +02:00
Akim Demaille d7f7fcd9c7 dot: also use a dot in the output
* src/print-graph.c (print_core): Use a dot instead of a point.
* doc/figs/example-reduce.gv, doc/figs/example-reduce.txt,
* doc/figs/example-shift.gv, doc/figs/example-shift.txt,
* doc/figs/example.gv: Update.
* tests/output.at, tests/report.at: Adjust.
2020-07-03 06:51:57 +02:00
Akim DemailleandAkim Demaille 0fd542c3e0 doc: improve a sentence
* doc/bison.texi: here.
2020-07-02 07:21:33 +02:00
Akim Demaille 413908e5a4 news: formatting changes 2020-07-01 07:05:48 +02:00
Akim Demaille 84ef175287 news, todo: update 2020-07-01 07:05:41 +02:00
Akim Demaille 5234c8390f doc: clarify that the pcontext interface is *.c only
Reported by Rici Lake.
https://lists.gnu.org/r/bug-bison/2020-06/msg00054.html

* doc/bison.texi (Syntax Error Reporting Function): Make it clear that
this is not exported.
Remove C++ details that landed in the C doc.
2020-06-30 20:16:31 +02:00
Akim Demaille 21f7690570 doc: use color in the cex examples
* doc/bison.texi: here.
And use smallexample when it no longer fits in PDF.
2020-06-30 20:16:31 +02:00
Akim Demaille edb39c29a2 doc: repair the references to the Bibliography
In commit c80cdf2db2 ("doc: simplify
uses of @ref", Jan 27 2020, released in Bison 3.6), I broke the
references to the Bibliography.  For instance:

     For a more detailed exposition of the mysterious behavior in LALR parsers
    -and the benefits of IELR, @pxref{Bibliography,,Denny 2008 March}, and
    -@ref{Bibliography,,Denny 2010 November}.
    +and the benefits of IELR, @pxref{Bibliography}, and
    +@ref{Bibliography}.

which results in "see Bibliography" twice, instead of the more precise
reference.

* doc/bison.texi (@pcite, @tcite): New.
Use them instead of @ref to Bibliography.
Cite only the first author (that's what we did for the other entries).
2020-06-30 08:01:40 +02:00
Vincent ImbimboandAkim Demaille 1247d94ba6 doc: cex documentation
* NEWS, doc/bison.texi: Add documentation for conflict counterexample
generation.
2020-06-30 08:01:40 +02:00
Akim Demaille ed9a821caa doc: update Doxygen template file
* doc/Doxyfile.in: here.
2020-06-30 08:01:40 +02:00
Akim Demaille 330552ea49 yacc.c: push: don't clear the parser state when accepting/rejecting
Currently when a push parser finishes its parsing (i.e., it did not
return YYPUSH_MORE), it also clears its state.  It is therefore
impossible to see if it had parse errors.

In the context of autocompletion, because error recovery might have
fired, the parser is actually already in a different state.  For
instance on `(1 + + <TAB>` in the bistromathic, because there's a
`exp: "(" error ")"` recovery rule, `1 + +` tokens have already been
popped, replaced by `error`, and autocompletions think we are ready
for the closing ")".  So here, we would like to see if there was a
syntax error, yet `yynerrs` was cleared.

In the case of a successful parse, we still have a problem: if error
recovery succeeded, we won't know it, since, again, `yynerrs` is
clearer.

It seems much more natural to leave the parser state available for
analysis when there is a failure.

To reuse the parser, we should either:

1. provide an explicit means to reinitialize a parser state for future
   parses.

2. automatically reset the parser state when it is used in a new
   parse.

Option 2 requires to check whether we need to reinitialize the parser
each time we call `yypush_parse`, i.e., each time we give a new token.
This seems expensive compared to Option 1, but benchmarks revealed no
difference.  Option 1 is incompatible with the documentation
("After `yypush_parse` returns a status other than `YYPUSH_MORE`, the
parser instance `yyps` may be reused for a new parse.").

So Option 2 wins, reusing the private `yynew` member to record that a
parse was finished, and therefore that the state must reset in the
next call to `yypull_parse`.

While at it, this implementation now reuses the previously enlarged
stacks from one parse to another.

* data/skeletons/yacc.c (yypstate_new): Set up the stacks in their
initial configurations (setting their bottom to the stack array), and
use yypstate_clear to reset them (moving their top to their bottom).
(yypstate_delete): Adjust.
(yypush_parse): At the beginning, clear yypstate if needed, and at the
end, record when yypstate needs to be clearer.

* examples/c/bistromathic/parse.y (expected_tokens): Do not propose
autocompletion when there are parse errors.
* examples/c/bistromathic/bistromathic.test: Check that case.
2020-06-29 19:36:41 +02:00
Akim Demaille 7c609859ee bistromathic: don't display undefined locations
Currently, completion when there is a syntax error shows broken
locations.

* examples/c/bistromathic/parse.y (expected_tokens): Initialize the
location.
* examples/c/bistromathic/bistromathic.test: Check that.
2020-06-29 19:10:05 +02:00
Akim Demaille ed10c308fa yacc.c: simplify initialization of push parsers
The previous commit ("yacc.c: declare and initialize and the same
time") made b4_initialize_parser_state_variables useless.

* data/skeletons/yacc.c (b4_initialize_parser_state_variables): Inline
into...
(yypstate_clear): here.
2020-06-29 19:10:05 +02:00
Akim Demaille b91566edd1 regen 2020-06-29 19:10:05 +02:00
Akim Demaille 29520abb3b yacc.c: declare and initialize and the same time
In order to factor the code of push and pull parsers, the declaration
of the parser's state variable was common (being local variable in
pull parsers, and struct members in push parsers).  This result in
rather poor style in pull parser, with first variable declarations,
and then their initializations.

The initialization is about to differ between push and pull parsers,
so it is no longer worth keeping both cases together.

* data/skeletons/yacc.c (b4_declare_parser_state_variables): Accept an
argument, and when it is set, initialize the variables.
Adjust dependencies.
2020-06-29 19:10:05 +02:00
Akim Demaille 2491de1eef yacc.c: style changes in push mode
* data/skeletons/yacc.c: here.
2020-06-29 19:10:05 +02:00
Akim Demaille ec207d1bb2 yacc.c: simplify yypull_parse
Currently yypull_parse takes a yypstate* as argument, and accepts it
to be NULL.  This does not seem to make a lot of sense: rather it is
its callers that should do that.

I believe this is historical: yypull_parse was introduced
first (c3d503425f), with yyparse being a
macro.  So yyparse could hardly deal with memory allocation properly.
In 7172e23e8f that yyparse was turned
into a genuine function.  At that point, it should have allocated its
own yypstate*, which would have left yypull_parse deal with only one
single non-null ypstate* argument.

Fortunately, it is nowhere documented that it is valid to pass NULL to
yypull_parse.  It is now forbidden.

* data/skeletons/yacc.c (yypull_parse): Don't allocate a yypstate.
Needs a location to issue the error message.
(yyparse): Allocate the yypstate.
2020-06-29 19:10:05 +02:00
Akim Demaille 688b3404a2 doc: tidy the text files
* etc/README: Rename/reformat as...
* etc/README.md: this.
And ship it.
2020-06-29 19:10:05 +02:00
Akim Demaille cd6ef1e7d7 bench: simplify the rand target
* etc/bench.pl.in: There is no need to recompile the bench cases
themselves.
2020-06-29 19:10:05 +02:00
Akim Demaille 2b518d621f bench: make it easy to edit the generated files
* etc/bench.pl.in (&compile): Generate rules that compile the
generated files independently of the source files.
2020-06-29 19:08:15 +02:00
Akim Demaille 1ae4f1d329 tests: don't use $VERBOSE
It is used by the test suite itself, which results in this test
failing.

* tests/c++.at: Use $DEBUG, not $VERBOSE.
2020-06-29 06:45:44 +02:00
Akim Demaille 160df55c56 doc: overhaul of the readmes
* README-hacking.md (Working from the Repository): Make it first to
make it easier to find the instructions to build from the repo.
(Implementation Notes): New.
* README: Provide more links.
2020-06-28 14:57:41 +02:00
Akim Demaille e0b0a67b86 java: rename package as api.package
* data/skeletons/lalr1.java: here.
* doc/bison.texi: Update.
* src/muscle-tab.c: Ensure backward compat.
* tests/java.at: Check it.
2020-06-28 09:49:00 +02:00
Akim Demaille 0e5cbd38b2 style: shift/reduce, not shift-reduce
* src/reader.c: here.
2020-06-28 08:33:24 +02:00
Akim Demaille feb0bb0a59 style: rename endtoken as eoftoken
* src/symtab.h, src/symtab.c (endtoken): Rename as...
(eoftoken): this.
Adjust dependencies.
2020-06-27 17:31:59 +02:00
Akim Demaille d796e11f8f news: fixes
Reported by Jacob L. Mandelson.

* NEWS: here.
2020-06-27 17:04:50 +02:00
Akim Demaille 0895858d8e style: use 'nonterminal' consistently
* doc/bison.texi: Formatting changes.
* src/gram.h, src/gram.c (nvars): Rename as...
(nnterms): this.
Adjust dependencies.
(section): New.  Use it.
Replace "non terminal" and "non-terminal" by "nonterminal".
2020-06-27 11:39:32 +02:00
Akim Demaille 4efb2f7bd2 doc: parse.assert in C++ requires RTTI
* doc/bison.texi (%define Summary): Say it.
2020-06-27 10:31:59 +02:00
Akim Demaille eeafc706e8 c++: by default, use const std::string for file names
Reported by Martin Blais and Yuriy Solodkyy.
https://lists.gnu.org/r/help-bison/2020-05/msg00011.html
https://lists.gnu.org/r/bug-bison/2020-06/msg00038.html

While at it, modernize filename_type as api.filename.type and document
it properly.

* data/skeletons/c++.m4 (filename_type): Rename as...
(api.filename.type): this.
Default to const std::string.
* data/skeletons/location.cc (position, location): Expose the
filename_type type.
Use api.filename.type.
* doc/bison.texi (%define Summary): Document api.filename.type.
(C++ Location Values): Document position::filename_type.
* src/muscle-tab.c (muscle_percent_variable_update): Ensure backward
compatibility.
* tests/c++.at: Check that using const file names is ok.
tests/input.at: Check backward compat.
2020-06-27 10:06:00 +02:00
Akim Demaille cf6d8d0631 ielr: fix crash on memory management
Reported by Dwight Guth.
https://lists.gnu.org/r/bug-bison/2020-06/msg00037.html

* src/AnnotationList.c (AnnotationList__computePredecessorAnnotations):
Beware that SBITSET__FOR_EACH nests _two_ for-loops, so "break" does
not actually break out of it.
That was the only occurrence in the code.
* src/Sbitset.h (SBITSET__FOR_EACH): Warn passersby.
2020-06-27 08:16:07 +02:00
Akim Demaille 8f44164443 style: factor the access to a rule from its items
* src/counterexample.c (item_rule): Move to...
* src/counterexample.h: here.
* src/AnnotationList.c, src/counterexample.c, src/ielr.c: Use it.
2020-06-25 19:36:07 +02:00
Akim Demaille 1001f48416 style: clean up nullable
* src/nullable.c: Reduce scopes.
Prefer `r` to `rules_ruleno`, which is truly an ugly name.
2020-06-25 19:36:07 +02:00
Akim Demaille 3be228f64c style: clean up ielr
* src/AnnotationList.c, src/ielr.c: Fix include order.
Prefer `res` to `result`.
Reduce scopes.
Be free of the oldish 76 cols limitation when it clutters too much the
code.
Denest when possible (we're starving for horizontal width).
2020-06-25 19:30:06 +02:00
Akim Demaille 670c7e7a75 don't use strlen to compute visual width
* src/output.c (prepare_symbol_names): Use mbswidth.
2020-06-23 08:27:26 +02:00
Akim Demaille c4b1a2b68f doc: use dot/'•' rather than point/'.'
AFAICT, "dotted rule" is a more frequent synonym of "item" than
"pointed rule".  So let's migrate to using "dot" only.

* doc/bison.texi: Use dot/'•' rather than point/'.'.

* src/print-xml.c (print_core): Use dot rather than point.  This is
not backward compatible, but AFAICT, we don't have actual user of the
XML output (but ourselves).  So...
* data/xslt/xml2dot.xsl, data/xslt/xml2text.xsl,
* data/xslt/xml2xhtml.xsl, tests/report.at: ... adjust.
2020-06-23 07:37:29 +02:00
Akim Demaille b65bd16e45 cex: display all the S/R conflicts, not just one per (state, rule)
Before this commit, on

    %%
    exp
    : "if" exp "then" exp
    | "if" exp "then" exp "else" exp
    | exp "+" exp
    | "num"

we used to not display the third counterexample below:

    Shift/reduce conflict on token "+":
      Example              exp "+" exp . "+" exp
      First derivation     exp ::=[ exp ::=[ exp "+" exp . ] "+" exp ]
      Second derivation    exp ::=[ exp "+" exp ::=[ exp . "+" exp ] ]

    Shift/reduce conflict on token "else":
      Example              "if" exp "then" "if" exp "then" exp . "else" exp
      First derivation     exp ::=[ "if" exp "then" exp ::=[ "if" exp "then" exp . ] "else" exp ]
      Second derivation    exp ::=[ "if" exp "then" exp ::=[ "if" exp "then" exp . "else" exp ] ]

    Shift/reduce conflict on token "+":
      Example              "if" exp "then" exp . "+" exp
      First derivation     exp ::=[ exp ::=[ "if" exp "then" exp . ] "+" exp ]
      Second derivation    exp ::=[ "if" exp "then" exp ::=[ exp . "+" exp ] ]

    Shift/reduce conflict on token "+":
      Example              "if" exp "then" exp "else" exp . "+" exp
      First derivation     exp ::=[ exp ::=[ "if" exp "then" exp "else" exp . ] "+" exp ]
      Second derivation    exp ::=[ "if" exp "then" exp "else" exp ::=[ exp . "+" exp ] ]

* src/counterexample.c (counterexample_report_state): Don't stop of
the first conflicts.
* tests/conflicts.at, tests/counterexample.at, tests/diagnostics.at,
* tests/report.at: Adjust.
2020-06-23 06:56:04 +02:00
Akim Demaille 0f120354b6 cex: don't display twice unifying examples if there is no color
It makes no sense, and is actually confusing, to display twice the
same example with no visible difference.

* src/complain.h, src/complain.c (is_styled): New.
* src/counterexample.c (print_counterexample): Display the unified
example a second time only if it makes a difference.
* tests/conflicts.at, tests/counterexample.at, tests/report.at: Adjust.
* tests/diagnostics.at: Make sure we do display the unifying examples
twice when colors are enabled.  And check those colors.
2020-06-22 19:33:30 +02:00
Vincent ImbimboandAkim Demaille 69e3b405d9 cex: fix reporting of null nonterminals
I implemented this to print A ::= [ ], but A ::= [ %empty ] might be
clearer.

* src/parse-simulation.c (nullable_closure): Don't generate null
nonterminal derivations as leaves.
* src/derivation.c (derivation_print_impl): Don't print seperator
spaces for null nonterminal.
* tests/counterexample.at: Update test results.
2020-06-22 07:11:31 +02:00
Akim Demaille 3dd8f2305a cex: use the bullet in HTML
* data/xslt/xml2xhtml.xsl: here.
2020-06-22 07:02:29 +02:00
Akim Demaille 9e75066819 cex: style changes
* src/counterexample.c: Simplify a bit.
* src/parse-simulation.c, src/parse-simulation.h: Enforce coding style.
2020-06-19 08:02:18 +02:00
Akim Demaille efb65daa36 c++: get rid of global_tokens_and_yystype
This was a hack to make it easier for people to migrate from yacc.c to
lalr1.cc and from glr.c to glr.cc: when set, YYSTYPE and YYLTYPE were
`#defined`.  It was never documented (just mentioned in NEWS for Bison
2.2, 2006-05-19), but was used to simplify the test suite.  Stop that:
adjust the test suite to the skeletons, not the converse.

In C++ use yy::parser::semantic_type, yy::parser::location_type, and
yy::parser::token::MY_TOKEN, instead of YYSTYPE, YYLTYPE and MY_TOKEN.

* data/skeletons/glr.cc, data/skeletons/lalr1.cc: Remove its support.
* tests/actions.at, tests/c++.at, tests/calc.at: Adjust.
2020-06-16 08:14:42 +02:00
Akim Demaille e077bf1ebc cex: don't assume the terminal supports "•"
Use of print_unicode_char suggested by Bruno Haible.
https://lists.gnu.org/r/bug-gettext/2020-06/msg00012.html

* src/gram.h (print_dot_fallback, print_dot): New.
* src/gram.c, src/derivation.c: Use it.
* tests/counterexample.at, tests/report.at: Adjust the test suite.
* .travis.yml, README-hacking.md: Adjust.
2020-06-16 07:58:40 +02:00
Akim Demaille c35e829a76 cex: also include in the report on --report=counterexamples
And let --report=all include the counterexamples.

* src/getargs.h, src/getargs.c (report_cex): New.
* src/main.c: Compute counterexamples when -rcex is specified.
* src/print.c: Include the counterexamples when -rcex is specified.

* tests/conflicts.at, tests/existing.at, tests/local.at: Adjust.
2020-06-16 07:30:46 +02:00
Akim Demaille d4f854e5b2 cex: also include the counterexamples in the report
The report is the best place to show the details about
counterexamples, since we have the state right under the nose.

For instance:

State 7

    1 exp: exp . "⊕" exp
    2    | exp . "+" exp
    2    | exp "+" exp .  [$end, "+", "⊕"]
    3    | exp . "+" exp
    3    | exp "+" exp .  [$end, "+", "⊕"]

    "⊕"  shift, and go to state 6

    $end      reduce using rule 2 (exp)
    $end      [reduce using rule 3 (exp)]
    "+"       reduce using rule 2 (exp)
    "+"       [reduce using rule 3 (exp)]
    "⊕"       [reduce using rule 2 (exp)]
    "⊕"       [reduce using rule 3 (exp)]
    $default  reduce using rule 2 (exp)

    Conflict between rule 2 and token "+" resolved as reduce (%left "+").

    Shift/reduce conflict on token "⊕":
        2 exp: exp "+" exp .
        1 exp: exp . "⊕" exp
      Example                  exp "+" exp • "⊕" exp
      First derivation         exp ::=[ exp ::=[ exp "+" exp • ] "⊕" exp ]
      Example                  exp "+" exp • "⊕" exp
      Second derivation        exp ::=[ exp "+" exp ::=[ exp • "⊕" exp ] ]

    Reduce/reduce conflict on tokens $end, "+", "⊕":
        2 exp: exp "+" exp .
        3 exp: exp "+" exp .
      Example                  exp "+" exp •
      First derivation         exp ::=[ exp "+" exp • ]
      Example                  exp "+" exp •
      Second derivation        exp ::=[ exp "+" exp • ]

    Shift/reduce conflict on token "⊕":
        3 exp: exp "+" exp .
        1 exp: exp . "⊕" exp
      Example                  exp "+" exp • "⊕" exp
      First derivation         exp ::=[ exp ::=[ exp "+" exp • ] "⊕" exp ]
      Example                  exp "+" exp • "⊕" exp
      Second derivation        exp ::=[ exp "+" exp ::=[ exp • "⊕" exp ] ]

* src/conflicts.h, src/conflicts.c (has_conflicts): New.
* src/counterexample.h, src/counterexample.c (print_counterexample):
Add a `prefix` argument.
(counterexample_report_shift_reduce)
(counterexample_report_reduce_reduce): Show the items when there's a
prefix.
* src/state-item.h, src/state-item.c (print_state_item):
Add a `prefix` argument.
* src/derivation.h, src/derivation.c (derivation_print)
(derivation_print_leaves): Add a prefix argument.
* src/print.c (print_state): When -Wcex is enabled, show the
conflicts.
* tests/report.at: Adjust.
2020-06-16 07:30:26 +02:00
Akim Demaille 35c0fe6789 cex: indent the diagnostics to highlight the structure
Instead of

    Shift/reduce conflict on token D:
    Example              A a • D
    First derivation     s ::=[ A a a ::=[ b ::=[ c ::=[ • ] ] ] d ::=[ D ] ]
    Example              A a • D
    Second derivation    s ::=[ A a d ::=[ • D ] ]

display

    Shift/reduce conflict on token D:
      Example              A a • D
      First derivation     s ::=[ A a a ::=[ b ::=[ c ::=[ • ] ] ] d ::=[ D ] ]
      Example              A a • D
      Second derivation    s ::=[ A a d ::=[ • D ] ]

* src/counterexample.c (print_counterexample): Indent.
* tests/counterexample.at: Adjust.
2020-06-16 07:29:46 +02:00
Akim Demaille 22f62414f9 cex: don't report the items
Showing the items (with the state numbers) is really something we
should restrict to the report.

* src/counterexample.c (counterexample_report_shift_reduce)
(counterexample_report_reduce_reduce): Don't show the pointed rules,
we will do that in the report.
* tests/counterexample.at: Adjust.
2020-06-16 07:29:46 +02:00
Akim Demaille 9206b15c4e cex: make sure traces go to stderr
* src/parse-simulation.h, src/parse-simulation.c (print_parse_state):
here.
2020-06-16 07:29:46 +02:00
Akim Demaille 5edac5e15a cex: add an argument to the reporting functions to specify the stream
* src/conflicts.c (find_state_item_number, report_state_counterexamples):
Move to...
* src/counterexample.h, src/counterexample.c (find_state_item_number)
(counterexample_report_state): this.
Add support for `out` as an argument.
(counterexample_report_reduce_reduce, counterexample_report_shift_reduce):
Accept an `out` argument, and be static.
2020-06-16 07:29:46 +02:00
Akim Demaille 1c3189734c style: more uses of const
* src/print.c, src/state.h, src/state.c: here.
2020-06-16 07:29:46 +02:00
Akim Demaille c662b23735 Merge 'maint'
* upstream/maint:
  maint: post-release administrivia
  version 3.6.4
  glr.cc: don't leak glr.c/glr.cc scaffolding to the user

Some fixes were needed to adjust to recent changes in glr.cc and
glr.c.

* data/skeletons/glr.cc: Stop messing with the user's epilogue to
insert glr.cc code.  We need that code to be inserted _before_ the
user's epilogue, not after.  So define b4_glr_cc_pre_epilogue.
* data/skeletons/glr.c: Use it.
2020-06-16 07:16:00 +02:00
Akim Demaille 627fecb19e maint: post-release administrivia
* NEWS: Add header line for next release.
* .prev-version: Record previous version.
* cfg.mk (old_NEWS_hash): Auto-update.
2020-06-15 20:39:01 +02:00
Akim Demaille 2a069f22c6 version 3.6.4
* NEWS: Record release date.
2020-06-15 20:18:50 +02:00
Akim Demaille 3f4ffea6f2 glr.cc: don't leak glr.c/glr.cc scaffolding to the user
Until we have a decent reimplementation of glr.cc, we have to use
tricks to shoehorn C++ symbols to the C engine of glr.c.  Some of them
are done via #define.  Unfortunately in Bison 3.6 some of these we
done in the header file, which broke valid user code.

Reported by Egor Pugin.
https://lists.gnu.org/r/bug-bison/2020-06/msg00003.html

* data/skeletons/glr.cc: Stop playing tricks with b4_pre_epilogue.
(b4_glr_cc_setup, b4_glr_cc_cleanup): New.
Much cleaner way to instal glr.cc's scaffolding around glr.c.
* data/skeletons/glr.c: Adjust to use them.
2020-06-15 20:18:47 +02:00
Akim Demaille 251e1b137f reports: the column width differs from the byte count
From

    "number"          shift, and go to state 1
    "Ñùṃéℝô"  shift, and go to state 2

to

    "number"  shift, and go to state 1
    "Ñùṃéℝô"  shift, and go to state 2

* src/print.c: Use mbswidth, not strlen, to compute visual columns.
* tests/report.at: Adjust.
2020-06-13 17:21:51 +02:00
Akim Demaille efbcadeca7 reports: don't escape the labels
Currently we use "quotearg" to escape the strings output in Dot.  As a
result, if the user's locale is C for instance, all the non-ASCII are
escaped.  Unfortunately graphviz does not interpret this style of
escaping.

For instance:

    5 -> 2 [style=solid label="\"\303\221\303\271\341\271\203\303\251\342\204\235\303\264\""]

was displayed as a sequence of numbers.  We now output:

    5 -> 2 [style=solid label="\"Ñùṃéℝô\""]

independently of the user's locale.

* src/system.h (obstack_backslash): New.
* src/graphviz.h, src/graphviz.c (escape): Remove, use
obstack_backslash instead.
* src/print-graph.c: Likewise.
* tests/report.at: Adjust.
2020-06-13 16:58:13 +02:00
Akim Demaille e4d33cf579 regen 2020-06-13 16:58:03 +02:00
Akim Demaille 5855da4722 parser: keep string aliases as the user wrote it
Currently our scanner decodes all the escapes in the strings, and we
later reescape the strings when we emit them.

This is troublesome, as we do not respect the user input.  For
instance, when the user writes in UTF-8, we destroy her string when we
write it back.  And this shows everywhere: in the reports we show the
escaped string instead of the actual alias:

    0 $accept: . exp $end
    1 exp: . exp "\342\212\225" exp
    2    | . exp "+" exp
    3    | . exp "+" exp
    4    | . "number"
    5    | . "\303\221\303\271\341\271\203\303\251\342\204\235\303\264"

    "number"                                                    shift, and go to state 1
    "\303\221\303\271\341\271\203\303\251\342\204\235\303\264"  shift, and go to state 2

This commit preserves the user's exact spelling of the string aliases,
instead of interpreting the escapes and then reescaping.  The report
now shows:

    0 $accept: . exp $end
    1 exp: . exp "⊕" exp
    2    | . exp "+" exp
    3    | . exp "+" exp
    4    | . "number"
    5    | . "Ñùṃéℝô"

    "number"          shift, and go to state 1
    "Ñùṃéℝô"  shift, and go to state 2

Likewise, the XML (and therefore HTML) outputs are fixed.

* src/scan-gram.l (STRING, TSTRING): Do not interpret the escapes in
the resulting string.
* src/parse-gram.y (unquote, parser_init, parser_free, unquote_free)
(handle_defines, handle_language, obstack_for_unquote): New.
Use them to unquote where needed.
* tests/regression.at, tests/report.at: Update.
2020-06-13 16:56:40 +02:00
Akim Demaille 5d5e1df1dc tests: check reports with conflicts and UTF-8
This is to record the current state of the report, which escapes the
UTF-8 characters (as parse.error="verbose" does), but shouldn't (as
parse.error="detailed" does).

* tests/report.at: here.
2020-06-13 15:58:32 +02:00
Akim Demaille cef13e11f5 style: factor common bits about string scanning
* src/scan-gram.l: here.
2020-06-13 15:20:56 +02:00
Akim Demaille b7fbfd050e style: introduce & use STRING_1GROW
* src/flex-scanner.h (STRING_1GROW): New.
* src/scan-gram.l, src/scan-skel.l: Use it.
2020-06-13 15:20:56 +02:00
Akim Demaille e088b4f90f style: reduce scopes
* src/scan-gram.l (STRING_GROW_ESCAPE): Move the static_assert about
type sizes here.
2020-06-13 15:20:56 +02:00
Akim Demaille c857ed4f72 style: prefer 'FOO ()' to 'FOO' for function-like macros
* src/flex-scanner.h (STRING_GROW, STRING_FINISH, STRING_FREE):
Make them function-like macros.
Adjust dependencies.
2020-06-13 15:20:56 +02:00
Akim Demaille 1998606a90 regen 2020-06-11 19:11:33 +02:00
Akim Demaille b0bb4cde2e cex: suggest -Wcounterexamples when there are unexpected conflicts
Suggesting -Wcounterexamples when there are conflicts is probably not
what the user wants.  If she knows her conflicts and has set
%expect/%expect-rr appropriately, we shouldn't warn.

The commit also swaps the counterexamples and the report of conflicts,
into, IMHO, a more natural order: from

    Shift/reduce conflict on token B:
    1:    3 a: A .
    1:    8 y: A . B
    Example              A • B C
    First derivation     s ::=[ a ::=[ A • ] x ::=[ B C ] ]
    Example              A • B C
    Second derivation    s ::=[ y ::=[ A • B ] c ::=[ C ] ]

    input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
    input.y:4.4: warning: rule useless in parser due to conflicts [-Wother]

to

    input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
    Shift/reduce conflict on token B:
    1:    3 a: A .
    1:    8 y: A . B
    Example              A • B C
    First derivation     s ::=[ a ::=[ A • ] x ::=[ B C ] ]
    Example              A • B C
    Second derivation    s ::=[ y ::=[ A • B ] c ::=[ C ] ]

    input.y:4.4: warning: rule useless in parser due to conflicts [-Wother]

* src/conflicts.c (rule_conflicts_print): Rename as...
(report_rule_expectation_mismatches): this.
Move the handling of report_counterexamples to...
(conflicts_print): Here.
Display this warning when applicable.
2020-06-10 09:51:39 +02:00
Akim Demaille d2acc4b401 cex: rename -Wcounterexample as -Wcounterexamples, and support -Wcex
Plural vs. singular is always a problem...

But we already have conflicts-sr and conflicts-rr, so counterexamples
makes more sense than counterexample.  Besides, -Wcounterexample will
still be accepted as an unambiguous prefix of -Wcounterexamples.

Add -Wcex as a convenient alias.

While at it, use only "counterexample", never "counter example".

* src/complain.h, src/complain.c
(Wcounterexample, warning_counterexample): Rename as...
(Wcounterexamples, warning_counterexamples): these.
(argmatch_warning_docs): Rename -Wcounterexample as -Wcounterexamples.
(argmatch_warning_args): Likewise.
Add support for -Wcex.
Adjust dependencies.
2020-06-10 07:53:44 +02:00
Akim Demaille a53c6026cd api.header.include: document it, and fix its default value
While defining api.header.include worked as expected, its default
value was incorrectly defined.  As a result, by default, the generated
parsers still duplicated the content of the generated header instead
of including it.

* data/skeletons/yacc.c (api.header.include): Fix its default value.
* tests/output.at: Check it.
* doc/bison.texi (%define Summary): Document api.header.include.
While at it, move the definition of api.namespace at the proper
place.
2020-06-09 08:09:26 +02:00
Akim Demaille ae5edcc23b cex: color the counterexamples
Use colors to show the counterexamples and the derivations in color,
to highlight their structure.  Align the outputs, and add i18n
support. Reduce width by using a one-space separator instead of
two-space.

From

    Example  A  •  B  C
    First  derivation  s ::=[ a ::=[ A  • ]  x ::=[ B  C ] ]
    Second derivation  s ::=[ y ::=[ A  •  B ]  c ::=[ C ] ]

to

    Example              A • B C
    First derivation     s ::=[ a ::=[ A • ] x ::=[ B C ] ]
    Example              A • B C
    Second derivation    s ::=[ y ::=[ A • B ] c ::=[ C ] ]

with colors.

* data/bison-default.css (cex-dot, cex-0, cex-1, cex-2, cex-3, cex-4)
(cex-5, cex-6, cex-7, cex-step, cex-leaf): New.
* src/derivation.c (derivation_print_styled_impl): New.
(derivation_print, derivation_print_leaves): Use it.
* src/counterexample.c: Reformat the output.
* tests/counterexample.at: Adjust.
2020-06-07 09:18:58 +02:00
Akim Demaille 296e2f90ab cex: enforce case for tokens/nonterminals
It's unfortunate that the traditions between formal language theory
and Yacc differs, but here, tokens should be upper case, and
nonterminals should be lower case.

* tests/counterexample.at: Comply with this.
2020-06-07 09:18:58 +02:00
Akim Demaille 1ccb4be02b cex: reformat the s/r and r/r reports
In Bison we refer to "shift/reduce" conflicts, not "shift-reduce" (in
Bison 3.6.3 186 occurrences vs 15).  Enforce consistency on this.

Instead of "spending" a second line for each conflict to report the
lookaheads, put that on the same line as the type of conflict.  Also,
prefer "token" to "symbol".  Maybe we should even prefer "lookahead".
While at it, enable internationalization, with plurals where
appropriate.

As a consequence, instead of

    Shift-Reduce Conflict:
    6:    3 b: . %empty
    6:    6 d: c . A
    On Symbol: A

display

    Shift/reduce conflict on token A:
    6:    3 b: . %empty
    6:    6 d: c . A

* NEWS, doc/bison.texi, src/conflicts.c: Spell it "shift/reduce", not
"shift-reduce".
* src/counterexample.c (counterexample_report_shift_reduce)
(counterexample_report_reduce_reduce): Reformat and internationalize
output.
* tests/counterexample.at: Adjust expectations.
2020-06-07 09:18:58 +02:00
Akim Demaille 421662ec88 style: fix syntax-check issues
* src/counterexample.c, src/files.c, src/files.h, src/lssi.c,
* src/state-item.c: here.
2020-06-07 09:18:58 +02:00
Akim Demaille 39be113b1f all: show the rules in comments before the user actions
For instance, in the case of Bison's own parser:

    -  case 40:
    +  case 40:  /* grammar_declaration: "%code" "identifier" "{...}"  */
         {
           muscle_percent_code_grow ((yyvsp[-1].ID), (yylsp[-1]),
                                     translate_code_braceless ((yyvsp[0].BRACED_CODE), (yylsp[0])),
                                     (yylsp[0]));
           code_scanner_last_string_free ();
         }
         break;

* data/skeletons/c.m4: Modified.
* data/skeletons/d.m4: Modified.
* data/skeletons/java.m4: Modified.
* src/output.c (output_escaped): New.
(quoted_output): Use it, and rename as...
(output_quoted): this.
Adjust dependencies.
(rule_output): New.
(user_actions_output): Use it.
* data/skeletons/c.m4, data/skeletons/d.m4, data/skeletons/java.m4
(b4_case): Add support for $3, an optional comment.
2020-06-07 06:50:58 +02:00
Akim Demaille 2101b0e210 CI: use GCC10 on ppc too
We were still using GCC9, because GCC10 was failing.

* .travis.yml (PPC64le): Use GCC10.
While at it, use -O2 instead of -O3: it's certainly nicer for the
CPUs, and allows to test different sets of compiler flags (we use -O3
in several other configurations).
2020-06-06 07:48:40 +02:00
Akim Demaille b1327c56f7 examples: fix missing includes
* examples/c/bistromathic/parse.y: Use abort rather than assert so
that the "unused result" warning is silenced even with -DNDEBUG.
2020-06-06 07:37:20 +02:00
Akim Demaille ae03b16785 warnings: fix -Wmissing-prototypes issues
* src/counterexample.c, src/lssi.c, src/parse-simulation.c,
* src/state-item.c:
Here.
2020-06-03 08:31:08 +02:00
Akim Demaille 7e16bd2cae Merge maint into HEAD
* upstream/maint:
  maint: post-release administrivia
  version 3.6.3
  build: check -Wmissing-prototypes
  tests: show logs
  c++: fix printing of state number on streams
2020-06-03 08:12:10 +02:00
Akim Demaille 508ac09939 maint: post-release administrivia
* NEWS: Add header line for next release.
* .prev-version: Record previous version.
* cfg.mk (old_NEWS_hash): Auto-update.
2020-06-03 07:52:30 +02:00
Akim Demaille 0535d2a608 version 3.6.3
* NEWS: Record release date.
2020-06-03 07:31:43 +02:00
Akim Demaille 94f7606db6 build: check -Wstrict-aliasing
* configure.ac (warn_common): Add -Wstrict-aliasing.
2020-06-01 18:52:23 +02:00
Akim Demaille de5be4a693 doc: using asan
* README-hacking.md: here.
2020-06-01 18:52:23 +02:00
Akim Demaille 03a6b439f6 style: fix includes
* src/fixits.c: Follow our usual pattern.
* src/scan-code.l, src/scan-gram.l, src/scan-skel.l: Prefer "" to
include src/ headers.
* README-hacking.md: Document the pattern.
2020-06-01 18:52:22 +02:00
Akim Demaille 742910838e lists: fix various issues with the use of gnulib's list
First, we should avoid code such as

    gl_list_iterator_t it = gl_list_iterator (deriv->children);
    derivation *child = NULL;
    while (gl_list_iterator_next (&it, (const void **) &child, NULL))
      {
        derivation_print (child, f);

because of -Wstrict-aliasing (whose job is to catch type-punning
issues).  See https://lists.gnu.org/r/bug-bison/2020-05/msg00039.html.

Rather we need

    gl_list_iterator_t it = gl_list_iterator (deriv->children);
    const void **p = NULL;
    while (gl_list_iterator_next (&it, &p, NULL))
      {
        derivation *child = (derivation *) p;
        derivation_print (child, f);

Second, list iterators actually have destructors.  Even though they
are noop in the case of linked-lists, we should use them.

Let's address both issues with typed wrappers (such as
derivation_list_next) that take care of both issues, and besides allow
to scope the iterators within the loop:

    derivation *child;
    for (gl_list_iterator_t it = gl_list_iterator (deriv->children);
         derivation_list_next (&it, &child);
         )
      {
        derivation_print (child, f);

* src/derivation.h, src/derivation.c (derivation_list_next): New.
Use it where appropriate.
* src/counterexample.c (search_state_list_next): New.
Use it where appropriate.
* src/parse-simulation.h, src/parse-simulation.c
* src/state-item.h (state_item_list_next): New.
Use it where appropriate.
2020-06-01 18:50:35 +02:00
Akim Demaille 52ce2a008b build: check -Wmissing-prototypes
pstate_clear is lacking a prototype.
Reported by Ryan
https://lists.gnu.org/r/bug-bison/2020-05/msg00101.html

Besides, none of the C examples were compiled with the warning flags.

* configure.ac (warn_c): Add -Wmissing-prototypes.
* data/skeletons/yacc.c (pstate_clear): Make it static.
* examples/local.mk (TEST_CFLAGS): New.
* examples/c/bistromathic/local.mk, examples/c/calc/local.mk,
* examples/c/lexcalc/local.mk, examples/c/mfcalc/local.mk,
* examples/c/pushcalc/local.mk, examples/c/reccalc/local.mk,
* examples/c/rpcalc/local.mk:
Use it.

GCC's warn_unused_result is not silenced by a cast to void, so we have
to "use" scanf's result.
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=25509
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66425

Flex generated code produces too many warnings, including things such
as, with ICC:

    examples/c/lexcalc/scan.c(1088): error #1682: implicit conversion
              of a 64-bit integral type to a smaller integral type (potential portability problem)
    2259                YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
    2260                ^
    2261
    2262

I am tired of trying to fix Flex's output.  The project does not seem
maintained.  We ought to avoid it.  So, for the time being, don't try
to enable warnings with Flex.

* examples/c/bistromathic/parse.y, examples/c/reccalc/scan.l: Fix
warnings.
* doc/bison.texi: Discard scanf's return value to defeat
-Werror=unused-result.
2020-06-01 08:29:53 +02:00
Akim Demaille bb311cfbed gnulib: update 2020-05-31 12:49:08 +02:00
Akim Demaille 518dc6ca26 style: make item_index a truly different type from item_number
See previous commit.

* src/gram.h (item_index): Make it unsigned.
Fix remaiming issues.
2020-05-25 07:41:05 +02:00
Vincent ImbimboandAkim Demaille 6a1a681fd2 style: decouple different uses of item_number
item_number is used for elements of ritem as well as indices into
ritem which is fairly confusing.  Introduce item_index to represent
indices into ritem.

* src/gram.h (item_index): Introduce it for ritem indices.
* src/closure.h, src/closure.c, src/ielr.c, src/lr0.c,
* src/print-graph.c, src/state.h, src/state.h:
Replace uses of item_number with item_index where appropriate.
2020-05-25 07:14:34 +02:00
Joshua WattandAkim Demaille dd878d1851 bison: add command line option to map file prefixes
Teaches bison about a new command line option, --file-prefix-map OLD=NEW
(based on the -ffile-prefix-map option from GCC) which causes it to
replace and file path of OLD in the text of the output file with NEW,
mainly for header guards and comments. The primary use of this is to
make builds reproducible with different input paths, and in particular
the debugging information produced when the source code is compiled. For
example, a distro may know that the bison source code will be located at
"/usr/src/bison" and thus can generate bison files that are reproducible
with the following command:

    bison --output=/build/bison/parse.c -d --file-prefix-map=/build/bison/=/usr/src/bison/ parse.y

Importantly, this will change the header guards and #line directives
from:

    #ifndef YY_BUILD_BISON_PARSE_H
    #line 100 "/build/bison/parse.h"

to

    #ifndef YY_USR_SRC_BISON_PARSE_H
    #line 100 "/usr/src/bison/parse.h"

which is reproducible.

See https://lists.gnu.org/r/bison-patches/2020-05/msg00016.html
Signed-off-by: Joshua Watt <[email protected]>

* src/files.h, src/files.c (spec_mapped_header_file)
(mapped_dir_prefix, map_file_name, add_prefix_map): New.
* src/getargs.c (-M, --file-prefix-map): New option.
* src/output.c (prepare): Define b4_mapped_dir_prefix and
b4_spec_header_file.
* src/scan-skel.l (@ofile@): Output the mapped file name.
* data/skeletons/glr.c, data/skeletons/glr.cc,
* data/skeletons/lalr1.cc, data/skeletons/location.cc,
* data/skeletons/yacc.c:
Adjust.
* doc/bison.texi: Document.
* tests/input.at, tests/output.at: Check.
2020-05-24 15:17:15 +02:00
Akim Demaille 6ed813c122 tests: fix expectations
Should have been part of 1ec93ca2a2.

* tests/counterexample.at: here.
2020-05-24 15:17:14 +02:00
Akim Demaille 1ec93ca2a2 cex: clean the display of conflicted symbols
Instead of `On Symbols: {b,c,}`, display `On Symbols: b, c`.

* src/counterexample.c (counterexample_report_reduce_reduce): We don't
need braces.
Use commas as a separator, not a terminator.
* tests/counterexample.at: Adjust.
2020-05-23 18:23:07 +02:00
Akim Demaille 12f4091de4 tests: show logs
* examples/c/bistromathic/bistromathic.test, examples/test: here.
2020-05-23 18:02:44 +02:00
Akim Demaille 8ece778cb8 c++: fix printing of state number on streams
Avoid this kind of display:

    LAC: checking lookahead identifier: R4 R3 G^B S5

* data/skeletons/lalr1.cc: Convert state_t to int before printing it.
2020-05-23 18:02:24 +02:00
Akim Demaille f32ba07f94 c++: fix printing of state number on streams
Avoid this kind of display:

    LAC: checking lookahead identifier: R4 R3 G^B S5

* data/skeletons/lalr1.cc: Convert state_t to int before printing it.
2020-05-23 17:45:03 +02:00
Vincent ImbimboandAkim Demaille 50cd3f16de cex: fix pruning crash
Fixes a crash on Cim's grammar.
https://lists.gnu.org/r/bison-patches/2020-05/msg00107.html

* src/state-item.c (prune_disabled_paths): Prune forward and backwards
paths in seperate passes.
(prune_forward, prune_backward): New.
(disable_state_item): Change function argument from state_item_number
to state_item.
(state_items_report): Add disabling to graph print-out.
* src/conflicts.c (find_state_item_number,
report_state_counterexamples): Add SI_DISABLED checks.
2020-05-23 17:35:19 +02:00
Akim Demaille 37da3c4b42 regen 2020-05-23 15:41:29 +02:00
Akim Demaille 79bae4d6bb kinds: use the symbol kinds where applicable
Instead of generating switch statements with numbers, let's use the
symbol kinds.  Not only is this more readable, it also makes reading
diff easier, as a change in symbol numbers won't have such a large
effect on the implementation of symbol actions.

* data/skeletons/bison.m4 (_b4_symbol_case): Use the symbol kind
rather than its number.
2020-05-23 15:41:29 +02:00
Akim Demaille 23f7554188 kinds: also define the possibly qualified symbol kinds
* data/skeletons/bison.m4 (b4_symbol_kind): Rename as...
(b4_symbol_kind_base): this.
(b4_symbol_kind): New, for fully qualified kind name.
* data/skeletons/lalr1.cc (b4_symbol_kind): New.
Adjust to use b4_symbol_kind where appropriate.
* src/parse-gram.h, src/parse-gram.c: regen.
2020-05-23 15:41:29 +02:00
Akim Demaille 3ff248ebfe m4: simplify useless quotation
* data/skeletons/bison.m4: The result of b4_symbol is "quoted"
already, no need for m4_expand.
2020-05-23 15:40:48 +02:00
Akim Demaille 4e1a5aae96 m4: use m4_shift2 etc.
* data/skeletons/bison.m4 (m4_shift4): New.
Use them where applicable.
2020-05-23 14:59:18 +02:00
Akim Demaille 8e70880af1 tests: show logs
* examples/c/bistromathic/bistromathic.test, examples/test: here.
2020-05-23 13:47:31 +02:00
Akim Demaille 3fea8fade8 style: spell fixes
* Makefile.am (codespell): New.
* doc/bison.texi: Fixes.
Use @option for options.
* src/lssi.c, src/lssi.h, src/parse-simulation.h, src/state-item.c:
Fix spellos.
2020-05-23 11:19:27 +02:00
Akim Demaille e7aff57122 style: rename user_token_number as code
This should have been done in 3.6, but I wanted to avoid introducing
conflicts into Vincent's work on counterexamples.  It turns out it's
completely orthogonal.

* data/README.md, data/skeletons/bison.m4, data/skeletons/c++.m4,
* data/skeletons/c.m4, data/skeletons/glr.c, data/skeletons/java.m4,
* data/skeletons/lalr1.d, data/skeletons/lalr1.java,
* data/skeletons/variant.hh, data/skeletons/yacc.c, src/conflicts.c,
* src/derives.c, src/gram.c, src/gram.h, src/output.c,
* src/parse-gram.c, src/parse-gram.y, src/print-xml.c, src/print.c,
* src/reader.c, src/symtab.c, src/symtab.h, tests/input.at,
* tests/types.at:
s/user_token_number/code/g.
Plus minor changes.
2020-05-23 08:43:58 +02:00
Akim Demaille 339d11badf Merge maint into master
* upstream/maint:
  fix generated comments
  traces: provide a means to get short m4 traces
  traces: show the full m4 invocation
2020-05-22 20:35:13 +02:00
Vincent ImbimboandAkim Demaille 99260caef9 cex: replace state-item data structures
* src/state-item.h: Add trans, prods, and revs edges to state-item
struct.
(si_trans, si_revs, si_prods_lookup): Remove.
* src/state-item.c, src/lssi.c, src/parse-simulation.c,
* src/counterexample.c: Update state-item API usage accordingly.
2020-05-22 08:45:44 +02:00
Vincent ImbimboandAkim Demaille c19af5cbb4 cex: fix bad reference counting
* src/counterexample.c (si_bfs_free): Fix reference_count
decrementing.
2020-05-22 08:45:44 +02:00
Vincent ImbimboandAkim Demaille b54181ff9b cex: fix miscellaneous leaks
* src/counterexample.c (unifying_counterexample): Always free
stage3result when it exists.
* src/conflicts.c (report_state_counterexamples): free leaked bitset.
* src/state-item.c (prune_disabled_paths): free leaked queue.
2020-05-22 08:45:44 +02:00
Vincent ImbimboandAkim Demaille 86c45be582 cex: fix counterexample leak
* src/counterexample.c (free_counterexample): New.
Free counterexamples after printing.
2020-05-22 08:45:44 +02:00
Vincent ImbimboandAkim Demaille b5e0351c3e cex: fix lssi leaks
* src/lssi.c (shortest_path_from_start): Free the root of
shortest_path_from_start search.
Free eligible bitset.
2020-05-22 08:45:44 +02:00
Vincent ImbimboandAkim Demaille 150b2318ed cex: fix parse state leaks
* src/parse_simulation.c: Fix bug in parse_state_free.
Free new_root when simulate_reduction generates zero states.

* src/parse-simulation.c, src/parse-simulation.h
(parse_state_list, parse_state_list_append): New.
* src/parse-simulation.c, src/parse-simulation.h,
* src/counterexample.c: Replace all uses of lists of parse states and
appends to parse_state_lists with the new API.
2020-05-22 08:45:44 +02:00
Vincent ImbimboandAkim Demaille 35c4a8e65e cex: derivation reference counting
* src/derivation.h, src/derivation.c: Make derivation struct opaque.
Add derivation_list type for clarity.
(derivation_list_new): New.
(derivation_list_append): New.
(derivation_list_prepend): New.
(derivation_new_leaf): New constructor for derivations with no
children.
* src/counterexample.c, src/parse-simulation.c,
* src/parse-simulation.h: Replace uses of gl_list_t containing
derivations with derivation_list and its API.
Replace calls of dervation_new using null children with
derivation_new_leaf.
* src/parse-simulation.c: replace ps_chunk and its API with typed
versions si_chunk and deriv_chunk.
* src/parse-simlation.h, src/parse-simulation.c: Remove
parse_state_retain_deriv in favor of derivation reference counting.
* src/counterexample.c: Remove search_state_retain_deriv.
2020-05-22 08:45:44 +02:00
Akim Demaille fc39ccab6b cex: style changes in parse-simulation
* src/parse-simulation.c: Formatting changes.
(parse_state_list_new): New.
Use it.
2020-05-22 08:45:44 +02:00
Akim Demaille 9a33fb9317 cex: style: prefer res for returned value
* src/lssi.c, src/parse-simulation.c: here.
2020-05-22 08:45:44 +02:00
Akim Demaille 866bc6a49f cex: fix memory leaks when there are conflicts
* src/counterexample.c (production_step, reduction_step): Release
memory of temporary objects.
2020-05-22 08:45:43 +02:00
Akim Demaille e8619330e8 cex: be sure to always reclaim memory put in hashes
One call to hash_initialize did not provide a function to free memory.

* src/state-item.c (hash_pair_table_create): New.
Use it.
2020-05-22 08:45:43 +02:00
Akim Demaille 193dc86965 cex: properly reclaim hash's allocated memory
* src/state-item.c: Use hash_free where appropriate.
2020-05-22 08:45:43 +02:00
Akim Demaille 51fa2ab0a2 cex: avoid gratuitous heap allocations
There's no need to go for the heap when using gnulib's hash module.

* src/state-item.c (hash_pair_lookup, hash_pair_remove,
state_sym_lookup): Use the heap Luke.
That removes a leak from hash_pair_lookup.
(init_prods): Use hash_pair_insert instead of duplicating it.
2020-05-22 08:45:43 +02:00
Vincent ImbimboandAkim Demaille 2d8c3edbf8 cex: fix leaks
* src/state-item.c: Various functions were using heap allocated locals
and not freeing them.
2020-05-22 08:45:43 +02:00
Akim Demaille 4590071287 style: use hash_xinsert
* gnulib: Update to get hash_xinsert.
Use it where appropriate.
2020-05-22 08:45:43 +02:00
Akim Demaille ac3b6c18a5 cex: style changes in state-item
* src/state-item.h, src/state-item.c (state_item): Make the state
const.
(state_item_set): Make it clearer that it works in the state_items
global array.
2020-05-22 08:45:43 +02:00
Akim Demaille f3ef847539 cex: stylistic changes
* src/counterexample.c: Use 'res' as a variable name for returned
value, as elsewhere.
Avoid uninitialized variables, especially pointers.
Avoid assignment where possible.
2020-05-22 08:45:43 +02:00
Akim Demaille 16f2353723 cex: avoid uninitialized variables
* src/counterexample.c (item_rule_bounds): Split into...
(item_rule_start, item_rule_end): these.
Adjust dependencies.
* src/conflicts.c (find_state_item_number): New.
Use it to avoid uninitialized variables.
2020-05-22 08:45:29 +02:00
Akim Demaille da5317cc9d cex: isolate missing API from gl_list
* src/counterexample.c (list_get_end): New.
Use it.
Reduce scopes.
2020-05-22 07:52:27 +02:00
Akim Demaille e0cb91a922 cex: tests: be robust to variations in time limit reports
The CI has "failures" such as (253, "Null nonterminals"):

    @@ -21,7 +21,7 @@
     3:    3 b: . %empty
     3:    4 c: . %empty
     On Symbols: {A,}
    -time limit exceeded: 6.000000
    +time limit exceeded: 11.000000
     First  Example c  •  c  A  A  $end
     First  derivation  $accept ::=[ a ::=[ c  d ::=[ a ::=[ b ::=[ • ]  d ::=[ c  A  A ] ] ] ]  $end ]
     Second Example c  •  A  $end

* tests/counterexample.at (AT_BISON_CHECK_CEX): New.
Use it to neutralize differences in timeout values.
2020-05-22 07:52:27 +02:00
Vincent ImbimboandAkim Demaille 482b370540 cex: fix stack overflow
* src/parse-simulation.c: Replace reference counting with
parse_state_retain everywhere.
(free_parse_state): Make this function iterative instead of
recursive. Long parse_state chains were causing stack exhaustion.

* tests/counterexample.at: Fix expectations.
2020-05-22 07:52:27 +02:00
Vincent ImbimboandAkim Demaille 66283fb625 cex: fix crash from zombie result
Fixes the SEGV in test 247 (counterexample.at:195): "S/R after first
token".

* src/counterexample.c: here.
* tests/counterexample.at: Fix expectations.
2020-05-22 07:52:27 +02:00
Akim Demaille 93c849ef0d cex: fixes, and enable tests
* src/counterexample.c, src/derivation.c:
Do not output diagnostics on stdout, that's the job of stderr, and the
testsuite heavily depend on this.
Do not leave trailing spaces in the output.
* tests/counterexample.at: Use AT_KEYWORDS.
Specify the expected outputs.
* tests/local.mk: Add counterexample.at.
2020-05-22 07:52:27 +02:00
Akim Demaille 6279945003 cex: fix a crash
* src/state-item.c (init_state_items): If the rule has no reductions
at all, don't read at all in its list of reduced rules.
2020-05-22 07:52:27 +02:00
Vincent ImbimboandAkim Demaille dcb6c972a2 cex: add tests
* tests/counterexample.at: New.
2020-05-22 07:52:27 +02:00
Vincent ImbimboandAkim Demaille af0441cfd2 cex: bind counterexample generation
* src/complain.h, src/complain.c: Add support for -Wcounterexample.
* src/conflicts.c (report_counterexamples): New.
(rule_conflicts_print): Use it when -Wcounterexample is given.
* src/getargs.h, src/getargs.c: Add support for --trace=cex.
* src/main.c (main): Init and deinit counterexample generation.
2020-05-22 07:52:27 +02:00
Vincent ImbimboandAkim Demaille bbb63b1ca9 cex: introduce counterexample search
* src/counterexample.h, src/counterexample.c: New.
2020-05-22 07:52:27 +02:00
Vincent ImbimboandAkim Demaille ac54d19eba cex: introduce the parse simulator
* src/derivation.h, src/derivation.c,
* src/parse-simulation.h, src/parse-simulation.c: New.
2020-05-22 07:52:27 +02:00
Vincent ImbimboandAkim Demaille 5807dd9279 cex: add support for state-item pair graph generation
* src/lssi.h, src/lssi.c, src/state-item.h, src/state-item.c: New.
2020-05-22 07:52:27 +02:00
Akim Demaille 94bfdf3b4b cex: add gnulib dependencies
* bootstrap.conf (gnulib_modules): Add linked-list.
2020-05-22 07:52:27 +02:00
Akim Demaille f80890c4bb fix generated comments
In Bison 3.6.2, the comments with brackets lose their brackets, for
improper m4 quotation.

* data/skeletons/bison.m4 (b4_gsub): New.
* data/skeletons/c-like.m4 (_b4_comment): Use it.
* tests/m4.at: Check b4_gsub.
2020-05-21 20:14:59 +02:00
Akim Demaille 1ebc2ac55c traces: provide a means to get short m4 traces
Let --trace=m4-early dump all the logs from the start (as --trace=m4
used to do), and have --trace=m4 now start traces only when actually
working of the user's grammar.

Can make a big difference in the case of small inputs.  E.g.

    $ bison -S tests/testsuite.dir/001/input.m4 tests/testsuite.dir/001/input.y --trace=m4 |& wc
       3952   19446  251068
    $ bison -S tests/testsuite.dir/001/input.m4 tests/testsuite.dir/001/input.y --trace=m4-early |& wc
      19491  131904 1830495

* data/skeletons/traceon.m4: New.
* src/getargs.h, src/getargs.c: Introduce --trace=m4-early.
* src/output.c (output_skeleton): Adjust for --trace=m4 and --trace=m4-early.
2020-05-21 20:13:04 +02:00
Akim Demaille 94952779b6 traces: show the full m4 invocation
Unfortunately the effect of -dV is still position independent.

* src/output.c (output_skeleton): here.
2020-05-21 20:13:04 +02:00
Thomas PetazzoniandAkim Demaille ed7d5c2b5b src: make path to m4 relocatable
Commit a4ede8f85b ("package: make bison
a relocatable package") made Bison relocatable, but in fact it still
contains one absolute reference: the M4 variable, which points to the
M4 program. Let's fix that by using relocate(), see if an M4 binary is
available at the relocated location, and otherwise fallback to the
original M4 location.

See https://lists.gnu.org/r/bison-patches/2020-05/msg00078.html,
and https://lists.gnu.org/r/bison-patches/2020-05/msg00087.html.

* src/files.h, src/files.c (m4path): New.
* src/output.c: Use it.
2020-05-20 08:09:27 +02:00
Akim Demaille 1ce02e13c3 CI: fix PPC recipe 2020-05-17 11:01:19 +02:00
Akim Demaille 8ef0b12eb7 Merge branch 'maint'
* upstream/maint:
  maint: post-release administrivia
  version 3.6.2
  tests: improve update-test
  CI: add GCC 10 and Clang 10
  fix: do not emit nested comments
  todo: update
  examples: use markdown hyperlinks
  tests: don't use == to compare const char *...
  gnulib: update
2020-05-17 09:16:51 +02:00
Akim Demaille e6d83116ae c: more fixes for _Noreturn
The previous fix was insufficient.

    tests/types.at:366: $CXX $CXXFLAGS $CPPFLAGS  $LDFLAGS -o test test.cc $LIBS
    ++ ccache clang++-mp-9.0 -Qunused-arguments -ggdb -Wall -Wextra -Wcast-align -Wchar-subscripts -fparse-all-comments -Wdocumentation -Wformat -Wimplicit-fallthrough -Wnull-dereference -Wno-sign-compare -Wno-tautological-constant-out-of-range-compare -Wpointer-arith -Wshadow -Wwrite-strings -Wextra-semi -Wold-style-cast -Wundefined-func-template -Wweak-vtables -Wunreachable-code -Wundef -pedantic -Wconversion -Wdeprecated -Wsign-compare -Wsign-conversion -Wtautological-constant-out-of-range-compare -fno-color-diagnostics -Wno-keyword-macro -Werror -std=c++98 -I/Users/akim/src/gnu/bison/tests -isystem /opt/gostai/include -isystem /opt/local/include -L/opt/gostai/lib -L/opt/local/lib -o test test.cc /Users/akim/src/gnu/bison/_build/c9d/lib/libbison.a -lintl -Wl,-framework -Wl,CoreFoundation
    stderr:
    test.cc:955:1: error: _Noreturn functions are a C11-specific feature [-Werror,-Wc11-extensions]
    _Noreturn static void
    ^
    test.cc:963:1: error: _Noreturn functions are a C11-specific feature [-Werror,-Wc11-extensions]
    _Noreturn static void
    ^
    2 errors generated.

* data/skeletons/c.m4 (b4_attribute_define): Do not use _Noreturn at
all in C++, clang or not.
2020-05-17 09:16:41 +02:00
Akim Demaille 4d9fa28ba8 maint: post-release administrivia
* NEWS: Add header line for next release.
* .prev-version: Record previous version.
* cfg.mk (old_NEWS_hash): Auto-update.
2020-05-17 08:55:47 +02:00
Akim Demaille a100a3c4c1 version 3.6.2
* NEWS: Record release date.
2020-05-17 08:30:46 +02:00
Akim Demaille b18ceb50f1 tests: improve update-test
* build-aux/update-test: When given a directory, use the testsuite.log
which it contains.
Do not accept empty "from"s, as substituting the empty string with
something is rarely a good idea.
2020-05-17 08:28:12 +02:00
Akim Demaille ff4d67ede8 CI: add GCC 10 and Clang 10
* .travis.yml: Here.
* tests/input.at, tests/regression.at: Beware of clang's -Wdocumentation.
2020-05-17 08:28:12 +02:00
Akim Demaille 465babb635 fix: do not emit nested comments
With input such as

    %token<fl> yVL_CLOCK "/*verilator sc_clock*/"

we generate

    yVL_CLOCK = 610,      /* "/*verilator sc_clock*/"  */

which is invalid since the comment will actually be closed on the
first "*/".  Let's turn "*/" into "*\/" to avoid this.  But GCC will
also warn about "/*" inside a comment, so let's "escape" it too.

Reported by Huang Rui.
https://github.com/akimd/bison/issues/38

* data/skeletons/c-like.m4 (_b4_comment): Escape comment delimiters in
comments.
* tests/input.at (Torturing the Scanner): Check thes cases.
* tests/m4.at: New.
2020-05-17 08:28:12 +02:00
Akim Demaille 22c3839168 c: restore definition of _Noreturn as [[noreturn]] in C++
c.m4 contains a definition of _Noreturn which is modeled after
gnulib's lib/_Noreturn.h.  The latter was recently
changed (b61bf2f0e8) to not using
[[noreturn]] at all, because the uses of _Noreturn in gnulib are
sometimes incompatible with the rules of [[noreturn]].

As a result glr.cc started to use _Noreturn in C++, which clang
refuses (all the glr.cc tests currently fail with Clang++).

* data/skeletons/c.m4 (b4_attribute_define): Restore the definition of
_Noreturn as [[noreturn]] in modern C++.
The generated code uses _Noreturn in places where [[noreturn]] is
valid.
2020-05-16 17:29:38 +02:00
Akim Demaille 4619b32dc0 examples: don't promote unchecked function calls
* etc/bench.pl.in, examples/c/bistromathic/parse.y,
* examples/c/calc/calc.y, examples/c/pushcalc/calc.y: Check scanf's
return value.
* doc/bison.texi: Likewise, but only for the second example, to avoid
cluttering the very simple case.
2020-05-16 14:39:57 +02:00
Akim Demaille ad921890c1 gnulib: update 2020-05-16 14:39:57 +02:00
Akim Demaille 6a28e6d412 todo: update 2020-05-15 07:18:15 +02:00
Akim Demaille f4495da337 examples: use markdown hyperlinks
* examples/c++/README.md, examples/c++/calc++/README.md,
* examples/c/README.md: here.
2020-05-14 07:26:55 +02:00
Akim Demaille dbaed0bbf2 tests: don't use == to compare const char *...
Reported by Dagobert Michelsen.
https://lists.gnu.org/r/bug-bison/2020-05/msg00091.html

* tests/c++.at: here.
2020-05-14 07:26:34 +02:00
Akim Demaille 78c7fb6460 gnulib: update 2020-05-14 07:25:09 +02:00
Akim Demaille 14ce500508 tests: improve update-test
* build-aux/update-test: When given a directory, use the testsuite.log
which it contains.
Do not accept empty "from"s, as substituting the empty string with
something is rarely a good idea.
2020-05-13 19:48:03 +02:00
Akim Demaille acba58ac59 Merge branch maint
* maint:
  news: update
  maint: post-release administrivia
  version 3.6.1
  c++: style: reorder generated code
  c++: provide yy::parser::symbol_type::name
  c++: make parser::symbol_name public
  examples: beware of ~/.inputrc
  build: also provide lzip compressed tarballs
  style: minor fixes
  yacc.c: restore ansi-c compatibility
2020-05-10 17:33:12 +02:00
Akim Demaille da29809969 news: update 2020-05-10 17:32:28 +02:00
Akim Demaille 87e4895189 maint: post-release administrivia
* NEWS: Add header line for next release.
* .prev-version: Record previous version.
* cfg.mk (old_NEWS_hash): Auto-update.
2020-05-10 14:47:51 +02:00
Akim Demaille 9c21da3363 bench: add support to randomize the order of execution
It's amazing how much the order matters.  To a point that many of
these benches are meaningless.  For instance (some of the benches
where run with `make -C benches/latest rand
BENCHFLAGS=--benchmark_min_time=3`):

    compiler: g++ -std=c++11 -O2
      0. %define nofinal
      1.
    --------------------------------------------------
    Benchmark           Time           CPU Iterations
    --------------------------------------------------
    BM_y0            1543 ns       1541 ns     441660
    BM_y1            1521 ns       1520 ns     456535
    --------------------------------------------------
    BM_y0            1531 ns       1530 ns     440584
    BM_y1            1512 ns       1511 ns     457591
    --------------------------------------------------
    BM_y0            1539 ns       1538 ns    2749330
    BM_y1            1516 ns       1515 ns    2771500
    --------------------------------------------------
    BM_y0            1571 ns       1570 ns    2600782
    BM_y1            1542 ns       1541 ns    2708349
    --------------------------------------------------
    BM_y0            1530 ns       1529 ns    2670363
    BM_y1            1519 ns       1518 ns    2764096

    --------------------------------------------------
    Benchmark           Time           CPU Iterations
    --------------------------------------------------
    BM_y1            1529 ns       1528 ns     451937
    BM_y0            1508 ns       1507 ns     453944
    --------------------------------------------------
    BM_y1            1525 ns       1524 ns    2750684
    BM_y0            1516 ns       1515 ns    2794034
    --------------------------------------------------
    BM_y1            1526 ns       1525 ns    2749620
    BM_y0            1515 ns       1514 ns    2808112
    --------------------------------------------------
    BM_y1            1524 ns       1523 ns    4475844
    BM_y0            1502 ns       1501 ns    4611665

* etc/bench.pl.in: here.
2020-05-10 11:51:46 +02:00
Akim Demaille febf6115a0 bench: use a Makefile
This makes it much easier to toy with the benchs.

* etc/bench.pl.in: Generate a Makefile instead of directly compiling
the files.
2020-05-10 11:51:41 +02:00
Akim Demaille 11b5bac7bf examples: use markdown hyperlinks
* examples/c++/README.md, examples/c++/calc++/README.md,
* examples/c/README.md: here.
2020-05-10 11:51:17 +02:00
Akim Demaille b61bf2f0e8 don't use stdnoreturn
Reported by Paul Eggert.

* src/getargs.c: We don't need it anyway, since we use _Noreturn.
* data/skeletons/c.m4: While at it, update the definition of _Noreturn
stolen from gnulib.
2020-05-10 10:46:03 +02:00
Akim Demaille 19f45df02b bench: use *.cc for C++
Using *.c is simpler, but triggers annoying warnings with Clang++.

* etc/bench.pl.in: Please the dictator.
2020-05-09 16:43:59 +02:00
Akim Demaille 2ab4058de0 style: minor fixes
* examples/c/README.md: here.
2020-05-09 16:43:59 +02:00
Akim Demaille f2277c3fec gnulib: update 2020-05-09 15:40:38 +02:00
Akim Demaille fb49a10e2c gnulib: update, and use the attribute module
* gnulib: Update.
* bootstrap.conf: Use attribute.
* src/system.h: Remove macros for attributes.
Adjust dependencies.
* src/scan-gram.l (DEPRECATED): Rename as...
(DEPRECATED_DIRECTIVE): this, to avoid the clash with the DEPRECATED macro.
2020-05-08 18:29:30 +02:00
Akim Demaille f049a57eec build: also provide lzip compressed tarballs
Suggested by Matias Fonzo <[email protected]>.

* cfg.mk: Post announcements to bison-announce.
* configure.ac: Build lzip packages.
* .travis.yml: Build only xz, we don't care about the other formats
here.
2020-05-08 18:29:21 +02:00
158 changed files with 11677 additions and 2514 deletions
+1 -1
View File
@@ -1 +1 @@
3.6
3.6.93
+68 -46
View File
@@ -29,12 +29,13 @@ jobs:
clone: true
dist: bionic
script:
- sudo apt-get install -qq autoconf automake autopoint flex gettext graphviz help2man m4 texinfo
- sudo apt-get install -qq autoconf automake autopoint flex gettext gperf graphviz help2man m4 texinfo
- autoconf --version
- automake --version
- autopoint --version
- dot -V
- gettext --version
- gperf --version
- help2man --version
- makeinfo --version
- m4 --version
@@ -69,53 +70,53 @@ jobs:
# Start with three completely different environments, to get errors asap.
- name: "GCC 9 -O3"
- name: "GCC 10 -O3"
stage: check
os: linux
dist: bionic
addons: &gcc9
addons: &gcc10
apt:
sources:
# See https://github.com/travis-ci/apt-source-safelist/issues/410.
- sourceline: 'ppa:ubuntu-toolchain-r/test'
packages: g++-9
packages: g++-10
env:
- CC=gcc-9
- CXX=g++-9
- CC=gcc-10
- CXX=g++-10
- CONFIGUREFLAGS='CPPFLAGS=-DNDEBUG CFLAGS=-O3 CXXFLAGS=-O3'
# ASAN is time consuming, and we timeout the 50min granted by
# Travis if we run all the tests in one go. Run in two parts.
- name: "Clang 9 libc++ and ASAN part 1"
- name: "Clang 10 libc++ and ASAN part 1"
stage: check
os: linux
dist: bionic
addons: &clang9
addons: &clang10
apt:
sources:
# See https://github.com/travis-ci/apt-source-safelist/issues/410.
- sourceline: 'ppa:ubuntu-toolchain-r/test'
- sourceline: 'deb http://apt.llvm.org/bionic/ llvm-toolchain-bionic-9 main'
- sourceline: 'deb http://apt.llvm.org/bionic/ llvm-toolchain-bionic-10 main'
key_url: 'https://apt.llvm.org/llvm-snapshot.gpg.key'
packages:
- clang-9
- libc++-9-dev
- libc++abi-9-dev
- clang-10
- libc++-10-dev
- libc++abi-10-dev
env:
# Do not use ASAN with ubuntu's libc++: https://bugs.llvm.org/show_bug.cgi?id=17379
- CC='clang-9 -fsanitize=address'
- CXX='clang++-9 -fsanitize=address -stdlib=libc++'
- CC='clang-10 -fsanitize=address'
- CXX='clang++-10 -fsanitize=address -stdlib=libc++'
- PART=1
- name: "Clang 9 libc++ and ASAN part 2"
- name: "Clang 10 libc++ and ASAN part 2"
stage: check
os: linux
dist: bionic
addons: *clang9
addons: *clang10
env:
# Do not use ASAN with ubuntu's libc++: https://bugs.llvm.org/show_bug.cgi?id=17379
- CC='clang-9 -fsanitize=address'
- CXX='clang++-9 -fsanitize=address -stdlib=libc++'
- CC='clang-10 -fsanitize=address'
- CXX='clang++-10 -fsanitize=address -stdlib=libc++'
- PART=2
- name: "ICC"
@@ -135,62 +136,64 @@ jobs:
packages:
- intel-oneapi-icc
## ------- ##
## First. ##
## ------- ##
# Start with three completely different environments, to get
# errors asap.
- name: "ARM64: GCC 9 -O3 part 1"
- name: "ARM64: GCC 10 -O2 part 1"
stage: check
os: linux
arch: arm64
dist: bionic
addons: *gcc9
addons: *gcc10
env:
- CC=gcc-9
- CXX=g++-9
- CONFIGUREFLAGS='CPPFLAGS=-DNDEBUG CFLAGS=-O3 CXXFLAGS=-O3'
- CC=gcc-10
- CXX=g++-10
- CONFIGUREFLAGS='CPPFLAGS=-DNDEBUG CFLAGS=-O2 CXXFLAGS=-O2'
- PART=1
- name: "PPC64le: GCC 9 part 1"
- name: "PPC64le: GCC 10 -O2 part 1"
stage: check
os: linux
arch: ppc64le
dist: bionic
addons: *gcc9
addons:
apt:
sources:
# See https://github.com/travis-ci/apt-source-safelist/issues/410.
- sourceline: 'ppa:ubuntu-toolchain-r/test'
packages: g++-10
env:
- CC=gcc-9
- CXX=g++-9
- CONFIGUREFLAGS='CFLAGS=-O3 CXXFLAGS=-O3'
- CC=gcc-10
- CXX=g++-10
- CONFIGUREFLAGS='CFLAGS=-O2 CXXFLAGS=-O2'
- PART=1
- name: "s390x: GCC 9 part 1"
- name: "s390x: GCC 10 -O2 part 1"
stage: check
os: linux
arch: s390x
dist: bionic
addons: *gcc9
addons: *gcc10
env:
- CC=gcc-9
- CXX=g++-9
- CONFIGUREFLAGS='CFLAGS=-O3 CXXFLAGS=-O3'
- CC=gcc-10
- CXX=g++-10
- CONFIGUREFLAGS='CFLAGS=-O2 CXXFLAGS=-O2'
- PART=1
## ----- ##
## GCC. ##
## ----- ##
- name: "GCC 8 with sanitizers part 1"
- name: "GCC 9 with sanitizers part 1"
stage: check
os: linux
dist: bionic
addons:
apt:
packages: g++-8
sources:
# See https://github.com/travis-ci/apt-source-safelist/issues/410.
- sourceline: 'ppa:ubuntu-toolchain-r/test'
packages: g++-9
env:
- CC='gcc-8 -fsanitize=undefined,address -fno-omit-frame-pointer'
- CXX='g++-8 -fsanitize=undefined,address -fno-omit-frame-pointer'
- CC='gcc-9 -fsanitize=undefined,address -fno-omit-frame-pointer'
- CXX='g++-9 -fsanitize=undefined,address -fno-omit-frame-pointer'
- CONFIGUREFLAGS='CFLAGS=-O1 CXXFLAGS=-O1'
- PART=1
@@ -292,7 +295,27 @@ jobs:
## Clang. ##
## ------- ##
- name: "Clang 8 -O3"
- name: "Clang 9 -O3"
stage: check
os: linux
dist: bionic
addons:
apt:
sources:
# See https://github.com/travis-ci/apt-source-safelist/issues/410.
- sourceline: 'ppa:ubuntu-toolchain-r/test'
- sourceline: 'deb http://apt.llvm.org/bionic/ llvm-toolchain-bionic-9 main'
key_url: 'https://apt.llvm.org/llvm-snapshot.gpg.key'
packages:
- clang-9
- libc++-9-dev
- libc++abi-9-dev
env:
- CC='clang-9'
- CXX='clang++-9 -stdlib=libc++'
- CONFIGUREFLAGS='CPPFLAGS=-DNDEBUG CFLAGS=-O3 CXXFLAGS=-O3'
- name: "Clang 8"
stage: check
os: linux
dist: bionic
@@ -305,7 +328,6 @@ jobs:
env:
- CC=clang-8
- CXX='clang++-8 -stdlib=libc++'
- CONFIGUREFLAGS='CPPFLAGS=-DNDEBUG CFLAGS=-O3 CXXFLAGS=-O3'
- name: "Clang 7"
stage: check
+12
View File
@@ -127,3 +127,15 @@ gen-ChangeLog:
--since=$(gen_start_date) > $$cl.tmp && \
mv -f $$cl.tmp $$cl; \
fi
# Useful to debug.
.c.i:
$(CC) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -o $@ -E $<
.PHONY: codespell
codespell:
$(AM_V_GEN) cd $(srcdir) \
&& codespell \
--regex "[\\w\\-'\`]+\+*" \
--ignore-words-list "ba,circularly,cloneable,copyable,define'd,dout,froms,iff,ifset,od,ois" \
$$(git ls-files data doc lib src tests)
+385 -57
View File
@@ -1,9 +1,281 @@
GNU Bison NEWS
* Noteworthy changes in release 3.7 (2020-07-23) [stable]
** Deprecated features
The YYPRINT macro, which works only with yacc.c and only for tokens, was
obsoleted long ago by %printer, introduced in Bison 1.50 (November 2002).
It is deprecated and its support will be removed eventually.
In conformance with the recommendations of the Graphviz team, in the next
version Bison the option `--graph` will generate a *.gv file by default,
instead of *.dot. A transition started in Bison 3.4.
** New features
*** Counterexample Generation
Contributed by Vincent Imbimbo.
When given `-Wcounterexamples`/`-Wcex`, bison will now output
counterexamples for conflicts.
**** 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
↳ "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 •
When text styling is enabled, colors are used in the examples and the
derivations to highlight the structure of both analyses. In this case,
"if" exp "then" [ "if" exp "then" exp • ] "else" exp
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.
**** 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
Contributed by Joshua Watt.
Bison learned a new argument, `--file-prefix-map OLD=NEW`. Any file path
in the output (specifically `#line` directives and `#ifdef` header guards)
that begins with the prefix OLD will have it replaced with the prefix NEW,
similar to the `-ffile-prefix-map` in GCC. This option can be used to
make bison output reproducible.
** 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`),
bison will now also look for a relocated m4.
*** C++ file names
The `filename_type` %define variable was renamed `api.filename.type`.
Instead of
%define filename_type "symbol"
write
%define api.filename.type {symbol}
(Or let `bison --update` do it for you).
It now defaults to `const std::string` instead of `std::string`.
*** Deprecated %define variable names
The following variables have been renamed for consistency. Backward
compatibility is ensured, but upgrading is recommended.
filename_type -> api.filename.type
package -> api.package
*** Push parsers no longer clear their state when parsing is finished
Previously push-parsers cleared their state when parsing was finished (on
success and on failure). This made it impossible to check if there were
parse errors, since `yynerrs` was also reset. This can be especially
troublesome when used in autocompletion, since a parser with error
recovery would suggest (irrelevant) expected tokens even if there were
failure.
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)
Historically, when --defines was used, bison generated a header and pasted
an exact copy of it into the generated parser implementation file. Since
Bison 3.4 it is possible to specify that the header should be `#include`d,
and how. For instance
%define api.header.include {"parse.h"}
or
%define api.header.include {<parser/parse.h>}
Now api.header.include defaults to `"header-basename"`, as was intended in
Bison 3.4, where `header-basename` is the basename of the generated
header. This is disabled when the generated header is `y.tab.h`, to
comply with Automake's ylwrap.
*** String aliases are faithfully propagated
Bison used to interpret user strings (i.e., decoding backslash escapes)
when reading them, and to escape them (i.e., issue non-printable
characters as backslash escapes, taking the locale into account) when
outputting them. As a consequence non-ASCII strings (say in UTF-8) ended
up "ciphered" as sequences of backslash escapes. This happened not only
in the generated sources (where the compiler will reinterpret them), but
also in all the generated reports (text, xml, html, dot, etc.). Reports
were therefore not readable when string aliases were not pure ASCII.
Worse yet: the output depended on the user's locale.
Now Bison faithfully treats the string aliases exactly the way the user
spelled them. This fixes all the aforementioned problems. However, now,
string aliases semantically equivalent but syntactically different (e.g.,
"A", "\x41", "\101") are considered to be different.
*** Crash when generating IELR
An old, well hidden, bug in the generation of IELR parsers was fixed.
* Noteworthy changes in release 3.6.4 (2020-06-15) [stable]
** Bug fixes
In glr.cc some internal macros leaked in the user's code, and could damage
access to the token kinds.
* Noteworthy changes in release 3.6.3 (2020-06-03) [stable]
** Bug fixes
Incorrect comments in the generated parsers.
Warnings in push parsers (yacc.c).
Incorrect display of gotos in LAC traces (lalr1.cc).
* Noteworthy changes in release 3.6.2 (2020-05-17) [stable]
** Bug fixes
Some tests were fixed.
When token aliases contain comment delimiters:
%token FOO "/* foo */"
bison used to emit "nested" comments, which is invalid C.
* Noteworthy changes in release 3.6.1 (2020-05-10) [stable]
** Bug fixes
Restored ANSI-C compliance in yacc.c.
GNU readline portability issues.
In C++, yy::parser::symbol_name is now a public member, as was intended.
@@ -12,6 +284,7 @@ GNU Bison NEWS
In C++, yy::parser::symbol_type now has a public name() member function.
* Noteworthy changes in release 3.6 (2020-05-08) [stable]
** Backward incompatible changes
@@ -234,6 +507,7 @@ GNU Bison NEWS
autocompletion on the existing variables, rather than of the word
"variable".
* Noteworthy changes in release 3.5.4 (2020-04-05) [stable]
** WARNING: Future backward-incompatibilities!
@@ -254,6 +528,7 @@ GNU Bison NEWS
Fix api.token.raw support in Java.
* Noteworthy changes in release 3.5.3 (2020-03-08) [stable]
** Bug fixes
@@ -264,6 +539,7 @@ GNU Bison NEWS
Several unlikely crashes found by fuzzing have been fixed.
* Noteworthy changes in release 3.5.2 (2020-02-13) [stable]
** Bug fixes
@@ -273,6 +549,7 @@ GNU Bison NEWS
The lalr1.cc skeleton properly rejects unsupported values for parse.lac
(as yacc.c does).
* Noteworthy changes in release 3.5.1 (2020-01-19) [stable]
** Bug fixes
@@ -281,6 +558,7 @@ GNU Bison NEWS
Fix compiler warnings.
* Noteworthy changes in release 3.5 (2019-12-11) [stable]
** Backward incompatible changes
@@ -488,6 +766,7 @@ GNU Bison NEWS
In Java, %define api.prefix was ignored. It now behaves as expected.
* Noteworthy changes in release 3.4.2 (2019-09-12) [stable]
** Bug fixes
@@ -505,12 +784,14 @@ GNU Bison NEWS
When lone carriage-return characters appeared in the input file,
diagnostics could hang forever.
* Noteworthy changes in release 3.4.1 (2019-05-22) [stable]
** Bug fixes
Portability fixes.
* Noteworthy changes in release 3.4 (2019-05-19) [stable]
** Deprecated features
@@ -651,6 +932,7 @@ GNU Bison NEWS
system, in December 1987. See the NEWS of Bison 3.3 for the previous
oldest bug.
* Noteworthy changes in release 3.3.2 (2019-02-03) [stable]
** Bug fixes
@@ -658,6 +940,7 @@ GNU Bison NEWS
Bison 3.3 failed to generate parsers for grammars with unused nonterminal
symbols.
* Noteworthy changes in release 3.3.1 (2019-01-27) [stable]
** Changes
@@ -665,6 +948,7 @@ GNU Bison NEWS
The option -y/--yacc used to imply -Werror=yacc, which turns uses of Bison
extensions into errors. It now makes them simple warnings (-Wyacc).
* Noteworthy changes in release 3.3 (2019-01-26) [stable]
A new mailing list was created, Bison Announce. It is low traffic, and is
@@ -807,11 +1091,11 @@ GNU Bison NEWS
...
Looking at the output from -v, one can see that the shift-reduce conflict
Looking at the output from -v, one can see that the shift/reduce conflict
here is due to the fact that the parser does not know whether to reduce
arguments to argument_list until it sees the token _after_ the following
','. By marking the rule with %expect 1 (because there is a conflict in
one state), we document the source of the 1 overall shift-reduce conflict.
one state), we document the source of the 1 overall shift/reduce conflict.
In GLR parsers, we can use %expect-rr in a rule for reduce/reduce
conflicts. In this case, we mark each of the conflicting rules. For
@@ -926,7 +1210,7 @@ GNU Bison NEWS
** Bug fixes
*** Incorrect number of reduce-reduce conflicts
*** Incorrect number of reduce/reduce conflicts
On a grammar such as
@@ -980,6 +1264,7 @@ GNU Bison NEWS
literal such as "number". The post-fix quantifiers are ? (zero or
one), * (zero or more) and + (one or more).
* Noteworthy changes in release 3.2.4 (2018-12-24) [stable]
** Bug fixes
@@ -988,6 +1273,7 @@ GNU Bison NEWS
Always provide a copy constructor for symbol_type, even in modern C++.
* Noteworthy changes in release 3.2.3 (2018-12-18) [stable]
** Bug fixes
@@ -995,12 +1281,14 @@ GNU Bison NEWS
Properly support token constructors in C++ with types that include commas
(e.g., std::pair<int, int>). A regression introduced in Bison 3.2.
* Noteworthy changes in release 3.2.2 (2018-11-21) [stable]
** Bug fixes
C++ portability issues.
* Noteworthy changes in release 3.2.1 (2018-11-09) [stable]
** Bug fixes
@@ -1008,6 +1296,7 @@ GNU Bison NEWS
Several portability issues have been fixed in the build system, in the
test suite, and in the generated parsers in C++.
* Noteworthy changes in release 3.2 (2018-10-29) [stable]
** Backward incompatible changes
@@ -1174,6 +1463,7 @@ GNU Bison NEWS
Portability/warning issues with Flex.
* Noteworthy changes in release 3.1 (2018-08-27) [stable]
** Backward incompatible changes
@@ -1314,6 +1604,7 @@ GNU Bison NEWS
Useless code was removed from C++ parsers, and some of the generated
constructors are more 'natural'.
* Noteworthy changes in release 3.0.5 (2018-05-27) [stable]
** Bug fixes
@@ -1344,6 +1635,7 @@ GNU Bison NEWS
On some platforms, some Java and/or C++ tests were failing.
* Noteworthy changes in release 3.0.4 (2015-01-23) [stable]
** Bug fixes
@@ -1356,6 +1648,7 @@ GNU Bison NEWS
Several portability issues in tests were fixed.
* Noteworthy changes in release 3.0.3 (2015-01-15) [stable]
** Bug fixes
@@ -1412,6 +1705,7 @@ GNU Bison NEWS
- calc++
a calculator in C++ using variant support and token constructors.
* Noteworthy changes in release 3.0.2 (2013-12-05) [stable]
** Bug fixes
@@ -1436,6 +1730,7 @@ GNU Bison NEWS
When C++ variant support is enabled, an error triggered via YYERROR, but
not caught via error recovery, resulted in a double deletion.
* Noteworthy changes in release 3.0.1 (2013-11-12) [stable]
** Bug fixes
@@ -1467,6 +1762,7 @@ GNU Bison NEWS
Bugs and portability issues.
* Noteworthy changes in release 3.0 (2013-07-25) [stable]
** WARNING: Future backward-incompatibilities!
@@ -1837,7 +2133,7 @@ GNU Bison NEWS
%error-verbose directive is deprecated in favor of "%define parse.error
verbose".
** Renamed %define variables
** Deprecated %define variable names
The following variables have been renamed for consistency. Backward
compatibility is ensured, but upgrading is recommended.
@@ -2063,6 +2359,7 @@ GNU Bison NEWS
There are operator- and operator-= for 'location'. Negative line/column
increments can no longer underflow the resulting value.
* Noteworthy changes in release 2.7.1 (2013-04-15) [stable]
** Bug fixes
@@ -2073,6 +2370,7 @@ GNU Bison NEWS
*** Fix some compiler warnings (lalr1.cc)
* Noteworthy changes in release 2.7 (2012-12-12) [stable]
** Bug fixes
@@ -2197,6 +2495,7 @@ GNU Bison NEWS
The translation of midrule actions is now described.
* Noteworthy changes in release 2.6.5 (2012-11-07) [stable]
We consider compiler warnings about Bison generated parsers to be bugs.
@@ -2216,10 +2515,12 @@ GNU Bison NEWS
When possible, yylloc is correctly initialized before calling yylex. It
is no longer necessary to initialize it in the %initial-action.
* Noteworthy changes in release 2.6.4 (2012-10-23) [stable]
Bison 2.6.3's --version was incorrect. This release fixes this issue.
* Noteworthy changes in release 2.6.3 (2012-10-22) [stable]
** Bug fixes
@@ -2264,6 +2565,7 @@ GNU Bison NEWS
"function declared 'noreturn' should not return") have also been
addressed.
* Noteworthy changes in release 2.6.2 (2012-08-03) [stable]
** Bug fixes
@@ -2280,6 +2582,7 @@ GNU Bison NEWS
The generated files no longer end (nor start) with empty lines.
* Noteworthy changes in release 2.6.1 (2012-07-30) [stable]
Bison no longer executes user-specified M4 code when processing a grammar.
@@ -2318,6 +2621,7 @@ GNU Bison NEWS
will display two values for each typed and untyped symbol (provided
that YYSTYPE has both "ival" and "fval" fields).
* Noteworthy changes in release 2.6 (2012-07-19) [stable]
** Future changes
@@ -2451,6 +2755,7 @@ GNU Bison NEWS
#endif /* !BAR_FOO_H */ #endif /* !BAR_FOO_H */
* Noteworthy changes in release 2.5.1 (2012-06-05) [stable]
** Future changes:
@@ -2548,6 +2853,7 @@ GNU Bison NEWS
Running "make install-pdf" (or -dvi, -html, -info, and -ps) no longer
halts in the middle of its course.
* Noteworthy changes in release 2.5 (2011-05-14)
** Grammar symbol names can now contain non-initial dashes:
@@ -2903,6 +3209,7 @@ GNU Bison NEWS
This bug has been fixed.
* Noteworthy changes in release 2.4.3 (2010-08-05)
** Bison now obeys -Werror and --warnings=error for warnings about
@@ -2923,6 +3230,7 @@ GNU Bison NEWS
** Minor documentation fixes.
* Noteworthy changes in release 2.4.2 (2010-03-20)
** Some portability problems that resulted in failures and livelocks
@@ -3017,6 +3325,7 @@ GNU Bison NEWS
message translations were not installed although supported by the
host system.
* Noteworthy changes in release 2.4.1 (2008-12-11)
** In the GLR defines file, unexpanded M4 macros in the yylval and yylloc
@@ -3042,6 +3351,7 @@ GNU Bison NEWS
** A few minor improvements to the Bison manual.
* Noteworthy changes in release 2.4 (2008-11-02)
** %language is an experimental feature.
@@ -3057,6 +3367,7 @@ GNU Bison NEWS
** Several bugs in the C++ skeleton and the experimental Java skeleton have been
fixed.
* Noteworthy changes in release 2.3b (2008-05-27)
** The quotes around NAME that used to be required in the following directive
@@ -3243,6 +3554,7 @@ GNU Bison NEWS
** The nonfunctional --no-parser, -n, and %no-parser options have been
completely removed from Bison.
* Noteworthy changes in release 2.3a (2006-09-13)
** Instead of %union, you can define and use your own union type
@@ -3357,6 +3669,7 @@ GNU Bison NEWS
The old spelling still works, but is not documented and may be removed
in a future release.
* Noteworthy changes in release 2.3 (2006-06-05)
** GLR grammars should now use "YYRECOVERING ()" instead of "YYRECOVERING",
@@ -3365,6 +3678,7 @@ GNU Bison NEWS
** It is now documented that any definition of YYSTYPE or YYLTYPE should
be to a type name that does not contain parentheses or brackets.
* Noteworthy changes in release 2.2 (2006-05-19)
** The distribution terms for all Bison-generated parsers now permit
@@ -3447,6 +3761,7 @@ GNU Bison NEWS
** DJGPP support added.
* Noteworthy changes in release 2.1 (2005-09-16)
** The C++ lalr1.cc skeleton supports %lex-param.
@@ -3473,6 +3788,7 @@ GNU Bison NEWS
print 'syntax error, unexpected number' instead of 'syntax error,
unexpected "number"'.
* Noteworthy changes in release 2.0 (2004-12-25)
** Possibly-incompatible changes
@@ -3536,6 +3852,7 @@ GNU Bison NEWS
- Semicolons are now allowed before "|" in grammar rules, as POSIX requires.
* Noteworthy changes in release 1.875 (2003-01-01)
** The documentation license has been upgraded to version 1.2
@@ -3656,6 +3973,7 @@ GNU Bison NEWS
ago, but nobody noticed until we recently asked someone to try
building Bison with a K&R C compiler.
* Noteworthy changes in release 1.75 (2002-10-14)
** Bison should now work on 64-bit hosts.
@@ -3687,6 +4005,7 @@ GNU Bison NEWS
was incorrectly rejected: $1 is defined in the second midrule
action, and is equal to the $$ of the first midrule action.
* Noteworthy changes in release 1.50 (2002-10-04)
** GLR parsing
@@ -3831,6 +4150,7 @@ GNU Bison NEWS
** GNU M4 is now required when using Bison.
* Noteworthy changes in release 1.35 (2002-03-25)
** C Skeleton
@@ -3846,6 +4166,7 @@ GNU Bison NEWS
This kludge also addresses some C++ problems when the stack was
extended.
* Noteworthy changes in release 1.34 (2002-03-12)
** File name clashes are detected
@@ -3866,6 +4187,7 @@ GNU Bison NEWS
** Fix test suite portability problems.
* Noteworthy changes in release 1.33 (2002-02-07)
** Fix C++ issues
@@ -3875,6 +4197,7 @@ GNU Bison NEWS
** Catch invalid @n
As is done with $n.
* Noteworthy changes in release 1.32 (2002-01-23)
** Fix Yacc output file names
@@ -3883,6 +4206,7 @@ GNU Bison NEWS
** Italian, Dutch translations
* Noteworthy changes in release 1.31 (2002-01-14)
** Many Bug Fixes
@@ -3970,6 +4294,7 @@ GNU Bison NEWS
** --output
New, aliasing "--output-file".
* Noteworthy changes in release 1.30 (2001-10-26)
** "--defines" and "--graph" have now an optional argument which is the
@@ -3981,6 +4306,7 @@ GNU Bison NEWS
** Portability fixes.
* Noteworthy changes in release 1.29 (2001-09-07)
** The output file does not define const, as this caused problems when used
@@ -4016,6 +4342,7 @@ GNU Bison NEWS
** @$
Automatic location tracking.
* Noteworthy changes in release 1.28 (1999-07-06)
** Should compile better now with K&R compilers.
@@ -4026,11 +4353,13 @@ GNU Bison NEWS
** There is now a FAQ.
* Noteworthy changes in release 1.27
** The make rule which prevented bison.simple from being created on
some systems has been fixed.
* Noteworthy changes in release 1.26
** Bison now uses Automake.
@@ -4048,6 +4377,7 @@ GNU Bison NEWS
** Generated parsers should now work even on operating systems which do
not provide alloca().
* Noteworthy changes in release 1.25 (1995-10-16)
** Errors in the input grammar are not fatal; Bison keeps reading
@@ -4073,6 +4403,7 @@ the parser engine; a project can now use its own parser engine.
The actions go into a separate file called NAME.act, in the form of
a switch statement body.
* Noteworthy changes in release 1.23
The user can define YYPARSE_PARAM as the name of an argument to be
@@ -4082,72 +4413,69 @@ by casting it to the proper pointer type.
Line numbers in output file corrected.
* Noteworthy changes in release 1.22
--help option added.
* Noteworthy changes in release 1.20
Output file does not redefine const for C++.
-----
Copyright (C) 1995-2015, 2018-2020 Free Software Foundation, Inc.
This file is part of Bison, the GNU Parser Generator.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
LocalWords: yacc YYBACKUP glr GCC lalr ArrayIndexOutOfBoundsException nullptr
LocalWords: cplusplus liby rpl fprintf mfcalc Wyacc stmt cond expr mk sym lr
LocalWords: IELR ielr Lookahead YYERROR nonassoc LALR's api lookaheads yychar
LocalWords: destructor lookahead YYRHSLOC YYLLOC Rhs ifndef YYFAIL cpp sr rr
LocalWords: preprocessor initializer Wno Wnone Werror FreeBSD prec livelocks
LocalWords: Solaris AIX UX RHEL Tru LHS gcc's Wundef YYENABLE NLS YYLTYPE VCG
LocalWords: yyerror cpp's Wunused yylval yylloc prepend yyparse yylex yypush
LocalWords: Graphviz xml nonterminals midrule destructor's YYSTYPE typedef ly
LocalWords: CHR chr printf stdout namespace preprocessing enum pre include's
LocalWords: YYRECOVERING nonfree destructors YYABORT YYACCEPT params enums de
LocalWords: struct yystype DJGPP lex param Haible NUM alloca YYSTACK NUL goto
LocalWords: YYMAXDEPTH Unescaped UCNs YYLTYPE's yyltype typedefs inline Yaccs
LocalWords: Heriyanto Reenable dprec Hilfinger Eggert MYEOF Folle Menezes EOF
LocalWords: Lackovic define's itemset Groff Gettext malloc NEWS'ed YYDEBUG YY
LocalWords: namespaces strerror const autoconfiguration Dconst Autoconf's FDL
LocalWords: Automake TMPDIR LESSEQ ylwrap endif yydebug YYTOKEN YYLSP ival hh
LocalWords: extern YYTOKENTYPE TOKENTYPE yytokentype tokentype STYPE lval pdf
LocalWords: lang yyoutput dvi html ps POSIX lvalp llocp Wother nterm arg init
LocalWords: TOK calc yyo fval Wconflicts parsers yystackp yyval yynerrs
LocalWords: Théophile Ranquet Santet fno fnone stype associativity Tolmer
LocalWords: Wprecedence Rassoul Wempty Paolo Bonzini parser's Michiel loc
LocalWords: redeclaration sval fcaret reentrant XSLT xsl Wmaybe yyvsp Tedi
LocalWords: pragmas noreturn untyped Rozenman unexpanded Wojciech Polak
LocalWords: Alexandre MERCHANTABILITY yytype emplace ptr automove lvalues
LocalWords: nonterminal yy args Pragma dereference yyformat rhs docdir bw
LocalWords: Redeclarations rpcalc Autoconf YFLAGS Makefiles PROG DECL num
LocalWords: Heimbigner AST src ast Makefile srcdir MinGW xxlex XXSTYPE
LocalWords: XXLTYPE strictfp IDEs ffixit fdiagnostics parseable fixits
LocalWords: Wdeprecated yytext Variadic variadic yyrhs yyphrs RCS README
LocalWords: noexcept constexpr ispell american deprecations backend Teoh
LocalWords: YYPRINT Mangold Bonzini's Wdangling exVal baz checkable gcc
LocalWords: fsanitize Vogelsgesang lis redeclared stdint automata yytname
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
LocalWords: yacc YYBACKUP glr GCC lalr ArrayIndexOutOfBoundsException nullptr
LocalWords: cplusplus liby rpl fprintf mfcalc Wyacc stmt cond expr mk sym lr
LocalWords: IELR ielr Lookahead YYERROR nonassoc LALR's api lookaheads yychar
LocalWords: destructor lookahead YYRHSLOC YYLLOC Rhs ifndef YYFAIL cpp sr rr
LocalWords: preprocessor initializer Wno Wnone Werror FreeBSD prec livelocks
LocalWords: Solaris AIX UX RHEL Tru LHS gcc's Wundef YYENABLE NLS YYLTYPE VCG
LocalWords: yyerror cpp's Wunused yylval yylloc prepend yyparse yylex yypush
LocalWords: Graphviz xml nonterminals midrule destructor's YYSTYPE typedef ly
LocalWords: CHR chr printf stdout namespace preprocessing enum pre include's
LocalWords: YYRECOVERING nonfree destructors YYABORT YYACCEPT params enums de
LocalWords: struct yystype DJGPP lex param Haible NUM alloca YYSTACK NUL goto
LocalWords: YYMAXDEPTH Unescaped UCNs YYLTYPE's yyltype typedefs inline Yaccs
LocalWords: Heriyanto Reenable dprec Hilfinger Eggert MYEOF Folle Menezes EOF
LocalWords: Lackovic define's itemset Groff Gettext malloc NEWS'ed YYDEBUG YY
LocalWords: namespaces strerror const autoconfiguration Dconst Autoconf's FDL
LocalWords: Automake TMPDIR LESSEQ ylwrap endif yydebug YYTOKEN YYLSP ival hh
LocalWords: extern YYTOKENTYPE TOKENTYPE yytokentype tokentype STYPE lval pdf
LocalWords: lang yyoutput dvi html ps POSIX lvalp llocp Wother nterm arg init
LocalWords: TOK calc yyo fval Wconflicts parsers yystackp yyval yynerrs
LocalWords: Théophile Ranquet Santet fno fnone stype associativity Tolmer
LocalWords: Wprecedence Rassoul Wempty Paolo Bonzini parser's Michiel loc
LocalWords: redeclaration sval fcaret reentrant XSLT xsl Wmaybe yyvsp Tedi
LocalWords: pragmas noreturn untyped Rozenman unexpanded Wojciech Polak
LocalWords: Alexandre MERCHANTABILITY yytype emplace ptr automove lvalues
LocalWords: nonterminal yy args Pragma dereference yyformat rhs docdir bw
LocalWords: Redeclarations rpcalc Autoconf YFLAGS Makefiles PROG DECL num
LocalWords: Heimbigner AST src ast Makefile srcdir MinGW xxlex XXSTYPE
LocalWords: XXLTYPE strictfp IDEs ffixit fdiagnostics parseable fixits
LocalWords: Wdeprecated yytext Variadic variadic yyrhs yyphrs RCS README
LocalWords: noexcept constexpr ispell american deprecations backend Teoh
LocalWords: YYPRINT Mangold Bonzini's Wdangling exVal baz checkable gcc
LocalWords: fsanitize Vogelsgesang lis redeclared stdint automata yytname
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 Wcex Nonunifying rcex
Local Variables:
ispell-dictionary: "american"
mode: outline
fill-column: 76
End:
Copyright (C) 1995-2015, 2018-2020 Free Software Foundation, Inc.
This file is part of Bison, the GNU Parser Generator.
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3 or
any later version published by the Free Software Foundation; with no
Invariant Sections, with no Front-Cover Texts, and with no Back-Cover
Texts. A copy of the license is included in the "GNU Free
Documentation License" file as part of this distribution.
+15 -14
View File
@@ -17,17 +17,18 @@ GNU Bison's home page is https://gnu.org/software/bison/.
# Installation
## Build from git
Here are basic installation instructions for a repository checkout:
The [README-hacking.md file](README-hacking.md) is about building, modifying
and checking Bison. See its "Working from the Repository" section to build
Bison from the git repo. Roughly, run:
$ git submodule update --init
$ ./bootstrap
then proceed with the usual `configure && make` steps.
The file README-hacking.md is about building, modifying and checking Bison.
## Build from tarball
See the file INSTALL for generic compilation and installation instructions.
See the [INSTALL file](INSTALL] for generic compilation and installation
instructions.
Bison requires GNU m4 1.4.6 or later. See
https://ftp.gnu.org/gnu/m4/m4-1.4.6.tar.gz.
@@ -100,6 +101,16 @@ that the range specifies every single year in that closed interval.
<!--
LocalWords: parsers ngettext Texinfo pdf html YYYY ZZZZ ispell american md
LocalWords: MERCHANTABILITY GLR LALR IELR submodule init README src bw
LocalWords: Relocatability symlinks symlink
Local Variables:
mode: markdown
fill-column: 76
ispell-dictionary: "american"
End:
Copyright (C) 1992, 1998-1999, 2003-2005, 2008-2015, 2018-2020 Free
Software Foundation, Inc.
@@ -112,14 +123,4 @@ Invariant Sections, with no Front-Cover Texts, and with no Back-Cover
Texts. A copy of the license is included in the "GNU Free
Documentation License" file as part of this distribution.
Local Variables:
mode: markdown
fill-column: 76
ispell-dictionary: "american"
End:
LocalWords: parsers ngettext Texinfo pdf html YYYY ZZZZ ispell american md
LocalWords: MERCHANTABILITY GLR LALR IELR submodule init README src bw
LocalWords: Relocatability symlinks symlink
-->
+233 -154
View File
@@ -5,151 +5,6 @@ Everything related to the development of Bison is on Savannah:
http://savannah.gnu.org/projects/bison/.
Administrivia
=============
## If you incorporate a change from somebody on the net:
First, if it is a large change, you must make sure they have signed the
appropriate paperwork. Second, be sure to add their name and email address
to THANKS.
## If a change fixes a test, mention the test in the commit message.
## Bug reports
If somebody reports a new bug, mention his name in the commit message and in
the test case you write. Put him into THANKS.
The correct response to most actual bugs is to write a new test case which
demonstrates the bug. Then fix the bug, re-run the test suite, and check
everything in.
Hacking
=======
## Visible Changes
Which include serious bug fixes, must be mentioned in NEWS.
## Translations
Only user visible strings are to be translated: error messages, bits of the
.output file etc. This excludes impossible error messages (comparable to
assert/abort), and all the --trace output which is meant for the maintainers
only.
## Syntax highlighting
It's quite nice to be in C++ mode when editing lalr1.cc for instance.
However tools such as Emacs will be fooled by the fact that braces and
parens do not nest, as in `[[}]]`. As a consequence you might be misguided
by its visual pairing to parens. The m4-mode is safer. Unfortunately the
m4-mode is also fooled by `#` which is sees as a comment, stops pairing with
parens/brackets that are inside...
## Coding Style
Do not add horizontal tab characters to any file in Bison's repository
except where required. For example, do not use tabs to format C code.
However, make files, ChangeLog, and some regular expressions require tabs.
Also, test cases might need to contain tabs to check that Bison properly
processes tabs in its input.
Prefer "res" as the name of the local variable that will be "return"ed by
the function.
### Bison
Follow the GNU Coding Standards.
Don't reinvent the wheel: we use gnulib, which features many components.
Actually, Bison has legacy code that we should replace with gnulib modules
(e.g., many ad hoc implementations of lists).
### Skeletons
We try to use the "typical" coding style for each language.
#### CPP
We indent the CPP directives this way:
```
#if FOO
# if BAR
# define BAZ
# endif
#endif
```
Don't indent with leading spaces in the skeletons (it's ok in the grammar
files though, e.g., in `%code {...}` blocks).
On occasions, use `cppi -c` to see where we stand. We don't aim at full
correctness: depending `-d`, some bits can be in the *.c file, or the *.h
file within the double-inclusion cpp-guards. In that case, favor the case
of the *.h file, but don't waste time on this.
Don't hesitate to leave a comment on the `#endif` (e.g., `#endif /* FOO
*/`), especially for long blocks.
There is no conistency on `! defined` vs. `!defined`. The day gnulib
decides, we'll follow them.
#### C/C++
Follow the GNU Coding Standards.
The `glr.c` skeleton was implemented with `camlCase`. We are migrating it
to `snake_case`. Because we are standardizing the code, it is currently
inconsistent.
Use `YYFOO` and `yyfoo` for entities that are exposed to the user. They are
part of our contract with the users wrt backward compatibility.
Use `YY_FOO` and `yy_foo` for private matters. Users should not use them,
we are free to change them without fear of backward compatibility issues.
Use `*_t` for types, especially for `yy*_t` in which case we shouldn't worry
about the C standard introducing such a name.
#### C++
Follow the C++ Core Guidelines
(http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines). The Google
ones may be interesting too
(https://google.github.io/styleguide/cppguide.html).
Our enumerators, such as the kinds (symbol and token kinds), should be lower
case, but it was too late to follow that track for token kinds, and symbol
kind enumerators are made to be consistent with them.
Use `*_type` for type aliases. Use `foo_get()` and `foo_set(v)` for
accessors, or simply `foo()` and `foo(v)`.
Use the `yy` prefix for private stuff, but there's no need for it in the
public API. The `yy` prefix is already taken care of via the namespace.
#### Java
We follow https://www.oracle.com/technetwork/java/codeconventions-150003.pdf
and https://google.github.io/styleguide/javaguide.html. Unfortunately at
some point some GNU Coding Style was installed in Java, but it's an error.
So we should for instance stop putting spaces in function calls. Because we
are standardizing the code, it is currently inconsistent.
Use a 2-space indentation (Google) rather than 4 (Oracle).
Don't use the "yy" prefix for public members: "getExpectedTokens", not
"yyexpectedTokens" or "yygetExpectedTokens".
## Commit Messages
Imitate the style we use. Use `git log` to get sources of inspiration.
If the changes have a small impact on Bison's generated parser, embed these
changes in the commit itself. If the impact is large, first push all the
changes except those about src/parse-gram.[ch], and then another commit
named "regen" which is only about them.
## Debugging
Bison supports tracing of its various steps, via the `--trace` option.
Since it is not meant for the end user, it is not displayed by `bison
--help`, nor is it documented in the manual. Instead, run `bison
--trace=help`.
Working from the Repository
===========================
@@ -168,6 +23,7 @@ tools we depend upon, including:
- Automake <http://www.gnu.org/software/automake/>
- Flex <http://www.gnu.org/software/flex/>
- Gettext <http://www.gnu.org/software/gettext/>
- Gperf <http://www.gnu.org/software/gperf/>
- Graphviz <http://www.graphviz.org>
- Gzip <http://www.gnu.org/software/gzip/>
- Help2man <http://www.gnu.org/software/help2man/>
@@ -184,7 +40,7 @@ above packages depends on your system. The following shell command should
work for Debian-based systems such as Ubuntu:
sudo apt-get install \
autoconf automake autopoint flex graphviz help2man texinfo valgrind
autoconf automake autopoint flex gperf graphviz help2man texinfo valgrind
Bison is written using Bison grammars, so there are bootstrapping issues.
The bootstrap script attempts to discover when the C code generated from the
@@ -322,6 +178,201 @@ version, compile bison, then force it to recreate the files:
$ make -C _build
Administrivia
=============
## If you incorporate a change from somebody on the net:
First, if it is a large change, you must make sure they have signed the
appropriate paperwork. Second, be sure to add their name and email address
to THANKS.
## If a change fixes a test, mention the test in the commit message.
## Bug reports
If somebody reports a new bug, mention his name in the commit message and in
the test case you write. Put him into THANKS.
The correct response to most actual bugs is to write a new test case which
demonstrates the bug. Then fix the bug, re-run the test suite, and check
everything in.
Hacking
=======
## Visible Changes
Which include serious bug fixes, must be mentioned in NEWS.
## Translations
Only user visible strings are to be translated: error messages, bits of the
.output file etc. This excludes impossible error messages (comparable to
assert/abort), and all the --trace output which is meant for the maintainers
only.
## Vocabulary
- "lookahead", not "look-ahead".
- "midrule", not "mid-rule".
- "nonterminal", not "variable" or "non-terminal" or "non terminal".
Abbreviated as "nterm".
- "shift/reduce" and "reduce/reduce", not "shift-reduce" or "shift reduce",
etc.
## Syntax Highlighting
It's quite nice to be in C++ mode when editing lalr1.cc for instance.
However tools such as Emacs will be fooled by the fact that braces and
parens do not nest, as in `[[}]]`. As a consequence you might be misguided
by its visual pairing to parens. The m4-mode is safer. Unfortunately the
m4-mode is also fooled by `#` which is sees as a comment, stops pairing with
parens/brackets that are inside...
## Implementation Notes
There are several places with interesting details about the implementation:
- [Understanding C parsers generated by GNU
Bison](https://www.cs.uic.edu/~spopuri/cparser.html) by Satya Kiran Popuri,
is a wonderful piece of work that explains the implementation of Bison,
- [src/gram.h](src/gram.h) documents the way the grammar is represented
- [src/tables.h](src/tables.h) documents the generated tables
- [data/README.md](data/README.md) contains details about the m4 implementation
## Coding Style
Do not add horizontal tab characters to any file in Bison's repository
except where required. For example, do not use tabs to format C code.
However, make files, ChangeLog, and some regular expressions require tabs.
Also, test cases might need to contain tabs to check that Bison properly
processes tabs in its input.
Prefer `res` as the name of the local variable that will be "return"ed by
the function.
In writing arithmetic comparisons, use "<" and "<=" rather than ">" and ">="
(http://www.gelato.unsw.edu.au/archives/git/0505/4507.html).
### Bison
Follow the GNU Coding Standards.
Don't reinvent the wheel: we use gnulib, which features many components.
Actually, Bison has legacy code that we should replace with gnulib modules
(e.g., many ad hoc implementations of lists).
#### Includes
The `#include` directives follow an order:
- first section for *.c files is `<config.h>`. Don't include it in header
files
- then, for *.c files, the corresponding *.h file
- then possibly the `"system.h"` header
- then the system headers.
Consider headers from `lib/` like system headers (i.e., `#include
<verify.h>`, not `#include "verify.h"`).
- then headers from src/ with double quotes (`#include "getargs.h"`).
Keep headers sorted alphabetically in each section.
See also the [Header
files](https://www.gnu.org/software/gnulib/manual/html_node/Header-files.html)
and the [Implementation
files](https://www.gnu.org/software/gnulib/manual/html_node/Implementation-files.html#Implementation-files)
nodes of the gnulib documentation.
Some source files are in the build tree (e.g., `src/scan-gram.c` made from
`src/scan-gram.l`). For them to find the headers from `src/`, we actually
use `#include "src/getargs.h"` instead of `#include "getargs.h"`---that
saves us from additional `-I` flags.
### Skeletons
We try to use the "typical" coding style for each language.
#### CPP
We indent the CPP directives this way:
```
#if FOO
# if BAR
# define BAZ
# endif
#endif
```
Don't indent with leading spaces in the skeletons (it's OK in the grammar
files though, e.g., in `%code {...}` blocks).
On occasions, use `cppi -c` to see where we stand. We don't aim at full
correctness: depending `-d`, some bits can be in the *.c file, or the *.h
file within the double-inclusion cpp-guards. In that case, favor the case
of the *.h file, but don't waste time on this.
Don't hesitate to leave a comment on the `#endif` (e.g., `#endif /* FOO
*/`), especially for long blocks.
There is no consistency on `! defined` vs. `!defined`. The day gnulib
decides, we'll follow them.
#### C/C++
Follow the GNU Coding Standards.
The `glr.c` skeleton was implemented with `camlCase`. We are migrating it
to `snake_case`. Because we are gradually standardizing the code, it is
currently inconsistent.
Use `YYFOO` and `yyfoo` for entities that are exposed to the user. They are
part of our contract with the users wrt backward compatibility.
Use `YY_FOO` and `yy_foo` for private matters. Users should not use them,
we are free to change them without fear of backward compatibility issues.
Use `*_t` for types, especially for `yy*_t` in which case we shouldn't worry
about the C standard introducing such a name.
#### C++
Follow the [C++ Core
Guidelines](http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines).
The [Google ones](https://google.github.io/styleguide/cppguide.html) may be
interesting too.
Our enumerators, such as the kinds (symbol and token kinds), should be lower
case, but it was too late to follow that track for token kinds, and symbol
kind enumerators are made to be consistent with them.
Use `*_type` for type aliases. Use `foo_get()` and `foo_set(v)` for
accessors, or simply `foo()` and `foo(v)`.
Use the `yy` prefix for private stuff, but there's no need for it in the
public API. The `yy` prefix is already taken care of via the namespace.
#### Java
We follow the [Java Code
Conventions](https://www.oracle.com/technetwork/java/codeconventions-150003.pdf)
and [Google Java Style
Guide](https://google.github.io/styleguide/javaguide.html). Unfortunately
at some point some GNU Coding Style was installed in Java, but it's an
error. So we should for instance stop putting spaces in function calls.
Because we are standardizing the code, it is currently inconsistent.
Use a 2-space indentation (Google) rather than 4 (Oracle).
Don't use the "yy" prefix for public members: "getExpectedTokens", not
"yyexpectedTokens" or "yygetExpectedTokens".
## Commit Messages
Imitate the style we use. Use `git log` to get sources of inspiration.
If the changes have a small impact on Bison's generated parser, embed these
changes in the commit itself. If the impact is large, first push all the
changes except those about src/parse-gram.[ch], and then another commit
named "regen" which is only about them.
## Debugging
Bison supports tracing of its various steps, via the `--trace` option.
Since it is not meant for the end user, it is not displayed by `bison
--help`, nor is it documented in the manual. Instead, run `bison
--trace=help`.
## Documentation
Use `@option` for options and options with their argument if they have no
space (e.g., `@option{-Dfoo=bar}`). However, use `@samp` elsewhere (e.g.,
`@samp{-I foo}`).
Test Suite
==========
@@ -331,9 +382,9 @@ examples, and the main test suite.
### The Examples
In examples/, there is a number of ready-to-use examples (see
examples/README.md). These examples have small test suites run by `make
check`. The test results are in local `*.log` files (e.g.,
`$build/examples/c/calc/calc.log`).
[examples/README.md](examples/README.md)). These examples have small test
suites run by `make check`. The test results are in local `*.log` files
(e.g., `$build/examples/c/calc/calc.log`).
### The Main Test Suite
The main test suite, in tests/, is written on top of GNU Autotest, which is
@@ -393,7 +444,7 @@ added the `[-Wother]` part to all the warnings). Part of the update can be
done with a crude tool: `build-aux/update-test`.
Once you ran the test suite, and therefore have many `testsuite.log` files,
run, from the source tree:
run `make update-tests`. Or, by hand, from the *source* tree:
$ ./build-aux/update-test $build/tests/testsuite.dir/*/testsuite.log
@@ -409,6 +460,31 @@ Use the `javaexec.sh` script. For instance to run the parser of test case
$ sh ./_build/javaexec.sh -cp ./_build/tests/testsuite.dir/504 Calc
## Using Sanitizers
Address sanitizer (ASAN) and undefined-behavior sanitizer (UBSAN) are very
useful. Here's one way to set ASAN up with GCC 10 on Mac Ports
1. Configure with
$ ./configure -C --enable-gcc-warnings \
CPPFLAGS='-isystem /opt/local/include' \
CC='gcc-mp-10 -fsanitize=address' \
CFLAGS='-ggdb' \
CXX='g++-mp-10.0 -fsanitize=address' \
CXXFLAGS='-ggdb' \
LDFLAGS='-L/opt/local/lib'
2. Compile
3. Generate debug symbols:
$ dsymutil src/bison
4. Run the tests with leak detection enabled
(`ASAN_OPTIONS=detect_leaks=1`). E.g. for counterexamples:
$ make check-local TESTSUITEFLAGS='-j5 -k cex' ASAN_OPTIONS=detect_leaks=1
## make maintainer-check-valgrind
This target uses valgrind both to check bison, and the generated parsers.
@@ -488,7 +564,8 @@ re-run the tests, run:
Release Procedure
=================
See README-release.
See the [README-release file](README-release), created when the package is
bootstrapped.
<!--
@@ -524,8 +601,10 @@ LocalWords: symlinks vti html lt POSIX Cc'ed Graphviz Texinfo autoconf jN
LocalWords: automake autopoint graphviz texinfo PROG Wother parsers YYFOO
LocalWords: TESTSUITEFLAGS deprec struct gnulib's getopt config ggdb yyfoo
LocalWords: bitset fsanitize symlink CFLAGS MERCHANTABILITY ispell wrt YY
LocalWords: american Administrivia camlCase yy accessors namespace src
LocalWords: getExpectedTokens yyexpectedTokens yygetExpectedTokens
LocalWords: regen dogfooding Autotest testsuite
LocalWords: american Administrivia camlCase yy accessors namespace src hoc
LocalWords: getExpectedTokens yyexpectedTokens yygetExpectedTokens parens
LocalWords: regen dogfooding Autotest testsuite getargs CPP BAZ endif cppi
LocalWords: cpp javaexec cp Calc ASAN UBSAN CPPFLAGS isystem CXX cex Gperf
LocalWords: CXXFLAGS LDFLAGS dsymutil gperf
-->
+6
View File
@@ -45,6 +45,7 @@ Csaba Raduly [email protected]
Dagobert Michelsen [email protected]
Daniel Frużyński [email protected]
Daniel Galloway [email protected]
Daniela Becker [email protected]
Daniel Hagerty [email protected]
David Barto [email protected]
David J. MacKenzie [email protected]
@@ -59,6 +60,7 @@ Di-an Jan [email protected]
Dick Streefland [email protected]
Didier Godefroy [email protected]
Don Macpherson [email protected]
Dwight Guth [email protected]
Efi Fogel [email protected]
Enrico Scholz [email protected]
Eric Blake [email protected]
@@ -83,6 +85,7 @@ Guido Trentalancia [email protected]
H. Merijn Brand [email protected]
Hans Åberg [email protected]
Horst Von Brand [email protected]
Jacob L. Mandelson [email protected]
Jan Nieuwenhuizen [email protected]
Jannick [email protected]
Jeff Hammond [email protected]
@@ -111,6 +114,7 @@ Marc Autret [email protected]
Marc Mendiola [email protected]
Marc Schönefeld [email protected]
Mark Boyall [email protected]
Martin Blais [email protected]
Martin Jacobs [email protected]
Martin Mokrejs [email protected]
Martin Nylin [email protected]
@@ -162,6 +166,7 @@ Quoc Peyrot [email protected]
R Blake [email protected]
Raja R Harinath [email protected]
Ralf Wildenhues [email protected]
Ryan [email protected]
Rich Wilson [email protected]
Richard Stallman [email protected]
Rici Lake [email protected]
@@ -213,6 +218,7 @@ Wolfram Wagner [email protected]
Wwp [email protected]
xolodho [email protected]
Yuichiro Kaneko [email protected]
Yuriy Solodkyy [email protected]
Zack Weinberg [email protected]
江 祖铭 [email protected]
長田偉伸 [email protected]
+62 -54
View File
@@ -1,15 +1,41 @@
* Bison 3.7
** Cex
*** Improve gnulib
Don't do this (counterexample.c):
// This is the fastest way to get the tail node from the gl_list API.
gl_list_node_t
list_get_end (gl_list_t list)
{
gl_list_node_t sentinel = gl_list_add_last (list, NULL);
gl_list_node_t res = gl_list_previous_node (list, sentinel);
gl_list_remove_node (list, sentinel);
return res;
}
*** Ambiguous rewriting
If the user is stupid enough to have equal rules, then the derivations are
harder to read:
Reduce/reduce conflict on tokens $end, "+", "⊕":
2 exp: exp "+" exp .
3 exp: exp "+" exp .
Example exp "+" exp •
First derivation exp ::=[ exp "+" exp • ]
Example exp "+" exp •
Second derivation exp ::=[ exp "+" exp • ]
Do we care about this? In color, we use twice the same color here, but we
could try to use the same color for the same rule.
*** XML reports
Show the counterexamples. This is going to be really hard and/or painful.
Unless we play it dumb (little structure).
** Bistromathic
- Hitting tab on a line with a syntax error is ugly
- Be robust to existing ~/.inputrc
- How about not evaluating incomplete lines when the text is not finished
(as shells do).
** Doc
*** api.header.include
** Questions
*** Java
- Should i18n be part of the Lexer? Currently it's a static method of
@@ -39,23 +65,6 @@ enough.
*** calc.at
Stop hard-coding "Calc". Adjust local.at (look for FIXME).
** Counter example generation
See https://github.com/akimd/bison/pull/15.
** Clean up
Rename user_token_number for tokens as "code". It's not a "user number",
it's the token code, and the user can control it, but this code always
exists.
See also USER_NUMBER_UNDEFINED and NUMBER_UNDEFINED.
Rename endtoken as eoftoken.
Also do it in data/skeletons.
Don't rename in Bison 3.6 (it would be logical to do so) because that
would probably create many conflicts in Vincent's work (see previous point).
** 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.
@@ -66,7 +75,7 @@ generates tons of white space in the page, and may contribute to bad page
breaks.
** consistency
token vs terminal, variable vs non terminal.
token vs terminal.
** api.token.raw
The YYUNDEFTOK could be assigned a semantic value so that yyerror could be
@@ -128,7 +137,29 @@ Rici:
> At a minimum, the fact that yyclearin does not invoke the %destructor
> should be highlighted in the documentation, since it is not at all obvious.
** Issues in i18n
Les catégories d'avertissements incluent :
conflicts-sr conflits S/R (activé par défaut)
conflicts-rr conflits R/R (activé par défaut)
dangling-alias l'alias chaîne n'est pas attaché à un symbole
deprecated construction obsolète
empty-rule règle vide sans %empty
midrule-values valeurs de règle intermédiaire non définies ou inutilisées
precedence priorité et associativité inutiles
yacc incompatibilités avec POSIX Yacc
other tous les autres avertissements (activé par défaut)
all tous les avertissements sauf « dangling-alias » et « yacc »
no-CATEGORY désactiver les avertissements dans CATEGORIE
none désactiver tous les avertissements
error[=CATEGORY] traiter les avertissements comme des erreurs
Line -1 and -3 should mention CATEGORIE, not CATEGORY.
* Bison 3.8
** Rewrite glr.cc
Get rid of scaffolding in glr.c.
** Unit rules / Injection rules (Akim Demaille)
Maybe we could expand unit rules (or "injections", see
https://homepages.cwi.nl/~daybuild/daily-books/syntax/2-sdf/sdf.html), i.e.,
@@ -395,16 +426,6 @@ undocumented ''features''. Maybe an empty action ought to be
presented too. Shall we try to make a single grammar with all these
features, or should we have several very small grammars?
** --report=conflict-path
Provide better assistance for understanding the conflicts by providing
a sample text exhibiting the (LALR) ambiguity. See the paper from
DeRemer and Penello: they already provide the algorithm.
** Statically check for potential ambiguities in GLR grammars
See <http://www.lsv.fr/~schmitz/pub/expamb.pdf> for an approach.
An Experimental Ambiguity Detection Tool Sylvain Schmitz
LORIA, INRIA Nancy - Grand Est, Nancy, France
* Extensions
** More languages?
Well, only if there is really some demand for it.
@@ -495,13 +516,6 @@ XML output for GNU Bison and gcc
XML output for GNU Bison
http://yaxx.sourceforge.net/
** Counterexample generation
https://lists.gnu.org/archive/html/bug-bison/2016-06/msg00000.html
http://www.cs.cornell.edu/andru/papers/cupex/
Andrew Myers and Vincent Imbimbo are working on this item, see
https://github.com/akimd/bison/issues/12
* Coding system independence
Paul notes:
@@ -578,15 +592,9 @@ Foundation, Inc.
This file is part of Bison, the GNU Compiler Compiler.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3 or
any later version published by the Free Software Foundation; with no
Invariant Sections, with no Front-Cover Texts, and with no Back-Cover
Texts. A copy of the license is included in the "GNU Free
Documentation License" file as part of this distribution.
+5 -3
View File
@@ -17,7 +17,7 @@
# gnulib modules used by this package.
gnulib_modules='
argmatch array-list assert assure
argmatch array-list assert assure attribute
bitsetv
calloc-posix close closeout config-h c-strcase
configmake
@@ -30,6 +30,7 @@ gnulib_modules='
javaexec-script
ldexpl
libtextstyle-optional
linked-list
malloc-gnu
mbfile mbswidth
non-recursive-gnulib-prefix-hack
@@ -37,14 +38,15 @@ gnulib_modules='
obstack-printf
perror progname
quote quotearg
rbtreehash-list
readline
readme-release
realloc-posix
relocatable-prog relocatable-script
rename
spawn-pipe stdbool stpcpy strdup-posix strerror strverscmp
spawn-pipe stdbool stpcpy stpncpy strdup-posix strerror strverscmp
timevar
unistd unistd-safer unlink unlocked-io
unicodeio unistd unistd-safer unlink unlocked-io
update-copyright unsetenv verify
warnings
winsz-ioctl
+7
View File
@@ -73,6 +73,11 @@ def diff_to_re(match):
is_diff = True
to.append(l)
if is_diff:
# Do not run s//SOMETHING/g (with an emty pattern), that won't
# work well...
if frm == []:
trace("no from for", match.group(1))
return
frm = "\n".join(frm)
to = "\n".join(to)
subst[frm] = to
@@ -112,4 +117,6 @@ def process(logfile):
for logfile in args.logs:
trace("FILE:", logfile)
if os.path.isdir(logfile):
logfile = os.path.join(logfile, 'testsuite.log')
process(logfile)
+4 -2
View File
@@ -132,10 +132,12 @@ if test "$enable_gcc_warnings" = yes; then
-fparse-all-comments -Wdocumentation
-Wformat -Wimplicit-fallthrough -Wnull-dereference
-Wno-sign-compare -Wno-tautological-constant-out-of-range-compare
-Wpointer-arith -Wshadow
-Wpointer-arith -Wshadow -Wstrict-aliasing
-Wwrite-strings
-wr188 -wr2259 -wr3179'
warn_c='-Wbad-function-cast -Wstrict-prototypes'
warn_c='-Wbad-function-cast
-Wmissing-prototypes
-Wstrict-prototypes'
warn_cxx='-Wextra-semi -Wnoexcept -Wold-style-cast -Wundefined-func-template
-Wweak-vtables'
# Warnings for the test suite only.
+24 -16
View File
@@ -1,6 +1,6 @@
This directory contains data needed by Bison.
# Directory content
# Directory Content
## Skeletons
Bison skeletons: the general shapes of the different parser kinds, that are
specialized for specific grammars by the bison program.
@@ -48,7 +48,7 @@ various formats.
- xml2xhtml.xsl
Conversion into XHTML.
# Implementation note about the skeletons
# Implementation Notes About the Skeletons
"Skeleton" in Bison parlance means "backend": a skeleton is fed by the bison
executable with LR tables, facts about the symbols, etc. and they generate
@@ -84,29 +84,35 @@ field), where field can `has_id`, `id`, etc.: see
The macro `b4_symbol(NUM, FIELD)` gives access to the following FIELDS:
- `has_id`: 0 or 1
Whether the symbol has an id.
Whether the symbol has an `id`.
- `id`: string
If has_id, the id (prefixed by api.token.prefix if defined), otherwise
defined as empty. Guaranteed to be usable as a C identifier. This is
used to define the token kind (i.e., the enum used by the return value of
yylex).
- `id`: string (e.g., `exp`, `NUM`, or `TOK_NUM` with api.token.prefix)
If `has_id`, the name of the token kind (prefixed by api.token.prefix if
defined), otherwise empty. Guaranteed to be usable as a C identifier.
This is used to define the token kind (i.e., the enum used by the return
value of yylex). Should be named `token_kind`.
- `tag`: string
A human representation of the symbol. Can be 'foo', 'foo.id', '"foo"' etc.
A human readable representation of the symbol. Can be `'foo'`,
`'foo.id'`, `'"foo"'` etc.
- `user_number`: integer
The code associated to the `id`.
- `code`: integer
The token code associated to the token kind `id`.
The external number as used by yylex. Can be ASCII code when a character,
some number chosen by bison, or some user number in the case of
%token FOO <NUM>. Corresponds to yychar in yacc.c.
some number chosen by bison, or some user number in the case of `%token
FOO <NUM>`. Corresponds to `yychar` in `yacc.c`.
- `is_token`: 0 or 1
Whether this is a terminal symbol.
- `kind_base`: string (e.g., `YYSYMBOL_exp`, `YYSYMBOL_NUM`)
The base of the symbol kind, i.e., the enumerator of this symbol (token or
nonterminal) which is mapped to its `number`.
- `kind`: string
The symbol kind, i.e., the enumerator of this symbol (token or nonterminal)
which is mapping to its `number`.
Same as `kind_base`, but possibly with a prefix in some languages. E.g.,
EOF's `kind_base` and `kind` are `YYSYMBOL_YYEOF` in C, but are
`S_YYEMPTY` and `symbol_kind::S_YYEMPTY` in C++.
- `number`: integer
The code associated to the `kind`.
@@ -173,7 +179,7 @@ The data corresponding to the symbol `#POS`, where the current rule has
Expansion of `$<TYPE>POS`, where the current rule has `RULE-LENGTH` symbols
on RHS.
-----
<!--
Local Variables:
mode: markdown
@@ -197,3 +203,5 @@ GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
+27
View File
@@ -30,5 +30,32 @@
/* "Sections" in traces (--trace). */
.trace0 { color: green; }
/* Syntax error messages. */
.expected { color: green; }
.unexpected { color: red; }
/* Counterexamples. */
/* Cex: point in rule. */
.cex-dot { color: red; }
/* Cex: coloring various rules. */
.cex-0 { color: yellow; }
.cex-1 { color: green; }
.cex-2 { color: blue; }
.cex-3 { color: purple; }
.cex-4 { color: violet; }
.cex-5 { color: orange; }
.cex-6 { color: brown; }
.cex-7 { color: mauve; }
.cex-8 { color: #013220; } /* Dark green. */
.cex-9 { color: #e75480; } /* Dark pink. */
.cex-10 { color: cyan; }
.cex-11 { color: orange; }
/* Cex: derivation rewriting steps. */
.cex-step { font-style: italic; }
/* Cex: leaves of a derivation. */
.cex-leaf { font-weight: 600; }
+1
View File
@@ -34,6 +34,7 @@ dist_skeletons_DATA = \
data/skeletons/lalr1.java \
data/skeletons/location.cc \
data/skeletons/stack.hh \
data/skeletons/traceon.m4 \
data/skeletons/variant.hh \
data/skeletons/yacc.c
+41 -10
View File
@@ -19,6 +19,29 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# m4_gsub(STRING, RE1, SUBST1, RE2, SUBST2, ...)
# ----------------------------------------------
# m4 equivalent of
#
# $_ = STRING;
# s/RE1/SUBST1/g;
# s/RE2/SUBST2/g;
# ...
#
# Really similar to m4_bpatsubsts, but behaves properly with quotes.
# See m4.at's "Generating Comments". Super inelegant, but so far, I
# did not find any better solution.
m4_define([b4_gsub],
[m4_bpatsubst(m4_bpatsubst(m4_bpatsubst([[[[$1]]]],
[$2], [$3]),
[$4], [$5]),
[$6], [$7])])
# m4_shift2 and m4_shift3 are provided by m4sugar.
m4_define([m4_shift4], [m4_shift(m4_shift(m4_shift(m4_shift($@))))])
## ---------------- ##
## Identification. ##
## ---------------- ##
@@ -162,7 +185,7 @@ m4_define([b4_error],
[b4_cat([[@complain][(]$1[@,]$2[@,]$3[@,]$4[]]dnl
[m4_if([$#], [4], [],
[m4_foreach([b4_arg],
m4_dquote(m4_shift(m4_shift(m4_shift(m4_shift($@))))),
m4_dquote(m4_shift4($@)),
[[@,]b4_arg])])[@)]])])
# b4_warn(FORMAT, [ARG1], [ARG2], ...)
@@ -415,14 +438,14 @@ m4_define([b4_symbol_token_kind],
_b4_symbol([$1], [id])])
# b4_symbol_kind(NUM)
# -------------------
# b4_symbol_kind_base(NUM)
# ------------------------
# Build the name of the kind of this symbol. It must always exist,
# otherwise some symbols might not be represented in the enum, which
# might be compiled into too small a type to contain all the symbol
# numbers.
m4_define([b4_symbol_prefix], [b4_percent_define_get([api.symbol.prefix])])
m4_define([b4_symbol_kind],
m4_define([b4_symbol_kind_base],
[b4_percent_define_get([api.symbol.prefix])dnl
m4_case([$1],
[-2], [[YYEMPTY]],
@@ -435,6 +458,13 @@ m4_case([$1],
[m4_bpatsubst([$1-][]_b4_symbol([$1], [tag]), [[^a-zA-Z_0-9]+], [_])])])])])
# b4_symbol_kind(NUM)
# -------------------
# Same as b4_symbol_kind, but possibly with a prefix in some
# languages. E.g., EOF's kind_base and kind are YYSYMBOL_YYEOF in C,
# but are S_YYEMPTY and symbol_kind::S_YYEMPTY in C++.
m4_copy([b4_symbol_kind_base], [b4_symbol_kind])
# b4_symbol(NUM, FIELD)
# ---------------------
# Fetch FIELD of symbol #NUM (or "orig NUM"). Fail if undefined.
@@ -442,8 +472,9 @@ m4_case([$1],
# If FIELD = id, prepend the token prefix.
m4_define([b4_symbol],
[m4_case([$2],
[id], [b4_symbol_token_kind([$1])],
[kind], [b4_symbol_kind([$1])],
[id], [b4_symbol_token_kind([$1])],
[kind_base], [b4_symbol_kind_base([$1])],
[kind], [b4_symbol_kind([$1])],
[_b4_symbol($@)])])
@@ -516,7 +547,7 @@ m4_popdef([b4_actions_])dnl
# easier to use with m4_map, but then, use []dnl to suppress the last
# one.
m4_define([_b4_symbol_case],
[case b4_symbol([$1], [number]): b4_symbol_tag_comment([$1])])
[case b4_symbol([$1], [kind]): b4_symbol_tag_comment([$1])])
])
@@ -564,8 +595,8 @@ m4_define([b4_any_token_visible_if],
m4_define([b4_token_format],
[b4_token_visible_if([$2],
[m4_format([[$1]],
m4_expand(b4_symbol([$2], [id])),
m4_expand(b4_symbol([$2], b4_api_token_raw_if([[number]], [[user_number]]))))])])
b4_symbol([$2], [id]),
b4_symbol([$2], b4_api_token_raw_if([[number]], [[code]])))])])
# b4_last_enum_token
@@ -727,7 +758,7 @@ m4_define([b4_check_user_names],
[m4_pushdef([b4_occurrence], b4_occurrence)dnl
m4_pushdef([b4_user_name], m4_car(b4_occurrence))dnl
m4_pushdef([b4_start], m4_car(m4_shift(b4_occurrence)))dnl
m4_pushdef([b4_end], m4_shift(m4_shift(b4_occurrence)))dnl
m4_pushdef([b4_end], m4_shift2(b4_occurrence))dnl
m4_ifndef($3[(]m4_quote(b4_user_name)[)],
[b4_complain_at([b4_start], [b4_end],
[[%s '%s' is not used]],
+8 -7
View File
@@ -105,7 +105,7 @@ b4_percent_define_default([[api.parser.class]], [[parser]])
#
# b4_percent_define_default([[api.location.type]], [[location]])
b4_percent_define_default([[filename_type]], [[std::string]])
b4_percent_define_default([[api.filename.type]], [[const std::string]])
# Make it a warning for those who used betas of Bison 3.0.
b4_percent_define_default([[api.namespace]], m4_defn([b4_prefix]))
@@ -193,7 +193,7 @@ m4_define([b4_declare_symbol_enum],
[[enum symbol_kind_type
{
YYNTOKENS = ]b4_tokens_number[, ///< Number of tokens.
]b4_symbol_kind([-2])[ = -2,
]b4_symbol(-2, kind_base)[ = -2,
]b4_symbol_foreach([ b4_symbol_enum])dnl
[ };]])
@@ -507,7 +507,7 @@ m4_define([b4_public_types_define],
bool
]b4_parser_class[::basic_symbol<Base>::empty () const YY_NOEXCEPT
{
return this->kind () == symbol_kind::]b4_symbol_prefix[YYEMPTY;
return this->kind () == ]b4_symbol(-2, kind)[;
}
template <typename Base>
@@ -523,7 +523,7 @@ m4_define([b4_public_types_define],
// by_kind.
]b4_inline([$1])b4_parser_class[::by_kind::by_kind ()
: kind_ (symbol_kind::]b4_symbol_prefix[YYEMPTY)
: kind_ (]b4_symbol(-2, kind)[)
{}
#if 201103L <= YY_CPLUSPLUS
@@ -545,7 +545,7 @@ m4_define([b4_public_types_define],
]b4_inline([$1])[void
]b4_parser_class[::by_kind::clear ()
{
kind_ = symbol_kind::]b4_symbol_prefix[YYEMPTY;
kind_ = ]b4_symbol(-2, kind)[;
}
]b4_inline([$1])[void
@@ -594,11 +594,12 @@ m4_define([b4_yytranslate_define],
{
]b4_translate[
};
const int user_token_number_max_ = ]b4_user_token_number_max[;
// Last valid token kind.
const int code_max = ]b4_code_max[;
if (t <= 0)
return symbol_kind::]b4_symbol_prefix[YYEOF;
else if (t <= user_token_number_max_)
else if (t <= code_max)
return YY_CAST (symbol_kind_type, translate_table[t]);
else
return symbol_kind::]b4_symbol_prefix[YYUNDEF;]])[
+7 -1
View File
@@ -17,15 +17,21 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# _b4_comment(TEXT, OPEN, CONTINUE, END)
# --------------------------------------
# Put TEXT in comment. Avoid trailing spaces: don't indent empty lines.
# Avoid adding indentation to the first line, as the indentation comes
# from OPEN. That's why we don't patsubst([$1], [^\(.\)], [ \1]).
# Turn "*/" in TEXT into "* /" so that we don't unexpectedly close
# the comments before its end.
#
# Prefix all the output lines with PREFIX.
m4_define([_b4_comment],
[$2[]m4_bpatsubst(m4_expand([[$1]]), [
[$2[]b4_gsub(m4_expand([$1]),
[[*]/], [*\\/],
[/[*]], [/\\*],
[
\(.\)], [
$3\1])$4])
+17 -9
View File
@@ -355,15 +355,23 @@ m4_define([b4_attribute_define],
#endif
]m4_bmatch([$1], [\bnoreturn\b], [[/* The _Noreturn keyword of C11. */
]dnl This is an exact copy of lib/_Noreturn.h.
]dnl This is close to lib/_Noreturn.h, except that we do enable
dnl the use of [[noreturn]], because _Noreturn is used in places
dnl where [[noreturn]] works in C++. We need this in particular
dnl because of glr.cc which compiles code from glr.c in C++.
dnl And the C++ compiler chokes on _Noreturn. Also, we do not
dnl use C' _Noreturn in C++, to avoid -Wc11-extensions warnings.
[#ifndef _Noreturn
# if (defined __cplusplus \
&& ((201103 <= __cplusplus && !(__GNUC__ == 4 && __GNUC_MINOR__ == 7)) \
|| (defined _MSC_VER && 1900 <= _MSC_VER)))
# define _Noreturn [[noreturn]]
# elif ((!defined __cplusplus || defined __clang__) \
# elif (!defined __cplusplus \
&& (201112 <= (defined __STDC_VERSION__ ? __STDC_VERSION__ : 0) \
|| 4 < __GNUC__ + (7 <= __GNUC_MINOR__)))
|| 4 < __GNUC__ + (7 <= __GNUC_MINOR__) \
|| (defined __apple_build_version__ \
? 6000000 <= __apple_build_version__ \
: 3 < __clang_major__ + (5 <= __clang_minor__))))
/* _Noreturn works as-is. */
# elif 2 < __GNUC__ + (8 <= __GNUC_MINOR__) || 0x5110 <= __SUNPRO_C
# define _Noreturn __attribute__ ((__noreturn__))
@@ -515,7 +523,7 @@ m4_define([b4_token_enum],
[m4_format([ %-30s %s],
m4_format([[%s = %s%s%s]],
b4_symbol([$1], [id]),
b4_symbol([$1], b4_api_token_raw_if([[number]], [[user_number]])),
b4_symbol([$1], b4_api_token_raw_if([[number]], [[code]])),
m4_if([$1], b4_last_enum_token, [], [[,]])),
[b4_symbol_tag_comment([$1])])])])
@@ -564,7 +572,7 @@ m4_define([b4_symbol_translate],
m4_define([b4_symbol_enum],
[m4_format([ %-40s %s],
m4_format([[%s = %s%s%s]],
b4_symbol([$1], [kind]),
b4_symbol([$1], [kind_base]),
[$1],
m4_if([$1], b4_last_symbol, [], [[,]])),
[b4_symbol_tag_comment([$1])])])
@@ -579,7 +587,7 @@ m4_define([b4_declare_symbol_enum],
[[/* Symbol kind. */
enum yysymbol_kind_t
{
]b4_symbol_kind([-2])[ = -2,
]b4_symbol([-2], kind_base)[ = -2,
]b4_symbol_foreach([b4_symbol_enum])dnl
[};
typedef enum yysymbol_kind_t yysymbol_kind_t;
@@ -658,10 +666,10 @@ m4_define([b4_sync_start], [[#]line $1 $2])
## User actions. ##
## -------------- ##
# b4_case(LABEL, STATEMENTS)
# --------------------------
# b4_case(LABEL, STATEMENTS, [COMMENTS])
# --------------------------------------
m4_define([b4_case],
[ case $1:
[ case $1:m4_ifval([$3], [ b4_comment([$3])])
$2
b4_syncline([@oline@], [@ofile@])dnl
break;])
+12 -5
View File
@@ -152,6 +152,8 @@ private static immutable b4_int_type_for([$2])[[]] yy$1_ =
## Token kinds. ##
## ------------- ##
m4_define([b4_symbol(-2, id)], [[YYEMPTY]])
# b4_token_enum(TOKEN-NAME, TOKEN-NUMBER)
# ---------------------------------------
# Output the definition of this token as an enum.
@@ -178,6 +180,11 @@ b4_symbol_foreach([b4_token_enum])dnl
b4_percent_define_default([[api.symbol.prefix]], [[S_]])
# b4_symbol_kind(NUM)
# -------------------
m4_define([b4_symbol_kind],
[SymbolKind.b4_symbol_kind_base($@)])
# b4_symbol_enum(SYMBOL-NUM)
# --------------------------
@@ -185,7 +192,7 @@ b4_percent_define_default([[api.symbol.prefix]], [[S_]])
m4_define([b4_symbol_enum],
[m4_format([ %-30s %s],
m4_format([[%s = %s,]],
b4_symbol([$1], [kind]),
b4_symbol([$1], [kind_base]),
[$1]),
[b4_symbol_tag_comment([$1])])])
@@ -199,16 +206,16 @@ m4_define([b4_declare_symbol_enum],
[[ /* Symbol kinds. */
public enum SymbolKind
{
]b4_symbol_kind([-2])[ = -2, /* No symbol. */
]b4_symbol(-2, kind_base)[ = -2, /* No symbol. */
]b4_symbol_foreach([b4_symbol_enum])dnl
[ };
]])])
# b4-case(ID, CODE)
# -----------------
m4_define([b4_case], [ case $1:
# b4-case(ID, CODE, [COMMENTS])
# -----------------------------
m4_define([b4_case], [ case $1:m4_ifval([$3], [ b4_comment([$3])])
$2
break;])
+10 -7
View File
@@ -189,9 +189,9 @@ b4_glr_cc_if([],
[b4_output_begin([b4_spec_header_file])
b4_copyright([Skeleton interface for Bison GLR parsers in C],
[2002-2015, 2018-2020])[
]b4_cpp_guard_open([b4_spec_header_file])[
]b4_cpp_guard_open([b4_spec_mapped_header_file])[
]b4_shared_declarations[
]b4_cpp_guard_close([b4_spec_header_file])[
]b4_cpp_guard_close([b4_spec_mapped_header_file])[
]b4_output_end[
]])])
@@ -230,7 +230,9 @@ b4_copyright([Skeleton implementation for Bison GLR parsers in C],
]b4_defines_if([[#include "@basename(]b4_spec_header_file[@)"]],
[b4_shared_declarations])[
]b4_declare_symbol_enum[
]b4_glr_cc_if([b4_glr_cc_setup],
[b4_declare_symbol_enum])[
/* Default (constant) value used for initialization for null
right-hand sides. Unlike the standard yacc.c template, here we set
@@ -331,8 +333,8 @@ static YYLTYPE yyloc_default][]b4_yyloc_default;])[
accessed by $0, $-1, etc., in any rule. */
#define YYMAXLEFT ]b4_max_left_semantic_context[
/* YYMAXUTOK -- Last valid token number (for yychar). */
#define YYMAXUTOK ]b4_user_token_number_max[
/* YYMAXUTOK -- Last valid token kind. */
#define YYMAXUTOK ]b4_code_max[
/* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM
as returned by yylex, with out-of-bounds checking. */
@@ -2731,7 +2733,8 @@ m4_if(b4_prefix, [yy], [],
#define yynerrs ]b4_prefix[nerrs]b4_locations_if([[
#define yylloc ]b4_prefix[lloc]])])[
]m4_ifdef([b4_pre_epilogue], [b4_pre_epilogue])[]dnl This is a hack for glr.cc. To remove when we have a better glr.cc.
b4_percent_code_get([[epilogue]])[]dnl
]b4_glr_cc_if([b4_glr_cc_pre_epilogue
b4_glr_cc_cleanup])[
]b4_percent_code_get([[epilogue]])[]dnl
b4_epilogue[]dnl
b4_output_end
+57 -44
View File
@@ -66,12 +66,6 @@ m4_defn([b4_parse_param]))],
[[b4_namespace_ref::b4_parser_class[& yyparser], [[yyparser]]]])
])
# b4_declare_symbol_enum
# ----------------------
m4_append([b4_declare_symbol_enum],
[[typedef symbol_kind_type yysymbol_kind_t;
]])
# b4_yy_symbol_print_define
# -------------------------
@@ -105,15 +99,9 @@ yyerror (]b4_locations_if([[const ]b4_namespace_ref::b4_parser_class[::location_
]])[]m4_ifset([b4_parse_param], [b4_formals(b4_parse_param),
])[const char* msg);]])[
]b4_percent_define_flag_if([[global_tokens_and_yystype]], [],
[m4_define([b4_pre_epilogue],
[[/* The user is using the C++ token kind, not the C one. */
#undef ]b4_symbol(0, [id])
])])[
# Hijack the epilogue to define implementations (yyerror, parser member
# Inserted before the epilogue to define implementations (yyerror, parser member
# functions etc.).
]m4_append([b4_epilogue],
]m4_define([b4_glr_cc_pre_epilogue],
[b4_syncline([@oline@], [@ofile@])dnl
[
/*------------------.
@@ -222,6 +210,57 @@ b4_namespace_close[]dnl
])
m4_define([b4_define_symbol_kind],
[m4_format([#define %-15s %s],
b4_symbol($][1, kind_base),
b4_namespace_ref[::]b4_parser_class[::symbol_kind::]b4_symbol($1, kind_base))
])
# b4_glr_cc_setup
# ---------------
# Setup redirections for glr.c: Map the names used in c.m4 to the ones used
# in c++.m4.
m4_define([b4_glr_cc_setup],
[[#undef ]b4_symbol(-2, [id])[
#define ]b4_symbol(-2, [id])[ ]b4_namespace_ref[::]b4_parser_class[::token::]b4_symbol(-2, [id])[
#undef ]b4_symbol(0, [id])[
#define ]b4_symbol(0, [id])[ ]b4_namespace_ref[::]b4_parser_class[::token::]b4_symbol(0, [id])[
#undef ]b4_symbol(1, [id])[
#define ]b4_symbol(1, [id])[ ]b4_namespace_ref[::]b4_parser_class[::token::]b4_symbol(1, [id])[
#ifndef ]b4_api_PREFIX[STYPE
# define ]b4_api_PREFIX[STYPE ]b4_namespace_ref[::]b4_parser_class[::semantic_type
#endif
#ifndef ]b4_api_PREFIX[LTYPE
# define ]b4_api_PREFIX[LTYPE ]b4_namespace_ref[::]b4_parser_class[::location_type
#endif
typedef ]b4_namespace_ref[::]b4_parser_class[::symbol_kind_type yysymbol_kind_t;
// Expose C++ symbol kinds to C.
]b4_define_symbol_kind(-2)dnl
b4_symbol_foreach([b4_define_symbol_kind])])[
]])
m4_define([b4_undef_symbol_kind],
[[#undef ]b4_symbol($1, kind_base)[
]])
# b4_glr_cc_cleanup
# -----------------
# Remove redirections for glr.c.
m4_define([b4_glr_cc_cleanup],
[[#undef ]b4_symbol(-2, [id])[
#undef ]b4_symbol(0, [id])[
#undef ]b4_symbol(1, [id])[
]b4_undef_symbol_kind(-2)dnl
b4_symbol_foreach([b4_undef_symbol_kind])dnl
])
# b4_shared_declarations(hh|cc)
# -----------------------------
# Declaration that might either go into the header (if --defines, $1 = hh)
@@ -333,48 +372,22 @@ b4_percent_code_get([[requires]])[
]b4_parse_param_vars[
};
]dnl Redirections for glr.c.
b4_percent_define_flag_if([[global_tokens_and_yystype]],
[b4_token_defines
])[
]b4_namespace_close[
]dnl Map the name used in c.m4 to the one used in c++.m4.
[#undef ]b4_symbol(-2, [id])[
#define ]b4_symbol(-2, [id])[ ]b4_namespace_ref[::]b4_parser_class[::token::]b4_symbol(-2, [id])[
#undef ]b4_symbol(0, [id])[
#define ]b4_symbol(0, [id])[ ]b4_namespace_ref[::]b4_parser_class[::token::]b4_symbol(0, [id])[
#undef ]b4_symbol(1, [id])[
#define ]b4_symbol(1, [id])[ ]b4_namespace_ref[::]b4_parser_class[::token::]b4_symbol(1, [id])[
#ifndef ]b4_api_PREFIX[STYPE
# define ]b4_api_PREFIX[STYPE ]b4_namespace_ref[::]b4_parser_class[::semantic_type
#endif
#ifndef ]b4_api_PREFIX[LTYPE
# define ]b4_api_PREFIX[LTYPE ]b4_namespace_ref[::]b4_parser_class[::location_type
#endif
]m4_define([b4_declare_symbol_enum],
[[typedef ]b4_namespace_ref[::]b4_parser_class[::symbol_kind_type yysymbol_kind_t;
#define ]b4_symbol_prefix[YYEMPTY ]b4_namespace_ref[::]b4_parser_class[::symbol_kind::]b4_symbol_prefix[YYEMPTY
#define ]b4_symbol_prefix[YYerror ]b4_namespace_ref[::]b4_parser_class[::symbol_kind::]b4_symbol_prefix[YYerror
#define ]b4_symbol_prefix[YYEOF ]b4_namespace_ref[::]b4_parser_class[::symbol_kind::]b4_symbol_prefix[YYEOF
#define ]b4_symbol_prefix[YYUNDEF ]b4_namespace_ref[::]b4_parser_class[::symbol_kind::]b4_symbol_prefix[YYUNDEF
]])[
]b4_percent_code_get([[provides]])[
]m4_popdef([b4_parse_param])dnl
])
])[
b4_defines_if(
]b4_defines_if(
[b4_output_begin([b4_spec_header_file])
b4_copyright([Skeleton interface for Bison GLR parsers in C++],
[2002-2015, 2018-2020])[
// C++ GLR parser skeleton written by Akim Demaille.
]b4_disclaimer[
]b4_cpp_guard_open([b4_spec_header_file])[
]b4_cpp_guard_open([b4_spec_mapped_header_file])[
]b4_shared_declarations[
]b4_cpp_guard_close([b4_spec_header_file])[
]b4_cpp_guard_close([b4_spec_mapped_header_file])[
]b4_output_end])
# Let glr.c (and b4_shared_declarations) believe that the user
+12 -5
View File
@@ -143,7 +143,7 @@ m4_define([b4_token_enum],
]],
b4_symbol([$1], [tag]),
b4_symbol([$1], [id]),
b4_symbol([$1], b4_api_token_raw_if([[number]], [[user_number]])))])])
b4_symbol([$1], b4_api_token_raw_if([[number]], [[code]])))])])
# b4_token_enums
@@ -159,13 +159,20 @@ b4_symbol_foreach([b4_token_enum])])])
## Symbol kinds. ##
## -------------- ##
# b4_symbol_kind(NUM)
# -------------------
m4_define([b4_symbol_kind],
[SymbolKind.b4_symbol_kind_base($@)])
# b4_symbol_enum(SYMBOL-NUM)
# --------------------------
# Output the definition of this symbol as an enum.
m4_define([b4_symbol_enum],
[m4_format([ %-30s %s],
m4_format([[%s(%s)%s]],
b4_symbol([$1], [kind]),
b4_symbol([$1], [kind_base]),
[$1],
m4_if([$1], b4_last_symbol, [[;]], [[,]])),
[b4_symbol_tag_comment([$1])])])
@@ -255,11 +262,11 @@ m4_define([b4_declare_symbol_enum],
# b4_case(ID, CODE)
# -----------------
# b4_case(ID, CODE, [COMMENTS])
# -----------------------------
# We need to fool Java's stupid unreachable code detection.
m4_define([b4_case],
[ case $1:
[ case $1:m4_ifval([$3], [ b4_comment([$3])])
if (yyn == $1)
$2;
break;
+22 -23
View File
@@ -59,6 +59,13 @@ m4_define([b4_integral_parser_table_define],
};dnl
])
# b4_symbol_kind(NUM)
# -------------------
m4_define([b4_symbol_kind],
[symbol_kind::b4_symbol_kind_base($@)])
# b4_symbol_value_template(VAL, SYMBOL-NUM, [TYPE])
# -------------------------------------------------
# Same as b4_symbol_value, but used in a template method. It makes
@@ -486,14 +493,6 @@ m4_define([b4_shared_declarations],
]b4_public_types_define([$1])])[
]b4_namespace_close[
]b4_percent_define_flag_if([[global_tokens_and_yystype]],
[b4_token_defines
#ifndef ]b4_api_PREFIX[STYPE
// Redirection for backward compatibility.
# define ]b4_api_PREFIX[STYPE b4_namespace_ref::b4_parser_class::semantic_type
#endif
])[
]b4_percent_code_get([[provides]])[
]])
@@ -506,16 +505,16 @@ b4_defines_if(
b4_copyright([Skeleton interface for Bison LALR(1) parsers in C++])
[
/**
** \file ]b4_spec_header_file[
** \file ]b4_spec_mapped_header_file[
** Define the ]b4_namespace_ref[::parser class.
*/
// C++ LALR(1) parser skeleton written by Akim Demaille.
]b4_disclaimer[
]b4_cpp_guard_open([b4_spec_header_file])[
]b4_cpp_guard_open([b4_spec_mapped_header_file])[
]b4_shared_declarations(hh)[
]b4_cpp_guard_close([b4_spec_header_file])[
]b4_cpp_guard_close([b4_spec_mapped_header_file])[
]b4_output_end[
]])
@@ -666,7 +665,7 @@ m4_if(b4_prefix, [yy], [],
]b4_parser_class[::by_state::kind () const YY_NOEXCEPT
{
if (state == empty_state)
return symbol_kind::]b4_symbol(-2, kind)[;
return ]b4_symbol(-2, kind)[;
else
return YY_CAST (symbol_kind_type, yystos_[+state]);
}
@@ -691,7 +690,7 @@ m4_if(b4_prefix, [yy], [],
b4_symbol_variant([that.kind ()],
[value], [move], [YY_MOVE (that.value)])])[
// that is emptied.
that.kind_ = symbol_kind::]b4_symbol(-2, kind)[;
that.kind_ = ]b4_symbol(-2, kind)[;
}
#if YY_CPLUSPLUS < 201103L
@@ -920,13 +919,13 @@ b4_dollar_popdef])[]dnl
}
YY_SYMBOL_PRINT ("Next token is", yyla);
if (yyla.kind () == ]symbol_kind::b4_symbol(1, kind)[)
if (yyla.kind () == ]b4_symbol(1, kind)[)
{
// The scanner already issued an error message, process directly
// to error recovery. But do not keep the error token as
// lookahead, it is too special and may lead us to an endless
// loop in error recovery. */
yyla.kind_ = ]symbol_kind::b4_symbol(2, kind)[;
yyla.kind_ = ]b4_symbol(2, kind)[;
goto yyerrlab1;
}
@@ -1063,7 +1062,7 @@ b4_dollar_popdef])[]dnl
error, discard it. */
// Return failure if at end of input.
if (yyla.kind () == symbol_kind::]b4_symbol_prefix[YYEOF)
if (yyla.kind () == ]b4_symbol(0, kind)[)
YYABORT;
else if (!yyla.empty ())
{
@@ -1104,9 +1103,9 @@ b4_dollar_popdef])[]dnl
yyn = yypact_[+yystack_[0].state];
if (!yy_pact_value_is_default_ (yyn))
{
yyn += symbol_kind::]b4_symbol(1, kind)[;
yyn += ]b4_symbol(1, kind)[;
if (0 <= yyn && yyn <= yylast_
&& yycheck_[yyn] == symbol_kind::]b4_symbol(1, kind)[)
&& yycheck_[yyn] == ]b4_symbol(1, kind)[)
{
yyn = yytable_[yyn];
if (0 < yyn)
@@ -1298,8 +1297,8 @@ b4_dollar_popdef])[]dnl
for (int yyx = 0; yyx < YYNTOKENS; ++yyx)
{
symbol_kind_type yysym = YY_CAST (symbol_kind_type, yyx);
if (yysym != symbol_kind::]b4_symbol(1, kind)[
&& yysym != symbol_kind::]b4_symbol_prefix[YYUNDEF
if (yysym != ]b4_symbol(1, kind)[
&& yysym != ]b4_symbol(2, kind)[
&& yyparser_.yy_lac_check_ (yysym))
{
if (!yyarg)
@@ -1321,7 +1320,7 @@ b4_dollar_popdef])[]dnl
int yychecklim = yylast_ - yyn + 1;
int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
for (int yyx = yyxbegin; yyx < yyxend; ++yyx)
if (yycheck_[yyx + yyn] == yyx && yyx != symbol_kind::]b4_symbol(1, kind)[
if (yycheck_[yyx + yyn] == yyx && yyx != ]b4_symbol(1, kind)[
&& !yy_table_value_is_error_ (yytable_[yyx + yyn]))
{
if (!yyarg)
@@ -1334,7 +1333,7 @@ b4_dollar_popdef])[]dnl
}
]])[
if (yyarg && yycount == 0 && 0 < yyargn)
yyarg[0] = symbol_kind::]b4_symbol(-2, kind)[;
yyarg[0] = ]b4_symbol(-2, kind)[;
return yycount;
}
@@ -1411,7 +1410,7 @@ b4_dollar_popdef])[]dnl
: yylac_stack_.back ());
// Push the resulting state of the reduction.
state_type state = yy_lr_goto_state_ (top_state, yyr1_[yyrule]);
YYCDEBUG << " G" << state;
YYCDEBUG << " G" << int (state);
yylac_stack_.push_back (state);
}
}
+18 -16
View File
@@ -428,9 +428,10 @@ b4_locations_if([, ref ]b4_location_type[ yylocationp])[)
*/
public bool parse ()
{
/// Lookahead and lookahead in internal form.
// Lookahead token kind.
int yychar = TokenKind.YYEMPTY;
SymbolKind yytoken = SymbolKind.]b4_symbol(-2, kind)[;
// Lookahead symbol kind.
SymbolKind yytoken = ]b4_symbol(-2, kind)[;
/* State. */
int yyn = 0;
@@ -509,14 +510,14 @@ m4_popdef([b4_at_dollar])])dnl
yytoken = yytranslate_ (yychar);]b4_parse_trace_if([[
yy_symbol_print ("Next token is", yytoken, yylval]b4_locations_if([, yylloc])[);]])[
if (yytoken == SymbolKind.]b4_symbol(1, kind)[)
if (yytoken == ]b4_symbol(1, kind)[)
{
// The scanner already issued an error message, process directly
// to error recovery. But do not keep the error token as
// lookahead, it is too special and may lead us to an endless
// loop in error recovery. */
yychar = TokenKind.YYUNDEF;
yytoken = SymbolKind.]b4_symbol_prefix[YYUNDEF;]b4_locations_if([[
yychar = TokenKind.]b4_symbol(2, id)[;
yytoken = ]b4_symbol(2, kind)[;]b4_locations_if([[
yyerrloc = yylloc;]])[
label = YYERRLAB1;
}
@@ -587,8 +588,8 @@ m4_popdef([b4_at_dollar])])dnl
if (yyerrstatus_ == 0)
{
++yynerrs_;
if (yychar == TokenKind.YYEMPTY)
yytoken = SymbolKind.]b4_symbol(-2, kind)[;
if (yychar == TokenKind.]b4_symbol(-2, id)[)
yytoken = ]b4_symbol(-2, kind)[;
yyerror (]b4_locations_if([yylloc, ])[yysyntax_error (yystate, yytoken));
}
]b4_locations_if([
@@ -638,8 +639,8 @@ m4_popdef([b4_at_dollar])])dnl
yyn = yypact_[yystate];
if (!yy_pact_value_is_default_ (yyn))
{
yyn += SymbolKind.]b4_symbol(1, kind)[;
if (0 <= yyn && yyn <= yylast_ && yycheck_[yyn] == SymbolKind.]b4_symbol(1, kind)[)
yyn += ]b4_symbol(1, kind)[;
if (0 <= yyn && yyn <= yylast_ && yycheck_[yyn] == ]b4_symbol(1, kind)[)
{
yyn = yytable_[yyn];
if (0 < yyn)
@@ -726,7 +727,7 @@ m4_popdef([b4_at_dollar])])dnl
will still contain any token that will not be accepted due
to an error action in a later state.
*/
if (tok != SymbolKind.]b4_symbol(-2, kind)[)
if (tok != ]b4_symbol(-2, kind)[)
{
// FIXME: This method of building the message is not compatible
// with internationalization.
@@ -745,14 +746,14 @@ m4_popdef([b4_at_dollar])])dnl
int yyxend = yychecklim < yyntokens_ ? yychecklim : yyntokens_;
int count = 0;
for (int x = yyxbegin; x < yyxend; ++x)
if (yycheck_[x + yyn] == x && x != SymbolKind.]b4_symbol(1, kind)[
if (yycheck_[x + yyn] == x && x != ]b4_symbol(1, kind)[
&& !yy_table_value_is_error_ (yytable_[x + yyn]))
++count;
if (count < 5)
{
count = 0;
for (int x = yyxbegin; x < yyxend; ++x)
if (yycheck_[x + yyn] == x && x != SymbolKind.]b4_symbol(1, kind)[
if (yycheck_[x + yyn] == x && x != ]b4_symbol(1, kind)[
&& !yy_table_value_is_error_ (yytable_[x + yyn]))
{
res ~= count++ == 0 ? ", expecting " : " or ";
@@ -841,17 +842,18 @@ m4_popdef([b4_at_dollar])])dnl
]b4_translate[
@};
immutable int user_token_number_max_ = ]b4_user_token_number_max[;
// Last valid token kind.
immutable int code_max = ]b4_code_max[;
if (t <= 0)
return SymbolKind.]b4_symbol_prefix[YYEOF;
else if (t <= user_token_number_max_)
return ]b4_symbol(0, kind)[;
else if (t <= code_max)
{
import std.conv : to;
return to!SymbolKind (translate_table[t]);
}
else
return SymbolKind.]b4_symbol_prefix[YYUNDEF;]])[
return ]b4_symbol(2, kind)[;]])[
}
private static immutable int yylast_ = ]b4_last[;
+29 -27
View File
@@ -53,8 +53,9 @@ b4_use_push_for_pull_if([
# allows them to be defined either in parse() when doing pull parsing,
# or as class instance variable when doing push parsing.
m4_define([b4_define_state],[[
/* Lookahead and lookahead in internal form. */
/* Lookahead token kind. */
int yychar = YYEMPTY_;
/* Lookahead symbol kind. */
SymbolKind yytoken = null;
/* State. */
@@ -79,7 +80,7 @@ m4_define([b4_define_state],[[
]b4_copyright([Skeleton implementation for Bison LALR(1) parsers in Java],
[2007-2015, 2018-2020])[
]b4_disclaimer[
]b4_percent_define_ifdef([package], [package b4_percent_define_get([package]);[
]b4_percent_define_ifdef([api.package], [package b4_percent_define_get([api.package]);[
]])[
]b4_user_pre_prologue[
]b4_user_post_prologue[
@@ -602,9 +603,9 @@ b4_dollar_popdef[]dnl
push_token_consumed = false;]], [b4_parse_trace_if([[
yycdebug ("Reading a token");]])[
yychar = yylexer.yylex ();
yylval = yylexer.getLVal ();]b4_locations_if([
yylloc = new b4_location_type (yylexer.getStartPos (),
yylexer.getEndPos ());])[
yylval = yylexer.getLVal();]b4_locations_if([[
yylloc = new ]b4_location_type[(yylexer.getStartPos(),
yylexer.getEndPos());]])[
]])[
}
@@ -613,14 +614,14 @@ b4_dollar_popdef[]dnl
yySymbolPrint("Next token is", yytoken,
yylval]b4_locations_if([, yylloc])[);]])[
if (yytoken == SymbolKind.]b4_symbol_prefix[YYerror)
if (yytoken == ]b4_symbol(1, kind)[)
{
// The scanner already issued an error message, process directly
// to error recovery. But do not keep the error token as
// lookahead, it is too special and may lead us to an endless
// loop in error recovery. */
yychar = Lexer.]b4_percent_define_get([api.token.prefix])[YYUNDEF;
yytoken = SymbolKind.]b4_symbol_prefix[YYUNDEF;]b4_locations_if([[
yychar = Lexer.]b4_symbol(2, id)[;
yytoken = ]b4_symbol(2, kind)[;]b4_locations_if([[
yyerrloc = yylloc;]])[
label = YYERRLAB1;
}
@@ -628,8 +629,8 @@ b4_dollar_popdef[]dnl
{
/* If the proper action on seeing token YYTOKEN is to reduce or to
detect an error, take that action. */
yyn += yytoken.getCode ();
if (yyn < 0 || YYLAST_ < yyn || yycheck_[yyn] != yytoken.getCode ())
yyn += yytoken.getCode();
if (yyn < 0 || YYLAST_ < yyn || yycheck_[yyn] != yytoken.getCode())
label = YYDEFAULT;
/* <= 0 means reduce or error. */
@@ -744,9 +745,9 @@ b4_dollar_popdef[]dnl
yyn = yypact_[yystate];
if (!yyPactValueIsDefault (yyn))
{
yyn += SymbolKind.]b4_symbol(1, kind)[.getCode ();
yyn += ]b4_symbol(1, kind)[.getCode();
if (0 <= yyn && yyn <= YYLAST_
&& yycheck_[yyn] == SymbolKind.]b4_symbol(1, kind)[.getCode ())
&& yycheck_[yyn] == ]b4_symbol(1, kind)[.getCode())
{
yyn = yytable_[yyn];
if (0 < yyn)
@@ -779,7 +780,7 @@ b4_dollar_popdef[]dnl
yystack.pop (2);]])[
/* Shift the error token. */]b4_parse_trace_if([[
yySymbolPrint("Shifting", SymbolKind.get (yystos_[yyn]),
yySymbolPrint("Shifting", SymbolKind.get(yystos_[yyn]),
yylval]b4_locations_if([, yyloc])[);]])[
yystate = yyn;
@@ -933,15 +934,15 @@ b4_dollar_popdef[]dnl
int yychecklim = YYLAST_ - yyn + 1;
int yyxend = yychecklim < NTOKENS ? yychecklim : NTOKENS;
for (int yyx = yyxbegin; yyx < yyxend; ++yyx)
if (yycheck_[yyx + yyn] == yyx && yyx != SymbolKind.]b4_symbol(1, kind)[.getCode ()
&& !yyTableValueIsError (yytable_[yyx + yyn]))
if (yycheck_[yyx + yyn] == yyx && yyx != ]b4_symbol(1, kind)[.getCode()
&& !yyTableValueIsError(yytable_[yyx + yyn]))
{
if (yyarg == null)
yycount += 1;
else if (yycount == yyargn)
return 0; // FIXME: this is incorrect.
else
yyarg[yycount++] = SymbolKind.get (yyx);
yyarg[yycount++] = SymbolKind.get(yyx);
}
}
if (yyarg != null && yycount == yyoffset && yyoffset < yyargn)
@@ -981,12 +982,12 @@ b4_dollar_popdef[]dnl
to an error action in a later state.
*/
int yycount = 0;
if (yyctx.getToken () != null)
if (yyctx.getToken() != null)
{
if (yyarg != null)
yyarg[yycount] = yyctx.getToken ();
yyarg[yycount] = yyctx.getToken();
yycount += 1;
yycount += yyctx.getExpectedTokens (yyarg, 1, yyargn);
yycount += yyctx.getExpectedTokens(yyarg, 1, yyargn);
}
return yycount;
}
@@ -1071,27 +1072,28 @@ b4_dollar_popdef[]dnl
/* The symbols being reduced. */
for (int yyi = 0; yyi < yynrhs; yyi++)
yySymbolPrint(" $" + (yyi + 1) + " =",
SymbolKind.get (yystos_[yystack.stateAt (yynrhs - (yyi + 1))]),
SymbolKind.get(yystos_[yystack.stateAt (yynrhs - (yyi + 1))]),
]b4_rhs_data(yynrhs, yyi + 1)b4_locations_if([,
b4_rhs_location(yynrhs, yyi + 1)])[);
}]])[
/* YYTRANSLATE_(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM
as returned by yylex, with out-of-bounds checking. */
private static final SymbolKind yytranslate_ (int t)
private static final SymbolKind yytranslate_(int t)
]b4_api_token_raw_if(dnl
[[ {
return SymbolKind.get (t);
return SymbolKind.get(t);
}
]],
[[ {
int user_token_number_max_ = ]b4_user_token_number_max[;
// Last valid token kind.
int code_max = ]b4_code_max[;
if (t <= 0)
return SymbolKind.]b4_symbol_prefix[YYEOF;
else if (t <= user_token_number_max_)
return SymbolKind.get (yytranslate_table_[t]);
return ]b4_symbol(0, kind)[;
else if (t <= code_max)
return SymbolKind.get(yytranslate_table_[t]);
else
return SymbolKind.]b4_symbol_prefix[YYUNDEF;
return ]b4_symbol(2, kind)[;
}
]b4_integral_parser_table_define([translate_table], [b4_translate])[
]])[
+10 -6
View File
@@ -48,7 +48,7 @@ m4_ifdef([b4_location_file],
["b4_location_file"])])
m4_define([b4_location_path],
b4_percent_define_get([[api.location.include]],
["b4_dir_prefix[]b4_location_file"]))
["b4_mapped_dir_prefix[]b4_location_file"]))
m4_define([b4_location_path],
m4_substr(m4_defn([b4_location_path]), 1, m4_eval(m4_len(m4_defn([b4_location_path])) - 2)))
])
@@ -63,11 +63,13 @@ m4_define([b4_location_define],
class position
{
public:
/// Type for file name.
typedef ]b4_percent_define_get([[api.filename.type]])[ filename_type;
/// Type for line and column numbers.
typedef int counter_type;
]m4_ifdef([b4_location_constructors], [[
/// Construct a position.
explicit position (]b4_percent_define_get([[filename_type]])[* f = YY_NULLPTR,
explicit position (filename_type* f = YY_NULLPTR,
counter_type l = ]b4_location_initial_line[,
counter_type c = ]b4_location_initial_column[)
: filename (f)
@@ -77,7 +79,7 @@ m4_define([b4_location_define],
]])[
/// Initialization.
void initialize (]b4_percent_define_get([[filename_type]])[* fn = YY_NULLPTR,
void initialize (filename_type* fn = YY_NULLPTR,
counter_type l = ]b4_location_initial_line[,
counter_type c = ]b4_location_initial_column[)
{
@@ -106,7 +108,7 @@ m4_define([b4_location_define],
/** \} */
/// File name to which this position refers.
]b4_percent_define_get([[filename_type]])[* filename;
filename_type* filename;
/// Current line number.
counter_type line;
/// Current column number.
@@ -184,6 +186,8 @@ m4_define([b4_location_define],
class location
{
public:
/// Type for file name.
typedef position::filename_type filename_type;
/// Type for line and column numbers.
typedef position::counter_type counter_type;
]m4_ifdef([b4_location_constructors], [
@@ -200,7 +204,7 @@ m4_define([b4_location_define],
{}
/// Construct a 0-width location in \a f, \a l, \a c.
explicit location (]b4_percent_define_get([[filename_type]])[* f,
explicit location (filename_type* f,
counter_type l = ]b4_location_initial_line[,
counter_type c = ]b4_location_initial_column[)
: begin (f, l, c)
@@ -209,7 +213,7 @@ m4_define([b4_location_define],
])[
/// Initialization.
void initialize (]b4_percent_define_get([[filename_type]])[* f = YY_NULLPTR,
void initialize (filename_type* f = YY_NULLPTR,
counter_type l = ]b4_location_initial_line[,
counter_type c = ]b4_location_initial_column[)
{
+2
View File
@@ -0,0 +1,2 @@
dnl GNU M4 treats -dV in a position-independent manner.
m4_debugmode(V)m4_traceon()dnl
+1 -1
View File
@@ -392,7 +392,7 @@ m4_define([_b4_type_clause],
[b4_symbol_if([$1], [is_token],
[b4_symbol_if([$1], [has_id],
[tok == token::b4_symbol([$1], [id])],
[tok == b4_symbol([$1], [user_number])])])])
[tok == b4_symbol([$1], [code])])])])
# _b4_token_constructor_define(SYMBOL-NUM...)
+97 -95
View File
@@ -48,6 +48,10 @@ m4_define([b4_pure_if],
## api.push-pull. ##
## --------------- ##
# b4_pull_if, b4_push_if
# ----------------------
# Whether the pull/push APIs are needed. Both can be enabled.
b4_percent_define_default([[api.push-pull]], [[pull]])
b4_percent_define_check_values([[[[api.push-pull]],
[[pull]], [[push]], [[both]]]])
@@ -155,7 +159,7 @@ m4_define([b4_rhs_location],
# Declare the variables that are global, or local to YYPARSE if
# pure-parser.
m4_define([b4_declare_scanner_communication_variables], [[
/* The lookahead symbol. */
/* Lookahead token kind. */
int yychar;
]b4_pure_if([[
@@ -176,68 +180,47 @@ YYLTYPE yylloc]b4_yyloc_default[;]])[
int yynerrs;]])])
# b4_declare_parser_state_variables
# ---------------------------------
# b4_declare_parser_state_variables([INIT])
# -----------------------------------------
# Declare all the variables that are needed to maintain the parser state
# between calls to yypush_parse.
# If INIT is non-null, initialize these variables.
m4_define([b4_declare_parser_state_variables],
[b4_pure_if([[
/* Number of syntax errors so far. */
int yynerrs;
int yynerrs]m4_ifval([$1], [ = 0])[;
]])[
yy_state_fast_t yystate;
yy_state_fast_t yystate]m4_ifval([$1], [ = 0])[;
/* Number of tokens to shift before error messages enabled. */
int yyerrstatus;
int yyerrstatus]m4_ifval([$1], [ = 0])[;
/* The stacks and their tools:
'yyss': related to states.
'yyvs': related to semantic values.]b4_locations_if([[
'yyls': related to locations.]])[
Refer to the stacks through separate pointers, to allow yyoverflow
/* Refer to the stacks through separate pointers, to allow yyoverflow
to reallocate them elsewhere. */
/* Their size. */
YYPTRDIFF_T yystacksize;
YYPTRDIFF_T yystacksize]m4_ifval([$1], [ = YYINITDEPTH])[;
/* The state stack. */
/* The state stack: array, bottom, top. */
yy_state_t yyssa[YYINITDEPTH];
yy_state_t *yyss;
yy_state_t *yyssp;
yy_state_t *yyss]m4_ifval([$1], [ = yyssa])[;
yy_state_t *yyssp]m4_ifval([$1], [ = yyss])[;
/* The semantic value stack. */
/* The semantic value stack: array, bottom, top. */
YYSTYPE yyvsa[YYINITDEPTH];
YYSTYPE *yyvs;
YYSTYPE *yyvsp;]b4_locations_if([[
YYSTYPE *yyvs]m4_ifval([$1], [ = yyvsa])[;
YYSTYPE *yyvsp]m4_ifval([$1], [ = yyvs])[;]b4_locations_if([[
/* The location stack. */
/* The location stack: array, bottom, top. */
YYLTYPE yylsa[YYINITDEPTH];
YYLTYPE *yyls;
YYLTYPE *yylsp;]])[]b4_lac_if([[
YYLTYPE *yyls]m4_ifval([$1], [ = yylsa])[;
YYLTYPE *yylsp]m4_ifval([$1], [ = yyls])[;]])[]b4_lac_if([[
yy_state_t yyesa@{]b4_percent_define_get([[parse.lac.es-capacity-initial]])[@};
yy_state_t *yyes;
YYPTRDIFF_T yyes_capacity;]])])
# b4_initialize_parser_state_variables
# ------------------------------------
# Initialize these variables.
m4_define([b4_initialize_parser_state_variables],
[[ yynerrs = 0;
yystate = 0;
yyerrstatus = 0;
yystacksize = YYINITDEPTH;
yyssp = yyss = yyssa;
yyvsp = yyvs = yyvsa;]b4_locations_if([[
yylsp = yyls = yylsa;]])[]b4_lac_if([[
yyes = yyesa;
yyes_capacity = ]b4_percent_define_get([[parse.lac.es-capacity-initial]])[;
if (YYMAXDEPTH < yyes_capacity)
yyes_capacity = YYMAXDEPTH;]])[
]])
yy_state_t *yyes]m4_ifval([$1], [ = yyesa])[;
YYPTRDIFF_T yyes_capacity][]m4_ifval([$1],
[m4_do([ = b4_percent_define_get([[parse.lac.es-capacity-initial]]) < YYMAXDEPTH],
[ ? b4_percent_define_get([[parse.lac.es-capacity-initial]])],
[ : YYMAXDEPTH])])[;]])])
m4_define([b4_macro_define],
@@ -313,14 +296,14 @@ m4_define([b4_declare_yyparse],
# Declaration that might either go into the header (if --defines)
# or open coded in the parser body.
m4_define([b4_shared_declarations],
[b4_cpp_guard_open([b4_spec_header_file])[
[b4_cpp_guard_open([b4_spec_mapped_header_file])[
]b4_declare_yydebug[
]b4_percent_code_get([[requires]])[
]b4_token_enums_defines[
]b4_declare_yylstype[
]b4_declare_yyparse[
]b4_percent_code_get([[provides]])[
]b4_cpp_guard_close([b4_spec_header_file])[]dnl
]b4_cpp_guard_close([b4_spec_mapped_header_file])[]dnl
])
@@ -335,7 +318,7 @@ m4_define([b4_header_include_if],
[$2])],
[$2])])
m4_if(b4_spec_header_file, [[y.tab.h]],
m4_if(b4_spec_header_file, [y.tab.h], [],
[b4_percent_define_default([[api.header.include]],
[["@basename(]b4_spec_header_file[@)"]])])
@@ -592,7 +575,8 @@ union yyalloc
/* YYNSTATES -- Number of states. */
#define YYNSTATES ]b4_states_number[
#define YYMAXUTOK ]b4_user_token_number_max[
/* YYMAXUTOK -- Last valid token kind. */
#define YYMAXUTOK ]b4_code_max[
/* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM
@@ -829,7 +813,8 @@ int yydebug;
/* Parser data structure. */
struct yypstate
{]b4_declare_parser_state_variables[
/* Whether this instance has not started parsing yet. */
/* Whether this instance has not started parsing yet.
* If 2, it corresponds to a finished parsing. */
int yynew;
};]b4_pure_if([], [[
@@ -1444,49 +1429,54 @@ yysyntax_error (YYPTRDIFF_T *yymsg_alloc, char **yymsg,
int
yyparse (]m4_ifset([b4_parse_param], [b4_formals(b4_parse_param)], [void])[)
{
return yypull_parse (YY_NULLPTR]b4_user_args[);
yypstate *yyps = yypstate_new ();
if (!yyps)
{]b4_pure_if([b4_locations_if([[
static YYLTYPE yyloc_default][]b4_yyloc_default[;
YYLTYPE yylloc = yyloc_default;]])[
yyerror (]b4_yyerror_args[YY_("memory exhausted"));]], [[
if (!yypstate_allocated)
yyerror (]b4_yyerror_args[YY_("memory exhausted"));]])[
return 2;
}
int yystatus = yypull_parse (yyps]b4_user_args[);
yypstate_delete (yyps);
return yystatus;
}
int
yypull_parse (yypstate *yyps]b4_user_formals[)
{]b4_pure_if([b4_locations_if([[
{
YY_ASSERT (yyps);]b4_pure_if([b4_locations_if([[
static YYLTYPE yyloc_default][]b4_yyloc_default[;
YYLTYPE yylloc = yyloc_default;]])])[
yypstate *yyps_local;
if (yyps)
yyps_local = yyps;
else
{
yyps_local = yypstate_new ();
if (!yyps_local)
{]b4_pure_if([[
yyerror (]b4_yyerror_args[YY_("memory exhausted"));]], [[
if (!yypstate_allocated)
yyerror (]b4_yyerror_args[YY_("memory exhausted"));]])[
return 2;
}
}
int yystatus;
do {
]b4_pure_if([[ YYSTYPE yylval;
int ]])[yychar = ]b4_lex[;
yystatus = yypush_parse (yyps_local]b4_pure_if([[, yychar, &yylval]b4_locations_if([[, &yylloc]])])m4_ifset([b4_parse_param], [, b4_args(b4_parse_param)])[);
yystatus = yypush_parse (yyps]b4_pure_if([[, yychar, &yylval]b4_locations_if([[, &yylloc]])])m4_ifset([b4_parse_param], [, b4_args(b4_parse_param)])[);
} while (yystatus == YYPUSH_MORE);
if (!yyps)
yypstate_delete (yyps_local);
return yystatus;
}]])[
]b4_parse_state_variable_macros([b4_pstate_macro_define])[
/* Initialize the parser data structure. */
void
static void
yypstate_clear (yypstate *yyps)
{
]b4_initialize_parser_state_variables[
yynerrs = 0;
yystate = 0;
yyerrstatus = 0;
yyssp = yyss;
yyvsp = yyvs;]b4_locations_if([[
yylsp = yyls;]])[
/* Initialize the state stack, in case yypcontext_expected_tokens is
called before the first call to yyparse. */
*yyssp = 0;
yyps->yynew = 1;
}
/* Initialize the parser data structure. */
@@ -1498,9 +1488,16 @@ yypstate_new (void)
return YY_NULLPTR;]])[
yyps = YY_CAST (yypstate *, malloc (sizeof *yyps));
if (!yyps)
return YY_NULLPTR;
yyps->yynew = 1;]b4_pure_if([], [[
return YY_NULLPTR;]b4_pure_if([], [[
yypstate_allocated = 1;]])[
yystacksize = YYINITDEPTH;
yyss = yyssa;
yyvs = yyvsa;]b4_locations_if([[
yyls = yylsa;]])[]b4_lac_if([[
yyes = yyesa;
yyes_capacity = ]b4_percent_define_get([[parse.lac.es-capacity-initial]])[;
if (YYMAXDEPTH < yyes_capacity)
yyes_capacity = YYMAXDEPTH;]])[
yypstate_clear (yyps);
return yyps;
}
@@ -1513,10 +1510,10 @@ yypstate_delete (yypstate *yyps)
#ifndef yyoverflow
/* If the stack was reallocated but the parse did not complete, then the
stack still needs to be freed. */
if (!yyps->yynew && yyss != yyssa)
if (yyss != yyssa)
YYSTACK_FREE (yyss);
#endif]b4_lac_if([[
if (!yyps->yynew && yyes != yyesa)
if (yyes != yyesa)
YYSTACK_FREE (yyes);]])[
free (yyps);]b4_pure_if([], [[
yypstate_allocated = 0;]])[
@@ -1545,14 +1542,14 @@ yyparse (]m4_ifset([b4_parse_param], [b4_formals(b4_parse_param)], [void])[)]])[
YYSTYPE yypushed_val = yylval;]b4_locations_if([[
YYLTYPE yypushed_loc = yylloc;]])
])],
[b4_declare_parser_state_variables
[b4_declare_parser_state_variables([init])
])b4_lac_if([[
/* Whether LAC context is established. A Boolean. */
int yy_lac_established = 0;]])[
int yyn;
/* The return value of yyparse. */
int yyresult;
/* Lookahead token as an internal (translated) token number. */
/* Lookahead symbol kind. */
yysymbol_kind_t yytoken = ]b4_symbol(-2, kind)[;
/* The variables used to return semantic value and location from the
action routines. */
@@ -1572,14 +1569,19 @@ yyparse (]m4_ifset([b4_parse_param], [b4_formals(b4_parse_param)], [void])[)]])[
/* The number of symbols on the RHS of the reduced rule.
Keep to zero when no symbol should be popped. */
int yylen = 0;
]b4_push_if([[
if (!yyps->yynew)
int yylen = 0;]b4_push_if([[
switch (yyps->yynew)
{
case 2:
yypstate_clear (yyps);
goto case_0;
case_0:
case 0:
yyn = yypact[yystate];
goto yyread_pushed_token;
}]], [
b4_initialize_parser_state_variables])[
}]])[
YYDPRINTF ((stderr, "Starting parse\n"));
@@ -2048,13 +2050,13 @@ yyabortlab:
yyexhaustedlab:
yyerror (]b4_yyerror_args[YY_("memory exhausted"));
yyresult = 2;
/* Fall through. */
goto yyreturn;
#endif
/*-----------------------------------------------------.
| yyreturn -- parsing is finished, return the result. |
`-----------------------------------------------------*/
/*-------------------------------------------------------.
| yyreturn -- parsing is finished, clean up and return. |
`-------------------------------------------------------*/
yyreturn:
if (yychar != ]b4_symbol(-2, id)[)
{
@@ -2073,21 +2075,21 @@ yyreturn:
yydestruct ("Cleanup: popping",
YY_ACCESSING_SYMBOL (+*yyssp), yyvsp]b4_locations_if([, yylsp])[]b4_user_args[);
YYPOPSTACK (1);
}
}]b4_push_if([[
yyps->yynew = 2;
goto yypushreturn;
/*-------------------------.
| yypushreturn -- return. |
`-------------------------*/
yypushreturn:]], [[
#ifndef yyoverflow
if (yyss != yyssa)
YYSTACK_FREE (yyss);
#endif]b4_lac_if([[
if (yyes != yyesa)
YYSTACK_FREE (yyes);]])b4_push_if([[
yypstate_clear (yyps);
yyps->yynew = 1;
/*-----------------------------------------.
| yypushreturn -- ask for the next token. |
`-----------------------------------------*/
yypushreturn:]])[
YYSTACK_FREE (yyes);]])])[
]b4_parse_error_bmatch([detailed\|verbose],
[[ if (yymsg != yymsgbuf)
YYSTACK_FREE (yymsg);]])[
+4 -4
View File
@@ -159,7 +159,7 @@
<xsl:param name="prev-rule-number"
select="preceding-sibling::item[1]/@rule-number"/>
<xsl:apply-templates select="key('bison:ruleByNumber', @rule-number)">
<xsl:with-param name="point" select="@point"/>
<xsl:with-param name="dot" select="@dot"/>
<xsl:with-param name="num" select="@rule-number"/>
<xsl:with-param name="prev-lhs"
select="key('bison:ruleByNumber', $prev-rule-number)/lhs[text()]"
@@ -169,7 +169,7 @@
</xsl:template>
<xsl:template match="rule">
<xsl:param name="point"/>
<xsl:param name="dot"/>
<xsl:param name="num"/>
<xsl:param name="prev-lhs"/>
<xsl:text>&#10;</xsl:text>
@@ -198,14 +198,14 @@
<xsl:text>:</xsl:text>
</xsl:otherwise>
</xsl:choose>
<xsl:if test="$point = 0">
<xsl:if test="$dot = 0">
<xsl:text> .</xsl:text>
</xsl:if>
<!-- RHS -->
<xsl:for-each select="rhs/symbol|rhs/empty">
<xsl:apply-templates select="."/>
<xsl:if test="$point = position()">
<xsl:if test="$dot = position()">
<xsl:text> .</xsl:text>
</xsl:if>
</xsl:for-each>
+18 -10
View File
@@ -52,7 +52,7 @@
<xsl:if test="nonterminal[@usefulness='useless-in-grammar']">
<xsl:text>Nonterminals useless in grammar&#10;&#10;</xsl:text>
<xsl:for-each select="nonterminal[@usefulness='useless-in-grammar']">
<xsl:text> </xsl:text>
<xsl:text> </xsl:text>
<xsl:value-of select="@name"/>
<xsl:text>&#10;</xsl:text>
</xsl:for-each>
@@ -65,7 +65,7 @@
<xsl:text>Terminals unused in grammar&#10;&#10;</xsl:text>
<xsl:for-each select="terminal[@usefulness='unused-in-grammar']">
<xsl:sort select="@symbol-number" data-type="number"/>
<xsl:text> </xsl:text>
<xsl:text> </xsl:text>
<xsl:value-of select="@name"/>
<xsl:text>&#10;</xsl:text>
</xsl:for-each>
@@ -136,6 +136,7 @@
</xsl:template>
<xsl:template match="terminal">
<xsl:text> </xsl:text>
<xsl:value-of select="@name"/>
<xsl:call-template name="line-wrap">
<xsl:with-param name="first-line-length">
@@ -148,6 +149,9 @@
</xsl:with-param>
<xsl:with-param name="line-length" select="66" />
<xsl:with-param name="text">
<xsl:if test="string-length(@type) != 0">
<xsl:value-of select="concat(' &lt;', @type, '&gt;')"/>
</xsl:if>
<xsl:value-of select="concat(' (', @token-number, ')')"/>
<xsl:for-each select="key('bison:ruleByRhs', @name)">
<xsl:value-of select="concat(' ', @number)"/>
@@ -157,14 +161,18 @@
</xsl:template>
<xsl:template match="nonterminal">
<xsl:text> </xsl:text>
<xsl:value-of select="@name"/>
<xsl:if test="string-length(@type) != 0">
<xsl:value-of select="concat(' &lt;', @type, '&gt;')"/>
</xsl:if>
<xsl:value-of select="concat(' (', @symbol-number, ')')"/>
<xsl:text>&#10;</xsl:text>
<xsl:variable name="output">
<xsl:call-template name="line-wrap">
<xsl:with-param name="line-length" select="66" />
<xsl:with-param name="text">
<xsl:text> </xsl:text>
<xsl:text> </xsl:text>
<xsl:if test="key('bison:ruleByLhs', @name)">
<xsl:text>on@left:</xsl:text>
<xsl:for-each select="key('bison:ruleByLhs', @name)">
@@ -173,7 +181,7 @@
</xsl:if>
<xsl:if test="key('bison:ruleByRhs', @name)">
<xsl:if test="key('bison:ruleByLhs', @name)">
<xsl:text>, </xsl:text>
<xsl:text>&#10; </xsl:text>
</xsl:if>
<xsl:text>on@right:</xsl:text>
<xsl:for-each select="key('bison:ruleByRhs', @name)">
@@ -300,7 +308,7 @@
name="prev-lhs"
select="key('bison:ruleByNumber', $prev-rule-number)/lhs[text()]"
/>
<xsl:with-param name="point" select="@point"/>
<xsl:with-param name="dot" select="@dot"/>
<xsl:with-param name="lookaheads">
<xsl:apply-templates select="lookaheads"/>
</xsl:with-param>
@@ -311,7 +319,7 @@
<xsl:param name="itemset"/>
<xsl:param name="pad"/>
<xsl:param name="prev-lhs"/>
<xsl:param name="point"/>
<xsl:param name="dot"/>
<xsl:param name="lookaheads"/>
<xsl:if test="$itemset != 'true' and not($prev-lhs = lhs[text()])">
@@ -347,12 +355,12 @@
<!-- RHS -->
<xsl:for-each select="rhs/*">
<xsl:if test="position() = $point + 1">
<xsl:text> .</xsl:text>
<xsl:if test="position() = $dot + 1">
<xsl:text> </xsl:text>
</xsl:if>
<xsl:apply-templates select="."/>
<xsl:if test="position() = last() and position() = $point">
<xsl:text> .</xsl:text>
<xsl:if test="position() = last() and position() = $dot">
<xsl:text> </xsl:text>
</xsl:if>
</xsl:for-each>
<xsl:if test="$lookaheads">
+79 -55
View File
@@ -75,7 +75,7 @@
ol.lower-alpha {
list-style-type: lower-alpha;
}
.point {
.dot {
color: #cc0000;
}
#footer {
@@ -227,6 +227,7 @@
<xsl:text>&#10;</xsl:text>
<p class="pre">
<xsl:call-template name="style-rule-set">
<xsl:with-param name="anchor" select="'true'" />
<xsl:with-param
name="rule-set" select="rules/rule[@usefulness!='useless-in-grammar']"
/>
@@ -238,9 +239,11 @@
</xsl:template>
<xsl:template name="style-rule-set">
<xsl:param name="anchor"/>
<xsl:param name="rule-set"/>
<xsl:for-each select="$rule-set">
<xsl:apply-templates select=".">
<xsl:with-param name="anchor" select="$anchor"/>
<xsl:with-param name="pad" select="'3'"/>
<xsl:with-param name="prev-lhs">
<xsl:if test="position()>1">
@@ -306,9 +309,10 @@
<xsl:text> Terminals, with rules where they appear</xsl:text>
</h3>
<xsl:text>&#10;&#10;</xsl:text>
<p class="pre">
<ul>
<xsl:text>&#10;</xsl:text>
<xsl:apply-templates select="terminal"/>
</p>
</ul>
<xsl:text>&#10;&#10;</xsl:text>
</xsl:template>
@@ -318,41 +322,64 @@
<xsl:text> Nonterminals, with rules where they appear</xsl:text>
</h3>
<xsl:text>&#10;&#10;</xsl:text>
<p class="pre">
<ul>
<xsl:text>&#10;</xsl:text>
<xsl:apply-templates
select="nonterminal[@usefulness!='useless-in-grammar']"
/>
</p>
</ul>
</xsl:template>
<xsl:template match="terminal">
<b><xsl:value-of select="@name"/></b>
<xsl:value-of select="concat(' (', @token-number, ')')"/>
<xsl:for-each select="key('bison:ruleByRhs', @name)">
<xsl:apply-templates select="." mode="number-link"/>
</xsl:for-each>
<xsl:text> </xsl:text>
<li>
<b><xsl:value-of select="@name"/></b>
<xsl:if test="string-length(@type) != 0">
<xsl:value-of select="concat(' &lt;', @type, '&gt;')"/>
</xsl:if>
<xsl:value-of select="concat(' (', @token-number, ')')"/>
<xsl:for-each select="key('bison:ruleByRhs', @name)">
<xsl:apply-templates select="." mode="number-link"/>
</xsl:for-each>
</li>
<xsl:text>&#10;</xsl:text>
</xsl:template>
<xsl:template match="nonterminal">
<b><xsl:value-of select="@name"/></b>
<xsl:value-of select="concat(' (', @symbol-number, ')')"/>
<xsl:text>&#10; </xsl:text>
<xsl:if test="key('bison:ruleByLhs', @name)">
<xsl:text>on left:</xsl:text>
<xsl:for-each select="key('bison:ruleByLhs', @name)">
<xsl:apply-templates select="." mode="number-link"/>
</xsl:for-each>
</xsl:if>
<xsl:if test="key('bison:ruleByRhs', @name)">
<xsl:if test="key('bison:ruleByLhs', @name)">
<xsl:text>&#10; </xsl:text>
<xsl:text> </xsl:text>
<li>
<b><xsl:value-of select="@name"/></b>
<xsl:if test="string-length(@type) != 0">
<xsl:value-of select="concat(' &lt;', @type, '&gt;')"/>
</xsl:if>
<xsl:text>on right:</xsl:text>
<xsl:for-each select="key('bison:ruleByRhs', @name)">
<xsl:apply-templates select="." mode="number-link"/>
</xsl:for-each>
</xsl:if>
<xsl:value-of select="concat(' (', @symbol-number, ')')"/>
<xsl:text>&#10; </xsl:text>
<ul>
<xsl:text>&#10;</xsl:text>
<xsl:if test="key('bison:ruleByLhs', @name)">
<xsl:text> </xsl:text>
<li>
<xsl:text>on left:</xsl:text>
<xsl:for-each select="key('bison:ruleByLhs', @name)">
<xsl:apply-templates select="." mode="number-link"/>
</xsl:for-each>
</li>
<xsl:text>&#10;</xsl:text>
</xsl:if>
<xsl:if test="key('bison:ruleByRhs', @name)">
<xsl:text> </xsl:text>
<li>
<xsl:text>on right:</xsl:text>
<xsl:for-each select="key('bison:ruleByRhs', @name)">
<xsl:apply-templates select="." mode="number-link"/>
</xsl:for-each>
</li>
<xsl:text>&#10;</xsl:text>
</xsl:if>
<xsl:text> </xsl:text>
</ul>
<xsl:text>&#10; </xsl:text>
</li>
<xsl:text>&#10;</xsl:text>
</xsl:template>
@@ -385,7 +412,7 @@
<xsl:value-of select="concat('state_', @number)"/>
</xsl:attribute>
</a>
<xsl:text>state </xsl:text>
<xsl:text>State </xsl:text>
<xsl:value-of select="@number"/>
</h3>
<xsl:text>&#10;&#10;</xsl:text>
@@ -457,35 +484,44 @@
<xsl:with-param name="prev-lhs"
select="key('bison:ruleByNumber', $prev-rule-number)/lhs[text()]"
/>
<xsl:with-param name="point" select="@point"/>
<xsl:with-param name="dot" select="@dot"/>
<xsl:with-param name="lookaheads">
<xsl:apply-templates select="lookaheads"/>
</xsl:with-param>
</xsl:apply-templates>
</xsl:template>
<!--
anchor = 'true': define as an <a> anchor.
itemset = 'true': show the items.
-->
<xsl:template match="rule">
<xsl:param name="anchor"/>
<xsl:param name="itemset"/>
<xsl:param name="pad"/>
<xsl:param name="prev-lhs"/>
<xsl:param name="point"/>
<xsl:param name="dot"/>
<xsl:param name="lookaheads"/>
<xsl:if test="$itemset != 'true' and not($prev-lhs = lhs[text()])">
<xsl:text>&#10;</xsl:text>
</xsl:if>
<xsl:if test="$itemset != 'true'">
<a>
<xsl:attribute name="name">
<xsl:value-of select="concat('rule_', @number)"/>
</xsl:attribute>
</a>
</xsl:if>
<xsl:text> </xsl:text>
<xsl:choose>
<xsl:when test="$itemset = 'true'">
<xsl:when test="$anchor = 'true'">
<a>
<xsl:attribute name="name">
<xsl:value-of select="concat('rule_', @number)"/>
</xsl:attribute>
<xsl:call-template name="lpad">
<xsl:with-param name="str" select="string(@number)"/>
<xsl:with-param name="pad" select="number($pad)"/>
</xsl:call-template>
</a>
</xsl:when>
<xsl:otherwise>
<a>
<xsl:attribute name="href">
<xsl:value-of select="concat('#rule_', @number)"/>
@@ -495,25 +531,13 @@
<xsl:with-param name="pad" select="number($pad)"/>
</xsl:call-template>
</a>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="lpad">
<xsl:with-param name="str" select="string(@number)"/>
<xsl:with-param name="pad" select="number($pad)"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
<xsl:text> </xsl:text>
<!-- LHS -->
<xsl:choose>
<xsl:when test="$itemset != 'true' and $prev-lhs = lhs[text()]">
<xsl:call-template name="lpad">
<xsl:with-param name="str" select="'|'"/>
<xsl:with-param name="pad" select="number(string-length(lhs[text()])) + 2"/>
</xsl:call-template>
</xsl:when>
<xsl:when test="$itemset = 'true' and $prev-lhs = lhs[text()]">
<xsl:when test="$prev-lhs = lhs[text()]">
<xsl:call-template name="lpad">
<xsl:with-param name="str" select="'|'"/>
<xsl:with-param name="pad" select="number(string-length(lhs[text()])) + 2"/>
@@ -529,14 +553,14 @@
<!-- RHS -->
<xsl:for-each select="rhs/*">
<xsl:if test="position() = $point + 1">
<xsl:if test="position() = $dot + 1">
<xsl:text> </xsl:text>
<span class="point">.</span>
<span class="dot">&#x2022;</span>
</xsl:if>
<xsl:apply-templates select="."/>
<xsl:if test="position() = last() and position() = $point">
<xsl:if test="position() = last() and position() = $dot">
<xsl:text> </xsl:text>
<span class="point">.</span>
<span class="dot">&#x2022;</span>
</xsl:if>
</xsl:for-each>
<xsl:if test="$lookaheads">
+19 -14
View File
@@ -1,4 +1,4 @@
# Doxyfile 1.8.17
# Doxyfile 1.8.18
# This file describes the settings to be used by the documentation system
# doxygen (www.doxygen.org) for a project.
@@ -253,12 +253,6 @@ TAB_SIZE = 8
ALIASES =
# This tag can be used to specify a number of word-keyword mappings (TCL only).
# A mapping has the form "name=value". For example adding "class=itcl::class"
# will allow you to use the command class in the itcl::class meaning.
TCL_SUBST =
# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
# only. Doxygen will then generate output that is more tailored for C. For
# instance, some of the names that are used will be different. The list of all
@@ -300,13 +294,13 @@ OPTIMIZE_OUTPUT_SLICE = NO
# extension. Doxygen has a built-in mapping, but you can override or extend it
# using this tag. The format is ext=language, where ext is a file extension, and
# language is one of the parsers supported by doxygen: IDL, Java, JavaScript,
# Csharp (C#), C, C++, D, PHP, md (Markdown), Objective-C, Python, Slice,
# Csharp (C#), C, C++, D, PHP, md (Markdown), Objective-C, Python, Slice, VHDL,
# Fortran (fixed format Fortran: FortranFixed, free formatted Fortran:
# FortranFree, unknown formatted Fortran: Fortran. In the later case the parser
# tries to guess whether the code is fixed or free formatted code, this is the
# default for Fortran type files), VHDL, tcl. For instance to make doxygen treat
# .inc files as Fortran files (default is PHP), and .f files as C (default is
# Fortran), use: inc=Fortran f=C.
# default for Fortran type files). For instance to make doxygen treat .inc files
# as Fortran files (default is PHP), and .f files as C (default is Fortran),
# use: inc=Fortran f=C.
#
# Note: For files without extension you can use no_extension as a placeholder.
#
@@ -844,7 +838,7 @@ INPUT_ENCODING = UTF-8
# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc,
# *.m, *.markdown, *.md, *.mm, *.dox (to be provided as doxygen C comment),
# *.doc (to be provided as doxygen C comment), *.txt (to be provided as doxygen
# C comment), *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, *.f, *.for, *.tcl, *.vhd,
# C comment), *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, *.f18, *.f, *.for, *.vhd,
# *.vhdl, *.ucf, *.qsf and *.ice.
FILE_PATTERNS = *.c \
@@ -1490,6 +1484,17 @@ TREEVIEW_WIDTH = 250
EXT_LINKS_IN_WINDOW = NO
# If the HTML_FORMULA_FORMAT option is set to svg, doxygen will use the pdf2svg
# tool (see https://github.com/dawbarton/pdf2svg) or inkscape (see
# https://inkscape.org) to generate formulas as SVG images instead of PNGs for
# the HTML output. These images will generally look nicer at scaled resolutions.
# Possible values are: png The default and svg Looks nicer but requires the
# pdf2svg tool.
# The default value is: png.
# This tag requires that the tag GENERATE_HTML is set to YES.
HTML_FORMULA_FORMAT = png
# Use this tag to change the font size of LaTeX formulas included as images in
# the HTML documentation. When you change the font size after a successful
# doxygen run you need to manually remove any form_*.png images from the HTML
@@ -1545,7 +1550,7 @@ MATHJAX_FORMAT = HTML-CSS
# Content Delivery Network so you can quickly see the result without installing
# MathJax. However, it is strongly recommended to install a local copy of
# MathJax from https://www.mathjax.org before deployment.
# The default value is: https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/.
# The default value is: https://cdn.jsdelivr.net/npm/mathjax@2.
# This tag requires that the tag USE_MATHJAX is set to YES.
MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest
@@ -1715,7 +1720,7 @@ COMPACT_LATEX = NO
# The default value is: a4.
# This tag requires that the tag GENERATE_LATEX is set to YES.
PAPER_TYPE = a4wide
PAPER_TYPE = a4
# The EXTRA_PACKAGES tag can be used to specify one or more LaTeX package names
# that should be included in the LaTeX output. The package can be specified just
+1059 -300
View File
File diff suppressed because it is too large Load Diff
+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;
+1 -1
View File
@@ -3,7 +3,7 @@ digraph "reduce.y"
node [fontname=courier shape=box]
edge [fontname=courier]
1 [label="State 1\n 3 a: \"0\" . [\".\"]\l 4 b: \"0\" . [\";\"]\l"]
1 [label="State 1\n 3 a: \"0\" [\".\"]\l 4 b: \"0\" [\";\"]\l"]
1 -> "1R3" [label="" style=solid]
"1R3" [style=filled shape=diamond fillcolor=yellowgreen label="R3"]
1 -> "1R4" [label="[\";\"]" style=solid]
+2 -2
View File
@@ -1,7 +1,7 @@
.------------------.
| State 1 |
| 3 a: "0" . [";"] |
| 4 b: "0" . ["."] |
| 3 a: "0" [";"] |
| 4 b: "0" ["."] |
`------------------'
/ \
/ \ ["."]
+2 -2
View File
@@ -3,7 +3,7 @@ digraph "shift.y"
node [fontname=courier shape=box]
edge [fontname=courier]
3 [label="State 3\n 1 exp: a . \".\"\l"]
3 [label="State 3\n 1 exp: a \".\"\l"]
3 -> 6 [style=solid label="\".\""]
6 [label="State 6\n 1 exp: a \".\" .\l"]
6 [label="State 6\n 1 exp: a \".\" \l"]
}
+2 -2
View File
@@ -1,6 +1,6 @@
.----------------.
| State 3 |
| 1 exp: a . ";" |
| 1 exp: a ";" |
`----------------'
|
| ";"
@@ -8,5 +8,5 @@
v
.----------------.
| State 6 |
| 1 exp: a ";" . |
| 1 exp: a ";" |
`----------------'
+9 -9
View File
@@ -2,34 +2,34 @@
// Report bugs to <[email protected]>.
// Home page: <http://www.gnu.org/software/bison/>.
digraph "/tmp/fo.y"
digraph "example.y"
{
node [fontname = courier, shape = box, colorscheme = paired6]
edge [fontname = courier]
0 [label="State 0\n\l 0 $accept: . exp $end\l 1 exp: . a \";\"\l 2 | . b \".\"\l 3 a: . \"0\"\l 4 b: . \"0\"\l"]
0 [label="State 0\n\l 0 $accept: exp $end\l 1 exp: a \";\"\l 2 | b \".\"\l 3 a: \"0\"\l 4 b: \"0\"\l"]
0 -> 1 [style=solid label="\"0\""]
0 -> 2 [style=dashed label="exp"]
0 -> 3 [style=dashed label="a"]
0 -> 4 [style=dashed label="b"]
1 [label="State 1\n\l 3 a: \"0\" . [\";\"]\l 4 b: \"0\" . [\".\"]\l"]
1 [label="State 1\n\l 3 a: \"0\" [\";\"]\l 4 b: \"0\" [\".\"]\l"]
1 -> "1R3" [style=solid]
"1R3" [label="R3", fillcolor=3, shape=diamond, style=filled]
1 -> "1R4" [label="[\".\"]", style=solid]
"1R4" [label="R4", fillcolor=3, shape=diamond, style=filled]
2 [label="State 2\n\l 0 $accept: exp . $end\l"]
2 [label="State 2\n\l 0 $accept: exp $end\l"]
2 -> 5 [style=solid label="$end"]
3 [label="State 3\n\l 1 exp: a . \";\"\l"]
3 [label="State 3\n\l 1 exp: a \";\"\l"]
3 -> 6 [style=solid label="\";\""]
4 [label="State 4\n\l 2 exp: b . \".\"\l"]
4 [label="State 4\n\l 2 exp: b \".\"\l"]
4 -> 7 [style=solid label="\".\""]
5 [label="State 5\n\l 0 $accept: exp $end .\l"]
5 [label="State 5\n\l 0 $accept: exp $end \l"]
5 -> "5R0" [style=solid]
"5R0" [label="Acc", fillcolor=1, shape=diamond, style=filled]
6 [label="State 6\n\l 1 exp: a \";\" .\l"]
6 [label="State 6\n\l 1 exp: a \";\" \l"]
6 -> "6R1" [style=solid]
"6R1" [label="R1", fillcolor=3, shape=diamond, style=filled]
7 [label="State 7\n\l 2 exp: b \".\" .\l"]
7 [label="State 7\n\l 2 exp: b \".\" \l"]
7 -> "7R2" [style=solid]
"7R2" [label="R2", fillcolor=3, shape=diamond, style=filled]
}
+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"
+10
View File
@@ -0,0 +1,10 @@
%%
sequence:
%empty
| maybeword
| sequence "word"
;
maybeword:
%empty
| "word"
;
-38
View File
@@ -1,38 +0,0 @@
* bench.pl
A primitive Perl script to run benches. Currently its only bench is
the usual calculator: it has a lightweight processing part (but not
null), so it is really emphasizing the cost of the whole parsing
(including scanning and I/O).
Set the envvars BISON and CC to the programs and flags you want to
use. They default to bison and gcc. To run a non-installed bison
from a tarball built in _build, I suggest the following.
BISON=_build/tests/bison CC='gcc -O2' ./bench.pl
(The _build/tests/bison wrapper makes sure that _build/src/bison will
use the tarballs' skeletons, not those already installed as a
straightforward use of _build/src/bison would.)
--
Copyright (C) 2006, 2009-2015, 2018-2020 Free Software Foundation, Inc.
This file is part of Bison, the GNU Compiler Compiler.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Local Variables:
mode: outline
End:
+36
View File
@@ -0,0 +1,36 @@
# bench.pl
A primitive Perl script to run benches. Currently its only bench is the
usual calculator: it has a lightweight processing part (but not null), so it
is really emphasizing the cost of the whole parsing (including scanning and
I/O).
Set the envvars `BISON` and `CC` to the programs and flags you want to use.
They default to `bison` and `gcc`. To run a non-installed bison from a
tarball built in _build, I suggest the following.
BISON=_build/tests/bison CC='gcc -O2' ./bench.pl
(The `_build/tests/bison` wrapper makes sure that `_build/src/bison` will
use the tarballs' skeletons, not those already installed as a
straightforward use of `_build/src/bison` would.)
<!--
Local Variables:
mode: markdown
fill-column: 76
ispell-dictionary: "american"
End:
Copyright (C) 2006, 2009-2015, 2018-2020 Free Software Foundation, Inc.
This file is part of Bison, the GNU Compiler Compiler.
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3 or
any later version published by the Free Software Foundation; with no
Invariant Sections, with no Front-Cover Texts, and with no Back-Cover
Texts. A copy of the license is included in the "GNU Free
Documentation License" file as part of this distribution.
-->
+81 -22
View File
@@ -498,7 +498,8 @@ yylex (void)
case '5': case '6': case '7': case '8': case '9':
{
int nchars = 0;
sscanf (input - 1, "%d%n", &yylval.NUM, &nchars);
int n = sscanf (input - 1, "%d%n", &yylval.NUM, &nchars);
assert (n == 1);
input += nchars - 1;
return NUM;
}
@@ -775,7 +776,31 @@ sub run ($)
##################################################################
=item C<compile ($base)>
=item C<language ($base)>
The language to use depending on the %language specification in
C<$base.y>: C<c> or C<c++>.
=cut
sub language ($)
{
my ($base) = @_;
if ($gbench)
{
"c++";
}
else
{
my $language = `sed -ne '/%language "\\(.*\\)"/{s//\\1/;p;q;}' $base.y`;
chomp $language;
$language eq 'C++' ? "c++" : "c";
}
}
##################################################################
=item C<compiler ($base)>
The compiler to use depending on the %language specification in
C<$base.y>.
@@ -785,16 +810,12 @@ C<$base.y>.
sub compiler ($)
{
my ($base) = @_;
if ($gbench)
{
$cxx;
}
else
{
my $language = `sed -ne '/%language "\\(.*\\)"/{s//\\1/;p;q;}' $base.y`;
chomp $language;
$language eq 'C++' ? $cxx : $cc;
}
my %compiler =
(
'c++' => $cxx,
'c' => $cc,
);
$compiler{language ($base)};
}
##################################################################
@@ -805,21 +826,38 @@ Compile C<$base.y> to an executable.
=cut
sub compile ($)
sub compile ($$)
{
my ($base) = @_;
my ($makefile, $base) = @_;
my $compiler = compiler ($base);
my $my_bison = `sed -ne '/[/][/] %bison "\\(.*\\)"/{s//\\1/;p;q;}' $base.y`;
chop $my_bison;
run ((length $my_bison ? $my_bison : $bison) . " $base.y -o $base.c");
my %ext =
(
'c++' => 'cc',
'c' => 'c',
);
my $ext = $ext{language ($base)};
if ($gbench)
{
run "$compiler -c -o $base.o $cflags $base.c";
print $makefile <<EOF;
$base.$ext: $base.y
\t@{[length $my_bison ? $my_bison : $bison]} $base.y -o $base.$ext
$base.o: $base.$ext
\t$compiler -c -o $base.o $cflags $base.$ext
EOF
}
else
{
run "$compiler -o $base $cflags $base.c";
print $makefile <<EOF;
$base.$ext: $base.y
\t@{[length $my_bison ? $my_bison : $bison]} $base.y -o $base.$ext
$base: $base.$ext
\t$compiler -o $base $cflags $base.$ext
EOF
}
}
@@ -849,11 +887,13 @@ sub bench_with_timethese ($@)
# For each bench, capture the size.
my %size;
my $makefile = new IO::File ">Makefile";
while (my ($name, $directives) = each %bench)
{
generate_grammar ($grammar, $name, $directives);
# Compile the executable.
compile ($name);
compile ($makefile, $name);
run "make $name";
$bench{$name} = "system ('./$name');";
chop($size{$name} = `wc -c <$name`);
}
@@ -906,6 +946,20 @@ sub bench_with_gbenchmark ($@)
my $readme = new IO::File ">README.md";
print $readme <<EOF;
compiler: $compiler $cflags
EOF
my $makefile = new IO::File ">Makefile";
print $makefile <<EOF;
.PHONY: bench
bench: main
\t./main \$(BENCHFLAGS) | tee -a README.md
# Link the bench cases in a different order to run the bench case in a
# different order.
.PHONY: rand
rand:
\t-rm main
\tmake bench OBJECTS="\$\$(shuf -e \$(OBJECTS) | xargs)"
EOF
my @obj = ();
@@ -916,19 +970,24 @@ EOF
print $m;
print $readme $m;
generate_grammar ($grammar, $base, $directive[$i]);
compile ($base);
compile ($makefile, $base);
push @obj, "$base.o";
}
my $out = new IO::File ">main.c";
my $out = new IO::File ">main.cc";
print $out <<EOF;
#include <benchmark/benchmark.h>
BENCHMARK_MAIN();
EOF
run "$compiler -o main $cflags main.c @obj -lbenchmark";
run "./main | tee -a README.md";
print $makefile <<EOF;
OBJECTS = @{obj}
main: \$(OBJECTS)
\t$compiler -o main $cflags main.cc \$(OBJECTS) -lbenchmark
EOF
run "make";
}
######################################################################
+2 -1
View File
@@ -14,4 +14,5 @@
## You should have received a copy of the GNU General Public License
## along with this program. If not, see <http://www.gnu.org/licenses/>.
nodist_noinst_SCRIPTS = etc/bench.pl
dist_noinst_DATA = %D%/README.md
nodist_noinst_SCRIPTS = %D%/bench.pl
+4 -4
View File
@@ -13,8 +13,8 @@ semantic value.
Run as `./simple`.
Extracted from the documentation: "A Simple C++ Example".
https://www.gnu.org/software/bison/manual/html_node/A-Simple-C_002b_002b-Example.html
Extracted from the documentation: [A Simple C++
Example](https://www.gnu.org/software/bison/manual/html_node/A-Simple-C_002b_002b-Example.html).
## variant.yy - Self-contained example in C++98
A variation of simple.yy, in C++98.
@@ -36,8 +36,8 @@ starting point for a clean parser in C++. The previous examples are better
introductory examples, and the C examples are also useful introductory
examples.
Extracted from the documentation: "A Complete C++ Example".
https://www.gnu.org/software/bison/manual/html_node/A-Complete-C_002b_002b-Example.html
Extracted from the documentation: [A Complete C++
Example](https://www.gnu.org/software/bison/manual/html_node/A-Complete-C_002b_002b-Example.html).
<!---
+3 -3
View File
@@ -5,9 +5,9 @@ saw the traditional implementation in C, please first read
examples/c/lexcalc, which can be seen as a C precursor of this example.
Read the corresponding chapter in the documentation: "A Complete C++
Example". It is also available on line (maybe with a different version of
Bison):
https://www.gnu.org/software/bison/manual/html_node/A-Complete-C_002b_002b-Example.html
Example". It is also available [on
line](https://www.gnu.org/software/bison/manual/html_node/A-Complete-C_002b_002b-Example.html)
(maybe with a different version of Bison).
To use it, copy this directory into some work directory, and run `make` to
compile the executable, and try it. It is a simple calculator which accepts
+14 -5
View File
@@ -10,8 +10,8 @@ The first example is that of a simple double-precision Reverse Polish
Notation calculator (a calculator using postfix operators). This example
provides a good starting point, since operator precedence is not an issue.
Extracted from the documentation: "Reverse Polish Notation Calculator"
https://www.gnu.org/software/bison/manual/html_node/RPN-Calc.html
Extracted from the documentation: [Reverse Polish Notation
Calculator](https://www.gnu.org/software/bison/manual/html_node/RPN-Calc.html).
## calc - Simple Calculator
This example is slightly more complex than rpcalc: it features infix
@@ -24,8 +24,8 @@ A more complete C example: a multi-function calculator. More complex than
the previous example. Using precedence directives to support infix
operators.
Extracted from the documentation: "Multi-Function Calculator: mfcalc".
https://www.gnu.org/software/bison/manual/html_node/Multi_002dfunction-Calc.html
Extracted from the documentation: [Multi-Function Calculator:
mfcalc](https://www.gnu.org/software/bison/manual/html_node/Multi_002dfunction-Calc.html).
## lexcalc - calculator with Flex and Bison
The calculator with precedence directives and location tracking. It uses
@@ -53,7 +53,9 @@ push-parser model.
This example demonstrates best practices when using Bison.
- Its hand-written scanner tracks locations.
- Its interface is pure.
- It uses the `error` token to get error recovery.
- It uses %params to pass user information to the parser and scanner.
- Its scanner uses the `error` token to signal lexical errors and enter
error recovery.
- Its interface is "incremental", well suited for interaction: it uses the
push-parser API to feed the parser with the incoming tokens.
- It features an interactive command line with completion based on the
@@ -62,6 +64,13 @@ This example demonstrates best practices when using Bison.
messages.
- It uses a custom syntax error with location, lookahead correction and
token internationalization.
- Error messages quote the source with squiggles that underline the error:
```
> 123 456
1.5-7: syntax error: expected end of file or + or - or * or / or ^ before number
1 | 123 456
| ^~~
```
- It supports debug traces with semantic values.
- It uses named references instead of the traditional $1, $2, etc.
+10 -1
View File
@@ -2,7 +2,9 @@
This example demonstrates best practices when using Bison.
- Its hand-written scanner tracks locations.
- Its interface is pure.
- It uses the `error` token to get error recovery.
- It uses %params to pass user information to the parser and scanner.
- Its scanner uses the `error` token to signal lexical errors and enter
error recovery.
- Its interface is "incremental", well suited for interaction: it uses the
push-parser API to feed the parser with the incoming tokens.
- It features an interactive command line with completion based on the
@@ -11,6 +13,13 @@ This example demonstrates best practices when using Bison.
messages.
- It uses a custom syntax error with location, lookahead correction and
token internationalization.
- Error messages quote the source with squiggles that underline the error:
```
> 123 456
1.5-7: syntax error: expected end of file or + or - or * or / or ^ before number
1 | 123 456
| ^~~
```
- It supports debug traces with semantic values.
- It uses named references instead of the traditional $1, $2, etc.
+62 -9
View File
@@ -45,7 +45,7 @@ echo >perfect '> 0
echo >ok '0'
echo '0' | prog >effective
echo "checking for readline output"
echo "checking for readline output..."
if diff perfect effective; then
# Alles ist gut.
strip_prompt=false
@@ -101,14 +101,28 @@ cat >input <<EOF
EOF
run 0 '> *
> ''
err: 1.1: syntax error: expected end of file or - or ( or exit or number or function etc., before *'
err: 1.1: syntax error: expected end of file or - or ( or exit or number or function etc., before *
err: 1 | *
err: | ^'
# Underline long errors.
cat >input <<EOF
123 123456
EOF
run 0 '> 123 123456
> ''
err: 1.5-10: syntax error: expected end of file or + or - or * or / or ^ before number
err: 1 | 123 123456
err: | ^~~~~~'
cat >input <<EOF
1 + 2 * * 3
EOF
run 0 '> 1 + 2 * * 3
> ''
err: 1.9: syntax error: expected - or ( or number or function or variable before *'
err: 1.9: syntax error: expected - or ( or number or function or variable before *
err: 1 | 1 + 2 * * 3
err: | ^'
cat >input <<EOF
1 / 0
@@ -132,8 +146,14 @@ run 0 '> ((1 ++ 2) ** 3)
1332
> ''
err: 1.6: syntax error: expected - or ( or number or function or variable before +
err: 1 | ((1 ++ 2) ** 3)
err: | ^
err: 2.5: syntax error: expected - or ( or number or function or variable before +
err: 2.16: syntax error: expected - or ( or number or function or variable before *'
err: 2 | (1 ++ 2) + (3 ** 4)
err: | ^
err: 2.16: syntax error: expected - or ( or number or function or variable before *
err: 2 | (1 ++ 2) + (3 ** 4)
err: | ^'
# The rule "( error )" should work even if there are no tokens between "(" and ")".
cat >input <<EOF
@@ -142,7 +162,9 @@ EOF
run 0 '> ()
666
> ''
err: 1.2: syntax error: expected - or ( or number or function or variable before )'
err: 1.2: syntax error: expected - or ( or number or function or variable before )
err: 1 | ()
err: | ^'
cat >input <<EOF
@@ -189,6 +211,8 @@ err: LAC: checking lookahead function: S5
err: LAC: checking lookahead variable: S6
err: LAC: checking lookahead NEG: Err
err: 1.2: syntax error: expected - or ( or number or function or variable before +
err: 1 | (+_)
err: | ^
err: LAC: initial context discarded due to error recovery
err: Shifting token error (1.2: )
err: Entering state 10
@@ -269,8 +293,8 @@ fi
# On Windows10/MSYS2 the ^G coming from <tab> completion is not
# emitted the same way
# (https://lists.gnu.org/r/bug-bison/2020-05/msg00076.html).
echo "checking for kernel name"
case `uname -s` in
echo "checking for kernel name... $(uname -s)"
case $(uname -s) in
(MSYS*)
echo "SKIP: this is Windows/MSYS"
exit $status
@@ -286,7 +310,9 @@ run 0 '> (1+
( - atan cos exp ln number sin sqrt
> (1+
> ''
err: 1.4: syntax error: expected - or ( or number or function or variable before end of file'
err: 1.4: syntax error: expected - or ( or number or function or variable before end of file
err: 1 | (1+
err: | ^'
# Check the completion of a word.
sed -e 's/\\t/ /g' >input <<EOF
@@ -294,7 +320,9 @@ sed -e 's/\\t/ /g' >input <<EOF
EOF
run 0 '> (atan ( ''
> ''
err: 1.9: syntax error: expected - or ( or number or function or variable before end of file'
err: 1.9: syntax error: expected - or ( or number or function or variable before end of file
err: 1 | (atan ( ''
err: | ^'
# Check the completion at the very beginning.
sed -e 's/\\t/ /g' >input <<EOF
@@ -306,3 +334,28 @@ end of file exit exp ''
0
> ''
err: '
# Check that completion prints valid locations even when there is an error.
sed -e 's/\\t/ /g' >input <<EOF
1++\t
EOF
run -n 0 '> 1++ ''
> ''
err: 1.3: syntax error: expected - or ( or number or function or variable before +
err: 1 | 1++ ''
err: | ^
'
# And even when the error was recovered from.
sed -e 's/\\t/ /g' >input <<EOF
(1++2) + 3 +\t\t
EOF
run -n 0 '> (1++2) + 3 + ''
> ''
err: 1.4: syntax error: expected - or ( or number or function or variable before +
err: 1 | (1++2) + 3 + ''
err: | ^
err: 1.15: syntax error: expected - or ( or number or function or variable before end of file
err: 1 | (1++2) + 3 + ''
err: | ^
'
+1
View File
@@ -31,6 +31,7 @@ if ENABLE_BISTROMATHIC
-DBISON_LOCALEDIR='"$(localdir)"' \
-DLOCALEDIR='"$(localdir)"' \
-I$(top_srcdir)/%D% -I$(top_builddir)/%D%
%C%_bistromathic_CFLAGS = $(TEST_CFLAGS)
%C%_bistromathic_LDADD = -lm $(LIBREADLINE) $(LIBINTL)
endif
+112 -34
View File
@@ -1,7 +1,26 @@
%require "3.6"
/* Parser and scanner for bistromathic. -*- C -*-
Copyright (C) 2019-2020 Free Software Foundation, Inc.
This file is part of Bison, the GNU Compiler Compiler.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
%require "3.7"
// Emitted on top of the implementation file.
%code top {
#include <assert.h>
#include <ctype.h> // isdigit
#include <locale.h> // LC_ALL
#include <math.h> // cos, sin, etc.
@@ -25,6 +44,7 @@
#endif
}
// Emitted in the header file, before the definition of YYSTYPE.
%code requires {
// Function type.
typedef double (func_t) (double);
@@ -45,19 +65,34 @@
symrec *putsym (char const *name, int sym_type);
symrec *getsym (char const *name);
// Exchanging information with the parser.
typedef struct
{
// Whether to not emit error messages.
int silent;
// The current input line.
const char *line;
} user_context;
}
// Emitted in the header file, after the definition of YYSTYPE.
%code provides {
# ifndef __attribute__
# ifndef __GNUC__
# define __attribute__(Spec) /* empty */
# endif
# endif
int yylex (const char **line, YYSTYPE *yylval, YYLTYPE *yylloc);
void yyerror (YYLTYPE *loc, char const *format, ...)
__attribute__ ((__format__ (__printf__, 2, 3)));
yytoken_kind_t
yylex (const char **line, YYSTYPE *yylval, YYLTYPE *yylloc,
const user_context *uctx);
void yyerror (YYLTYPE *loc, const user_context *uctx,
char const *format, ...)
__attribute__ ((__format__ (__printf__, 3, 4)));
}
// Emitted in the implementation file.
%code {
#if defined ENABLE_NLS && ENABLE_NLS
# define _(Msgid) gettext (Msgid)
@@ -69,6 +104,9 @@
int done = 0;
}
// Include the header in the implementation rather than duplicating it.
%define api.header.include {"parse.h"}
// Don't share global variables between the scanner and the parser.
%define api.pure full
@@ -91,6 +129,9 @@
// Generate the parser description file (calc.output).
%verbose
// User information exchanged with the parser and scanner.
%param {const user_context *uctx}
// Generate YYSTYPE from the types assigned to symbols.
%define api.value.type union
%token
@@ -146,7 +187,7 @@ exp:
{
if ($r == 0)
{
yyerror (&@$, "error: division by zero");
yyerror (&@$, uctx, "error: division by zero");
YYERROR;
}
else
@@ -218,7 +259,7 @@ getsym (char const *name)
}
// How many symbols are registered.
int
static int
symbol_count (void)
{
int res = 0;
@@ -232,8 +273,9 @@ symbol_count (void)
| Scanner. |
`----------*/
int
yylex (const char **line, YYSTYPE *yylval, YYLTYPE *yylloc)
yytoken_kind_t
yylex (const char **line, YYSTYPE *yylval, YYLTYPE *yylloc,
const user_context *uctx)
{
int c;
@@ -268,7 +310,8 @@ yylex (const char **line, YYSTYPE *yylval, YYLTYPE *yylloc)
case '5': case '6': case '7': case '8': case '9':
{
int nchars = 0;
sscanf (*line - 1, "%lf%n", &yylval->TOK_NUM, &nchars);
if (sscanf (*line - 1, "%lf%n", &yylval->TOK_NUM, &nchars) != 1)
abort ();
*line += nchars - 1;
yylloc->last_column += nchars - 1;
return TOK_NUM;
@@ -284,7 +327,8 @@ yylex (const char **line, YYSTYPE *yylval, YYLTYPE *yylloc)
{
int nchars = 0;
char buf[100];
sscanf (*line - 1, "%99[a-z]%n", buf, &nchars);
if (sscanf (*line - 1, "%99[a-z]%n", buf, &nchars) != 1)
abort ();
*line += nchars - 1;
yylloc->last_column += nchars - 1;
if (strcmp (buf, "exit") == 0)
@@ -301,7 +345,7 @@ yylex (const char **line, YYSTYPE *yylval, YYLTYPE *yylloc)
// Stray characters.
default:
yyerror (yylloc, "syntax error: invalid character: %c", c);
yyerror (yylloc, uctx, "syntax error: invalid character: %c", c);
return TOK_YYerror;
}
}
@@ -312,7 +356,7 @@ yylex (const char **line, YYSTYPE *yylval, YYLTYPE *yylloc)
`---------*/
const char *
static const char *
error_format_string (int argc)
{
switch (argc)
@@ -339,8 +383,11 @@ error_format_string (int argc)
int
yyreport_syntax_error (const yypcontext_t *ctx)
yyreport_syntax_error (const yypcontext_t *ctx, const user_context *uctx)
{
if (uctx->silent)
return 0;
enum { ARGS_MAX = 6 };
yysymbol_kind_t arg[ARGS_MAX];
int argsize = yypcontext_expected_tokens (ctx, arg, ARGS_MAX);
@@ -351,11 +398,12 @@ yyreport_syntax_error (const yypcontext_t *ctx)
argsize = ARGS_MAX;
const char *format = error_format_string (1 + argsize + too_many_expected_tokens);
const YYLTYPE *loc = yypcontext_location (ctx);
while (*format)
// %@: location.
if (format[0] == '%' && format[1] == '@')
{
YY_LOCATION_PRINT (stderr, *yypcontext_location (ctx));
YY_LOCATION_PRINT (stderr, *loc);
format += 2;
}
// %u: unexpected token.
@@ -380,13 +428,25 @@ yyreport_syntax_error (const yypcontext_t *ctx)
++format;
}
fputc ('\n', stderr);
// Quote the source line.
{
fprintf (stderr, "%5d | %s\n", loc->first_line, uctx->line);
fprintf (stderr, "%5s | %*s", "", loc->first_column, "^");
for (int i = loc->last_column - loc->first_column - 1; 0 < i; --i)
putc ('~', stderr);
putc ('\n', stderr);
}
return 0;
}
// Called by yyparse on error.
void yyerror (YYLTYPE *loc, char const *format, ...)
void yyerror (YYLTYPE *loc, const user_context *uctx, char const *format, ...)
{
if (uctx->silent)
return;
YY_LOCATION_PRINT (stderr, *loc);
fputs (": ", stderr);
va_list args;
@@ -407,7 +467,8 @@ xstrndup (const char *string, size_t n)
const char *end = memchr (string, '\0', n);
size_t len = end ? (size_t) (end - string) : n;
char *new = malloc (len + 1);
assert (new);
if (!new)
abort ();
new[len] = '\0';
return memcpy (new, string, len);
}
@@ -418,13 +479,16 @@ xstrndup (const char *string, size_t n)
`-----------*/
// Parse (and execute) this line.
int process_line (YYLTYPE *lloc, const char *line)
static int
process_line (YYLTYPE *lloc, const char *line)
{
user_context uctx = {0, line};
yypstate *ps = yypstate_new ();
int status = 0;
do {
YYSTYPE lval;
status = yypush_parse (ps, yylex (&line, &lval, lloc), &lval, lloc);
yytoken_kind_t token = yylex (&line, &lval, lloc, &uctx);
status = yypush_parse (ps, token, &lval, lloc, &uctx);
} while (status == YYPUSH_MORE);
yypstate_delete (ps);
lloc->last_line++;
@@ -433,27 +497,36 @@ int process_line (YYLTYPE *lloc, const char *line)
}
// Get the list of possible tokens after INPUT was read.
int
// Returns a nonnegative.
static int
expected_tokens (const char *input,
int *tokens, int ntokens)
{
YYDPRINTF ((stderr, "expected_tokens (\"%s\")", input));
user_context uctx = {1, input};
// Parse the current state of the line.
yypstate *ps = yypstate_new ();
int status = 0;
YYLTYPE lloc = { 1, 1, 1, 1 };
do {
YYLTYPE lloc;
YYSTYPE lval;
int token = yylex (&input, &lval, &lloc);
yytoken_kind_t token = yylex (&input, &lval, &lloc, &uctx);
// Don't let the parse know when we reach the end of input.
if (!token)
if (token == TOK_YYEOF)
break;
status = yypush_parse (ps, token, &lval, &lloc);
status = yypush_parse (ps, token, &lval, &lloc, &uctx);
} while (status == YYPUSH_MORE);
// Then query for the accepted tokens at this point.
int res = yypstate_expected_tokens (ps, tokens, ntokens);
int res = 0;
// If there were parse errors, don't propose completions.
if (!ps->yynerrs)
{
// Then query for the accepted tokens at this point.
res = yypstate_expected_tokens (ps, tokens, ntokens);
if (res < 0)
abort ();
}
yypstate_delete (ps);
return res;
}
@@ -463,7 +536,7 @@ expected_tokens (const char *input,
// TEXT is the word to complete. We can use the entire contents of
// rl_line_buffer in case we want to do some simple parsing. Return
// the array of matches, or NULL if there aren't any.
char **
static char **
completion (const char *text, int start, int end)
{
YYDPRINTF ((stderr, "completion (\"%.*s[%.*s]%s\")\n",
@@ -473,14 +546,17 @@ completion (const char *text, int start, int end)
// Get list of token numbers.
int tokens[YYNTOKENS];
char *line = xstrndup (rl_line_buffer, start);
char *line = xstrndup (rl_line_buffer, (size_t) start);
int ntokens = expected_tokens (line, tokens, YYNTOKENS);
free (line);
// Build MATCHES, the list of possible completions.
const int len = strlen (text);
const size_t len = strlen (text);
// Need initial prefix and final NULL.
char **matches = calloc (ntokens + symbol_count () + 2, sizeof *matches);
char **matches
= calloc ((size_t) ntokens + (size_t) symbol_count () + 2, sizeof *matches);
if (!matches)
abort ();
int match = 1;
for (int i = 0; i < ntokens; ++i)
switch (tokens[i])
@@ -510,9 +586,9 @@ completion (const char *text, int start, int end)
matches[0] = strdup (text);
else
{
int lcplen = strlen (matches[1]);
size_t lcplen = strlen (matches[1]);
for (int i = 2; i < match && lcplen; ++i)
for (int j = 0; j < lcplen; ++j)
for (size_t j = 0; j < lcplen; ++j)
if (matches[1][j] != matches[i][j])
lcplen = j;
matches[0] = xstrndup (matches[1], lcplen);
@@ -536,7 +612,8 @@ completion (const char *text, int start, int end)
return matches;
}
void init_readline (void)
static void
init_readline (void)
{
// Allow conditional parsing of the ~/.inputrc file.
rl_readline_name = "bistromathic";
@@ -555,7 +632,8 @@ void init_readline (void)
| Main. |
`-------*/
int main (int argc, char const* argv[])
int
main (int argc, char const* argv[])
{
#if defined ENABLE_NLS && ENABLE_NLS
// Set up internationalization.
+5 -2
View File
@@ -1,6 +1,8 @@
%code top {
#include <assert.h>
#include <ctype.h> /* isdigit. */
#include <stdio.h> /* For printf, etc. */
#include <stdio.h> /* printf. */
#include <stdlib.h> /* abort. */
#include <string.h> /* strcmp. */
int yylex (void);
@@ -73,7 +75,8 @@ yylex (void)
if (c == '.' || isdigit (c))
{
ungetc (c, stdin);
scanf ("%lf", &yylval.NUM);
if (scanf ("%lf", &yylval.NUM) != 1)
abort ();
return NUM;
}
+1
View File
@@ -27,6 +27,7 @@ nodist_%C%_calc_SOURCES = %D%/calc.y
# Don't use gnulib's system headers.
%C%_calc_CPPFLAGS = -I$(top_srcdir)/%D% -I$(top_builddir)/%D%
%C%_calc_CFLAGS = $(TEST_CFLAGS)
dist_calc_DATA = %D%/calc.y %D%/Makefile %D%/README.md
CLEANFILES += %D%/calc.[ch] %D%/calc.output %D%/scan.c
+2
View File
@@ -25,6 +25,8 @@ if FLEX_WORKS
nodist_%C%_lexcalc_SOURCES = %D%/parse.y %D%/parse.h %D%/scan.l
# Don't use gnulib's system headers.
%C%_lexcalc_CPPFLAGS = -I$(top_srcdir)/%D% -I$(top_builddir)/%D%
# Fighting warnings triggered by Flex is just too painful.
# %C%_lexcalc_CFLAGS = $(TEST_CFLAGS)
endif FLEX_WORKS
%D%/parse.c: $(dependencies)
+22
View File
@@ -1,3 +1,22 @@
/* Parser for lexcalc. -*- C -*-
Copyright (C) 2018-2020 Free Software Foundation, Inc.
This file is part of Bison, the GNU Compiler Compiler.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
// Prologue (directives).
%expect 0
@@ -19,6 +38,9 @@
#include <stdlib.h> // getenv.
}
// Include the header in the implementation rather than duplicating it.
%define api.header.include {"parse.h"}
// Don't share global variables between the scanner and the parser.
%define api.pure full
+22 -3
View File
@@ -1,10 +1,29 @@
/* Prologue (directives). -*- C -*- */
/* Scanner for lexcalc. -*- C -*-
Copyright (C) 2018-2020 Free Software Foundation, Inc.
This file is part of Bison, the GNU Compiler Compiler.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* Prologue (directives). */
/* Disable Flex features we don't need, to avoid warnings. */
%option nodefault noinput nounput noyywrap
%{
#include <errno.h> /* errno, ERANGE */
#include <errno.h> /* errno, ERANGE */
#include <limits.h> /* INT_MIN */
#include <stdlib.h> /* strtol */
@@ -12,7 +31,7 @@
// Each time a rule is matched, advance the end cursor/position.
#define YY_USER_ACTION \
yylloc->last_column += yyleng;
yylloc->last_column += (int) yyleng;
// Move the first position onto the last.
#define LOCATION_STEP() \
+1
View File
@@ -31,6 +31,7 @@ nodist_%C%_mfcalc_SOURCES = $(mfcalc_sources)
%D%/mfcalc.c: $(dependencies)
# Don't use gnulib's system headers.
%C%_mfcalc_CPPFLAGS = -I$(top_srcdir)/%D% -I$(top_builddir)/%D%
%C%_mfcalc_CFLAGS = $(TEST_CFLAGS)
%C%_mfcalc_LDADD = -lm
dist_TESTS += %D%/mfcalc.test
+23 -3
View File
@@ -1,7 +1,26 @@
/* Parser and scanner for pushcalc. -*- C -*-
Copyright (C) 2020 Free Software Foundation, Inc.
This file is part of Bison, the GNU Compiler Compiler.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
%code top {
#include <ctype.h> /* isdigit. */
#include <stdbool.h>
#include <stdio.h> /* For printf, etc. */
#include <stdio.h> /* printf. */
#include <stdlib.h> /* abort. */
#include <string.h> /* strcmp. */
}
@@ -81,7 +100,8 @@ yylex (YYSTYPE *yylval)
if (c == '.' || isdigit (c))
{
ungetc (c, stdin);
scanf ("%lf", &yylval->NUM);
if (scanf ("%lf", &yylval->NUM) != 1)
abort ();
return NUM;
}
+1
View File
@@ -27,6 +27,7 @@ nodist_%C%_calc_SOURCES = %D%/calc.y
# Don't use gnulib's system headers.
%C%_calc_CPPFLAGS = -I$(top_srcdir)/%D% -I$(top_builddir)/%D%
%C%_calc_CFLAGS = $(TEST_CFLAGS)
dist_pushcalc_DATA = %D%/calc.y %D%/Makefile %D%/README.md
CLEANFILES += %D%/calc.[ch] %D%/calc.output
+2
View File
@@ -26,6 +26,8 @@ if FLEX_WORKS
BUILT_SOURCES += $(nodist_%C%_reccalc_SOURCES)
# Don't use gnulib's system headers.
%C%_reccalc_CPPFLAGS = -I$(top_srcdir)/%D% -I$(top_builddir)/%D%
# Fighting warnings triggered by Flex is just too painful.
# %C%_reccalc_CFLAGS = $(TEST_CFLAGS)
endif FLEX_WORKS
%D%/parse.c: $(dependencies)
+36 -2
View File
@@ -1,3 +1,22 @@
/* Parser for reccalc. -*- C -*-
Copyright (C) 2019-2020 Free Software Foundation, Inc.
This file is part of Bison, the GNU Compiler Compiler.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
// Prologue (directives).
%expect 0
@@ -46,14 +65,29 @@
result parse (void);
}
// Include the header in the implementation rather than duplicating it.
%define api.header.include {"parse.h"}
// Don't share global variables between the scanner and the parser.
%define api.pure full
// To avoid name clashes (e.g., with C's EOF) prefix token definitions
// with TOK_ (e.g., TOK_EOF).
%define api.token.prefix {TOK_}
// Generate YYSTYPE from the types assigned to symbols.
%define api.value.type union
%define parse.error verbose
// Error messages with "unexpected XXX, expected XXX...".
%define parse.error detailed
// Enable run-time traces (yydebug).
%define parse.trace
// Generate the parser description file (parse.output).
%verbose
// Scanner and error count are exchanged between main, yyparse and yylex.
// Scanner and error count are exchanged between main, yyparse and yylex.
%param {yyscan_t scanner}{result *res}
%token
+21 -2
View File
@@ -1,3 +1,22 @@
/* Scanner for reccalc. -*- C -*-
Copyright (C) 2019-2020 Free Software Foundation, Inc.
This file is part of Bison, the GNU Compiler Compiler.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* Prologue (directives). -*- C -*- */
/* Disable Flex features we don't need, to avoid warnings. */
@@ -32,9 +51,9 @@
do \
capacity = capacity ? 2 * capacity : 128; \
while (capacity < size + yyleng + 1); \
str = realloc (str, capacity); \
str = realloc (str, (size_t) capacity); \
} \
memcpy (str + size, yytext, yyleng); \
memcpy (str + size, yytext, (size_t) yyleng); \
size += yyleng; \
assert (size < capacity); \
} while (0)
+1
View File
@@ -31,6 +31,7 @@ nodist_%C%_rpcalc_SOURCES = $(rpcalc_sources)
%D%/rpcalc.c: $(dependencies)
# Don't use gnulib's system headers.
%C%_rpcalc_CPPFLAGS = -I$(top_builddir)/%D%
%C%_rpcalc_CFLAGS = $(TEST_CFLAGS)
%C%_rpcalc_LDADD = -lm
dist_TESTS += %D%/rpcalc.test
+19
View File
@@ -1,3 +1,22 @@
/* Parser and scanner for calc in D. -*- D -*-
Copyright (C) 2018-2020 Free Software Foundation, Inc.
This file is part of Bison, the GNU Compiler Compiler.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
%language "D"
%define api.parser.class {Calc}
+19
View File
@@ -1,3 +1,22 @@
/* Parser and scanner for calc in Java. -*- Java -*-
Copyright (C) 2018-2020 Free Software Foundation, Inc.
This file is part of Bison, the GNU Compiler Compiler.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
%language "Java"
%define api.parser.class {Calc}
+19
View File
@@ -1,3 +1,22 @@
/* Simple parser and scanner in Java. -*- Java -*-
Copyright (C) 2018-2020 Free Software Foundation, Inc.
This file is part of Bison, the GNU Compiler Compiler.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
%language "Java"
%define api.parser.class {Calc}
+3
View File
@@ -35,6 +35,9 @@
dist_noinst_SCRIPTS = %D%/extexi %D%/test
TEST_LOG_COMPILER = $(SHELL) $(top_srcdir)/%D%/test
TEST_CFLAGS = \
$(WARN_CFLAGS) $(WARN_CFLAGS_TEST) $(WERROR_CFLAGS)
AM_CXXFLAGS = \
$(WARN_CXXFLAGS) $(WARN_CXXFLAGS_TEST) $(WERROR_CXXFLAGS)
+2 -1
View File
@@ -36,10 +36,11 @@ strip_prompt=false
# If diff supports --strip-trailing-cr, use it, to avoid EOL issues
# when testing Java programs on Windows.
echo "checking for diff --strip-trailing-cr"
echo "checking for diff --strip-trailing-cr..."
if diff --strip-trailing-cr "$1" "$1"; then
diff_opts=--strip-trailing-cr
fi
echo "checking for diff --strip-trailing-cr... $diff_opts"
# The exercised program.
abs_medir=$cwd/examples/$medir
+1 -1
Submodule gnulib updated: 2ac33b29fc...ac34618e85
+47
View File
@@ -18,7 +18,9 @@
/asnprintf.c
/asprintf.c
/assure.h
/attribute.h
/basename-lgpl.c
/basename-lgpl.h
/basename.c
/binary-io.c
/binary-io.h
@@ -117,10 +119,31 @@
/gettext.h
/gettime.c
/gettimeofday.c
/gl_anyhash1.h
/gl_anyhash2.h
/gl_anyhash_primes.h
/gl_anylinked_list1.h
/gl_anylinked_list2.h
/gl_anyrbtree_list1.h
/gl_anyrbtree_list2.h
/gl_anytree_list1.h
/gl_anytree_list2.h
/gl_anytree_oset.h
/gl_anytreehash_list1.h
/gl_anytreehash_list2.h
/gl_array_list.c
/gl_array_list.h
/gl_linked_list.c
/gl_linked_list.h
/gl_list.c
/gl_list.h
/gl_oset.c
/gl_oset.h
/gl_rbtree_ordered.h
/gl_rbtree_oset.c
/gl_rbtree_oset.h
/gl_rbtreehash_list.c
/gl_rbtreehash_list.h
/gl_xlist.c
/gl_xlist.h
/gnulib.mk
@@ -128,6 +151,23 @@
/hard-locale.h
/hash.c
/hash.h
/iconv.c
/iconv.h
/iconv.in.h
/iconv_close.c
/iconv_open-aix.gperf
/iconv_open-aix.h
/iconv_open-hpux.gperf
/iconv_open-hpux.h
/iconv_open-irix.gperf
/iconv_open-irix.h
/iconv_open-osf.gperf
/iconv_open-osf.h
/iconv_open-solaris.gperf
/iconv_open-solaris.h
/iconv_open-zos.gperf
/iconv_open-zos.h
/iconv_open.c
/intprops.h
/inttypes.h
/inttypes.in.h
@@ -273,6 +313,7 @@
/stdlib.h
/stdlib.in.h
/stpcpy.c
/stpncpy.c
/strchrnul.c
/strchrnul.valgrind
/strdup.c
@@ -305,11 +346,16 @@
/timespec.h
/timevar.c
/timevar.h
/unicodeio.c
/unicodeio.h
/unistd--.h
/unistd-safer.h
/unistd.c
/unistd.h
/unistd.in.h
/unistr.h
/unistr.in.h
/unistr/
/unitypes.h
/unitypes.in.h
/uniwidth
@@ -318,6 +364,7 @@
/unlink.c
/unlocked-io.h
/unsetenv.c
/unused-parameter.h
/vasnprintf.c
/vasnprintf.h
/vasprintf.c
+7 -2
View File
@@ -1,4 +1,3 @@
/extern-inline.m4~
/*~
/00gnulib.m4
/__inline.m4
@@ -6,6 +5,7 @@
/alloca.m4
/asm-underscore.m4
/assert.m4
/builtin-expect.m4
/calloc.m4
/canonicalize.m4
/clock_time.m4
@@ -13,7 +13,6 @@
/codeset.m4
/config-h.m4
/configmake.m4
/dirname.m4
/double-slash-root.m4
/dup2.m4
/eealloc.m4
@@ -25,6 +24,7 @@
/exponentl.m4
/extensions.m4
/extern-inline.m4
/extern-inline.m4~
/fatal-signal.m4
/fcntl-o.m4
/fcntl.m4
@@ -57,7 +57,10 @@
/gnulib-tool.m4
/host-cpu-c-abi.m4
/iconv.m4
/iconv_h.m4
/iconv_open.m4
/include_next.m4
/inline.m4
/intdiv0.m4
/intl.m4
/intldir.m4
@@ -172,6 +175,7 @@
/stdio_h.m4
/stdlib_h.m4
/stpcpy.m4
/stpncpy.m4
/strchrnul.m4
/strdup.m4
/strerror.m4
@@ -192,6 +196,7 @@
/timespec.m4
/tls.m4
/uintmax_t.m4
/unicodeio.m4
/unistd-safer.m4
/unistd_h.m4
/unlink.m4
+1
View File
@@ -2,6 +2,7 @@ examples/c/bistromathic/parse.y
examples/java/calc/Calc.y
src/complain.c
src/conflicts.c
src/counterexample.c
src/files.c
src/fixits.c
src/getargs.c
+165 -180
View File
@@ -18,11 +18,13 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include <config.h>
#include "system.h"
#include "AnnotationList.h"
#include "lalr.h"
#include "system.h"
#include "ielr.h"
#include "lalr.h"
/**
* \pre
@@ -38,15 +40,14 @@ static AnnotationList*
AnnotationList__alloc_on_obstack (ContributionIndex contribution_count,
struct obstack *annotations_obstackp)
{
AnnotationList *result;
size_t contributions_size =
contribution_count * sizeof result->contributions[0];
result = obstack_alloc (annotations_obstackp,
offsetof (AnnotationList, contributions)
+ contributions_size);
result->next = NULL;
result->inadequacyNode = NULL;
return result;
AnnotationList *res;
size_t contributions_size = contribution_count * sizeof res->contributions[0];
res = obstack_alloc (annotations_obstackp,
offsetof (AnnotationList, contributions)
+ contributions_size);
res->next = NULL;
res->inadequacyNode = NULL;
return res;
}
/**
@@ -102,13 +103,12 @@ AnnotationList__insertInto (AnnotationList *self, AnnotationList **list,
for (node = list; *node; node = &(*node)->next)
{
int cmp = 0;
ContributionIndex ci;
if (self->inadequacyNode->id < (*node)->inadequacyNode->id)
cmp = 1;
else if ((*node)->inadequacyNode->id < self->inadequacyNode->id)
cmp = -1;
else
for (ci = 0;
for (ContributionIndex ci = 0;
cmp == 0 && ci < self->inadequacyNode->contributionCount;
++ci)
{
@@ -120,19 +120,16 @@ AnnotationList__insertInto (AnnotationList *self, AnnotationList **list,
else if (AnnotationList__isContributionAlways (*node, ci))
cmp = 1;
else
{
size_t item;
for (item = 0; cmp == 0 && item < nitems; ++item)
{
if (!Sbitset__test (self->contributions[ci], item))
{
if (Sbitset__test ((*node)->contributions[ci], item))
cmp = -1;
}
else if (!Sbitset__test ((*node)->contributions[ci], item))
cmp = 1;
}
}
for (size_t item = 0; cmp == 0 && item < nitems; ++item)
{
if (!Sbitset__test (self->contributions[ci], item))
{
if (Sbitset__test ((*node)->contributions[ci], item))
cmp = -1;
}
else if (!Sbitset__test ((*node)->contributions[ci], item))
cmp = 1;
}
}
if (cmp < 0)
{
@@ -172,10 +169,10 @@ AnnotationList__compute_conflicted_tokens (bitset shift_tokens,
bitset_copy (tokens, shift_tokens);
for (int i = 0; i < reds->num; ++i)
{
bitset_and (conflicted_tokens_rule, tokens, reds->lookahead_tokens[i]);
bitset_and (conflicted_tokens_rule, tokens, reds->lookaheads[i]);
bitset_or (conflicted_tokens,
conflicted_tokens, conflicted_tokens_rule);
bitset_or (tokens, tokens, reds->lookahead_tokens[i]);
bitset_or (tokens, tokens, reds->lookaheads[i]);
/* Check that rules are sorted on rule number or the next step in
AnnotationList__compute_from_inadequacies will misbehave. */
aver (i == 0 || reds->rules[i-1] < reds->rules[i]);
@@ -188,7 +185,7 @@ AnnotationList__compute_conflicted_tokens (bitset shift_tokens,
}
static bool
AnnotationList__compute_lhs_contributions (state *s, rule *the_rule,
AnnotationList__compute_lhs_contributions (state *s, const rule *the_rule,
symbol_number conflicted_token,
bitsetv follow_kernel_items,
bitsetv always_follows,
@@ -232,115 +229,110 @@ AnnotationList__computePredecessorAnnotations (
annotation_node->inadequacyNode = self->inadequacyNode;
bool potential_contribution = false;
bitset *lookaheads = NULL;
{
for (ContributionIndex ci = 0; ci < self->inadequacyNode->contributionCount; ++ci)
{
symbol_number contribution_token =
InadequacyList__getContributionToken (self->inadequacyNode, ci)
->content->number;
if (AnnotationList__isContributionAlways (self, ci))
{
annotation_node->contributions[ci] = NULL;
continue;
}
annotation_node->contributions[ci] =
Sbitset__new_on_obstack ((*predecessor)->nitems,
annotations_obstackp);
for (ContributionIndex ci = 0; ci < self->inadequacyNode->contributionCount; ++ci)
{
symbol_number contribution_token =
InadequacyList__getContributionToken (self->inadequacyNode, ci)
->content->number;
if (AnnotationList__isContributionAlways (self, ci))
{
size_t predecessor_item = 0;
Sbitset sbiter_item;
Sbitset__Index self_item;
SBITSET__FOR_EACH (self->contributions[ci], s->nitems,
sbiter_item, self_item)
{
/* If this kernel item is the beginning of a RHS, it must be
the kernel item in the start state, and so it has an empty
lookahead set. Thus, it can't contribute to inadequacies,
and so it should never have been identified as a
contribution. If, instead, this kernel item is the
successor of the start state's kernel item, the lookahead
set is still empty, and so it also should never have been
identified as a contribution. This situation is fortunate
because we want to avoid the - 2 below in both cases. */
aver (s->items[self_item] > 1);
/* If this kernel item is next to the beginning of the RHS,
then check all of the predecessor's goto follows for the
LHS. */
if (item_number_is_rule_number (ritem[s->items[self_item]
- 2]))
{
int rulei;
for (rulei = s->items[self_item];
!item_number_is_rule_number (ritem[rulei]);
++rulei)
continue;
Sbitset items;
if (AnnotationList__compute_lhs_contributions (
*predecessor,
&rules[item_number_as_rule_number (ritem[rulei])],
contribution_token,
follow_kernel_items, always_follows, predecessors,
item_lookahead_sets, &items, annotations_obstackp))
{
obstack_free (annotations_obstackp,
annotation_node->contributions[ci]);
annotation_node->contributions[ci] = NULL;
break;
}
else
{
Sbitset__or (annotation_node->contributions[ci],
annotation_node->contributions[ci],
items, (*predecessor)->nitems);
obstack_free (annotations_obstackp, items);
}
}
/* If this kernel item is later in the RHS, then check the
predecessor item's lookahead set. */
else
{
/* We don't have to start the predecessor item search at
the beginning every time because items from both
states are sorted by their indices in ritem. */
for (;
predecessor_item < (*predecessor)->nitems;
++predecessor_item)
if ((*predecessor)->items[predecessor_item]
== s->items[self_item] - 1)
break;
aver (predecessor_item != (*predecessor)->nitems);
if (ielr_item_has_lookahead (*predecessor, 0,
predecessor_item,
contribution_token,
predecessors,
item_lookahead_sets))
Sbitset__set (annotation_node->contributions[ci],
predecessor_item);
}
}
annotation_node->contributions[ci] = NULL;
continue;
}
if (annotation_node->contributions[ci])
annotation_node->contributions[ci] =
Sbitset__new_on_obstack ((*predecessor)->nitems,
annotations_obstackp);
{
size_t predecessor_item = 0;
Sbitset sbiter_item;
Sbitset__Index self_item;
SBITSET__FOR_EACH (self->contributions[ci], s->nitems,
sbiter_item, self_item)
{
Sbitset biter;
Sbitset__Index i;
SBITSET__FOR_EACH (annotation_node->contributions[ci],
(*predecessor)->nitems, biter, i)
/* If this kernel item is the beginning of a RHS, it must be
the kernel item in the start state, and so it has an empty
lookahead set. Thus, it can't contribute to inadequacies,
and so it should never have been identified as a
contribution. If, instead, this kernel item is the
successor of the start state's kernel item, the lookahead
set is still empty, and so it also should never have been
identified as a contribution. This situation is fortunate
because we want to avoid the - 2 below in both cases. */
aver (s->items[self_item] > 1);
/* If this kernel item is next to the beginning of the RHS,
then check all of the predecessor's goto follows for the
LHS. */
if (item_number_is_rule_number (ritem[s->items[self_item] - 2]))
{
potential_contribution = true;
if (!lookaheads)
Sbitset items;
if (AnnotationList__compute_lhs_contributions (
*predecessor,
item_rule (&ritem[s->items[self_item]]),
contribution_token,
follow_kernel_items, always_follows, predecessors,
item_lookahead_sets, &items, annotations_obstackp))
{
lookaheads = xnmalloc ((*predecessor)->nitems,
sizeof *lookaheads);
for (size_t j = 0; j < (*predecessor)->nitems; ++j)
lookaheads[j] = NULL;
obstack_free (annotations_obstackp,
annotation_node->contributions[ci]);
annotation_node->contributions[ci] = NULL;
// "Break" out of SBITSET__FOR_EACH.
goto after_sbitset__for_each;
}
if (!lookaheads[i])
lookaheads[i] = bitset_create (ntokens, BITSET_FIXED);
bitset_set (lookaheads[i], contribution_token);
else
{
Sbitset__or (annotation_node->contributions[ci],
annotation_node->contributions[ci],
items, (*predecessor)->nitems);
obstack_free (annotations_obstackp, items);
}
}
/* If this kernel item is later in the RHS, then check the
predecessor item's lookahead set. */
else
{
/* We don't have to start the predecessor item search at
the beginning every time because items from both
states are sorted by their indices in ritem. */
for (;
predecessor_item < (*predecessor)->nitems;
++predecessor_item)
if ((*predecessor)->items[predecessor_item]
== s->items[self_item] - 1)
break;
aver (predecessor_item != (*predecessor)->nitems);
if (ielr_item_has_lookahead (*predecessor, 0,
predecessor_item,
contribution_token,
predecessors,
item_lookahead_sets))
Sbitset__set (annotation_node->contributions[ci],
predecessor_item);
}
}
after_sbitset__for_each:;
}
}
if (annotation_node->contributions[ci])
{
Sbitset biter;
Sbitset__Index i;
SBITSET__FOR_EACH (annotation_node->contributions[ci],
(*predecessor)->nitems, biter, i)
{
potential_contribution = true;
if (!lookaheads)
{
lookaheads = xnmalloc ((*predecessor)->nitems,
sizeof *lookaheads);
for (size_t j = 0; j < (*predecessor)->nitems; ++j)
lookaheads[j] = NULL;
}
if (!lookaheads[i])
lookaheads[i] = bitset_create (ntokens, BITSET_FIXED);
bitset_set (lookaheads[i], contribution_token);
}
}
}
/* If the predecessor has any contributions besides just "always" and
"never" contributions:
@@ -409,7 +401,7 @@ AnnotationList__compute_from_inadequacies (
struct obstack *annotations_obstackp,
InadequacyListNodeCount *inadequacy_list_node_count)
{
/* Return an empty list if s->lookahead_tokens = NULL. */
/* Return an empty list if s->lookaheads = NULL. */
if (s->consistent)
return;
@@ -425,16 +417,12 @@ AnnotationList__compute_from_inadequacies (
BITSET_FOR_EACH (biter_conflict, conflicted_tokens, conflicted_token, 0)
{
AnnotationList *annotation_node;
/* FIXME: Would a BITSET_FRUGAL or BITEST_SPARSE be more efficient? Now
or convert it inside InadequacyList__new_conflict? */
bitset actions = bitset_create (s->reductions->num + 1, BITSET_FIXED);
ContributionIndex contribution_count = 0;
bool potential_contribution = false;
/* Allocate the annotation node. */
{
for (int rule_i = 0; rule_i < s->reductions->num; ++rule_i)
if (bitset_test (s->reductions->lookahead_tokens[rule_i],
if (bitset_test (s->reductions->lookaheads[rule_i],
conflicted_token))
++contribution_count;
if (bitset_test (shift_tokens, conflicted_token))
@@ -444,6 +432,11 @@ AnnotationList__compute_from_inadequacies (
annotations_obstackp);
}
/* FIXME: Would a BITSET_FRUGAL or BITEST_SPARSE be more efficient? Now
or convert it inside InadequacyList__new_conflict? */
bitset actions = bitset_create (s->reductions->num + 1, BITSET_FIXED);
bool potential_contribution = false;
/* Add a contribution for each reduction that has conflicted_token as a
lookahead. */
{
@@ -452,7 +445,7 @@ AnnotationList__compute_from_inadequacies (
for (int rule_i = 0; rule_i < s->reductions->num; ++rule_i)
{
rule *the_rule = s->reductions->rules[rule_i];
if (bitset_test (s->reductions->lookahead_tokens[rule_i],
if (bitset_test (s->reductions->lookaheads[rule_i],
conflicted_token))
{
bitset_set (actions, rule_i);
@@ -464,11 +457,8 @@ AnnotationList__compute_from_inadequacies (
annotations_obstackp);
/* Catch item_i up to rule_i. This works because both are
sorted on rule number. */
while (!item_number_is_rule_number (
ritem[s->items[item_i]])
|| item_number_as_rule_number (
ritem[s->items[item_i]])
!= the_rule->number)
while (!item_number_is_rule_number (ritem[s->items[item_i]])
|| item_number_as_rule_number (ritem[s->items[item_i]]) != the_rule->number)
{
++item_i;
aver (item_i < s->nitems);
@@ -571,44 +561,40 @@ AnnotationList__debug (AnnotationList const *self, size_t nitems, int spaces)
AnnotationIndex ai;
for (a = self, ai = 0; a; a = a->next, ++ai)
{
for (int j = 0; j < spaces; ++j)
putc (' ', stderr);
fprintf (stderr, "Annotation %d (manifesting state %d):\n",
fprintf (stderr, "%*sAnnotation %d (manifesting state %d):\n",
spaces, "",
ai, a->inadequacyNode->manifestingState->number);
{
bitset_bindex rulei
= bitset_first (a->inadequacyNode->inadequacy.conflict.actions);
for (ContributionIndex ci = 0; ci < a->inadequacyNode->contributionCount; ++ci)
{
symbol_number token =
InadequacyList__getContributionToken (a->inadequacyNode, ci)
->content->number;
for (int j = 0; j < spaces+2; ++j)
putc (' ', stderr);
if (ci == InadequacyList__getShiftContributionIndex (
a->inadequacyNode))
fprintf (stderr, "Contributes shift of token %d.\n", token);
else
{
fprintf (stderr, "Contributes token %d", token);
aver (rulei != BITSET_BINDEX_MAX);
fprintf (stderr, " as lookahead, rule number %d",
a->inadequacyNode->manifestingState
->reductions->rules[rulei]->number);
rulei =
bitset_next (a->inadequacyNode->inadequacy.conflict.actions,
rulei+1);
if (AnnotationList__isContributionAlways (a, ci))
fprintf (stderr, " always.");
else
{
fprintf (stderr, ", items: ");
Sbitset__fprint (a->contributions[ci], nitems, stderr);
}
fprintf (stderr, "\n");
}
}
}
bitset_bindex rulei
= bitset_first (a->inadequacyNode->inadequacy.conflict.actions);
for (ContributionIndex ci = 0; ci < a->inadequacyNode->contributionCount; ++ci)
{
symbol_number token =
InadequacyList__getContributionToken (a->inadequacyNode, ci)
->content->number;
fprintf (stderr, "%*s", spaces+2, "");
if (ci == InadequacyList__getShiftContributionIndex (
a->inadequacyNode))
fprintf (stderr, "Contributes shift of token %d.\n", token);
else
{
fprintf (stderr, "Contributes token %d", token);
aver (rulei != BITSET_BINDEX_MAX);
fprintf (stderr, " as lookahead, rule number %d",
a->inadequacyNode->manifestingState
->reductions->rules[rulei]->number);
rulei =
bitset_next (a->inadequacyNode->inadequacy.conflict.actions,
rulei+1);
if (AnnotationList__isContributionAlways (a, ci))
fprintf (stderr, " always.");
else
{
fprintf (stderr, ", items: ");
Sbitset__fprint (a->contributions[ci], nitems, stderr);
}
fprintf (stderr, "\n");
}
}
}
}
@@ -775,8 +761,7 @@ AnnotationList__computeDominantContribution (AnnotationList const *self,
/* R/R conflict, so the reduction with the lowest rule number dominates.
Fortunately, contributions are sorted by rule number. */
for (ContributionIndex ci = 0; ci < self->inadequacyNode->contributionCount; ++ci)
if (AnnotationList__stateMakesContribution (self, nitems, ci,
lookaheads))
if (AnnotationList__stateMakesContribution (self, nitems, ci, lookaheads))
{
if (require_split_stable
&& !AnnotationList__isContributionAlways (self, ci))
+1
View File
@@ -21,6 +21,7 @@
# define ANNOTATION_LIST_H_
# include <bitsetv.h>
# include "Sbitset.h"
# include "InadequacyList.h"
# include "state.h"
+2
View File
@@ -81,6 +81,8 @@ void Sbitset__fprint (Sbitset self, Sbitset__Index nbits, FILE *file);
*ptr_self = *ptr_other1 | *ptr_other2; \
} while (0)
/* ATTENTION: there are *two* loops here, "break" and "continue" will
not apply to the whole loop, just the inner one. */
# define SBITSET__FOR_EACH(SELF, NBITS, ITER, INDEX) \
for ((ITER) = (SELF); (ITER) < (SELF) + Sbitset__nbytes (NBITS); ++(ITER)) \
if (*(ITER) != 0) \
+20 -20
View File
@@ -32,7 +32,7 @@
#include "symtab.h"
/* NITEMSET is the size of the array ITEMSET. */
item_number *itemset;
item_index *itemset;
size_t nitemset;
/* RULESET contains a bit for each rule. CLOSURE sets the bits for
@@ -54,16 +54,16 @@ static bitsetv firsts = NULL;
`-----------------*/
static void
closure_print (char const *title, item_number const *array, size_t size)
closure_print (char const *title, item_index const *array, size_t size)
{
fprintf (stderr, "Closure: %s\n", title);
for (size_t i = 0; i < size; ++i)
{
fprintf (stderr, " %2d: .", array[i]);
item_number *rp;
for (rp = &ritem[array[i]]; *rp >= 0; ++rp)
for (rp = &ritem[array[i]]; 0 <= *rp; ++rp)
fprintf (stderr, " %s", symbols[*rp]->tag);
fprintf (stderr, " (rule %d)\n", -*rp - 1);
fprintf (stderr, " (rule %d)\n", item_number_as_rule_number (*rp));
}
fputs ("\n\n", stderr);
}
@@ -104,21 +104,21 @@ print_fderives (void)
fprintf (stderr, "\n\n");
}
/*------------------------------------------------------------------.
| Set FIRSTS to be an NVARS array of NVARS bitsets indicating which |
| items can represent the beginning of the input corresponding to |
| which other items. |
| |
| For example, if some rule expands symbol 5 into the sequence of |
| symbols 8 3 20, the symbol 8 can be the beginning of the data for |
| symbol 5, so the bit [8 - ntokens] in first[5 - ntokens] (= FIRST |
| (5)) is set. |
`------------------------------------------------------------------*/
/*-------------------------------------------------------------------.
| Set FIRSTS to be an NNTERMS array of NNTERMS bitsets indicating |
| which items can represent the beginning of the input corresponding |
| to which other items. |
| |
| For example, if some rule expands symbol 5 into the sequence of |
| symbols 8 3 20, the symbol 8 can be the beginning of the data for |
| symbol 5, so the bit [8 - ntokens] in first[5 - ntokens] (= FIRST |
| (5)) is set. |
`-------------------------------------------------------------------*/
static void
set_firsts (void)
{
firsts = bitsetv_create (nvars, nvars, BITSET_FIXED);
firsts = bitsetv_create (nnterms, nnterms, BITSET_FIXED);
for (symbol_number i = ntokens; i < nsyms; ++i)
for (symbol_number j = 0; derives[i - ntokens][j]; ++j)
@@ -139,8 +139,8 @@ set_firsts (void)
}
/*-------------------------------------------------------------------.
| Set FDERIVES to an NVARS by NRULES matrix of bits indicating which |
| rules can help derive the beginning of the data for each |
| Set FDERIVES to an NNTERMS by NRULES matrix of bits indicating |
| which rules can help derive the beginning of the data for each |
| nonterminal. |
| |
| For example, if symbol 5 can be derived as the sequence of symbols |
@@ -151,7 +151,7 @@ set_firsts (void)
static void
set_fderives (void)
{
fderives = bitsetv_create (nvars, nrules, BITSET_FIXED);
fderives = bitsetv_create (nnterms, nrules, BITSET_FIXED);
set_firsts ();
@@ -182,7 +182,7 @@ closure_new (int n)
void
closure (item_number const *core, size_t n)
closure (item_index const *core, size_t n)
{
if (trace_flag & trace_closure)
closure_print ("input", core, n);
@@ -203,7 +203,7 @@ closure (item_number const *core, size_t n)
bitset_iterator iter;
BITSET_FOR_EACH (iter, ruleset, ruleno, 0)
{
item_number itemno = rules[ruleno].rhs - ritem;
item_index itemno = rules[ruleno].rhs - ritem;
while (c < n && core[c] < itemno)
{
itemset[nitemset] = core[c];
+4 -4
View File
@@ -30,12 +30,12 @@
void closure_new (int n);
/* Given the kernel (aka core) of a state (a sorted vector of item numbers
/* Given the kernel (aka core) of a state (a sorted vector of item indices
ITEMS, of length N), set up RULESET and ITEMSET to indicate what
rules could be run and which items could be accepted when those
items are the active ones. */
void closure (item_number const *items, size_t n);
void closure (item_index const *items, size_t n);
/* Free ITEMSET, RULESET and internal data. */
@@ -43,12 +43,12 @@ void closure (item_number const *items, size_t n);
void closure_free (void);
/* ITEMSET is a sorted vector of item numbers; NITEMSET is its size
/* ITEMSET is a sorted vector of item indices; NITEMSET is its size
(actually, points to just beyond the end of the part of it that is
significant). CLOSURE places there the indices of all items which
represent units of input that could arrive next. */
extern item_number *itemset;
extern item_index *itemset;
extern size_t nitemset;
#endif /* !CLOSURE_H_ */
+68 -19
View File
@@ -35,6 +35,13 @@
#include "getargs.h"
#include "quote.h"
// The URL of the manual page about diagnostics. Use the per-node
// manual, to avoid downloading repeatedly the whole manual over the
// Internet.
static const char *diagnostics_url
= "https://www.gnu.org/software/bison/manual/html_node/Diagnostics.html";
err_status complaint_status = status_none;
bool warnings_are_errors = false;
@@ -96,6 +103,20 @@ end_use_class (const char *s, FILE *out)
}
}
static void
begin_hyperlink (FILE *out, const char *ref)
{
if (out == stderr)
styled_ostream_set_hyperlink (errstream, ref, NULL);
}
static void
end_hyperlink (FILE *out)
{
if (out == stderr)
styled_ostream_set_hyperlink (errstream, NULL, NULL);
}
void
flush (FILE *out)
{
@@ -104,6 +125,23 @@ flush (FILE *out)
fflush (out);
}
bool
is_styled (FILE *out)
{
if (out != stderr)
return false;
if (color_debug)
return true;
#if HAVE_LIBTEXTSTYLE
return (color_mode == color_yes
|| color_mode == color_html
|| (color_mode == color_tty && isatty (STDERR_FILENO)));
#else
return false;
#endif
}
/*------------------------.
| --warnings's handling. |
`------------------------*/
@@ -114,6 +152,7 @@ static const argmatch_warning_doc argmatch_warning_docs[] =
{
{ "conflicts-sr", N_("S/R conflicts (enabled by default)") },
{ "conflicts-rr", N_("R/R conflicts (enabled by default)") },
{ "counterexamples", N_("generate conflict counterexamples") },
{ "dangling-alias", N_("string aliases not attached to a symbol") },
{ "deprecated", N_("obsolete constructs") },
{ "empty-rule", N_("empty rules without %empty") },
@@ -121,7 +160,7 @@ static const argmatch_warning_doc argmatch_warning_docs[] =
{ "precedence", N_("useless precedence and associativity") },
{ "yacc", N_("incompatibilities with POSIX Yacc") },
{ "other", N_("all other warnings (enabled by default)") },
{ "all", N_("all the warnings except 'dangling-alias' and 'yacc'") },
{ "all", N_("all the warnings except 'counterexamples', 'dangling-alias' and 'yacc'") },
{ "no-CATEGORY", N_("turn off warnings in CATEGORY") },
{ "none", N_("turn off all the warnings") },
{ "error[=CATEGORY]", N_("treat warnings as errors") },
@@ -130,18 +169,19 @@ static const argmatch_warning_doc argmatch_warning_docs[] =
static const argmatch_warning_arg argmatch_warning_args[] =
{
{ "all", Wall },
{ "conflicts-rr", Wconflicts_rr },
{ "conflicts-sr", Wconflicts_sr },
{ "dangling-alias", Wdangling_alias },
{ "deprecated", Wdeprecated },
{ "empty-rule", Wempty_rule },
{ "everything", Weverything },
{ "midrule-values", Wmidrule_values },
{ "none", Wnone },
{ "other", Wother },
{ "precedence", Wprecedence },
{ "yacc", Wyacc },
{ "all", Wall },
{ "conflicts-rr", Wconflicts_rr },
{ "conflicts-sr", Wconflicts_sr },
{ "counterexamples", Wcounterexamples }, { "cex", Wcounterexamples }, // Show cex second.
{ "dangling-alias", Wdangling_alias },
{ "deprecated", Wdeprecated },
{ "empty-rule", Wempty_rule },
{ "everything", Weverything },
{ "midrule-values", Wmidrule_values },
{ "none", Wnone },
{ "other", Wother },
{ "precedence", Wprecedence },
{ "yacc", Wyacc },
{ NULL, Wnone }
};
@@ -286,9 +326,7 @@ void
complain_init_color (void)
{
#if HAVE_LIBTEXTSTYLE
if (color_mode == color_yes
|| color_mode == color_html
|| (color_mode == color_tty && isatty (STDERR_FILENO)))
if (is_styled (stderr))
{
style_file_prepare ("BISON_STYLE", "BISON_STYLEDIR", pkgdatadir (),
"bison-default.css");
@@ -410,9 +448,20 @@ warnings_print_categories (warnings warn_flags, FILE *out)
const char* style = severity_style (s);
fputs (" [", out);
begin_use_class (style, out);
fprintf (out, "-W%s%s",
s == severity_error ? "error=" : "",
argmatch_warning_argument (&w));
// E.g., "counterexamples".
const char *warning = argmatch_warning_argument (&w);
char ref[200];
snprintf (ref, sizeof ref,
"%s#W%s", diagnostics_url, warning);
begin_hyperlink (out, ref);
ostream_printf (errstream,
"-W%s%s",
s == severity_error ? "error=" : "",
warning);
end_hyperlink (out);
// Because we mix stdio with ostream I/O, we need to flush
// here for sake of color == debug.
flush (out);
end_use_class (style, out);
fputc (']', out);
/* Display only the first match, the second is "-Wall". */
+9 -3
View File
@@ -19,6 +19,8 @@
#ifndef COMPLAIN_H_
# define COMPLAIN_H_ 1
# include <attribute.h>
# include "location.h"
/*---------------.
@@ -34,6 +36,8 @@ void end_use_class (const char *style, FILE *out);
/** Flush \a out. */
void flush (FILE *out);
/** Whether there's styling on OUT. */
bool is_styled (FILE *out);
/*-------------.
| --warnings. |
@@ -44,6 +48,7 @@ typedef enum
{
warning_conflicts_rr,
warning_conflicts_sr,
warning_counterexamples,
warning_dangling_alias,
warning_deprecated,
warning_empty_rule,
@@ -104,6 +109,7 @@ typedef enum
Wconflicts_rr = 1 << warning_conflicts_rr,
Wconflicts_sr = 1 << warning_conflicts_sr,
Wcounterexamples = 1 << warning_counterexamples,
Wdangling_alias = 1 << warning_dangling_alias,
Wdeprecated = 1 << warning_deprecated,
Wempty_rule = 1 << warning_empty_rule,
@@ -120,7 +126,7 @@ typedef enum
/**< All above warnings. */
Weverything = ~complaint & ~fatal & ~silent,
Wall = Weverything & ~Wdangling_alias & ~Wyacc
Wall = Weverything & ~Wcounterexamples & ~Wdangling_alias & ~Wyacc
} warnings;
/** Whether the warnings of \a flags are all unset.
@@ -132,7 +138,7 @@ bool warning_is_enabled (warnings flags);
/** Make a complaint, with maybe a location. */
void complain (location const *loc, warnings flags, char const *message, ...)
__attribute__ ((__format__ (__printf__, 3, 4)));
ATTRIBUTE_FORMAT ((__printf__, 3, 4));
/** Likewise, but with an \a argc/argv interface. */
void complain_args (location const *loc, warnings w,
@@ -141,7 +147,7 @@ void complain_args (location const *loc, warnings w,
/** Make a subcomplain with location and note. */
void subcomplain (location const *loc, warnings flags,
char const *message, ...)
__attribute__ ((__format__ (__printf__, 3, 4)));
ATTRIBUTE_FORMAT ((__printf__, 3, 4));
/** GNU Bison extension not valid with POSIX Yacc. */
+87 -48
View File
@@ -25,6 +25,7 @@
#include "complain.h"
#include "conflicts.h"
#include "counterexample.h"
#include "files.h"
#include "getargs.h"
#include "gram.h"
@@ -48,6 +49,12 @@ static struct obstack solved_conflicts_xml_obstack;
static bitset shift_set;
static bitset lookahead_set;
bool
has_conflicts (const state *s)
{
return conflicts[s->number];
}
enum conflict_resolution
@@ -219,7 +226,7 @@ log_resolution (rule *r, symbol_number token,
/*------------------------------------------------------------------.
| Turn off the shift recorded for the specified token in the |
| specified state. Used when we resolve a shift-reduce conflict in |
| specified state. Used when we resolve a shift/reduce conflict in |
| favor of the reduction or as an error (%nonassoc). |
`------------------------------------------------------------------*/
@@ -238,19 +245,19 @@ flush_shift (state *s, int token)
/*--------------------------------------------------------------------.
| Turn off the reduce recorded for the specified token in the |
| specified lookahead set. Used when we resolve a shift-reduce |
| specified lookahead set. Used when we resolve a shift/reduce |
| conflict in favor of the shift or as an error (%nonassoc). |
`--------------------------------------------------------------------*/
static void
flush_reduce (bitset lookahead_tokens, int token)
flush_reduce (bitset lookaheads, int token)
{
bitset_reset (lookahead_tokens, token);
bitset_reset (lookaheads, token);
}
/*------------------------------------------------------------------.
| Attempt to resolve shift-reduce conflict for one rule by means of |
| Attempt to resolve shift/reduce conflict for one rule by means of |
| precedence declarations. It has already been checked that the |
| rule has a precedence. A conflict is resolved by modifying the |
| shift or reduce tables so that there is no longer a conflict. |
@@ -268,14 +275,14 @@ resolve_sr_conflict (state *s, int ruleno, symbol **errors, int *nerrs)
/* Find the rule to reduce by to get precedence of reduction. */
rule *redrule = reds->rules[ruleno];
int redprec = redrule->prec->prec;
bitset lookahead_tokens = reds->lookahead_tokens[ruleno];
bitset lookaheads = reds->lookaheads[ruleno];
for (symbol_number i = 0; i < ntokens; ++i)
if (bitset_test (lookahead_tokens, i)
if (bitset_test (lookaheads, i)
&& bitset_test (lookahead_set, i)
&& symbols[i]->content->prec)
{
/* Shift-reduce conflict occurs for token number i
/* Shift/reduce conflict occurs for token number i
and it has a precedence.
The precedence of shifting is that of token i. */
if (symbols[i]->content->prec < redprec)
@@ -288,7 +295,7 @@ resolve_sr_conflict (state *s, int ruleno, symbol **errors, int *nerrs)
{
register_precedence (i, redrule->prec->number);
log_resolution (redrule, i, shift_resolution);
flush_reduce (lookahead_tokens, i);
flush_reduce (lookaheads, i);
}
else
/* Matching precedence levels.
@@ -309,7 +316,7 @@ resolve_sr_conflict (state *s, int ruleno, symbol **errors, int *nerrs)
case right_assoc:
register_assoc (i, redrule->prec->number);
log_resolution (redrule, i, right_resolution);
flush_reduce (lookahead_tokens, i);
flush_reduce (lookaheads, i);
break;
case left_assoc:
@@ -322,7 +329,7 @@ resolve_sr_conflict (state *s, int ruleno, symbol **errors, int *nerrs)
register_assoc (i, redrule->prec->number);
log_resolution (redrule, i, nonassoc_resolution);
flush_shift (s, i);
flush_reduce (lookahead_tokens, i);
flush_reduce (lookaheads, i);
/* Record an explicit error for this token. */
errors[(*nerrs)++] = symbols[i];
break;
@@ -357,11 +364,12 @@ set_conflicts (state *s, symbol **errors)
}
/* Loop over all rules which require lookahead in this state. First
check for shift-reduce conflict, and try to resolve using
check for shift/reduce conflict, and try to resolve using
precedence. */
for (int i = 0; i < reds->num; ++i)
if (reds->rules[i]->prec && reds->rules[i]->prec->prec
&& !bitset_disjoint_p (reds->lookahead_tokens[i], lookahead_set))
if (reds->rules[i]->prec
&& reds->rules[i]->prec->prec
&& !bitset_disjoint_p (reds->lookaheads[i], lookahead_set))
resolve_sr_conflict (s, i, errors, &nerrs);
if (nerrs)
@@ -377,13 +385,13 @@ set_conflicts (state *s, symbol **errors)
/* Loop over all rules which require lookahead in this state. Check
for conflicts not resolved above.
reds->lookahead_tokens can be NULL if the LR type is LR(0). */
if (reds->lookahead_tokens)
reds->lookaheads can be NULL if the LR type is LR(0). */
if (reds->lookaheads)
for (int i = 0; i < reds->num; ++i)
{
if (!bitset_disjoint_p (reds->lookahead_tokens[i], lookahead_set))
if (!bitset_disjoint_p (reds->lookaheads[i], lookahead_set))
conflicts[s->number] = true;
bitset_or (lookahead_set, lookahead_set, reds->lookahead_tokens[i]);
bitset_or (lookahead_set, lookahead_set, reds->lookaheads[i]);
}
}
@@ -452,7 +460,7 @@ count_state_sr_conflicts (const state *s)
}
for (int i = 0; i < reds->num; ++i)
bitset_or (lookahead_set, lookahead_set, reds->lookahead_tokens[i]);
bitset_or (lookahead_set, lookahead_set, reds->lookaheads[i]);
bitset_and (lookahead_set, lookahead_set, shift_set);
@@ -491,7 +499,7 @@ count_state_rr_conflicts (const state *s)
{
int count = 0;
for (int j = 0; j < reds->num; ++j)
count += bitset_test (reds->lookahead_tokens[j], i);
count += bitset_test (reds->lookaheads[j], i);
if (2 <= count)
res += count-1;
}
@@ -526,7 +534,7 @@ count_rule_state_sr_conflicts (rule *r, state *s)
for (int i = 0; i < reds->num; ++i)
if (reds->rules[i] == r)
{
bitset lookaheads = reds->lookahead_tokens[i];
bitset lookaheads = reds->lookaheads[i];
int j;
FOR_EACH_SHIFT (trans, j)
res += bitset_test (lookaheads, TRANSITION_SYMBOL (trans, j));
@@ -568,8 +576,8 @@ count_rule_state_rr_conflicts (rule *r, state *s)
if (reds->rules[j] != r)
{
bitset_and (lookaheads,
reds->lookahead_tokens[i],
reds->lookahead_tokens[j]);
reds->lookaheads[i],
reds->lookaheads[j]);
res += bitset_count (lookaheads);
}
bitset_free (lookaheads);
@@ -624,12 +632,20 @@ conflicts_total_count (void)
return count_sr_conflicts () + count_rr_conflicts ();
}
/*------------------------------.
| Reporting per-rule conflicts. |
`------------------------------*/
static void
report_counterexamples (void)
{
for (state_number sn = 0; sn < nstates; ++sn)
if (conflicts[sn])
counterexample_report_state (states[sn], stderr, "");
}
/*------------------------------------------------.
| Report per-rule %expect/%expect-rr mismatches. |
`------------------------------------------------*/
static void
rule_conflicts_print (void)
report_rule_expectation_mismatches (void)
{
for (rule_number i = 0; i < nrules; i += 1)
{
@@ -644,13 +660,13 @@ rule_conflicts_print (void)
complain (&r->location, complaint,
_("shift/reduce conflicts for rule %d:"
" %d found, %d expected"),
r->user_number, sr, expected_sr);
r->code, sr, expected_sr);
int rr = count_rule_rr_conflicts (r);
if (rr != expected_rr && (rr != 0 || expected_rr != -1))
complain (&r->location, complaint,
_("reduce/reduce conflicts for rule %d:"
" %d found, %d expected"),
r->user_number, rr, expected_rr);
r->code, rr, expected_rr);
}
}
}
@@ -662,7 +678,7 @@ rule_conflicts_print (void)
void
conflicts_print (void)
{
rule_conflicts_print ();
report_rule_expectation_mismatches ();
if (! glr_parser && expected_rr_conflicts != -1)
{
@@ -670,8 +686,10 @@ conflicts_print (void)
expected_rr_conflicts = -1;
}
/* Screams for factoring, but almost useless because of the
different strings to translate. */
// 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. */
{
int total = count_sr_conflicts ();
/* If %expect is not used, but %expect-rr is, then expect 0 sr. */
@@ -682,16 +700,23 @@ conflicts_print (void)
if (expected != -1)
{
if (expected != total)
complain (NULL, complaint,
_("shift/reduce conflicts: %d found, %d expected"),
total, expected);
{
complain (NULL, complaint,
_("shift/reduce conflicts: %d found, %d expected"),
total, expected);
if (total)
unexpected_conflicts_warning = complaint;
}
}
else if (total)
complain (NULL, Wconflicts_sr,
ngettext ("%d shift/reduce conflict",
"%d shift/reduce conflicts",
total),
total);
{
complain (NULL, Wconflicts_sr,
ngettext ("%d shift/reduce conflict",
"%d shift/reduce conflicts",
total),
total);
unexpected_conflicts_warning = Wconflicts_sr;
}
}
{
@@ -704,17 +729,31 @@ conflicts_print (void)
if (expected != -1)
{
if (expected != total)
complain (NULL, complaint,
_("reduce/reduce conflicts: %d found, %d expected"),
total, expected);
{
complain (NULL, complaint,
_("reduce/reduce conflicts: %d found, %d expected"),
total, expected);
if (total)
unexpected_conflicts_warning = complaint;
}
}
else if (total)
complain (NULL, Wconflicts_rr,
ngettext ("%d reduce/reduce conflict",
"%d reduce/reduce conflicts",
total),
total);
{
complain (NULL, Wconflicts_rr,
ngettext ("%d reduce/reduce conflict",
"%d reduce/reduce conflicts",
total),
total);
unexpected_conflicts_warning = Wconflicts_rr;
}
}
if (warning_is_enabled (Wcounterexamples))
report_counterexamples ();
else if (unexpected_conflicts_warning != Wnone)
subcomplain (NULL, unexpected_conflicts_warning,
_("rerun with option '-Wcounterexamples'"
" to generate conflict counterexamples"));
}
void
+2
View File
@@ -41,6 +41,8 @@ int conflicts_total_count (void);
void conflicts_output (FILE *out);
void conflicts_free (void);
bool has_conflicts (const state *s);
/* Were there conflicts? */
extern int expected_sr_conflicts;
extern int expected_rr_conflicts;
+1390
View File
File diff suppressed because it is too large Load Diff
+36
View File
@@ -0,0 +1,36 @@
/* Conflict counterexample generation
Copyright (C) 2020 Free Software Foundation, Inc.
This file is part of Bison, the GNU Compiler Compiler.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
#ifndef COUNTEREXAMPLE_H
# define COUNTEREXAMPLE_H
# include "state.h"
// Init/deinit this module.
void counterexample_init (void);
void counterexample_free (void);
// Print the counterexamples for the conflicts of state S.
//
// Used both for the warnings on the terminal (OUT = stderr, PREFIX =
// ""), and for the reports (OUT != stderr, PREFIX != "").
void
counterexample_report_state (const state *s, FILE *out, const char *prefix);
#endif /* COUNTEREXAMPLE_H */
+444
View File
@@ -0,0 +1,444 @@
/* Counterexample derivation trees
Copyright (C) 2020 Free Software Foundation, Inc.
This file is part of Bison, the GNU Compiler Compiler.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include <config.h>
#include "derivation.h"
#include "glyphs.h"
#include <c-ctype.h>
#include <gl_linked_list.h>
#include <mbswidth.h>
#include "system.h"
#include "complain.h"
struct derivation
{
symbol_number sym;
derivation_list children;
int reference_count;
// Color assigned for styling. Guarantees that the derivation is
// always displayed with the same color, independently of the order
// in which the derivations are traversed.
int color;
};
static derivation d_dot = { -1, NULL, -1, -1 };
derivation *
derivation_dot (void)
{
return &d_dot;
}
void
derivation_list_append (derivation_list dl, derivation *d)
{
derivation_retain (d);
gl_list_add_last (dl, d);
}
void
derivation_list_prepend (derivation_list dl, derivation *d)
{
derivation_retain (d);
gl_list_add_first (dl, d);
}
void derivation_list_free (derivation_list dl)
{
derivation *d = NULL;
for (gl_list_iterator_t it = gl_list_iterator (dl);
derivation_list_next (&it, &d);
)
if (d != &d_dot)
derivation_free (d);
gl_list_free (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;
}
void
derivation_retain (derivation *d)
{
++d->reference_count;
}
void
derivation_free (derivation *d)
{
if (!d)
return;
derivation_list free_queue =
gl_list_create (GL_LINKED_LIST, NULL, NULL, NULL, true,
1, (const void **)&d);
while (gl_list_size (free_queue) > 0)
{
derivation *deriv = (derivation *) gl_list_get_at (free_queue, 0);
if (--deriv->reference_count == 0)
{
if (deriv->children)
{
derivation *child = NULL;
for (gl_list_iterator_t it = gl_list_iterator (deriv->children);
derivation_list_next (&it, &child);
)
if (child != &d_dot)
gl_list_add_last (free_queue, child);
gl_list_free (deriv->children);
}
free (deriv);
}
gl_list_remove_at (free_queue, 0);
}
gl_list_free (free_queue);
}
size_t
derivation_size (const derivation *deriv)
{
if (!deriv->children)
return 1;
int size = 1;
derivation *child = NULL;
for (gl_list_iterator_t it = gl_list_iterator (deriv->children);
derivation_list_next (&it, &child);
)
size += derivation_size (child);
return size;
}
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)
{
if (deriv->children)
{
// Children's depth cannot be 0, even if there are no children
// (the case of a derivation with an empty RHS).
int res = 1;
derivation *child;
for (gl_list_iterator_t it = gl_list_iterator (deriv->children);
derivation_list_next (&it, &child);
)
res = max (res, derivation_depth (child));
return res + 1;
}
else
return 1;
}
static bool
all_spaces (const char *s)
{
while (c_isspace (*s))
s++;
return *s == '\0';
}
// Printing the derivation as trees without trailing spaces is
// painful: we cannot simply pad one "column" before moving to the
// next:
//
// exp
// ↳ x1 e1 foo1 x1
// ↳ x2 ↳ ε ↳ foo2 ↳ x2
// ↳ x3 ↳ foo3 ↳ x3
// ↳ "X" • ↳ x1 foo4 ↳ "X"
// ↳ x2 ↳ "quuux"
// ↳ x3
// ↳ "X"
//
// It's hard for a column to know that it's "last" to decide whether
// to output the right-padding or not. So when we need to pad on the
// right to complete a column, we don't output the spaces, we
// accumulate the width of padding in *PADDING.
//
// Each time we actually print something (non space), we flush that
// padding. When we _don't_ print something, its width is added to
// the current padding.
//
// This function implements this.
//
// 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)
{
int res = mbswidth (s, 0);
if (cond && !all_spaces (s))
{
fprintf (out, "%*s%s", *padding, "", s);
*padding = 0;
}
else
{
*padding += res;
}
return res;
}
// The width taken to report this derivation recursively down to its
// leaves.
static int
derivation_width (const derivation *deriv)
{
if (deriv->children)
{
const symbol *sym = symbols[deriv->sym];
int self_width = mbswidth (sym->tag, 0);
// Arrow and space.
int children_width = down_arrow_width;
if (gl_list_size (deriv->children) == 0)
// Empty rhs.
children_width += empty_width;
else
{
derivation *child;
for (gl_list_iterator_t it = gl_list_iterator (deriv->children);
derivation_list_next (&it, &child);
)
children_width
+= derivation_separator_width + derivation_width (child);
// No separator at the beginning.
children_width -= derivation_separator_width;
}
return max (self_width, children_width);
}
else if (deriv == &d_dot)
{
return dot_width;
}
else // leaf.
{
const symbol *sym = symbols[deriv->sym];
return mbswidth (sym->tag, 0);
}
}
// Print DERIV for DEPTH.
//
// The tree is printed from top to bottom with DEPTH ranging from 0 to
// the total depth of the tree. DERIV should only printed when we
// reach its depth, i.e., then DEPTH is 0.
//
// When DEPTH is 1 and we're on a subderivation, then we print the RHS
// of the derivation (in DEPTH 0 we printed its LHS).
//
// Return the "logical printed" width. We might have not have reached
// that width, in which case the missing spaces are in *PADDING.
static int
derivation_print_tree_impl (const derivation *deriv, FILE *out,
int depth, int *padding)
{
const int width = derivation_width (deriv);
int res = 0;
if (deriv->children)
{
const symbol *sym = symbols[deriv->sym];
char style[20];
snprintf (style, 20, "cex-%d", deriv->color);
if (depth == 0 || depth == 1)
{
begin_use_class (style, out);
begin_use_class ("cex-step", out);
}
if (depth == 0)
{
res += fputs_if (true, out, padding, sym->tag);
}
else
{
res += fputs_if (depth == 1, out, padding, down_arrow);
if (gl_list_size (deriv->children) == 0)
// Empty rhs.
res += fputs_if (depth == 1, out, padding, empty);
else
{
bool first = true;
derivation *child;
for (gl_list_iterator_t it = gl_list_iterator (deriv->children);
derivation_list_next (&it, &child);
)
{
if (!first)
res += fputs_if (depth == 1, out, padding, derivation_separator);
res += derivation_print_tree_impl (child, out, depth - 1, padding);
first = false;
}
}
}
if (depth == 0 || depth == 1)
{
end_use_class ("cex-step", out);
end_use_class (style, out);
}
*padding += width - res;
res = width;
}
else if (deriv == &d_dot)
{
if (depth == 0)
begin_use_class ("cex-dot", out);
res += fputs_if (depth == 0, out, padding, dot);
if (depth == 0)
end_use_class ("cex-dot", out);
}
else // leaf.
{
const symbol *sym = symbols[deriv->sym];
if (depth == 0)
begin_use_class ("cex-leaf", out);
res += fputs_if (depth == 0, out, padding, sym->tag);
if (depth == 0)
end_use_class ("cex-leaf", out);
}
return res;
}
static void
derivation_print_tree (const derivation *deriv, FILE *out, const char *prefix)
{
fputc ('\n', out);
for (int depth = 0, max_depth = derivation_depth (deriv);
depth < max_depth; ++depth)
{
int padding = 0;
fprintf (out, " %s", prefix);
derivation_print_tree_impl (deriv, out, depth, &padding);
fputc ('\n', out);
}
}
/* Print DERIV, colored according to COUNTER.
Return false if nothing is printed. */
static bool
derivation_print_flat_impl (derivation *deriv, FILE *out,
bool leaves_only,
int *counter, const char *prefix)
{
if (deriv->children)
{
const symbol *sym = symbols[deriv->sym];
deriv->color = *counter;
++*counter;
char style[20];
snprintf (style, 20, "cex-%d", deriv->color);
begin_use_class (style, out);
if (!leaves_only)
{
fputs (prefix, out);
begin_use_class ("cex-step", out);
fprintf (out, "%s %s [ ", sym->tag, arrow);
end_use_class ("cex-step", out);
prefix = "";
}
bool res = false;
derivation *child;
for (gl_list_iterator_t it = gl_list_iterator (deriv->children);
derivation_list_next (&it, &child);
)
{
if (derivation_print_flat_impl (child, out,
leaves_only, counter, prefix))
{
prefix = " ";
res = true;
}
else if (!leaves_only)
prefix = " ";
}
if (!leaves_only)
{
begin_use_class ("cex-step", out);
if (res)
fputs (" ]", out);
else
fputs ("]", out);
end_use_class ("cex-step", out);
}
end_use_class (style, out);
return res;
}
else if (deriv == &d_dot)
{
fputs (prefix, out);
begin_use_class ("cex-dot", out);
fputs (dot, out);
end_use_class ("cex-dot", out);
}
else // leaf.
{
fputs (prefix, out);
const symbol *sym = symbols[deriv->sym];
begin_use_class ("cex-leaf", out);
fprintf (out, "%s", sym->tag);
end_use_class ("cex-leaf", out);
}
return true;
}
static void
derivation_print_flat (const derivation *deriv, FILE *out, const char *prefix)
{
int counter = 0;
fputs (prefix, out);
derivation_print_flat_impl ((derivation *)deriv, out, false, &counter, "");
fputc ('\n', out);
}
void
derivation_print_leaves (const derivation *deriv, FILE *out)
{
int counter = 0;
derivation_print_flat_impl ((derivation *)deriv, out, true, &counter, "");
fputc ('\n', out);
}
void
derivation_print (const derivation *deriv, FILE *out, const char *prefix)
{
if (getenv ("YYFLAT"))
derivation_print_flat (deriv, out, prefix);
else
derivation_print_tree (deriv, out, prefix);
}
+74
View File
@@ -0,0 +1,74 @@
/* Counterexample derivation trees
Copyright (C) 2020 Free Software Foundation, Inc.
This file is part of Bison, the GNU Compiler Compiler.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
#ifndef DERIVATION_H
# define DERIVATION_H
# include <gl_linked_list.h>
# include <gl_xlist.h>
# include "gram.h"
/* Derivations are trees of symbols such that each nonterminal's
children are symbols that produce that nonterminal if they are
relevant to the counterexample. The leaves of a derivation form a
counterexample when printed. */
typedef gl_list_t derivation_list;
typedef struct derivation derivation;
static inline derivation_list derivation_list_new (void)
{
return gl_list_create_empty (GL_LINKED_LIST, NULL, NULL, NULL, true);
}
static inline bool
derivation_list_next (gl_list_iterator_t *it, derivation **d)
{
const void *p = NULL;
bool res = gl_list_iterator_next (it, &p, NULL);
if (res)
*d = (derivation *) p;
else
gl_list_iterator_free (it);
return res;
}
void derivation_list_append (derivation_list dl, derivation *d);
void derivation_list_prepend (derivation_list dl, derivation *d);
void derivation_list_free (derivation_list dl);
derivation *derivation_new (symbol_number sym, derivation_list children);
static inline derivation *derivation_new_leaf (symbol_number sym)
{
return derivation_new (sym, NULL);
}
// Number of symbols.
size_t derivation_size (const derivation *deriv);
void derivation_print (const derivation *deriv, FILE *out, const char *prefix);
void derivation_print_leaves (const derivation *deriv, FILE *out);
void derivation_free (derivation *deriv);
void derivation_retain (derivation *deriv);
// A derivation denoting the position of the dot.
derivation *derivation_dot (void);
#endif /* DERIVATION_H */
+4 -4
View File
@@ -47,7 +47,7 @@ print_derives (void)
fprintf (stderr, " %s derives\n", symbols[i]->tag);
for (rule **rp = derives[i - ntokens]; *rp; ++rp)
{
fprintf (stderr, " %3d ", (*rp)->user_number);
fprintf (stderr, " %3d ", (*rp)->code);
rule_rhs_print (*rp, stderr);
fprintf (stderr, "\n");
}
@@ -62,7 +62,7 @@ derives_compute (void)
{
/* DSET[NTERM - NTOKENS] -- A linked list of the numbers of the rules
whose LHS is NTERM. */
rule_list **dset = xcalloc (nvars, sizeof *dset);
rule_list **dset = xcalloc (nnterms, sizeof *dset);
/* DELTS[RULE] -- There are NRULES rule number to attach to nterms.
Instead of performing NRULES allocations for each, have an array
@@ -82,9 +82,9 @@ derives_compute (void)
/* DSET contains what we need under the form of a linked list. Make
it a single array. */
derives = xnmalloc (nvars, sizeof *derives);
derives = xnmalloc (nnterms, sizeof *derives);
/* Q is the storage for DERIVES[...] (DERIVES[0] = q). */
rule **q = xnmalloc (nvars + nrules, sizeof *q);
rule **q = xnmalloc (nnterms + nrules, sizeof *q);
for (symbol_number i = ntokens; i < nsyms; ++i)
{
+106 -2
View File
@@ -22,13 +22,18 @@
#include "system.h"
#include <configmake.h> /* PKGDATADIR */
#include <error.h>
#include <dirname.h>
#include <error.h>
#include <get-errno.h>
#include <gl_array_list.h>
#include <gl_xlist.h>
#include <quote.h>
#include <quotearg.h>
#include <relocatable.h> /* relocate2 */
#include <stdio-safer.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <xstrndup.h>
#include "complain.h"
@@ -52,6 +57,7 @@ char *spec_verbose_file = NULL; /* for --verbose. */
char *spec_graph_file = NULL; /* for -g. */
char *spec_xml_file = NULL; /* for -x. */
char *spec_header_file = NULL; /* for --defines. */
char *spec_mapped_header_file = NULL;
char *parser_file_name;
/* All computed output file names. */
@@ -70,7 +76,7 @@ static int generated_files_size = 0;
uniqstr grammar_file = NULL;
/* If --output=dir/foo.c was specified,
DIR_PREFIX is 'dir/' and ALL_BUT_EXT and ALL_BUT_TAB_EXT are 'dir/foo'.
DIR_PREFIX gis 'dir/' and ALL_BUT_EXT and ALL_BUT_TAB_EXT are 'dir/foo'.
If --output=dir/foo.tab.c was specified, DIR_PREFIX is 'dir/',
ALL_BUT_EXT is 'dir/foo.tab', and ALL_BUT_TAB_EXT is 'dir/foo'.
@@ -88,11 +94,20 @@ uniqstr grammar_file = NULL;
char *all_but_ext;
static char *all_but_tab_ext;
char *dir_prefix;
char *mapped_dir_prefix;
/* C source file extension (the parser source). */
static char *src_extension = NULL;
/* Header file extension (if option '`-d'' is specified). */
static char *header_extension = NULL;
struct prefix_map
{
char *oldprefix;
char *newprefix;
};
static gl_list_t prefix_maps = NULL;
/*-----------------------------------------------------------------.
| Return a newly allocated string composed of the concatenation of |
@@ -156,6 +171,70 @@ xfdopen (int fd, char const *mode)
return res;
}
/* Given an input file path, returns a dynamically allocated string that
contains the path with the file prefix mapping rules applied, or NULL if
the input was NULL. */
char *
map_file_name (char const *filename)
{
if (!filename)
return NULL;
struct prefix_map const *p = NULL;
if (prefix_maps)
{
void const *ptr;
gl_list_iterator_t iter = gl_list_iterator (prefix_maps);
while (gl_list_iterator_next (&iter, &ptr, NULL))
{
p = ptr;
if (strncmp (p->oldprefix, filename, strlen (p->oldprefix)) == 0)
break;
p = NULL;
}
gl_list_iterator_free (&iter);
}
if (!p)
return xstrdup (filename);
size_t oldprefix_len = strlen (p->oldprefix);
size_t newprefix_len = strlen (p->newprefix);
char *s = xmalloc (newprefix_len + strlen (filename) - oldprefix_len + 1);
char *end = stpcpy (s, p->newprefix);
stpcpy (end, filename + oldprefix_len);
return s;
}
static void
prefix_map_free (struct prefix_map *p)
{
free (p->oldprefix);
free (p->newprefix);
free (p);
}
/* Adds a new file prefix mapping. If a file path starts with oldprefix, it
will be replaced with newprefix */
void
add_prefix_map (char const *oldprefix, char const *newprefix)
{
if (!prefix_maps)
prefix_maps = gl_list_create_empty (GL_ARRAY_LIST,
/* equals */ NULL,
/* hashcode */ NULL,
(gl_listelement_dispose_fn) prefix_map_free,
true);
struct prefix_map *p = xmalloc (sizeof (*p));
p->oldprefix = xstrdup (oldprefix);
p->newprefix = xstrdup (newprefix);
gl_list_add_last (prefix_maps, p);
}
/*------------------------------------------------------------------.
| Compute ALL_BUT_EXT, ALL_BUT_TAB_EXT and output files extensions. |
`------------------------------------------------------------------*/
@@ -360,6 +439,9 @@ compute_output_file_names (void)
output_file_name_check (&spec_verbose_file, false);
}
spec_mapped_header_file = map_file_name (spec_header_file);
mapped_dir_prefix = map_file_name (dir_prefix);
free (all_but_tab_ext);
free (src_extension);
free (header_extension);
@@ -421,6 +503,23 @@ pkgdatadir (void)
}
}
char const *
m4path (void)
{
char const *m4 = getenv ("M4");
if (m4)
return m4;
/* We don't use relocate2() to store the temporary buffer and re-use
it, because m4path() is only called once. */
char const *m4_relocated = relocate (M4);
struct stat buf;
if (stat (m4_relocated, &buf) == 0)
return m4_relocated;
return M4;
}
void
output_file_names_free (void)
{
@@ -429,10 +528,15 @@ output_file_names_free (void)
free (spec_graph_file);
free (spec_xml_file);
free (spec_header_file);
free (spec_mapped_header_file);
free (parser_file_name);
free (dir_prefix);
free (mapped_dir_prefix);
for (int i = 0; i < generated_files_size; i++)
free (generated_files[i].name);
free (generated_files);
free (relocate_buffer);
if (prefix_maps)
gl_list_free (prefix_maps);
}
+12
View File
@@ -50,9 +50,15 @@ extern char *spec_xml_file;
/* File name specified with --defines. */
extern char *spec_header_file;
/* File name specified with --defines, adjusted for mapped prefixes. */
extern char *spec_mapped_header_file;
/* Directory prefix of output file names. */
extern char *dir_prefix;
/* Directory prefix of output file name, adjusted for mapped prefixes. */
extern char *mapped_dir_prefix;
/* The file name as given on the command line.
Not named "input_file" because Flex uses this name for an argument,
and therefore GCC warns about a name clash. */
@@ -64,6 +70,9 @@ extern char *all_but_ext;
/* Where our data files are installed. */
char const *pkgdatadir (void);
/* Where the m4 program is installed. */
char const *m4path (void);
void compute_output_file_names (void);
void output_file_names_free (void);
@@ -82,4 +91,7 @@ FILE *xfopen (const char *name, char const *mode);
void xfclose (FILE *ptr);
FILE *xfdopen (int fd, char const *mode);
char *map_file_name (char const *filename);
void add_prefix_map (char const *oldprefix, char const *newprefix);
#endif /* !FILES_H_ */
+10 -10
View File
@@ -21,19 +21,19 @@
#include "fixits.h"
#include <error.h>
#include <get-errno.h>
#include <gl_array_list.h>
#include <gl_xlist.h>
#include <progname.h>
#include <quote.h>
#include <quotearg.h>
#include <vasnprintf.h>
#include "system.h"
#include "error.h"
#include "get-errno.h"
#include "getargs.h"
#include "gl_array_list.h"
#include "gl_xlist.h"
#include "progname.h"
#include "quote.h"
#include "quotearg.h"
#include "vasnprintf.h"
#include "files.h"
#include "getargs.h"
typedef struct
{
+10 -7
View File
@@ -94,22 +94,25 @@ int FLEX_PREFIX (lex_destroy) (void);
keep (to construct ID, STRINGS etc.). Use the following macros to
use it.
Use STRING_GROW to append what has just been matched, and
STRING_FINISH to end the string (it puts the ending 0).
STRING_FINISH also stores this string in LAST_STRING, which can be
used, and which is used by STRING_FREE to free the last string. */
Use STRING_GROW () to append what has just been matched, and
STRING_FINISH () to end the string (it puts the ending 0).
STRING_FINISH () also stores this string in LAST_STRING, which can be
used, and which is used by STRING_FREE () to free the last string. */
#ifndef FLEX_NO_OBSTACK
static struct obstack obstack_for_string;
# define STRING_GROW \
# define STRING_GROW() \
obstack_grow (&obstack_for_string, yytext, yyleng)
# define STRING_FINISH \
# define STRING_FINISH() \
(last_string = obstack_finish0 (&obstack_for_string))
# define STRING_FREE \
# define STRING_1GROW(Char) \
obstack_1grow (&obstack_for_string, Char)
# define STRING_FREE() \
obstack_free (&obstack_for_string, last_string)
#endif
+62 -34
View File
@@ -151,8 +151,8 @@ flags_argmatch (const char *opt,
*/
#define FLAGS_ARGMATCH(FlagName, Args, All) \
flags_argmatch ("--" #FlagName, \
(xargmatch_fn*) argmatch_## FlagName ## _value, \
argmatch_## FlagName ## _usage, \
(xargmatch_fn*) argmatch_## FlagName ## _value, \
argmatch_ ## FlagName ## _usage, \
All, &FlagName ## _flag, Args)
/*---------------------.
@@ -206,23 +206,26 @@ ARGMATCH_DEFINE_GROUP (report, enum report)
static const argmatch_report_doc argmatch_report_docs[] =
{
{ "states", N_("describe the states") },
{ "itemsets", N_("complete the core item sets with their closure") },
{ "lookaheads", N_("explicitly associate lookahead tokens to items") },
{ "solved", N_("describe shift/reduce conflicts solving") },
{ "all", N_("include all the above information") },
{ "none", N_("disable the report") },
{ "states", N_("describe the states") },
{ "itemsets", N_("complete the core item sets with their closure") },
{ "lookaheads", N_("explicitly associate lookahead tokens to items") },
{ "solved", N_("describe shift/reduce conflicts solving") },
{ "counterexamples", N_("generate conflict counterexamples") },
{ "all", N_("include all the above information") },
{ "none", N_("disable the report") },
{ NULL, NULL },
};
static const argmatch_report_arg argmatch_report_args[] =
{
{ "none", report_none },
{ "states", report_states },
{ "itemsets", report_states | report_itemsets },
{ "lookaheads", report_states | report_lookahead_tokens },
{ "solved", report_states | report_solved_conflicts },
{ "all", report_all },
{ "none", report_none },
{ "states", report_states },
{ "itemsets", report_states | report_itemsets },
{ "lookaheads", report_states | report_lookaheads },
{ "solved", report_states | report_solved_conflicts },
{ "counterexamples", report_cex },
{ "cex", report_cex },
{ "all", report_all },
{ NULL, report_none },
};
@@ -257,10 +260,12 @@ static const argmatch_trace_doc argmatch_trace_docs[] =
{ "sets", "grammar sets: firsts, nullable etc." },
{ "muscles", "m4 definitions passed to the skeleton" },
{ "tools", "m4 invocation" },
{ "m4", "m4 traces" },
{ "m4-early", "m4 traces starting from the start" },
{ "m4", "m4 traces starting from the skeleton evaluation" },
{ "skeleton", "skeleton postprocessing" },
{ "time", "time consumption" },
{ "ielr", "IELR conversion" },
{ "cex", "counterexample generation"},
{ "all", "all of the above" },
{ NULL, NULL},
};
@@ -279,10 +284,12 @@ static const argmatch_trace_arg argmatch_trace_args[] =
{ "sets", trace_sets },
{ "muscles", trace_muscles },
{ "tools", trace_tools },
{ "m4-early", trace_m4_early },
{ "m4", trace_m4 },
{ "skeleton", trace_skeleton },
{ "time", trace_time },
{ "ielr", trace_ielr },
{ "cex", trace_cex },
{ "all", trace_all },
{ NULL, trace_none},
};
@@ -337,7 +344,8 @@ const argmatch_feature_group_type argmatch_feature_group =
| Display the help message and exit STATUS. |
`-------------------------------------------*/
static void usage (int) ATTRIBUTE_NORETURN;
_Noreturn
static void usage (int);
static void
usage (int status)
@@ -418,15 +426,17 @@ Tuning the Parser:\n\
* won't assume that -d also takes an argument. */
fputs (_("\
Output Files:\n\
--defines[=FILE] also produce a header file\n\
-d likewise but cannot specify FILE (for POSIX Yacc)\n\
-r, --report=THINGS also produce details on the automaton\n\
--report-file=FILE write report to FILE\n\
-v, --verbose same as '--report=state'\n\
-b, --file-prefix=PREFIX specify a PREFIX for output files\n\
-o, --output=FILE leave output to FILE\n\
-g, --graph[=FILE] also output a graph of the automaton\n\
-x, --xml[=FILE] also output an XML report of the automaton\n\
--defines[=FILE] also produce a header file\n\
-d likewise but cannot specify FILE (for POSIX Yacc)\n\
-r, --report=THINGS also produce details on the automaton\n\
--report-file=FILE write report to FILE\n\
-v, --verbose same as '--report=state'\n\
-b, --file-prefix=PREFIX specify a PREFIX for output files\n\
-o, --output=FILE leave output to FILE\n\
-g, --graph[=FILE] also output a graph of the automaton\n\
-x, --xml[=FILE] also output an XML report of the automaton\n\
-M, --file-prefix-map=OLD=NEW replace prefix OLD with NEW when writing file paths\n\
in output files\n\
"), stdout);
putc ('\n', stdout);
@@ -547,6 +557,7 @@ static char const short_options[] =
"h"
"k"
"l"
"M:"
"o:"
"p:"
"r:"
@@ -598,14 +609,15 @@ static struct option const long_options[] =
{ "yacc", no_argument, 0, 'y' },
/* Output Files. */
{ "defines", optional_argument, 0, 'd' },
{ "report", required_argument, 0, 'r' },
{ "report-file", required_argument, 0, REPORT_FILE_OPTION },
{ "verbose", no_argument, 0, 'v' },
{ "file-prefix", required_argument, 0, 'b' },
{ "output", required_argument, 0, 'o' },
{ "graph", optional_argument, 0, 'g' },
{ "xml", optional_argument, 0, 'x' },
{ "defines", optional_argument, 0, 'd' },
{ "report", required_argument, 0, 'r' },
{ "report-file", required_argument, 0, REPORT_FILE_OPTION },
{ "verbose", no_argument, 0, 'v' },
{ "file-prefix", required_argument, 0, 'b' },
{ "output", required_argument, 0, 'o' },
{ "graph", optional_argument, 0, 'g' },
{ "xml", optional_argument, 0, 'x' },
{ "file-prefix-map", required_argument, 0, 'M' },
/* Hidden. */
{ "fixed-output-files", no_argument, 0, FIXED_OUTPUT_FILES_OPTION },
@@ -711,6 +723,22 @@ getargs (int argc, char *argv[])
language_argmatch (optarg, command_line_prio, loc);
break;
case 'M': // -MOLDPREFIX=NEWPREFIX
{
char *newprefix = strchr (optarg, '=');
if (newprefix)
{
*newprefix = '\0';
add_prefix_map (optarg, newprefix + 1);
}
else
{
complain (&loc, complaint, _("invalid argument for %s: %s"),
quote ("--file-prefix-map"), quotearg_n (1, optarg));
}
}
break;
case 'S':
skeleton_arg (optarg, command_line_prio, loc);
break;
@@ -860,7 +888,7 @@ getargs (int argc, char *argv[])
void
tr (char *s, char from, char to)
{
for (; *s; s++)
for (; *s; ++s)
if (*s == from)
*s = to;
}
+9 -6
View File
@@ -77,8 +77,9 @@ enum report
report_none = 0,
report_states = 1 << 0,
report_itemsets = 1 << 1,
report_lookahead_tokens = 1 << 2,
report_lookaheads = 1 << 2,
report_solved_conflicts = 1 << 3,
report_cex = 1 << 4,
report_all = ~0
};
/** What appears in the *.output file. */
@@ -100,11 +101,13 @@ enum trace
trace_grammar = 1 << 7, /**< Reading, reducing the grammar. */
trace_time = 1 << 8, /**< Time consumption. */
trace_skeleton = 1 << 9, /**< Skeleton postprocessing. */
trace_m4 = 1 << 10, /**< M4 traces. */
trace_muscles = 1 << 11, /**< M4 definitions of the muscles. */
trace_ielr = 1 << 12, /**< IELR conversion. */
trace_closure = 1 << 13, /**< Input/output of closure(). */
trace_locations = 1 << 14, /**< Full display of locations. */
trace_m4_early = 1 << 10, /**< M4 early traces. */
trace_m4 = 1 << 11, /**< M4 traces. */
trace_muscles = 1 << 12, /**< M4 definitions of the muscles. */
trace_ielr = 1 << 13, /**< IELR conversion. */
trace_closure = 1 << 14, /**< Input/output of closure(). */
trace_locations = 1 << 15, /**< Full display of locations. */
trace_cex = 1 << 16, /**< Counterexample generation */
trace_all = ~0 /**< All of the above. */
};
/** What debug items bison displays during its run. */
+93
View File
@@ -0,0 +1,93 @@
/* Graphical symbols.
Copyright (C) 2020 Free Software Foundation, Inc.
This file is part of Bison, the GNU Compiler Compiler.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include <config.h>
#include "glyphs.h"
#include <assert.h>
#include <attribute.h>
#include <stdbool.h>
#include <string.h>
#include <mbswidth.h>
#include <unicodeio.h>
glyph_buffer_t arrow;
int arrow_width;
glyph_buffer_t down_arrow;
int down_arrow_width;
glyph_buffer_t dot;
int dot_width;
glyph_buffer_t empty;
int empty_width;
const char *derivation_separator = " ";
int derivation_separator_width = 1;
typedef struct
{
glyph_buffer_t *pbuf;
const char *fallback;
} callback_arg_t;
static long
on_success (const char *buf, size_t buflen, void *callback_arg)
{
callback_arg_t *arg = (callback_arg_t *) callback_arg;
assert (buflen + 1 < sizeof *arg->pbuf);
*stpncpy (*arg->pbuf, buf, buflen) = '\0';
return 1;
}
static long
on_failure (unsigned code MAYBE_UNUSED, const char *msg MAYBE_UNUSED,
void *callback_arg)
{
callback_arg_t *arg = (callback_arg_t *) callback_arg;
assert (strlen (arg->fallback) + 1 < sizeof *arg->pbuf);
strcpy (*arg->pbuf, arg->fallback);
return 0;
}
static bool
glyph_set (glyph_buffer_t *glyph, int *width,
unsigned code, const char *fallback)
{
callback_arg_t arg = { glyph, fallback };
int res = unicode_to_mb (code, on_success, on_failure, &arg);
*width = mbswidth (*glyph, 0);
return res;
}
void
glyphs_init (void)
{
glyph_set (&arrow, &arrow_width, 0x2192, "->");
glyph_set (&dot, &dot_width, 0x2022, ".");
glyph_set (&down_arrow, &down_arrow_width, 0x21b3, "`->");
glyph_set (&empty, &empty_width, 0x03b5, "%empty");
strncat (down_arrow, " ", sizeof down_arrow - strlen (down_arrow) - 1);
down_arrow_width += 1;
}
+50
View File
@@ -0,0 +1,50 @@
/* Graphical symbols.
Copyright (C) 2020 Free Software Foundation, Inc.
This file is part of Bison, the GNU Compiler Compiler.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
#ifndef GLYPHS_H
# define GLYPHS_H
/* Initialize the following variables. */
void glyphs_init (void);
/* In gnulib/lib/unicodeio.h unicode_to_mb uses a buffer of 25 bytes.
In down_arrow, we append one space. */
typedef char glyph_buffer_t[26];
/* "→", separates the lhs of a rule from its rhs. */
extern glyph_buffer_t arrow;
extern int arrow_width;
/* "•", a point in an item (aka, a dotted rule). */
extern glyph_buffer_t dot;
extern int dot_width;
/* "↳ ", below an lhs to announce the rhs. */
extern glyph_buffer_t down_arrow;
extern int down_arrow_width;
/* "ε", an empty rhs. */
extern glyph_buffer_t empty;
extern int empty_width;
/* " ", separate symbols in the rhs of a derivation. */
extern const char *derivation_separator;
extern int derivation_separator_width;
#endif /* GLYPHS_H */
+24 -24
View File
@@ -23,6 +23,7 @@
#include "complain.h"
#include "getargs.h"
#include "glyphs.h"
#include "gram.h"
#include "print-xml.h"
#include "reader.h"
@@ -40,25 +41,14 @@ rule_number nrules = 0;
symbol **symbols = NULL;
int nsyms = 0;
int ntokens = 1;
int nvars = 0;
int nnterms = 0;
symbol_number *token_translations = NULL;
int max_user_token_number = 256;
int max_code = 256;
int required_version = 0;
rule const *
item_rule (item_number const *item)
{
item_number const *sp = item;
while (0 <= *sp)
++sp;
rule_number r = item_number_as_rule_number (*sp);
return &rules[r];
}
void
item_print (item_number *item, rule const *previous_rule, FILE *out)
{
@@ -67,7 +57,7 @@ item_print (item_number *item, rule const *previous_rule, FILE *out)
for (item_number *sp = r->rhs; sp < item; sp++)
fprintf (out, " %s", symbols[*sp]->tag);
fputs (" .", out);
fprintf (out, " %s", dot);
if (0 <= *r->rhs)
for (item_number *sp = item; 0 <= *sp; ++sp)
fprintf (out, " %s", symbols[*sp]->tag);
@@ -202,10 +192,10 @@ grammar_rules_partial_print (FILE *out, const char *title,
if (first)
fprintf (out, "%s\n\n", title);
else if (previous_rule && previous_rule->lhs != rules[r].lhs)
fputc ('\n', out);
putc ('\n', out);
first = false;
rule_print (&rules[r], previous_rule, out);
fputc ('\n', out);
putc ('\n', out);
previous_rule = &rules[r];
}
if (!first)
@@ -251,15 +241,25 @@ grammar_rules_print_xml (FILE *out, int level)
xml_puts (out, level + 1, "<rules/>");
}
static void
section (FILE *out, const char *s)
{
fprintf (out, "%s\n", s);
for (int i = strlen (s); 0 < i; --i)
putc ('-', out);
putc ('\n', out);
putc ('\n', out);
}
void
grammar_dump (FILE *out, const char *title)
{
fprintf (out, "%s\n\n", title);
fprintf (out,
"ntokens = %d, nvars = %d, nsyms = %d, nrules = %d, nritems = %d\n\n",
ntokens, nvars, nsyms, nrules, nritems);
"ntokens = %d, nnterms = %d, nsyms = %d, nrules = %d, nritems = %d\n\n",
ntokens, nnterms, nsyms, nrules, nritems);
fprintf (out, "Tokens\n------\n\n");
section (out, "Tokens");
{
fprintf (out, "Value Sprec Sassoc Tag\n");
@@ -271,7 +271,7 @@ grammar_dump (FILE *out, const char *title)
fprintf (out, "\n\n");
}
fprintf (out, "Non terminals\n-------------\n\n");
section (out, "Nonterminals");
{
fprintf (out, "Value Tag\n");
@@ -281,7 +281,7 @@ grammar_dump (FILE *out, const char *title)
fprintf (out, "\n\n");
}
fprintf (out, "Rules\n-----\n\n");
section (out, "Rules");
{
fprintf (out,
"Num (Prec, Assoc, Useful, UselessChain) Lhs"
@@ -303,17 +303,17 @@ grammar_dump (FILE *out, const char *title)
/* Dumped the RHS. */
for (item_number *rhsp = rule_i->rhs; 0 <= *rhsp; ++rhsp)
fprintf (out, " %3d", *rhsp);
fputc ('\n', out);
putc ('\n', out);
}
}
fprintf (out, "\n\n");
fprintf (out, "Rules interpreted\n-----------------\n\n");
section (out, "Rules interpreted");
for (rule_number r = 0; r < nrules + nuseless_productions; ++r)
{
fprintf (out, "%-5d %s:", r, rules[r].lhs->symbol->tag);
rule_rhs_print (&rules[r], out);
fputc ('\n', out);
putc ('\n', out);
}
fprintf (out, "\n\n");
}
+20 -6
View File
@@ -23,9 +23,9 @@
/* Representation of the grammar rules:
NTOKENS is the number of tokens, and NVARS is the number of
NTOKENS is the number of tokens, and NNTERMS is the number of
variables (nonterminals). NSYMS is the total number, ntokens +
nvars.
nnterms.
Each symbol (either token or variable) receives a symbol number.
Numbers 0 to NTOKENS - 1 are for tokens, and NTOKENS to NSYMS - 1
@@ -101,6 +101,8 @@
Associativities are recorded similarly in SYMBOLS[I]->assoc. */
# include "system.h"
# include "location.h"
# include "symtab.h"
@@ -109,13 +111,17 @@
extern int nsyms;
extern int ntokens;
extern int nvars;
extern int nnterms;
/* Elements of ritem. */
typedef int item_number;
# define ITEM_NUMBER_MAX INT_MAX
extern item_number *ritem;
extern int nritems;
/* Indices into ritem. */
typedef unsigned int item_index;
/* There is weird relationship between OT1H item_number and OTOH
symbol_number and rule_number: we store the latter in
item_number. symbol_number values are stored as-is, while
@@ -173,7 +179,7 @@ typedef struct
{
/* The number of the rule in the source. It is usually the index in
RULES too, except if there are useless rules. */
rule_number user_number;
rule_number code;
/* The index in RULES. Usually the rule number in the source,
except if some rules are useless. */
@@ -210,7 +216,15 @@ extern rule *rules;
extern rule_number nrules;
/* Get the rule associated to this item. ITEM points inside RITEM. */
rule const *item_rule (item_number const *item);
static inline rule const *
item_rule (item_number const *item)
{
item_number const *sp = item;
while (!item_number_is_rule_number (*sp))
++sp;
rule_number r = item_number_as_rule_number (*sp);
return &rules[r];
}
/* Pretty-print this ITEM (as in the report). ITEM points inside
RITEM. PREVIOUS_RULE is used to see if the lhs is common, in which
@@ -262,7 +276,7 @@ extern symbol **symbols;
by the user's yylex routine, it yields the internal token number
used by the parser and throughout bison. */
extern symbol_number *token_translations;
extern int max_user_token_number;
extern int max_code;
+14 -12
View File
@@ -72,18 +72,20 @@ output_edge (int source, int destination, char const *label,
{
fprintf (fout, " %d -> %d [style=%s", source, destination, style);
if (label)
fprintf (fout, " label=%s", quote (label));
{
fputs (" label=\"", fout);
for (const char *cp = label; *cp; ++cp)
switch (*cp)
{
case '"': fputs ("\\\"", fout); break;
case '\\': fputs ("\\\\", fout); break;
default: fputc (*cp, fout); break;
}
fputc ('"', fout);
}
fputs ("]\n", fout);
}
char const *
escape (char const *name)
{
char *q = quote (name);
q[strlen (q) - 1] = '\0';
return q + 1;
}
static void
no_reduce_bitset_init (state const *s, bitset *no_reduce_set)
{
@@ -149,7 +151,7 @@ print_token (struct obstack *out, bool first, char const *tok)
{
if (! first)
obstack_sgrow (out, ", ");
obstack_sgrow (out, escape (tok));
obstack_backslash (out, tok);
return false;
}
@@ -182,9 +184,9 @@ output_red (state const *s, reductions const *reds, FILE *fout)
bool firste = true;
rule_number ruleno = reds->rules[j]->number;
if (reds->lookahead_tokens)
if (reds->lookaheads)
for (int i = 0; i < ntokens; i++)
if (bitset_test (reds->lookahead_tokens[j], i))
if (bitset_test (reds->lookaheads[j], i))
{
if (bitset_test (no_reduce_set, i))
firstd = print_token (&dout, firstd, symbols[i]->tag);

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