Compare commits

...
218 Commits
Author SHA1 Message Date
Akim Demaille a3efd13e44 version 3.0.2
* NEWS: Record release date.
2013-12-05 14:58:22 +01:00
Akim Demaille a4122000c6 gnulib: update
* gnulib: here.
2013-12-05 14:42:08 +01:00
Akim Demaille 461983270c output: do not generate source files when late errors are caught
Reported by Alexandre Duret-Lutz as "second problem" in:
http://lists.gnu.org/archive/html/bug-bison/2013-09/msg00015.html

* bootstrap.conf: We need the "unlink" module.
* src/files.h, src/files.c (unlink_generated_sources): New.
* src/output.c: Use it.
* tests/output.at: Check the case of late errors.
2013-12-04 15:53:01 +01:00
Akim Demaille ea99d6e6a0 output: record what generated files are source or report files
* src/files.h, src/files.c (output_file_name_check): Take an additional
argument to record whether a file is a source or report file.
* src/files.c (generated_file): New.
(file_names, file_names_count): Replace with...
(generated_files, generated_files_size): these.
* src/scan-skel.l: Adjust.
2013-12-04 15:53:01 +01:00
Akim Demaille 184b42c85b output: do not generate source files when early errors are caught
Reported by Alexandre Duret-Lutz as "second problem" in:
http://lists.gnu.org/archive/html/bug-bison/2013-09/msg00015.html

One problem is that some errors are caught early, before the
generation of output files, while others can only be detected
afterwards (since, for instance, skeletons can raise errors
themselves).

This will be addressed in two steps: early errors do not generate
source files at all, while later errors will remove the files that
have already been generated.

* src/scan-skel.l (yyout): Open to /dev/null when there are errors.
* tests/output.at (AT_CHECK_FILES): Factored out of...
(AT_CHECK_OUTPUT): this.
Fuse the "SHELLIO" argument in the "FLAGS" one.
Use $5 to denote the expected exit status.
Add a test case for early errors.
2013-12-04 15:53:01 +01:00
Akim Demaille be29c71dd8 xml: also use "%empty" with html output
* data/xslt/xml2xhtml.xsl: No longer issue an Epsilon, display as in
dot and text formats.
2013-11-26 16:28:22 +01:00
Akim Demaille d439985436 style: formatting changes
* src/print-xml.c: here.
2013-11-26 16:20:55 +01:00
Akim Demaille f3d2a1b2ac xml: also display %empty for empty right-hand sides
* data/xslt/xml2dot.xsl, data/xslt/xml2text.xsl: Display %empty where needed.
2013-11-26 16:20:52 +01:00
Akim Demaille 21cf80399f reports: display %empty in the generated pointed-rules
* src/print.c (print_core): Use %empty for empty rules.
* src/print_graph.c (print_core): Ditto.
* tests/conflicts.at, tests/output.at, tests/reduce.at: Adjust
expectations.
2013-11-26 15:31:52 +01:00
Akim Demaille 7b0ca050f7 news: YYERROR vs variants 2013-11-26 15:31:51 +01:00
Akim Demaille a339aef48a style: scope reduction in lalr.cc
* src/lalr.c: Shorten variable scopes.
(lookahead_tokens_print): Use the same variable name in two loops
iterating over the same structure.
2013-11-18 10:29:23 +01:00
Akim Demaille 44186fc4ec lalr1.cc: formatting changes
* data/lalr1.cc: Fix indentation.
2013-11-15 10:14:06 +01:00
Akim Demaille 5c77412162 lalr1.cc: fix the support of YYERROR with variants
When variant are enabled, the yylhs variable (the left-hand side of
the rule being reduced, i.e. $$ and @$) is explicitly destroyed when
YYERROR is called.  This is because before running the user code, $$
is initialized, so that the user can properly use it.

However, when quitting yyparse, yylhs is also reclaimed by the C++
compiler: the variable goes out of scope.

Instead of trying to be too smart, let the compiler do its job: reduce
the scope of yylhs to exactly the reduction.  This way, whatever the
type of scope exit (regular, exception, return, goto...) this variable
will be properly reclaimed.

Reported by Paolo Simone Gasparello.
<http://lists.gnu.org/archive/html/bug-bison/2013-10/msg00003.html>

* data/lalr1.cc (yyparse): Reduce the scope of yylhs.
* tests/c++.at: We now pass this test.
2013-11-15 10:14:05 +01:00
Akim Demaille 5cf6e669af tests: check $$'s destruction with variant, YYERROR, and no error recovery
When variant are enabled, the yylhs variable (the left-hand side of
the rule being reduced, i.e. $$ and @$) is explicitly destroyed when
YYERROR is called.  This is because before running the user code, $$
is initialized, so that the user can properly use it.

However, when quitting yyparse, yylhs is also reclaimed by the C++
compiler: the variable goes out of scope.

This was not detected by the test suite because (i) the Object tracker
was too weak, and (ii) the problem does not show when there is error
recovery.

Reported by Paolo Simone Gasparello.
<http://lists.gnu.org/archive/html/bug-bison/2013-10/msg00003.html>

* tests/c++.at (Exception safety): Improve the objects logger to make
sure that we never destroy twice an object.
Also track copy-constructors.
Use a set instead of a list.
Display the logs before running the function body, this is more
useful in case of failure.
Generalize to track with and without error recovery.
2013-11-15 10:13:47 +01:00
Akim Demaille 16bb9f1647 tests: simplify useless obfuscation
* tests/c++.at: $$ is not special for M4, there is no need to "escape"
it.
2013-11-15 09:38:15 +01:00
Akim Demaille edb2e90531 skeletons: use better names when computing a "goto"
* data/glr.c (yyLRgotoState): Name the symbol argument yysym, instead
of yylhs.
* data/lalr1.cc (yy_lr_goto_state_): Likewise.
* data/lalr1.java (yy_lr_goto_state_): New, modeled after the previous
two routines.
Use it.
2013-11-14 16:26:16 +01:00
Akim Demaille 6d94eebba7 maint: post-release administrivia
* NEWS: Add header line for next release.
* .prev-version: Record previous version.
* cfg.mk (old_NEWS_hash): Auto-update.
2013-11-12 18:37:14 +01:00
Akim Demaille c2ecada32b version 3.0.1
* NEWS: Record release date.
2013-11-12 15:55:33 +01:00
Akim Demaille 458171e6df aver: it is no longer "protected against NDEBUG"
Apply the same rules for aver as for assert: no side effects,
especially not important ones.

* src/AnnotationList.c, src/muscle-tab.c: Adjust aver uses to resist
to -DNDEBUG.
2013-11-12 15:49:10 +01:00
Akim Demaille 8d0b7cef7d parsers: rename YY_NULL as YY_NULLPTR to avoid conflicts with Flex
Flex also defines YY_NULL (to 0).  Avoid gratuitous conflicts.

* data/c.m4 (b4_null_define): Rename YY_NULL as YY_NULLPTR.

* data/glr.c, data/lalr1.cc, data/location.cc, data/variant.hh,
* data/yacc.c, src/parse-gram.c, tests/actions.at, tests/c++.at,
* tests/cxx-type.at, tests/glr-regression.at, tests/headers.at,
* tests/push.at, tests/regression.at:
Adjust.
2013-11-08 10:52:15 +01:00
Akim Demaille afc4457605 build: use Automake 1.14's non-recursive Makefile features
* configure.ac: Require Automake 1.14.
* examples/calc++/local.mk, examples/local.mk, examples/mfcalc/local.mk,
* examples/rpcalc/local.mk, tests/local.mk: Use %D% and %C%.
2013-11-05 14:32:20 +01:00
Akim Demaille 60dcc936ce build: restore maintainer-push-check
* tests/local.mk: here.
2013-11-05 14:15:15 +01:00
Akim Demaille ad9d4f9f2e c++: use __attribute__((__pure__)) to avoid warnings
Building C++ parsers with -Wsuggest-attribute=const and
-Wsuggest-attribute=noreturn triggers warning in generated code.

* data/lalr1.cc: Call b4_attribute_define.
(debug_stream, debug_level): Flag as pure.
* tests/headers.at (Several parsers): There are now more YY macros
that "leak".
2013-11-05 10:44:03 +01:00
Akim Demaille 3cc83855d9 skeletons: update the handling of compiler attributes
* data/c.m4 (b4_attribute_define): Instead of defining __attribute__,
define YY_ATTRIBUTE conditionally.
(YY_ATTRIBUTE_PURE, YY_ATTRIBUTE_UNUSED, _Noreturn): New.
Use them.
* data/glr.c: Use them.
2013-11-05 10:44:03 +01:00
Akim Demaille 5407fc7d76 gnulib: update 2013-11-05 10:44:03 +01:00
Akim Demaille 516652b474 style: use /* ... */ comments
* src/complain.c: Here.
2013-10-24 17:22:21 +02:00
Akim Demaille 026816664f tests: skip C++ tests that are too demanding for some compilers
Some tests now fail when compiled with G++ 4.3 or 4.4 on MacPorts.

* tests/local.at (AT_SKIP_IF_EXCEPTION_SUPPORT_IS_POOR): New.
* tests/c++.at (Exception safety): Use it.
2013-10-24 17:22:21 +02:00
Akim Demaille 265640d56e install: do not install yacc.1 when --disable-yacc
* configure.ac (ENABLE_YACC): New conditional.
(YACC_SCRIPT, YACC_LIBRARY): Remove.
* lib/local.mk, src/local.mk: Use the former instead of the latter.
* doc/local.mk: Use ENABLE_YACC to avoid installing yacc.1.
2013-10-22 17:34:22 +02:00
Akim Demaille ee9cdb8595 style: avoid tabs
* src/scan-code.l: here.
2013-10-22 16:43:17 +02:00
Akim Demaille a810712331 c++: fix generated doxygen comments
* configure.ac: Enable -Wdocumentation if supported.
* data/lalr1.cc: Fix comments.
2013-10-22 16:31:57 +02:00
Akim Demaille 1a9646fc91 fix: uniqstr are already pointers
* src/uniqstr.c (uniqstr_assert): Remove incorrect double indirection,
and now useless cast.
2013-10-22 16:29:22 +02:00
Paul Eggert 67411a88a0 bison: pacify Sun C 5.12
* src/scan-code.l (show_sub_message):
Redo initializations to work around a bogus Sun C 5.12 warning.
(parse_ref): Remove unreachable code that Sun C 5.12 complains about.
* src/uniqstr.h (uniqstr_vsprintf): Use
_GL_ATTRIBUTE_FORMAT_PRINTF (...)  instead of __attribute__
((__format__ (__printf__, ...))).  Otherwise, Sun C 5.12
complains about an unknown attribute.
2013-10-21 15:23:43 -07:00
Paul Eggert 0bfe22b6d5 maint: git now ignores rpcalc
* examples/rpcalc/.gitignore: Ignore rpcalc.
2013-10-21 15:23:43 -07:00
Paul Eggert 3a684d611e build: examples/calc++/calc++ requires flex
* configure.ac (FLEX_CXX_WORKS): New AM_CONDITIONAL.
* examples/calc++/local.mk (examples/calc++/calc++):
Build if FLEX_CXX_WORKS, not BISON_CXX_WORKS.
2013-10-21 15:23:42 -07:00
Paul Eggert a9733794bb maint: mention help2man, texinfo, apt-get
* README-hacking: Add help2man, texinfo.
Describe how to add packages if you're using Debian.
2013-10-21 15:23:42 -07:00
Paul Eggert 19fe1aa332 maint: git now ignores .log and .trs files
* .gitignore: Add *.log, *.trs.
2013-10-21 15:23:42 -07:00
Akim Demaille 39bace5da8 tests: fix incorrect object construction
Reported by Ken Moffat.
http://lists.gnu.org/archive/html/bug-bison/2013-10/msg00009.html

* tests/c++.at (Exception safety): Here.
2013-10-21 10:36:53 +02:00
Akim Demaille 071863b3d8 glr: allow spaces between "%?" and "{" in predicates
Reported by Rici Lake.
http://lists.gnu.org/archive/html/bug-bison/2013-10/msg00004.html
http://stackoverflow.com/questions/19330171/

* src/scan-gram.l: Do not try to be too smart when diagnosing invalid
directives.
* tests/glr-regression.at (Predicates): New test.
2013-10-16 15:51:25 +02:00
Akim Demaille e4678430c2 diagnostics: "-Werror -Wno-error=foo" must not emit errors
Currently "-Werror -Wno-error=foo" still turns "foo" warnings into errors.
Reported by Alexandre Duret-Lutz.
See http://lists.gnu.org/archive/html/bug-bison/2013-09/msg00015.html.

* src/complain.c (errority, errority_flag): New.
(complain_init): Initialize the latter.
(warning_argmatch): Extract the loop iterating on the flag's bits.
Set and unset errority_flag here.
(warnings_argmatch): -Wno-error is not the same as -Wno-error=everything:
we must remember if category foo was explicitly turned in an error/warning
via -W(no-)error=foo.
(warning_severity): Use errority_flag.

* tests/input.at (Symbols): Just check --yacc, not -Wyacc, that's the
job of tests on -W.
(-Werror is not affected by -Wnone and -Wall): Rename as...
(-Werror combinations): this.
Tests more combinations of -W, -W(no-)error, and -W(no-)error=foo.
* tests/local.at (AT_BISON_CHECK_WARNINGS): Don't expect -Werror
to turn runs that issue warnings into runs with errors, as the
warnings might be enforced as warnings by -Wno-error=foo, in which
case -Werror does not change anything.

* doc/bison.texi (Bison Options): Try to be clearer about how
-W(no-)error and -W(no-)error=foo interact.
2013-10-16 14:56:09 +02:00
Akim Demaille 2b7fe38c36 comment changes
* src/complain.h, src/complain.c: More documentation, more comments.
2013-10-16 14:45:27 +02:00
Andreas SchwabandAkim Demaille 4c4191cec2 location: fix EOF check
* location.c (location_caret): Use int, not char, for values from
getc.
2013-10-04 14:00:52 +02:00
Akim Demaille ae7cd18c98 style: variant: remove empty line
* data/variant.hh (b4_symbol_constructor_define_): Remove
stray eol.
2013-09-19 16:45:09 +02:00
Akim Demaille 77482f2783 glr: more assertions
* data/glr.c (yyaddDeferredAction, yyglrShiftDefer, yypdumpstack):
More assertions.
2013-09-19 15:58:00 +02:00
Akim Demaille 5a6e85fb8d glr: shorten scopes
* data/glr.c (yyglrReduce): Define yyflag with its value.
2013-09-19 15:57:59 +02:00
Akim Demaille 9e87ff5472 glr: formatting changes
* data/glr.c: here.
2013-09-19 15:57:59 +02:00
Akim Demaille 3afe18fd1f glr: better use of tracing macros
* data/glr.c (yydestroyGLRState): Use YY_SYMBOL_PRINT instead of
yy_symbol_print.
2013-09-19 15:57:59 +02:00
Akim Demaille b51cf830a6 examples: improve the output of the "variant" example
* examples/variant.yy: Improve the printing of lists.
2013-09-19 15:57:59 +02:00
Akim Demaille 66b03e134f variant: remove useless assertion
* data/variant.hh (move): Remove precondition assertion which is
ensured by the first call of the body (this precondition is also one
of "build").
2013-09-19 15:57:59 +02:00
Akim Demaille 3dc50b3bc2 tests: remove stray debugging traces
* tests/atlocal.in: Remove traces.
Be ready to remove conftest.dSYM generated on OS X.
2013-09-19 15:57:59 +02:00
Akim Demaille 0a244a2269 tests: do not use grep -q
Reported by Daniel Galloway.
http://lists.gnu.org/archive/html/bug-bison/2013-08/msg00020.html

* tests/java.at: Ignore grep's output instead.
2013-09-04 17:26:17 +02:00
Paul Eggert b5e27aa262 build: don't require flex for ordinary builds
* configure.ac (LEX): Don't fail if this is lex, as flex is not
required for ordinary builds.  Instead, issue a warning and
substitute a no-op LEX.  Reported by Michael Felt in
<http://lists.gnu.org/archive/html/bug-bison/2013-08/msg00009.html>.
2013-08-24 18:22:44 -07:00
Paul Eggert 0149d39e6e maint: update .gitignore
* .gitignore: Add *.eps, *.o, *.pdf, *.png, *.stamp, *~,
.deps, .dirstamp.  Needed to suppress unwanted chatter from
'git status' after a bootstrap build.
2013-08-24 18:00:52 -07:00
Paul Eggert 1d91bfdf1c build: port to pre-5.8.7 perl
* examples/local.mk (extract): Omit -f from perl options.
This doesn't work with perl versions before 5.8.7
that are configured without USE_SITECUSTOMIZE.
Reported by Michael Felt in
<http://lists.gnu.org/archive/html/bug-bison/2013-08/msg00006.html>.
2013-08-24 07:55:47 -07:00
Akim Demaille db40c3f869 tests: minor change to make it easier to test other skeletons
* tests/c++.at (Variants): Pass the skeleton as argument.
2013-08-01 16:11:27 +02:00
Valentin TolmerandAkim Demaille b663fd5322 uniqstr: fix assertion
* src/uniqstr.c (uniqstr_assert): Really make sure str is a uniqstr,
not just whether some uniqstr with the same content was registered.
2013-08-01 15:29:21 +02:00
Akim Demaille c4aa4ff541 build: ship the ASCII art figures
We don't ship the *.txt files that are used to build the info
file.
Reported by Colin Daley.

* doc/figs/example.txt: New.
* doc/local.mk (bison.info): Depend on the txt files.
And ship them.
2013-08-01 11:41:49 +02:00
Akim Demaille b97bbbaed7 doc: prefer the ".gv" extension to ".dot"
See http://marc.info/?l=graphviz-devel&m=129418103126092 for the
motivation (basically, some word processor now uses *.dot).

* doc/figs/example-reduce.dot: Rename as...
* doc/figs/example-reduce.gv: this.
* doc/figs/example-shift.dot: Rename as...
* doc/figs/example-shift.gv: this.
* doc/figs/example.dot: Rename as...
* doc/figs/example.gv: this.
* doc/local.mk: Adjust.
2013-08-01 11:20:13 +02:00
Akim Demaille e386b50f26 maint: post-release administrivia
* NEWS: Add header line for next release.
* .prev-version: Record previous version.
* cfg.mk (old_NEWS_hash): Auto-update.
2013-07-25 18:13:53 +02:00
Akim Demaille 534497f54b version 3.0
* NEWS: Record release date.
2013-07-25 17:55:58 +02:00
Akim Demaille a62a7b014c regen 2013-07-25 17:55:32 +02:00
Akim Demaille de1a2f20dd news: prepare 3.0
* NEWS (3.0): Reorder.
2013-07-25 17:53:59 +02:00
Akim Demaille afcc58c63e tests: fix invalid assignment when using variants in C++11
* tests/c++.at (Exception safety): In variant mode $$ is an instance
of Object.  Assigning YY_NULL in C++98 is incorrect, but behaves ok,
as it assigns YY_NULL=0 using Object::operator= (char v).  It is wrong
in C++11 as there is operator for "$$ = nullptr".
2013-07-25 17:53:59 +02:00
Akim Demaille d3ae5af6ec yacc: beware of "uninitialized uses" warnings
Again some issues with the fact that yylval is reported by GCC as
possibly not initialized in some cases.  Here, the case at hand is the
%destructor.

I am still not convinced that it is worth going all the trouble of
using pragmas to disable temporarily some warnings, instead of just
initializing the looking symbol once for all, but that's what Paul
voted for, see
<http://lists.gnu.org/archive/html/bison-patches/2012-10/msg00050.html>.

* data/c.m4 (b4_attribute_define): Define
YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN, YY_IGNORE_MAYBE_UNINITIALIZED_END,
YY_INITIAL_VALUE here, as we will need them in the generation of the
destructor function, which is defined in yacc.c before yyparse, which
was in charge of defining these macros.
* data/yacc.c (b4_declare_scanner_communication_variables): Simplify:
trying to factor the definitions of the case pure and impure is
too complex.
Actually, it is not even clear that this macro should really exist,
as even the calls are complex.
Be careful not to issue a lone ";", as this is a statement, and C90
forbids declarations after statements ; so write
"YY_INITIAL_VALUE(Decl;)", not "YY_INITIAL_VALUE(Decl);".
2013-07-25 17:53:59 +02:00
Akim Demaille 41dfa1cbf0 gnulib: update 2013-07-25 13:47:01 +02:00
Akim Demaille b7171c45f4 tests: skip C++ tests if we can't compile a simple program
There are possible conflicts between gnulib replacement functions (in
<stdio.h>) and their C++ wrappers (in <stream>).  Trying to address
these in configure seems too hard, and I don't know how to fix the issue
in gnulib.  Cowardly avoid the problem by skipping C++ tests when this
happens.
Reported by Stefano Lattarini.
http://lists.gnu.org/archive/html/bug-bison/2013-06/msg00001.html

* tests/atlocal.in (BISON_CXX_WORKS): Also set it to "skip" if we can't
compile a simple program using <stream>.
* tests/local.at: Comment changes.
2013-07-03 17:18:54 +02:00
Akim Demaille ac953ff80a tests: fix 'find' portability issues
Reported by Stefano Lattarini.
http://lists.gnu.org/archive/html/bug-bison/2013-06/msg00000.html

* tests/output.at (AT_CHECK_OUTPUT): Use Perl instead.
2013-07-03 08:39:41 +02:00
Akim Demaille facb910cbd maint: post-release administrivia
* NEWS: Add header line for next release.
* .prev-version: Record previous version.
* cfg.mk (old_NEWS_hash): Auto-update.
2013-06-24 10:29:36 +02:00
Akim Demaille 8faace8d1d version 2.7.91
* NEWS: Record release date.
2013-06-24 10:21:33 +02:00
Akim Demaille 9cdcbdf2cf NEWS: prepare for 2.7.91
* NEWS (2.7.91): Java push parsers.
2013-06-24 10:20:46 +02:00
Akim Demaille 45c64fa627 java: rename YYMORE as YYPUSH_MORE for consistency with C
http://lists.gnu.org/archive/html/bison-patches/2013-06/msg00008.html

* data/lalr1.java, doc/bison.texi, tests/javapush.at:
s/YYMORE/YYPUSH_MORE.
2013-06-24 09:37:18 +02:00
Akim Demaille 58b465ae5f tests: fix Java push failure when running with BISON_USE_PUSH_FOR_PULL
* tests/javapush.at (Trivial Push Parser with api.push-pull verification):
When push for pull is enabled, there is one such function generated.
2013-06-21 11:39:02 +02:00
Akim Demaille d116722c54 style: minor changes in the Java tests
* tests/java.at (AT_CHECK_JAVA_GREP): Ignore the exit status.
* tests/javapush.at (AT_CHECK_JAVA_GREP): Be more alike the previous
one.
Formating changes.
Remove stray debugging "jj" file.
2013-06-21 11:38:47 +02:00
Akim Demaille 1d678854a4 java: push: do not reset the error counter
* data/lalr1.java (parse): here, when in push-pull is in "both" mode.
This breaks the test suite, for instance
make check TESTSUITEFLAGS='-d 388 BISON_USE_PUSH_FOR_PULL=1'.
More generally make maintainer-push-check.
2013-06-21 11:17:05 +02:00
Akim Demaille 28c4075b58 build: add Valgrind suppression file for GNU/Linux
* build-aux/linux-gnu.valgrind: New.
* build-aux/local.mk: Ship it.
* configure.ac: Use it.
2013-06-14 09:58:12 +02:00
Dennis HeimbignerandAkim Demaille aa94def12d java: add push-parser support
* data/lalr1.java: Capture the declarations as m4 macros to avoid
duplication.  When push parsing, the declarations occur at the class
instance level rather than within the parse() function.

Change the way that the parser state is initialized.  For
push-parsing, the parse state declarations are moved to
"push_parse_initialize()", which is called on the first invocation of
"push_parse()". The %initial-action code is also inserted after the
invocation of "push_parse_initialize()".

The body of the parse loop is modified to return values at appropriate
points when doing push parsing.  In order to make push parsing work,
it is necessary to divide YYNEWSTATE into two states: YYNEWSTATE and
YYGETTOKEN. On the first call to push_parse(), the state is
YYNEWSTATE. On all later entries, the state is set to YYGETTOKEN. The
YYNEWSTATE switch arm falls through into YYGETTOKEN. YYGETTOKEN
indicates that a new token is potentially needed.  Normally, with a
pull parser, this new token would be obtained by calling "yylex()". In
the push parser, the value YYMORE is returned to the caller. On the
next call to push_parse(), the parser will return to the YYGETTOKEN
state and continue operation.

* tests/javapush.at: New test file for java push parsing.
* tests/testsuite.at: Use it.
* tests/local.mk: Adjust.
* doc/bison.texi (Java Push Parser Interface): New.

Signed-off-by: Akim Demaille <[email protected]>
2013-06-13 10:38:14 +02:00
Akim Demaille 0fcc2e9a74 build: ship all the files, even if the C++ compiler is broken
* examples/calc++/local.mk: Be sure to ship calc++.test even if
the current C++ compiler is not sufficient to run the tests.
2013-06-11 16:36:38 +02:00
Dennis HeimbignerandAkim Demaille 94a6225578 style: comment changes in Java skeleton
* data/lalr1.java: Here.
2013-06-05 10:04:21 +02:00
Akim Demaille 02798ba13d tests: fix a G++ warning
* tests/c++.at: Use YY_NULL instead of 0 for the null pointer.
And formatting changes.
2013-06-03 16:41:17 +02:00
Akim Demaille 8e13c5c03b build: fix a warning from clang
* src/muscle-tab.c: Declare local functions static.
2013-06-03 16:40:30 +02:00
Akim Demaille 266cdc3025 maint: post-release administrivia
* NEWS: Add header line for next release.
* .prev-version: Record previous version.
* cfg.mk (old_NEWS_hash): Auto-update.
2013-05-30 15:28:44 +02:00
Akim Demaille fea2516636 version 2.7.90
* NEWS: Record release date.
2013-05-30 15:02:52 +02:00
Akim Demaille c0ef22ab0b style: syntax-check fixes
* data/yacc.c, src/Sbitset.c, src/Sbitset.h, src/muscle-tab.h,
* src/output.c, src/parse-gram.y, src/reader.c, src/symtab.c,
* src/uniqstr.c, src/uniqstr.h: Fix space before parens.
* cfg.mk (_space_before_paren_exempt): Add needed exceptions.
2013-05-30 14:10:05 +02:00
Akim Demaille 971ef18e30 xml: use %empty in the text output
* data/xslt/xml2text.xsl: here.
2013-05-30 11:07:57 +02:00
Akim Demaille ec991d74e1 build: locally disable new GCC warnings that fail on Flex generated code
* configure.ac: here.
2013-05-30 11:07:57 +02:00
Akim Demaille c0efa83c0b fix a memory leak
* src/print-xml.c (num_escape_bufs): New.
(print_xml): Be sure to release all the escape_bufs.
2013-05-30 11:07:57 +02:00
Akim Demaille e37054cf27 regen 2013-05-30 11:07:56 +02:00
Akim Demaille 89ff1b5e71 build: be sure to include config.h first in the generated parser
Using %code for config.h is wrong, as some headers will already have
been included by Bison.  In some cases, e.g., glibc's string.h, this
results in some declaration not being made for lack of definition of
_GNU_SOURCE, which is performed by config.h.

* src/parse-gram.y: here.
2013-05-30 10:47:49 +02:00
Akim Demaille f122444873 Merge remote-tracking branch 'origin/maint'
* origin/maint:
  maint: post-release administrivia
  version 2.7.1
  regen
2013-05-29 09:05:12 +02:00
Petr MachataandAkim Demaille 30465cb778 drop unused options --raw, -n, -e, --include and -I
* --raw appears to be ignored.  It was marked as obsolete in the
  commit ec3bc39, and documented as no longer supported as of 1.29
  (2001-09-07).  Support for %raw appears to have been dropped in
  e9955c83 on 2002-06-11, but --raw was kept around.  Maybe it's time
  to drop it as well?

* Commit e9955c83 dropped support for %no-parser as well, and
  converted it to option.  --no-parser was later dropped in 728c4be2
  on 2007-08-12, but -n was kept around, probably as an omission.  All
  three are documented as removed since 2.3b (2008-05-27).

* -e existed for a single day in 2001.  It was introduced in eeeb962b
  on 2001-11-27.  The handling was removed in c7925b99 on 2001-11-28,
  but "e" was kept in the list of short options.  Probably an
  omission.

* --include appears to be dead code.  The option sets a variable, but
  that variable is not used anywhere.  It was added in f6bd5427 on
  2001-11-26 as a %-directive, with comments that it's not yet
  implemented.  It was converted to a command-line option later, but
  doesn't seem to ever have been actually implemented.

Signed-off-by: Petr Machata <[email protected]>
Signed-off-by: Akim Demaille <[email protected]>
2013-05-29 08:57:31 +02:00
Akim Demaille f9340b27b2 gnulib: update 2013-05-28 16:40:44 +02:00
Akim Demaille f249e803f0 diagnostics: always point to the first directive
Some directives cannot be used several times (e.g., a given symbol may
only have a single printer).  In case of repeated definitions, an
error is issued for the second definition, yet it is not discarded,
and becomes the definition used for the rest of the file.

This is not consistent with the idea that multiple definitions are not
allowed: discard any repeated directive.

* src/symtab.c (symbol_type_set, symbol_code_props_set)
(semantic_type_code_props_set, symbol_class_set, symbol_translation):
Discard repeated directives.
* tests/input.at (Default %printer and %destructor redeclared)
(Per-type %printer and %destructor redeclared): Update expectations.
2013-04-22 13:55:00 +02:00
Akim Demaille dfb12d6845 tests: factor test for printer/desctructor redefined
* tests/input.at (Default %printer and %destructor redeclared):
Introduce AT_TEST to factor.
2013-04-22 13:47:50 +02:00
Akim Demaille d8ce703102 diagnostics: use appropriate location for useless precedence/associativity
* src/symtab.c (symbol_precedence_set): Use prec_location, not
location (which is the first occurrence of the symbol, possibly just
%token).
Also, as redefinitions are not allowed, keep the first values, not
the subsequent ones.
* tests/conflicts.at, tests/existing.at, tests/regression.at: Adjust.
2013-04-22 11:36:22 +02:00
Akim Demaille 8782fe26cb tests: factor duplicate expected warnings
* tests/existing.at: Instead of "t ? abc : aBc", write "a(t?b:B)c".
2013-04-22 11:13:09 +02:00
Akim Demaille 7ba01e111c tests: enable -Wsign-compare and fix corresponding warnings
-Wsign-compare was disabled for bison's own code, following gnulib's
approach.  However, the generated parsers should not trigger such
warnings.

Reported by Efi Fogel.
http://lists.gnu.org/archive/html/help-bison/2013-04/msg00018.html

See also http://stackoverflow.com/questions/16101062 for the weird
"-(unsigned)i" piece of code.

* configure.ac (warn_tests): Enable -Wsign-compare.
* data/location.cc (position::add_): New.
(position::lines, position::columns): Use it.
* tests/actions.at (AT_CHECK_PRINTER_AND_DESTRUCTOR): Fix signedness issues.
2013-04-19 17:13:07 +02:00
Akim Demaille 6ce4b4ff1b muscle: check more cases of %define variables with code values
* data/bison.m4 (b4_percent_define_check_kind): Fix overquotation.
(api.location.type, api.position.type): Check they have code values here.
* data/c++.m4 (api.location.type): No longer checked here.
(parser_class_name): Check it here.
* data/java.m4 (api.value.type, init_throws, lex_throws, parser_class_name)
(throws, annotations, extends, implements): Check they have code values.
* doc/bison.texi: Fix every incorrect occurrence of %define.
Document the additional syntax for %define: code values.
Document the additional syntax for -D/-F: string and code values.
* tests/calc.at, tests/headers.at, tests/input.at, tests/java.at,
* tests/local.at: Fix dependencies.
2013-04-18 17:19:30 +02:00
Akim Demaille 332019e19a regen 2013-04-18 16:47:41 +02:00
Akim Demaille 9402b62353 parser: do not convert $ and @ in code values of %define variables
* src/parse-gram.y (value: "{...}"): Just strip the braces, but pass
the value as is.
2013-04-18 16:37:23 +02:00
Akim Demaille 985d7177e8 parser: no longer use the "braceless" non-terminal
The purpose of this symbol was only to factor function calls.  As a
result the actions were indeed simpler, but the grammar was somewhat
uselessly obfuscated.  Get rid of this symbol, but introduce functions
to simplify dependencies.

There is no (intended) changes of behavior here.

* src/parse-gram.y (strip_braces, translate_code(
(translate_code_braceless): New.
(braceless): Remove, use "{...}" instead, and one of the previous
functions depending on the context.
(STRING, "%{...%}", EPILOGUE): Declare as <code>, instead of <chars>,
the difference between both is useless (well, I couldn't make sense of
it, even after having read the initial commit that introduced them).
(%union): Remove the now useless "chars" type.
Adjust the printers.
* src/scan-gram.l: Adjust.
2013-04-18 16:36:58 +02:00
Akim Demaille 7dbadca2d0 regen 2013-04-18 15:12:24 +02:00
Akim Demaille 3f21a394f4 style: avoid %{...%} in our parser
* src/parse-gram.y (%{...%}): Split in %code and %code requires.
* src/location.h: Add missing includes for self containedness.
2013-04-18 15:11:53 +02:00
Akim Demaille 827aca04eb style: use %code for local function declarations in our parser
* src/parse-gram.y (version_check, gram_error, char_name, lloc_default):
Move their prototypes from %{...%} to %code.
(YYLLOC_DEFAULT, YY_LOCATION_PRINT): Move from %{...%} to %code.
(current_lhs): Move its implementation to the epilogue.
2013-04-18 15:10:35 +02:00
Akim Demaille ff2e3d397a regen 2013-04-16 18:06:08 +02:00
Akim Demaille aba47f5624 muscle: check the kind of api.prefix, api.location.type
* data/bison.m4: Check api.prefix.
* data/c++.m4: Check api.location.type.
* doc/bison.texi: Fix uses of api.value.type, api.prefix, api.location.type.
Document {...} values for %define.
* src/parse-gram.y: Fix use of api.prefix.
* tests/calc.at: Fix uses of api.location.type.
* tests/input.at: Check api.prefix, and api.location.type.
2013-04-16 17:42:43 +02:00
Akim Demaille abcfd805b8 maint: post-release administrivia
* NEWS: Add header line for next release.
* .prev-version: Record previous version.
* cfg.mk (old_NEWS_hash): Auto-update.
2013-04-15 14:09:40 +02:00
Akim Demaille 1f5542fe2d version 2.7.1
* NEWS: Record release date.
2013-04-15 13:59:02 +02:00
Akim Demaille d065cb3853 regen 2013-04-15 11:29:54 +02:00
Akim Demaille c53b684889 muscle: enforce definition syntax for keyword variables
* src/muscle-tab.c (muscle_percent_define_get_kind)
(muscle_percent_define_check_kind): New.
(muscle_percent_define_default): Variables with a default value are
of "keyword" kind.
(muscle_percent_define_flag_if, muscle_percent_define_check_values):
Check that the variable is of keyword kind.
* data/bison.m4: Likewise, but in M4.  That is to say...
(b4_percent_define_default): Define the kind when the variable is undefined.
(b4_percent_define_check_kind): Use a better error message.
(_b4_percent_define_check_values, _b4_percent_define_check_values):
Former "enum" variables should be defined using the keyword syntax.
* doc/bison.texi: Update.
A couple of fixes.
* tests/input.at (%define keyword variables): New.
2013-04-15 10:57:19 +02:00
Akim Demaille 5fad4d4f09 muscle: let -D/-F support the three kinds of %define variable values
See http://lists.gnu.org/archive/html/bison-patches/2013-04/msg00012.html

* src/getargs.c (getargs): Recognize {value} and "value" for -D and -F.
2013-04-15 10:57:19 +02:00
Akim Demaille 7956485cd6 muscle: minor refactoring
* src/muscle-tab.c (muscle_percent_define_default): Reduce the scopes.
2013-04-15 10:57:05 +02:00
Akim Demaille bb4b189b9c muscle: minor simplification which uncovers a missing warning
* src/muscle-tab.c (muscle_percent_define_ensure): Discover the virtues
of || to factor conditionals.
* NEWS: As api.pure is no longer flagged as "used" by accident,
we now have warnings for useless definitions.
* tests/calc.at: So remove api.pure settings when running C++ tests,
since C++ skeletons use a pure interface.
2013-04-15 10:50:30 +02:00
Akim Demaille d9cfa2bee2 muscle: factor the field retrieval
* src/muscle-tab.c (muscle_percent_define_get_raw): New.
Use it where appropriate.
(location_decode): No longer fetch the value from the table,
take the value as argument.
2013-04-15 10:50:30 +02:00
Akim Demaille 0f9583b69b muscle: factor the handling of used variables
* src/muscle-tab.c (muscle_percent_define_use): New, corresponding
to b4_percent_define_use.
Use it where appropriate.
2013-04-15 10:50:30 +02:00
Akim Demaille c98b5143b0 muscle: factor the computation of variable names
* src/muscle-tab.c (muscle_name): New.
Use it.
Propagate "uniqstr" as value type instead of plain "char const *".
2013-04-15 10:50:12 +02:00
Akim Demaille 07e65a77aa muscle: factor the kind check in M4
* data/bison.m4 (b4_percent_define_check_kind): New.
Use it to check api.token.prefix.
* data/c++.m4: Check the kind of api.namespace.
* doc/bison.texi: Update a reference to former 'namespace' variable.
* tests/input.at ("%define" code variables): Check api.namespace.
2013-04-15 10:37:00 +02:00
Akim Demaille ee616bdc62 muscle: factor conditionals on defined %define variables
* data/bison.m4 (b4_percent_define_ifdef_): New.
Use it where appropriate.
2013-04-15 10:32:48 +02:00
Akim Demaille 630a021850 api.token.prefix: use code values
* data/bison.m4: Remove useless (and incorrect: m4_* instead of b4_*)
default assignment to api.token.prefix.
Check that api.token.prefix is assigned code.
* tests/input.at (%define code variables): New test.
* NEWS, doc/bison.texi, tests/c++.at, tests/calc.at,
* tests/java.at, tests/local.at: Adjust to use braces.
2013-04-11 15:54:46 +02:00
Akim Demaille 75ae829984 c++: fix several issues with locations
Reported by Daniel Frużyński.
http://lists.gnu.org/archive/html/bug-bison/2013-02/msg00000.html

* data/location.cc (position::columns, position::lines): Check for
underflow.
Fix some weird function signatures.
(location): Accept signed integers as arguments where appropriate.
Add operator- and operator+=.
* doc/bison.texi (C++ position, C++ location): Various fixes
and completion.
* tests/c++.at (C++ Locations): New tests.
2013-04-11 12:50:59 +02:00
Akim Demaille 08cc1a3b18 muscles: be sure that %code snippets are not glue together on a single line
Recently "braceless" in the parser was changed so that an eol was no
longer added to the value.  This is not correct when a %code is used
multiple times, because the syncline of the next snippet might be
appended to the last (and not ended) line of the previous snippet.

* src/muscle-tab.h (muscle_grow): Make it private.
* src/muscle-tab.c (muscle_grow): Accept a fourth argument: a required
terminator.
Adjust callers.
* tests/input.at (Multiple %code): New.
2013-04-11 09:21:08 +02:00
Akim Demaille edaa22ec15 style: fix comments
* tests/actions.at: Fix incorrect "prototype".
2013-04-11 08:47:43 +02:00
Akim Demaille cc8962bdde Merge remote-tracking branch 'origin/maint'
* origin/maint:
  glr.cc: fix a clang warning
  maint: update copyright years
  build: fix VPATH issue
  build: avoid clang's colored diagnostics in the test suite
  tests: please clang and use ".cc", not ".c", for C++ input
  gnulib: update
  skeletons: avoid empty switch constructs
  lalr1.cc: fix compiler warnings
  yacc.c: do not use __attribute__ unprotected
  tests: style changes
2013-04-10 10:24:56 +02:00
Akim Demaille 435575cb5e api.value.type: use keyword/brace values
Suggested by Joel E. Denny.
http://lists.gnu.org/archive/html/bison-patches/2013-03/msg00016.html

* data/bison.m4 (b4_percent_define_get_kind): New.
(b4_variant_flag): Check that api.value.type is defined as the 'variant'
keyword value.
* data/c.m4 (_b4_value_type_setup_keyword): New.
(b4_value_type_setup): Use it to simplify reading.
Use b4_define_silent.
Decode api.value.type, including its type.
(b4_value_type_define): Likewise.
* data/c++.m4 (b4_value_type_declare): Adjust the decoding of api.value.type,
taking its kind into account.
* doc/bison.texi: Adjust all the examples to the new syntax.
* NEWS: Ditto.
* tests/types.at: Adjust
2013-04-09 16:59:06 +02:00
Akim Demaille 1fa19a7697 api.value.type: diagnose guaranteed failure with --yacc
Instead of generating invalid C code, generate an error when --yacc and
'%define api.value.type union' are used together.

* data/bison.m4: Issue an error in this case.
* tests/types.at (%yacc vs. %define api.value.type union): New, check this
error.
* doc/bison.texi (Type Generation): Document it.
* tests/output.at: Check that '-o y.tab.c' and '-y' behave equally
wrt generated file names.
* NEWS (Use of YACC='bison -y'): New.
Promote the use of 'bison -o y.tab.c'.
2013-04-09 14:07:52 +02:00
Akim Demaille d1a07886ee doc: style changes
* doc/bison.texi (Destructor Decl, Printer Decl): Group series of %token
and %type together.
2013-04-09 14:07:52 +02:00
Akim Demaille 71846502ae doc: display locations in error as recommended by GNU Coding Standards
* doc/bison.texi (Actions and Locations): here.
2013-04-09 14:07:52 +02:00
Akim Demaille 90b89dadb2 doc: api.value.type union
* doc/bison.texi (Type Generation): New section.
(Multi-function Calc): Convert to use api.value.type=union.
2013-04-09 14:07:51 +02:00
Akim Demaille e4d49586b6 doc: move the section about "%union" where types are discussed
* doc/bison.texi (Union Decl): Move to...
(Defining Language Semantics): here.
2013-04-09 14:07:51 +02:00
Akim Demaille 21e3a2b56c doc: deprecate #define YYSTYPE in favor of %define api.value.type
* doc/bison.texi: Convert examples with YYSTYPE to use api.value.type.
Deprecate YYSTYPE.
2013-04-09 14:07:51 +02:00
Akim Demaille cb8d8bb9b6 value type: accept "->" in type tags
Provide a means to dereference pointers when defining tags.  One
example could be:

  %code requires
  {
    typedef struct ListElementType
    {
      union value
      {
        int intVal;
        float floatVal;
        char* charptrVal;
      } value;

      struct ListElementType* next;
    } ListElementType;
  }

  %union
  {
    ListElementType* list;
  }

  %token <list->value.charptrVal> STRING
  %token <list->value.intVal> INTEGER
  %token <list->value.floatVal> REAL
  %type <list> ElementList LiteralType

* src/scan-code.l, src/scan-gram.l: Accept "->" in tags.
* tests/types.at: Add more test cases to cover this case.
2013-04-09 14:07:51 +02:00
Akim Demaille e52ddf820b style: simplify the scanning of type tags
* src/scan-gram.l: Remove the rule for simple tags: the "complex" case
subsumes it.  It was more efficient, but duplicated the code for a
negligible benefit.
2013-04-09 14:07:51 +02:00
Akim Demaille 6574576cfb api.value.type: implement proper support, check, and document
* data/c.m4 (b4_symbol_type_register, b4_type_define_tag)
(b4_symbol_value_union, b4_value_type_setup_union)
(b4_value_type_setup_variant, b4_value_type_setup):
New.
(b4_value_type_define): Use it to set up properly the type.
Handle the various possible values of api.value.type.
* data/c++.m4 (b4_value_type_declare): Likewise.
* data/lalr1.cc (b4_value_type_setup_variant): Redefine.

* tests/types.at: New.
Exercise all the C/C++ skeletons with different types of
api.value.type values.
* tests/local.mk, tests/testsuite.at: Use it.

* doc/bison.texi (%define Summary): Document api.value.type.
* NEWS: Advertise it, together with api.token.constructor.
2013-04-09 14:07:51 +02:00
Akim Demaille dde95ca432 m4: allow the definition of side-effect only macros
* data/bison.m4 (b4_divert_kill, b4_define_silent): New.
* data/c.m4: Comment change.
2013-04-09 14:07:51 +02:00
Akim Demaille 6155db81aa variant: fix inconsistent quotation
* data/variant.hh (b4_char_sizeof): De-overquote.
(b4_value_type_declare): De-underquote.
2013-04-09 14:07:51 +02:00
Akim Demaille 11872a8372 m4: style changes in error messages
* data/bison.m4: Use $0 to denote the current macro's name.
2013-04-09 14:07:50 +02:00
Akim Demaille 49964a4fe0 glr.cc: fix a clang warning
* data/glr.cc (b4_epilogue): Be sure to end with an end-of-line,
so that the file does end with one.
2013-04-08 19:52:16 +02:00
Akim Demaille 68f91d58f1 maint: update copyright years
Run "make update-copyright".
2013-04-08 13:44:57 +02:00
Akim Demaille 42bcf1ce44 build: fix VPATH issue
* Makefile.am (update-b4-copyright, update-package-copyright-year): Fix
path to build-aux.
(cherry picked from commit f6df83b4e8)

Conflicts:
	Makefile.am
2013-04-08 13:39:21 +02:00
Akim Demaille de7331a075 build: avoid clang's colored diagnostics in the test suite
The syncline tests, which try to recognize compiler diagnostics,
are confused by escapes for colors.

* configure.ac (warn_tests): New, to factor the warnings for both
C and C++ tests.
Add -fno-color-diagnostics to it.
* tests/local.at (AT_TEST_TABLES_AND_PARSE): Do not remove glue
together compiler flags.

Conflicts:
	configure.ac
2013-04-08 13:32:47 +02:00
Akim Demaille b0db817ff2 tests: please clang and use ".cc", not ".c", for C++ input
When fed with foo.c, clang++ 3.2 answers:

  clang: error: treating 'c' input as 'c++' when in C++ mode,
                this behavior is deprecated

* tests/output.at (AT_CHECK_OUTPUT_FILE_NAME): Use *.cc and *.hh
for C++.
2013-04-08 13:29:26 +02:00
Akim Demaille a565f73276 gnulib: update 2013-04-08 11:26:44 +02:00
Akim Demaille 3cf3393bd4 skeletons: avoid empty switch constructs
Reported by Rob Conde.
http://lists.gnu.org/archive/html/bug-bison/2013-03/msg00003.html

* data/c.m4 (b4_symbol_actions): Rename as...
(_b4_symbol_actions): this.
(b4_symbol_actions): New wrapper.
Do not emit empty switches.
Adjust all b4_symbol_actions callers.
2013-04-08 11:17:09 +02:00
Akim Demaille e83be476a5 lalr1.cc: fix compiler warnings
Reported by Rob Conde.
http://lists.gnu.org/archive/html/bug-bison/2013-03/msg00003.html

* data/stack.hh (operator=, stack(const stack&)): Make this class
uncopyable, i.e., "undefine" these operators: make them private and
don't implement them.
(clear): New.
* data/lalr1.cc: Use it instead of an assignment.
(parser): Make this class uncopyable.
2013-04-08 10:59:19 +02:00
Akim Demaille 80a2826e69 yacc.c: do not use __attribute__ unprotected
Reported by Victor Khomenko.
http://lists.gnu.org/archive/html/bug-bison/2013-04/msg00001.html

* data/glr.c (YYUSE, __attribute__): Fuse their definition into...
* data/c.m4 (b4_attribute_define): this new macro.
* data/yacc.c, data/glr.c: Use it.
2013-04-08 10:44:09 +02:00
Akim Demaille eb0e86ac80 api.namespace: demonstrate and use {...} values instead of "..." values
* tests/c++.at, tests/input.at: Use "%define api.namespace {foo}" instead
of using quotes.
* tests/local.at (AT_SETUP_STRIP, AT_NAME_PREFIX): Recognize uses of
braces instead of quotes.
* doc/bison.texi: Use braces for api.namespace's values.
2013-04-05 10:43:44 +02:00
Akim Demaille 57597927ef grammar: do not add a \n at the end of blocks of code
Now that we use "braceless" (which is {...} blocks of code with
initial and final braces stripped) to denote "short" values (such as
api.namespaces), the added end-of-line is a nuisance.  As a matter of
fact, this extra-safety was useless, as every expansion of "braceless"
(aka, "user code") is followed by an end of line.

* src/parse-gram.y, src/parse-gram.c (braceless): Instead of replacing
the final brace by \n, just delete the brace.
2013-04-05 10:42:59 +02:00
Akim Demaille de5fb744c9 regen 2013-04-04 16:50:55 +02:00
Akim Demaille 14bfd2e9d9 grammar: record the kind of %define variable values
Provide a means to tell the difference between "keyword" values (e.g.,
%define api.pull both), "string" values (e.g., %define file.name
"foo"), and "code" values (e.g., %define api.namespace {calc}).

Suggested by Joel E. Denny.
http://lists.gnu.org/archive/html/bison-patches/2013-03/msg00016.html

* src/muscle-tab.h, src/muscle-tab.c (muscle_kind, muscle_kind_new)
(muscle_kind_string): New.
(muscle_percent_define_insert): Take the kind as new argument.
Insert it in the muscle table.
Adjust callers.
* src/getargs.c: Adjust callers.
* src/parse-gram.y: Ditto.
(content.opt): Remove, replaced by...
(value): this new non-terminal, whose semantics value is stored
in the new "value" union member.
Provide a printer.
Support values in braces in additions to keyword and string values.

fuse me
2013-04-04 16:50:38 +02:00
Akim Demaille 36a17b50b5 style: fix comments
* src/muscle-tab.c (muscle_percent_define_ensure): Update obsolete
comments.
2013-04-04 16:27:54 +02:00
Akim Demaille 8a9283494b regen 2013-04-04 15:48:08 +02:00
Akim Demaille dac72a91d9 grammar: style changes
* src/parse-gram.y (PARAM_TYPE): Remove useless typedef guard.
There's a header guard.
Use 'yyo' with %printer.
Use a consistent style for %union one-liners.
2013-04-04 15:41:49 +02:00
Akim Demaille a17c70f876 grammar: split %union to group together related aspects
* src/parse-gram.y (INT): Fuse the %type and %token declaration.
Move its %union right before its introduction.
(%union): Split in several %unions, right before their use.
2013-04-04 15:38:06 +02:00
Akim Demaille c56d0037d2 muscle: refactor
* src/muscle-tab.c (muscle_lookup, muscle_entry_new): New.
(muscle_insert, muscle_grow, muscle_find_const, muscle_find): Use them.
2013-04-04 15:18:29 +02:00
Akim Demaille 9fb61ca8d8 style: comment changes
* src/muscle-tab.c: Move the documentation of public functions to...
* src/muscle-tab.h: here.
Fix comment consistency issues.
2013-04-03 17:15:50 +02:00
Akim Demaille 3f6e5dd6ac muscle: minor refactoring
* src/muscle-tab.h (MUSCLE_INSERT_C_STRING): Use MUSCLE_INSERT_STRING.
2013-04-03 17:07:22 +02:00
Akim Demaille 2dc8862bab regen 2013-03-06 10:31:55 +01:00
Valentin TolmerandAkim Demaille 5202b6ac1d gram: correct token numbering in precedence declarations
In a precedence declaration, when tokens are declared with a litteral
character (e.g., 'a') or with a identifier (e.g., B), Bison behaved
differently: the litteral tokens would be numbered first, and then the
other ones, leading to the following grammar:

  %right A B 'c' 'd'

being numbered as such: 'c' 'd' A B.

* src/parse-gram.y (symbol.prec): Set the symbol number when reading the
symbols.
* tests/conflicts.at (Token declaration order: literals vs. identifiers):
New.

Signed-off-by: Akim Demaille <[email protected]>
2013-03-06 10:31:47 +01:00
Akim Demaille 02879b4e81 maint: update autoconf submodule
* submodules/autoconf: Up to master.
No significant changes in the files we use (m4sugar.m4 and foreach.m4).
2013-03-04 18:26:25 +01:00
Akim Demaille f24695eff9 diagnostics: no longer include the yacc category in -Wall
It would be a pity to warn the users against Bison features...
http://lists.gnu.org/archive/html/bison-patches/2013-02/msg00107.html

* src/complain.h, src/complain.c (Wall): Disable Wyacc.
(Weverything): New (hidden so far) category which really denotes all
the categories (what used to be Wall).
(warnings_args, warnings_types): Adjust.
(warning_argmatch): Now !none = Weverything and conversely, no longer Wall.
* NEWS, doc/bison.texi, src/getargs.c: Adjust the documentation.
* tests/input.at (-Werror is not affected by -Wnone and -Wall): Adjust
by not using a -Wyacc type of warning.
2013-03-04 18:21:44 +01:00
Akim Demaille 05e25f2384 grammar: no longer detect and cure missing semicolon at end of actions
Bison 3.0 is already breaking backward compatibility with other
features.  It is an appropriate time to drop this feature.  Note that
it was disabled when --yacc is passed.  See
http://lists.gnu.org/archive/html/bison-patches/2013-02/msg00102.html

Basically, revert e8cd1ad655.

* src/scan-code.l (braces_level, need_semicolon, in_cpp): Remove.
Remove every rule needed to detect and add missing semicolon.
* tests/actions.at (Fix user actions without a trailing semicolon):
Remove.
* NEWS: Adjust.
2013-03-04 08:29:18 +01:00
Akim Demaille f1526426cd build: stop using bison -y
* Makefile.am (YACC): Pass -o y.tab.c, so that ylwrap is happy, and
yet we don't pass --yacc to bison.
(AM_YFLAGS): Disable Yacc warnings.
2013-03-04 08:25:32 +01:00
Akim Demaille 7601a471f5 c++: rename b4_semantic_type_declare as b4_value_type_declare
This is to match the names used in C and api.value.type, even if the
parser actually defines semantic_type.

* data/c++.m4 (b4_semantic_type_declare): Rename as...
(b4_value_type_declare): this.
* data/variant.hh: Likewise.
2013-02-23 16:16:15 +01:00
Akim Demaille 6c7022f7d3 news: typo
* NEWS: here.
2013-02-23 16:16:15 +01:00
Akim Demaille edd3280b69 style: space changes in the tests
* tests/local.at: here.
2013-02-23 16:16:15 +01:00
Akim Demaille fe65b14424 style: formatting changes in the doc
* doc/bison.texi: Use @file where appropriate.
2013-02-22 13:18:39 +01:00
Akim Demaille e39fcdda38 tests: fix invalid C++11 code
* tests/c++.at (Object): Somehow instances of Object were assigned
YY_NULL, which is 0 most of the time (that case passes), but is
nullptr in C++11, and there is nothing in Object to support such an
assignment (failure).  Use 0 as value, and provide the needed
assignment operator.
Also, use a more natural order within the class definition.
2013-02-19 17:47:13 +01:00
Akim Demaille 5ae8eb3202 tests: fix failures with G++ 4.8 in Flex scanner
* configure.ac (WARN_NO_NULL_CONVERSION_CXXFLAGS): Rename as...
(FLEX_SCANNER_CXXFLAGS): this.
Pass -Wno-zero-as-null-pointer-constant to G++ if it supports it.
* examples/calc++/local.mk: Adjust.
2013-02-19 17:42:33 +01:00
Akim Demaille bbed3fdef6 regen 2013-02-19 10:07:37 +01:00
Akim Demaille 42fef01256 gnulib: update 2013-02-19 09:51:38 +01:00
Akim Demaille 29248b4c13 style: rename variant private members
* data/variant.hh (buffer, tname, as_, raw, align_me): Rename as...
(yybuffer_, yytname_,yyas_, yyraw, yyalign_me): these.
2013-02-19 09:51:38 +01:00
Akim Demaille 361444e419 style: space changes
* data/variant.hh: Be sure to leave a space before arguments in function
calls.
2013-02-19 09:51:38 +01:00
Akim Demaille 85bc7f5466 variant: fix G++ 4.4 warnings
The changes by Théophile Ranquet about type punning issues need
to be extend to in-place new to please G++ 4.4.7.

* data/variant.hh (variant::as_): New, factors the casts that avoid
compiler warnings.
(as, build): Use them.
2013-02-19 09:51:38 +01:00
Akim Demaille 1282c12476 news: spell fixes
* NEWS: here.
2013-02-18 14:30:19 +01:00
Akim Demaille 0fe5a72a26 diagnostics: factor and enhance messages about duplicate rule directives
When reporting a duplicate directive on a rule, point to its first
occurrence:

one.y:11.10-15: error: only one %empty allowed per rule
   %empty {} %empty
             ^^^^^^
one.y:11.3-8: previous declaration
   %empty {} %empty
   ^^^^^^

And consistently discard the second one.

* src/complain.h, src/complain.c (duplicate_directive): New.
* src/reader.c: Use it where appropriate.
* src/symlist.h, src/symlist.c (symbol_list): Add a dprec_location member.
* tests/actions.at: Adjust expected output.
2013-02-18 10:01:29 +01:00
Akim Demaille 4c9b8f1318 style: no longer use backquotes
* tests/actions.at, tests/atlocal.in, tests/c++.at, tests/calc.at,
* tests/conflicts.at, tests/existing.at, tests/glr-regression.at,
* tests/input.at, tests/java.at, tests/local.at, tests/sets.at,
* tests/synclines.at, doc/bison.texi, lib/libiberty.h, lib/timevar.h:
Use single quotes.
2013-02-18 10:01:28 +01:00
Akim Demaille 45eebca42d style: no longer use backquotes
* README, REFERENCES, TODO, configure.ac, data/README, data/bison.m4,
* data/c++.m4, data/c.m4, data/java.m4, data/lalr1.cc,
* data/lalr1.java, data/yacc.c, doc/local.mk, etc/bench.pl.in,
* src/conflicts.c, src/files.c, src/getargs.c, src/gram.h, src/lalr.c,
* src/location.c, src/location.h, src/muscle-tab.c, src/muscle-tab.h,
* src/output.c, src/parse-gram.c, src/parse-gram.y, src/print-xml.c,
* src/print.c, src/reader.c, src/reduce.c, src/scan-skel.l,
* src/symtab.h, src/system.h, src/tables.c:
Use single quotes, as currently recommended by the GNU Coding Standards.
2013-02-18 10:01:28 +01:00
Akim Demaille d49751602c style: no longer use backquotes in messages
* src/getargs.c (usage): Use single quotes.
2013-02-18 10:01:28 +01:00
Akim Demaille 6240346aa0 doc: use %empty instead of /* empty */
* doc/bison.texi: Change the comments into explicit %empty.
2013-02-18 10:01:28 +01:00
Akim Demaille 09add9c24f doc: introduce %empty and -Wempty-rule
* doc/bison.texi (Grammar Rules): Make it a @section which
contains...
(Rules Syntax): this new subsection (with the previous contents of
"Grammar Rules".
(Empty Rules): New subsection, extracted from the former
"Grammar Rules".
Document %empty.
(Recursion): New a subsection of "Grammar Rules".
Complete a few index entries.
(Bison Options): Document -Wempty-rule.
2013-02-18 10:01:28 +01:00
Akim Demaille 8b807f1177 report: use %empty to denote empty rules
* src/gram.c (rule_rhs_print): Use %empty for empty rules.
* tests/conflicts.at, tests/regression.at, tests/sets.at: Adjust.
2013-02-18 10:01:28 +01:00
Akim Demaille 42d101da8d diagnostics: %empty enables -Wempty-rule
* src/complain.h, src/complain.c (warning_is_unset): New.
* src/reader.c (grammar_current_rule_empty_set): If enabled -Wempty-rule,
if not disabled.
* tests/actions.at (Implicitly empty rule): Check this feature.
Also check that -Wno-empty-rule does disable this warning.
2013-02-18 10:01:28 +01:00
Akim Demaille f68a49ed49 -Wempty-rule: diagnose empty rules without %empty
* src/complain.h, src/complain.c (warning_empty_rule, Wempty_rule):
New warning category.
(warnings_args, warnings_types): Adjust.
* src/reader.c (grammar_rule_check): Check the empty rules are
flagged by %empty.
* tests/actions.at (Implicitly empty rule): New.
* tests/existing.at: Add expected warnings.
2013-02-18 10:01:27 +01:00
Akim Demaille 684083f065 tests: use %empty
* tests/actions.at, tests/input.at, tests/reduce.at,
* tests/regression.at:
here.
2013-02-18 10:01:27 +01:00
Akim Demaille 8ecac08f2d regen 2013-02-18 10:01:27 +01:00
Akim Demaille fd003416d5 parser: use %empty
Avoid that Bison's own use of "bison -Wall" trigger warnings.

* src/parse-gram.y: Use %empty for every empty rule.
2013-02-18 10:01:27 +01:00
Akim Demaille ae2b48f5c0 grammar: introduce %empty
Provide a means to explicitly denote empty right-hand sides of rules:
instead of

  exp:  { ... }

allow

  exp: %empty { ... }

Make sure that %empty is properly used.

With help from Joel E. Denny and Gabriel Rassoul.
http://lists.gnu.org/archive/html/bison-patches/2013-01/msg00142.html

* src/reader.h, src/reader.c (grammar_current_rule_empty_set): New.
* src/parse-gram.y (%empty): New token.
Use it.
* src/scan-gram.l (%empty): Scan it.
* src/reader.c (grammar_rule_check): Check that %empty is properly used.
* tests/actions.at (Invalid uses of %empty, Valid uses of %empty): New.
2013-02-18 10:01:27 +01:00
Akim Demaille 9e4917b2a1 getargs: minor simplification
* src/getargs.c (flag_argmatch): Simplify the handling of "none".
2013-02-16 07:45:14 +01:00
Akim Demaille 12bc1c9e47 style: move argument handling of -W into the diagnostics module
This allows to reduce the number of public interfaces.

* src/getargs.c (--yacc): Use warning_argmatch instead of tweaking
directly warnings_flag (which will be private).
(warning_argmatch, warnings_argmatch): Move to...
* src/complain.h, src/complain.c: here.

* src/getargs.h, src/getargs.c (warnings_args, warnings_types): Move to...
* src/complain.c: here, now private.

* src/complain.h (severity, warnings_flag): Move to...
* src/complain.c: here, now private.
2013-02-16 07:45:07 +01:00
Akim Demaille 808e523db4 diagnostics: revamp the handling of -Werror
Recent discussions with Joel E. Denny
(http://lists.gnu.org/archive/html/bison-patches/2013-02/msg00026.html)
show that it is desirable to tell the difference between an option
that was explicitly disabled with -Wno-foo, as opposed to be left
unset.  The current framework does not allow this.

Instead of having a first int to store which options are enabled, and
another to store which are turned into errors, use an array that for
each warning category tells its status: disabled, unset, warning,
error.

* src/complain.h, src/complain.c (warning_bit): New enum.
(warnings): Use it.
(severity): New enum.
(warnings_flag): Now an array of severity.
(errors_flag): Remove, now done by warnings_flag.
(complain_init): New function, to initialie warnings_flag.
(warnings_are_errors): New Boolean, for -Werror.
* src/complain.c (warning_severity): New.
(warnings_print_categories, complains): Use it.
* src/getargs.c (warning_argmatch): Adjust to use warnings_flag.
(warnings_argmatch): Ditto.
Handle -Werror and -Wno-error here.
(getargs): Adjust.
* src/main.c (main): Call complain_init.
* tests/input.at (Invalid options): Add more corner cases.
2013-02-16 07:45:06 +01:00
Akim Demaille 4a3c55cf1a options: simplify the handling of -W
* src/getargs.c (warnings_argmatch, warning_argmatch): Simplify by
replacing function arguments with their actual values.
(WARNING_ARGMATCH): Remove, useless.
Adjust callers.
2013-02-14 15:00:52 +01:00
Akim Demaille c017f88fde options: don't accept "error=" for -f and -r
* src/getargs.c (warning_argmatch, warnings_argmatch, WARNINGS_ARGMATCH):
New.
Use them for -W/--warning.
They are copied from...
(flag_argmatch, flags_argmatch, FLAGS_ARGMATCH): these.
Simplify by removing the support for "error".
* tests/input.at (Invalid options): New.
* TODO (Laxism in Bison invocation arguments): Remove.
2013-02-14 15:00:51 +01:00
Akim Demaille 219458e22f diagnostics: factor the list of warning names
* src/getargs.h, src/getargs.c (warnings_args, warnings_types): Make
them public.
* src/complain.h, src/complain.c (warnings_print_categories): Its
only use outside complain.c was removed in a recent commit, so
make it static.
Simplify its implementation.
Use warnings_args and warnings_types.
* src/muscle-tab.c (muscle_percent_define_check_values): Make it
silent.
2013-02-14 15:00:51 +01:00
Akim Demaille fec5f3c0cc diagnostics: no longer pretty-print rules in error messages, carets suffice
* src/gram.c (grammar_rules_useless_report): Let -fcaret handle the
pretty-printing of the guilty rules.
(rule_print): Inline in its only use.
* tests/conflicts.at, tests/existing.at, tests/reduce.at,
* tests/regression.at: Adjust.
* NEWS: Document.
2013-02-14 15:00:51 +01:00
Akim Demaille 9a9130f26d options: no longer document warnings when diagnosing an invalid -W
The argmatch functions accept prefixes of the alternatives (like
getopt does for long options).  Bison uses this to document the
warning categories.  This is troublesome: it duplicates the --help
documentation, it is not gettextized, it is displayed with ugly quotes
(because argmatch uses it to display the list of possible answers),
and it prevents straighforward uses of the tables of valid warning
categories (for instance so that warning diagnostics end with the name
of the warning).

The "hidden" option --trace uses the same trick, but it does not need
to be translated, nor to be described in --help.

* src/getargs.c (warnings_args): Remove pseudo documentation.
Comment changes.
2013-02-14 15:00:44 +01:00
Akim Demaille 312d0d654f tests: enlarge the allowed duration for calc tests
Hydra "often" fails on this test:

252. calc.at:658: 252. Calculator %glr-parser api.pure
parse.error=verbose %debug %locations %defines api.prefix="calc"
%verbose %yacc %parse-param {semantic_value *result}
%parse-param {int *count} (calc.at:658): FAILED

* tests/calc.at: Give 200s instead of 100s.
Use AT_DEBUG_IF.
2013-02-11 09:07:25 +01:00
Akim Demaille 848bcc288d debug: improve the display of symbol lists
* src/symtab.c (symbol_print): Remove useless quotes (the symbol already
has quotes).
Prefer fputs.
* src/symlist.c (symbol_list_syms_print): Likewise.
Fix separators.
2013-02-11 09:04:17 +01:00
Akim Demaille ec6dc4375e style: minor changes
* src/complain.c: Space changes.
* src/reader.c: Comment changes.
Avoid && in assertions.
* src/location.c: Move comments to...
* src/location.h: here.
* src/symlist.h, src/symlist.c: Create a pseudo section for members
that apply to the rule.
2013-02-09 18:35:28 +01:00
Akim Demaille c21e515e05 news: restructure, document variants for C++
* NEWS: here.
2013-02-08 17:28:06 +01:00
Akim Demaille 1dce289a00 c++: api.token.constructor requires api.value.type=variant
Eventually it should also support "union".

* data/glr.cc: Move this check to...
* data/c++.m4: here, as lalr1.cc is affected too.
2013-02-08 17:28:02 +01:00
Akim Demaille 66c209cf43 build: restore C90 compatibility
* src/parse-gram.y, src/parse-gram.c: Don't use // comments.
2013-02-05 14:37:55 +01:00
Akim Demaille efbc95a7e4 doc: use @group to improve page breaking
* doc/bison.texi: here.
2013-02-05 11:44:12 +01:00
Akim Demaille c5dbd909d0 style: rename internal "stype" as "union_members" for clarity
"stype" is quite unclear, and it also collides with the former %define
variable that had the same name (replaced by api.value.type).

* src/parse-gram.y (stype): Rename as...
(union_members): this.
* data/bison.m4: Adjust.
(b4_user_stype): Rename as...
(b4_user_union_members): this.
* data/c++.m4, data/c.m4: Adjust.
* src/parse-gram.c: regen.
2013-02-04 18:45:21 +01:00
Akim Demaille 6112cb1802 tests: improve the language independance layer
* tests/local.at (_AT_LANG_DISPATCH): New, shamelessly stolen from
Autoconf's _AT_LANG_DISPATCH.
(AT_LANG_DISPATCH): New.
(AT_YYERROR_FORMALS, AT_YYERROR_PROTOTYPE, AT_YYERROR_DECLARE_EXTERN)
(AT_YYERROR_DECLARE, AT_YYERROR_DEFINE, AT_MAIN_DEFINE, AT_COMPILE)
(AT_FULL_COMPILE):
Use AT_LANG_DISPATCH instead of an ad hoc m4_case.
2013-02-04 16:49:10 +01:00
Akim Demaille 246ff8c1d3 regen 2013-02-04 16:49:10 +01:00
Akim Demaille f50fa14529 style: space changes in the parser
* src/parse-gram.y: Fix spaces.
2013-02-04 16:49:09 +01:00
Akim Demaille 2c056d696d parser: use api.pure full
* src/parse-gram.y: Use api.pure full instead of silly macro tricks.
2013-02-04 16:49:09 +01:00
Akim Demaille 06505b0c69 style: use a for loop instead of a while loop, and scope reduction
* src/reader.c (packgram): Improve readability.
The parser calls grammar_current_rule_end at the end of every rhs,
which adds a NULL to separate the rules.  So there is no need to
check whether "p" is non-null before proceeding.
2013-02-04 16:46:54 +01:00
Theophile Ranquet e96415a54b variants: stylistic change
* data/variant.hh (tname): Respect the GNU Coding Standards for this
pointer's declaration.
2013-02-01 15:09:54 +01:00
Theophile Ranquet f038e56cdc grammar: free the association tracking graph
The graph introduced by Valentin wasn't free'd after use.

* src/symtab.c (assoc_free): New, clear the array of linked lists with...
(linkedlist_free): This, new.
(print_precedence_warnings): Call assoc_free when done.
(print_assoc_warnings): Free used_assoc after use.
2013-02-01 15:06:26 +01:00
Theophile Ranquet f2e1d4090d tests: use AT_FULL_COMPILE where possible
* tests/c++.at (C++ Variant-based Symbol, Variants): Here.  Rename the
generated input files to use .y instead of .yy, as a requirement for using
AT_FULL_COMPILE instead of a combination of AT_BISON_CHECK and
AT_BISON_COMPILE_CXX.
2013-02-01 15:06:26 +01:00
Theophile Ranquet be6fa942ac variants: avoid type punning issue
This is based on what is recommended by both Scott Meyers, in 'Effective
C++', and Andrei Alexandrescu and Herb Sutter in 'C++ Coding Standards'.

Use a static_cast on void* rather than directly use a reinterpret_cast,
which can have nefarious effects on objects.  However, even though following
this guideline is good practice in general, I am not quite sure how relevant
it is when applied to conversions from POD to objects.  Actually, it might
very well be the opposite: isn't this exactly what reinterpret_cast is for?
What we really want *is* to transmit the memory map as a series of bytes,
which, if I am correct, falls into the kind of "low level" hack for which
this cast is meant.

In any case, this silences the warning, which will be greatly appreciated by
anyone using variants with a compiler supporting -fstrict-aliasing.

* data/variant.hh (as): Here.
* tests/c++.at (Exception safety, C++ Variant-based Symbols, Variants):
Don't use NO_STRICT_ALIAS_CXXFLAGS (revert commit ddb9db15), as type punning
is no longer an issue.
* tests/atlocal.in, configure.ac (NO_STRICT_ALIAS_CXXFLAGS): Remove
definition.
* examples/local.mk (NO_STRICT_ALIAS_CXXFLAGS): Remove from AM_CXXFLAGS.
* doc/bison.texi: Don't mention type punning issues.
2013-02-01 15:06:20 +01:00
Theophile Ranquet f29f8af3ed todo: update
Reformulate and give more details on my thoughts concerning the graphical
visualization, and add an entry about a bug in the options processing for
warnings as errors.

* TODO: Here.
2013-02-01 14:44:23 +01:00
Akim Demaille 74ce3cfbf6 regen 2013-02-01 14:26:29 +01:00
Akim Demaille b805eca764 location: pass the location first
* src/location.h, src/location.c (location_print): For consistency
with other data structures and other location_* routines, pass the
location argument first.
* src/complain.c: Adjust.
(location_caret): Likewise.
* src/parse-gram.y: Adjust.
2013-02-01 14:24:48 +01:00
Akim Demaille e6c25014bb symlist: use the right stream
* src/symlist.c (symbol_list_syms_print): Use "f", not stderr.
2013-02-01 14:23:49 +01:00
Akim Demaille 97ad789d10 tests: put two related tests together
* tests/conflicts.at (Useless associativity warning): Move next
to "Useless precedence warning".
2013-01-30 21:41:41 +01:00
Akim Demaille d2f9ae18be news: name contributors
* NEWS: here.
2013-01-30 21:40:47 +01:00
Valentin TolmerandAkim Demaille cc2235ace2 warnings: introduce -Wprecedence
The new warning category "precedence" flags useless precedence and
associativity.  -Wprecedence can now be used, it is disabled by default.
The warnings about precedence and associativity are grouped into one, and
the testsuite was corrected accordingly.

* src/complain.h (warnings): Introduce "precedence".
* src/complain.c (warnings_print_categories): Adjust.
* src/getargs.c (warnings_args, warning_types): Likewise.
* src/symtab.h, src/symtab.c (print_associativity_warnings): Remove.
* src/symtab.h (register_assoc): Correct arguments.
* src/symtab.c (print_precedence_warnings): Print both warnings together.
* doc/bison.texi (Bison options): Document the warnings and provide an
example.
* tests/conflicts.at, tests/existing.at, tests/local.at,
* tests/regression.at: Adapt the testsuite for the new category
(-Wprecedence instead of -Wother where appropriate).
2013-01-30 21:39:08 +01:00
Akim Demaille 657ed6d3be tests: style changes
* tests/glr-regression.at: Issue yyerror before yylex.
2012-12-15 14:58:05 +01:00
113 changed files with 6927 additions and 3714 deletions
+10 -1
View File
@@ -1,7 +1,16 @@
*.eps
*.log
*.o
*.pdf
*.png
*.stamp
*.trs
*~
.deps
.dirstamp
/*.cache
/*.flc
/*.prj
/*~
/.tarball-version
/.version
/ABOUT-NLS
+1 -1
View File
@@ -1 +1 @@
2.7
3.0.1
+4 -4
View File
@@ -32,8 +32,8 @@ EXTRA_DIST = .prev-version .version \
## version of Bison nearby...
BISON = $(top_builddir)/tests/bison
BISON_IN = $(top_srcdir)/tests/bison.in
YACC = $(BISON) -y
AM_YFLAGS = -d -v --warnings=all,error --report=all
YACC = $(BISON) -o y.tab.c
AM_YFLAGS = -d -v -Werror -Wall -Wno-yacc --report=all
# Initialization before completion by local.mk's.
AM_CFLAGS = $(WARN_CFLAGS)
@@ -78,11 +78,11 @@ dist-hook: gen-ChangeLog
.PHONY: update-b4-copyright update-package-copyright-year
update-b4-copyright:
find $(srcdir)/data -type f \
$(AM_V_GEN)find $(srcdir)/data -type f \
| xargs $(srcdir)/build-aux/$@
@echo 'warning: src/parse-gram.[hc] may need to be regenerated.'
update-package-copyright-year:
$(srcdir)/build-aux/$@ $(srcdir)/configure.ac
$(AM_V_GEN)$(srcdir)/build-aux/$@ $(srcdir)/configure.ac
gen_start_date = 2012-01-16
.PHONY: gen-ChangeLog
+424 -61
View File
@@ -1,17 +1,64 @@
GNU Bison NEWS
* Noteworthy changes in release ?.? (????-??-??) [?]
* Noteworthy changes in release 3.0.2 (2013-12-05) [stable]
** Bug fixes
*** Generated source files when errors are reported
When warnings are issued and -Werror is set, bison would still generate
the source files (*.c, *.h...). As a consequence, some runs of "make"
could fail the first time, but not the second (as the files were generated
anyway).
This is fixed: bison no longer generates this source files, but, of
course, still produces the various reports (*.output, *.xml, etc.).
*** %empty is used in reports
Empty right-hand sides are denoted by '%empty' in all the reports (text,
dot, XML and formats derived from it).
*** YYERROR and variants
When C++ variant support is enabled, an error triggered via YYERROR, but
not caught via error recovery, resulted in a double deletion.
* Noteworthy changes in release 3.0.1 (2013-11-12) [stable]
** Bug fixes
*** Errors in caret diagnostics
On some platforms, some errors could result in endless diagnostics.
*** Fixes of the -Werror option
Options such as "-Werror -Wno-error=foo" were still turning "foo"
diagnostics into errors instead of warnings. This is fixed.
Actually, for consistency with GCC, "-Wno-error=foo -Werror" now also
leaves "foo" diagnostics as warnings. Similarly, with "-Werror=foo
-Wno-error", "foo" diagnostics are now errors.
*** GLR Predicates
As demonstrated in the documentation, one can now leave spaces between
"%?" and its "{".
*** Installation
The yacc.1 man page is no longer installed if --disable-yacc was
specified.
*** Fixes in the test suite
Bugs and portability issues.
* Noteworthy changes in release 3.0 (2013-07-25) [stable]
** WARNING: Future backward-incompatibilities!
Bison will stop adding a semicolon at the end of the actions (as announced
in the release 2.5):
foo.y:2.22: warning: a ';' might be needed at the end of action code
exp: "num" { $$ = $1 }
^
foo.y:2.22: future versions of Bison will not add the ';'
Like other GNU packages, Bison will start using some of the C99 features
for its own code, especially the definition of variables after statements.
The generated C parsers still aim at C90.
@@ -28,9 +75,32 @@ GNU Bison NEWS
Support for YYLEX_PARAM and YYPARSE_PARAM is removed (deprecated in Bison
1.875): use %lex-param, %parse-param, or %param.
Missing semicolons at the end of actions are no longer added (as announced
in the release 2.5).
*** Use of YACC='bison -y'
TL;DR: With Autoconf <= 2.69, pass -Wno-yacc to (AM_)YFLAGS if you use
Bison extensions.
Traditional Yacc generates 'y.tab.c' whatever the name of the input file.
Therefore Makefiles written for Yacc expect 'y.tab.c' (and possibly
'y.tab.h' and 'y.outout') to be generated from 'foo.y'.
To this end, for ages, AC_PROG_YACC, Autoconf's macro to look for an
implementation of Yacc, was using Bison as 'bison -y'. While it does
ensure compatible output file names, it also enables warnings for
incompatibilities with POSIX Yacc. In other words, 'bison -y' triggers
warnings for Bison extensions.
Autoconf 2.70+ fixes this incompatibility by using YACC='bison -o y.tab.c'
(which also generates 'y.tab.h' and 'y.output' when needed).
Alternatively, disable Yacc warnings by passing '-Wno-yacc' to your Yacc
flags (YFLAGS, or AM_YFLAGS with Automake).
** Bug fixes
*** The epilogue is no longer affected by internal #defines
*** The epilogue is no longer affected by internal #defines (glr.c)
The glr.c skeleton uses defines such as #define yylval (yystackp->yyval) in
generated code. These weren't properly undefined before the inclusion of
@@ -39,7 +109,7 @@ GNU Bison NEWS
int yylex (YYSTYPE *yylval);
This is has been fixed: yylval, yynerrs, yychar, and yylloc are now valid
This is fixed: yylval, yynerrs, yychar, and yylloc are now valid
identifiers for user-provided variables.
*** stdio.h is no longer needed when locations are enabled (yacc.c)
@@ -47,6 +117,8 @@ GNU Bison NEWS
Changes in Bison 2.7 introduced a dependency on FILE and fprintf when
locations are enabled. This is fixed.
*** Warnings about useless %pure-parser/%define api.pure are restored
** Diagnostics reported by Bison
Most of these features were contributed by Théophile Ranquet and Victor
@@ -58,6 +130,29 @@ GNU Bison NEWS
activated by default. The old format can still be used by invoking Bison
with -fno-caret (or -fnone).
Some error messages that reproduced excerpts of the grammar are now using
the caret information only. For instance on:
%%
exp: 'a' | 'a';
Bison 2.7 reports:
in.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
in.y:2.12-14: warning: rule useless in parser due to conflicts: exp: 'a' [-Wother]
Now bison reports:
in.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
in.y:2.12-14: warning: rule useless in parser due to conflicts [-Wother]
exp: 'a' | 'a';
^^^
and "bison -fno-caret" reports:
in.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
in.y:2.12-14: warning: rule useless in parser due to conflicts [-Wother]
*** Enhancements of the -Werror option
The -Werror=CATEGORY option is now recognized, and will treat specified
@@ -198,12 +293,10 @@ GNU Bison NEWS
bar.y: error: shift/reduce conflicts: 1 found, 0 expected
bar.y: error: reduce/reduce conflicts: 2 found, 0 expected
*** Useless precedence
** Incompatibilities with POSIX Yacc
Bison now warns about symbols with a declared precedence but no declared
associativity (i.e. declared with %precedence), and whose precedence is
never used. In that case, the symbol can be safely declared with %token
instead, without modifying the parsing tables.
The 'yacc' category is no longer part of '-Wall', enable it explicitly
with '-Wyacc'.
** Additional yylex/yyparse arguments
@@ -220,13 +313,271 @@ GNU Bison NEWS
%param {arg1_type *arg1} {arg2_type *arg2}
** Java skeleton improvements
** Types of values for %define variables
Contributed by Paolo Bonzini.
Bison used to make no difference between '%define foo bar' and '%define
foo "bar"'. The former is now called a 'keyword value', and the latter a
'string value'. A third kind was added: 'code values', such as '%define
foo {bar}'.
Keyword variables are used for fixed value sets, e.g.,
%define lr.type lalr
Code variables are used for value in the target language, e.g.,
%define api.value.type {struct semantic_type}
String variables are used remaining cases, e.g. file names.
** Variable api.token.prefix
The variable api.token.prefix changes the way tokens are identified in
the generated files. This is especially useful to avoid collisions
with identifiers in the target language. For instance
%token FILE for ERROR
%define api.token.prefix {TOK_}
%%
start: FILE for ERROR;
will generate the definition of the symbols TOK_FILE, TOK_for, and
TOK_ERROR in the generated sources. In particular, the scanner must
use these prefixed token names, although the grammar itself still
uses the short names (as in the sample rule given above).
** Variable api.value.type
This new %define variable supersedes the #define macro YYSTYPE. The use
of YYSTYPE is discouraged. In particular, #defining YYSTYPE *and* either
using %union or %defining api.value.type results in undefined behavior.
Either define api.value.type, or use "%union":
%union
{
int ival;
char *sval;
}
%token <ival> INT "integer"
%token <sval> STRING "string"
%printer { fprintf (yyo, "%d", $$); } <ival>
%destructor { free ($$); } <sval>
/* In yylex(). */
yylval.ival = 42; return INT;
yylval.sval = "42"; return STRING;
The %define variable api.value.type supports both keyword and code values.
The keyword value 'union' means that the user provides genuine types, not
union member names such as "ival" and "sval" above (WARNING: will fail if
-y/--yacc/%yacc is enabled).
%define api.value.type union
%token <int> INT "integer"
%token <char *> STRING "string"
%printer { fprintf (yyo, "%d", $$); } <int>
%destructor { free ($$); } <char *>
/* In yylex(). */
yylval.INT = 42; return INT;
yylval.STRING = "42"; return STRING;
The keyword value variant is somewhat equivalent, but for C++ special
provision is made to allow classes to be used (more about this below).
%define api.value.type variant
%token <int> INT "integer"
%token <std::string> STRING "string"
Code values (in braces) denote user defined types. This is where YYSTYPE
used to be used.
%code requires
{
struct my_value
{
enum
{
is_int, is_string
} kind;
union
{
int ival;
char *sval;
} u;
};
}
%define api.value.type {struct my_value}
%token <u.ival> INT "integer"
%token <u.sval> STRING "string"
%printer { fprintf (yyo, "%d", $$); } <u.ival>
%destructor { free ($$); } <u.sval>
/* In yylex(). */
yylval.u.ival = 42; return INT;
yylval.u.sval = "42"; return STRING;
** Variable parse.error
This variable controls the verbosity of error messages. The use of the
%error-verbose directive is deprecated in favor of "%define parse.error
verbose".
** Renamed %define variables
The following variables have been renamed for consistency. Backward
compatibility is ensured, but upgrading is recommended.
lr.default-reductions -> lr.default-reduction
lr.keep-unreachable-states -> lr.keep-unreachable-state
namespace -> api.namespace
stype -> api.value.type
** Semantic predicates
Contributed by Paul Hilfinger.
The new, experimental, semantic-predicate feature allows actions of the
form "%?{ BOOLEAN-EXPRESSION }", which cause syntax errors (as for
YYERROR) if the expression evaluates to 0, and are evaluated immediately
in GLR parsers, rather than being deferred. The result is that they allow
the programmer to prune possible parses based on the values of run-time
expressions.
** The directive %expect-rr is now an error in non GLR mode
It used to be an error only if used in non GLR mode, _and_ if there are
reduce/reduce conflicts.
** Tokens are numbered in their order of appearance
Contributed by Valentin Tolmer.
With '%token A B', A had a number less than the one of B. However,
precedence declarations used to generate a reversed order. This is now
fixed, and introducing tokens with any of %token, %left, %right,
%precedence, or %nonassoc yields the same result.
When mixing declarations of tokens with a litteral character (e.g., 'a')
or with an identifier (e.g., B) in a precedence declaration, Bison
numbered the litteral characters first. For example
%right A B 'c' 'd'
would lead to the tokens declared in this order: 'c' 'd' A B. Again, the
input order is now preserved.
These changes were made so that one can remove useless precedence and
associativity declarations (i.e., map %nonassoc, %left or %right to
%precedence, or to %token) and get exactly the same output.
** Useless precedence and associativity
Contributed by Valentin Tolmer.
When developing and maintaining a grammar, useless associativity and
precedence directives are common. They can be a nuisance: new ambiguities
arising are sometimes masked because their conflicts are resolved due to
the extra precedence or associativity information. Furthermore, it can
hinder the comprehension of a new grammar: one will wonder about the role
of a precedence, where in fact it is useless. The following changes aim
at detecting and reporting these extra directives.
*** Precedence warning category
A new category of warning, -Wprecedence, was introduced. It flags the
useless precedence and associativity directives.
*** Useless associativity
Bison now warns about symbols with a declared associativity that is never
used to resolve conflicts. In that case, using %precedence is sufficient;
the parsing tables will remain unchanged. Solving these warnings may raise
useless precedence warnings, as the symbols no longer have associativity.
For example:
%left '+'
%left '*'
%%
exp:
"number"
| exp '+' "number"
| exp '*' exp
;
will produce a
warning: useless associativity for '+', use %precedence [-Wprecedence]
%left '+'
^^^
*** Useless precedence
Bison now warns about symbols with a declared precedence and no declared
associativity (i.e., declared with %precedence), and whose precedence is
never used. In that case, the symbol can be safely declared with %token
instead, without modifying the parsing tables. For example:
%precedence '='
%%
exp: "var" '=' "number";
will produce a
warning: useless precedence for '=' [-Wprecedence]
%precedence '='
^^^
*** Useless precedence and associativity
In case of both useless precedence and associativity, the issue is flagged
as follows:
%nonassoc '='
%%
exp: "var" '=' "number";
The warning is:
warning: useless precedence and associativity for '=' [-Wprecedence]
%nonassoc '='
^^^
** Empty rules
With help from Joel E. Denny and Gabriel Rassoul.
Empty rules (i.e., with an empty right-hand side) can now be explicitly
marked by the new %empty directive. Using %empty on a non-empty rule is
an error. The new -Wempty-rule warning reports empty rules without
%empty. On the following grammar:
%%
s: a b c;
a: ;
b: %empty;
c: 'a' %empty;
bison reports:
3.4-5: warning: empty rule without %empty [-Wempty-rule]
a: {}
^^
5.8-13: error: %empty on non-empty rule
c: 'a' %empty {};
^^^^^^
** Java skeleton improvements
The constants for token names were moved to the Lexer interface. Also, it
is possible to add code to the parser's constructors using "%code init"
and "%define init_throws".
Contributed by Paolo Bonzini.
The Java skeleton now supports push parsing.
Contributed by Dennis Heimbigner.
** C++ skeletons improvements
@@ -249,59 +600,66 @@ GNU Bison NEWS
used by the scanner, or rejecting invalid combinations from a
factory invoked by the user actions).
** Renamed %define variables
*** %define api.value.type variant
The following variables have been renamed for consistency. Backward
compatibility is ensured, but upgrading is recommended.
This is based on a submission from Michiel De Wilde. With help
from Théophile Ranquet.
lr.default-reductions -> lr.default-reduction
lr.keep-unreachable-states -> lr.keep-unreachable-state
namespace -> api.namespace
stype -> api.value.type
In this mode, complex C++ objects can be used as semantic values. For
instance:
** Variable api.token.prefix
The variable api.token.prefix changes the way tokens are identified in
the generated files. This is especially useful to avoid collisions
with identifiers in the target language. For instance
%token FILE for ERROR
%define api.token.prefix "TOK_"
%token <::std::string> TEXT;
%token <int> NUMBER;
%token SEMICOLON ";"
%type <::std::string> item;
%type <::std::list<std::string>> list;
%%
start: FILE for ERROR;
result:
list { std::cout << $1 << std::endl; }
;
will generate the definition of the symbols TOK_FILE, TOK_for, and
TOK_ERROR in the generated sources. In particular, the scanner must
use these prefixed token names, although the grammar itself still
uses the short names (as in the sample rule given above).
list:
%empty { /* Generates an empty string list. */ }
| list item ";" { std::swap ($$, $1); $$.push_back ($2); }
;
** Variable parse.error
item:
TEXT { std::swap ($$, $1); }
| NUMBER { $$ = string_cast ($1); }
;
This variable controls the verbosity of error messages. The use of the
%error-verbose directive is deprecated in favor of "%define parse.error
verbose".
*** %define api.token.constructor
** Semantic predicates
When variants are enabled, Bison can generate functions to build the
tokens. This guarantees that the token type (e.g., NUMBER) is consistent
with the semantic value (e.g., int):
Contributed by Paul Hilfinger.
parser::symbol_type yylex ()
{
parser::location_type loc = ...;
...
return parser::make_TEXT ("Hello, world!", loc);
...
return parser::make_NUMBER (42, loc);
...
return parser::make_SEMICOLON (loc);
...
}
The new, experimental, semantic-predicate feature allows actions of the
form "%?{ BOOLEAN-EXPRESSION }", which cause syntax errors (as for
YYERROR) if the expression evaluates to 0, and are evaluated immediately
in GLR parsers, rather than being deferred. The result is that they allow
the programmer to prune possible parses based on the values of run-time
expressions.
*** C++ locations
** The directive %expect-rr is now an error in non GLR mode
There are operator- and operator-= for 'location'. Negative line/column
increments can no longer underflow the resulting value.
It used to be an error only if used in non GLR mode, _and_ if there are
reduce/reduce conflicts.
* Noteworthy changes in release 2.7.1 (2013-04-15) [stable]
** Token numbering has changed to preserve the user-defined order
** Bug fixes
When declaring %token A B, the numbering for A is inferior to B. Up to now,
when declaring associativity at the same time, with %left (or %right,
%precedence, %nonassoc), B was inferior to A.
*** Fix compiler attribute portability (yacc.c)
With locations enabled, __attribute__ was used unprotected.
*** Fix some compiler warnings (lalr1.cc)
* Noteworthy changes in release 2.7 (2012-12-12) [stable]
@@ -353,8 +711,8 @@ GNU Bison NEWS
exp: exp '+' exp { $exp = $1 + $3; };
^^^
The default behaviour for now is still not to display these unless
explictly asked with -fcaret (or -fall). However, in a later release, it
The default behavior for now is still not to display these unless
explicitly asked with -fcaret (or -fall). However, in a later release, it
will be made the default behavior (but may still be deactivated with
-fno-caret).
@@ -441,7 +799,7 @@ GNU Bison NEWS
Other issues in the test suite have been addressed.
Nul characters are correctly displayed in error messages.
Null characters are correctly displayed in error messages.
When possible, yylloc is correctly initialized before calling yylex. It
is no longer necessary to initialize it in the %initial-action.
@@ -2357,7 +2715,12 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
LocalWords: Automake TMPDIR LESSEQ ylwrap endif yydebug YYTOKEN YYLSP ival hh
LocalWords: extern YYTOKENTYPE TOKENTYPE yytokentype tokentype STYPE lval pdf
LocalWords: lang yyoutput dvi html ps POSIX lvalp llocp Wother nterm arg init
LocalWords: TOK calc yyo fval Wconflicts
LocalWords: TOK calc yyo fval Wconflicts parsers yystackp yyval yynerrs
LocalWords: Théophile Ranquet Santet fno fnone stype associativity Tolmer
LocalWords: Wprecedence Rassoul Wempty Paolo Bonzini parser's Michiel loc
LocalWords: redeclaration sval fcaret reentrant XSLT xsl Wmaybe yyvsp Tedi
LocalWords: pragmas noreturn untyped Rozenman unexpanded Wojciech Polak
LocalWords: Alexandre MERCHANTABILITY yytype
Local Variables:
mode: outline
+1 -1
View File
@@ -30,7 +30,7 @@ not answer them, please send mail to <[email protected]>.
* Bug reports
Please send bug reports to <[email protected]>. Please include the
version number from `bison --version', and a complete, self-contained
version number from 'bison --version', and a complete, self-contained
test case in each bug report.
* Copyright statements
+9
View File
@@ -62,13 +62,22 @@ tools we depend upon, including:
- Gettext <http://www.gnu.org/software/gettext/>
- Graphviz <http://www.graphviz.org>
- Gzip <http://www.gnu.org/software/gzip/>
- Help2man <http://www.gnu.org/software/help2man/>
- Perl <http://www.cpan.org/>
- Rsync <http://samba.anu.edu.au/rsync/>
- Tar <http://www.gnu.org/software/tar/>
- Texinfo <http://www.gnu.org/software/texinfo/>
Valgrind <http://valgrind.org/> is also highly recommended, if it supports
your architecture.
If you're using a GNU/Linux distribution, the easiest way to install the
above packages depends on your system. The following shell command should
work for Debian-based systems such as Ubuntu:
sudo apt-get install \
autoconf automake autopoint flex graphviz help2man texinfo valgrind
Bison is written using Bison grammars, so there are bootstrapping issues.
The bootstrap script attempts to discover when the C code generated from the
grammars is out of date, and to bootstrap with an out-of-date version of the
+1 -1
View File
@@ -9,7 +9,7 @@ Bison supports the @N construction, which gives you access to
the starting and ending line number and character number associated
with any of the symbols in the current rule.
Also, Bison supports the command `%expect N' which says not to mention
Also, Bison supports the command '%expect N' which says not to mention
the conflicts if there are N shift/reduce conflicts and no reduce/reduce
conflicts.
+12
View File
@@ -25,10 +25,13 @@ Bruce Lilly [email protected]
Bruno Haible [email protected]
Charles-Henri de Boysson [email protected]
Christian Burger [email protected]
Colin Daley [email protected]
Cris Bailiff [email protected]
Cris van Pelt [email protected]
Csaba Raduly [email protected]
Dagobert Michelsen [email protected]
Daniel Frużyński [email protected]
Daniel Galloway [email protected]
Daniel Hagerty [email protected]
David J. MacKenzie [email protected]
David Kastrup [email protected]
@@ -37,6 +40,7 @@ Derek M. Jones [email protected]
Di-an Jan [email protected]
Dick Streefland [email protected]
Didier Godefroy [email protected]
Efi Fogel [email protected]
Enrico Scholz [email protected]
Eric Blake [email protected]
Evgeny Stambulchik [email protected]
@@ -44,6 +48,7 @@ Fabrice Bauzac [email protected]
Florian Krohm [email protected]
Frank Heckenbach [email protected]
Frans Englich [email protected]
Gabriel Rassoul [email protected]
Georg Sauthoff [email protected]
George Neuner [email protected]
Gilles Espinasse [email protected]
@@ -61,6 +66,7 @@ Johan van Selst [email protected]
Jonathan Fabrizio [email protected]
Jonathan Nieder [email protected]
Juan Manuel Guerrero [email protected]
Ken Moffat [email protected]
Kees Zeelenberg [email protected]
Keith Browne [email protected]
Laurent Mascherpa [email protected]
@@ -74,6 +80,7 @@ Martin Mokrejs [email protected]
Martin Nylin [email protected]
Matt Kraai [email protected]
Matt Rosing [email protected]
Michael Felt [email protected]
Michael Hayes [email protected]
Michael Raskin [email protected]
Michiel De Wilde [email protected]
@@ -89,6 +96,7 @@ Odd Arild Olsen [email protected]
Oleg Smolsky [email protected]
Oleksii Taran [email protected]
Paolo Bonzini [email protected]
Paolo Simone Gasparello [email protected]
Pascal Bart [email protected]
Paul Eggert [email protected]
Paul Hilfinger [email protected]
@@ -97,6 +105,7 @@ Peter Eisentraut [email protected]
Peter Fales [email protected]
Peter Hamorsky [email protected]
Peter Simons [email protected]
Petr Machata [email protected]
Piotr Gackiewicz [email protected]
Quentin Hocquet [email protected]
Quoc Peyrot [email protected]
@@ -104,8 +113,10 @@ R Blake [email protected]
Raja R Harinath [email protected]
Ralf Wildenhues [email protected]
Richard Stallman [email protected]
Rici Lake [email protected]
Rob Vermaas [email protected]
Robert Anisko [email protected]
Rob Conde [email protected]
Roland Levillain [email protected]
Satya Kiran Popuri [email protected]
Sebastian Setzer [email protected]
@@ -126,6 +137,7 @@ Tommy Nordgren [email protected]
Troy A. Johnson [email protected]
Tys Lefering [email protected]
Valentin Tolmer [email protected]
Victor Khomenko [email protected]
Vin Shelton [email protected]
W.C.A. Wijngaards [email protected]
Wayne Green [email protected]
+23 -12
View File
@@ -1,16 +1,27 @@
* Short term
** Graphviz display code thoughts
The code for the --graph option is over two files: print_graph, and
graphviz. I believe this is because Bison used to also produce VCG graphs,
but since this is no longer true, maybe we could consider these files for
fusion.
graphviz. This is because Bison used to also produce VCG graphs, but since
this is no longer true, maybe we could consider these files for fusion.
Little effort factoring seems to have been given to factoring in these files,
and their print-xml and print counterpart. We would very much like to re-use
the pretty format of states from .output in the .dot
An other consideration worth noting is that print_graph.c (correct me if I
am wrong) should contain generic functions, whereas graphviz.c and other
potential files should contain just the specific code for that output
format. It will probably prove difficult to tell if the implementation is
actually generic whilst only having support for a single format, but it
would be nice to keep stuff a bit tidier: right now, the construction of the
bitset used to show reductions is in the graphviz-specific code, and on the
opposite side we have some use of \l, which is graphviz-specific, in what
should be generic code.
Also, the underscore in print_graph.[ch] isn't very fitting considering
the dashes in the other filenames.
Little effort seems to have been given to factoring these files and their
rint{,-xml} counterpart. We would very much like to re-use the pretty format
of states from .output for the graphs, etc.
Also, the underscore in print_graph.[ch] isn't very fitting considering the
dashes in the other filenames.
Since graphviz dies on medium-to-big grammars, maybe consider an other tool?
** push-parser
Check it too when checking the different kinds of parsers. And be
@@ -165,13 +176,13 @@ part of $default. Should we make the two reductions explicit, or just
keep $default? See the following point.
** Disabled Reductions
See `tests/conflicts.at (Defaulted Conflicted Reduction)', and decide
See 'tests/conflicts.at (Defaulted Conflicted Reduction)', and decide
what we want to do.
** Documentation
Extend with error productions. The hard part will probably be finding
the right rule so that a single state does not exhibit too many yet
undocumented ``features''. Maybe an empty action ought to be
undocumented ''features''. Maybe an empty action ought to be
presented too. Shall we try to make a single grammar with all these
features, or should we have several very small grammars?
@@ -232,9 +243,9 @@ into
exp: exp '+' exp | exp '&' exp;
when there are no actions. This can significantly speed up some
grammars. I can't find the papers. In particular the book `LR
grammars. I can't find the papers. In particular the book 'LR
parsing: Theory and Practice' is impossible to find, but according to
`Parsing Techniques: a Practical Guide', it includes information about
'Parsing Techniques: a Practical Guide', it includes information about
this issue. Does anybody have it?
+80 -66
View File
@@ -1,6 +1,6 @@
#! /bin/sh
# Print a version string.
scriptversion=2012-12-28.10; # UTC
scriptversion=2013-08-15.22; # UTC
# Bootstrap this package from checked-out sources.
@@ -140,20 +140,21 @@ po_download_command_format2=\
"wget --mirror -nd -q -np -A.po -P '%s' \
http://translationproject.org/latest/%s/"
# Prefer a non-empty tarname (4th argument of AC_INIT if given), else
# fall back to the package name (1st argument with munging)
extract_package_name='
/^AC_INIT(/{
/.*,.*,.*, */{
s///
s/[][]//g
s/)$//
/^AC_INIT(\[*/{
s///
/^[^,]*,[^,]*,[^,]*,[ []*\([^][ ,)]\)/{
s//\1/
s/[],)].*//
p
q
}
s/AC_INIT(\[*//
s/]*,.*//
s/[],)].*//
s/^GNU //
y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/
s/[^A-Za-z0-9_]/-/g
s/[^abcdefghijklmnopqrstuvwxyz0123456789_]/-/g
p
}
'
@@ -208,12 +209,16 @@ bootstrap_sync=false
# Use git to update gnulib sources
use_git=true
check_exists() {
($1 --version </dev/null) >/dev/null 2>&1
test $? -lt 126
}
# find_tool ENVVAR NAMES...
# -------------------------
# Search for a required program. Use the value of ENVVAR, if set,
# otherwise find the first of the NAMES that can be run (i.e.,
# supports --version). If found, set ENVVAR to the program name,
# die otherwise.
# otherwise find the first of the NAMES that can be run.
# If found, set ENVVAR to the program name, die otherwise.
#
# FIXME: code duplication, see also gnu-web-doc-update.
find_tool ()
@@ -223,27 +228,21 @@ find_tool ()
find_tool_names=$@
eval "find_tool_res=\$$find_tool_envvar"
if test x"$find_tool_res" = x; then
for i
do
if ($i --version </dev/null) >/dev/null 2>&1; then
find_tool_res=$i
break
for i; do
if check_exists $i; then
find_tool_res=$i
break
fi
done
else
find_tool_error_prefix="\$$find_tool_envvar: "
fi
test x"$find_tool_res" != x \
|| die "one of these is required: $find_tool_names"
($find_tool_res --version </dev/null) >/dev/null 2>&1 \
|| die "${find_tool_error_prefix}cannot run $find_tool_res --version"
if test x"$find_tool_res" = x; then
warn_ "one of these is required: $find_tool_names;"
die "alternatively set $find_tool_envvar to a compatible tool"
fi
eval "$find_tool_envvar=\$find_tool_res"
eval "export $find_tool_envvar"
}
# Find sha1sum, named gsha1sum on MacPorts, and shasum on Mac OS X 10.6.
find_tool SHA1SUM sha1sum gsha1sum shasum
# Override the default configuration, if necessary.
# Make sure that bootstrap.conf is sourced from the current directory
# if we were invoked as "sh bootstrap".
@@ -255,12 +254,12 @@ esac
# Extra files from gnulib, which override files from other sources.
test -z "${gnulib_extra_files}" && \
gnulib_extra_files="
$build_aux/install-sh
$build_aux/mdate-sh
$build_aux/texinfo.tex
$build_aux/depcomp
$build_aux/config.guess
$build_aux/config.sub
build-aux/install-sh
build-aux/mdate-sh
build-aux/texinfo.tex
build-aux/depcomp
build-aux/config.guess
build-aux/config.sub
doc/INSTALL
"
@@ -306,34 +305,34 @@ if test -n "$checkout_only_file" && test ! -r "$checkout_only_file"; then
die "Bootstrapping from a non-checked-out distribution is risky."
fi
# Ensure that lines starting with ! sort last, per gitignore conventions
# for whitelisting exceptions after a more generic blacklist pattern.
sort_patterns() {
sort -u "$@" | sed '/^!/ {
H
d
}
$ {
P
x
s/^\n//
}' | sed '/^$/d'
# Strip blank and comment lines to leave significant entries.
gitignore_entries() {
sed '/^#/d; /^$/d' "$@"
}
# If $STR is not already on a line by itself in $FILE, insert it,
# sorting the new contents of the file and replacing $FILE with the result.
insert_sorted_if_absent() {
# If $STR is not already on a line by itself in $FILE, insert it at the start.
# Entries are inserted at the start of the ignore list to ensure existing
# entries starting with ! are not overridden. Such entries support
# whitelisting exceptions after a more generic blacklist pattern.
insert_if_absent() {
file=$1
str=$2
test -f $file || touch $file
echo "$str" | sort_patterns - $file | cmp -s - $file > /dev/null \
|| { echo "$str" | sort_patterns - $file > $file.bak \
&& mv $file.bak $file; } \
|| die "insert_sorted_if_absent $file $str: failed"
test -r $file || die "Error: failed to read ignore file: $file"
duplicate_entries=$(gitignore_entries $file | sort | uniq -d)
if [ "$duplicate_entries" ] ; then
die "Error: Duplicate entries in $file: " $duplicate_entries
fi
linesold=$(gitignore_entries $file | wc -l)
linesnew=$( { echo "$str"; cat $file; } | gitignore_entries | sort -u | wc -l)
if [ $linesold != $linesnew ] ; then
{ echo "$str" | cat - $file > $file.bak && mv $file.bak $file; } \
|| die "insert_if_absent $file $str: failed"
fi
}
# Adjust $PATTERN for $VC_IGNORE_FILE and insert it with
# insert_sorted_if_absent.
# insert_if_absent.
insert_vc_ignore() {
vc_ignore_file="$1"
pattern="$2"
@@ -344,7 +343,7 @@ insert_vc_ignore() {
# .gitignore entry.
pattern=$(echo "$pattern" | sed s,^,/,);;
esac
insert_sorted_if_absent "$vc_ignore_file" "$pattern"
insert_if_absent "$vc_ignore_file" "$pattern"
}
# Die if there is no AC_CONFIG_AUX_DIR($build_aux) line in configure.ac.
@@ -468,8 +467,7 @@ check_versions() {
if [ "$req_ver" = "-" ]; then
# Merely require app to exist; not all prereq apps are well-behaved
# so we have to rely on $? rather than get_version.
$app --version >/dev/null 2>&1
if [ 126 -le $? ]; then
if ! check_exists $app; then
warn_ "Error: '$app' not found"
ret=1
fi
@@ -502,6 +500,12 @@ print_versions() {
# can't depend on column -t
}
# Find sha1sum, named gsha1sum on MacPorts, shasum on Mac OS X 10.6.
# Also find the compatible sha1 utility on the BSDs
if test x"$SKIP_PO" = x; then
find_tool SHA1SUM sha1sum gsha1sum shasum sha1
fi
use_libtool=0
# We'd like to use grep -E, to see if any of LT_INIT,
# AC_PROG_LIBTOOL, AM_PROG_LIBTOOL is used in configure.ac,
@@ -550,10 +554,10 @@ fi
echo "$0: Bootstrapping from checked-out $package sources..."
# See if we can use gnulib's git-merge-changelog merge driver.
if test -d .git && (git --version) >/dev/null 2>/dev/null ; then
if $use_git && test -d .git && check_exists git; then
if git config merge.merge-changelog.driver >/dev/null ; then
:
elif (git-merge-changelog --version) >/dev/null 2>/dev/null ; then
elif check_exists git-merge-changelog; then
echo "$0: initializing git-merge-changelog driver"
git config merge.merge-changelog.name 'GNU-style ChangeLog merge driver'
git config merge.merge-changelog.driver 'git-merge-changelog %O %A %B'
@@ -573,13 +577,17 @@ git_modules_config () {
test -f .gitmodules && git config --file .gitmodules "$@"
}
gnulib_path=$(git_modules_config submodule.gnulib.path)
test -z "$gnulib_path" && gnulib_path=gnulib
if $use_git; then
gnulib_path=$(git_modules_config submodule.gnulib.path)
test -z "$gnulib_path" && gnulib_path=gnulib
fi
# Get gnulib files.
# Get gnulib files. Populate $GNULIB_SRCDIR, possibly updating a
# submodule, for use in the rest of the script.
case ${GNULIB_SRCDIR--} in
-)
# Note that $use_git is necessarily true in this case.
if git_modules_config submodule.gnulib.url >/dev/null; then
echo "$0: getting gnulib files..."
git submodule init || exit $?
@@ -600,8 +608,8 @@ case ${GNULIB_SRCDIR--} in
GNULIB_SRCDIR=$gnulib_path
;;
*)
# Use GNULIB_SRCDIR as a reference.
if test -d "$GNULIB_SRCDIR"/.git && \
# Use GNULIB_SRCDIR directly or as a reference.
if $use_git && test -d "$GNULIB_SRCDIR"/.git && \
git_modules_config submodule.gnulib.url >/dev/null; then
echo "$0: getting gnulib files..."
if git submodule -h|grep -- --reference > /dev/null; then
@@ -627,12 +635,19 @@ case ${GNULIB_SRCDIR--} in
;;
esac
# $GNULIB_SRCDIR now points to the version of gnulib to use, and
# we no longer need to use git or $gnulib_path below here.
if $bootstrap_sync; then
cmp -s "$0" "$GNULIB_SRCDIR/build-aux/bootstrap" || {
echo "$0: updating bootstrap and restarting..."
case $(sh -c 'echo "$1"' -- a) in
a) ignored=--;;
*) ignored=ignored;;
esac
exec sh -c \
'cp "$1" "$2" && shift && exec "${CONFIG_SHELL-/bin/sh}" "$@"' \
-- "$GNULIB_SRCDIR/build-aux/bootstrap" \
$ignored "$GNULIB_SRCDIR/build-aux/bootstrap" \
"$0" "$@" --no-bootstrap-sync
}
fi
@@ -680,11 +695,10 @@ update_po_files() {
cksum_file="$ref_po_dir/$po.s1"
if ! test -f "$cksum_file" ||
! test -f "$po_dir/$po.po" ||
! $SHA1SUM -c --status "$cksum_file" \
< "$new_po" > /dev/null; then
! $SHA1SUM -c "$cksum_file" < "$new_po" > /dev/null 2>&1; then
echo "$me: updated $po_dir/$po.po..."
cp "$new_po" "$po_dir/$po.po" \
&& $SHA1SUM < "$new_po" > "$cksum_file"
&& $SHA1SUM < "$new_po" > "$cksum_file" || return
fi
done
}
+2 -1
View File
@@ -34,7 +34,8 @@ gnulib_modules='
readme-release
realloc-posix
spawn-pipe stdbool stpcpy strdup-posix strerror strtoul strverscmp
unistd unistd-safer unlocked-io update-copyright unsetenv verify
unistd unistd-safer unlink unlocked-io
update-copyright unsetenv verify
warnings
xalloc
xalloc-die
+16
View File
@@ -0,0 +1,16 @@
# Linux seattle 2.6.32-5-amd64 #1 SMP Thu Mar 22 17:26:33 UTC 2012
# x86_64 GNU/Linux
{
index
Memcheck:Cond
fun:index
fun:expand_dynamic_string_token
fun:_dl_map_object
fun:map_doit
fun:_dl_catch_error
fun:do_preload
fun:dl_main
fun:_dl_sysdep_start
fun:_dl_start
obj:/lib/ld-2.11.3.so
}
+1 -2
View File
@@ -1,5 +1,3 @@
## Makefile for Bison testsuite.
# Copyright (C) 2000-2013 Free Software Foundation, Inc.
#
# This program is free software: you can redistribute it and/or modify
@@ -18,6 +16,7 @@
EXTRA_DIST += \
build-aux/cross-options.pl \
build-aux/darwin11.4.0.valgrind \
build-aux/linux-gnu.valgrind \
build-aux/move-if-change \
build-aux/prev-version.txt \
build-aux/update-b4-copyright
+2 -1
View File
@@ -135,7 +135,7 @@ _sed_rm_comments_q = $(subst ','\'',$(_sed_remove_comments))
_space_before_paren_exempt =? \\n\\$$
_space_before_paren_exempt = \
(^ *\#|\\n\\$$|%s\(to %s|(date|group|character)\(s\))
(^ *\#|(LA)?LR\([01]\)|percent_(code|define)|b4_syncline|m4_(define|init)|symbol)
# Ensure that there is a space before each open parenthesis in C code.
sc_space_before_open_paren:
@if $(VC_LIST_EXCEPT) | grep -l '\.[ch]$$' > /dev/null; then \
@@ -175,5 +175,6 @@ $(call exclude, \
prohibit_strcmp=^doc/bison\.texi|tests/local\.at$$ \
prohibit_tab_based_indentation=\.(am|mk)$$|^djgpp/|^\.git \
require_config_h_first=^(lib/yyerror|data/(glr|yacc))\.c$$ \
space_before_open_paren=^(data/|djgpp/) \
unmarked_diagnostics=^(djgpp/|doc/bison.texi$$|tests/c\+\+\.at$$) \
)
+25 -25
View File
@@ -18,7 +18,7 @@
# In order for some versions of Sun Studio to compile our C++ test cases
# correctly, we need Autoconf 2.64 or better to handle the restrict
# keyword in at least string.h from gnulib. We need Autoconf 2.68 or
# better to avoid a typo in the `configure --help' entry for the YACC
# better to avoid a typo in the 'configure --help' entry for the YACC
# environment variable.
AC_PREREQ([2.68])
m4_pattern_forbid([^gl_[A-Z]])
@@ -33,11 +33,7 @@ AC_DEFINE_UNQUOTED([PACKAGE_COPYRIGHT_YEAR], [$PACKAGE_COPYRIGHT_YEAR],
AC_CONFIG_AUX_DIR([build-aux])
AC_CONFIG_MACRO_DIR([m4])
# Automake 1.10.3 and 1.11.1 fix a security flaw discussed here:
#
# http://thread.gmane.org/gmane.comp.sysutils.autotools.announce/131
#
# To avoid 1.11, we make 1.11.1 the minimum version.
# We use Automake 1.14's %D% and %C%.
#
# We want gnits strictness only when rolling a stable release. For
# release candidates, we use version strings like 2.4.3_rc1, but gnits
@@ -45,7 +41,7 @@ AC_CONFIG_MACRO_DIR([m4])
# releases, we want to be able run make dist without being required to
# add a bogus NEWS entry. In that case, the version string
# automatically contains a dash, which we also let disable gnits.
AM_INIT_AUTOMAKE([1.11.1 dist-xz nostdinc
AM_INIT_AUTOMAKE([1.14 dist-xz nostdinc
color-tests parallel-tests
silent-rules]
m4_bmatch(m4_defn([AC_PACKAGE_VERSION]), [[-_]],
@@ -82,7 +78,7 @@ AC_ARG_ENABLE([gcc-warnings],
esac],
[enable_gcc_warnings=no])
if test "$enable_gcc_warnings" = yes; then
warn_common='-Wall -Wextra -Wno-sign-compare -Wcast-align
warn_common='-Wall-Wextra -Wno-sign-compare -Wcast-align -Wdocumentation
-Wformat -Wpointer-arith -Wwrite-strings'
warn_c='-Wbad-function-cast -Wshadow -Wstrict-prototypes'
warn_cxx='-Wnoexcept'
@@ -91,7 +87,7 @@ if test "$enable_gcc_warnings" = yes; then
# -fno-color-diagnostics: Clang's use of colors in the error
# messages is confusing the tests looking at the compiler's output
# (e.g., synclines.at).
warn_tests='-Wundef -pedantic -fno-color-diagnostics'
warn_tests='-Wundef -pedantic -Wsign-compare -fno-color-diagnostics'
AC_LANG_PUSH([C])
# Clang supports many of GCC's -W options, but only issues warnings
@@ -143,9 +139,11 @@ if test "$enable_gcc_warnings" = yes; then
gl_WARN_ADD([$i], [WARN_CXXFLAGS_TEST])
done
# Clang++ 3.2+ reject C code generated by Flex.
gl_WARN_ADD([-Wno-null-conversion], [WARN_NO_NULL_CONVERSION_CXXFLAGS])
# Variants break strict aliasing analysis.
gl_WARN_ADD([-fno-strict-aliasing], [NO_STRICT_ALIAS_CXXFLAGS])
gl_WARN_ADD([-Wno-null-conversion], [FLEX_SCANNER_CXXFLAGS])
# So does G++ 4.8...
gl_WARN_ADD([-Wno-sign-compare], [FLEX_SCANNER_CXXFLAGS])
# ... possiby in std=c++11 mode.
gl_WARN_ADD([-Wno-zero-as-null-pointer-constant], [FLEX_SCANNER_CXXFLAGS])
CXXFLAGS=$save_CXXFLAGS
AC_LANG_POP([C++])
fi
@@ -159,21 +157,17 @@ AC_ARG_ENABLE([yacc],
[AC_HELP_STRING([--disable-yacc],
[do not build a yacc command or an -ly library])],
, [enable_yacc=yes])
case $enable_yacc in
yes)
YACC_SCRIPT=src/yacc
YACC_LIBRARY=lib/liby.a;;
*)
YACC_SCRIPT=
YACC_LIBRARY=;;
esac
AC_SUBST([YACC_SCRIPT])
AC_SUBST([YACC_LIBRARY])
AM_CONDITIONAL([ENABLE_YACC], [test "$enable_yacc" = yes])
# Checks for programs.
AM_MISSING_PROG([DOT], [dot])
AC_PROG_LEX
$LEX_IS_FLEX || AC_MSG_ERROR([Flex is required])
$LEX_IS_FLEX || test "X$LEX" = X: || {
AC_MSG_WARN([bypassing lex because flex is required])
LEX=:
}
AM_CONDITIONAL([FLEX_CXX_WORKS],
[$LEX_IS_FLEX && test $bison_cv_cxx_works = yes])
AC_PROG_YACC
AC_PROG_RANLIB
AC_PROG_GNU_M4
@@ -228,10 +222,16 @@ case $VALGRIND:$host_os in
'':*) ;;
*:darwin*)
# See README-hacking.
# VALGRIND+=' --suppressions=$(abs_top_srcdir)/build-aux/darwin11.4.0.valgrind'
# VALGRIND+='-q --suppressions=$(abs_top_srcdir)/build-aux/darwin11.4.0.valgrind'
VALGRIND=;;
*:*)
AC_SUBST([VALGRIND_PREBISON], ["$VALGRIND -q"]);;
suppfile=build-aux/$host_os.valgrind
if test -f "$srcdir/$suppfile"; then
VALGRIND="$VALGRIND --gen-suppressions=all"
VALGRIND="$VALGRIND --suppressions=\$(abs_top_srcdir)/$suppfile"
fi
AC_SUBST([VALGRIND_PREBISON], ["$VALGRIND -q"])
;;
esac
AM_MISSING_PROG([AUTOM4TE], [autom4te])
+1 -1
View File
@@ -27,7 +27,7 @@ Currently, the supported skeletons are:
These skeletons are the only ones supported by the Bison team.
Because the interface between skeletons and the bison program is not
finished, *we are not bound to it*. In particular, Bison is not
mature enough for us to consider that ``foreign skeletons'' are
mature enough for us to consider that "foreign skeletons" are
supported.
* m4sugar
+141 -28
View File
@@ -85,6 +85,20 @@ m4_changecom([#])
])
# b4_divert_kill(CODE)
# --------------------
# Expand CODE for its side effects, discard its output.
m4_define([b4_divert_kill],
[m4_divert_text([KILL], [$1])])
# b4_define_silent(MACRO, CODE)
# -----------------------------
# Same as m4_define, but throw away the expansion of CODE.
m4_define([b4_define_silent],
[m4_define([$1], [b4_divert_kill([$2])])])
## ---------------- ##
## Error handling. ##
## ---------------- ##
@@ -313,7 +327,7 @@ m4_define([b4_define_flag_if],
# _b4_define_flag_if($1, $2, FLAG)
# --------------------------------
# Work around the impossibility to define macros inside macros,
# because issuing `[$1]' is not possible in M4. GNU M4 should provide
# because issuing '[$1]' is not possible in M4. GNU M4 should provide
# $$1 a la M5/TeX.
m4_define([_b4_define_flag_if],
[m4_if([$1$2], $[1]$[2], [],
@@ -347,6 +361,7 @@ b4_define_flag_if([yacc]) # Whether POSIX Yacc is emulated.
# Whether the symbol has an id.
# - id: string
# If has_id, the id. Guaranteed to be usable as a C identifier.
# Prefixed by api.token.prefix if defined.
# - tag: string.
# A representat of the symbol. Can be 'foo', 'foo.id', '"foo"' etc.
# - user_number: integer
@@ -357,9 +372,13 @@ b4_define_flag_if([yacc]) # Whether POSIX Yacc is emulated.
# The internalized number (used after yytranslate).
# - has_type: 0, 1
# Whether has a semantic value.
# - type_tag: string
# When api.value.type=union, the generated name for the union member.
# yytype_INT etc. for symbols that has_id, otherwise yytype_1 etc.
# - type
# If it has a semantic value, its type tag, or, if variant are used,
# its type.
# In the case of api.value.type=union, type is the real type (e.g. int).
# - has_printer: 0, 1
# - printer: string
# - printer_file: string
@@ -442,6 +461,24 @@ m4_define([b4_symbol_destructor], [b4_symbol_action([$1], [destructor])])
m4_define([b4_symbol_printer], [b4_symbol_action([$1], [printer])])
# b4_symbol_actions(KIND, [TYPE = yytype])
# ----------------------------------------
# Emit the symbol actions for KIND ("printer" or "destructor").
# Dispatch on TYPE.
m4_define([b4_symbol_actions],
[m4_pushdef([b4_actions_], m4_expand([b4_symbol_foreach([b4_symbol_$1])]))dnl
m4_ifval(m4_defn([b4_actions_]),
[switch (m4_default([$2], [yytype]))
{
m4_defn([b4_actions_])
default:
break;
}dnl
],
[YYUSE (m4_default([$2], [yytype]));])dnl
m4_popdef([b4_actions_])dnl
])
# b4_symbol_case_(SYMBOL-NUM)
# ---------------------------
# Issue a "case NUM" for SYMBOL-NUM.
@@ -577,14 +614,14 @@ m4_define([b4_define_user_code],
# b4_user_initial_action
# b4_user_post_prologue
# b4_user_pre_prologue
# b4_user_stype
# b4_user_union_members
# ----------------------
# Macros that issue user code, ending with synclines.
b4_define_user_code([actions])
b4_define_user_code([initial_action])
b4_define_user_code([post_prologue])
b4_define_user_code([pre_prologue])
b4_define_user_code([stype])
b4_define_user_code([union_members])
# b4_check_user_names(WHAT, USER-LIST, BISON-NAMESPACE)
@@ -665,9 +702,9 @@ m4_define([b4_percent_define_use],
# b4_percent_define_get([[foo]])
m4_define([b4_percent_define_get],
[b4_percent_define_use([$1])dnl
m4_ifdef([b4_percent_define(]$1[)],
[m4_indir([b4_percent_define(]$1[)])],
[$2])])
b4_percent_define_ifdef_([$1],
[m4_indir([b4_percent_define(]$1[)])],
[$2])])
# b4_percent_define_get_loc(VARIABLE)
# -----------------------------------
@@ -686,7 +723,21 @@ m4_define([b4_percent_define_get_loc],
[m4_pushdef([b4_loc], m4_indir([b4_percent_define_loc(]$1[)]))dnl
b4_loc[]dnl
m4_popdef([b4_loc])],
[b4_fatal([[b4_percent_define_get_loc: undefined %%define variable '%s']], [$1])])])
[b4_fatal([[$0: undefined %%define variable '%s']], [$1])])])
# b4_percent_define_get_kind(VARIABLE)
# ------------------------------------
# Get the kind (code, keyword, string) of VARIABLE, i.e., how its
# value was defined (braces, not delimiters, quotes).
#
# If the %define variable VARIABLE is undefined, complain fatally
# since that's a Bison or skeleton error. Don't record this as a
# Bison usage of VARIABLE as there's no reason to suspect that the
# user-supplied value has yet influenced the output.
m4_define([b4_percent_define_get_kind],
[m4_ifdef([b4_percent_define_kind(]$1[)],
[m4_indir([b4_percent_define_kind(]$1[)])],
[b4_fatal([[$0: undefined %%define variable '%s']], [$1])])])
# b4_percent_define_get_syncline(VARIABLE)
# ----------------------------------------
@@ -703,7 +754,20 @@ m4_popdef([b4_loc])],
m4_define([b4_percent_define_get_syncline],
[m4_ifdef([b4_percent_define_syncline(]$1[)],
[m4_indir([b4_percent_define_syncline(]$1[)])],
[b4_fatal([[b4_percent_define_get_syncline: undefined %%define variable '%s']], [$1])])])
[b4_fatal([[$0: undefined %%define variable '%s']], [$1])])])
# b4_percent_define_ifdef_(VARIABLE, IF-TRUE, [IF-FALSE])
# ------------------------------------------------------
# If the %define variable VARIABLE is defined, expand IF-TRUE, else expand
# IF-FALSE. Don't record usage of VARIABLE.
#
# For example:
#
# b4_percent_define_ifdef_([[foo]], [[it's defined]], [[it's undefined]])
m4_define([b4_percent_define_ifdef_],
[m4_ifdef([b4_percent_define(]$1[)],
[$2],
[$3])])
# b4_percent_define_ifdef(VARIABLE, IF-TRUE, [IF-FALSE])
# ------------------------------------------------------
@@ -716,9 +780,9 @@ m4_define([b4_percent_define_get_syncline],
#
# b4_percent_define_ifdef([[foo]], [[it's defined]], [[it's undefined]])
m4_define([b4_percent_define_ifdef],
[m4_ifdef([b4_percent_define(]$1[)],
[b4_percent_define_use([$1])$2],
[$3])])
[b4_percent_define_ifdef_([$1],
[b4_percent_define_use([$1])$2],
[$3])])
## --------- ##
@@ -747,11 +811,11 @@ m4_define([b4_percent_define_flag_if],
[[invalid value for %%define Boolean variable '%s']],
[$1])],
[[b4_percent_define_flag_if($1)]])])],
[b4_fatal([[b4_percent_define_flag_if: undefined %%define variable '%s']], [$1])])])
[b4_fatal([[$0: undefined %%define variable '%s']], [$1])])])
# b4_percent_define_default(VARIABLE, DEFAULT)
# --------------------------------------------
# b4_percent_define_default(VARIABLE, DEFAULT, [KIND = keyword])
# --------------------------------------------------------------
# Mimic muscle_percent_define_default in ../src/muscle-tab.h exactly. That is,
# if the %define variable VARIABLE is undefined, set its value to DEFAULT.
# Don't record this as a Bison usage of VARIABLE as there's no reason to
@@ -761,8 +825,10 @@ m4_define([b4_percent_define_flag_if],
#
# b4_percent_define_default([[foo]], [[default value]])
m4_define([b4_percent_define_default],
[m4_ifndef([b4_percent_define(]$1[)],
[b4_percent_define_ifdef_([$1], [],
[m4_define([b4_percent_define(]$1[)], [$2])dnl
m4_define([b4_percent_define_kind(]$1[)],
[m4_default([$3], [keyword])])dnl
m4_define([b4_percent_define_loc(]$1[)],
[[[[<skeleton default value>:-1.-1]],
[[<skeleton default value>:-1.-1]]]])dnl
@@ -772,8 +838,8 @@ m4_define([b4_percent_define_default],
# b4_percent_define_if_define(NAME, [VARIABLE = NAME])
# ----------------------------------------------------
# Define b4_NAME_if that executes its $1 or $2 depending whether
# VARIABLE was %defined. The characters `.' and `-' in VARIABLE are mapped
# to `_'.
# VARIABLE was %defined. The characters '.' and `-' in VARIABLE are mapped
# to '_'.
m4_define([b4_percent_define_if_define_],
[m4_define(m4_bpatsubst([b4_$1_if], [[-.]], [_]),
[b4_percent_define_flag_if(m4_default([$2], [$1]),
@@ -783,6 +849,21 @@ m4_define([b4_percent_define_if_define],
b4_percent_define_if_define_([$1], [$2], $[1], $[2])])
# b4_percent_define_check_kind(VARIABLE, KIND, [DIAGNOSTIC = complain])
# ---------------------------------------------------------------------
m4_define([b4_percent_define_check_kind],
[b4_percent_define_ifdef_([$1],
[m4_if(b4_percent_define_get_kind([$1]), [$2], [],
[b4_error([m4_default([$3], [complain])],
b4_percent_define_get_loc([$1]),
[m4_case([$2],
[code], [[%%define variable '%s' requires '{...}' values]],
[keyword], [[%%define variable '%s' requires keyword values]],
[string], [[%%define variable '%s' requires '"..."' values]])],
[$1])])])dnl
])
# b4_percent_define_check_values(VALUES)
# --------------------------------------
# Mimic muscle_percent_define_check_values in ../src/muscle-tab.h exactly
@@ -804,8 +885,9 @@ m4_define([b4_percent_define_check_values],
[_b4_percent_define_check_values(b4_sublist)])])
m4_define([_b4_percent_define_check_values],
[m4_ifdef([b4_percent_define(]$1[)],
[m4_pushdef([b4_good_value], [0])dnl
[b4_percent_define_ifdef_([$1],
[b4_percent_define_check_kind(]$1[, [keyword], [deprecated])dnl
m4_pushdef([b4_good_value], [0])dnl
m4_if($#, 1, [],
[m4_foreach([b4_value], m4_dquote(m4_shift($@)),
[m4_if(m4_indir([b4_percent_define(]$1[)]), b4_value,
@@ -820,7 +902,7 @@ m4_define([_b4_percent_define_check_values],
[[accepted value: '%s']],
m4_dquote(b4_value))])])dnl
m4_popdef([b4_good_value])],
[b4_fatal([[b4_percent_define_check_values: undefined %%define variable '%s']], [$1])])])
[b4_fatal([[$0: undefined %%define variable '%s']], [$1])])])
# b4_percent_code_get([QUALIFIER])
# --------------------------------
@@ -861,10 +943,6 @@ m4_define([b4_percent_code_ifdef],
## Common variables. ##
## ------------------ ##
# Default values for %define.
# ---------------------------
# If the api.token.prefix, it is empty.
m4_percent_define_default([[api.token.prefix]], [[]])
# b4_parse_assert_if([IF-ASSERTIONS-ARE-USED], [IF-NOT])
# b4_parse_trace_if([IF-DEBUG-TRACES-ARE-ENABLED], [IF-NOT])
@@ -904,9 +982,11 @@ b4_error_verbose_if([m4_define([b4_token_table_flag], [1])])
# b4_variant_if([IF-VARIANT-ARE-USED], [IF-NOT])
# ----------------------------------------------
b4_percent_define_if_define([variant])
m4_case(b4_percent_define_get([[api.value.type]]),
[variant], [m4_define([b4_variant_flag], [[1]])],
[m4_define([b4_variant_flag], [[0]])])
m4_define([b4_variant_flag], [[0]])
b4_percent_define_ifdef([[api.value.type]],
[m4_case(b4_percent_define_get_kind([[api.value.type]]), [keyword],
[m4_case(b4_percent_define_get([[api.value.type]]), [variant],
[m4_define([b4_variant_flag], [[1]])])])])
b4_define_flag_if([variant])
@@ -941,10 +1021,43 @@ m4_define_default([b4_parse_param], [])
m4_define_default([b4_location_initial_column], [1])
m4_define_default([b4_location_initial_line], [1])
# Sanity checks.
## --------------- ##
## Sanity checks. ##
## --------------- ##
# api.location.prefix={...} (Java and C++).
b4_percent_define_check_kind([api.location.type], [code], [deprecated])
# api.position.prefix={...} (Java).
b4_percent_define_check_kind([api.position.type], [code], [deprecated])
# api.prefix >< %name-prefix.
b4_percent_define_check_kind([api.prefix], [code], [deprecated])
b4_percent_define_ifdef([api.prefix],
[m4_ifdef([b4_prefix],
[b4_complain_at(b4_percent_define_get_loc([api.prefix]),
[['%s' and '%s' cannot be used together]],
[%name-prefix],
[%define api.prefix])])])
# api.token.prefix={...}
# Make it a warning for those who used betas of Bison 3.0.
b4_percent_define_check_kind([api.token.prefix], [code], [deprecated])
# api.value.type >< %union.
b4_percent_define_ifdef([api.value.type],
[m4_ifdef([b4_union_members],
[b4_complain_at(b4_percent_define_get_loc([api.value.type]),
[['%s' and '%s' cannot be used together]],
[%union],
[%define api.value.type])])])
# api.value.type=union >< %yacc.
b4_percent_define_ifdef([api.value.type],
[m4_if(b4_percent_define_get([api.value.type]), [union],
[b4_yacc_if(dnl
[b4_complain_at(b4_percent_define_get_loc([api.value.type]),
[['%s' and '%s' cannot be used together]],
[%yacc],
[%define api.value.type "union"])])])])
+35 -13
View File
@@ -25,6 +25,12 @@ m4_include(b4_pkgdatadir/[c.m4])
m4_define([b4_comment],
[b4_comment_([$1], [$2// ], [$2// ])])
## -------- ##
## Checks. ##
## -------- ##
b4_percent_define_check_kind([api.namespace], [code], [deprecated])
b4_percent_define_check_kind([parser_class_name], [code], [deprecated])
## ---------------- ##
## Default values. ##
@@ -38,6 +44,7 @@ b4_percent_define_default([[parser_class_name]], [[parser]])
# b4_percent_define_default([[api.location.type]], [[location]])
b4_percent_define_default([[filename_type]], [[std::string]])
# Make it a warning for those who used betas of Bison 3.0.
b4_percent_define_default([[api.namespace]], m4_defn([b4_prefix]))
b4_percent_define_default([[global_tokens_and_yystype]], [[false]])
@@ -54,8 +61,8 @@ b4_percent_define_default([[define_location_comparison]],
m4_define([b4_namespace_ref], [b4_percent_define_get([[api.namespace]])])
# Don't permit an empty b4_namespace_ref. Any `::parser::foo' appended to it
# would compile as an absolute reference with `parser' in the global namespace.
# Don't permit an empty b4_namespace_ref. Any '::parser::foo' appended to it
# would compile as an absolute reference with 'parser' in the global namespace.
# b4_namespace_open would open an anonymous namespace and thus establish
# internal linkage. This would compile. However, it's cryptic, and internal
# linkage for the parser would be specified in all translation units that
@@ -112,19 +119,24 @@ m4_define([b4_token_enums],
## Semantic Values. ##
## ----------------- ##
# b4_semantic_type_declare
# ------------------------
# b4_value_type_declare
# ---------------------
# Declare semantic_type.
m4_define([b4_semantic_type_declare],
m4_define([b4_value_type_declare],
[b4_value_type_setup[]dnl
[ /// Symbol semantic values.
m4_ifdef([b4_stype],
[ union semantic_type
]m4_bmatch(b4_percent_define_get_kind([[api.value.type]]),
[code],
[[ typedef ]b4_percent_define_get([[api.value.type]])[ semantic_type;]],
[m4_bmatch(b4_percent_define_get([[api.value.type]]),
[union\|union-directive],
[[ union semantic_type
{
b4_user_stype
};],
[m4_if(b4_tag_seen_flag, 0,
[[ typedef int semantic_type;]],
[[ typedef ]b4_api_PREFIX[STYPE semantic_type;]])])])
]b4_user_union_members[
};]])])dnl
])
# b4_public_types_declare
@@ -133,7 +145,7 @@ b4_user_stype
# Depending on %define token_lex, may be output in the header or source file.
m4_define([b4_public_types_declare],
[[#ifndef ]b4_api_PREFIX[STYPE
]b4_semantic_type_declare[
]b4_value_type_declare[
#else
typedef ]b4_api_PREFIX[STYPE semantic_type;
#endif]b4_locations_if([
@@ -520,3 +532,13 @@ m4_define([b4_yylloc_default_define],
while (/*CONSTCOND*/ false)
# endif
]])
## -------- ##
## Checks. ##
## -------- ##
b4_token_ctor_if([b4_variant_if([],
[b4_fatal_at(b4_percent_define_get_loc(api.token.constructor),
[cannot use '%s' without '%s'],
[%define api.token.constructor],
[%define api.value.type variant]))])])
+218 -37
View File
@@ -150,7 +150,7 @@ m4_popdef([$1])dnl
# b4_parse_param_use([VAL], [LOC])
# --------------------------------
# `YYUSE' VAL, LOC if locations are enabled, and all the parse-params.
# 'YYUSE' VAL, LOC if locations are enabled, and all the parse-params.
m4_define([b4_parse_param_use],
[m4_ifvaln([$1], [ YYUSE ([$1]);])dnl
b4_locations_if([m4_ifvaln([$2], [ YYUSE ([$2]);])])dnl
@@ -182,7 +182,7 @@ m4_define([b4_int_type],
# b4_int_type_for(NAME)
# ---------------------
# Return the smallest int type able to handle numbers ranging from
# `NAME_min' to `NAME_max' (included).
# 'NAME_min' to 'NAME_max' (included).
m4_define([b4_int_type_for],
[b4_int_type($1_min, $1_max)])
@@ -199,6 +199,69 @@ m4_define([b4_table_value_equals],
[(!!(($2) == ($3)))])])
## ----------------- ##
## Compiler issues. ##
## ----------------- ##
# b4_attribute_define
# -------------------
# Provide portable compiler "attributes".
m4_define([b4_attribute_define],
[#ifndef YY_ATTRIBUTE
# if (defined __GNUC__ \
&& (2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__))) \
|| defined __SUNPRO_C && 0x5110 <= __SUNPRO_C
# define YY_ATTRIBUTE(Spec) __attribute__(Spec)
# else
# define YY_ATTRIBUTE(Spec) /* empty */
# endif
#endif
#ifndef YY_ATTRIBUTE_PURE
# define YY_ATTRIBUTE_PURE YY_ATTRIBUTE ((__pure__))
#endif
#ifndef YY_ATTRIBUTE_UNUSED
# define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__))
#endif
#if !defined _Noreturn \
&& (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112)
# if defined _MSC_VER && 1200 <= _MSC_VER
# define _Noreturn __declspec (noreturn)
# else
# define _Noreturn YY_ATTRIBUTE ((__noreturn__))
# endif
#endif
/* Suppress unused-variable warnings by "using" E. */
#if ! defined lint || defined __GNUC__
# define YYUSE(E) ((void) (E))
#else
# define YYUSE(E) /* empty */
#endif
#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__
/* Suppress an incorrect diagnostic about yylval being uninitialized. */
# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
_Pragma ("GCC diagnostic push") \
_Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\
_Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"")
# define YY_IGNORE_MAYBE_UNINITIALIZED_END \
_Pragma ("GCC diagnostic pop")
#else
# define YY_INITIAL_VALUE(Value) Value
#endif
#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
# define YY_IGNORE_MAYBE_UNINITIALIZED_END
#endif
#ifndef YY_INITIAL_VALUE
# define YY_INITIAL_VALUE(Value) /* Nothing. */
#endif
])
## ---------##
## Values. ##
## ---------##
@@ -206,14 +269,14 @@ m4_define([b4_table_value_equals],
# b4_null_define
# --------------
# Portability issues: define a YY_NULL appropriate for the current
# Portability issues: define a YY_NULLPTR appropriate for the current
# language (C, C++98, or C++11).
m4_define([b4_null_define],
[# ifndef YY_NULL
[# ifndef YY_NULLPTR
# if defined __cplusplus && 201103L <= __cplusplus
# define YY_NULL nullptr
# define YY_NULLPTR nullptr
# else
# define YY_NULL 0
# define YY_NULLPTR 0
# endif
# endif[]dnl
])
@@ -222,7 +285,7 @@ m4_define([b4_null_define],
# b4_null
# -------
# Return a null pointer constant.
m4_define([b4_null], [YY_NULL])
m4_define([b4_null], [YY_NULLPTR])
# b4_integral_parser_table_define(TABLE-NAME, CONTENT, COMMENT)
# -------------------------------------------------------------
@@ -421,12 +484,9 @@ m4_ifset([b4_parse_param], [, b4_parse_param]))[
yymsg = "Deleting";
YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
switch (yytype)
{
]b4_symbol_foreach([b4_symbol_destructor])dnl
[ default:
break;
}
YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
]b4_symbol_actions([destructor])[
YY_IGNORE_MAYBE_UNINITIALIZED_END
}]dnl
])
@@ -436,9 +496,9 @@ m4_ifset([b4_parse_param], [, b4_parse_param]))[
# Define the "yy_symbol_print" function.
m4_define_default([b4_yy_symbol_print_define],
[[
/*--------------------------------.
| Print this symbol on YYOUTPUT. |
`--------------------------------*/
/*----------------------------------------.
| Print this symbol's value on YYOUTPUT. |
`----------------------------------------*/
]b4_function_define([yy_symbol_value_print],
[static void],
@@ -459,12 +519,7 @@ m4_if(b4_skeleton, ["yacc.c"],
YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
# endif
]])dnl
[ switch (yytype)
{
]b4_symbol_foreach([b4_symbol_printer])dnl
[ default:
break;
}
b4_symbol_actions([printer])[
}
@@ -492,28 +547,154 @@ b4_locations_if([, yylocationp])[]b4_user_args[);
}]dnl
])
## ---------------- ##
## api.value.type. ##
## ---------------- ##
# ---------------------- #
# api.value.type=union. #
# ---------------------- #
# b4_symbol_type_register(SYMBOL-NUM)
# -----------------------------------
# Symbol SYMBOL-NUM has a type (for variant) instead of a type-tag.
# Extend the definition of %union's body with a field of that type,
# and extend the symbol's "type" field to point to the field name,
# instead of the type name.
m4_define([b4_symbol_type_register],
[m4_define([b4_symbol($1, type_tag)],
[b4_symbol_if([$1], [has_id],
[b4_symbol([$1], [id])],
[yytype_[]b4_symbol([$1], [number])])])dnl
m4_append([b4_user_union_members],
m4_expand([
b4_symbol_tag_comment([$1])dnl
b4_symbol([$1], [type]) b4_symbol([$1], [type_tag]);]))
])
# b4_type_define_tag(SYMBOL1-NUM, ...)
# ------------------------------------
# For the batch of symbols SYMBOL1-NUM... (which all have the same
# type), enhance the %union definition for each of them, and set
# there "type" field to the field tag name, instead of the type name.
m4_define([b4_type_define_tag],
[b4_symbol_if([$1], [has_type],
[m4_map([b4_symbol_type_register], [$@])])
])
# b4_symbol_value_union(VAL, [TYPE])
# ----------------------------------
# Same of b4_symbol_value, but when api.value.type=union.
m4_define([b4_symbol_value_union],
[m4_ifval([$2],
[(*($2*)(&$1))],
[$1])])
])
# b4_value_type_setup_union
# -------------------------
# Setup support for api.value.type=union. Symbols are defined with a
# type instead of a union member name: build the corresponding union,
# and give the symbols their tag.
m4_define([b4_value_type_setup_union],
[m4_define([b4_union_members])
b4_type_foreach([b4_type_define_tag])
m4_copy_force([b4_symbol_value_union], [b4_symbol_value])
])
# ---------------- #
# api.value.type. #
# ---------------- #
# b4_value_type_setup_variant
# ---------------------------
# Setup support for api.value.type=variant. By default, fail, specialized
# by other skeletons.
m4_define([b4_value_type_setup_variant],
[b4_complain_at(b4_percent_define_get_loc([[api.value.type]]),
[['%s' does not support '%s']],
[b4_skeleton],
[%define api.value.type variant])])
# _b4_value_type_setup_keyword
# ----------------------------
# api.value.type is defined with a keyword/string syntax. Check if
# that is properly defined, and prepare its use.
m4_define([_b4_value_type_setup_keyword],
[b4_percent_define_check_values([[[[api.value.type]],
[[none]],
[[union]],
[[union-directive]],
[[variant]],
[[yystype]]]])dnl
m4_case(b4_percent_define_get([[api.value.type]]),
[union], [b4_value_type_setup_union],
[variant], [b4_value_type_setup_variant])])
# b4_value_type_setup
# -------------------
# Check if api.value.type is properly defined, and possibly prepare
# its use.
b4_define_silent([b4_value_type_setup],
[# Define default value.
b4_percent_define_ifdef([[api.value.type]], [],
[# %union => api.value.type=union-directive
m4_ifdef([b4_union_members],
[m4_define([b4_percent_define_kind(api.value.type)], [keyword])
m4_define([b4_percent_define(api.value.type)], [union-directive])],
[# no tag seen => api.value.type={int}
m4_if(b4_tag_seen_flag, 0,
[m4_define([b4_percent_define_kind(api.value.type)], [code])
m4_define([b4_percent_define(api.value.type)], [int])],
[# otherwise api.value.type=yystype
m4_define([b4_percent_define_kind(api.value.type)], [keyword])
m4_define([b4_percent_define(api.value.type)], [yystype])])])])
# Set up.
m4_bmatch(b4_percent_define_get_kind([[api.value.type]]),
[keyword\|string], [_b4_value_type_setup_keyword])
])
## -------------- ##
## Declarations. ##
## -------------- ##
# b4_value_type_define
# --------------------
m4_define([b4_value_type_define],
[[/* Value type. */
#if ! defined ]b4_api_PREFIX[STYPE && ! defined ]b4_api_PREFIX[STYPE_IS_DECLARED
]m4_ifdef([b4_stype],
[[typedef union ]b4_union_name[ ]b4_api_PREFIX[STYPE;
union ]b4_union_name[
{
]b4_user_stype[
};
# define ]b4_api_PREFIX[STYPE_IS_TRIVIAL 1]],
[m4_if(b4_tag_seen_flag, 0,
[[typedef int ]b4_api_PREFIX[STYPE;
# define ]b4_api_PREFIX[STYPE_IS_TRIVIAL 1]])])[
[b4_value_type_setup[]dnl
/* Value type. */
m4_bmatch(b4_percent_define_get_kind([[api.value.type]]),
[code],
[[#if ! defined ]b4_api_PREFIX[STYPE && ! defined ]b4_api_PREFIX[STYPE_IS_DECLARED
typedef ]b4_percent_define_get([[api.value.type]])[ ]b4_api_PREFIX[STYPE;
# define ]b4_api_PREFIX[STYPE_IS_TRIVIAL 1
# define ]b4_api_PREFIX[STYPE_IS_DECLARED 1
#endif
]])
]],
[m4_bmatch(b4_percent_define_get([[api.value.type]]),
[union\|union-directive],
[[#if ! defined ]b4_api_PREFIX[STYPE && ! defined ]b4_api_PREFIX[STYPE_IS_DECLARED
typedef union ]b4_union_name[ ]b4_api_PREFIX[STYPE;
union ]b4_union_name[
{
]b4_user_union_members[
};
# define ]b4_api_PREFIX[STYPE_IS_TRIVIAL 1
# define ]b4_api_PREFIX[STYPE_IS_DECLARED 1
#endif
]])])])
# b4_location_type_define
@@ -549,7 +730,7 @@ b4_pure_if([], [[extern ]b4_api_PREFIX[STYPE ]b4_prefix[lval;
# b4_YYDEBUG_define
# ------------------
# -----------------
m4_define([b4_YYDEBUG_define],
[[/* Debug traces. */
]m4_if(b4_api_prefix, [yy],
@@ -621,7 +802,7 @@ m4_define([b4_yy_location_print_define],
/* Print *YYLOCP on YYO. Private, do not rely on its existence. */
__attribute__((__unused__))
YY_ATTRIBUTE_UNUSED
]b4_function_define([yy_location_print_],
[static unsigned],
[[FILE *yyo], [yyo]],
+82 -97
View File
@@ -246,13 +246,6 @@ b4_percent_code_get[]dnl
# endif
#endif
/* Suppress unused-variable warnings by "using" E. */
#ifdef __GNUC__
# define YYUSE(E) ((void) (E))
#else
# define YYUSE(E) /* empty */
#endif
#ifndef YYFREE
# define YYFREE free
#endif
@@ -281,17 +274,7 @@ b4_percent_code_get[]dnl
# define YYLONGJMP(Env, Val) (longjmp (Env, Val), YYASSERT (0))
#endif
/*-----------------.
| GCC extensions. |
`-----------------*/
#ifndef __attribute__
/* This feature is available in gcc versions 2.5 and later. */
# if (! defined __GNUC__ || __GNUC__ < 2 \
|| (__GNUC__ == 2 && __GNUC_MINOR__ < 5))
# define __attribute__(Spec) /* empty */
# endif
#endif
]b4_attribute_define[
#ifndef YYASSERT
# define YYASSERT(Condition) ((void) ((Condition) || (abort (), 0)))
@@ -462,9 +445,9 @@ int yydebug;
struct yyGLRStack;
static void yypstack (struct yyGLRStack* yystackp, size_t yyk)
__attribute__ ((__unused__));
YY_ATTRIBUTE_UNUSED;
static void yypdumpstack (struct yyGLRStack* yystackp)
__attribute__ ((__unused__));
YY_ATTRIBUTE_UNUSED;
#else /* !]b4_api_PREFIX[DEBUG */
@@ -686,19 +669,15 @@ struct yyGLRStack {
static void yyexpandGLRStack (yyGLRStack* yystackp);
#endif
static void yyFail (yyGLRStack* yystackp]b4_pure_formals[, const char* yymsg)
__attribute__ ((__noreturn__));
static void
static _Noreturn void
yyFail (yyGLRStack* yystackp]b4_pure_formals[, const char* yymsg)
{
if (yymsg != YY_NULL)
if (yymsg != YY_NULLPTR)
yyerror (]b4_yyerror_args[yymsg);
YYLONGJMP (yystackp->yyexception_buffer, 1);
}
static void yyMemoryExhausted (yyGLRStack* yystackp)
__attribute__ ((__noreturn__));
static void
static _Noreturn void
yyMemoryExhausted (yyGLRStack* yystackp)
{
YYLONGJMP (yystackp->yyexception_buffer, 2);
@@ -719,7 +698,7 @@ yytokenName (yySymbol yytoken)
/** Fill in YYVSP[YYLOW1 .. YYLOW0-1] from the chain of states starting
* at YYVSP[YYLOW0].yystate.yypred. Leaves YYVSP[YYLOW1].yystate.yypred
* containing the pointer to the next state in the chain. */
static void yyfillin (yyGLRStackItem *, int, int) __attribute__ ((__unused__));
static void yyfillin (yyGLRStackItem *, int, int) YY_ATTRIBUTE_UNUSED;
static void
yyfillin (yyGLRStackItem *yyvsp, int yylow0, int yylow1)
{
@@ -736,7 +715,7 @@ yyfillin (yyGLRStackItem *yyvsp, int yylow0, int yylow1)
else
/* The effect of using yysval or yyloc (in an immediate rule) is
* undefined. */
yyvsp[i].yystate.yysemantics.yyfirstVal = YY_NULL;]b4_locations_if([[
yyvsp[i].yystate.yysemantics.yyfirstVal = YY_NULLPTR;]b4_locations_if([[
yyvsp[i].yystate.yyloc = s->yyloc;]])[
s = yyvsp[i].yystate.yypred = s->yypred;
}
@@ -746,7 +725,7 @@ yyfillin (yyGLRStackItem *yyvsp, int yylow0, int yylow1)
* YYVSP[YYLOW1 .. *YYLOW-1] as in yyfillin and set *YYLOW = YYLOW1.
* For convenience, always return YYLOW1. */
static inline int yyfill (yyGLRStackItem *, int *, int, yybool)
__attribute__ ((__unused__));
YY_ATTRIBUTE_UNUSED;
static inline int
yyfill (yyGLRStackItem *yyvsp, int *yylow, int yylow1, yybool yynormal)
{
@@ -768,8 +747,7 @@ yyuserAction (yyRuleNum yyn, size_t yyrhslen, yyGLRStackItem* yyvsp,
yyGLRStack* yystackp,
YYSTYPE* yyvalp]b4_locuser_formals[)
{
yybool yynormal __attribute__ ((__unused__)) =
(yystackp->yysplitPoint == YY_NULL);
yybool yynormal YY_ATTRIBUTE_UNUSED = (yystackp->yysplitPoint == YY_NULLPTR);
int yylow;
]b4_parse_param_use([yyvalp], [yylocp])dnl
[ YYUSE (yyrhslen);
@@ -853,12 +831,10 @@ yydestroyGLRState (char const *yymsg, yyGLRState *yys]b4_user_formals[)
if (yydebug)
{
if (yys->yysemantics.yyfirstVal)
YYFPRINTF (stderr, "%s unresolved ", yymsg);
YYFPRINTF (stderr, "%s unresolved", yymsg);
else
YYFPRINTF (stderr, "%s incomplete ", yymsg);
yy_symbol_print (stderr, yystos[yys->yylrState],
YY_NULL]b4_locuser_args([&yys->yyloc])[);
YYFPRINTF (stderr, "\n");
YYFPRINTF (stderr, "%s incomplete", yymsg);
YY_SYMBOL_PRINT ("", yystos[yys->yylrState], YY_NULLPTR, &yys->yyloc);
}
#endif
@@ -934,14 +910,18 @@ yygetLRActions (yyStateNum yystate, int yytoken,
}
}
/** Compute post-reduction state.
* \param yystate the current state
* \param yysym the nonterminal to push on the stack
*/
static inline yyStateNum
yyLRgotoState (yyStateNum yystate, yySymbol yylhs)
yyLRgotoState (yyStateNum yystate, yySymbol yysym)
{
int yyr = yypgoto[yylhs - YYNTOKENS] + yystate;
int yyr = yypgoto[yysym - YYNTOKENS] + yystate;
if (0 <= yyr && yyr <= YYLAST && yycheck[yyr] == yystate)
return yytable[yyr];
else
return yydefgoto[yylhs - YYNTOKENS];
return yydefgoto[yysym - YYNTOKENS];
}
static inline yybool
@@ -983,6 +963,7 @@ yyaddDeferredAction (yyGLRStack* yystackp, size_t yyk, yyGLRState* yystate,
{
yySemanticOption* yynewOption =
&yynewGLRStackItem (yystackp, yyfalse)->yyoption;
YYASSERT (!yynewOption->yyisState);
yynewOption->yystate = yyrhs;
yynewOption->yyrule = yyrule;
if (yystackp->yytops.yylookaheadNeeds[yyk])
@@ -1010,7 +991,7 @@ yyinitStateSet (yyGLRStateSet* yyset)
yyset->yystates = (yyGLRState**) YYMALLOC (16 * sizeof yyset->yystates[0]);
if (! yyset->yystates)
return yyfalse;
yyset->yystates[0] = YY_NULL;
yyset->yystates[0] = YY_NULLPTR;
yyset->yylookaheadNeeds =
(yybool*) YYMALLOC (16 * sizeof yyset->yylookaheadNeeds[0]);
if (! yyset->yylookaheadNeeds)
@@ -1040,8 +1021,8 @@ yyinitGLRStack (yyGLRStack* yystackp, size_t yysize)
if (!yystackp->yyitems)
return yyfalse;
yystackp->yynextFree = yystackp->yyitems;
yystackp->yysplitPoint = YY_NULL;
yystackp->yylastDeleted = YY_NULL;
yystackp->yysplitPoint = YY_NULLPTR;
yystackp->yylastDeleted = YY_NULLPTR;
return yyinitStateSet (&yystackp->yytops);
}
@@ -1080,10 +1061,10 @@ yyexpandGLRStack (yyGLRStack* yystackp)
{
yyGLRState* yys0 = &yyp0->yystate;
yyGLRState* yys1 = &yyp1->yystate;
if (yys0->yypred != YY_NULL)
if (yys0->yypred != YY_NULLPTR)
yys1->yypred =
YYRELOC (yyp0, yyp1, yys0->yypred, yystate);
if (! yys0->yyresolved && yys0->yysemantics.yyfirstVal != YY_NULL)
if (! yys0->yyresolved && yys0->yysemantics.yyfirstVal != YY_NULLPTR)
yys1->yysemantics.yyfirstVal =
YYRELOC (yyp0, yyp1, yys0->yysemantics.yyfirstVal, yyoption);
}
@@ -1091,18 +1072,18 @@ yyexpandGLRStack (yyGLRStack* yystackp)
{
yySemanticOption* yyv0 = &yyp0->yyoption;
yySemanticOption* yyv1 = &yyp1->yyoption;
if (yyv0->yystate != YY_NULL)
if (yyv0->yystate != YY_NULLPTR)
yyv1->yystate = YYRELOC (yyp0, yyp1, yyv0->yystate, yystate);
if (yyv0->yynext != YY_NULL)
if (yyv0->yynext != YY_NULLPTR)
yyv1->yynext = YYRELOC (yyp0, yyp1, yyv0->yynext, yyoption);
}
}
if (yystackp->yysplitPoint != YY_NULL)
if (yystackp->yysplitPoint != YY_NULLPTR)
yystackp->yysplitPoint = YYRELOC (yystackp->yyitems, yynewItems,
yystackp->yysplitPoint, yystate);
yystackp->yysplitPoint, yystate);
for (yyn = 0; yyn < yystackp->yytops.yysize; yyn += 1)
if (yystackp->yytops.yystates[yyn] != YY_NULL)
if (yystackp->yytops.yystates[yyn] != YY_NULLPTR)
yystackp->yytops.yystates[yyn] =
YYRELOC (yystackp->yyitems, yynewItems,
yystackp->yytops.yystates[yyn], yystate);
@@ -1126,7 +1107,7 @@ yyfreeGLRStack (yyGLRStack* yystackp)
static inline void
yyupdateSplit (yyGLRStack* yystackp, yyGLRState* yys)
{
if (yystackp->yysplitPoint != YY_NULL && yystackp->yysplitPoint > yys)
if (yystackp->yysplitPoint != YY_NULLPTR && yystackp->yysplitPoint > yys)
yystackp->yysplitPoint = yys;
}
@@ -1134,9 +1115,9 @@ yyupdateSplit (yyGLRStack* yystackp, yyGLRState* yys)
static inline void
yymarkStackDeleted (yyGLRStack* yystackp, size_t yyk)
{
if (yystackp->yytops.yystates[yyk] != YY_NULL)
if (yystackp->yytops.yystates[yyk] != YY_NULLPTR)
yystackp->yylastDeleted = yystackp->yytops.yystates[yyk];
yystackp->yytops.yystates[yyk] = YY_NULL;
yystackp->yytops.yystates[yyk] = YY_NULLPTR;
}
/** Undelete the last stack in *YYSTACKP that was marked as deleted. Can
@@ -1145,12 +1126,12 @@ yymarkStackDeleted (yyGLRStack* yystackp, size_t yyk)
static void
yyundeleteLastStack (yyGLRStack* yystackp)
{
if (yystackp->yylastDeleted == YY_NULL || yystackp->yytops.yysize != 0)
if (yystackp->yylastDeleted == YY_NULLPTR || yystackp->yytops.yysize != 0)
return;
yystackp->yytops.yystates[0] = yystackp->yylastDeleted;
yystackp->yytops.yysize = 1;
YYDPRINTF ((stderr, "Restoring last deleted stack as stack #0.\n"));
yystackp->yylastDeleted = YY_NULL;
yystackp->yylastDeleted = YY_NULLPTR;
}
static inline void
@@ -1160,7 +1141,7 @@ yyremoveDeletes (yyGLRStack* yystackp)
yyi = yyj = 0;
while (yyj < yystackp->yytops.yysize)
{
if (yystackp->yytops.yystates[yyi] == YY_NULL)
if (yystackp->yytops.yystates[yyi] == YY_NULLPTR)
{
if (yyi == yyj)
{
@@ -1218,12 +1199,13 @@ yyglrShiftDefer (yyGLRStack* yystackp, size_t yyk, yyStateNum yylrState,
size_t yyposn, yyGLRState* yyrhs, yyRuleNum yyrule)
{
yyGLRState* yynewState = &yynewGLRStackItem (yystackp, yytrue)->yystate;
YYASSERT (yynewState->yyisState);
yynewState->yylrState = yylrState;
yynewState->yyposn = yyposn;
yynewState->yyresolved = yyfalse;
yynewState->yypred = yystackp->yytops.yystates[yyk];
yynewState->yysemantics.yyfirstVal = YY_NULL;
yynewState->yysemantics.yyfirstVal = YY_NULLPTR;
yystackp->yytops.yystates[yyk] = yynewState;
/* Invokes YY_RESERVE_GLRSTACK. */
@@ -1283,7 +1265,7 @@ yydoAction (yyGLRStack* yystackp, size_t yyk, yyRuleNum yyrule,
{
int yynrhs = yyrhsLength (yyrule);
if (yystackp->yysplitPoint == YY_NULL)
if (yystackp->yysplitPoint == YY_NULLPTR)
{
/* Standard special case: single stack. */
yyGLRStackItem* yyrhs = (yyGLRStackItem*) yystackp->yytops.yystates[yyk];
@@ -1335,14 +1317,13 @@ yyglrReduce (yyGLRStack* yystackp, size_t yyk, yyRuleNum yyrule,
{
size_t yyposn = yystackp->yytops.yystates[yyk]->yyposn;
if (yyforceEval || yystackp->yysplitPoint == YY_NULL)
if (yyforceEval || yystackp->yysplitPoint == YY_NULLPTR)
{
YYRESULTTAG yyflag;
YYSTYPE yysval;]b4_locations_if([
YYLTYPE yyloc;])[
YYSTYPE yysval;]b4_locations_if([[
YYLTYPE yyloc;]])[
yyflag = yydoAction (yystackp, yyk, yyrule, &yysval]b4_locuser_args([&yyloc])[);
if (yyflag == yyerr && yystackp->yysplitPoint != YY_NULL)
YYRESULTTAG yyflag = yydoAction (yystackp, yyk, yyrule, &yysval]b4_locuser_args([&yyloc])[);
if (yyflag == yyerr && yystackp->yysplitPoint != YY_NULLPTR)
{
YYDPRINTF ((stderr, "Parse on stack %lu rejected by rule #%d.\n",
(unsigned long int) yyk, yyrule - 1));
@@ -1375,7 +1356,7 @@ yyglrReduce (yyGLRStack* yystackp, size_t yyk, yyRuleNum yyrule,
"Now in state %d.\n",
(unsigned long int) yyk, yyrule - 1, yynewLRState));
for (yyi = 0; yyi < yystackp->yytops.yysize; yyi += 1)
if (yyi != yyk && yystackp->yytops.yystates[yyi] != YY_NULL)
if (yyi != yyk && yystackp->yytops.yystates[yyi] != YY_NULLPTR)
{
yyGLRState *yysplit = yystackp->yysplitPoint;
yyGLRState *yyp = yystackp->yytops.yystates[yyi];
@@ -1402,7 +1383,7 @@ yyglrReduce (yyGLRStack* yystackp, size_t yyk, yyRuleNum yyrule,
static size_t
yysplitStack (yyGLRStack* yystackp, size_t yyk)
{
if (yystackp->yysplitPoint == YY_NULL)
if (yystackp->yysplitPoint == YY_NULLPTR)
{
YYASSERT (yyk == 0);
yystackp->yysplitPoint = yystackp->yytops.yystates[yyk];
@@ -1412,7 +1393,7 @@ yysplitStack (yyGLRStack* yystackp, size_t yyk)
yyGLRState** yynewStates;
yybool* yynewLookaheadNeeds;
yynewStates = YY_NULL;
yynewStates = YY_NULLPTR;
if (yystackp->yytops.yycapacity
> (YYSIZEMAX / (2 * sizeof yynewStates[0])))
@@ -1423,7 +1404,7 @@ yysplitStack (yyGLRStack* yystackp, size_t yyk)
(yyGLRState**) YYREALLOC (yystackp->yytops.yystates,
(yystackp->yytops.yycapacity
* sizeof yynewStates[0]));
if (yynewStates == YY_NULL)
if (yynewStates == YY_NULLPTR)
yyMemoryExhausted (yystackp);
yystackp->yytops.yystates = yynewStates;
@@ -1431,7 +1412,7 @@ yysplitStack (yyGLRStack* yystackp, size_t yyk)
(yybool*) YYREALLOC (yystackp->yytops.yylookaheadNeeds,
(yystackp->yytops.yycapacity
* sizeof yynewLookaheadNeeds[0]));
if (yynewLookaheadNeeds == YY_NULL)
if (yynewLookaheadNeeds == YY_NULLPTR)
yyMemoryExhausted (yystackp);
yystackp->yytops.yylookaheadNeeds = yynewLookaheadNeeds;
}
@@ -1495,9 +1476,9 @@ yymergeOptionSets (yySemanticOption* yyy0, yySemanticOption* yyy1)
yySemanticOption* yyz1 = yys1->yysemantics.yyfirstVal;
while (yytrue)
{
if (yyz1 == *yyz0p || yyz1 == YY_NULL)
if (yyz1 == *yyz0p || yyz1 == YY_NULLPTR)
break;
else if (*yyz0p == YY_NULL)
else if (*yyz0p == YY_NULLPTR)
{
*yyz0p = yyz1;
break;
@@ -1618,7 +1599,7 @@ yyreportTree (yySemanticOption* yyx, int yyindent)
for (yyi = yynrhs, yys = yyx->yystate; 0 < yyi; yyi -= 1, yys = yys->yypred)
yystates[yyi] = yys;
if (yys == YY_NULL)
if (yys == YY_NULLPTR)
{
yyleftmost_state.yyposn = 0;
yystates[0] = &yyleftmost_state;
@@ -1689,7 +1670,7 @@ yyresolveLocations (yyGLRState* yys1, int yyn1,
yyGLRStackItem yyrhsloc[1 + YYMAXRHS];
int yynrhs;
yySemanticOption *yyoption = yys1->yysemantics.yyfirstVal;
YYASSERT (yyoption != YY_NULL);
YYASSERT (yyoption != YY_NULLPTR);
yynrhs = yyrhsLength (yyoption->yyrule);
if (yynrhs > 0)
{
@@ -1748,7 +1729,7 @@ yyresolveValue (yyGLRState* yys, yyGLRStack* yystackp]b4_user_formals[)
YYRESULTTAG yyflag;]b4_locations_if([
YYLTYPE *yylocp = &yys->yyloc;])[
for (yypp = &yyoptionList->yynext; *yypp != YY_NULL; )
for (yypp = &yyoptionList->yynext; *yypp != YY_NULLPTR; )
{
yySemanticOption* yyp = *yypp;
@@ -1790,7 +1771,7 @@ yyresolveValue (yyGLRState* yys, yyGLRStack* yystackp]b4_user_formals[)
int yyprec = yydprec[yybest->yyrule];
yyflag = yyresolveAction (yybest, yystackp, &yysval]b4_locuser_args[);
if (yyflag == yyok)
for (yyp = yybest->yynext; yyp != YY_NULL; yyp = yyp->yynext)
for (yyp = yybest->yynext; yyp != YY_NULLPTR; yyp = yyp->yynext)
{
if (yyprec == yydprec[yyp->yyrule])
{
@@ -1817,14 +1798,14 @@ yyresolveValue (yyGLRState* yys, yyGLRStack* yystackp]b4_user_formals[)
yys->yysemantics.yysval = yysval;
}
else
yys->yysemantics.yyfirstVal = YY_NULL;
yys->yysemantics.yyfirstVal = YY_NULLPTR;
return yyflag;
}
static YYRESULTTAG
yyresolveStack (yyGLRStack* yystackp]b4_user_formals[)
{
if (yystackp->yysplitPoint != YY_NULL)
if (yystackp->yysplitPoint != YY_NULLPTR)
{
yyGLRState* yys;
int yyn;
@@ -1844,10 +1825,10 @@ yycompressStack (yyGLRStack* yystackp)
{
yyGLRState* yyp, *yyq, *yyr;
if (yystackp->yytops.yysize != 1 || yystackp->yysplitPoint == YY_NULL)
if (yystackp->yytops.yysize != 1 || yystackp->yysplitPoint == YY_NULLPTR)
return;
for (yyp = yystackp->yytops.yystates[0], yyq = yyp->yypred, yyr = YY_NULL;
for (yyp = yystackp->yytops.yystates[0], yyq = yyp->yypred, yyr = YY_NULLPTR;
yyp != yystackp->yysplitPoint;
yyr = yyp, yyp = yyq, yyq = yyp->yypred)
yyp->yypred = yyr;
@@ -1855,10 +1836,10 @@ yycompressStack (yyGLRStack* yystackp)
yystackp->yyspaceLeft += yystackp->yynextFree - yystackp->yyitems;
yystackp->yynextFree = ((yyGLRStackItem*) yystackp->yysplitPoint) + 1;
yystackp->yyspaceLeft -= yystackp->yynextFree - yystackp->yyitems;
yystackp->yysplitPoint = YY_NULL;
yystackp->yylastDeleted = YY_NULL;
yystackp->yysplitPoint = YY_NULLPTR;
yystackp->yylastDeleted = YY_NULLPTR;
while (yyr != YY_NULL)
while (yyr != YY_NULLPTR)
{
yystackp->yynextFree->yystate = *yyr;
yyr = yyr->yypred;
@@ -1873,7 +1854,7 @@ static YYRESULTTAG
yyprocessOneStack (yyGLRStack* yystackp, size_t yyk,
size_t yyposn]b4_pure_formals[)
{
while (yystackp->yytops.yystates[yyk] != YY_NULL)
while (yystackp->yytops.yystates[yyk] != YY_NULLPTR)
{
yyStateNum yystate = yystackp->yytops.yystates[yyk]->yylrState;
YYDPRINTF ((stderr, "Stack %lu Entering state %d\n",
@@ -1995,13 +1976,13 @@ yyreportSyntaxError (yyGLRStack* yystackp]b4_user_formals[)
#else
{
yySymbol yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar);
size_t yysize0 = yytnamerr (YY_NULL, yytokenName (yytoken));
size_t yysize0 = yytnamerr (YY_NULLPTR, yytokenName (yytoken));
size_t yysize = yysize0;
yybool yysize_overflow = yyfalse;
char* yymsg = YY_NULL;
char* yymsg = YY_NULLPTR;
enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
/* Internationalized format string. */
const char *yyformat = YY_NULL;
const char *yyformat = YY_NULLPTR;
/* Arguments of yyformat. */
char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
/* Number of reported tokens (one for the "unexpected", one per
@@ -2057,7 +2038,7 @@ yyreportSyntaxError (yyGLRStack* yystackp]b4_user_formals[)
}
yyarg[yycount++] = yytokenName (yyx);
{
size_t yysz = yysize + yytnamerr (YY_NULL, yytokenName (yyx));
size_t yysz = yysize + yytnamerr (YY_NULLPTR, yytokenName (yyx));
yysize_overflow |= yysz < yysize;
yysize = yysz;
}
@@ -2135,7 +2116,7 @@ yyrecoverSyntaxError (yyGLRStack* yystackp]b4_user_formals[)
{
yySymbol yytoken;
if (yychar == YYEOF)
yyFail (yystackp][]b4_lpure_args[, YY_NULL);
yyFail (yystackp][]b4_lpure_args[, YY_NULLPTR);
if (yychar != YYEMPTY)
{]b4_locations_if([[
/* We throw away the lookahead, but the error range
@@ -2176,10 +2157,10 @@ yyrecoverSyntaxError (yyGLRStack* yystackp]b4_user_formals[)
/* Reduce to one stack. */
for (yyk = 0; yyk < yystackp->yytops.yysize; yyk += 1)
if (yystackp->yytops.yystates[yyk] != YY_NULL)
if (yystackp->yytops.yystates[yyk] != YY_NULLPTR)
break;
if (yyk >= yystackp->yytops.yysize)
yyFail (yystackp][]b4_lpure_args[, YY_NULL);
yyFail (yystackp][]b4_lpure_args[, YY_NULLPTR);
for (yyk += 1; yyk < yystackp->yytops.yysize; yyk += 1)
yymarkStackDeleted (yystackp, yyk);
yyremoveDeletes (yystackp);
@@ -2187,7 +2168,7 @@ yyrecoverSyntaxError (yyGLRStack* yystackp]b4_user_formals[)
/* Now pop stack until we find a state that shifts the error token. */
yystackp->yyerrState = 3;
while (yystackp->yytops.yystates[0] != YY_NULL)
while (yystackp->yytops.yystates[0] != YY_NULLPTR)
{
yyGLRState *yys = yystackp->yytops.yystates[0];
yyj = yypact[yys->yylrState];
@@ -2211,14 +2192,14 @@ yyrecoverSyntaxError (yyGLRStack* yystackp]b4_user_formals[)
}
}]b4_locations_if([[
yystackp->yyerror_range[1].yystate.yyloc = yys->yyloc;]])[
if (yys->yypred != YY_NULL)
if (yys->yypred != YY_NULLPTR)
yydestroyGLRState ("Error: popping", yys]b4_user_args[);
yystackp->yytops.yystates[0] = yys->yypred;
yystackp->yynextFree -= 1;
yystackp->yyspaceLeft += 1;
}
if (yystackp->yytops.yystates[0] == YY_NULL)
yyFail (yystackp][]b4_lpure_args[, YY_NULL);
if (yystackp->yytops.yystates[0] == YY_NULLPTR)
yyFail (yystackp][]b4_lpure_args[, YY_NULLPTR);
}
#define YYCHK1(YYE) \
@@ -2461,7 +2442,7 @@ b4_dollar_popdef])[]dnl
{
yyGLRState *yys = yystates[yyk];
]b4_locations_if([[ yystack.yyerror_range[1].yystate.yyloc = yys->yyloc;]]
)[ if (yys->yypred != YY_NULL)
)[ if (yys->yypred != YY_NULLPTR)
yydestroyGLRState ("Cleanup: popping", yys]b4_user_args[);
yystates[yyk] = yys->yypred;
yystack.yynextFree -= 1;
@@ -2493,7 +2474,7 @@ yy_yypstack (yyGLRState* yys)
static void
yypstates (yyGLRState* yyst)
{
if (yyst == YY_NULL)
if (yyst == YY_NULLPTR)
YYFPRINTF (stderr, "<null>");
else
yy_yypstack (yyst);
@@ -2507,7 +2488,7 @@ yypstack (yyGLRStack* yystackp, size_t yyk)
}
#define YYINDEX(YYX) \
((YYX) == YY_NULL ? -1 : (yyGLRStackItem*) (YYX) - yystackp->yyitems)
((YYX) == YY_NULLPTR ? -1 : (yyGLRStackItem*) (YYX) - yystackp->yyitems)
static void
@@ -2521,6 +2502,8 @@ yypdumpstack (yyGLRStack* yystackp)
(unsigned long int) (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,
@@ -2532,6 +2515,8 @@ yypdumpstack (yyGLRStack* yystackp)
}
else
{
YYASSERT (!yyp->yystate.yyisState);
YYASSERT (!yyp->yyoption.yyisState);
YYFPRINTF (stderr, "Option. rule: %d, state: %ld, next: %ld",
yyp->yyoption.yyrule - 1,
(long int) YYINDEX (yyp->yyoption.yystate),
+1 -12
View File
@@ -43,12 +43,6 @@
# user must initialize the first positions (in particular the
# filename member).
b4_token_ctor_if([b4_variant_if([],
[b4_fatal_at(b4_percent_define_get_loc(api.token.constructor),
[cannot use '%s' without '%s'],
[%define api.token.constructor],
[%define api.value.type variant]))])])
# We require a pure interface.
m4_define([b4_pure_flag], [1])
@@ -193,12 +187,7 @@ m4_pushdef([b4_parse_param], m4_defn([b4_parse_param_orig]))dnl
std::ostream& yyoutput = debug_stream ();
std::ostream& yyo = yyoutput;
YYUSE (yyo);
switch (yytype)
{
]b4_symbol_foreach([b4_symbol_printer])dnl
[ default:
break;
}
]b4_symbol_actions([printer])[
}
+17 -1
View File
@@ -103,7 +103,7 @@ m4_define([b4_int_type],
# b4_int_type_for(NAME)
# ---------------------
# Return the smallest int type able to handle numbers ranging from
# `NAME_min' to `NAME_max' (included).
# 'NAME_min' to 'NAME_max' (included).
m4_define([b4_int_type_for],
[b4_int_type($1_min, $1_max)])
@@ -169,6 +169,22 @@ m4_define([b4_predicate_case], [ case $1:
])
## -------- ##
## Checks. ##
## -------- ##
b4_percent_define_check_kind([[api.value.type]], [code], [deprecated])
b4_percent_define_check_kind([[annotations]], [code], [deprecated])
b4_percent_define_check_kind([[extends]], [code], [deprecated])
b4_percent_define_check_kind([[implements]], [code], [deprecated])
b4_percent_define_check_kind([[init_throws]], [code], [deprecated])
b4_percent_define_check_kind([[lex_throws]], [code], [deprecated])
b4_percent_define_check_kind([[parser_class_name]], [code], [deprecated])
b4_percent_define_check_kind([[throws]], [code], [deprecated])
## ---------------- ##
## Default values. ##
## ---------------- ##
+75 -80
View File
@@ -17,6 +17,8 @@
m4_include(b4_pkgdatadir/[c++.m4])
# api.value.type=variant is valid.
m4_define([b4_value_type_setup_variant])
# b4_integral_parser_table_declare(TABLE-NAME, CONTENT, COMMENT)
# --------------------------------------------------------------
@@ -38,13 +40,14 @@ m4_define([b4_integral_parser_table_define],
};dnl
])
# b4_symbol_value_template(VAL, [TYPE])
# -------------------------------------
# Same as b4_symbol_value, but used in a template method. It makes
# a difference when using variants.
# a difference when using variants. Note that b4_value_type_setup_union
# overrides b4_symbol_value, so we must override it again.
m4_copy([b4_symbol_value], [b4_symbol_value_template])
m4_append([b4_value_type_setup_union],
[m4_copy_force([b4_symbol_value_union], [b4_symbol_value_template])])
# b4_lhs_value([TYPE])
# --------------------
@@ -154,6 +157,7 @@ m4_define([b4_shared_declarations],
]b4_bison_locations_if([[# include "location.hh"]])])[
]b4_variant_if([b4_variant_includes])[
]b4_attribute_define[
]b4_YYDEBUG_define[
]b4_namespace_open[
@@ -180,14 +184,14 @@ b4_location_define])])[
#if ]b4_api_PREFIX[DEBUG
/// The current debugging stream.
std::ostream& debug_stream () const;
std::ostream& debug_stream () const YY_ATTRIBUTE_PURE;
/// Set the current debugging stream.
void set_debug_stream (std::ostream &);
/// Type for debugging levels.
typedef int debug_level_type;
/// The current debugging level.
debug_level_type debug_level () const;
debug_level_type debug_level () const YY_ATTRIBUTE_PURE;
/// Set the current debugging level.
void set_debug_level (debug_level_type l);
#endif
@@ -201,6 +205,10 @@ b4_location_define])])[
void error (const syntax_error& err);
private:
/// This class is not copyable.
]b4_parser_class_name[ (const ]b4_parser_class_name[&);
]b4_parser_class_name[& operator= (const ]b4_parser_class_name[&);
/// State numbers.
typedef int state_type;
@@ -212,8 +220,8 @@ b4_location_define])])[
/// Compute post-reduction state.
/// \param yystate the current state
/// \param yylhs the nonterminal to push on the stack
state_type yy_lr_goto_state_ (state_type yystate, int yylhs);
/// \param yysym the nonterminal to push on the stack
state_type yy_lr_goto_state_ (state_type yystate, int yysym);
/// Whether the given \c yypact_ value indicates a defaulted state.
/// \param yyvalue the value to check
@@ -260,7 +268,7 @@ b4_location_define])])[
/// \brief Reclaim the memory associated to a symbol.
/// \param yymsg Why this token is reclaimed.
/// If null, print nothing.
/// \param s The symbol.
/// \param yysym The symbol.
template <typename Base>
void yy_destroy_ (const char* yymsg, basic_symbol<Base>& yysym) const;
@@ -334,13 +342,13 @@ b4_location_define])])[
enum
{
yyeof_ = 0,
yylast_ = ]b4_last[, //< Last index in yytable_.
yynnts_ = ]b4_nterms_number[, //< Number of nonterminal symbols.
yylast_ = ]b4_last[, ///< Last index in yytable_.
yynnts_ = ]b4_nterms_number[, ///< Number of nonterminal symbols.
yyempty_ = -2,
yyfinal_ = ]b4_final_state_number[, //< Termination state number.
yyfinal_ = ]b4_final_state_number[, ///< Termination state number.
yyterror_ = 1,
yyerrcode_ = 256,
yyntokens_ = ]b4_tokens_number[ //< Number of tokens.
yyntokens_ = ]b4_tokens_number[ ///< Number of tokens.
};
]b4_parse_param_vars[
@@ -591,13 +599,7 @@ m4_if(b4_prefix, [yy], [],
YY_SYMBOL_PRINT (yymsg, yysym);]b4_variant_if([], [
// User destructor.
symbol_number_type yytype = yysym.type_get ();
switch (yytype)
{
]b4_symbol_foreach([b4_symbol_destructor])dnl
[ default:
break;
}])[
b4_symbol_actions([destructor], [yysym.type_get ()])])[
}
#if ]b4_api_PREFIX[DEBUG
@@ -612,12 +614,7 @@ m4_if(b4_prefix, [yy], [],
yyo << (yytype < yyntokens_ ? "token" : "nterm")
<< ' ' << yytname_[yytype] << " ("]b4_locations_if([
<< yysym.location << ": "])[;
switch (yytype)
{
]b4_symbol_foreach([b4_symbol_printer])dnl
[ default:
break;
}
]b4_symbol_actions([printer])[
yyo << ')';
}
#endif
@@ -674,13 +671,13 @@ m4_if(b4_prefix, [yy], [],
#endif // ]b4_api_PREFIX[DEBUG
inline ]b4_parser_class_name[::state_type
]b4_parser_class_name[::yy_lr_goto_state_ (state_type yystate, int yylhs)
]b4_parser_class_name[::yy_lr_goto_state_ (state_type yystate, int yysym)
{
int yyr = yypgoto_[yylhs - yyntokens_] + yystate;
int yyr = yypgoto_[yysym - yyntokens_] + yystate;
if (0 <= yyr && yyr <= yylast_ && yycheck_[yyr] == yystate)
return yytable_[yyr];
else
return yydefgoto_[yylhs - yyntokens_];
return yydefgoto_[yysym - yyntokens_];
}
inline bool
@@ -703,6 +700,7 @@ m4_if(b4_prefix, [yy], [],
// State.
int yyn;
/// Length of the RHS of the rule being reduced.
int yylen = 0;
// Error handling.
@@ -715,9 +713,6 @@ m4_if(b4_prefix, [yy], [],
/// The locations where the error started and ended.
stack_symbol_type yyerror_range[3];]])[
/// $$ and @@$.
stack_symbol_type yylhs;
/// The return value of parse ().
int yyresult;
@@ -737,8 +732,8 @@ b4_dollar_popdef])[]dnl
yynewstate, since the latter expects the semantical and the
location values to have been already stored, initialize these
stacks with a primary value. */
yystack_ = stack_type (0);
yypush_ (YY_NULL, 0, yyla);
yystack_.clear ();
yypush_ (YY_NULLPTR, 0, yyla);
// A new symbol was pushed on the stack.
yynewstate:
@@ -818,52 +813,55 @@ b4_dollar_popdef])[]dnl
`-----------------------------*/
yyreduce:
yylen = yyr2_[yyn];
yylhs.state = yy_lr_goto_state_(yystack_[yylen].state, yyr1_[yyn]);]b4_variant_if([
/* Variants are always initialized to an empty instance of the
correct type. The default $$=$1 action is NOT applied when using
variants. */
b4_symbol_variant([[yyr1_@{yyn@}]], [yylhs.value], [build])],[
/* If YYLEN is nonzero, implement the default value of the action:
`$$ = $1'. Otherwise, use the top of the stack.
{
stack_symbol_type yylhs;
yylhs.state = yy_lr_goto_state_(yystack_[yylen].state, yyr1_[yyn]);]b4_variant_if([
/* Variants are always initialized to an empty instance of the
correct type. The default '$$ = $1' action is NOT applied
when using variants. */
b4_symbol_variant([[yyr1_@{yyn@}]], [yylhs.value], [build])], [
/* If YYLEN is nonzero, implement the default value of the
action: '$$ = $1'. Otherwise, use the top of the stack.
Otherwise, the following line sets YYLHS.VALUE to garbage.
This behavior is undocumented and Bison
users should not rely upon it. */
if (yylen)
yylhs.value = yystack_@{yylen - 1@}.value;
else
yylhs.value = yystack_@{0@}.value;])[
Otherwise, the following line sets YYLHS.VALUE to garbage.
This behavior is undocumented and Bison users should not rely
upon it. */
if (yylen)
yylhs.value = yystack_@{yylen - 1@}.value;
else
yylhs.value = yystack_@{0@}.value;])[
]b4_locations_if([dnl
[
// Compute the default @@$.
{
slice<stack_symbol_type, stack_type> slice (yystack_, yylen);
YYLLOC_DEFAULT (yylhs.location, slice, yylen);
}]])[
// Perform the reduction.
YY_REDUCE_PRINT (yyn);
try
// Compute the default @@$.
{
switch (yyn)
{
slice<stack_symbol_type, stack_type> slice (yystack_, yylen);
YYLLOC_DEFAULT (yylhs.location, slice, yylen);
}]])[
// Perform the reduction.
YY_REDUCE_PRINT (yyn);
try
{
switch (yyn)
{
]b4_user_actions[
default:
break;
}
}
catch (const syntax_error& yyexc)
{
error (yyexc);
YYERROR;
}
YY_SYMBOL_PRINT ("-> $$ =", yylhs);
yypop_ (yylen);
yylen = 0;
YY_STACK_PRINT ();
default:
break;
}
}
catch (const syntax_error& yyexc)
{
error (yyexc);
YYERROR;
}
YY_SYMBOL_PRINT ("-> $$ =", yylhs);
yypop_ (yylen);
yylen = 0;
YY_STACK_PRINT ();
// Shift the result of the reduction.
yypush_ (YY_NULL, yylhs);
// Shift the result of the reduction.
yypush_ (YY_NULLPTR, yylhs);
}
goto yynewstate;
/*--------------------------------------.
@@ -910,10 +908,7 @@ b4_dollar_popdef])[]dnl
code. */
if (false)
goto yyerrorlab;]b4_locations_if([[
yyerror_range[1].location = yystack_[yylen - 1].location;]])b4_variant_if([[
/* $$ was initialized before running the user action. */
YY_SYMBOL_PRINT ("Error: discarding", yylhs);
yylhs.~stack_symbol_type();]])[
yyerror_range[1].location = yystack_[yylen - 1].location;]])[
/* Do not reclaim the symbols of the rule whose action triggered
this YYERROR. */
yypop_ (yylen);
@@ -992,11 +987,11 @@ b4_dollar_popdef])[]dnl
// Do not try to display the values of the reclaimed symbols,
// as their printer might throw an exception.
if (!yyempty)
yy_destroy_ (YY_NULL, yyla);
yy_destroy_ (YY_NULLPTR, yyla);
while (1 < yystack_.size ())
{
yy_destroy_ (YY_NULL, yystack_[0]);
yy_destroy_ (YY_NULLPTR, yystack_[0]);
yypop_ ();
}
throw;
@@ -1078,7 +1073,7 @@ b4_error_verbose_if([state_type yystate, symbol_number_type yytoken],
}
}
char const* yyformat = YY_NULL;
char const* yyformat = YY_NULLPTR;
switch (yycount)
{
#define YYCASE_(N, S) \
+274 -79
View File
@@ -20,7 +20,8 @@ m4_include(b4_pkgdatadir/[java.m4])
b4_defines_if([b4_fatal([%s: %%defines does not make sense in Java],
[b4_skeleton])])
# We don't depend on %debug in Java, but pacify warnings about non-used flags.
# We do not depend on %debug in Java, but pacify warnings about
# non-used flags.
b4_parse_trace_if([0], [0])
m4_define([b4_symbol_no_destructor_assert],
@@ -30,6 +31,57 @@ m4_define([b4_symbol_no_destructor_assert],
[b4_symbol_action_location([$1], [destructor])])])])
b4_symbol_foreach([b4_symbol_no_destructor_assert])
# Setup some macros for api.push-pull.
b4_percent_define_default([[api.push-pull]], [[pull]])
b4_percent_define_check_values([[[[api.push-pull]],
[[pull]], [[push]], [[both]]]])
# Define m4 conditional macros that encode the value
# of the api.push-pull flag.
b4_define_flag_if([pull]) m4_define([b4_pull_flag], [[1]])
b4_define_flag_if([push]) m4_define([b4_push_flag], [[1]])
m4_case(b4_percent_define_get([[api.push-pull]]),
[pull], [m4_define([b4_push_flag], [[0]])],
[push], [m4_define([b4_pull_flag], [[0]])])
# Define a macro to be true when api.push-pull has the value "both".
m4_define([b4_both_if],[b4_push_if([b4_pull_if([$1],[$2])],[$2])])
# Handle BISON_USE_PUSH_FOR_PULL for the test suite. So that push parsing
# tests function as written, do not let BISON_USE_PUSH_FOR_PULL modify the
# behavior of Bison at all when push parsing is already requested.
b4_define_flag_if([use_push_for_pull])
b4_use_push_for_pull_if([
b4_push_if([m4_define([b4_use_push_for_pull_flag], [[0]])],
[m4_define([b4_push_flag], [[1]])])])
# Define a macro to encapsulate the parse state variables.
# This allows them to be defined either in parse() when doing
# pull parsing, or as class instance variable when doing push parsing.
m4_define([b4_define_state],[[
/* Lookahead and lookahead in internal form. */
int yychar = yyempty_;
int yytoken = 0;
/* State. */
int yyn = 0;
int yylen = 0;
int yystate = 0;
YYStack yystack = new YYStack ();
int label = YYNEWSTATE;
/* Error handling. */
int yynerrs_ = 0;
]b4_locations_if([/* The location where the error started. */
b4_location_type yyerrloc = null;
/* Location. */
b4_location_type yylloc = new b4_location_type (null, null);])[
/* Semantic value of the lookahead. */
]b4_yystype[ yylval = null;
]])
b4_output_begin([b4_parser_file_name])
b4_copyright([Skeleton implementation for Bison LALR(1) parsers in Java],
[2007-2013])
@@ -55,7 +107,9 @@ b4_percent_define_get3([implements], [ implements ])[
{
]b4_identification[
]b4_error_verbose_if([[
/** True if verbose error messages are enabled. */
/**
* True if verbose error messages are enabled.
*/
private boolean yyErrorVerbose = true;
/**
@@ -76,18 +130,24 @@ b4_locations_if([[
* A class defining a pair of positions. Positions, defined by the
* <code>]b4_position_type[</code> class, denote a point in the input.
* Locations represent a part of the input through the beginning
* and ending positions. */
* and ending positions.
*/
public class ]b4_location_type[ {
/** The first, inclusive, position in the range. */
/**
* The first, inclusive, position in the range.
*/
public ]b4_position_type[ begin;
/** The first position beyond the range. */
/**
* The first position beyond the range.
*/
public ]b4_position_type[ end;
/**
* Create a <code>]b4_location_type[</code> denoting an empty range located at
* a given point.
* @@param loc The position at which the range is anchored. */
* @@param loc The position at which the range is anchored.
*/
public ]b4_location_type[ (]b4_position_type[ loc) {
this.begin = this.end = loc;
}
@@ -95,7 +155,8 @@ b4_locations_if([[
/**
* Create a <code>]b4_location_type[</code> from the endpoints of the range.
* @@param begin The first position included in the range.
* @@param end The first position beyond the range. */
* @@param end The first position beyond the range.
*/
public ]b4_location_type[ (]b4_position_type[ begin, ]b4_position_type[ end) {
this.begin = begin;
this.end = end;
@@ -104,7 +165,8 @@ b4_locations_if([[
/**
* Print a representation of the location. For this to be correct,
* <code>]b4_position_type[</code> should override the <code>equals</code>
* method. */
* method.
*/
public String toString () {
if (begin.equals (end))
return begin.toString ();
@@ -136,24 +198,28 @@ b4_locations_if([[
]b4_locations_if([[/**
* Method to retrieve the beginning position of the last scanned token.
* @@return the position at which the last scanned token starts. */
* @@return the position at which the last scanned token starts.
*/
]b4_position_type[ getStartPos ();
/**
* Method to retrieve the ending position of the last scanned token.
* @@return the first position beyond the last scanned token. */
* @@return the first position beyond the last scanned token.
*/
]b4_position_type[ getEndPos ();]])[
/**
* Method to retrieve the semantic value of the last scanned token.
* @@return the semantic value of the last scanned token. */
* @@return the semantic value of the last scanned token.
*/
]b4_yystype[ getLVal ();
/**
* Entry point for the scanner. Returns the token identifier corresponding
* to the next token and prepares to return the semantic value
* ]b4_locations_if([and beginning/ending positions ])[of the token.
* @@return the token identifier corresponding to the next token. */
* @@return the token identifier corresponding to the next token.
*/
int yylex () ]b4_maybe_throws([b4_lex_throws])[;
/**
@@ -162,7 +228,8 @@ b4_locations_if([[
*
* ]b4_locations_if([[@@param loc The location of the element to which the
* error message is related]])[
* @@param msg The string for the error message. */
* @@param msg The string for the error message.
*/
void yyerror (]b4_locations_if([b4_location_type[ loc, ]])[String msg);]
}
@@ -170,7 +237,9 @@ b4_locations_if([[
]b4_percent_code_get([[lexer]])[
}
]])[/** The object doing lexical analysis for us. */
]])[/**
* The object doing lexical analysis for us.
*/
private Lexer yylexer;
]
b4_parse_param_vars
@@ -336,46 +405,74 @@ b4_lexer_if([[
/**
* Returned by a Bison action in order to stop the parsing process and
* return success (<tt>true</tt>). */
* return success (<tt>true</tt>).
*/
public static final int YYACCEPT = 0;
/**
* Returned by a Bison action in order to stop the parsing process and
* return failure (<tt>false</tt>). */
* return failure (<tt>false</tt>).
*/
public static final int YYABORT = 1;
]b4_push_if([
/**
* Returned by a Bison action in order to request a new token.
*/
public static final int YYPUSH_MORE = 4;])[
/**
* Returned by a Bison action in order to start error recovery without
* printing an error message. */
* printing an error message.
*/
public static final int YYERROR = 2;
// Internal return codes that are not supported for user semantic
// actions.
/**
* Internal return codes that are not supported for user semantic
* actions.
*/
private static final int YYERRLAB = 3;
private static final int YYNEWSTATE = 4;
private static final int YYDEFAULT = 5;
private static final int YYREDUCE = 6;
private static final int YYERRLAB1 = 7;
private static final int YYRETURN = 8;
]b4_push_if([[ private static final int YYGETTOKEN = 9; /* Signify that a new token is expected when doing push-parsing. */]])[
private int yyerrstatus_ = 0;
]b4_push_if([dnl
b4_define_state])[
/**
* Return whether error recovery is being done. In this state, the parser
* reads token until it reaches a known state, and then restarts normal
* operation. */
* operation.
*/
public final boolean recovering ()
{
return yyerrstatus_ == 0;
}
/** Compute post-reduction state.
* @@param yystate the current state
* @@param yysym the nonterminal to push on the stack
*/
private int yy_lr_goto_state_ (int yystate, int yysym)
{
int yyr = yypgoto_[yysym - yyntokens_] + yystate;
if (0 <= yyr && yyr <= yylast_ && yycheck_[yyr] == yystate)
return yytable_[yyr];
else
return yydefgoto_[yysym - yyntokens_];
}
private int yyaction (int yyn, YYStack yystack, int yylen) ]b4_maybe_throws([b4_throws])[
{
]b4_yystype[ yyval;
]b4_locations_if([b4_location_type[ yyloc = yylloc (yystack, yylen);]])[
/* If YYLEN is nonzero, implement the default value of the action:
`$$ = $1'. Otherwise, use the top of the stack.
'$$ = $1'. Otherwise, use the top of the stack.
Otherwise, the following line sets YYVAL to garbage.
This behavior is undocumented and Bison
@@ -399,14 +496,7 @@ b4_lexer_if([[
yylen = 0;
/* Shift the result of the reduction. */
yyn = yyr1_[yyn];
int yystate = yypgoto_[yyn - yyntokens_] + yystack.stateAt (0);
if (0 <= yystate && yystate <= yylast_
&& yycheck_[yystate] == yystack.stateAt (0))
yystate = yytable_[yystate];
else
yystate = yydefgoto_[yyn - yyntokens_];
int yystate = yy_lr_goto_state_ (yystack.stateAt (0), yyr1_[yyn]);
yystack.push (yystate, yyval]b4_locations_if([, yyloc])[);
return YYNEWSTATE;
}
@@ -463,6 +553,7 @@ b4_lexer_if([[
+ (yyvaluep == null ? "(null)" : yyvaluep.toString ()) + ")");
}
]b4_push_if([],[[
/**
* Parse input from the scanner that was specified at object construction
* time. Return whether the end of the input was reached successfully.
@@ -470,46 +561,53 @@ b4_lexer_if([[
* @@return <tt>true</tt> if the parsing succeeds. Note that this does not
* imply that there were no syntax errors.
*/
public boolean parse () ]b4_maybe_throws([b4_list2([b4_lex_throws], [b4_throws])])[
public boolean parse () ]b4_maybe_throws([b4_list2([b4_lex_throws], [b4_throws])])[]])[
]b4_push_if([
/**
* Push Parse input from external lexer
*
* @@param yylextoken current token
* @@param yylexval current lval
]b4_locations_if([ * @@param yylexloc current position])[
*
* @@return <tt>YYACCEPT, YYABORT, YYPUSH_MORE</tt>
*/
public int push_parse (int yylextoken, b4_yystype yylexval[]b4_locations_if([, b4_location_type yylexloc]))
b4_maybe_throws([b4_list2([b4_lex_throws], [b4_throws])])])[
{
/// Lookahead and lookahead in internal form.
int yychar = yyempty_;
int yytoken = 0;
/* State. */
int yyn = 0;
int yylen = 0;
int yystate = 0;
YYStack yystack = new YYStack ();
/* Error handling. */
int yynerrs_ = 0;
]b4_locations_if([/// The location where the error started.
]b4_location_type[ yyerrloc = null;
/// ]b4_location_type[ of the lookahead.
]b4_location_type[ yylloc = new ]b4_location_type[ (null, null);
/// @@$.
]b4_location_type[ yyloc;])
/// Semantic value of the lookahead.
b4_yystype[ yylval = null;
]b4_locations_if([/* @@$. */
b4_location_type yyloc;])[
]b4_push_if([],[[
]b4_define_state[
yycdebug ("Starting parse\n");
yyerrstatus_ = 0;
/* Initialize the stack. */
yystack.push (yystate, yylval ]b4_locations_if([, yylloc])[);
]m4_ifdef([b4_initial_action], [
b4_dollar_pushdef([yylval], [], [yylloc])dnl
/* User initialization code. */
b4_user_initial_action
b4_dollar_popdef])[]dnl
b4_dollar_popdef[]dnl
])[
]])[
]b4_push_if([[
if (!this.push_parse_initialized)
{
push_parse_initialize ();
]m4_ifdef([b4_initial_action], [
b4_dollar_pushdef([yylval], [], [yylloc])dnl
/* User initialization code. */
b4_user_initial_action
b4_dollar_popdef[]dnl
])[
yycdebug ("Starting parse\n");
yyerrstatus_ = 0;
} else
label = YYGETTOKEN;
[ /* Initialize the stack. */
yystack.push (yystate, yylval]b4_locations_if([, yylloc])[);
int label = YYNEWSTATE;
boolean push_token_consumed = true;
]])[
for (;;)
switch (label)
{
@@ -522,7 +620,8 @@ b4_dollar_popdef])[]dnl
/* Accept? */
if (yystate == yyfinal_)
return true;
]b4_push_if([{label = YYACCEPT; break;}],
[return true;])[
/* Take a decision. First try without lookahead. */
yyn = yypact_[yystate];
@@ -531,16 +630,27 @@ b4_dollar_popdef])[]dnl
label = YYDEFAULT;
break;
}
]b4_push_if([ /* Fall Through */
case YYGETTOKEN:])[
/* Read a lookahead token. */
if (yychar == yyempty_)
{
]b4_push_if([[
if (!push_token_consumed)
return YYPUSH_MORE;
yycdebug ("Reading a token: ");
yychar = yylexer.yylex ();]
b4_locations_if([[
yylloc = new ]b4_location_type[(yylexer.getStartPos (),
yylexer.getEndPos ());]])
yylval = yylexer.getLVal ();[
yychar = yylextoken;
yylval = yylexval;]b4_locations_if([
yylloc = yylexloc;])[
push_token_consumed = false;]])[
]b4_push_if([],[[
yycdebug ("Reading a token: ");
yychar = yylexer.yylex ();
yylval = yylexer.getLVal ();]b4_locations_if([
yylloc = new b4_location_type (yylexer.getStartPos (),
yylexer.getEndPos ());])[
]])[
}
/* Convert token to internal form. */
@@ -637,10 +747,10 @@ b4_dollar_popdef])[]dnl
{
/* Return failure if at end of input. */
if (yychar == Lexer.EOF)
return false;
]b4_push_if([{label = YYABORT; break;}],[return false;])[
}
else
yychar = yyempty_;
yychar = yyempty_;
}
/* Else will try to reuse lookahead token after shifting the error
@@ -648,9 +758,9 @@ b4_dollar_popdef])[]dnl
label = YYERRLAB1;
break;
/*---------------------------------------------------.
/*-------------------------------------------------.
| errorlab -- error raised explicitly by YYERROR. |
`---------------------------------------------------*/
`-------------------------------------------------*/
case YYERROR:
]b4_locations_if([yyerrloc = yystack.locationAt (yylen - 1);])[
@@ -682,9 +792,10 @@ b4_dollar_popdef])[]dnl
}
}
/* Pop the current state because it cannot handle the error token. */
/* Pop the current state because it cannot handle the
* error token. */
if (yystack.height == 0)
return false;
]b4_push_if([{label = YYABORT; break;}],[return false;])[
]b4_locations_if([yyerrloc = yystack.locationAt (0);])[
yystack.pop ();
@@ -693,7 +804,11 @@ b4_dollar_popdef])[]dnl
yystack.print (yyDebugStream);
}
]b4_locations_if([
if (label == YYABORT)
/* Leave the switch. */
break;
]b4_locations_if([
/* Muck with the stack to setup for yylloc. */
yystack.push (0, null, yylloc);
yystack.push (0, null, yyerrloc);
@@ -711,13 +826,91 @@ b4_dollar_popdef])[]dnl
/* Accept. */
case YYACCEPT:
return true;
]b4_push_if([this.push_parse_initialized = false; return YYACCEPT;],
[return true;])[
/* Abort. */
case YYABORT:
return false;
]b4_push_if([this.push_parse_initialized = false; return YYABORT;],
[return false;])[
}
}
]b4_push_if([[
boolean push_parse_initialized = false;
/**
* (Re-)Initialize the state of the push parser.
*/
public void push_parse_initialize()
{
/* Lookahead and lookahead in internal form. */
this.yychar = yyempty_;
this.yytoken = 0;
/* State. */
this.yyn = 0;
this.yylen = 0;
this.yystate = 0;
this.yystack = new YYStack ();
this.label = YYNEWSTATE;
/* Error handling. */
this.yynerrs_ = 0;
]b4_locations_if([/* The location where the error started. */
this.yyerrloc = null;
this.yylloc = new b4_location_type (null, null);])[
/* Semantic value of the lookahead. */
this.yylval = null;
yystack.push (this.yystate, this.yylval]b4_locations_if([, this.yylloc])[);
this.push_parse_initialized = true;
}
]b4_locations_if([
/**
* Push parse given input from an external lexer.
*
* @@param yylextoken current token
* @@param yylexval current lval
* @@param yyylexpos current position
*
* @@return <tt>YYACCEPT, YYABORT, YYPUSH_MORE</tt>
*/
public int push_parse (int yylextoken, b4_yystype yylexval, b4_position_type yylexpos)
b4_maybe_throws([b4_list2([b4_lex_throws], [b4_throws])])
{
return push_parse (yylextoken, yylexval, new b4_location_type (yylexpos));
}
])[]])
b4_both_if([[
/**
* Parse input from the scanner that was specified at object construction
* time. Return whether the end of the input was reached successfully.
* This version of parse () is defined only when api.push-push=both.
*
* @@return <tt>true</tt> if the parsing succeeds. Note that this does not
* imply that there were no syntax errors.
*/
public boolean parse () ]b4_maybe_throws([b4_list2([b4_lex_throws], [b4_throws])])[
{
if (yylexer == null)
throw new NullPointerException("Null Lexer");
int status;
do {
int token = yylexer.yylex();
]b4_yystype[ lval = yylexer.getLVal();
]b4_locations_if([dnl
b4_location_type yyloc = new b4_location_type (yylexer.getStartPos (),
yylexer.getEndPos ());])[
]b4_locations_if([status = push_parse(token,lval,yyloc);],[
status = push_parse(token,lval);])[
} while (status == YYPUSH_MORE);
return (status == YYACCEPT);
}
]])[
// Generate an error message.
private String yysyntax_error (int yystate, int tok)
@@ -752,8 +945,8 @@ b4_dollar_popdef])[]dnl
*/
if (tok != yyempty_)
{
// FIXME: This method of building the message is not compatible
// with internationalization.
/* FIXME: This method of building the message is not compatible
with internationalization. */
StringBuffer res =
new StringBuffer ("syntax error, unexpected ");
res.append (yytnamerr_ (yytname_[tok]));
@@ -802,8 +995,9 @@ b4_dollar_popdef])[]dnl
}
/**
* Whether the given <code>yytable_</code> value indicates a syntax error.
* @@param yyvalue the value to check
* Whether the given <code>yytable_</code>
* value indicates a syntax error.
* @@param yyvalue the value to check
*/
private static boolean yy_table_value_is_error_ (int yyvalue)
{
@@ -825,6 +1019,7 @@ b4_dollar_popdef])[]dnl
]b4_integral_parser_table_define([rline], [b4_rline],
[[YYRLINE[YYN] -- Source line where rule number YYN was defined.]])[
// Report on the debug stream that the rule yyrule is going to be reduced.
private void yy_reduce_print (int yyrule, YYStack yystack)
{
+46 -27
View File
@@ -25,10 +25,9 @@ m4_define([b4_position_define],
[[ /// Abstract a position.
class position
{
public:
]m4_ifdef([b4_location_constructors], [[
public:]m4_ifdef([b4_location_constructors], [[
/// Construct a position.
explicit position (]b4_percent_define_get([[filename_type]])[* f = YY_NULL,
explicit position (]b4_percent_define_get([[filename_type]])[* f = YY_NULLPTR,
unsigned int l = ]b4_location_initial_line[u,
unsigned int c = ]b4_location_initial_column[u)
: filename (f)
@@ -39,7 +38,7 @@ m4_define([b4_position_define],
]])[
/// Initialization.
void initialize (]b4_percent_define_get([[filename_type]])[* fn = YY_NULL,
void initialize (]b4_percent_define_get([[filename_type]])[* fn = YY_NULLPTR,
unsigned int l = ]b4_location_initial_line[u,
unsigned int c = ]b4_location_initial_column[u)
{
@@ -53,14 +52,17 @@ m4_define([b4_position_define],
/// (line related) Advance to the COUNT next lines.
void lines (int count = 1)
{
column = ]b4_location_initial_column[u;
line += count;
if (count)
{
column = ]b4_location_initial_column[u;
line = add_ (line, count, ]b4_location_initial_line[);
}
}
/// (column related) Advance to the COUNT next columns.
void columns (int count = 1)
{
column = std::max (]b4_location_initial_column[u, column + count);
column = add_ (column, count, ]b4_location_initial_column[);
}
/** \} */
@@ -70,36 +72,44 @@ m4_define([b4_position_define],
unsigned int line;
/// Current column number.
unsigned int column;
private:
/// Compute max(min, lhs+rhs) (provided min <= lhs).
static unsigned int add_ (unsigned int lhs, int rhs, unsigned int min)
{
return (0 < rhs || -static_cast<unsigned int>(rhs) < lhs
? rhs + lhs
: min);
}
};
/// Add and assign a position.
inline position&
operator+= (position& res, const int width)
operator+= (position& res, int width)
{
res.columns (width);
return res;
}
/// Add two position objects.
inline const position
operator+ (const position& begin, const int width)
inline position
operator+ (position res, int width)
{
position res = begin;
return res += width;
}
/// Add and assign a position.
inline position&
operator-= (position& res, const int width)
operator-= (position& res, int width)
{
return res += -width;
}
/// Add two position objects.
inline const position
operator- (const position& begin, const int width)
inline position
operator- (position res, int width)
{
return begin + -width;
return res -= width;
}
]b4_percent_define_flag_if([[define_location_comparison]], [[
/// Compare two position objects.
@@ -168,7 +178,7 @@ m4_define([b4_location_define],
])[
/// Initialization.
void initialize (]b4_percent_define_get([[filename_type]])[* f = YY_NULL,
void initialize (]b4_percent_define_get([[filename_type]])[* f = YY_NULLPTR,
unsigned int l = ]b4_location_initial_line[u,
unsigned int c = ]b4_location_initial_column[u)
{
@@ -186,13 +196,13 @@ m4_define([b4_location_define],
}
/// Extend the current location to the COUNT next columns.
void columns (unsigned int count = 1)
void columns (int count = 1)
{
end += count;
}
/// Extend the current location to the COUNT next lines.
void lines (unsigned int count = 1)
void lines (int count = 1)
{
end.lines (count);
}
@@ -207,26 +217,35 @@ m4_define([b4_location_define],
};
/// Join two location objects to create a location.
inline const location operator+ (const location& begin, const location& end)
inline location operator+ (location res, const location& end)
{
location res = begin;
res.end = end.end;
return res;
}
/// Add two location objects.
inline const location operator+ (const location& begin, unsigned int width)
/// Change end position in place.
inline location& operator+= (location& res, int width)
{
location res = begin;
res.columns (width);
return res;
}
/// Add and assign a location.
inline location& operator+= (location& res, unsigned int width)
/// Change end position.
inline location operator+ (location res, int width)
{
res.columns (width);
return res;
return res += width;
}
/// Change end position in place.
inline location& operator-= (location& res, int width)
{
return res += -width;
}
/// Change end position.
inline location operator- (const location& begin, int width)
{
return begin + -width;
}
]b4_percent_define_flag_if([[define_location_comparison]], [[
/// Compare two location objects.
+8
View File
@@ -72,6 +72,12 @@ m4_define([b4_stack_define],
seq_.pop_back ();
}
void
clear ()
{
seq_.clear ();
}
inline
typename S::size_type
size () const
@@ -94,6 +100,8 @@ m4_define([b4_stack_define],
}
private:
stack (const stack&);
stack& operator= (const stack&);
/// The wrapped container.
S seq_;
};
+56 -41
View File
@@ -26,7 +26,7 @@
# YYTYPE.
m4_define([b4_symbol_variant],
[m4_pushdef([b4_dollar_dollar],
[$2.$3< $][3 >(m4_shift3($@))])dnl
[$2.$3< $][3 > (m4_shift3($@))])dnl
switch ($1)
{
b4_type_foreach([b4_type_action_])[]dnl
@@ -63,7 +63,7 @@ m4_define([b4_char_sizeof],
[b4_symbol_if([$1], [has_type],
[
m4_map([ b4_symbol_tag_comment], [$@])dnl
char _b4_char_sizeof_dummy@{sizeof([b4_symbol([$1], [type])])@};
char _b4_char_sizeof_dummy@{sizeof(b4_symbol([$1], [type]))@};
])])
@@ -95,22 +95,22 @@ m4_define([b4_variant_define],
/// Empty construction.
variant ()]b4_parse_assert_if([
: tname (YY_NULL)])[
: yytname_ (YY_NULLPTR)])[
{}
/// Construct and fill.
template <typename T>
variant (const T& t)]b4_parse_assert_if([
: tname (typeid (T).name ())])[
: yytname_ (typeid (T).name ())])[
{
YYASSERT (sizeof (T) <= S);
new (buffer.raw) T (t);
new (yyas_<T> ()) T (t);
}
/// Destruction, allowed only if empty.
~variant ()
{]b4_parse_assert_if([
YYASSERT (!tname);
YYASSERT (!yytname_);
])[}
/// Instantiate an empty \a T in here.
@@ -118,10 +118,10 @@ m4_define([b4_variant_define],
T&
build ()
{]b4_parse_assert_if([
YYASSERT (!tname);
YYASSERT (!yytname_);
YYASSERT (sizeof (T) <= S);
tname = typeid (T).name ();])[
return *new (buffer.raw) T;
yytname_ = typeid (T).name ();])[
return *new (yyas_<T> ()) T;
}
/// Instantiate a \a T in here from \a t.
@@ -129,10 +129,10 @@ m4_define([b4_variant_define],
T&
build (const T& t)
{]b4_parse_assert_if([
YYASSERT (!tname);
YYASSERT (!yytname_);
YYASSERT (sizeof (T) <= S);
tname = typeid (T).name ();])[
return *new (buffer.raw) T (t);
yytname_ = typeid (T).name ();])[
return *new (yyas_<T> ()) T (t);
}
/// Accessor to a built \a T.
@@ -140,9 +140,9 @@ m4_define([b4_variant_define],
T&
as ()
{]b4_parse_assert_if([
YYASSERT (tname == typeid (T).name ());
YYASSERT (yytname_ == typeid (T).name ());
YYASSERT (sizeof (T) <= S);])[
return reinterpret_cast<T&> (buffer.raw);
return *yyas_<T> ();
}
/// Const accessor to a built \a T (for %printer).
@@ -150,9 +150,9 @@ m4_define([b4_variant_define],
const T&
as () const
{]b4_parse_assert_if([
YYASSERT (tname == typeid (T).name ());
YYASSERT (yytname_ == typeid (T).name ());
YYASSERT (sizeof (T) <= S);])[
return reinterpret_cast<const T&> (buffer.raw);
return *yyas_<T> ();
}
/// Swap the content with \a other, of same type.
@@ -167,9 +167,9 @@ m4_define([b4_variant_define],
void
swap (self_type& other)
{]b4_parse_assert_if([
YYASSERT (tname);
YYASSERT (tname == other.tname);])[
std::swap (as<T>(), other.as<T>());
YYASSERT (yytname_);
YYASSERT (yytname_ == other.yytname_);])[
std::swap (as<T> (), other.as<T> ());
}
/// Move the content of \a other to this.
@@ -178,11 +178,10 @@ m4_define([b4_variant_define],
template <typename T>
void
move (self_type& other)
{]b4_parse_assert_if([
YYASSERT (!tname);])[
build<T>();
swap<T>(other);
other.destroy<T>();
{
build<T> ();
swap<T> (other);
other.destroy<T> ();
}
/// Copy the content of \a other to this.
@@ -199,7 +198,7 @@ m4_define([b4_variant_define],
destroy ()
{
as<T> ().~T ();]b4_parse_assert_if([
tname = YY_NULL;])[
yytname_ = YY_NULLPTR;])[
}
private:
@@ -207,17 +206,34 @@ m4_define([b4_variant_define],
self_type& operator=(const self_type&);
variant (const self_type&);
/// A buffer large enough to store any of the semantic values.
/// Long double is chosen as it has the strongest alignment
/// constraints.
/// Accessor to raw memory as \a T.
template <typename T>
T*
yyas_ ()
{
void *yyp = yybuffer_.yyraw;
return static_cast<T*> (yyp);
}
/// Const accessor to raw memory as \a T.
template <typename T>
const T*
yyas_ () const
{
const void *yyp = yybuffer_.yyraw;
return static_cast<const T*> (yyp);
}
union
{
long double align_me;
char raw[S];
} buffer;]b4_parse_assert_if([
/// Strongest alignment constraints.
long double yyalign_me;
/// A buffer large enough to store any of the semantic values.
char yyraw[S];
} yybuffer_;]b4_parse_assert_if([
/// Whether the content is built: if defined, the name of the stored type.
const char* tname;])[
const char *yytname_;])[
};
]])
@@ -227,16 +243,16 @@ m4_define([b4_variant_define],
## -------------------------- ##
# b4_semantic_type_declare
# ------------------------
# b4_value_type_declare
# ---------------------
# Declare semantic_type.
m4_define([b4_semantic_type_declare],
[ /// An auxiliary type to compute the largest semantic type.
m4_define([b4_value_type_declare],
[[ /// An auxiliary type to compute the largest semantic type.
union union_type
{]b4_type_foreach([b4_char_sizeof])[};
/// Symbol semantic values.
typedef variant<sizeof(union_type)> semantic_type;dnl
typedef variant<sizeof(union_type)> semantic_type;][]dnl
])
@@ -246,7 +262,7 @@ m4_define([b4_semantic_type_declare],
# ----------------------------
m4_define([b4_symbol_value],
[m4_ifval([$2],
[$1.as< $2 >()],
[$1.as< $2 > ()],
[$1])])
# b4_symbol_value_template(VAL, [TYPE])
@@ -254,7 +270,7 @@ m4_define([b4_symbol_value],
# Same as b4_symbol_value, but used in a template method.
m4_define([b4_symbol_value_template],
[m4_ifval([$2],
[$1.template as< $2 >()],
[$1.template as< $2 > ()],
[$1])])
@@ -304,14 +320,13 @@ b4_join(b4_symbol_if([$1], [has_type],
return symbol_type (b4_join([token::b4_symbol([$1], [id])],
b4_symbol_if([$1], [has_type], [v]),
b4_locations_if([l])));
}
])])])
# b4_basic_symbol_constructor_declare
# ----------------------------------
# -----------------------------------
# Generate a constructor declaration for basic_symbol from given type.
m4_define([b4_basic_symbol_constructor_declare],
[[
+5 -1
View File
@@ -201,6 +201,8 @@
<xsl:if test="$point = 0">
<xsl:text> .</xsl:text>
</xsl:if>
<!-- RHS -->
<xsl:for-each select="rhs/symbol|rhs/empty">
<xsl:apply-templates select="."/>
<xsl:if test="$point = position()">
@@ -214,7 +216,9 @@
<xsl:value-of select="."/>
</xsl:template>
<xsl:template match="empty"/>
<xsl:template match="empty">
<xsl:text> %empty</xsl:text>
</xsl:template>
<xsl:template match="lookaheads">
<xsl:text> [</xsl:text>
+2 -7
View File
@@ -350,12 +350,7 @@
<xsl:if test="position() = $point + 1">
<xsl:text> .</xsl:text>
</xsl:if>
<xsl:if test="$itemset = 'true' and name(.) != 'empty'">
<xsl:apply-templates select="."/>
</xsl:if>
<xsl:if test="$itemset != 'true'">
<xsl:apply-templates select="."/>
</xsl:if>
<xsl:apply-templates select="."/>
<xsl:if test="position() = last() and position() = $point">
<xsl:text> .</xsl:text>
</xsl:if>
@@ -373,7 +368,7 @@
</xsl:template>
<xsl:template match="empty">
<xsl:text> /* empty */</xsl:text>
<xsl:text> %empty</xsl:text>
</xsl:template>
<xsl:template match="lookaheads">
+2 -7
View File
@@ -532,12 +532,7 @@
<xsl:text> </xsl:text>
<span class="point">.</span>
</xsl:if>
<xsl:if test="$itemset = 'true' and name(.) != 'empty'">
<xsl:apply-templates select="."/>
</xsl:if>
<xsl:if test="$itemset != 'true'">
<xsl:apply-templates select="."/>
</xsl:if>
<xsl:apply-templates select="."/>
<xsl:if test="position() = last() and position() = $point">
<xsl:text> </xsl:text>
<span class="point">.</span>
@@ -563,7 +558,7 @@
</xsl:template>
<xsl:template match="empty">
<xsl:text> &#949;</xsl:text>
<xsl:text> %empty</xsl:text>
</xsl:template>
<xsl:template match="lookaheads">
+22 -45
View File
@@ -143,7 +143,6 @@ m4_define([b4_rhs_value],
[b4_symbol_value([yyvsp@{b4_subtract([$2], [$1])@}], [$3])])
## ----------- ##
## Locations. ##
## ----------- ##
@@ -176,36 +175,19 @@ m4_define([b4_declare_scanner_communication_variables], [[
int yychar;
]b4_pure_if([[
#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__
/* Suppress an incorrect diagnostic about yylval being uninitialized. */
# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
_Pragma ("GCC diagnostic push") \
_Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\
_Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"")
# define YY_IGNORE_MAYBE_UNINITIALIZED_END \
_Pragma ("GCC diagnostic pop")
#else
/* The semantic value of the lookahead symbol. */
/* Default value used for initialization, for pacifying older GCCs
or non-GCC compilers. */
static YYSTYPE yyval_default;
# define YY_INITIAL_VALUE(Value) = Value
#endif]b4_locations_if([[
static YYLTYPE yyloc_default][]b4_yyloc_default[;]])])[
#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
# define YY_IGNORE_MAYBE_UNINITIALIZED_END
#endif
#ifndef YY_INITIAL_VALUE
# define YY_INITIAL_VALUE(Value) /* Nothing. */
#endif
/* The semantic value of the lookahead symbol. */
YYSTYPE yylval YY_INITIAL_VALUE(yyval_default);]b4_locations_if([[
YY_INITIAL_VALUE (static YYSTYPE yyval_default;)
YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);]b4_locations_if([[
/* Location data for the lookahead symbol. */
YYLTYPE yylloc]b4_pure_if([ = yyloc_default], [b4_yyloc_default])[;
]])b4_pure_if([], [[
static YYLTYPE yyloc_default]b4_yyloc_default[;
YYLTYPE yylloc = yyloc_default;]])],
[[/* The semantic value of the lookahead symbol. */
YYSTYPE yylval;]b4_locations_if([[
/* Location data for the lookahead symbol. */
YYLTYPE yylloc]b4_yyloc_default[;]])[
/* Number of syntax errors so far. */
int yynerrs;]])])
@@ -223,9 +205,9 @@ m4_define([b4_declare_parser_state_variables], [b4_pure_if([[
int yyerrstatus;
/* The stacks and their tools:
`yyss': related to states.
`yyvs': related to semantic values.]b4_locations_if([[
`yyls': related to locations.]])[
'yyss': related to states.
'yyvs': related to semantic values.]b4_locations_if([[
'yyls': related to locations.]])[
Refer to the stacks through separate pointers, to allow yyoverflow
to reallocate them elsewhere. */
@@ -431,12 +413,7 @@ typedef short int yytype_int16;
# endif
#endif
/* Suppress unused-variable warnings by "using" E. */
#ifdef __GNUC__
# define YYUSE(E) ((void) (E))
#else
# define YYUSE(E) /* empty */
#endif
]b4_attribute_define[
#if ]b4_lac_if([[1]], [[! defined yyoverflow || YYERROR_VERBOSE]])[
@@ -468,7 +445,7 @@ b4_push_if([], [b4_lac_if([], [[
# endif]])])[
# ifdef YYSTACK_ALLOC
/* Pacify GCC's `empty if-body' warning. */
/* Pacify GCC's 'empty if-body' warning. */
# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
# ifndef YYSTACK_ALLOC_MAXIMUM
/* The OS might guarantee only one guard page at the bottom of the stack,
@@ -1131,11 +1108,11 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
]b4_lac_if([[yytype_int16 *yyesa, yytype_int16 **yyes,
YYSIZE_T *yyes_capacity, ]])[yytype_int16 *yyssp, int yytoken)
{
YYSIZE_T yysize0 = yytnamerr (YY_NULL, yytname[yytoken]);
YYSIZE_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]);
YYSIZE_T yysize = yysize0;
enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
/* Internationalized format string. */
const char *yyformat = YY_NULL;
const char *yyformat = YY_NULLPTR;
/* Arguments of yyformat. */
char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
/* Number of reported tokens (one for the "unexpected", one per
@@ -1210,7 +1187,7 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
}
yyarg[yycount++] = yytname[yyx];
{
YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULL, yytname[yyx]);
YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]);
if (! (yysize <= yysize1
&& yysize1 <= YYSTACK_ALLOC_MAXIMUM))
return 2;
@@ -1294,7 +1271,7 @@ static char yypstate_allocated = 0;]])b4_pull_if([
b4_function_define([[yyparse]], [[int]], b4_parse_param)[
{
return yypull_parse (YY_NULL]m4_ifset([b4_parse_param],
return yypull_parse (YY_NULLPTR]m4_ifset([b4_parse_param],
[[, ]b4_args(b4_parse_param)])[);
}
@@ -1336,10 +1313,10 @@ b4_function_define([[yyparse]], [[int]], b4_parse_param)[
{
yypstate *yyps;]b4_pure_if([], [[
if (yypstate_allocated)
return YY_NULL;]])[
return YY_NULLPTR;]])[
yyps = (yypstate *) malloc (sizeof *yyps);
if (!yyps)
return YY_NULL;
return YY_NULLPTR;
yyps->yynew = 1;]b4_pure_if([], [[
yypstate_allocated = 1;]])[
return yyps;
@@ -1654,7 +1631,7 @@ yyreduce:
yylen = yyr2[yyn];
/* If YYLEN is nonzero, implement the default value of the action:
`$$ = $1'.
'$$ = $1'.
Otherwise, the following line sets YYVAL to garbage.
This behavior is undocumented and Bison
@@ -1702,7 +1679,7 @@ yyreduce:
*++yyvsp = yyval;]b4_locations_if([
*++yylsp = yyloc;])[
/* Now `shift' the result of the reduction. Determine what state
/* Now 'shift' the result of the reduction. Determine what state
that goes to, based on the state we popped back to and the rule
number reduced by. */
+716 -310
View File
File diff suppressed because it is too large Load Diff
+2
View File
@@ -0,0 +1,2 @@
This file is a stub, not used by the documentation. If you feel like
contributing ASCII art for example.gv, please step forward!
+17 -14
View File
@@ -23,9 +23,10 @@ doc_bison_TEXINFOS = \
# Cannot express dependencies directly on file names because of Automake.
# Obfuscate with a variable.
doc_bison = doc/bison
$(doc_bison).dvi: $(FIGS_DOT:.dot=.eps)
$(doc_bison).pdf: $(FIGS_DOT:.dot=.pdf)
$(doc_bison).html: $(FIGS_DOT:.dot=.png)
$(doc_bison).dvi: $(FIGS_GV:.gv=.eps)
$(doc_bison).info: $(FIGS_GV:.gv=.txt)
$(doc_bison).pdf: $(FIGS_GV:.gv=.pdf)
$(doc_bison).html: $(FIGS_GV:.gv=.png)
TEXI2DVI = texi2dvi --build-dir=doc/bison.t2d -I doc
CLEANDIRS = doc/bison.t2d
@@ -37,7 +38,7 @@ MOSTLYCLEANFILES += $(top_srcdir)/doc/*.t
CROSS_OPTIONS_PL = $(top_srcdir)/build-aux/cross-options.pl
CROSS_OPTIONS_TEXI = $(top_srcdir)/doc/cross-options.texi
$(CROSS_OPTIONS_TEXI): doc/bison.help $(CROSS_OPTIONS_PL)
# Create $@~ which is the previous contents. Don't use `mv' here so
# Create $@~ which is the previous contents. Don't use 'mv' here so
# that even if we are interrupted, the file is still available for
# diff in the next run. Note that $@ might not exist yet.
$(AM_V_GEN){ test ! -f $@ || cat $@; } >$@~
@@ -117,32 +118,34 @@ $(top_srcdir)/doc/bison.1: doc/bison.help doc/bison.x $(top_srcdir)/configure
fi
$(AM_V_at)rm -f $@*.t
if ENABLE_YACC
nodist_man_MANS = doc/yacc.1
endif
## ----------------------------- ##
## Graphviz examples generation. ##
## ----------------------------- ##
CLEANDIRS += doc/figs
FIGS_DOT = \
doc/figs/example.dot \
doc/figs/example-reduce.dot doc/figs/example-shift.dot
EXTRA_DIST += \
$(FIGS_DOT) \
$(FIGS_DOT:.dot=.eps) $(FIGS_DOT:.dot=.pdf) $(FIGS_DOT:.dot=.png)
SUFFIXES += .dot .eps .pdf .png
FIGS_GV = \
doc/figs/example.gv \
doc/figs/example-reduce.gv doc/figs/example-shift.gv
EXTRA_DIST += \
$(FIGS_GV) $(FIGS_GV:.gv=.txt) \
$(FIGS_GV:.gv=.eps) $(FIGS_GV:.gv=.pdf) $(FIGS_GV:.gv=.png)
SUFFIXES += .gv .eps .pdf .png
.dot.eps:
.gv.eps:
$(AM_V_GEN) $(MKDIR_P) `echo "./$@" | sed -e 's,/[^/]*$$,,'`
$(AM_V_at) $(DOT) -Gmargin=0 -Teps $< >$@.tmp
$(AM_V_at) mv $@.tmp $@
.dot.pdf:
.gv.pdf:
$(AM_V_GEN) $(MKDIR_P) `echo "./$@" | sed -e 's,/[^/]*$$,,'`
$(AM_V_at) $(DOT) -Gmargin=0 -Tpdf $< >$@.tmp
$(AM_V_at) mv $@.tmp $@
.dot.png:
.gv.png:
$(AM_V_GEN) $(MKDIR_P) `echo "./$@" | sed -e 's,/[^/]*$$,,'`
$(AM_V_at) $(DOT) -Gmargin=0 -Tpng $< >$@.tmp
$(AM_V_at) mv $@.tmp $@
+2 -2
View File
@@ -204,9 +204,9 @@ Format the list of directives for Bison for bench named C<$bench>.
sub directives($@)
{
my ($bench, @directive) = @_;
my $res = "/* Directives for bench `$bench'. */\n";
my $res = "/* Directives for bench '$bench'. */\n";
$res .= join ("\n", @directive) . "\n";
$res .= "/* End of directives for bench `$bench'. */\n";
$res .= "/* End of directives for bench '$bench'. */\n";
return $res;
}
+32 -31
View File
@@ -19,7 +19,7 @@
# Don't depend on $(BISON) otherwise we would rebuild these files
# in srcdir, including during distcheck, which is forbidden.
examples/calc++/calc++-parser.stamp: $(BISON_IN)
%D%/calc++-parser.stamp: $(BISON_IN)
SUFFIXES += .yy .stamp
.yy.stamp:
$(AM_V_YACC)rm -f $@
@@ -27,14 +27,14 @@ SUFFIXES += .yy .stamp
$(AM_V_at)$(YACCCOMPILE) -o $*.cc $<
$(AM_V_at)mv -f $@.tmp $@
$(calc_sources_generated): examples/calc++/calc++-parser.stamp
@test -f $@ || rm -f examples/calc++/calc++-parser.stamp
@test -f $@ || $(MAKE) $(AM_MAKEFLAGS) examples/calc++/calc++-parser.stamp
$(calc_sources_generated): %D%/calc++-parser.stamp
@test -f $@ || rm -f %D%/calc++-parser.stamp
@test -f $@ || $(MAKE) $(AM_MAKEFLAGS) %D%/calc++-parser.stamp
CLEANFILES += \
$(calc_sources_generated) \
examples/calc++/calc++-parser.output \
examples/calc++/calc++-parser.stamp \
examples/calc++/calc++-scanner.cc
%D%/calc++-parser.output \
%D%/calc++-parser.stamp \
%D%/calc++-scanner.cc
## -------------------- ##
@@ -42,34 +42,35 @@ CLEANFILES += \
## -------------------- ##
# Avoid using BUILT_SOURCES which is too global.
$(examples_calc___calc___OBJECTS): $(calc_sources_generated)
$(%C%_calc___OBJECTS): $(calc_sources_generated)
calc_sources_extracted = \
examples/calc++/calc++-driver.cc \
examples/calc++/calc++-driver.hh \
examples/calc++/calc++-scanner.ll \
examples/calc++/calc++.cc
calc_extracted = \
$(calc_sources_extracted) \
examples/calc++/calc++-parser.yy
calc_sources_extracted = \
%D%/calc++-driver.cc \
%D%/calc++-driver.hh \
%D%/calc++-scanner.ll \
%D%/calc++.cc
calc_extracted = \
$(calc_sources_extracted) \
%D%/calc++-parser.yy
extracted += $(calc_extracted)
calc_sources_generated = \
examples/calc++/calc++-parser.cc \
examples/calc++/calc++-parser.hh \
examples/calc++/location.hh \
examples/calc++/position.hh \
examples/calc++/stack.hh
calc_sources = \
$(calc_sources_extracted) \
calc_sources_generated = \
%D%/calc++-parser.cc \
%D%/calc++-parser.hh \
%D%/location.hh \
%D%/position.hh \
%D%/stack.hh
calc_sources = \
$(calc_sources_extracted) \
$(calc_sources_generated)
if BISON_CXX_WORKS
check_PROGRAMS += examples/calc++/calc++
nodist_examples_calc___calc___SOURCES = \
if FLEX_CXX_WORKS
check_PROGRAMS += %D%/calc++
nodist_%C%_calc___SOURCES = \
$(calc_sources)
examples_calc___calc___CPPFLAGS = -I$(top_builddir)/examples/calc++
examples_calc___calc___CXXFLAGS = \
$(AM_CXXFLAGS) $(WARN_NO_NULL_CONVERSION_CXXFLAGS)
dist_TESTS += examples/calc++/calc++.test
%C%_calc___CPPFLAGS = -I$(top_builddir)/%D%
%C%_calc___CXXFLAGS = $(AM_CXXFLAGS) $(FLEX_SCANNER_CXXFLAGS)
dist_TESTS += %D%/calc++.test
else
EXTRA_DIST += %D%/calc++.test
endif
+12 -13
View File
@@ -13,11 +13,10 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
dist_noinst_SCRIPTS = examples/extexi examples/test
TEST_LOG_COMPILER = $(top_srcdir)/examples/test
dist_noinst_SCRIPTS = %D%/extexi %D%/test
TEST_LOG_COMPILER = $(top_srcdir)/%D%/test
AM_CXXFLAGS = \
$(NO_STRICT_ALIAS_CXXFLAGS) \
$(WARN_CXXFLAGS) $(WARN_CXXFLAGS_TEST) $(WERROR_CXXFLAGS)
## ------------ ##
@@ -25,20 +24,20 @@ AM_CXXFLAGS = \
## ------------ ##
doc = $(top_srcdir)/doc/bison.texi
extexi = $(top_srcdir)/examples/extexi
extract = VERSION="$(VERSION)" $(PERL) -f $(extexi) $(doc) --
extexi = $(top_srcdir)/%D%/extexi
extract = VERSION="$(VERSION)" $(PERL) $(extexi) $(doc) --
extracted =
CLEANFILES += $(extracted) examples/extracted.stamp
examples/extracted.stamp: $(doc) $(extexi)
CLEANFILES += $(extracted) %D%/extracted.stamp
%D%/extracted.stamp: $(doc) $(extexi)
$(AM_V_GEN)rm -f $@ $@.tmp
$(AM_V_at)touch $@.tmp
$(AM_V_at)$(extract) $(extracted)
$(AM_V_at)mv $@.tmp $@
$(extracted): examples/extracted.stamp
@test -f $@ || rm -f examples/extracted.stamp
@test -f $@ || $(MAKE) $(AM_MAKEFLAGS) examples/extracted.stamp
$(extracted): %D%/extracted.stamp
@test -f $@ || rm -f %D%/extracted.stamp
@test -f $@ || $(MAKE) $(AM_MAKEFLAGS) %D%/extracted.stamp
include examples/calc++/local.mk
include examples/mfcalc/local.mk
include examples/rpcalc/local.mk
include %D%/calc++/local.mk
include %D%/mfcalc/local.mk
include %D%/rpcalc/local.mk
+8 -12
View File
@@ -18,19 +18,15 @@
## -------------------- ##
BUILT_SOURCES += $(mfcalc_sources)
CLEANFILES += examples/mfcalc/mfcalc.[ch] examples/mfcalc/mfcalc.output
CLEANFILES += %D%/mfcalc.[ch] %D%/mfcalc.output
mfcalc_extracted = \
examples/mfcalc/calc.h \
examples/mfcalc/mfcalc.y
mfcalc_sources = \
$(mfcalc_extracted)
mfcalc_extracted = %D%/calc.h %D%/mfcalc.y
mfcalc_sources = $(mfcalc_extracted)
extracted += $(mfcalc_extracted)
check_PROGRAMS += examples/mfcalc/mfcalc
examples_mfcalc_mfcalc_LDADD = -lm
nodist_examples_mfcalc_mfcalc_SOURCES = \
$(mfcalc_sources)
check_PROGRAMS += %D%/mfcalc
%C%_mfcalc_LDADD = -lm
nodist_%C%_mfcalc_SOURCES = $(mfcalc_sources)
examples_mfcalc_mfcalc_CPPFLAGS = -I$(top_builddir)/examples/mfcalc
dist_TESTS += examples/mfcalc/mfcalc.test
%C%_mfcalc_CPPFLAGS = -I$(top_builddir)/%D%
dist_TESTS += %D%/mfcalc.test
+1
View File
@@ -1,4 +1,5 @@
/calc.h
/rpcalc
/rpcalc.c
/rpcalc.h
/rpcalc.output
+8 -11
View File
@@ -18,18 +18,15 @@
## -------------------- ##
BUILT_SOURCES += $(rpcalc_sources)
CLEANFILES += examples/rpcalc/rpcalc.[ch] examples/rpcalc/rpcalc.output
CLEANFILES += %D%/rpcalc.[ch] %D%/rpcalc.output
rpcalc_extracted = \
examples/rpcalc/rpcalc.y
rpcalc_sources = \
$(rpcalc_extracted)
rpcalc_extracted = %D%/rpcalc.y
rpcalc_sources = $(rpcalc_extracted)
extracted += $(rpcalc_extracted)
check_PROGRAMS += examples/rpcalc/rpcalc
examples_rpcalc_rpcalc_LDADD = -lm
nodist_examples_rpcalc_rpcalc_SOURCES = \
$(rpcalc_sources)
check_PROGRAMS += %D%/rpcalc
%C%_rpcalc_LDADD = -lm
nodist_%C%_rpcalc_SOURCES = $(rpcalc_sources)
examples_rpcalc_rpcalc_CPPFLAGS = -I$(top_builddir)/examples/rpcalc
dist_TESTS += examples/rpcalc/rpcalc.test
%C%_rpcalc_CPPFLAGS = -I$(top_builddir)/%D%
dist_TESTS += %D%/rpcalc.test
+11 -5
View File
@@ -16,7 +16,7 @@
*/
%debug
%skeleton "lalr1.cc"
%language "c++"
%defines
%define api.token.constructor
%define api.value.type variant
@@ -48,11 +48,17 @@ typedef std::list<std::string> strings_type;
namespace std
{
std::ostream&
operator<< (std::ostream& o, const strings_type& s)
operator<< (std::ostream& o, const strings_type& ss)
{
std::copy (s.begin (), s.end (),
std::ostream_iterator<strings_type::value_type> (o, "\n"));
return o;
o << "(" << &ss << ") {";
const char *sep = "";
for (strings_type::const_iterator i = ss.begin(), end = ss.end();
i != end; ++i)
{
o << sep << *i;
sep = ", ";
}
return o << "}";
}
}
+1 -1
Submodule gnulib updated: c67e3c0414...74540d44dc
+2
View File
@@ -272,3 +272,5 @@
/sig-handler.c
/unistd.c
/wctype-h.c
/lstat.c
/unlink.c
+1 -1
View File
@@ -17,7 +17,7 @@
/* Bison depends on libiberty's implementation of bitsets, which
requires a `libiberty.h' file. This file provides the minimum
requires a 'libiberty.h' file. This file provides the minimum
services. */
#ifndef BISON_LIBIBERTY_H_
+3 -1
View File
@@ -51,6 +51,8 @@ lib_libbison_a_SOURCES += \
lib/get-errno.c
# The Yacc compatibility library.
lib_LIBRARIES = $(YACC_LIBRARY)
if ENABLE_YACC
lib_LIBRARIES = lib/liby.a
EXTRA_LIBRARIES = lib/liby.a
lib_liby_a_SOURCES = lib/main.c lib/yyerror.c
endif
+1 -1
View File
@@ -36,7 +36,7 @@
Timing variables may be pushed onto the stack; elapsed time is
attributed to the topmost timing variable on the stack. When
another variable is pushed on, the previous topmost variable is
`paused' until the pushed variable is popped back off.
'paused' until the pushed variable is popped back off.
- As a standalone timer, using timevar_start and timevar_stop.
All time elapsed between the two calls is attributed to the
+3
View File
@@ -180,3 +180,6 @@
/obstack-printf.m4
/extern-inline.m4
/non-recursive-gnulib-prefix-hack.m4
/absolute-header.m4
/lstat.m4
/unlink.m4
+7 -3
View File
@@ -541,9 +541,13 @@ AnnotationList__compute_from_inadequacies (
{
InadequacyList__prependTo (conflict_node,
&inadequacy_lists[s->number]);
aver (AnnotationList__insertInto (
annotation_node, &annotation_lists[s->number],
s->nitems));
{
bool b =
AnnotationList__insertInto (annotation_node,
&annotation_lists[s->number],
s->nitems);
aver (b);
}
/* This aver makes sure the
AnnotationList__computeDominantContribution check above
does discard annotations in the simplest case of a S/R
+1 -1
View File
@@ -60,7 +60,7 @@ Sbitset__isEmpty (Sbitset self, Sbitset__Index nbits)
}
void
Sbitset__fprint(Sbitset self, Sbitset__Index nbits, FILE *file)
Sbitset__fprint (Sbitset self, Sbitset__Index nbits, FILE *file)
{
Sbitset__Index i;
Sbitset itr;
+6 -6
View File
@@ -44,31 +44,31 @@ void Sbitset__delete (Sbitset self);
bool Sbitset__isEmpty (Sbitset self, Sbitset__Index nbits);
void Sbitset__fprint(Sbitset self, Sbitset__Index nbits, FILE *file);
void Sbitset__fprint (Sbitset self, Sbitset__Index nbits, FILE *file);
# define Sbitset__set(SELF, INDEX) \
do { \
*Sbitset__byteAddress ((SELF), (INDEX)) = \
*Sbitset__byteAddress ((SELF), (INDEX)) | Sbitset__bit_mask (INDEX); \
} while(0)
} while (0)
# define Sbitset__reset(SELF, INDEX) \
do { \
*Sbitset__byteAddress ((SELF), (INDEX)) = \
*Sbitset__byteAddress ((SELF), (INDEX)) & ~Sbitset__bit_mask (INDEX); \
} while(0)
} while (0)
/* NBITS is the size of the bitset. More than NBITS bits might be reset. */
# define Sbitset__zero(SELF, NBITS) \
do { \
memset (SELF, 0, Sbitset__nbytes (NBITS)); \
} while(0)
} while (0)
/* NBITS is the size of the bitset. More than NBITS bits might be set. */
# define Sbitset__ones(SELF, NBITS) \
do { \
memset (SELF, UCHAR_MAX, Sbitset__nbytes (NBITS)); \
} while(0)
} while (0)
/* NBITS is the size of every bitset. More than NBITS bits might be set. */
# define Sbitset__or(SELF, OTHER1, OTHER2, NBITS) \
@@ -79,7 +79,7 @@ void Sbitset__fprint(Sbitset self, Sbitset__Index nbits, FILE *file);
Sbitset end_self = ptr_self + Sbitset__nbytes (NBITS); \
for (; ptr_self < end_self; ++ptr_self, ++ptr_other1, ++ptr_other2) \
*ptr_self = *ptr_other1 | *ptr_other2; \
} while(0)
} while (0)
# define SBITSET__FOR_EACH(SELF, NBITS, ITER, INDEX) \
for ((ITER) = (SELF); (ITER) < (SELF) + Sbitset__nbytes (NBITS); ++(ITER)) \
+243 -46
View File
@@ -22,6 +22,7 @@
#include <config.h>
#include "system.h"
#include <argmatch.h>
#include <stdarg.h>
#include <progname.h>
@@ -30,42 +31,223 @@
#include "getargs.h"
#include "quote.h"
warnings warnings_flag =
Wconflicts_sr | Wconflicts_rr | Wdeprecated | Wother;
warnings errors_flag;
err_status complaint_status = status_none;
bool warnings_are_errors = false;
/** Whether -Werror/-Wno-error was applied to a warning. */
typedef enum
{
errority_unset = 0, /** No explict status. */
errority_disabled = 1, /** Explictly disabled with -Wno-error=foo. */
errority_enabled = 2 /** Explictly enabled with -Werror=foo. */
} errority;
/** For each warning type, its errority. */
static errority errority_flag[warnings_size];
/** Diagnostics severity. */
typedef enum
{
severity_disabled = 0, /**< Explicitly disabled via -Wno-foo. */
severity_unset = 1, /**< Unspecified status. */
severity_warning = 2, /**< A warning. */
severity_error = 3, /**< An error (continue, but die soon). */
severity_fatal = 4 /**< Fatal error (die now). */
} severity;
/** For each warning type, its severity. */
static severity warnings_flag[warnings_size];
static unsigned *indent_ptr = 0;
void
warnings_print_categories (warnings warn_flags)
{
if (! (warn_flags & silent))
{
char const *warn_names[] =
{
"midrule-values",
"yacc",
"conflicts-sr",
"conflicts-rr",
"deprecated",
"other"
};
/*------------------------.
| --warnings's handling. |
`------------------------*/
bool any = false;
int i;
for (i = 0; i < ARRAY_CARDINALITY (warn_names); ++i)
if (warn_flags & 1 << i)
{
bool err = warn_flags & errors_flag;
fprintf (stderr, "%s-W", any ? ", " : " [");
fprintf (stderr, "%s%s", err ? "error=" : "" , warn_names[i]);
any = true;
}
if (any)
fprintf (stderr, "]");
static const char * const warnings_args[] =
{
"none",
"midrule-values",
"yacc",
"conflicts-sr",
"conflicts-rr",
"deprecated",
"empty-rule",
"precedence",
"other",
"all",
"error",
"everything",
0
};
static const int warnings_types[] =
{
Wnone,
Wmidrule_values,
Wyacc,
Wconflicts_sr,
Wconflicts_rr,
Wdeprecated,
Wempty_rule,
Wprecedence,
Wother,
Wall,
Werror,
Weverything
};
ARGMATCH_VERIFY (warnings_args, warnings_types);
void
warning_argmatch (char const *arg, size_t no, size_t err)
{
int value = XARGMATCH ("--warning", arg + no + err,
warnings_args, warnings_types);
/* -Wnone == -Wno-everything, and -Wno-none == -Weverything. */
if (!value)
{
value = Weverything;
no = !no;
}
size_t b;
for (b = 0; b < warnings_size; ++b)
if (value & 1 << b)
{
if (err && no)
/* -Wno-error=foo. */
errority_flag[b] = errority_disabled;
else if (err && !no)
{
/* -Werror=foo: enables -Wfoo. */
errority_flag[b] = errority_enabled;
warnings_flag[b] = severity_warning;
}
else if (no)
/* -Wno-foo. */
warnings_flag[b] = severity_disabled;
else
/* -Wfoo. */
warnings_flag[b] = severity_warning;
}
}
/** Decode a comma-separated list of arguments from -W.
*
* \param args comma separated list of effective subarguments to decode.
* If 0, then activate all the flags.
*/
void
warnings_argmatch (char *args)
{
if (args)
for (args = strtok (args, ","); args; args = strtok (NULL, ","))
if (STREQ (args, "error"))
warnings_are_errors = true;
else if (STREQ (args, "no-error"))
warnings_are_errors = false;
else
{
/* The length of the possible 'no-' prefix: 3, or 0. */
size_t no = STRPREFIX_LIT ("no-", args) ? 3 : 0;
/* The length of the possible 'error=' (possibly after
'no-') prefix: 6, or 0. */
size_t err = STRPREFIX_LIT ("error=", args + no) ? 6 : 0;
warning_argmatch (args, no, err);
}
else
warning_argmatch ("all", 0, 0);
}
/*-----------.
| complain. |
`-----------*/
void
complain_init (void)
{
warnings warnings_default =
Wconflicts_sr | Wconflicts_rr | Wdeprecated | Wother;
size_t b;
for (b = 0; b < warnings_size; ++b)
{
warnings_flag[b] = (1 << b & warnings_default
? severity_warning
: severity_unset);
errority_flag[b] = errority_unset;
}
}
/* A diagnostic with FLAGS is about to be issued. With what severity?
(severity_fatal, severity_error, severity_disabled, or
severity_warning.) */
static severity
warning_severity (warnings flags)
{
if (flags & fatal)
/* Diagnostics about fatal errors. */
return severity_fatal;
else if (flags & complaint)
/* Diagnostics about errors. */
return severity_error;
else
{
/* Diagnostics about warnings. */
severity res = severity_disabled;
size_t b;
for (b = 0; b < warnings_size; ++b)
if (flags & 1 << b)
{
res = res < warnings_flag[b] ? warnings_flag[b] : res;
/* If the diagnostic is enabled, and -Werror is enabled,
and -Wno-error=foo was not explicitly requested, this
is an error. */
if (res == severity_warning
&& (errority_flag[b] == errority_enabled
|| (warnings_are_errors
&& errority_flag[b] != errority_disabled)))
res = severity_error;
}
return res;
}
}
bool
warning_is_unset (warnings flags)
{
size_t b;
for (b = 0; b < warnings_size; ++b)
if (flags & 1 << b && warnings_flag[b] != severity_unset)
return false;
return true;
}
/** Display a "[-Wyacc]" like message on \a f. */
static void
warnings_print_categories (warnings warn_flags, FILE *f)
{
/* Display only the first match, the second is "-Wall". */
size_t i;
for (i = 0; warnings_args[i]; ++i)
if (warn_flags & warnings_types[i])
{
severity s = warning_severity (warnings_types[i]);
fprintf (f, " [-W%s%s]",
s == severity_error ? "error=" : "",
warnings_args[i]);
return;
}
}
/** Report an error message.
@@ -88,7 +270,7 @@ error_message (const location *loc, warnings flags, const char *prefix,
unsigned pos = 0;
if (loc)
pos += location_print (stderr, *loc);
pos += location_print (*loc, stderr);
else
pos += fprintf (stderr, "%s", current_file ? current_file : program_name);
pos += fprintf (stderr, ": ");
@@ -108,7 +290,8 @@ error_message (const location *loc, warnings flags, const char *prefix,
fprintf (stderr, "%s: ", prefix);
vfprintf (stderr, message, args);
warnings_print_categories (flags);
if (! (flags & silent))
warnings_print_categories (flags, stderr);
{
size_t l = strlen (message);
if (l < 2 || message[l - 2] != ':' || message[l - 1] != ' ')
@@ -116,29 +299,34 @@ error_message (const location *loc, warnings flags, const char *prefix,
putc ('\n', stderr);
fflush (stderr);
if (loc && feature_flag & feature_caret && !(flags & no_caret))
location_caret (stderr, *loc);
location_caret (*loc, stderr);
}
}
fflush (stderr);
}
/** Raise a complaint. That can be a fatal error, a complaint or just a
/** Raise a complaint. That can be a fatal error, an error or just a
warning. */
static inline void
static void
complains (const location *loc, warnings flags, const char *message,
va_list args)
{
const char* prefix =
flags & fatal ? _("fatal error")
: flags & (errors_flag | complaint) ? _("error")
: _("warning");
severity s = warning_severity (flags);
if ((flags & complaint) && complaint_status < status_complaint)
complaint_status = status_complaint;
else if ((flags & (warnings_flag & errors_flag)) && ! complaint_status)
complaint_status = status_warning_as_error;
if (flags & (warnings_flag | fatal | complaint))
error_message (loc, flags, prefix, message, args);
if (severity_warning <= s)
{
const char* prefix =
s == severity_fatal ? _("fatal error")
: s == severity_error ? _("error")
: _("warning");
if (severity_error <= s && ! complaint_status)
complaint_status = status_warning_as_error;
error_message (loc, flags, prefix, message, args);
}
if (flags & fatal)
exit (EXIT_FAILURE);
}
@@ -189,7 +377,6 @@ complain_args (location const *loc, warnings w, unsigned *indent,
complain (loc, fatal, "too many arguments for complains");
break;
}
}
void
@@ -204,3 +391,13 @@ deprecated_directive (location const *loc, char const *old, char const *upd)
_("deprecated directive: %s, use %s"),
quote (old), quote_n (1, upd));
}
void
duplicate_directive (char const *directive,
location first, location second)
{
unsigned i = 0;
complain (&second, complaint, _("only one %s allowed per rule"), directive);
i += SUB_INDENT;
complain_indent (&first, complaint, &i, _("previous declaration"));
}
+74 -22
View File
@@ -28,15 +28,67 @@
| --warnings. |
`-------------*/
/** The bits assigned to each warning type. */
typedef enum
{
Wnone = 0, /**< Issue no warnings. */
Wmidrule_values = 1 << 0, /**< Unset or unused midrule values. */
Wyacc = 1 << 1, /**< POSIXME. */
Wconflicts_sr = 1 << 2, /**< S/R conflicts. */
Wconflicts_rr = 1 << 3, /**< R/R conflicts. */
Wdeprecated = 1 << 4, /**< Obsolete constructs. */
Wother = 1 << 5, /**< All other warnings. */
warning_midrule_values, /**< Unset or unused midrule values. */
warning_yacc, /**< POSIXME. */
warning_conflicts_sr, /**< S/R conflicts. */
warning_conflicts_rr, /**< R/R conflicts. */
warning_empty_rule, /**< Implicitly empty rules. */
warning_deprecated, /**< Obsolete constructs. */
warning_precedence, /**< Useless precedence and associativity. */
warning_other, /**< All other warnings. */
warnings_size /**< The number of warnings. Must be last. */
} warning_bit;
/** Whether -Werror was set. */
extern bool warnings_are_errors;
/** Decode a single argument from -W.
*
* \param arg the subarguments to decode.
* If null, then activate all the flags.
* \param no length of the potential "no-" prefix.
* Can be 0 or 3. If 3, negate the action of the subargument.
* \param err length of a potential "error=".
* Can be 0 or 6. If 6, treat the subargument as a CATEGORY.
*
* If VALUE != 0 then KEY sets flags and no-KEY clears them.
* If VALUE == 0 then KEY clears all flags from \c all and no-KEY sets all
* flags from \c all. Thus no-none = all and no-all = none.
*/
void warning_argmatch (char const *arg, size_t no, size_t err);
/** Decode a comma-separated list of arguments from -W.
*
* \param args comma separated list of effective subarguments to decode.
* If 0, then activate all the flags.
*/
void warnings_argmatch (char *args);
/*-----------.
| complain. |
`-----------*/
/** Initialize this module. */
void complain_init (void);
typedef enum
{
/**< Issue no warnings. */
Wnone = 0,
Wmidrule_values = 1 << warning_midrule_values,
Wyacc = 1 << warning_yacc,
Wconflicts_sr = 1 << warning_conflicts_sr,
Wconflicts_rr = 1 << warning_conflicts_rr,
Wdeprecated = 1 << warning_deprecated,
Wempty_rule = 1 << warning_empty_rule,
Wprecedence = 1 << warning_precedence,
Wother = 1 << warning_other,
Werror = 1 << 10, /** This bit is no longer used. */
@@ -46,17 +98,13 @@ typedef enum
no_caret = 1 << 14, /**< Do not display caret location. */
/**< All above warnings. */
Wall = ~complaint & ~fatal & ~silent
Weverything = ~complaint & ~fatal & ~silent,
Wall = Weverything & ~Wyacc
} warnings;
/** What warnings are issued. */
extern warnings warnings_flag;
/** What warnings are made errors. */
extern warnings errors_flag;
/** Display a "[-Wyacc]" like message on stderr. */
void warnings_print_categories (warnings warn_flags);
/** Whether the warnings of \a flags are all unset.
(Never enabled, never disabled). */
bool warning_is_unset (warnings flags);
/** Make a complaint, with maybe a location. */
void complain (location const *loc, warnings flags, char const *message, ...)
@@ -76,14 +124,18 @@ void complain_indent (location const *loc, warnings flags, unsigned *indent,
void deprecated_directive (location const *loc,
char const *obsolete, char const *updated);
/** Warnings treated as errors shouldn't stop the execution as regular errors
should (because due to their nature, it is safe to go on). Thus, there are
three possible execution statuses. */
/** Report a repeated directive for a rule. */
void duplicate_directive (char const *directive,
location first, location second);
/** Warnings treated as errors shouldn't stop the execution as regular
errors should (because due to their nature, it is safe to go
on). Thus, there are three possible execution statuses. */
typedef enum
{
status_none,
status_warning_as_error,
status_complaint
status_none, /**< No diagnostic issued so far. */
status_warning_as_error, /**< A warning was issued (but no error). */
status_complaint /**< An error was issued. */
} err_status;
/** Whether an error was reported. */
+1 -1
View File
@@ -403,7 +403,7 @@ conflicts_solve (void)
set_conflicts (states[i], errors);
/* For uniformity of the code, make sure all the states have a valid
`errs' member. */
'errs' member. */
if (!states[i]->errs)
states[i]->errs = errs_new (0, 0);
}
+48 -28
View File
@@ -34,7 +34,7 @@
#include "getargs.h"
#include "gram.h"
/* Initializing some values below (such SPEC_NAME_PREFIX to `yy') is
/* Initializing some values below (such SPEC_NAME_PREFIX to 'yy') is
tempting, but don't do that: for the time being our handling of the
%directive vs --option leaves precedence to the options by deciding
that if a %directive sets a variable which is really set (i.e., not
@@ -51,27 +51,36 @@ char *spec_defines_file = NULL; /* for --defines. */
char *parser_file_name;
/* All computed output file names. */
static char **file_names = NULL;
static int file_names_count = 0;
typedef struct generated_file
{
/** File name. */
char *name;
/** Whether is a generated source file (e.g., *.c, *.java...), as
opposed to the report file (e.g., *.output). When late errors
are detected, generated source files are removed. */
bool is_source;
} generated_file;
static generated_file *generated_files = NULL;
static int generated_files_size = 0;
uniqstr grammar_file = NULL;
uniqstr current_file = NULL;
/* If --output=dir/foo.c was specified,
DIR_PREFIX is `dir/' and ALL_BUT_EXT and ALL_BUT_TAB_EXT are `dir/foo'.
DIR_PREFIX is 'dir/' and ALL_BUT_EXT and ALL_BUT_TAB_EXT are 'dir/foo'.
If --output=dir/foo.tab.c was specified, DIR_PREFIX is `dir/',
ALL_BUT_EXT is `dir/foo.tab', and ALL_BUT_TAB_EXT is `dir/foo'.
If --output=dir/foo.tab.c was specified, DIR_PREFIX is 'dir/',
ALL_BUT_EXT is 'dir/foo.tab', and ALL_BUT_TAB_EXT is 'dir/foo'.
If --output was not specified but --file-prefix=dir/foo was specified,
ALL_BUT_EXT = `foo.tab' and ALL_BUT_TAB_EXT = `foo'.
ALL_BUT_EXT = 'foo.tab' and ALL_BUT_TAB_EXT = 'foo'.
If neither --output nor --file was specified but the input grammar
is name dir/foo.y, ALL_BUT_EXT and ALL_BUT_TAB_EXT are `foo'.
is name dir/foo.y, ALL_BUT_EXT and ALL_BUT_TAB_EXT are 'foo'.
If neither --output nor --file was specified, DIR_PREFIX is the
empty string (meaning the current directory); otherwise it is
`dir/'. */
'dir/'. */
char *all_but_ext;
static char *all_but_tab_ext;
@@ -79,7 +88,7 @@ char *dir_prefix;
/* C source file extension (the parser source). */
static char *src_extension = NULL;
/* Header file extension (if option ``-d'' is specified). */
/* Header file extension (if option '`-d'' is specified). */
static char *header_extension = NULL;
/*-----------------------------------------------------------------.
@@ -191,7 +200,7 @@ compute_exts_from_src (const char *ext)
*EXT points to the last period in the basename, or NULL if none.
If there is no *EXT, *TAB is NULL. Otherwise, *TAB points to
`.tab' or `_tab' if present right before *EXT, or is NULL. *TAB
'.tab' or '_tab' if present right before *EXT, or is NULL. *TAB
cannot be equal to *BASE.
None are allocated, they are simply pointers to parts of FILE_NAME.
@@ -222,7 +231,7 @@ file_name_split (const char *file_name,
*ext = strrchr (*base, '.');
*tab = NULL;
/* If there is an extension, check if there is a `.tab' part right
/* If there is an extension, check if there is a '.tab' part right
before. */
if (*ext)
{
@@ -270,7 +279,7 @@ compute_file_name_parts (void)
if (spec_file_prefix)
{
/* If --file-prefix=foo was specified, ALL_BUT_TAB_EXT = `foo'. */
/* If --file-prefix=foo was specified, ALL_BUT_TAB_EXT = 'foo'. */
dir_prefix =
xstrndup (spec_file_prefix,
last_component (spec_file_prefix) - spec_file_prefix);
@@ -278,14 +287,14 @@ compute_file_name_parts (void)
}
else if (yacc_flag)
{
/* If --yacc, then the output is `y.tab.c'. */
/* If --yacc, then the output is 'y.tab.c'. */
dir_prefix = xstrdup ("");
all_but_tab_ext = xstrdup ("y");
}
else
{
/* Otherwise, ALL_BUT_TAB_EXT is computed from the input
grammar: `foo/bar.yy' => `bar'. */
grammar: 'foo/bar.yy' => 'bar'. */
dir_prefix = xstrdup ("");
all_but_tab_ext =
xstrndup (base, (strlen (base) - (ext ? strlen (ext) : 0)));
@@ -332,21 +341,21 @@ compute_output_file_names (void)
{
if (! spec_graph_file)
spec_graph_file = concat2 (all_but_tab_ext, ".dot");
output_file_name_check (&spec_graph_file);
output_file_name_check (&spec_graph_file, false);
}
if (xml_flag)
{
if (! spec_xml_file)
spec_xml_file = concat2 (all_but_tab_ext, ".xml");
output_file_name_check (&spec_xml_file);
output_file_name_check (&spec_xml_file, false);
}
if (report_flag)
{
if (!spec_verbose_file)
spec_verbose_file = concat2 (all_but_tab_ext, OUTPUT_EXT);
output_file_name_check (&spec_verbose_file);
output_file_name_check (&spec_verbose_file, false);
}
free (all_but_tab_ext);
@@ -355,7 +364,7 @@ compute_output_file_names (void)
}
void
output_file_name_check (char **file_name)
output_file_name_check (char **file_name, bool source)
{
bool conflict = false;
if (STREQ (*file_name, grammar_file))
@@ -367,11 +376,11 @@ output_file_name_check (char **file_name)
else
{
int i;
for (i = 0; i < file_names_count; i++)
if (STREQ (file_names[i], *file_name))
for (i = 0; i < generated_files_size; i++)
if (STREQ (generated_files[i].name, *file_name))
{
complain (NULL, Wother, _("conflicting outputs to file %s"),
quote (*file_name));
quote (generated_files[i].name));
conflict = true;
}
}
@@ -382,12 +391,23 @@ output_file_name_check (char **file_name)
}
else
{
file_names = xnrealloc (file_names, ++file_names_count,
sizeof *file_names);
file_names[file_names_count-1] = xstrdup (*file_name);
generated_files = xnrealloc (generated_files, ++generated_files_size,
sizeof *generated_files);
generated_files[generated_files_size-1].name = xstrdup (*file_name);
generated_files[generated_files_size-1].is_source = source;
}
}
void
unlink_generated_sources (void)
{
int i;
for (i = 0; i < generated_files_size; i++)
if (generated_files[i].is_source)
/* Ignore errors. The file might not even exist. */
unlink (generated_files[i].name);
}
void
output_file_names_free (void)
{
@@ -400,8 +420,8 @@ output_file_names_free (void)
free (dir_prefix);
{
int i;
for (i = 0; i < file_names_count; i++)
free (file_names[i]);
for (i = 0; i < generated_files_size; i++)
free (generated_files[i].name);
}
free (file_names);
free (generated_files);
}
+9 -1
View File
@@ -63,7 +63,15 @@ extern char *all_but_ext;
void compute_output_file_names (void);
void output_file_names_free (void);
void output_file_name_check (char **file_name);
/** Record that we generate file \a file_name.
* \param source whether this is a source file (*c, *.java...)
* as opposed to a report (*.output, *.dot...).
*/
void output_file_name_check (char **file_name, bool source);
/** Remove all the generated source files. */
void unlink_generated_sources (void);
FILE *xfopen (const char *name, char const *mode);
void xfclose (FILE *ptr);
+64 -109
View File
@@ -61,7 +61,6 @@ int skeleton_prio = default_prio;
const char *skeleton = NULL;
int language_prio = default_prio;
struct bison_language const *language = &valid_languages[0];
const char *include = NULL;
/** Decode an option's key.
*
@@ -74,8 +73,6 @@ const char *include = NULL;
* If null, then activate all the flags.
* \param no length of the potential "no-" prefix.
* Can be 0 or 3. If 3, negate the action of the subargument.
* \param err length of a potential "error=".
* Can be 0 or 6. If 6, treat the subargument as a CATEGORY
*
* If VALUE != 0 then KEY sets flags and no-KEY clears them.
* If VALUE == 0 then KEY clears all flags from \c all and no-KEY sets all
@@ -84,36 +81,23 @@ const char *include = NULL;
static void
flag_argmatch (const char *option,
const char * const keys[], const int values[],
int all, int *flags, char *arg, size_t no, size_t err)
int all, int *flags, char *arg, size_t no)
{
int value = 0;
if (!err || arg[no + err++] != '\0')
value = XARGMATCH (option, arg + no + err, keys, values);
int value = XARGMATCH (option, arg + no, keys, values);
if (value)
/* -rnone == -rno-all, and -rno-none == -rall. */
if (!value)
{
if (no)
*flags &= ~value;
else
{
if (err)
warnings_flag |= value;
*flags |= value;
}
value = all;
no = !no;
}
if (no)
*flags &= ~value;
else
{
/* With a simpler 'if (no)' version, -Werror means -Werror=all
(or rather, -Werror=no-none, but that syntax is invalid).
The difference is:
- Werror activates all errors, but not the warnings
- Werror=all activates errors, and all warnings */
if (no ? !err : err)
*flags |= all;
else
*flags &= ~all;
}
*flags |= value;
}
/** Decode an option's set of keys.
*
* \param option option being decoded.
@@ -133,16 +117,14 @@ flags_argmatch (const char *option,
for (args = strtok (args, ","); args; args = strtok (NULL, ","))
{
size_t no = STRPREFIX_LIT ("no-", args) ? 3 : 0;
size_t err = STRPREFIX_LIT ("error", args + no) ? 5 : 0;
flag_argmatch (option, keys,
values, all, err ? &errors_flag : flags,
args, no, err);
values, all, flags, args, no);
}
else
*flags |= all;
}
/** Decode a set of sub arguments.
*
* \param FlagName the flag familly to update.
@@ -196,8 +178,6 @@ ARGMATCH_VERIFY (report_args, report_types);
static const char * const trace_args[] =
{
/* In a series of synonyms, present the most meaningful first, so
that argmatch_valid be more readable. */
"none - no traces",
"scan - grammar scanner traces",
"parse - grammar parser traces",
@@ -238,41 +218,6 @@ static const int trace_types[] =
ARGMATCH_VERIFY (trace_args, trace_types);
/*------------------------.
| --warnings's handling. |
`------------------------*/
static const char * const warnings_args[] =
{
/* In a series of synonyms, present the most meaningful first, so
that argmatch_valid be more readable. */
"none - no warnings",
"midrule-values - unset or unused midrule values",
"yacc - incompatibilities with POSIX Yacc",
"conflicts-sr - S/R conflicts",
"conflicts-rr - R/R conflicts",
"deprecated - obsolete constructs",
"other - all other warnings",
"all - all of the above",
"error - warnings are errors",
0
};
static const int warnings_types[] =
{
Wnone,
Wmidrule_values,
Wyacc,
Wconflicts_sr,
Wconflicts_rr,
Wdeprecated,
Wother,
Wall,
Werror
};
ARGMATCH_VERIFY (warnings_args, warnings_types);
/*-----------------------.
| --feature's handling. |
`-----------------------*/
@@ -304,7 +249,7 @@ static void
usage (int status)
{
if (status != 0)
fprintf (stderr, _("Try `%s --help' for more information.\n"),
fprintf (stderr, _("Try '%s --help' for more information.\n"),
program_name);
else
{
@@ -346,7 +291,7 @@ Parser:\n\
-L, --language=LANGUAGE specify the output programming language\n\
-S, --skeleton=FILE specify the skeleton to use\n\
-t, --debug instrument the parser for tracing\n\
same as `-Dparse.trace'\n\
same as '-Dparse.trace'\n\
--locations enable location support\n\
-D, --define=NAME[=VALUE] similar to '%define NAME \"VALUE\"'\n\
-F, --force-define=NAME[=VALUE] override '%define NAME \"VALUE\"'\n\
@@ -365,7 +310,7 @@ Output:\n\
-d likewise but cannot specify FILE (for POSIX Yacc)\n\
-r, --report=THINGS also produce details on the automaton\n\
--report-file=FILE write report to FILE\n\
-v, --verbose same as `--report=state'\n\
-v, --verbose same as '--report=state'\n\
-b, --file-prefix=PREFIX specify a PREFIX for output files\n\
-o, --output=FILE leave output to FILE\n\
-g, --graph[=FILE] also output a graph of the automaton\n\
@@ -376,35 +321,37 @@ Output:\n\
fputs (_("\
Warning categories include:\n\
`midrule-values' unset or unused midrule values\n\
`yacc' incompatibilities with POSIX Yacc\n\
`conflicts-sr' S/R conflicts (enabled by default)\n\
`conflicts-rr' R/R conflicts (enabled by default)\n\
`deprecated' obsolete constructs\n\
`other' all other warnings (enabled by default)\n\
`all' all the warnings\n\
`no-CATEGORY' turn off warnings in CATEGORY\n\
`none' turn off all the warnings\n\
`error[=CATEGORY]' treat warnings as errors\n\
'midrule-values' unset or unused midrule values\n\
'yacc' incompatibilities with POSIX Yacc\n\
'conflicts-sr' S/R conflicts (enabled by default)\n\
'conflicts-rr' R/R conflicts (enabled by default)\n\
'deprecated' obsolete constructs\n\
'empty-rule' empty rules without %empty\n\
'precedence' useless precedence and associativity\n\
'other' all other warnings (enabled by default)\n\
'all' all the warnings except 'yacc'\n\
'no-CATEGORY' turn off warnings in CATEGORY\n\
'none' turn off all the warnings\n\
'error[=CATEGORY]' treat warnings as errors\n\
"), stdout);
putc ('\n', stdout);
fputs (_("\
THINGS is a list of comma separated words that can include:\n\
`state' describe the states\n\
`itemset' complete the core item sets with their closure\n\
`lookahead' explicitly associate lookahead tokens to items\n\
`solved' describe shift/reduce conflicts solving\n\
`all' include all the above information\n\
`none' disable the report\n\
'state' describe the states\n\
'itemset' complete the core item sets with their closure\n\
'lookahead' explicitly associate lookahead tokens to items\n\
'solved' describe shift/reduce conflicts solving\n\
'all' include all the above information\n\
'none' disable the report\n\
"), stdout);
putc ('\n', stdout);
fputs (_("\
FEATURE is a list of comma separated words that can include:\n\
`caret' show errors with carets\n\
`all' all of the above\n\
`none' disable all of the above\n\
'caret' show errors with carets\n\
'all' all of the above\n\
'none' disable all of the above\n\
"), stdout);
putc ('\n', stdout);
@@ -517,12 +464,10 @@ static char const short_options[] =
"b:"
"d"
"f::"
"e"
"g::"
"h"
"k"
"l"
"n"
"o:"
"p:"
"r:"
@@ -552,7 +497,6 @@ static struct option const long_options[] =
/* Parser. */
{ "name-prefix", required_argument, 0, 'p' },
{ "include", required_argument, 0, 'I' },
/* Output. */
{ "file-prefix", required_argument, 0, 'b' },
@@ -581,7 +525,6 @@ static struct option const long_options[] =
{ "force-define", required_argument, 0, 'F' },
{ "locations", no_argument, 0, LOCATIONS_OPTION },
{ "no-lines", no_argument, 0, 'l' },
{ "raw", no_argument, 0, 0 },
{ "skeleton", required_argument, 0, 'S' },
{ "language", required_argument, 0, 'L' },
{ "token-table", no_argument, 0, 'k' },
@@ -590,7 +533,7 @@ static struct option const long_options[] =
};
/* Under DOS, there is no difference on the case. This can be
troublesome when looking for `.tab' etc. */
troublesome when looking for '.tab' etc. */
#ifdef MSDOS
# define AS_FILE_NAME(File) (strlwr (File), (File))
#else
@@ -626,24 +569,36 @@ getargs (int argc, char *argv[])
/* Certain long options cause getopt_long to return 0. */
break;
case 'D': /* -DNAME[=VALUE]. */
case 'F': /* -FNAME[=VALUE]. */
case 'D': /* -DNAME[=(VALUE|"VALUE"|{VALUE})]. */
case 'F': /* -FNAME[=(VALUE|"VALUE"|{VALUE})]. */
{
char* name = optarg;
char* value = strchr (optarg, '=');
char *name = optarg;
char *value = strchr (optarg, '=');
muscle_kind kind = muscle_keyword;
if (value)
*value++ = 0;
{
char *end = value + strlen (value) - 1;
*value++ = 0;
if (*value == '{' && *end == '}')
{
kind = muscle_code;
++value;
*end = 0;
}
else if (*value == '"' && *end == '"')
{
kind = muscle_string;
++value;
*end = 0;
}
}
muscle_percent_define_insert (name, command_line_location (),
value ? value : "",
kind, value ? value : "",
c == 'D' ? MUSCLE_PERCENT_DEFINE_D
: MUSCLE_PERCENT_DEFINE_F);
}
break;
case 'I':
include = AS_FILE_NAME (optarg);
break;
case 'L':
language_argmatch (optarg, command_line_prio,
command_line_location ());
@@ -667,7 +622,7 @@ getargs (int argc, char *argv[])
break;
case 'W':
FLAGS_ARGMATCH (warnings, optarg, Wall);
warnings_argmatch (optarg);
break;
case 'b':
@@ -718,7 +673,8 @@ getargs (int argc, char *argv[])
case 't':
muscle_percent_define_insert ("parse.trace",
command_line_location (), "",
command_line_location (),
muscle_keyword, "",
MUSCLE_PERCENT_DEFINE_D);
break;
@@ -736,8 +692,7 @@ getargs (int argc, char *argv[])
break;
case 'y':
warnings_flag |= Wyacc;
errors_flag |= Wyacc;
warning_argmatch ("error=yacc", 0, 6);
yacc_flag = true;
break;
+1
View File
@@ -121,6 +121,7 @@ enum feature
/** What additional features to use. */
extern int feature_flag;
/** Process the command line arguments.
*
* \param argc size of \a argv
+8 -31
View File
@@ -93,16 +93,14 @@ rule_rhs_length (rule const *r)
void
rule_rhs_print (rule const *r, FILE *out)
{
if (*r->rhs >= 0)
if (0 <= *r->rhs)
{
item_number *rp;
for (rp = r->rhs; *rp >= 0; rp++)
fprintf (out, " %s", symbols[*rp]->tag);
}
else
{
fprintf (out, " /* %s */", _("empty"));
}
fputs (" %empty", out);
}
static void
@@ -125,13 +123,6 @@ rule_rhs_print_xml (rule const *r, FILE *out, int level)
}
}
static void
rule_print (rule const *r, FILE *out)
{
fprintf (out, "%s:", r->lhs->tag);
rule_rhs_print (r, out);
}
void
ritem_print (FILE *out)
{
@@ -289,8 +280,8 @@ grammar_dump (FILE *out, const char *title)
rule_number r;
for (r = 0; r < nrules + nuseless_productions; r++)
{
fprintf (out, "%-5d ", r);
rule_print (&rules[r], out);
fprintf (out, "%-5d %s:", r, rules[r].lhs->tag);
rule_rhs_print (&rules[r], out);
fprintf (out, "\n");
}
}
@@ -300,24 +291,10 @@ grammar_dump (FILE *out, const char *title)
void
grammar_rules_useless_report (const char *message)
{
warnings w = Wother;
if (warnings_flag & w)
{
rule_number r;
for (r = 0; r < nrules ; ++r)
if (!rules[r].useful)
{
if (feature_flag & feature_caret)
complain (&rules[r].location, w, "%s", message);
else
{
complain (&rules[r].location, w | silent, "%s: ", message);
rule_print (&rules[r], stderr);
warnings_print_categories (w);
fprintf (stderr, "\n");
}
}
}
rule_number r;
for (r = 0; r < nrules ; ++r)
if (!rules[r].useful)
complain (&rules[r].location, Wother, "%s", message);
}
void
+6 -6
View File
@@ -35,7 +35,7 @@
The rules receive rule numbers 1 to NRULES in the order they are
written. More precisely Bison augments the grammar with the
initial rule, `$accept: START-SYMBOL $end', which is numbered 1,
initial rule, '$accept: START-SYMBOL $end', which is numbered 1,
all the user rules are 2, 3 etc. Each time a rule number is
presented to the user, we subtract 1, so *displayed* rule numbers
are 0, 1, 2...
@@ -61,7 +61,7 @@
RULES[R].prec -- the symbol providing the precedence level of R.
RULES[R].precsym -- the symbol attached (via %prec) to give its
precedence to R. Of course, if set, it is equal to `prec', but we
precedence to R. Of course, if set, it is equal to 'prec', but we
need to distinguish one from the other when reducing: a symbol used
in a %prec is not useless.
@@ -205,11 +205,11 @@ extern rule *rules;
/* A function that selects a rule. */
typedef bool (*rule_filter) (rule const *);
/* Return true IFF the rule has a `number' smaller than NRULES. That is, it is
/* Return true IFF the rule has a 'number' smaller than NRULES. That is, it is
useful in the grammar. */
bool rule_useful_in_grammar_p (rule const *r);
/* Return true IFF the rule has a `number' higher than NRULES. That is, it is
/* Return true IFF the rule has a 'number' higher than NRULES. That is, it is
useless in the grammar. */
bool rule_useless_in_grammar_p (rule const *r);
@@ -262,8 +262,8 @@ void grammar_rules_print_xml (FILE *out, int level);
void grammar_dump (FILE *out, const char *title);
/* Report on STDERR the rules that are not flagged USEFUL, using the
MESSAGE (which can be `rule useless in grammar' when invoked after grammar
reduction, or `rule useless in parser due to conflicts' after conflicts
MESSAGE (which can be 'rule useless in grammar' when invoked after grammar
reduction, or 'rule useless in parser due to conflicts' after conflicts
were taken into account). */
void grammar_rules_useless_report (const char *message);
+20 -24
View File
@@ -67,17 +67,13 @@ static goto_number **includes;
static goto_list **lookback;
void
set_goto_map (void)
{
state_number s;
goto_number *temp_map;
goto_number *temp_map = xnmalloc (nvars + 1, sizeof *temp_map);
goto_map = xcalloc (nvars + 1, sizeof *goto_map);
temp_map = xnmalloc (nvars + 1, sizeof *temp_map);
ngotos = 0;
for (s = 0; s < nstates; ++s)
{
@@ -132,16 +128,13 @@ set_goto_map (void)
goto_number
map_goto (state_number s0, symbol_number sym)
{
goto_number high;
goto_number low;
goto_number middle;
state_number s;
low = goto_map[sym - ntokens];
high = goto_map[sym - ntokens + 1] - 1;
goto_number low = goto_map[sym - ntokens];
goto_number high = goto_map[sym - ntokens + 1] - 1;
for (;;)
{
goto_number middle;
state_number s;
aver (low <= high);
middle = (low + high) / 2;
s = from_state[middle];
@@ -342,7 +335,7 @@ state_lookahead_tokens_count (state *s, bool default_reduction_only_for_accept)
/* We need a lookahead either to distinguish different reductions
(i.e., there are two or more), or to distinguish a reduction from a
shift. Otherwise, it is straightforward, and the state is
`consistent'. However, do not treat a state with any reductions as
'consistent'. However, do not treat a state with any reductions as
consistent unless it is the accepting state (because there is never
a lookahead token that makes sense there, and so no lookahead token
should be read) if the user has otherwise disabled default
@@ -412,7 +405,6 @@ static void
lookahead_tokens_print (FILE *out)
{
state_number i;
int j, k;
fprintf (out, "Lookahead tokens: BEGIN\n");
for (i = 0; i < nstates; ++i)
{
@@ -421,21 +413,25 @@ lookahead_tokens_print (FILE *out)
int n_lookahead_tokens = 0;
if (reds->lookahead_tokens)
for (k = 0; k < reds->num; ++k)
if (reds->lookahead_tokens[k])
++n_lookahead_tokens;
{
int j;
for (j = 0; j < reds->num; ++j)
if (reds->lookahead_tokens[j])
++n_lookahead_tokens;
}
fprintf (out, "State %d: %d lookahead tokens\n",
i, n_lookahead_tokens);
if (reds->lookahead_tokens)
for (j = 0; j < reds->num; ++j)
BITSET_FOR_EACH (iter, reds->lookahead_tokens[j], k, 0)
{
fprintf (out, " on %d (%s) -> rule %d\n",
k, symbols[k]->tag,
reds->rules[j]->number);
};
{
int j, k;
for (j = 0; j < reds->num; ++j)
BITSET_FOR_EACH (iter, reds->lookahead_tokens[j], k, 0)
fprintf (out, " on %d (%s) -> rule %d\n",
k, symbols[k]->tag,
reds->rules[j]->number);
}
}
fprintf (out, "Lookahead tokens: END\n");
}
+3 -1
View File
@@ -111,7 +111,9 @@ BUILT_SOURCES += \
## yacc. ##
## ------ ##
bin_SCRIPTS = $(YACC_SCRIPT)
if ENABLE_YACC
bin_SCRIPTS = src/yacc
endif
EXTRA_SCRIPTS = src/yacc
MOSTLYCLEANFILES += src/yacc
+4 -6
View File
@@ -96,10 +96,8 @@ location_compute (location *loc, boundary *cur, char const *token, size_t size)
}
/* Output to OUT the location LOC.
Warning: it uses quotearg's slot 3. */
unsigned
location_print (FILE *out, location loc)
location_print (location loc, FILE *out)
{
unsigned res = 0;
int end_col = 0 != loc.end.column ? loc.end.column - 1 : 0;
@@ -161,7 +159,7 @@ cleanup_caret ()
}
void
location_caret (FILE *out, location loc)
location_caret (location loc, FILE *out)
{
/* FIXME: find a way to support multifile locations, and only open once each
file. That would make the procedure future-proof. */
@@ -190,7 +188,7 @@ location_caret (FILE *out, location loc)
/* Read the actual line. Don't update the offset, so that we keep a pointer
to the start of the line. */
{
char c = getc (caret_info.source);
int c = getc (caret_info.source);
if (c != EOF)
{
/* Quote the file, indent by a single column. */
@@ -221,7 +219,7 @@ void
boundary_set_from_string (boundary *bound, char *loc_str)
{
/* Must search in reverse since the file name field may
* contain `.' or `:'. */
* contain '.' or ':'. */
char *delim = strrchr (loc_str, '.');
aver (delim);
*delim = '\0';
+10 -5
View File
@@ -20,6 +20,10 @@
#ifndef LOCATION_H_
# define LOCATION_H_
# include <stdbool.h>
# include <stdio.h>
# include <string.h> /* strcmp */
# include "uniqstr.h"
/* A boundary between two characters. */
@@ -98,16 +102,17 @@ extern location const empty_location;
void location_compute (location *loc,
boundary *cur, char const *token, size_t size);
/* Print location to file. Return number of actually printed
characters. */
unsigned location_print (FILE *out, location loc);
/* Print location to file.
Return number of actually printed characters.
Warning: uses quotearg's slot 3. */
unsigned location_print (location loc, FILE *out);
/* Free any allocated ressources and close any open file handles that are
left-over by the usage of location_caret. */
void cleanup_caret (void);
/* Output to OUT the line and caret corresponding to location LOC. */
void location_caret (FILE *out, location loc);
void location_caret (location loc, FILE *out);
/* Return -1, 0, 1, depending whether a is before, equal, or
after b. */
@@ -120,7 +125,7 @@ location_cmp (location a, location b)
return res;
}
/* LOC_STR must be formatted as `file:line.column', it will be modified. */
/* LOC_STR must be formatted as 'file:line.column', it will be modified. */
void boundary_set_from_string (boundary *bound, char *loc_str);
#endif /* ! defined LOCATION_H_ */
+1 -2
View File
@@ -76,6 +76,7 @@ main (int argc, char *argv[])
uniqstrs_new ();
muscle_init ();
complain_init ();
getargs (argc, argv);
@@ -146,8 +147,6 @@ main (int argc, char *argv[])
print_precedence_warnings ();
print_assoc_warnings ();
/* Output file names. */
compute_output_file_names ();
+216 -167
View File
@@ -28,6 +28,31 @@
#include "muscle-tab.h"
#include "quote.h"
muscle_kind
muscle_kind_new (char const *k)
{
if (STREQ (k, "code"))
return muscle_code;
else if (STREQ (k, "keyword"))
return muscle_keyword;
else if (STREQ (k, "string"))
return muscle_string;
aver (0);
}
char const *
muscle_kind_string (muscle_kind k)
{
switch (k)
{
case muscle_code: return "code";
case muscle_keyword: return "keyword";
case muscle_string: return "string";
}
aver (0);
}
/* A key-value pair, along with storage that can be reclaimed when
this pair is no longer needed. */
typedef struct
@@ -35,8 +60,21 @@ typedef struct
char const *key;
char const *value;
char *storage;
muscle_kind kind;
} muscle_entry;
/* The name of muscle for the %define variable VAR (corresponding to
FIELD, if defined). */
static uniqstr
muscle_name (char const *var, char const *field)
{
if (field)
return UNIQSTR_CONCAT ("percent_define_", field, "(", var, ")");
else
return UNIQSTR_CONCAT ("percent_define(", var, ")");
}
/* An obstack used to create some entries. */
struct obstack muscle_obstack;
@@ -60,10 +98,18 @@ hash_muscle (const void *x, size_t tablesize)
return hash_string (m->key, tablesize);
}
/*-----------------------------------------------------------------.
| Create the MUSCLE_TABLE, and initialize it with default values. |
| Also set up the MUSCLE_OBSTACK. |
`-----------------------------------------------------------------*/
/* Create a fresh muscle name KEY, and insert in the hash table. */
static void *
muscle_entry_new (char const *key)
{
muscle_entry *res = xmalloc (sizeof *res);
res->key = key;
res->value = NULL;
res->storage = NULL;
if (!hash_insert (muscle_table, res))
xalloc_die ();
return res;
}
static void
muscle_entry_free (void *entry)
@@ -87,10 +133,6 @@ muscle_init (void)
}
/*------------------------------------------------------------.
| Free all the memory consumed by the muscle machinery only. |
`------------------------------------------------------------*/
void
muscle_free (void)
{
@@ -98,71 +140,64 @@ muscle_free (void)
obstack_free (&muscle_obstack, NULL);
}
/* Look for the muscle named KEY. Return NULL if does not exist. */
static
muscle_entry *
muscle_lookup (char const *key)
{
muscle_entry probe;
probe.key = key;
return hash_lookup (muscle_table, &probe);
}
/*------------------------------------------------------------.
| Insert (KEY, VALUE). If KEY already existed, overwrite the |
| previous value. |
`------------------------------------------------------------*/
void
muscle_insert (char const *key, char const *value)
{
muscle_entry probe;
muscle_entry *entry;
probe.key = key;
entry = hash_lookup (muscle_table, &probe);
if (!entry)
{
/* First insertion in the hash. */
entry = xmalloc (sizeof *entry);
entry->key = key;
if (!hash_insert (muscle_table, entry))
xalloc_die ();
}
else
muscle_entry *entry = muscle_lookup (key);
if (entry)
free (entry->storage);
else
/* First insertion in the hash. */
entry = muscle_entry_new (key);
entry->value = value;
entry->storage = NULL;
}
/*-------------------------------------------------------------------.
| Append VALUE to the current value of KEY. If KEY did not already |
| exist, create it. Use MUSCLE_OBSTACK. De-allocate the previously |
| associated value. Copy VALUE and SEPARATOR. |
`-------------------------------------------------------------------*/
/* Append VALUE to the current value of KEY. If KEY did not already
exist, create it. Use MUSCLE_OBSTACK. De-allocate the previously
associated value. Copy VALUE and SEPARATOR. If VALUE does not end
with TERMINATOR, append one. */
void
muscle_grow (const char *key, const char *val, const char *separator)
static void
muscle_grow (const char *key, const char *val,
const char *separator, const char *terminator)
{
muscle_entry probe;
muscle_entry *entry = NULL;
muscle_entry *entry = muscle_lookup (key);
size_t vals = strlen (val);
size_t terms = strlen (terminator);
probe.key = key;
entry = hash_lookup (muscle_table, &probe);
if (!entry)
if (entry)
{
/* First insertion in the hash. */
entry = xmalloc (sizeof *entry);
entry->key = key;
if (!hash_insert (muscle_table, entry))
xalloc_die ();
entry->value = entry->storage = xstrdup (val);
obstack_sgrow (&muscle_obstack, entry->value);
obstack_sgrow (&muscle_obstack, separator);
free (entry->storage);
}
else
{
/* Grow the current value. */
char *new_val;
obstack_printf (&muscle_obstack, "%s%s%s", entry->value, separator, val);
free (entry->storage);
new_val = obstack_finish0 (&muscle_obstack);
entry->value = entry->storage = xstrdup (new_val);
obstack_free (&muscle_obstack, new_val);
}
entry = muscle_entry_new (key);
obstack_sgrow (&muscle_obstack, val);
if (terms <= vals
&& STRNEQ (val + vals - terms, terminator))
obstack_sgrow (&muscle_obstack, terminator);
{
char *new_val = obstack_finish0 (&muscle_obstack);
entry->value = entry->storage = xstrdup (new_val);
obstack_free (&muscle_obstack, new_val);
}
}
/*------------------------------------------------------------------.
@@ -179,7 +214,7 @@ muscle_syncline_grow (char const *key, location loc)
quotearg_style (c_quoting_style, loc.start.file));
obstack_sgrow (&muscle_obstack, ")[");
extension = obstack_finish0 (&muscle_obstack);
muscle_grow (key, extension, "");
muscle_grow (key, extension, "", "");
obstack_free (&muscle_obstack, extension);
}
@@ -193,12 +228,13 @@ void
muscle_code_grow (const char *key, const char *val, location loc)
{
muscle_syncline_grow (key, loc);
muscle_grow (key, val, "\n");
muscle_grow (key, val, "\n", "\n");
}
void muscle_pair_list_grow (const char *muscle,
const char *a1, const char *a2)
void
muscle_pair_list_grow (const char *muscle,
const char *a1, const char *a2)
{
char *pair;
obstack_sgrow (&muscle_obstack, "[");
@@ -207,54 +243,33 @@ void muscle_pair_list_grow (const char *muscle,
obstack_quote (&muscle_obstack, a2);
obstack_sgrow (&muscle_obstack, "]");
pair = obstack_finish0 (&muscle_obstack);
muscle_grow (muscle, pair, ",\n");
muscle_grow (muscle, pair, ",\n", "");
obstack_free (&muscle_obstack, pair);
}
/*----------------------------------------------------------------------------.
| Find the value of muscle KEY. Unlike MUSCLE_FIND, this is always reliable |
| to determine whether KEY has a value. |
`----------------------------------------------------------------------------*/
char const *
muscle_find_const (char const *key)
{
muscle_entry probe;
muscle_entry *result = NULL;
probe.key = key;
result = hash_lookup (muscle_table, &probe);
if (result)
return result->value;
return NULL;
muscle_entry *entry = muscle_lookup (key);
return entry ? entry->value : NULL;
}
/*----------------------------------------------------------------------------.
| Find the value of muscle KEY. Abort if muscle_insert was invoked more |
| recently than muscle_grow for KEY since muscle_find can't return a |
| char const *. |
`----------------------------------------------------------------------------*/
char *
muscle_find (char const *key)
{
muscle_entry probe;
muscle_entry *result = NULL;
probe.key = key;
result = hash_lookup (muscle_table, &probe);
if (result)
muscle_entry *entry = muscle_lookup (key);
if (entry)
{
aver (result->value == result->storage);
return result->storage;
aver (entry->value == entry->storage);
return entry->storage;
}
return NULL;
}
/* In the format `file_name:line.column', append BOUND to MUSCLE. Use
/* In the format 'file_name:line.column', append BOUND to MUSCLE. Use
digraphs for special characters in the file name. */
static void
@@ -265,12 +280,12 @@ muscle_boundary_grow (char const *key, boundary bound)
obstack_escape (&muscle_obstack, bound.file);
obstack_printf (&muscle_obstack, ":%d.%d]]", bound.line, bound.column);
extension = obstack_finish0 (&muscle_obstack);
muscle_grow (key, extension, "");
muscle_grow (key, extension, "", "");
obstack_free (&muscle_obstack, extension);
}
/* In the format `[[file_name:line.column]], [[file_name:line.column]]',
/* In the format '[[file_name:line.column]], [[file_name:line.column]]',
append LOC to MUSCLE. Use digraphs for special characters in each
file name. */
@@ -278,14 +293,15 @@ static void
muscle_location_grow (char const *key, location loc)
{
muscle_boundary_grow (key, loc.start);
muscle_grow (key, "", ", ");
muscle_grow (key, "", ", ", "");
muscle_boundary_grow (key, loc.end);
}
#define COMMON_DECODE(Value) \
case '$': \
aver (*++(Value) == ']'); \
aver (*++(Value) == '['); \
++(Value); aver (*(Value) == '['); \
++(Value); aver (*(Value) == ']'); \
++(Value); aver (*(Value) == '['); \
obstack_sgrow (&muscle_obstack, "$"); \
break; \
case '@': \
@@ -329,13 +345,12 @@ string_decode (char const *key)
/* Reverse of muscle_location_grow. */
static location
location_decode (char const *key)
location_decode (char const *value)
{
location loc;
char const *value = muscle_find_const (key);
aver (value);
aver (*value == '[');
aver (*++value == '[');
++value; aver (*value == '[');
while (*++value)
switch (*value)
{
@@ -346,16 +361,16 @@ location_decode (char const *key)
case ']':
{
char *boundary_str;
aver (*++value == ']');
++value; aver (*value == ']');
boundary_str = obstack_finish0 (&muscle_obstack);
switch (*++value)
{
case ',':
boundary_set_from_string (&loc.start, boundary_str);
obstack_free (&muscle_obstack, boundary_str);
aver (*++value == ' ');
aver (*++value == '[');
aver (*++value == '[');
++value; aver (*value == ' ');
++value; aver (*value == '[');
++value; aver (*value == '[');
break;
case '\0':
boundary_set_from_string (&loc.end, boundary_str);
@@ -377,11 +392,11 @@ void
muscle_user_name_list_grow (char const *key, char const *user_name,
location loc)
{
muscle_grow (key, "[[[[", ",");
muscle_grow (key, user_name, "");
muscle_grow (key, "]], ", "");
muscle_grow (key, "[[[[", ",", "");
muscle_grow (key, user_name, "", "");
muscle_grow (key, "]], ", "", "");
muscle_location_grow (key, loc);
muscle_grow (key, "]]", "");
muscle_grow (key, "]]", "", "");
}
@@ -475,16 +490,17 @@ muscle_percent_variable_update (char const *variable, location variable_loc,
void
muscle_percent_define_insert (char const *var, location variable_loc,
muscle_kind kind,
char const *value,
muscle_percent_define_how how)
{
/* Backward compatibility. */
char *variable = muscle_percent_variable_update (var, variable_loc, &value);
char const *name = UNIQSTR_CONCAT ("percent_define(", variable, ")");
char const *loc_name = UNIQSTR_CONCAT ("percent_define_loc(", variable, ")");
char const *syncline_name =
UNIQSTR_CONCAT ("percent_define_syncline(", variable, ")");
char const *how_name = UNIQSTR_CONCAT ("percent_define_how(", variable, ")");
uniqstr name = muscle_name (variable, NULL);
uniqstr loc_name = muscle_name (variable, "loc");
uniqstr syncline_name = muscle_name (variable, "syncline");
uniqstr how_name = muscle_name (variable, "how");
uniqstr kind_name = muscle_name (variable, "kind");
/* Command-line options are processed before the grammar file. */
if (how == MUSCLE_PERCENT_DEFINE_GRAMMAR_FILE
@@ -510,6 +526,7 @@ muscle_percent_define_insert (char const *var, location variable_loc,
muscle_user_name_list_grow ("percent_define_user_variables", variable,
variable_loc);
MUSCLE_INSERT_INT (how_name, how);
MUSCLE_INSERT_STRING (kind_name, muscle_kind_string (kind));
end:
free (variable);
}
@@ -520,85 +537,120 @@ void
muscle_percent_define_ensure (char const *variable, location loc,
bool value)
{
uniqstr name = muscle_name (variable, NULL);
char const *val = value ? "" : "false";
char const *name = UNIQSTR_CONCAT ("percent_define(", variable, ")");
/* %pure-parser is deprecated in favor of `%define api.pure', so use
`%define api.pure' in a backward-compatible manner here. First,
don't complain if %pure-parser is specified multiple times. */
if (!muscle_find_const (name))
muscle_percent_define_insert (variable, loc, val,
MUSCLE_PERCENT_DEFINE_GRAMMAR_FILE);
/* In all cases, use api.pure now so that the backend doesn't complain if
the skeleton ignores api.pure, but do warn now if there's a previous
conflicting definition from an actual %define. */
if (muscle_percent_define_flag_if (variable) != value)
muscle_percent_define_insert (variable, loc, val,
/* Don't complain is VARIABLE is already defined, but be sure to set
its value to VAL. */
if (!muscle_find_const (name)
|| muscle_percent_define_flag_if (variable) != value)
muscle_percent_define_insert (variable, loc, muscle_keyword, val,
MUSCLE_PERCENT_DEFINE_GRAMMAR_FILE);
}
/* Mark %define VARIABLE as used. */
static void
muscle_percent_define_use (char const *variable)
{
muscle_insert (muscle_name (variable, "bison_variables"), "");
}
/* The value of %define variable VARIABLE (corresponding to FIELD, if
defined). Do not register as used, but diagnose unset variables. */
static
char const *
muscle_percent_define_get_raw (char const *variable, char const *field)
{
uniqstr name = muscle_name (variable, field);
char const *res = muscle_find_const (name);
if (!res)
complain (NULL, fatal, _("%s: undefined %%define variable %s"),
"muscle_percent_define_get_raw", quote (variable));
return res;
}
char *
muscle_percent_define_get (char const *variable)
{
char const *name = UNIQSTR_CONCAT ("percent_define(", variable, ")");
char const *usage_name =
UNIQSTR_CONCAT ("percent_define_bison_variables(", variable, ")");
uniqstr name = muscle_name (variable, NULL);
char *value = string_decode (name);
if (!value)
value = xstrdup ("");
muscle_insert (usage_name, "");
muscle_percent_define_use (variable);
return value;
}
/* The kind of VARIABLE. An error if undefined. */
static muscle_kind
muscle_percent_define_get_kind (char const *variable)
{
return muscle_kind_new (muscle_percent_define_get_raw (variable, "kind"));
}
/* Check the kind of VARIABLE. An error if undefined. */
static void
muscle_percent_define_check_kind (char const *variable, muscle_kind kind)
{
if (muscle_percent_define_get_kind (variable) != kind)
{
location loc = muscle_percent_define_get_loc (variable);
switch (kind)
{
case muscle_code:
complain (&loc, Wdeprecated,
"%%define variable '%s' requires '{...}' values",
variable);
break;
case muscle_keyword:
complain (&loc, Wdeprecated,
"%%define variable '%s' requires keyword values",
variable);
break;
case muscle_string:
complain (&loc, Wdeprecated,
"%%define variable '%s' requires '\"...\"' values",
variable);
break;
}
}
}
location
muscle_percent_define_get_loc (char const *variable)
{
char const *loc_name = UNIQSTR_CONCAT ("percent_define_loc(", variable, ")");
if (!muscle_find_const (loc_name))
complain (NULL, fatal, _("%s: undefined %%define variable %s"),
"muscle_percent_define_get_loc", quote (variable));
return location_decode (loc_name);
return location_decode (muscle_percent_define_get_raw (variable, "loc"));
}
char const *
muscle_percent_define_get_syncline (char const *variable)
{
char const *syncline_name =
UNIQSTR_CONCAT ("percent_define_syncline(", variable, ")");
char const *syncline = muscle_find_const (syncline_name);
if (!syncline)
complain (NULL, fatal, _("%s: undefined %%define variable %s"),
"muscle_percent_define_get_syncline", quote (variable));
return syncline;
return muscle_percent_define_get_raw (variable, "syncline");
}
bool
muscle_percent_define_ifdef (char const *variable)
{
char const *name = UNIQSTR_CONCAT ("percent_define(", variable, ")");
char const *usage_name =
UNIQSTR_CONCAT ("percent_define_bison_variables(", variable, ")");
char const *value = muscle_find_const (name);
if (value)
if (muscle_find_const (muscle_name (variable, NULL)))
{
muscle_insert (usage_name, "");
muscle_percent_define_use (variable);
return true;
}
return false;
else
return false;
}
bool
muscle_percent_define_flag_if (char const *variable)
{
char const *invalid_boolean_name =
UNIQSTR_CONCAT ("percent_define_invalid_boolean(", variable, ")");
uniqstr invalid_boolean_name = muscle_name (variable, "invalid_boolean");
bool result = false;
if (muscle_percent_define_ifdef (variable))
{
char *value = muscle_percent_define_get (variable);
muscle_percent_define_check_kind (variable, muscle_keyword);
if (value[0] == '\0' || STREQ (value, "true"))
result = true;
else if (STREQ (value, "false"))
@@ -623,20 +675,21 @@ muscle_percent_define_flag_if (char const *variable)
void
muscle_percent_define_default (char const *variable, char const *value)
{
char const *name = UNIQSTR_CONCAT ("percent_define(", variable, ")");
char const *loc_name = UNIQSTR_CONCAT ("percent_define_loc(", variable, ")");
char const *syncline_name =
UNIQSTR_CONCAT ("percent_define_syncline(", variable, ")");
uniqstr name = muscle_name (variable, NULL);
if (!muscle_find_const (name))
{
location loc;
MUSCLE_INSERT_STRING (name, value);
loc.start.file = loc.end.file = "<default value>";
loc.start.line = loc.end.line = -1;
loc.start.column = loc.end.column = -1;
muscle_insert (loc_name, "");
muscle_location_grow (loc_name, loc);
muscle_insert (syncline_name, "");
MUSCLE_INSERT_STRING (muscle_name (variable, "kind"), "keyword");
{
uniqstr loc_name = muscle_name (variable, "loc");
location loc;
loc.start.file = loc.end.file = "<default value>";
loc.start.line = loc.end.line = -1;
loc.start.column = loc.end.column = -1;
muscle_insert (loc_name, "");
muscle_location_grow (loc_name, loc);
}
muscle_insert (muscle_name (variable, "syncline"), "");
}
}
@@ -646,8 +699,9 @@ muscle_percent_define_check_values (char const * const *values)
for (; *values; ++values)
{
char const * const *variablep = values;
char const *name = UNIQSTR_CONCAT ("percent_define(", *variablep, ")");
uniqstr name = muscle_name (*variablep, NULL);
char *value = string_decode (name);
muscle_percent_define_check_kind (*variablep, muscle_keyword);
if (value)
{
for (++values; *values; ++values)
@@ -664,7 +718,7 @@ muscle_percent_define_check_values (char const * const *values)
quote (*variablep), quote_n (1, value));
i += SUB_INDENT;
for (values = variablep + 1; *values; ++values)
complain_indent (&loc, complaint | no_caret, &i,
complain_indent (&loc, complaint | no_caret | silent, &i,
_("accepted value: %s"), quote (*values));
}
else
@@ -711,11 +765,6 @@ muscle_m4_output_processor (void *entry, void *out)
}
/*----------------------------------------------------------------.
| Output the definition of all the current muscles into a list of |
| m4_defines. |
`----------------------------------------------------------------*/
void
muscles_m4_output (FILE *out)
{
+44 -18
View File
@@ -24,10 +24,41 @@
# include "location.h"
/* The kind of value associated to this muscle, depending on the
syntax of the value: keyword (no delimiter, e.g., true), string
(double quotes, e.g., "foo.h"), or code (braces, e.g., {int}). */
typedef enum
{
muscle_code,
muscle_keyword,
muscle_string
} muscle_kind;
/* Conversion from string. */
muscle_kind muscle_kind_new (char const *k);
/* Conversion to string. */
char const *muscle_kind_string (muscle_kind k);
/* Create the MUSCLE_TABLE, and initialize it with default values.
Also set up the MUSCLE_OBSTACK. */
void muscle_init (void);
/* Insert (KEY, VALUE). If KEY already existed, overwrite the
previous value. Otherwise create as a muscle_string type. */
void muscle_insert (char const *key, char const *value);
/* Find the value of muscle KEY. Unlike MUSCLE_FIND, this is always
reliable to determine whether KEY has a value. */
char const *muscle_find_const (char const *key);
/* Find the value of muscle KEY. Abort if muscle_insert was invoked
more recently than muscle_grow for KEY since muscle_find can't
return a char const *. */
char *muscle_find (char const *key);
/* Free all the memory consumed by the muscle machinery only. */
void muscle_free (void);
@@ -47,14 +78,14 @@ extern struct obstack muscle_obstack;
} while (0)
# define MUSCLE_INSERT_INT(Key, Value) \
MUSCLE_INSERTF(Key, "%d", Value)
MUSCLE_INSERTF (Key, "%d", Value)
# define MUSCLE_INSERT_LONG_INT(Key, Value) \
MUSCLE_INSERTF(Key, "%ld", Value)
MUSCLE_INSERTF (Key, "%ld", Value)
/* Key -> Value, but don't apply escaping to Value. */
# define MUSCLE_INSERT_STRING_RAW(Key, Value) \
MUSCLE_INSERTF(Key, "%s", Value)
MUSCLE_INSERTF (Key, "%s", Value)
/* Key -> Value, applying M4 escaping to Value. */
# define MUSCLE_INSERT_STRING(Key, Value) \
@@ -63,23 +94,14 @@ extern struct obstack muscle_obstack;
muscle_insert (Key, obstack_finish0 (&muscle_obstack)); \
} while (0)
/* Key -> Value, applying C escaping to Value (and then M4). */
# define MUSCLE_INSERT_C_STRING(Key, Value) \
do { \
obstack_escape (&muscle_obstack, \
quotearg_style (c_quoting_style, Value)); \
muscle_insert (Key, obstack_finish0 (&muscle_obstack)); \
} while (0)
/* Append VALUE to the current value of KEY. If KEY did not already
exist, create it. Use MUSCLE_OBSTACK. De-allocate the previously
associated value. Copy VALUE and SEPARATOR. */
void muscle_grow (const char *key, const char *value, const char *separator);
MUSCLE_INSERT_STRING (Key, quotearg_style (c_quoting_style, Value))
/* Append VALUE to the current value of KEY, using muscle_grow. But
in addition, issue a synchronization line for the location LOC. */
in addition, issue a synchronization line for the location LOC.
Be sure to append on a new line. */
void muscle_code_grow (const char *key, const char *value, location loc);
@@ -92,14 +114,15 @@ void muscle_pair_list_grow (const char *muscle,
/* Grow KEY for the occurrence of the name USER_NAME at LOC appropriately for
use with b4_check_user_names in ../data/bison.m4. USER_NAME is not escaped
with digraphs, so it must not contain `[' or `]'. */
with digraphs, so it must not contain '[' or ']'. */
void muscle_user_name_list_grow (char const *key, char const *user_name,
location loc);
/* Indicates whether a variable's value was specified with -D/--define, with
-F/--force-define, or in the grammar file. */
typedef enum {
MUSCLE_PERCENT_DEFINE_D = 0, MUSCLE_PERCENT_DEFINE_F,
MUSCLE_PERCENT_DEFINE_D = 0,
MUSCLE_PERCENT_DEFINE_F,
MUSCLE_PERCENT_DEFINE_GRAMMAR_FILE
} muscle_percent_define_how;
@@ -113,6 +136,7 @@ typedef enum {
this as a user occurrence of VARIABLE by invoking
muscle_user_name_list_grow. */
void muscle_percent_define_insert (char const *variable, location variable_loc,
muscle_kind kind,
char const *value,
muscle_percent_define_how how);
@@ -186,6 +210,8 @@ void muscle_percent_define_check_values (char const * const *values);
void muscle_percent_code_grow (char const *qualifier, location qualifier_loc,
char const *code, location code_loc);
/* Output the definition of all the current muscles into a list of
m4_defines. */
void muscles_m4_output (FILE *out);
#endif /* not MUSCLE_TAB_H_ */
+25 -21
View File
@@ -90,20 +90,19 @@ Name (char const *name, \
\
lmin = min; \
lmax = max; \
/* Build `NAME_min' and `NAME_max' in the obstack. */ \
/* 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); \
obstack_printf (&format_obstack, "%s_max", 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_int_table, int)
GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_base_table, base_number)
GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_rule_number_table, rule_number)
GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_symbol_number_table, symbol_number)
GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_state_number_table, state_number)
GENERATE_MUSCLE_INSERT_TABLE (muscle_insert_unsigned_int_table, unsigned int)
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)
GENERATE_MUSCLE_INSERT_TABLE (muscle_insert_symbol_number_table, symbol_number)
GENERATE_MUSCLE_INSERT_TABLE (muscle_insert_state_number_table, state_number)
/*----------------------------------------------------------------.
| Print to OUT a representation of CP quoted and escaped for M4. |
@@ -227,7 +226,7 @@ prepare_rules (void)
/* LHS of the rule R. */
r1[r] = rules[r].lhs->number;
/* Length of rule R's RHS. */
r2[r] = rule_rhs_length(&rules[r]);
r2[r] = rule_rhs_length (&rules[r]);
/* Line where rule was defined. */
rline[r] = rules[r].location.start.line;
/* Dynamic precedence (GLR). */
@@ -417,31 +416,31 @@ prepare_symbol_definitions (void)
/* Whether the symbol has an identifier. */
value = symbol_id_get (sym);
SET_KEY("has_id");
SET_KEY ("has_id");
MUSCLE_INSERT_INT (key, !!value);
/* Its identifier. */
SET_KEY("id");
SET_KEY ("id");
MUSCLE_INSERT_STRING (key, value ? value : "");
/* Its tag. Typically for documentation purpose. */
SET_KEY("tag");
SET_KEY ("tag");
MUSCLE_INSERT_STRING (key, sym->tag);
SET_KEY("user_number");
SET_KEY ("user_number");
MUSCLE_INSERT_INT (key, sym->user_token_number);
SET_KEY("is_token");
SET_KEY ("is_token");
MUSCLE_INSERT_INT (key,
i < ntokens && sym != errtoken && sym != undeftoken);
SET_KEY("number");
SET_KEY ("number");
MUSCLE_INSERT_INT (key, sym->number);
SET_KEY("has_type");
SET_KEY ("has_type");
MUSCLE_INSERT_INT (key, !!sym->type_name);
SET_KEY("type");
SET_KEY ("type");
MUSCLE_INSERT_STRING (key, sym->type_name ? sym->type_name : "");
{
@@ -451,18 +450,18 @@ prepare_symbol_definitions (void)
/* "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);
SET_KEY2 ("has", pname);
MUSCLE_INSERT_INT (key, !!p->code);
if (p->code)
{
SET_KEY2(pname, "file");
SET_KEY2 (pname, "file");
MUSCLE_INSERT_STRING (key, p->location.start.file);
SET_KEY2(pname, "line");
SET_KEY2 (pname, "line");
MUSCLE_INSERT_INT (key, p->location.start.line);
SET_KEY(pname);
SET_KEY (pname);
MUSCLE_INSERT_STRING_RAW (key, p->code);
}
}
@@ -705,6 +704,11 @@ output (void)
/* Process the selected skeleton file. */
output_skeleton ();
/* If late errors were generated, destroy the generated source
files. */
if (complaint_status)
unlink_generated_sources ();
obstack_free (&format_obstack, NULL);
}
+704 -702
View File
File diff suppressed because it is too large Load Diff
+89 -133
View File
@@ -1,4 +1,4 @@
/* A Bison parser, made by GNU Bison 2.7.1021-bb417-dirty. */
/* A Bison parser, made by GNU Bison 3.0. */
/* Bison interface for Yacc-like parsers in C
@@ -48,10 +48,12 @@
extern int gram_debug;
#endif
/* "%code requires" blocks. */
#line 223 "src/parse-gram.y" /* yacc.c:1932 */
#line 21 "src/parse-gram.y" /* yacc.c:1909 */
#include "symlist.h"
#include "symtab.h"
#line 221 "src/parse-gram.y" /* yacc.c:1909 */
# ifndef PARAM_TYPE
# define PARAM_TYPE
typedef enum
{
param_none = 0,
@@ -59,10 +61,10 @@ extern int gram_debug;
param_parse = 1 << 1,
param_both = param_lex | param_parse
} param_type;
# endif
#line 645 "src/parse-gram.y" /* yacc.c:1909 */
#include "muscle-tab.h"
#line 66 "src/parse-gram.h" /* yacc.c:1932 */
#line 68 "src/parse-gram.h" /* yacc.c:1909 */
/* Token type. */
#ifndef GRAM_TOKENTYPE
@@ -71,143 +73,97 @@ extern int gram_debug;
{
GRAM_EOF = 0,
STRING = 258,
INT = 259,
PERCENT_TOKEN = 260,
PERCENT_NTERM = 261,
PERCENT_TYPE = 262,
PERCENT_DESTRUCTOR = 263,
PERCENT_PRINTER = 264,
PERCENT_LEFT = 265,
PERCENT_RIGHT = 266,
PERCENT_NONASSOC = 267,
PERCENT_PRECEDENCE = 268,
PERCENT_PREC = 269,
PERCENT_DPREC = 270,
PERCENT_MERGE = 271,
PERCENT_CODE = 272,
PERCENT_DEFAULT_PREC = 273,
PERCENT_DEFINE = 274,
PERCENT_DEFINES = 275,
PERCENT_ERROR_VERBOSE = 276,
PERCENT_EXPECT = 277,
PERCENT_EXPECT_RR = 278,
PERCENT_FLAG = 279,
PERCENT_FILE_PREFIX = 280,
PERCENT_GLR_PARSER = 281,
PERCENT_INITIAL_ACTION = 282,
PERCENT_LANGUAGE = 283,
PERCENT_NAME_PREFIX = 284,
PERCENT_NO_DEFAULT_PREC = 285,
PERCENT_NO_LINES = 286,
PERCENT_NONDETERMINISTIC_PARSER = 287,
PERCENT_OUTPUT = 288,
PERCENT_REQUIRE = 289,
PERCENT_SKELETON = 290,
PERCENT_START = 291,
PERCENT_TOKEN_TABLE = 292,
PERCENT_VERBOSE = 293,
PERCENT_YACC = 294,
BRACED_CODE = 295,
BRACED_PREDICATE = 296,
BRACKETED_ID = 297,
CHAR = 298,
EPILOGUE = 299,
EQUAL = 300,
ID = 301,
ID_COLON = 302,
PERCENT_PERCENT = 303,
PIPE = 304,
PROLOGUE = 305,
SEMICOLON = 306,
TAG = 307,
TAG_ANY = 308,
TAG_NONE = 309,
PERCENT_TOKEN = 259,
PERCENT_NTERM = 260,
PERCENT_TYPE = 261,
PERCENT_DESTRUCTOR = 262,
PERCENT_PRINTER = 263,
PERCENT_LEFT = 264,
PERCENT_RIGHT = 265,
PERCENT_NONASSOC = 266,
PERCENT_PRECEDENCE = 267,
PERCENT_PREC = 268,
PERCENT_DPREC = 269,
PERCENT_MERGE = 270,
PERCENT_CODE = 271,
PERCENT_DEFAULT_PREC = 272,
PERCENT_DEFINE = 273,
PERCENT_DEFINES = 274,
PERCENT_ERROR_VERBOSE = 275,
PERCENT_EXPECT = 276,
PERCENT_EXPECT_RR = 277,
PERCENT_FLAG = 278,
PERCENT_FILE_PREFIX = 279,
PERCENT_GLR_PARSER = 280,
PERCENT_INITIAL_ACTION = 281,
PERCENT_LANGUAGE = 282,
PERCENT_NAME_PREFIX = 283,
PERCENT_NO_DEFAULT_PREC = 284,
PERCENT_NO_LINES = 285,
PERCENT_NONDETERMINISTIC_PARSER = 286,
PERCENT_OUTPUT = 287,
PERCENT_REQUIRE = 288,
PERCENT_SKELETON = 289,
PERCENT_START = 290,
PERCENT_TOKEN_TABLE = 291,
PERCENT_VERBOSE = 292,
PERCENT_YACC = 293,
BRACED_CODE = 294,
BRACED_PREDICATE = 295,
BRACKETED_ID = 296,
CHAR = 297,
EPILOGUE = 298,
EQUAL = 299,
ID = 300,
ID_COLON = 301,
PERCENT_PERCENT = 302,
PIPE = 303,
PROLOGUE = 304,
SEMICOLON = 305,
TAG = 306,
TAG_ANY = 307,
TAG_NONE = 308,
INT = 309,
PERCENT_PARAM = 310,
PERCENT_UNION = 311
PERCENT_UNION = 311,
PERCENT_EMPTY = 312
};
#endif
/* Tokens. */
#define GRAM_EOF 0
#define STRING 258
#define INT 259
#define PERCENT_TOKEN 260
#define PERCENT_NTERM 261
#define PERCENT_TYPE 262
#define PERCENT_DESTRUCTOR 263
#define PERCENT_PRINTER 264
#define PERCENT_LEFT 265
#define PERCENT_RIGHT 266
#define PERCENT_NONASSOC 267
#define PERCENT_PRECEDENCE 268
#define PERCENT_PREC 269
#define PERCENT_DPREC 270
#define PERCENT_MERGE 271
#define PERCENT_CODE 272
#define PERCENT_DEFAULT_PREC 273
#define PERCENT_DEFINE 274
#define PERCENT_DEFINES 275
#define PERCENT_ERROR_VERBOSE 276
#define PERCENT_EXPECT 277
#define PERCENT_EXPECT_RR 278
#define PERCENT_FLAG 279
#define PERCENT_FILE_PREFIX 280
#define PERCENT_GLR_PARSER 281
#define PERCENT_INITIAL_ACTION 282
#define PERCENT_LANGUAGE 283
#define PERCENT_NAME_PREFIX 284
#define PERCENT_NO_DEFAULT_PREC 285
#define PERCENT_NO_LINES 286
#define PERCENT_NONDETERMINISTIC_PARSER 287
#define PERCENT_OUTPUT 288
#define PERCENT_REQUIRE 289
#define PERCENT_SKELETON 290
#define PERCENT_START 291
#define PERCENT_TOKEN_TABLE 292
#define PERCENT_VERBOSE 293
#define PERCENT_YACC 294
#define BRACED_CODE 295
#define BRACED_PREDICATE 296
#define BRACKETED_ID 297
#define CHAR 298
#define EPILOGUE 299
#define EQUAL 300
#define ID 301
#define ID_COLON 302
#define PERCENT_PERCENT 303
#define PIPE 304
#define PROLOGUE 305
#define SEMICOLON 306
#define TAG 307
#define TAG_ANY 308
#define TAG_NONE 309
#define PERCENT_PARAM 310
#define PERCENT_UNION 311
/* Value type. */
#if ! defined GRAM_STYPE && ! defined GRAM_STYPE_IS_DECLARED
typedef union GRAM_STYPE GRAM_STYPE;
union GRAM_STYPE
{
#line 109 "src/parse-gram.y" /* yacc.c:1932 */
assoc assoc;
char *code;
char const *chars;
int integer;
named_ref *named_ref;
symbol *symbol;
symbol_list *list;
uniqstr uniqstr;
unsigned char character;
#line 247 "src/parse-gram.y" /* yacc.c:1932 */
param_type param;
#line 423 "src/parse-gram.y" /* yacc.c:1932 */
#line 182 "src/parse-gram.y" /* yacc.c:1909 */
unsigned char character;
#line 186 "src/parse-gram.y" /* yacc.c:1909 */
char *code;
#line 191 "src/parse-gram.y" /* yacc.c:1909 */
uniqstr uniqstr;
#line 199 "src/parse-gram.y" /* yacc.c:1909 */
int integer;
#line 203 "src/parse-gram.y" /* yacc.c:1909 */
symbol *symbol;
#line 208 "src/parse-gram.y" /* yacc.c:1909 */
assoc assoc;
#line 211 "src/parse-gram.y" /* yacc.c:1909 */
symbol_list *list;
#line 214 "src/parse-gram.y" /* yacc.c:1909 */
named_ref *named_ref;
#line 241 "src/parse-gram.y" /* yacc.c:1909 */
param_type param;
#line 409 "src/parse-gram.y" /* yacc.c:1909 */
code_props_type code_type;
#line 647 "src/parse-gram.y" /* yacc.c:1909 */
#line 211 "src/parse-gram.h" /* yacc.c:1932 */
struct
{
char const *chars;
muscle_kind kind;
} value;
#line 167 "src/parse-gram.h" /* yacc.c:1909 */
};
# define GRAM_STYPE_IS_TRIVIAL 1
# define GRAM_STYPE_IS_DECLARED 1
+184 -145
View File
@@ -1,4 +1,4 @@
%{/* Bison Grammar Parser -*- C -*-
/* Bison Grammar Parser -*- C -*-
Copyright (C) 2002-2013 Free Software Foundation, Inc.
@@ -17,45 +17,35 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
%code requires
{
#include "symlist.h"
#include "symtab.h"
}
%code top
{
/* On column 0 to please syntax-check. */
#include <config.h>
#include "system.h"
#include "c-ctype.h"
#include "complain.h"
#include "conflicts.h"
#include "files.h"
#include "getargs.h"
#include "gram.h"
#include "muscle-tab.h"
#include "named-ref.h"
#include "quotearg.h"
#include "reader.h"
#include "symlist.h"
#include "symtab.h"
#include "scan-gram.h"
#include "scan-code.h"
#include "xmemdup0.h"
#define YYLLOC_DEFAULT(Current, Rhs, N) (Current) = lloc_default (Rhs, N)
static YYLTYPE lloc_default (YYLTYPE const *, int);
#define YY_LOCATION_PRINT(File, Loc) \
location_print (File, Loc)
static void version_check (location const *loc, char const *version);
/* Request detailed syntax error messages, and pass them to GRAM_ERROR.
FIXME: depends on the undocumented availability of YYLLOC. */
#undef yyerror
#define yyerror(Msg) \
gram_error (&yylloc, Msg)
static void gram_error (location const *, char const *);
static char const *char_name (char);
%}
}
%code
{
#include "system.h"
#include "c-ctype.h"
#include "complain.h"
#include "conflicts.h"
#include "files.h"
#include "getargs.h"
#include "gram.h"
#include "named-ref.h"
#include "quotearg.h"
#include "reader.h"
#include "scan-gram.h"
#include "scan-code.h"
#include "xmemdup0.h"
static int current_prec = 0;
static location current_lhs_location;
static named_ref *current_lhs_named_ref;
@@ -66,20 +56,37 @@ static char const *char_name (char);
/** Set the new current left-hand side symbol, possibly common
* to several right-hand side parts of rule.
*/
static
void
current_lhs(symbol *sym, location loc, named_ref *ref)
{
current_lhs_symbol = sym;
current_lhs_location = 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
result in several uses when the user factors lhs between several
rules using "|". Therefore free the parser's original copy. */
free (current_lhs_named_ref);
current_lhs_named_ref = ref;
}
static void current_lhs (symbol *sym, location loc, named_ref *ref);
#define YYLLOC_DEFAULT(Current, Rhs, N) \
(Current) = lloc_default (Rhs, N)
static YYLTYPE lloc_default (YYLTYPE const *, int);
#define YY_LOCATION_PRINT(File, Loc) \
location_print (Loc, File)
/* Strip initial '{' and final '}' (must be first and last characters).
Return the result. */
static char *strip_braces (char *code);
/* Convert CODE by calling code_props_plain_init if PLAIN, otherwise
code_props_symbol_action_init. Call
gram_scanner_last_string_free to release the latest string from
the scanner (should be CODE). */
static char const *translate_code (char *code, location loc, bool plain);
/* Convert CODE by calling code_props_plain_init after having
stripped the first and last characters (expected to be '{', and
'}'). Call gram_scanner_last_string_free to release the latest
string from the scanner (should be CODE). */
static char const *translate_code_braceless (char *code, location loc);
static void version_check (location const *loc, char const *version);
static void gram_error (location const *, char const *);
/* A string that describes a char (e.g., 'a' -> "'a'"). */
static char const *char_name (char);
#define YYTYPE_INT16 int_fast16_t
#define YYTYPE_INT8 int_fast8_t
@@ -87,8 +94,8 @@ static char const *char_name (char);
#define YYTYPE_UINT8 uint_fast8_t
}
%define api.prefix "gram_"
%define api.pure
%define api.prefix {gram_}
%define api.pure full
%define locations
%define parse.error verbose
%define parse.lac full
@@ -105,23 +112,9 @@ static char const *char_name (char);
boundary_set (&@$.end, current_file, 1, 1);
}
%union
{
assoc assoc;
char *code;
char const *chars;
int integer;
named_ref *named_ref;
symbol *symbol;
symbol_list *list;
uniqstr uniqstr;
unsigned char character;
};
/* Define the tokens together with their human representation. */
%token GRAM_EOF 0 "end of file"
%token STRING "string"
%token INT "integer"
%token PERCENT_TOKEN "%token"
%token PERCENT_NTERM "%nterm"
@@ -186,18 +179,16 @@ static char const *char_name (char);
%token TAG_ANY "<*>"
%token TAG_NONE "<>"
%union {unsigned char character;}
%type <character> CHAR
%printer { fputs (char_name ($$), yyo); } CHAR
/* braceless is not to be used for rule or symbol actions, as it
calls code_props_plain_init. */
%type <chars> STRING "%{...%}" EPILOGUE braceless content.opt
%type <code> "{...}" "%?{...}"
%printer { fputs (quotearg_style (c_quoting_style, $$), yyo); }
STRING
%printer { fprintf (yyo, "{\n%s\n}", $$); }
braceless content.opt "{...}" "%{...%}" EPILOGUE
%union {char *code;};
%type <code> "{...}" "%?{...}" "%{...%}" EPILOGUE STRING
%printer { fputs (quotearg_style (c_quoting_style, $$), yyo); } STRING
%printer { fprintf (yyo, "{\n%s\n}", $$); } <code>
%union {uniqstr uniqstr;}
%type <uniqstr> BRACKETED_ID ID ID_COLON PERCENT_FLAG TAG tag variable
%printer { fputs ($$, yyo); } <uniqstr>
%printer { fprintf (yyo, "[%s]", $$); } BRACKETED_ID
@@ -205,15 +196,22 @@ static char const *char_name (char);
%printer { fprintf (yyo, "%%%s", $$); } PERCENT_FLAG
%printer { fprintf (yyo, "<%s>", $$); } TAG tag
%type <integer> INT
%union {int integer;};
%token <integer> INT "integer"
%printer { fprintf (yyo, "%d", $$); } <integer>
%union {symbol *symbol;}
%type <symbol> id id_colon string_as_id symbol symbol.prec
%printer { fprintf (yyo, "%s", $$->tag); } <symbol>
%printer { fprintf (yyo, "%s:", $$->tag); } id_colon
%union {assoc assoc;};
%type <assoc> precedence_declarator
%union {symbol_list *list;}
%type <list> symbols.1 symbols.prec generic_symlist generic_symlist_item
%union {named_ref *named_ref;}
%type <named_ref> named_ref.opt
/*---------.
@@ -221,8 +219,6 @@ static char const *char_name (char);
`---------*/
%code requires
{
# ifndef PARAM_TYPE
# define PARAM_TYPE
typedef enum
{
param_none = 0,
@@ -230,7 +226,6 @@ static char const *char_name (char);
param_parse = 1 << 1,
param_both = param_lex | param_parse
} param_type;
# endif
};
%code
{
@@ -243,20 +238,17 @@ static char const *char_name (char);
static void add_param (param_type type, char *decl, location loc);
static param_type current_param = param_none;
};
%union
{
param_type param;
}
%union {param_type param;}
%token <param> PERCENT_PARAM "%param";
%printer
{
switch ($$)
{
#define CASE(In, Out) \
case param_ ## In: fputs ("%" #Out, stderr); break
CASE(lex, lex-param);
CASE(parse, parse-param);
CASE(both, param);
case param_ ## In: fputs ("%" #Out, yyo); break
CASE (lex, lex-param);
CASE (parse, parse-param);
CASE (both, param);
#undef CASE
case param_none: aver (false); break;
}
@@ -278,7 +270,7 @@ input:
`------------------------------------*/
prologue_declarations:
/* Nothing */
%empty
| prologue_declarations prologue_declaration
;
@@ -286,21 +278,17 @@ prologue_declaration:
grammar_declaration
| "%{...%}"
{
code_props plain_code;
code_props_plain_init (&plain_code, $1, @1);
code_props_translate_code (&plain_code);
gram_scanner_last_string_free ();
muscle_code_grow (union_seen ? "post_prologue" : "pre_prologue",
plain_code.code, @1);
translate_code ($1, @1, true), @1);
code_scanner_last_string_free ();
}
| "%<flag>"
{
muscle_percent_define_ensure ($1, @1, true);
}
| "%define" variable content.opt
| "%define" variable value
{
muscle_percent_define_insert ($2, @2, $3,
muscle_percent_define_insert ($2, @2, $3.kind, $3.chars,
MUSCLE_PERCENT_DEFINE_GRAMMAR_FILE);
}
| "%defines" { defines_flag = true; }
@@ -311,7 +299,8 @@ prologue_declaration:
}
| "%error-verbose"
{
muscle_percent_define_insert ("parse.error", @1, "verbose",
muscle_percent_define_insert ("parse.error", @1, muscle_keyword,
"verbose",
MUSCLE_PERCENT_DEFINE_GRAMMAR_FILE);
}
| "%expect" INT { expected_sr_conflicts = $2; }
@@ -324,11 +313,7 @@ prologue_declaration:
}
| "%initial-action" "{...}"
{
code_props action;
code_props_symbol_action_init (&action, $2, @2);
code_props_translate_code (&action);
gram_scanner_last_string_free ();
muscle_code_grow ("initial_action", action.code, @2);
muscle_code_grow ("initial_action", translate_code ($2, @2, false), @2);
code_scanner_last_string_free ();
}
| "%language" STRING { language_argmatch ($2, grammar_prio, @1); }
@@ -405,16 +390,17 @@ grammar_declaration:
{
default_prec = false;
}
| "%code" braceless
| "%code" "{...}"
{
/* Do not invoke muscle_percent_code_grow here since it invokes
muscle_user_name_list_grow. */
muscle_code_grow ("percent_code()", $2, @2);
muscle_code_grow ("percent_code()",
translate_code_braceless ($2, @2), @2);
code_scanner_last_string_free ();
}
| "%code" ID braceless
| "%code" ID "{...}"
{
muscle_percent_code_grow ($2, @2, $3, @3);
muscle_percent_code_grow ($2, @2, translate_code_braceless ($3, @3), @3);
code_scanner_last_string_free ();
}
;
@@ -434,15 +420,15 @@ code_props_type:
%token PERCENT_UNION "%union";
union_name:
/* Nothing. */ {}
| ID { muscle_code_grow ("union_name", $1, @1); }
%empty {}
| ID { muscle_code_grow ("union_name", $1, @1); }
;
grammar_declaration:
"%union" union_name braceless
"%union" union_name "{...}"
{
union_seen = true;
muscle_code_grow ("stype", $3, @3);
muscle_code_grow ("union_members", translate_code_braceless ($3, @3), @3);
code_scanner_last_string_free ();
}
;
@@ -494,8 +480,8 @@ precedence_declarator:
;
tag.opt:
/* Nothing. */ { current_type = NULL; }
| TAG { current_type = $1; tag_seen = true; }
%empty { current_type = NULL; }
| TAG { current_type = $1; tag_seen = true; }
;
/* Just like symbols.1 but accept INT for the sake of POSIX. */
@@ -507,8 +493,17 @@ symbols.prec:
;
symbol.prec:
symbol { $$ = $1; }
| symbol INT { $$ = $1; symbol_user_token_number_set ($1, $2, @2); }
symbol
{
$$ = $1;
symbol_class_set ($1, token_sym, @1, false);
}
| symbol INT
{
$$ = $1;
symbol_user_token_number_set ($1, $2, @2);
symbol_class_set ($1, token_sym, @1, false);
}
;
/* One or more symbols to be %typed. */
@@ -609,8 +604,9 @@ rhses.1:
| rhses.1 ";"
;
%token PERCENT_EMPTY "%empty";
rhs:
/* Nothing. */
%empty
{ grammar_current_rule_begin (current_lhs_symbol, current_lhs_location,
current_lhs_named_ref); }
| rhs symbol named_ref.opt
@@ -619,6 +615,8 @@ rhs:
{ grammar_current_rule_action_append ($2, @2, $3, false); }
| rhs "%?{...}"
{ grammar_current_rule_action_append ($2, @2, NULL, true); }
| rhs "%empty"
{ grammar_current_rule_empty_set (@2); }
| rhs "%prec" symbol
{ grammar_current_rule_prec_set ($3, @3); }
| rhs "%dprec" INT
@@ -628,44 +626,47 @@ rhs:
;
named_ref.opt:
/* Nothing. */ { $$ = 0; }
|
BRACKETED_ID { $$ = named_ref_new($1, @1); }
%empty { $$ = 0; }
| BRACKETED_ID { $$ = named_ref_new ($1, @1); }
;
/*---------------------------.
| variable and content.opt. |
`---------------------------*/
/*---------------------.
| variable and value. |
`---------------------*/
/* The STRING form of variable is deprecated and is not M4-friendly.
For example, M4 fails for `%define "[" "value"'. */
For example, M4 fails for '%define "[" "value"'. */
variable:
ID
| STRING { $$ = uniqstr_new ($1); }
;
/* Some content or empty by default. */
content.opt:
/* Nothing. */ { $$ = ""; }
| ID { $$ = $1; }
| STRING
;
/*------------.
| braceless. |
`------------*/
braceless:
"{...}"
%code requires {#include "muscle-tab.h"};
%union
{
struct
{
char const *chars;
muscle_kind kind;
} value;
};
%type <value> value;
%printer
{
switch ($$.kind)
{
code_props plain_code;
$1[strlen ($1) - 1] = '\n';
code_props_plain_init (&plain_code, $1+1, @1);
code_props_translate_code (&plain_code);
gram_scanner_last_string_free ();
$$ = plain_code.code;
case muscle_code: fprintf (yyo, "{%s}", $$.chars); break;
case muscle_keyword: fprintf (yyo, "%s", $$.chars); break;
case muscle_string: fprintf (yyo, "\"%s\"", $$.chars); break;
}
} <value>;
value:
%empty { $$.kind = muscle_keyword; $$.chars = ""; }
| ID { $$.kind = muscle_keyword; $$.chars = $1; }
| STRING { $$.kind = muscle_string; $$.chars = $1; }
| "{...}" { $$.kind = muscle_code; $$.chars = strip_braces ($1); }
;
@@ -707,14 +708,10 @@ string_as_id:
;
epilogue.opt:
/* Nothing. */
%empty
| "%%" EPILOGUE
{
code_props plain_code;
code_props_plain_init (&plain_code, $2, @2);
code_props_translate_code (&plain_code);
gram_scanner_last_string_free ();
muscle_code_grow ("epilogue", plain_code.code, @2);
muscle_code_grow ("epilogue", translate_code ($2, @2, true), @2);
code_scanner_last_string_free ();
}
;
@@ -750,6 +747,33 @@ lloc_default (YYLTYPE const *rhs, int n)
return loc;
}
static
char *strip_braces (char *code)
{
code[strlen (code) - 1] = 0;
return code + 1;
}
static
char const *
translate_code (char *code, location loc, bool plain)
{
code_props plain_code;
if (plain)
code_props_plain_init (&plain_code, code, loc);
else
code_props_symbol_action_init (&plain_code, code, loc);
code_props_translate_code (&plain_code);
gram_scanner_last_string_free ();
return plain_code.code;
}
static
char const *
translate_code_braceless (char *code, location loc)
{
return translate_code (strip_braces (code), loc, true);
}
static void
add_param (param_type type, char *decl, location loc)
@@ -832,3 +856,18 @@ char_name (char c)
return quotearg_style (escape_quoting_style, buf);
}
}
static
void
current_lhs (symbol *sym, location loc, named_ref *ref)
{
current_lhs_symbol = sym;
current_lhs_location = 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
result in several uses when the user factors lhs between several
rules using "|". Therefore free the parser's original copy. */
free (current_lhs_named_ref);
current_lhs_named_ref = ref;
}
+46 -40
View File
@@ -45,7 +45,8 @@ struct escape_buf
char *ptr;
size_t size;
};
static struct escape_buf escape_bufs[3];
enum { num_escape_bufs = 3 };
static struct escape_buf escape_bufs[num_escape_bufs];
/*--------------------------------.
@@ -64,40 +65,39 @@ print_core (FILE *out, int level, state *s)
sitems = itemset;
snritems = nitemset;
if (!snritems) {
xml_puts (out, level, "<itemset/>");
return;
}
if (!snritems)
{
xml_puts (out, level, "<itemset/>");
return;
}
xml_puts (out, level, "<itemset>");
for (i = 0; i < snritems; i++)
{
bool printed = false;
item_number *sp;
item_number *sp1;
rule_number r;
item_number *sp1 = ritem + sitems[i];
item_number *sp = sp1;
rule *r;
sp1 = sp = ritem + sitems[i];
while (*sp >= 0)
while (0 <= *sp)
sp++;
r = item_number_as_rule_number (*sp);
sp = rules[r].rhs;
r = &rules[item_number_as_rule_number (*sp)];
sp = r->rhs;
/* Display the lookahead tokens? */
if (item_number_is_rule_number (*sp1))
{
reductions *reds = s->reductions;
int red = state_reduction_find (s, &rules[r]);
int red = state_reduction_find (s, r);
/* Print item with lookaheads if there are. */
if (reds->lookahead_tokens && red != -1)
{
xml_printf (out, level + 1,
"<item rule-number=\"%d\" point=\"%d\">",
rules[r].number, sp1 - sp);
state_rule_lookahead_tokens_print_xml (s, &rules[r],
r->number, sp1 - sp);
state_rule_lookahead_tokens_print_xml (s, r,
out, level + 2);
xml_puts (out, level + 1, "</item>");
printed = true;
@@ -105,12 +105,10 @@ print_core (FILE *out, int level, state *s)
}
if (!printed)
{
xml_printf (out, level + 1,
"<item rule-number=\"%d\" point=\"%d\"/>",
rules[r].number,
sp1 - sp);
}
xml_printf (out, level + 1,
"<item rule-number=\"%d\" point=\"%d\"/>",
r->number,
sp1 - sp);
}
xml_puts (out, level, "</itemset>");
}
@@ -135,10 +133,11 @@ print_transitions (state *s, FILE *out, int level)
}
/* Nothing to report. */
if (!n) {
xml_puts (out, level, "<transitions/>");
return;
}
if (!n)
{
xml_puts (out, level, "<transitions/>");
return;
}
/* Report lookahead tokens and shifts. */
xml_puts (out, level, "<transitions>");
@@ -189,10 +188,11 @@ print_errs (FILE *out, int level, state *s)
count = true;
/* Nothing to report. */
if (!count) {
xml_puts (out, level, "<errors/>");
return;
}
if (!count)
{
xml_puts (out, level, "<errors/>");
return;
}
/* Report lookahead tokens and errors. */
xml_puts (out, level, "<errors>");
@@ -209,7 +209,7 @@ print_errs (FILE *out, int level, state *s)
/*-------------------------------------------------------------------------.
| Report a reduction of RULE on LOOKAHEAD_TOKEN (which can be `default'). |
| Report a reduction of RULE on LOOKAHEAD_TOKEN (which can be 'default'). |
| If not ENABLED, the rule is masked by a shift or a reduce (S/R and |
| R/R conflicts). |
`-------------------------------------------------------------------------*/
@@ -286,10 +286,11 @@ print_reductions (FILE *out, int level, state *s)
}
/* Nothing to report. */
if (!report) {
xml_puts (out, level, "<reductions/>");
return;
}
if (!report)
{
xml_puts (out, level, "<reductions/>");
return;
}
xml_puts (out, level, "<reductions>");
@@ -496,7 +497,6 @@ xml_escape (char const *str)
void
print_xml (void)
{
state_number i;
int level = 0;
FILE *out = xfopen (spec_xml_file, "w");
@@ -522,8 +522,11 @@ print_xml (void)
/* print automaton */
fputc ('\n', out);
xml_puts (out, level + 1, "<automaton>");
for (i = 0; i < nstates; i++)
print_state (out, level + 2, states[i]);
{
state_number i;
for (i = 0; i < nstates; i++)
print_state (out, level + 2, states[i]);
}
xml_puts (out, level + 1, "</automaton>");
bitset_free (no_reduce_set);
@@ -531,8 +534,11 @@ print_xml (void)
xml_puts (out, 0, "</bison-xml-report>");
free (escape_bufs[0].ptr);
free (escape_bufs[1].ptr);
{
int i;
for (i = 0; i < num_escape_bufs; ++i)
free (escape_bufs[i].ptr);
}
xfclose (out);
}
+7 -4
View File
@@ -106,8 +106,11 @@ print_core (FILE *out, state *s)
for (sp = rules[r].rhs; sp < sp1; sp++)
fprintf (out, " %s", symbols[*sp]->tag);
fputs (" .", out);
for (/* Nothing */; *sp >= 0; ++sp)
fprintf (out, " %s", symbols[*sp]->tag);
if (0 <= *rules[r].rhs)
for (/* Nothing */; 0 <= *sp; ++sp)
fprintf (out, " %s", symbols[*sp]->tag);
else
fprintf (out, " %%empty");
/* Display the lookahead tokens? */
if (report_flag & report_lookahead_tokens
@@ -206,7 +209,7 @@ print_errs (FILE *out, state *s)
/*-------------------------------------------------------------------------.
| Report a reduction of RULE on LOOKAHEAD_TOKEN (which can be `default'). |
| Report a reduction of RULE on LOOKAHEAD_TOKEN (which can be 'default'). |
| If not ENABLED, the rule is masked by a shift or a reduce (S/R and |
| R/R conflicts). |
`-------------------------------------------------------------------------*/
@@ -514,7 +517,7 @@ print_results (void)
print_grammar (out);
/* If the whole state item sets, not only the kernels, are wanted,
`closure' will be run, which needs memory allocation/deallocation. */
'closure' will be run, which needs memory allocation/deallocation. */
if (report_flag & report_itemsets)
new_closure (nritems);
/* Storage for print_reductions. */
+5 -2
View File
@@ -84,8 +84,11 @@ print_core (struct obstack *oout, state *s)
obstack_1grow (oout, '.');
for (/* Nothing */; *sp >= 0; ++sp)
obstack_printf (oout, " %s", escape (symbols[*sp]->tag));
if (0 <= *r->rhs)
for (/* Nothing */; *sp >= 0; ++sp)
obstack_printf (oout, " %s", escape (symbols[*sp]->tag));
else
obstack_printf (oout, " %%empty");
/* Experimental feature: display the lookahead tokens. */
if (report_flag & report_lookahead_tokens
+82 -43
View File
@@ -267,9 +267,9 @@ symbol_should_be_used (symbol_list const *s, bool *midrule_warning)
return true;
if ((s->midrule && s->midrule->action_props.is_value_used)
|| (s->midrule_parent_rule
&& symbol_list_n_get (s->midrule_parent_rule,
s->midrule_parent_rhs_index)
->action_props.is_value_used))
&& (symbol_list_n_get (s->midrule_parent_rule,
s->midrule_parent_rhs_index)
->action_props.is_value_used)))
{
*midrule_warning = true;
return true;
@@ -321,7 +321,7 @@ grammar_rule_check (const symbol_list *r)
bool midrule_warning = false;
if (!l->action_props.is_value_used
&& symbol_should_be_used (l, &midrule_warning)
/* The default action, $$ = $1, `uses' both. */
/* The default action, $$ = $1, 'uses' both. */
&& (r->action_props.code || (n != 0 && n != 1)))
{
warnings warn_flag = midrule_warning ? Wmidrule_values : Wother;
@@ -333,6 +333,18 @@ grammar_rule_check (const symbol_list *r)
}
}
/* Check that %empty => empty rule. */
if (r->percent_empty_loc.start.file
&& r->next && r->next->content.sym)
complain (&r->percent_empty_loc, complaint,
_("%%empty on non-empty rule"));
/* Check that empty rule => %empty. */
if (!(r->next && r->next->content.sym)
&& !r->midrule_parent_rule
&& !r->percent_empty_loc.start.file)
complain (&r->location, Wempty_rule, _("empty rule without %%empty"));
/* See comments in grammar_current_rule_prec_set for how POSIX
mandates this complaint. It's only for identifiers, so skip
it for char literals and strings, which are always tokens. */
@@ -430,8 +442,26 @@ grammar_current_rule_prec_set (symbol *precsym, location loc)
token. */
symbol_class_set (precsym, token_sym, loc, false);
if (current_rule->ruleprec)
complain (&loc, complaint, _("only one %s allowed per rule"), "%prec");
current_rule->ruleprec = precsym;
duplicate_directive ("%prec",
current_rule->ruleprec->location, loc);
else
current_rule->ruleprec = precsym;
}
/* Set %empty for the current rule. */
void
grammar_current_rule_empty_set (location loc)
{
/* If %empty is used and -Wno-empty-rule is not, then enable
-Wempty-rule. */
if (warning_is_unset (Wempty_rule))
warning_argmatch ("empty-rule", 0, 0);
if (current_rule->percent_empty_loc.start.file)
duplicate_directive ("%empty",
current_rule->percent_empty_loc, loc);
else
current_rule->percent_empty_loc = loc;
}
/* Attach dynamic precedence DPREC to the current rule. */
@@ -446,8 +476,13 @@ grammar_current_rule_dprec_set (int dprec, location loc)
complain (&loc, complaint, _("%s must be followed by positive number"),
"%dprec");
else if (current_rule->dprec != 0)
complain (&loc, complaint, _("only one %s allowed per rule"), "%dprec");
current_rule->dprec = dprec;
duplicate_directive ("%dprec",
current_rule->dprec_location, loc);
else
{
current_rule->dprec = dprec;
current_rule->dprec_location = loc;
}
}
/* Attach a merge function NAME with argument type TYPE to current
@@ -460,9 +495,13 @@ grammar_current_rule_merge_set (uniqstr name, location loc)
complain (&loc, Wother, _("%s affects only GLR parsers"),
"%merge");
if (current_rule->merger != 0)
complain (&loc, complaint, _("only one %s allowed per rule"), "%merge");
current_rule->merger = get_merge_function (name);
current_rule->merger_declaration_location = loc;
duplicate_directive ("%merge",
current_rule->merger_declaration_location, loc);
else
{
current_rule->merger = get_merge_function (name);
current_rule->merger_declaration_location = loc;
}
}
/* Attach SYM to the current rule. If needed, move the previous
@@ -477,7 +516,7 @@ grammar_current_rule_symbol_append (symbol *sym, location loc,
grammar_midrule_action ();
p = grammar_symbol_append (sym, loc);
if (name)
assign_named_ref(p, name);
assign_named_ref (p, name);
if (sym->status == undeclared || sym->status == used)
sym->status = needed;
}
@@ -507,7 +546,7 @@ packgram (void)
{
unsigned int itemno = 0;
rule_number ruleno = 0;
symbol_list *p = grammar;
symbol_list *p;
ritem = xnmalloc (nritems + 1, sizeof *ritem);
@@ -516,9 +555,8 @@ packgram (void)
rules = xnmalloc (nrules, sizeof *rules);
while (p)
for (p = grammar; p; p = p->next)
{
int rule_length = 0;
symbol *ruleprec = p->ruleprec;
record_merge_function_type (p->merger, p->content.sym->type_name,
p->merger_declaration_location);
@@ -536,14 +574,14 @@ packgram (void)
rules[ruleno].action_location = p->action_props.location;
rules[ruleno].is_predicate = p->action_props.is_predicate;
/* If the midrule's $$ is set or its $n is used, remove the `$' from the
/* If the midrule's $$ is set or its $n is used, remove the '$' from the
symbol name so that it's a user-defined symbol so that the default
%destructor and %printer apply. */
if (p->midrule_parent_rule
&& (p->action_props.is_value_used
|| symbol_list_n_get (p->midrule_parent_rule,
p->midrule_parent_rhs_index)
->action_props.is_value_used))
|| (symbol_list_n_get (p->midrule_parent_rule,
p->midrule_parent_rhs_index)
->action_props.is_value_used)))
p->content.sym->tag += 1;
/* Don't check the generated rule 0. It has no action, so some rhs
@@ -552,24 +590,27 @@ packgram (void)
if (p != grammar)
grammar_rule_check (p);
for (p = p->next; p && p->content.sym; p = p->next)
{
++rule_length;
{
size_t rule_length = 0;
for (p = p->next; p->content.sym; p = p->next)
{
++rule_length;
/* Don't allow rule_length == INT_MAX, since that might
cause confusion with strtol if INT_MAX == LONG_MAX. */
if (rule_length == INT_MAX)
complain (&rules[ruleno].location, fatal, _("rule is too long"));
/* Don't allow rule_length == INT_MAX, since that might
cause confusion with strtol if INT_MAX == LONG_MAX. */
if (rule_length == INT_MAX)
complain (&rules[ruleno].location, fatal, _("rule is too long"));
/* 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);
/* 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;
}
/* 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);
/* 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 this rule has a %prec,
the specified symbol's precedence replaces the default. */
@@ -583,9 +624,6 @@ packgram (void)
aver (itemno < ITEM_NUMBER_MAX);
++ruleno;
aver (ruleno < RULE_NUMBER_MAX);
if (p)
p = p->next;
}
aver (itemno == nritems);
@@ -713,7 +751,7 @@ check_and_convert_grammar (void)
/* Insert the initial rule, whose line is that of the first rule
(not that of the start symbol):
accept: %start EOF. */
$accept: %start $end. */
{
symbol_list *p = symbol_list_sym_new (accept, empty_location);
p->location = grammar->location;
@@ -726,7 +764,8 @@ check_and_convert_grammar (void)
grammar = p;
}
aver (nsyms <= SYMBOL_NUMBER_MAXIMUM && nsyms == ntokens + nvars);
aver (nsyms <= SYMBOL_NUMBER_MAXIMUM);
aver (nsyms == ntokens + nvars);
/* Assign the symbols their symbol numbers. Write #defines for the
token symbols into FDEFINES if requested. */
@@ -737,11 +776,11 @@ check_and_convert_grammar (void)
action type checking.
Before invoking grammar_rule_check (in packgram below) on any rule, make
sure all actions have already been scanned in order to set `used' flags.
sure all actions have already been scanned in order to set 'used' flags.
Otherwise, checking that a midrule's $$ should be set will not always work
properly because the check must forward-reference the midrule's parent
rule. For the same reason, all the `used' flags must be set before
checking whether to remove `$' from any midrule symbol name (also in
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;
+2
View File
@@ -47,6 +47,8 @@ void grammar_current_rule_begin (symbol *lhs, location loc,
named_ref *lhs_named_ref);
void grammar_current_rule_end (location loc);
void grammar_midrule_action (void);
/* Apply %empty to the current rule. */
void grammar_current_rule_empty_set (location loc);
void grammar_current_rule_prec_set (symbol *precsym, location loc);
void grammar_current_rule_dprec_set (int dprec, location loc);
void grammar_current_rule_merge_set (uniqstr name, location loc);
+1 -1
View File
@@ -49,7 +49,7 @@ static bitset P;
static bitset V;
/* Set of symbols used to define rule precedence (so they are
`useless', but no warning should be issued). */
'useless', but no warning should be issued). */
static bitset V1;
static rule_number nuseful_productions;
+23 -89
View File
@@ -78,8 +78,9 @@ static bool untyped_var_seen;
/* POSIX says that a tag must be both an id and a C union member, but
historically almost any character is allowed in a tag. We disallow
NUL and newline, as this simplifies our implementation. */
tag [^\0\n>]+
NUL and newline, as this simplifies our implementation. We allow
"->" as a means to dereference a pointer. */
tag ([^\0\n>]|->)+
/* Zero or more instances of backslash-newline. Following GCC, allow
white space between the backslash and the newline. */
@@ -95,26 +96,6 @@ ref -?[0-9]+|{id}|"["{id}"]"|"$"
%%
%{
/* Nesting level of the current code in braces. */
int braces_level = 0;
/* Whether a semicolon is probably needed.
The heuristic is that a semicolon is not needed after '{', '}',
';', or a C preprocessor directive, and that whitespaces and
comments do not affect this flag. Note that '{' does not need a
semicolon because of '{}'. A semicolon may be needed before a
cpp directive, but don't bother.
While it is maintained in several start-conditions (factoring
opportunities), it is meaningful only for SC_RULE_ACTION. */
bool need_semicolon = false;
/* Whether in a C preprocessor directive. Don't use a start condition
for this because, at the end of strings and comments, we still need
to know whether we're in a directive. */
bool in_cpp = false;
/* This scanner is special: it is invoked only once, henceforth
is expected to return only once. This initialization is
therefore done once per action to translate. */
@@ -167,32 +148,14 @@ ref -?[0-9]+|{id}|"["{id}"]"|"$"
<SC_RULE_ACTION,SC_SYMBOL_ACTION>
{
"'" {
STRING_GROW;
BEGIN SC_CHARACTER;
need_semicolon = true;
}
"\"" {
STRING_GROW;
BEGIN SC_STRING;
need_semicolon = true;
}
"/"{splice}"*" {
STRING_GROW;
BEGIN SC_COMMENT;
}
"/"{splice}"/" {
STRING_GROW;
BEGIN SC_LINE_COMMENT;
}
"'" STRING_GROW; BEGIN SC_CHARACTER;
"\"" STRING_GROW; BEGIN SC_STRING;
"/"{splice}"*" STRING_GROW; BEGIN SC_COMMENT;
"/"{splice}"/" STRING_GROW; BEGIN SC_LINE_COMMENT;
[$@] {
complain (loc, Wother, _("stray '%s'"), yytext);
obstack_escape (&obstack_for_string, yytext);
need_semicolon = true;
}
[\[\]] {
obstack_escape (&obstack_for_string, yytext);
need_semicolon = true;
}
}
@@ -203,51 +166,13 @@ ref -?[0-9]+|{id}|"["{id}"]"|"$"
handle_action_dollar (self->rule, yytext, *loc);
if (ref_tail_fields)
obstack_sgrow (&obstack_for_string, ref_tail_fields);
need_semicolon = true;
}
"@"{ref} {
ref_tail_fields = NULL;
handle_action_at (self->rule, yytext, *loc);
if (ref_tail_fields)
obstack_sgrow (&obstack_for_string, ref_tail_fields);
need_semicolon = true;
}
";" STRING_GROW; need_semicolon = false;
"{" STRING_GROW; ++braces_level; need_semicolon = false;
"}" {
bool outer_brace = --braces_level == 0;
/* As an undocumented Bison extension, append ';' before the last
brace in braced code, so that the user code can omit trailing
';'. But do not append ';' if emulating Yacc, since Yacc does
not append one. This is deprecated since release 2.4.1. */
if (outer_brace && !yacc_flag && language_prio == default_prio
&& skeleton_prio == default_prio && need_semicolon && ! in_cpp)
{
unsigned int indent = 0;
complain_indent (loc, Wdeprecated, &indent,
_("a ';' might be needed at the end of action code"));
indent += SUB_INDENT;
complain_indent (loc, Wdeprecated | silent | no_caret, &indent,
_("future versions of Bison will not add the ';'"));
obstack_1grow (&obstack_for_string, ';');
}
STRING_GROW;
need_semicolon = false;
}
/* Preprocessing directives should only be recognized at the beginning
of lines, allowing whitespace including comments, but in C/C++,
'#' can only be the start of preprocessor directives or within
'#define' directives anyway, so don't bother with begin of line. */
"#" STRING_GROW; in_cpp = true;
{splice} STRING_GROW;
[\n\r] STRING_GROW; if (in_cpp) in_cpp = need_semicolon = false;
[ \t\f] STRING_GROW;
. STRING_GROW; need_semicolon = true;
}
<SC_SYMBOL_ACTION>
@@ -417,8 +342,19 @@ show_sub_message (warnings warning,
{
static struct obstack msg_buf;
const char *tail = explicit_bracketing ? "" : cp + strlen (var->id);
const char *id = var->hidden_by ? var->hidden_by->id : var->id;
location id_loc = var->hidden_by ? var->hidden_by->loc : var->loc;
const char *id;
location id_loc;
if (var->hidden_by)
{
id = var->hidden_by->id;
id_loc = var->hidden_by->loc;
}
else
{
id = var->id;
id_loc = var->loc;
}
/* Create the explanation message. */
obstack_init (&msg_buf);
@@ -648,9 +584,6 @@ parse_ref (char *cp, symbol_list *rule, int rule_length,
return INVALID_REF;
}
}
/* Not reachable. */
return INVALID_REF;
}
/* Keeps track of the maximum number of semantic values to the left of
@@ -671,7 +604,8 @@ fetch_type_name (char *cp, char const **type_name,
if (*cp == '<')
{
*type_name = ++cp;
while (*cp != '>')
/* Series of non-'>' or "->". */
while (*cp != '>' || cp[-1] == '-')
++cp;
/* The '>' symbol will be later replaced by '\0'. Original
+17 -24
View File
@@ -112,7 +112,12 @@ static void unexpected_newline (boundary, char const *);
/* A identifier was just read in directives/rules. Special state
to capture the sequence 'identifier :'. */
%x SC_AFTER_IDENTIFIER
/* A complex tag, with nested angles brackets. */
/* POSIX says that a tag must be both an id and a C union member, but
historically almost any character is allowed in a tag. We
disallow NUL, as this simplifies our implementation. We match
angle brackets in nested pairs: several languages use them for
generics/template types. */
%x SC_TAG
/* Four types of user code:
@@ -133,13 +138,6 @@ notletter [^.abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_]{-}[%\{]
id {letter}({letter}|[-0-9])*
int [0-9]+
/* POSIX says that a tag must be both an id and a C union member, but
historically almost any character is allowed in a tag. We disallow
NUL, as this simplifies our implementation. We disallow angle
bracket to match them in nested pairs: several languages use them
for generics/template types. */
tag [^\0<>]+
/* Zero or more instances of backslash-newline. Following GCC, allow
white space between the backslash and the newline. */
splice (\\[ \f\t\v]*\n)*
@@ -217,6 +215,7 @@ eqopt ([[:space:]]*=)?
"%defines" return PERCENT_DEFINES;
"%destructor" return PERCENT_DESTRUCTOR;
"%dprec" return PERCENT_DPREC;
"%empty" return PERCENT_EMPTY;
"%error-verbose" return PERCENT_ERROR_VERBOSE;
"%expect" return PERCENT_EXPECT;
"%expect-rr" return PERCENT_EXPECT_RR;
@@ -267,7 +266,7 @@ eqopt ([[:space:]]*=)?
"%pure"[-_]"parser" DEPRECATED("%pure-parser");
"%token"[-_]"table" DEPRECATED("%token-table");
"%"{id}|"%"{notletter}([[:graph:]])+ {
"%"{id} {
complain (loc, complaint, _("invalid directive: %s"), quote (yytext));
}
@@ -324,13 +323,6 @@ eqopt ([[:space:]]*=)?
/* A type. */
"<*>" return TAG_ANY;
"<>" return TAG_NONE;
"<"{tag}">" {
obstack_grow (&obstack_for_string, yytext + 1, yyleng - 2);
STRING_FINISH;
val->uniqstr = uniqstr_new (last_string);
STRING_FREE;
return TAG;
}
"<" {
nesting = 0;
token_start = loc->start;
@@ -520,7 +512,7 @@ eqopt ([[:space:]]*=)?
"\"" {
STRING_FINISH;
loc->start = token_start;
val->chars = last_string;
val->code = last_string;
BEGIN INITIAL;
return STRING;
}
@@ -558,10 +550,11 @@ eqopt ([[:space:]]*=)?
<<EOF>> unexpected_eof (token_start, "'");
}
/*-----------------------------------------------------------.
| Scanning a Bison nested tag. The initial angle bracket is |
| already eaten. |
`-----------------------------------------------------------*/
/*--------------------------------------------------------------.
| Scanning a tag. The initial angle bracket is already eaten. |
`--------------------------------------------------------------*/
<SC_TAG>
{
@@ -579,7 +572,7 @@ eqopt ([[:space:]]*=)?
STRING_GROW;
}
[^<>]+ STRING_GROW;
([^<>]|->)+ STRING_GROW;
"<"+ STRING_GROW; nesting += yyleng;
<<EOF>> unexpected_eof (token_start, ">");
@@ -758,7 +751,7 @@ eqopt ([[:space:]]*=)?
"%}" {
STRING_FINISH;
loc->start = code_start;
val->chars = last_string;
val->code = last_string;
BEGIN INITIAL;
return PROLOGUE;
}
@@ -777,7 +770,7 @@ eqopt ([[:space:]]*=)?
<<EOF>> {
STRING_FINISH;
loc->start = code_start;
val->chars = last_string;
val->code = last_string;
BEGIN INITIAL;
return EPILOGUE;
}
+8 -5
View File
@@ -72,7 +72,7 @@ static void fail_for_invalid_at (char const *at);
"@@" fputc ('@', yyout);
"@{" fputc ('[', yyout);
"@}" fputc (']', yyout);
"@`" continue; /* Used by b4_cat in ../data/bison.m4. */
"@'" continue; /* Used by b4_cat in ../data/bison.m4. */
@\n continue;
"@oline@" fprintf (yyout, "%d", out_lineno + 1);
@@ -83,7 +83,7 @@ static void fail_for_invalid_at (char const *at);
"@output(" at_init (&argc, argv, &at_ptr, &at_output);
/* This pattern must not match more than the previous @ patterns. */
@[^@{}`(\n]* fail_for_invalid_at (yytext);
@[^@{}\'(\n]* fail_for_invalid_at (yytext);
\n out_lineno++; ECHO;
[^@\n]+ ECHO;
@@ -103,7 +103,7 @@ static void fail_for_invalid_at (char const *at);
"@@" obstack_1grow (&obstack_for_string, '@');
"@{" obstack_1grow (&obstack_for_string, '[');
"@}" obstack_1grow (&obstack_for_string, ']');
"@`" continue; /* For starting an argument that begins with whitespace. */
"@'" continue; /* For starting an argument that begins with whitespace. */
@\n continue;
@[,)] {
@@ -183,6 +183,8 @@ flag (const char *arg)
/* compare with values issued from b4_error */
if (STREQ (arg, "complain"))
return complaint;
else if (STREQ (arg, "deprecated"))
return Wdeprecated;
else if (STREQ (arg, "fatal"))
return fatal;
else if (STREQ (arg, "note"))
@@ -242,8 +244,9 @@ at_output (int argc, char *argv[], char **out_namep, int *out_linenop)
xfclose (yyout);
}
*out_namep = xstrdup (argv[1]);
output_file_name_check (out_namep);
yyout = xfopen (*out_namep, "w");
output_file_name_check (out_namep, true);
/* If there were errors, do not generate the output. */
yyout = xfopen (complaint_status ? "/dev/null" : *out_namep, "w");
*out_linenop = 1;
}
+14 -7
View File
@@ -36,18 +36,20 @@ symbol_list_sym_new (symbol *sym, location loc)
res->content_type = SYMLIST_SYMBOL;
res->content.sym = sym;
res->location = res->sym_loc = loc;
res->named_ref = NULL;
res->midrule = NULL;
res->midrule_parent_rule = NULL;
res->midrule_parent_rhs_index = 0;
code_props_none_init (&res->action_props);
/* Members used for LHS only. */
res->ruleprec = NULL;
res->percent_empty_loc = empty_location;
code_props_none_init (&res->action_props);
res->dprec = 0;
res->dprec_location = empty_location;
res->merger = 0;
res->named_ref = NULL;
res->merger_declaration_location = empty_location;
res->next = NULL;
@@ -85,12 +87,17 @@ symbol_list_type_new (uniqstr type_name, location loc)
void
symbol_list_syms_print (const symbol_list *l, FILE *f)
{
char const *sep = "";
for (/* Nothing. */; l && l->content.sym; l = l->next)
{
fputs (sep, f);
fputs (l->content_type == SYMLIST_SYMBOL ? "symbol: "
: l->content_type == SYMLIST_TYPE ? "type: "
: "invalid content_type: ",
f);
symbol_print (l->content.sym, f);
fprintf (stderr, l->action_props.is_value_used ? " used" : " unused");
if (l && l->content.sym)
fprintf (f, ", ");
fputs (l->action_props.is_value_used ? " used" : " unused", f);
sep = ", ";
}
}
+15 -5
View File
@@ -50,6 +50,9 @@ typedef struct symbol_list
} content;
location location;
/* Named reference. */
named_ref *named_ref;
/* Proper location of the symbol, not all the rule */
location sym_loc;
@@ -64,19 +67,26 @@ typedef struct symbol_list
struct symbol_list *midrule_parent_rule;
int midrule_parent_rhs_index;
/* ---------------------------------------------- */
/* Apply to the rule (attached to the LHS only). */
/* ---------------------------------------------- */
/* Precedence/associativity. */
symbol *ruleprec;
/* The action is attached to the LHS of a rule, but action properties for
* each RHS are also stored here. */
code_props action_props;
/* Precedence/associativity. */
symbol *ruleprec;
/* The location of the first %empty for this rule, or \a
empty_location. */
location percent_empty_loc;
int dprec;
location dprec_location;
int merger;
location merger_declaration_location;
/* Named reference. */
named_ref *named_ref;
/* The list. */
struct symbol_list *next;
} symbol_list;
+77 -39
View File
@@ -153,13 +153,13 @@ symbol_print (symbol const *s, FILE *f)
{
if (s)
{
fprintf (f, "\"%s\"", s->tag);
fputs (s->tag, f);
SYMBOL_ATTR_PRINT (type_name);
SYMBOL_CODE_PRINT (destructor);
SYMBOL_CODE_PRINT (printer);
}
else
fprintf (f, "<NULL>");
fputs ("<NULL>", f);
}
#undef SYMBOL_ATTR_PRINT
@@ -243,9 +243,12 @@ symbol_type_set (symbol *sym, uniqstr type_name, location loc)
{
if (sym->type_name)
symbol_redeclaration (sym, "%type", sym->type_location, loc);
uniqstr_assert (type_name);
sym->type_name = type_name;
sym->type_location = loc;
else
{
uniqstr_assert (type_name);
sym->type_name = type_name;
sym->type_location = loc;
}
}
}
@@ -261,7 +264,8 @@ symbol_code_props_set (symbol *sym, code_props_type kind,
symbol_redeclaration (sym, code_props_type_string (kind),
sym->props[kind].location,
code->location);
sym->props[kind] = *code;
else
sym->props[kind] = *code;
}
/*-----------------------------------------------------.
@@ -277,7 +281,8 @@ semantic_type_code_props_set (semantic_type *type,
semantic_type_redeclaration (type, code_props_type_string (kind),
type->props[kind].location,
code->location);
type->props[kind] = *code;
else
type->props[kind] = *code;
}
/*---------------------------------------------------.
@@ -321,12 +326,15 @@ symbol_precedence_set (symbol *sym, int prec, assoc a, location loc)
{
if (a != undef_assoc)
{
if (sym->prec != 0)
if (sym->prec)
symbol_redeclaration (sym, assoc_to_string (a), sym->prec_location,
loc);
sym->prec = prec;
sym->assoc = a;
sym->prec_location = loc;
else
{
sym->prec = prec;
sym->assoc = a;
sym->prec_location = loc;
}
}
/* Only terminals have a precedence. */
@@ -360,7 +368,8 @@ symbol_class_set (symbol *sym, symbol_class class, location loc, bool declaring)
{
if (sym->status == declared && !warned)
complain (&loc, Wother, _("symbol %s redeclared"), sym->tag);
sym->status = declared;
else
sym->status = declared;
}
}
@@ -441,7 +450,7 @@ semantic_type_check_defined (semantic_type *sem_type)
/* <*> and <> do not have to be "declared". */
if (sem_type->status == declared
|| !*sem_type->tag
|| STREQ(sem_type->tag, "*"))
|| STREQ (sem_type->tag, "*"))
{
int i;
for (i = 0; i < 2; ++i)
@@ -615,8 +624,8 @@ symbol_translation (symbol *this)
(this->user_token_number,
symbols[token_translations[this->user_token_number]],
this);
token_translations[this->user_token_number] = this->number;
else
token_translations[this->user_token_number] = this->number;
}
return true;
@@ -1057,27 +1066,40 @@ register_precedence (graphid first, graphid snd)
}
/*--------------------------------------------------.
| Print a warning for unused precedence relations. |
`--------------------------------------------------*/
/*---------------------------------------.
| Deep clear a linked / adjacency list). |
`---------------------------------------*/
void
print_precedence_warnings (void)
static void
linkedlist_free (symgraphlink *node)
{
if (node)
{
while (node->next)
{
symgraphlink *tmp = node->next;
free (node);
node = tmp;
}
free (node);
}
}
/*----------------------------------------------.
| Clear and destroy association tracking table. |
`----------------------------------------------*/
static void
assoc_free (void)
{
int i;
if (!prec_nodes)
init_prec_nodes ();
for (i = 0; i < nsyms; ++i)
{
symbol *s = symbols[i];
if (s
&& s->prec != 0
&& !prec_nodes[i]->pred
&& !prec_nodes[i]->succ
&& s->assoc == precedence_assoc)
complain (&s->location, Wother,
_("useless precedence for %s"), s->tag);
linkedlist_free (prec_nodes[i]->pred);
linkedlist_free (prec_nodes[i]->succ);
free (prec_nodes[i]);
}
free (prec_nodes);
}
/*---------------------------------------.
@@ -1088,7 +1110,7 @@ static void
init_assoc (void)
{
graphid i;
used_assoc = xcalloc(nsyms, sizeof(*used_assoc));
used_assoc = xcalloc (nsyms, sizeof *used_assoc);
for (i = 0; i < nsyms; ++i)
used_assoc[i] = false;
}
@@ -1119,21 +1141,37 @@ register_assoc (graphid i, graphid j)
used_assoc[j] = true;
}
/*------------------------------------------------------.
| Print a warning for each unused symbol associativity. |
`------------------------------------------------------*/
/*--------------------------------------------------.
| Print a warning for unused precedence relations. |
`--------------------------------------------------*/
void
print_assoc_warnings (void)
print_precedence_warnings (void)
{
graphid i;
int i;
if (!prec_nodes)
init_prec_nodes ();
if (!used_assoc)
init_assoc ();
for (i = 0; i < nsyms; ++i)
{
symbol *s = symbols[i];
if (is_assoc_useless (s))
complain (&s->location, Wother,
_("useless associativity for %s"), s->tag);
if (s
&& s->prec != 0
&& !prec_nodes[i]->pred
&& !prec_nodes[i]->succ)
{
if (is_assoc_useless (s))
complain (&s->prec_location, Wprecedence,
_("useless precedence and associativity for %s"), s->tag);
else if (s->assoc == precedence_assoc)
complain (&s->prec_location, Wprecedence,
_("useless precedence for %s"), s->tag);
}
else if (is_assoc_useless (s))
complain (&s->prec_location, Wprecedence,
_("useless associativity for %s, use %%precedence"), s->tag);
}
free (used_assoc);
assoc_free ();
}
+6 -7
View File
@@ -128,9 +128,9 @@ 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
/* '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
@@ -266,7 +266,8 @@ struct symgraph
void register_precedence (graphid first, graphid snd);
/** Print a warning for each symbol whose precedence is useless. */
/** Print a warning for each symbol whose precedence and/or associativity
* is useless. */
void print_precedence_warnings (void);
@@ -274,9 +275,7 @@ void print_precedence_warnings (void);
| Symbol associativity |
`----------------------*/
void register_assoc (int i, int j);
void print_assoc_warnings (void);
void register_assoc (graphid i, graphid j);
/*-----------------.
| Semantic types. |
+1 -1
View File
@@ -99,7 +99,7 @@ typedef size_t uintptr_t;
# endif
# endif
/* The __-protected variants of `format' and `printf' attributes
/* The __-protected variants of 'format' and 'printf' attributes
are accepted by gcc versions 2.6.4 (effectively 2.7) and later. */
# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7)
# define __format__ format
+7 -7
View File
@@ -35,7 +35,7 @@
#include "tables.h"
/* Several tables are indexed both by state and nonterminal numbers.
We call such an index a `vector'; i.e., a vector is either a state
We call such an index a 'vector'; i.e., a vector is either a state
or a nonterminal number.
Of course vector_number_t ought to be wide enough to contain
@@ -90,18 +90,18 @@ static base_number *width;
/* For a given state, N = ACTROW[SYMBOL]:
If N = 0, stands for `run the default action'.
If N = MIN, stands for `raise a syntax error'.
If N > 0, stands for `shift SYMBOL and go to n'.
If N < 0, stands for `reduce -N'. */
If N = 0, stands for 'run the default action'.
If N = MIN, stands for 'raise a syntax error'.
If N > 0, stands for 'shift SYMBOL and go to n'.
If N < 0, stands for 'reduce -N'. */
typedef int action_number;
#define ACTION_NUMBER_MINIMUM INT_MIN
static action_number *actrow;
/* FROMS and TOS are reordered to be compressed. ORDER[VECTOR] is the
new vector number of VECTOR. We skip `empty' vectors (i.e.,
TALLY[VECTOR] = 0), and call these `entries'. */
new vector number of VECTOR. We skip 'empty' vectors (i.e.,
TALLY[VECTOR] = 0), and call these 'entries'. */
static vector_number *order;
static int nentries;
+3 -2
View File
@@ -77,7 +77,8 @@ uniqstr_vsprintf (char const *format, ...)
void
uniqstr_assert (char const *str)
{
if (!hash_lookup (uniqstrs_table, str))
uniqstr s = hash_lookup (uniqstrs_table, str);
if (!s || s != str)
{
error (0, 0,
"not a uniqstr: %s", quotearg (str));
@@ -105,7 +106,7 @@ uniqstr_print_processor (void *ustr, void *null ATTRIBUTE_UNUSED)
int
uniqstr_cmp(uniqstr l, uniqstr r)
uniqstr_cmp (uniqstr l, uniqstr r)
{
return (l == r ? 0
: !l ? -1
+4 -2
View File
@@ -20,6 +20,8 @@
#ifndef UNIQSTR_H_
# define UNIQSTR_H_
# include <stdio.h>
/*-----------------------------------------.
| Pointers to unique copies of C strings. |
`-----------------------------------------*/
@@ -33,14 +35,14 @@ uniqstr uniqstr_new (char const *str);
strings, use UNIQSTR_CONCAT, which is a convenient wrapper around
this function. */
uniqstr uniqstr_vsprintf (char const *format, ...)
__attribute__ ((__format__ (__printf__, 1, 2)));
_GL_ATTRIBUTE_FORMAT_PRINTF (1, 2);
/* Two uniqstr values have the same value iff they are the same. */
# define UNIQSTR_EQ(Ustr1, Ustr2) (!!((Ustr1) == (Ustr2)))
/* Compare two uniqstr a la strcmp: negative for <, nul for =, and
positive for >. Undefined order, relies on addresses. */
int uniqstr_cmp(uniqstr u1, uniqstr u2);
int uniqstr_cmp (uniqstr u1, uniqstr u2);
/* Die if STR is not a uniqstr. */
void uniqstr_assert (char const *str);
+126 -122
View File
@@ -64,6 +64,119 @@ AT_PARSER_CHECK([./input], 0,
AT_CLEANUP
## ----------------------- ##
## Implicitly empty rule. ##
## ----------------------- ##
AT_SETUP([Implicitly empty rule])
AT_DATA_GRAMMAR([[1.y]],
[[%%
exp: a b;
a: /* empty. */ {};
// A mid-rule action does not count as an empty rule.
b: {} {};
]])
AT_BISON_CHECK([-fcaret -Wempty-rule 1.y], [0], [],
[[1.y:11.17-18: warning: empty rule without %empty [-Wempty-rule]
a: /* empty. */ {};
^^
]])
AT_DATA_GRAMMAR([[2.y]],
[[%%
exp: a b c;
a: /* empty. */ {};
b: %empty {};
c: /* empty. */ {};
]])
AT_BISON_CHECK([-fcaret 2.y], [0], [],
[[2.y:11.17-18: warning: empty rule without %empty [-Wempty-rule]
a: /* empty. */ {};
^^
2.y:13.17-18: warning: empty rule without %empty [-Wempty-rule]
c: /* empty. */ {};
^^
]])
AT_BISON_CHECK([-fcaret -Wno-empty-rule 2.y], [0])
AT_CLEANUP
## ------------------------ ##
## Invalid uses of %empty. ##
## ------------------------ ##
AT_SETUP([Invalid uses of %empty])
AT_DATA_GRAMMAR([[one.y]],
[[%%
exp:
%empty {} %empty
;
]])
AT_BISON_CHECK([-fcaret one.y], [1], [],
[[one.y:11.13-18: error: only one %empty allowed per rule
%empty {} %empty
^^^^^^
one.y:11.3-8: previous declaration
%empty {} %empty
^^^^^^
]])
AT_DATA_GRAMMAR([[two.y]],
[[%%
exp:
'a' %empty {}
| %empty 'a' {}
| %empty {} {}
;
]])
AT_BISON_CHECK([-fcaret two.y], [1], [],
[[two.y:11.7-12: error: %empty on non-empty rule
'a' %empty {}
^^^^^^
two.y:12.3-8: error: %empty on non-empty rule
| %empty 'a' {}
^^^^^^
two.y:13.3-8: error: %empty on non-empty rule
| %empty {} {}
^^^^^^
]])
AT_CLEANUP
## ---------------------- ##
## Valid uses of %empty. ##
## ---------------------- ##
AT_SETUP([Valid uses of %empty])
AT_BISON_OPTION_PUSHDEFS
AT_DATA_GRAMMAR([[input.y]],
[[
%debug
%code
{
]AT_YYERROR_DECLARE[
]AT_YYLEX_DECLARE[
}
%%
exp: %empty {}
%%
]AT_YYERROR_DEFINE[
]AT_YYLEX_DEFINE[
]AT_MAIN_DEFINE[
]])
AT_FULL_COMPILE([input])
AT_PARSER_CHECK([./input])
AT_BISON_OPTION_POPDEFS
AT_CLEANUP
## ------------------ ##
## Initial location. ##
@@ -173,8 +286,8 @@ m4_popdef([AT_TEST])
## Location Print. ##
## ---------------- ##
# AT_TEST(SKELETON-NAME, DIRECTIVES, [MORE-DIRECTIVES], [LOCATION = 1.1])
# -----------------------------------------------------------------------
# AT_TEST(SKELETON-NAME, DIRECTIVES, [MORE-DIRECTIVES])
# -----------------------------------------------------
# Check that the initial location is correct.
m4_pushdef([AT_TEST],
[AT_SETUP([Location print: $1 $2])
@@ -192,7 +305,7 @@ AT_DATA_GRAMMAR([[input.y]],
]AT_YYLEX_DECLARE[
}
%%
exp: /* empty */;
exp: %empty;
%%
]AT_YYERROR_DEFINE[
]AT_YYLEX_DEFINE[
@@ -415,7 +528,7 @@ AT_LALR1_CC_IF([typedef yy::location YYLTYPE;])[
%%
/*
This grammar is made to exercise error recovery.
"Lines" starting with `(' support error recovery, with
"Lines" starting with '(' support error recovery, with
')' as synchronizing token. Lines starting with 'x' can never
be recovered from if in error.
*/
@@ -483,7 +596,7 @@ thing:
;
%%
/* Alias to ARGV[1]. */
const char *source = YY_NULL;
const char *source = YY_NULLPTR;
]AT_YYERROR_DEFINE[
@@ -492,11 +605,11 @@ static
{
static unsigned int counter = 0;
int c = ]AT_VAL[]m4_ifval([$6], [.ival])[ = counter++;
unsigned int 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;
assert (0 <= c && c <= strlen (source));
assert (c <= strlen (source));
if (source[c])
fprintf (stderr, "sending: '%c'", source[c]);
else
@@ -578,7 +691,7 @@ Successful parse.
# Syntax errors caught by the parser
# ----------------------------------
# Exercise the discarding of stack top and input until `error'
# Exercise the discarding of stack top and input until 'error'
# can be reduced.
#
# '(', 'x', 'x', 'x', 'x', 'x', ')',
@@ -735,13 +848,13 @@ AT_CLEANUP
AT_CHECK_PRINTER_AND_DESTRUCTOR([])
AT_CHECK_PRINTER_AND_DESTRUCTOR([], [with union])
AT_CHECK_PRINTER_AND_DESTRUCTOR([], [ with union])
AT_CHECK_PRINTER_AND_DESTRUCTOR([%defines %skeleton "lalr1.cc"])
AT_CHECK_PRINTER_AND_DESTRUCTOR([%defines %skeleton "lalr1.cc"], [with union])
AT_CHECK_PRINTER_AND_DESTRUCTOR([%defines %skeleton "lalr1.cc"], [ with union])
AT_CHECK_PRINTER_AND_DESTRUCTOR([%glr-parser])
AT_CHECK_PRINTER_AND_DESTRUCTOR([%glr-parser], [with union])
AT_CHECK_PRINTER_AND_DESTRUCTOR([%glr-parser], [ with union])
@@ -1174,7 +1287,7 @@ AT_SETUP([Default %printer and %destructor are not for $accept])
# - The %printer and %destructor code generated for $accept would always be
# dead code because $accept is currently never shifted onto the stack.
# - $$ for $accept would always be of type YYSTYPE because it's not possible
# to declare `%type <field> $accept'. (Also true for $undefined.)
# to declare '%type <field> $accept'. (Also true for $undefined.)
# - Thus, the compiler might complain that the user code assumes the wrong
# type for $$ since the code might assume the type associated with a
# specific union field, which is especially reasonable in C++ since that
@@ -1494,115 +1607,6 @@ AT_TEST([glr.cc])
m4_popdef([AT_TEST])
## ----------------------------------------------- ##
## Fix user actions without a trailing semicolon. ##
## ----------------------------------------------- ##
AT_SETUP([[Fix user actions without a trailing semicolon]])
# This feature is undocumented, but we accidentally broke it in 2.3a,
# and there was a complaint at:
# <http://lists.gnu.org/archive/html/bug-bison/2008-11/msg00001.html>.
AT_BISON_OPTION_PUSHDEFS
AT_DATA([input.y],
[[%%
start: test2 test1 test0 testc;
test2
: 'a' { semi; /* TEST:N:2 */ }
| 'b' { if (0) {no_semi} /* TEST:N:2 */ }
| 'c' { if (0) {semi;} /* TEST:N:2 */ }
| 'd' { semi; no_semi /* TEST:Y:2 */ }
| 'e' { semi(); no_semi() /* TEST:Y:2 */ }
| 'f' { semi[]; no_semi[] /* TEST:Y:2 */ }
| 'g' { semi++; no_semi++ /* TEST:Y:2 */ }
| 'h' { {no_semi} no_semi /* TEST:Y:2 */ }
| 'i' { {semi;} no_semi /* TEST:Y:2 */ }
;
test1
: 'a' { semi; // TEST:N:1 ;
} | 'b' { if (0) {no_semi} // TEST:N:1 ;
} | 'c' { if (0) {semi;} // TEST:N:1 ;
} | 'd' { semi; no_semi // TEST:Y:1 ;
} | 'e' { semi(); no_semi() // TEST:Y:1 ;
} | 'f' { semi[]; no_semi[] // TEST:Y:1 ;
} | 'g' { semi++; no_semi++ // TEST:Y:1 ;
} | 'h' { {no_semi} no_semi // TEST:Y:1 ;
} | 'i' { {semi;} no_semi // TEST:Y:1 ;
} ;
test0
: 'a' { semi; // TEST:N:1 {}
} | 'b' { if (0) {no_semi} // TEST:N:1 {}
} | 'c' { if (0) {semi;} // TEST:N:1 {}
} | 'd' { semi; no_semi // TEST:Y:1 {}
} | 'e' { semi(); no_semi() // TEST:Y:1 {}
} | 'f' { semi[]; no_semi[] // TEST:Y:1 {}
} | 'g' { semi++; no_semi++ // TEST:Y:1 {}
} | 'h' { {no_semi} no_semi // TEST:Y:1 {}
} | 'i' { {semi;} no_semi // TEST:Y:1 {}
} ;
testc
: 'a' {
#define TEST_MACRO_N \
[]"broken\" $ @ $$ @$ [];\
string;"}
| 'b' {
no_semi
#define TEST_MACRO_N \
[]"broken\" $ @ $$ @$ [];\
string;"}
]])
AT_BISON_OPTION_POPDEFS
AT_BISON_CHECK([[-o input.c input.y]], [0], [],
[[input.y:8.48: warning: a ';' might be needed at the end of action code [-Wdeprecated]
input.y:8.48: future versions of Bison will not add the ';'
input.y:9.48: warning: a ';' might be needed at the end of action code [-Wdeprecated]
input.y:9.48: future versions of Bison will not add the ';'
input.y:10.48: warning: a ';' might be needed at the end of action code [-Wdeprecated]
input.y:10.48: future versions of Bison will not add the ';'
input.y:11.48: warning: a ';' might be needed at the end of action code [-Wdeprecated]
input.y:11.48: future versions of Bison will not add the ';'
input.y:12.48: warning: a ';' might be needed at the end of action code [-Wdeprecated]
input.y:12.48: future versions of Bison will not add the ';'
input.y:13.48: warning: a ';' might be needed at the end of action code [-Wdeprecated]
input.y:13.48: future versions of Bison will not add the ';'
input.y:20.1: warning: a ';' might be needed at the end of action code [-Wdeprecated]
input.y:20.1: future versions of Bison will not add the ';'
input.y:21.1: warning: a ';' might be needed at the end of action code [-Wdeprecated]
input.y:21.1: future versions of Bison will not add the ';'
input.y:22.1: warning: a ';' might be needed at the end of action code [-Wdeprecated]
input.y:22.1: future versions of Bison will not add the ';'
input.y:23.1: warning: a ';' might be needed at the end of action code [-Wdeprecated]
input.y:23.1: future versions of Bison will not add the ';'
input.y:24.1: warning: a ';' might be needed at the end of action code [-Wdeprecated]
input.y:24.1: future versions of Bison will not add the ';'
input.y:25.1: warning: a ';' might be needed at the end of action code [-Wdeprecated]
input.y:25.1: future versions of Bison will not add the ';'
input.y:31.1: warning: a ';' might be needed at the end of action code [-Wdeprecated]
input.y:31.1: future versions of Bison will not add the ';'
input.y:32.1: warning: a ';' might be needed at the end of action code [-Wdeprecated]
input.y:32.1: future versions of Bison will not add the ';'
input.y:33.1: warning: a ';' might be needed at the end of action code [-Wdeprecated]
input.y:33.1: future versions of Bison will not add the ';'
input.y:34.1: warning: a ';' might be needed at the end of action code [-Wdeprecated]
input.y:34.1: future versions of Bison will not add the ';'
input.y:35.1: warning: a ';' might be needed at the end of action code [-Wdeprecated]
input.y:35.1: future versions of Bison will not add the ';'
input.y:36.1: warning: a ';' might be needed at the end of action code [-Wdeprecated]
input.y:36.1: future versions of Bison will not add the ';'
]])
AT_MATCHES_CHECK([input.c], [[/\* TEST:N:2 \*/ \}$]], [[3]])
AT_MATCHES_CHECK([input.c], [[/\* TEST:Y:2 \*/ ;\}$]], [[6]])
AT_MATCHES_CHECK([input.c], [[// TEST:N:1 [;{}]*\n\}$]], [[6]])
AT_MATCHES_CHECK([input.c], [[// TEST:Y:1 [;{}]*\n;\}$]], [[12]])
AT_MATCHES_CHECK([input.c], [[#define TEST_MACRO_N \\\n\[\]"broken\\" \$ \@ \$\$ \@\$ \[\];\\\nstring;"\}]], [[2]])
AT_CLEANUP
## -------------------------------------------------- ##
## Destroying lookahead assigned by semantic action. ##
## -------------------------------------------------- ##
@@ -1637,7 +1641,7 @@ AT_DATA_GRAMMAR([input.y],
// that has set yychar might not always return normally. Instead,
// skeletons must translate before every use of yytoken.
start: 'a' accept { USE($1); } ;
accept: /*empty*/ {
accept: %empty {
assert (yychar == YYEMPTY);
yychar = 'b';
YYACCEPT;
+31 -4
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/>.
# We need `config.h'.
# We need 'config.h'.
CPPFLAGS="-I$abs_top_builddir/lib @CPPFLAGS@"
# Don't just check if $POSIXLY_CORRECT is set, as Bash, when launched
@@ -47,12 +47,39 @@ NO_WERROR_CXXFLAGS='@CXXFLAGS@ @WARN_CXXFLAGS@ @WARN_CXXFLAGS_TEST@'
CFLAGS="$NO_WERROR_CFLAGS @WERROR_CFLAGS@"
CXXFLAGS="$NO_WERROR_CXXFLAGS @WERROR_CXXFLAGS@"
# C++ variants break strict aliasing analysis.
NO_STRICT_ALIAS_CXXFLAGS='@NO_STRICT_ALIAS_CXXFLAGS@'
# If 'exit 77'; skip all C++ tests; otherwise ':'.
BISON_CXX_WORKS='@BISON_CXX_WORKS@'
# 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.
#
# http://lists.gnu.org/archive/html/bug-bison/2013-06/msg00001.html
#
# FIXME: Check (say 2014) whether this is still needed.
if $BISON_CXX_WORKS; then
# See AT_DATA_SOURCE_PROLOGUE.
cat >conftest.cc <<EOF
#include <config.h>
/* We don't need perfect functions for these tests. */
#undef malloc
#undef memcmp
#undef realloc
#include <iostream>
int main ()
{
std::cout << "Works" << std::endl;
}
EOF
$CXX $CXXFLAGS $CPPFLAGS $LDFLAGS $LIBS -o conftest conftest.cc
case $? in
0);;
*) BISON_CXX_WORKS="as_fn_error 77 cannot-compile-simple-program";;
esac
rm -fr conftest*
fi
# Whether the compiler supports POSIXLY_CORRECT defined.
: ${C_COMPILER_POSIXLY_CORRECT='@C_COMPILER_POSIXLY_CORRECT@'}
: ${CXX_COMPILER_POSIXLY_CORRECT='@CXX_COMPILER_POSIXLY_CORRECT@'}
+152 -69
View File
@@ -18,6 +18,68 @@
AT_BANNER([[C++ Features.]])
## --------------- ##
## C++ Locations. ##
## --------------- ##
AT_SETUP([C++ Locations])
AT_BISON_OPTION_PUSHDEFS([%locations %skeleton "lalr1.cc"])
AT_DATA_GRAMMAR([[input.y]],
[[%code {#include <sstream>}
%locations
%debug
%skeleton "lalr1.cc"
%code
{
]AT_YYERROR_DECLARE[
]AT_YYLEX_DECLARE[
}
%%
exp: %empty;
%%
]AT_YYERROR_DEFINE[
]AT_YYLEX_DEFINE[
template <typename T>
bool
check (const T& in, const std::string& s)
{
std::stringstream os;
os << in;
if (os.str () != s)
{
std::cerr << "fail: " << os.str () << ", expected: " << s << std::endl;
return false;
}
return true;
}
int
main (void)
{
int fail = 0;
]AT_YYLTYPE[ loc; fail += check (loc, "1.1");
loc += 10; fail += check (loc, "1.1-10");
loc += -5; fail += check (loc, "1.1-5");
loc -= 5; fail += check (loc, "1.1");
// Check that we don't go below.
// http://lists.gnu.org/archive/html/bug-bison/2013-02/msg00000.html
loc -= 10; fail += check (loc, "1.1");
loc.columns (10); loc.lines (10); fail += check (loc, "1.1-11.0");
loc.lines (-2); fail += check (loc, "1.1-9.0");
loc.lines (-10); fail += check (loc, "1.1");
return !fail;
}
]])
AT_FULL_COMPILE([input])
AT_PARSER_CHECK([./input], 0)
AT_BISON_OPTION_POPDEFS
AT_CLEANUP
## --------------------------- ##
## C++ Variant-based Symbols. ##
## --------------------------- ##
@@ -28,7 +90,7 @@ AT_KEYWORDS([variant])
AT_BISON_OPTION_PUSHDEFS([%skeleton "lalr1.cc" %debug $1])
# Store strings and integers in a list of strings.
AT_DATA_GRAMMAR([list.yy],
AT_DATA_GRAMMAR([list.y],
[[%skeleton "lalr1.cc"
%define api.value.type variant
%define parse.assert
@@ -92,8 +154,7 @@ int main()
}
]])
AT_BISON_CHECK([-o list.cc list.yy])
AT_COMPILE_CXX([list], [$NO_STRICT_ALIAS_CXXFLAGS list.cc])
AT_FULL_COMPILE([list])
AT_PARSER_CHECK([./list], 0, [],
[12
123
@@ -113,11 +174,10 @@ AT_CLEANUP
m4_pushdef([AT_TEST],
[AT_SETUP([Variants $1])
AT_BISON_OPTION_PUSHDEFS([%skeleton "lalr1.cc" %debug $1])
AT_BISON_OPTION_PUSHDEFS([%debug $1])
# Store strings and integers in a list of strings.
AT_DATA_GRAMMAR([list.yy],
AT_DATA_GRAMMAR([list.y],
[[%debug
%skeleton "lalr1.cc"
%define api.value.type variant
]m4_bpatsubst([$1], [\\n], [
])[
@@ -183,7 +243,7 @@ typedef std::list<std::string> strings_type;
// digraph for the left square bracket.
%type <::std::list<std::string>> list result;
%printer { yyo << $][$; }
%printer { yyo << $$; }
<int> <::std::string> <::std::list<std::string>>;
%%
@@ -193,13 +253,13 @@ result:
list:
/* nothing */ { /* Generates an empty string list */ }
| list item { std::swap ($][$,$][1); $$.push_back ($][2); }
| list error { std::swap ($][$,$][1); }
| list item { std::swap ($$,$][1); $$.push_back ($][2); }
| list error { std::swap ($$,$][1); }
;
item:
TEXT { std::swap ($][$,$][1); }
| NUMBER { if ($][1 == 3) YYERROR; else $][$ = string_cast ($][1); }
TEXT { std::swap ($$,$][1); }
| NUMBER { if ($][1 == 3) YYERROR; else $$ = string_cast ($][1); }
;
%%
]AT_TOKEN_CTOR_IF([],
@@ -250,8 +310,7 @@ namespace yy
]AT_MAIN_DEFINE[
]])
AT_BISON_CHECK([-o list.cc list.yy])
AT_COMPILE_CXX([list], [$NO_STRICT_ALIAS_CXXFLAGS list.cc])
AT_FULL_COMPILE([list])
AT_PARSER_CHECK([./list], 0,
[(0, 1, 2, 4)
])
@@ -260,13 +319,13 @@ AT_BISON_OPTION_POPDEFS
AT_CLEANUP
])
AT_TEST([])
AT_TEST([%define parse.assert])
AT_TEST([%locations %define parse.assert])
AT_TEST([[%define parse.assert %code {\n#define TWO_STAGE_BUILD\n}]])
AT_TEST([[%define parse.assert %define api.token.constructor]])
AT_TEST([[%define parse.assert %define api.token.constructor %define api.token.prefix "TOK_"]])
AT_TEST([[%locations %define parse.assert %define api.token.constructor %define api.token.prefix "TOK_"]])
AT_TEST([[%skeleton "lalr1.cc" ]])
AT_TEST([[%skeleton "lalr1.cc" %define parse.assert]])
AT_TEST([[%skeleton "lalr1.cc" %locations %define parse.assert]])
AT_TEST([[%skeleton "lalr1.cc" %define parse.assert %code {\n#define TWO_STAGE_BUILD\n}]])
AT_TEST([[%skeleton "lalr1.cc" %define parse.assert %define api.token.constructor]])
AT_TEST([[%skeleton "lalr1.cc" %define parse.assert %define api.token.constructor %define api.token.prefix {TOK_}]])
AT_TEST([[%skeleton "lalr1.cc" %locations %define parse.assert %define api.token.constructor %define api.token.prefix {TOK_}]])
m4_popdef([AT_TEST])
@@ -363,10 +422,10 @@ AT_CHECK_DOXYGEN([Private])
# is specified, then Bison should accept the input, but compilation will fail,
# so don't check compilation.
m4_pushdef([AT_TEST],
[AT_BISON_OPTION_PUSHDEFS([%language "C++" %define api.namespace "$1"])
[AT_BISON_OPTION_PUSHDEFS([%language "C++" %define api.namespace {$1}])
AT_DATA_GRAMMAR([[input.y]],
[[%language "C++"
%define api.namespace "]$1["
%define api.namespace {]$1[}
%union { int i; }
%define global_tokens_and_yystype
%locations
@@ -422,8 +481,8 @@ AT_CLEANUP
AT_SETUP([[Syntactically invalid namespace references]])
AT_TEST([[:foo:bar]], [[-]])
AT_TEST([[foo: :bar]], [[-]])
# This one is interesting because `[3]' is encoded as `@<:@3@:>@', which
# contains single occurrences of `:'.
# This one is interesting because '[3]' is encoded as '@<:@3@:>@', which
# contains single occurrences of ':'.
AT_TEST([[foo[3]::bar::baz]], [[-]])
AT_TEST([[foo::bar,baz]], [[-]])
AT_TEST([[foo::bar::(baz /* Pacify Emacs ) */]], [[-]])
@@ -590,11 +649,14 @@ AT_CLEANUP
## Exception safety. ##
## ------------------ ##
# AT_TEST([BISON-DIRECTIVES])
# ---------------------------
# AT_TEST([BISON-DIRECTIVES = ''], [WITH-RECOVERY = "with"])
# ----------------------------------------------------------
# Check that no object is leaked when exceptions are thrown.
# WITH-RECOVERY = "with" or "without".
m4_pushdef([AT_TEST],
[AT_SETUP([[Exception safety $1]])
[AT_SETUP([[Exception safety $2 error recovery $1]])
AT_SKIP_IF_EXCEPTION_SUPPORT_IS_POOR
AT_BISON_OPTION_PUSHDEFS([%skeleton "lalr1.cc" $1])
@@ -608,21 +670,59 @@ $1
#include <cassert>
#include <cstdlib> // size_t and getenv.
#include <iostream>
#include <list>
#include <set>
bool debug = false;
/// A class that counts its number of instances.
/// A class that tracks its instances.
struct Object
{
typedef std::list<const Object*> objects;
static objects instances;
char val;
Object ()
: val ('?')
{
log (this, "Object::Object");
Object::instances.insert (this);
}
Object (const Object& that)
: val (that.val)
{
log (this, "Object::Object");
Object::instances.insert (this);
}
Object (char v)
: val (v)
{
log (this, "Object::Object");
Object::instances.insert (this);
}
~Object ()
{
log (this, "Object::~Object");
objects::const_iterator i = instances.find (this);
// Make sure this object is alive.
assert (i != instances.end ());
Object::instances.erase (i);
}
Object& operator= (char v)
{
val = v;
return *this;
}
// Static part.
typedef std::set<const Object*> objects;
static objects instances;
static bool
empty ()
{
return instances.empty();
return instances.empty ();
}
static void
@@ -645,26 +745,6 @@ $1
std::cerr << " }" << std::endl;
}
}
Object (char v)
: val (v)
{
instances.push_back(this);
log (this, "Object::Object");
}
Object ()
: val ('?')
{
instances.push_back(this);
log (this, "Object::Object");
}
~Object ()
{
instances.remove(this);
log (this, "Object::~Object");
}
};
}
@@ -716,22 +796,23 @@ $1
start: list {]AT_VARIANT_IF([], [ delete $][1]; )[};
list:
item { $][$ = $][1; }
item { $$ = $][1; }
// Right recursion to load the stack.
| item list { $][$ = $][1; ]AT_VARIANT_IF([], [delete $][2]; )[}
| item list { $$ = $][1; ]AT_VARIANT_IF([], [delete $][2]; )[}
;
item:
'a' { $$][ = $][1; }
| 'e' { YYUSE ($][$); YYUSE($][1); error ("syntax error"); }
'a' { $$ = $][1; }
| 'e' { YYUSE ($$); YYUSE($][1); error ("syntax error"); }
// Not just 'E', otherwise we reduce when 'E' is the lookahead, and
// then the stack is emptied, defeating the point of the test.
| 'E' 'a' { YYUSE($][1); $][$ = $][2; }
| 'R' { $][$ = YY_NULL; ]AT_VARIANT_IF([], [delete $][1]; )[YYERROR; }
| 'p' { $][$ = $][1; }
| 's' { $][$ = $][1; throw std::runtime_error ("reduction"); }
| 'T' { $][$ = YY_NULL; ]AT_VARIANT_IF([], [delete $][1]; )[YYABORT; }
| error { $][$ = YY_NULL; yyerrok; }
| 'E' 'a' { YYUSE($][1); $$ = $][2; }
| 'R' { ]AT_VARIANT_IF([], [$$ = YY_NULLPTR; delete $][1]; )[YYERROR; }
| 'p' { $$ = $][1; }
| 's' { $$ = $][1; throw std::runtime_error ("reduction"); }
| 'T' { ]AT_VARIANT_IF([], [$$ = YY_NULLPTR; delete $][1]; )[YYABORT; }
]m4_if([$2], [with],
[[| error { $$ = ]AT_VARIANT_IF([], [new ])[Object ('R'); yyerrok; }]])[
;
%%
@@ -751,7 +832,8 @@ yylex (yy::parser::semantic_type *lvalp)
case 'l':
throw std::runtime_error ("yylex");
default:
lvalp]AT_VARIANT_IF([->build (res)], [->obj = new Object (res)])[;
lvalp->]AT_VARIANT_IF([build (Object (res))],
[obj = new Object (res)])[;
// Fall through.
case 0:
return res;
@@ -798,13 +880,13 @@ main (int argc, const char *argv[])
{
std::cerr << "unknown exception caught" << std::endl;
}
Object::log (YY_NULL, "end");
Object::log (YY_NULLPTR, "end");
assert (Object::empty());
return res;
}
]])
AT_BISON_CHECK([[-o input.cc --report=all input.yy]])
AT_COMPILE_CXX([input], [[$NO_STRICT_ALIAS_CXXFLAGS input.cc]])
AT_COMPILE_CXX([[input]])
AT_PARSER_CHECK([[./input aaaas]], [[2]], [[]],
[[exception caught: reduction
@@ -833,16 +915,17 @@ AT_PARSER_CHECK([[./input aaaaE]], [[2]], [[]],
AT_PARSER_CHECK([[./input aaaaT]], [[1]])
# There is error-recovery, so exit success.
AT_PARSER_CHECK([[./input aaaaR]], [[0]])
AT_PARSER_CHECK([[./input aaaaR]], [m4_if([$2], [with], [0], [1])])
AT_BISON_OPTION_POPDEFS
AT_CLEANUP
])
AT_TEST
AT_TEST([%define api.value.type variant])
AT_TEST([], [with])
AT_TEST([], [without])
AT_TEST([%define api.value.type variant], [with])
AT_TEST([%define api.value.type variant], [without])
m4_popdef([AT_TEST])
+48 -48
View File
@@ -27,11 +27,11 @@
# _AT_DATA_CALC_Y($1, $2, $3, [BISON-DIRECTIVES])
# -----------------------------------------------
# Produce `calc.y' and, if %defines was specified, `calc-lex.c' or
# `calc-lex.cc'.
# Produce 'calc.y' and, if %defines was specified, 'calc-lex.c' or
# 'calc-lex.cc'.
#
# Don't call this macro directly, because it contains some occurrences
# of `$1' etc. which will be interpreted by m4. So you should call it
# of '$1' etc. which will be interpreted by m4. So you should call it
# with $1, $2, and $3 as arguments, which is what AT_DATA_CALC_Y does.
#
# When %defines is not passed, generate a single self-contained file.
@@ -72,10 +72,12 @@ main (int argc, const char **argv)
int count = 0;
int status;
/* This used to be alarm (10), but that isn't enough time for
a July 1995 vintage DEC Alphastation 200 4/100 system,
according to Nelson H. F. Beebe. 100 seconds is enough. */
alarm (100);
/* This used to be alarm (10), but that isn't enough time for a July
1995 vintage DEC Alphastation 200 4/100 system, according to
Nelson H. F. Beebe. 100 seconds was enough for regular users,
but the Hydra build farm, which is heavily loaded needs more. */
alarm (200);
if (argc == 2)
input = fopen (argv[1], "r");
@@ -88,8 +90,7 @@ main (int argc, const char **argv)
return 3;
}
]AT_SKEL_CC_IF([], [m4_bmatch([$4], [%debug],
[ ]AT_NAME_PREFIX[debug = 1;])])[
]AT_SKEL_CC_IF([], [AT_DEBUG_IF([ ]AT_NAME_PREFIX[debug = 1;])])[
status = ]AT_NAME_PREFIX[parse (]AT_PARAM_IF([[&result, &count]])[);
if (fclose (input))
perror ("fclose");
@@ -133,7 +134,7 @@ unget_char (]AT_YYLEX_PRE_FORMALS[ int c)
{
]AT_USE_LEX_ARGS[;
]AT_LOCATION_IF([
/* Wrong when C == `\n'. */
/* Wrong when C == '\n'. */
AT_LOC = last_yylloc;
])[
ungetc (c, input);
@@ -365,8 +366,8 @@ m4_popdef([AT_CALC_LEX])
# AT_DATA_CALC_Y([BISON-OPTIONS])
# -------------------------------
# Produce `calc.y' and, if %defines was specified, `calc-lex.c' or
# `calc-lex.cc'.
# Produce 'calc.y' and, if %defines was specified, 'calc-lex.c' or
# 'calc-lex.cc'.
m4_define([AT_DATA_CALC_Y],
[_AT_DATA_CALC_Y($[1], $[2], $[3], [$1])
])
@@ -375,9 +376,9 @@ m4_define([AT_DATA_CALC_Y],
# _AT_CHECK_CALC(BISON-OPTIONS, INPUT, [NUM-STDERR-LINES])
# --------------------------------------------------------
# Run `calc' on INPUT and expect no STDOUT nor STDERR.
# Run 'calc' on INPUT and expect no STDOUT nor STDERR.
#
# If BISON-OPTIONS contains `%debug' but not `%glr-parser', then
# If BISON-OPTIONS contains '%debug' but not '%glr-parser', then
#
# NUM-STDERR-LINES is the number of expected lines on stderr.
# Currently this is ignored, though, since the output format is fluctuating.
@@ -396,7 +397,7 @@ AT_PARSER_CHECK([./calc input], 0, [], [stderr])
# [NUM-STDERR-LINES],
# [VERBOSE-AND-LOCATED-ERROR-MESSAGE])
# ---------------------------------------------------------
# Run `calc' on INPUT, and expect a `syntax error' message.
# Run 'calc' on INPUT, and expect a 'syntax error' message.
#
# If INPUT starts with a slash, it is used as absolute input file name,
# otherwise as contents.
@@ -404,14 +405,14 @@ AT_PARSER_CHECK([./calc input], 0, [], [stderr])
# NUM-STDERR-LINES is the number of expected lines on stderr.
# Currently this is ignored, though, since the output format is fluctuating.
#
# If BISON-OPTIONS contains `%location', then make sure the ERROR-LOCATION
# If BISON-OPTIONS contains '%location', then make sure the ERROR-LOCATION
# is correctly output on stderr.
#
# If BISON-OPTIONS contains `%define parse.error verbose', then make sure the
# IF-YYERROR-VERBOSE message is properly output after `syntax error, '
# If BISON-OPTIONS contains '%define parse.error verbose', then make sure the
# IF-YYERROR-VERBOSE message is properly output after 'syntax error, '
# on STDERR.
#
# If BISON-OPTIONS contains `%debug' but not `%glr', then NUM-STDERR-LINES
# If BISON-OPTIONS contains '%debug' but not '%glr', then NUM-STDERR-LINES
# is the number of expected lines on stderr.
m4_define([_AT_CHECK_CALC_ERROR],
[m4_bmatch([$3], [^/],
@@ -448,7 +449,7 @@ AT_DATA([[expout]],
AT_YYERROR_SEES_LOC_IF([],
[[sed 's/^[-0-9.]*: //' expout >at-expout
mv at-expout expout]])
# 4. If error-verbose is not used, strip the`, unexpected....' part.
# 4. If error-verbose is not used, strip the', unexpected....' part.
m4_bmatch([$1], [%define parse.error verbose], [],
[[sed 's/syntax error, .*$/syntax error/' expout >at-expout
mv at-expout expout]])
@@ -478,7 +479,7 @@ m4_define([AT_CHECK_SPACES],
# AT_CHECK_CALC([BISON-OPTIONS])
# ------------------------------
# Start a testing chunk which compiles `calc' grammar with
# 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])])
@@ -538,7 +539,7 @@ _AT_CHECK_CALC_ERROR([$1], [1], [/dev/null], [4],
# - (* * *): nothing to pop, a lot to discard
# - (1 + 2 * *): some to pop and discard
#
# - test the action associated to `error'
# - test the action associated to 'error'
#
# - check the lookahead that triggers an error is not discarded
# when we enter error recovery. Below, the lookahead causing the
@@ -587,7 +588,7 @@ AT_BANNER([[Simple LALR(1) Calculator.]])
# AT_CHECK_CALC_LALR([BISON-OPTIONS])
# -----------------------------------
# Start a testing chunk which compiles `calc' grammar with
# Start a testing chunk which compiles 'calc' grammar with
# BISON-OPTIONS, and performs several tests over the parser.
m4_define([AT_CHECK_CALC_LALR],
[AT_CHECK_CALC($@)])
@@ -606,17 +607,17 @@ AT_CHECK_CALC_LALR([%define api.pure full %locations])
AT_CHECK_CALC_LALR([%define api.push-pull both %define api.pure full %locations])
AT_CHECK_CALC_LALR([%define parse.error verbose %locations])
AT_CHECK_CALC_LALR([%define parse.error verbose %locations %defines %define api.prefix "calc" %verbose %yacc])
AT_CHECK_CALC_LALR([%define parse.error verbose %locations %defines %name-prefix "calc" %define api.token.prefix "TOK_" %verbose %yacc])
AT_CHECK_CALC_LALR([%define parse.error verbose %locations %defines %define api.prefix {calc} %verbose %yacc])
AT_CHECK_CALC_LALR([%define parse.error verbose %locations %defines %name-prefix "calc" %define api.token.prefix {TOK_} %verbose %yacc])
AT_CHECK_CALC_LALR([%debug])
AT_CHECK_CALC_LALR([%define parse.error verbose %debug %locations %defines %name-prefix "calc" %verbose %yacc])
AT_CHECK_CALC_LALR([%define parse.error verbose %debug %locations %defines %define api.prefix "calc" %verbose %yacc])
AT_CHECK_CALC_LALR([%define parse.error verbose %debug %locations %defines %define api.prefix {calc} %verbose %yacc])
AT_CHECK_CALC_LALR([%define api.pure full %define parse.error verbose %debug %locations %defines %name-prefix "calc" %verbose %yacc])
AT_CHECK_CALC_LALR([%define api.push-pull both %define api.pure full %define parse.error verbose %debug %locations %defines %define api.prefix "calc" %verbose %yacc])
AT_CHECK_CALC_LALR([%define api.push-pull both %define api.pure full %define parse.error verbose %debug %locations %defines %define api.prefix {calc} %verbose %yacc])
AT_CHECK_CALC_LALR([%define api.pure %define parse.error verbose %debug %locations %defines %define api.prefix "calc" %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}])
AT_CHECK_CALC_LALR([%define api.pure %define parse.error verbose %debug %locations %defines %define api.prefix {calc} %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}])
# ----------------------- #
@@ -627,7 +628,7 @@ AT_BANNER([[Simple GLR Calculator.]])
# AT_CHECK_CALC_GLR([BISON-OPTIONS])
# ----------------------------------
# Start a testing chunk which compiles `calc' grammar with
# Start a testing chunk which compiles 'calc' grammar with
# BISON-OPTIONS and %glr-parser, and performs several tests over the parser.
m4_define([AT_CHECK_CALC_GLR],
[AT_CHECK_CALC([%glr-parser] $@)])
@@ -638,7 +639,7 @@ AT_CHECK_CALC_GLR()
AT_CHECK_CALC_GLR([%defines])
AT_CHECK_CALC_GLR([%locations])
AT_CHECK_CALC_GLR([%name-prefix "calc"])
AT_CHECK_CALC_GLR([%define api.prefix "calc"])
AT_CHECK_CALC_GLR([%define api.prefix {calc}])
AT_CHECK_CALC_GLR([%verbose])
AT_CHECK_CALC_GLR([%yacc])
AT_CHECK_CALC_GLR([%define parse.error verbose])
@@ -650,12 +651,12 @@ AT_CHECK_CALC_GLR([%define parse.error verbose %locations %defines %name-prefix
AT_CHECK_CALC_GLR([%debug])
AT_CHECK_CALC_GLR([%define parse.error verbose %debug %locations %defines %name-prefix "calc" %verbose %yacc])
AT_CHECK_CALC_GLR([%define parse.error verbose %debug %locations %defines %define api.prefix "calc" %define api.token.prefix "TOK_" %verbose %yacc])
AT_CHECK_CALC_GLR([%define parse.error verbose %debug %locations %defines %define api.prefix {calc} %define api.token.prefix {TOK_} %verbose %yacc])
AT_CHECK_CALC_GLR([%define api.pure %define parse.error verbose %debug %locations %defines %name-prefix "calc" %verbose %yacc])
AT_CHECK_CALC_GLR([%define api.pure %define parse.error verbose %debug %locations %defines %name-prefix "calc" %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}])
AT_CHECK_CALC_GLR([%define api.pure %define parse.error verbose %debug %locations %defines %define api.prefix "calc" %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}])
AT_CHECK_CALC_GLR([%define api.pure %define parse.error verbose %debug %locations %defines %define api.prefix {calc} %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}])
# ----------------------------- #
@@ -669,26 +670,26 @@ AT_CHECK_CALC([%skeleton "lalr1.cc" %defines])
# AT_CHECK_CALC_LALR1_CC([BISON-OPTIONS])
# ---------------------------------------
# Start a testing chunk which compiles `calc' grammar with
# 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_LALR1_CC([])
AT_CHECK_CALC_LALR1_CC([%locations])
AT_CHECK_CALC_LALR1_CC([%locations %define api.location.type Span])
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])
AT_CHECK_CALC_LALR1_CC([%locations %define parse.error verbose %define api.prefix "calc" %verbose %yacc])
AT_CHECK_CALC_LALR1_CC([%locations %define parse.error verbose %define api.prefix {calc} %verbose %yacc])
AT_CHECK_CALC_LALR1_CC([%locations %define parse.error verbose %debug %name-prefix "calc" %verbose %yacc])
AT_CHECK_CALC_LALR1_CC([%locations %pure-parser %define parse.error verbose %debug %define api.prefix "calc" %verbose %yacc])
AT_CHECK_CALC_LALR1_CC([%locations %pure-parser %define parse.error verbose %debug %define api.prefix "calc" %define api.token.prefix "TOK_" %verbose %yacc])
AT_CHECK_CALC_LALR1_CC([%locations %define parse.error verbose %debug %define api.prefix {calc} %verbose %yacc])
AT_CHECK_CALC_LALR1_CC([%locations %define parse.error verbose %debug %define api.prefix {calc} %define api.token.prefix {TOK_} %verbose %yacc])
AT_CHECK_CALC_LALR1_CC([%defines %locations %pure-parser %define parse.error verbose %debug %name-prefix "calc" %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}])
AT_CHECK_CALC_LALR1_CC([%defines %locations %define parse.error verbose %debug %name-prefix "calc" %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}])
AT_CHECK_CALC_LALR1_CC([%pure-parser %define parse.error verbose %debug %define api.prefix "calc" %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}])
AT_CHECK_CALC_LALR1_CC([%defines %locations %pure-parser %define parse.error verbose %debug %define api.prefix "calc" %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}])
AT_CHECK_CALC_LALR1_CC([%define parse.error verbose %debug %define api.prefix {calc} %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}])
AT_CHECK_CALC_LALR1_CC([%defines %locations %define parse.error verbose %debug %define api.prefix {calc} %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}])
@@ -703,22 +704,21 @@ AT_CHECK_CALC([%skeleton "glr.cc"])
# AT_CHECK_CALC_GLR_CC([BISON-OPTIONS])
# -------------------------------------
# Start a testing chunk which compiles `calc' grammar with
# Start a testing chunk which compiles 'calc' grammar with
# the GLR C++ skeleton, and performs several tests over the parser.
m4_define([AT_CHECK_CALC_GLR_CC],
[AT_CHECK_CALC([%language "C++" %glr-parser] $@)])
AT_CHECK_CALC_GLR_CC([])
AT_CHECK_CALC_GLR_CC([%locations])
AT_CHECK_CALC_GLR_CC([%locations %define api.location.type Span])
AT_CHECK_CALC_GLR_CC([%locations %define api.location.type {Span}])
AT_CHECK_CALC_GLR_CC([%defines %define parse.error verbose %name-prefix "calc" %verbose %yacc])
AT_CHECK_CALC_GLR_CC([%define parse.error verbose %define api.prefix "calc" %verbose %yacc])
AT_CHECK_CALC_GLR_CC([%define parse.error verbose %define api.prefix {calc} %verbose %yacc])
AT_CHECK_CALC_GLR_CC([%debug])
AT_CHECK_CALC_GLR_CC([%define parse.error verbose %debug %name-prefix "calc" %verbose %yacc])
AT_CHECK_CALC_GLR_CC([%define parse.error verbose %debug %name-prefix "calc" %define api.token.prefix {TOK_} %verbose %yacc])
AT_CHECK_CALC_GLR_CC([%pure-parser %define parse.error verbose %debug %name-prefix "calc" %verbose %yacc])
AT_CHECK_CALC_GLR_CC([%pure-parser %define parse.error verbose %debug %name-prefix "calc" %define api.token.prefix "TOK_" %verbose %yacc])
AT_CHECK_CALC_GLR_CC([%locations %defines %pure-parser %define parse.error verbose %debug %name-prefix "calc" %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}])
AT_CHECK_CALC_GLR_CC([%locations %defines %pure-parser %define parse.error verbose %debug %define api.prefix "calc" %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}])
AT_CHECK_CALC_GLR_CC([%locations %defines %define parse.error verbose %debug %name-prefix "calc" %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}])
AT_CHECK_CALC_GLR_CC([%locations %defines %define parse.error verbose %debug %define api.prefix {calc} %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}])
+179 -111
View File
@@ -17,42 +17,9 @@
AT_BANNER([[Conflicts.]])
## ------------------------------ ##
## Useless associativity warning. ##
## ------------------------------ ##
AT_SETUP([Useless associativity warning])
AT_DATA([[input.y]],
[[%token T
%left A B
%right C
%nonassoc D
%precedence E
%%
e: T A T
| T B T
| T C T
| T D T
| T E T
;
]])
AT_BISON_CHECK([input.y], 0, [],
[[input.y:5.13: warning: useless precedence for E [-Wother]
input.y:2.7: warning: useless associativity for A [-Wother]
input.y:2.9: warning: useless associativity for B [-Wother]
input.y:3.8: warning: useless associativity for C [-Wother]
input.y:4.11: warning: useless associativity for D [-Wother]
]])
AT_CLEANUP
## ------------------------ ##
## Token declaration order. ##
## ------------------------ ##
## ------------------------- ##
## Token declaration order. ##
## ------------------------- ##
# This test checks that token are declared left to right when in a precedence
# statement.
@@ -110,27 +77,7 @@ int main (void)
}
]])
AT_BISON_CHECK([-o input.c input.y], [], [],
[[input.y:24.13: warning: useless precedence for R [-Wother]
input.y:24.15: warning: useless precedence for S [-Wother]
input.y:24.17: warning: useless precedence for T [-Wother]
input.y:24.19: warning: useless precedence for U [-Wother]
input.y:25.13: warning: useless precedence for V [-Wother]
input.y:25.15: warning: useless precedence for W [-Wother]
input.y:18.8: warning: useless associativity for E [-Wother]
input.y:18.10: warning: useless associativity for F [-Wother]
input.y:18.12: warning: useless associativity for G [-Wother]
input.y:19.8: warning: useless associativity for H [-Wother]
input.y:19.10: warning: useless associativity for I [-Wother]
input.y:20.8: warning: useless associativity for J [-Wother]
input.y:21.8: warning: useless associativity for K [-Wother]
input.y:22.8: warning: useless associativity for L [-Wother]
input.y:22.10: warning: useless associativity for M [-Wother]
input.y:22.12: warning: useless associativity for N [-Wother]
input.y:23.11: warning: useless associativity for O [-Wother]
input.y:23.13: warning: useless associativity for P [-Wother]
input.y:23.15: warning: useless associativity for Q [-Wother]
]])
AT_BISON_CHECK([-o input.c input.y])
AT_COMPILE([input])
AT_PARSER_CHECK([./input])
@@ -140,6 +87,127 @@ AT_BISON_OPTION_POPDEFS
AT_CLEANUP
## --------------------------------------------------- ##
## Token declaration order: literals vs. identifiers. ##
## --------------------------------------------------- ##
# This test checks that when several tokens are declared by the same keyword,
# some of them defined as a character ('a'), others as simple textual reference
# (A), they are declared correctly left to right.
# Previously, the following test would declare the states in the order 'o' 'p'
# M N, instead of M N 'o' 'p'.
AT_SETUP([Token declaration order: literals vs. identifiers])
AT_DATA_GRAMMAR([[input.y]],
[[%token 'a' 'b' C D
%token E F 'g' 'h'
%right 'i' 'j' K L
%right M N 'o' 'p'
%%
exp: 'a'
| 'b'
| C
| D
| E
| F
| 'g'
| 'h'
| 'i'
| 'j'
| K
| L
| M
| N
| 'o'
| 'p'
;
%%
]])
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,
[[State 0
0 $accept: . exp $end
1 exp: . 'a'
2 | . 'b'
3 | . C
4 | . D
5 | . E
6 | . F
7 | . 'g'
8 | . 'h'
9 | . 'i'
10 | . 'j'
11 | . K
12 | . L
13 | . M
14 | . N
15 | . 'o'
16 | . 'p'
'a' shift, and go to state 1
'b' shift, and go to state 2
C shift, and go to state 3
D shift, and go to state 4
E shift, and go to state 5
F shift, and go to state 6
'g' shift, and go to state 7
'h' shift, and go to state 8
'i' shift, and go to state 9
'j' shift, and go to state 10
K shift, and go to state 11
L shift, and go to state 12
M shift, and go to state 13
N shift, and go to state 14
'o' shift, and go to state 15
'p' shift, and go to state 16
exp go to state 17
State 1
]])
AT_CLEANUP
## ------------------------------- ##
## Useless associativity warning. ##
## ------------------------------- ##
AT_SETUP([Useless associativity warning])
AT_DATA([[input.y]],
[[%token EQ "=" PL "+" ST "*" LP "("
%nonassoc "="
%left "+"
%left "*"
%precedence "("
%%
stmt:
exp
| "var" "=" exp
;
exp:
exp "+" exp
| exp "*" "num"
| "(" exp ")"
| "num"
;
]])
AT_BISON_CHECK([-Wprecedence input.y], 0, [],
[[input.y:2.1-9: warning: useless precedence and associativity for "=" [-Wprecedence]
input.y:4.1-5: warning: useless associativity for "*", use %precedence [-Wprecedence]
input.y:5.1-11: warning: useless precedence for "(" [-Wprecedence]
]])
AT_CLEANUP
## ---------------------------- ##
## Useless precedence warning. ##
## ---------------------------- ##
@@ -147,7 +215,7 @@ AT_CLEANUP
AT_SETUP([Useless precedence warning])
AT_DATA([[input.y]],
[[%token A B
[[%token A B U V W X Y Z
%precedence Z
%left X
%precedence Y
@@ -174,19 +242,19 @@ f: B
;
]])
AT_BISON_CHECK([-fcaret -o input.c input.y], 0, [],
[[input.y:2.13: warning: useless precedence for Z [-Wother]
%precedence Z
^
input.y:5.7: warning: useless associativity for W [-Wother]
%left W
^
input.y:6.8: warning: useless associativity for V [-Wother]
%right V
^
input.y:7.11: warning: useless associativity for U [-Wother]
AT_BISON_CHECK([-Wprecedence -fcaret -o input.c input.y], 0, [],
[[input.y:7.1-9: warning: useless precedence and associativity for U [-Wprecedence]
%nonassoc U
^
^^^^^^^^^
input.y:6.1-6: warning: useless precedence and associativity for V [-Wprecedence]
%right V
^^^^^^
input.y:5.1-5: warning: useless precedence and associativity for W [-Wprecedence]
%left W
^^^^^
input.y:2.1-11: warning: useless precedence for Z [-Wprecedence]
%precedence Z
^^^^^^^^^^^
]])
AT_CLEANUP
@@ -211,7 +279,7 @@ e: 'e' | /* Nothing. */;
]])
AT_BISON_CHECK([-o input.c input.y], 0, [],
[[input.y:4.9: warning: rule useless in parser due to conflicts: e: /* empty */ [-Wother]
[[input.y:4.9: warning: rule useless in parser due to conflicts [-Wother]
]])
AT_BISON_CHECK([-fcaret -o input.c input.y], 0, [],
@@ -939,7 +1007,7 @@ cond:
AT_BISON_CHECK([-o input.c input.y], 0, [],
[[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
input.y:12.3-18: warning: rule useless in parser due to conflicts: cond: cond "then" cond [-Wother]
input.y:12.3-18: warning: rule useless in parser due to conflicts [-Wother]
]])
AT_CLEANUP
@@ -955,13 +1023,13 @@ AT_CLEANUP
# $end reduce using rule 3 (num)
# $end [reduce using rule 4 (id)]
#
# But when `reduce 3' is the default action, we'd produce:
# But when 'reduce 3' is the default action, we'd produce:
#
# $end [reduce using rule 4 (id)]
# $default reduce using rule 3 (num)
#
# In this precise case (a reduction is masked by the default
# reduction), we make the `reduce 3' explicit:
# reduction), we make the 'reduce 3' explicit:
#
# $end reduce using rule 3 (num)
# $end [reduce using rule 4 (id)]
@@ -983,7 +1051,7 @@ id : '0';
AT_BISON_CHECK([-o input.c --report=all input.y], 0, [],
[[input.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
input.y:4.6-8: warning: rule useless in parser due to conflicts: id: '0' [-Wother]
input.y:4.6-8: warning: rule useless in parser due to conflicts [-Wother]
]])
# Check the contents of the report.
@@ -1196,10 +1264,10 @@ e: e '+' e
;
]])
AT_BISON_CHECK([-o input.c input.y], 0, [],
AT_BISON_CHECK([-Wall -o input.c input.y], 0, [],
[[input.y: warning: 4 shift/reduce conflicts [-Wconflicts-sr]
input.y:1.7-9: warning: useless associativity for '+' [-Wother]
input.y:2.7-9: warning: useless associativity for '*' [-Wother]
input.y:1.1-5: warning: useless precedence and associativity for '+' [-Wprecedence]
input.y:2.1-5: warning: useless precedence and associativity for '*' [-Wprecedence]
]])
AT_CLEANUP
@@ -1303,13 +1371,13 @@ reported_conflicts:
AT_BISON_CHECK([[--report=all input.y]], 0, [],
[[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
input.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
input.y:12.5-20: warning: rule useless in parser due to conflicts: resolved_conflict: 'a' unreachable1 [-Wother]
input.y:20.5-20: warning: rule useless in parser due to conflicts: unreachable1: 'a' unreachable2 [-Wother]
input.y:21.4: warning: rule useless in parser due to conflicts: unreachable1: /* empty */ [-Wother]
input.y:25.13: warning: rule useless in parser due to conflicts: unreachable2: /* empty */ [-Wother]
input.y:25.16: warning: rule useless in parser due to conflicts: unreachable2: /* empty */ [-Wother]
input.y:31.5-7: warning: rule useless in parser due to conflicts: reported_conflicts: 'a' [-Wother]
input.y:32.4: warning: rule useless in parser due to conflicts: reported_conflicts: /* empty */ [-Wother]
input.y:12.5-20: warning: rule useless in parser due to conflicts [-Wother]
input.y:20.5-20: warning: rule useless in parser due to conflicts [-Wother]
input.y:21.4: warning: rule useless in parser due to conflicts [-Wother]
input.y:25.13: warning: rule useless in parser due to conflicts [-Wother]
input.y:25.16: warning: rule useless in parser due to conflicts [-Wother]
input.y:31.5-7: warning: rule useless in parser due to conflicts [-Wother]
input.y:32.4: warning: rule useless in parser due to conflicts [-Wother]
]])
AT_CHECK([[cat input.output]], 0,
@@ -1318,13 +1386,13 @@ AT_CHECK([[cat input.output]], 0,
2 resolved_conflict: 'a' unreachable1
4 unreachable1: 'a' unreachable2
5 | /* empty */
5 | %empty
6 unreachable2: /* empty */
7 | /* empty */
6 unreachable2: %empty
7 | %empty
9 reported_conflicts: 'a'
10 | /* empty */
10 | %empty
State 4 conflicts: 1 shift/reduce
@@ -1338,17 +1406,17 @@ Grammar
1 start: resolved_conflict 'a' reported_conflicts 'a'
2 resolved_conflict: 'a' unreachable1
3 | /* empty */
3 | %empty
4 unreachable1: 'a' unreachable2
5 | /* empty */
5 | %empty
6 unreachable2: /* empty */
7 | /* empty */
6 unreachable2: %empty
7 | %empty
8 reported_conflicts: 'a'
9 | 'a'
10 | /* empty */
10 | %empty
Terminals, with rules where they appear
@@ -1379,7 +1447,7 @@ State 0
0 $accept: . start $end
1 start: . resolved_conflict 'a' reported_conflicts 'a'
2 resolved_conflict: . 'a' unreachable1
3 | . ['a']
3 | . %empty ['a']
$default reduce using rule 3 (resolved_conflict)
@@ -1415,7 +1483,7 @@ State 4
1 start: resolved_conflict 'a' . reported_conflicts 'a'
8 reported_conflicts: . 'a'
9 | . 'a'
10 | . ['a']
10 | . %empty ['a']
'a' shift, and go to state 5
@@ -1456,10 +1524,10 @@ AT_CHECK([[cat input.y >> input-keep.y]])
AT_BISON_CHECK([[input-keep.y]], 0, [],
[[input-keep.y: warning: 2 shift/reduce conflicts [-Wconflicts-sr]
input-keep.y: warning: 2 reduce/reduce conflicts [-Wconflicts-rr]
input-keep.y:22.4: warning: rule useless in parser due to conflicts: unreachable1: /* empty */ [-Wother]
input-keep.y:26.16: warning: rule useless in parser due to conflicts: unreachable2: /* empty */ [-Wother]
input-keep.y:32.5-7: warning: rule useless in parser due to conflicts: reported_conflicts: 'a' [-Wother]
input-keep.y:33.4: warning: rule useless in parser due to conflicts: reported_conflicts: /* empty */ [-Wother]
input-keep.y:22.4: warning: rule useless in parser due to conflicts [-Wother]
input-keep.y:26.16: warning: rule useless in parser due to conflicts [-Wother]
input-keep.y:32.5-7: warning: rule useless in parser due to conflicts [-Wother]
input-keep.y:33.4: warning: rule useless in parser due to conflicts [-Wother]
]])
AT_CLEANUP
@@ -1508,11 +1576,11 @@ AT_CHECK([[cat input.output | sed -n '/^State 0$/,/^State 1$/p']], 0,
6 | . empty_c1 'c'
7 | . empty_c2 'c'
8 | . empty_c3 'c'
9 empty_a: . ['a']
10 empty_b: . []
11 empty_c1: . []
12 empty_c2: . []
13 empty_c3: . ['c']
9 empty_a: . %empty ['a']
10 empty_b: . %empty []
11 empty_c1: . %empty []
12 empty_c2: . %empty []
13 empty_c3: . %empty ['c']
'b' shift, and go to state 1
@@ -1584,11 +1652,11 @@ AT_CHECK([[cat input.output | sed -n '/^State 0$/,/^State 1$/p']], 0,
6 | . empty_c1 'c'
7 | . empty_c2 'c'
8 | . empty_c3 'c'
9 empty_a: . []
10 empty_b: . []
11 empty_c1: . []
12 empty_c2: . ['c']
13 empty_c3: . ['c']
9 empty_a: . %empty []
10 empty_b: . %empty []
11 empty_c1: . %empty []
12 empty_c2: . %empty ['c']
13 empty_c3: . %empty ['c']
'a' error (nonassociative)
'b' error (nonassociative)
@@ -1639,7 +1707,7 @@ exp: 'a' | 'a';
AT_BISON_CHECK([[2.y]], [[0]], [],
[[2.y: warning: %expect-rr applies only to GLR parsers [-Wother]
2.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
2.y:3.12-14: warning: rule useless in parser due to conflicts: exp: 'a' [-Wother]
2.y:3.12-14: warning: rule useless in parser due to conflicts [-Wother]
]])
AT_CLEANUP
+7 -7
View File
@@ -94,19 +94,19 @@ prog :
stmt : expr ';' $2 { $$ = ]$[1; }
| decl $3
| error ';' { $$ = new_nterm ("<error>", YY_NULL, YY_NULL, YY_NULL); }
| error ';' { $$ = new_nterm ("<error>", YY_NULLPTR, YY_NULLPTR, YY_NULLPTR); }
| '@' { YYACCEPT; }
;
expr : ID
| TYPENAME '(' expr ')'
{ $$ = new_nterm ("<cast>(%s,%s)", ]$[3, ]$[1, YY_NULL); }
| expr '+' expr { $$ = new_nterm ("+(%s,%s)", ]$[1, ]$[3, YY_NULL); }
| expr '=' expr { $$ = new_nterm ("=(%s,%s)", ]$[1, ]$[3, YY_NULL); }
{ $$ = new_nterm ("<cast>(%s,%s)", ]$[3, ]$[1, YY_NULLPTR); }
| expr '+' expr { $$ = new_nterm ("+(%s,%s)", ]$[1, ]$[3, YY_NULLPTR); }
| expr '=' expr { $$ = new_nterm ("=(%s,%s)", ]$[1, ]$[3, YY_NULLPTR); }
;
decl : TYPENAME declarator ';'
{ $$ = new_nterm ("<declare>(%s,%s)", ]$[1, ]$[2, YY_NULL); }
{ $$ = new_nterm ("<declare>(%s,%s)", ]$[1, ]$[2, YY_NULLPTR); }
| TYPENAME declarator '=' expr ';'
{ $$ = new_nterm ("<init-declare>(%s,%s,%s)", ]$[1,
]$[2, ]$[4); }
@@ -195,7 +195,7 @@ main (int argc, char **argv)
{
colNum += 1;
tok = c;
yylval = YY_NULL;
yylval = YY_NULLPTR;
}]AT_LOCATION_IF([[
yylloc.last_column = colNum-1;]])[
return tok;
@@ -287,7 +287,7 @@ m4_bmatch([$2], [stmtMerge],
[[static YYSTYPE
stmtMerge (YYSTYPE x0, YYSTYPE x1)
{
return new_nterm ("<OR>(%s,%s)", x0, x1, YY_NULL);
return new_nterm ("<OR>(%s,%s)", x0, x1, YY_NULLPTR);
}
]])
)
+156 -143
View File
@@ -403,68 +403,60 @@ dnl parses it as:
dnl
dnl getline $!(4*0);
dnl
dnl That is, they shift `*' immediately and make it part of the getline
dnl That is, they shift '*' immediately and make it part of the getline
dnl argument.
dnl
dnl The grammar below using LALR(1) parses it as a syntax error. So does
dnl GNU AWK 3.0.6, 3.1.0, and 3.1.1. They reduce the full getline expression
dnl before shifting `*' even though `*' is not a valid lookahead.
dnl before shifting '*' even though '*' is not a valid lookahead.
dnl
dnl GNU AWK 3.1.2, 3.1.3, 3.1.4, and 3.1.5 parse it as:
dnl
dnl (getline $!4)*0;
dnl
dnl That is, like the other versions of GNU AWK, they reduce the full getline
dnl expression before shifting `*'. However, because of a different LHS on the
dnl getline rule, `*' actually is a valid lookahead. Solaris /usr/xpg4/bin/awk
dnl expression before shifting '*'. However, because of a different LHS on the
dnl getline rule, '*' actually is a valid lookahead. Solaris /usr/xpg4/bin/awk
dnl and the Open Group awk specification seem to agree:
dnl
dnl http://www.opengroup.org/pubs/online/7908799/xcu/awk.html
dnl
dnl /bin/nawk and /bin/awk on Solaris 10 report it as a syntax error, but they
dnl don't like even `print $!4;'.
dnl don't like even 'print $!4;'.
[[LEX_GETLINE, '$', '!', YNUMBER, '*', YNUMBER, ';']],
dnl BISON-STDERR
[AT_COND_CASE([[canonical LR]],
[[input.y: warning: 265 shift/reduce conflicts [-Wconflicts-sr]
input.y:19.8-16: warning: useless associativity for FUNC_CALL [-Wother]
input.y:21.8-14: warning: useless associativity for YNUMBER [-Wother]
input.y:21.16-22: warning: useless associativity for YSTRING [-Wother]
input.y:22.14-22: warning: useless associativity for APPEND_OP [-Wother]
input.y:23.8-15: warning: useless associativity for ASSIGNOP [-Wother]
input.y:23.33-41: warning: useless associativity for CONCAT_OP [-Wother]
input.y:27.8-18: warning: useless associativity for LEX_GETLINE [-Wother]
input.y:28.8-13: warning: useless associativity for LEX_IN [-Wother]
input.y:29.23-31: warning: useless associativity for INCREMENT [-Wother]
input.y:29.33-41: warning: useless associativity for DECREMENT [-Wother]
input.y:30.8-18: warning: useless associativity for LEX_BUILTIN [-Wother]
input.y:30.20-29: warning: useless associativity for LEX_LENGTH [-Wother]
input.y:40.11-13: warning: useless associativity for ',' [-Wother]
input.y:47.8-10: warning: useless associativity for '!' [-Wother]
input.y:47.12-16: warning: useless associativity for UNARY [-Wother]
input.y:50.7-9: warning: useless associativity for '$' [-Wother]
input.y:51.7-9: warning: useless associativity for '(' [-Wother]
input.y:51.11-13: warning: useless associativity for ')' [-Wother]]],
[[input.y: warning: 65 shift/reduce conflicts [-Wconflicts-sr]
input.y:19.8-16: warning: useless associativity for FUNC_CALL [-Wother]
input.y:21.8-14: warning: useless associativity for YNUMBER [-Wother]
input.y:21.16-22: warning: useless associativity for YSTRING [-Wother]
input.y:22.14-22: warning: useless associativity for APPEND_OP [-Wother]
input.y:23.8-15: warning: useless associativity for ASSIGNOP [-Wother]
input.y:23.33-41: warning: useless associativity for CONCAT_OP [-Wother]
input.y:27.8-18: warning: useless associativity for LEX_GETLINE [-Wother]
input.y:28.8-13: warning: useless associativity for LEX_IN [-Wother]
input.y:29.23-31: warning: useless associativity for INCREMENT [-Wother]
input.y:29.33-41: warning: useless associativity for DECREMENT [-Wother]
input.y:30.8-18: warning: useless associativity for LEX_BUILTIN [-Wother]
input.y:30.20-29: warning: useless associativity for LEX_LENGTH [-Wother]
input.y:40.11-13: warning: useless associativity for ',' [-Wother]
input.y:47.8-10: warning: useless associativity for '!' [-Wother]
input.y:47.12-16: warning: useless associativity for UNARY [-Wother]
input.y:50.7-9: warning: useless associativity for '$' [-Wother]
input.y:51.7-9: warning: useless associativity for '(' [-Wother]
input.y:51.11-13: warning: useless associativity for ')' [-Wother]]])[
[[input.y:66.10: warning: empty rule without %empty [-Wempty-rule]
input.y:169.8: warning: empty rule without %empty [-Wempty-rule]
input.y:174.12: warning: empty rule without %empty [-Wempty-rule]
input.y:179.13: warning: empty rule without %empty [-Wempty-rule]
input.y:187.15: warning: empty rule without %empty [-Wempty-rule]
input.y:201.8: warning: empty rule without %empty [-Wempty-rule]
input.y:206.21: warning: empty rule without %empty [-Wempty-rule]
input.y:220.20: warning: empty rule without %empty [-Wempty-rule]
input.y:299.13: warning: empty rule without %empty [-Wempty-rule]
input.y:322.9: warning: empty rule without %empty [-Wempty-rule]
]AT_COND_CASE([[canonical LR]],
[[input.y: warning: 265 shift/reduce conflicts [-Wconflicts-sr]]],
[[input.y: warning: 65 shift/reduce conflicts [-Wconflicts-sr]]])[
input.y:39.1-5: warning: useless associativity for FUNC_CALL, use %precedence [-Wprecedence]
input.y:44.1-5: warning: useless associativity for YNUMBER, use %precedence [-Wprecedence]
input.y:44.1-5: warning: useless associativity for YSTRING, use %precedence [-Wprecedence]
input.y:42.1-9: warning: useless precedence and associativity for APPEND_OP [-Wprecedence]
input.y:33.1-6: warning: useless associativity for ASSIGNOP, use %precedence [-Wprecedence]
input.y:43.1-5: warning: useless associativity for CONCAT_OP, use %precedence [-Wprecedence]
input.y:37.1-5: warning: useless precedence and associativity for LEX_GETLINE [-Wprecedence]
input.y:38.1-9: warning: useless associativity for LEX_IN, use %precedence [-Wprecedence]
input.y:49.1-5: warning: useless associativity for INCREMENT, use %precedence [-Wprecedence]
input.y:49.1-5: warning: useless associativity for DECREMENT, use %precedence [-Wprecedence]
input.y:39.1-5: warning: useless associativity for LEX_BUILTIN, use %precedence [-Wprecedence]
input.y:39.1-5: warning: useless associativity for LEX_LENGTH, use %precedence [-Wprecedence]
input.y:40.1-9: warning: useless precedence and associativity for ',' [-Wprecedence]
input.y:47.1-6: warning: useless associativity for '!', use %precedence [-Wprecedence]
input.y:47.1-6: warning: useless associativity for UNARY, use %precedence [-Wprecedence]
input.y:50.1-5: warning: useless associativity for '$', use %precedence [-Wprecedence]
input.y:51.1-5: warning: useless associativity for '(', use %precedence [-Wprecedence]
input.y:51.1-5: warning: useless precedence and associativity for ')' [-Wprecedence]
]],
dnl LAST-STATE
@@ -1403,23 +1395,39 @@ dnl INPUT
[[]],
dnl BISON-STDERR
[AT_COND_CASE([[canonical LR]],
[[input.y:128.12: warning: empty rule without %empty [-Wempty-rule]
input.y:137.10: warning: empty rule without %empty [-Wempty-rule]
input.y:142.8: warning: empty rule without %empty [-Wempty-rule]
input.y:161.15: warning: empty rule without %empty [-Wempty-rule]
input.y:179.17: warning: empty rule without %empty [-Wempty-rule]
input.y:205.16: warning: empty rule without %empty [-Wempty-rule]
input.y:213.9: warning: empty rule without %empty [-Wempty-rule]
input.y:225.6: warning: empty rule without %empty [-Wempty-rule]
input.y:292.18: warning: empty rule without %empty [-Wempty-rule]
input.y:294.19: warning: empty rule without %empty [-Wempty-rule]
input.y:367.16: warning: empty rule without %empty [-Wempty-rule]
input.y:373.11: warning: empty rule without %empty [-Wempty-rule]
input.y:387.15: warning: empty rule without %empty [-Wempty-rule]
input.y:401.18: warning: empty rule without %empty [-Wempty-rule]
input.y:413.15: warning: empty rule without %empty [-Wempty-rule]
input.y:443.15: warning: empty rule without %empty [-Wempty-rule]
input.y:471.15: warning: empty rule without %empty [-Wempty-rule]
input.y:474.15: warning: empty rule without %empty [-Wempty-rule]
input.y:489.15: warning: empty rule without %empty [-Wempty-rule]
input.y:506.14: warning: empty rule without %empty [-Wempty-rule]
input.y:587.9: warning: empty rule without %empty [-Wempty-rule]
input.y:591.14: warning: empty rule without %empty [-Wempty-rule]
]AT_COND_CASE([[canonical LR]],
[[input.y: warning: 1876 shift/reduce conflicts [-Wconflicts-sr]
input.y: warning: 144 reduce/reduce conflicts [-Wconflicts-rr]
input.y:32.9-12: warning: useless associativity for HQUA [-Wother]
input.y:53.8-14: warning: useless associativity for HASSIGN [-Wother]
input.y:54.9-15: warning: useless associativity for HORELSE [-Wother]
input.y:55.9-16: warning: useless associativity for HANDTHEN [-Wother]
input.y:61.9-12: warning: useless associativity for HNOT [-Wother]
input.y:68.7-11: warning: useless associativity for UNEAR [-Wother]]],
input.y: warning: 144 reduce/reduce conflicts [-Wconflicts-rr]]],
[[input.y: warning: 78 shift/reduce conflicts [-Wconflicts-sr]
input.y: warning: 10 reduce/reduce conflicts [-Wconflicts-rr]
input.y:32.9-12: warning: useless associativity for HQUA [-Wother]
input.y:53.8-14: warning: useless associativity for HASSIGN [-Wother]
input.y:54.9-15: warning: useless associativity for HORELSE [-Wother]
input.y:55.9-16: warning: useless associativity for HANDTHEN [-Wother]
input.y:61.9-12: warning: useless associativity for HNOT [-Wother]
input.y:68.7-11: warning: useless associativity for UNEAR [-Wother]]])[
input.y: warning: 10 reduce/reduce conflicts [-Wconflicts-rr]]])[
input.y:72.1-5: warning: useless associativity for HQUA, use %precedence [-Wprecedence]
input.y:53.1-6: warning: useless associativity for HASSIGN, use %precedence [-Wprecedence]
input.y:54.1-5: warning: useless associativity for HORELSE, use %precedence [-Wprecedence]
input.y:55.1-5: warning: useless associativity for HANDTHEN, use %precedence [-Wprecedence]
input.y:61.1-5: warning: useless associativity for HNOT, use %precedence [-Wprecedence]
input.y:68.1-5: warning: useless associativity for UNEAR, use %precedence [-Wprecedence]
]],
dnl LAST-STATE
@@ -1585,7 +1593,7 @@ box "foo" above ljust == box ("foo" above ljust)
%left LEFT RIGHT
/* Give attributes that take an optional expression a higher
precedence than left and right, so that eg `line chop left'
precedence than left and right, so that eg 'line chop left'
parses properly. */
%left CHOP SOLID DASHED DOTTED UP DOWN FILL COLORED OUTLINED
%left LABEL
@@ -1598,7 +1606,7 @@ parses properly. */
/* these need to be lower than '-' */
%left HEIGHT RADIUS WIDTH DIAMETER FROM TO AT THICKNESS
/* these must have higher precedence than CHOP so that `label %prec CHOP'
/* these must have higher precedence than CHOP so that 'label %prec CHOP'
works */
%left DOT_N DOT_E DOT_W DOT_S DOT_NE DOT_SE DOT_NW DOT_SW DOT_C
%left DOT_START DOT_END TOP BOTTOM LEFT_CORNER RIGHT_CORNER
@@ -2001,88 +2009,93 @@ dnl without being followed by "of".)
[[VARIABLE, '=', LABEL, LEFT, DOT_X]],
dnl BISON-STDERR
[[input.y:471.11-48: warning: rule useless in parser due to conflicts: path: ORDINAL LAST object_type relative_path [-Wother]
input.y:19.8-12: warning: useless associativity for LABEL [-Wother]
input.y:20.8-15: warning: useless associativity for VARIABLE [-Wother]
input.y:21.8-13: warning: useless associativity for NUMBER [-Wother]
input.y:22.8-11: warning: useless associativity for TEXT [-Wother]
input.y:25.8-14: warning: useless associativity for ORDINAL [-Wother]
input.y:30.8-11: warning: useless associativity for LAST [-Wother]
input.y:31.8-9: warning: useless associativity for UP [-Wother]
input.y:32.8-11: warning: useless associativity for DOWN [-Wother]
input.y:35.8-10: warning: useless associativity for BOX [-Wother]
input.y:36.8-13: warning: useless associativity for CIRCLE [-Wother]
input.y:37.8-14: warning: useless associativity for ELLIPSE [-Wother]
input.y:38.8-10: warning: useless associativity for ARC [-Wother]
input.y:39.8-11: warning: useless associativity for LINE [-Wother]
input.y:40.8-12: warning: useless associativity for ARROW [-Wother]
input.y:42.8-13: warning: useless associativity for SPLINE [-Wother]
input.y:43.8-13: warning: useless associativity for HEIGHT [-Wother]
input.y:44.8-13: warning: useless associativity for RADIUS [-Wother]
input.y:45.8-12: warning: useless associativity for WIDTH [-Wother]
input.y:46.8-15: warning: useless associativity for DIAMETER [-Wother]
input.y:47.8-11: warning: useless associativity for FROM [-Wother]
input.y:48.8-9: warning: useless associativity for TO [-Wother]
input.y:49.8-9: warning: useless associativity for AT [-Wother]
input.y:53.8-12: warning: useless associativity for SOLID [-Wother]
input.y:54.8-13: warning: useless associativity for DOTTED [-Wother]
input.y:55.8-13: warning: useless associativity for DASHED [-Wother]
input.y:56.8-11: warning: useless associativity for CHOP [-Wother]
input.y:59.8-12: warning: useless associativity for LJUST [-Wother]
input.y:60.8-12: warning: useless associativity for RJUST [-Wother]
input.y:61.8-12: warning: useless associativity for ABOVE [-Wother]
input.y:62.8-12: warning: useless associativity for BELOW [-Wother]
input.y:63.8-9: warning: useless associativity for OF [-Wother]
input.y:66.8-14: warning: useless associativity for BETWEEN [-Wother]
input.y:67.8-10: warning: useless associativity for AND [-Wother]
input.y:68.8-11: warning: useless associativity for HERE [-Wother]
input.y:69.8-12: warning: useless associativity for DOT_N [-Wother]
input.y:70.8-12: warning: useless associativity for DOT_E [-Wother]
input.y:71.8-12: warning: useless associativity for DOT_W [-Wother]
input.y:72.8-12: warning: useless associativity for DOT_S [-Wother]
input.y:73.8-13: warning: useless associativity for DOT_NE [-Wother]
input.y:74.8-13: warning: useless associativity for DOT_SE [-Wother]
input.y:75.8-13: warning: useless associativity for DOT_NW [-Wother]
input.y:76.8-13: warning: useless associativity for DOT_SW [-Wother]
input.y:77.8-12: warning: useless associativity for DOT_C [-Wother]
input.y:78.8-16: warning: useless associativity for DOT_START [-Wother]
input.y:79.8-14: warning: useless associativity for DOT_END [-Wother]
input.y:85.8-10: warning: useless associativity for SIN [-Wother]
input.y:86.8-10: warning: useless associativity for COS [-Wother]
input.y:87.8-12: warning: useless associativity for ATAN2 [-Wother]
input.y:88.8-10: warning: useless associativity for LOG [-Wother]
input.y:89.8-10: warning: useless associativity for EXP [-Wother]
input.y:90.8-11: warning: useless associativity for SQRT [-Wother]
input.y:91.8-12: warning: useless associativity for K_MAX [-Wother]
input.y:92.8-12: warning: useless associativity for K_MIN [-Wother]
input.y:93.8-10: warning: useless associativity for INT [-Wother]
input.y:94.8-11: warning: useless associativity for RAND [-Wother]
input.y:95.8-12: warning: useless associativity for SRAND [-Wother]
input.y:98.8-10: warning: useless associativity for TOP [-Wother]
input.y:99.8-13: warning: useless associativity for BOTTOM [-Wother]
input.y:100.8-12: warning: useless associativity for UPPER [-Wother]
input.y:101.8-12: warning: useless associativity for LOWER [-Wother]
input.y:116.8-18: warning: useless associativity for LEFT_CORNER [-Wother]
input.y:117.8-19: warning: useless associativity for RIGHT_CORNER [-Wother]
input.y:118.8-12: warning: useless associativity for NORTH [-Wother]
input.y:119.8-12: warning: useless associativity for SOUTH [-Wother]
input.y:120.8-11: warning: useless associativity for EAST [-Wother]
input.y:121.8-11: warning: useless associativity for WEST [-Wother]
input.y:122.8-13: warning: useless associativity for CENTER [-Wother]
input.y:123.8-10: warning: useless associativity for END [-Wother]
input.y:124.8-12: warning: useless associativity for START [-Wother]
input.y:127.8-11: warning: useless associativity for PLOT [-Wother]
input.y:128.8-16: warning: useless associativity for THICKNESS [-Wother]
input.y:129.8-11: warning: useless associativity for FILL [-Wother]
input.y:130.8-14: warning: useless associativity for COLORED [-Wother]
input.y:131.8-15: warning: useless associativity for OUTLINED [-Wother]
input.y:134.8-14: warning: useless associativity for SPRINTF [-Wother]
input.y:137.7-9: warning: useless associativity for '.' [-Wother]
input.y:156.23-25: warning: useless associativity for '(' [-Wother]
input.y:157.20-22: warning: useless associativity for '`' [-Wother]
input.y:159.48-50: warning: useless associativity for '@<:@' [-Wother]
input.y:170.7-9: warning: useless associativity for ',' [-Wother]
input.y:181.8-10: warning: useless associativity for '!' [-Wother]
[[input.y:202.19: warning: empty rule without %empty [-Wempty-rule]
input.y:270.6: warning: empty rule without %empty [-Wempty-rule]
input.y:292.12: warning: empty rule without %empty [-Wempty-rule]
input.y:309.17: warning: empty rule without %empty [-Wempty-rule]
input.y:382.13: warning: empty rule without %empty [-Wempty-rule]
input.y:471.11-48: warning: rule useless in parser due to conflicts [-Wother]
input.y:154.1-5: warning: useless associativity for LABEL, use %precedence [-Wprecedence]
input.y:156.1-5: warning: useless associativity for VARIABLE, use %precedence [-Wprecedence]
input.y:156.1-5: warning: useless associativity for NUMBER, use %precedence [-Wprecedence]
input.y:141.1-5: warning: useless associativity for TEXT, use %precedence [-Wprecedence]
input.y:157.1-5: warning: useless associativity for ORDINAL, use %precedence [-Wprecedence]
input.y:156.1-5: warning: useless associativity for LAST, use %precedence [-Wprecedence]
input.y:153.1-5: warning: useless associativity for UP, use %precedence [-Wprecedence]
input.y:153.1-5: warning: useless associativity for DOWN, use %precedence [-Wprecedence]
input.y:159.1-5: warning: useless associativity for BOX, use %precedence [-Wprecedence]
input.y:159.1-5: warning: useless associativity for CIRCLE, use %precedence [-Wprecedence]
input.y:159.1-5: warning: useless associativity for ELLIPSE, use %precedence [-Wprecedence]
input.y:159.1-5: warning: useless associativity for ARC, use %precedence [-Wprecedence]
input.y:159.1-5: warning: useless associativity for LINE, use %precedence [-Wprecedence]
input.y:159.1-5: warning: useless associativity for ARROW, use %precedence [-Wprecedence]
input.y:159.1-5: warning: useless associativity for SPLINE, use %precedence [-Wprecedence]
input.y:162.1-5: warning: useless associativity for HEIGHT, use %precedence [-Wprecedence]
input.y:162.1-5: warning: useless associativity for RADIUS, use %precedence [-Wprecedence]
input.y:162.1-5: warning: useless associativity for WIDTH, use %precedence [-Wprecedence]
input.y:162.1-5: warning: useless associativity for DIAMETER, use %precedence [-Wprecedence]
input.y:162.1-5: warning: useless associativity for FROM, use %precedence [-Wprecedence]
input.y:162.1-5: warning: useless associativity for TO, use %precedence [-Wprecedence]
input.y:162.1-5: warning: useless associativity for AT, use %precedence [-Wprecedence]
input.y:153.1-5: warning: useless precedence and associativity for SOLID [-Wprecedence]
input.y:153.1-5: warning: useless associativity for DOTTED, use %precedence [-Wprecedence]
input.y:153.1-5: warning: useless associativity for DASHED, use %precedence [-Wprecedence]
input.y:153.1-5: warning: useless associativity for CHOP, use %precedence [-Wprecedence]
input.y:147.1-5: warning: useless precedence and associativity for LJUST [-Wprecedence]
input.y:147.1-5: warning: useless precedence and associativity for RJUST [-Wprecedence]
input.y:147.1-5: warning: useless precedence and associativity for ABOVE [-Wprecedence]
input.y:147.1-5: warning: useless precedence and associativity for BELOW [-Wprecedence]
input.y:176.1-5: warning: useless associativity for OF, use %precedence [-Wprecedence]
input.y:176.1-5: warning: useless associativity for BETWEEN, use %precedence [-Wprecedence]
input.y:177.1-5: warning: useless associativity for AND, use %precedence [-Wprecedence]
input.y:157.1-5: warning: useless associativity for HERE, use %precedence [-Wprecedence]
input.y:166.1-5: warning: useless associativity for DOT_N, use %precedence [-Wprecedence]
input.y:166.1-5: warning: useless associativity for DOT_E, use %precedence [-Wprecedence]
input.y:166.1-5: warning: useless associativity for DOT_W, use %precedence [-Wprecedence]
input.y:166.1-5: warning: useless associativity for DOT_S, use %precedence [-Wprecedence]
input.y:166.1-5: warning: useless associativity for DOT_NE, use %precedence [-Wprecedence]
input.y:166.1-5: warning: useless associativity for DOT_SE, use %precedence [-Wprecedence]
input.y:166.1-5: warning: useless associativity for DOT_NW, use %precedence [-Wprecedence]
input.y:166.1-5: warning: useless associativity for DOT_SW, use %precedence [-Wprecedence]
input.y:166.1-5: warning: useless associativity for DOT_C, use %precedence [-Wprecedence]
input.y:167.1-5: warning: useless associativity for DOT_START, use %precedence [-Wprecedence]
input.y:167.1-5: warning: useless associativity for DOT_END, use %precedence [-Wprecedence]
input.y:156.1-5: warning: useless associativity for SIN, use %precedence [-Wprecedence]
input.y:156.1-5: warning: useless associativity for COS, use %precedence [-Wprecedence]
input.y:156.1-5: warning: useless associativity for ATAN2, use %precedence [-Wprecedence]
input.y:156.1-5: warning: useless associativity for LOG, use %precedence [-Wprecedence]
input.y:156.1-5: warning: useless associativity for EXP, use %precedence [-Wprecedence]
input.y:156.1-5: warning: useless associativity for SQRT, use %precedence [-Wprecedence]
input.y:156.1-5: warning: useless associativity for K_MAX, use %precedence [-Wprecedence]
input.y:156.1-5: warning: useless associativity for K_MIN, use %precedence [-Wprecedence]
input.y:156.1-5: warning: useless associativity for INT, use %precedence [-Wprecedence]
input.y:156.1-5: warning: useless associativity for RAND, use %precedence [-Wprecedence]
input.y:156.1-5: warning: useless associativity for SRAND, use %precedence [-Wprecedence]
input.y:167.1-5: warning: useless associativity for TOP, use %precedence [-Wprecedence]
input.y:167.1-5: warning: useless associativity for BOTTOM, use %precedence [-Wprecedence]
input.y:168.1-5: warning: useless associativity for UPPER, use %precedence [-Wprecedence]
input.y:168.1-5: warning: useless associativity for LOWER, use %precedence [-Wprecedence]
input.y:167.1-5: warning: useless associativity for LEFT_CORNER, use %precedence [-Wprecedence]
input.y:167.1-5: warning: useless associativity for RIGHT_CORNER, use %precedence [-Wprecedence]
input.y:168.1-5: warning: useless associativity for NORTH, use %precedence [-Wprecedence]
input.y:168.1-5: warning: useless associativity for SOUTH, use %precedence [-Wprecedence]
input.y:168.1-5: warning: useless associativity for EAST, use %precedence [-Wprecedence]
input.y:168.1-5: warning: useless associativity for WEST, use %precedence [-Wprecedence]
input.y:168.1-5: warning: useless associativity for CENTER, use %precedence [-Wprecedence]
input.y:168.1-5: warning: useless associativity for END, use %precedence [-Wprecedence]
input.y:168.1-5: warning: useless associativity for START, use %precedence [-Wprecedence]
input.y:140.1-5: warning: useless associativity for PLOT, use %precedence [-Wprecedence]
input.y:162.1-5: warning: useless associativity for THICKNESS, use %precedence [-Wprecedence]
input.y:153.1-5: warning: useless associativity for FILL, use %precedence [-Wprecedence]
input.y:153.1-5: warning: useless precedence and associativity for COLORED [-Wprecedence]
input.y:153.1-5: warning: useless precedence and associativity for OUTLINED [-Wprecedence]
input.y:141.1-5: warning: useless associativity for SPRINTF, use %precedence [-Wprecedence]
input.y:137.1-5: warning: useless associativity for '.', use %precedence [-Wprecedence]
input.y:156.1-5: warning: useless associativity for '(', use %precedence [-Wprecedence]
input.y:157.1-5: warning: useless associativity for '`', use %precedence [-Wprecedence]
input.y:159.1-5: warning: useless associativity for '@<:@', use %precedence [-Wprecedence]
input.y:170.1-5: warning: useless associativity for ',', use %precedence [-Wprecedence]
input.y:181.1-6: warning: useless associativity for '!', use %precedence [-Wprecedence]
]],
dnl LAST-STATE
+38 -8
View File
@@ -67,7 +67,7 @@ static YYSTYPE exprMerge (YYSTYPE x0, YYSTYPE x1)
return 0;
}
const char *input = YY_NULL;
const char *input = YY_NULLPTR;
int
main (int argc, const char* argv[])
@@ -304,7 +304,7 @@ MergeRule (int x0, int x1)
}
]AT_YYERROR_DEFINE[
FILE *input = YY_NULL;
FILE *input = YY_NULLPTR;
int P[] = { P1, P2 };
int O[] = { O1, O2 };
@@ -486,8 +486,8 @@ start:
;
%%
]AT_YYLEX_DEFINE(["a"])[
]AT_YYERROR_DEFINE[
]AT_YYLEX_DEFINE(["a"])[
]AT_MAIN_DEFINE[
]])
AT_BISON_OPTION_POPDEFS
@@ -1015,17 +1015,17 @@ main (void)
int exit_status = yyparse ();
if (parent_rhs_before_value)
{
fprintf (stderr, "`parent_rhs_before' destructor not called.\n");
fprintf (stderr, "'parent_rhs_before' destructor not called.\n");
exit_status = 1;
}
if (merged_value)
{
fprintf (stderr, "`merged' destructor not called.\n");
fprintf (stderr, "'merged' destructor not called.\n");
exit_status = 1;
}
if (parent_rhs_after_value)
{
fprintf (stderr, "`PARENT_RHS_AFTER' destructor not called.\n");
fprintf (stderr, "'PARENT_RHS_AFTER' destructor not called.\n");
exit_status = 1;
}
return exit_status;
@@ -1449,7 +1449,7 @@ main (void)
int exit_status = yyparse () != 1;
if (parent_rhs_before_value)
{
fprintf (stderr, "`parent_rhs_before' destructor not called.\n");
fprintf (stderr, "'parent_rhs_before' destructor not called.\n");
exit_status = 1;
}
return exit_status;
@@ -1679,8 +1679,8 @@ start:
b: 'b';
d: /* nada. */;
%%
]AT_YYLEX_DEFINE(["abc"])[
]AT_YYERROR_DEFINE[
]AT_YYLEX_DEFINE(["abc"])[
]AT_MAIN_DEFINE[
]])
AT_BISON_OPTION_POPDEFS
@@ -1749,3 +1749,33 @@ Cleanup: popping token 'a' ()
])
AT_CLEANUP
## ----------------------------------------------------------------- ##
## Predicates. ##
## ##
## http://lists.gnu.org/archive/html/bug-bison/2013-10/msg00004.html ##
## ----------------------------------------------------------------- ##
AT_SETUP([Predicates])
# FIXME: We need genuine test cases with uses of %?.
AT_DATA_GRAMMAR([input.y],
[[%glr-parser
%expect-rr 1
%%
// Exercise "%?{...}" and "%? {...}".
widget:
%? {new_syntax} "widget" id new_args { $$ = f($3, $4); }
| %?{!new_syntax} "widget" id old_args { $$ = f($3, $4); }
;
id:;
new_args:;
old_args:;
%%
]])
AT_BISON_CHECK([[input.y]])
AT_CLEANUP
+8 -4
View File
@@ -117,9 +117,9 @@ AT_SETUP([Several parsers])
# nor yy* identifiers in the header. Check that headers are
# self-contained, and can be compiled by a C++ compiler.
m4_pushdef([AT_TEST],
[AT_BISON_OPTION_PUSHDEFS([%define api.prefix "$1_" $2])
[AT_BISON_OPTION_PUSHDEFS([%define api.prefix {$1_} $2])
AT_DATA_GRAMMAR([$1.y],
[[%define api.prefix "$1_"
[[%define api.prefix {$1_}
$2
%error-verbose
%union
@@ -223,9 +223,13 @@ AT_CHECK([[$PERL -n -0777 -e '
s{/\*.*?\*/}{}gs;
s{//.*}{}g;
s{\b(YYChar
|YYPUSH_MORE(_DEFINED)?
|YYPUSH_MORE(?:_DEFINED)?
|YYUSE
|YY_ATTRIBUTE(?:_PURE|_UNUSED)?
|YY_IGNORE_MAYBE_UNINITIALIZED_(?:BEGIN|END)
|YY_INITIAL_VALUE
|YY_\w+_INCLUDED
|YY_NULL
|YY_NULLPTR
|(defined|if)\ YYDEBUG
)\b}{}gx;
while (/^(.*YY.*)$/gm)

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