Compare commits

..
105 Commits
Author SHA1 Message Date
Akim Demaille 2caaeba496 version 3.1
* NEWS: Record release date.
2018-08-27 21:52:23 +02:00
Akim Demaille 95a65a3215 build: tabs are ok in a Makefile
* cfg.mk: TABs are ok in examples/calc++/Makefile.
2018-08-27 21:11:12 +02:00
Akim Demaille 33e523878b C++: make sure the generated header is self container
See the previous commit.

* data/lalr1.cc: Be sure to define YY_NULLPTR.
* tests/headers.at: Check the case that was failing.
2018-08-26 18:54:42 +02:00
Akim Demaille 2360e39906 tests: check that headers are sane
The header generated for variants with assertions but without
locations, is not self-contained.  Prepare a check for this.

* tests/headers.at (Sane headers): New, extracted from...
(Several parsers): here.
2018-08-26 18:51:11 +02:00
Akim Demaille 10082ac068 "C++: restore copy-constructor for stack_symbol_type
Benchmarks show that it is more efficient to keep this copy
constructor, rather than forcing the use of the default constructor
and then assignment.

This reverts commit 7ab25ad020.
2018-08-25 11:05:53 +02:00
Akim Demaille de64159e7f examples: calc++: a Makefile and a README
* examples/calc++/Makefile, examples/calc++/README: New.
* examples/calc++/local.mk: Ship and install them.
* doc/bison.texi: Formatting changes.
2018-08-25 08:49:26 +02:00
Akim Demaille 280c40a350 gnulib: update 2018-08-25 07:47:25 +02:00
Jiahao LiandAkim Demaille c1cf82f9c8 variant: fix uninitialized memory access in variant<>
Currently, in bison's C++ parser template (`lalr.cc`), the `variant<>`
struct's `build()` method uses placement-new in the form `new (...) T`
to initialize a variant type.  However, for POD variant types, this
will leave the memory space uninitialized.  If we subsequently tries
to `::move` into a variant object in such state, the call can trigger
clang's undefined behavior sanitizer due to accessing the
uninitialized memory.

https://lists.gnu.org/archive/html/bison-patches/2018-08/msg00098.html

* data/variant.hh (build): Always initialize the stored value.

Signed-off-by: Akim Demaille <[email protected]>
2018-08-25 07:25:05 +02:00
Akim Demaille 55947367c6 NEWS: update 2018-08-24 19:48:19 +02:00
Akim Demaille b4e9eaefd5 examples: calc++: minor improvements
* doc/bison.texi (A Complete C++ Example): Prefer throw exceptions
from the scanner.
Show the invalid characters.
Since the scanner sends exceptions, it no longer needs to report
errors, so we can get rid of the driver's routine to report error,
do it in yyerror.
Use @group/@end group to improve rendering.
2018-08-24 19:40:36 +02:00
Akim Demaille 1a968edcb8 examples: calc++: make sure the file name in location is set
Reported by Hans Åberg.
http://lists.gnu.org/archive/html/bug-bison/2018-08/msg00039.html

* doc/bison.texi (A Complete C++ Example): Move the token's location
from the scanner to the driver.
2018-08-24 19:24:37 +02:00
Akim Demaille 82fa282a1b examples: calc++: remove prefixes
This example uses the calcxx_ prefix for each class.  That's uselessly
heavy.

* doc/bison.texi (A Complete C++ Example): Simplify the class names.
Since now 'driver' denotes the class, use 'drv' for the values.
Formatting changes.
2018-08-24 19:24:34 +02:00
Akim Demaille e504c843c1 examples: fix the leading empty line
* examples/extexi: Really avoid the first empty line.
Remove useless `next`.
2018-08-23 19:16:11 +02:00
Akim Demaille 3fda8335bf examples: shorten the name of the calc++ files
* doc/bison.texi: Turn the calc++- prefix into calc++/.
* examples/extexi (%file_wanted): Replace with
(&file_wanted): this.
* examples/calc++/local.mk: Adjust.
2018-08-23 13:37:52 +02:00
Akim Demaille 9645a2b20e tests: disable -Wmaybe-uninitialized in some tests
On these tests, at -O2 and above, GCC 8 complains that yylval may be
uninitialized.  But it seems wrong: it is initialized.  Rather than
turning off the warning in the skeleton (hence possibility hiding
relevant warnings of user parsers), let's turn it off in the tests
only.

    163: parse.error=verbose and consistent errors:      FAILED (conflicts.at:625)
    165: parse.error=verbose and consistent errors: lr.default-reduction=consistent FAILED (conflicts.at:635)
    166: parse.error=verbose and consistent errors: lr.default-reduction=accepting FAILED (conflicts.at:641)
    167: parse.error=verbose and consistent errors: lr.type=canonical-lr FAILED (conflicts.at:645)
    168: parse.error=verbose and consistent errors: parse.lac=full FAILED (conflicts.at:650)
    169: parse.error=verbose and consistent errors: parse.lac=full lr.default-reduction=accepting FAILED (conflicts.at:655)

We get:

    input.c: In function 'yyparse':
    input.c:980:9: error: 'yylval' may be used uninitialized in this function [-Werror=maybe-uninitialized]
     YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
             ^~~~~~
    cc1: all warnings being treated as errors

See https://lists.gnu.org/archive/html/bison-patches/2018-08/msg00063.html.

* tests/conflicts.at (AT_CONSISTENT_ERRORS_CHECK): Disable
-Wmaybe-uninitialized.
2018-08-23 13:36:19 +02:00
Akim Demaille 7ff6b7bbca doc: clarify that the push parser object can be reused
Suggested by Rici Lake.
https://lists.gnu.org/archive/html/bug-bison/2018-08/msg00033.html

* doc/bison.texi: Complete description of the first node in the main
@menu.
(Push Decl): Remove the 'experimental' warnings about push parser.
Clarify that the push parser object can be reused in several parses.
2018-08-19 21:02:17 +02:00
Akim Demaille 44e76d801f lalr1.cc: support compilation with disabled support for exceptions
Reported by Brooks Moses <[email protected]>
http://lists.gnu.org/archive/html/bison-patches/2018-02/msg00000.html

* data/lalr1.cc (YY_EXCEPTIONS): New.
Use it to disable try/catch clauses.

* doc/bison.texi (C++ Parser Interface): Document it.

* configure.ac (CXXFLAGS_NO_EXCEPTIONS): New.
* tests/atlocal.in: Receive it.
* tests/local.at (AT_FULL_COMPILE, AT_LANG_COMPILE):
Accept a new argument, extra compiler flags.
* tests/calc.at: Run the C++ calculator with exception support disabled.
2018-08-19 17:47:59 +02:00
Akim Demaille 32e0fd1a99 examples: add empty lines
Currently the examples are too dense, let's put empty lines where
'#line' would be issued.  And also remove some spurious empty
lines (remains from @group, @end group, etc.).

* examples/extexi: Do that.
* examples/local.mk (extexiFLAGS): Rename as...
(EXTEXIFLAGS): this.
2018-08-19 17:47:59 +02:00
Akim Demaille b610f43f25 examples: check the variant example
* examples/mfcalc/local.mk, examples/rpcalc/local.mk: Define the
programs in a more natural order, source, preproc, then linker.

* examples/test: Be ready to work on programs that are not in
a subdir.
* examples/variant.test: New.
* examples/local.mk: Use it.
* examples/variant.yy: Don't use 0 for nullptr.
Use a more natural output for a list of string.
2018-08-19 17:47:59 +02:00
Akim Demaille f348522005 C++: fix portability issue with MSVC 2017
Visual Studio issues a C4146 warning on '-static_cast<unsigned>(rhs)'.
The code is weird, probably to cope with INT_MIN.  Let's go back to
using std::max (whose header is still included in position.hh...) like
originally, but with the needed casts.

Reported by 長田偉伸, and with help from Rici Lake.

See also
http://lists.gnu.org/archive/html/bug-bison/2013-02/msg00000.html
and commit 75ae829984.

* data/location.cc (position::add_): Take min as an int.
Use std::max.
While here, get rid of a couple of useless inlines.
2018-08-18 18:07:43 +02:00
Akim Demaille e866c476fd build: fix concurrent build failure
Reported by Dengke Du and Robert Yang.
https://lists.gnu.org/archive/html/bison-patches/2017-07/msg00000.html

* src/local.mk (src/yacc): Make sure the directory exists.
2018-08-18 15:37:14 +02:00
Akim Demaille 72252aaa97 lalr1.cc: remove debug comment
* data/lalr1.cc: Remove a comment about indentation.
I'm not sure it would be nice to indent even more, it's already quite
of the right.
2018-08-18 14:46:17 +02:00
Akim Demaille a1513c265b doc: fix the name of the GFDL section
Reported by dine <[email protected]>.
http://lists.gnu.org/archive/html/bug-bison/2016-10/msg00000.html

I mirrored what the Coreutils do.

* doc/bison.texi (Copying This Manual): Rename as...
(GNU Free Documentation License): this, since that the name we
used in the preamble.
2018-08-18 14:33:06 +02:00
Akim Demaille 425044a936 doc: clarify the destructor selection example
Reported by Gary L Peskin.
http://lists.gnu.org/archive/html/help-bison/2016-02/msg00000.html

* doc/bison.texi (Destructor Decl): here.
2018-08-18 14:15:21 +02:00
Akim Demaille 5010af94d0 portability: don't use _Pragma with ICC
ICC defines __GNUC__ [1], but does not support GCC's _Pragma for
diagnostics.  As a matter of fact, I believe it does not support
_Pragma at all (only #pragma) [2].

Reported by Maxim Prohorenko.
https://savannah.gnu.org/support/index.php?108339

[1] https://software.intel.com/en-us/cpp-compiler-18.0-developer-guide-and-reference-gcc-compatibility-and-interoperability
[2] https://software.intel.com/en-us/cpp-compiler-18.0-developer-guide-and-reference-pragmas

* data/c.m4 (YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN): Exclude ICC from
the club.
2018-08-18 14:15:13 +02:00
Akim Demaille 005ea24cbb doc: typed mid-rule actions
* doc/bison.texi (Mid-Rule Actions): Restructure to insert...
(Typed Mid-Rule Actions): this new section.
Move the manual translation of mid-rule actions into regular actions
to...
(Mid-Rule Action Translation): here.
2018-08-18 10:42:35 +02:00
Akim Demaille adf0425d11 escape properly the file names in #line for printer/destructor
Reported by Jannick.
http://lists.gnu.org/archive/html/bug-bison/2017-05/msg00001.html

"Amusingly" enough, we have the same problem with %defines when the
parser file name has backslashes or quotes: we generate #includes with
an incorrect C string.

* src/output.c (prepare_symbol_definitions): Escape properly the file
names before passing them to M4.
* data/bison.m4, data/lalr1.cc: Don't simply put the file name between
two quotes (that should have been strong enough a smell...), expect
the string to be properly quoted.
* tests/synclines.at: New tests to check this.
2018-08-18 10:04:50 +02:00
Akim Demaille cb4e7ecefa tests: fix title and improve quoting
* tests/synclines.at: here.
Also, prefer '%code' to ;%{...%}' for yylex/yyerror prototypes.
2018-08-18 10:00:21 +02:00
Akim Demaille 2e9ad04cdb style: reduce scopes
* src/output.c: here.
2018-08-18 09:53:29 +02:00
Akim Demaille 28cde9c128 style: reduce scopes
* src/scan-code.l: here.
2018-08-18 09:53:29 +02:00
Akim Demaille d288047e9b regen 2018-08-18 07:42:07 +02:00
Akim Demaille d135a16792 style: reduce scopes
* src/parse-gram.y: Declare iterator within the for-loop.
2018-08-18 07:42:07 +02:00
Akim Demaille 75417c1c1c tests: style changes
* tests/c++.at, tests/local.at: Formatting and title changes.
2018-08-18 07:28:04 +02:00
Akim Demaille 8bc4348cc7 reader: simplify the search of the start symbol
Suggested by Paul Eggert.

* src/reader.c (find_start_symbol): Don't check 'res', we know it is
not null.  That suffices to avoid the GCC warnings.
* bootstrap.conf: We don't need 'assume', which doesn't exist anyway.
2018-08-17 06:22:47 +02:00
Akim Demaille 1113522acb c++: fix GCC8 warnings about uninitialized values
In 0931d14728 I removed too many
initializations from some ctors: some were not about base ctors, but
about member variables.  In fact, more of them were missing to please
GCC 8.

While at it, generate more natural code for C++ without variant:
instead of

    template <typename Base>
    parser::basic_symbol<Base>::basic_symbol (const basic_symbol& other)
      : Base (other)
      , value ()
    {
      value = other.value
    }

generate

    template <typename Base>
    parser::basic_symbol<Base>::basic_symbol (const basic_symbol& other)
      : Base (other)
      , value (other.value)
    {}

* data/c++.m4 (basic_symbol::basic_symbol): Always initialize 'value',
it might be a POD without a ctor.
* data/lalr1.cc (stack_symbol_type::stack_symbol_type): Likewise.
* data/variant.hh (variant::variant): Default initialize the buffer too.
2018-08-15 20:24:16 +02:00
Akim Demaille 45b9d97b54 tests: style: use %empty
* tests/conflicts.at: here.
2018-08-15 19:40:19 +02:00
Akim Demaille b01b80836d tests: fix warnings in push mode
Fix warning with GCC 8, -DNDEBUG.

    422. push.at:83: testing Multiple impure instances ...
    input.y: In function 'main':
    input.c:1022:12: error: potential null pointer dereference [-Werror=null-dereference]
       if (!yyps->yynew && yyps->yyss != yyps->yyssa)
            ~~~~^~~~~~~

* data/yacc.c (pstate_delete): Do nothing if called on null pointer.
2018-08-15 19:40:15 +02:00
Akim Demaille bd07c76b0a c++: avoid GCC 8 warnings
GCC 8 issues warnings whose root cause was a bit hard to find.

    calc.cc: In member function 'virtual int yy::parser::parse()':
    calc.cc:810:18: warning: '*((void*)&<anonymous> +8)' may be used uninitialized in this function [-Wmaybe-uninitialized]
         , location (l)
                      ^
    calc.cc: In member function 'void yy::parser::yypush_(const char*, yy::parser::stack_symbol_type&)':
    calc.cc:810:18: warning: '*((void*)&<anonymous> +8)' may be used uninitialized in this function [-Wmaybe-uninitialized]
         , location (l)
                      ^
    calc.cc: In member function 'void yy::parser::yypush_(const char*, yy::parser::state_type, yy::parser::symbol_type&)':
    calc.cc:810:18: warning: '*((void*)&<anonymous> +8)' may be used uninitialized in this function [-Wmaybe-uninitialized]
         , location (l)
                      ^

The problem is with locations that don't have a constructor, such as
Span (in calc.cc) which is POD.  It is POD on purpose: so that we can
use that structure to test glr.cc which cannot use non POD in its
(C) stacks.

* data/c++.m4 (basic_symbol): Also ensure that 'location' is
initialized.
2018-08-15 19:23:00 +02:00
Akim Demaille 45ca5043ce tests: avoid compiler warnings
* tests/calc.at (AT_CALC_MAIN): Declare yyparse and operator<< in an
unnamed namespace to avoid "not declared" warnings (clang
-Weverything).
Remove useless prototypes.
2018-08-15 19:21:17 +02:00
Akim Demaille ef98967ada build: work around GCC warnings on Flex code
With GCC 7.3.0 and Flex 2.6.4, we get warnings on all the generated
scanners:

    examples/calc++/calc++-scanner.cc: In function 'void yyrestart(FILE*)':
    examples/calc++/calc++-scanner.cc:1611:20: error: potential null pointer dereference [-Werror=null-dereference]
     /* %endif */
      ~~~~~~~~~~~       ^
    examples/calc++/calc++-scanner.cc:1607:19: error: potential null pointer dereference [-Werror=null-dereference]
     /* %if-c-only */
      ~~~~~~~~~~~~~~~  ^
    examples/calc++/calc++-scanner.cc:1611:20: error: potential null pointer dereference [-Werror=null-dereference]
     /* %endif */
      ~~~~~~~~~~~       ^
    examples/calc++/calc++-scanner.cc:1607:19: error: potential null pointer dereference [-Werror=null-dereference]
     /* %if-c-only */
      ~~~~~~~~~~~~~~~  ^
    cc1plus: all warnings being treated as errors

Obviously the lines are incorrect, and the warnings are emitted twice.
Still, let's get rid of these warnings.

* doc/bison.texi, src/flex-scanner.h: Disable these warnings in code
generated by Flex.
2018-08-15 14:42:09 +02:00
Akim Demaille 7783ba2d4f fix incorrect C code
Commit 3df32101e7 introduced invalid C
code.  Caught by GCC 7.3.0.

* bootstrap.conf (gnulib_modules): We need assume.
* src/reader.c (find_start_symbol): Fix the signature (too much C++,
sorry...).
Prefer 'assume' to 'assert', so that we don't have these warnings even
when NDEBUG is defined.
2018-08-15 14:39:46 +02:00
Akim Demaille bbd17b68fb examples: fix Englishoes
* examples/README: Fix my mistakes.
2018-08-14 13:40:54 +02:00
Akim Demaille 30c179fee8 examples: ship and install variant.yy
This file was meant to be shown as an example.  Install it.

* README, data/README: Put Emacs metadata in the final section.
* examples/README: New.
* examples/variant.yy: Use %empty.
* examples/local.mk: Install both these files.
2018-08-14 13:36:47 +02:00
Akim Demaille 7ab25ad020 C++: remove useless copy-constructor
We currently generate copy constructors such as the following
one (taken from examples/variant.yy):

    parser::stack_symbol_type::stack_symbol_type (const stack_symbol_type& that)
      : super_type (that.state, that.location)
    {
      switch (that.type_get ())
      {
        case 3: // TEXT
        case 8: // item
          value.copy< ::std::string > (that.value);
          break;

        case 7: // list
          value.copy< ::std::vector<std::string> > (that.value);
          break;

        case 4: // NUMBER
          value.copy< int > (that.value);
          break;

        default:
          break;
      }
    }

they are actually useless: we never need it.

* data/lalr1.cc: Don't generate the stack_symbol_type copy ctor.
2018-08-14 06:17:21 +02:00
Akim Demaille e555fb5e55 C++: symbol constructors: add a missing reference
Fix a typo so that instead of

    basic_symbol::basic_symbol (typename Base::kind_type t, const int v)

we now generate

    basic_symbol::basic_symbol (typename Base::kind_type t, const int& v)

* data/variant.hh (b4_basic_symbol_constructor_declare)
(b4_basic_symbol_constructor_define): Add missing reference.
2018-08-14 06:17:21 +02:00
Akim Demaille 0931d14728 C++: remove useless calls to the base default constructor
* data/c++.m4, data/stack.hh, data/variant.hh: here.
2018-08-14 06:17:21 +02:00
Akim Demaille e76245fcd9 C++: prefer size_type to unsigned for indexes
* data/stack.hh (size_type): New, based on the container type.
2018-08-14 06:17:21 +02:00
Akim Demaille c2de9dafd1 regen 2018-08-14 06:15:42 +02:00
Akim Demaille f7de571ff1 style: m4: remove useless reference to 'int' in integral types
* m4/cxx.m4: Prefer 'unsigned' to 'unsigned int'.
2018-08-14 06:15:42 +02:00
Akim Demaille c226d4ed48 style: doc: remove useless reference to 'int' in integral types
* doc/bison.texi: Prefer 'unsigned' to 'unsigned int'.  Likewise for
long and short.
2018-08-14 06:15:41 +02:00
Akim Demaille 9df53e7288 style: lib: remove useless reference to 'int' in integral types
* lib/abitset.c, lib/bbitset.h, lib/bitset.c, lib/bitset.h,
* lib/bitset_stats.c, lib/bitsetv-print.c, lib/bitsetv.c,
* lib/bitsetv.h, lib/ebitset.c, lib/lbitset.c, lib/timevar.c,
* lib/vbitset.c:
Prefer 'unsigned' to 'unsigned int'.  Likewise for long and short.
2018-08-14 06:15:41 +02:00
Akim Demaille 9a5c688ae4 style: src: remove useless reference to 'int' in integral types
* src/AnnotationList.c, src/AnnotationList.h, src/InadequacyList.h,
* src/closure.c, src/closure.h, src/gram.c, src/gram.h, src/ielr.c,
* src/location.c, src/output.c, src/reader.c, src/relation.c,
* src/scan-code.l, src/scan-gram.l, src/tables.c, src/tables.h:
Prefer 'unsigned' to 'unsigned int'.  Likewise for long and short.
2018-08-14 06:15:41 +02:00
Akim Demaille e3b7c01820 style: tests: remove useless reference to 'int' in integral types
* tests/actions.at, tests/cxx-type.at: Prefer 'unsigned' to 'unsigned
int'.  Likewise for long and short.
2018-08-14 06:15:41 +02:00
Akim Demaille 5cc5703239 style: data: remove useless reference to 'int' in integral types
* data/c.m4, data/glr.c, data/yacc.c: Prefer 'unsigned' to 'unsigned
int'.  Likewise for long and short.
2018-08-14 06:15:41 +02:00
Akim Demaille c8dc9a8f51 gnulib: update
* bootstrap.conf: gnulib_mk is defined again by bootstrap.
2018-08-12 11:23:38 +02:00
Akim Demaille f9a6b34147 doc: avoid type aliases
* doc/bison.texi (C++ Location Values): Use 'unsigned' instead of
'uint'.
2018-08-12 09:40:32 +02:00
Akim Demaille 48828e779f doc: remove the "experimental" warning for some features
Several features were flagged 'experimental' and waiting for user
feedback to 'stabilize', but i. AFAIK, no user ever reported anything
about them, ii. they'be been here long enough to prove they don't do
harm.

* doc/bison.texi: No longer experimental: default %printer and
%destructor (typed: <*> and untyped: <>), %define api.value.type union
and variant, Java parsers, XML output, LR family (lr, ielr, lalr),
semantic predicates (%?).
2018-08-12 09:15:01 +02:00
Akim Demaille 4ad0ed3425 tests: check variants and typed mid-rule actions
See
http://lists.gnu.org/archive/html/bison-patches/2018-08/msg00013.html

* tests/c++.at (Variants and Typed Mid-rule Actions): New.
2018-08-12 09:04:04 +02:00
Akim Demaille ad42f96053 tests: fix minor issues
* tests/actions.at: Fix some log messages.
Prefer #error to fprintf: it fixes the invalid use of yyoutput in
%destructor, and it is an even stronger check: that the code is not
even emitted.  The portability of #error is not really a problem here,
since the point is anyway to have the compilation fail.
2018-08-12 08:44:32 +02:00
Akim Demaille 4410084223 c++: variant: add more assertions
* data/variant.hh (variant::as): Check yytypeid_ before
checking *yytypeid_.
2018-08-11 18:27:10 +02:00
Akim Demaille ccc759e81a doc: -fcaret is enabled by default
* doc/bison.texi (Mid-Rule Action Translation): So no need to pass it.
2018-08-11 18:27:09 +02:00
Akim Demaille e19e088e66 style: reduce scopes
* src/closure.c, src/conflicts.c: here.
2018-08-11 18:27:09 +02:00
Akim Demaille 9c80fa286e NEWS: update 2018-08-11 18:09:29 +02:00
Akim Demaille da8f4a2f5f rule actions cannot be typed
Make sure that we cannot apply a type to the (main) action of a rule.

* src/reader.c (grammar_rule_check): Issue the warning.
* tests/input.at (Cannot type action): Check the warning.
2018-08-11 18:09:29 +02:00
Akim Demaille f18f71cfb0 warn about typed mid-rule actions in Yacc mode
* src/reader.c (grammar_current_rule_action_append): Warn.
* tests/input.at (AT_CHECK_UNUSED_VALUES): Check.
2018-08-11 18:09:29 +02:00
Akim Demaille 11548b8e68 tests: check typed mid-rule actions
* tests/input.at (_AT_UNUSED_VALUES_DECLARATIONS): Check
typed mid-rule actions.
* tests/report.at (Reports): Check that types of typed mid-rule
actions are reported.
* tests/actions.at (Typed mid-rule actions): Check that
the values of typed mid-rule actions are correct.
2018-08-11 18:09:29 +02:00
Akim Demaille b79b889de5 regen 2018-08-11 18:09:29 +02:00
Akim Demaille 7b24c424b5 add support for typed mid-rule actions
Prompted on Piotr Marcińczyk's message:
http://lists.gnu.org/archive/html/bug-bison/2017-06/msg00000.html.
See also http://lists.gnu.org/archive/html/bug-bison/2018-06/msg00001.html.

Because their type is unknown to Bison, the values of midrule actions are
not treated like the others: they don't have %printer and %destructor
support.  In addition, in C++, (Bison) variants cannot work properly.

Typed midrule actions address these issues.  Instead of:

    exp: { $<ival>$ = 1; } { $<ival>$ = 2; }   { $$ = $<ival>1 + $<ival>2; }

write:

    exp: <ival>{ $$ = 1; } <ival>{ $$ = 2; }   { $$ = $1 + $2; }

* src/scan-code.h, src/scan-code.l (code_props): Add a `type` field to
record the declared type of an action.
(code_props_rule_action_init): Add a type argument.
* src/parse-gram.y: Accept an optional type tag for actions.
* src/reader.h, src/reader.c (grammar_current_rule_action_append): Add
a type argument.
(grammar_midrule_action): When a mid-rule is typed, pass its type to
the defined dummy non terminal symbol.
2018-08-11 18:09:29 +02:00
Akim Demaille 0d06a966f8 tests: make room for more cases
* tests/input.at (AT_CHECK_UNUSED_VALUES): Add an empty line
to allow more symbols, and adjust line numbers.
Use a more consistent m4 quoting scheme.
2018-08-05 20:25:59 +02:00
Akim Demaille 3df32101e7 warnings: address -Wnull-dereference in reader.c
Based on a patch by David Michael.
http://lists.gnu.org/archive/html/bison-patches/2018-07/msg00000.html

* src/reader.c (find_start): New, extracted from...
(check_and_convert_grammar): here.
2018-08-05 20:25:58 +02:00
Akim Demaille c699078246 style: ielr: reduce scopes
* src/ielr.c: Use modern C to reduce the scopes of some variables.
2018-08-05 20:17:25 +02:00
Akim Demaille 4c7377f499 style: move to C99 to reduce scopes
* src/symtab.c, src/reader.c: Freely mix statements and variable
definitions.  And use for-loops with initializers.
2018-07-26 20:18:32 +02:00
Akim Demaille 9502b2ab48 style: split a function in two
grammar_current_rule_action_append was used in two different places:
for actual action (`{...}`), and for predicates (`%?{...}`).  Let's
split this in two different functions.

* src/reader.h, src/reader.c (grammar_current_rule_predicate_append): New.
Extracted from...
(grammar_current_rule_action_append): here.
Remove arguments that don't apply.
Adjust dependencies.
2018-07-26 20:18:32 +02:00
Akim Demaille a0f33a28e9 tests: fix typo
* tests/actions.at: Remove (harmless) stray character.
2018-07-26 20:13:05 +02:00
Akim Demaille 0def17c3d1 print: remove unused function
This function was unused since 1991's original import by
rms (e06f0c3442).

* src/print.c (print_token): Remove.
2018-07-26 20:10:38 +02:00
Akim Demaille d2e7bc1613 doc: fix Texinfo syntax error
* doc/bison.texi (Understanding): here.
2018-06-23 09:12:06 +02:00
Akim Demaille 70875b4873 doc: we now show the type of the symbols
* doc/bison.texi (Understanding Your Parser): Update the output
from Bison.
Use types in the example, and show them in the report.
* NEWS: Update.
2018-06-22 09:51:32 +02:00
Akim Demaille 34d1773990 tests: check the typed symbols in the reports
* tests/report.at: New.
* tests/local.mk, tests/testsuite.at: Use it.
2018-06-18 08:53:27 +02:00
Akim Demaille 27767290da report: display the type of the symbols
* src/print.c (print_nonterminal_symbols, print_terminal_symbols):
Also should the type of the symbols.
2018-06-18 07:18:14 +02:00
Akim Demaille 2efaa8e96a style: reduce scopes
* src/print.c (print_terminal_symbols, print_nonterminal_symbols): Here.
2018-06-18 07:16:03 +02:00
Akim Demaille 4cdcb6f243 style: split large function
* src/print.c (print_grammar): Split into...
(print_terminal_symbols, print_nonterminal_symbols): these.
Adjust dependencies.
2018-06-18 07:15:56 +02:00
Akim Demaille 7f42eb0a5e style: reduce scopes
* src/print.c (print_grammar): Shorten scopes.
2018-06-18 07:15:48 +02:00
Akim Demaille d03ad8b686 gnulib: update
Fixes the `make install-pdf` problem reported by Hans Åberg in
http://lists.gnu.org/archive/html/bug-bison/2018-06/msg00000.html
that had already been fixed by Joel E. Denny in
http://lists.gnu.org/archive/html/bug-bison/2012-04/msg00011.html
Final fix in
http://lists.gnu.org/archive/html/bug-gnulib/2018-06/msg00019.html
2018-06-18 07:13:28 +02:00
Akim Demaille f462a08572 Merge maint into master
* upstream/maint: (48 commits)
  THANKS: update an address
  tests: adjust syncline tests to GCC 7
  glr: fix improperly placed synclines
  bison: be git grep friendly
  Replace ftp with https
  maint: post-release administrivia
  version 3.0.5
  bison: style: indentation fixes
  regen
  bison: please address sanitizer
  C++: style: fix indentation
  NEWS: update
  C++: style: prefer `unsigned` to `unsigned int`
  C++: style: space before paren
  C++: fix -Wdeprecated warnings
  tests: fix -Wdeprecated warning
  maint: update syntax-check exclusions
  autoconf: update
  regen
  Update copyright years
  ...
2018-06-17 18:43:59 +02:00
Akim Demaille 0ac08d2d6c THANKS: update an address 2018-05-30 19:18:04 +02:00
Akim Demaille 6053dcae59 tests: adjust syncline tests to GCC 7
GCC 7 also underlines the error.

    syncline.c:4:2: error: #error "4"
     #error "4"
      ^~~~~

* tests/synclines.at (_AT_SYNCLINES_COMPILE): Remove tildas from GCC 7.
2018-05-30 19:17:06 +02:00
Akim Demaille 5952fe5abf glr: fix improperly placed synclines
Predicates with GLR are issued with synclines in the middle of C code:

          case 2:
      if (! (#line 6 "sempred.y" /* glr.c:816  */
      new_syntax)) YYERROR;
    #line 793 "sempred.tab.c" /* glr.c:816  */
      break;

Reported by Rici Lake.
http://lists.gnu.org/archive/html/bug-bison/2018-05/msg00033.html

* data/c.m4 (b4_predicate_case): Be sure to start on column 0.
It would be nicer if b4_syncline could ensure this by itself
(that would avoid ugly code when synclines are disabled), but that's
way more work.
* tests/glr-regression.at (Predicates): Be a real end-to-end test.
This would have caught this error years ago...
2018-05-29 09:02:21 +02:00
Akim Demaille d0447d949b bison: be git grep friendly
* src/output.c (user_actions_output): Make calls to b4_case and
b4_predicate_case explicit.
2018-05-29 09:02:12 +02:00
Akim Demaille f3bd6a25bf Replace ftp with https
Reported by Hans Åberg.

* README, cfg.mk, doc/bison.texi: here.
2018-05-29 07:28:02 +02:00
Akim Demaille 38d91ccd96 maint: post-release administrivia
* NEWS: Add header line for next release.
* .prev-version: Record previous version.
* cfg.mk (old_NEWS_hash): Auto-update.
2018-05-27 14:42:55 +02:00
Akim Demaille d6445ec10b Merge remote-tracking branch 'origin/maint'
* origin/maint:
  maint: post-release administrivia
  version 3.0.4
  gnulib: update
  build: re-enable compiler warnings, and fix them
  tests: c++: fix a C++03 conformance issue
  tests: fix a title
  c++: reserve 200 slots in the parser's stack
  tests: be more robust to unrecognized synclines, and try to recognize xlc
  tests: fix C++ conformance
  build: fix some warnings
  build: avoid infinite recursions on include_next
2015-01-23 15:17:35 +01:00
Akim Demaille eabb3df7aa Merge remote-tracking branch 'origin/maint' into origin/master
* origin/maint:
  doc: minor fixes
  gnulib: strtoul is considered obsolete and now useless
  c++: avoid warnings when destructors don't use $$
  maint: post-release administrivia
  version 3.0.3
  gnulib: update
2015-01-16 15:14:41 +01:00
Akim Demaille 875ef1b90c symbol: use the first occurrence as an LHS as defining location
Currently on the following grammar:

    %type <foo> foo
    %%
    start: foo | bar | "baz"
    foo: foo
    bar: bar

bison reports:

    warning: 2 nonterminals useless in grammar [-Wother]
    warning: 4 rules useless in grammar [-Wother]
    1.13-15: warning: nonterminal useless in grammar: foo [-Wother]
     %type <foo> foo
                 ^^^
    3.14-16: warning: nonterminal useless in grammar: bar [-Wother]
     start: foo | bar | "baz"
                  ^^^
    [...]

i.e., the location of the first occurrence of a symbol is taken as its
definition point.  In the case of nonterminals, the first occurrence
as a left-hand side of a rule makes more sense:

    warning: 2 nonterminals useless in grammar [-Wother]
    warning: 4 rules useless in grammar [-Wother]
    4.1-3: warning: nonterminal useless in grammar: foo [-Wother]
     foo: foo
     ^^^
    5.1-3: warning: nonterminal useless in grammar: bar [-Wother]
     bar: bar
     ^^^
    [...]

* src/symtab.h, src/symtab.c (symbol::location_of_lhs): New.
(symbol_location_as_lhs_set): New.
* src/parse-gram.y (current_lhs): Use it.
* tests/reduce.at: Update locations.
2015-01-14 17:05:35 +01:00
Akim Demaille 650af77812 reduce: don't complain about rules whose lhs is useless
In the following grammar, the 'exp' nonterminal is trivially useless.
So, of course, its rules are useless too.

    %%
    input: '0' | exp
    exp: exp '+' exp | exp '-' exp | '(' exp ')'

Previously all the useless rules were reported, including those whose
left-hand side is the 'exp' nonterminal:

    warning: 1 nonterminal useless in grammar [-Wother]
    warning: 4 rules useless in grammar [-Wother]
    2.14-16: warning: nonterminal useless in grammar: exp [-Wother]
     input: '0' | exp
                  ^^^
    2.14-16: warning: rule useless in grammar [-Wother]
     input: '0' | exp
                  ^^^
  ! 3.6-16: warning: rule useless in grammar [-Wother]
  !  exp: exp '+' exp | exp '-' exp | '(' exp ')'
  !       ^^^^^^^^^^^
  ! 3.20-30: warning: rule useless in grammar [-Wother]
  !  exp: exp '+' exp | exp '-' exp | '(' exp ')'
  !                     ^^^^^^^^^^^
  ! 3.34-44: warning: rule useless in grammar [-Wother]
  !  exp: exp '+' exp | exp '-' exp | '(' exp ')'
  !                                   ^^^^^^^^^^^

The interest of being so verbose is dubious.  I suspect most of the
time nonterminals are not expected to be useless, so the user wants to
fix the nonterminal, not remove its rules.  And even if the user
wanted to get rid of its rules, the position of these rules probably
does not help more that just having the name of the nonterminal.

This commit discard these messages, marked with '!', and keep the
others.  In particular, we still report:

    2.14-16: warning: rule useless in grammar [-Wother]
     input: '0' | exp
                  ^^^

All the useless rules (including the '!' ones) are still reported in
the reports (xml, text, etc.); only the diagnostics on stderr change.

* src/gram.c (grammar_rules_useless_report): Don't complain about
useless rules whose lhs is useless.
* src/reduce.h, src/reduce.c (reduce_nonterminal_useless_in_grammar):
Take a sym_content as argument.
Adjust callers.
* tests/reduce.at (Useless Rules, Underivable Rules, Reduced Automaton):
Adjust.
2015-01-14 13:59:53 +01:00
Akim Demaille c03a8db0cc style: reduce: use unsigned to count a number of objects
* src/reduce.h, src/reduce.c (nuseful_productions, nuseless_productions)
(nuseful_nonterminals, nuseless_nonterminals): Declare as unsigned.
Simplify "0 <" tests into non-zero tests.
2015-01-14 10:13:49 +01:00
Akim Demaille 8b06c6b871 style: reduce: introduce and use a swap for bitset
* src/reduce.c (bitset_swap): New.
Use it.
2015-01-14 10:13:49 +01:00
Akim Demaille c5da1a2adc style: reduce: reduce scopes and other stylistic changes
* src/reduce.c: Various stylistic changes:
Reduce scopes.
Prefer ++i to i++.
Prefer < to >.
2015-01-14 10:13:30 +01:00
Akim Demaille dfd5b89d01 Merge remote-tracking branch 'origin/maint'
* origin/maint:
  tests: split a large test case into several smaller ones
  package: a bit of trouble shooting indications
  doc: liby's main arms the internationalization
  bison: avoid warnings from static code analysis
  c++: fix the use of destructors when variants are enabled
  style: tests: simplify the handling of some C++ tests
  c++: symbols can be empty, so use it
  c++: variants: don't leak the lookahead in error recovery
  c++: provide a means to clear symbols
  c++: clean up the handling of empty symbols
  c++: comment and style changes
  c++: variants: comparing addresses of typeid.name() is undefined
  c++: locations: complete the API and fix comments
  build: do not clean figure sources in make clean
2015-01-13 14:45:15 +01:00
Akim Demaille 13e294ee55 Merge remote-tracking branch 'origin/maint'
* origin/maint:
  build: don't try to generate docs when cross-compiling
  package: fix a reporter's name
  %union: fix the support for named %union
  package: bump to 2015
  flex: don't trust YY_USER_INIT
  yacc.c: fix broken union when api.value.type=union and %defines are used
  doc: fix missing xref
  gnulib: update
  location: remove some ugly debugging code traces
  build: use abort to pacify compiler errors
  package: bump to 2014
  doc: specify documentation encoding
2015-01-05 13:51:30 +01:00
Akim Demaille 8044fda634 symbols: properly fuse the properties of two symbol aliases
This completes and fixes a728075710.
Reported by Valentin Tolmer.

Before it Bison used to put the properties of the symbols
(associativity, printer, etc.) in the 'symbol' structure.  An
identifier-named token (FOO) and its string-named alias ("foo")
duplicated these properties, and symbol_check_alias_consistency()
checked that both had compatible properties and fused them, at the end
of the parsing of the grammar.

The commit a728075710 introduces a
sym_content structure that keeps all these properties, and ensures
that both aliases point to the same sym_content (instead of
duplicating).  However, it removed symbol_check_alias_consistency,
which resulted in the non-fusion of *existing* properties:

  %token FOO "foo"
  %left FOO %left "foo"

was properly diagnosed as a redeclaration, but

  %left FOO %left "foo"
  %token FOO "foo"

was not, as the properties of FOO and "foo" were not checked before
fusion.  It certainly also means that

  %left "foo"
  %token FOO "foo"

did not transfer properly the associativity to FOO.

The fix is simple: reintroduce symbol_check_alias_consistency (under a
better name, symbol_merge_properties) and call it where appropriate.

Also, that commit made USER_NUMBER_HAS_STRING_ALIAS useless, but left
it.

* src/symtab.h (USER_NUMBER_HAS_STRING_ALIAS): Remove, unused.
Adjust dependencies.
* src/symtab.c (symbol_merge_properties): New, based on the former
symbol_check_alias_consistency.
* tests/input.at: Re-enable tests that we now pass.
2013-12-10 09:43:33 +01:00
Akim Demaille b7d4c48e55 Merge remote-tracking branch 'origin/maint'
* origin/maint:
  package: install the examples
  package: install README and the like in docdir
  diagnostics: fix the order of multiple declarations reports
  symbol: provide an easy means to compare them in source order

Conflicts:
  src/symtab.c
  tests/input.at

* tests/input.at: Comment out a test that master currently does not
pass (because of a728075710).
2013-12-10 08:53:07 +01:00
Akim Demaille fc6c85664a Merge remote-tracking branch 'origin/maint'
* origin/maint: (43 commits)
  maint: post-release administrivia
  version 3.0.2
  gnulib: update
  output: do not generate source files when late errors are caught
  output: record what generated files are source or report files
  output: do not generate source files when early errors are caught
  xml: also use "%empty" with html output
  style: formatting changes
  xml: also display %empty for empty right-hand sides
  reports: display %empty in the generated pointed-rules
  news: YYERROR vs variants
  style: scope reduction in lalr.cc
  lalr1.cc: formatting changes
  lalr1.cc: fix the support of YYERROR with variants
  tests: check $$'s destruction with variant, YYERROR, and no error recovery
  tests: simplify useless obfuscation
  skeletons: use better names when computing a "goto"
  maint: post-release administrivia
  version 3.0.1
  aver: it is no longer "protected against NDEBUG"
  ...

Conflicts:
  data/glr.c
2013-12-09 10:43:37 +01:00
Akim Demaille 4f3cc9c21b Merge remote-tracking branch 'origin/maint'
* origin/maint:
  glr: more assertions
  glr: shorten scopes
  glr: formatting changes
  glr: better use of tracing macros
  examples: improve the output of the "variant" example
  variant: remove useless assertion
  tests: remove stray debugging traces
  tests: do not use grep -q
  build: don't require flex for ordinary builds
  maint: update .gitignore
  build: port to pre-5.8.7 perl
  tests: minor change to make it easier to test other skeletons
  uniqstr: fix assertion
2013-09-19 16:33:20 +02:00
Akim Demaille 55a2063005 glr: simplify the invocation of YYLLOC_DEFAULT
The commit which introduces yyresolveLocations (commit
8710fc41aa) saves and restores the
look-ahead (type, value and location) for no clear reason.  This
appears to be useless.

* data/glr.c (yyresolveLocations): Don't save/restore the current
look-ahead to call YYLLOC_DEFAULT.
Minor style changes.
2013-09-19 16:14:07 +02:00
Valentin TolmerandAkim Demaille a728075710 symbols: improve symbol aliasing
Rather than having duplicate info in the symbol and the alias that has
to be resolved later on, both the symbol and the alias have a common
pointer to a separate structure containing this info.

* src/symtab.h (sym_content): New structure.
* src/symtab.c (sym_content_new, sym_content_free, symbol_free): New

* src/AnnotationList.c, src/conflicts.c, src/gram.c, src/gram.h,
* src/graphviz.c, src/ielr.c, src/output.c, src/parse-gram.y, src/print.c
* src/print-xml.c, src/print_graph.c, src/reader.c, src/reduce.c,
* src/state.h, src/symlist.c, src/symtab.c, src/symtab.h, src/tables.c:
Adjust.

* tests/input.at: Fix expectations (order changes).
2013-08-01 12:49:51 +02:00
98 changed files with 3007 additions and 1872 deletions
+1 -1
View File
@@ -1 +1 @@
3.0.4
3.0.5
+140
View File
@@ -1,5 +1,145 @@
GNU Bison NEWS
* Noteworthy changes in release 3.1 (2018-08-27) [stable]
** Backward incompatible changes
Compiling Bison now requires a C99 compiler---as announced during the
release of Bison 3.0, five years ago. Generated parsers do not require a
C99 compiler.
Support for DJGPP, which have been unmaintained and untested for years, is
obsolete. Unless there is activity to revive it, the next release of Bison
will have it removed.
** New features
*** Typed midrule actions
Because their type is unknown to Bison, the values of midrule actions are
not treated like the others: they don't have %printer and %destructor
support. It also prevents C++ (Bison) variants to handle them properly.
Typed midrule actions address these issues. Instead of:
exp: { $<ival>$ = 1; } { $<ival>$ = 2; } { $$ = $<ival>1 + $<ival>2; }
write:
exp: <ival>{ $$ = 1; } <ival>{ $$ = 2; } { $$ = $1 + $2; }
*** Reports include the type of the symbols
The sections about terminal and nonterminal symbols of the '*.output' file
now specify their declared type. For instance, for:
%token <ival> NUM
the report now shows '<ival>':
Terminals, with rules where they appear
NUM <ival> (258) 5
*** Diagnostics about useless rules
In the following grammar, the 'exp' nonterminal is trivially useless. So,
of course, its rules are useless too.
%%
input: '0' | exp
exp: exp '+' exp | exp '-' exp | '(' exp ')'
Previously all the useless rules were reported, including those whose
left-hand side is the 'exp' nonterminal:
warning: 1 nonterminal useless in grammar [-Wother]
warning: 4 rules useless in grammar [-Wother]
2.14-16: warning: nonterminal useless in grammar: exp [-Wother]
input: '0' | exp
^^^
2.14-16: warning: rule useless in grammar [-Wother]
input: '0' | exp
^^^
3.6-16: warning: rule useless in grammar [-Wother]
exp: exp '+' exp | exp '-' exp | '(' exp ')'
^^^^^^^^^^^
3.20-30: warning: rule useless in grammar [-Wother]
exp: exp '+' exp | exp '-' exp | '(' exp ')'
^^^^^^^^^^^
3.34-44: warning: rule useless in grammar [-Wother]
exp: exp '+' exp | exp '-' exp | '(' exp ')'
^^^^^^^^^^^
Now, rules whose left-hand side symbol is useless are no longer reported
as useless. The locations of the errors have also been adjusted to point
to the first use of the nonterminal as a left-hand side of a rule:
warning: 1 nonterminal useless in grammar [-Wother]
warning: 4 rules useless in grammar [-Wother]
3.1-3: warning: nonterminal useless in grammar: exp [-Wother]
exp: exp '+' exp | exp '-' exp | '(' exp ')'
^^^
2.14-16: warning: rule useless in grammar [-Wother]
input: '0' | exp
^^^
*** C++: Generated parsers can be compiled with -fno-exceptions (lalr1.cc)
When compiled with exceptions disabled, the generated parsers no longer
uses try/catch clauses.
Currently only GCC and Clang are supported.
** Documentation
*** A demonstration of variants
A new example was added (installed in .../share/doc/bison/examples),
'variant.yy', which shows how to use (Bison) variants in C++.
The other examples were made nicer to read.
*** Some features are no longer 'experimental'
The following features, mature enough, are no longer flagged as
experimental in the documentation: push parsers, default %printer and
%destructor (typed: <*> and untyped: <>), %define api.value.type union and
variant, Java parsers, XML output, LR family (lr, ielr, lalr), and
semantic predicates (%?).
** Bug fixes
*** GLR: Predicates support broken by #line directives
Predicates (%?) in GLR such as
widget:
%? {new_syntax} 'w' id new_args
| %?{!new_syntax} 'w' id old_args
were issued with #lines in the middle of C code.
*** Printer and destructor with broken #line directives
The #line directives were not properly escaped when emitting the code for
%printer/%destructor, which resulted in compiler errors if there are
backslashes or double-quotes in the grammar file name.
*** Portability on ICC
The Intel compiler claims compatibility with GCC, yet rejects its _Pragma.
Generated parsers now work around this.
*** Various
There were several small fixes in the test suite and in the build system,
many warnings in bison and in the generated parsers were eliminated. The
documentation also received its share of minor improvements.
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
+3 -3
View File
@@ -7,7 +7,7 @@ instructions.
Bison requires GNU m4 1.4.6 or later. See:
ftp://ftp.gnu.org/gnu/m4/m4-1.4.6.tar.gz
https://ftp.gnu.org/gnu/m4/m4-1.4.6.tar.gz
** Internationalization
Bison supports two catalogues: one for Bison itself (i.e., for the
@@ -37,13 +37,13 @@ test case in each bug report.
For any copyright year range specified as YYYY-ZZZZ in this package,
note that the range specifies every single year in that closed interval.
-----
Local Variables:
mode: outline
fill-column: 76
End:
-----
Copyright (C) 1992, 1998-1999, 2003-2005, 2008-2015, 2018 Free Software
Foundation, Inc.
+10 -1
View File
@@ -25,6 +25,7 @@ Bert Deknuydt [email protected]
Bill Allombert [email protected]
Bob Rossi [email protected]
Brandon Lucia [email protected]
Brooks Moses [email protected]
Bruce Lilly [email protected]
Bruno Haible [email protected]
Charles-Henri de Boysson [email protected]
@@ -39,6 +40,8 @@ Daniel Galloway [email protected]
Daniel Hagerty [email protected]
David J. MacKenzie [email protected]
David Kastrup [email protected]
David Michael [email protected]
Dengke Du [email protected]
Dennis Clarke [email protected]
Derek Clegg [email protected]
Derek M. Jones [email protected]
@@ -55,14 +58,16 @@ Florian Krohm [email protected]
Frank Heckenbach [email protected]
Frans Englich [email protected]
Gabriel Rassoul [email protected]
Gary L Peskin [email protected]
Georg Sauthoff [email protected]
George Neuner [email protected]
Gilles Espinasse [email protected]
Goran Uddeborg [email protected]
Guido Trentalancia [email protected]
H. Merijn Brand [email protected]
Hans Aberg haberg@matematik.su.se
Hans Åberg haberg[email protected]
Jan Nieuwenhuizen [email protected]
Jannick [email protected]
Jerry Quinn [email protected]
Jesse Thilo [email protected]
Jim Kent [email protected]
@@ -87,6 +92,7 @@ Martin Mokrejs [email protected]
Martin Nylin [email protected]
Matt Kraai [email protected]
Matt Rosing [email protected]
Maxim Prohorenko [email protected]
Michael Catanzaro [email protected]
Michael Felt [email protected]
Michael Hayes [email protected]
@@ -120,6 +126,7 @@ Peter Simons [email protected]
Petr Machata [email protected]
Pho [email protected]
Piotr Gackiewicz [email protected]
Piotr Marcińczyk [email protected]
Quentin Hocquet [email protected]
Quoc Peyrot [email protected]
R Blake [email protected]
@@ -131,6 +138,7 @@ Rici Lake [email protected]
Rob Conde [email protected]
Rob Vermaas [email protected]
Robert Anisko [email protected]
Robert Yang [email protected]
Roland Levillain [email protected]
Satya Kiran Popuri [email protected]
Sebastian Setzer [email protected]
@@ -165,6 +173,7 @@ Wolfram Wagner [email protected]
Wwp [email protected]
xolodho [email protected]
Zack Weinberg [email protected]
長田偉伸 [email protected]
Many people are not named here because we lost track of them. We
thank them! Please, help us keeping this list up to date.
+1 -1
View File
@@ -112,7 +112,7 @@ We could (should?) also treat the case of the undef_token, which is
numbered 257 for yylex, and 2 internal. Both appear for instance in
toknum:
const unsigned short int
const unsigned short
parser::yytoken_number_[] =
{
0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
+55 -12
View File
@@ -1,6 +1,6 @@
#! /bin/sh
# Print a version string.
scriptversion=2018-04-28.14; # UTC
scriptversion=2018-07-25.07; # UTC
# Bootstrap this package from checked-out sources.
@@ -47,6 +47,8 @@ PERL="${PERL-perl}"
me=$0
default_gnulib_url=git://git.sv.gnu.org/gnulib
usage() {
cat <<EOF
Usage: $me [OPTION]...
@@ -76,6 +78,37 @@ contents are read as shell variables to configure the bootstrap.
For build prerequisites, environment variables like \$AUTOCONF and \$AMTAR
are honored.
Gnulib sources can be fetched in various ways:
* If this package is in a git repository with a 'gnulib' submodule
configured, then that submodule is initialized and updated and sources
are fetched from there. If \$GNULIB_SRCDIR is set (directly or via
--gnulib-srcdir) and is a git repository, then it is used as a reference.
* Otherwise, if \$GNULIB_SRCDIR is set (directly or via --gnulib-srcdir),
then sources are fetched from that local directory. If it is a git
repository and \$GNULIB_REVISION is set, then that revision is checked
out.
* Otherwise, if this package is in a git repository with a 'gnulib'
submodule configured, then that submodule is initialized and updated and
sources are fetched from there.
* Otherwise, if the 'gnulib' directory does not exist, Gnulib sources are
cloned into that directory using git from \$GNULIB_URL, defaulting to
$default_gnulib_url.
If \$GNULIB_REVISION is set, then that revision is checked out.
* Otherwise, the existing Gnulib sources in the 'gnulib' directory are
used. If it is a git repository and \$GNULIB_REVISION is set, then that
revision is checked out.
If you maintain a package and want to pin a particular revision of the
Gnulib sources that has been tested with your package, then there are two
possible approaches: either configure a 'gnulib' submodule with the
appropriate revision, or set \$GNULIB_REVISION (and if necessary
\$GNULIB_URL) in $me.conf.
Running without arguments will suffice in most cases.
EOF
}
@@ -109,6 +142,9 @@ die() { warn_ "$@"; exit 1; }
# Configuration.
# Name of the Makefile.am
gnulib_mk=gnulib.mk
# List of gnulib modules needed.
gnulib_modules=
@@ -132,7 +168,7 @@ bootstrap_epilogue() { :; }
# options because the latest/%s directory and the .po files within are
# all symlinks.
po_download_command_format=\
"rsync --delete --exclude '*.s1' -Lrtvz \
"rsync --include '*.po' --exclude '*' -Lrtvz \
'translationproject.org::tp/latest/%s/' '%s'"
# Fallback for downloading .po files (if rsync fails).
@@ -634,9 +670,11 @@ if $use_gnulib; then
trap cleanup_gnulib 1 2 13 15
shallow=
git clone -h 2>&1 | grep -- --depth > /dev/null && shallow='--depth 2'
git clone $shallow git://git.sv.gnu.org/gnulib "$gnulib_path" ||
cleanup_gnulib
if test -z "$GNULIB_REVISION"; then
git clone -h 2>&1 | grep -- --depth > /dev/null && shallow='--depth 2'
fi
git clone $shallow ${GNULIB_URL:-$default_gnulib_url} "$gnulib_path" \
|| cleanup_gnulib
trap - 1 2 13 15
fi
@@ -671,6 +709,11 @@ if $use_gnulib; then
;;
esac
if test -d "$GNULIB_SRCDIR"/.git && test -n "$GNULIB_REVISION" \
&& ! git_modules_config submodule.gnulib.url >/dev/null; then
(cd "$GNULIB_SRCDIR" && git checkout "$GNULIB_REVISION") || cleanup_gnulib
fi
# $GNULIB_SRCDIR now points to the version of gnulib to use, and
# we no longer need to use git or $gnulib_path below here.
@@ -902,13 +945,13 @@ fi
if $use_gnulib; then
gnulib_tool_options="\
--no-changelog\
--aux-dir $build_aux\
--doc-base $doc_base\
--lib $gnulib_name\
--m4-base $m4_base/\
--source-base $source_base/\
--tests-base $tests_base\
--local-dir $local_gl_dir\
--aux-dir=$build_aux\
--doc-base=$doc_base\
--lib=$gnulib_name\
--m4-base=$m4_base/\
--source-base=$source_base/\
--tests-base=$tests_base\
--local-dir=$local_gl_dir\
$gnulib_tool_option_extras\
"
if test $use_libtool = 1; then
+3 -2
View File
@@ -17,7 +17,8 @@
# gnulib modules used by this package.
gnulib_modules='
argmatch assert calloc-posix close closeout config-h c-strcase
argmatch assert
calloc-posix close closeout config-h c-strcase
configmake
dirname
error extensions fdl fopen-safer
@@ -81,7 +82,7 @@ gnulib_tool_option_extras='--symlink --makefile-name=gnulib.mk'
bootstrap_post_import_hook()
{
# Massage lib/gnulib.mk before using it later in the bootstrapping process.
build-aux/prefix-gnulib-mk --lib-name=$gnulib_name lib/gnulib.mk
build-aux/prefix-gnulib-mk --lib-name="$gnulib_name" "lib/$gnulib_mk"
# Ensure that ChangeLog exists, for automake.
test -f ChangeLog || touch ChangeLog
+2 -2
View File
@@ -34,7 +34,7 @@ _is-dist-target = $(filter-out %clean maintainer-check% maintainer-%-check, \
$(filter maintainer-% dist% alpha beta major,$(MAKECMDGOALS)))
url_dir_list = \
ftp://$(gnu_rel_host)/gnu/bison
https://$(gnu_rel_host)/gnu/bison
# Tests not to run as part of "make distcheck".
local-checks-to-skip = \
@@ -173,7 +173,7 @@ $(call exclude, \
prohibit_magic_number_exit=^doc/bison.texi$$ \
prohibit_magic_number_exit+=?|^tests/(conflicts|regression).at$$ \
prohibit_strcmp=^doc/bison\.texi|tests/local\.at$$ \
prohibit_tab_based_indentation=\.(am|mk)$$|^djgpp/|^\.git \
prohibit_tab_based_indentation=\.(am|mk)$$|^djgpp/|^\.git|Makefile$$ \
require_config_h_first=^(lib/yyerror|data/(glr|yacc))\.c$$ \
space_before_open_paren=^(data/|djgpp/) \
two_space_separator_in_usage=^(bootstrap) \
+1
View File
@@ -153,6 +153,7 @@ if test "$enable_gcc_warnings" = yes; then
# ... possiby in std=c++11 mode.
gl_WARN_ADD([-Wno-zero-as-null-pointer-constant], [FLEX_SCANNER_CXXFLAGS])
CXXFLAGS=$save_CXXFLAGS
gl_WARN_ADD([-fno-exceptions], [CXXFLAGS_NO_EXCEPTIONS])
AC_LANG_POP([C++])
fi
+4 -2
View File
@@ -1,5 +1,3 @@
-*- outline -*-
This directory contains data needed by Bison.
* Skeletons
@@ -52,6 +50,10 @@ into various formats.
-----
Local Variables:
mode: outline
End:
Copyright (C) 2002, 2008-2015, 2018 Free Software Foundation, Inc.
This file is part of GNU Bison.
+1 -1
View File
@@ -444,7 +444,7 @@ m4_define([b4_symbol_action],
[m4_dquote(b4_symbol([$1], [type]))]),
[(*yylocationp)])dnl
b4_symbol_case_([$1])[]dnl
b4_syncline([b4_symbol([$1], [$2_line])], ["b4_symbol([$1], [$2_file])"])
b4_syncline([b4_symbol([$1], [$2_line])], [b4_symbol([$1], [$2_file])])
b4_symbol([$1], [$2])
b4_syncline([@oline@], [@ofile@])
break;
+6 -6
View File
@@ -297,18 +297,18 @@ m4_define([b4_public_types_define],
// basic_symbol.
template <typename Base>
]b4_parser_class_name[::basic_symbol<Base>::basic_symbol ()
: value ()
: value ()]b4_locations_if([
, location ()])[
{}
template <typename Base>
]b4_parser_class_name[::basic_symbol<Base>::basic_symbol (const basic_symbol& other)
: Base (other)
, value ()]b4_locations_if([
, value (]b4_variant_if([], [other.value])[)]b4_locations_if([
, location (other.location)])[
{
]b4_variant_if([b4_symbol_variant([other.type_get ()], [value], [copy],
[other.value])],
[value = other.value;])[
{]b4_variant_if([
b4_symbol_variant([other.type_get ()], [value], [copy],
[other.value])])[
}
template <typename Base>
+6 -5
View File
@@ -172,10 +172,10 @@ m4_define([b4_int_type],
[m4_if(b4_ints_in($@, [0], [255]), [1], [unsigned char],
b4_ints_in($@, [-128], [127]), [1], [signed char],
b4_ints_in($@, [0], [65535]), [1], [unsigned short int],
b4_ints_in($@, [-32768], [32767]), [1], [short int],
b4_ints_in($@, [0], [65535]), [1], [unsigned short],
b4_ints_in($@, [-32768], [32767]), [1], [short],
m4_eval([0 <= $1]), [1], [unsigned int],
m4_eval([0 <= $1]), [1], [unsigned],
[int])])
@@ -242,7 +242,7 @@ m4_define([b4_attribute_define],
# define YYUSE(E) /* empty */
#endif
#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__
#if defined __GNUC__ && ! defined __ICC && 407 <= __GNUC__ * 100 + __GNUC_MINOR__
/* Suppress an incorrect diagnostic about yylval being uninitialized. */
# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
_Pragma ("GCC diagnostic push") \
@@ -459,7 +459,8 @@ b4_syncline([@oline@], [@ofile@])
# ------------------------------------
m4_define([b4_predicate_case],
[ case $1:
if (! ($2)) YYERROR;
if (! (
$2)) YYERROR;
b4_syncline([@oline@], [@ofile@])
break;])
+42 -53
View File
@@ -337,7 +337,7 @@ b4_percent_code_get[]dnl
#define YYMAXUTOK ]b4_user_token_number_max[
#define YYTRANSLATE(YYX) \
((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
((unsigned) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */
static const ]b4_int_type_for([b4_translate])[ yytranslate[] =
@@ -398,9 +398,9 @@ static const ]b4_int_type_for([b4_conflict_list_heads])[ yyconflp[] =
/* YYCONFL[I] -- lists of conflicting rule numbers, each terminated by
0, pointed into by YYCONFLP. */
]dnl Do not use b4_int_type_for here, since there are places where
dnl pointers onto yyconfl are taken, whose type is "short int *".
dnl pointers onto yyconfl are taken, whose type is "short*".
dnl We probably ought to introduce a type for confl.
[static const short int yyconfl[] =
[static const short yyconfl[] =
{
]b4_conflicting_rules[
};
@@ -613,7 +613,7 @@ typedef int yyRuleNum;
typedef int yySymbol;
/** Item references, as in LALR(1) machine */
typedef short int yyItemNum;
typedef short yyItemNum;
typedef struct yyGLRState yyGLRState;
typedef struct yyGLRStateSet yyGLRStateSet;
@@ -923,7 +923,7 @@ yydefaultAction (yyStateNum yystate)
*/
static inline void
yygetLRActions (yyStateNum yystate, int yytoken,
int* yyaction, const short int** yyconflicts)
int* yyaction, const short** yyconflicts)
{
int yyindex = yypact[yystate] + yytoken;
if (yypact_value_is_default (yypact[yystate])
@@ -1196,7 +1196,7 @@ yyremoveDeletes (yyGLRStack* yystackp)
if (yyj != yyi)
{
YYDPRINTF ((stderr, "Rename stack %lu -> %lu.\n",
(unsigned long int) yyi, (unsigned long int) yyj));
(unsigned long) yyi, (unsigned long) yyj));
}
yyj += 1;
}
@@ -1267,8 +1267,8 @@ yy_reduce_print (int yynormal, yyGLRStackItem* yyvsp, size_t yyk,
int yylow = 1;])[
int yyi;
YYFPRINTF (stderr, "Reducing stack %lu by rule %d (line %lu):\n",
(unsigned long int) yyk, yyrule - 1,
(unsigned long int) yyrline[yyrule]);
(unsigned long) yyk, yyrule - 1,
(unsigned long) yyrline[yyrule]);
if (! yynormal)
yyfillin (yyvsp, 1, -yynrhs);
/* The symbols being reduced. */
@@ -1360,7 +1360,7 @@ yyglrReduce (yyGLRStack* yystackp, size_t yyk, yyRuleNum yyrule,
if (yyflag == yyerr && yystackp->yysplitPoint != YY_NULLPTR)
{
YYDPRINTF ((stderr, "Parse on stack %lu rejected by rule #%d.\n",
(unsigned long int) yyk, yyrule - 1));
(unsigned long) yyk, yyrule - 1));
}
if (yyflag != yyok)
return yyflag;
@@ -1388,7 +1388,7 @@ yyglrReduce (yyGLRStack* yystackp, size_t yyk, yyRuleNum yyrule,
YYDPRINTF ((stderr,
"Reduced stack %lu by rule #%d; action deferred. "
"Now in state %d.\n",
(unsigned long int) yyk, yyrule - 1, yynewLRState));
(unsigned long) yyk, yyrule - 1, yynewLRState));
for (yyi = 0; yyi < yystackp->yytops.yysize; yyi += 1)
if (yyi != yyk && yystackp->yytops.yystates[yyi] != YY_NULLPTR)
{
@@ -1401,8 +1401,8 @@ yyglrReduce (yyGLRStack* yystackp, size_t yyk, yyRuleNum yyrule,
yyaddDeferredAction (yystackp, yyk, yyp, yys0, yyrule);
yymarkStackDeleted (yystackp, yyk);
YYDPRINTF ((stderr, "Merging stack %lu into stack %lu.\n",
(unsigned long int) yyk,
(unsigned long int) yyi));
(unsigned long) yyk,
(unsigned long) yyi));
return yyok;
}
yyp = yyp->yypred;
@@ -1648,8 +1648,8 @@ yyreportTree (yySemanticOption* yyx, int yyindent)
else
YYFPRINTF (stderr, "%*s%s -> <Rule %d, tokens %lu .. %lu>\n",
yyindent, "", yytokenName (yylhsNonterm (yyx->yyrule)),
yyx->yyrule - 1, (unsigned long int) (yys->yyposn + 1),
(unsigned long int) yyx->yystate->yyposn);
yyx->yyrule - 1, (unsigned long) (yys->yyposn + 1),
(unsigned long) yyx->yystate->yyposn);
for (yyi = 1; yyi <= yynrhs; yyi += 1)
{
if (yystates[yyi]->yyresolved)
@@ -1660,8 +1660,8 @@ yyreportTree (yySemanticOption* yyx, int yyindent)
else
YYFPRINTF (stderr, "%*s%s <tokens %lu .. %lu>\n", yyindent+2, "",
yytokenName (yystos[yystates[yyi]->yylrState]),
(unsigned long int) (yystates[yyi-1]->yyposn + 1),
(unsigned long int) yystates[yyi]->yyposn);
(unsigned long) (yystates[yyi-1]->yyposn + 1),
(unsigned long) yystates[yyi]->yyposn);
}
else
yyreportTree (yystates[yyi]->yysemantics.yyfirstVal, yyindent+2);
@@ -1693,7 +1693,7 @@ yyreportAmbiguity (yySemanticOption* yyx0,
* ending at YYS1. Has no effect on previously resolved states.
* The first semantic option of a state is always chosen. */
static void
yyresolveLocations (yyGLRState* yys1, int yyn1,
yyresolveLocations (yyGLRState *yys1, int yyn1,
yyGLRStack *yystackp]b4_user_formals[)
{
if (0 < yyn1)
@@ -1704,9 +1704,9 @@ yyresolveLocations (yyGLRState* yys1, int yyn1,
yyGLRStackItem yyrhsloc[1 + YYMAXRHS];
int yynrhs;
yySemanticOption *yyoption = yys1->yysemantics.yyfirstVal;
YYASSERT (yyoption != YY_NULLPTR);
YYASSERT (yyoption);
yynrhs = yyrhsLength (yyoption->yyrule);
if (yynrhs > 0)
if (0 < yynrhs)
{
yyGLRState *yys;
int yyn;
@@ -1729,18 +1729,7 @@ yyresolveLocations (yyGLRState* yys1, int yyn1,
yyGLRState *yyprevious = yyoption->yystate;
yyrhsloc[0].yystate.yyloc = yyprevious->yyloc;
}
{
int yychar_current = yychar;
YYSTYPE yylval_current = yylval;
YYLTYPE yylloc_current = yylloc;
yychar = yyoption->yyrawchar;
yylval = yyoption->yyval;
yylloc = yyoption->yyloc;
YYLLOC_DEFAULT ((yys1->yyloc), yyrhsloc, yynrhs);
yychar = yychar_current;
yylval = yylval_current;
yylloc = yylloc_current;
}
YYLLOC_DEFAULT ((yys1->yyloc), yyrhsloc, yynrhs);
}
}
}]])[
@@ -1892,7 +1881,7 @@ yyprocessOneStack (yyGLRStack* yystackp, size_t yyk,
{
yyStateNum yystate = yystackp->yytops.yystates[yyk]->yylrState;
YYDPRINTF ((stderr, "Stack %lu Entering state %d\n",
(unsigned long int) yyk, yystate));
(unsigned long) yyk, yystate));
YYASSERT (yystate != YYFINAL);
@@ -1903,7 +1892,7 @@ yyprocessOneStack (yyGLRStack* yystackp, size_t yyk,
if (yyrule == 0)
{
YYDPRINTF ((stderr, "Stack %lu dies.\n",
(unsigned long int) yyk));
(unsigned long) yyk));
yymarkStackDeleted (yystackp, yyk);
return yyok;
}
@@ -1913,7 +1902,7 @@ yyprocessOneStack (yyGLRStack* yystackp, size_t yyk,
YYDPRINTF ((stderr,
"Stack %lu dies "
"(predicate failure or explicit user error).\n",
(unsigned long int) yyk));
(unsigned long) yyk));
yymarkStackDeleted (yystackp, yyk);
return yyok;
}
@@ -1924,7 +1913,7 @@ yyprocessOneStack (yyGLRStack* yystackp, size_t yyk,
{
yySymbol yytoken;
int yyaction;
const short int* yyconflicts;
const short* yyconflicts;
yystackp->yytops.yylookaheadNeeds[yyk] = yytrue;
if (yychar == YYEMPTY)
@@ -1951,8 +1940,8 @@ yyprocessOneStack (yyGLRStack* yystackp, size_t yyk,
YYRESULTTAG yyflag;
size_t yynewStack = yysplitStack (yystackp, yyk);
YYDPRINTF ((stderr, "Splitting off stack %lu from %lu.\n",
(unsigned long int) yynewStack,
(unsigned long int) yyk));
(unsigned long) yynewStack,
(unsigned long) yyk));
yyflag = yyglrReduce (yystackp, yynewStack,
*yyconflicts,
yyimmediate[*yyconflicts]]b4_user_args[);
@@ -1962,7 +1951,7 @@ yyprocessOneStack (yyGLRStack* yystackp, size_t yyk,
else if (yyflag == yyerr)
{
YYDPRINTF ((stderr, "Stack %lu dies.\n",
(unsigned long int) yynewStack));
(unsigned long) yynewStack));
yymarkStackDeleted (yystackp, yynewStack);
}
else
@@ -1975,7 +1964,7 @@ yyprocessOneStack (yyGLRStack* yystackp, size_t yyk,
else if (yyisErrorAction (yyaction))
{
YYDPRINTF ((stderr, "Stack %lu dies.\n",
(unsigned long int) yyk));
(unsigned long) yyk));
yymarkStackDeleted (yystackp, yyk);
break;
}
@@ -1988,7 +1977,7 @@ yyprocessOneStack (yyGLRStack* yystackp, size_t yyk,
YYDPRINTF ((stderr,
"Stack %lu dies "
"(predicate failure or explicit user error).\n",
(unsigned long int) yyk));
(unsigned long) yyk));
yymarkStackDeleted (yystackp, yyk);
break;
}
@@ -2297,7 +2286,7 @@ b4_dollar_popdef])[]dnl
{
yyRuleNum yyrule;
int yyaction;
const short int* yyconflicts;
const short* yyconflicts;
yyStateNum yystate = yystack.yytops.yystates[0]->yylrState;
YYDPRINTF ((stderr, "Entering state %d\n", yystate));
@@ -2410,17 +2399,17 @@ b4_dollar_popdef])[]dnl
for (yys = 0; yys < yystack.yytops.yysize; yys += 1)
{
int yyaction;
const short int* yyconflicts;
const short* yyconflicts;
yyStateNum yystate = yystack.yytops.yystates[yys]->yylrState;
yygetLRActions (yystate, yytoken_to_shift, &yyaction,
&yyconflicts);
/* Note that yyconflicts were handled by yyprocessOneStack. */
YYDPRINTF ((stderr, "On stack %lu, ", (unsigned long int) yys));
YYDPRINTF ((stderr, "On stack %lu, ", (unsigned long) yys));
YY_SYMBOL_PRINT ("shifting", yytoken_to_shift, &yylval, &yylloc);
yyglrShift (&yystack, yys, yyaction, yyposn,
&yylval]b4_locations_if([, &yylloc])[);
YYDPRINTF ((stderr, "Stack %lu now in state #%d\n",
(unsigned long int) yys,
(unsigned long) yys,
yystack.yytops.yystates[yys]->yylrState));
}
@@ -2503,7 +2492,7 @@ yy_yypstack (yyGLRState* yys)
YYFPRINTF (stderr, " -> ");
}
YYFPRINTF (stderr, "%d@@%lu", yys->yylrState,
(unsigned long int) yys->yyposn);
(unsigned long) yys->yyposn);
}
static void
@@ -2534,18 +2523,18 @@ yypdumpstack (yyGLRStack* yystackp)
for (yyp = yystackp->yyitems; yyp < yystackp->yynextFree; yyp += 1)
{
YYFPRINTF (stderr, "%3lu. ",
(unsigned long int) (yyp - yystackp->yyitems));
(unsigned long) (yyp - yystackp->yyitems));
if (*(yybool *) yyp)
{
YYASSERT (yyp->yystate.yyisState);
YYASSERT (yyp->yyoption.yyisState);
YYFPRINTF (stderr, "Res: %d, LR State: %d, posn: %lu, pred: %ld",
yyp->yystate.yyresolved, yyp->yystate.yylrState,
(unsigned long int) yyp->yystate.yyposn,
(long int) YYINDEX (yyp->yystate.yypred));
(unsigned long) yyp->yystate.yyposn,
(long) YYINDEX (yyp->yystate.yypred));
if (! yyp->yystate.yyresolved)
YYFPRINTF (stderr, ", firstVal: %ld",
(long int) YYINDEX (yyp->yystate
(long) YYINDEX (yyp->yystate
.yysemantics.yyfirstVal));
}
else
@@ -2554,15 +2543,15 @@ yypdumpstack (yyGLRStack* yystackp)
YYASSERT (!yyp->yyoption.yyisState);
YYFPRINTF (stderr, "Option. rule: %d, state: %ld, next: %ld",
yyp->yyoption.yyrule - 1,
(long int) YYINDEX (yyp->yyoption.yystate),
(long int) YYINDEX (yyp->yyoption.yynext));
(long) YYINDEX (yyp->yyoption.yystate),
(long) YYINDEX (yyp->yyoption.yynext));
}
YYFPRINTF (stderr, "\n");
}
YYFPRINTF (stderr, "Tops:");
for (yyi = 0; yyi < yystackp->yytops.yysize; yyi += 1)
YYFPRINTF (stderr, "%lu: %ld; ", (unsigned long int) yyi,
(long int) YYINDEX (yystackp->yytops.yystates[yyi]));
YYFPRINTF (stderr, "%lu: %ld; ", (unsigned long) yyi,
(long) YYINDEX (yystackp->yytops.yystates[yyi]));
YYFPRINTF (stderr, "\n");
}
#endif
+29 -11
View File
@@ -107,7 +107,7 @@ b4_dollar_pushdef([yysym.value],
[m4_dquote(b4_symbol([$1], [type]))]),
[yysym.location])dnl
b4_symbol_case_([$1])
b4_syncline([b4_symbol([$1], [$2_line])], ["b4_symbol([$1], [$2_file])"])
b4_syncline([b4_symbol([$1], [$2_line])], [b4_symbol([$1], [$2_file])])
b4_symbol([$1], [$2])
b4_syncline([@oline@], [@ofile@])
break;
@@ -159,6 +159,7 @@ m4_define([b4_shared_declarations],
]b4_variant_if([b4_variant_includes])[
]b4_attribute_define[
]b4_null_define[
]b4_YYDEBUG_define[
]b4_namespace_open[
@@ -314,7 +315,7 @@ b4_location_define])])[
typedef basic_symbol<by_state> super_type;
/// Construct an empty symbol.
stack_symbol_type ();
/// Copy construct.
/// Copy construct (for efficiency).
stack_symbol_type (const stack_symbol_type& that);
/// Steal the contents from \a sym to build this.
stack_symbol_type (state_type s, symbol_type& sym);
@@ -426,6 +427,15 @@ m4_if(b4_prefix, [yy], [],
# endif
#endif
// Whether we are compiled with exception support.
#ifndef YY_EXCEPTIONS
# if defined __GNUC__ && !defined __EXCEPTIONS
# define YY_EXCEPTIONS 0
# else
# define YY_EXCEPTIONS 1
# endif
#endif
]b4_locations_if([dnl
[#define YYRHSLOC(Rhs, K) ((Rhs)[K].location)
]b4_yylloc_default_define])[
@@ -584,11 +594,10 @@ m4_if(b4_prefix, [yy], [],
}
]b4_parser_class_name[::stack_symbol_type::stack_symbol_type (state_type s, symbol_type& that)
: super_type (s]b4_locations_if([, that.location])[)
{
]b4_variant_if([b4_symbol_variant([that.type_get ()],
[value], [move], [that.value])],
[[value = that.value;]])[
: super_type (s]b4_variant_if([], [, that.value])[]b4_locations_if([, that.location])[)
{]b4_variant_if([
b4_symbol_variant([that.type_get ()],
[value], [move], [that.value])])[
// that is emptied.
that.type = empty_symbol;
}
@@ -728,9 +737,9 @@ m4_if(b4_prefix, [yy], [],
/// The return value of parse ().
int yyresult;
// FIXME: This shoud be completely indented. It is not yet to
// avoid gratuitous conflicts when merging into the master branch.
#if YY_EXCEPTIONS
try
#endif // YY_EXCEPTIONS
{
YYCDEBUG << "Starting parse\n";
@@ -759,7 +768,6 @@ b4_dollar_popdef])[]dnl
// Backup.
yybackup:
// Try to take a decision without lookahead.
yyn = yypact_[yystack_[0].state];
if (yy_pact_value_is_default_ (yyn))
@@ -769,17 +777,21 @@ b4_dollar_popdef])[]dnl
if (yyla.empty ())
{
YYCDEBUG << "Reading a token: ";
#if YY_EXCEPTIONS
try
#endif // YY_EXCEPTIONS
{]b4_token_ctor_if([[
symbol_type yylookahead (]b4_lex[);
yyla.move (yylookahead);]], [[
yyla.type = yytranslate_ (]b4_lex[);]])[
}
#if YY_EXCEPTIONS
catch (const syntax_error& yyexc)
{
error (yyexc);
goto yyerrlab1;
}
#endif // YY_EXCEPTIONS
}
YY_SYMBOL_PRINT ("Next token is", yyla);
@@ -849,7 +861,9 @@ b4_dollar_popdef])[]dnl
// Perform the reduction.
YY_REDUCE_PRINT (yyn);
#if YY_EXCEPTIONS
try
#endif // YY_EXCEPTIONS
{
switch (yyn)
{
@@ -858,11 +872,13 @@ b4_dollar_popdef])[]dnl
break;
}
}
#if YY_EXCEPTIONS
catch (const syntax_error& yyexc)
{
error (yyexc);
YYERROR;
}
#endif // YY_EXCEPTIONS
YY_SYMBOL_PRINT ("-> $$ =", yylhs);
yypop_ (yylen);
yylen = 0;
@@ -987,11 +1003,12 @@ b4_dollar_popdef])[]dnl
return yyresult;
}
#if YY_EXCEPTIONS
catch (...)
{
YYCDEBUG << "Exception caught: cleaning lookahead and stack\n";
// Do not try to display the values of the reclaimed symbols,
// as their printer might throw an exception.
// as their printers might throw an exception.
if (!yyla.empty ())
yy_destroy_ (YY_NULLPTR, yyla);
@@ -1002,6 +1019,7 @@ b4_dollar_popdef])[]dnl
}
throw;
}
#endif // YY_EXCEPTIONS
}
void
+5 -7
View File
@@ -73,12 +73,10 @@ m4_define([b4_position_define],
unsigned column;
private:
/// Compute max(min, lhs+rhs) (provided min <= lhs).
static unsigned add_ (unsigned lhs, int rhs, unsigned min)
/// Compute max(min, lhs+rhs).
static unsigned add_ (unsigned lhs, int rhs, int min)
{
return (0 < rhs || -static_cast<unsigned>(rhs) < lhs
? rhs + lhs
: min);
return static_cast<unsigned>(std::max(min, static_cast<int>(lhs) + rhs));
}
};
@@ -134,7 +132,7 @@ m4_define([b4_position_define],
** \param pos a reference to the position to redirect
*/
template <typename YYChar>
inline std::basic_ostream<YYChar>&
std::basic_ostream<YYChar>&
operator<< (std::basic_ostream<YYChar>& ostr, const position& pos)
{
if (pos.filename)
@@ -271,7 +269,7 @@ m4_define([b4_location_define],
** Avoid duplicate information.
*/
template <typename YYChar>
inline std::basic_ostream<YYChar>&
std::basic_ostream<YYChar>&
operator<< (std::basic_ostream<YYChar>& ostr, const location& loc)
{
unsigned end_col = 0 < loc.end.column ? loc.end.column - 1 : 0;
+10 -9
View File
@@ -29,14 +29,14 @@ m4_define([b4_stack_define],
// Hide our reversed order.
typedef typename S::reverse_iterator iterator;
typedef typename S::const_reverse_iterator const_iterator;
typedef typename S::size_type size_type;
stack ()
: seq_ ()
{
seq_.reserve (200);
}
stack (unsigned n)
stack (size_type n)
: seq_ (n)
{}
@@ -44,7 +44,7 @@ m4_define([b4_stack_define],
///
/// Index 0 returns the topmost element.
T&
operator[] (unsigned i)
operator[] (size_type i)
{
return seq_[seq_.size () - 1 - i];
}
@@ -53,7 +53,7 @@ m4_define([b4_stack_define],
///
/// Index 0 returns the topmost element.
const T&
operator[] (unsigned i) const
operator[] (size_type i) const
{
return seq_[seq_.size () - 1 - i];
}
@@ -69,7 +69,7 @@ m4_define([b4_stack_define],
}
void
pop (unsigned n = 1)
pop (size_type n = 1)
{
for (; n; --n)
seq_.pop_back ();
@@ -81,7 +81,7 @@ m4_define([b4_stack_define],
seq_.clear ();
}
typename S::size_type
size_type
size () const
{
return seq_.size ();
@@ -111,20 +111,21 @@ m4_define([b4_stack_define],
class slice
{
public:
slice (const S& stack, unsigned range)
typedef typename S::size_type size_type;
slice (const S& stack, size_type range)
: stack_ (stack)
, range_ (range)
{}
const T&
operator [] (unsigned i) const
operator[] (size_type i) const
{
return stack_[range_ - i];
}
private:
const S& stack_;
unsigned range_;
size_type range_;
};
]])
+10 -7
View File
@@ -94,8 +94,9 @@ m4_define([b4_variant_define],
typedef variant<S> self_type;
/// Empty construction.
variant ()]b4_parse_assert_if([
: yytypeid_ (YY_NULLPTR)])[
variant ()
: yybuffer_ ()]b4_parse_assert_if([
, yytypeid_ (YY_NULLPTR)])[
{}
/// Construct and fill.
@@ -121,7 +122,7 @@ m4_define([b4_variant_define],
YYASSERT (!yytypeid_);
YYASSERT (sizeof (T) <= S);
yytypeid_ = & typeid (T);])[
return *new (yyas_<T> ()) T;
return *new (yyas_<T> ()) T ();
}
/// Instantiate a \a T in here from \a t.
@@ -140,6 +141,7 @@ m4_define([b4_variant_define],
T&
as ()
{]b4_parse_assert_if([
YYASSERT (yytypeid_);
YYASSERT (*yytypeid_ == typeid (T));
YYASSERT (sizeof (T) <= S);])[
return *yyas_<T> ();
@@ -150,6 +152,7 @@ m4_define([b4_variant_define],
const T&
as () const
{]b4_parse_assert_if([
YYASSERT (yytypeid_);
YYASSERT (*yytypeid_ == typeid (T));
YYASSERT (sizeof (T) <= S);])[
return *yyas_<T> ();
@@ -332,7 +335,7 @@ m4_define([b4_basic_symbol_constructor_declare],
[[
basic_symbol (]b4_join(
[typename Base::kind_type t],
b4_symbol_if([$1], [has_type], const b4_symbol([$1], [type])[ v]),
b4_symbol_if([$1], [has_type], const b4_symbol([$1], [type])[& v]),
b4_locations_if([const location_type& l]))[);
]])
@@ -344,10 +347,10 @@ m4_define([b4_basic_symbol_constructor_define],
template <typename Base>
]b4_parser_class_name[::basic_symbol<Base>::basic_symbol (]b4_join(
[typename Base::kind_type t],
b4_symbol_if([$1], [has_type], const b4_symbol([$1], [type])[ v]),
b4_symbol_if([$1], [has_type], const b4_symbol([$1], [type])[& v]),
b4_locations_if([const location_type& l]))[)
: Base (t)
, value (]b4_symbol_if([$1], [has_type], [v])[)]b4_locations_if([
: Base (t)]b4_symbol_if([$1], [has_type], [
, value (v)])[]b4_locations_if([
, location (l)])[
{}
]])
+19 -16
View File
@@ -118,7 +118,7 @@ m4_define([b4_int_type],
b4_ints_in($@, [0], [65535]), [1], [yytype_uint16],
b4_ints_in($@, [-32768], [32767]), [1], [yytype_int16],
m4_eval([0 <= $1]), [1], [unsigned int],
m4_eval([0 <= $1]), [1], [unsigned],
[int])])
@@ -377,13 +377,13 @@ typedef signed char yytype_int8;
#ifdef YYTYPE_UINT16
typedef YYTYPE_UINT16 yytype_uint16;
#else
typedef unsigned short int yytype_uint16;
typedef unsigned short yytype_uint16;
#endif
#ifdef YYTYPE_INT16
typedef YYTYPE_INT16 yytype_int16;
#else
typedef short int yytype_int16;
typedef short yytype_int16;
#endif
#ifndef YYSIZE_T
@@ -395,7 +395,7 @@ typedef short int yytype_int16;
# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
# define YYSIZE_T size_t
# else
# define YYSIZE_T unsigned int
# define YYSIZE_T unsigned
# endif
#endif
@@ -571,7 +571,7 @@ union yyalloc
#define YYMAXUTOK ]b4_user_token_number_max[
#define YYTRANSLATE(YYX) \
((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
((unsigned) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM
as returned by yylex, without out-of-bounds checking. */
@@ -719,7 +719,7 @@ do { \
])[[int yyrule], [yyrule]]m4_ifset([b4_parse_param], [,
b4_parse_param]))[
{
unsigned long int yylno = yyrline[yyrule];
unsigned long yylno = yyrline[yyrule];
int yynrhs = yyr2[yyrule];
int yyi;
YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
@@ -827,7 +827,7 @@ yy_lac_stack_realloc (YYSIZE_T *yycapacity, YYSIZE_T yyadd,
*yycapacity = yyalloc;]m4_if(b4_percent_define_get([[parse.lac.memory-trace]]),
[full], [[
YYDPRINTF ((stderr, "%srealloc to %lu%s", yydebug_prefix,
(unsigned long int) yyalloc, yydebug_suffix));]])[
(unsigned long) yyalloc, yydebug_suffix));]])[
}
return 0;
}
@@ -1326,16 +1326,19 @@ b4_function_define([[yyparse]], [[int]], b4_parse_param)[
]b4_function_define([[yypstate_delete]], [[void]],
[[[yypstate *yyps]], [[yyps]]])[
{
if (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 && yyps->yyss != yyps->yyssa)
YYSTACK_FREE (yyps->yyss);
/* If the stack was reallocated but the parse did not complete, then the
stack still needs to be freed. */
if (!yyps->yynew && yyps->yyss != yyps->yyssa)
YYSTACK_FREE (yyps->yyss);
#endif]b4_lac_if([[
if (!yyps->yynew && yyps->yyes != yyps->yyesa)
YYSTACK_FREE (yyps->yyes);]])[
free (yyps);]b4_pure_if([], [[
yypstate_allocated = 0;]])[
if (!yyps->yynew && yyps->yyes != yyps->yyesa)
YYSTACK_FREE (yyps->yyes);]])[
free (yyps);]b4_pure_if([], [[
yypstate_allocated = 0;]])[
}
}
]b4_pure_if([[
#define ]b4_prefix[nerrs yyps->]b4_prefix[nerrs]])[
@@ -1510,7 +1513,7 @@ b4_locations_if([[ yylsp[0] = ]b4_push_if([b4_pure_if([*])yypushed_loc], [yyllo
yylsp = yyls + yysize - 1;])[
YYDPRINTF ((stderr, "Stack size increased to %lu\n",
(unsigned long int) yystacksize));
(unsigned long) yystacksize));
if (yyss + yystacksize - 1 <= yyssp)
YYABORT;
+351 -339
View File
File diff suppressed because it is too large Load Diff
+40
View File
@@ -0,0 +1,40 @@
This directory contains examples of Bison grammar files.
* mfcalc
A C example of a multi-function calculator. Extracted from the
documentation.
* calc++
A C++ version of the canonical example for parsers: a calculator. Also uses
Flex for the scanner. Extracted from the documentation.
* variant.yy
A C++ example that uses variants (they allow to use any C++ type as semantic
value type) and symbol constructors (they ensure consistency between
declared token type and effective semantic value).
-----
Local Variables:
mode: outline
fill-column: 76
End:
Copyright (C) 2018 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/>.
# LocalWords: mfcalc calc parsers yy
+9 -9
View File
@@ -2,18 +2,18 @@
/*.tmp
/.deps
/calc++
/calc++-driver.cc
/calc++-driver.hh
/calc++-parser.cc
/calc++-parser.hh
/calc++-parser.output
/calc++-parser.stamp
/calc++-parser.yy
/calc++-scanner.cc
/calc++-scanner.ll
/calc++.cc
/calc++.exe
/calc.stamp
/driver.cc
/driver.hh
/location.hh
/parser.cc
/parser.hh
/parser.output
/parser.stamp
/parser.yy
/position.hh
/scanner.cc
/scanner.ll
/stack.hh
+27
View File
@@ -0,0 +1,27 @@
# This Makefile is designed to be simple and readable. It does not
# aim at portability. It requires GNU Make.
BISON = bison
CXX = g++
FLEX = flex
all: calc++
%.cc %.hh: %.yy
$(BISON) $(BISONFLAGS) -o $*.cc $<
%.cc: %.ll
$(FLEX) $(FLEXFLAGS) -o$@ $<
%.o: %.cc
$(CXX) $(CXXFLAGS) -c -o$@ $<
calc++: calc++.o driver.o parser.o scanner.o
$(CXX) -o $@ $^
calc++.o: parser.hh
parser.o: parser.hh
scanner.o: parser.hh
clean:
rm -f calc++ *.o parser.hh parser.cc scanner.cc
+51
View File
@@ -0,0 +1,51 @@
This directory contains calc++, a simple Bison grammar file in C++.
Please, 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
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
several variable definitions, one per line, and then a single expression to
evaluate.
The program calc++ expects the file to parse as argument; pass `-` to read
the standard input (and then hit <Ctrl-d>, control-d, to end your input).
$ ./calc++ -
one := 1
two := 2
three := 3
(one + two * three) * two * three
<Ctrl-d>
42
You may pass `-p` to activate the parser debug traces, and `-s` to activate
the scanner's.
-----
Local Variables:
mode: outline
fill-column: 76
End:
Copyright (C) 2018 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/>.
# LocalWords: mfcalc calc parsers yy MERCHANTABILITY
+17 -16
View File
@@ -20,7 +20,7 @@
# Don't depend on $(BISON) otherwise we would rebuild these files
# in srcdir, including during distcheck, which is forbidden.
%D%/calc++-parser.stamp: $(BISON_IN)
%D%/parser.stamp: $(BISON_IN)
SUFFIXES += .yy .stamp
.yy.stamp:
$(AM_V_YACC)rm -f $@
@@ -28,14 +28,14 @@ SUFFIXES += .yy .stamp
$(AM_V_at)$(YACCCOMPILE) -o $*.cc $<
$(AM_V_at)mv -f $@.tmp $@
$(calcxx_sources_generated): %D%/calc++-parser.stamp
@test -f $@ || rm -f %D%/calc++-parser.stamp
@test -f $@ || $(MAKE) $(AM_MAKEFLAGS) %D%/calc++-parser.stamp
CLEANFILES += \
$(calcxx_sources_generated) \
%D%/calc++-parser.output \
%D%/calc++-parser.stamp \
%D%/calc++-scanner.cc
$(calcxx_sources_generated): %D%/parser.stamp
@test -f $@ || rm -f %D%/parser.stamp
@test -f $@ || $(MAKE) $(AM_MAKEFLAGS) %D%/parser.stamp
CLEANFILES += \
$(calcxx_sources_generated) \
%D%/parser.output \
%D%/parser.stamp \
%D%/scanner.cc
## -------------------- ##
@@ -45,18 +45,18 @@ CLEANFILES += \
# Avoid using BUILT_SOURCES which is too global.
$(%C%_calc___OBJECTS): $(calcxx_sources_generated)
calcxx_sources_extracted = \
%D%/calc++-driver.cc \
%D%/calc++-driver.hh \
%D%/calc++-scanner.ll \
calcxx_sources_extracted = \
%D%/driver.cc \
%D%/driver.hh \
%D%/scanner.ll \
%D%/calc++.cc
calcxx_extracted = \
$(calcxx_sources_extracted) \
%D%/calc++-parser.yy
%D%/parser.yy
extracted += $(calcxx_extracted)
calcxx_sources_generated = \
%D%/calc++-parser.cc \
%D%/calc++-parser.hh \
%D%/parser.cc \
%D%/parser.hh \
%D%/location.hh \
%D%/position.hh \
%D%/stack.hh
@@ -83,3 +83,4 @@ endif
calcxxdir = $(docdir)/examples/calc++
calcxx_DATA = $(calcxx_extracted)
dist_calcxx_DATA = %D%/README %D%/Makefile
-6
View File
@@ -1,6 +0,0 @@
// Work around an Automake 1.11.2 bug: it asks for the creation of
// y.tab.c and y.tab.h and then renames them as calc++-parser.cc and
// calc++-parser.h, but in the former it does not convert the
// #include "y.tab.h". We don't want this to show in the
// documentation.
#include "calc++-parser.hh"
+20 -8
View File
@@ -45,7 +45,7 @@ sub normalize($)
{
local ($_) = @_;
s/^\@(c |comment|dots|end (ignore|group)|ignore|group).*//mg;
s/^\@(c |comment|dots|end (ignore|group)|ignore|group).*\n//mg;
s/\@value\{VERSION\}/$ENV{VERSION}/g;
s/^\@(error|result)\{\}//mg;
s/\@([{}@])/$1/g;
@@ -65,8 +65,21 @@ sub message($)
}
}
# basename => full file name for files we should extract.
my %file_wanted;
# The list of files we should extract.
my @file_wanted;
# Whether we should extract that file, and then under which path.
sub file_wanted ($)
{
my ($f) = @_;
for my $file (@file_wanted)
{
# No endswith in Perl 5...
return $file if $f eq substr($file, -length($f));
}
undef
}
sub process ($)
{
@@ -89,9 +102,9 @@ sub process ($)
{
my $f = $1;
$block = $2 || 1;
if ($file_wanted{$f})
if (file_wanted($f))
{
$file = $file_wanted{$f};
$file = file_wanted($f);
message(" GEN $file");
}
else
@@ -106,13 +119,13 @@ sub process ($)
# Bison supports synclines, but not Flex.
$input .= sprintf ("#line %s \"$in\"\n", $. + 1)
if $synclines && $file =~ /\.[chy]*$/;
next;
}
elsif (/^\@end (small)?example$/)
{
die "no contents: $file"
if $input eq "";
$file{$file}{$block} .= "\n" if defined $file{$file}{$block};
$file{$file}{$block} .= normalize($input);
$file = $input = undef;
++$block;
@@ -141,8 +154,7 @@ for my $arg (@ARGV)
{
if ($seen_dash)
{
use File::Basename;
$file_wanted{basename($arg)} = $arg;
push @file_wanted, $arg;
}
elsif ($arg eq '--')
{
+15 -2
View File
@@ -26,9 +26,9 @@ AM_CXXFLAGS = \
doc = $(top_srcdir)/doc/bison.texi
extexi = $(top_srcdir)/%D%/extexi
if ENABLE_GCC_WARNINGS
extexiFLAGS = --synclines
EXTEXIFLAGS = --synclines
endif
extract = VERSION="$(VERSION)" $(PERL) $(extexi) $(extexiFLAGS) $(doc) --
extract = VERSION="$(VERSION)" $(PERL) $(extexi) $(EXTEXIFLAGS) $(doc) --
extracted =
CLEANFILES += $(extracted) %D%/extracted.stamp
%D%/extracted.stamp: $(doc) $(extexi)
@@ -41,6 +41,19 @@ $(extracted): %D%/extracted.stamp
@test -f $@ || rm -f %D%/extracted.stamp
@test -f $@ || $(MAKE) $(AM_MAKEFLAGS) %D%/extracted.stamp
## ---------- ##
## Examples. ##
## ---------- ##
examplesdir = $(docdir)/examples
dist_examples_DATA = %D%/README %D%/variant.yy
check_PROGRAMS += %D%/variant
nodist_%C%_variant_SOURCES = %D%/variant.yy
%C%_variant_CPPFLAGS = -I$(top_builddir)
dist_TESTS += %D%/variant.test
include %D%/calc++/local.mk
include %D%/mfcalc/local.mk
include %D%/rpcalc/local.mk
+2 -2
View File
@@ -26,10 +26,10 @@ mfcalc_sources = $(mfcalc_extracted)
extracted += $(mfcalc_extracted)
check_PROGRAMS += %D%/mfcalc
%C%_mfcalc_LDADD = -lm
nodist_%C%_mfcalc_SOURCES = $(mfcalc_sources)
%C%_mfcalc_CPPFLAGS = -I$(top_builddir)/%D%
%C%_mfcalc_LDADD = -lm
dist_TESTS += %D%/mfcalc.test
## ------------ ##
+2 -2
View File
@@ -26,10 +26,10 @@ rpcalc_sources = $(rpcalc_extracted)
extracted += $(rpcalc_extracted)
check_PROGRAMS += %D%/rpcalc
%C%_rpcalc_LDADD = -lm
nodist_%C%_rpcalc_SOURCES = $(rpcalc_sources)
%C%_rpcalc_CPPFLAGS = -I$(top_builddir)/%D%
%C%_rpcalc_LDADD = -lm
dist_TESTS += %D%/rpcalc.test
## ------------ ##
+12 -1
View File
@@ -27,7 +27,18 @@ exit=true
cwd=`pwd`
# The exercised program.
prog=$cwd/examples/$me/$me
for p in $cwd/examples/$me/$me $cwd/examples/$me
do
if test -x "$p"; then
prog=$p
break
fi
done
if test x"$prog" = x; then
echo "$me: ERROR: cannot find program to exercise"
exit 1
fi
# cleanup
# -------
+19
View File
@@ -0,0 +1,19 @@
#! /bin/sh
# Copyright (C) 2018 Free Software Foundation, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
: >input
run 0 "{I have three numbers for you., 1, 2, 3, And that's all!}"
+7 -7
View File
@@ -50,7 +50,7 @@ typedef std::vector<std::string> strings_type;
std::ostream&
operator<< (std::ostream& o, const strings_type& ss)
{
o << '(' << &ss << ") {";
o << '{';
const char *sep = "";
for (strings_type::const_iterator i = ss.begin(), end = ss.end();
i != end; ++i)
@@ -75,7 +75,7 @@ typedef std::vector<std::string> strings_type;
%token <::std::string> TEXT;
%token <int> NUMBER;
%printer { yyoutput << $$; } <*>;
%printer { yyo << '(' << &$$ << ") " << $$; } <*>;
%token END_OF_FILE 0;
%type <::std::string> item;
@@ -88,13 +88,13 @@ result:
;
list:
/* nothing */ { /* Generates an empty string list */ }
| list item { std::swap ($$, $1); $$.push_back ($2); }
%empty { /* Generates an empty string list */ }
| list item { std::swap ($$, $1); $$.push_back ($2); }
;
item:
TEXT { std::swap ($$, $1); }
| NUMBER { $$ = string_cast ($1); }
TEXT { std::swap ($$, $1); }
| NUMBER { $$ = string_cast ($1); }
;
%%
@@ -114,7 +114,7 @@ namespace yy
{
static int stage = -1;
++stage;
parser::location_type loc(0, stage + 1, stage + 1);
parser::location_type loc(YY_NULLPTR, stage + 1, stage + 1);
switch (stage)
{
case 0:
+1 -1
Submodule gnulib updated: 0d10473be6...a05181f4bd
-3
View File
@@ -36,7 +36,6 @@
/closeout.h
/concat-filename.c
/concat-filename.h
/config.charset
/config.h
/config.in.h
/configmake.h
@@ -159,9 +158,7 @@
/rawmemchr.valgrind
/realloc.c
/ref-add.sed
/ref-add.sin
/ref-del.sed
/ref-del.sin
/sched.h
/sched.in.h
/sig-handler.c
+2 -2
View File
@@ -146,7 +146,7 @@ abitset_list_reverse (bitset src, bitset_bindex *list,
bitset_bindex rbitno;
bitset_bindex count;
bitset_windex windex;
unsigned int bitcnt;
unsigned bitcnt;
bitset_bindex bitoff;
bitset_word *srcp = ABITSET_WORDS (src);
bitset_bindex n_bits = BITSET_SIZE_ (src);
@@ -302,7 +302,7 @@ abitset_list (bitset src, bitset_bindex *list,
static inline void
abitset_unused_clear (bitset dst)
{
unsigned int last_bit;
unsigned last_bit;
last_bit = BITSET_SIZE_ (dst) % BITSET_WORD_BITS;
if (last_bit)
+2 -2
View File
@@ -50,8 +50,8 @@ extern const char * const bitset_type_names[];
enum bitset_alloc_type {BITSET_MALLOC, BITSET_OBALLOC};
/* Data type used to store a word of bits. */
typedef unsigned long int bitset_word;
#define BITSET_WORD_BITS ((unsigned int) (CHAR_BIT * sizeof (bitset_word)))
typedef unsigned long bitset_word;
#define BITSET_WORD_BITS ((unsigned) (CHAR_BIT * sizeof (bitset_word)))
/* Bit index. In theory we might need a type wider than size_t, but
in practice we lose at most a factor of CHAR_BIT by going with
+5 -5
View File
@@ -101,7 +101,7 @@ bitset_init (bitset bset, bitset_bindex n_bits, enum bitset_type type)
specified by ATTR. For variable size bitsets, N_BITS is only a
hint and may be zero. */
enum bitset_type
bitset_type_choose (bitset_bindex n_bits ATTRIBUTE_UNUSED, unsigned int attr)
bitset_type_choose (bitset_bindex n_bits ATTRIBUTE_UNUSED, unsigned attr)
{
/* Check attributes. */
if (attr & BITSET_FIXED && attr & BITSET_VARIABLE)
@@ -169,7 +169,7 @@ bitset_obstack_alloc (struct obstack *bobstack,
/* Create a bitset of N_BITS and with attribute hints specified by
ATTR. */
bitset
bitset_create (bitset_bindex n_bits, unsigned int attr)
bitset_create (bitset_bindex n_bits, unsigned attr)
{
enum bitset_type type;
@@ -291,13 +291,13 @@ bitset_only_set_p (bitset src, bitset_bindex bitno)
static void
bitset_print (FILE *file, bitset bset, bool verbose)
{
unsigned int pos;
unsigned pos;
bitset_bindex i;
bitset_iterator iter;
if (verbose)
fprintf (file, "n_bits = %lu, set = {",
(unsigned long int) bitset_size (bset));
(unsigned long) bitset_size (bset));
pos = 30;
BITSET_FOR_EACH (iter, bset, i, 0)
@@ -308,7 +308,7 @@ bitset_print (FILE *file, bitset bset, bool verbose)
pos = 0;
}
fprintf (file, "%lu ", (unsigned long int) i);
fprintf (file, "%lu ", (unsigned long) i);
pos += 1 + (i >= 10) + (i >= 100);
};
+3 -3
View File
@@ -40,7 +40,7 @@ enum bitset_attr {BITSET_FIXED = 1, /* Bitset size fixed. */
BITSET_FRUGAL = 16, /* Prefer most compact. */
BITSET_GREEDY = 32}; /* Prefer fastest at memory expense. */
typedef unsigned int bitset_attrs;
typedef unsigned bitset_attrs;
/* The contents of the union should be considered to be private.
While I would like to make this union opaque, it needs to be
@@ -310,7 +310,7 @@ extern void bitset_dump (FILE *, bitset);
BITSET_FOR_EACH (iter, src, i, 0)
{
printf ("%lu ", (unsigned long int) i);
printf ("%lu ", (unsigned long) i);
};
*/
#define BITSET_FOR_EACH(ITER, BSET, INDEX, MIN) \
@@ -332,7 +332,7 @@ extern void bitset_dump (FILE *, bitset);
BITSET_FOR_EACH_REVERSE (iter, src, i, 0)
{
printf ("%lu ", (unsigned long int) i);
printf ("%lu ", (unsigned long) i);
};
*/
#define BITSET_FOR_EACH_REVERSE(ITER, BSET, INDEX, MIN) \
+22 -22
View File
@@ -77,23 +77,23 @@
struct bitset_type_info_struct
{
unsigned int allocs;
unsigned int frees;
unsigned int lists;
unsigned int sets;
unsigned int cache_sets;
unsigned int resets;
unsigned int cache_resets;
unsigned int tests;
unsigned int cache_tests;
unsigned int list_counts[BITSET_LOG_COUNT_BINS];
unsigned int list_sizes[BITSET_LOG_SIZE_BINS];
unsigned int list_density[BITSET_DENSITY_BINS];
unsigned allocs;
unsigned frees;
unsigned lists;
unsigned sets;
unsigned cache_sets;
unsigned resets;
unsigned cache_resets;
unsigned tests;
unsigned cache_tests;
unsigned list_counts[BITSET_LOG_COUNT_BINS];
unsigned list_sizes[BITSET_LOG_SIZE_BINS];
unsigned list_density[BITSET_DENSITY_BINS];
};
struct bitset_stats_info_struct
{
unsigned int runs;
unsigned runs;
struct bitset_type_info_struct types[BITSET_TYPE_NUM];
};
@@ -106,10 +106,10 @@ bool bitset_stats_enabled = false;
/* Print a percentage histogram with message MSG to FILE. */
static void
bitset_percent_histogram_print (FILE *file, const char *name, const char *msg,
unsigned int n_bins, unsigned int *bins)
unsigned n_bins, unsigned *bins)
{
unsigned int i;
unsigned int total;
unsigned i;
unsigned total;
total = 0;
for (i = 0; i < n_bins; i++)
@@ -130,11 +130,11 @@ bitset_percent_histogram_print (FILE *file, const char *name, const char *msg,
/* Print a log histogram with message MSG to FILE. */
static void
bitset_log_histogram_print (FILE *file, const char *name, const char *msg,
unsigned int n_bins, unsigned int *bins)
unsigned n_bins, unsigned *bins)
{
unsigned int i;
unsigned int total;
unsigned int max_width;
unsigned i;
unsigned total;
unsigned max_width;
total = 0;
for (i = 0; i < n_bins; i++)
@@ -149,7 +149,7 @@ bitset_log_histogram_print (FILE *file, const char *name, const char *msg,
n_bins = i;
/* 2 * ceil (log10 (2) * (N - 1)) + 1. */
max_width = 2 * (unsigned int) (0.30103 * (n_bins - 1) + 0.9999) + 1;
max_width = 2 * (unsigned) (0.30103 * (n_bins - 1) + 0.9999) + 1;
fprintf (file, "%s %s", name, msg);
for (i = 0; i < 2; i++)
@@ -158,7 +158,7 @@ bitset_log_histogram_print (FILE *file, const char *name, const char *msg,
for (; i < n_bins; i++)
fprintf (file, "%*lu-%lu\t%8u (%5.1f%%)\n",
max_width - ((unsigned int) (0.30103 * (i) + 0.9999) + 1),
max_width - ((unsigned) (0.30103 * (i) + 0.9999) + 1),
1UL << (i - 1),
(1UL << i) - 1,
bins[i],
+1 -1
View File
@@ -54,7 +54,7 @@ bitsetv_matrix_dump (FILE * out, const char *title, bitsetv bset)
/* Contents. */
for (i = 0; bset[i]; ++i)
{
fprintf (out, "%2lu|", (unsigned long int) i);
fprintf (out, "%2lu|", (unsigned long) i);
for (j = 0; j < hsize; ++j)
fputs (bitset_test (bset[i], j) ? "1" : " ", out);
fputs ("|\n", out);
+3 -3
View File
@@ -62,7 +62,7 @@ bitsetv_alloc (bitset_bindex n_vecs, bitset_bindex n_bits,
/* Create a vector of N_VECS bitsets, each of N_BITS, and with
attribute hints specified by ATTR. */
bitset *
bitsetv_create (bitset_bindex n_vecs, bitset_bindex n_bits, unsigned int attr)
bitsetv_create (bitset_bindex n_vecs, bitset_bindex n_bits, unsigned attr)
{
enum bitset_type type;
@@ -146,7 +146,7 @@ bitsetv_dump (FILE *file, char const *title, char const *subtitle,
fprintf (file, "%s\n", title);
for (i = 0; bsetv[i]; i++)
{
fprintf (file, "%s %lu\n", subtitle, (unsigned long int) i);
fprintf (file, "%s %lu\n", subtitle, (unsigned long) i);
bitset_dump (file, bsetv[i]);
}
@@ -161,7 +161,7 @@ debug_bitsetv (bitsetv bsetv)
for (i = 0; bsetv[i]; i++)
{
fprintf (stderr, "%lu: ", (unsigned long int) i);
fprintf (stderr, "%lu: ", (unsigned long) i);
debug_bitset (bsetv[i]);
}
+1 -1
View File
@@ -31,7 +31,7 @@ extern bitsetv bitsetv_alloc (bitset_bindex, bitset_bindex, enum bitset_type);
/* Create a vector of N_VECS bitsets, each of N_BITS, and with
attribute hints specified by ATTR. */
extern bitsetv bitsetv_create (bitset_bindex, bitset_bindex, unsigned int);
extern bitsetv bitsetv_create (bitset_bindex, bitset_bindex, unsigned);
/* Free vector of bitsets. */
extern void bitsetv_free (bitsetv);
+8 -8
View File
@@ -52,7 +52,7 @@
/* Number of bits stored in each element. */
#define EBITSET_ELT_BITS \
((unsigned int) (EBITSET_ELT_WORDS * BITSET_WORD_BITS))
((unsigned) (EBITSET_ELT_WORDS * BITSET_WORD_BITS))
/* Ebitset element. We use an array of bits. */
typedef struct ebitset_elt_struct
@@ -433,7 +433,7 @@ ebitset_equal_p (bitset dst, bitset src)
for (j = 0; j < EBITSET_SIZE (src); j++)
{
unsigned int i;
unsigned i;
ebitset_elt *selt = selts[j];
ebitset_elt *delt = delts[j];
@@ -570,7 +570,7 @@ ebitset_list_reverse (bitset bset, bitset_bindex *list,
bitset_bindex n_bits;
bitset_bindex bitno;
bitset_bindex rbitno;
unsigned int bcount;
unsigned bcount;
bitset_bindex boffset;
bitset_windex windex;
bitset_windex eindex;
@@ -836,7 +836,7 @@ ebitset_list (bitset bset, bitset_bindex *list,
static inline void
ebitset_unused_clear (bitset dst)
{
unsigned int last_bit;
unsigned last_bit;
bitset_bindex n_bits;
n_bits = BITSET_NBITS_ (dst);
@@ -923,7 +923,7 @@ ebitset_empty_p (bitset dst)
static void
ebitset_not (bitset dst, bitset src)
{
unsigned int i;
unsigned i;
ebitset_elt *selt;
ebitset_elt *delt;
bitset_windex j;
@@ -965,7 +965,7 @@ ebitset_subset_p (bitset dst, bitset src)
for (j = 0; j < ssize; j++)
{
unsigned int i;
unsigned i;
ebitset_elt *selt;
ebitset_elt *delt;
@@ -1007,7 +1007,7 @@ ebitset_disjoint_p (bitset dst, bitset src)
for (j = 0; j < ssize; j++)
{
unsigned int i;
unsigned i;
ebitset_elt *selt;
ebitset_elt *delt;
@@ -1040,7 +1040,7 @@ ebitset_op3_cmp (bitset dst, bitset src1, bitset src2, enum bitset_ops op)
bitset_word *srcp2;
bitset_word *dstp;
bool changed = false;
unsigned int i;
unsigned i;
bitset_windex j;
ebitset_resize (dst, max (BITSET_NBITS_ (src1), BITSET_NBITS_ (src2)));
+10 -10
View File
@@ -54,7 +54,7 @@ typedef bitset_word lbitset_word;
/* Number of bits stored in each element. */
#define LBITSET_ELT_BITS \
((unsigned int) (LBITSET_ELT_WORDS * LBITSET_WORD_BITS))
((unsigned) (LBITSET_ELT_WORDS * LBITSET_WORD_BITS))
/* Lbitset element. We use an array of bits for each element.
These are linked together in a doubly-linked list. */
@@ -571,7 +571,7 @@ lbitset_list_reverse (bitset bset, bitset_bindex *list,
{
bitset_bindex rbitno;
bitset_bindex bitno;
unsigned int bcount;
unsigned bcount;
bitset_bindex boffset;
bitset_windex windex;
bitset_bindex count;
@@ -883,7 +883,7 @@ lbitset_empty_p (bitset dst)
static inline void
lbitset_unused_clear (bitset dst)
{
unsigned int last_bit;
unsigned last_bit;
bitset_bindex n_bits;
n_bits = BITSET_SIZE_ (dst);
@@ -939,7 +939,7 @@ lbitset_not (bitset dst, bitset src)
lbitset_elt *selt;
lbitset_elt *delt;
bitset_windex i;
unsigned int j;
unsigned j;
bitset_windex windex;
windex = (BITSET_SIZE_ (dst) + BITSET_WORD_BITS - 1) / BITSET_WORD_BITS;
@@ -966,7 +966,7 @@ lbitset_subset_p (bitset dst, bitset src)
{
lbitset_elt *selt;
lbitset_elt *delt;
unsigned int j;
unsigned j;
for (selt = LBITSET_HEAD (src), delt = LBITSET_HEAD (dst);
selt || delt; selt = selt->next, delt = delt->next)
@@ -1003,7 +1003,7 @@ lbitset_disjoint_p (bitset dst, bitset src)
{
lbitset_elt *selt;
lbitset_elt *delt;
unsigned int j;
unsigned j;
for (selt = LBITSET_HEAD (src), delt = LBITSET_HEAD (dst);
selt && delt; selt = selt->next, delt = delt->next)
@@ -1049,7 +1049,7 @@ lbitset_op3_cmp (bitset dst, bitset src1, bitset src2, enum bitset_ops op)
bitset_word *srcp2;
bitset_word *dstp;
bool changed = false;
unsigned int i;
unsigned i;
LBITSET_HEAD (dst) = 0;
dst->b.csize = 0;
@@ -1376,17 +1376,17 @@ void
debug_lbitset (bitset bset)
{
lbitset_elt *elt;
unsigned int i;
unsigned i;
if (!bset)
return;
for (elt = LBITSET_HEAD (bset); elt; elt = elt->next)
{
fprintf (stderr, "Elt %lu\n", (unsigned long int) elt->index);
fprintf (stderr, "Elt %lu\n", (unsigned long) elt->index);
for (i = 0; i < LBITSET_ELT_WORDS; i++)
{
unsigned int j;
unsigned j;
bitset_word word;
word = elt->words[i];
+2 -2
View File
@@ -448,7 +448,7 @@ timevar_print (fp)
{
/* Only print stuff if we have some sort of time information. */
#if defined HAVE_USER_TIME || defined HAVE_SYS_TIME || defined HAVE_WALL_TIME
unsigned int /* timevar_id_t */ id;
unsigned /* timevar_id_t */ id;
struct timevar_time_def *total = &timevars[TV_TOTAL].elapsed;
struct timevar_time_def now;
@@ -473,7 +473,7 @@ timevar_print (fp)
start_time = now;
fputs (_("\nExecution times (seconds)\n"), fp);
for (id = 0; id < (unsigned int) TIMEVAR_LAST; ++id)
for (id = 0; id < (unsigned) TIMEVAR_LAST; ++id)
{
struct timevar_def *tv = &timevars[(timevar_id_t) id];
const float tiny = 5e-3;
+23 -23
View File
@@ -170,7 +170,7 @@ vbitset_list_reverse (src, list, num, next)
bitset_bindex rbitno;
bitset_bindex count;
bitset_windex windex;
unsigned int bitcnt;
unsigned bitcnt;
bitset_bindex bitoff;
bitset_word *srcp = VBITSET_WORDS (src);
bitset_bindex n_bits = BITSET_SIZE_ (src);
@@ -330,7 +330,7 @@ static inline void
vbitset_unused_clear (dst)
bitset dst;
{
unsigned int last_bit;
unsigned last_bit;
last_bit = BITSET_SIZE_ (dst) % BITSET_WORD_BITS;
if (last_bit)
@@ -343,7 +343,7 @@ static void
vbitset_ones (bitset dst)
{
bitset_word *dstp = VBITSET_WORDS (dst);
unsigned int bytes;
unsigned bytes;
bytes = sizeof (bitset_word) * VBITSET_SIZE (dst);
@@ -356,7 +356,7 @@ static void
vbitset_zero (bitset dst)
{
bitset_word *dstp = VBITSET_WORDS (dst);
unsigned int bytes;
unsigned bytes;
bytes = sizeof (bitset_word) * VBITSET_SIZE (dst);
@@ -367,7 +367,7 @@ vbitset_zero (bitset dst)
static bool
vbitset_empty_p (bitset dst)
{
unsigned int i;
unsigned i;
bitset_word *dstp = VBITSET_WORDS (dst);
for (i = 0; i < VBITSET_SIZE (dst); i++)
@@ -406,7 +406,7 @@ vbitset_copy1 (bitset dst, bitset src)
static void
vbitset_not (bitset dst, bitset src)
{
unsigned int i;
unsigned i;
bitset_word *srcp;
bitset_word *dstp;
bitset_windex ssize;
@@ -431,7 +431,7 @@ vbitset_not (bitset dst, bitset src)
static bool
vbitset_equal_p (bitset dst, bitset src)
{
unsigned int i;
unsigned i;
bitset_word *srcp = VBITSET_WORDS (src);
bitset_word *dstp = VBITSET_WORDS (dst);
bitset_windex ssize = VBITSET_SIZE (src);
@@ -461,7 +461,7 @@ vbitset_equal_p (bitset dst, bitset src)
static bool
vbitset_subset_p (bitset dst, bitset src)
{
unsigned int i;
unsigned i;
bitset_word *srcp = VBITSET_WORDS (src);
bitset_word *dstp = VBITSET_WORDS (dst);
bitset_windex ssize = VBITSET_SIZE (src);
@@ -485,7 +485,7 @@ vbitset_subset_p (bitset dst, bitset src)
static bool
vbitset_disjoint_p (bitset dst, bitset src)
{
unsigned int i;
unsigned i;
bitset_word *srcp = VBITSET_WORDS (src);
bitset_word *dstp = VBITSET_WORDS (dst);
bitset_windex ssize = VBITSET_SIZE (src);
@@ -502,7 +502,7 @@ vbitset_disjoint_p (bitset dst, bitset src)
static void
vbitset_and (bitset dst, bitset src1, bitset src2)
{
unsigned int i;
unsigned i;
bitset_word *src1p;
bitset_word *src2p;
bitset_word *dstp;
@@ -529,7 +529,7 @@ vbitset_and (bitset dst, bitset src1, bitset src2)
static bool
vbitset_and_cmp (bitset dst, bitset src1, bitset src2)
{
unsigned int i;
unsigned i;
int changed = 0;
bitset_word *src1p;
bitset_word *src2p;
@@ -582,7 +582,7 @@ vbitset_and_cmp (bitset dst, bitset src1, bitset src2)
static void
vbitset_andn (bitset dst, bitset src1, bitset src2)
{
unsigned int i;
unsigned i;
bitset_word *src1p;
bitset_word *src2p;
bitset_word *dstp;
@@ -622,7 +622,7 @@ vbitset_andn (bitset dst, bitset src1, bitset src2)
static bool
vbitset_andn_cmp (bitset dst, bitset src1, bitset src2)
{
unsigned int i;
unsigned i;
int changed = 0;
bitset_word *src1p;
bitset_word *src2p;
@@ -687,7 +687,7 @@ vbitset_andn_cmp (bitset dst, bitset src1, bitset src2)
static void
vbitset_or (bitset dst, bitset src1, bitset src2)
{
unsigned int i;
unsigned i;
bitset_word *src1p;
bitset_word *src2p;
bitset_word *dstp;
@@ -723,7 +723,7 @@ vbitset_or (bitset dst, bitset src1, bitset src2)
static bool
vbitset_or_cmp (bitset dst, bitset src1, bitset src2)
{
unsigned int i;
unsigned i;
int changed = 0;
bitset_word *src1p;
bitset_word *src2p;
@@ -778,7 +778,7 @@ vbitset_or_cmp (bitset dst, bitset src1, bitset src2)
static void
vbitset_xor (bitset dst, bitset src1, bitset src2)
{
unsigned int i;
unsigned i;
bitset_word *src1p;
bitset_word *src2p;
bitset_word *dstp;
@@ -814,7 +814,7 @@ vbitset_xor (bitset dst, bitset src1, bitset src2)
static bool
vbitset_xor_cmp (bitset dst, bitset src1, bitset src2)
{
unsigned int i;
unsigned i;
int changed = 0;
bitset_word *src1p;
bitset_word *src2p;
@@ -872,7 +872,7 @@ vbitset_xor_cmp (bitset dst, bitset src1, bitset src2)
static void
vbitset_and_or (bitset dst, bitset src1, bitset src2, bitset src3)
{
unsigned int i;
unsigned i;
bitset_word *src1p;
bitset_word *src2p;
bitset_word *src3p;
@@ -902,7 +902,7 @@ vbitset_and_or (bitset dst, bitset src1, bitset src2, bitset src3)
static bool
vbitset_and_or_cmp (bitset dst, bitset src1, bitset src2, bitset src3)
{
unsigned int i;
unsigned i;
int changed = 0;
bitset_word *src1p;
bitset_word *src2p;
@@ -939,7 +939,7 @@ vbitset_and_or_cmp (bitset dst, bitset src1, bitset src2, bitset src3)
static void
vbitset_andn_or (bitset dst, bitset src1, bitset src2, bitset src3)
{
unsigned int i;
unsigned i;
bitset_word *src1p;
bitset_word *src2p;
bitset_word *src3p;
@@ -969,7 +969,7 @@ vbitset_andn_or (bitset dst, bitset src1, bitset src2, bitset src3)
static bool
vbitset_andn_or_cmp (bitset dst, bitset src1, bitset src2, bitset src3)
{
unsigned int i;
unsigned i;
int changed = 0;
bitset_word *src1p;
bitset_word *src2p;
@@ -1006,7 +1006,7 @@ vbitset_andn_or_cmp (bitset dst, bitset src1, bitset src2, bitset src3)
static void
vbitset_or_and (bitset dst, bitset src1, bitset src2, bitset src3)
{
unsigned int i;
unsigned i;
bitset_word *src1p;
bitset_word *src2p;
bitset_word *src3p;
@@ -1036,7 +1036,7 @@ vbitset_or_and (bitset dst, bitset src1, bitset src2, bitset src3)
static bool
vbitset_or_and_cmp (bitset dst, bitset src1, bitset src2, bitset src3)
{
unsigned int i;
unsigned i;
int changed = 0;
bitset_word *src1p;
bitset_word *src2p;
-1
View File
@@ -46,7 +46,6 @@
/gnulib-common.m4
/gnulib-comp.m4
/gnulib-tool.m4
/hard-locale.m4
/iconv.m4
/include_next.m4
/intdiv0.m4
+3 -3
View File
@@ -34,9 +34,9 @@ AC_DEFUN([BISON_TEST_FOR_WORKING_CXX_COMPILER],
using namespace std;],
[std::cerr << "";
cout << "";
typedef std::pair<unsigned int, int> uipair;
std::map<unsigned int, int> m;
std::map<unsigned int, int>::iterator i;
typedef std::pair<unsigned, int> uipair;
std::map<unsigned, int> m;
std::map<unsigned, int>::iterator i;
m.insert (uipair (4, -4));
for (i = m.begin (); i != m.end (); ++i)
if (i->first != 4)
+10 -9
View File
@@ -242,7 +242,7 @@ AnnotationList__computePredecessorAnnotations (AnnotationList *self, state *s,
{
symbol_number contribution_token =
InadequacyList__getContributionToken (self->inadequacyNode, ci)
->number;
->content->number;
if (AnnotationList__isContributionAlways (self, ci))
{
annotation_node->contributions[ci] = NULL;
@@ -275,7 +275,7 @@ AnnotationList__computePredecessorAnnotations (AnnotationList *self, state *s,
- 2]))
{
Sbitset items;
unsigned int rulei;
unsigned rulei;
for (rulei = s->items[self_item];
!item_number_is_rule_number (ritem[rulei]);
++rulei)
@@ -553,7 +553,7 @@ AnnotationList__compute_from_inadequacies (
does discard annotations in the simplest case of a S/R
conflict with no token precedence. */
aver (!bitset_test (shift_tokens, conflicted_token)
|| symbols[conflicted_token]->prec);
|| symbols[conflicted_token]->content->prec);
++annotation_counts[s->number];
if (contribution_count > *max_contributionsp)
*max_contributionsp = contribution_count;
@@ -599,7 +599,7 @@ AnnotationList__debug (AnnotationList const *self, size_t nitems, int spaces)
{
symbol_number token =
InadequacyList__getContributionToken (a->inadequacyNode, ci)
->number;
->content->number;
{
int j;
for (j = 0; j < spaces+2; ++j)
@@ -648,7 +648,7 @@ AnnotationList__computeLookaheadFilter (AnnotationList const *self,
Sbitset biter;
symbol_number token =
InadequacyList__getContributionToken (self->inadequacyNode, ci)
->number;
->content->number;
SBITSET__FOR_EACH (self->contributions[ci], nitems, biter, item)
bitset_set (lookahead_filter[item], token);
}
@@ -683,7 +683,8 @@ AnnotationList__stateMakesContribution (AnnotationList const *self,
return false;
{
symbol_number token =
InadequacyList__getContributionToken (self->inadequacyNode, ci)->number;
InadequacyList__getContributionToken (self->inadequacyNode, ci)
->content->number;
Sbitset__Index item;
Sbitset biter;
SBITSET__FOR_EACH (self->contributions[ci], nitems, biter, item)
@@ -713,7 +714,7 @@ AnnotationList__computeDominantContribution (AnnotationList const *self,
ContributionIndex ci;
int actioni;
ContributionIndex ci_rr_dominator = ContributionIndex__none;
int shift_precedence = token->prec;
int shift_precedence = token->content->prec;
/* If the token has no precedence set, shift is always chosen. */
if (!shift_precedence)
@@ -743,7 +744,7 @@ AnnotationList__computeDominantContribution (AnnotationList const *self,
if (reduce_precedence
&& (reduce_precedence < shift_precedence
|| (reduce_precedence == shift_precedence
&& token->assoc == right_assoc)))
&& token->content->assoc == right_assoc)))
continue;
if (!AnnotationList__stateMakesContribution (self, nitems, ci,
lookaheads))
@@ -751,7 +752,7 @@ AnnotationList__computeDominantContribution (AnnotationList const *self,
/* This uneliminated reduction contributes, so see if it can cause
an error action. */
if (reduce_precedence == shift_precedence
&& token->assoc == non_assoc)
&& token->content->assoc == non_assoc)
{
/* It's not possible to find split-stable domination over
shift after a potential %nonassoc. */
+1 -1
View File
@@ -25,7 +25,7 @@
# include "InadequacyList.h"
# include "state.h"
typedef unsigned int AnnotationIndex;
typedef unsigned AnnotationIndex;
/**
* A node in a list of annotations on a particular LR(0) state. Each
+1 -1
View File
@@ -31,7 +31,7 @@
* This must remain unsigned so that the overflow check in
* \c InadequacyList__new_conflict works properly.
*/
typedef unsigned long long int InadequacyListNodeCount;
typedef unsigned long long InadequacyListNodeCount;
/**
* For a conflict, each rule in the grammar can have at most one contributing
+20 -33
View File
@@ -54,12 +54,11 @@ static bitsetv firsts = NULL;
static void
print_closure (char const *title, item_number const *array, size_t size)
{
size_t i;
fprintf (stderr, "Closure: %s\n", title);
for (i = 0; i < size; ++i)
for (size_t i = 0; i < size; ++i)
{
item_number *rp;
fprintf (stderr, " %2d: .", array[i]);
item_number *rp;
for (rp = &ritem[array[i]]; *rp >= 0; ++rp)
fprintf (stderr, " %s", symbols[*rp]->tag);
fprintf (stderr, " (rule %d)\n", -*rp - 1);
@@ -71,13 +70,12 @@ print_closure (char const *title, item_number const *array, size_t size)
static void
print_firsts (void)
{
symbol_number i, j;
fprintf (stderr, "FIRSTS\n");
for (i = ntokens; i < nsyms; i++)
for (symbol_number i = ntokens; i < nsyms; ++i)
{
bitset_iterator iter;
fprintf (stderr, " %s firsts\n", symbols[i]->tag);
bitset_iterator iter;
symbol_number j;
BITSET_FOR_EACH (iter, FIRSTS (i), j, 0)
fprintf (stderr, " %s\n", symbols[j + ntokens]->tag);
}
@@ -88,14 +86,12 @@ print_firsts (void)
static void
print_fderives (void)
{
int i;
rule_number r;
fprintf (stderr, "FDERIVES\n");
for (i = ntokens; i < nsyms; i++)
for (symbol_number i = ntokens; i < nsyms; ++i)
{
bitset_iterator iter;
fprintf (stderr, " %s derives\n", symbols[i]->tag);
bitset_iterator iter;
rule_number r;
BITSET_FOR_EACH (iter, FDERIVES (i), r, 0)
{
fprintf (stderr, " %3d ", r);
@@ -120,12 +116,10 @@ print_fderives (void)
static void
set_firsts (void)
{
symbol_number i, j;
firsts = bitsetv_create (nvars, nvars, BITSET_FIXED);
for (i = ntokens; i < nsyms; i++)
for (j = 0; derives[i - ntokens][j]; ++j)
for (symbol_number i = ntokens; i < nsyms; ++i)
for (symbol_number j = 0; derives[i - ntokens][j]; ++j)
{
item_number sym = derives[i - ntokens][j]->rhs[0];
if (ISVAR (sym))
@@ -155,17 +149,14 @@ set_firsts (void)
static void
set_fderives (void)
{
symbol_number i, j;
rule_number k;
fderives = bitsetv_create (nvars, nrules, BITSET_FIXED);
set_firsts ();
for (i = ntokens; i < nsyms; ++i)
for (j = ntokens; j < nsyms; ++j)
for (symbol_number i = ntokens; i < nsyms; ++i)
for (symbol_number j = ntokens; j < nsyms; ++j)
if (bitset_test (FIRSTS (i), j - ntokens))
for (k = 0; derives[j - ntokens][k]; ++k)
for (rule_number k = 0; derives[j - ntokens][k]; ++k)
bitset_set (FDERIVES (i), derives[j - ntokens][k]->number);
if (trace_flag & trace_sets)
@@ -177,7 +168,7 @@ set_fderives (void)
void
new_closure (unsigned int n)
new_closure (unsigned n)
{
itemset = xnmalloc (n, sizeof *itemset);
@@ -191,27 +182,23 @@ new_closure (unsigned int n)
void
closure (item_number const *core, size_t n)
{
/* Index over CORE. */
size_t c;
/* A bit index over RULESET. */
rule_number ruleno;
bitset_iterator iter;
if (trace_flag & trace_sets)
print_closure ("input", core, n);
bitset_zero (ruleset);
for (c = 0; c < n; ++c)
for (size_t c = 0; c < n; ++c)
if (ISVAR (ritem[core[c]]))
bitset_or (ruleset, ruleset, FDERIVES (ritem[core[c]]));
/* core is sorted on item index in ritem, which is sorted on rule number.
Compute itemset with the same sort. */
/* A bit index over RULESET. */
rule_number ruleno;
bitset_iterator iter;
nitemset = 0;
c = 0;
size_t c = 0;
BITSET_FOR_EACH (iter, ruleset, ruleno, 0)
{
item_number itemno = rules[ruleno].rhs - ritem;
+1 -1
View File
@@ -27,7 +27,7 @@
data so that closure can be called. n is the number of elements to
allocate for itemset. */
void new_closure (unsigned int n);
void new_closure (unsigned n);
/* Given the kernel (aka core) of a state (a sorted vector of item numbers
+38 -46
View File
@@ -104,7 +104,7 @@ log_resolution (rule *r, symbol_number token,
case shift_resolution:
obstack_printf (&solved_conflicts_obstack,
" (%s < %s)",
r->prec->tag,
r->prec->symbol->tag,
symbols[token]->tag);
break;
@@ -112,7 +112,7 @@ log_resolution (rule *r, symbol_number token,
obstack_printf (&solved_conflicts_obstack,
" (%s < %s)",
symbols[token]->tag,
r->prec->tag);
r->prec->symbol->tag);
break;
case left_resolution:
@@ -176,7 +176,7 @@ log_resolution (rule *r, symbol_number token,
case shift_resolution:
obstack_printf (&solved_conflicts_xml_obstack,
"%s &lt; %s",
xml_escape_n (0, r->prec->tag),
xml_escape_n (0, r->prec->symbol->tag),
xml_escape_n (1, symbols[token]->tag));
break;
@@ -184,7 +184,7 @@ log_resolution (rule *r, symbol_number token,
obstack_printf (&solved_conflicts_xml_obstack,
"%s &lt; %s",
xml_escape_n (0, symbols[token]->tag),
xml_escape_n (1, r->prec->tag));
xml_escape_n (1, r->prec->symbol->tag));
break;
case left_resolution:
@@ -221,10 +221,9 @@ static void
flush_shift (state *s, int token)
{
transitions *trans = s->transitions;
int i;
bitset_reset (lookahead_set, token);
for (i = 0; i < trans->num; i++)
for (int i = 0; i < trans->num; ++i)
if (!TRANSITION_IS_DISABLED (trans, i)
&& TRANSITION_SYMBOL (trans, i) == token)
TRANSITION_DISABLE (trans, i);
@@ -259,28 +258,27 @@ flush_reduce (bitset lookahead_tokens, int token)
static void
resolve_sr_conflict (state *s, int ruleno, symbol **errors, int *nerrs)
{
symbol_number i;
reductions *reds = s->reductions;
/* 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];
for (i = 0; i < ntokens; i++)
for (symbol_number i = 0; i < ntokens; ++i)
if (bitset_test (lookahead_tokens, i)
&& bitset_test (lookahead_set, i)
&& symbols[i]->prec)
&& symbols[i]->content->prec)
{
/* Shift-reduce conflict occurs for token number i
and it has a precedence.
The precedence of shifting is that of token i. */
if (symbols[i]->prec < redprec)
if (symbols[i]->content->prec < redprec)
{
register_precedence (redrule->prec->number, i);
log_resolution (redrule, i, reduce_resolution);
flush_shift (s, i);
}
else if (symbols[i]->prec > redprec)
else if (symbols[i]->content->prec > redprec)
{
register_precedence (i, redrule->prec->number);
log_resolution (redrule, i, shift_resolution);
@@ -294,7 +292,7 @@ resolve_sr_conflict (state *s, int ruleno, symbol **errors, int *nerrs)
For right associativity, keep only the shift.
For nonassociativity, keep neither. */
switch (symbols[i]->assoc)
switch (symbols[i]->content->assoc)
{
case undef_assoc:
abort ();
@@ -337,33 +335,34 @@ resolve_sr_conflict (state *s, int ruleno, symbol **errors, int *nerrs)
static void
set_conflicts (state *s, symbol **errors)
{
int i;
transitions *trans = s->transitions;
reductions *reds = s->reductions;
int nerrs = 0;
if (s->consistent)
return;
reductions *reds = s->reductions;
int nerrs = 0;
bitset_zero (lookahead_set);
FOR_EACH_SHIFT (trans, i)
bitset_set (lookahead_set, TRANSITION_SYMBOL (trans, i));
{
transitions *trans = s->transitions;
int i;
FOR_EACH_SHIFT (trans, i)
bitset_set (lookahead_set, TRANSITION_SYMBOL (trans, i));
}
/* Loop over all rules which require lookahead in this state. First
check for shift-reduce conflict, and try to resolve using
precedence. */
for (i = 0; i < reds->num; ++i)
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))
resolve_sr_conflict (s, i, errors, &nerrs);
if (nerrs)
{
/* Some tokens have been explicitly made errors. Allocate a
permanent errs structure for this state, to record them. */
state_errs_set (s, nerrs, errors);
}
/* Some tokens have been explicitly made errors. Allocate a
permanent errs structure for this state, to record them. */
state_errs_set (s, nerrs, errors);
if (obstack_object_size (&solved_conflicts_obstack))
s->solved_conflicts = obstack_finish0 (&solved_conflicts_obstack);
if (obstack_object_size (&solved_conflicts_xml_obstack))
@@ -371,7 +370,7 @@ set_conflicts (state *s, symbol **errors)
/* Loop over all rules which require lookahead in this state. Check
for conflicts not resolved above. */
for (i = 0; i < reds->num; ++i)
for (int i = 0; i < reds->num; ++i)
{
if (!bitset_disjoint_p (reds->lookahead_tokens[i], lookahead_set))
conflicts[s->number] = 1;
@@ -388,7 +387,6 @@ set_conflicts (state *s, symbol **errors)
void
conflicts_solve (void)
{
state_number i;
/* List of lookahead tokens on which we explicitly raise a syntax error. */
symbol **errors = xnmalloc (ntokens + 1, sizeof *errors);
@@ -398,7 +396,7 @@ conflicts_solve (void)
obstack_init (&solved_conflicts_obstack);
obstack_init (&solved_conflicts_xml_obstack);
for (i = 0; i < nstates; i++)
for (state_number i = 0; i < nstates; ++i)
{
set_conflicts (states[i], errors);
@@ -416,8 +414,7 @@ void
conflicts_update_state_numbers (state_number old_to_new[],
state_number nstates_old)
{
state_number i;
for (i = 0; i < nstates_old; ++i)
for (state_number i = 0; i < nstates_old; ++i)
if (old_to_new[i] != nstates_old)
conflicts[old_to_new[i]] = conflicts[i];
}
@@ -430,7 +427,6 @@ conflicts_update_state_numbers (state_number old_to_new[],
static size_t
count_state_sr_conflicts (state *s)
{
int i;
transitions *trans = s->transitions;
reductions *reds = s->reductions;
@@ -440,10 +436,13 @@ count_state_sr_conflicts (state *s)
bitset_zero (lookahead_set);
bitset_zero (shift_set);
FOR_EACH_SHIFT (trans, i)
bitset_set (shift_set, TRANSITION_SYMBOL (trans, i));
{
int i;
FOR_EACH_SHIFT (trans, i)
bitset_set (shift_set, TRANSITION_SYMBOL (trans, i));
}
for (i = 0; i < reds->num; ++i)
for (int i = 0; i < reds->num; ++i)
bitset_or (lookahead_set, lookahead_set, reds->lookahead_tokens[i]);
bitset_and (lookahead_set, lookahead_set, shift_set);
@@ -459,10 +458,8 @@ static size_t
count_sr_conflicts (void)
{
size_t res = 0;
state_number i;
/* Conflicts by state. */
for (i = 0; i < nstates; i++)
for (state_number i = 0; i < nstates; ++i)
if (conflicts[i])
res += count_state_sr_conflicts (states[i]);
return res;
@@ -480,15 +477,13 @@ count_sr_conflicts (void)
static size_t
count_state_rr_conflicts (state *s, bool one_per_token)
{
int i;
reductions *reds = s->reductions;
size_t res = 0;
for (i = 0; i < ntokens; i++)
for (symbol_number i = 0; i < ntokens; ++i)
{
int count = 0;
int j;
for (j = 0; j < reds->num; ++j)
for (int j = 0; j < reds->num; ++j)
count += bitset_test (reds->lookahead_tokens[j], i);
if (count >= 2)
res += one_per_token ? 1 : count-1;
@@ -501,10 +496,8 @@ static size_t
count_rr_conflicts (bool one_per_token)
{
size_t res = 0;
state_number i;
/* Conflicts by state. */
for (i = 0; i < nstates; i++)
for (state_number i = 0; i < nstates; ++i)
if (conflicts[i])
res += count_state_rr_conflicts (states[i], one_per_token);
return res;
@@ -519,8 +512,7 @@ void
conflicts_output (FILE *out)
{
bool printed_sth = false;
state_number i;
for (i = 0; i < nstates; i++)
for (state_number i = 0; i < nstates; ++i)
{
state *s = states[i];
if (conflicts[i])
+14
View File
@@ -44,6 +44,20 @@ int FLEX_PREFIX (lex_destroy) (void);
#define last_string FLEX_PREFIX (last_string)
// Pacify warnings in yy_init_buffer (observed with Flex 2.6.4 and GCC
// 7.3.0).
//
// ./src/scan-skel.c: In function 'skel_restart':
// ./src/scan-skel.c:2035:20: error: potential null pointer dereference [-Werror=null-dereference]
// b->yy_fill_buffer = 1;
// ~~~~~~~~~~~~~~~~~~^~~
// ./src/scan-skel.c:2031:19: error: potential null pointer dereference [-Werror=null-dereference]
// b->yy_input_file = file;
// ~~~~~~~~~~~~~~~~~^~~~~~
#if defined __GNUC__ && 7 <= __GNUC__
# pragma GCC diagnostic ignored "-Wnull-dereference"
#endif
/* It seems to be a nice "feature" of Flex that one cannot use yytext,
yyleng etc. when a prefix is given, since there is no longer a
#define, but rather the token is actually changed in the output.
+16 -13
View File
@@ -32,7 +32,7 @@
/* Comments for these variables are in gram.h. */
item_number *ritem = NULL;
unsigned int nritems = 0;
unsigned nritems = 0;
rule *rules = NULL;
rule_number nrules = 0;
@@ -65,19 +65,19 @@ rule_useless_in_parser_p (rule const *r)
}
void
rule_lhs_print (rule const *r, symbol const *previous_lhs, FILE *out)
rule_lhs_print (rule const *r, sym_content const *previous_lhs, FILE *out)
{
fprintf (out, " %3d ", r->number);
if (previous_lhs != r->lhs)
fprintf (out, "%s:", r->lhs->tag);
fprintf (out, "%s:", r->lhs->symbol->tag);
else
fprintf (out, "%*s|", (int) strlen (previous_lhs->tag), "");
fprintf (out, "%*s|", (int) strlen (previous_lhs->symbol->tag), "");
}
void
rule_lhs_print_xml (rule const *r, FILE *out, int level)
{
xml_printf (out, level, "<lhs>%s</lhs>", r->lhs->tag);
xml_printf (out, level, "<lhs>%s</lhs>", r->lhs->symbol->tag);
}
size_t
@@ -126,7 +126,7 @@ rule_rhs_print_xml (rule const *r, FILE *out, int level)
void
ritem_print (FILE *out)
{
unsigned int i;
unsigned i;
fputs ("RITEM\n", out);
for (i = 0; i < nritems; ++i)
if (ritem[i] >= 0)
@@ -158,7 +158,7 @@ grammar_rules_partial_print (FILE *out, const char *title,
{
rule_number r;
bool first = true;
symbol *previous_lhs = NULL;
sym_content *previous_lhs = NULL;
/* rule # : LHS -> RHS */
for (r = 0; r < nrules + nuseless_productions; r++)
@@ -209,7 +209,7 @@ grammar_rules_print_xml (FILE *out, int level)
rules[r].number, usefulness);
if (rules[r].precsym)
fprintf (out, " percent_prec=\"%s\"",
xml_escape (rules[r].precsym->tag));
xml_escape (rules[r].precsym->symbol->tag));
fputs (">\n", out);
}
rule_lhs_print_xml (&rules[r], out, level + 3);
@@ -239,7 +239,7 @@ grammar_dump (FILE *out, const char *title)
for (i = ntokens; i < nsyms; i++)
fprintf (out, "%5d %5d %5d %s\n",
i,
symbols[i]->prec, symbols[i]->assoc,
symbols[i]->content->prec, symbols[i]->content->assoc,
symbols[i]->tag);
fprintf (out, "\n\n");
}
@@ -254,8 +254,8 @@ grammar_dump (FILE *out, const char *title)
{
rule const *rule_i = &rules[i];
item_number *rp = NULL;
unsigned int rhs_itemno = rule_i->rhs - ritem;
unsigned int rhs_count = 0;
unsigned rhs_itemno = rule_i->rhs - ritem;
unsigned rhs_count = 0;
/* Find the last RHS index in ritems. */
for (rp = rule_i->rhs; *rp >= 0; ++rp)
++rhs_count;
@@ -280,7 +280,7 @@ grammar_dump (FILE *out, const char *title)
rule_number r;
for (r = 0; r < nrules + nuseless_productions; r++)
{
fprintf (out, "%-5d %s:", r, rules[r].lhs->tag);
fprintf (out, "%-5d %s:", r, rules[r].lhs->symbol->tag);
rule_rhs_print (&rules[r], out);
fprintf (out, "\n");
}
@@ -293,7 +293,10 @@ grammar_rules_useless_report (const char *message)
{
rule_number r;
for (r = 0; r < nrules ; ++r)
if (!rules[r].useful)
/* Don't complain about rules whose LHS is useless, we already
complained about it. */
if (!reduce_nonterminal_useless_in_grammar (rules[r].lhs)
&& !rules[r].useful)
complain (&rules[r].location, Wother, "%s", message);
}
+6 -5
View File
@@ -115,7 +115,7 @@ extern int nvars;
typedef int item_number;
# define ITEM_NUMBER_MAX INT_MAX
extern item_number *ritem;
extern unsigned int nritems;
extern unsigned nritems;
/* There is weird relationship between OT1H item_number and OTOH
symbol_number and rule_number: we store the latter in
@@ -180,17 +180,17 @@ typedef struct
except if some rules are useless. */
rule_number number;
symbol *lhs;
sym_content *lhs;
item_number *rhs;
/* This symbol provides both the associativity, and the precedence. */
symbol *prec;
sym_content *prec;
int dprec;
int merger;
/* This symbol was attached to the rule via %prec. */
symbol *precsym;
sym_content *precsym;
location location;
bool useful;
@@ -220,7 +220,8 @@ bool rule_useless_in_parser_p (rule const *r);
/* Print this rule's number and lhs on OUT. If a PREVIOUS_LHS was
already displayed (by a previous call for another rule), avoid
useless repetitions. */
void rule_lhs_print (rule const *r, symbol const *previous_lhs, FILE *out);
void rule_lhs_print (rule const *r, sym_content const *previous_lhs,
FILE *out);
void rule_lhs_print_xml (rule const *r, FILE *out, int level);
/* Return the length of the RHS. */
+1 -1
View File
@@ -94,7 +94,7 @@ no_reduce_bitset_init (state const *s, bitset *no_reduce_set)
bitset_set (*no_reduce_set, TRANSITION_SYMBOL (s->transitions, n));
for (n = 0; n < s->errs->num; ++n)
if (s->errs->symbols[n])
bitset_set (*no_reduce_set, s->errs->symbols[n]->number);
bitset_set (*no_reduce_set, s->errs->symbols[n]->content->number);
}
static void
+69 -105
View File
@@ -49,7 +49,7 @@ static bitset
ielr_compute_ritem_sees_lookahead_set (void)
{
bitset result = bitset_create (nritems, BITSET_FIXED);
unsigned int i = nritems-1;
unsigned i = nritems-1;
while (i>0)
{
--i;
@@ -101,16 +101,14 @@ ielr_compute_internal_follow_edges (bitset ritem_sees_lookahead_set,
*edge_countsp = xnmalloc (ngotos, sizeof **edge_countsp);
{
bitset sources = bitset_create (ngotos, BITSET_FIXED);
goto_number i;
for (i = 0; i < ngotos; ++i)
for (goto_number i = 0; i < ngotos; ++i)
(*edge_countsp)[i] = 0;
for (i = 0; i < ngotos; ++i)
for (goto_number i = 0; i < ngotos; ++i)
{
int nsources = 0;
{
rule **rulep;
for (rulep = derives[states[to_state[i]]->accessing_symbol
- ntokens];
for (rule **rulep = derives[states[to_state[i]]->accessing_symbol
- ntokens];
*rulep;
++rulep)
{
@@ -198,30 +196,26 @@ ielr_compute_follow_kernel_items (bitset ritem_sees_lookahead_set,
{
{
size_t max_nitems = 0;
state_number i;
for (i = 0; i < nstates; ++i)
for (state_number i = 0; i < nstates; ++i)
if (states[i]->nitems > max_nitems)
max_nitems = states[i]->nitems;
*follow_kernel_itemsp = bitsetv_create (ngotos, max_nitems, BITSET_FIXED);
}
{
goto_number i;
for (i = 0; i < ngotos; ++i)
{
size_t nitems = states[from_state[i]]->nitems;
item_number *items = states[from_state[i]]->items;
size_t j;
for (j = 0; j < nitems; ++j)
/* If this item has this goto and if all subsequent symbols in this
RHS (if any) are nullable nonterminals, then record this item as
one whose lookahead set is included in this goto's follows. */
if (item_number_is_symbol_number (ritem[items[j]])
&& item_number_as_symbol_number (ritem[items[j]])
== states[to_state[i]]->accessing_symbol
&& bitset_test (ritem_sees_lookahead_set, items[j]))
bitset_set ((*follow_kernel_itemsp)[i], j);
}
}
for (goto_number i = 0; i < ngotos; ++i)
{
size_t nitems = states[from_state[i]]->nitems;
item_number *items = states[from_state[i]]->items;
size_t j;
for (j = 0; j < nitems; ++j)
/* If this item has this goto and if all subsequent symbols in this
RHS (if any) are nullable nonterminals, then record this item as
one whose lookahead set is included in this goto's follows. */
if (item_number_is_symbol_number (ritem[items[j]])
&& item_number_as_symbol_number (ritem[items[j]])
== states[to_state[i]]->accessing_symbol
&& bitset_test (ritem_sees_lookahead_set, items[j]))
bitset_set ((*follow_kernel_itemsp)[i], j);
}
relation_digraph (internal_follow_edges, ngotos, follow_kernel_itemsp);
if (trace_flag & trace_ielr)
@@ -252,8 +246,7 @@ ielr_compute_always_follows (goto_number ***edgesp,
*always_followsp = bitsetv_create (ngotos, ntokens, BITSET_FIXED);
{
goto_number *edge_array = xnmalloc (ngotos, sizeof *edge_array);
goto_number i;
for (i = 0; i < ngotos; ++i)
for (goto_number i = 0; i < ngotos; ++i)
{
goto_number nedges = edge_counts[i];
{
@@ -300,32 +293,28 @@ ielr_compute_always_follows (goto_number ***edgesp,
static state ***
ielr_compute_predecessors (void)
{
state_number i;
int *predecessor_counts = xnmalloc (nstates, sizeof *predecessor_counts);
state ***result = xnmalloc (nstates, sizeof *result);
for (i = 0; i < nstates; ++i)
for (state_number i = 0; i < nstates; ++i)
predecessor_counts[i] = 0;
for (i = 0; i < nstates; ++i)
for (state_number i = 0; i < nstates; ++i)
{
int j;
for (j = 0; j < states[i]->transitions->num; ++j)
++predecessor_counts[states[i]->transitions->states[j]->number];
}
for (i = 0; i < nstates; ++i)
for (state_number i = 0; i < nstates; ++i)
{
result[i] = xnmalloc (predecessor_counts[i]+1, sizeof *result[i]);
result[i][predecessor_counts[i]] = NULL;
predecessor_counts[i] = 0;
}
for (i = 0; i < nstates; ++i)
{
int j;
for (j = 0; j < states[i]->transitions->num; ++j)
{
state_number k = states[i]->transitions->states[j]->number;
result[k][predecessor_counts[k]++] = states[i];
}
}
for (state_number i = 0; i < nstates; ++i)
for (int j = 0; j < states[i]->transitions->num; ++j)
{
state_number k = states[i]->transitions->states[j]->number;
result[k][predecessor_counts[k]++] = states[i];
}
free (predecessor_counts);
return result;
}
@@ -354,11 +343,8 @@ ielr_compute_auxiliary_tables (bitsetv *follow_kernel_itemsp,
bitset_free (ritem_sees_lookahead_set);
}
ielr_compute_always_follows (&edges, edge_counts, always_followsp);
{
int i;
for (i = 0; i < ngotos; ++i)
free (edges[i]);
}
for (int i = 0; i < ngotos; ++i)
free (edges[i]);
free (edges);
free (edge_counts);
if (predecessorsp)
@@ -381,10 +367,9 @@ ielr_item_has_lookahead (state *s, symbol_number lhs, size_t item,
{
if (!item_lookahead_sets[s->number])
{
size_t i;
item_lookahead_sets[s->number] =
xnmalloc (s->nitems, sizeof item_lookahead_sets[s->number][0]);
for (i = 0; i < s->nitems; ++i)
for (size_t i = 0; i < s->nitems; ++i)
item_lookahead_sets[s->number][i] = NULL;
}
if (!item_lookahead_sets[s->number][item])
@@ -412,20 +397,19 @@ ielr_item_has_lookahead (state *s, symbol_number lhs, size_t item,
top-level invocation), go get it. */
if (!lhs)
{
unsigned int i;
unsigned i;
for (i = s->items[item];
!item_number_is_rule_number (ritem[i]);
++i)
;
continue;
lhs = rules[item_number_as_rule_number (ritem[i])].lhs->number;
}
/* If this kernel item is next to the beginning of the RHS, then
check all predecessors' goto follows for the LHS. */
if (item_number_is_rule_number (ritem[s->items[item] - 2]))
{
state **predecessor;
aver (lhs != accept->number);
for (predecessor = predecessors[s->number];
aver (lhs != accept->content->number);
for (state **predecessor = predecessors[s->number];
*predecessor;
++predecessor)
bitset_or (item_lookahead_sets[s->number][item],
@@ -437,8 +421,7 @@ ielr_item_has_lookahead (state *s, symbol_number lhs, size_t item,
predecessor items' lookahead sets. */
else
{
state **predecessor;
for (predecessor = predecessors[s->number];
for (state **predecessor = predecessors[s->number];
*predecessor;
++predecessor)
{
@@ -492,12 +475,11 @@ ielr_compute_annotation_lists (bitsetv follow_kernel_items,
AnnotationIndex *annotation_counts =
xnmalloc (nstates, sizeof *annotation_counts);
ContributionIndex max_contributions = 0;
unsigned int total_annotations = 0;
state_number i;
unsigned total_annotations = 0;
*inadequacy_listsp = xnmalloc (nstates, sizeof **inadequacy_listsp);
*annotation_listsp = xnmalloc (nstates, sizeof **annotation_listsp);
for (i = 0; i < nstates; ++i)
for (state_number i = 0; i < nstates; ++i)
{
item_lookahead_sets[i] = NULL;
(*inadequacy_listsp)[i] = NULL;
@@ -506,7 +488,7 @@ ielr_compute_annotation_lists (bitsetv follow_kernel_items,
}
{
InadequacyListNodeCount inadequacy_list_node_count = 0;
for (i = 0; i < nstates; ++i)
for (state_number i = 0; i < nstates; ++i)
AnnotationList__compute_from_inadequacies (
states[i], follow_kernel_items, always_follows, predecessors,
item_lookahead_sets, *inadequacy_listsp, *annotation_listsp,
@@ -514,7 +496,7 @@ ielr_compute_annotation_lists (bitsetv follow_kernel_items,
&inadequacy_list_node_count);
}
*max_annotationsp = 0;
for (i = 0; i < nstates; ++i)
for (state_number i = 0; i < nstates; ++i)
{
if (annotation_counts[i] > *max_annotationsp)
*max_annotationsp = annotation_counts[i];
@@ -522,7 +504,7 @@ ielr_compute_annotation_lists (bitsetv follow_kernel_items,
}
if (trace_flag & trace_ielr)
{
for (i = 0; i < nstates; ++i)
for (state_number i = 0; i < nstates; ++i)
{
fprintf (stderr, "Inadequacy annotations for state %d:\n", i);
AnnotationList__debug ((*annotation_listsp)[i],
@@ -536,11 +518,10 @@ ielr_compute_annotation_lists (bitsetv follow_kernel_items,
fprintf (stderr, "Max number of contributions per annotation: %d\n",
max_contributions);
}
for (i = 0; i < nstates; ++i)
for (state_number i = 0; i < nstates; ++i)
if (item_lookahead_sets[i])
{
size_t j;
for (j = 0; j < states[i]->nitems; ++j)
for (size_t j = 0; j < states[i]->nitems; ++j)
if (item_lookahead_sets[i][j])
bitset_free (item_lookahead_sets[i][j]);
free (item_lookahead_sets[i]);
@@ -580,7 +561,7 @@ typedef struct state_list {
static void
ielr_compute_goto_follow_set (bitsetv follow_kernel_items,
bitsetv always_follows, state_list *s,
symbol *n, bitset follow_set)
sym_content *n, bitset follow_set)
{
goto_number n_goto = map_goto (s->lr0Isocore->state->number, n->number);
bitset_copy (follow_set, always_follows[n_goto]);
@@ -615,9 +596,8 @@ ielr_compute_lookaheads (bitsetv follow_kernel_items, bitsetv always_follows,
bitsetv lookaheads)
{
size_t s_item = 0;
size_t t_item;
bitsetv_zero (lookaheads);
for (t_item = 0; t_item < t->nitems; ++t_item)
for (size_t t_item = 0; t_item < t->nitems; ++t_item)
{
/* If this kernel item is the beginning of a RHS, it must be the
kernel item in the start state, but t is supposed to be a successor
@@ -631,7 +611,7 @@ ielr_compute_lookaheads (bitsetv follow_kernel_items, bitsetv always_follows,
{
if (item_number_is_rule_number (ritem[t->items[t_item] - 2]))
{
unsigned int rule_item;
unsigned rule_item;
for (rule_item = t->items[t_item];
!item_number_is_rule_number (ritem[rule_item]);
++rule_item)
@@ -771,15 +751,12 @@ ielr_compute_state (bitsetv follow_kernel_items, bitsetv always_follows,
}
has_lookaheads = false;
{
size_t i;
for (i = 0; i < lr0_isocore->state->nitems; ++i)
if (!bitset_empty_p (lookaheads[i]))
{
has_lookaheads = true;
break;
}
}
for (size_t i = 0; i < lr0_isocore->state->nitems; ++i)
if (!bitset_empty_p (lookaheads[i]))
{
has_lookaheads = true;
break;
}
/* Merge with an existing isocore. */
if (this_isocorep == &t->state_list || *this_isocorep != t->state_list)
@@ -822,11 +799,10 @@ ielr_compute_state (bitsetv follow_kernel_items, bitsetv always_follows,
(*this_isocorep)->recomputedAsSuccessor = true;
else if (new_lookaheads)
{
int i;
/* When merging demands identical lookahead sets, it is impossible to
merge new lookaheads. */
aver (annotation_lists);
for (i = 0; i < (*tp)->transitions->num; ++i)
for (int i = 0; i < (*tp)->transitions->num; ++i)
{
state *t2 = (*tp)->transitions->states[i];
/* At any time, there's at most one state for which we have so
@@ -969,9 +945,8 @@ ielr_split_states (bitsetv follow_kernel_items, bitsetv always_follows,
/* Set up state list and some reusable bitsets. */
{
size_t max_nitems = 0;
state_number i;
state_list **nodep = &first_state;
for (i = 0; i < nstates; ++i)
for (state_number i = 0; i < nstates; ++i)
{
*nodep = states[i]->state_list = last_state = xmalloc (sizeof **nodep);
(*nodep)->state = states[i];
@@ -993,12 +968,12 @@ ielr_split_states (bitsetv follow_kernel_items, bitsetv always_follows,
/* Recompute states. */
{
ContributionIndex *work = xnmalloc (max_annotations, sizeof *work);
state_list *this_state;
for (this_state = first_state; this_state; this_state = this_state->next)
for (state_list *this_state = first_state;
this_state;
this_state = this_state->next)
{
state *s = this_state->state;
int i;
for (i = 0; i < s->transitions->num; ++i)
for (int i = 0; i < s->transitions->num; ++i)
{
state *t = s->transitions->states[i];
if (annotation_lists)
@@ -1022,11 +997,8 @@ ielr_split_states (bitsetv follow_kernel_items, bitsetv always_follows,
/* Store states back in the states array. */
states = xnrealloc (states, nstates, sizeof *states);
{
state_list *node;
for (node = first_state; node; node = node->next)
states[node->state->number] = node->state;
}
for (state_list *node = first_state; node; node = node->next)
states[node->state->number] = node->state;
/* In the case of canonical LR(1), copy item lookahead sets to reduction
lookahead sets. */
@@ -1034,14 +1006,12 @@ ielr_split_states (bitsetv follow_kernel_items, bitsetv always_follows,
{
timevar_push (TV_IELR_PHASE4);
initialize_LA ();
state_list *node;
for (node = first_state; node; node = node->next)
for (state_list *node = first_state; node; node = node->next)
if (!node->state->consistent)
{
size_t i = 0;
item_number *itemset = node->state->items;
size_t r;
for (r = 0; r < node->state->reductions->num; ++r)
for (size_t r = 0; r < node->state->reductions->num; ++r)
{
rule *this_rule = node->state->reductions->rules[r];
bitset lookahead_set =
@@ -1149,11 +1119,8 @@ ielr (void)
predecessors, &max_annotations,
&inadequacy_lists, &annotation_lists,
&annotations_obstack);
{
state_number i;
for (i = 0; i < nstates; ++i)
free (predecessors[i]);
}
for (state_number i = 0; i < nstates; ++i)
free (predecessors[i]);
free (predecessors);
bitsetv_free (goto_follows);
lalr_free ();
@@ -1168,11 +1135,8 @@ ielr (void)
ielr_split_states (follow_kernel_items, always_follows,
annotation_lists, max_annotations);
if (inadequacy_lists)
{
state_number i;
for (i = 0; i < nstates_lr0; ++i)
InadequacyList__delete (inadequacy_lists[i]);
}
for (state_number i = 0; i < nstates_lr0; ++i)
InadequacyList__delete (inadequacy_lists[i]);
}
free (inadequacy_lists);
if (annotation_lists)
+1
View File
@@ -119,6 +119,7 @@ MOSTLYCLEANFILES += src/yacc
src/yacc:
$(AM_V_GEN)rm -f $@ $@.tmp
$(AM_V_at)$(MKDIR_P) src
$(AM_V_at)echo '#! /bin/sh' >$@.tmp
$(AM_V_at)echo "exec '$(bindir)/bison' -y "'"$$@"' >>$@.tmp
$(AM_V_at)chmod a+x $@.tmp
+1 -1
View File
@@ -37,7 +37,7 @@ static inline int
add_column_width (int column, char const *buf, size_t bufsize)
{
size_t width;
unsigned int remaining_columns = INT_MAX - column;
unsigned remaining_columns = INT_MAX - column;
if (buf)
{
+49 -65
View File
@@ -64,13 +64,10 @@ Name (char const *name, \
{ \
Type min = first; \
Type max = first; \
long int lmin; \
long int lmax; \
int i; \
int j = 1; \
\
obstack_printf (&format_obstack, "%6d", first); \
for (i = begin; i < end; ++i) \
for (int i = begin; i < end; ++i) \
{ \
obstack_1grow (&format_obstack, ','); \
if (j >= 10) \
@@ -88,8 +85,8 @@ Name (char const *name, \
} \
muscle_insert (name, obstack_finish0 (&format_obstack)); \
\
lmin = min; \
lmax = max; \
long lmin = min; \
long lmax = max; \
/* Build 'NAME_min' and 'NAME_max' in the obstack. */ \
obstack_printf (&format_obstack, "%s_min", name); \
MUSCLE_INSERT_LONG_INT (obstack_finish0 (&format_obstack), lmin); \
@@ -97,7 +94,7 @@ Name (char const *name, \
MUSCLE_INSERT_LONG_INT (obstack_finish0 (&format_obstack), lmax); \
}
GENERATE_MUSCLE_INSERT_TABLE (muscle_insert_unsigned_int_table, unsigned int)
GENERATE_MUSCLE_INSERT_TABLE (muscle_insert_unsigned_int_table, unsigned)
GENERATE_MUSCLE_INSERT_TABLE (muscle_insert_int_table, int)
GENERATE_MUSCLE_INSERT_TABLE (muscle_insert_base_table, base_number)
GENERATE_MUSCLE_INSERT_TABLE (muscle_insert_rule_number_table, rule_number)
@@ -149,7 +146,7 @@ prepare_symbols (void)
MUSCLE_INSERT_INT ("tokens_number", ntokens);
MUSCLE_INSERT_INT ("nterms_number", nvars);
MUSCLE_INSERT_INT ("symbols_number", nsyms);
MUSCLE_INSERT_INT ("undef_token_number", undeftoken->number);
MUSCLE_INSERT_INT ("undef_token_number", undeftoken->content->number);
MUSCLE_INSERT_INT ("user_token_number_max", max_user_token_number);
muscle_insert_symbol_number_table ("translate",
@@ -159,13 +156,12 @@ prepare_symbols (void)
/* tname -- token names. */
{
int i;
/* We assume that the table will be output starting at column 2. */
int j = 2;
struct quoting_options *qo = clone_quoting_options (0);
set_quoting_style (qo, c_quoting_style);
set_quoting_flags (qo, QA_SPLIT_TRIGRAPHS);
for (i = 0; i < nsyms; i++)
for (int i = 0; i < nsyms; i++)
{
char *cp = quotearg_alloc (symbols[i]->tag, -1, qo);
/* Width of the next token, including the two quotes, the
@@ -194,10 +190,9 @@ prepare_symbols (void)
/* Output YYTOKNUM. */
{
int i;
int *values = xnmalloc (ntokens, sizeof *values);
for (i = 0; i < ntokens; ++i)
values[i] = symbols[i]->user_token_number;
for (int i = 0; i < ntokens; ++i)
values[i] = symbols[i]->content->user_token_number;
muscle_insert_int_table ("toknum", values,
values[0], 1, ntokens);
free (values);
@@ -213,15 +208,14 @@ prepare_symbols (void)
static void
prepare_rules (void)
{
unsigned int *rline = xnmalloc (nrules, sizeof *rline);
unsigned *rline = xnmalloc (nrules, sizeof *rline);
symbol_number *r1 = xnmalloc (nrules, sizeof *r1);
unsigned int *r2 = xnmalloc (nrules, sizeof *r2);
unsigned *r2 = xnmalloc (nrules, sizeof *r2);
int *dprec = xnmalloc (nrules, sizeof *dprec);
int *merger = xnmalloc (nrules, sizeof *merger);
int *immediate = xnmalloc (nrules, sizeof *immediate);
rule_number r;
for (r = 0; r < nrules; ++r)
for (rule_number r = 0; r < nrules; ++r)
{
/* LHS of the rule R. */
r1[r] = rules[r].lhs->number;
@@ -262,9 +256,8 @@ prepare_rules (void)
static void
prepare_states (void)
{
state_number i;
symbol_number *values = xnmalloc (nstates, sizeof *values);
for (i = 0; i < nstates; ++i)
for (state_number i = 0; i < nstates; ++i)
values[i] = states[i]->accessing_symbol;
muscle_insert_symbol_number_table ("stos", values,
0, 1, nstates);
@@ -283,9 +276,9 @@ prepare_states (void)
static int
symbol_type_name_cmp (const symbol **lhs, const symbol **rhs)
{
int res = uniqstr_cmp ((*lhs)->type_name, (*rhs)->type_name);
int res = uniqstr_cmp ((*lhs)->content->type_name, (*rhs)->content->type_name);
if (!res)
res = (*lhs)->number - (*rhs)->number;
res = (*lhs)->content->number - (*rhs)->content->number;
return res;
}
@@ -312,16 +305,16 @@ symbols_by_type_name (void)
static void
type_names_output (FILE *out)
{
int i;
symbol **syms = symbols_by_type_name ();
fputs ("m4_define([b4_type_names],\n[", out);
for (i = 0; i < nsyms; /* nothing */)
for (int i = 0; i < nsyms; /* nothing */)
{
/* The index of the first symbol of the current type-name. */
int i0 = i;
fputs (i ? ",\n[" : "[", out);
for (; i < nsyms && syms[i]->type_name == syms[i0]->type_name; ++i)
fprintf (out, "%s%d", i != i0 ? ", " : "", syms[i]->number);
for (; i < nsyms
&& syms[i]->content->type_name == syms[i0]->content->type_name; ++i)
fprintf (out, "%s%d", i != i0 ? ", " : "", syms[i]->content->number);
fputs ("]", out);
}
fputs ("])\n\n", out);
@@ -336,9 +329,8 @@ type_names_output (FILE *out)
static void
symbol_numbers_output (FILE *out)
{
int i;
fputs ("m4_define([b4_symbol_numbers],\n[", out);
for (i = 0; i < nsyms; ++i)
for (int i = 0; i < nsyms; ++i)
fprintf (out, "%s[%d]", i ? ", " : "", i);
fputs ("])\n\n", out);
}
@@ -351,14 +343,12 @@ symbol_numbers_output (FILE *out)
static void
user_actions_output (FILE *out)
{
rule_number r;
fputs ("m4_define([b4_actions], \n[", out);
for (r = 0; r < nrules; ++r)
for (rule_number r = 0; r < nrules; ++r)
if (rules[r].action)
{
fprintf (out, "b4_%scase(%d, [b4_syncline(%d, ",
rules[r].is_predicate ? "predicate_" : "",
fprintf (out, "%s(%d, [b4_syncline(%d, ",
rules[r].is_predicate ? "b4_predicate_case" : "b4_case",
r + 1, rules[r].action_location.start.line);
string_output (out, rules[r].action_location.start.file);
fprintf (out, ")\n[ %s]])\n\n", rules[r].action);
@@ -373,10 +363,9 @@ user_actions_output (FILE *out)
static void
merger_output (FILE *out)
{
fputs ("m4_define([b4_mergers], \n[[", out);
int n;
merger_list* p;
fputs ("m4_define([b4_mergers], \n[[", out);
for (n = 1, p = merge_functions; p != NULL; n += 1, p = p->next)
{
if (p->type[0] == '\0')
@@ -397,12 +386,10 @@ merger_output (FILE *out)
static void
prepare_symbol_definitions (void)
{
int i;
for (i = 0; i < nsyms; ++i)
for (int i = 0; i < nsyms; ++i)
{
symbol *sym = symbols[i];
const char *key;
const char *value;
#define SET_KEY(Entry) \
obstack_printf (&format_obstack, "symbol(%d, %s)", \
@@ -415,7 +402,7 @@ prepare_symbol_definitions (void)
key = obstack_finish0 (&format_obstack);
/* Whether the symbol has an identifier. */
value = symbol_id_get (sym);
const char *value = symbol_id_get (sym);
SET_KEY ("has_id");
MUSCLE_INSERT_INT (key, !!value);
@@ -428,44 +415,42 @@ prepare_symbol_definitions (void)
MUSCLE_INSERT_STRING (key, sym->tag);
SET_KEY ("user_number");
MUSCLE_INSERT_INT (key, sym->user_token_number);
MUSCLE_INSERT_INT (key, sym->content->user_token_number);
SET_KEY ("is_token");
MUSCLE_INSERT_INT (key,
i < ntokens && sym != errtoken && sym != undeftoken);
SET_KEY ("number");
MUSCLE_INSERT_INT (key, sym->number);
MUSCLE_INSERT_INT (key, sym->content->number);
SET_KEY ("has_type");
MUSCLE_INSERT_INT (key, !!sym->type_name);
MUSCLE_INSERT_INT (key, !!sym->content->type_name);
SET_KEY ("type");
MUSCLE_INSERT_STRING (key, sym->type_name ? sym->type_name : "");
MUSCLE_INSERT_STRING (key, sym->content->type_name
? sym->content->type_name : "");
{
int j;
for (j = 0; j < CODE_PROPS_SIZE; ++j)
{
/* "printer", not "%printer". */
char const *pname = code_props_type_string (j) + 1;
code_props const *p = symbol_code_props_get (sym, j);
SET_KEY2 ("has", pname);
MUSCLE_INSERT_INT (key, !!p->code);
for (int j = 0; j < CODE_PROPS_SIZE; ++j)
{
/* "printer", not "%printer". */
char const *pname = code_props_type_string (j) + 1;
code_props const *p = symbol_code_props_get (sym, j);
SET_KEY2 ("has", pname);
MUSCLE_INSERT_INT (key, !!p->code);
if (p->code)
{
SET_KEY2 (pname, "file");
MUSCLE_INSERT_STRING (key, p->location.start.file);
if (p->code)
{
SET_KEY2 (pname, "file");
MUSCLE_INSERT_C_STRING (key, p->location.start.file);
SET_KEY2 (pname, "line");
MUSCLE_INSERT_INT (key, p->location.start.line);
SET_KEY2 (pname, "line");
MUSCLE_INSERT_INT (key, p->location.start.line);
SET_KEY (pname);
MUSCLE_INSERT_STRING_RAW (key, p->code);
}
}
}
SET_KEY (pname);
MUSCLE_INSERT_STRING_RAW (key, p->code);
}
}
#undef SET_KEY2
#undef SET_KEY
}
@@ -543,9 +528,6 @@ muscles_output (FILE *out)
static void
output_skeleton (void)
{
int filter_fd[2];
pid_t pid;
/* Compute the names of the package data dir and skeleton files. */
char const *m4 = (m4 = getenv ("M4")) ? m4 : M4;
char const *datadir = pkgdatadir ();
@@ -573,6 +555,8 @@ output_skeleton (void)
See the thread starting at
<http://lists.gnu.org/archive/html/bug-bison/2008-07/msg00000.html>
for details. */
int filter_fd[2];
pid_t pid;
{
char const *argv[10];
int i = 0;
+258 -260
View File
File diff suppressed because it is too large Load Diff
+17 -17
View File
@@ -1,4 +1,4 @@
/* A Bison parser, made by GNU Bison 3.0.4.38-1047-dirty. */
/* A Bison parser, made by GNU Bison 3.0.5.75-d835. */
/* Bison interface for Yacc-like parsers in C
@@ -48,11 +48,11 @@
extern int gram_debug;
#endif
/* "%code requires" blocks. */
#line 21 "src/parse-gram.y" /* yacc.c:1910 */
#line 21 "src/parse-gram.y" /* yacc.c:1913 */
#include "symlist.h"
#include "symtab.h"
#line 221 "src/parse-gram.y" /* yacc.c:1910 */
#line 221 "src/parse-gram.y" /* yacc.c:1913 */
typedef enum
{
@@ -61,10 +61,10 @@ extern int gram_debug;
param_parse = 1 << 1,
param_both = param_lex | param_parse
} param_type;
#line 647 "src/parse-gram.y" /* yacc.c:1910 */
#line 644 "src/parse-gram.y" /* yacc.c:1913 */
#include "muscle-tab.h"
#line 68 "src/parse-gram.h" /* yacc.c:1910 */
#line 68 "src/parse-gram.h" /* yacc.c:1913 */
/* Token type. */
#ifndef GRAM_TOKENTYPE
@@ -135,27 +135,27 @@ extern int gram_debug;
union GRAM_STYPE
{
#line 182 "src/parse-gram.y" /* yacc.c:1910 */
#line 182 "src/parse-gram.y" /* yacc.c:1913 */
unsigned char character;
#line 186 "src/parse-gram.y" /* yacc.c:1910 */
#line 186 "src/parse-gram.y" /* yacc.c:1913 */
char *code;
#line 191 "src/parse-gram.y" /* yacc.c:1910 */
#line 191 "src/parse-gram.y" /* yacc.c:1913 */
uniqstr uniqstr;
#line 199 "src/parse-gram.y" /* yacc.c:1910 */
#line 199 "src/parse-gram.y" /* yacc.c:1913 */
int integer;
#line 203 "src/parse-gram.y" /* yacc.c:1910 */
#line 203 "src/parse-gram.y" /* yacc.c:1913 */
symbol *symbol;
#line 208 "src/parse-gram.y" /* yacc.c:1910 */
#line 208 "src/parse-gram.y" /* yacc.c:1913 */
assoc assoc;
#line 211 "src/parse-gram.y" /* yacc.c:1910 */
#line 211 "src/parse-gram.y" /* yacc.c:1913 */
symbol_list *list;
#line 214 "src/parse-gram.y" /* yacc.c:1910 */
#line 214 "src/parse-gram.y" /* yacc.c:1913 */
named_ref *named_ref;
#line 241 "src/parse-gram.y" /* yacc.c:1910 */
#line 241 "src/parse-gram.y" /* yacc.c:1913 */
param_type param;
#line 409 "src/parse-gram.y" /* yacc.c:1910 */
#line 408 "src/parse-gram.y" /* yacc.c:1913 */
code_props_type code_type;
#line 649 "src/parse-gram.y" /* yacc.c:1910 */
#line 646 "src/parse-gram.y" /* yacc.c:1913 */
struct
{
@@ -163,7 +163,7 @@ code_props_type code_type;
muscle_kind kind;
} value;
#line 167 "src/parse-gram.h" /* yacc.c:1910 */
#line 167 "src/parse-gram.h" /* yacc.c:1913 */
};
typedef union GRAM_STYPE GRAM_STYPE;
+9 -11
View File
@@ -376,8 +376,7 @@ grammar_declaration:
code_props_symbol_action_init (&code, $2, @2);
code_props_translate_code (&code);
{
symbol_list *list;
for (list = $3; list; list = list->next)
for (symbol_list *list = $3; list; list = list->next)
symbol_list_code_props_set (list, $1, &code);
symbol_list_free ($3);
}
@@ -451,9 +450,8 @@ symbol_declaration:
}
| "%type" TAG symbols.1
{
symbol_list *list;
tag_seen = true;
for (list = $3; list; list = list->next)
for (symbol_list *list = $3; list; list = list->next)
symbol_type_set (list->content.sym, $2, @2);
symbol_list_free ($3);
}
@@ -462,9 +460,8 @@ symbol_declaration:
precedence_declaration:
precedence_declarator tag.opt symbols.prec
{
symbol_list *list;
++current_prec;
for (list = $3; list; list = list->next)
for (symbol_list *list = $3; list; list = list->next)
{
symbol_type_set (list->content.sym, current_type, @2);
symbol_precedence_set (list->content.sym, current_prec, $1, @1);
@@ -613,10 +610,10 @@ rhs:
current_lhs_named_ref); }
| rhs symbol named_ref.opt
{ grammar_current_rule_symbol_append ($2, @2, $3); }
| rhs "{...}" named_ref.opt
{ grammar_current_rule_action_append ($2, @2, $3, false); }
| rhs tag.opt "{...}"[act] named_ref.opt[name]
{ grammar_current_rule_action_append ($act, @act, $name, current_type); }
| rhs "%?{...}"
{ grammar_current_rule_action_append ($2, @2, NULL, true); }
{ grammar_current_rule_predicate_append ($2, @2); }
| rhs "%empty"
{ grammar_current_rule_empty_set (@2); }
| rhs "%prec" symbol
@@ -728,7 +725,6 @@ epilogue.opt:
static YYLTYPE
lloc_default (YYLTYPE const *rhs, int n)
{
int i;
YYLTYPE loc;
/* SGI MIPSpro 7.4.1m miscompiles "loc.start = loc.end = rhs[n].end;".
@@ -739,7 +735,7 @@ lloc_default (YYLTYPE const *rhs, int n)
/* Ignore empty nonterminals the start of the right-hand side.
Do not bother to ignore them at the end of the right-hand side,
since empty nonterminals have the same end as their predecessors. */
for (i = 1; i <= n; i++)
for (int i = 1; i <= n; i++)
if (! equal_boundaries (rhs[i].start, rhs[i].end))
{
loc.start = rhs[i].start;
@@ -865,6 +861,8 @@ current_lhs (symbol *sym, location loc, named_ref *ref)
{
current_lhs_symbol = sym;
current_lhs_location = loc;
if (sym)
symbol_location_as_lhs_set (sym, loc);
/* In order to simplify memory management, named references for lhs
are always assigned by deep copy into the current symbol_list
node. This is because a single named-ref in the grammar may
+5 -5
View File
@@ -259,7 +259,7 @@ print_reductions (FILE *out, int level, state *s)
bitset_set (no_reduce_set, TRANSITION_SYMBOL (trans, i));
for (i = 0; i < s->errs->num; ++i)
if (s->errs->symbols[i])
bitset_set (no_reduce_set, s->errs->symbols[i]->number);
bitset_set (no_reduce_set, s->errs->symbols[i]->content->number);
if (default_reduction)
report = true;
@@ -388,11 +388,11 @@ print_grammar (FILE *out, int level)
/* Terminals */
xml_puts (out, level + 1, "<terminals>");
for (i = 0; i < max_user_token_number + 1; i++)
if (token_translations[i] != undeftoken->number)
if (token_translations[i] != undeftoken->content->number)
{
char const *tag = symbols[token_translations[i]]->tag;
int precedence = symbols[token_translations[i]]->prec;
assoc associativity = symbols[token_translations[i]]->assoc;
int precedence = symbols[token_translations[i]]->content->prec;
assoc associativity = symbols[token_translations[i]]->content->assoc;
xml_indent (out, level + 2);
fprintf (out,
"<terminal symbol-number=\"%d\" token-number=\"%d\""
@@ -417,7 +417,7 @@ print_grammar (FILE *out, int level)
"<nonterminal symbol-number=\"%d\" name=\"%s\""
" usefulness=\"%s\"/>",
i, xml_escape (tag),
reduce_nonterminal_useless_in_grammar (i)
reduce_nonterminal_useless_in_grammar (symbols[i]->content)
? "useless-in-grammar" : "useful");
}
xml_puts (out, level + 1, "</nonterminals>");
+35 -26
View File
@@ -40,14 +40,6 @@
static bitset no_reduce_set;
#if 0
static void
print_token (int extnum, int token)
{
fprintf (out, _(" type %d is %s\n"), extnum, tags[token]);
}
#endif
/*---------------------------------------.
@@ -72,7 +64,7 @@ print_core (FILE *out, state *s)
size_t i;
item_number *sitems = s->items;
size_t snritems = s->nitems;
symbol *previous_lhs = NULL;
sym_content *previous_lhs = NULL;
/* Output all the items of a state, not only its kernel. */
if (report_flag & report_itemsets)
@@ -226,7 +218,8 @@ print_reduction (FILE *out, size_t width,
if (!enabled)
fputc ('[', out);
if (r->number)
fprintf (out, _("reduce using rule %d (%s)"), r->number, r->lhs->tag);
fprintf (out, _("reduce using rule %d (%s)"), r->number,
r->lhs->symbol->tag);
else
fprintf (out, _("accept"));
if (!enabled)
@@ -260,7 +253,7 @@ print_reductions (FILE *out, state *s)
bitset_set (no_reduce_set, TRANSITION_SYMBOL (trans, i));
for (i = 0; i < s->errs->num; ++i)
if (s->errs->symbols[i])
bitset_set (no_reduce_set, s->errs->symbols[i]->number);
bitset_set (no_reduce_set, s->errs->symbols[i]->content->number);
/* Compute the width of the lookahead token column. */
if (default_reduction)
@@ -401,27 +394,30 @@ print_state (FILE *out, state *s)
static void
print_grammar (FILE *out)
print_terminal_symbols (FILE *out)
{
symbol_number i;
char buffer[90];
int column = 0;
grammar_rules_print (out);
/* TERMINAL (type #) : rule #s terminal is on RHS */
fprintf (out, "%s\n\n", _("Terminals, with rules where they appear"));
for (i = 0; i < max_user_token_number + 1; i++)
if (token_translations[i] != undeftoken->number)
if (token_translations[i] != undeftoken->content->number)
{
const char *tag = symbols[token_translations[i]]->tag;
int column = strlen (tag);
char buffer[90];
rule_number r;
item_number *rhsp;
buffer[0] = 0;
column = strlen (tag);
fputs (tag, out);
END_TEST (65);
if (symbols[token_translations[i]]->content->type_name)
{
column += fprintf (out, " <%s>",
symbols[token_translations[i]]->content->type_name);
END_TEST (65);
}
sprintf (buffer, " (%d)", i);
for (r = 0; r < nrules; r++)
@@ -435,14 +431,23 @@ print_grammar (FILE *out)
fprintf (out, "%s\n", buffer);
}
fputs ("\n\n", out);
}
static void
print_nonterminal_symbols (FILE *out)
{
symbol_number i;
fprintf (out, "%s\n\n", _("Nonterminals, with rules where they appear"));
for (i = ntokens; i < nsyms; i++)
{
const char *tag = symbols[i]->tag;
int column = strlen (tag);
int left_count = 0, right_count = 0;
rule_number r;
const char *tag = symbols[i]->tag;
char buffer[90];
buffer[0] = 0;
for (r = 0; r < nrules; r++)
{
@@ -457,9 +462,10 @@ print_grammar (FILE *out)
}
}
buffer[0] = 0;
fputs (tag, out);
column = strlen (tag);
if (symbols[i]->content->type_name)
column += fprintf (out, " <%s>",
symbols[i]->content->type_name);
sprintf (buffer, " (%d)", i);
END_TEST (0);
@@ -503,8 +509,6 @@ print_grammar (FILE *out)
void
print_results (void)
{
state_number i;
/* We used to use just .out if SPEC_NAME_PREFIX (-p) was used, but
that conflicts with Posix. */
FILE *out = xfopen (spec_verbose_file, "w");
@@ -515,7 +519,9 @@ print_results (void)
rule_useless_in_parser_p);
conflicts_output (out);
print_grammar (out);
grammar_rules_print (out);
print_terminal_symbols (out);
print_nonterminal_symbols (out);
/* If the whole state item sets, not only the kernels, are wanted,
'closure' will be run, which needs memory allocation/deallocation. */
@@ -523,8 +529,11 @@ print_results (void)
new_closure (nritems);
/* Storage for print_reductions. */
no_reduce_set = bitset_create (ntokens, BITSET_FIXED);
for (i = 0; i < nstates; i++)
print_state (out, states[i]);
{
state_number i;
for (i = 0; i < nstates; i++)
print_state (out, states[i]);
}
bitset_free (no_reduce_set);
if (report_flag & report_itemsets)
free_closure ();
+5 -4
View File
@@ -47,7 +47,7 @@ static void
print_core (struct obstack *oout, state *s)
{
item_number const *sitems = s->items;
symbol *previous_lhs = NULL;
sym_content *previous_lhs = NULL;
size_t i;
size_t snritems = s->nitems;
@@ -73,11 +73,12 @@ print_core (struct obstack *oout, state *s)
r = &rules[item_number_as_rule_number (*sp)];
obstack_printf (oout, "%3d ", r->number);
if (previous_lhs && UNIQSTR_EQ (previous_lhs->tag, r->lhs->tag))
if (previous_lhs && UNIQSTR_EQ (previous_lhs->symbol->tag,
r->lhs->symbol->tag))
obstack_printf (oout, "%*s| ",
(int) strlen (previous_lhs->tag), "");
(int) strlen (previous_lhs->symbol->tag), "");
else
obstack_printf (oout, "%s: ", escape (r->lhs->tag));
obstack_printf (oout, "%s: ", escape (r->lhs->symbol->tag));
previous_lhs = r->lhs;
for (sp = r->rhs; sp < sp1; sp++)
+85 -66
View File
@@ -78,13 +78,13 @@ grammar_start_symbol_set (symbol *sym, location loc)
static int
get_merge_function (uniqstr name)
{
if (! glr_parser)
return 0;
merger_list *syms;
merger_list head;
int n;
if (! glr_parser)
return 0;
head.next = merge_functions;
for (syms = &head, n = 1; syms->next; syms = syms->next, n += 1)
if (UNIQSTR_EQ (name, syms->next->name))
@@ -111,12 +111,12 @@ get_merge_function (uniqstr name)
static void
record_merge_function_type (int merger, uniqstr type, location declaration_loc)
{
int merger_find;
merger_list *merge_function;
if (merger <= 0)
return;
int merger_find;
merger_list *merge_function;
if (type == NULL)
type = uniqstr_new ("");
@@ -227,26 +227,24 @@ void
grammar_current_rule_begin (symbol *lhs, location loc,
named_ref *lhs_name)
{
symbol_list* p;
/* Start a new rule and record its lhs. */
++nrules;
previous_rule_end = grammar_end;
p = grammar_symbol_append (lhs, loc);
symbol_list *p = grammar_symbol_append (lhs, loc);
if (lhs_name)
assign_named_ref (p, named_ref_copy (lhs_name));
current_rule = grammar_end;
/* Mark the rule's lhs as a nonterminal if not already so. */
if (lhs->class == unknown_sym)
if (lhs->content->class == unknown_sym)
{
lhs->class = nterm_sym;
lhs->number = nvars;
lhs->content->class = nterm_sym;
lhs->content->number = nvars;
++nvars;
}
else if (lhs->class == token_sym)
else if (lhs->content->class == token_sym)
complain (&loc, complaint, _("rule given for %s, which is a token"),
lhs->tag);
}
@@ -292,15 +290,15 @@ grammar_rule_check (const symbol_list *r)
Don't worry about the default action if $$ is untyped, since $$'s
value can't be used. */
if (!r->action_props.code && r->content.sym->type_name)
if (!r->action_props.code && r->content.sym->content->type_name)
{
symbol *first_rhs = r->next->content.sym;
/* If $$ is being set in default way, report if any type mismatch. */
if (first_rhs)
{
char const *lhs_type = r->content.sym->type_name;
char const *lhs_type = r->content.sym->content->type_name;
const char *rhs_type =
first_rhs->type_name ? first_rhs->type_name : "";
first_rhs->content->type_name ? first_rhs->content->type_name : "";
if (!UNIQSTR_EQ (lhs_type, rhs_type))
complain (&r->location, Wother,
_("type clash on default action: <%s> != <%s>"),
@@ -314,9 +312,8 @@ grammar_rule_check (const symbol_list *r)
/* Check that symbol values that should be used are in fact used. */
{
symbol_list const *l = r;
int n = 0;
for (; l && l->content.sym; l = l->next, ++n)
for (symbol_list const *l = r; l && l->content.sym; l = l->next, ++n)
{
bool midrule_warning = false;
if (!l->action_props.is_value_used
@@ -350,9 +347,15 @@ grammar_rule_check (const symbol_list *r)
it for char literals and strings, which are always tokens. */
if (r->ruleprec
&& r->ruleprec->tag[0] != '\'' && r->ruleprec->tag[0] != '"'
&& r->ruleprec->status != declared && !r->ruleprec->prec)
&& r->ruleprec->content->status != declared
&& !r->ruleprec->content->prec)
complain (&r->location, Wother,
_("token for %%prec is not defined: %s"), r->ruleprec->tag);
/* Check that the (main) action was not typed. */
if (r->action_props.type)
complain (&r->location, Wother,
_("only midrule actions can be typed: %s"), r->action_props.type);
}
@@ -370,7 +373,7 @@ grammar_current_rule_end (location loc)
/*-------------------------------------------------------------------.
| The previous action turns out the be a mid-rule action. Attach it |
| The previous action turns out to be a mid-rule action. Attach it |
| to the current rule, i.e., create a dummy symbol, attach it this |
| mid-rule action, and append this dummy nonterminal to the current |
| rule. |
@@ -387,6 +390,8 @@ grammar_midrule_action (void)
action. Create the MIDRULE. */
location dummy_location = current_rule->action_props.location;
symbol *dummy = dummy_symbol_get (dummy_location);
symbol_type_set(dummy,
current_rule->action_props.type, current_rule->action_props.location);
symbol_list *midrule = symbol_list_sym_new (dummy, dummy_location);
/* Remember named_ref of previous action. */
@@ -401,7 +406,9 @@ grammar_midrule_action (void)
code_props_rule_action_init (&midrule->action_props,
current_rule->action_props.code,
current_rule->action_props.location,
midrule, 0,
midrule,
/* name_ref */ NULL,
/* type */ NULL,
current_rule->action_props.is_predicate);
code_props_none_init (&current_rule->action_props);
@@ -511,28 +518,41 @@ void
grammar_current_rule_symbol_append (symbol *sym, location loc,
named_ref *name)
{
symbol_list *p;
if (current_rule->action_props.code)
grammar_midrule_action ();
p = grammar_symbol_append (sym, loc);
symbol_list *p = grammar_symbol_append (sym, loc);
if (name)
assign_named_ref (p, name);
if (sym->status == undeclared || sym->status == used)
sym->status = needed;
if (sym->content->status == undeclared || sym->content->status == used)
sym->content->status = needed;
}
/* Attach an ACTION to the current rule. */
void
grammar_current_rule_action_append (const char *action, location loc,
named_ref *name, bool is_predicate)
named_ref *name, uniqstr type)
{
if (current_rule->action_props.code)
grammar_midrule_action ();
if (type)
complain (&loc, Wyacc,
_("POSIX Yacc does not support typed midrule actions"));
/* After all symbol declarations have been parsed, packgram invokes
code_props_translate_code. */
code_props_rule_action_init (&current_rule->action_props, action, loc,
current_rule, name, is_predicate);
current_rule,
name, type,
/* is_predicate */ false);
}
void
grammar_current_rule_predicate_append (const char *pred, location loc)
{
if (current_rule->action_props.code)
grammar_midrule_action ();
code_props_rule_action_init (&current_rule->action_props, pred, loc,
current_rule,
NULL, NULL,
/* is_predicate */ true);
}
@@ -544,9 +564,8 @@ grammar_current_rule_action_append (const char *action, location loc,
static void
packgram (void)
{
unsigned int itemno = 0;
unsigned itemno = 0;
rule_number ruleno = 0;
symbol_list *p;
ritem = xnmalloc (nritems + 1, sizeof *ritem);
@@ -555,14 +574,14 @@ packgram (void)
rules = xnmalloc (nrules, sizeof *rules);
for (p = grammar; p; p = p->next)
for (symbol_list *p = grammar; p; p = p->next)
{
symbol *ruleprec = p->ruleprec;
record_merge_function_type (p->merger, p->content.sym->type_name,
record_merge_function_type (p->merger, p->content.sym->content->type_name,
p->merger_declaration_location);
rules[ruleno].user_number = ruleno;
rules[ruleno].number = ruleno;
rules[ruleno].lhs = p->content.sym;
rules[ruleno].lhs = p->content.sym->content;
rules[ruleno].rhs = ritem + itemno;
rules[ruleno].prec = NULL;
rules[ruleno].dprec = p->dprec;
@@ -604,11 +623,11 @@ packgram (void)
/* item_number = symbol_number.
But the former needs to contain more: negative rule numbers. */
ritem[itemno++] =
symbol_number_as_item_number (p->content.sym->number);
symbol_number_as_item_number (p->content.sym->content->number);
/* A rule gets by default the precedence and associativity
of its last token. */
if (p->content.sym->class == token_sym && default_prec)
rules[ruleno].prec = p->content.sym;
if (p->content.sym->content->class == token_sym && default_prec)
rules[ruleno].prec = p->content.sym->content;
}
}
@@ -616,8 +635,8 @@ packgram (void)
the specified symbol's precedence replaces the default. */
if (ruleprec)
{
rules[ruleno].precsym = ruleprec;
rules[ruleno].prec = ruleprec;
rules[ruleno].precsym = ruleprec->content;
rules[ruleno].prec = ruleprec->content;
}
/* An item ends by the rule number (negated). */
ritem[itemno++] = rule_number_as_item_number (ruleno);
@@ -647,19 +666,19 @@ reader (void)
/* Construct the accept symbol. */
accept = symbol_get ("$accept", empty_location);
accept->class = nterm_sym;
accept->number = nvars++;
accept->content->class = nterm_sym;
accept->content->number = nvars++;
/* Construct the error token */
errtoken = symbol_get ("error", empty_location);
errtoken->class = token_sym;
errtoken->number = ntokens++;
errtoken->content->class = token_sym;
errtoken->content->number = ntokens++;
/* Construct a token that represents all undefined literal tokens.
It is always token number 2. */
undeftoken = symbol_get ("$undefined", empty_location);
undeftoken->class = token_sym;
undeftoken->number = ntokens++;
undeftoken->content->class = token_sym;
undeftoken->content->number = ntokens++;
gram_in = xfopen (grammar_file, "r");
@@ -704,6 +723,20 @@ prepare_percent_define_front_end_variables (void)
}
}
/* Find the first LHS which is not a dummy. */
static symbol *
find_start_symbol (void)
{
symbol_list *res = grammar;
/* Skip all the possible dummy rules of the first rule. */
for (; symbol_is_dummy (res->content.sym); res = res->next)
/* Skip the LHS, and then all the RHS of the dummy rule. */
for (res = res->next; res->content.sym; res = res->next)
continue;
return res->content.sym;
}
/*-------------------------------------------------------------.
| Check the grammar that has just been read, and convert it to |
@@ -721,10 +754,10 @@ check_and_convert_grammar (void)
if (!endtoken)
{
endtoken = symbol_get ("$end", empty_location);
endtoken->class = token_sym;
endtoken->number = 0;
endtoken->content->class = token_sym;
endtoken->content->number = 0;
/* Value specified by POSIX. */
endtoken->user_token_number = 0;
endtoken->content->user_token_number = 0;
}
/* Report any undefined symbols and consider them nonterminals. */
@@ -733,19 +766,8 @@ check_and_convert_grammar (void)
/* Find the start symbol if no %start. */
if (!start_flag)
{
symbol_list *node;
for (node = grammar;
node != NULL && symbol_is_dummy (node->content.sym);
node = node->next)
{
for (node = node->next;
node != NULL && node->content.sym != NULL;
node = node->next)
;
}
aver (node != NULL);
grammar_start_symbol_set (node->content.sym,
node->content.sym->location);
symbol *start = find_start_symbol ();
grammar_start_symbol_set (start, start->location);
}
/* Insert the initial rule, whose line is that of the first rule
@@ -782,11 +804,8 @@ check_and_convert_grammar (void)
rule. For the same reason, all the 'used' flags must be set before
checking whether to remove '$' from any midrule symbol name (also in
packgram). */
{
symbol_list *sym;
for (sym = grammar; sym; sym = sym->next)
code_props_translate_code (&sym->action_props);
}
for (symbol_list *sym = grammar; sym; sym = sym->next)
code_props_translate_code (&sym->action_props);
/* Convert the grammar into the format described in gram.h. */
packgram ();
+4 -1
View File
@@ -54,8 +54,11 @@ void grammar_current_rule_dprec_set (int dprec, location loc);
void grammar_current_rule_merge_set (uniqstr name, location loc);
void grammar_current_rule_symbol_append (symbol *sym, location loc,
named_ref *nref);
/* Attach an ACTION to the current rule. */
void grammar_current_rule_action_append (const char *action, location loc,
named_ref *nref, bool);
named_ref *nref, uniqstr tag);
/* Attach a PREDICATE to the current rule. */
void grammar_current_rule_predicate_append (const char *predicate, location loc);
void reader (void);
void free_merger_functions (void);
+79 -82
View File
@@ -39,7 +39,7 @@
#include "reduce.h"
#include "symtab.h"
/* Set of all nonterminals which are not useless. */
/* Set of all nonterminals whose language is not empty. */
static bitset N;
/* Set of all rules which have no useless nonterminals in their RHS. */
@@ -52,11 +52,18 @@ static bitset V;
'useless', but no warning should be issued). */
static bitset V1;
static rule_number nuseful_productions;
rule_number nuseless_productions;
static int nuseful_nonterminals;
symbol_number nuseless_nonterminals;
static unsigned nuseful_productions;
unsigned nuseless_productions;
static unsigned nuseful_nonterminals;
unsigned nuseless_nonterminals;
#define bitset_swap(Lhs, Rhs) \
do { \
bitset lhs__ = Lhs; \
Lhs = Rhs; \
Rhs = lhs__; \
} while (0)
/*-------------------------------------------------------------------.
| Another way to do this would be with a set for each production and |
| then do subset tests against N0, but even for the C grammar the |
@@ -71,7 +78,7 @@ useful_production (rule_number r, bitset N0)
/* A production is useful if all of the nonterminals in its appear
in the set of useful nonterminals. */
for (rhsp = rules[r].rhs; *rhsp >= 0; ++rhsp)
for (rhsp = rules[r].rhs; 0 <= *rhsp; ++rhsp)
if (ISVAR (*rhsp) && !bitset_test (N0, *rhsp - ntokens))
return false;
return true;
@@ -85,14 +92,10 @@ useful_production (rule_number r, bitset N0)
static void
useless_nonterminals (void)
{
bitset Np, Ns;
rule_number r;
/* N is set as built. Np is set being built this iteration. P is
set of all productions which have a RHS all in N. */
Np = bitset_create (nvars, BITSET_FIXED);
bitset Np = bitset_create (nvars, BITSET_FIXED);
/* The set being computed is a set of nonterminals which can derive
the empty string or strings consisting of all terminals. At each
@@ -112,8 +115,9 @@ useless_nonterminals (void)
while (1)
{
rule_number r;
bitset_copy (Np, N);
for (r = 0; r < nrules; r++)
for (r = 0; r < nrules; ++r)
if (!bitset_test (P, r)
&& useful_production (r, N))
{
@@ -122,9 +126,7 @@ useless_nonterminals (void)
}
if (bitset_equal_p (N, Np))
break;
Ns = Np;
Np = N;
N = Ns;
bitset_swap (N, Np);
}
bitset_free (N);
N = Np;
@@ -134,8 +136,6 @@ useless_nonterminals (void)
static void
inaccessable_symbols (void)
{
bitset Vp, Vs, Pp;
/* Find out which productions are reachable and which symbols are
used. Starting with an empty set of productions and a set of
symbols which only has the start symbol in it, iterate over all
@@ -159,46 +159,43 @@ inaccessable_symbols (void)
terminals are printed (if running in verbose mode) so that the
user can know. */
Vp = bitset_create (nsyms, BITSET_FIXED);
Pp = bitset_create (nrules, BITSET_FIXED);
bitset Vp = bitset_create (nsyms, BITSET_FIXED);
bitset Pp = bitset_create (nrules, BITSET_FIXED);
/* If the start symbol isn't useful, then nothing will be useful. */
if (bitset_test (N, accept->number - ntokens))
if (bitset_test (N, accept->content->number - ntokens))
{
bitset_set (V, accept->number);
bitset_set (V, accept->content->number);
while (1)
{
rule_number r;
bitset_copy (Vp, V);
for (r = 0; r < nrules; r++)
{
if (!bitset_test (Pp, r)
&& bitset_test (P, r)
&& bitset_test (V, rules[r].lhs->number))
{
item_number *rhsp;
for (rhsp = rules[r].rhs; *rhsp >= 0; rhsp++)
if (ISTOKEN (*rhsp) || bitset_test (N, *rhsp - ntokens))
bitset_set (Vp, *rhsp);
bitset_set (Pp, r);
}
}
for (r = 0; r < nrules; ++r)
if (!bitset_test (Pp, r)
&& bitset_test (P, r)
&& bitset_test (V, rules[r].lhs->number))
{
item_number *rhsp;
for (rhsp = rules[r].rhs; 0 <= *rhsp; ++rhsp)
if (ISTOKEN (*rhsp) || bitset_test (N, *rhsp - ntokens))
bitset_set (Vp, *rhsp);
bitset_set (Pp, r);
}
if (bitset_equal_p (V, Vp))
break;
Vs = Vp;
Vp = V;
V = Vs;
bitset_swap (V, Vp);
}
}
bitset_free (V);
V = Vp;
/* Tokens 0, 1, and 2 are internal to Bison. Consider them useful. */
bitset_set (V, endtoken->number); /* end-of-input token */
bitset_set (V, errtoken->number); /* error token */
bitset_set (V, undeftoken->number); /* some undefined token */
/* These tokens (numbered 0, 1, and 2) are internal to Bison.
Consider them useful. */
bitset_set (V, endtoken->content->number); /* end-of-input token */
bitset_set (V, errtoken->content->number); /* error token */
bitset_set (V, undeftoken->content->number); /* some undefined token */
bitset_free (P);
P = Pp;
@@ -209,9 +206,8 @@ inaccessable_symbols (void)
nuseful_nonterminals = 0;
{
symbol_number i;
for (i = ntokens; i < nsyms; i++)
if (bitset_test (V, i))
nuseful_nonterminals++;
for (i = ntokens; i < nsyms; ++i)
nuseful_nonterminals += bitset_test (V, i);
}
nuseless_nonterminals = nvars - nuseful_nonterminals;
@@ -236,7 +232,7 @@ reduce_grammar_tables (void)
/* Report and flag useless productions. */
{
rule_number r;
for (r = 0; r < nrules; r++)
for (r = 0; r < nrules; ++r)
rules[r].useful = bitset_test (P, r);
grammar_rules_useless_report (_("rule useless in grammar"));
}
@@ -257,8 +253,8 @@ reduce_grammar_tables (void)
for (r = 0; r < nrules; ++r)
{
item_number *rhsp = rules[r].rhs;
for (/* Nothing. */; *rhsp >= 0; ++rhsp)
/* Nothing. */;
for (/* Nothing. */; 0 <= *rhsp; ++rhsp)
continue;
*rhsp = rule_number_as_item_number (r);
rules[r].number = r;
}
@@ -289,31 +285,33 @@ nonterminals_reduce (void)
afterwards. Kept for later report. */
symbol_number *nontermmap = xnmalloc (nvars, sizeof *nontermmap);
symbol_number n = ntokens;
symbol_number i;
for (i = ntokens; i < nsyms; i++)
if (bitset_test (V, i))
nontermmap[i - ntokens] = n++;
for (i = ntokens; i < nsyms; i++)
if (!bitset_test (V, i))
{
{
symbol_number n = ntokens;
symbol_number i;
for (i = ntokens; i < nsyms; ++i)
if (bitset_test (V, i))
nontermmap[i - ntokens] = n++;
if (symbols[i]->status != used)
complain (&symbols[i]->location, Wother,
_("nonterminal useless in grammar: %s"),
symbols[i]->tag);
}
for (i = ntokens; i < nsyms; ++i)
if (!bitset_test (V, i))
{
nontermmap[i - ntokens] = n++;
if (symbols[i]->content->status != used)
complain (&symbols[i]->location, Wother,
_("nonterminal useless in grammar: %s"),
symbols[i]->tag);
}
}
/* Shuffle elements of tables indexed by symbol number. */
{
symbol **symbols_sorted = xnmalloc (nvars, sizeof *symbols_sorted);
for (i = ntokens; i < nsyms; i++)
symbols[i]->number = nontermmap[i - ntokens];
for (i = ntokens; i < nsyms; i++)
symbol_number i;
for (i = ntokens; i < nsyms; ++i)
symbols[i]->content->number = nontermmap[i - ntokens];
for (i = ntokens; i < nsyms; ++i)
symbols_sorted[nontermmap[i - ntokens] - ntokens] = symbols[i];
for (i = ntokens; i < nsyms; i++)
for (i = ntokens; i < nsyms; ++i)
symbols[i] = symbols_sorted[i - ntokens];
free (symbols_sorted);
}
@@ -323,12 +321,12 @@ nonterminals_reduce (void)
for (r = 0; r < nrules; ++r)
{
item_number *rhsp;
for (rhsp = rules[r].rhs; *rhsp >= 0; ++rhsp)
for (rhsp = rules[r].rhs; 0 <= *rhsp; ++rhsp)
if (ISVAR (*rhsp))
*rhsp = symbol_number_as_item_number (nontermmap[*rhsp
- ntokens]);
}
accept->number = nontermmap[accept->number - ntokens];
accept->content->number = nontermmap[accept->content->number - ntokens];
}
nsyms -= nuseless_nonterminals;
@@ -345,7 +343,7 @@ nonterminals_reduce (void)
void
reduce_output (FILE *out)
{
if (nuseless_nonterminals > 0)
if (nuseless_nonterminals)
{
int i;
fprintf (out, "%s\n\n", _("Nonterminals useless in grammar"));
@@ -357,7 +355,7 @@ reduce_output (FILE *out)
{
bool b = false;
int i;
for (i = 0; i < ntokens; i++)
for (i = 0; i < ntokens; ++i)
if (reduce_token_unused_in_grammar (i))
{
if (!b)
@@ -369,7 +367,7 @@ reduce_output (FILE *out)
fputs ("\n\n", out);
}
if (nuseless_productions > 0)
if (nuseless_productions)
grammar_rules_partial_print (out, _("Rules useless in grammar"),
rule_useless_in_grammar_p);
}
@@ -382,12 +380,12 @@ reduce_output (FILE *out)
static void
reduce_print (void)
{
if (nuseless_nonterminals > 0)
if (nuseless_nonterminals)
complain (NULL, Wother, ngettext ("%d nonterminal useless in grammar",
"%d nonterminals useless in grammar",
nuseless_nonterminals),
nuseless_nonterminals);
if (nuseless_productions > 0)
if (nuseless_productions)
complain (NULL, Wother, ngettext ("%d rule useless in grammar",
"%d rules useless in grammar",
nuseless_productions),
@@ -397,8 +395,6 @@ reduce_print (void)
void
reduce_grammar (void)
{
bool reduced;
/* Allocate the global sets used to compute the reduced grammar */
N = bitset_create (nvars, BITSET_FIXED);
@@ -409,13 +405,13 @@ reduce_grammar (void)
useless_nonterminals ();
inaccessable_symbols ();
reduced = (nuseless_nonterminals + nuseless_productions > 0);
if (!reduced)
/* Did we reduce something? */
if (!nuseless_nonterminals && !nuseless_productions)
return;
reduce_print ();
if (!bitset_test (N, accept->number - ntokens))
if (!bitset_test (N, accept->content->number - ntokens))
complain (&startsymbol_location, fatal,
_("start symbol %s does not derive any sentence"),
startsymbol->tag);
@@ -423,9 +419,9 @@ reduce_grammar (void)
/* First reduce the nonterminals, as they renumber themselves in the
whole grammar. If you change the order, nonterms would be
renumbered only in the reduced grammar. */
if (nuseless_nonterminals > 0)
if (nuseless_nonterminals)
nonterminals_reduce ();
if (nuseless_productions > 0)
if (nuseless_productions)
reduce_grammar_tables ();
if (trace_flag & trace_grammar)
@@ -446,10 +442,11 @@ reduce_token_unused_in_grammar (symbol_number i)
}
bool
reduce_nonterminal_useless_in_grammar (symbol_number i)
reduce_nonterminal_useless_in_grammar (const sym_content *sym)
{
aver (ntokens <= i && i < nsyms + nuseless_nonterminals);
return nsyms <= i;
symbol_number n = sym->number;
aver (ntokens <= n && n < nsyms + nuseless_nonterminals);
return nsyms <= n;
}
/*-----------------------------------------------------------.
+8 -3
View File
@@ -24,9 +24,14 @@
void reduce_grammar (void);
void reduce_output (FILE *out);
bool reduce_token_unused_in_grammar (symbol_number i);
bool reduce_nonterminal_useless_in_grammar (symbol_number i);
/** Whether symbol \a i is useless in the grammar.
* \pre reduce_grammar was called before.
*/
bool reduce_nonterminal_useless_in_grammar (const sym_content *sym);
void reduce_free (void);
extern symbol_number nuseless_nonterminals;
extern rule_number nuseless_productions;
extern unsigned nuseless_nonterminals;
extern unsigned nuseless_productions;
#endif /* !REDUCE_H_ */
+2 -2
View File
@@ -34,10 +34,10 @@ relation_print (relation r, relation_node size, FILE *out)
for (i = 0; i < size; ++i)
{
fprintf (out, "%3lu: ", (unsigned long int) i);
fprintf (out, "%3lu: ", (unsigned long) i);
if (r[i])
for (j = 0; r[i][j] != END_NODE; ++j)
fprintf (out, "%3lu ", (unsigned long int) r[i][j]);
fprintf (out, "%3lu ", (unsigned long) r[i][j]);
fputc ('\n', out);
}
fputc ('\n', out);
+9 -3
View File
@@ -23,6 +23,7 @@
# include "location.h"
# include "named-ref.h"
# include "uniqstr.h"
struct symbol_list;
@@ -81,8 +82,11 @@ typedef struct code_props {
/** \c NULL iff \c code_props::kind is not \c CODE_PROPS_RULE_ACTION. */
struct symbol_list *rule;
/* Named reference. */
/** Named reference. */
named_ref *named_ref;
/** Type, for mid-rule actions. */
uniqstr type;
} code_props;
/**
@@ -103,7 +107,8 @@ void code_props_none_init (code_props *self);
/* .is_predicate = */ false, \
/* .is_used = */ false, \
/* .rule = */ NULL, \
/* .named_ref = */ NULL \
/* .named_ref = */ NULL, \
/* .type = */ NULL, \
}
/** Initialized by \c CODE_PROPS_NONE_INIT with no further modification. */
@@ -158,7 +163,8 @@ void code_props_symbol_action_init (code_props *self, char const *code,
*/
void code_props_rule_action_init (code_props *self, char const *code,
location code_loc, struct symbol_list *rule,
named_ref *name, bool is_predicate);
named_ref *name, uniqstr type,
bool is_predicate);
/**
* \pre
+27 -34
View File
@@ -296,9 +296,7 @@ static variant *
variant_add (uniqstr id, location id_loc, unsigned symbol_index,
char *cp, char *cp_end, bool explicit_bracketing)
{
char *prefix_end;
prefix_end = find_prefix_end (id, cp, cp_end);
char *prefix_end = find_prefix_end (id, cp, cp_end);
if (prefix_end &&
(prefix_end == cp_end ||
(!explicit_bracketing && is_dot_or_dash (*prefix_end))))
@@ -340,8 +338,6 @@ show_sub_message (warnings warning,
var->id, at_spec);
else
{
static struct obstack msg_buf;
const char *tail = explicit_bracketing ? "" : cp + strlen (var->id);
const char *id;
location id_loc;
@@ -356,7 +352,10 @@ show_sub_message (warnings warning,
id_loc = var->loc;
}
const char *tail = explicit_bracketing ? "" : cp + strlen (var->id);
/* Create the explanation message. */
static struct obstack msg_buf;
obstack_init (&msg_buf);
obstack_printf (&msg_buf, _("possibly meant: %c"), dollar_or_at);
@@ -395,9 +394,7 @@ show_sub_messages (warnings warning,
int midrule_rhs_index, char dollar_or_at,
unsigned indent)
{
unsigned i;
for (i = 0; i < variant_count; ++i)
for (unsigned i = 0; i < variant_count; ++i)
show_sub_message (warning | silent,
cp, explicit_bracketing,
midrule_rhs_index, dollar_or_at,
@@ -415,24 +412,17 @@ show_sub_messages (warnings warning,
/* Parse named or positional reference. In case of positional
references, can return negative values for $-n "deep" stack
accesses. */
static long int
static long
parse_ref (char *cp, symbol_list *rule, int rule_length,
int midrule_rhs_index, char *text, location text_loc,
char dollar_or_at)
{
symbol_list *l;
char *cp_end;
bool explicit_bracketing;
unsigned i;
unsigned valid_variants = 0;
unsigned valid_variant_index = 0;
if ('$' == *cp)
return LHS_REF;
if (c_isdigit (*cp) || (*cp == '-' && c_isdigit (* (cp + 1))))
{
long int num = strtol (cp, &cp, 10);
long num = strtol (cp, &cp, 10);
if (1 - INT_MAX + rule_length <= num && num <= rule_length)
return num;
else
@@ -443,6 +433,9 @@ parse_ref (char *cp, symbol_list *rule, int rule_length,
}
}
char *cp_end;
bool explicit_bracketing;
if ('[' == *cp)
{
/* Ignore the brackets. */
@@ -473,16 +466,17 @@ parse_ref (char *cp, symbol_list *rule, int rule_length,
/* Add all relevant variants. */
{
unsigned symbol_index;
symbol_list *l;
variant_count = 0;
for (symbol_index = 0, l = rule; !symbol_list_null (l);
++symbol_index, l = l->next)
{
variant *var;
if (l->content_type != SYMLIST_SYMBOL)
continue;
var = variant_add (l->content.sym->tag, l->sym_loc,
symbol_index, cp, cp_end, explicit_bracketing);
variant *var
= variant_add (l->content.sym->tag, l->sym_loc,
symbol_index, cp, cp_end, explicit_bracketing);
if (var && l->named_ref)
var->hidden_by = l->named_ref;
@@ -493,7 +487,9 @@ parse_ref (char *cp, symbol_list *rule, int rule_length,
}
/* Check errors. */
for (i = 0; i < variant_count; ++i)
unsigned valid_variants = 0;
unsigned valid_variant_index = 0;
for (unsigned i = 0; i < variant_count; ++i)
{
variant *var = &variant_table[i];
unsigned symbol_index = var->symbol_index;
@@ -630,11 +626,8 @@ fetch_type_name (char *cp, char const **type_name,
static void
handle_action_dollar (symbol_list *rule, char *text, location dollar_loc)
{
char const *type_name = NULL;
char *cp = text + 1;
symbol_list *effective_rule;
int effective_rule_length;
int n;
if (rule->midrule_parent_rule)
{
@@ -648,10 +641,11 @@ handle_action_dollar (symbol_list *rule, char *text, location dollar_loc)
}
/* Get the type name if explicit. */
cp = fetch_type_name (cp, &type_name, dollar_loc);
char const *type_name = NULL;
char *cp = fetch_type_name (text + 1, &type_name, dollar_loc);
n = parse_ref (cp, effective_rule, effective_rule_length,
rule->midrule_parent_rhs_index, text, dollar_loc, '$');
int n = parse_ref (cp, effective_rule, effective_rule_length,
rule->midrule_parent_rhs_index, text, dollar_loc, '$');
/* End type_name. */
if (type_name)
@@ -726,10 +720,8 @@ handle_action_dollar (symbol_list *rule, char *text, location dollar_loc)
static void
handle_action_at (symbol_list *rule, char *text, location at_loc)
{
char *cp = text + 1;
symbol_list *effective_rule;
int effective_rule_length;
int n;
if (rule->midrule_parent_rule)
{
@@ -744,8 +736,8 @@ handle_action_at (symbol_list *rule, char *text, location at_loc)
muscle_percent_define_ensure("locations", at_loc, true);
n = parse_ref (cp, effective_rule, effective_rule_length,
rule->midrule_parent_rhs_index, text, at_loc, '@');
int n = parse_ref (text + 1, effective_rule, effective_rule_length,
rule->midrule_parent_rhs_index, text, at_loc, '@');
switch (n)
{
case INVALID_REF:
@@ -773,7 +765,6 @@ handle_action_at (symbol_list *rule, char *text, location at_loc)
static char const *
translate_action (code_props *self, int sc_context)
{
char *res;
static bool initialized = false;
if (!initialized)
{
@@ -784,7 +775,7 @@ translate_action (code_props *self, int sc_context)
loc->start = loc->end = self->location.start;
yy_switch_to_buffer (yy_scan_string (self->code));
res = code_lex (self, sc_context);
char *res = code_lex (self, sc_context);
yy_delete_buffer (YY_CURRENT_BUFFER);
return res;
@@ -825,7 +816,8 @@ code_props_symbol_action_init (code_props *self, char const *code,
void
code_props_rule_action_init (code_props *self, char const *code,
location code_loc, symbol_list *rule,
named_ref *name, bool is_predicate)
named_ref *name, uniqstr type,
bool is_predicate)
{
code_props_none_init (self);
self->kind = CODE_PROPS_RULE_ACTION;
@@ -833,6 +825,7 @@ code_props_rule_action_init (code_props *self, char const *code,
self->location = code_loc;
self->rule = rule;
self->named_ref = name;
self->type = type;
self->is_predicate = is_predicate;
}
+7 -7
View File
@@ -96,7 +96,7 @@ gram_scanner_last_string_free (void)
}
static void handle_syncline (char *, location);
static unsigned long int scan_integer (char const *p, int base, location loc);
static unsigned long scan_integer (char const *p, int base, location loc);
static int convert_ucn_to_byte (char const *hex_text);
static void unexpected_eof (boundary, char const *);
static void unexpected_newline (boundary, char const *);
@@ -591,7 +591,7 @@ eqopt ([[:space:]]*=)?
<SC_ESCAPED_STRING,SC_ESCAPED_CHARACTER>
{
\\[0-7]{1,3} {
unsigned long int c = strtoul (yytext + 1, NULL, 8);
unsigned long c = strtoul (yytext + 1, NULL, 8);
if (!c || UCHAR_MAX < c)
complain (loc, complaint, _("invalid number after \\-escape: %s"),
yytext+1);
@@ -601,7 +601,7 @@ eqopt ([[:space:]]*=)?
\\x[0-9abcdefABCDEF]+ {
verify (UCHAR_MAX < ULONG_MAX);
unsigned long int c = strtoul (yytext + 2, NULL, 16);
unsigned long c = strtoul (yytext + 2, NULL, 16);
if (!c || UCHAR_MAX < c)
complain (loc, complaint, _("invalid number after \\-escape: %s"),
yytext+1);
@@ -844,11 +844,11 @@ no_cr_read (FILE *fp, char *buf, size_t size)
| Scan NUMBER for a base-BASE integer at location LOC. |
`------------------------------------------------------*/
static unsigned long int
static unsigned long
scan_integer (char const *number, int base, location loc)
{
verify (INT_MAX < ULONG_MAX);
unsigned long int num = strtoul (number, NULL, base);
unsigned long num = strtoul (number, NULL, base);
if (INT_MAX < num)
{
@@ -871,7 +871,7 @@ static int
convert_ucn_to_byte (char const *ucn)
{
verify (UCHAR_MAX <= INT_MAX);
unsigned long int code = strtoul (ucn + 2, NULL, 16);
unsigned long code = strtoul (ucn + 2, NULL, 16);
/* FIXME: Currently we assume Unicode-compatible unibyte characters
on ASCII hosts (i.e., Latin-1 on hosts with 8-bit bytes). On
@@ -926,7 +926,7 @@ static void
handle_syncline (char *args, location loc)
{
char *file;
unsigned long int lineno = strtoul (args, &file, 10);
unsigned long lineno = strtoul (args, &file, 10);
if (INT_MAX <= lineno)
{
complain (&loc, Wother, _("line number overflow"));
+1 -1
View File
@@ -135,7 +135,7 @@ typedef struct
/* Is the TRANSITIONS->states[Num] labelled by the error token? */
# define TRANSITION_IS_ERROR(Transitions, Num) \
(TRANSITION_SYMBOL (Transitions, Num) == errtoken->number)
(TRANSITION_SYMBOL (Transitions, Num) == errtoken->content->number)
/* When resolving a SR conflicts, if the reduction wins, the shift is
disabled. */
+3 -3
View File
@@ -192,7 +192,7 @@ symbol_list_n_get (symbol_list *l, int n)
uniqstr
symbol_list_n_type_name_get (symbol_list *l, int n)
{
return symbol_list_n_get (l, n)->content.sym->type_name;
return symbol_list_n_get (l, n)->content.sym->content->type_name;
}
bool
@@ -210,8 +210,8 @@ symbol_list_code_props_set (symbol_list *node, code_props_type kind,
{
case SYMLIST_SYMBOL:
symbol_code_props_set (node->content.sym, kind, cprops);
if (node->content.sym->status == undeclared)
node->content.sym->status = used;
if (node->content.sym->content->status == undeclared)
node->content.sym->content->status = used;
break;
case SYMLIST_TYPE:
semantic_type_code_props_set
+197 -198
View File
@@ -58,6 +58,32 @@ static symgraph **prec_nodes;
bool *used_assoc = NULL;
/*--------------------------.
| Create a new sym_content. |
`--------------------------*/
static sym_content *
sym_content_new (symbol *s)
{
sym_content *res = xmalloc (sizeof *res);
res->symbol = s;
res->type_name = NULL;
for (int i = 0; i < CODE_PROPS_SIZE; ++i)
code_props_none_init (&res->props[i]);
res->number = NUMBER_UNDEFINED;
res->prec = 0;
res->assoc = undef_assoc;
res->user_token_number = USER_NUMBER_UNDEFINED;
res->class = unknown_sym;
res->status = undeclared;
return res;
}
/*---------------------------------.
| Create a new symbol, named TAG. |
`---------------------------------*/
@@ -76,22 +102,10 @@ symbol_new (uniqstr tag, location loc)
res->tag = tag;
res->location = loc;
res->type_name = NULL;
{
int i;
for (i = 0; i < CODE_PROPS_SIZE; ++i)
code_props_none_init (&res->props[i]);
}
res->number = NUMBER_UNDEFINED;
res->prec = 0;
res->assoc = undef_assoc;
res->user_token_number = USER_NUMBER_UNDEFINED;
res->location_of_lhs = false;
res->alias = NULL;
res->class = unknown_sym;
res->status = undeclared;
res->content = sym_content_new (res);
res->is_alias = false;
if (nsyms == SYMBOL_NUMBER_MAXIMUM)
complain (NULL, fatal, _("too many symbols in input grammar (limit is %d)"),
@@ -100,6 +114,31 @@ symbol_new (uniqstr tag, location loc)
return res;
}
/*--------------------.
| Free a sym_content. |
`--------------------*/
static void
sym_content_free (sym_content *sym)
{
free (sym);
}
/*---------------------------------------------------------.
| Free a symbol and its associated content if appropriate. |
`---------------------------------------------------------*/
static void
symbol_free (void *ptr)
{
symbol *sym = (symbol *)ptr;
if (!sym->is_alias)
sym_content_free (sym->content);
free (sym);
}
/* If needed, swap first and second so that first has the earliest
location (according to location_cmp).
@@ -148,6 +187,7 @@ code_props_type_string (code_props_type kind)
abort ();
}
/*----------------------------------------.
| Create a new semantic type, named TAG. |
`----------------------------------------*/
@@ -161,11 +201,8 @@ semantic_type_new (uniqstr tag, const location *loc)
res->tag = tag;
res->location = loc ? *loc : empty_location;
res->status = undeclared;
{
int i;
for (i = 0; i < CODE_PROPS_SIZE; ++i)
code_props_none_init (&res->props[i]);
}
for (int i = 0; i < CODE_PROPS_SIZE; ++i)
code_props_none_init (&res->props[i]);
return res;
}
@@ -176,12 +213,12 @@ semantic_type_new (uniqstr tag, const location *loc)
`-----------------*/
#define SYMBOL_ATTR_PRINT(Attr) \
if (s->Attr) \
fprintf (f, " %s { %s }", #Attr, s->Attr)
if (s->content->Attr) \
fprintf (f, " %s { %s }", #Attr, s->content->Attr)
#define SYMBOL_CODE_PRINT(Attr) \
if (s->props[Attr].code) \
fprintf (f, " %s { %s }", #Attr, s->props[Attr].code)
if (s->content->props[Attr].code) \
fprintf (f, " %s { %s }", #Attr, s->content->props[Attr].code)
void
symbol_print (symbol const *s, FILE *f)
@@ -228,7 +265,6 @@ is_identifier (uniqstr s)
uniqstr
symbol_id_get (symbol const *sym)
{
aver (sym->user_token_number != USER_NUMBER_HAS_STRING_ALIAS);
if (sym->alias)
sym = sym->alias;
return is_identifier (sym->tag) ? sym->tag : 0;
@@ -267,6 +303,13 @@ semantic_type_redeclaration (semantic_type *s, const char *what, location first,
}
void
symbol_location_as_lhs_set (symbol *sym, location loc)
{
if (!sym->location_of_lhs)
sym->location = loc;
}
/*-----------------------------------------------------------------.
| Set the TYPE_NAME associated with SYM. Does nothing if passed 0 |
@@ -278,13 +321,13 @@ symbol_type_set (symbol *sym, uniqstr type_name, location loc)
{
if (type_name)
{
if (sym->type_name)
symbol_redeclaration (sym, "%type", sym->type_location, loc);
if (sym->content->type_name)
symbol_redeclaration (sym, "%type", sym->content->type_location, loc);
else
{
uniqstr_assert (type_name);
sym->type_name = type_name;
sym->type_location = loc;
sym->content->type_name = type_name;
sym->content->type_location = loc;
}
}
}
@@ -297,12 +340,12 @@ void
symbol_code_props_set (symbol *sym, code_props_type kind,
code_props const *code)
{
if (sym->props[kind].code)
if (sym->content->props[kind].code)
symbol_redeclaration (sym, code_props_type_string (kind),
sym->props[kind].location,
sym->content->props[kind].location,
code->location);
else
sym->props[kind] = *code;
sym->content->props[kind] = *code;
}
/*-----------------------------------------------------.
@@ -330,14 +373,14 @@ code_props *
symbol_code_props_get (symbol *sym, code_props_type kind)
{
/* Per-symbol code props. */
if (sym->props[kind].code)
return &sym->props[kind];
if (sym->content->props[kind].code)
return &sym->content->props[kind];
/* Per-type code props. */
if (sym->type_name)
if (sym->content->type_name)
{
code_props *code =
&semantic_type_get (sym->type_name, NULL)->props[kind];
&semantic_type_get (sym->content->type_name, NULL)->props[kind];
if (code->code)
return code;
}
@@ -345,8 +388,8 @@ symbol_code_props_get (symbol *sym, code_props_type kind)
/* Apply default code props's only to user-defined symbols. */
if (sym->tag[0] != '$' && sym != errtoken)
{
code_props *code =
&semantic_type_get (sym->type_name ? "*" : "", NULL)->props[kind];
code_props *code = &semantic_type_get (sym->content->type_name ? "*" : "",
NULL)->props[kind];
if (code->code)
return code;
}
@@ -363,14 +406,15 @@ symbol_precedence_set (symbol *sym, int prec, assoc a, location loc)
{
if (a != undef_assoc)
{
if (sym->prec)
symbol_redeclaration (sym, assoc_to_string (a), sym->prec_location,
loc);
sym_content *s = sym->content;
if (s->prec)
symbol_redeclaration (sym, assoc_to_string (a),
s->prec_location, loc);
else
{
sym->prec = prec;
sym->assoc = a;
sym->prec_location = loc;
s->prec = prec;
s->assoc = a;
s->prec_location = loc;
}
}
@@ -387,26 +431,26 @@ void
symbol_class_set (symbol *sym, symbol_class class, location loc, bool declaring)
{
bool warned = false;
if (sym->class != unknown_sym && sym->class != class)
if (sym->content->class != unknown_sym && sym->content->class != class)
{
complain (&loc, complaint, _("symbol %s redefined"), sym->tag);
/* Don't report both "redefined" and "redeclared". */
warned = true;
}
if (class == nterm_sym && sym->class != nterm_sym)
sym->number = nvars++;
else if (class == token_sym && sym->number == NUMBER_UNDEFINED)
sym->number = ntokens++;
if (class == nterm_sym && sym->content->class != nterm_sym)
sym->content->number = nvars++;
else if (class == token_sym && sym->content->number == NUMBER_UNDEFINED)
sym->content->number = ntokens++;
sym->class = class;
sym->content->class = class;
if (declaring)
{
if (sym->status == declared && !warned)
if (sym->content->status == declared && !warned)
complain (&loc, Wother, _("symbol %s redeclared"), sym->tag);
else
sym->status = declared;
sym->content->status = declared;
}
}
@@ -420,10 +464,7 @@ symbol_user_token_number_set (symbol *sym, int user_token_number, location loc)
{
int *user_token_numberp;
if (sym->user_token_number != USER_NUMBER_HAS_STRING_ALIAS)
user_token_numberp = &sym->user_token_number;
else
user_token_numberp = &sym->alias->user_token_number;
user_token_numberp = &sym->content->user_token_number;
if (*user_token_numberp != USER_NUMBER_UNDEFINED
&& *user_token_numberp != user_token_number)
complain (&loc, complaint, _("redefining user token number of %s"),
@@ -433,12 +474,12 @@ symbol_user_token_number_set (symbol *sym, int user_token_number, location loc)
/* User defined $end token? */
if (user_token_number == 0)
{
endtoken = sym;
endtoken = sym->content->symbol;
/* It is always mapped to 0, so it was already counted in
NTOKENS. */
if (endtoken->number != NUMBER_UNDEFINED)
if (endtoken->content->number != NUMBER_UNDEFINED)
--ntokens;
endtoken->number = 0;
endtoken->content->number = 0;
}
}
@@ -451,29 +492,27 @@ symbol_user_token_number_set (symbol *sym, int user_token_number, location loc)
static inline bool
symbol_check_defined (symbol *sym)
{
if (sym->class == unknown_sym)
sym_content *s = sym->content;
if (s->class == unknown_sym)
{
assert (sym->status != declared);
assert (s->status != declared);
complain (&sym->location,
sym->status == needed ? complaint : Wother,
s->status == needed ? complaint : Wother,
_("symbol %s is used, but is not defined as a token"
" and has no rules"),
sym->tag);
sym->class = nterm_sym;
sym->number = nvars++;
s->class = nterm_sym;
s->number = nvars++;
}
{
int i;
for (i = 0; i < 2; ++i)
symbol_code_props_get (sym, i)->is_used = true;
}
for (int i = 0; i < 2; ++i)
symbol_code_props_get (sym, i)->is_used = true;
/* Set the semantic type status associated to the current symbol to
'declared' so that we could check semantic types unnecessary uses. */
if (sym->type_name)
if (s->type_name)
{
semantic_type *sem_type = semantic_type_get (sym->type_name, NULL);
semantic_type *sem_type = semantic_type_get (s->type_name, NULL);
if (sem_type)
sem_type->status = declared;
}
@@ -489,8 +528,7 @@ semantic_type_check_defined (semantic_type *sem_type)
|| !*sem_type->tag
|| STREQ (sem_type->tag, "*"))
{
int i;
for (i = 0; i < 2; ++i)
for (int i = 0; i < 2; ++i)
if (sem_type->props[i].kind != CODE_PROPS_NONE
&& ! sem_type->props[i].is_used)
complain (&sem_type->location, Wother,
@@ -519,6 +557,42 @@ semantic_type_check_defined_processor (void *sem_type,
}
/*-------------------------------------------------------------------.
| Merge the properties (precedence, associativity, etc.) of SYM, and |
| its string-named alias STR; check consistency. |
`-------------------------------------------------------------------*/
static void
symbol_merge_properties (symbol *sym, symbol *str)
{
if (str->content->type_name != sym->content->type_name)
{
if (str->content->type_name)
symbol_type_set (sym,
str->content->type_name, str->content->type_location);
else
symbol_type_set (str,
sym->content->type_name, sym->content->type_location);
}
for (int i = 0; i < CODE_PROPS_SIZE; ++i)
if (str->content->props[i].code)
symbol_code_props_set (sym, i, &str->content->props[i]);
else if (sym->content->props[i].code)
symbol_code_props_set (str, i, &sym->content->props[i]);
if (sym->content->prec || str->content->prec)
{
if (str->content->prec)
symbol_precedence_set (sym, str->content->prec, str->content->assoc,
str->content->prec_location);
else
symbol_precedence_set (str, sym->content->prec, sym->content->assoc,
sym->content->prec_location);
}
}
void
symbol_make_alias (symbol *sym, symbol *str, location loc)
{
@@ -530,71 +604,17 @@ symbol_make_alias (symbol *sym, symbol *str, location loc)
_("symbol %s given more than one literal string"), sym->tag);
else
{
str->class = token_sym;
str->user_token_number = sym->user_token_number;
sym->user_token_number = USER_NUMBER_HAS_STRING_ALIAS;
symbol_merge_properties (sym, str);
sym_content_free (str->content);
str->content = sym->content;
str->content->symbol = str;
str->is_alias = true;
str->alias = sym;
sym->alias = str;
str->number = sym->number;
symbol_type_set (str, sym->type_name, loc);
}
}
/*---------------------------------------------------------.
| Check that THIS, and its alias, have same precedence and |
| associativity. |
`---------------------------------------------------------*/
static inline void
symbol_check_alias_consistency (symbol *this)
{
symbol *sym = this;
symbol *str = this->alias;
/* Check only the symbol in the symbol-string pair. */
if (!(this->alias
&& this->user_token_number == USER_NUMBER_HAS_STRING_ALIAS))
return;
if (str->type_name != sym->type_name)
{
if (str->type_name)
symbol_type_set (sym, str->type_name, str->type_location);
else
symbol_type_set (str, sym->type_name, sym->type_location);
}
{
int i;
for (i = 0; i < CODE_PROPS_SIZE; ++i)
if (str->props[i].code)
symbol_code_props_set (sym, i, &str->props[i]);
else if (sym->props[i].code)
symbol_code_props_set (str, i, &sym->props[i]);
}
if (sym->prec || str->prec)
{
if (str->prec)
symbol_precedence_set (sym, str->prec, str->assoc,
str->prec_location);
else
symbol_precedence_set (str, sym->prec, sym->assoc,
sym->prec_location);
}
}
static bool
symbol_check_alias_consistency_processor (void *this,
void *null ATTRIBUTE_UNUSED)
{
symbol_check_alias_consistency (this);
return true;
}
/*-------------------------------------------------------------------.
| Assign a symbol number, and write the definition of the token name |
| into FDEFINES. Put in SYMBOLS. |
@@ -603,13 +623,11 @@ symbol_check_alias_consistency_processor (void *this,
static inline bool
symbol_pack (symbol *this)
{
aver (this->number != NUMBER_UNDEFINED);
if (this->class == nterm_sym)
this->number += ntokens;
else if (this->user_token_number == USER_NUMBER_HAS_STRING_ALIAS)
return true;
aver (this->content->number != NUMBER_UNDEFINED);
if (this->content->class == nterm_sym)
this->content->number += ntokens;
symbols[this->number] = this;
symbols[this->content->number] = this->content->symbol;
return true;
}
@@ -619,7 +637,6 @@ symbol_pack_processor (void *this, void *null ATTRIBUTE_UNUSED)
return symbol_pack (this);
}
static void
user_token_number_redeclaration (int num, symbol *first, symbol *second)
{
@@ -642,17 +659,18 @@ static inline bool
symbol_translation (symbol *this)
{
/* Non-terminal? */
if (this->class == token_sym
&& this->user_token_number != USER_NUMBER_HAS_STRING_ALIAS)
if (this->content->class == token_sym
&& !this->is_alias)
{
/* A token which translation has already been set? */
if (token_translations[this->user_token_number] != undeftoken->number)
/* A token which translation has already been set?*/
if (token_translations[this->content->user_token_number]
!= undeftoken->content->number)
user_token_number_redeclaration
(this->user_token_number,
symbols[token_translations[this->user_token_number]],
this);
(this->content->user_token_number,
symbols[token_translations[this->content->user_token_number]], this);
else
token_translations[this->user_token_number] = this->number;
token_translations[this->content->user_token_number]
= this->content->number;
}
return true;
@@ -738,7 +756,7 @@ symbols_new (void)
NULL,
hash_symbol_hasher,
hash_symbol_comparator,
free);
symbol_free);
semantic_type_table = hash_initialize (HT_INITIAL_CAPACITY,
NULL,
hash_semantic_type_hasher,
@@ -756,10 +774,9 @@ symbol *
symbol_from_uniqstr (const uniqstr key, location loc)
{
symbol probe;
symbol *entry;
probe.tag = key;
entry = hash_lookup (symbol_table, &probe);
symbol *entry = hash_lookup (symbol_table, &probe);
if (!entry)
{
@@ -782,10 +799,9 @@ semantic_type *
semantic_type_from_uniqstr (const uniqstr key, const location *loc)
{
semantic_type probe;
semantic_type *entry;
probe.tag = key;
entry = hash_lookup (semantic_type_table, &probe);
semantic_type *entry = hash_lookup (semantic_type_table, &probe);
if (!entry)
{
@@ -834,12 +850,10 @@ dummy_symbol_get (location loc)
static int dummy_count = 0;
static char buf[256];
symbol *sym;
sprintf (buf, "$@%d", ++dummy_count);
sym = symbol_get (buf, loc);
sym->class = nterm_sym;
sym->number = nvars++;
symbol *sym = symbol_get (buf, loc);
sym->content->class = nterm_sym;
sym->content->number = nvars++;
return sym;
}
@@ -892,11 +906,8 @@ symbols_do (Hash_processor processor, void *processor_data,
hash_get_entries (table, (void**)*sorted, count);
qsort (*sorted, count, sizeof **sorted, symbols_cmp_qsort);
}
{
size_t i;
for (i = 0; i < count; ++i)
processor ((*sorted)[i], processor_data);
}
for (size_t i = 0; i < count; ++i)
processor ((*sorted)[i], processor_data);
}
/*--------------------------------------------------------------.
@@ -922,14 +933,13 @@ static void
symbols_token_translations_init (void)
{
bool num_256_available_p = true;
int i;
/* Find the highest user token number, and whether 256, the POSIX
preferred user token number for the error token, is used. */
max_user_token_number = 0;
for (i = 0; i < ntokens; ++i)
for (int i = 0; i < ntokens; ++i)
{
symbol *this = symbols[i];
sym_content *this = symbols[i]->content;
if (this->user_token_number != USER_NUMBER_UNDEFINED)
{
if (this->user_token_number > max_user_token_number)
@@ -941,16 +951,16 @@ symbols_token_translations_init (void)
/* If 256 is not used, assign it to error, to follow POSIX. */
if (num_256_available_p
&& errtoken->user_token_number == USER_NUMBER_UNDEFINED)
errtoken->user_token_number = 256;
&& errtoken->content->user_token_number == USER_NUMBER_UNDEFINED)
errtoken->content->user_token_number = 256;
/* Set the missing user numbers. */
if (max_user_token_number < 256)
max_user_token_number = 256;
for (i = 0; i < ntokens; ++i)
for (int i = 0; i < ntokens; ++i)
{
symbol *this = symbols[i];
sym_content *this = symbols[i]->content;
if (this->user_token_number == USER_NUMBER_UNDEFINED)
this->user_token_number = ++max_user_token_number;
if (this->user_token_number > max_user_token_number)
@@ -962,8 +972,8 @@ symbols_token_translations_init (void)
/* Initialize all entries for literal tokens to the internal token
number for $undefined, which represents all invalid inputs. */
for (i = 0; i < max_user_token_number + 1; i++)
token_translations[i] = undeftoken->number;
for (int i = 0; i < max_user_token_number + 1; i++)
token_translations[i] = undeftoken->content->number;
symbols_do (symbol_translation_processor, NULL,
symbol_table, &symbols_sorted);
}
@@ -977,18 +987,13 @@ symbols_token_translations_init (void)
void
symbols_pack (void)
{
symbols_do (symbol_check_alias_consistency_processor, NULL,
symbol_table, &symbols_sorted);
symbols = xcalloc (nsyms, sizeof *symbols);
symbols_do (symbol_pack_processor, NULL, symbol_table, &symbols_sorted);
/* Aliases leave empty slots in symbols, so remove them. */
{
int writei;
int readi;
int nsyms_old = nsyms;
for (writei = 0, readi = 0; readi < nsyms_old; readi += 1)
for (int writei = 0, readi = 0; readi < nsyms_old; readi += 1)
{
if (symbols[readi] == NULL)
{
@@ -998,9 +1003,7 @@ symbols_pack (void)
else
{
symbols[writei] = symbols[readi];
symbols[writei]->number = writei;
if (symbols[writei]->alias)
symbols[writei]->alias->number = writei;
symbols[writei]->content->number = writei;
writei += 1;
}
}
@@ -1009,11 +1012,11 @@ symbols_pack (void)
symbols_token_translations_init ();
if (startsymbol->class == unknown_sym)
if (startsymbol->content->class == unknown_sym)
complain (&startsymbol_location, fatal,
_("the start symbol %s is undefined"),
startsymbol->tag);
else if (startsymbol->class == token_sym)
else if (startsymbol->content->class == token_sym)
complain (&startsymbol_location, fatal,
_("the start symbol %s is a token"),
startsymbol->tag);
@@ -1026,9 +1029,8 @@ symbols_pack (void)
static void
init_prec_nodes (void)
{
int i;
prec_nodes = xcalloc (nsyms, sizeof *prec_nodes);
for (i = 0; i < nsyms; ++i)
for (int i = 0; i < nsyms; ++i)
{
prec_nodes[i] = xmalloc (sizeof *prec_nodes[i]);
symgraph *s = prec_nodes[i];
@@ -1119,8 +1121,7 @@ linkedlist_free (symgraphlink *node)
static void
assoc_free (void)
{
int i;
for (i = 0; i < nsyms; ++i)
for (int i = 0; i < nsyms; ++i)
{
linkedlist_free (prec_nodes[i]->pred);
linkedlist_free (prec_nodes[i]->succ);
@@ -1136,9 +1137,8 @@ assoc_free (void)
static void
init_assoc (void)
{
graphid i;
used_assoc = xcalloc (nsyms, sizeof *used_assoc);
for (i = 0; i < nsyms; ++i)
for (graphid i = 0; i < nsyms; ++i)
used_assoc[i] = false;
}
@@ -1150,9 +1150,9 @@ static inline bool
is_assoc_useless (symbol *s)
{
return s
&& s->assoc != undef_assoc
&& s->assoc != precedence_assoc
&& !used_assoc[s->number];
&& s->content->assoc != undef_assoc
&& s->content->assoc != precedence_assoc
&& !used_assoc[s->content->number];
}
/*-------------------------------.
@@ -1175,28 +1175,27 @@ register_assoc (graphid i, graphid j)
void
print_precedence_warnings (void)
{
int i;
if (!prec_nodes)
init_prec_nodes ();
if (!used_assoc)
init_assoc ();
for (i = 0; i < nsyms; ++i)
for (int i = 0; i < nsyms; ++i)
{
symbol *s = symbols[i];
if (s
&& s->prec != 0
&& s->content->prec != 0
&& !prec_nodes[i]->pred
&& !prec_nodes[i]->succ)
{
if (is_assoc_useless (s))
complain (&s->prec_location, Wprecedence,
complain (&s->content->prec_location, Wprecedence,
_("useless precedence and associativity for %s"), s->tag);
else if (s->assoc == precedence_assoc)
complain (&s->prec_location, Wprecedence,
else if (s->content->assoc == precedence_assoc)
complain (&s->content->prec_location, Wprecedence,
_("useless precedence for %s"), s->tag);
}
else if (is_assoc_useless (s))
complain (&s->prec_location, Wprecedence,
complain (&s->content->prec_location, Wprecedence,
_("useless associativity for %s, use %%precedence"), s->tag);
}
free (used_assoc);
+31 -13
View File
@@ -50,6 +50,7 @@ typedef int symbol_number;
typedef struct symbol symbol;
typedef struct sym_content sym_content;
/* Declaration status of a symbol.
@@ -82,15 +83,36 @@ typedef enum code_props_type code_props_type;
enum { CODE_PROPS_SIZE = 2 };
/* When extending this structure, be sure to complete
symbol_check_alias_consistency. */
struct symbol
{
/** The key, name of the symbol. */
uniqstr tag;
/** The location of its first occurrence. */
/** The "defining" location. */
location location;
/** Whether \a location is about the first uses as left-hand side
symbol of a rule (true), or simply the first occurrence (e.g.,
in a %type, or as a rhs symbol of a rule). The former type of
location is more natural in error messages. This Boolean helps
moving from location of the first occurrence to first use as
lhs. */
bool location_of_lhs;
/** Points to the other in the symbol-string pair for an alias. */
symbol *alias;
/** Whether this symbol is the alias of another or not. */
bool is_alias;
/** All the info about the pointed symbol is there. */
sym_content *content;
};
struct sym_content
{
symbol *symbol;
/** Its \c \%type.
Beware that this is the type_name as was entered by the user,
@@ -117,10 +139,6 @@ struct symbol
assoc assoc;
int user_token_number;
/* Points to the other in the symbol-string pair for an alias.
Special value USER_NUMBER_HAS_STRING_ALIAS in the symbol half of the
symbol-string pair for an alias. */
symbol *alias;
symbol_class class;
status status;
};
@@ -128,12 +146,6 @@ struct symbol
/** Undefined user number. */
# define USER_NUMBER_UNDEFINED -1
/* 'symbol->user_token_number == USER_NUMBER_HAS_STRING_ALIAS' means
this symbol has a literal string alias. For instance, '%token foo
"foo"' has '"foo"' numbered regularly, and 'foo' numbered as
USER_NUMBER_HAS_STRING_ALIAS. */
# define USER_NUMBER_HAS_STRING_ALIAS -9991
/* Undefined internal token number. */
# define NUMBER_UNDEFINED (-1)
@@ -174,6 +186,12 @@ uniqstr symbol_id_get (symbol const *sym);
*/
void symbol_make_alias (symbol *sym, symbol *str, location loc);
/**
* This symbol is used as the lhs of a rule. Record this location
* as definition point, if not already done.
*/
void symbol_location_as_lhs_set (symbol *sym, location loc);
/** Set the \c type_name associated with \c sym.
Do nothing if passed 0 as \c type_name. */
+8 -8
View File
@@ -83,7 +83,7 @@ int nvectors;
static base_number **froms;
static base_number **tos;
static unsigned int **conflict_tos;
static unsigned **conflict_tos;
static size_t *tally;
static base_number *width;
@@ -112,9 +112,9 @@ base_number *base = NULL;
base_number base_ninf = 0;
static base_number *pos = NULL;
static unsigned int *conflrow;
unsigned int *conflict_table;
unsigned int *conflict_list;
static unsigned *conflrow;
unsigned *conflict_table;
unsigned *conflict_list;
int conflict_list_cnt;
static int conflict_list_free;
@@ -290,7 +290,7 @@ action_row (state *s)
/* Do not use any default reduction if there is a shift for
error */
if (sym == errtoken->number)
if (sym == errtoken->content->number)
nodefault = true;
}
@@ -300,7 +300,7 @@ action_row (state *s)
for (i = 0; i < errp->num; i++)
{
symbol *sym = errp->symbols[i];
actrow[sym->number] = ACTION_NUMBER_MINIMUM;
actrow[sym->content->number] = ACTION_NUMBER_MINIMUM;
}
/* Turn off default reductions where requested by the user. See
@@ -394,7 +394,7 @@ save_row (state_number s)
/* Allocate non defaulted actions. */
base_number *sp1 = froms[s] = xnmalloc (count, sizeof *sp1);
base_number *sp2 = tos[s] = xnmalloc (count, sizeof *sp2);
unsigned int *sp3 = conflict_tos[s] =
unsigned *sp3 = conflict_tos[s] =
nondeterministic_parser ? xnmalloc (count, sizeof *sp3) : NULL;
/* Store non defaulted actions. */
@@ -670,7 +670,7 @@ pack_vector (vector_number vector)
size_t t = tally[i];
base_number *from = froms[i];
base_number *to = tos[i];
unsigned int *conflict_to = conflict_tos[i];
unsigned *conflict_to = conflict_tos[i];
aver (t != 0);
+2 -2
View File
@@ -122,8 +122,8 @@ extern base_number *base;
keep parser tables small. */
extern base_number base_ninf;
extern unsigned int *conflict_table;
extern unsigned int *conflict_list;
extern unsigned *conflict_table;
extern unsigned *conflict_list;
extern int conflict_list_cnt;
extern base_number *table;
+71 -22
View File
@@ -1,4 +1,4 @@
e# Executing Actions. -*- Autotest -*-
# Executing Actions. -*- Autotest -*-
# Copyright (C) 2001-2015, 2018 Free Software Foundation, Inc.
@@ -64,6 +64,55 @@ AT_PARSER_CHECK([./input], 0,
AT_CLEANUP
## ------------------------ ##
## Typed mid-rule actions. ##
## ------------------------ ##
AT_SETUP([Typed mid-rule actions])
AT_BISON_OPTION_PUSHDEFS
AT_DATA_GRAMMAR([[input.y]],
[[%define parse.error verbose
%debug
%code {
]AT_YYERROR_DECLARE[
]AT_YYLEX_DECLARE[
}
%union {
int ival;
}
%type <ival> exp
%%
exp: <ival>{ $$ = 0; }
'1' <ival>{ $$ = 1; }
'2' <ival>{ $$ = 2; }
'3' <ival>{ $$ = 3; }
'4' <ival>{ $$ = 4; }
'5' <ival>{ $$ = 5; }
'6' <ival>{ $$ = 6; }
'7' <ival>{ $$ = 7; }
'8' <ival>{ $$ = 8; }
'9' <ival>{ $$ = 9; } <ival>{ $$ = 10; } <ival>{ $$ = 11; }
{
$$ = $1 + $3 + $5 + $7 + $9 + $11 + $13 + $15 + $17 + $19 + $20 + $21;
printf ("%d\n", $$);
}
;
%%
]AT_YYERROR_DEFINE[
]AT_YYLEX_DEFINE(["123456789"])[
]AT_MAIN_DEFINE[
]])
AT_BISON_OPTION_POPDEFS
AT_BISON_CHECK([-d -v -o input.c input.y])
AT_COMPILE([input])
AT_PARSER_CHECK([./input], 0,
[[66
]])
AT_CLEANUP
## ----------------------- ##
## Implicitly empty rule. ##
## ----------------------- ##
@@ -515,11 +564,11 @@ AT_LALR1_CC_IF([typedef yy::location YYLTYPE;])[
thing
%destructor
{ fprintf (stderr, "Freeing raise thing (%d@%d-%d)\n", $$, RANGE (@$)); }
{ fprintf (stderr, "Freeing nterm raise (%d@%d-%d)\n", $$, RANGE (@$)); }
raise
%destructor
{ fprintf (stderr, "Freeing check-spontaneous-errors thing (%d@%d-%d)\n", $$, RANGE (@$)); }
{ fprintf (stderr, "Freeing nterm check-spontaneous-errors (%d@%d-%d)\n", $$, RANGE (@$)); }
check-spontaneous-errors
%destructor
@@ -645,9 +694,9 @@ const char *source = YY_NULLPTR;
static
]AT_YYLEX_PROTOTYPE[
{
static unsigned int counter = 0;
static unsigned counter = 0;
unsigned int c = ]AT_VAL[]m4_ifval([$6], [.ival])[ = counter++;
unsigned c = ]AT_VAL[]m4_ifval([$6], [.ival])[ = counter++;
/* As in BASIC, line numbers go from 10 to 10. */
]AT_LOC_FIRST_LINE[ = ]AT_LOC_FIRST_COLUMN[ = 10 * c;
]AT_LOC_LAST_LINE[ = ]AT_LOC_LAST_COLUMN[ = ]AT_LOC_FIRST_LINE[ + 9;
@@ -953,7 +1002,7 @@ AT_DATA_GRAMMAR([[input.y]],
}
%printer {
fprintf (yyoutput, "<*> printer should not be called.\n");
#error "<*> printer should not be used."
} <*>
%printer {
@@ -971,7 +1020,7 @@ AT_DATA_GRAMMAR([[input.y]],
} 'b' 'c'
%destructor {
fprintf (yyoutput, "<*> destructor should not be called.\n");
#error "<*> destructor should not be used."
} <*>
%%
@@ -1045,7 +1094,7 @@ AT_DATA_GRAMMAR([[input.y]],
%}
%printer {
fprintf (yyoutput, "<> printer should not be called.\n");
#error "<> printer should not be used."
} <>
%union { int field0; int field1; int field2; }
@@ -1072,7 +1121,7 @@ AT_DATA_GRAMMAR([[input.y]],
%destructor { fprintf (stdout, "'d' destructor.\n"); } 'd'
%destructor {
fprintf (yyoutput, "<> destructor should not be called.\n");
#error "<> destructor should not be used."
} <>
%%
@@ -1173,7 +1222,7 @@ AT_DATA_GRAMMAR([[input]]$1[[.y]],
}
%destructor {
fprintf (yyoutput, "<]]not_kind[[> destructor should not be called.\n");
#error "<]]not_kind[[> destructor should not be used."
} <]]not_kind[[>
%token END 0
@@ -1185,7 +1234,7 @@ AT_DATA_GRAMMAR([[input]]$1[[.y]],
} <]]kind[[>
%printer {
fprintf (yyoutput, "<]]not_kind[[> printer should not be called.\n");
#error "<]]not_kind[[> printer should not be used."
} <]]not_kind[[>
]]m4_if($1, 0, [[[
@@ -1433,10 +1482,10 @@ AT_DATA_GRAMMAR([[input.y]],
# define LOCATION_PRINT(File, Loc)
%}
%printer { fprintf (yyoutput, "%d", @$); } <>
%printer { fprintf (yyoutput, "%d", @$); } <>
%destructor { fprintf (stderr, "DESTROY %d\n", @$); } <>
%printer { fprintf (yyoutput, "<*> printer should not be called"); } <*>
%destructor { fprintf (yyoutput, "<*> destructor should not be called"); } <*>
%printer { #error "<*> printer should not be used" } <*>
%destructor { #error "<*> destructor should not be used" } <*>
%%
@@ -1457,19 +1506,19 @@ start:
AT_BISON_OPTION_POPDEFS
AT_BISON_CHECK([-o input.c input.y], 0,,
[[input.y:24.70-72: warning: useless %destructor for type <*> [-Wother]
input.y:24.70-72: warning: useless %printer for type <*> [-Wother]
[[input.y:24.57-59: warning: useless %destructor for type <*> [-Wother]
input.y:24.57-59: warning: useless %printer for type <*> [-Wother]
input.y:33.3-23: warning: unset value: $$ [-Wother]
input.y:32.3-23: warning: unused value: $3 [-Wother]
]])
AT_BISON_CHECK([-fcaret -o input.c input.y], 0,,
[[input.y:24.70-72: warning: useless %destructor for type <*> [-Wother]
%printer { fprintf (yyoutput, "<*> printer should not be called"); } <*>
^^^
input.y:24.70-72: warning: useless %printer for type <*> [-Wother]
%printer { fprintf (yyoutput, "<*> printer should not be called"); } <*>
^^^
[[input.y:24.57-59: warning: useless %destructor for type <*> [-Wother]
%printer { #error "<*> printer should not be used" } <*>
^^^
input.y:24.57-59: warning: useless %printer for type <*> [-Wother]
%printer { #error "<*> printer should not be used" } <*>
^^^
input.y:33.3-23: warning: unset value: $$ [-Wother]
{ @$ = 4; } // Only used.
^^^^^^^^^^^^^^^^^^^^^
+3
View File
@@ -50,6 +50,9 @@ CXXFLAGS="$NO_WERROR_CXXFLAGS @WERROR_CXXFLAGS@"
# If 'exit 77'; skip all C++ tests; otherwise ':'.
BISON_CXX_WORKS='@BISON_CXX_WORKS@'
# Compiler flags to disable exception support.
CXXFLAGS_NO_EXCEPTIONS='@CXXFLAGS_NO_EXCEPTIONS@'
# Be sure that the C++ compiler is not broken because of gnulib. This
# cannot be checked in configure (gnulib is not parameterized yet),
# and checking this in every C++ test in AC_COMPILE_CXX is too costly.
+133 -5
View File
@@ -19,11 +19,11 @@
AT_BANNER([[C++ Features.]])
## --------------- ##
## C++ Locations. ##
## --------------- ##
## -------------------------- ##
## C++ Locations Unit Tests. ##
## -------------------------- ##
AT_SETUP([C++ Locations])
AT_SETUP([C++ Locations Unit Tests])
AT_BISON_OPTION_PUSHDEFS([%locations %skeleton "lalr1.cc"])
AT_DATA_GRAMMAR([[input.y]],
@@ -185,6 +185,8 @@ AT_CLEANUP
m4_pushdef([AT_TEST],
[AT_SETUP([Variants $1])
AT_KEYWORDS([variant])
AT_BISON_OPTION_PUSHDEFS([%debug $1])
# Store strings and integers in a vector of strings.
AT_DATA_GRAMMAR([list.y],
@@ -375,7 +377,7 @@ AT_BISON_OPTION_POPDEFS
AT_CLEANUP
])
AT_TEST([[%skeleton "lalr1.cc" ]])
AT_TEST([[%skeleton "lalr1.cc"]])
AT_TEST([[%skeleton "lalr1.cc" %define parse.assert]])
AT_TEST([[%skeleton "lalr1.cc" %define parse.assert %locations]])
AT_TEST([[%skeleton "lalr1.cc" %define parse.assert %code {\n#define TWO_STAGE_BUILD\n}]])
@@ -386,6 +388,132 @@ AT_TEST([[%skeleton "lalr1.cc" %define parse.assert %define api.token.constructo
m4_popdef([AT_TEST])
## ------------------------------------- ##
## Variants and Typed Mid-rule Actions. ##
## ------------------------------------- ##
AT_SETUP([Variants and Typed Mid-rule Actions])
# See http://lists.gnu.org/archive/html/bug-bison/2017-06/msg00000.html.
#
# Check that typed mid-rule actions behave properly (pre-construction
# of $$ before the user action, support of %printer and %destructor,
# etc.).
AT_BISON_OPTION_PUSHDEFS([%skeleton "lalr1.cc"])
AT_DATA_GRAMMAR([[input.y]],
[[%skeleton "lalr1.cc"
%defines
%debug
%define parse.assert
%define api.value.type variant
%define api.token.constructor
%error-verbose
%code
{
#include <iostream>
namespace yy
{
static yy::parser::symbol_type yylex();
}
}
%token <int> NUMBER;
%nterm <int> expr;
%token EOI 0;
%printer { yyo << $$; } <int>;
%destructor { std::cerr << "destroy: " << $$ << '\n'; } <int>
%%
expr:
NUMBER { $$ = $1 * 10; }
| expr <int>{ $$ = 20; } NUMBER
{
std::cerr << "expr: " << $1 << ' ' << $2 << ' ' << $3 << '\n';
$$ = 40;
}
;
%%
namespace yy
{
parser::symbol_type yylex()
{
static int loc = 0;
switch (loc++)
{
case 0:
return parser::make_NUMBER (1);
case 1:
return parser::make_NUMBER (30);
default:
return parser::make_EOI ();
}
}
void parser::error(const std::string& message)
{
std::cerr << message << '\n';
}
}
int main()
{
yy::parser p;
p.set_debug_level (1);
return p.parse();
}
]])
AT_FULL_COMPILE([[input]])
# This used to print "Discarding 'a'." again at the end.
AT_PARSER_CHECK([[./input]], [[0]], [[]],
[[Starting parse
Entering state 0
Reading a token: Next token is token NUMBER (1)
Shifting token NUMBER (1)
Entering state 1
Reducing stack by rule 1 (line 34):
$1 = token NUMBER (1)
-> $$ = nterm expr (10)
destroy: 1
Stack now 0
Entering state 2
Reading a token: Next token is token NUMBER (30)
Reducing stack by rule 2 (line 35):
-> $$ = nterm @1 (20)
Stack now 2 0
Entering state 4
Next token is token NUMBER (30)
Shifting token NUMBER (30)
Entering state 5
Reducing stack by rule 3 (line 35):
$1 = nterm expr (10)
$2 = nterm @1 (20)
$3 = token NUMBER (30)
expr: 10 20 30
-> $$ = nterm expr (40)
destroy: 30
destroy: 20
destroy: 10
Stack now 0
Entering state 2
Reading a token: Next token is token EOI ()
Shifting token EOI ()
Entering state 3
Cleanup: popping token EOI ()
Cleanup: popping nterm expr (40)
destroy: 40
]])
AT_BISON_OPTION_POPDEFS
AT_CLEANUP
## ----------------------- ##
## Doxygen Documentation. ##
## ----------------------- ##
+22 -17
View File
@@ -49,15 +49,18 @@ m4_pushdef([AT_CALC_MAIN],
#include <unistd.h>
AT_SKEL_CC_IF([[
/* A C++ ]AT_NAME_PREFIX[parse that simulates the C signature. */
int
]AT_NAME_PREFIX[parse (]AT_PARAM_IF([semantic_value *result, int *count]))[
namespace
{
]AT_NAME_PREFIX[::parser parser]AT_PARAM_IF([ (result, count)])[;
#if ]AT_API_PREFIX[DEBUG
parser.set_debug_level (1);
#endif
return parser.parse ();
/* A C++ ]AT_NAME_PREFIX[parse that simulates the C signature. */
int
]AT_NAME_PREFIX[parse (]AT_PARAM_IF([semantic_value *result, int *count]))[
{
]AT_NAME_PREFIX[::parser parser]AT_PARAM_IF([ (result, count)])[;
#if ]AT_API_PREFIX[DEBUG
parser.set_debug_level (1);
#endif
return parser.parse ();
}
}
]])[
@@ -105,8 +108,6 @@ m4_pushdef([AT_CALC_LEX],
[[#include <ctype.h>
]AT_YYLEX_DECLARE_EXTERN[
static int get_char (]AT_YYLEX_FORMALS[);
static void unget_char (]AT_YYLEX_PRE_FORMALS[ int c);
]AT_LOCATION_IF([
static AT_YYLTYPE last_yylloc;
@@ -322,7 +323,7 @@ exp:
;
%%
static int
int
power (int base, int exponent)
{
int res = 1;
@@ -334,6 +335,8 @@ power (int base, int exponent)
]AT_SKEL_CC_IF(
[AT_LOCATION_TYPE_IF([[
namespace
{
std::ostream&
operator<< (std::ostream& o, const Span& s)
{
@@ -344,6 +347,7 @@ power (int base, int exponent)
o << '-' << s.last.c - 1;
return o;
}
}
]])])[
]AT_YYERROR_DEFINE[
]AT_DEFINES_IF([],
@@ -477,20 +481,20 @@ m4_define([AT_CHECK_SPACES],
])
# AT_CHECK_CALC([BISON-OPTIONS])
# ------------------------------
# AT_CHECK_CALC([BISON-OPTIONS], [COMPILER-OPTIONS])
# --------------------------------------------------
# Start a testing chunk which compiles 'calc' grammar with
# BISON-OPTIONS, and performs several tests over the parser.
m4_define([AT_CHECK_CALC],
[m4_ifval([$2], [m4_fatal([$0: expected a single argument])])
[m4_ifval([$3], [m4_fatal([$0: expected at most two arguments])])
# We use integers to avoid dependencies upon the precision of doubles.
AT_SETUP([Calculator $1])
AT_SETUP([Calculator $1 $2])
AT_BISON_OPTION_PUSHDEFS([$1])
AT_DATA_CALC_Y([$1])
AT_FULL_COMPILE([calc], AT_DEFINES_IF([[lex], [main]]))
AT_FULL_COMPILE([calc], AT_DEFINES_IF([[lex], [main]]), [], [$2])
AT_CHECK_SPACES(m4_join([ ],
[calc.AT_SKEL_CC_IF([cc], [c])],
[AT_DEFINES_IF([calc.AT_SKEL_CC_IF([hh], [h])])]))
@@ -673,10 +677,11 @@ AT_CHECK_CALC([%skeleton "lalr1.cc" %defines])
# Start a testing chunk which compiles 'calc' grammar with
# the C++ skeleton, and performs several tests over the parser.
m4_define([AT_CHECK_CALC_LALR1_CC],
[AT_CHECK_CALC([%language "C++"] $@)])
[AT_CHECK_CALC([%language "C++" $1], [$2])])
AT_CHECK_CALC_LALR1_CC([])
AT_CHECK_CALC_LALR1_CC([%locations])
AT_CHECK_CALC_LALR1_CC([%locations], [$CXXFLAGS_NO_EXCEPTIONS])
AT_CHECK_CALC_LALR1_CC([%locations %define api.location.type {Span}])
AT_CHECK_CALC_LALR1_CC([%defines %locations %define parse.error verbose %name-prefix "calc" %verbose %yacc])
+21 -8
View File
@@ -394,6 +394,10 @@ AT_CLEANUP
## parse.error=verbose and consistent errors. ##
## ------------------------------------------- ##
AT_CONSISTENT_ERRORS_CHECK([BISON-DIRECTIVE],
[GRAMMAR],
[INPUT],
[UNEXPECTED-TOKEN], [EXPECTED-TOKEN])
m4_pushdef([AT_CONSISTENT_ERRORS_CHECK], [
AT_SETUP([[parse.error=verbose and consistent errors: ]$1])
@@ -422,6 +426,14 @@ AT_SKEL_JAVA_IF([AT_DATA], [AT_DATA_GRAMMAR])([input.y],
]AT_SKEL_CC_IF([[%defines]], [[%define api.pure]])])[
]AT_YACC_IF([[
%code {
#if defined __GNUC__ && 8 <= __GNUC__
# pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
#endif
}
]])[
]$1[
%define parse.error verbose
@@ -501,7 +513,7 @@ consistent-error-on-a-a:
| 'a' shift
;
default-reduction: /*empty*/ ;
default-reduction: %empty ;
shift: 'b' ;
// Provide another context in which all rules are useful so that this
@@ -601,7 +613,8 @@ error-reduce:
{ USE ($][1); }
;
consistent-reduction: /*empty*/ {
consistent-reduction: %empty
{
assert (yychar == YYEMPTY);
yylval = 0;
yychar = 'b';
@@ -609,7 +622,7 @@ consistent-reduction: /*empty*/ {
consistent-error:
'a' { USE ($][1); }
| /*empty*/ %prec 'a'
| %empty %prec 'a'
;
// Provide another context in which all rules are useful so that this
@@ -1561,11 +1574,11 @@ start:
| empty_c2 'c'
| empty_c3 'c'
;
empty_a: %prec 'a' ;
empty_b: %prec 'b' ;
empty_c1: %prec 'c' ;
empty_c2: %prec 'c' ;
empty_c3: %prec 'd' ;
empty_a: %empty %prec 'a' ;
empty_b: %empty %prec 'b' ;
empty_c1: %empty %prec 'c' ;
empty_c2: %empty %prec 'c' ;
empty_c3: %empty %prec 'd' ;
]])
AT_BISON_CHECK([[--report=all -o input.c input.y]], 0, [], [ignore])
AT_CHECK([[cat input.output | sed -n '/^State 0$/,/^State 1$/p']], 0,
+1 -1
View File
@@ -139,7 +139,7 @@ main (int argc, char **argv)
{
char buffer[256];
int c;
unsigned int i;
unsigned i;
static int lineNum = 1;
static int colNum = 0;
+42 -9
View File
@@ -1755,27 +1755,60 @@ AT_CLEANUP
## Predicates. ##
## ##
## http://lists.gnu.org/archive/html/bug-bison/2013-10/msg00004.html ##
## http://lists.gnu.org/archive/html/bug-bison/2018-05/msg00033.html ##
## ----------------------------------------------------------------- ##
AT_SETUP([Predicates])
# FIXME: We need genuine test cases with uses of %?.
AT_DATA_GRAMMAR([input.y],
[[%glr-parser
%error-verbose
%expect-rr 1
%code requires
{
#include <assert.h>
#include <stdbool.h>
bool new_syntax = false;
const char *input = YY_NULLPTR;
]AT_YYERROR_DECLARE[
]AT_YYLEX_DECLARE[
}
%%
// Exercise "%?{...}" and "%? {...}".
widget:
%? {new_syntax} "widget" id new_args { $$ = f($3, $4); }
| %?{!new_syntax} "widget" id old_args { $$ = f($3, $4); }
%? {new_syntax} 'w' id new_args { printf("new"); }
| %?{!new_syntax} 'w' id old_args { printf("old"); }
;
id:;
new_args:;
old_args:;
id: 'i';
new_args: 'n';
old_args: 'o';
%%
]AT_YYERROR_DEFINE[
int
yylex (void)
{
return *input++;
}
int
main (int argc, const char* argv[])
{
assert (argc == 2); (void) argc;
// First char decides whether new, or old syntax.
// Then the input.
new_syntax = argv[1][0] == 'N';
input = argv[1] + 1;
return yyparse ();
}
]])
AT_BISON_CHECK([[input.y]])
AT_BISON_CHECK([[-o input.c input.y]])
AT_COMPILE([input])
AT_PARSER_CHECK([[./input Nwin]], [0], [new])
AT_PARSER_CHECK([[./input Owin]], [1], [], [[syntax error, unexpected 'n', expecting 'o'
]])
AT_PARSER_CHECK([[./input Owio]], [0], [old])
AT_PARSER_CHECK([[./input Nwio]], [1], [], [[syntax error, unexpected 'o', expecting 'n'
]])
AT_CLEANUP
+89 -21
View File
@@ -105,6 +105,85 @@ AT_PARSER_CHECK([./caller])
AT_BISON_OPTION_POPDEFS
AT_CLEANUP
## -------------- ##
## Sane headers. ##
## -------------- ##
# AT_TEST([DIRECTIVES])
# ---------------------
# Check that headers are self-contained and protected againt multiple
# inclusions.
m4_pushdef([AT_TEST],
[AT_SETUP([Sane headers: $1])
AT_BISON_OPTION_PUSHDEFS([$1])
AT_DATA_GRAMMAR([input.y],
[[$1
%error-verbose
]AT_VARIANT_IF([], [%union {int integer;}])[
%code {
#include <stdio.h>
]AT_YYERROR_DECLARE[
]AT_YYLEX_DECLARE[
}
%%
exp:
'x' { printf ("x\n"); }
;
%%
]AT_YYERROR_DEFINE[
]AT_YYLEX_DEFINE(["x"])[
]])
AT_BISON_CHECK([-d -o input.AT_SKEL_CC_IF([cc], [c]) input.y])
AT_LANG_COMPILE([input.o])
AT_DATA([main.cc],
[AT_DATA_SOURCE_PROLOGUE
AT_MAIN_DEFINE
])
# Check that the headers are self-contained, and protected against
# multiple inclusions. While at it, check they are sane for C++.
for h in *.AT_SKEL_CC_IF([hh], [h])
do
# No shell expansion with AT_DATA.
cat >$h.AT_SKEL_CC_IF([cc], [c]) <<EOF
AT_DATA_SOURCE_PROLOGUE
#include "$h"
#include "$h"
EOF
AT_LANG_COMPILE([$h.o])
done
AT_BISON_OPTION_POPDEFS
AT_CLEANUP
])# AT_TEST
AT_TEST([])
AT_TEST([%locations %debug])
AT_TEST([%glr-parser])
AT_TEST([%locations %debug %glr-parser])
AT_TEST([%define api.pure])
AT_TEST([%define api.push-pull both])
AT_TEST([%define api.pure %define api.push-pull both])
AT_TEST([%language "c++"])
AT_TEST([%locations %debug %language "c++"])
AT_TEST([%language "c++" %define api.value.type variant %define parse.assert])
AT_TEST([%locations %language "c++" %glr-parser])
## ----------------- ##
## Several parsers. ##
## ----------------- ##
@@ -114,8 +193,8 @@ AT_SETUP([Several parsers])
# AT_TEST([PREFIX], [DIRECTIVES])
# -------------------------------
# Generate and compile to *.o. Make sure there is no (allowed) YY*
# nor yy* identifiers in the header. Check that headers are
# self-contained, and can be compiled by a C++ compiler.
# nor yy* identifiers in the header after applying api.prefix. Check
# that headers can be compiled by a C++ compiler.
m4_pushdef([AT_TEST],
[AT_BISON_OPTION_PUSHDEFS([%define api.prefix {$1_} $2])
AT_DATA_GRAMMAR([$1.y],
@@ -212,13 +291,15 @@ AT_TEST([x7], [%define api.push-pull both])
AT_TEST([x8], [%define api.pure %define api.push-pull both])
#AT_TEST([x5], [%locations %language "c++" %glr-parser])
# Check there is no 'yy' left.
# C++ output relies on namespaces and still uses yy a lot.
# Check that api.prefix works properly:
#
# Check there is no 'YY' left.
# Ignore comments, YYChar (template parameter), YYPUSH_MORE(_DEFINED)?
# (constant definition), YY_\w+_INCLUDED (header guards).
# YYDEBUG (not renamed) can be read, but not changed.
# - no 'yy' left.
# C++ output relies on namespaces and still uses yy a lot.
#
# - no 'YY' left.
# Ignore comments, YYChar (template parameter), YYPUSH_MORE(_DEFINED)?
# (constant definition), YY_\w+_INCLUDED (header guards).
# YYDEBUG (not renamed) can be read, but not changed.
AT_CHECK([[$PERL -n -0777 -e '
s{/\*.*?\*/}{}gs;
s{//.*}{}g;
@@ -245,19 +326,6 @@ AT_CHECK([[$PERL -n -0777 -e '
}
' -- *.hh *.h]])
# Check that the headers are self-contained, and protected against
# multiple inclusions. While at it, check they are sane for C++.
for h in *.h *.hh
do
# No shell expansion with AT_DATA.
cat >$h.cc <<EOF
AT_DATA_SOURCE_PROLOGUE
#include "$h"
#include "$h"
EOF
AT_COMPILE_CXX([$h.o])
done
# Do this late, so that other checks have been performed.
AT_SKIP_IF_CANNOT_LINK_C_AND_CXX
+125 -48
View File
@@ -168,13 +168,13 @@ AT_CLEANUP
# declarations for the unused values tests.
m4_define([_AT_UNUSED_VALUES_DECLARATIONS],
[[[%token <integer> INT;
%type <integer> a b c d e f g h i j k l;
%destructor { destroy ($$); } INT a b c d e f g h i j k l;]]])
%type <integer> a b c d e f g h i j k l m n o;
%destructor { destroy ($$); } <integer>;]]])
# AT_CHECK_UNUSED_VALUES(DECLARATIONS_AFTER, CHECK_MIDRULE_VALUES)
# ----------------------------------------------------------------
# Generate a grammar to test unused values, compile it, run it. If
# Generate a grammar to test unused values, and compile it. If
# DECLARATIONS_AFTER is set, then the token, type, and destructor
# declarations are generated after the rules rather than before. If
# CHECK_MIDRULE_VALUES is set, then --warnings=midrule-values is set.
@@ -186,128 +186,185 @@ m4_ifval($1, [
], [_AT_UNUSED_VALUES_DECLARATIONS
])[[%%
start:
'a' a { $]2[; } | 'b' b { $]2[; } | 'c' c { $]2[; } | 'd' d { $]2[; }
| 'e' e { $]2[; } | 'f' f { $]2[; } | 'g' g { $]2[; } | 'h' h { $]2[; }
| 'i' i { $]2[; } | 'j' j { $]2[; } | 'k' k { $]2[; } | 'l' l { $]2[; }
'a' a { $][2; } | 'b' b { $][2; } | 'c' c { $][2; } | 'd' d { $][2; }
| 'e' e { $][2; } | 'f' f { $][2; } | 'g' g { $][2; } | 'h' h { $][2; }
| 'i' i { $][2; } | 'j' j { $][2; } | 'k' k { $][2; } | 'l' l { $][2; }
| 'm' m { $][2; } | 'n' n { $][2; } | 'o' o { $][2; }
;
a: INT | INT { } INT { } INT { };
b: INT | %empty;
c: INT | INT { $]1[; } INT { $<integer>2; } INT { $<integer>4; };
d: INT | INT { } INT { $]1[; } INT { $<integer>2; };
e: INT | INT { } INT { } INT { $]1[; };
f: INT | INT { } INT { } INT { $]$[ = $]1[ + $]3[ + $]5[; };
c: INT | INT { $][1; } INT { $<integer>2; } INT { $<integer>4; };
d: INT | INT { } INT { $][1; } INT { $<integer>2; };
e: INT | INT { } INT { } INT { $][1; };
f: INT | INT { } INT { } INT { $][$ = $][1 + $][3 + $][5; };
g: INT | INT { $<integer>$; } INT { $<integer>$; } INT { };
h: INT | INT { $<integer>$; } INT { $<integer>$ = $<integer>2; } INT { };
i: INT | INT INT { } { $]$[ = $]1[ + $]2[; };
j: INT | INT INT { $<integer>$ = 1; } { $]$[ = $]1[ + $]2[; };
i: INT | INT INT { } { $][$ = $][1 + $][2; };
j: INT | INT INT { $<integer>$ = 1; } { $][$ = $][1 + $][2; };
k: INT | INT INT { $<integer>$; } { $<integer>$ = $<integer>3; } { };
l: INT | INT { $<integer>$ = $<integer>1; } INT { $<integer>$ = $<integer>2 + $<integer>3; } INT { $<integer>$ = $<integer>4 + $<integer>5; };]]m4_ifval($1, [
l: INT | INT { $<integer>$ = $<integer>1; } INT { $<integer>$ = $<integer>2 + $<integer>3; } INT { $<integer>$ = $<integer>4 + $<integer>5; };
m: INT | INT <integer>{ $][$ = $][1; } INT <integer>{ $][$ = $][2 + $][3; } INT { $][$ = $][4 + $][5; };
n: INT | INT <integer>{ } INT <integer>{ } INT { };
o: INT | INT <integer>{ } INT <integer>{ } INT { $][$ = $][1 + $][2 + $][3 + $][4 + $][5; };
]]m4_ifval($1, [
_AT_UNUSED_VALUES_DECLARATIONS])
)
AT_BISON_CHECK(m4_ifval($2, [--warnings=midrule-values ])[-fcaret input.y],
[0], [],
[[input.y:11.10-32: warning: unset value: $][$ [-Wother]
[[input.y:12.10-32: warning: unset value: $][$ [-Wother]
a: INT | INT { } INT { } INT { };
^^^^^^^^^^^^^^^^^^^^^^^
input.y:11.10-12: warning: unused value: $][1 [-Wother]
input.y:12.10-12: warning: unused value: $][1 [-Wother]
a: INT | INT { } INT { } INT { };
^^^
input.y:11.18-20: warning: unused value: $][3 [-Wother]
input.y:12.18-20: warning: unused value: $][3 [-Wother]
a: INT | INT { } INT { } INT { };
^^^
input.y:11.26-28: warning: unused value: $][5 [-Wother]
input.y:12.26-28: warning: unused value: $][5 [-Wother]
a: INT | INT { } INT { } INT { };
^^^
input.y:12.10-15: warning: empty rule for typed nonterminal, and no action [-Wother]
input.y:13.10-15: warning: empty rule for typed nonterminal, and no action [-Wother]
b: INT | %empty;
^^^^^^
]]m4_ifval($2, [[[input.y:13.14-20: warning: unset value: $][$ [-Wmidrule-values]
]]m4_ifval($2, [[[input.y:14.14-20: warning: unset value: $][$ [-Wmidrule-values]
c: INT | INT { $][1; } INT { $<integer>2; } INT { $<integer>4; };
^^^^^^^
input.y:13.26-41: warning: unset value: $][$ [-Wmidrule-values]
input.y:14.26-41: warning: unset value: $][$ [-Wmidrule-values]
c: INT | INT { $][1; } INT { $<integer>2; } INT { $<integer>4; };
^^^^^^^^^^^^^^^^
]]])[[input.y:13.10-62: warning: unset value: $][$ [-Wother]
]]])[[input.y:14.10-62: warning: unset value: $][$ [-Wother]
c: INT | INT { $][1; } INT { $<integer>2; } INT { $<integer>4; };
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
input.y:13.22-24: warning: unused value: $][3 [-Wother]
input.y:14.22-24: warning: unused value: $][3 [-Wother]
c: INT | INT { $][1; } INT { $<integer>2; } INT { $<integer>4; };
^^^
input.y:13.43-45: warning: unused value: $][5 [-Wother]
input.y:14.43-45: warning: unused value: $][5 [-Wother]
c: INT | INT { $][1; } INT { $<integer>2; } INT { $<integer>4; };
^^^
]]m4_ifval($2, [[[input.y:14.14-16: warning: unset value: $][$ [-Wmidrule-values]
]]m4_ifval($2, [[[input.y:15.14-16: warning: unset value: $][$ [-Wmidrule-values]
d: INT | INT { } INT { $][1; } INT { $<integer>2; };
^^^
]]])[[input.y:14.10-49: warning: unset value: $][$ [-Wother]
]]])[[input.y:15.10-49: warning: unset value: $][$ [-Wother]
d: INT | INT { } INT { $][1; } INT { $<integer>2; };
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
input.y:14.18-20: warning: unused value: $][3 [-Wother]
input.y:15.18-20: warning: unused value: $][3 [-Wother]
d: INT | INT { } INT { $][1; } INT { $<integer>2; };
^^^
input.y:14.30-32: warning: unused value: $][5 [-Wother]
input.y:15.30-32: warning: unused value: $][5 [-Wother]
d: INT | INT { } INT { $][1; } INT { $<integer>2; };
^^^
input.y:15.10-37: warning: unset value: $][$ [-Wother]
input.y:16.10-37: warning: unset value: $][$ [-Wother]
e: INT | INT { } INT { } INT { $][1; };
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
input.y:15.18-20: warning: unused value: $][3 [-Wother]
input.y:16.18-20: warning: unused value: $][3 [-Wother]
e: INT | INT { } INT { } INT { $][1; };
^^^
input.y:15.27-29: warning: unused value: $][5 [-Wother]
input.y:16.27-29: warning: unused value: $][5 [-Wother]
e: INT | INT { } INT { } INT { $][1; };
^^^
input.y:17.10-58: warning: unset value: $][$ [-Wother]
input.y:18.10-58: warning: unset value: $][$ [-Wother]
g: INT | INT { $<integer>$; } INT { $<integer>$; } INT { };
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
input.y:17.10-12: warning: unused value: $][1 [-Wother]
input.y:18.10-12: warning: unused value: $][1 [-Wother]
g: INT | INT { $<integer>$; } INT { $<integer>$; } INT { };
^^^
]]m4_ifval($2, [[[input.y:17.14-29: warning: unused value: $][2 [-Wmidrule-values]
]]m4_ifval($2, [[[input.y:18.14-29: warning: unused value: $][2 [-Wmidrule-values]
g: INT | INT { $<integer>$; } INT { $<integer>$; } INT { };
^^^^^^^^^^^^^^^^
]]])[[input.y:17.31-33: warning: unused value: $][3 [-Wother]
]]])[[input.y:18.31-33: warning: unused value: $][3 [-Wother]
g: INT | INT { $<integer>$; } INT { $<integer>$; } INT { };
^^^
]]m4_ifval($2, [[[input.y:17.35-50: warning: unused value: $][4 [-Wmidrule-values]
]]m4_ifval($2, [[[input.y:18.35-50: warning: unused value: $][4 [-Wmidrule-values]
g: INT | INT { $<integer>$; } INT { $<integer>$; } INT { };
^^^^^^^^^^^^^^^^
]]])[[input.y:17.52-54: warning: unused value: $][5 [-Wother]
]]])[[input.y:18.52-54: warning: unused value: $][5 [-Wother]
g: INT | INT { $<integer>$; } INT { $<integer>$; } INT { };
^^^
input.y:18.10-72: warning: unset value: $][$ [-Wother]
input.y:19.10-72: warning: unset value: $][$ [-Wother]
h: INT | INT { $<integer>$; } INT { $<integer>$ = $<integer>2; } INT { };
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
input.y:18.10-12: warning: unused value: $][1 [-Wother]
input.y:19.10-12: warning: unused value: $][1 [-Wother]
h: INT | INT { $<integer>$; } INT { $<integer>$ = $<integer>2; } INT { };
^^^
input.y:18.31-33: warning: unused value: $][3 [-Wother]
input.y:19.31-33: warning: unused value: $][3 [-Wother]
h: INT | INT { $<integer>$; } INT { $<integer>$ = $<integer>2; } INT { };
^^^
]]m4_ifval($2, [[[input.y:18.35-64: warning: unused value: $][4 [-Wmidrule-values]
]]m4_ifval($2, [[[input.y:19.35-64: warning: unused value: $][4 [-Wmidrule-values]
h: INT | INT { $<integer>$; } INT { $<integer>$ = $<integer>2; } INT { };
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
]]])[[input.y:18.66-68: warning: unused value: $][5 [-Wother]
]]])[[input.y:19.66-68: warning: unused value: $][5 [-Wother]
h: INT | INT { $<integer>$; } INT { $<integer>$ = $<integer>2; } INT { };
^^^
]]m4_ifval($2, [[[input.y:20.18-37: warning: unused value: $][3 [-Wmidrule-values]
]]m4_ifval($2, [[[input.y:21.18-37: warning: unused value: $][3 [-Wmidrule-values]
j: INT | INT INT { $<integer>$ = 1; } { $][$ = $][1 + $][2; };
^^^^^^^^^^^^^^^^^^^^
]]])[[input.y:21.10-68: warning: unset value: $][$ [-Wother]
]]])[[input.y:22.10-68: warning: unset value: $][$ [-Wother]
k: INT | INT INT { $<integer>$; } { $<integer>$ = $<integer>3; } { };
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
input.y:21.10-12: warning: unused value: $][1 [-Wother]
input.y:22.10-12: warning: unused value: $][1 [-Wother]
k: INT | INT INT { $<integer>$; } { $<integer>$ = $<integer>3; } { };
^^^
input.y:21.14-16: warning: unused value: $][2 [-Wother]
input.y:22.14-16: warning: unused value: $][2 [-Wother]
k: INT | INT INT { $<integer>$; } { $<integer>$ = $<integer>3; } { };
^^^
]]m4_ifval($2, [[[input.y:21.35-64: warning: unused value: $][4 [-Wmidrule-values]
]]m4_ifval($2, [[[input.y:22.35-64: warning: unused value: $][4 [-Wmidrule-values]
k: INT | INT INT { $<integer>$; } { $<integer>$ = $<integer>3; } { };
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
]]]))
]]])[[input.y:25.23-25: warning: unset value: $][$ [-Wother]
n: INT | INT <integer>{ } INT <integer>{ } INT { };
^^^
input.y:25.40-42: warning: unset value: $][$ [-Wother]
n: INT | INT <integer>{ } INT <integer>{ } INT { };
^^^
input.y:25.10-50: warning: unset value: $][$ [-Wother]
n: INT | INT <integer>{ } INT <integer>{ } INT { };
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
input.y:25.10-12: warning: unused value: $][1 [-Wother]
n: INT | INT <integer>{ } INT <integer>{ } INT { };
^^^
input.y:25.23-25: warning: unused value: $][2 [-Wother]
n: INT | INT <integer>{ } INT <integer>{ } INT { };
^^^
input.y:25.27-29: warning: unused value: $][3 [-Wother]
n: INT | INT <integer>{ } INT <integer>{ } INT { };
^^^
input.y:25.40-42: warning: unused value: $][4 [-Wother]
n: INT | INT <integer>{ } INT <integer>{ } INT { };
^^^
input.y:25.44-46: warning: unused value: $][5 [-Wother]
n: INT | INT <integer>{ } INT <integer>{ } INT { };
^^^
input.y:26.23-25: warning: unset value: $][$ [-Wother]
o: INT | INT <integer>{ } INT <integer>{ } INT { $][$ = $][1 + $][2 + $][3 + $][4 + $][5; };
^^^
input.y:26.40-42: warning: unset value: $][$ [-Wother]
o: INT | INT <integer>{ } INT <integer>{ } INT { $][$ = $][1 + $][2 + $][3 + $][4 + $][5; };
^^^
]])
AT_BISON_CHECK([-Wnone,yacc -fcaret input.y],
[0], [],
[[input.y:24.23-34: warning: POSIX Yacc does not support typed midrule actions [-Wyacc]
m: INT | INT <integer>{ $][$ = $][1; } INT <integer>{ $][$ = $][2 + $][3; } INT { $][$ = $][4 + $][5; };
^^^^^^^^^^^^
input.y:24.49-65: warning: POSIX Yacc does not support typed midrule actions [-Wyacc]
m: INT | INT <integer>{ $][$ = $][1; } INT <integer>{ $][$ = $][2 + $][3; } INT { $][$ = $][4 + $][5; };
^^^^^^^^^^^^^^^^^
input.y:25.23-25: warning: POSIX Yacc does not support typed midrule actions [-Wyacc]
n: INT | INT <integer>{ } INT <integer>{ } INT { };
^^^
input.y:25.40-42: warning: POSIX Yacc does not support typed midrule actions [-Wyacc]
n: INT | INT <integer>{ } INT <integer>{ } INT { };
^^^
input.y:26.23-25: warning: POSIX Yacc does not support typed midrule actions [-Wyacc]
o: INT | INT <integer>{ } INT <integer>{ } INT { $][$ = $][1 + $][2 + $][3 + $][4 + $][5; };
^^^
input.y:26.40-42: warning: POSIX Yacc does not support typed midrule actions [-Wyacc]
o: INT | INT <integer>{ } INT <integer>{ } INT { $][$ = $][1 + $][2 + $][3 + $][4 + $][5; };
^^^
]])
])
## --------------- ##
@@ -2136,7 +2193,7 @@ input.y:13.11-21: previous definition
AT_CLEANUP
##--------------------------- ##
## -------------------------- ##
## Non-deprecated directives. ##
## -------------------------- ##
@@ -2167,3 +2224,23 @@ AT_BISON_CHECK([[input.y]], [[0]], [[]],
]])
AT_CLEANUP
## -------------------- ##
## Cannot type action. ##
## -------------------- ##
AT_SETUP([[Cannot type action]])
AT_DATA_GRAMMAR([[input.y]],
[[%%
exp: <int> {}
]])
AT_BISON_CHECK([[-fcaret input.y]], [[0]], [[]],
[[input.y:10.6-13: warning: only midrule actions can be typed: int [-Wother]
exp: <int> {}
^^^^^^^^
]])
AT_CLEANUP
+24 -21
View File
@@ -740,8 +740,8 @@ m4_define([AT_QUELL_VALGRIND],
## ------------------------ ##
# AT_COMPILE(OUTPUT, [SOURCES = OUTPUT.c])
# ----------------------------------------
# AT_COMPILE(OUTPUT, [SOURCES = OUTPUT.c], [EXTRA-COMPILER-FLAGS])
# ----------------------------------------------------------------
# Compile SOURCES into OUTPUT.
#
# If OUTPUT does not contain '.', assume that we are linking too,
@@ -750,16 +750,16 @@ m4_define([AT_QUELL_VALGRIND],
m4_define([AT_COMPILE],
[AT_CHECK([$BISON_C_WORKS], 0, ignore, ignore)
AT_CHECK(m4_join([ ],
[$CC $CFLAGS $CPPFLAGS],
[m4_bmatch([$1], [[.]], [-c], [$LDFLAGS])],
[-o $1],
[m4_default([$2], [m4_bpatsubst([$1], [\.o$]).c])],
[m4_bmatch([$1], [[.]], [], [$LIBS])]),
0, [ignore], [ignore])])
[$CC $CFLAGS $CPPFLAGS $3],
[m4_bmatch([$1], [[.]], [-c], [$LDFLAGS])],
[-o $1],
[m4_default([$2], [m4_bpatsubst([$1], [\.o$]).c])],
[m4_bmatch([$1], [[.]], [], [$LIBS])]),
0, [ignore], [ignore])])
# AT_COMPILE_CXX(OUTPUT, [SOURCES = OUTPUT.cc])
# ---------------------------------------------
# AT_COMPILE_CXX(OUTPUT, [SOURCES = OUTPUT.cc], [EXTRA-COMPILER-FLAGS])
# ---------------------------------------------------------------------
# Compile SOURCES into OUTPUT. If the C++ compiler does not work,
# ignore the test.
#
@@ -770,7 +770,7 @@ m4_define([AT_COMPILE_CXX],
[AT_KEYWORDS(c++)
AT_CHECK([$BISON_CXX_WORKS], 0, ignore, ignore)
AT_CHECK(m4_join([ ],
[$CXX $CXXFLAGS $CPPFLAGS],
[$CXX $CXXFLAGS $CPPFLAGS $3],
[m4_bmatch([$1], [[.]], [-c], [$LDFLAGS])],
[-o $1],
[m4_default([$2], [m4_bpatsubst([$1], [\.o$]).cc])],
@@ -790,21 +790,21 @@ AT_CHECK([[$SHELL ../../../javacomp.sh ]$1],
[[0]], [ignore], [ignore])])
# AT_LANG_COMPILE(OUTPUT, [SOURCES = OUTPUT.c]
# --------------------------------------------
# AT_LANG_COMPILE(OUTPUT, [SOURCES = OUTPUT.c], [EXTRA-COMPILER-FLAGS])
# ---------------------------------------------------------------------
# Compile SOURCES into OUTPUT. Skip if compiler does not work.
#
# If OUTPUT does not contain '.', assume that we are linking too,
# otherwise pass "-c"; this is a hack. The default SOURCES is OUTPUT
# with trailing .o removed, and ".c"/".cc" appended.
m4_define([AT_LANG_COMPILE], [AT_LANG_DISPATCH([$0], $@)])
m4_define([AT_LANG_COMPILE(c)], [AT_COMPILE([$1], [$2])])
m4_define([AT_LANG_COMPILE(c++)], [AT_COMPILE_CXX([$1], [$2])])
m4_define([AT_LANG_COMPILE(java)], [AT_JAVA_COMPILE([$1.java], [$2])])
m4_define([AT_LANG_COMPILE(c)], [AT_COMPILE([$1], [$2], [$3])])
m4_define([AT_LANG_COMPILE(c++)], [AT_COMPILE_CXX([$1], [$2], [$3])])
m4_define([AT_LANG_COMPILE(java)], [AT_JAVA_COMPILE([$1.java], [$2], [$3])])
# AT_FULL_COMPILE(OUTPUT, [OTHER1], [OTHER2])
# -------------------------------------------
# AT_FULL_COMPILE(OUTPUT, [OTHER1], [OTHER2], [EXTRA-COMPILER-FLAGS)
# ------------------------------------------------------------------
# Compile OUTPUT.y to OUTPUT.c, OUTPUT.cc, or OUTPUT.java, and then
# compile it to OUTPUT or OUTPUT.class. If OTHER is specified, compile
# OUTPUT-OTHER.c, OUTPUT-OTHER.cc, or OUTPUT-OTHER.java to OUTPUT or
@@ -817,7 +817,8 @@ m4_define([AT_FULL_COMPILE(c)],
m4_join([ ],
[$1.c],
m4_ifval($2, [[$1-$2.c]]),
m4_ifval($3, [[$1-$3.c]])))])
m4_ifval($3, [[$1-$3.c]])),
[$4])])
m4_define([AT_FULL_COMPILE(c++)],
[AT_BISON_CHECK([-o $1.cc $1.y])
@@ -825,7 +826,8 @@ m4_define([AT_FULL_COMPILE(c++)],
m4_join([ ],
[$1.cc],
m4_ifval($2, [[$1-$2.cc]]),
m4_ifval($3, [[$1-$3.cc]])))])
m4_ifval($3, [[$1-$3.cc]])),
[$4])])
m4_define([AT_FULL_COMPILE(java)],
[AT_BISON_CHECK([-o $1.java $1.y])
@@ -833,7 +835,8 @@ m4_define([AT_FULL_COMPILE(java)],
m4_join([ ],
[$1.java],
m4_ifval($2, [[$1-$2.java]]),
m4_ifval($3, [[$1-$3.java]])))])
m4_ifval($3, [[$1-$3.java]])),
[$4])])
+1
View File
@@ -61,6 +61,7 @@ TESTSUITE_AT = \
tests/push.at \
tests/reduce.at \
tests/regression.at \
tests/report.at \
tests/sets.at \
tests/skeletons.at \
tests/synclines.at \
+12 -41
View File
@@ -173,33 +173,6 @@ input.y:13.1-8: warning: nonterminal useless in grammar: useless8 [-Wother]
input.y:14.1-8: warning: nonterminal useless in grammar: useless9 [-Wother]
useless9: '9';
^^^^^^^^
input.y:6.11-13: warning: rule useless in grammar [-Wother]
useless1: '1';
^^^
input.y:7.11-13: warning: rule useless in grammar [-Wother]
useless2: '2';
^^^
input.y:8.11-13: warning: rule useless in grammar [-Wother]
useless3: '3';
^^^
input.y:9.11-13: warning: rule useless in grammar [-Wother]
useless4: '4';
^^^
input.y:10.11-13: warning: rule useless in grammar [-Wother]
useless5: '5';
^^^
input.y:11.11-13: warning: rule useless in grammar [-Wother]
useless6: '6';
^^^
input.y:12.11-13: warning: rule useless in grammar [-Wother]
useless7: '7';
^^^
input.y:13.11-13: warning: rule useless in grammar [-Wother]
useless8: '8';
^^^
input.y:14.11-13: warning: rule useless in grammar [-Wother]
useless9: '9';
^^^
]])
@@ -282,18 +255,12 @@ not-reduced.y: warning: 3 rules useless in grammar [-Wother]
not-reduced.y:14.1-13: warning: nonterminal useless in grammar: not_reachable [-Wother]
not_reachable: useful { /* A not reachable action. */ }
^^^^^^^^^^^^^
not-reduced.y:11.6-19: warning: nonterminal useless in grammar: non_productive [-Wother]
| non_productive { /* A non productive action. */ }
^^^^^^^^^^^^^^
not-reduced.y:17.1-14: warning: nonterminal useless in grammar: non_productive [-Wother]
non_productive: non_productive useless_token
^^^^^^^^^^^^^^
not-reduced.y:11.6-57: warning: rule useless in grammar [-Wother]
| non_productive { /* A non productive action. */ }
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
not-reduced.y:14.16-56: warning: rule useless in grammar [-Wother]
not_reachable: useful { /* A not reachable action. */ }
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
not-reduced.y:17.17-18.63: warning: rule useless in grammar [-Wother]
non_productive: non_productive useless_token
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
]])
AT_CHECK([[sed -n '/^Grammar/q;/^$/!p' not-reduced.output]], 0,
@@ -361,14 +328,18 @@ underivable: indirection;
indirection: underivable;
]])
AT_BISON_CHECK([[input.y]], 0, [],
AT_BISON_CHECK([[-fcaret input.y]], 0, [],
[[input.y: warning: 2 nonterminals useless in grammar [-Wother]
input.y: warning: 3 rules useless in grammar [-Wother]
input.y:5.15-25: warning: nonterminal useless in grammar: underivable [-Wother]
input.y:6.14-24: warning: nonterminal useless in grammar: indirection [-Wother]
input.y:6.1-11: warning: nonterminal useless in grammar: underivable [-Wother]
underivable: indirection;
^^^^^^^^^^^
input.y:7.1-11: warning: nonterminal useless in grammar: indirection [-Wother]
indirection: underivable;
^^^^^^^^^^^
input.y:5.15-25: warning: rule useless in grammar [-Wother]
input.y:6.14-24: warning: rule useless in grammar [-Wother]
input.y:7.14-24: warning: rule useless in grammar [-Wother]
exp: useful | underivable;
^^^^^^^^^^^
]])
AT_CHECK([[sed -n '/^Grammar/q;/^$/!p' input.output]], 0,
+299
View File
@@ -0,0 +1,299 @@
# Bison Reports. -*- Autotest -*-
# Copyright (C) 2018 Free Software Foundation, Inc.
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
AT_BANNER([[Test reports.]])
## --------- ##
## Reports. ##
## --------- ##
AT_SETUP([Reports])
AT_KEYWORDS([report])
AT_BISON_OPTION_PUSHDEFS
AT_DATA([input.yy],
[[%token
END 0 "end of file"
ASSIGN ":="
INCR "incr"
;
%token <std::string> IDENTIFIER "identifier"
%type <std::string> id
%token <int> NUMBER "number"
%type <int> exp
%%
%start unit;
unit: assignments exp { driver.result = $2; };
assignments:
%empty {}
| assignments assignment {};
assignment:
id ":=" exp { driver.variables[$id] = $exp; };
id:
"identifier";
exp:
"incr" exp <int>{ $$ = 1; } <int>{ $$ = 10; } exp { $$ = $2 + $3 + $4 + $5; }
| "(" exp ")" { std::swap ($$, $2); }
| "identifier" { $$ = driver.variables[$1]; }
| "number" { std::swap ($$, $1); };
]])
AT_BISON_OPTION_POPDEFS
AT_BISON_CHECK([-o input.cc -v input.yy])
# Check the contents of the report.
AT_CHECK([cat input.output], [],
[[Grammar
0 $accept: unit "end of file"
1 unit: assignments exp
2 assignments: %empty
3 | assignments assignment
4 assignment: id ":=" exp
5 id: "identifier"
6 @1: %empty
7 @2: %empty
8 exp: "incr" exp @1 @2 exp
9 | "(" exp ")"
10 | "identifier"
11 | "number"
Terminals, with rules where they appear
"end of file" (0) 0
error (256)
":=" (258) 4
"incr" (259) 8
"identifier" <std::string> (260) 5 10
"number" <int> (261) 11
"(" (262) 9
")" (263) 9
Nonterminals, with rules where they appear
$accept (9)
on left: 0
unit (10)
on left: 1, on right: 0
assignments (11)
on left: 2 3, on right: 1 3
assignment (12)
on left: 4, on right: 3
id <std::string> (13)
on left: 5, on right: 4
exp <int> (14)
on left: 8 9 10 11, on right: 1 4 8 9
@1 <int> (15)
on left: 6, on right: 8
@2 <int> (16)
on left: 7, on right: 8
State 0
0 $accept: . unit "end of file"
$default reduce using rule 2 (assignments)
unit go to state 1
assignments go to state 2
State 1
0 $accept: unit . "end of file"
"end of file" shift, and go to state 3
State 2
1 unit: assignments . exp
3 assignments: assignments . assignment
"incr" shift, and go to state 4
"identifier" shift, and go to state 5
"number" shift, and go to state 6
"(" shift, and go to state 7
assignment go to state 8
id go to state 9
exp go to state 10
State 3
0 $accept: unit "end of file" .
$default accept
State 4
8 exp: "incr" . exp @1 @2 exp
"incr" shift, and go to state 4
"identifier" shift, and go to state 11
"number" shift, and go to state 6
"(" shift, and go to state 7
exp go to state 12
State 5
5 id: "identifier" .
10 exp: "identifier" .
"end of file" reduce using rule 10 (exp)
$default reduce using rule 5 (id)
State 6
11 exp: "number" .
$default reduce using rule 11 (exp)
State 7
9 exp: "(" . exp ")"
"incr" shift, and go to state 4
"identifier" shift, and go to state 11
"number" shift, and go to state 6
"(" shift, and go to state 7
exp go to state 13
State 8
3 assignments: assignments assignment .
$default reduce using rule 3 (assignments)
State 9
4 assignment: id . ":=" exp
":=" shift, and go to state 14
State 10
1 unit: assignments exp .
$default reduce using rule 1 (unit)
State 11
10 exp: "identifier" .
$default reduce using rule 10 (exp)
State 12
8 exp: "incr" exp . @1 @2 exp
$default reduce using rule 6 (@1)
@1 go to state 15
State 13
9 exp: "(" exp . ")"
")" shift, and go to state 16
State 14
4 assignment: id ":=" . exp
"incr" shift, and go to state 4
"identifier" shift, and go to state 11
"number" shift, and go to state 6
"(" shift, and go to state 7
exp go to state 17
State 15
8 exp: "incr" exp @1 . @2 exp
$default reduce using rule 7 (@2)
@2 go to state 18
State 16
9 exp: "(" exp ")" .
$default reduce using rule 9 (exp)
State 17
4 assignment: id ":=" exp .
$default reduce using rule 4 (assignment)
State 18
8 exp: "incr" exp @1 @2 . exp
"incr" shift, and go to state 4
"identifier" shift, and go to state 11
"number" shift, and go to state 6
"(" shift, and go to state 7
exp go to state 19
State 19
8 exp: "incr" exp @1 @2 exp .
$default reduce using rule 8 (exp)
]])
AT_CLEANUP
+135 -31
View File
@@ -16,7 +16,7 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
AT_BANNER([[User Actions.]])
AT_BANNER([[Sync Lines.]])
# _AT_SYNCLINES_COMPILE(FILE)
@@ -84,6 +84,12 @@ m4_define([_AT_SYNCLINES_COMPILE],
#
# Newer GCCs go further and if the function is declared static, complain
# that it's not used.
#
# GCC 7 also underlines the error.
#
# syncline.c:4:2: error: #error "4"
# #error "4"
# ^~~~~
AT_CHECK([[$PERL -p -0777 - stderr <<\EOF
# 1. Remove useless lines.
@@ -93,8 +99,8 @@ AT_CHECK([[$PERL -p -0777 - stderr <<\EOF
s/^clang: warning: treating 'c' input as 'c\+\+'.*\n//gm;
# Function context.
s/^[^:]*: In function '[^']+':\n//gm;
# Caret error.
s/^ *#error.*\n *\^\n//gm;
# Caret error (with possible '~' to underline).
s/^ *#error.*\n *\^~*\n//gm;
# Number of errors.
s/^1 error generated\.\n//gm;
@@ -178,9 +184,11 @@ AT_CLEANUP
AT_TEST([Prologue syncline],
[[%{
#error "2"
]AT_YYERROR_DECLARE_EXTERN[
]AT_YYLEX_DECLARE_EXTERN[
%}
%code {
]AT_YYERROR_DECLARE_EXTERN[
]AT_YYLEX_DECLARE_EXTERN[
}
%%
exp: '0';
%%
@@ -198,10 +206,10 @@ AT_TEST([%union syncline],
#error "2"
char dummy;
}
%{
]AT_YYERROR_DECLARE_EXTERN[
]AT_YYLEX_DECLARE_EXTERN[
%}
%code {
]AT_YYERROR_DECLARE_EXTERN[
]AT_YYLEX_DECLARE_EXTERN[
}
%%
exp: '0';
%%
@@ -223,9 +231,9 @@ AT_DATA([[input.y]],
{
char dummy;
}
%{
]AT_YYERROR_DECLARE_EXTERN[
]AT_YYLEX_DECLARE_EXTERN[
%code {
]AT_YYERROR_DECLARE_EXTERN[
]AT_YYLEX_DECLARE_EXTERN[
%}
%%
exp: '0';
@@ -244,22 +252,25 @@ AT_CLEANUP
## ----------------------- ##
AT_TEST([Postprologue syncline],
[[%{
]AT_YYERROR_DECLARE_EXTERN[
]AT_YYLEX_DECLARE_EXTERN[
[[%code {
]AT_YYERROR_DECLARE_EXTERN[
]AT_YYLEX_DECLARE_EXTERN[
}
%{
/* Preprologue. */
%}
%union
{
int ival;
}
%{
#error "10"
#error "13"
%}
%%
exp: '0';
%%
]],
[input.y:10: #error "10"
[input.y:13: #error "13"
])
@@ -268,10 +279,10 @@ exp: '0';
## ----------------- ##
AT_TEST([Action syncline],
[[%{
]AT_YYERROR_DECLARE_EXTERN[
]AT_YYLEX_DECLARE_EXTERN[
%}
[[%code {
]AT_YYERROR_DECLARE_EXTERN[
]AT_YYLEX_DECLARE_EXTERN[
}
%%
exp:
{
@@ -287,10 +298,10 @@ exp:
## ------------------- ##
AT_TEST([Epilogue syncline],
[[%{
]AT_YYERROR_DECLARE_EXTERN[
]AT_YYLEX_DECLARE_EXTERN[
%}
[[%code {
]AT_YYERROR_DECLARE_EXTERN[
]AT_YYLEX_DECLARE_EXTERN[
}
%%
exp: '0';
%%
@@ -307,10 +318,10 @@ AT_TEST([%code top syncline],
[[%code top {
#error "2"
}
%{
]AT_YYERROR_DECLARE_EXTERN[
]AT_YYLEX_DECLARE_EXTERN[
%}
%code {
]AT_YYERROR_DECLARE_EXTERN[
]AT_YYLEX_DECLARE_EXTERN[
}
%%
exp: '0';
%%
@@ -318,25 +329,118 @@ exp: '0';
[input.y:2: #error "2"
])
## ---------------------- ##
## %destructor syncline. ##
## ---------------------- ##
AT_TEST([%destructor syncline],
[[%destructor {
#error "2"
} <ival>
%{
]AT_YYERROR_DECLARE_EXTERN[
]AT_YYLEX_DECLARE_EXTERN[
%}
%union {
int ival;
}
%nterm <ival> exp
%%
exp: '0' { $$ = 0; };
%%
]],
[input.y:2: #error "2"
])
## ------------------- ##
## %printer syncline. ##
## ------------------- ##
AT_TEST([%printer syncline],
[[%printer {
#error "2"
} <ival>
%debug
%code {
]AT_YYERROR_DECLARE_EXTERN[
]AT_YYLEX_DECLARE_EXTERN[
}
%union {
int ival;
}
%nterm <ival> exp
%%
exp: '0' { $$ = 0; };
%%
]],
[input.y:2: #error "2"
])
m4_popdef([AT_TEST])
## ------------------ ##
## syncline escapes. ##
## ------------------ ##
# AT_TEST([SKELETON])
# -------------------
m4_pushdef([AT_TEST],
[AT_SETUP([syncline escapes: $1])
AT_BISON_OPTION_PUSHDEFS([%skeleton "$1"])
AT_DATA_GRAMMAR([\"\\\"\".y],
[[%skeleton "$1"
%code {
]AT_YYERROR_DECLARE[
]AT_YYLEX_DECLARE[
}
%destructor {} <>
%printer {} <>
%%
exp: '0'
%%
]AT_YYERROR_DEFINE[
]AT_YYLEX_DEFINE[
]AT_MAIN_DEFINE[
]])
AT_FULL_COMPILE([\"\\\"\"])
AT_BISON_OPTION_POPDEFS
AT_CLEANUP
])
AT_TEST([yacc.c])
AT_TEST([glr.c])
AT_TEST([lalr1.cc])
AT_TEST([glr.cc])
m4_popdef([AT_TEST])
## ----------- ##
## %no-lines. ##
## ----------- ##
# AT_TEST([SKELETON])
# -------------------
m4_pushdef([AT_TEST],
[AT_SETUP([%no-lines: $1])
AT_BISON_OPTION_PUSHDEFS([%skeleton "$1" %defines])
AT_DATA_GRAMMAR([input.y],
[%skeleton "$1" %defines
[[%skeleton "$1" %defines
%{
]AT_YYERROR_DECLARE_EXTERN[
]AT_YYLEX_DECLARE_EXTERN[
%}
%%
exp: '0'
])
]])
AT_BISON_CHECK([--no-lines -o input.AT_SKEL_CC_IF([cc], [c]) -d input.y])
AT_CHECK([[grep '#line' ]AT_SKEL_CC_IF([*.cc *.hh], [*.c *.h])], 1)
AT_BISON_OPTION_POPDEFS
+3
View File
@@ -35,6 +35,9 @@ m4_include([sets.at])
# Testing grammar reduction.
m4_include([reduce.at])
# Testing generated reports.
m4_include([report.at])
# Testing conflicts detection and resolution.
m4_include([conflicts.at])