Compare commits

..
Author SHA1 Message Date
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 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 657ed6d3be tests: style changes
* tests/glr-regression.at: Issue yyerror before yylex.
2012-12-15 14:58:05 +01:00
172 changed files with 12432 additions and 20393 deletions
+444 -2891
View File
File diff suppressed because it is too large Load Diff
+22 -44
View File
@@ -1,7 +1,7 @@
## Process this file with automake to produce Makefile.in.
## Process this file with automake to produce Makefile.in -*-Makefile-*-
## Copyright (C) 2001-2013 Free Software Foundation, Inc.
# Copyright (C) 2001-2013 Free Software Foundation, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
@@ -15,51 +15,29 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
AUTOMAKE_OPTIONS = subdir-objects
ACLOCAL_AMFLAGS = -I m4
SUBDIRS = po runtime-po .
SUBDIRS = build-aux po runtime-po lib data src doc examples tests etc
# Files installed for use by Automake.
aclocaldir = @aclocaldir@
aclocal_DATA = m4/bison-i18n.m4
EXTRA_DIST = .prev-version .version \
cfg.mk ChangeLog-1998 ChangeLog-2012 PACKAGING
cfg.mk ChangeLog-1998 ChangeLog-2012 PACKAGING \
djgpp/Makefile.maint djgpp/README.in djgpp/config.bat \
djgpp/config.sed djgpp/config.site djgpp/config_h.sed \
djgpp/subpipe.c djgpp/subpipe.h djgpp/djunpack.bat \
djgpp/fnchange.lst djgpp/testsuite.sed
## Running the bison from this tarball. To generate our own parser,
## but also to run the tests. Of course, you ought to keep a sane
## 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
# Initialization before completion by local.mk's.
AM_CFLAGS = $(WARN_CFLAGS)
# Find builddir/src/scan-code.c etc.
AM_CPPFLAGS = -I. -Ilib -I$(top_srcdir) -I$(top_srcdir)/lib
BUILT_SOURCES =
CLEANFILES =
DISTCLEANFILES =
EXTRA_DIST += $(dist_TESTS)
MOSTLYCLEANDIRS =
MOSTLYCLEANFILES =
SUFFIXES =
TESTS = $(dist_TESTS)
check_PROGRAMS =
dist_TESTS =
noinst_LIBRARIES =
include build-aux/local.mk
include data/local.mk
include djgpp/local.mk
include doc/local.mk
include etc/local.mk
include examples/local.mk
include lib/local.mk
include src/local.mk
include tests/local.mk
MAINTAINER_CHECKS = \
maintainer-check \
maintainer-push-check \
maintainer-xml-check \
maintainer-release-check
.PHONY: $(MAINTAINER_CHECKS)
$(MAINTAINER_CHECKS):
$(AM_V_GEN)cd tests && $(MAKE) $(AM_MAKEFLAGS) $@
# See comments in build-aux/git-version-gen. However, we make .version depend
# on configure so that .version and VERSION/PACKAGE_VERSION stay in sync in the
@@ -70,19 +48,19 @@ include tests/local.mk
# a developer might naively reference .version in a test case while the bison
# executable still compiles with VERSION, and so the test case might fail or
# pass incorrectly.
BUILT_SOURCES += $(top_srcdir)/.version
BUILT_SOURCES = $(top_srcdir)/.version
$(top_srcdir)/.version: configure
echo $(VERSION) > $@-t && mv $@-t $@
$(AM_V_GEN)echo $(VERSION) > $@-t && mv $@-t $@
dist-hook: gen-ChangeLog
echo $(VERSION) > $(distdir)/.tarball-version
$(AM_V_GEN)echo $(VERSION) > $(distdir)/.tarball-version
.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
+9 -308
View File
@@ -1,307 +1,14 @@
GNU Bison NEWS
* Noteworthy changes in release ?.? (????-??-??) [?]
** 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.
** Backward incompatible changes
*** Obsolete features
Support for YYFAIL is removed (deprecated in Bison 2.4.2): use YYERROR.
Support for yystype and yyltype is removed (deprecated in Bison 1.875):
use YYSTYPE and YYLTYPE.
Support for YYLEX_PARAM and YYPARSE_PARAM is removed (deprecated in Bison
1.875): use %lex-param, %parse-param, or %param.
* Noteworthy changes in release 2.7.1 (2013-04-15) [stable]
** Bug fixes
*** The epilogue is no longer affected by internal #defines
*** Fix compiler attribute portability (yacc.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
the user epilogue, so functions such as the following were butchered by the
preprocessor expansion:
With locations enabled, __attribute__ was used unprotected.
int yylex (YYSTYPE *yylval);
This is has been 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)
Changes in Bison 2.7 introduced a dependency on FILE and fprintf when
locations are enabled. This is fixed.
** Diagnostics reported by Bison
Most of these features were contributed by Théophile Ranquet and Victor
Santet.
*** Carets
Version 2.7 introduced caret errors, for a prettier output. These are now
activated by default. The old format can still be used by invoking Bison
with -fno-caret (or -fnone).
*** Enhancements of the -Werror option
The -Werror=CATEGORY option is now recognized, and will treat specified
warnings as errors. The warnings need not have been explicitly activated
using the -W option, this is similar to what GCC 4.7 does.
For example, given the following command line, Bison will treat both
warnings related to POSIX Yacc incompatibilities and S/R conflicts as
errors (and only those):
$ bison -Werror=yacc,error=conflicts-sr input.y
If no categories are specified, -Werror will make all active warnings into
errors. For example, the following line does the same the previous example:
$ bison -Werror -Wnone -Wyacc -Wconflicts-sr input.y
(By default -Wconflicts-sr,conflicts-rr,deprecated,other is enabled.)
Note that the categories in this -Werror option may not be prefixed with
"no-". However, -Wno-error[=CATEGORY] is valid.
Note that -y enables -Werror=yacc. Therefore it is now possible to require
Yacc-like behavior (e.g., always generate y.tab.c), but to report
incompatibilities as warnings: "-y -Wno-error=yacc".
*** The display of warnings is now richer
The option that controls a given warning is now displayed:
foo.y:4.6: warning: type clash on default action: <foo> != <bar> [-Wother]
In the case of warnings treated as errors, the prefix is changed from
"warning: " to "error: ", and the suffix is displayed, in a manner similar
to GCC, as [-Werror=CATEGORY].
For instance, where the previous version of Bison would report (and exit
with failure):
bison: warnings being treated as errors
input.y:1.1: warning: stray ',' treated as white space
it now reports:
input.y:1.1: error: stray ',' treated as white space [-Werror=other]
*** Deprecated constructs
The new 'deprecated' warning category flags obsolete constructs whose
support will be discontinued. It is enabled by default. These warnings
used to be reported as 'other' warnings.
*** Useless semantic types
Bison now warns about useless (uninhabited) semantic types. Since
semantic types are not declared to Bison (they are defined in the opaque
%union structure), it is %printer/%destructor directives about useless
types that trigger the warning:
%token <type1> term
%type <type2> nterm
%printer {} <type1> <type3>
%destructor {} <type2> <type4>
%%
nterm: term { $$ = $1; };
3.28-34: warning: type <type3> is used, but is not associated to any symbol
4.28-34: warning: type <type4> is used, but is not associated to any symbol
*** Undefined but unused symbols
Bison used to raise an error for undefined symbols that are not used in
the grammar. This is now only a warning.
%printer {} symbol1
%destructor {} symbol2
%type <type> symbol3
%%
exp: "a";
*** Useless destructors or printers
Bison now warns about useless destructors or printers. In the following
example, the printer for <type1>, and the destructor for <type2> are
useless: all symbols of <type1> (token1) already have a printer, and all
symbols of type <type2> (token2) already have a destructor.
%token <type1> token1
<type2> token2
<type3> token3
<type4> token4
%printer {} token1 <type1> <type3>
%destructor {} token2 <type2> <type4>
*** Conflicts
The warnings and error messages about shift/reduce and reduce/reduce
conflicts have been normalized. For instance on the following foo.y file:
%glr-parser
%%
exp: exp '+' exp | '0' | '0';
compare the previous version of bison:
$ bison foo.y
foo.y: conflicts: 1 shift/reduce, 2 reduce/reduce
$ bison -Werror foo.y
bison: warnings being treated as errors
foo.y: conflicts: 1 shift/reduce, 2 reduce/reduce
with the new behavior:
$ bison foo.y
foo.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
foo.y: warning: 2 reduce/reduce conflicts [-Wconflicts-rr]
$ bison -Werror foo.y
foo.y: error: 1 shift/reduce conflict [-Werror=conflicts-sr]
foo.y: error: 2 reduce/reduce conflicts [-Werror=conflicts-rr]
When %expect or %expect-rr is used, such as with bar.y:
%expect 0
%glr-parser
%%
exp: exp '+' exp | '0' | '0';
Former behavior:
$ bison bar.y
bar.y: conflicts: 1 shift/reduce, 2 reduce/reduce
bar.y: expected 0 shift/reduce conflicts
bar.y: expected 0 reduce/reduce conflicts
New one:
$ bison bar.y
bar.y: error: shift/reduce conflicts: 1 found, 0 expected
bar.y: error: reduce/reduce conflicts: 2 found, 0 expected
*** Useless precedence
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.
** Additional yylex/yyparse arguments
The new directive %param declares additional arguments to both yylex and
yyparse. The %lex-param, %parse-param, and %param directives support one
or more arguments. Instead of
%lex-param {arg1_type *arg1}
%lex-param {arg2_type *arg2}
%parse-param {arg1_type *arg1}
%parse-param {arg2_type *arg2}
one may now declare
%param {arg1_type *arg1} {arg2_type *arg2}
** Java skeleton improvements
Contributed by Paolo Bonzini.
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".
** C++ skeletons improvements
*** The parser header is no longer mandatory (lalr1.cc, glr.cc)
Using %defines is now optional. Without it, the needed support classes
are defined in the generated parser, instead of additional files (such as
location.hh, position.hh and stack.hh).
*** Locations are no longer mandatory (lalr1.cc, glr.cc)
Both lalr1.cc and glr.cc no longer require %location.
*** syntax_error exception (lalr1.cc)
The C++ parser features a syntax_error exception, which can be
thrown from the scanner or from user rules to raise syntax errors.
This facilitates reporting errors caught in sub-functions (e.g.,
rejecting too large integral literals from a conversion function
used by the scanner, or rejecting invalid combinations from a
factory invoked by the user actions).
** 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
** 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 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".
** 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.
** Token numbering has changed to preserve the user-defined order
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 some compiler warnings (lalr1.cc)
* Noteworthy changes in release 2.7 (2012-12-12) [stable]
@@ -313,8 +20,6 @@ GNU Bison NEWS
** Diagnostics are improved
Contributed by Théophile Ranquet.
*** Changes in the format of error messages
This used to be the format of many error reports:
@@ -400,8 +105,6 @@ GNU Bison NEWS
** Graph improvements in DOT and XSLT
Contributed by Théophile Ranquet.
The graphical presentation of the states is more readable: their shape is
now rectangular, the state number is clearly displayed, and the items are
numbered and left-justified.
@@ -512,7 +215,7 @@ GNU Bison NEWS
* Noteworthy changes in release 2.6.1 (2012-07-30) [stable]
Bison no longer executes user-specified M4 code when processing a grammar.
Bison no longer executes user-specified M4 code when processing a grammar.
** Future Changes
@@ -550,7 +253,7 @@ GNU Bison NEWS
* Noteworthy changes in release 2.6 (2012-07-19) [stable]
** Future changes
** Future Changes
The next major release of Bison will drop support for the following
deprecated features. Please report disagreements to [email protected].
@@ -843,9 +546,7 @@ GNU Bison NEWS
These features are experimental. More user feedback will help to
stabilize them.
** LAC (Lookahead Correction) for syntax error handling
Contributed by Joel E. Denny.
** LAC (Lookahead Correction) for syntax error handling:
Canonical LR, IELR, and LALR can suffer from a couple of problems
upon encountering a syntax error. First, the parser might perform
@@ -2356,8 +2057,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
LocalWords: namespaces strerror const autoconfiguration Dconst Autoconf's FDL
LocalWords: Automake TMPDIR LESSEQ ylwrap endif yydebug YYTOKEN YYLSP ival hh
LocalWords: extern YYTOKENTYPE TOKENTYPE yytokentype tokentype STYPE lval pdf
LocalWords: lang yyoutput dvi html ps POSIX lvalp llocp Wother nterm arg init
LocalWords: TOK calc yyo fval Wconflicts
LocalWords: lang yyoutput dvi html ps POSIX lvalp llocp calc yyo fval Wmaybe
LocalWords: yyvsp pragmas noreturn java's
Local Variables:
mode: outline
-32
View File
@@ -35,13 +35,6 @@ of the .output file etc. This excludes impossible error messages
(comparable to assert/abort), and all the --trace output which is
meant for the maintainers only.
** Horizontal tabs
Do not add horizontal tab characters to any file in Bison's repository
except where required. For example, do not use tabs to format C code.
However, make files, ChangeLog, and some regular expressions require
tabs. Also, test cases might need to contain tabs to check that Bison
properly processes tabs in its input.
* Working from the repository
@@ -176,28 +169,6 @@ decide whether to update.
** make check
Use liberally.
** TESTSUITEFLAGS
The default is for make check to run all tests sequentially. This can be
very time consumming when checking repeatedly or on slower setups. This can
be sped up in two ways:
Using -j, in a make-like fashion, for example:
$ make check TESTSUITEFLAGS='-j8'
Running only the tests of a certain category, as specified in the AT files
with AT_KEYWORDS([[category]]). Categories include:
- c++, for c++ parsers
- deprec, for tests concerning deprecated constructs.
- glr, for glr parsers
- java, for java parsers
- report, for automaton dumps
To run a specific set of tests, use -k (for "keyword"). For example:
$ make check TESTSUITEFLAGS='-k c++'
Both can be combined.
** Typical errors
If the test suite shows failures such as the following one
@@ -269,9 +240,6 @@ release:
that it does not make sense for glr.c, which should be ANSI, but
currently is actually GNU C, nor for lalr1.cc.
- Test with a very recent version of GCC for both C and C++. Testing
with older versions that are still in use is nice too.
* Release Procedure
This section needs to be updated to take into account features from
+2 -2
View File
@@ -25,8 +25,8 @@ LALR(1) Look-Ahead Sets", ACM Transactions on Programming Languages
and Systems (TOPLAS) 4, 4 (October 1982), 615-649. Their
technique is the standard one now.)
paul rubin
free software foundation
paul rubin
free software foundation
[DeRemer-Pennello reference corrected by Paul Eggert <[email protected]>,
+2 -5
View File
@@ -76,12 +76,10 @@ Matt Kraai [email protected]
Matt Rosing [email protected]
Michael Hayes [email protected]
Michael Raskin [email protected]
Michiel De Wilde [email protected]
Mickael Labau [email protected]
Mike Castle [email protected]
Neil Booth [email protected]
Nelson H. F. Beebe [email protected]
Nick Bowler [email protected]
Nicolas Burrus [email protected]
Nicolas Tisserand [email protected]
Noah Friedman [email protected]
@@ -98,7 +96,6 @@ Peter Fales [email protected]
Peter Hamorsky [email protected]
Peter Simons [email protected]
Piotr Gackiewicz [email protected]
Quentin Hocquet [email protected]
Quoc Peyrot [email protected]
R Blake [email protected]
Raja R Harinath [email protected]
@@ -106,7 +103,7 @@ Ralf Wildenhues [email protected]
Richard Stallman [email protected]
Rob Vermaas [email protected]
Robert Anisko [email protected]
Roland Levillain [email protected]
Rob Conde [email protected]
Satya Kiran Popuri [email protected]
Sebastian Setzer [email protected]
Sebastien Fricker [email protected]
@@ -125,7 +122,7 @@ Tom Tromey [email protected]
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]
+26 -33
View File
@@ -12,41 +12,15 @@ the pretty format of states from .output in the .dot
Also, the underscore in print_graph.[ch] isn't very fitting considering
the dashes in the other filenames.
** push-parser
Check it too when checking the different kinds of parsers. And be
sure to check that the initial-action is performed once per parsing.
** Variable names.
What should we name `variant' and `lex_symbol'?
** m4 names
b4_shared_declarations is no longer what it is. Make it
b4_parser_declaration for instance.
** Use b4_symbol in all the skeleton
Move its definition in the more standard places and deploy it in other
skeletons. Then remove the older system, including the tables
generated by output.c
** yychar in lalr1.cc
There is a large difference bw maint and master on the handling of
yychar (which was removed in lalr1.cc). See what needs to be
back-ported.
/* User semantic actions sometimes alter yychar, and that requires
that yytoken be updated with the new translation. We take the
approach of translating immediately before every use of yytoken.
One alternative is translating here after every semantic action,
but that translation would be missed if the semantic action
invokes YYABORT, YYACCEPT, or YYERROR immediately after altering
yychar. In the case of YYABORT or YYACCEPT, an incorrect
destructor might then be invoked immediately. In the case of
YYERROR, subsequent parser actions might lead to an incorrect
destructor call or verbose syntax error message before the
lookahead is translated. */
/* Make sure we have latest lookahead translation. See comments at
user semantic actions for why this is necessary. */
yytoken = yytranslate_ (yychar);
** stack.hh
Get rid of it. The original idea is nice, but actually it makes
the code harder to follow, and uselessly different from the other
skeletons.
** Update the documentation on gnu.org
** Get rid of fake #lines [Bison: ...]
Possibly as simple as checking whether the column number is nonnegative.
@@ -74,7 +48,14 @@ since it is no longer bound to a particular parser, it's just a
** Rename LR0.cc
as lr0.cc, why upper case?
** bench several bisons.
Enhance bench.pl with %b to run different bisons.
* Various
** Warnings
Warnings about type tags that are used in printer and dtors, but not
for symbols?
** YYERRCODE
Defined to 256, but not used, not documented. Probably the token
number for the error token, which POSIX wants to be 256, but which
@@ -120,6 +101,9 @@ so both 256 and 257 are "mysterious".
"\"end of command\"", "error", "$undefined", "\"=\"", "\"break\"",
** YYFAIL
It is seems to be *really* obsolete now, shall we remove it?
** yychar == yyempty_
The code in yyerrlab reads:
@@ -137,6 +121,12 @@ really possible? The test suite does not exercise this case.
This shows that it would be interesting to manage to install skeleton
coverage analysis to the test suite.
** Table definitions
It should be very easy to factor the definition of the various tables,
including the separation bw declaration and definition. See for
instance b4_table_define in lalr1.cc. This way, we could even factor
C vs. C++ definitions.
* From lalr1.cc to yacc.c
** Single stack
Merging the three stacks in lalr1.cc simplified the code, prompted for
@@ -262,6 +252,9 @@ Paul notes:
tokens, either via escapes (e.g., "x\0y") or via a NUL byte in
the source code. This should get fixed.
* --graph
Show reductions.
* Broken options ?
** %token-table
** Skeleton strategy
+27 -23
View File
@@ -1,6 +1,6 @@
#! /bin/sh
# Print a version string.
scriptversion=2012-12-28.10; # UTC
scriptversion=2013-03-08.16; # UTC
# Bootstrap this package from checked-out sources.
@@ -306,34 +306,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" | gitignore_entries - $file | 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 +344,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.
@@ -630,9 +630,13 @@ esac
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
+6 -12
View File
@@ -21,12 +21,12 @@ gnulib_modules='
configmake
dirname
error extensions fdl fopen-safer
getline
getopt-gnu
gettext git-version-gen gitlog-to-changelog
gpl-3.0 hash inttypes isnan javacomp-script
javaexec-script ldexpl malloc-gnu
javaexec-script ldexpl malloc-gnu mbschr mbsrchr
mbswidth
non-recursive-gnulib-prefix-hack
obstack
obstack-printf
perror progname
@@ -36,11 +36,7 @@ gnulib_modules='
spawn-pipe stdbool stpcpy strdup-posix strerror strtoul strverscmp
unistd unistd-safer unlocked-io update-copyright unsetenv verify
warnings
xalloc
xalloc-die
xconcat-filename
xmemdup0
xstrndup
xalloc xalloc-die xmemdup0 xstrndup
fprintf-posix printf-posix snprintf-posix sprintf-posix
vsnprintf-posix vsprintf-posix
@@ -50,8 +46,9 @@ gnulib_modules='
XGETTEXT_OPTIONS=$XGETTEXT_OPTIONS'\\\
--from-code=UTF-8\\\
--flag=asprintf:2:c-format\\\
--flag=complain:3:c-format\\\
--flag=complain_indent:4:c-format\\\
--flag=complain:1:c-format --flag=complain_at:2:c-format\\\
--flag=fatal:1:c-format --flag=fatal_at:2:c-format\\\
--flag=warn:1:c-format --flag=warn_at:2:c-format\\\
--flag=unexpected_end:2:c-format\\\
'
XGETTEXT_OPTIONS_RUNTIME=$XGETTEXT_OPTIONS'\\\
@@ -79,9 +76,6 @@ gnulib_tool_option_extras='--symlink --makefile-name=gnulib.mk'
bootstrap_post_import_hook()
{
# Massage lib/gnulib.mk before using it later in the bootstrapping process.
build-aux/prefix-gnulib-mk --lib-name=$gnulib_name lib/$gnulib_mk
# Ensure that ChangeLog exists, for automake.
test -f ChangeLog || touch ChangeLog
}
+2 -3
View File
@@ -1,10 +1,11 @@
/Makefile
/Makefile.in
/announce-gen
/arg-nonnull.h
/c++defs.h
/compile
/config.guess
/config.rpath
/config.rpath~
/config.sub
/depcomp
/do-release-commit-and-tag
@@ -19,11 +20,9 @@
/link-warning.h
/mdate-sh
/missing
/test-driver
/texinfo.tex
/update-copyright
/useless-if-before-free
/vc-list-files
/warn-on-use.h
/ylwrap
/prefix-gnulib-mk
+6 -9
View File
@@ -1,7 +1,5 @@
## Makefile for Bison testsuite.
## Copyright (C) 2006, 2009-2013 Free Software Foundation, Inc.
# Copyright (C) 2000-2013 Free Software Foundation, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
@@ -15,9 +13,8 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
EXTRA_DIST += \
build-aux/cross-options.pl \
build-aux/darwin11.4.0.valgrind \
build-aux/move-if-change \
build-aux/prev-version.txt \
build-aux/update-b4-copyright
EXTRA_DIST = \
cross-options.pl \
darwin11.4.0.valgrind \
prev-version.txt \
update-b4-copyright
+37 -37
View File
@@ -18,50 +18,50 @@ while (<STDIN>)
\s # Spaces.
/x)
{
my ($short, $long, $opt, $arg) = ($1, $2, $3, $4);
$short = '' if ! defined $short;
$short = '-d' if $long eq '--defines' && ! $short;
my $dir = '%' . substr($long, 2);
if (index ($scanner, "\"$dir\"") < 0)
{
if ($long eq '--force-define') { $dir = '%define'; }
else { $dir = ''; }
}
if ($arg)
{
my ($short, $long, $opt, $arg) = ($1, $2, $3, $4);
$short = '' if ! defined $short;
$short = '-d' if $long eq '--defines' && ! $short;
my $dir = '%' . substr($long, 2);
if (index ($scanner, "\"$dir\"") < 0)
{
if ($long eq '--force-define') { $dir = '%define'; }
else { $dir = ''; }
}
if ($arg)
{
# if $opt, $arg contains the closing ].
substr ($arg, -1) = ''
if $opt eq '[';
$arg =~ s/^=//;
$arg =~ s/^=//;
$arg = lc ($arg);
my $dir_arg = $arg;
my $dir_arg = $arg;
# If the argument is compite (e.g., for --define[=NAME[=VALUE]]),
# put each word in @var, to build @var{name}[=@var{value}], not
# @var{name[=value]}].
$arg =~ s/(\w+)/\@var{$1}/g;
my $long_arg = "=$arg";
if ($opt eq '[') {
$long_arg = "[$long_arg]";
$arg = "[$arg]";
}
# For arguments of directives: this only works if all arguments
# are strings and have the same syntax as on the command line.
if ($dir_arg eq 'name[=value]')
{
$dir_arg = '@var{name} ["@var{value}"]';
}
else
{
$dir_arg =~ s/(\w+)/\@var{"$1"}/g;
$dir_arg = '[' . $dir_arg . ']'
if $opt eq '[';
}
$long = "$long$long_arg";
$short = "$short $arg" if $short && $short ne '-d';
$dir = "$dir $dir_arg" if $dir;
}
$option{$long} = $short;
$directive{$long} = $dir;
$arg =~ s/(\w+)/\@var{$1}/g;
my $long_arg = "=$arg";
if ($opt eq '[') {
$long_arg = "[$long_arg]";
$arg = "[$arg]";
}
# For arguments of directives: this only works if all arguments
# are strings and have the same syntax as on the command line.
if ($dir_arg eq 'name[=value]')
{
$dir_arg = '@var{name} ["@var{value}"]';
}
else
{
$dir_arg =~ s/(\w+)/\@var{"$1"}/g;
$dir_arg = '[' . $dir_arg . ']'
if $opt eq '[';
}
$long = "$long$long_arg";
$short = "$short $arg" if $short && $short ne '-d';
$dir = "$dir $dir_arg" if $dir;
}
$option{$long} = $short;
$directive{$long} = $dir;
}
}
-1
View File
@@ -1 +0,0 @@
../gnulib/build-aux/move-if-change
+10 -96
View File
@@ -37,9 +37,15 @@ url_dir_list = \
ftp://$(gnu_rel_host)/gnu/bison
# Tests not to run as part of "make distcheck".
local-checks-to-skip = \
# Exclude changelog-check here so that there's less churn in ChangeLog
# files -- otherwise, you'd need to have the upcoming version number
# at the top of the file for each `make distcheck' run.
local-checks-to-skip = \
changelog-check \
sc_immutable_NEWS \
sc_prohibit_atoi_atof
sc_prohibit_always_true_header_tests \
sc_prohibit_atoi_atof \
sc_prohibit_strcmp
# The local directory containing the checked-out copy of gnulib used in
# this release. Used solely to get a date for the "announcement" target.
@@ -55,11 +61,6 @@ update-copyright: update-b4-copyright update-package-copyright-year
update-copyright-env = \
UPDATE_COPYRIGHT_FORCE=1 UPDATE_COPYRIGHT_USE_INTERVALS=1
## -------------------- ##
## More syntax-checks. ##
## -------------------- ##
# At least for Mac OS X's grep, the order between . and [ in "[^.[]"
# matters:
# $ LC_ALL=fr_FR grep -nE '[^[.]' /dev/null
@@ -72,108 +73,21 @@ sc_at_parser_check:
halt='use AT_PARSER_CHECK for and only for generated parsers' \
$(_sc_search_regexp)
# Indent only with spaces.
# Taken from Coreutils.
sc_prohibit_tab_based_indentation:
@prohibit='^ * ' \
halt='TAB in indentation; use only spaces' \
$(_sc_search_regexp)
# Prohibit the use of `...` in tests/. Use $(...) instead.
# Taken from Coreutils.
# Not ready for Bison yet.
#sc_prohibit_test_backticks:
# @prohibit='`' in_vc_files='^tests/' \
# halt='use $$(...), not `...` in tests/' \
# $(_sc_search_regexp)
# Enforce recommended preprocessor indentation style.
# Taken from Coreutils.
sc_preprocessor_indentation:
@if cppi --version >/dev/null 2>&1; then \
$(VC_LIST_EXCEPT) | grep '\.[ch]$$' | xargs cppi -a -c \
|| { echo '$(ME): incorrect preprocessor indentation' 1>&2; \
exit 1; }; \
else \
echo '$(ME): skipping test $@: cppi not installed' 1>&2; \
fi
###########################################################
# Taken from Coreutils.
_p0 = \([^"'/]\|"\([^\"]\|[\].\)*"\|'\([^\']\|[\].\)*'
_pre = $(_p0)\|[/][^"'/*]\|[/]"\([^\"]\|[\].\)*"\|[/]'\([^\']\|[\].\)*'\)*
_pre_anchored = ^\($(_pre)\)
_comment_and_close = [^*]\|[*][^/*]\)*[*][*]*/
# help font-lock mode: '
# A sed expression that removes ANSI C and ISO C99 comments.
# Derived from the one in GNU gettext's 'moopp' preprocessor.
_sed_remove_comments = \
/[/][/*]/{ \
ta; \
:a; \
s,$(_pre_anchored)//.*,\1,; \
te; \
s,$(_pre_anchored)/[*]\($(_comment_and_close),\1 ,; \
ta; \
/^$(_pre)[/][*]/{ \
s,$(_pre_anchored)/[*].*,\1 ,; \
tu; \
:u; \
n; \
s,^\($(_comment_and_close),,; \
tv; \
s,^.*$$,,; \
bu; \
:v; \
}; \
:e; \
}
# Quote all single quotes.
_sed_rm_comments_q = $(subst ','\'',$(_sed_remove_comments))
# help font-lock mode: '
_space_before_paren_exempt =? \\n\\$$
_space_before_paren_exempt = \
(^ *\#|\\n\\$$|%s\(to %s|(date|group|character)\(s\))
# 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 \
fail=0; \
for c in $$($(VC_LIST_EXCEPT) | grep '\.[ch]$$'); do \
sed '$(_sed_rm_comments_q)' $$c 2>/dev/null \
| grep -i '[[:alnum:]](' \
| grep -vE '$(_space_before_paren_exempt)' \
| grep . && { fail=1; echo "*** $$c"; }; \
done; \
test $$fail = 1 && \
{ echo '$(ME): the above files lack a space-before-open-paren' \
1>&2; exit 1; } || :; \
else :; \
fi
## -------------------------- ##
## syntax-checks exceptions. ##
## -------------------------- ##
exclude = \
$(foreach a,$(1),$(eval $(subst $$,$$$$,exclude_file_name_regexp--sc_$(a))))
$(call exclude, \
bindtextdomain=^lib/main.c$$ \
preprocessor_indentation=^data/|^lib/|^src/parse-gram.[ch]$$ \
program_name=^lib/main.c$$ \
prohibit_always-defined_macros=^data/yacc.c$$|^djgpp/ \
prohibit_always-defined_macros+=?|^lib/timevar.c$$ \
prohibit_always-defined_macros+=?|^src/(parse-gram.c|system.h)$$ \
prohibit_always-defined_macros+=?|^tests/regression.at$$ \
prohibit_always_true_header_tests=^djgpp/subpipe.h$$|^lib/timevar.c$$ \
prohibit_always_true_header_tests+=?|^m4/timevar.m4$$ \
prohibit_defined_have_decl_tests=?|^lib/timevar.c$$ \
prohibit_doubled_word=^tests/named-refs.at$$ \
prohibit_magic_number_exit=^doc/bison.texi$$ \
prohibit_magic_number_exit+=?|^tests/(conflicts|regression).at$$ \
prohibit_strcmp=^doc/bison\.texi|tests/local\.at$$ \
prohibit_tab_based_indentation=\.(am|mk)$$|^djgpp/|^\.git \
require_config_h_first=^(lib/yyerror|data/(glr|yacc))\.c$$ \
space_tab=^tests/(input|c\+\+)\.at$$ \
trailing_blank=^src/parse-gram.[ch]$$ \
unmarked_diagnostics=^(djgpp/|doc/bison.texi$$|tests/c\+\+\.at$$) \
)
+15 -10
View File
@@ -45,9 +45,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
color-tests parallel-tests
silent-rules]
AM_INIT_AUTOMAKE([1.11.1 dist-xz silent-rules]
m4_bmatch(m4_defn([AC_PACKAGE_VERSION]), [[-_]],
[gnu], [gnits]))
AM_SILENT_RULES([yes])
@@ -161,8 +159,8 @@ AC_ARG_ENABLE([yacc],
, [enable_yacc=yes])
case $enable_yacc in
yes)
YACC_SCRIPT=src/yacc
YACC_LIBRARY=lib/liby.a;;
YACC_SCRIPT=yacc
YACC_LIBRARY=liby.a;;
*)
YACC_SCRIPT=
YACC_LIBRARY=;;
@@ -220,8 +218,8 @@ AC_SUBST([aclocaldir])
AC_CONFIG_FILES([etc/bench.pl], [chmod +x etc/bench.pl])
# Initialize the test suite.
AC_CONFIG_TESTDIR([tests], [$ac_abs_top_builddir/tests])
AC_CONFIG_FILES([tests/atlocal])
AC_CONFIG_TESTDIR(tests)
AC_CONFIG_FILES([tests/Makefile tests/atlocal])
AC_CONFIG_FILES([tests/bison], [chmod +x tests/bison])
AC_CHECK_PROGS([VALGRIND], [valgrind])
case $VALGRIND:$host_os in
@@ -238,10 +236,17 @@ AM_MISSING_PROG([AUTOM4TE], [autom4te])
# Needed by tests/atlocal.in.
AC_SUBST([GCC])
gt_JAVACOMP([1.3], [1.4])
gt_JAVACOMP([1.3])
gt_JAVAEXEC
AC_CONFIG_FILES([Makefile
po/Makefile.in
doc/yacc.1])
build-aux/Makefile
po/Makefile.in
data/Makefile
etc/Makefile
examples/Makefile
examples/calc++/Makefile
lib/Makefile src/Makefile
doc/Makefile
doc/yacc.1])
AC_OUTPUT
+2
View File
@@ -0,0 +1,2 @@
Makefile.in
Makefile
+2
View File
@@ -0,0 +1,2 @@
/Makefile.in
/Makefile
+30
View File
@@ -0,0 +1,30 @@
## Copyright (C) 2002, 2005-2013 Free Software Foundation, Inc.
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
dist_pkgdata_DATA = README bison.m4 \
c-like.m4 \
c-skel.m4 c.m4 yacc.c glr.c \
c++-skel.m4 c++.m4 location.cc lalr1.cc glr.cc stack.hh \
java-skel.m4 java.m4 lalr1.java
m4sugardir = $(pkgdatadir)/m4sugar
dist_m4sugar_DATA = m4sugar/m4sugar.m4 m4sugar/foreach.m4
xsltdir = $(pkgdatadir)/xslt
dist_xslt_DATA = \
xslt/bison.xsl \
xslt/xml2dot.xsl \
xslt/xml2text.xsl \
xslt/xml2xhtml.xsl
+54 -394
View File
@@ -22,17 +22,14 @@
## Identification. ##
## ---------------- ##
# b4_copyright(TITLE, [YEARS])
# ----------------------------
# If YEARS are not defined, use b4_copyright_years.
# b4_copyright(TITLE, YEARS)
# --------------------------
m4_define([b4_copyright],
[b4_comment([A Bison parser, made by GNU Bison b4_version.])
b4_comment([$1
]m4_dquote(m4_text_wrap([Copyright (C)
]m4_ifval([$2], [[$2]], [m4_defn([b4_copyright_years])])[
Free Software Foundation, Inc.]))[
m4_text_wrap([Copyright (C) $2 Free Software Foundation, Inc.], [ ])
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -106,16 +103,30 @@ _m4eof
])dnl
m4_if(m4_sysval, [0], [], [m4_fatal([$0: cannot write to stdout])])])
# b4_error(KIND, START, END, FORMAT, [ARG1], [ARG2], ...)
# -------------------------------------------------------
# Write @KIND(START@,END@,FORMAT@,ARG1@,ARG2@,...@) to stdout.
# b4_error(KIND, FORMAT, [ARG1], [ARG2], ...)
# -------------------------------------------
# Write @KIND(FORMAT@,ARG1@,ARG2@,...@) to stdout.
#
# For example:
#
# b4_error([[complain]], [[input.y:2.3]], [[input.y:5.4]],
# [[invalid %s]], [[foo]])
# b4_error([[warn]], [[invalid value for '%s': %s]], [[foo]], [[3]])
m4_define([b4_error],
[b4_cat([[@complain][(]$1[@,]$2[@,]$3[@,]$4[]]dnl
[b4_cat([[@]$1[(]$2[]]dnl
[m4_if([$#], [2], [],
[m4_foreach([b4_arg],
m4_dquote(m4_shift(m4_shift($@))),
[[@,]b4_arg])])[@)]])])
# b4_error_at(KIND, START, END, FORMAT, [ARG1], [ARG2], ...)
# ----------------------------------------------------------
# Write @KIND_at(START@,END@,FORMAT@,ARG1@,ARG2@,...@) to stdout.
#
# For example:
#
# b4_error_at([[complain]], [[input.y:2.3]], [[input.y:5.4]],
# [[invalid %s]], [[foo]])
m4_define([b4_error_at],
[b4_cat([[@]$1[_at(]$2[@,]$3[@,]$4[]]dnl
[m4_if([$#], [4], [],
[m4_foreach([b4_arg],
m4_dquote(m4_shift(m4_shift(m4_shift(m4_shift($@))))),
@@ -135,21 +146,21 @@ m4_define([b4_error],
# m4_define([asdf], [ASDF])
# m4_define([fsa], [FSA])
# m4_define([fdsa], [FDSA])
# b4_warn_at([[[asdf), asdf]]], [[[fsa), fsa]]], [[[fdsa), fdsa]]])
# b4_warn_at([[asdf), asdf]], [[fsa), fsa]], [[fdsa), fdsa]])
# b4_warn_at()
# b4_warn_at(1)
# b4_warn_at(1, 2)
# b4_warn([[[asdf), asdf]]], [[[fsa), fsa]]], [[[fdsa), fdsa]]])
# b4_warn([[asdf), asdf]], [[fsa), fsa]], [[fdsa), fdsa]])
# b4_warn()
# b4_warn(1)
# b4_warn(1, 2)
#
# Should produce this without newlines:
#
# @warn_at([asdf), asdf]@,@,@,[fsa), fsa]@,[fdsa), fdsa]@)
# @warn(asdf), asdf@,@,@,fsa), fsa@,fdsa), fdsa@)
# @warn([asdf), asdf]@,[fsa), fsa]@,[fdsa), fdsa]@)
# @warn(asdf), asdf@,fsa), fsa@,fdsa), fdsa@)
# @warn(@)
# @warn(1@)
# @warn(1@,2@)
m4_define([b4_warn],
[b4_error([[warn]], [], [], $@)])
[b4_error([[warn]], $@)])
# b4_warn_at(START, END, FORMAT, [ARG1], [ARG2], ...)
# ---------------------------------------------------
@@ -159,15 +170,15 @@ m4_define([b4_warn],
#
# b4_warn_at([[input.y:2.3]], [[input.y:5.4]], [[invalid %s]], [[foo]])
m4_define([b4_warn_at],
[b4_error([[warn]], $@)])
[b4_error_at([[warn]], $@)])
# b4_complain(FORMAT, [ARG1], [ARG2], ...)
# ----------------------------------------
# Bounce to b4_complain_at.
# Write @complain(FORMAT@,ARG1@,ARG2@,...@) to stdout.
#
# See b4_warn example.
m4_define([b4_complain],
[b4_error([[complain]], [], [], $@)])
[b4_error([[complain]], $@)])
# b4_complain_at(START, END, FORMAT, [ARG1], [ARG2], ...)
# -------------------------------------------------------
@@ -175,15 +186,15 @@ m4_define([b4_complain],
#
# See b4_warn_at example.
m4_define([b4_complain_at],
[b4_error([[complain]], $@)])
[b4_error_at([[complain]], $@)])
# b4_fatal(FORMAT, [ARG1], [ARG2], ...)
# -------------------------------------
# Bounce to b4_fatal_at.
# Write @fatal(FORMAT@,ARG1@,ARG2@,...@) to stdout and exit.
#
# See b4_warn example.
m4_define([b4_fatal],
[b4_error([[fatal]], [], [], $@)dnl
[b4_error([[fatal]], $@)dnl
m4_exit(1)])
# b4_fatal_at(START, END, FORMAT, [ARG1], [ARG2], ...)
@@ -192,7 +203,7 @@ m4_exit(1)])
#
# See b4_warn_at example.
m4_define([b4_fatal_at],
[b4_error([[fatal]], $@)dnl
[b4_error_at([[fatal]], $@)dnl
m4_exit(1)])
@@ -207,87 +218,6 @@ m4_define([b4_ints_in],
[m4_eval([$3 <= $1 && $1 <= $4 && $3 <= $2 && $2 <= $4])])
# b4_subtract(LHS, RHS)
# ---------------------
# Evaluate LHS - RHS if they are integer literals, otherwise expand
# to (LHS) - (RHS).
m4_define([b4_subtract],
[m4_bmatch([$1$2], [^[0123456789]*$],
[m4_eval([$1 - $2])],
[($1) - ($2)])])
# b4_join(ARG1, ...)
# _b4_join(ARG1, ...)
# -------------------
# Join with comma, skipping empty arguments.
# b4_join calls itself recursively until it sees the first non-empty
# argument, then calls _b4_join which prepends each non-empty argument
# with a comma.
m4_define([b4_join],
[m4_if([$#$1],
[1], [],
[m4_ifval([$1],
[$1[]_$0(m4_shift($@))],
[$0(m4_shift($@))])])])
# _b4_join(ARGS1, ...)
# --------------------
m4_define([_b4_join],
[m4_if([$#$1],
[1], [],
[m4_ifval([$1], [, $1])[]$0(m4_shift($@))])])
# b4_integral_parser_tables_map(MACRO)
# -------------------------------------
# Map MACRO on all the integral tables. MACRO is expected to have
# the signature MACRO(TABLE-NAME, CONTENT, COMMENT).
m4_define([b4_integral_parser_tables_map],
[$1([pact], [b4_pact],
[[YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
STATE-NUM.]])
$1([defact], [b4_defact],
[[YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
Performed when YYTABLE does not specify something else to do. Zero
means the default is an error.]])
$1([pgoto], [b4_pgoto], [[YYPGOTO[NTERM-NUM].]])
$1([defgoto], [b4_defgoto], [[YYDEFGOTO[NTERM-NUM].]])
$1([table], [b4_table],
[[YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If
positive, shift that token. If negative, reduce the rule whose
number is the opposite. If YYTABLE_NINF, syntax error.]])
$1([check], [b4_check])
$1([stos], [b4_stos],
[[YYSTOS[STATE-NUM] -- The (internal number of the) accessing
symbol of state STATE-NUM.]])
$1([r1], [b4_r1],
[[YYR1[YYN] -- Symbol number of symbol that rule YYN derives.]])
$1([r2], [b4_r2],
[[YYR2[YYN] -- Number of symbols on the right hand side of rule YYN.]])
])
# b4_parser_tables_declare
# b4_parser_tables_define
# ------------------------
# Define/declare the (deterministic) parser tables.
m4_define([b4_parser_tables_declare],
[b4_integral_parser_tables_map([b4_integral_parser_table_declare])])
m4_define([b4_parser_tables_define],
[b4_integral_parser_tables_map([b4_integral_parser_table_define])])
## ------------------ ##
## Decoding options. ##
@@ -299,8 +229,8 @@ m4_define([b4_parser_tables_define],
m4_define([b4_flag_if],
[m4_case(b4_$1_flag,
[0], [$3],
[1], [$2],
[m4_fatal([invalid $1 value: ]b4_$1_flag)])])
[1], [$2],
[m4_fatal([invalid $1 value: ]$1)])])
# b4_define_flag_if(FLAG)
@@ -326,202 +256,15 @@ m4_define([b4_$3_if],
# -----------------------------
# Expand IF-TRUE, if FLAG is true, IF-FALSE otherwise.
b4_define_flag_if([defines]) # Whether headers are requested.
b4_define_flag_if([error_verbose]) # Whether error are verbose.
b4_define_flag_if([glr]) # Whether a GLR parser is requested.
b4_define_flag_if([locations]) # Whether locations are tracked.
b4_define_flag_if([nondeterministic]) # Whether conflicts should be handled.
b4_define_flag_if([token_table]) # Whether yytoken_table is demanded.
b4_define_flag_if([yacc]) # Whether POSIX Yacc is emulated.
## --------- ##
## Symbols. ##
## --------- ##
# In order to unify the handling of the various aspects of symbols
# (tag, type_name, whether terminal, etc.), bison.exe defines one
# macro per (token, field), where field can has_id, id, etc.: see
# src/output.c:prepare_symbols_definitions().
#
# The various FIELDS are:
#
# - has_id: 0 or 1.
# Whether the symbol has an id.
# - id: string
# If has_id, the id. Guaranteed to be usable as a C identifier.
# - tag: string.
# A representat of the symbol. Can be 'foo', 'foo.id', '"foo"' etc.
# - user_number: integer
# The assigned (external) number as used by yylex.
# - is_token: 0 or 1
# Whether this is a terminal symbol.
# - number: integer
# The internalized number (used after yytranslate).
# - has_type: 0, 1
# Whether has a semantic value.
# - type
# If it has a semantic value, its type tag, or, if variant are used,
# its type.
# - has_printer: 0, 1
# - printer: string
# - printer_file: string
# - printer_line: integer
# If the symbol has a printer, everything about it.
# - has_destructor, destructor, destructor_file, destructor_line
# Likewise.
#
# The following macros provide access to these values.
# b4_symbol_(NUM, FIELD)
# ----------------------
# Recover a FIELD about symbol #NUM. Thanks to m4_indir, fails if
# undefined.
m4_define([b4_symbol_],
[m4_indir([b4_symbol($1, $2)])])
# b4_symbol(NUM, FIELD)
# ---------------------
# Recover a FIELD about symbol #NUM. Thanks to m4_indir, fails if
# undefined. If FIELD = id, prepend the token prefix.
m4_define([b4_symbol],
[m4_case([$2],
[id], [m4_do([b4_percent_define_get([api.token.prefix])],
[b4_symbol_([$1], [id])])],
[b4_symbol_($@)])])
# b4_symbol_if(NUM, FIELD, IF-TRUE, IF-FALSE)
# -------------------------------------------
# If FIELD about symbol #NUM is 1 expand IF-TRUE, if is 0, expand IF-FALSE.
# Otherwise an error.
m4_define([b4_symbol_if],
[m4_case(b4_symbol([$1], [$2]),
[1], [$3],
[0], [$4],
[m4_fatal([$0: field $2 of $1 is not a Boolean:] b4_symbol([$1], [$2]))])])
# b4_symbol_tag_comment(SYMBOL-NUM)
# ---------------------------------
# Issue a comment giving the tag of symbol NUM.
m4_define([b4_symbol_tag_comment],
[b4_comment([b4_symbol([$1], [tag])])
])
# b4_symbol_action_location(SYMBOL-NUM, KIND)
# -------------------------------------------
# Report the location of the KIND action as FILE:LINE.
m4_define([b4_symbol_action_location],
[b4_symbol([$1], [$2_file]):b4_syncline([b4_symbol([$1], [$2_line])])])
# b4_symbol_action(SYMBOL-NUM, KIND)
# ----------------------------------
# Run the action KIND (destructor or printer) for SYMBOL-NUM.
# Same as in C, but using references instead of pointers.
m4_define([b4_symbol_action],
[b4_symbol_if([$1], [has_$2],
[b4_dollar_pushdef([(*yyvaluep)],
b4_symbol_if([$1], [has_type],
[m4_dquote(b4_symbol([$1], [type]))]),
[(*yylocationp)])dnl
b4_symbol_case_([$1])[]dnl
b4_syncline([b4_symbol([$1], [$2_line])], ["b4_symbol([$1], [$2_file])"])
b4_symbol([$1], [$2])
b4_syncline([@oline@], [@ofile@])
break;
b4_dollar_popdef[]dnl
])])
# b4_symbol_destructor(SYMBOL-NUM)
# b4_symbol_printer(SYMBOL-NUM)
# --------------------------------
m4_define([b4_symbol_destructor], [b4_symbol_action([$1], [destructor])])
m4_define([b4_symbol_printer], [b4_symbol_action([$1], [printer])])
# b4_symbol_case_(SYMBOL-NUM)
# ---------------------------
# Issue a "case NUM" for SYMBOL-NUM.
m4_define([b4_symbol_case_],
[case b4_symbol([$1], [number]): b4_symbol_tag_comment([$1])])
])
# b4_symbol_foreach(MACRO)
# ------------------------
# Invoke MACRO(SYMBOL-NUM) for each SYMBOL-NUM.
m4_define([b4_symbol_foreach],
[m4_map([$1], m4_defn([b4_symbol_numbers]))])
# b4_symbol_map(MACRO)
# --------------------
# Return a list (possibly empty elements) of MACRO invoked for each
# SYMBOL-NUM.
m4_define([b4_symbol_map],
[m4_map_args_sep([$1(], [)], [,], b4_symbol_numbers)])
# b4_token_visible_if(NUM, IF-TRUE, IF-FALSE)
# -------------------------------------------
# Whether NUM denotes a token that has an exported definition (i.e.,
# shows in enum yytokentype).
m4_define([b4_token_visible_if],
[b4_symbol_if([$1], [is_token],
[b4_symbol_if([$1], [has_id], [$2], [$3])],
[$3])])
# b4_token_has_definition(NUM)
# ----------------------------
# 1 if NUM is visible, nothing otherwise.
m4_define([b4_token_has_definition],
[b4_token_visible_if([$1], [1])])
# b4_any_token_visible_if([IF-TRUE], [IF-FALSE])
# ----------------------------------------------
# Whether there is a token that needs to be defined.
m4_define([b4_any_token_visible_if],
[m4_ifval(b4_symbol_foreach([b4_token_has_definition]),
[$1], [$2])])
# b4_token_format(FORMAT, NUM)
# ----------------------------
m4_define([b4_token_format],
[b4_token_visible_if([$2],
[m4_quote(m4_format([$1],
[b4_symbol([$2], [id])],
[b4_symbol([$2], [user_number])]))])])
## ------- ##
## Types. ##
## ------- ##
# b4_type_action_(NUMS)
# ---------------------
# Run actions for the symbol NUMS that all have the same type-name.
# Skip NUMS that have no type-name.
#
# To specify the action to run, define b4_dollar_dollar(NUMBER,
# TAG, TYPE).
m4_define([b4_type_action_],
[b4_symbol_if([$1], [has_type],
[m4_map([ b4_symbol_case_], [$@])[]dnl
b4_dollar_dollar([b4_symbol([$1], [number])],
[b4_symbol([$1], [tag])],
[b4_symbol([$1], [type])]);
break;
])])
# b4_type_foreach(MACRO)
# ----------------------
# Invoke MACRO(SYMBOL-NUMS) for each set of SYMBOL-NUMS for each type set.
m4_define([b4_type_foreach],
[m4_map([$1], m4_defn([b4_type_names]))])
# yytoken_table is needed to support verbose errors.
b4_error_verbose_if([m4_define([b4_token_table_flag], [1])])
@@ -541,21 +284,11 @@ m4_define([b4_basename],
# -----------------------
m4_define([b4_syncline],
[b4_flag_if([synclines],
[b4_sync_start([$1], [$2]) b4_sync_end([__line__],
[b4_basename(m4_quote(__file__))])[]dnl
])])
# b4_sync_start(LINE, FILE)
# -----------------------
# Syncline for the new place. Typically a directive for the compiler.
m4_define([b4_sync_start], [b4_comment([$2:$1])])
# b4_sync_end(LINE, FILE)
# -----------------------
# Syncline for the current place, which ends. Typically a comment
# left for the reader.
m4_define([b4_sync_end], [b4_comment([$2:$1])])
[b4_sync_end([__line__], [b4_basename(m4_quote(__file__))])
b4_sync_start([$1], [$2])])])
m4_define([b4_sync_end], [b4_comment([Line $1 of $2])])
m4_define([b4_sync_start], [b4_comment([Line $1 of $2])])
# b4_user_code(USER-CODE)
# -----------------------
@@ -640,6 +373,7 @@ m4_popdef([b4_end])dnl
## --------------------- ##
## b4_percent_define_*. ##
## --------------------- ##
@@ -669,6 +403,7 @@ m4_ifdef([b4_percent_define(]$1[)],
[m4_indir([b4_percent_define(]$1[)])],
[$2])])
# b4_percent_define_get_loc(VARIABLE)
# -----------------------------------
# Mimic muscle_percent_define_get_loc in ../src/muscle-tab.h exactly. That is,
@@ -717,14 +452,8 @@ 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])])
## --------- ##
## Options. ##
## --------- ##
[m4_define([b4_percent_define_bison_variables(]$1[)])$2],
[$3])])
# b4_percent_define_flag_if(VARIABLE, IF-TRUE, [IF-FALSE])
# --------------------------------------------------------
@@ -749,7 +478,6 @@ m4_define([b4_percent_define_flag_if],
[[b4_percent_define_flag_if($1)]])])],
[b4_fatal([[b4_percent_define_flag_if: undefined %%define variable '%s']], [$1])])])
# b4_percent_define_default(VARIABLE, DEFAULT)
# --------------------------------------------
# Mimic muscle_percent_define_default in ../src/muscle-tab.h exactly. That is,
@@ -768,21 +496,6 @@ m4_define([b4_percent_define_default],
[[<skeleton default value>:-1.-1]]]])dnl
m4_define([b4_percent_define_syncline(]$1[)], [[]])])])
# 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 `_'.
m4_define([b4_percent_define_if_define_],
[m4_define(m4_bpatsubst([b4_$1_if], [[-.]], [_]),
[b4_percent_define_flag_if(m4_default([$2], [$1]),
[$3], [$4])])])
m4_define([b4_percent_define_if_define],
[b4_percent_define_default([m4_default([$2], [$1])], [[false]])
b4_percent_define_if_define_([$1], [$2], $[1], $[2])])
# b4_percent_define_check_values(VALUES)
# --------------------------------------
# Mimic muscle_percent_define_check_values in ../src/muscle-tab.h exactly
@@ -816,7 +529,7 @@ m4_define([_b4_percent_define_check_values],
[$1],
m4_dquote(m4_indir([b4_percent_define(]$1[)])))
m4_foreach([b4_value], m4_dquote(m4_shift($@)),
[b4_error([[note]], b4_percent_define_get_loc([$1]), []
[b4_complain_at(b4_percent_define_get_loc([$1]),
[[accepted value: '%s']],
m4_dquote(b4_value))])])dnl
m4_popdef([b4_good_value])],
@@ -854,60 +567,7 @@ m4_popdef([b4_macro_name])])
m4_define([b4_percent_code_ifdef],
[m4_ifdef([b4_percent_code(]$1[)],
[m4_ifval([$1], [m4_define([b4_percent_code_bison_qualifiers(]$1[)])])$2],
[$3])])
## ------------------ ##
## 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])
# b4_token_ctor_if([IF-YYLEX-RETURNS-A-TOKEN], [IF-NOT])
# ----------------------------------------------
b4_percent_define_if_define([token_ctor], [api.token.constructor])
b4_percent_define_if_define([locations]) # Whether locations are tracked.
b4_percent_define_if_define([parse.assert])
b4_percent_define_if_define([parse.trace])
# b4_bison_locations_if([IF-TRUE])
# --------------------------------
# Expand IF-TRUE if using locations, and using the default location
# type.
m4_define([b4_bison_locations_if],
[b4_locations_if([b4_percent_define_ifdef([[api.location.type]], [], [$1])])])
# b4_error_verbose_if([IF-ERRORS-ARE-VERBOSE], [IF-NOT])
# ------------------------------------------------------
# Map %define parse.error "(simple|verbose)" to b4_error_verbose_if and
# b4_error_verbose_flag.
b4_percent_define_default([[parse.error]], [[simple]])
b4_percent_define_check_values([[[[parse.error]],
[[simple]], [[verbose]]]])
m4_define([b4_error_verbose_flag],
[m4_case(b4_percent_define_get([[parse.error]]),
[simple], [[0]],
[verbose], [[1]])])
b4_define_flag_if([error_verbose])
# yytoken_table is needed to support verbose errors.
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]])])
b4_define_flag_if([variant])
[$3])])
## ----------------------------------------------------------- ##
+25 -342
View File
@@ -19,17 +19,11 @@
m4_include(b4_pkgdatadir/[c.m4])
# b4_comment(TEXT, [PREFIX])
# --------------------------
# Put TEXT in comment. Prefix all the output lines with PREFIX.
m4_define([b4_comment],
[b4_comment_([$1], [$2// ], [$2// ])])
## ---------------- ##
## Default values. ##
## ---------------- ##
# Default parser class name.
b4_percent_define_default([[parser_class_name]], [[parser]])
# Don't do that so that we remember whether we're using a user
@@ -38,21 +32,18 @@ b4_percent_define_default([[parser_class_name]], [[parser]])
# b4_percent_define_default([[api.location.type]], [[location]])
b4_percent_define_default([[filename_type]], [[std::string]])
b4_percent_define_default([[api.namespace]], m4_defn([b4_prefix]))
b4_percent_define_default([[namespace]], m4_defn([b4_prefix]))
b4_percent_define_default([[global_tokens_and_yystype]], [[false]])
b4_percent_define_default([[define_location_comparison]],
[m4_if(b4_percent_define_get([[filename_type]]),
[std::string], [[true]], [[false]])])
## ----------- ##
## Namespace. ##
## ----------- ##
m4_define([b4_namespace_ref], [b4_percent_define_get([[api.namespace]])])
m4_define([b4_namespace_ref], [b4_percent_define_get([[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.
@@ -62,7 +53,7 @@ m4_define([b4_namespace_ref], [b4_percent_define_get([[api.namespace]])])
# include the header, which is always generated. If we ever need to permit
# internal linkage somehow, surely we can find a cleaner approach.
m4_if(m4_bregexp(b4_namespace_ref, [^[ ]*$]), [-1], [],
[b4_complain_at(b4_percent_define_get_loc([[api.namespace]]),
[b4_complain_at(b4_percent_define_get_loc([[namespace]]),
[[namespace reference is empty]])])
# Instead of assuming the C++ compiler will do it, Bison should reject any
@@ -73,36 +64,36 @@ m4_if(m4_bregexp(b4_namespace_ref, [^[ ]*$]), [-1], [],
# Specifically, don't allow empty names as b4_namespace_open would just convert
# those into anonymous namespaces, and that might tempt some users.
m4_if(m4_bregexp(b4_namespace_ref, [::[ ]*::]), [-1], [],
[b4_complain_at(b4_percent_define_get_loc([[api.namespace]]),
[b4_complain_at(b4_percent_define_get_loc([[namespace]]),
[[namespace reference has consecutive "::"]])])
m4_if(m4_bregexp(b4_namespace_ref, [::[ ]*$]), [-1], [],
[b4_complain_at(b4_percent_define_get_loc([[api.namespace]]),
[b4_complain_at(b4_percent_define_get_loc([[namespace]]),
[[namespace reference has a trailing "::"]])])
m4_define([b4_namespace_open],
[b4_user_code([b4_percent_define_get_syncline([[api.namespace]])
[b4_user_code([b4_percent_define_get_syncline([[namespace]])
[namespace ]m4_bpatsubst(m4_dquote(m4_bpatsubst(m4_dquote(b4_namespace_ref),
[^\(.\)[ ]*::], [\1])),
[::], [ { namespace ])[ {]])])
m4_define([b4_namespace_close],
[b4_user_code([b4_percent_define_get_syncline([[api.namespace]])
[b4_user_code([b4_percent_define_get_syncline([[namespace]])
m4_bpatsubst(m4_dquote(m4_bpatsubst(m4_dquote(b4_namespace_ref[ ]),
[^\(.\)[ ]*\(::\)?\([^][:]\|:[^:]\)*],
[\1])),
[::\([^][:]\|:[^:]\)*], [} ])[} // ]b4_namespace_ref])])
# b4_token_enums
# --------------
# b4_token_enums(LIST-OF-PAIRS-TOKEN-NAME-TOKEN-NUMBER)
# -----------------------------------------------------
# Output the definition of the tokens as enums.
m4_define([b4_token_enums],
[[enum yytokentype
{
]m4_join([,
],
b4_symbol_map([b4_token_enum]))[
};]dnl
[/* Tokens. */
enum yytokentype {
m4_map_sep([ b4_token_enum], [,
],
[$@])
};
])
@@ -112,319 +103,12 @@ m4_define([b4_token_enums],
## Semantic Values. ##
## ----------------- ##
# b4_semantic_type_declare
# ------------------------
# Declare semantic_type.
m4_define([b4_semantic_type_declare],
[ /// Symbol semantic values.
m4_ifdef([b4_stype],
[ 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_public_types_declare
# -----------------------
# Define the public types: token, semantic value, location, and so forth.
# 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[
#else
typedef ]b4_api_PREFIX[STYPE semantic_type;
#endif]b4_locations_if([
/// Symbol locations.
typedef b4_percent_define_get([[api.location.type]],
[[location]]) location_type;])[
/// Syntax errors thrown from user actions.
struct syntax_error : std::runtime_error
{
syntax_error (]b4_locations_if([const location_type& l, ])[const std::string& m);]b4_locations_if([
location_type location;])[
};
/// Tokens.
struct token
{
]b4_token_enums[
};
/// (External) token type, as returned by yylex.
typedef token::yytokentype token_type;
/// Internal symbol number.
typedef int symbol_number_type;
/// Internal symbol number for tokens (subsumed by symbol_number_type).
typedef ]b4_int_type_for([b4_translate])[ token_number_type;
/// A complete symbol.
///
/// Expects its Base type to provide access to the symbol type
/// via type_get().
///
/// Provide access to semantic value]b4_locations_if([ and location])[.
template <typename Base>
struct basic_symbol : Base
{
/// Alias to Base.
typedef Base super_type;
/// Default constructor.
basic_symbol ();
/// Copy constructor.
basic_symbol (const basic_symbol& other);
]b4_variant_if([[
/// Constructor for valueless symbols, and symbols from each type.
]b4_type_foreach([b4_basic_symbol_constructor_declare])], [[
/// Constructor for valueless symbols.
basic_symbol (typename Base::kind_type t]b4_locations_if([,
const location_type& l])[);]])[
/// Constructor for symbols with semantic value.
basic_symbol (typename Base::kind_type t,
const semantic_type& v]b4_locations_if([,
const location_type& l])[);
~basic_symbol ();
/// Destructive move, \a s is emptied into this.
void move (basic_symbol& s);
/// The semantic value.
semantic_type value;]b4_locations_if([
/// The location.
location_type location;])[
private:
/// Assignment operator.
basic_symbol& operator= (const basic_symbol& other);
};
/// Type access provider for token (enum) based symbols.
struct by_type
{
/// Default constructor.
by_type ();
/// Copy constructor.
by_type (const by_type& other);
/// The symbol type as needed by the constructor.
typedef token_type kind_type;
/// Constructor from (external) token numbers.
by_type (kind_type t);
/// Steal the symbol type from \a that.
void move (by_type& that);
/// The (internal) type number (corresponding to \a type).
/// -1 when this symbol is empty.
symbol_number_type type_get () const;
/// The token.
token_type token () const;
enum { empty = 0 };
/// The symbol type.
/// -1 when this symbol is empty.
token_number_type type;
};
/// "External" symbols: returned by the scanner.
typedef basic_symbol<by_type> symbol_type;
]b4_symbol_constructor_declare])
# b4_public_types_define
# ----------------------
# Provide the implementation needed by the public types.
m4_define([b4_public_types_define],
[[ inline
]b4_parser_class_name[::syntax_error::syntax_error (]b4_locations_if([const location_type& l, ])[const std::string& m)
: std::runtime_error (m)]b4_locations_if([
, location (l)])[
{}
// basic_symbol.
template <typename Base>
inline
]b4_parser_class_name[::basic_symbol<Base>::basic_symbol ()
: value ()
{}
template <typename Base>
inline
]b4_parser_class_name[::basic_symbol<Base>::basic_symbol (const basic_symbol& other)
: Base (other)
, value ()]b4_locations_if([
, location (other.location)])[
{
]b4_variant_if([b4_symbol_variant([other.type_get ()], [value], [copy],
[other.value])],
[value = other.value;])[
}
template <typename Base>
inline
]b4_parser_class_name[::basic_symbol<Base>::basic_symbol (]b4_join(
[typename Base::kind_type t],
[const semantic_type& v],
b4_locations_if([const location_type& l]))[)
: Base (t)
, value (]b4_variant_if([], [v])[)]b4_locations_if([
, location (l)])[
{]b4_variant_if([[
(void) v;
]b4_symbol_variant([this->type_get ()], [value], [copy], [v])])[}
]b4_variant_if([[
// Implementation of basic_symbol constructor for each type.
]b4_type_foreach([b4_basic_symbol_constructor_define])], [[
/// Constructor for valueless symbols.
template <typename Base>
inline
]b4_parser_class_name[::basic_symbol<Base>::basic_symbol (]b4_join(
[typename Base::kind_type t],
b4_locations_if([const location_type& l]))[)
: Base (t)
, value ()]b4_locations_if([
, location (l)])[
{}]])[
template <typename Base>
inline
]b4_parser_class_name[::basic_symbol<Base>::~basic_symbol ()
{]b4_variant_if([[
// User destructor.
symbol_number_type yytype = this->type_get ();
switch (yytype)
{
]b4_symbol_foreach([b4_symbol_destructor])dnl
[ default:
break;
}
// Type destructor.
]b4_symbol_variant([[yytype]], [[value]], [[template destroy]])])[
}
template <typename Base>
inline
void
]b4_parser_class_name[::basic_symbol<Base>::move (basic_symbol& s)
{
super_type::move(s);
]b4_variant_if([b4_symbol_variant([this->type_get ()], [value], [move],
[s.value])],
[value = s.value;])[]b4_locations_if([
location = s.location;])[
}
// by_type.
inline
]b4_parser_class_name[::by_type::by_type ()
: type (empty)
{}
inline
]b4_parser_class_name[::by_type::by_type (const by_type& other)
: type (other.type)
{}
inline
]b4_parser_class_name[::by_type::by_type (token_type t)
: type (yytranslate_ (t))
{}
inline
void
]b4_parser_class_name[::by_type::move (by_type& that)
{
type = that.type;
that.type = empty;
}
inline
int
]b4_parser_class_name[::by_type::type_get () const
{
return type;
}
]b4_token_ctor_if([[
inline
]b4_parser_class_name[::token_type
]b4_parser_class_name[::by_type::token () const
{
// YYTOKNUM[NUM] -- (External) token number corresponding to the
// (internal) symbol number NUM (which must be that of a token). */
static
const ]b4_int_type_for([b4_toknum])[
yytoken_number_[] =
{
]b4_toknum[
};
return static_cast<token_type> (yytoken_number_[type]);
}
]])[]dnl
b4_symbol_constructor_define])
# b4_symbol_constructor_declare
# b4_symbol_constructor_define
# -----------------------------
# Declare/define symbol constructors for all the value types.
# Use at class-level. Redefined in variant.hh.
m4_define([b4_symbol_constructor_declare], [])
m4_define([b4_symbol_constructor_define], [])
# b4_yytranslate_define
# ---------------------
# Define yytranslate_. Sometimes used in the header file,
# sometimes in the cc file.
m4_define([b4_yytranslate_define],
[[ // Symbol number corresponding to token number t.
inline
]b4_parser_class_name[::token_number_type
]b4_parser_class_name[::yytranslate_ (]b4_token_ctor_if([token_type],
[int])[ t)
{
static
const token_number_type
translate_table[] =
{
]b4_translate[
};
const unsigned int user_token_number_max_ = ]b4_user_token_number_max[;
const token_number_type undef_token_ = ]b4_undef_token_number[;
if (static_cast<int>(t) <= yyeof_)
return yyeof_;
else if (static_cast<unsigned int> (t) <= user_token_number_max_)
return translate_table[t];
else
return undef_token_;
}
]])
# b4_lhs_value([TYPE])
# --------------------
# Expansion of $<TYPE>$.
m4_define([b4_lhs_value],
[b4_symbol_value([yyval], [$1])])
[(yyval[]m4_ifval([$1], [.$1]))])
# b4_rhs_value(RULE-LENGTH, NUM, [TYPE])
@@ -432,8 +116,7 @@ m4_define([b4_lhs_value],
# Expansion of $<TYPE>NUM, where the current rule has RULE-LENGTH
# symbols on RHS.
m4_define([b4_rhs_value],
[b4_symbol_value([yysemantic_stack_@{($1) - ($2)@}], [$3])])
[(yysemantic_stack_@{($1) - ($2)@}m4_ifval([$3], [.$3]))])
# b4_lhs_location()
# -----------------
@@ -470,27 +153,27 @@ m4_define([b4_parse_param_decl_1],
# Extra initialisations of the constructor.
m4_define([b4_parse_param_cons],
[m4_ifset([b4_parse_param],
[
[
b4_cc_constructor_calls(b4_parse_param)])])
m4_define([b4_cc_constructor_calls],
[m4_map_sep([b4_cc_constructor_call], [,
[m4_map_sep([b4_cc_constructor_call], [,
], [$@])])
m4_define([b4_cc_constructor_call],
[$2 ($2_yyarg)])
[$2 ($2_yyarg)])
# b4_parse_param_vars
# -------------------
# Extra instance variables.
m4_define([b4_parse_param_vars],
[m4_ifset([b4_parse_param],
[
// User arguments.
[
/* User arguments. */
b4_cc_var_decls(b4_parse_param)])])
m4_define([b4_cc_var_decls],
[m4_map_sep([b4_cc_var_decl], [
[m4_map_sep([b4_cc_var_decl], [
], [$@])])
m4_define([b4_cc_var_decl],
[ $1;])
[ $1;])
## ---------##
+4 -25
View File
@@ -17,37 +17,16 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# b4_comment_(TEXT, OPEN, CONTINUE, END)
# --------------------------------------
# Put TEXT in comment. Avoid trailing spaces: don't indent empty lines.
# Avoid adding indentation to the first line, as the indentation comes
# from OPEN. That's why we don't patsubst([$1], [^\(.\)], [ \1]).
#
# Prefix all the output lines with PREFIX.
m4_define([b4_comment_],
[$2[]m4_bpatsubst(m4_expand([[$1]]), [
\(.\)], [
$3\1])$4])
# b4_comment(TEXT, [PREFIX])
# --------------------------
# Put TEXT in comment. Prefix all the output lines with PREFIX.
m4_define([b4_comment],
[b4_comment_([$1], [$2/* ], [$2 ], [ */])])
# b4_dollar_dollar_(VALUE, FIELD, DEFAULT-FIELD)
# ----------------------------------------------
# If FIELD (or DEFAULT-FIELD) is non-null, return "VALUE.FIELD",
# otherwise just VALUE. Be sure to pass "(VALUE)" is VALUE is a
# pointer.
m4_define([b4_dollar_dollar_],
[b4_symbol_value([$1],
m4_if([$2], [[]],
[[$3]], [[$2]]))])
[m4_if([$2], [[]],
[m4_ifval([$3], [($1.$3)],
[$1])],
[($1.$2)])])
# b4_dollar_pushdef(VALUE-POINTER, DEFAULT-FIELD, LOCATION)
# b4_dollar_popdef
+274 -213
View File
@@ -51,6 +51,12 @@ m4_define([b4_cpp_guard_close],
## Identification. ##
## ---------------- ##
# b4_comment(TEXT)
# ----------------
m4_define([b4_comment], [/* m4_bpatsubst([$1], [
], [
]) */])
# b4_identification
# -----------------
# Depends on individual skeletons to define b4_pure_flag, b4_push_flag, or
@@ -104,27 +110,10 @@ m4_define_default([b4_union_name], [b4_api_PREFIX[]STYPE])
## Pure/impure interfaces. ##
## ------------------------ ##
# b4_lex_formals
# --------------
# All the yylex formal arguments.
# b4_lex_param arrives quoted twice, but we want to keep only one level.
m4_define([b4_lex_formals],
[b4_pure_if([[[[YYSTYPE *yylvalp]], [[&yylval]]][]dnl
b4_locations_if([, [[YYLTYPE *yyllocp], [&yylloc]]])])dnl
m4_ifdef([b4_lex_param], [, ]b4_lex_param)])
# b4_lex
# ------
# Call yylex.
m4_define([b4_lex],
[b4_function_call([yylex], [int], b4_lex_formals)])
# b4_user_args
# ------------
m4_define([b4_user_args],
[m4_ifset([b4_parse_param], [, b4_args(b4_parse_param)])])
[m4_ifset([b4_parse_param], [, b4_c_args(b4_parse_param)])])
# b4_parse_param
@@ -148,13 +137,11 @@ m4_popdef([$2])dnl
m4_popdef([$1])dnl
])])
# b4_parse_param_use([VAL], [LOC])
# --------------------------------
# `YYUSE' VAL, LOC if locations are enabled, and all the parse-params.
# b4_parse_param_use
# ------------------
# `YYUSE' 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
b4_parse_param_for([Decl], [Formal], [ YYUSE (Formal);
[b4_parse_param_for([Decl], [Formal], [ YYUSE (Formal);
])dnl
])
@@ -191,17 +178,38 @@ m4_define([b4_int_type_for],
# --------------------------------------------
# Without inducing a comparison warning from the compiler, check if the
# literal value LITERAL equals VALUE from table TABLE, which must have
# TABLE_min and TABLE_max defined.
# TABLE_min and TABLE_max defined. YYID must be defined as an identity
# function that suppresses warnings about constant conditions.
m4_define([b4_table_value_equals],
[m4_if(m4_eval($3 < m4_indir([b4_]$1[_min])
|| m4_indir([b4_]$1[_max]) < $3), [1],
[[0]],
[[YYID (0)]],
[(!!(($2) == ($3)))])])
## ---------##
## Values. ##
## ---------##
## ----------------- ##
## Compiler issues. ##
## ----------------- ##
# b4_attribute_define
# -------------------
# Provide portability for __attribute__.
m4_define([b4_attribute_define],
[#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
/* Suppress unused-variable warnings by "using" E. */
#if ! defined lint || defined __GNUC__
# define YYUSE(E) ((void) (E))
#else
# define YYUSE(E) /* empty */
#endif
])
# b4_null_define
@@ -224,148 +232,191 @@ m4_define([b4_null_define],
# Return a null pointer constant.
m4_define([b4_null], [YY_NULL])
# b4_integral_parser_table_define(TABLE-NAME, CONTENT, COMMENT)
# -------------------------------------------------------------
# Define "yy<TABLE-NAME>" whose contents is CONTENT.
m4_define([b4_integral_parser_table_define],
[m4_ifvaln([$3], [b4_comment([$3], [ ])])dnl
static const b4_int_type_for([$2]) yy$1[[]] =
{
$2
};dnl
])
## ------------------------- ##
## Assigning token numbers. ##
## ------------------------- ##
# b4_token_define(TOKEN-NUM)
# --------------------------
# b4_token_define(TOKEN-NAME, TOKEN-NUMBER)
# -----------------------------------------
# Output the definition of this token as #define.
m4_define([b4_token_define],
[b4_token_format([#define %s %s], [$1])])
[#define $1 $2
])
# b4_token_defines
# ----------------
# Output the definition of the tokens.
# b4_token_defines(LIST-OF-PAIRS-TOKEN-NAME-TOKEN-NUMBER)
# -------------------------------------------------------
# Output the definition of the tokens (if there are) as #defines.
m4_define([b4_token_defines],
[b4_any_token_visible_if([/* Tokens. */
m4_join([
], b4_symbol_map([b4_token_define]))
])])
[m4_if([$#$1], [1], [],
[/* Tokens. */
m4_map([b4_token_define], [$@])])
])
# b4_token_enum(TOKEN-NUM)
# ------------------------
# b4_token_enum(TOKEN-NAME, TOKEN-NUMBER)
# ---------------------------------------
# Output the definition of this token as an enum.
m4_define([b4_token_enum],
[b4_token_format([%s = %s], [$1])])
[$1 = $2])
# b4_token_enums
# --------------
# b4_token_enums(LIST-OF-PAIRS-TOKEN-NAME-TOKEN-NUMBER)
# -----------------------------------------------------
# Output the definition of the tokens (if there are) as enums.
m4_define([b4_token_enums],
[b4_any_token_visible_if([[/* Token type. */
[m4_if([$#$1], [1], [],
[[/* Tokens. */
#ifndef ]b4_api_PREFIX[TOKENTYPE
# define ]b4_api_PREFIX[TOKENTYPE
enum ]b4_api_prefix[tokentype
{
]m4_join([,
],
b4_symbol_map([b4_token_enum]))[
};
/* Put the tokens into the symbol table, so that GDB and other debuggers
know about them. */
enum ]b4_api_prefix[tokentype {
]m4_map_sep([ b4_token_enum], [,
],
[$@])[
};
#endif
]])])
# b4_token_enums_defines
# ----------------------
# Output the definition of the tokens (if there are any) as enums and,
# if POSIX Yacc is enabled, as #defines.
# b4_token_enums_defines(LIST-OF-PAIRS-TOKEN-NAME-TOKEN-NUMBER)
# -------------------------------------------------------------
# Output the definition of the tokens (if there are any) as enums and, if POSIX
# Yacc is enabled, as #defines.
m4_define([b4_token_enums_defines],
[b4_token_enums[]b4_yacc_if([b4_token_defines])])
## ----------------- ##
## Semantic Values. ##
## ----------------- ##
# b4_symbol_value(VAL, [TYPE])
# ----------------------------
# Given a semantic value VAL ($$, $1 etc.), extract its value of type
# TYPE if TYPE is given, otherwise just return VAL. The result can be
# used safetly, it is put in parens to avoid nasty precedence issues.
# TYPE is *not* put in braces, provide some if needed.
m4_define([b4_symbol_value],
[($1[]m4_ifval([$2], [.$2]))])
## ---------------------- ##
## Defining C functions. ##
## ---------------------- ##
# b4_function_define(NAME, RETURN-VALUE, [DECL1, NAME1], ...)
# -----------------------------------------------------------
# Declare the function NAME in C.
m4_define([b4_function_define],
[$2
$1 (b4_formals(m4_shift2($@)))[]dnl
[b4_token_enums($@)b4_yacc_if([b4_token_defines($@)], [])
])
# b4_formals([DECL1, NAME1], ...)
# -------------------------------
# The formal arguments of a C function definition.
m4_define([b4_formals],
## --------------------------------------------- ##
## Defining C functions in both K&R and ANSI-C. ##
## --------------------------------------------- ##
# b4_modern_c
# -----------
# A predicate useful in #if to determine whether C is ancient or modern.
#
# If __STDC__ is defined, the compiler is modern. IBM xlc 7.0 when run
# as 'cc' doesn't define __STDC__ (or __STDC_VERSION__) for pedantic
# reasons, but it defines __C99__FUNC__ so check that as well.
# Microsoft C normally doesn't define these macros, but it defines _MSC_VER.
# Consider a C++ compiler to be modern if it defines __cplusplus.
#
m4_define([b4_c_modern],
[[(defined __STDC__ || defined __C99__FUNC__ \
|| defined __cplusplus || defined _MSC_VER)]])
# b4_c_function_def(NAME, RETURN-VALUE, [DECL1, NAME1], ...)
# ----------------------------------------------------------
# Declare the function NAME.
m4_define([b4_c_function_def],
[#if b4_c_modern
b4_c_ansi_function_def($@)
#else
$2
$1 (b4_c_knr_formal_names(m4_shift2($@)))
b4_c_knr_formal_decls(m4_shift2($@))
#endif[]dnl
])
# b4_c_ansi_function_def(NAME, RETURN-VALUE, [DECL1, NAME1], ...)
# ---------------------------------------------------------------
# Declare the function NAME in ANSI.
m4_define([b4_c_ansi_function_def],
[$2
$1 (b4_c_ansi_formals(m4_shift2($@)))[]dnl
])
# b4_c_ansi_formals([DECL1, NAME1], ...)
# --------------------------------------
# Output the arguments ANSI-C definition.
m4_define([b4_c_ansi_formals],
[m4_if([$#], [0], [void],
[$#$1], [1], [void],
[m4_map_sep([b4_formal], [, ], [$@])])])
[m4_map_sep([b4_c_ansi_formal], [, ], [$@])])])
m4_define([b4_formal],
m4_define([b4_c_ansi_formal],
[$1])
# b4_c_knr_formal_names([DECL1, NAME1], ...)
# ------------------------------------------
# Output the argument names.
m4_define([b4_c_knr_formal_names],
[m4_map_sep([b4_c_knr_formal_name], [, ], [$@])])
## ----------------------- ##
## Declaring C functions. ##
## ----------------------- ##
m4_define([b4_c_knr_formal_name],
[$2])
# b4_function_declare(NAME, RETURN-VALUE, [DECL1, NAME1], ...)
# ------------------------------------------------------------
# Declare the function NAME.
m4_define([b4_function_declare],
[$2 $1 (b4_formals(m4_shift2($@)));[]dnl
# b4_c_knr_formal_decls([DECL1, NAME1], ...)
# ------------------------------------------
# Output the K&R argument declarations.
m4_define([b4_c_knr_formal_decls],
[m4_map_sep([b4_c_knr_formal_decl],
[
],
[$@])])
m4_define([b4_c_knr_formal_decl],
[ $1;])
## ------------------------------------------------------------ ##
## Declaring (prototyping) C functions in both K&R and ANSI-C. ##
## ------------------------------------------------------------ ##
# b4_c_ansi_function_decl(NAME, RETURN-VALUE, [DECL1, NAME1], ...)
# ----------------------------------------------------------------
# Declare the function NAME ANSI C style.
m4_define([b4_c_ansi_function_decl],
[$2 $1 (b4_c_ansi_formals(m4_shift2($@)));[]dnl
])
# b4_c_function_decl(NAME, RETURN-VALUE, [DECL1, NAME1], ...)
# -----------------------------------------------------------
# Declare the function NAME in both K&R and ANSI C.
m4_define([b4_c_function_decl],
[#if defined __STDC__ || defined __cplusplus
b4_c_ansi_function_decl($@)
#else
$2 $1 ();
#endif[]dnl
])
## --------------------- ##
## Calling C functions. ##
## --------------------- ##
# b4_function_call(NAME, RETURN-VALUE, [DECL1, NAME1], ...)
# b4_c_function_call(NAME, RETURN-VALUE, [DECL1, NAME1], ...)
# -----------------------------------------------------------
# Call the function NAME with arguments NAME1, NAME2 etc.
m4_define([b4_function_call],
[$1 (b4_args(m4_shift2($@)))[]dnl
m4_define([b4_c_function_call],
[$1 (b4_c_args(m4_shift2($@)))[]dnl
])
# b4_args([DECL1, NAME1], ...)
# ----------------------------
# b4_c_args([DECL1, NAME1], ...)
# ------------------------------
# Output the arguments NAME1, NAME2...
m4_define([b4_args],
[m4_map_sep([b4_arg], [, ], [$@])])
m4_define([b4_c_args],
[m4_map_sep([b4_c_arg], [, ], [$@])])
m4_define([b4_arg],
m4_define([b4_c_arg],
[$2])
@@ -387,28 +438,53 @@ m4_define([b4_sync_start], [[#]line $1 $2])
m4_define([b4_case],
[ case $1:
$2
b4_syncline([@oline@], [@ofile@])
break;])
# b4_predicate_case(LABEL, CONDITIONS)
# ------------------------------------
m4_define([b4_predicate_case],
[ case $1:
if (! ($2)) YYERROR;
# _b4_symbol_actions(FILENAME, LINENO,
# SYMBOL-TAG, SYMBOL-NUM,
# SYMBOL-ACTION, SYMBOL-TYPENAME)
# --------------------------------------------------
# Issue the code for a symbol action (e.g., %printer).
#
# Define b4_dollar_dollar([TYPE-NAME]), and b4_at_dollar, which are
# invoked where $<TYPE-NAME>$ and @$ were specified by the user.
m4_define([_b4_symbol_actions],
[b4_dollar_pushdef([(*yyvaluep)], [$6], [(*yylocationp)])dnl
case $4: /* $3 */
b4_syncline([$2], [$1])
$5;
b4_syncline([@oline@], [@ofile@])
break;])
break;
b4_dollar_popdef[]dnl
])
# b4_symbol_actions(KIND)
# -----------------------
# Emit the symbol actions for KIND ("printers" or "destructors").
# Dispatch on "yytype".
m4_define([b4_symbol_actions],
[m4_ifval(m4_defn([b4_symbol_$1]),
[[switch (yytype)
{
]m4_map([_b4_symbol_actions], m4_defn([b4_symbol_$1]))[
default:
break;
}]],
[YYUSE (yytype);])])
# b4_yydestruct_define
# --------------------
# Define the "yydestruct" function.
m4_define_default([b4_yydestruct_define],
# b4_yydestruct_generate(FUNCTION-DECLARATOR)
# -------------------------------------------
# Generate the "yydestruct" function, which declaration is issued using
# FUNCTION-DECLARATOR, which may be "b4_c_ansi_function_def" for ISO C
# or "b4_c_function_def" for K&R.
m4_define_default([b4_yydestruct_generate],
[[/*-----------------------------------------------.
| Release the memory associated to this symbol. |
`-----------------------------------------------*/
]b4_function_define([yydestruct],
/*ARGSUSED*/
]$1([yydestruct],
[static void],
[[const char *yymsg], [yymsg]],
[[int yytype], [yytype]],
@@ -416,31 +492,33 @@ m4_define_default([b4_yydestruct_define],
b4_locations_if( [, [[YYLTYPE *yylocationp], [yylocationp]]])[]dnl
m4_ifset([b4_parse_param], [, b4_parse_param]))[
{
]b4_parse_param_use([yyvaluep], [yylocationp])dnl
[ if (!yymsg)
YYUSE (yyvaluep);
]b4_locations_if([ YYUSE (yylocationp);
])dnl
b4_parse_param_use[]dnl
[
if (!yymsg)
yymsg = "Deleting";
YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
switch (yytype)
{
]b4_symbol_foreach([b4_symbol_destructor])dnl
[ default:
break;
}
]b4_symbol_actions([destructors])[
}]dnl
])
# b4_yy_symbol_print_define
# -------------------------
# Define the "yy_symbol_print" function.
m4_define_default([b4_yy_symbol_print_define],
# b4_yy_symbol_print_generate(FUNCTION-DECLARATOR)
# ------------------------------------------------
# Generate the "yy_symbol_print" function, which declaration is issued using
# FUNCTION-DECLARATOR, which may be "b4_c_ansi_function_def" for ISO C
# or "b4_c_function_def" for K&R.
m4_define_default([b4_yy_symbol_print_generate],
[[
/*--------------------------------.
| Print this symbol on YYOUTPUT. |
`--------------------------------*/
]b4_function_define([yy_symbol_value_print],
/*ARGSUSED*/
]$1([yy_symbol_value_print],
[static void],
[[FILE *yyoutput], [yyoutput]],
[[int yytype], [yytype]],
@@ -449,22 +527,19 @@ b4_locations_if([, [[YYLTYPE const * const yylocationp], [yylocationp]]])[]dnl
m4_ifset([b4_parse_param], [, b4_parse_param]))[
{
FILE *yyo = yyoutput;
]b4_parse_param_use([yyo], [yylocationp])dnl
[ if (!yyvaluep)
return;]
dnl glr.c does not feature yytoknum.
m4_if(b4_skeleton, ["yacc.c"],
[[# ifdef YYPRINT
YYUSE (yyo);
if (!yyvaluep)
return;
]b4_locations_if([ YYUSE (yylocationp);
])dnl
b4_parse_param_use[]dnl
[# ifdef YYPRINT
if (yytype < YYNTOKENS)
YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
# else
YYUSE (yyoutput);
# endif
]])dnl
[ switch (yytype)
{
]b4_symbol_foreach([b4_symbol_printer])dnl
[ default:
break;
}
]b4_symbol_actions([printers])[
}
@@ -472,7 +547,7 @@ m4_if(b4_skeleton, ["yacc.c"],
| Print this symbol on YYOUTPUT. |
`--------------------------------*/
]b4_function_define([yy_symbol_print],
]$1([yy_symbol_print],
[static void],
[[FILE *yyoutput], [yyoutput]],
[[int yytype], [yytype]],
@@ -480,8 +555,10 @@ m4_if(b4_skeleton, ["yacc.c"],
b4_locations_if([, [[YYLTYPE const * const yylocationp], [yylocationp]]])[]dnl
m4_ifset([b4_parse_param], [, b4_parse_param]))[
{
YYFPRINTF (yyoutput, "%s %s (",
yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]);
if (yytype < YYNTOKENS)
YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
else
YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
]b4_locations_if([ YY_LOCATION_PRINT (yyoutput, *yylocationp);
YYFPRINTF (yyoutput, ": ");
@@ -496,75 +573,59 @@ b4_locations_if([, yylocationp])[]b4_user_args[);
## 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]])])[
# define ]b4_api_PREFIX[STYPE_IS_DECLARED 1
#endif
]])
# b4_location_type_define
# -----------------------
m4_define([b4_location_type_define],
[[/* Location type. */
#if ! defined ]b4_api_PREFIX[LTYPE && ! defined ]b4_api_PREFIX[LTYPE_IS_DECLARED
typedef struct ]b4_api_PREFIX[LTYPE ]b4_api_PREFIX[LTYPE;
struct ]b4_api_PREFIX[LTYPE
{
int first_line;
int first_column;
int last_line;
int last_column;
};
# define ]b4_api_PREFIX[LTYPE_IS_DECLARED 1
# define ]b4_api_PREFIX[LTYPE_IS_TRIVIAL 1
#endif
]])
# b4_declare_yylstype
# -------------------
# Declarations that might either go into the header (if --defines) or
# in the parser body. Declare YYSTYPE/YYLTYPE, and yylval/yylloc.
m4_define([b4_declare_yylstype],
[b4_value_type_define[]b4_locations_if([
b4_location_type_define])
[[#if ! defined ]b4_api_PREFIX[STYPE && ! defined ]b4_api_PREFIX[STYPE_IS_DECLARED
]m4_ifdef([b4_stype],
[[typedef union ]b4_union_name[
{
]b4_user_stype[
} ]b4_api_PREFIX[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]])])[
# define ]b4_api_prefix[stype ]b4_api_PREFIX[STYPE /* obsolescent; will be withdrawn */
# define ]b4_api_PREFIX[STYPE_IS_DECLARED 1
#endif]b4_locations_if([[
#if ! defined ]b4_api_PREFIX[LTYPE && ! defined ]b4_api_PREFIX[LTYPE_IS_DECLARED
typedef struct ]b4_api_PREFIX[LTYPE
{
int first_line;
int first_column;
int last_line;
int last_column;
} ]b4_api_PREFIX[LTYPE;
# define ]b4_api_prefix[ltype ]b4_api_PREFIX[LTYPE /* obsolescent; will be withdrawn */
# define ]b4_api_PREFIX[LTYPE_IS_DECLARED 1
# define ]b4_api_PREFIX[LTYPE_IS_TRIVIAL 1
#endif]])
b4_pure_if([], [[extern ]b4_api_PREFIX[STYPE ]b4_prefix[lval;
]b4_locations_if([[extern ]b4_api_PREFIX[LTYPE ]b4_prefix[lloc;]])])[]dnl
])
# b4_YYDEBUG_define
# ------------------
m4_define([b4_YYDEBUG_define],
[[/* Debug traces. */
[[/* Enabling traces. */
]m4_if(b4_api_prefix, [yy],
[[#ifndef YYDEBUG
# define YYDEBUG ]b4_parse_trace_if([1], [0])[
# define YYDEBUG ]b4_debug_flag[
#endif]],
[[#ifndef ]b4_api_PREFIX[DEBUG
# if defined YYDEBUG
#if YYDEBUG
# if YYDEBUG
# define ]b4_api_PREFIX[DEBUG 1
# else
# define ]b4_api_PREFIX[DEBUG 0
# endif
# else /* ! defined YYDEBUG */
# define ]b4_api_PREFIX[DEBUG ]b4_parse_trace_if([1], [0])[
# define ]b4_api_PREFIX[DEBUG ]b4_debug_flag[
# endif /* ! defined YYDEBUG */
#endif /* ! defined ]b4_api_PREFIX[DEBUG */]])[]dnl
])
@@ -589,7 +650,7 @@ m4_define([b4_yylloc_default_define],
#ifndef YYLLOC_DEFAULT
# define YYLLOC_DEFAULT(Current, Rhs, N) \
do \
if (N) \
if (YYID (N)) \
{ \
(Current).first_line = YYRHSLOC (Rhs, 1).first_line; \
(Current).first_column = YYRHSLOC (Rhs, 1).first_column; \
@@ -603,7 +664,7 @@ m4_define([b4_yylloc_default_define],
(Current).first_column = (Current).last_column = \
YYRHSLOC (Rhs, 0).last_column; \
} \
while (0)
while (YYID (0))
#endif
]])
@@ -622,7 +683,7 @@ m4_define([b4_yy_location_print_define],
/* Print *YYLOCP on YYO. Private, do not rely on its existence. */
__attribute__((__unused__))
]b4_function_define([yy_location_print_],
]b4_c_function_def([yy_location_print_],
[static unsigned],
[[FILE *yyo], [yyo]],
[[YYLTYPE const * const yylocp], [yylocp]])[
@@ -631,20 +692,20 @@ __attribute__((__unused__))
int end_col = 0 != yylocp->last_column ? yylocp->last_column - 1 : 0;
if (0 <= yylocp->first_line)
{
res += YYFPRINTF (yyo, "%d", yylocp->first_line);
res += fprintf (yyo, "%d", yylocp->first_line);
if (0 <= yylocp->first_column)
res += YYFPRINTF (yyo, ".%d", yylocp->first_column);
res += fprintf (yyo, ".%d", yylocp->first_column);
}
if (0 <= yylocp->last_line)
{
if (yylocp->first_line < yylocp->last_line)
{
res += YYFPRINTF (yyo, "-%d", yylocp->last_line);
res += fprintf (yyo, "-%d", yylocp->last_line);
if (0 <= end_col)
res += YYFPRINTF (yyo, ".%d", end_col);
res += fprintf (yyo, ".%d", end_col);
}
else if (0 <= end_col && yylocp->first_column < end_col)
res += YYFPRINTF (yyo, "-%d", end_col);
res += fprintf (yyo, "-%d", end_col);
}
return res;
}
+291 -299
View File
File diff suppressed because it is too large Load Diff
+109 -123
View File
@@ -1,3 +1,5 @@
-*- C -*-
# C++ GLR skeleton for Bison
# Copyright (C) 2002-2013 Free Software Foundation, Inc.
@@ -27,7 +29,7 @@
#
# The additional arguments are stored as members of the parser
# object, yyparser. The C routines need to carry yyparser
# throughout the C parser; that's easy: make yyparser an
# throughout the C parser; that easy: just let yyparser become an
# additional parse-param. But because the C++ skeleton needs to
# know the "real" original parse-param, we save them
# (b4_parse_param_orig). Note that b4_parse_param is overquoted
@@ -37,23 +39,23 @@
# The locations
#
# We use location.cc just like lalr1.cc, but because glr.c stores
# the locations in a union, the position and location classes
# the locations in a (C++) union, the position and location classes
# must not have a constructor. Therefore, contrary to lalr1.cc, we
# must not define "b4_location_constructors". As a consequence the
# 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.
# We require a pure interface using locations.
m4_define([b4_locations_flag], [1])
m4_define([b4_pure_flag], [1])
# The header is mandatory.
b4_defines_if([],
[b4_fatal([b4_skeleton[: using %%defines is mandatory]])])
m4_include(b4_pkgdatadir/[c++.m4])
b4_bison_locations_if([m4_include(b4_pkgdatadir/[location.cc])])
b4_percent_define_ifdef([[api.location.type]], [],
[m4_include(b4_pkgdatadir/[location.cc])])
m4_define([b4_parser_class_name],
[b4_percent_define_get([[parser_class_name]])])
@@ -61,37 +63,25 @@ m4_define([b4_parser_class_name],
# Save the parse parameters.
m4_define([b4_parse_param_orig], m4_defn([b4_parse_param]))
# b4_parse_param_wrap
# -------------------
# New ones.
m4_ifset([b4_parse_param],
[m4_define([b4_parse_param_wrap],
[[b4_namespace_ref::b4_parser_class_name[& yyparser], [[yyparser]]],]
m4_defn([b4_parse_param]))],
[m4_define([b4_parse_param_wrap],
[[b4_namespace_ref::b4_parser_class_name[& yyparser], [[yyparser]]]])
])
# b4_yy_symbol_print_define
# -------------------------
# b4_yy_symbol_print_generate
# ---------------------------
# Bypass the default implementation to generate the "yy_symbol_print"
# and "yy_symbol_value_print" functions.
m4_define([b4_yy_symbol_print_define],
m4_define([b4_yy_symbol_print_generate],
[[
/*--------------------.
| Print this symbol. |
`--------------------*/
]b4_function_define([yy_symbol_print],
]b4_c_ansi_function_def([yy_symbol_print],
[static void],
[[FILE *], []],
[[int yytype], [yytype]],
[[FILE *], []],
[[int yytype], [yytype]],
[[const ]b4_namespace_ref::b4_parser_class_name[::semantic_type *yyvaluep],
[yyvaluep]][]dnl
b4_locations_if([,
[yyvaluep]],
[[const ]b4_namespace_ref::b4_parser_class_name[::location_type *yylocationp],
[yylocationp]]]),
[yylocationp]],
b4_parse_param)[
{
]b4_parse_param_use[]dnl
@@ -100,9 +90,10 @@ b4_locations_if([,
]])[
# Hijack the initial action to initialize the locations.
]b4_bison_locations_if([m4_define([b4_initial_action],
]b4_locations_if([b4_percent_define_ifdef([[api.location.type]], [],
[m4_define([b4_initial_action],
[yylloc.initialize ();]m4_ifdef([b4_initial_action], [
m4_defn([b4_initial_action])]))])[
m4_defn([b4_initial_action])]))])])[
# Hijack the post prologue to insert early definition of YYLLOC_DEFAULT
# and declaration of yyerror.
@@ -110,60 +101,43 @@ m4_defn([b4_initial_action])]))])[
[b4_syncline([@oline@], [@ofile@])[
]b4_yylloc_default_define[
#define YYRHSLOC(Rhs, K) ((Rhs)[K].yystate.yyloc)
]b4_function_declare([yyerror],
[static void],b4_locations_if([
]b4_c_ansi_function_decl([yyerror],
[static void],
[[const ]b4_namespace_ref::b4_parser_class_name[::location_type *yylocationp],
[yylocationp]],])
[yylocationp]],
b4_parse_param,
[[const char* msg], [msg]])])
#undef yynerrs
#undef yychar
#undef yylval]b4_locations_if([
#undef yylloc])
m4_if(b4_prefix, [yy], [],
[[/* Substitute the variable and function names. */
#define yyparse ]b4_prefix[parse
#define yylex ]b4_prefix[lex
#define yyerror ]b4_prefix[error
#define yydebug ]b4_prefix[debug
]]b4_pure_if([], [[
#define yylval ]b4_prefix[lval
#define yychar ]b4_prefix[char
#define yynerrs ]b4_prefix[nerrs]b4_locations_if([[
#define yylloc ]b4_prefix[lloc]])]))
# Hijack the epilogue to define implementations (yyerror, parser member
# functions etc.).
m4_append([b4_epilogue],
[b4_syncline([@oline@], [@ofile@])[
/*------------------.
| Report an error. |
`------------------*/
]b4_function_define([yyerror],
[static void],b4_locations_if([
]b4_c_ansi_function_def([yyerror],
[static void],
[[const ]b4_namespace_ref::b4_parser_class_name[::location_type *yylocationp],
[yylocationp]],])
[yylocationp]],
b4_parse_param,
[[const char* msg], [msg]])[
{
]b4_parse_param_use[]dnl
[ yyparser.error (]b4_locations_if([[*yylocationp, ]])[msg);
[ yyparser.error (*yylocationp, msg);
}
]b4_namespace_open[
]dnl In this section, the parse params are the original parse_params.
]dnl In this section, the parse param are the original parse_params.
m4_pushdef([b4_parse_param], m4_defn([b4_parse_param_orig]))dnl
[ /// Build a parser object.
]b4_parser_class_name::b4_parser_class_name[ (]b4_parse_param_decl[)]m4_ifset([b4_parse_param], [
:])[
#if ]b4_api_PREFIX[DEBUG
]m4_ifset([b4_parse_param], [ ], [ :])[yycdebug_ (&std::cerr)]m4_ifset([b4_parse_param], [,])[
]m4_ifset([b4_parse_param], [ ], [ :])[
yycdebug_ (&std::cerr)]m4_ifset([b4_parse_param], [,])[
#endif]b4_parse_param_cons[
{
}
@@ -185,32 +159,27 @@ m4_pushdef([b4_parse_param], m4_defn([b4_parse_param_orig]))dnl
inline void
]b4_parser_class_name[::yy_symbol_value_print_ (int yytype,
const semantic_type* yyvaluep]b4_locations_if([[,
const location_type* yylocationp]])[)
{]b4_locations_if([[
YYUSE (yylocationp);]])[
const semantic_type* yyvaluep,
const location_type* yylocationp)
{
YYUSE (yylocationp);
YYUSE (yyvaluep);
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([printers])[
}
void
]b4_parser_class_name[::yy_symbol_print_ (int yytype,
const semantic_type* yyvaluep]b4_locations_if([[,
const location_type* yylocationp]])[)
const semantic_type* yyvaluep,
const location_type* yylocationp)
{
*yycdebug_ << (yytype < YYNTOKENS ? "token" : "nterm")
<< ' ' << yytname[yytype] << " ("]b4_locations_if([[
<< *yylocationp << ": "]])[;
yy_symbol_value_print_ (yytype, yyvaluep]b4_locations_if([[, yylocationp]])[);
<< ' ' << yytname[yytype] << " ("
<< *yylocationp << ": ";
yy_symbol_value_print_ (yytype, yyvaluep, yylocationp);
*yycdebug_ << ')';
}
@@ -245,31 +214,63 @@ m4_pushdef([b4_parse_param], m4_defn([b4_parse_param_orig]))dnl
b4_namespace_close
])
# b4_shared_declarations
# ----------------------
# Declaration that might either go into the header (if --defines)
# or open coded in the parser body.
m4_define([b4_shared_declarations],
[m4_pushdef([b4_parse_param], m4_defn([b4_parse_param_orig]))dnl
b4_percent_code_get([[requires]])[
#include <stdexcept>
#include <string>
#include <iostream>]b4_defines_if([
b4_bison_locations_if([[#include "location.hh"]])])[
# Let glr.c believe that the user arguments include the parser itself.
m4_ifset([b4_parse_param],
[m4_pushdef([b4_parse_param],
[[b4_namespace_ref::b4_parser_class_name[& yyparser], [[yyparser]]],]
m4_defn([b4_parse_param]))],
[m4_pushdef([b4_parse_param],
[[b4_namespace_ref::b4_parser_class_name[& yyparser], [[yyparser]]]])
])
m4_include(b4_pkgdatadir/[glr.c])
m4_popdef([b4_parse_param])
b4_output_begin([b4_spec_defines_file])
b4_copyright([Skeleton interface for Bison GLR parsers in C++],
[2002-2006, 2009-2013])[
/* C++ GLR parser skeleton written by Akim Demaille. */
]b4_cpp_guard_open([b4_spec_defines_file])[
]b4_percent_code_get([[requires]])[
# include <string>
# include <iostream>
]b4_percent_define_ifdef([[api.location.type]], [],
[[# include "location.hh"]])[
]b4_YYDEBUG_define[
]b4_namespace_open[
]b4_defines_if([],
[b4_bison_locations_if([b4_position_define
b4_location_define])])[
/// A Bison parser.
class ]b4_parser_class_name[
{
public:
]b4_public_types_declare[
/// Symbol semantic values.
# ifndef ]b4_api_PREFIX[STYPE
]m4_ifdef([b4_stype],
[ union semantic_type
{
b4_user_stype
};],
[m4_if(b4_tag_seen_flag, 0,
[[ typedef int semantic_type;]],
[[ typedef ]b4_api_PREFIX[STYPE semantic_type;]])])[
# else
typedef ]b4_api_PREFIX[STYPE semantic_type;
# endif
/// Symbol locations.
typedef ]b4_percent_define_get([[api.location.type]],
[[location]])[ location_type;
/// Tokens.
struct token
{
]b4_token_enums(b4_tokens)[
};
/// Token type.
typedef token::yytokentype token_type;
/// Build a parser object.
]b4_parser_class_name[ (]b4_parse_param_decl[);
@@ -291,39 +292,42 @@ b4_location_define])])[
/// Set the current debugging level.
void set_debug_level (debug_level_type l);
private:
public:
/// Report a syntax error.]b4_locations_if([[
/// \param loc where the syntax error is found.]])[
/// Report a syntax error.
/// \param loc where the syntax error is found.
/// \param msg a description of the syntax error.
virtual void error (]b4_locations_if([[const location_type& loc, ]])[const std::string& msg);
virtual void error (const location_type& loc, const std::string& msg);
private:
# if ]b4_api_PREFIX[DEBUG
public:
/// \brief Report a symbol value on the debug stream.
/// \param yytype The token type.
/// \param yyvaluep Its semantic value.]b4_locations_if([[
/// \param yylocationp Its location.]])[
/// \param yyvaluep Its semantic value.
/// \param yylocationp Its location.
virtual void yy_symbol_value_print_ (int yytype,
const semantic_type* yyvaluep]b4_locations_if([[,
const location_type* yylocationp]])[);
const semantic_type* yyvaluep,
const location_type* yylocationp);
/// \brief Report a symbol on the debug stream.
/// \param yytype The token type.
/// \param yyvaluep Its semantic value.]b4_locations_if([[
/// \param yylocationp Its location.]])[
/// \param yyvaluep Its semantic value.
/// \param yylocationp Its location.
virtual void yy_symbol_print_ (int yytype,
const semantic_type* yyvaluep]b4_locations_if([[,
const location_type* yylocationp]])[);
const semantic_type* yyvaluep,
const location_type* yylocationp);
private:
// Debugging.
/* Debugging. */
std::ostream* yycdebug_;
#endif
# endif
]b4_parse_param_vars[
};
]dnl Redirections for glr.c.
b4_percent_define_flag_if([[global_tokens_and_yystype]],
[b4_token_defines])
[b4_token_defines(b4_tokens)])
[
#ifndef ]b4_api_PREFIX[STYPE
# define ]b4_api_PREFIX[STYPE ]b4_namespace_ref[::]b4_parser_class_name[::semantic_type
@@ -334,23 +338,5 @@ b4_percent_define_flag_if([[global_tokens_and_yystype]],
]b4_namespace_close[
]b4_percent_code_get([[provides]])[
]m4_popdef([b4_parse_param])dnl
])
b4_defines_if(
[b4_output_begin([b4_spec_defines_file])
b4_copyright([Skeleton interface for Bison GLR parsers in C++],
[2002-2013])[
// C++ GLR parser skeleton written by Akim Demaille.
]b4_cpp_guard_open([b4_spec_defines_file])[
]b4_shared_declarations[
]b4_cpp_guard_close([b4_spec_defines_file])[
]b4_output_end()])
# Let glr.c (and b4_shared_declarations) believe that the user
# arguments include the parser itself.
m4_pushdef([b4_parse_param], m4_defn([b4_parse_param_wrap]))
m4_include(b4_pkgdatadir/[glr.c])
m4_popdef([b4_parse_param])
]b4_output_end()
+44 -66
View File
@@ -19,12 +19,18 @@
m4_include(b4_pkgdatadir/[c-like.m4])
# b4_comment(TEXT)
# ----------------
m4_define([b4_comment], [/* m4_bpatsubst([$1], [
], [
]) */])
# b4_list2(LIST1, LIST2)
# ----------------------
# --------------------------
# Join two lists with a comma if necessary.
m4_define([b4_list2],
[$1[]m4_ifval(m4_quote($1), [m4_ifval(m4_quote($2), [[, ]])])[]$2])
[$1[]m4_ifval(m4_quote($1), [m4_ifval(m4_quote($2), [[, ]])])[]$2])
# b4_percent_define_get3(DEF, PRE, POST, NOT)
@@ -32,8 +38,8 @@ m4_define([b4_list2],
# Expand to the value of DEF surrounded by PRE and POST if it's %define'ed,
# otherwise NOT.
m4_define([b4_percent_define_get3],
[m4_ifval(m4_quote(b4_percent_define_get([$1])),
[$2[]b4_percent_define_get([$1])[]$3], [$4])])
[m4_ifval(m4_quote(b4_percent_define_get([$1])),
[$2[]b4_percent_define_get([$1])[]$3], [$4])])
@@ -98,7 +104,7 @@ m4_define([b4_identification],
m4_define([b4_int_type],
[m4_if(b4_ints_in($@, [-128], [127]), [1], [byte],
b4_ints_in($@, [-32768], [32767]), [1], [short],
[int])])
[int])])
# b4_int_type_for(NAME)
# ---------------------
@@ -112,45 +118,27 @@ m4_define([b4_int_type_for],
m4_define([b4_null], [null])
# b4_typed_parser_table_define(TYPE, NAME, DATA, COMMENT)
# -------------------------------------------------------
m4_define([b4_typed_parser_table_define],
[m4_ifval([$4], [b4_comment([$4])
])dnl
[private static final ]$1[ yy$2_[] = yy$2_init();
private static final ]$1[[] yy$2_init()
{
return new ]$1[[]
{
]$3[
};
}]])
# b4_integral_parser_table_define(NAME, DATA, COMMENT)
#-----------------------------------------------------
m4_define([b4_integral_parser_table_define],
[b4_typed_parser_table_define([b4_int_type_for([$2])], [$1], [$2], [$3])])
## ------------------------- ##
## Assigning token numbers. ##
## ------------------------- ##
# b4_token_enum(TOKEN-NUM)
# ------------------------
# b4_token_enum(TOKEN-NAME, TOKEN-NUMBER)
# ---------------------------------------
# Output the definition of this token as an enum.
m4_define([b4_token_enum],
[b4_token_format([ /** Token number, to be returned by the scanner. */
static final int %s = %s;
], [$1])])
[ /** Token number, to be returned by the scanner. */
public static final int $1 = $2;
])
# b4_token_enums
# --------------
# b4_token_enums(LIST-OF-PAIRS-TOKEN-NAME-TOKEN-NUMBER)
# -----------------------------------------------------
# Output the definition of the tokens (if there are) as enums.
m4_define([b4_token_enums],
[b4_any_token_visible_if([/* Tokens. */
b4_symbol_foreach([b4_token_enum])])])
[m4_if([$#$1], [1], [],
[/* Tokens. */
m4_map([b4_token_enum], [$@])])
])
# b4-case(ID, CODE)
# -----------------
@@ -161,20 +149,13 @@ m4_define([b4_case], [ case $1:
break;
])
# b4_predicate_case(LABEL, CONDITIONS)
# ------------------------------------
m4_define([b4_predicate_case], [ case $1:
if (! ($2)) YYERROR;
break;
])
## ---------------- ##
## Default values. ##
## ---------------- ##
m4_define([b4_yystype], [b4_percent_define_get([[api.value.type]])])
b4_percent_define_default([[api.value.type]], [[Object]])
m4_define([b4_yystype], [b4_percent_define_get([[stype]])])
b4_percent_define_default([[stype]], [[Object]])
# %name-prefix
m4_define_default([b4_prefix], [[YY]])
@@ -188,9 +169,6 @@ m4_define([b4_lex_throws], [b4_percent_define_get([[lex_throws]])])
b4_percent_define_default([[throws]], [])
m4_define([b4_throws], [b4_percent_define_get([[throws]])])
b4_percent_define_default([[init_throws]], [])
m4_define([b4_init_throws], [b4_percent_define_get([[init_throws]])])
b4_percent_define_default([[api.location.type]], [Location])
m4_define([b4_location_type], [b4_percent_define_get([[api.location.type]])])
@@ -246,16 +224,16 @@ m4_define([b4_lex_param], b4_lex_param)
m4_define([b4_parse_param], b4_parse_param)
# b4_lex_param_decl
# -----------------
# -------------------
# Extra formal arguments of the constructor.
m4_define([b4_lex_param_decl],
[m4_ifset([b4_lex_param],
[b4_remove_comma([$1],
b4_param_decls(b4_lex_param))],
[$1])])
b4_param_decls(b4_lex_param))],
[$1])])
m4_define([b4_param_decls],
[m4_map([b4_param_decl], [$@])])
[m4_map([b4_param_decl], [$@])])
m4_define([b4_param_decl], [, $1])
m4_define([b4_remove_comma], [m4_ifval(m4_quote($1), [$1, ], [])m4_shift2($@)])
@@ -268,21 +246,21 @@ m4_define([b4_remove_comma], [m4_ifval(m4_quote($1), [$1, ], [])m4_shift2($@)])
m4_define([b4_parse_param_decl],
[m4_ifset([b4_parse_param],
[b4_remove_comma([$1],
b4_param_decls(b4_parse_param))],
[$1])])
b4_param_decls(b4_parse_param))],
[$1])])
# b4_lex_param_call
# -----------------
# -------------------
# Delegating the lexer parameters to the lexer constructor.
m4_define([b4_lex_param_call],
[m4_ifset([b4_lex_param],
[b4_remove_comma([$1],
b4_param_calls(b4_lex_param))],
[$1])])
[b4_remove_comma([$1],
b4_param_calls(b4_lex_param))],
[$1])])
m4_define([b4_param_calls],
[m4_map([b4_param_call], [$@])])
[m4_map([b4_param_call], [$@])])
m4_define([b4_param_call], [, $2])
@@ -292,13 +270,13 @@ m4_define([b4_param_call], [, $2])
# Extra initialisations of the constructor.
m4_define([b4_parse_param_cons],
[m4_ifset([b4_parse_param],
[b4_constructor_calls(b4_parse_param)])])
[b4_constructor_calls(b4_parse_param)])])
m4_define([b4_constructor_calls],
[m4_map([b4_constructor_call], [$@])])
[m4_map([b4_constructor_call], [$@])])
m4_define([b4_constructor_call],
[this.$2 = $2;
])
[this.$2 = $2;
])
@@ -307,15 +285,15 @@ m4_define([b4_constructor_call],
# Extra instance variables.
m4_define([b4_parse_param_vars],
[m4_ifset([b4_parse_param],
[
[
/* User arguments. */
b4_var_decls(b4_parse_param)])])
m4_define([b4_var_decls],
[m4_map_sep([b4_var_decl], [
[m4_map_sep([b4_var_decl], [
], [$@])])
m4_define([b4_var_decl],
[ protected final $1;])
[ protected final $1;])
@@ -323,4 +301,4 @@ m4_define([b4_var_decl],
# -----------------------
# Expand to either an empty string or "throws THROWS".
m4_define([b4_maybe_throws],
[m4_ifval($1, [throws $1])])
[m4_ifval($1, [throws $1])])
+593 -621
View File
File diff suppressed because it is too large Load Diff
+226 -175
View File
@@ -17,18 +17,10 @@
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.
b4_parse_trace_if([0], [0])
m4_define([b4_symbol_no_destructor_assert],
[b4_symbol_if([$1], [has_destructor],
[b4_fatal([%s: %s: %%destructor does not make sense in Java],
[b4_skeleton],
[b4_symbol_action_location([$1], [destructor])])])])
b4_symbol_foreach([b4_symbol_no_destructor_assert])
b4_defines_if([b4_fatal([%s: %%defines does not make sense in Java], [b4_skeleton])])
m4_ifval(m4_defn([b4_symbol_destructors]),
[b4_fatal([%s: %%destructor does not make sense in Java], [b4_skeleton])],
[])
b4_output_begin([b4_parser_file_name])
b4_copyright([Skeleton implementation for Bison LALR(1) parsers in Java],
@@ -36,16 +28,14 @@ b4_copyright([Skeleton implementation for Bison LALR(1) parsers in Java],
b4_percent_define_ifdef([package], [package b4_percent_define_get([package]);
])[/* First part of user declarations. */
]b4_user_pre_prologue
b4_user_post_prologue
]b4_pre_prologue
b4_percent_code_get([[imports]])
[/**
* A Bison parser, automatically generated from <tt>]m4_bpatsubst(b4_file_name, [^"\(.*\)"$], [\1])[</tt>.
*
* @@author LALR (1) parser skeleton written by Paolo Bonzini.
*/
]b4_percent_define_get3([annotations], [], [ ])dnl
b4_public_if([public ])dnl
]b4_public_if([public ])dnl
b4_abstract_if([abstract ])dnl
b4_final_if([final ])dnl
b4_strictfp_if([strictfp ])dnl
@@ -54,22 +44,9 @@ b4_percent_define_get3([extends], [ extends ])dnl
b4_percent_define_get3([implements], [ implements ])[
{
]b4_identification[
]b4_error_verbose_if([[
/** True if verbose error messages are enabled. */
private boolean yyErrorVerbose = true;
/**
* Return whether verbose error messages are enabled.
*/
public final boolean getErrorVerbose() { return yyErrorVerbose; }
/**
* Set the verbosity of error messages.
* @@param verbose True to request verbose error messages.
*/
public final void setErrorVerbose(boolean verbose)
{ yyErrorVerbose = verbose; }
]])
public boolean errorVerbose = ]b4_flag_value([error_verbose]);
b4_locations_if([[
/**
@@ -115,6 +92,11 @@ b4_locations_if([[
]])
[ /** Token returned by the scanner to signal the end of its input. */
public static final int EOF = 0;]
b4_token_enums(b4_tokens)
b4_locations_if([[
private ]b4_location_type[ yylloc (YYStack rhs, int n)
{
@@ -129,11 +111,6 @@ b4_locations_if([[
* parser <tt>]b4_parser_class_name[</tt>.
*/
public interface Lexer {
/** Token returned by the scanner to signal the end of its input. */
public static final int EOF = 0;
]b4_token_enums[
]b4_locations_if([[/**
* Method to retrieve the beginning position of the last scanned token.
* @@return the position at which the last scanned token starts. */
@@ -162,8 +139,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. */
void yyerror (]b4_locations_if([b4_location_type[ loc, ]])[String msg);]
* @@param s The string for the error message. */
void yyerror (]b4_locations_if([b4_location_type[ loc, ]])[String s);]
}
b4_lexer_if([[private class YYLexer implements Lexer {
@@ -179,9 +156,7 @@ b4_lexer_if([[
/**
* Instantiates the Bison-generated parser.
*/
public ]b4_parser_class_name (b4_parse_param_decl([b4_lex_param_decl])[) ]b4_maybe_throws([b4_init_throws])[
{
]b4_percent_code_get([[init]])[
public ]b4_parser_class_name (b4_parse_param_decl([b4_lex_param_decl])[) {
this.yylexer = new YYLexer(]b4_lex_param_call[);
]b4_parse_param_cons[
}
@@ -191,9 +166,7 @@ b4_lexer_if([[
* Instantiates the Bison-generated parser.
* @@param yylexer The scanner that will supply tokens to the parser.
*/
b4_lexer_if([[protected]], [[public]]) b4_parser_class_name[ (]b4_parse_param_decl([[Lexer yylexer]])[) ]b4_maybe_throws([b4_init_throws])[
{
]b4_percent_code_get([[init]])[
b4_lexer_if([[protected]], [[public]]) b4_parser_class_name[ (]b4_parse_param_decl([[Lexer yylexer]])[) {
this.yylexer = yylexer;
]b4_parse_param_cons[
}
@@ -227,35 +200,20 @@ b4_lexer_if([[
*/
public final void setDebugLevel(int level) { yydebug = level; }
/**
* Print an error message via the lexer.
*]b4_locations_if([[ Use a <code>null</code> location.]])[
* @@param msg The error message.
*/
public final void yyerror (String msg)
{
yylexer.yyerror (]b4_locations_if([[(]b4_location_type[)null, ]])[msg);
private final int yylex () ]b4_maybe_throws([b4_lex_throws]) [{
return yylexer.yylex ();
}
]b4_locations_if([[
/**
* Print an error message via the lexer.
* @@param loc The location associated with the message.
* @@param msg The error message.
*/
public final void yyerror (]b4_location_type[ loc, String msg)
{
yylexer.yyerror (loc, msg);
protected final void yyerror (]b4_locations_if([b4_location_type[ loc, ]])[String s) {
yylexer.yyerror (]b4_locations_if([loc, ])[s);
}
/**
* Print an error message via the lexer.
* @@param pos The position associated with the message.
* @@param msg The error message.
*/
public final void yyerror (]b4_position_type[ pos, String msg)
{
yylexer.yyerror (new ]b4_location_type[ (pos), msg);
}]])
]b4_locations_if([
protected final void yyerror (String s) {
yylexer.yyerror ((]b4_location_type[)null, s);
}
protected final void yyerror (]b4_position_type[ loc, String s) {
yylexer.yyerror (new ]b4_location_type[ (loc), s);
}])
[protected final void yycdebug (String s) {
if (yydebug > 0)
@@ -271,24 +229,24 @@ b4_lexer_if([[
public int height = -1;
public final void push (int state, ]b4_yystype[ value]dnl
b4_locations_if([, ]b4_location_type[ loc])[) {
b4_locations_if([, ]b4_location_type[ loc])[) {
height++;
if (size == height)
{
int[] newStateStack = new int[size * 2];
System.arraycopy (stateStack, 0, newStateStack, 0, height);
stateStack = newStateStack;
]b4_locations_if([[
]b4_location_type[[] newLocStack = new ]b4_location_type[[size * 2];
System.arraycopy (locStack, 0, newLocStack, 0, height);
locStack = newLocStack;]])
int[] newStateStack = new int[size * 2];
System.arraycopy (stateStack, 0, newStateStack, 0, height);
stateStack = newStateStack;
]b4_locations_if([[
]b4_location_type[[] newLocStack = new ]b4_location_type[[size * 2];
System.arraycopy (locStack, 0, newLocStack, 0, height);
locStack = newLocStack;]])
b4_yystype[[] newValueStack = new ]b4_yystype[[size * 2];
System.arraycopy (valueStack, 0, newValueStack, 0, height);
valueStack = newValueStack;
b4_yystype[[] newValueStack = new ]b4_yystype[[size * 2];
System.arraycopy (valueStack, 0, newValueStack, 0, height);
valueStack = newValueStack;
size *= 2;
}
size *= 2;
}
stateStack[height] = state;
]b4_locations_if([[locStack[height] = loc;]])[
@@ -302,7 +260,7 @@ b4_lexer_if([[
public final void pop (int num) {
// Avoid memory leaks... garbage collection is a white lie!
if (num > 0) {
java.util.Arrays.fill (valueStack, height - num + 1, height + 1, null);
java.util.Arrays.fill (valueStack, height - num + 1, height + 1, null);
]b4_locations_if([[java.util.Arrays.fill (locStack, height - num + 1, height + 1, null);]])[
}
height -= num;
@@ -327,8 +285,8 @@ b4_lexer_if([[
for (int i = 0; i <= height; i++)
{
out.print (' ');
out.print (stateStack[i]);
out.print (' ');
out.print (stateStack[i]);
}
out.println ();
}
@@ -389,8 +347,8 @@ b4_lexer_if([[
switch (yyn)
{
]b4_user_actions[
default: break;
]b4_user_actions[
default: break;
}
yy_symbol_print ("-> $$ =", yyr1_[yyn], yyval]b4_locations_if([, yyloc])[);
@@ -402,7 +360,7 @@ b4_lexer_if([[
yyn = yyr1_[yyn];
int yystate = yypgoto_[yyn - yyntokens_] + yystack.stateAt (0);
if (0 <= yystate && yystate <= yylast_
&& yycheck_[yystate] == yystack.stateAt (0))
&& yycheck_[yystate] == yystack.stateAt (0))
yystate = yytable_[yystate];
else
yystate = yydefgoto_[yyn - yyntokens_];
@@ -411,7 +369,6 @@ b4_lexer_if([[
return YYNEWSTATE;
}
]b4_error_verbose_if([[
/* Return YYSTR after stripping away unnecessary quotes and
backslashes, so that it's suitable for yyerror. The heuristic is
that double-quoting is unnecessary unless the string contains an
@@ -430,7 +387,7 @@ b4_lexer_if([[
break strip_quotes;
case '\\':
if (yystr.charAt(++i) != '\\')
if (yystr.charAt(++i) != '\\')
break strip_quotes;
/* Fall through. */
default:
@@ -446,21 +403,20 @@ b4_lexer_if([[
return yystr;
}
]])[
/*--------------------------------.
| Print this symbol on YYOUTPUT. |
`--------------------------------*/
private void yy_symbol_print (String s, int yytype,
]b4_yystype[ yyvaluep]dnl
b4_locations_if([, Object yylocationp])[)
]b4_yystype[ yyvaluep]dnl
b4_locations_if([, Object yylocationp])[)
{
if (yydebug > 0)
yycdebug (s + (yytype < yyntokens_ ? " token " : " nterm ")
+ yytname_[yytype] + " ("]b4_locations_if([
+ yylocationp + ": "])[
+ (yyvaluep == null ? "(null)" : yyvaluep.toString ()) + ")");
+ yytname_[yytype] + " ("]b4_locations_if([
+ yylocationp + ": "])[
+ (yyvaluep == null ? "(null)" : yyvaluep.toString ()) + ")");
}
/**
@@ -502,8 +458,8 @@ b4_lexer_if([[
]m4_ifdef([b4_initial_action], [
b4_dollar_pushdef([yylval], [], [yylloc])dnl
/* User initialization code. */
b4_user_initial_action
/* User initialization code. */
b4_user_initial_action
b4_dollar_popdef])[]dnl
[ /* Initialize the stack. */
@@ -514,7 +470,7 @@ b4_dollar_popdef])[]dnl
switch (label)
{
/* New state. Unlike in the C/C++ skeletons, the state is already
pushed when we come here. */
pushed when we come here. */
case YYNEWSTATE:
yycdebug ("Entering state " + yystate + "\n");
if (yydebug > 0)
@@ -529,31 +485,31 @@ b4_dollar_popdef])[]dnl
if (yy_pact_value_is_default_ (yyn))
{
label = YYDEFAULT;
break;
break;
}
/* Read a lookahead token. */
if (yychar == yyempty_)
{
yycdebug ("Reading a token: ");
yychar = yylexer.yylex ();]
yycdebug ("Reading a token: ");
yychar = yylex ();]
b4_locations_if([[
yylloc = new ]b4_location_type[(yylexer.getStartPos (),
yylexer.getEndPos ());]])
yylloc = new ]b4_location_type[(yylexer.getStartPos (),
yylexer.getEndPos ());]])
yylval = yylexer.getLVal ();[
}
/* Convert token to internal form. */
if (yychar <= Lexer.EOF)
if (yychar <= EOF)
{
yychar = yytoken = Lexer.EOF;
yycdebug ("Now at end of input.\n");
yychar = yytoken = EOF;
yycdebug ("Now at end of input.\n");
}
else
{
yytoken = yytranslate_ (yychar);
yy_symbol_print ("Next token is", yytoken,
yylval]b4_locations_if([, yylloc])[);
yytoken = yytranslate_ (yychar);
yy_symbol_print ("Next token is", yytoken,
yylval]b4_locations_if([, yylloc])[);
}
/* If the proper action on seeing token YYTOKEN is to reduce or to
@@ -565,20 +521,20 @@ b4_dollar_popdef])[]dnl
/* <= 0 means reduce or error. */
else if ((yyn = yytable_[yyn]) <= 0)
{
if (yy_table_value_is_error_ (yyn))
label = YYERRLAB;
else
{
yyn = -yyn;
label = YYREDUCE;
}
if (yy_table_value_is_error_ (yyn))
label = YYERRLAB;
else
{
yyn = -yyn;
label = YYREDUCE;
}
}
else
{
/* Shift the lookahead token. */
yy_symbol_print ("Shifting", yytoken,
yylval]b4_locations_if([, yylloc])[);
yy_symbol_print ("Shifting", yytoken,
yylval]b4_locations_if([, yylloc])[);
/* Discard the token being shifted. */
yychar = yyempty_;
@@ -611,7 +567,7 @@ b4_dollar_popdef])[]dnl
case YYREDUCE:
yylen = yyr2_[yyn];
label = yyaction (yyn, yystack, yylen);
yystate = yystack.stateAt (0);
yystate = yystack.stateAt (0);
break;
/*------------------------------------.
@@ -630,17 +586,17 @@ b4_dollar_popdef])[]dnl
]b4_locations_if([yyerrloc = yylloc;])[
if (yyerrstatus_ == 3)
{
/* If just tried and failed to reuse lookahead token after an
error, discard it. */
/* If just tried and failed to reuse lookahead token after an
error, discard it. */
if (yychar <= Lexer.EOF)
{
/* Return failure if at end of input. */
if (yychar == Lexer.EOF)
return false;
}
else
yychar = yyempty_;
if (yychar <= EOF)
{
/* Return failure if at end of input. */
if (yychar == EOF)
return false;
}
else
yychar = yyempty_;
}
/* Else will try to reuse lookahead token after shifting the error
@@ -666,46 +622,46 @@ b4_dollar_popdef])[]dnl
| yyerrlab1 -- common code for both syntax error and YYERROR. |
`-------------------------------------------------------------*/
case YYERRLAB1:
yyerrstatus_ = 3; /* Each real token shifted decrements this. */
yyerrstatus_ = 3; /* Each real token shifted decrements this. */
for (;;)
{
yyn = yypact_[yystate];
if (!yy_pact_value_is_default_ (yyn))
{
yyn += yyterror_;
if (0 <= yyn && yyn <= yylast_ && yycheck_[yyn] == yyterror_)
{
yyn = yytable_[yyn];
if (0 < yyn)
break;
}
}
yyn = yypact_[yystate];
if (!yy_pact_value_is_default_ (yyn))
{
yyn += yyterror_;
if (0 <= yyn && yyn <= yylast_ && yycheck_[yyn] == yyterror_)
{
yyn = yytable_[yyn];
if (0 < yyn)
break;
}
}
/* Pop the current state because it cannot handle the error token. */
if (yystack.height == 0)
return false;
/* Pop the current state because it cannot handle the error token. */
if (yystack.height == 0)
return false;
]b4_locations_if([yyerrloc = yystack.locationAt (0);])[
yystack.pop ();
yystate = yystack.stateAt (0);
if (yydebug > 0)
yystack.print (yyDebugStream);
]b4_locations_if([yyerrloc = yystack.locationAt (0);])[
yystack.pop ();
yystate = yystack.stateAt (0);
if (yydebug > 0)
yystack.print (yyDebugStream);
}
]b4_locations_if([
/* Muck with the stack to setup for yylloc. */
yystack.push (0, null, yylloc);
yystack.push (0, null, yyerrloc);
]b4_locations_if([
/* Muck with the stack to setup for yylloc. */
yystack.push (0, null, yylloc);
yystack.push (0, null, yyerrloc);
yyloc = yylloc (yystack, 2);
yystack.pop (2);])[
yystack.pop (2);])[
/* Shift the error token. */
yy_symbol_print ("Shifting", yystos_[yyn],
yylval]b4_locations_if([, yyloc])[);
yylval]b4_locations_if([, yyloc])[);
yystate = yyn;
yystack.push (yyn, yylval]b4_locations_if([, yyloc])[);
yystack.push (yyn, yylval]b4_locations_if([, yyloc])[);
label = YYNEWSTATE;
break;
@@ -721,10 +677,15 @@ b4_dollar_popdef])[]dnl
// Generate an error message.
private String yysyntax_error (int yystate, int tok)
{]b4_error_verbose_if([[
if (yyErrorVerbose)
{
if (errorVerbose)
{
/* There are many possibilities here to consider:
- Assume YYFAIL is not used. It's too flawed to consider.
See
<http://lists.gnu.org/archive/html/bison-patches/2009-12/msg00024.html>
for details. YYERROR is fine as it does not invoke this
function.
- If this state is a consistent state with a default action,
then the only way this function was invoked is if the
default action is an error action. In that case, don't
@@ -788,7 +749,7 @@ b4_dollar_popdef])[]dnl
return res.toString ();
}
}
]])[
return "syntax error";
}
@@ -810,20 +771,107 @@ b4_dollar_popdef])[]dnl
return yyvalue == yytable_ninf_;
}
/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
STATE-NUM. */
private static final ]b4_int_type_for([b4_pact])[ yypact_ninf_ = ]b4_pact_ninf[;
private static final ]b4_int_type_for([b4_table])[ yytable_ninf_ = ]b4_table_ninf[;
private static final ]b4_int_type_for([b4_pact])[ yypact_[] =
{
]b4_pact[
};
]b4_parser_tables_define[
]b4_integral_parser_table_define([token_number], [b4_toknum],
[[YYTOKEN_NUMBER[YYLEX-NUM] -- Internal symbol number corresponding
to YYLEX-NUM.]])[
/* YYDEFACT[S] -- default reduction number in state S. Performed when
YYTABLE doesn't specify something else to do. Zero means the
default is an error. */
private static final ]b4_int_type_for([b4_defact])[ yydefact_[] =
{
]b4_defact[
};
/* YYPGOTO[NTERM-NUM]. */
private static final ]b4_int_type_for([b4_pgoto])[ yypgoto_[] =
{
]b4_pgoto[
};
/* YYDEFGOTO[NTERM-NUM]. */
private static final ]b4_int_type_for([b4_defgoto])[
yydefgoto_[] =
{
]b4_defgoto[
};
/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
positive, shift that token. If negative, reduce the rule which
number is the opposite. If YYTABLE_NINF_, syntax error. */
private static final ]b4_int_type_for([b4_table])[ yytable_ninf_ = ]b4_table_ninf[;
private static final ]b4_int_type_for([b4_table])[
yytable_[] =
{
]b4_table[
};
/* YYCHECK. */
private static final ]b4_int_type_for([b4_check])[
yycheck_[] =
{
]b4_check[
};
/* STOS_[STATE-NUM] -- The (internal number of the) accessing
symbol of state STATE-NUM. */
private static final ]b4_int_type_for([b4_stos])[
yystos_[] =
{
]b4_stos[
};
/* TOKEN_NUMBER_[YYLEX-NUM] -- Internal symbol number corresponding
to YYLEX-NUM. */
private static final ]b4_int_type_for([b4_toknum])[
yytoken_number_[] =
{
]b4_toknum[
};
/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
private static final ]b4_int_type_for([b4_r1])[
yyr1_[] =
{
]b4_r1[
};
/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
private static final ]b4_int_type_for([b4_r2])[
yyr2_[] =
{
]b4_r2[
};
/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
First, the terminals, then, starting at \a yyntokens_, nonterminals. */
]b4_typed_parser_table_define([String], [tname], [b4_tname])[
private static final String yytname_[] =
{
]b4_tname[
};
]b4_integral_parser_table_define([rline], [b4_rline],
[[YYRLINE[YYN] -- Source line where rule number YYN was defined.]])[
/* YYRHS -- A `-1'-separated list of the rules' RHS. */
private static final ]b4_int_type_for([b4_rhs])[ yyrhs_[] =
{
]b4_rhs[
};
/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
YYRHS. */
private static final ]b4_int_type_for([b4_prhs])[ yyprhs_[] =
{
]b4_prhs[
};
/* YYRLINE[YYN] -- Source line where rule number YYN was defined. */
private static final ]b4_int_type_for([b4_rline])[ yyrline_[] =
{
]b4_rline[
};
// Report on the debug stream that the rule yyrule is going to be reduced.
private void yy_reduce_print (int yyrule, YYStack yystack)
@@ -835,18 +883,21 @@ b4_dollar_popdef])[]dnl
int yynrhs = yyr2_[yyrule];
/* Print the symbols being reduced, and their result. */
yycdebug ("Reducing stack by rule " + (yyrule - 1)
+ " (line " + yylno + "), ");
+ " (line " + yylno + "), ");
/* The symbols being reduced. */
for (int yyi = 0; yyi < yynrhs; yyi++)
yy_symbol_print (" $" + (yyi + 1) + " =",
yystos_[yystack.stateAt(yynrhs - (yyi + 1))],
]b4_rhs_value(yynrhs, yyi + 1)b4_locations_if([,
b4_rhs_location(yynrhs, yyi + 1)])[);
yyrhs_[yyprhs_[yyrule] + yyi],
]b4_rhs_value(yynrhs, yyi + 1)b4_locations_if([,
b4_rhs_location(yynrhs, yyi + 1)])[);
}
/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
]b4_integral_parser_table_define([translate_table], [b4_translate])[
private static final ]b4_int_type_for([b4_translate])[ yytranslate_table_[] =
{
]b4_translate[
};
private static final ]b4_int_type_for([b4_translate])[ yytranslate_ (int t)
{
@@ -872,5 +923,5 @@ b4_percent_code_get[]dnl
}
b4_epilogue[]dnl
b4_epilogue
b4_output_end()
-45
View File
@@ -1,45 +0,0 @@
## Copyright (C) 2002, 2005-2013 Free Software Foundation, Inc.
## This program is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with this program. If not, see <http://www.gnu.org/licenses/>.
dist_pkgdata_DATA = \
data/README \
data/bison.m4 \
data/c++-skel.m4 \
data/c++.m4 \
data/c-like.m4 \
data/c-skel.m4 \
data/c.m4 \
data/glr.c \
data/glr.cc \
data/java-skel.m4 \
data/java.m4 \
data/lalr1.cc \
data/lalr1.java \
data/location.cc \
data/stack.hh \
data/variant.hh \
data/yacc.c
m4sugardir = $(pkgdatadir)/m4sugar
dist_m4sugar_DATA = \
data/m4sugar/foreach.m4 \
data/m4sugar/m4sugar.m4
xsltdir = $(pkgdatadir)/xslt
dist_xslt_DATA = \
data/xslt/bison.xsl \
data/xslt/xml2dot.xsl \
data/xslt/xml2text.xsl \
data/xslt/xml2xhtml.xsl
+50 -67
View File
@@ -1,6 +1,6 @@
# C++ skeleton for Bison
# Copyright (C) 2002-2013 Free Software Foundation, Inc.
# Copyright (C) 2002-2007, 2009-2013 Free Software Foundation, Inc.
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -15,14 +15,26 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
m4_pushdef([b4_copyright_years],
[2002-2013])
# b4_position_define
# ------------------
# Define class position.
m4_define([b4_position_define],
[[ /// Abstract a position.
b4_output_begin([b4_dir_prefix[]position.hh])
b4_copyright([Positions for Bison parsers in C++],
[2002-2007, 2009-2013])[
/**
** \file ]b4_dir_prefix[position.hh
** Define the ]b4_namespace_ref[::position class.
*/
]b4_cpp_guard_open([b4_dir_prefix[]position.hh])[
# include <algorithm> // std::max
# include <iostream>
# include <string>
]b4_null_define[
]b4_namespace_open[
/// Abstract a position.
class position
{
public:
@@ -132,13 +144,28 @@ m4_define([b4_position_define],
ostr << *pos.filename << ':';
return ostr << pos.line << '.' << pos.column;
}
]])
]b4_namespace_close[
]b4_cpp_guard_close([b4_dir_prefix[]position.hh])
b4_output_end()
# b4_location_define
# ------------------
m4_define([b4_location_define],
[[ /// Abstract a location.
b4_output_begin([b4_dir_prefix[]location.hh])
b4_copyright([Locations for Bison parsers in C++],
[2002-2007, 2009-2013])[
/**
** \file ]b4_dir_prefix[location.hh
** Define the ]b4_namespace_ref[::location class.
*/
]b4_cpp_guard_open([b4_dir_prefix[]location.hh])[
# include "position.hh"
]b4_namespace_open[
/// Abstract a location.
class location
{
public:
@@ -253,64 +280,20 @@ m4_define([b4_location_define],
inline std::basic_ostream<YYChar>&
operator<< (std::basic_ostream<YYChar>& ostr, const location& loc)
{
unsigned int end_col = 0 < loc.end.column ? loc.end.column - 1 : 0;
ostr << loc.begin// << "(" << loc.end << ") "
;
if (loc.end.filename
&& (!loc.begin.filename
|| *loc.begin.filename != *loc.end.filename))
ostr << '-' << loc.end.filename << ':' << loc.end.line << '.' << end_col;
else if (loc.begin.line < loc.end.line)
ostr << '-' << loc.end.line << '.' << end_col;
else if (loc.begin.column < end_col)
ostr << '-' << end_col;
position last = loc.end - 1;
ostr << loc.begin;
if (last.filename
&& (!loc.begin.filename
|| *loc.begin.filename != *last.filename))
ostr << '-' << last;
else if (loc.begin.line != last.line)
ostr << '-' << last.line << '.' << last.column;
else if (loc.begin.column != last.column)
ostr << '-' << last.column;
return ostr;
}
]])
b4_defines_if([
b4_output_begin([b4_dir_prefix[]position.hh])
b4_copyright([Positions for Bison parsers in C++])[
/**
** \file ]b4_dir_prefix[position.hh
** Define the ]b4_namespace_ref[::position class.
*/
]b4_cpp_guard_open([b4_dir_prefix[]position.hh])[
# include <algorithm> // std::max
# include <iostream>
# include <string>
]b4_null_define[
]b4_namespace_open[
]b4_position_define[
]b4_namespace_close[
]b4_cpp_guard_close([b4_dir_prefix[]position.hh])
b4_output_end()
b4_output_begin([b4_dir_prefix[]location.hh])
b4_copyright([Locations for Bison parsers in C++])[
/**
** \file ]b4_dir_prefix[location.hh
** Define the ]b4_namespace_ref[::location class.
*/
]b4_cpp_guard_open([b4_dir_prefix[]location.hh])[
# include "position.hh"
]b4_namespace_open[
]b4_location_define[
]b4_namespace_close[
]b4_cpp_guard_close([b4_dir_prefix[]location.hh])
b4_output_end()
])
m4_popdef([b4_copyright_years])
+36 -53
View File
@@ -18,10 +18,21 @@
m4_pushdef([b4_copyright_years],
[2002-2013])
# b4_stack_define
# ---------------
m4_define([b4_stack_define],
[[ template <class T, class S = std::vector<T> >
b4_output_begin([b4_dir_prefix[]stack.hh])
b4_copyright([Stack handling for Bison parsers in C++],
[2002-2013])[
/**
** \file ]b4_dir_prefix[stack.hh
** Define the ]b4_namespace_ref[::stack class.
*/
]b4_cpp_guard_open([b4_dir_prefix[]stack.hh])[
# include <deque>
]b4_namespace_open[
template <class T, class S = std::deque<T> >
class stack
{
public:
@@ -29,39 +40,33 @@ m4_define([b4_stack_define],
typedef typename S::reverse_iterator iterator;
typedef typename S::const_reverse_iterator const_iterator;
stack ()
: seq_ ()
stack () : seq_ ()
{
}
stack (unsigned int n)
: seq_ (n)
stack (unsigned int n) : seq_ (n)
{
}
inline
T&
operator[] (unsigned int i)
operator [] (unsigned int i)
{
return seq_[seq_.size () - 1 - i];
return seq_[i];
}
inline
const T&
operator[] (unsigned int i) const
operator [] (unsigned int i) const
{
return seq_[seq_.size () - 1 - i];
return seq_[i];
}
/// Steal the contents of \a t.
///
/// Close to move-semantics.
inline
void
push (T& t)
push (const T& t)
{
seq_.push_back (T());
operator[](0).move (t);
seq_.push_front (t);
}
inline
@@ -69,32 +74,28 @@ m4_define([b4_stack_define],
pop (unsigned int n = 1)
{
for (; n; --n)
seq_.pop_back ();
seq_.pop_front ();
}
void
clear ()
{
seq_.clear ();
}
inline
typename S::size_type
size () const
unsigned int
height () const
{
return seq_.size ();
}
inline
const_iterator
begin () const
{
return seq_.rbegin ();
}
inline
const_iterator
end () const
{
return seq_.rend ();
}
inline const_iterator begin () const { return seq_.rbegin (); }
inline const_iterator end () const { return seq_.rend (); }
private:
/// The wrapped container.
stack (const stack&);
stack& operator= (const stack&);
S seq_;
};
@@ -120,27 +121,9 @@ m4_define([b4_stack_define],
const S& stack_;
unsigned int range_;
};
]])
b4_defines_if(
[b4_output_begin([b4_dir_prefix[]stack.hh])
b4_copyright([Stack handling for Bison parsers in C++])[
/**
** \file ]b4_dir_prefix[stack.hh
** Define the ]b4_namespace_ref[::stack class.
*/
]b4_cpp_guard_open([b4_dir_prefix[]stack.hh])[
# include <vector>
]b4_namespace_open[
]b4_stack_define[
]b4_namespace_close[
]b4_cpp_guard_close([b4_dir_prefix[]stack.hh])
b4_output_end()
])
m4_popdef([b4_copyright_years])
-345
View File
@@ -1,345 +0,0 @@
# C++ skeleton for Bison
# Copyright (C) 2002-2013 Free Software Foundation, Inc.
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
## --------- ##
## variant. ##
## --------- ##
# b4_symbol_variant(YYTYPE, YYVAL, ACTION, [ARGS])
# ------------------------------------------------
# Run some ACTION ("build", or "destroy") on YYVAL of symbol type
# YYTYPE.
m4_define([b4_symbol_variant],
[m4_pushdef([b4_dollar_dollar],
[$2.$3< $][3 >(m4_shift3($@))])dnl
switch ($1)
{
b4_type_foreach([b4_type_action_])[]dnl
default:
break;
}
m4_popdef([b4_dollar_dollar])dnl
])
# _b4_char_sizeof_counter
# -----------------------
# A counter used by _b4_char_sizeof_dummy to create fresh symbols.
m4_define([_b4_char_sizeof_counter],
[0])
# _b4_char_sizeof_dummy
# ---------------------
# At each call return a new C++ identifier.
m4_define([_b4_char_sizeof_dummy],
[m4_define([_b4_char_sizeof_counter], m4_incr(_b4_char_sizeof_counter))dnl
dummy[]_b4_char_sizeof_counter])
# b4_char_sizeof(SYMBOL-NUMS)
# ---------------------------
# To be mapped on the list of type names to produce:
#
# char dummy1[sizeof(type_name_1)];
# char dummy2[sizeof(type_name_2)];
#
# for defined type names.
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])])@};
])])
# b4_variant_includes
# -------------------
# The needed includes for variants support.
m4_define([b4_variant_includes],
[b4_parse_assert_if([[#include <typeinfo>]])[
#ifndef YYASSERT
# include <cassert>
# define YYASSERT assert
#endif
]])
# b4_variant_define
# -----------------
# Define "variant".
m4_define([b4_variant_define],
[[ /// A char[S] buffer to store and retrieve objects.
///
/// Sort of a variant, but does not keep track of the nature
/// of the stored data, since that knowledge is available
/// via the current state.
template <size_t S>
struct variant
{
/// Type of *this.
typedef variant<S> self_type;
/// Empty construction.
variant ()]b4_parse_assert_if([
: tname (YY_NULL)])[
{}
/// Construct and fill.
template <typename T>
variant (const T& t)]b4_parse_assert_if([
: tname (typeid (T).name ())])[
{
YYASSERT (sizeof (T) <= S);
new (buffer.raw) T (t);
}
/// Destruction, allowed only if empty.
~variant ()
{]b4_parse_assert_if([
YYASSERT (!tname);
])[}
/// Instantiate an empty \a T in here.
template <typename T>
T&
build ()
{]b4_parse_assert_if([
YYASSERT (!tname);
YYASSERT (sizeof (T) <= S);
tname = typeid (T).name ();])[
return *new (buffer.raw) T;
}
/// Instantiate a \a T in here from \a t.
template <typename T>
T&
build (const T& t)
{]b4_parse_assert_if([
YYASSERT (!tname);
YYASSERT (sizeof (T) <= S);
tname = typeid (T).name ();])[
return *new (buffer.raw) T (t);
}
/// Accessor to a built \a T.
template <typename T>
T&
as ()
{]b4_parse_assert_if([
YYASSERT (tname == typeid (T).name ());
YYASSERT (sizeof (T) <= S);])[
return reinterpret_cast<T&> (buffer.raw);
}
/// Const accessor to a built \a T (for %printer).
template <typename T>
const T&
as () const
{]b4_parse_assert_if([
YYASSERT (tname == typeid (T).name ());
YYASSERT (sizeof (T) <= S);])[
return reinterpret_cast<const T&> (buffer.raw);
}
/// Swap the content with \a other, of same type.
///
/// Both variants must be built beforehand, because swapping the actual
/// data requires reading it (with as()), and this is not possible on
/// unconstructed variants: it would require some dynamic testing, which
/// should not be the variant's responsability.
/// Swapping between built and (possibly) non-built is done with
/// variant::move ().
template <typename T>
void
swap (self_type& other)
{]b4_parse_assert_if([
YYASSERT (tname);
YYASSERT (tname == other.tname);])[
std::swap (as<T>(), other.as<T>());
}
/// Move the content of \a other to this.
///
/// Destroys \a other.
template <typename T>
void
move (self_type& other)
{]b4_parse_assert_if([
YYASSERT (!tname);])[
build<T>();
swap<T>(other);
other.destroy<T>();
}
/// Copy the content of \a other to this.
template <typename T>
void
copy (const self_type& other)
{
build<T> (other.as<T> ());
}
/// Destroy the stored \a T.
template <typename T>
void
destroy ()
{
as<T> ().~T ();]b4_parse_assert_if([
tname = YY_NULL;])[
}
private:
/// Prohibit blind copies.
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.
union
{
long double align_me;
char raw[S];
} buffer;]b4_parse_assert_if([
/// Whether the content is built: if defined, the name of the stored type.
const char* tname;])[
};
]])
## -------------------------- ##
## Adjustments for variants. ##
## -------------------------- ##
# b4_semantic_type_declare
# ------------------------
# Declare semantic_type.
m4_define([b4_semantic_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
])
# How the semantic value is extracted when using variants.
# b4_symbol_value(VAL, [TYPE])
# ----------------------------
m4_define([b4_symbol_value],
[m4_ifval([$2],
[$1.as< $2 >()],
[$1])])
# b4_symbol_value_template(VAL, [TYPE])
# -------------------------------------
# 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])])
## ------------- ##
## make_SYMBOL. ##
## ------------- ##
# b4_symbol_constructor_declare_(SYMBOL-NUMBER)
# ---------------------------------------------
# Declare the overloaded version of make_symbol for the (common) type of
# these SYMBOL-NUMBERS. Use at class-level.
m4_define([b4_symbol_constructor_declare_],
[b4_symbol_if([$1], [is_token], [b4_symbol_if([$1], [has_id],
[ static inline
symbol_type
make_[]b4_symbol_([$1], [id]) (dnl
b4_join(b4_symbol_if([$1], [has_type],
[const b4_symbol([$1], [type])& v]),
b4_locations_if([const location_type& l])));
])])])
# b4_symbol_constructor_declare
# -----------------------------
# Declare symbol constructors for all the value types.
# Use at class-level.
m4_define([b4_symbol_constructor_declare],
[ // Symbol constructors declarations.
b4_symbol_foreach([b4_symbol_constructor_declare_])])
# b4_symbol_constructor_define_(SYMBOL-NUMBER)
# --------------------------------------------
# Define symbol constructor for this SYMBOL-NUMBER.
m4_define([b4_symbol_constructor_define_],
[b4_symbol_if([$1], [is_token], [b4_symbol_if([$1], [has_id],
[ b4_parser_class_name::symbol_type
b4_parser_class_name::make_[]b4_symbol_([$1], [id]) (dnl
b4_join(b4_symbol_if([$1], [has_type],
[const b4_symbol([$1], [type])& v]),
b4_locations_if([const location_type& l])))
{
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],
[[
basic_symbol (]b4_join(
[typename Base::kind_type t],
b4_symbol_if([$1], [has_type], const b4_symbol([$1], [type])[ v]),
b4_locations_if([const location_type& l]))[);
]])
# b4_basic_symbol_constructor_define
# ----------------------------------
# Generate a constructor implementation for basic_symbol from given type.
m4_define([b4_basic_symbol_constructor_define],
[[
template <typename Base>
]b4_parser_class_name[::basic_symbol<Base>::basic_symbol (]b4_join(
[typename Base::kind_type t],
b4_symbol_if([$1], [has_type], const b4_symbol([$1], [type])[ v]),
b4_locations_if([const location_type& l]))[)
: Base (t)
, value (]b4_symbol_if([$1], [has_type], [v])[)]b4_locations_if([
, location (l)])[
{}
]])
# b4_symbol_constructor_define
# ----------------------------
# Define the overloaded versions of make_symbol for all the value types.
m4_define([b4_symbol_constructor_define],
[ // Implementation of make_symbol for each symbol type.
b4_symbol_foreach([b4_symbol_constructor_define_])])
+10 -10
View File
@@ -279,20 +279,20 @@
<xsl:with-param name="dst" select="@state"/>
<xsl:with-param name="style">
<xsl:choose>
<xsl:when test="@symbol = 'error'">
<xsl:text>dotted</xsl:text>
</xsl:when>
<xsl:when test="@type = 'shift'">
<xsl:text>solid</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:text>dashed</xsl:text>
</xsl:otherwise>
<xsl:when test="@symbol = 'error'">
<xsl:text>dotted</xsl:text>
</xsl:when>
<xsl:when test="@type = 'shift'">
<xsl:text>solid</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:text>dashed</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:with-param>
<xsl:with-param name="label">
<xsl:if test="not(@symbol = 'error')">
<xsl:value-of select="@symbol"/>
<xsl:value-of select="@symbol"/>
</xsl:if>
</xsl:with-param>
</xsl:call-template>
+19 -19
View File
@@ -253,9 +253,9 @@
<xsl:text>&#10;</xsl:text>
<xsl:apply-templates select="transition[@type = $type]">
<xsl:with-param name="pad">
<xsl:call-template name="max-width-symbol">
<xsl:with-param name="node" select="transition[@type = $type]"/>
</xsl:call-template>
<xsl:call-template name="max-width-symbol">
<xsl:with-param name="node" select="transition[@type = $type]"/>
</xsl:call-template>
</xsl:with-param>
</xsl:apply-templates>
</xsl:if>
@@ -266,9 +266,9 @@
<xsl:text>&#10;</xsl:text>
<xsl:apply-templates select="error">
<xsl:with-param name="pad">
<xsl:call-template name="max-width-symbol">
<xsl:with-param name="node" select="error"/>
</xsl:call-template>
<xsl:call-template name="max-width-symbol">
<xsl:with-param name="node" select="error"/>
</xsl:call-template>
</xsl:with-param>
</xsl:apply-templates>
</xsl:if>
@@ -279,9 +279,9 @@
<xsl:text>&#10;</xsl:text>
<xsl:apply-templates select="reduction">
<xsl:with-param name="pad">
<xsl:call-template name="max-width-symbol">
<xsl:with-param name="node" select="reduction"/>
</xsl:call-template>
<xsl:call-template name="max-width-symbol">
<xsl:with-param name="node" select="reduction"/>
</xsl:call-template>
</xsl:with-param>
</xsl:apply-templates>
</xsl:if>
@@ -290,7 +290,7 @@
<xsl:template match="item">
<xsl:param name="pad"/>
<xsl:param name="prev-rule-number"
select="preceding-sibling::item[1]/@rule-number"/>
select="preceding-sibling::item[1]/@rule-number"/>
<xsl:apply-templates
select="key('bison:ruleByNumber', current()/@rule-number)"
>
@@ -329,14 +329,14 @@
<xsl:choose>
<xsl:when test="$itemset != 'true' and $prev-lhs = lhs[text()]">
<xsl:call-template name="lpad">
<xsl:with-param name="str" select="'|'"/>
<xsl:with-param name="pad" select="number(string-length(lhs[text()])) + 1"/>
<xsl:with-param name="str" select="'|'"/>
<xsl:with-param name="pad" select="number(string-length(lhs[text()])) + 1"/>
</xsl:call-template>
</xsl:when>
<xsl:when test="$itemset = 'true' and $prev-lhs = lhs[text()]">
<xsl:call-template name="lpad">
<xsl:with-param name="str" select="'|'"/>
<xsl:with-param name="pad" select="number(string-length(lhs[text()])) + 1"/>
<xsl:with-param name="str" select="'|'"/>
<xsl:with-param name="pad" select="number(string-length(lhs[text()])) + 1"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
@@ -442,7 +442,7 @@
<xsl:value-of select="@rule"/>
<xsl:text> (</xsl:text>
<xsl:value-of
select="key('bison:ruleByNumber', current()/@rule)/lhs[text()]"/>
select="key('bison:ruleByNumber', current()/@rule)/lhs[text()]"/>
<xsl:text>)</xsl:text>
</xsl:otherwise>
</xsl:choose>
@@ -479,9 +479,9 @@
<xsl:variable name="longest">
<xsl:for-each select="$node">
<xsl:sort data-type="number" select="string-length(@symbol)"
order="descending"/>
order="descending"/>
<xsl:if test="position() = 1">
<xsl:value-of select="string-length(@symbol)"/>
<xsl:value-of select="string-length(@symbol)"/>
</xsl:if>
</xsl:for-each>
</xsl:variable>
@@ -498,7 +498,7 @@
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="space">
<xsl:with-param name="repeat" select="$diff"/>
<xsl:with-param name="repeat" select="$diff"/>
</xsl:call-template>
<xsl:value-of select="$str"/>
</xsl:otherwise>
@@ -516,7 +516,7 @@
<xsl:otherwise>
<xsl:value-of select="$str"/>
<xsl:call-template name="space">
<xsl:with-param name="repeat" select="$diff"/>
<xsl:with-param name="repeat" select="$diff"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
+68 -68
View File
@@ -31,32 +31,32 @@
<xsl:import href="bison.xsl"/>
<xsl:output method="xml" encoding="UTF-8"
doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN"
doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"
indent="yes"/>
doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN"
doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"
indent="yes"/>
<xsl:template match="/">
<html>
<head>
<title>
<xsl:value-of select="bison-xml-report/filename"/>
<xsl:text> - GNU Bison XML Automaton Report</xsl:text>
<xsl:value-of select="bison-xml-report/filename"/>
<xsl:text> - GNU Bison XML Automaton Report</xsl:text>
</title>
<style type="text/css"><![CDATA[
body {
font-family: "Nimbus Sans L", Arial, sans-serif;
font-size: 9pt;
font-size: 9pt;
}
a:link {
color: #1f00ff;
text-decoration: none;
color: #1f00ff;
text-decoration: none;
}
a:visited {
color: #1f00ff;
text-decoration: none;
color: #1f00ff;
text-decoration: none;
}
a:hover {
color: red;
color: red;
}
#menu a {
text-decoration: underline;
@@ -109,21 +109,21 @@
<li>
<a href="#reductions">Reductions</a>
<ul class="lower-alpha">
<li><a href="#nonterminals_useless_in_grammar">Nonterminals useless in grammar</a></li>
<li><a href="#terminals_unused_in_grammar">Terminals unused in grammar</a></li>
<li><a href="#rules_useless_in_grammar">Rules useless in grammar</a></li>
<xsl:if test="grammar/rules/rule[@usefulness='useless-in-parser']">
<li><a href="#rules_useless_in_parser">Rules useless in parser due to conflicts</a></li>
</xsl:if>
<li><a href="#nonterminals_useless_in_grammar">Nonterminals useless in grammar</a></li>
<li><a href="#terminals_unused_in_grammar">Terminals unused in grammar</a></li>
<li><a href="#rules_useless_in_grammar">Rules useless in grammar</a></li>
<xsl:if test="grammar/rules/rule[@usefulness='useless-in-parser']">
<li><a href="#rules_useless_in_parser">Rules useless in parser due to conflicts</a></li>
</xsl:if>
</ul>
</li>
<li><a href="#conflicts">Conflicts</a></li>
<li>
<a href="#grammar">Grammar</a>
<ul class="lower-alpha">
<li><a href="#grammar">Itemset</a></li>
<li><a href="#terminals">Terminal symbols</a></li>
<li><a href="#nonterminals">Nonterminal symbols</a></li>
<li><a href="#grammar">Itemset</a></li>
<li><a href="#terminals">Terminal symbols</a></li>
<li><a href="#nonterminals">Nonterminal symbols</a></li>
</ul>
</li>
<li><a href="#automaton">Automaton</a></li>
@@ -154,9 +154,9 @@
<xsl:if test="nonterminal[@usefulness='useless-in-grammar']">
<p class="pre">
<xsl:for-each select="nonterminal[@usefulness='useless-in-grammar']">
<xsl:text> </xsl:text>
<xsl:value-of select="@name"/>
<xsl:text>&#10;</xsl:text>
<xsl:text> </xsl:text>
<xsl:value-of select="@name"/>
<xsl:text>&#10;</xsl:text>
</xsl:for-each>
<xsl:text>&#10;&#10;</xsl:text>
</p>
@@ -173,9 +173,9 @@
<p class="pre">
<xsl:for-each select="terminal[@usefulness='unused-in-grammar']">
<xsl:sort select="@symbol-number" data-type="number"/>
<xsl:text> </xsl:text>
<xsl:value-of select="@name"/>
<xsl:text>&#10;</xsl:text>
<xsl:text> </xsl:text>
<xsl:value-of select="@name"/>
<xsl:text>&#10;</xsl:text>
</xsl:for-each>
<xsl:text>&#10;&#10;</xsl:text>
</p>
@@ -381,7 +381,7 @@
<h3>
<a>
<xsl:attribute name="name">
<xsl:value-of select="concat('state_', @number)"/>
<xsl:value-of select="concat('state_', @number)"/>
</xsl:attribute>
</a>
<xsl:text>state </xsl:text>
@@ -410,9 +410,9 @@
<xsl:text>&#10;</xsl:text>
<xsl:apply-templates select="transition[@type = $type]">
<xsl:with-param name="pad">
<xsl:call-template name="max-width-symbol">
<xsl:with-param name="node" select="transition[@type = $type]"/>
</xsl:call-template>
<xsl:call-template name="max-width-symbol">
<xsl:with-param name="node" select="transition[@type = $type]"/>
</xsl:call-template>
</xsl:with-param>
</xsl:apply-templates>
</xsl:if>
@@ -423,9 +423,9 @@
<xsl:text>&#10;</xsl:text>
<xsl:apply-templates select="error">
<xsl:with-param name="pad">
<xsl:call-template name="max-width-symbol">
<xsl:with-param name="node" select="error"/>
</xsl:call-template>
<xsl:call-template name="max-width-symbol">
<xsl:with-param name="node" select="error"/>
</xsl:call-template>
</xsl:with-param>
</xsl:apply-templates>
</xsl:if>
@@ -436,9 +436,9 @@
<xsl:text>&#10;</xsl:text>
<xsl:apply-templates select="reduction">
<xsl:with-param name="pad">
<xsl:call-template name="max-width-symbol">
<xsl:with-param name="node" select="reduction"/>
</xsl:call-template>
<xsl:call-template name="max-width-symbol">
<xsl:with-param name="node" select="reduction"/>
</xsl:call-template>
</xsl:with-param>
</xsl:apply-templates>
</xsl:if>
@@ -447,7 +447,7 @@
<xsl:template match="item">
<xsl:param name="pad"/>
<xsl:param name="prev-rule-number"
select="preceding-sibling::item[1]/@rule-number"/>
select="preceding-sibling::item[1]/@rule-number"/>
<xsl:apply-templates
select="key('bison:ruleByNumber', current()/@rule-number)"
>
@@ -477,7 +477,7 @@
<xsl:if test="$itemset != 'true'">
<a>
<xsl:attribute name="name">
<xsl:value-of select="concat('rule_', @number)"/>
<xsl:value-of select="concat('rule_', @number)"/>
</xsl:attribute>
</a>
</xsl:if>
@@ -486,19 +486,19 @@
<xsl:choose>
<xsl:when test="$itemset = 'true'">
<a>
<xsl:attribute name="href">
<xsl:value-of select="concat('#rule_', @number)"/>
</xsl:attribute>
<xsl:call-template name="lpad">
<xsl:with-param name="str" select="string(@number)"/>
<xsl:with-param name="pad" select="number($pad)"/>
</xsl:call-template>
<xsl:attribute name="href">
<xsl:value-of select="concat('#rule_', @number)"/>
</xsl:attribute>
<xsl:call-template name="lpad">
<xsl:with-param name="str" select="string(@number)"/>
<xsl:with-param name="pad" select="number($pad)"/>
</xsl:call-template>
</a>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="lpad">
<xsl:with-param name="str" select="string(@number)"/>
<xsl:with-param name="pad" select="number($pad)"/>
<xsl:with-param name="str" select="string(@number)"/>
<xsl:with-param name="pad" select="number($pad)"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
@@ -508,19 +508,19 @@
<xsl:choose>
<xsl:when test="$itemset != 'true' and $prev-lhs = lhs[text()]">
<xsl:call-template name="lpad">
<xsl:with-param name="str" select="'|'"/>
<xsl:with-param name="pad" select="number(string-length(lhs[text()])) + 2"/>
<xsl:with-param name="str" select="'|'"/>
<xsl:with-param name="pad" select="number(string-length(lhs[text()])) + 2"/>
</xsl:call-template>
</xsl:when>
<xsl:when test="$itemset = 'true' and $prev-lhs = lhs[text()]">
<xsl:call-template name="lpad">
<xsl:with-param name="str" select="'|'"/>
<xsl:with-param name="pad" select="number(string-length(lhs[text()])) + 2"/>
<xsl:with-param name="str" select="'|'"/>
<xsl:with-param name="pad" select="number(string-length(lhs[text()])) + 2"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<span class="i">
<xsl:value-of select="lhs"/>
<xsl:value-of select="lhs"/>
</span>
<xsl:text> &#8594;</xsl:text>
</xsl:otherwise>
@@ -589,18 +589,18 @@
<xsl:choose>
<xsl:when test="@type = 'shift'">
<a>
<xsl:attribute name="href">
<xsl:value-of select="concat('#state_', @state)"/>
</xsl:attribute>
<xsl:value-of select="concat('shift, and go to state ', @state)"/>
<xsl:attribute name="href">
<xsl:value-of select="concat('#state_', @state)"/>
</xsl:attribute>
<xsl:value-of select="concat('shift, and go to state ', @state)"/>
</a>
</xsl:when>
<xsl:when test="@type = 'goto'">
<a>
<xsl:attribute name="href">
<xsl:value-of select="concat('#state_', @state)"/>
</xsl:attribute>
<xsl:value-of select="concat('go to state ', @state)"/>
<xsl:attribute name="href">
<xsl:value-of select="concat('#state_', @state)"/>
</xsl:attribute>
<xsl:value-of select="concat('go to state ', @state)"/>
</a>
</xsl:when>
</xsl:choose>
@@ -637,10 +637,10 @@
</xsl:when>
<xsl:otherwise>
<a>
<xsl:attribute name="href">
<xsl:value-of select="concat('#rule_', @rule)"/>
</xsl:attribute>
<xsl:value-of select="concat('reduce using rule ', @rule)"/>
<xsl:attribute name="href">
<xsl:value-of select="concat('#rule_', @rule)"/>
</xsl:attribute>
<xsl:value-of select="concat('reduce using rule ', @rule)"/>
</a>
<xsl:text> (</xsl:text>
<xsl:value-of
@@ -687,9 +687,9 @@
<xsl:variable name="longest">
<xsl:for-each select="$node">
<xsl:sort data-type="number" select="string-length(@symbol)"
order="descending"/>
order="descending"/>
<xsl:if test="position() = 1">
<xsl:value-of select="string-length(@symbol)"/>
<xsl:value-of select="string-length(@symbol)"/>
</xsl:if>
</xsl:for-each>
</xsl:variable>
@@ -706,7 +706,7 @@
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="space">
<xsl:with-param name="repeat" select="$diff"/>
<xsl:with-param name="repeat" select="$diff"/>
</xsl:call-template>
<xsl:value-of select="$str"/>
</xsl:otherwise>
@@ -724,7 +724,7 @@
<xsl:otherwise>
<xsl:value-of select="$str"/>
<xsl:call-template name="space">
<xsl:with-param name="repeat" select="$diff"/>
<xsl:with-param name="repeat" select="$diff"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
+335 -213
View File
@@ -1,12 +1,10 @@
-*- C -*-
# Yacc compatible skeleton for Bison
# Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation,
# Inc.
m4_pushdef([b4_copyright_years],
[1984, 1989-1990, 2000-2013])
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
@@ -97,9 +95,18 @@ m4_define([b4_yyerror_arg_loc_if],
# Arguments passed to yyerror: user args plus yylloc.
m4_define([b4_yyerror_args],
[b4_yyerror_arg_loc_if([&yylloc, ])dnl
m4_ifset([b4_parse_param], [b4_args(b4_parse_param), ])])
m4_ifset([b4_parse_param], [b4_c_args(b4_parse_param), ])])
# b4_lex_param
# ------------
# Accumulate in b4_lex_param all the yylex arguments.
# b4_lex_param arrives quoted twice, but we want to keep only one level.
m4_define([b4_lex_param],
m4_dquote(b4_pure_if([[[[YYSTYPE *]], [[&yylval]]][]dnl
b4_locations_if([, [[YYLTYPE *], [&yylloc]]])m4_ifdef([b4_lex_param], [, ])])dnl
m4_ifdef([b4_lex_param], b4_lex_param)))
## ------------ ##
## Data Types. ##
@@ -120,7 +127,7 @@ m4_define([b4_int_type],
m4_eval([0 <= $1]), [1], [unsigned int],
[int])])
[int])])
## ----------------- ##
@@ -132,7 +139,7 @@ m4_define([b4_int_type],
# --------------------
# Expansion of $<TYPE>$.
m4_define([b4_lhs_value],
[b4_symbol_value(yyval, [$1])])
[(yyval[]m4_ifval([$1], [.$1]))])
# b4_rhs_value(RULE-LENGTH, NUM, [TYPE])
@@ -140,7 +147,7 @@ m4_define([b4_lhs_value],
# Expansion of $<TYPE>NUM, where the current rule has RULE-LENGTH
# symbols on RHS.
m4_define([b4_rhs_value],
[b4_symbol_value([yyvsp@{b4_subtract([$2], [$1])@}], [$3])])
[(yyvsp@{($2) - ($1)@}m4_ifval([$3], [.$3]))])
@@ -160,7 +167,7 @@ m4_define([b4_lhs_location],
# Expansion of @NUM, where the current rule has RULE-LENGTH symbols
# on RHS.
m4_define([b4_rhs_location],
[(yylsp@{b4_subtract([$2], [$1])@})])
[(yylsp@{($2) - ($1)@})])
## -------------- ##
@@ -267,19 +274,19 @@ enum { YYPUSH_MORE = 4 };
typedef struct ]b4_prefix[pstate ]b4_prefix[pstate;
]b4_pull_if([b4_function_declare([b4_prefix[parse]], [[int]], b4_parse_param)
])b4_function_declare([b4_prefix[push_parse]], [[int]],
]b4_pull_if([b4_c_function_decl([b4_prefix[parse]], [[int]], b4_parse_param)
])b4_c_function_decl([b4_prefix[push_parse]], [[int]],
[[b4_prefix[pstate *ps]], [[ps]]]b4_pure_if([,
[[[int pushed_char]], [[pushed_char]]],
[[b4_api_PREFIX[STYPE const *pushed_val]], [[pushed_val]]]b4_locations_if([,
[[b4_api_PREFIX[LTYPE *pushed_loc]], [[pushed_loc]]]])])m4_ifset([b4_parse_param], [,
b4_parse_param]))
b4_pull_if([b4_function_declare([b4_prefix[pull_parse]], [[int]],
b4_pull_if([b4_c_function_decl([b4_prefix[pull_parse]], [[int]],
[[b4_prefix[pstate *ps]], [[ps]]]m4_ifset([b4_parse_param], [,
b4_parse_param]))])
b4_function_declare([b4_prefix[pstate_new]], [b4_prefix[pstate *]],
b4_c_function_decl([b4_prefix[pstate_new]], [b4_prefix[pstate *]],
[[[void]], []])
b4_function_declare([b4_prefix[pstate_delete]], [[void]],
b4_c_function_decl([b4_prefix[pstate_delete]], [[void]],
[[b4_prefix[pstate *ps]], [[ps]]])dnl
])
@@ -287,7 +294,13 @@ b4_function_declare([b4_prefix[pstate_delete]], [[void]],
# -------------------
# When not the push parser.
m4_define([b4_declare_yyparse_],
[b4_function_declare(b4_prefix[parse], [int], b4_parse_param)])
[[#ifdef YYPARSE_PARAM
]b4_c_function_decl(b4_prefix[parse], [int],
[[void *YYPARSE_PARAM], [YYPARSE_PARAM]])[
#else /* ! YYPARSE_PARAM */
]b4_c_function_decl(b4_prefix[parse], [int], b4_parse_param)[
#endif /* ! YYPARSE_PARAM */]dnl
])
# b4_declare_yyparse
@@ -306,19 +319,21 @@ m4_define([b4_shared_declarations],
[b4_cpp_guard_open([b4_spec_defines_file])[
]b4_declare_yydebug[
]b4_percent_code_get([[requires]])[
]b4_token_enums_defines[
]b4_token_enums_defines(b4_tokens)[
]b4_declare_yylstype[
]b4_declare_yyparse[
]b4_percent_code_get([[provides]])[
]b4_cpp_guard_close([b4_spec_defines_file])[]dnl
])
## -------------- ##
## Output files. ##
## -------------- ##
b4_output_begin([b4_parser_file_name])
b4_copyright([Bison implementation for Yacc-like parsers in C])[
b4_copyright([Bison implementation for Yacc-like parsers in C],
[1984, 1989-1990, 2000-2013])[
/* C LALR(1) parser skeleton written by Richard Stallman, by
simplifying the original so-called "semantic" parser. */
@@ -346,12 +361,11 @@ m4_if(b4_api_prefix, [yy], [],
#define yypstate ]b4_prefix[pstate]])[
#define yylex ]b4_prefix[lex
#define yyerror ]b4_prefix[error
#define yydebug ]b4_prefix[debug
#define yynerrs ]b4_prefix[nerrs
]]b4_pure_if([], [[
#define yylval ]b4_prefix[lval
#define yychar ]b4_prefix[char]b4_locations_if([[
#define yylloc ]b4_prefix[lloc]])]))[
#define yychar ]b4_prefix[char
#define yydebug ]b4_prefix[debug
#define yynerrs ]b4_prefix[nerrs]b4_locations_if([[
#define yylloc ]b4_prefix[lloc]])])[
/* Copy the first part of user declarations. */
]b4_user_pre_prologue[
@@ -363,7 +377,7 @@ m4_if(b4_api_prefix, [yy], [],
# undef YYERROR_VERBOSE
# define YYERROR_VERBOSE 1
#else
# define YYERROR_VERBOSE ]b4_error_verbose_if([1], [0])[
# define YYERROR_VERBOSE ]b4_error_verbose_flag[
#endif
]m4_ifval(m4_quote(b4_spec_defines_file),
@@ -388,8 +402,10 @@ typedef unsigned char yytype_uint8;
#ifdef YYTYPE_INT8
typedef YYTYPE_INT8 yytype_int8;
#else
#elif ]b4_c_modern[
typedef signed char yytype_int8;
#else
typedef short int yytype_int8;
#endif
#ifdef YYTYPE_UINT16
@@ -409,7 +425,7 @@ typedef short int yytype_int16;
# define YYSIZE_T __SIZE_TYPE__
# elif defined size_t
# define YYSIZE_T size_t
# elif ! defined YYSIZE_T
# elif ! defined YYSIZE_T && ]b4_c_modern[
# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
# define YYSIZE_T size_t
# else
@@ -431,11 +447,16 @@ typedef short int yytype_int16;
# endif
#endif
/* Suppress unused-variable warnings by "using" E. */
#ifdef __GNUC__
# define YYUSE(E) ((void) (E))
]b4_attribute_define[
/* Identity function, used to suppress warnings about constant conditions. */
#ifndef lint
# define YYID(N) (N)
#else
# define YYUSE(E) /* empty */
]b4_c_function_def([YYID], [static int], [[int yyi], [yyi]])[
{
return yyi;
}
#endif
#if ]b4_lac_if([[1]], [[! defined yyoverflow || YYERROR_VERBOSE]])[
@@ -456,7 +477,7 @@ b4_push_if([], [b4_lac_if([], [[
# define alloca _alloca
# else
# define YYSTACK_ALLOC alloca
# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS
# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS && ]b4_c_modern[
# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
/* Use EXIT_SUCCESS as a witness for stdlib.h. */
# ifndef EXIT_SUCCESS
@@ -469,7 +490,7 @@ b4_push_if([], [b4_lac_if([], [[
# ifdef YYSTACK_ALLOC
/* Pacify GCC's `empty if-body' warning. */
# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0))
# ifndef YYSTACK_ALLOC_MAXIMUM
/* The OS might guarantee only one guard page at the bottom of the stack,
and a page size can be as small as 4096 bytes. So we cannot safely
@@ -485,7 +506,7 @@ b4_push_if([], [b4_lac_if([], [[
# endif
# if (defined __cplusplus && ! defined EXIT_SUCCESS \
&& ! ((defined YYMALLOC || defined malloc) \
&& (defined YYFREE || defined free)))
&& (defined YYFREE || defined free)))
# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
# ifndef EXIT_SUCCESS
# define EXIT_SUCCESS 0
@@ -493,13 +514,13 @@ b4_push_if([], [b4_lac_if([], [[
# endif
# ifndef YYMALLOC
# define YYMALLOC malloc
# if ! defined malloc && ! defined EXIT_SUCCESS
# if ! defined malloc && ! defined EXIT_SUCCESS && ]b4_c_modern[
void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
# endif
# endif
# ifndef YYFREE
# define YYFREE free
# if ! defined free && ! defined EXIT_SUCCESS
# if ! defined free && ! defined EXIT_SUCCESS && ]b4_c_modern[
void free (void *); /* INFRINGES ON USER NAME SPACE */
# endif
# endif
@@ -510,8 +531,8 @@ void free (void *); /* INFRINGES ON USER NAME SPACE */
#if (! defined yyoverflow \
&& (! defined __cplusplus \
|| (]b4_locations_if([[defined ]b4_api_PREFIX[LTYPE_IS_TRIVIAL && ]b4_api_PREFIX[LTYPE_IS_TRIVIAL \
&& ]])[defined ]b4_api_PREFIX[STYPE_IS_TRIVIAL && ]b4_api_PREFIX[STYPE_IS_TRIVIAL)))
|| (]b4_locations_if([[defined ]b4_api_PREFIX[LTYPE_IS_TRIVIAL && ]b4_api_PREFIX[LTYPE_IS_TRIVIAL \
&& ]])[defined ]b4_api_PREFIX[STYPE_IS_TRIVIAL && ]b4_api_PREFIX[STYPE_IS_TRIVIAL)))
/* A type that is properly aligned for any stack member. */
union yyalloc
@@ -541,16 +562,16 @@ union yyalloc
elements in the stack, and YYPTR gives the new location of the
stack. Advance YYPTR to a properly aligned location for the next
stack. */
# define YYSTACK_RELOCATE(Stack_alloc, Stack) \
do \
{ \
YYSIZE_T yynewbytes; \
YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \
Stack = &yyptr->Stack_alloc; \
yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
yyptr += yynewbytes / sizeof (*yyptr); \
} \
while (0)
# define YYSTACK_RELOCATE(Stack_alloc, Stack) \
do \
{ \
YYSIZE_T yynewbytes; \
YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \
Stack = &yyptr->Stack_alloc; \
yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
yyptr += yynewbytes / sizeof (*yyptr); \
} \
while (YYID (0))
#endif
@@ -569,7 +590,7 @@ union yyalloc
for (yyi = 0; yyi < (Count); yyi++) \
(Dst)[yyi] = (Src)[yyi]; \
} \
while (0)
while (YYID (0))
# endif
# endif
#endif /* !YYCOPY_NEEDED */
@@ -585,27 +606,41 @@ union yyalloc
#define YYNNTS ]b4_nterms_number[
/* YYNRULES -- Number of rules. */
#define YYNRULES ]b4_rules_number[
/* YYNSTATES -- Number of states. */
/* YYNRULES -- Number of states. */
#define YYNSTATES ]b4_states_number[
/* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned
by yylex, with out-of-bounds checking. */
/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
#define YYUNDEFTOK ]b4_undef_token_number[
#define YYMAXUTOK ]b4_user_token_number_max[
#define YYTRANSLATE(YYX) \
#define YYTRANSLATE(YYX) \
((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM
as returned by yylex, without out-of-bounds checking. */
/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */
static const ]b4_int_type_for([b4_translate])[ yytranslate[] =
{
]b4_translate[
};
#if ]b4_api_PREFIX[DEBUG
]b4_integral_parser_table_define([rline], [b4_rline],
[[YYRLINE[YYN] -- Source line where rule number YYN was defined.]])[
/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
YYRHS. */
static const ]b4_int_type_for([b4_prhs])[ yyprhs[] =
{
]b4_prhs[
};
/* YYRHS -- A `-1'-separated list of the rules' RHS. */
static const ]b4_int_type_for([b4_rhs])[ yyrhs[] =
{
]b4_rhs[
};
/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
static const ]b4_int_type_for([b4_rline])[ yyrline[] =
{
]b4_rline[
};
#endif
#if ]b4_api_PREFIX[DEBUG || YYERROR_VERBOSE || ]b4_token_table_flag[
@@ -618,35 +653,105 @@ static const char *const yytname[] =
#endif
# ifdef YYPRINT
/* YYTOKNUM[NUM] -- (External) token number corresponding to the
(internal) symbol number NUM (which must be that of a token). */
/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
token YYLEX-NUM. */
static const ]b4_int_type_for([b4_toknum])[ yytoknum[] =
{
]b4_toknum[
};
# endif
/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
static const ]b4_int_type_for([b4_r1])[ yyr1[] =
{
]b4_r1[
};
/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
static const ]b4_int_type_for([b4_r2])[ yyr2[] =
{
]b4_r2[
};
/* YYDEFACT[STATE-NAME] -- Default reduction number in state STATE-NUM.
Performed when YYTABLE doesn't specify something else to do. Zero
means the default is an error. */
static const ]b4_int_type_for([b4_defact])[ yydefact[] =
{
]b4_defact[
};
/* YYDEFGOTO[NTERM-NUM]. */
static const ]b4_int_type_for([b4_defgoto])[ yydefgoto[] =
{
]b4_defgoto[
};
/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
STATE-NUM. */
#define YYPACT_NINF ]b4_pact_ninf[
static const ]b4_int_type_for([b4_pact])[ yypact[] =
{
]b4_pact[
};
/* YYPGOTO[NTERM-NUM]. */
static const ]b4_int_type_for([b4_pgoto])[ yypgoto[] =
{
]b4_pgoto[
};
/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
positive, shift that token. If negative, reduce the rule which
number is the opposite. If YYTABLE_NINF, syntax error. */
#define YYTABLE_NINF ]b4_table_ninf[
static const ]b4_int_type_for([b4_table])[ yytable[] =
{
]b4_table[
};
#define yypact_value_is_default(Yystate) \
]b4_table_value_equals([[pact]], [[Yystate]], [b4_pact_ninf])[
#define YYTABLE_NINF ]b4_table_ninf[
#define yytable_value_is_error(Yytable_value) \
]b4_table_value_equals([[table]], [[Yytable_value]], [b4_table_ninf])[
]b4_parser_tables_define[
static const ]b4_int_type_for([b4_check])[ yycheck[] =
{
]b4_check[
};
#define yyerrok (yyerrstatus = 0)
#define yyclearin (yychar = YYEMPTY)
#define YYEMPTY (-2)
#define YYEOF 0
/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
symbol of state STATE-NUM. */
static const ]b4_int_type_for([b4_stos])[ yystos[] =
{
]b4_stos[
};
#define YYACCEPT goto yyacceptlab
#define YYABORT goto yyabortlab
#define YYERROR goto yyerrorlab
#define yyerrok (yyerrstatus = 0)
#define yyclearin (yychar = YYEMPTY)
#define YYEMPTY (-2)
#define YYEOF 0
#define YYACCEPT goto yyacceptlab
#define YYABORT goto yyabortlab
#define YYERROR goto yyerrorlab
/* Like YYERROR except do call yyerror. This remains here temporarily
to ease the transition to the new meaning of YYERROR, for GCC.
Once GCC version 2 has supplanted version 1, this can go. However,
YYFAIL appears to be in use. Nevertheless, it is formally deprecated
in Bison 2.4.2's NEWS entry, where a plan to phase it out is
discussed. */
#define YYFAIL goto yyerrlab
#if defined YYFAIL
/* This is here to suppress warnings from the GCC cpp's
-Wunused-macros. Normally we don't worry about that warning, but
some users do, and we want to make it easy for users to remove
YYFAIL uses, which will produce warnings from Bison 2.5. */
#endif
#define YYRECOVERING() (!!yyerrstatus)
@@ -664,18 +769,26 @@ do \
else \
{ \
yyerror (]b4_yyerror_args[YY_("syntax error: cannot back up")); \
YYERROR; \
} \
while (0)
YYERROR; \
} \
while (YYID (0))
/* Error token number */
#define YYTERROR 1
#define YYERRCODE 256
#define YYTERROR 1
#define YYERRCODE 256
]b4_locations_if([[
]b4_yylloc_default_define[
#define YYRHSLOC(Rhs, K) ((Rhs)[K])
]])[
]b4_yy_location_print_define[
/* YYLEX -- calling `yylex' with the right arguments. */
#ifdef YYLEX_PARAM
# define YYLEX yylex (]b4_pure_if([&yylval[]b4_locations_if([, &yylloc]), ])[YYLEX_PARAM)
#else
# define YYLEX ]b4_c_function_call([yylex], [int], b4_lex_param)[
#endif
/* Enable debugging if requested. */
#if ]b4_api_PREFIX[DEBUG
@@ -685,35 +798,33 @@ while (0)
# define YYFPRINTF fprintf
# endif
# define YYDPRINTF(Args) \
do { \
if (yydebug) \
YYFPRINTF Args; \
} while (0)
# define YYDPRINTF(Args) \
do { \
if (yydebug) \
YYFPRINTF Args; \
} while (YYID (0))
]b4_yy_location_print_define[
# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \
do { \
if (yydebug) \
{ \
YYFPRINTF (stderr, "%s ", Title); \
yy_symbol_print (stderr, \
Type, Value]b4_locations_if([, Location])[]b4_user_args[); \
YYFPRINTF (stderr, "\n"); \
} \
} while (YYID (0))
# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \
do { \
if (yydebug) \
{ \
YYFPRINTF (stderr, "%s ", Title); \
yy_symbol_print (stderr, \
Type, Value]b4_locations_if([, Location])[]b4_user_args[); \
YYFPRINTF (stderr, "\n"); \
} \
} while (0)
]b4_yy_symbol_print_define[
]b4_yy_symbol_print_generate([b4_c_function_def])[
/*------------------------------------------------------------------.
| yy_stack_print -- Print the state stack from its BOTTOM up to its |
| TOP (included). |
`------------------------------------------------------------------*/
]b4_function_define([yy_stack_print], [static void],
[[yytype_int16 *yybottom], [yybottom]],
[[yytype_int16 *yytop], [yytop]])[
]b4_c_function_def([yy_stack_print], [static void],
[[yytype_int16 *yybottom], [yybottom]],
[[yytype_int16 *yytop], [yytop]])[
{
YYFPRINTF (stderr, "Stack now");
for (; yybottom <= yytop; yybottom++)
@@ -724,47 +835,45 @@ do { \
YYFPRINTF (stderr, "\n");
}
# define YY_STACK_PRINT(Bottom, Top) \
do { \
if (yydebug) \
yy_stack_print ((Bottom), (Top)); \
} while (0)
# define YY_STACK_PRINT(Bottom, Top) \
do { \
if (yydebug) \
yy_stack_print ((Bottom), (Top)); \
} while (YYID (0))
/*------------------------------------------------.
| Report that the YYRULE is going to be reduced. |
`------------------------------------------------*/
]b4_function_define([yy_reduce_print], [static void],
[[yytype_int16 *yyssp], [yyssp]],
[[YYSTYPE *yyvsp], [yyvsp]],
]b4_c_function_def([yy_reduce_print], [static void],
[[YYSTYPE *yyvsp], [yyvsp]],
b4_locations_if([[[YYLTYPE *yylsp], [yylsp]],
])[[int yyrule], [yyrule]]m4_ifset([b4_parse_param], [,
b4_parse_param]))[
])[[int yyrule], [yyrule]]m4_ifset([b4_parse_param], [,
b4_parse_param]))[
{
unsigned long int yylno = yyrline[yyrule];
int yynrhs = yyr2[yyrule];
int yyi;
unsigned long int yylno = yyrline[yyrule];
YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
yyrule - 1, yylno);
yyrule - 1, yylno);
/* The symbols being reduced. */
for (yyi = 0; yyi < yynrhs; yyi++)
{
YYFPRINTF (stderr, " $%d = ", yyi + 1);
yy_symbol_print (stderr,
yystos[yyssp[yyi + 1 - yynrhs]],
&]b4_rhs_value(yynrhs, yyi + 1)[
]b4_locations_if([, &]b4_rhs_location(yynrhs, yyi + 1))[]dnl
b4_user_args[);
yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
&]b4_rhs_value(yynrhs, yyi + 1)[
]b4_locations_if([, &]b4_rhs_location(yynrhs, yyi + 1))[]dnl
b4_user_args[);
YYFPRINTF (stderr, "\n");
}
}
# define YY_REDUCE_PRINT(Rule) \
do { \
if (yydebug) \
yy_reduce_print (yyssp, yyvsp, ]b4_locations_if([yylsp, ])[Rule]b4_user_args[); \
} while (0)
# define YY_REDUCE_PRINT(Rule) \
do { \
if (yydebug) \
yy_reduce_print (yyvsp, ]b4_locations_if([yylsp, ])[Rule]b4_user_args[); \
} while (YYID (0))
/* Nonzero means print parse trace. It is left uninitialized so that
multiple parsers can coexist. */
@@ -778,7 +887,7 @@ int yydebug;
/* YYINITDEPTH -- initial size of the parser's stacks. */
#ifndef YYINITDEPTH
#ifndef YYINITDEPTH
# define YYINITDEPTH ]b4_stack_depth_init[
#endif
@@ -898,7 +1007,7 @@ do { \
goto yyerrlab; \
} \
} \
} while (0)
} while (YYID (0))
/* Discard any previous initial lookahead context because of Event,
which may be a lookahead change or an invalidation of the currently
@@ -921,7 +1030,7 @@ do { \
Event "\n"); \
yy_lac_established = 0; \
} \
} while (0)
} while (YYID (0))
#else
# define YY_LAC_DISCARD(Event) yy_lac_established = 0
#endif
@@ -1037,7 +1146,7 @@ yy_lac (yytype_int16 *yyesa, yytype_int16 **yyes,
# define yystrlen strlen
# else
/* Return the length of YYSTR. */
]b4_function_define([yystrlen], [static YYSIZE_T],
]b4_c_function_def([yystrlen], [static YYSIZE_T],
[[const char *yystr], [yystr]])[
{
YYSIZE_T yylen;
@@ -1054,7 +1163,7 @@ yy_lac (yytype_int16 *yyesa, yytype_int16 **yyes,
# else
/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
YYDEST. */
]b4_function_define([yystpcpy], [static char *],
]b4_c_function_def([yystpcpy], [static char *],
[[char *yydest], [yydest]], [[const char *yysrc], [yysrc]])[
{
char *yyd = yydest;
@@ -1085,27 +1194,27 @@ yytnamerr (char *yyres, const char *yystr)
char const *yyp = yystr;
for (;;)
switch (*++yyp)
{
case '\'':
case ',':
goto do_not_strip_quotes;
switch (*++yyp)
{
case '\'':
case ',':
goto do_not_strip_quotes;
case '\\':
if (*++yyp != '\\')
goto do_not_strip_quotes;
/* Fall through. */
default:
if (yyres)
yyres[yyn] = *yyp;
yyn++;
break;
case '\\':
if (*++yyp != '\\')
goto do_not_strip_quotes;
/* Fall through. */
default:
if (yyres)
yyres[yyn] = *yyp;
yyn++;
break;
case '"':
if (yyres)
yyres[yyn] = '\0';
return yyn;
}
case '"':
if (yyres)
yyres[yyn] = '\0';
return yyn;
}
do_not_strip_quotes: ;
}
@@ -1143,6 +1252,10 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
int yycount = 0;
/* There are many possibilities here to consider:
- Assume YYFAIL is not used. It's too flawed to consider. See
<http://lists.gnu.org/archive/html/bison-patches/2009-12/msg00024.html>
for details. YYERROR is fine as it does not invoke this
function.
- If this state is a consistent state with a default action, then
the only way this function was invoked is if the default action
is an error action. In that case, don't check for expected
@@ -1277,7 +1390,7 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
}
#endif /* YYERROR_VERBOSE */
]b4_yydestruct_define[
]b4_yydestruct_generate([b4_c_function_def])[
]b4_pure_if([], [
@@ -1292,13 +1405,13 @@ struct yypstate
static char yypstate_allocated = 0;]])b4_pull_if([
b4_function_define([[yyparse]], [[int]], b4_parse_param)[
b4_c_function_def([[yyparse]], [[int]], b4_parse_param)[
{
return yypull_parse (YY_NULL]m4_ifset([b4_parse_param],
[[, ]b4_args(b4_parse_param)])[);
[[, ]b4_c_args(b4_parse_param)])[);
}
]b4_function_define([[yypull_parse]], [[int]],
]b4_c_function_def([[yypull_parse]], [[int]],
[[[yypstate *yyps]], [[yyps]]]m4_ifset([b4_parse_param], [,
b4_parse_param]))[
{
@@ -1322,9 +1435,9 @@ b4_function_define([[yyparse]], [[int]], b4_parse_param)[
}
}
do {
yychar = ]b4_lex[;
yychar = YYLEX;
yystatus =
yypush_parse (yyps_local]b4_pure_if([[, yychar, &yylval]b4_locations_if([[, &yylloc]])])m4_ifset([b4_parse_param], [, b4_args(b4_parse_param)])[);
yypush_parse (yyps_local]b4_pure_if([[, yychar, &yylval]b4_locations_if([[, &yylloc]])])m4_ifset([b4_parse_param], [, b4_c_args(b4_parse_param)])[);
} while (yystatus == YYPUSH_MORE);
if (!yyps)
yypstate_delete (yyps_local);
@@ -1332,7 +1445,7 @@ b4_function_define([[yyparse]], [[int]], b4_parse_param)[
}]])[
/* Initialize the parser data structure. */
]b4_function_define([[yypstate_new]], [[yypstate *]])[
]b4_c_function_def([[yypstate_new]], [[yypstate *]])[
{
yypstate *yyps;]b4_pure_if([], [[
if (yypstate_allocated)
@@ -1345,7 +1458,7 @@ b4_function_define([[yyparse]], [[int]], b4_parse_param)[
return yyps;
}
]b4_function_define([[yypstate_delete]], [[void]],
]b4_c_function_def([[yypstate_delete]], [[void]],
[[[yypstate *yyps]], [[yyps]]])[
{
#ifndef yyoverflow
@@ -1383,7 +1496,7 @@ b4_function_define([[yyparse]], [[int]], b4_parse_param)[
| yypush_parse. |
`---------------*/
]b4_function_define([[yypush_parse]], [[int]],
]b4_c_function_def([[yypush_parse]], [[int]],
[[[yypstate *yyps]], [[yyps]]]b4_pure_if([,
[[[int yypushed_char]], [[yypushed_char]]],
[[[YYSTYPE const *yypushed_val]], [[yypushed_val]]]b4_locations_if([,
@@ -1395,7 +1508,12 @@ b4_function_define([[yyparse]], [[int]], b4_parse_param)[
| yyparse. |
`----------*/
]b4_function_define([yyparse], [int], b4_parse_param)])[
#ifdef YYPARSE_PARAM
]b4_c_function_def([yyparse], [int],
[[void *YYPARSE_PARAM], [YYPARSE_PARAM]])[
#else /* ! YYPARSE_PARAM */
]b4_c_function_def([yyparse], [int], b4_parse_param)[
#endif]])[
{]b4_pure_if([b4_declare_scanner_communication_variables
])b4_push_if([b4_pure_if([], [[
int yypushed_char = yychar;
@@ -1479,26 +1597,26 @@ b4_locations_if([[ yylsp[0] = ]b4_push_if([b4_pure_if([*])yypushed_loc], [yyllo
#ifdef yyoverflow
{
/* Give user a chance to reallocate the stack. Use copies of
these so that the &'s don't force the real ones into
memory. */
YYSTYPE *yyvs1 = yyvs;
yytype_int16 *yyss1 = yyss;]b4_locations_if([
YYLTYPE *yyls1 = yyls;])[
/* Give user a chance to reallocate the stack. Use copies of
these so that the &'s don't force the real ones into
memory. */
YYSTYPE *yyvs1 = yyvs;
yytype_int16 *yyss1 = yyss;]b4_locations_if([
YYLTYPE *yyls1 = yyls;])[
/* Each stack pointer address is followed by the size of the
data in use in that stack, in bytes. This used to be a
conditional around just the two extra args, but that might
be undefined if yyoverflow is a macro. */
yyoverflow (YY_("memory exhausted"),
&yyss1, yysize * sizeof (*yyssp),
&yyvs1, yysize * sizeof (*yyvsp),]b4_locations_if([
&yyls1, yysize * sizeof (*yylsp),])[
&yystacksize);
/* Each stack pointer address is followed by the size of the
data in use in that stack, in bytes. This used to be a
conditional around just the two extra args, but that might
be undefined if yyoverflow is a macro. */
yyoverflow (YY_("memory exhausted"),
&yyss1, yysize * sizeof (*yyssp),
&yyvs1, yysize * sizeof (*yyvsp),]b4_locations_if([
&yyls1, yysize * sizeof (*yylsp),])[
&yystacksize);
]b4_locations_if([
yyls = yyls1;])[
yyss = yyss1;
yyvs = yyvs1;
yyls = yyls1;])[
yyss = yyss1;
yyvs = yyvs1;
}
#else /* no yyoverflow */
# ifndef YYSTACK_RELOCATE
@@ -1506,23 +1624,23 @@ b4_locations_if([[ yylsp[0] = ]b4_push_if([b4_pure_if([*])yypushed_loc], [yyllo
# else
/* Extend the stack our own way. */
if (YYMAXDEPTH <= yystacksize)
goto yyexhaustedlab;
goto yyexhaustedlab;
yystacksize *= 2;
if (YYMAXDEPTH < yystacksize)
yystacksize = YYMAXDEPTH;
yystacksize = YYMAXDEPTH;
{
yytype_int16 *yyss1 = yyss;
union yyalloc *yyptr =
(union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
if (! yyptr)
goto yyexhaustedlab;
YYSTACK_RELOCATE (yyss_alloc, yyss);
YYSTACK_RELOCATE (yyvs_alloc, yyvs);]b4_locations_if([
YYSTACK_RELOCATE (yyls_alloc, yyls);])[
yytype_int16 *yyss1 = yyss;
union yyalloc *yyptr =
(union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
if (! yyptr)
goto yyexhaustedlab;
YYSTACK_RELOCATE (yyss_alloc, yyss);
YYSTACK_RELOCATE (yyvs_alloc, yyvs);]b4_locations_if([
YYSTACK_RELOCATE (yyls_alloc, yyls);])[
# undef YYSTACK_RELOCATE
if (yyss1 != yyssa)
YYSTACK_FREE (yyss1);
if (yyss1 != yyssa)
YYSTACK_FREE (yyss1);
}
# endif
#endif /* no yyoverflow */
@@ -1532,10 +1650,10 @@ b4_locations_if([[ yylsp[0] = ]b4_push_if([b4_pure_if([*])yypushed_loc], [yyllo
yylsp = yyls + yysize - 1;])[
YYDPRINTF ((stderr, "Stack size increased to %lu\n",
(unsigned long int) yystacksize));
(unsigned long int) yystacksize));
if (yyss + yystacksize - 1 <= yyssp)
YYABORT;
YYABORT;
}
YYDPRINTF ((stderr, "Entering state %d\n", yystate));
@@ -1583,7 +1701,7 @@ yyread_pushed_token:]])[
yylval = *yypushed_val;]b4_locations_if([[
if (yypushed_loc)
yylloc = *yypushed_loc;]])])], [[
yychar = ]b4_lex[;]])[
yychar = YYLEX;]])[
}
if (yychar <= YYEOF)
@@ -1717,9 +1835,9 @@ yyreduce:
goto yynewstate;
/*--------------------------------------.
| yyerrlab -- here on detecting error. |
`--------------------------------------*/
/*------------------------------------.
| yyerrlab -- here on detecting error |
`------------------------------------*/
yyerrlab:
/* Make sure we have latest lookahead translation. See comments at
user semantic actions for why this is necessary. */
@@ -1773,20 +1891,20 @@ yyerrlab:
if (yyerrstatus == 3)
{
/* If just tried and failed to reuse lookahead token after an
error, discard it. */
error, discard it. */
if (yychar <= YYEOF)
{
/* Return failure if at end of input. */
if (yychar == YYEOF)
YYABORT;
}
{
/* Return failure if at end of input. */
if (yychar == YYEOF)
YYABORT;
}
else
{
yydestruct ("Error: discarding",
yytoken, &yylval]b4_locations_if([, &yylloc])[]b4_user_args[);
yychar = YYEMPTY;
}
{
yydestruct ("Error: discarding",
yytoken, &yylval]b4_locations_if([, &yylloc])[]b4_user_args[);
yychar = YYEMPTY;
}
}
/* Else will try to reuse lookahead token after shifting the error
@@ -1806,7 +1924,7 @@ yyerrorlab:
goto yyerrorlab;
]b4_locations_if([[ yyerror_range[1] = yylsp[1-yylen];
]])[ /* Do not reclaim the symbols of the rule whose action triggered
]])[ /* Do not reclaim the symbols of the rule which action triggered
this YYERROR. */
YYPOPSTACK (yylen);
yylen = 0;
@@ -1819,29 +1937,29 @@ yyerrorlab:
| yyerrlab1 -- common code for both syntax error and YYERROR. |
`-------------------------------------------------------------*/
yyerrlab1:
yyerrstatus = 3; /* Each real token shifted decrements this. */
yyerrstatus = 3; /* Each real token shifted decrements this. */
for (;;)
{
yyn = yypact[yystate];
if (!yypact_value_is_default (yyn))
{
yyn += YYTERROR;
if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
{
yyn = yytable[yyn];
if (0 < yyn)
break;
}
}
{
yyn += YYTERROR;
if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
{
yyn = yytable[yyn];
if (0 < yyn)
break;
}
}
/* Pop the current state because it cannot handle the error token. */
if (yyssp == yyss)
YYABORT;
YYABORT;
]b4_locations_if([[ yyerror_range[1] = *yylsp;]])[
yydestruct ("Error: popping",
yystos[yystate], yyvsp]b4_locations_if([, yylsp])[]b4_user_args[);
yystos[yystate], yyvsp]b4_locations_if([, yylsp])[]b4_user_args[);
YYPOPSTACK (1);
yystate = *yyssp;
YY_STACK_PRINT (yyss, yyssp);
@@ -1901,14 +2019,14 @@ yyreturn:
yydestruct ("Cleanup: discarding lookahead",
yytoken, &yylval]b4_locations_if([, &yylloc])[]b4_user_args[);
}
/* Do not reclaim the symbols of the rule whose action triggered
/* Do not reclaim the symbols of the rule which action triggered
this YYABORT or YYACCEPT. */
YYPOPSTACK (yylen);
YY_STACK_PRINT (yyss, yyssp);
while (yyssp != yyss)
{
yydestruct ("Cleanup: popping",
yystos[*yyssp], yyvsp]b4_locations_if([, yylsp])[]b4_user_args[);
yystos[*yyssp], yyvsp]b4_locations_if([, yylsp])[]b4_user_args[);
YYPOPSTACK (1);
}
#ifndef yyoverflow
@@ -1924,15 +2042,19 @@ yypushreturn:]])[
if (yymsg != yymsgbuf)
YYSTACK_FREE (yymsg);
#endif
return yyresult;
/* Make sure YYID is used. */
return YYID (yyresult);
}
]b4_epilogue[]dnl
b4_output_end()
b4_defines_if(
[b4_output_begin([b4_spec_defines_file])[
]b4_copyright([Bison interface for Yacc-like parsers in C])[
]b4_copyright([Bison interface for Yacc-like parsers in C],
[1984, 1989-1990, 2000-2013])[
]b4_shared_declarations[
]b4_output_end()
])# b4_defines_if
])
-27
View File
@@ -1,27 +0,0 @@
## Copyright (C) 2008-2013 Free Software Foundation, Inc.
## This program is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with this program. If not, see <http://www.gnu.org/licenses/>.
EXTRA_DIST += \
djgpp/Makefile.maint \
djgpp/README.in \
djgpp/config.bat \
djgpp/config.sed \
djgpp/config.site \
djgpp/config_h.sed \
djgpp/djunpack.bat \
djgpp/fnchange.lst \
djgpp/subpipe.c \
djgpp/subpipe.h \
djgpp/testsuite.sed
+2 -1
View File
@@ -1,12 +1,13 @@
/*~
/.dirstamp
/Makefile
/Makefile.in
/bison.1
/bison.aux
/bison.cp
/bison.cps
/bison.dvi
/bison.fn
/bison.help
/bison.html
/bison.info
/bison.ky
+169 -955
View File
File diff suppressed because it is too large Load Diff
+155
View File
@@ -0,0 +1,155 @@
## Process this file with automake to produce Makefile.in -*-Makefile-*-
## Copyright (C) 2001-2003, 2005-2013 Free Software Foundation, Inc.
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
AM_MAKEINFOFLAGS = --no-split
info_TEXINFOS = bison.texi
bison_TEXINFOS = $(srcdir)/cross-options.texi gpl-3.0.texi fdl.texi
CLEANFILES = bison.fns
CLEANDIRS = *.t2d
clean-local:
rm -rf $(CLEANDIRS)
CROSS_OPTIONS_PL = $(top_srcdir)/build-aux/cross-options.pl
$(srcdir)/cross-options.texi: $(top_srcdir)/src/getargs.c $(CROSS_OPTIONS_PL)
$(AM_V_GEN)mv -f $@ $@~ || : >$@~
$(AM_V_at)rm -f $@.tmp
$(AM_V_at)cd $(top_builddir)/src && $(MAKE) $(AM_MAKEFLAGS) bison
$(AM_V_at)$(top_builddir)/src/bison --help \
| $(PERL) $(CROSS_OPTIONS_PL) $(top_srcdir)/src/scan-gram.l >$@.tmp
$(AM_V_at)diff -u $@~ $@.tmp || true
$(AM_V_at)mv $@.tmp $@
MAINTAINERCLEANFILES = $(srcdir)/cross-options.texi
## ---------- ##
## Ref card. ##
## ---------- ##
EXTRA_DIST = refcard.tex
CLEANFILES += refcard.dvi refcard.log refcard.ps
refcard.dvi: refcard.tex
$(AM_V_GEN)tex refcard.tex
refcard.ps: refcard.dvi
## ----------- ##
## Man Pages. ##
## ----------- ##
dist_man_MANS = $(srcdir)/bison.1
EXTRA_DIST += $(dist_man_MANS:.1=.x) common.x
MAINTAINERCLEANFILES += $(dist_man_MANS)
# Depend on configure to get version number changes.
common_dep = $(top_srcdir)/configure $(srcdir)/common.x
srcsrcdir = $(top_srcdir)/bin
$(srcdir)/bison.1: $(common_dep) $(top_srcdir)/src/getargs.c
# Differences to ignore when comparing the man page (the date).
remove_time_stamp = \
sed 's/^\(\.TH[^"]*"[^"]*"[^"]*\)"[^"]*"/\1/'
MOSTLYCLEANFILES = $(srcdir)/*.t
SUFFIXES = .x .1
PREPATH = $(top_builddir)/src
.x.1:
$(AM_V_GEN)program=`expr "/$*" : '.*/\(.*\)'` && \
save_IFS=$IFS; \
IFS=$(PATH_SEPARATOR); \
for dir in $(PREPATH); do \
IFS=$save_IFS; \
echo cd $$dir '&&' $(MAKE) $(AM_MAKEFLAGS) $$program && \
(cd $$dir && $(MAKE) $(AM_MAKEFLAGS) $$program) || exit; \
done
$(AM_V_at)PATH="$(PREPATH)$(PATH_SEPARATOR)$$PATH"; \
export PATH; \
$(HELP2MAN) \
--include=$*.x \
--include=$(srcdir)/common.x \
--output=$@.t `echo '$*' | sed 's,.*/,,'`
$(AM_V_at)if $(remove_time_stamp) $@ >$@a.t 2>/dev/null && \
$(remove_time_stamp) $@.t | cmp $@a.t - >/dev/null 2>&1; then \
touch $@; \
else \
mv $@.t $@; \
fi
$(AM_V_at)rm -f $@*.t
nodist_man_MANS = yacc.1
## ------------------------------ ##
## Graphviz examples generation. ##
## ------------------------------ ##
CLEANDIRS += figs
FIGS_DOT = figs/example.dot figs/example-reduce.dot figs/example-shift.dot
EXTRA_DIST += \
figs/example.y \
$(FIGS_DOT) \
$(FIGS_DOT:.dot=.eps) $(FIGS_DOT:.dot=.pdf) $(FIGS_DOT:.dot=.png)
SUFFIXES += .dot .eps .pdf .png
bison.dvi: $(FIGS_DOT:.dot=.eps)
bison.html: $(FIGS_DOT:.dot=.png)
bison.pdf: $(FIGS_DOT:.dot=.pdf)
.dot.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:
$(AM_V_GEN) $(MKDIR_P) `echo "./$@" | sed -e 's,/[^/]*$$,,'`
$(AM_V_at) $(DOT) -Gmargin=0 -Tpdf $< >$@.tmp
$(AM_V_at) mv $@.tmp $@
.dot.png:
$(AM_V_GEN) $(MKDIR_P) `echo "./$@" | sed -e 's,/[^/]*$$,,'`
$(AM_V_at) $(DOT) -Gmargin=0 -Tpng $< >$@.tmp
$(AM_V_at) mv $@.tmp $@
## -------------- ##
## Doxygenation. ##
## -------------- ##
DOXYGEN = doxygen
.PHONY: doc html
doc: html
html-local: Doxyfile
$(DOXYGEN)
edit = sed -e 's,@PACKAGE_NAME\@,$(PACKAGE_NAME),g' \
-e 's,@PACKAGE_VERSION\@,$(PACKAGE_VERSION),g' \
-e 's,@top_builddir\@,$(top_builddir),g' \
-e 's,@top_srcdir\@,$(top_srcdir),g'
EXTRA_DIST += Doxyfile.in
CLEANFILES += Doxyfile
# Sed is used to generate Doxyfile from Doxyfile.in instead of
# configure, because the former is way faster than the latter.
Doxyfile: $(srcdir)/Doxyfile.in
$(AM_V_GEN)$(edit) $(srcdir)/Doxyfile.in >Doxyfile
CLEANDIRS += html latex
+432 -1133
View File
File diff suppressed because it is too large Load Diff
+1 -6
View File
@@ -39,7 +39,7 @@ This description of the options that can be given to
is adapted from the node
.B Invocation
in the
.B bison.texi
.B bison.texinfo
manual, which should be taken as authoritative.
.PP
.I Bison
@@ -53,8 +53,3 @@ are unique. When a long option takes an argument, like
.BR \-\-file-prefix ,
connect the option name and the argument with
.BR = .
[see also]
.BR lex (1),
.BR flex (1),
.BR yacc (1).
+4
View File
@@ -0,0 +1,4 @@
[see also]
.BR lex (1),
.BR flex (1),
.BR yacc (1).
-176
View File
@@ -1,176 +0,0 @@
## Copyright (C) 2001-2003, 2005-2013 Free Software Foundation, Inc.
## This program is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with this program. If not, see <http://www.gnu.org/licenses/>.
AM_MAKEINFOFLAGS = --no-split
info_TEXINFOS = doc/bison.texi
doc_bison_TEXINFOS = \
$(CROSS_OPTIONS_TEXI) \
doc/fdl.texi \
doc/gpl-3.0.texi
# 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)
TEXI2DVI = texi2dvi --build-dir=doc/bison.t2d -I doc
CLEANDIRS = doc/bison.t2d
clean-local:
rm -rf $(CLEANDIRS)
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
# 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 $@; } >$@~
$(AM_V_at)test ! -f $@.tmp || rm -f $@.tmp
$(AM_V_at)src/bison$(EXEEXT) --help | \
$(PERL) $(CROSS_OPTIONS_PL) $(top_srcdir)/src/scan-gram.l >$@.tmp
$(AM_V_at)diff -u $@~ $@.tmp || true
$(AM_V_at)mv $@.tmp $@
MAINTAINERCLEANFILES = $(CROSS_OPTIONS_TEXI)
## ---------- ##
## Ref card. ##
## ---------- ##
EXTRA_DIST += doc/refcard.tex
CLEANFILES += doc/refcard.pdf
doc/refcard.pdf: doc/refcard.tex
$(AM_V_GEN) cd doc && pdftex $(abs_top_srcdir)/doc/refcard.tex
## ---------------- ##
## doc/bison.help. ##
## ---------------- ##
# Some of our targets (cross-option.texi, bison.1) use "bison --help".
# Since we want to ship the generated file to avoid additional
# requirements over the user environment, we used not depend on
# src/bison itself, but on src/getargs.c and other files. Yet, we
# need "bison --help" to work to make help2man happy, so we used to
# include "make src/bison" in the commands. Then we may have a
# problem with concurrent builds, since one make might be aiming one
# of its jobs at compiling src/bison, and another job at generating
# the man page. If the latter is faster than the former, then we have
# two makes that concurrently try to compile src/bison. Doomed to
# failure.
#
# As a simple scheme to get our way out, make a stamp file,
# bison.help, which contains --version then --help. This file can
# depend on bison, which ensures its correctness. But update it
# *only* if needed (content changes). This way, we avoid useless
# compilations of cross-option.texi and bison.1. At the cost of
# repeated builds of bison.help.
EXTRA_DIST += $(top_srcdir)/doc/bison.help
MAINTAINERCLEANFILES += $(top_srcdir)/doc/bison.help
$(top_srcdir)/doc/bison.help: src/bison$(EXEEXT)
$(AM_V_GEN)src/bison$(EXEEXT) --version >doc/bison.help.tmp
$(AM_V_at) src/bison$(EXEEXT) --help >>doc/bison.help.tmp
$(AM_V_at)$(top_srcdir)/build-aux/move-if-change doc/bison.help.tmp $@
## ----------- ##
## Man Pages. ##
## ----------- ##
dist_man_MANS = $(top_srcdir)/doc/bison.1
EXTRA_DIST += $(dist_man_MANS:.1=.x)
MAINTAINERCLEANFILES += $(dist_man_MANS)
# Differences to ignore when comparing the man page (the date).
remove_time_stamp = \
sed 's/^\(\.TH[^"]*"[^"]*"[^"]*\)"[^"]*"/\1/'
# Depend on configure to get version number changes.
$(top_srcdir)/doc/bison.1: doc/bison.help doc/bison.x $(top_srcdir)/configure
$(AM_V_GEN)$(HELP2MAN) \
--include=$(top_srcdir)/doc/bison.x \
--output=$@.t src/bison$(EXEEXT)
$(AM_V_at)if $(remove_time_stamp) $@ >$@a.t 2>/dev/null && \
$(remove_time_stamp) $@.t | cmp $@a.t - >/dev/null 2>&1; then \
touch $@; \
else \
mv $@.t $@; \
fi
$(AM_V_at)rm -f $@*.t
nodist_man_MANS = doc/yacc.1
## ----------------------------- ##
## 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
.dot.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:
$(AM_V_GEN) $(MKDIR_P) `echo "./$@" | sed -e 's,/[^/]*$$,,'`
$(AM_V_at) $(DOT) -Gmargin=0 -Tpdf $< >$@.tmp
$(AM_V_at) mv $@.tmp $@
.dot.png:
$(AM_V_GEN) $(MKDIR_P) `echo "./$@" | sed -e 's,/[^/]*$$,,'`
$(AM_V_at) $(DOT) -Gmargin=0 -Tpng $< >$@.tmp
$(AM_V_at) mv $@.tmp $@
## -------------- ##
## Doxygenation. ##
## -------------- ##
DOXYGEN = doxygen
.PHONY: doc html
doc: html
html-local: doc/Doxyfile
$(AM_V_GEN) $(DOXYGEN) doc/Doxyfile
edit = sed -e 's,@PACKAGE_NAME\@,$(PACKAGE_NAME),g' \
-e 's,@PACKAGE_VERSION\@,$(PACKAGE_VERSION),g' \
-e 's,@PERL\@,$(PERL),g' \
-e 's,@top_builddir\@,$(top_builddir),g' \
-e 's,@top_srcdir\@,$(top_srcdir),g'
EXTRA_DIST += doc/Doxyfile.in
CLEANFILES += doc/Doxyfile
# Sed is used to generate Doxyfile from Doxyfile.in instead of
# configure, because the former is way faster than the latter.
doc/Doxyfile: $(top_srcdir)/doc/Doxyfile.in
$(AM_V_GEN) $(edit) $(top_srcdir)/doc/Doxyfile.in >doc/Doxyfile
CLEANDIRS += doc/html
+2
View File
@@ -1 +1,3 @@
/Makefile
/Makefile.in
/bench.pl
+2 -13
View File
@@ -1,7 +1,5 @@
#! /bin/sh
## Copyright (C) 2006, 2009-2013 Free Software Foundation, Inc.
# Copyright (C) 2005-2013 Free Software Foundation, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
@@ -15,13 +13,4 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
cat >input <<EOF
1+2*3
EOF
run 0 7
cat >input <<EOF
(1+2) * 3
EOF
run 0 9
run 0 9 -p
nodist_noinst_SCRIPTS = bench.pl
+35 -800
View File
@@ -17,236 +17,23 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
=head1 NAME
bench.pl - bench marks for Bison parsers.
=head1 SYNOPSIS
./bench.pl [OPTIONS]... DIRECTIVES
=head1 DIRECTIVES
Specify the set of benches to run. The following grammar defines the
I<directives>:
directives ::=
directives | directives -- Alternation
| directives & directives -- Concatenation
| [ directives> ] -- Optional
| ( directives> ) -- Parentheses
| %b PATH -- Use bison at PATH for this bench
| #d NAME[=VALUE] -- %code { #define NAME [VALUE] }
| %d NAME[=VALUE] -- %define NAME ["VALUE"]
| %s skeleton -- %skeleton "skeleton"
| directive
Parentheses only group to override precedence. For instance:
[ %debug ] & [ %error-verbose ] & [ %define variant ]
will generate eight different cases.
=head1 OPTIONS
=over 4
=item B<-b>, B<--bench>
Predefined benches, that is, combimation between a grammar and a I<directives>
request.
=over 4
=item I<push>
Test the push parser vs. the pull interface. Use the C parser.
=item I<variant>
Test the use of variants instead of union in the C++ parser.
=back
=item B<-c>, B<--cflags>=I<flags>
Flags to pass to the C or C++ compiler. Defaults to -O2.
=item B<-d>, B<--directive>=I<directives>
Add a set of Bison directives to bench against each other.
=item B<-g>, B<--grammar>=I<grammar>
Select the base I<grammar> to use. Defaults to I<calc>.
=over 4
=item I<calc>
Traditional calculator.
=item I<list>
C++ grammar that uses std::string and std::list. Can be used with
or without %define variant.
=item I<triangular>
Artificial grammar with very long rules.
=back
=item B<-h>, B<--help>
Display this message and exit succesfully. The more verbose, the more
details.
=item B<-i>, B<--iterations>=I<integer>
Say how many times a single test of the bench must be run. If
negative, specify the minimum number of CPU seconds to run. Defaults
to -1.
=item B<-q>, B<--quiet>
Decrease the verbosity level (defaults to 1).
=item B<-v>, B<--verbose>
Raise the verbosity level (defaults to 1).
=back
=cut
use strict;
use IO::File;
use Benchmark qw (:all);
my $bison = $ENV{'BISON'} || '@abs_top_builddir@/tests/bison';
my $cc = $ENV{'CC'} || 'gcc';
##################################################################
=head1 VARIABLES
=over 4
=item C<@bench>
The list of benches to run.
=item C<$bison>
The Bison program to use to compile the grammar.
=item C<$cc>
The C compiler.
=item C<$cxx>
The C++ compiler.
=item C<$cflags>
Compiler flags (C or C++).
=item C<@directive>
A list of directive sets to measure against each other.
=item C<$iterations>
The number of times the parser is run for a bench.
=item C<$verbose>
Verbosity level.
=back
=cut
my $bench;
my $bison = $ENV{'BISON'} || '@abs_top_builddir@/tests/bison';
my $cc = $ENV{'CC'} || 'gcc';
my $cxx = $ENV{'CXX'} || 'g++';
my $cflags = '-O2';
my @directive = ();
my $grammar = 'calc';
my $iterations = -1;
my $verbose = 1;
=head1 FUNCTIONS
=over 4
=item C<verbose($level, $message)>
Report the C<$message> is C<$level> E<lt>= C<$verbose>.
=cut
sub verbose($$)
sub triangular_grammar ($$$)
{
my ($level, $message) = @_;
print STDERR $message
if $level <= $verbose;
}
######################################################################
=item C<directives($bench, @directive)>
Format the list of directives for Bison for bench named C<$bench>.
=cut
sub directives($@)
{
my ($bench, @directive) = @_;
my $res = "/* Directives for bench `$bench'. */\n";
$res .= join ("\n", @directive) . "\n";
$res .= "/* End of directives for bench `$bench'. */\n";
return $res;
}
######################################################################
=item C<generate_grammar_triangular ($base, $max, @directive)>
Create a large triangular grammar which looks like :
input:
exp { if ($1 != 0) abort (); $$ = $1; }
| input exp { if ($2 != $1 + 1) abort (); $$ = $2; }
;
exp:
END { $$ = 0; }
| "1" END { $$ = 1; }
| "1" "2" END { $$ = 2; }
| "1" "2" "3" END { $$ = 3; }
| "1" "2" "3" "4" END { $$ = 4; }
| "1" "2" "3" "4" "5" END { $$ = 5; }
;
C<$base> is the base name for the file to create (F<$base.y>).
C<$max> is the number of such rules (here, 5). You may pass
additional Bison C<@directive>.
The created parser is self contained: it includes its scanner, and
source of input.
=cut
sub generate_grammar_triangular ($$@)
{
my ($base, $max, @directive) = @_;
my $directives = directives ($base, @directive);
my ($base, $max, $directives) = @_;
my $out = new IO::File ">$base.y"
or die;
print $out <<EOF;
%error-verbose
%debug
%{
#include <stdio.h>
#include <stdlib.h>
@@ -254,7 +41,6 @@ sub generate_grammar_triangular ($$@)
static int yylex (void);
static void yyerror (const char *msg);
%}
$directives
%union
{
int val;
@@ -285,8 +71,8 @@ for my $size (1 .. $max)
{
use Text::Wrap;
print $out wrap ("| ", " ",
(map { "\"$_\"" } (1 .. $size)),
" END \n"),
(map { "\"$_\"" } (1 .. $size)),
" END \n"),
" { \$\$ = $size; }\n";
};
print $out ";\n";
@@ -318,9 +104,7 @@ yyerror (const char *msg)
int
main (void)
{
#if YYDEBUG
yydebug = !!getenv ("YYDEBUG");
#endif
return yyparse ();
}
EOF
@@ -328,15 +112,6 @@ EOF
##################################################################
=item C<calc_input ($base, $max)>
Generate the input file F<$base.input> for the calc parser. The input
is composed of two expressions. The first one is using left recursion
only and consumes no stack. The second one requires a deep stack.
These two expressions are repeated C<$max> times in the output file.
=cut
sub calc_input ($$)
{
my ($base, $max) = @_;
@@ -351,22 +126,9 @@ sub calc_input ($$)
##################################################################
=item C<generate_grammar_calc ($base, $max, @directive)>
Generate a Bison file F<$base.y> for a calculator parser in C. Pass
the additional Bison C<@directive>. C<$max> is ignored, but left to
have the same interface as C<triangular_grammar>.
=cut
sub generate_grammar_calc ($$@)
sub calc_grammar ($$$)
{
my ($base, $max, @directive) = @_;
my $directives = directives ($base, @directive);
# Putting this request here is stupid, since the input will be
# generated each time we generate a grammar.
calc_input ('calc', 200);
my ($base, $max, $directives) = @_;
my $out = new IO::File ">$base.y"
or die;
@@ -386,9 +148,9 @@ static semantic_value global_result = 0;
static int global_count = 0;
%}
/* Exercise %union. */
$directives
%error-verbose
/* Exercise %union. */
%union
{
semantic_value ival;
@@ -412,7 +174,7 @@ static int yylex (void);
%token <ival> NUM "number"
%type <ival> exp
%nonassoc '=' /* comparison */
%nonassoc '=' /* comparison */
%left '-' '+'
%left '*' '/'
%left NEG /* negation--unary minus */
@@ -544,10 +306,6 @@ main (int argc, const char **argv)
int count = 0;
int status;
#if YYDEBUG
yydebug = !!getenv ("YYDEBUG");
#endif
input = fopen ("calc.input", "r");
if (!input)
{
@@ -568,567 +326,44 @@ EOF
##################################################################
=item C<generate_grammar_list ($base, $max, @directive)>
Generate a Bison file F<$base.y> for a C++ parser that uses C++
objects (std::string, std::list). Tailored for using %define variant.
=cut
sub generate_grammar_list ($$@)
{
my ($base, $max, @directive) = @_;
my $directives = directives ($base, @directive);
my $variant = grep { /%define "?variant"?/ } @directive;
my $token_ctor = grep { /%define "?api.token.constructor"?/ } @directive;
my $out = new IO::File ">$base.y"
or die;
print $out <<EOF;
%language "C++"
%defines
%locations
$directives
%code requires // *.h
{
#include <string>
}
%code // *.c
{
#include <algorithm>
#include <iostream>
#include <sstream>
#define STAGE_MAX ($max * 10) // max = $max
#define USE_TOKEN_CTOR $token_ctor
#define USE_VARIANTS $variant
// Prototype of the yylex function providing subsequent tokens.
static
#if USE_TOKEN_CTOR
yy::parser::symbol_type yylex();
#else
yy::parser::token_type yylex(yy::parser::semantic_type* yylvalp,
yy::parser::location_type* yyllocp);
#endif
// Conversion to string.
template <typename T>
inline
std::string
string_cast (const T& t)
{
std::ostringstream o;
o << t;
return o.str ();
}
}
%token END_OF_FILE 0
EOF
if ($variant)
{
print $out <<'EOF';
%token <std::string> TEXT
%token <int> NUMBER
%printer { std::cerr << "Number: " << $$; } <int>
%printer { std::cerr << "Text: " << $$; } <std::string>
%type <std::string> text result
%%
result:
text { /* Throw away the result. */ }
;
text:
/* nothing */ { /* This will generate an empty string */ }
| text TEXT { std::swap ($$, $2); }
| text NUMBER { $$ = string_cast($2); }
;
EOF
}
else
{
# Not using Bison variants.
print $out <<'EOF';
%union {int ival; std::string* sval;}
%token <sval> TEXT
%token <ival> NUMBER
%printer { std::cerr << "Number: " << $$; } <ival>
%printer { std::cerr << "Text: " << *$$; } <sval>
%type <sval> text result
%%
result:
text { delete $1; }
;
text:
/* nothing */ { $$ = new std::string; }
| text TEXT { delete $1; $$ = $2; }
| text NUMBER { delete $1; $$ = new std::string (string_cast ($2)); }
;
EOF
}
print $out <<'EOF';
%%
#
static
#if USE_TOKEN_CTOR
yy::parser::symbol_type yylex()
#else
yy::parser::token_type yylex(yy::parser::semantic_type* yylvalp,
yy::parser::location_type* yyllocp)
#endif
{
typedef yy::parser::location_type location_type;
typedef yy::parser::token token;
static int stage = -1;
++stage;
if (stage == STAGE_MAX)
{
#if USE_TOKEN_CTOR
return yy::parser::make_END_OF_FILE (location_type ());
#else
*yyllocp = location_type ();
return token::END_OF_FILE;
#endif
}
else if (stage % 2)
{
#if USE_TOKEN_CTOR
return yy::parser::make_NUMBER (stage, location_type ());
#else
# if defined ONE_STAGE_BUILD
yylvalp->build(stage);
# elif USE_VARIANTS
yylvalp->build<int>() = stage;
# else
yylvalp->ival = stage;
# endif
*yyllocp = location_type ();
return token::NUMBER;
#endif
}
else
{
#if USE_TOKEN_CTOR
return yy::parser::make_TEXT ("A string.", location_type ());
#else
# if defined ONE_STAGE_BUILD
yylvalp->build(std::string("A string."));
# elif USE_VARIANTS
yylvalp->build<std::string>() = std::string("A string.");
# else
yylvalp->sval = new std::string("A string.");
# endif
*yyllocp = location_type ();
return token::TEXT;
#endif
}
abort();
}
// Mandatory error function
void
yy::parser::error(const yy::parser::location_type& loc, const std::string& msg)
{
std::cerr << loc << ": " << msg << std::endl;
}
int main(int argc, char *argv[])
{
yy::parser p;
#if YYDEBUG
p.set_debug_level(!!getenv("YYDEBUG"));
#endif
p.parse();
return 0;
}
EOF
}
##################################################################
=item C<generate_grammar ($name, $base, @directive)>
Generate F<$base.y> by calling C<&generate_grammar_$name>.
=cut
sub generate_grammar ($$@)
{
my ($name, $base, @directive) = @_;
verbose 3, "Generating $base.y\n";
my %generator =
(
"calc" => \&generate_grammar_calc,
"list" => \&generate_grammar_list,
"triangular" => \&generate_grammar_triangular,
);
&{$generator{$name}}($base, 200, @directive);
}
##################################################################
=item C<run ($command)>
Run, possibly verbosely, the shell C<$command>.
=cut
sub run ($)
{
my ($command) = @_;
verbose 3, "$command\n";
system ("$command") == 0
or die "$command failed";
}
##################################################################
=item C<compile ($base)>
Compile C<$base.y> to an executable C, Using the C or C++ compiler
depending on the %language specification in C<$base.y>.
=cut
sub compile ($)
{
my ($base) = @_;
my $language = `sed -ne '/%language "\\(.*\\)"/{s//\\1/;p;q;}' $base.y`;
chomp $language;
my $compiler = $language eq 'C++' ? $cxx : $cc;
my $my_bison = `sed -ne '/%bison "\\(.*\\)"/{s//\\1/;p;q;}' $base.y`;
run ((length $my_bison ? $my_bison : $bison) . " $base.y -o $base.c");
run "$compiler -o $base $cflags $base.c";
system ("$bison $base.y -o $base.c") == 0
or die;
system ("$cc -o $base $base.c") == 0
or die;
}
######################################################################
=item C<bench ($grammar, @token)>
Generate benches for the C<$grammar> and the directive specification
given in the list of C<@token>.
=cut
sub bench ($@)
sub bench_grammar ($)
{
my ($grammar, @token) = @_;
use Benchmark qw (:all :hireswallclock);
my ($gram) = @_;
my %test =
(
"pull-impure" => '',
"pull-pure" => '%define api.pure',
"push-impure" => '%define api.push-pull "both"',
"push-pure" => '%define api.push-pull "both" %define api.pure',
);
my @directive = parse (@token);
# Set up the benches as expected by timethese.
my %bench;
# A counter of directive sets.
my $count = 1;
for my $d (@directive)
while (my ($name, $directives) = each %test)
{
$bench{$count} = $d;
printf " %2d. %s\n", $count, join (' ', split ("\n", $d));
$count++;
};
# For each bench, capture the size.
my %size;
while (my ($name, $directives) = each %bench)
{
generate_grammar ($grammar, $name, $directives);
# Compile the executable.
print STDERR "$name\n";
my $generator = "$gram" . "_grammar";
&$generator ($name, 200, $directives);
compile ($name);
$bench{$name} = "system ('./$name');";
chop($size{$name} = `wc -c <$name`);
}
# Run the benches.
#
# STYLE can be any of 'all', 'none', 'noc', 'nop' or 'auto'. 'all'
# shows each of the 5 times available ('wallclock' time, user time,
# system time, user time of children, and system time of
# children). 'noc' shows all except the two children times. 'nop'
# shows only wallclock and the two children times. 'auto' (the
# default) will act as 'all' unless the children times are both
# zero, in which case it acts as 'noc'. 'none' prevents output.
verbose 3, "Running the benches for $grammar\n";
my $res = timethese ($iterations, \%bench, 'nop');
# Output the speed result.
print "$gram:\n";
my $res = timethese (50, \%bench, 'nop');
cmpthese ($res, 'nop');
# Display the sizes.
print "Sizes (decreasing):\n";
my $width = 10;
for my $bench (keys %size)
{
$width = length $bench
if $width < length $bench;
}
# Benches sorted by decreasing size.
my @benches_per_size = sort {$size{$b} <=> $size{$a}} keys %size;
for my $bench (@benches_per_size)
{
printf "%${width}s: %5.2fkB\n", $bench, $size{$bench} / 1024;
}
}
######################################################################
=item C<bench_push_parser ()>
Bench the C push parser against the pull parser, pure and impure
interfaces.
=cut
sub bench_push_parser ()
{
bench ('calc',
qw(
[ %d api.pure ]
&
[ %d api.push-pull=both ]
));
}
######################################################################
=item C<bench_variant_parser ()>
Bench the C++ lalr1.cc parser using variants or %union.
=cut
sub bench_variant_parser ()
{
bench ('list',
qw(
[
%d variant
&
[ #d ONE_STAGE_BUILD | %d api.token.constructor ]
]
)
);
}
############################################################################
sub help ($)
{
my ($verbose) = @_;
use Pod::Usage;
# See <URL:http://perldoc.perl.org/pod2man.html#NOTES>.
pod2usage( { -message => "Bench Bison parsers",
-exitval => 0,
-verbose => $verbose,
-output => \*STDOUT });
}
######################################################################
# The end of the directives to parse.
my $eod = "end of directives";
# The list of tokens parsed by the following functions.
my @token;
# eat ($EXPECTED)
# ---------------
# Check that the current token is $EXPECTED, and move to the next.
sub eat ($)
{
my ($expected) = @_;
die "expected $expected, unexpected: $token[0] (@token)\n"
unless $token[0] eq $expected;
shift @token;
}
# Parse directive specifications:
# expr: term (| term)*
# term: fact (& fact)*
# fact: ( expr ) | [ expr ] | dirs
# dirs: %s SKELETON | #d NAME[=VALUE] | %d NAME[=VALUE] | directive
sub parse (@)
{
@token = (@_, $eod);
verbose 3, "Parsing: @token\n";
my @res = parse_expr ();
eat ($eod);
return @res;
}
sub parse_expr ()
{
my @res = parse_term ();
while ($token[0] eq '|')
{
eat ('|');
# Alternation.
push @res, parse_term ();
}
return @res;
}
sub parse_term ()
{
my @res = parse_fact ();
while ($token[0] eq '&')
{
eat ('&');
# Cartesian product.
my @lhs = @res;
@res = ();
for my $rhs (parse_fact ())
{
for my $lhs (@lhs)
{
push @res, $lhs . ($lhs && $rhs ? "\n" : "") . $rhs;
}
}
}
return @res;
}
sub parse_fact ()
{
my @res;
die "unexpected end of expression"
unless defined $token[0];
if ($token[0] eq '(')
{
eat ('(');
@res = parse_expr ();
eat (')');
}
elsif ($token[0] eq '[')
{
eat ('[');
@res = (parse_expr (), '');
eat (']');
}
else
{
@res = parse_dirs ();
}
return @res;
}
sub parse_dirs ()
{
my @res;
die "unexpected end of expression"
unless defined $token[0];
if ($token[0] eq '#d')
{
eat ('#d');
$token[0] =~ s/(.*?)=(.*)/$1 $2/;
@res = ("%code {\n#define $token[0]\n}");
shift @token;
}
elsif ($token[0] eq '%d')
{
shift @token;
$token[0] =~ s/(.*?)=(.*)/$1 "$2"/;
@res = ("%define $token[0]");
shift @token;
}
elsif ($token[0] eq '%s')
{
shift @token;
@res = ("%skeleton \"$token[0]\"");
shift @token;
}
elsif ($token[0] eq '%b')
{
shift @token;
@res = ("/*\n%bison \"$token[0]\"\\\n*/");
shift @token;
}
else
{
@res = $token[0];
shift @token;
}
return @res;
}
######################################################################
sub getopt ()
{
use Getopt::Long;
my %option = (
"b|bench=s" => \$bench,
"c|cflags=s" => \$cflags,
"d|directive=s" => \@directive,
"g|grammar=s" => \$grammar,
"h|help" => sub { help ($verbose) },
"i|iterations=i" => \$iterations,
"q|quiet" => sub { --$verbose },
"v|verbose" => sub { ++$verbose },
);
Getopt::Long::Configure ("bundling", "pass_through");
GetOptions (%option)
or exit 1;
}
######################################################################
getopt;
# Create the directory we work in.
mkdir "benches" or die "cannot create benches"
unless -d "benches";
my $count = 1;
++$count
while -d "benches/$count";
my $dir = "benches/$count";
mkdir $dir
or die "cannot create $dir";
chdir $dir
or die "cannot chdir $dir";
# The following message is tailored to please Emacs' compilation-mode.
verbose 1, "Entering directory `$dir'\n";
verbose 1, "Using bison=$bison.\n";
verbose 2, "Using cc=$cc.\n";
verbose 2, "Using cxx=$cxx.\n";
verbose 2, "Using cflags=$cflags.\n";
verbose 2, "Grammar: $grammar\n";
# Support -b: predefined benches.
my %bench =
(
"push" => \&bench_push_parser,
"variant" => \&bench_variant_parser,
);
if (defined $bench)
{
die "invalid argument for --bench: $bench"
unless defined $bench{$bench};
&{$bench{$bench}}();
exit 0;
}
else
{
# Launch the bench marking.
bench ($grammar, @ARGV);
}
print STDERR "Using $bison, $cc.\n";
calc_input ('calc', 200);
bench_grammar ('calc');
### Setup "GNU" style for perl-mode and cperl-mode.
## Local Variables:
-16
View File
@@ -1,16 +0,0 @@
## Copyright (C) 2006, 2008-2013 Free Software Foundation, Inc.
## This program is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with this program. If not, see <http://www.gnu.org/licenses/>.
nodist_noinst_SCRIPTS = etc/bench.pl
+2
View File
@@ -0,0 +1,2 @@
Makefile
Makefile.in
+2
View File
@@ -0,0 +1,2 @@
/Makefile
/Makefile.in
+6 -31
View File
@@ -1,7 +1,6 @@
#! /bin/sh
## Process this file with automake to produce Makefile.in -*-Makefile-*-
## Copyright (C) 2005, 2009-2013 Free Software Foundation, Inc.
# Copyright (C) 2005-2013 Free Software Foundation, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
@@ -15,32 +14,8 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
cat >input <<EOF
1 2 3 * +
EOF
run 0 7
if BISON_CXX_WORKS
SUBDIRS = calc++
endif
cat >input <<EOF
1.1 2.2 3.3 * +
EOF
run 0 8.36
cat >input <<EOF
1 2 + 3 *
EOF
run 0 9
cat >input <<EOF
1 2 3 4 5 6 7 8 9 * * * * * * * *
EOF
run 0 362880
cat >input <<EOF
3 7 + 3 4 5 * + - n
EOF
run 0 13
cat >input <<EOF
3 4 ^
EOF
run 0 81
dist_noinst_SCRIPTS = extexi
+8 -14
View File
@@ -1,19 +1,13 @@
/*.cc
/*.hh
/*.ll
/*.o
/*.output
/*.stamp
/*.tmp
/*.yy
/.deps
/Makefile
/Makefile.in
/calc++
/calc++-driver.cc
/calc++-driver.hh
/calc++-parser.cc
/calc++-parser.hh
/calc++-parser.output
/calc++-parser.stamp
/calc++-parser.yy
/calc++-scanner.cc
/calc++-scanner.ll
/calc++.cc
/calc++.exe
/calc.stamp
/location.hh
/position.hh
/stack.hh
+93
View File
@@ -0,0 +1,93 @@
## Process this file with automake to produce Makefile.in -*-Makefile-*-
## Copyright (C) 2005-2006, 2009-2013 Free Software Foundation, Inc.
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
## ------------------------------------- ##
## Running the bison from this tarball. ##
## ------------------------------------- ##
BISON = $(top_builddir)/tests/bison
BISON_IN = $(top_srcdir)/tests/bison.in
$(BISON): $(BISON_IN)
$(AM_V_GEN)cd $(top_builddir)/tests && $(MAKE) $(AM_MAKEFLAGS) bison
## ------------ ##
## Extracting. ##
## ------------ ##
doc = $(top_srcdir)/doc/bison.texi
extexi = $(top_srcdir)/examples/extexi
# Extract in src.
$(srcdir)/calc.stamp: $(doc) $(extexi)
$(AM_V_GEN)rm -f $@ $@.tmp
$(AM_V_at)touch $@.tmp
$(AM_V_at)cd $(srcdir) && \
$(AWK) -f ../extexi -v VERSION="$(VERSION)" \
../../doc/bison.texi -- calc++-parser.yy \
calc++-scanner.ll calc++.cc calc++-driver.hh calc++-driver.cc
$(AM_V_at)mv $@.tmp $@
$(calc_extracted): $(srcdir)/calc.stamp
## ------------------- ##
## Parser generation. ##
## ------------------- ##
DEFAULT_INCLUDES = -I. -I$(srcdir)
BUILT_SOURCES = $(calc_extracted) $(calc_sources_generated)
CLEANFILES = $(srcdir)/*.output *.tmp
MAINTAINERCLEANFILES = $(srcdir)/*.stamp $(BUILT_SOURCES)
# Compile the parser and save cycles.
# This code comes from "Handling Tools that Produce Many Outputs",
# from the Automake documentation.
EXTRA_DIST = \
$(srcdir)/calc++-parser.stamp \
$(srcdir)/calc++-parser.yy \
$(srcdir)/calc.stamp
# Don't depend on $(BISON) otherwise we would rebuild these files
# in srcdir, including during distcheck, which is forbidden.
$(srcdir)/calc++-parser.stamp: $(srcdir)/calc++-parser.yy $(BISON_IN)
$(AM_V_GEN)rm -f calc++-parser.tmp
$(AM_V_at)touch calc++-parser.tmp
$(AM_V_at)$(BISON) -d -ra -S lalr1.cc -o $(srcdir)/calc++-parser.cc \
$(srcdir)/calc++-parser.yy
$(AM_V_at)mv -f calc++-parser.tmp $@
$(calc_sources_generated): $(srcdir)/calc++-parser.stamp
$(AM_V_GEN)if test -f $@; then :; else \
rm -f $(srcdir)/calc++-parser.stamp && \
$(MAKE) $(AM_MAKEFLAGS) $(srcdir)/calc++-parser.stamp; \
fi
## --------------------------- ##
## Building & testing calc++. ##
## --------------------------- ##
check_PROGRAMS = calc++
calc_sources_extracted = $(srcdir)/calc++-scanner.ll $(srcdir)/calc++.cc \
$(srcdir)/calc++-driver.hh $(srcdir)/calc++-driver.cc
calc_extracted = $(calc_sources_extracted) $(srcdir)/calc++-parser.yy
calc_sources_generated = \
$(srcdir)/stack.hh $(srcdir)/position.hh $(srcdir)/location.hh \
$(srcdir)/calc++-parser.hh $(srcdir)/calc++-parser.cc
calc___SOURCES = $(calc_sources_extracted) $(calc_sources_generated)
TESTS = test
EXTRA_DIST += $(TESTS)
-75
View File
@@ -1,75 +0,0 @@
# Copyright (C) 2005-2006, 2008-2013 Free Software Foundation, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
## ------------------- ##
## Parser generation. ##
## ------------------- ##
# 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)
SUFFIXES += .yy .stamp
.yy.stamp:
$(AM_V_YACC)rm -f $@
$(AM_V_at)touch $@.tmp
$(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
CLEANFILES += \
$(calc_sources_generated) \
examples/calc++/calc++-parser.output \
examples/calc++/calc++-parser.stamp \
examples/calc++/calc++-scanner.cc
## -------------------- ##
## Building & testing. ##
## -------------------- ##
# Avoid using BUILT_SOURCES which is too global.
$(examples_calc___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
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)
if BISON_CXX_WORKS
check_PROGRAMS += examples/calc++/calc++
nodist_examples_calc___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
endif
@@ -15,36 +15,32 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
test -z "$VERBOSE" && {
exec > /dev/null 2>&1
set -x
}
cat >input <<EOF
a := 1
b := 2
c := 3
d := a + b * c
d
EOF
./calc++ input
./calc++ -p input
cat >input <<EOF
a := 1
d := a + b * c
EOF
./calc++ input
cat >input <<EOF
toto := 1
toto
EOF
run 0 1 -s
./calc++ -s input
cat >input <<EOF
a := 1
b := 2
c := 3
d := a + b * c
d
EOF
run 0 7
run 0 7 -p
cat >input <<EOF
a := 1
b := 2
c := 3
d := (a + b) * c
d
EOF
run 0 9
cat >input <<EOF
a := 1
d := a + b * c
EOF
run 1 ''
rm input
-6
View File
@@ -1,6 +0,0 @@
// Work around an Automake 1.11.2 bug: it asks for the creation of
// y.tab.c and y.tab.h and then renames them as calc++-parser.cc and
// calc++-parser.h, but in the former it does not convert the
// #include "y.tab.h". We don't want this to show in the
// documentation.
#include "calc++-parser.hh"
Executable → Regular
+109 -142
View File
@@ -1,5 +1,4 @@
#! /usr/bin/perl -w
# Extract all examples from the manual source.
# Extract all examples from the manual source. -*- AWK -*-
# This file is part of GNU Bison
@@ -19,154 +18,122 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# This script is for use with any Awk that conforms to POSIX.
# It was derived from a similar script tests/generate.awk in GNU m4.
#
# Usage: extexi input-file.texi ... -- [FILES to extract]
# Look for @example environments preceded with lines such as:
#
# @comment file calc.y
# or
# @comment file calc.y: 3
#
# and output their content in that file (calc.y). When numbers are
# provided, use them to decide the output order (block numbered 1 is
# output before block 2, even if the latter appears before). The same
# number may be used several time, in which case the order of
# appearance is used.
use strict;
# normalize($block)
# -----------------
# Remove Texinfo mark up.
sub normalize($)
{
local ($_) = @_;
s/^\@(c |comment|dots|end (ignore|group)|ignore|group).*//mg;
s/\@value\{VERSION\}/$ENV{VERSION}/g;
s/^\@(error|result)\{\}//mg;
s/\@([{}@])/$1/g;
s/\@comment.*//;
$_;
BEGIN {
if (!output_dir)
output_dir = ".";
for (argc = 1; argc < ARGC; ++argc)
if (ARGV[argc] == "--")
break;
for (i = argc + 1; i < ARGC; ++i)
file_wanted[ARGV[i]] = 1;
ARGC = argc;
}
# Print messages only once.
my %msg;
sub message($)
{
my ($msg) = @_;
if (! $msg{$msg})
{
print STDERR "extexi: $msg\n";
$msg{$msg} = 1;
}
/^@node / {
if (seq > 0)
print "AT_CLEANUP";
split ($0, tmp, ",");
node = substr(tmp[1], 7);
seq = 0;
}
# basename => full file name for files we should extract.
my %file_wanted;
sub process ($)
{
my ($in) = @_;
use IO::File;
my $f = new IO::File($in)
or die "$in: cannot open: $?";
# FILE-NAME => { BLOCK-NUM => CODE }
my %file;
# The latest "@comment file: FILE [BLOCK-NUM]" arguments.
my $file;
my $block;
# The @example block currently read.
my $input;
local $_;
while (<$f>)
{
if (/^\@comment file: ([^:\n]+)(?::\s*(\d+))?$/)
{
my $f = $1;
$block = $2 || 1;
if ($file_wanted{$f})
{
$file = $file_wanted{$f};
message(" GEN $file");
}
else
{
message("SKIP $f");
}
}
elsif ($file && /^\@(small)?example$/ .. /^\@end (small)?example$/)
{
if (/^\@(small)?example$/)
{
# Bison supports synclines, but not Flex.
$input .= sprintf ("#line %s \"$in\"\n", $. + 1)
if $file =~ /\.[chy]*$/;
next;
}
elsif (/^\@end (small)?example$/)
{
die "no contents: $file"
if $input eq "";
$file{$file}{$block} .= normalize($input);
$file = $input = undef;
++$block;
}
else
{
$input .= $_;
}
}
}
# Output the files.
for my $file (keys %file)
{
# No spurious end of line: use printf.
my $o = new IO::File(">$file")
or die "$file: cannot create: $?";
print $o $file{$file}{$_}
for sort keys %{$file{$file}};
}
}
my @input;
my $seen_dash = 0;
for my $arg (@ARGV)
{
if ($arg eq '--')
{
$seen_dash = 1;
}
elsif ($seen_dash)
{
use File::Basename;
$file_wanted{basename($arg)} = $arg;
}
/^@comment file: / {
if (!file_wanted[$3])
message("ignoring " $3);
else
{
push @input, $arg;
message("extracting " $3);
file = $3;
}
}
process $_
foreach @input;
/^@example$/, /^@end example$/ {
if (!file)
next;
if ($0 ~ /^@example$/)
{
input = files_output[file] ? "\n" : "";
# FNR is starting at 0 instead of 1, and
# #line report the line number of the *next* line.
# => + 2.
# Note that recent Bison support it, but not Flex.
if (file ~ /\.[chy]*$/)
input = "#line " (FNR + 1) " \"" FILENAME "\"\n";
next;
}
if ($0 ~ /^@end example$/)
{
if (input == "")
fatal("no contents: " file);
input = normalize(input);
# No spurious end of line: use printf.
if (files_output[file])
# The parens around the output file seem to be required
# by awk on Mac OS X Tiger (darwin 8.4.6).
printf ("%s", input) >> (output_dir "/" file);
else
printf ("%s", input) > (output_dir "/" file);
close (output_dir "/" file);
files_output[file] = 1;
file = input = "";
next;
}
input = input $0 "\n";
}
### Setup "GNU" style for perl-mode and cperl-mode.
## Local Variables:
## perl-indent-level: 2
## perl-continued-statement-offset: 2
## perl-continued-brace-offset: 0
## perl-brace-offset: 0
## perl-brace-imaginary-offset: 0
## perl-label-offset: -2
## cperl-indent-level: 2
## cperl-brace-offset: 0
## cperl-continued-brace-offset: 0
## cperl-label-offset: -2
## cperl-extra-newline-before-brace: t
## cperl-merge-trailing-else: nil
## cperl-continued-statement-offset: 2
## End:
# We have to handle CONTENTS line per line, since anchors in AWK are
# referring to the whole string, not the lines.
function normalize(contents, i, lines, n, line, res) {
# Remove the Texinfo tags.
n = split (contents, lines, "\n");
# We don't want the last field which empty: it's behind the last \n.
for (i = 1; i < n; ++i)
{
line = lines[i];
# Whole line commands.
if (line ~ /^@(c |comment|dots|end (ignore|group)|ignore|group)/)
# Gperf accepts empty lines as valid input!!!
if (file ~ /\.gperf$/)
continue;
else
line = "";
gsub (/"@value\{VERSION\}"/, "\"" VERSION "\"", line)
gsub (/^@result\{\}/, "", line);
gsub (/^@error\{\}/, "", line);
gsub ("@[{]", "{", line);
gsub ("@}", "}", line);
gsub ("@@", "@", line);
gsub ("@comment.*", "", line);
res = res line "\n";
}
return res;
}
function message(msg) {
if (! message_printed[msg])
{
print "extexi: " msg > "/dev/stderr";
message_printed[msg] = 1;
}
}
function fatal(msg) {
message(msg);
exit 1
}
-44
View File
@@ -1,44 +0,0 @@
# Copyright (C) 2005, 2008-2013 Free Software Foundation, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
dist_noinst_SCRIPTS = examples/extexi examples/test
TEST_LOG_COMPILER = $(top_srcdir)/examples/test
AM_CXXFLAGS = \
$(NO_STRICT_ALIAS_CXXFLAGS) \
$(WARN_CXXFLAGS) $(WARN_CXXFLAGS_TEST) $(WERROR_CXXFLAGS)
## ------------ ##
## Extracting. ##
## ------------ ##
doc = $(top_srcdir)/doc/bison.texi
extexi = $(top_srcdir)/examples/extexi
extract = VERSION="$(VERSION)" $(PERL) -f $(extexi) $(doc) --
extracted =
CLEANFILES += $(extracted) examples/extracted.stamp
examples/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
include examples/calc++/local.mk
include examples/mfcalc/local.mk
include examples/rpcalc/local.mk
-11
View File
@@ -1,11 +0,0 @@
/*.o
/*.tmp
/.deps
/calc.h
/mfcalc
/mfcalc.c
/mfcalc.exe
/mfcalc.h
/mfcalc.output
/mfcalc.stamp
/mfcalc.y
-36
View File
@@ -1,36 +0,0 @@
# Copyright (C) 2005-2006, 2008-2013 Free Software Foundation, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
## -------------------- ##
## Building & testing. ##
## -------------------- ##
BUILT_SOURCES += $(mfcalc_sources)
CLEANFILES += examples/mfcalc/mfcalc.[ch] examples/mfcalc/mfcalc.output
mfcalc_extracted = \
examples/mfcalc/calc.h \
examples/mfcalc/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)
examples_mfcalc_mfcalc_CPPFLAGS = -I$(top_builddir)/examples/mfcalc
dist_TESTS += examples/mfcalc/mfcalc.test
-6
View File
@@ -1,6 +0,0 @@
/calc.h
/rpcalc.c
/rpcalc.h
/rpcalc.output
/rpcalc.stamp
/rpcalc.y
-35
View File
@@ -1,35 +0,0 @@
# Copyright (C) 2005-2006, 2008-2013 Free Software Foundation, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
## -------------------- ##
## Building & testing. ##
## -------------------- ##
BUILT_SOURCES += $(rpcalc_sources)
CLEANFILES += examples/rpcalc/rpcalc.[ch] examples/rpcalc/rpcalc.output
rpcalc_extracted = \
examples/rpcalc/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)
examples_rpcalc_rpcalc_CPPFLAGS = -I$(top_builddir)/examples/rpcalc
dist_TESTS += examples/rpcalc/rpcalc.test
-82
View File
@@ -1,82 +0,0 @@
#! /bin/sh
# Copyright (C) 2005-2013 Free Software Foundation, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
me=`basename $1 .test`
# Number of the current test.
number=1
# Exit status of this script.
exit=true
# top_buiddir.
cwd=`pwd`
# The exercised program.
prog=$cwd/examples/$me/$me
# cleanup
# -------
cleanup ()
{
local status=$?
if test -z "$DEBUG"; then
cd $cwd
rm -rf $$.dir
fi
exit $status
}
trap cleanup 0 1 2 13 15
mkdir $$.dir
cd $$.dir
# run EXPECTED-EXIT-STATUS EXPECTED-OUTPUT [PARSER-OPTIONS]
# ---------------------------------------------------------
run ()
{
# Expected exit status.
local sta_exp=$1
shift
# Expected output.
local out_exp=$1
shift
# Effective exit status.
local sta_eff=0
$prog "$@" - <input >out_eff || sta_eff=$?
# Effective output.
local out_eff=`cat out_eff`
if test $sta_eff -eq $sta_exp; then
if test "$out_eff" = "$out_exp"; then
echo "$me: PASS: $number"
else
echo "$me: FAIL: $number (expected output: $out_exp, effective: $out_eff)"
exit=false
fi
else
echo "$me: FAIL: $number (expected status: $sta_exp, effective: $sta_eff)"
exit=false
fi
number=`expr $number + 1`
}
# We have cd'd one level deeper.
case $1 in
/*) . "$1";;
*) . "../$1";;
esac
$exit
-146
View File
@@ -1,146 +0,0 @@
/*
Copyright (C) 2008-2013 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
%debug
%skeleton "lalr1.cc"
%defines
%define api.token.constructor
%define api.value.type variant
%define parse.assert
%locations
%code requires // *.hh
{
#include <list>
#include <string>
typedef std::list<std::string> strings_type;
}
%code // *.cc
{
#include <algorithm>
#include <iostream>
#include <iterator>
#include <sstream>
// Prototype of the yylex function providing subsequent tokens.
namespace yy
{
static parser::symbol_type yylex ();
}
// Printing a list of strings.
// Koening look up will look into std, since that's an std::list.
namespace std
{
std::ostream&
operator<< (std::ostream& o, const strings_type& s)
{
std::copy (s.begin (), s.end (),
std::ostream_iterator<strings_type::value_type> (o, "\n"));
return o;
}
}
// Conversion to string.
template <typename T>
inline
std::string
string_cast (const T& t)
{
std::ostringstream o;
o << t;
return o.str ();
}
}
%token <::std::string> TEXT;
%token <int> NUMBER;
%printer { yyoutput << $$; } <*>;
%token END_OF_FILE 0;
%type <::std::string> item;
%type <::std::list<std::string>> list;
%%
result:
list { std::cout << $1 << std::endl; }
;
list:
/* nothing */ { /* Generates an empty string list */ }
| list item { std::swap ($$, $1); $$.push_back ($2); }
;
item:
TEXT { std::swap ($$, $1); }
| NUMBER { $$ = string_cast ($1); }
;
%%
namespace yy
{
// The yylex function providing subsequent tokens:
// TEXT "I have three numbers for you."
// NUMBER 1
// NUMBER 2
// NUMBER 3
// TEXT "And that's all!"
// END_OF_FILE
static
parser::symbol_type
yylex ()
{
static int stage = -1;
++stage;
parser::location_type loc(0, stage + 1, stage + 1);
switch (stage)
{
case 0:
return parser::make_TEXT ("I have three numbers for you.", loc);
case 1:
case 2:
case 3:
return parser::make_NUMBER (stage, loc);
case 4:
return parser::make_TEXT ("And that's all!", loc);
default:
return parser::make_END_OF_FILE (loc);
}
}
// Mandatory error function
void
parser::error (const parser::location_type& loc, const std::string& msg)
{
std::cerr << loc << ": " << msg << std::endl;
}
}
int
main ()
{
yy::parser p;
p.set_debug_level (!!getenv ("YYDEBUG"));
return p.parse ();
}
// Local Variables:
// mode: C++
// End:
+1 -1
Submodule gnulib updated: c67e3c0414...076ac82d1d
+15 -8
View File
@@ -35,8 +35,6 @@
/close.c
/closeout.c
/closeout.h
/concat-filename.c
/concat-filename.h
/config.charset
/config.h
/config.in.h
@@ -64,7 +62,6 @@
/fd-hook.h
/fd-safer-flag.c
/fd-safer.c
/filename.h
/float+.h
/float.c
/float.h
@@ -101,6 +98,7 @@
/isnanf.c
/isnanl-nolibm.h
/isnanl.c
/iswblank.c
/itold.c
/ldexpl.c
/localcharset.c
@@ -108,10 +106,15 @@
/malloc.c
/math.h
/math.in.h
/mbchar.c
/mbchar.h
/mbrtowc.c
/mbschr.c
/mbsinit.c
/mbsrchr.c
/mbswidth.c
/mbswidth.h
/mbuiter.h
/memchr.c
/memchr.valgrind
/msvc-inval.c
@@ -122,7 +125,6 @@
/nonblocking.h
/obstack.c
/obstack.h
/obstack_printf.c
/open.c
/pathmax.h
/perror.c
@@ -211,6 +213,8 @@
/stripslash.c
/strndup.c
/strnlen.c
/strnlen1.c
/strnlen1.h
/strtol.c
/strtoul.c
/strverscmp.c
@@ -221,7 +225,6 @@
/sys_socket.in.h
/sys_stat.h
/sys_stat.in.h
/sys_types.in.h
/sys_wait.h
/sys_wait.in.h
/sysexits.in.h
@@ -258,17 +261,21 @@
/xalloc-die.c
/xalloc-oversized.h
/xalloc.h
/xconcat-filename.c
/xmalloc.c
/xmemdup0.c
/xmemdup0.h
/xsize.h
/xstrndup.c
/xstrndup.h
/xmemdup0.c
/xmemdup0.h
/sys_types.in.h
/obstack_printf.c
/binary-io.c
/mbuiter.c
/xsize.c
/bitrotate.c
/math.c
/sig-handler.c
/unistd.c
/wctype-h.c
/getdelim.c
/getline.c
+55
View File
@@ -0,0 +1,55 @@
# Make bison/lib.
# Copyright (C) 2001-2004, 2006, 2008-2013 Free Software Foundation,
# Inc.
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
AM_CFLAGS =
AM_CPPFLAGS =
BUILT_SOURCES =
CLEANFILES =
EXTRA_DIST =
MOSTLYCLEANDIRS =
MOSTLYCLEANFILES =
SUFFIXES =
noinst_LIBRARIES =
include gnulib.mk
AM_CFLAGS += $(WARN_CFLAGS)
# Implementation of bitsets.
bitsets_sources = \
abitset.c abitset.h bbitset.h bitset.c bitset.h bitset_stats.c \
bitset_stats.h bitsetv.c bitsetv.h ebitset.c ebitset.h lbitset.c \
lbitset.h libiberty.h vbitset.c vbitset.h
# Additional bitset operations.
additional_bitsets_sources = \
bitsetv-print.h bitsetv-print.c
# timevars, stolen from GCC.
timevars_sources = \
timevar.h timevar.c timevar.def
# Non-gnulib sources in Bison's internal library.
libbison_a_SOURCES += \
get-errno.h get-errno.c \
$(bitsets_sources) $(additional_bitsets_sources) $(timevars_sources)
# The Yacc compatibility library.
lib_LIBRARIES = $(YACC_LIBRARY)
EXTRA_LIBRARIES = liby.a
liby_a_SOURCES = main.c yyerror.c
+115 -115
View File
@@ -47,7 +47,7 @@ abitset_resize (bitset src, bitset_bindex size)
found and with *NEXT indicating where search stopped. */
static bitset_bindex
abitset_small_list (bitset src, bitset_bindex *list,
bitset_bindex num, bitset_bindex *next)
bitset_bindex num, bitset_bindex *next)
{
bitset_bindex bitno;
bitset_bindex count;
@@ -73,27 +73,27 @@ abitset_small_list (bitset src, bitset_bindex *list,
if (num >= BITSET_WORD_BITS)
{
for (count = 0; word; bitno++)
{
if (word & 1)
list[count++] = bitno;
word >>= 1;
}
{
if (word & 1)
list[count++] = bitno;
word >>= 1;
}
}
else
{
for (count = 0; word; bitno++)
{
if (word & 1)
{
list[count++] = bitno;
if (count >= num)
{
bitno++;
break;
}
}
word >>= 1;
}
{
if (word & 1)
{
list[count++] = bitno;
if (count >= num)
{
bitno++;
break;
}
}
word >>= 1;
}
}
*next = bitno;
@@ -115,7 +115,7 @@ abitset_set (bitset dst ATTRIBUTE_UNUSED, bitset_bindex bitno ATTRIBUTE_UNUSED)
/* Reset bit BITNO in bitset DST. */
static void
abitset_reset (bitset dst ATTRIBUTE_UNUSED,
bitset_bindex bitno ATTRIBUTE_UNUSED)
bitset_bindex bitno ATTRIBUTE_UNUSED)
{
/* This should never occur for abitsets since we should always hit
the cache. It is likely someone is trying to access outside the
@@ -126,7 +126,7 @@ abitset_reset (bitset dst ATTRIBUTE_UNUSED,
/* Test bit BITNO in bitset SRC. */
static bool
abitset_test (bitset src ATTRIBUTE_UNUSED,
bitset_bindex bitno ATTRIBUTE_UNUSED)
bitset_bindex bitno ATTRIBUTE_UNUSED)
{
/* This should never occur for abitsets since we should always
hit the cache. */
@@ -140,7 +140,7 @@ abitset_test (bitset src ATTRIBUTE_UNUSED,
stopped. */
static bitset_bindex
abitset_list_reverse (bitset src, bitset_bindex *list,
bitset_bindex num, bitset_bindex *next)
bitset_bindex num, bitset_bindex *next)
{
bitset_bindex bitno;
bitset_bindex rbitno;
@@ -173,18 +173,18 @@ abitset_list_reverse (bitset src, bitset_bindex *list,
word = srcp[windex] << (BITSET_WORD_BITS - 1 - bitcnt);
for (; word; bitcnt--)
{
if (word & BITSET_MSB)
{
list[count++] = bitoff + bitcnt;
if (count >= num)
{
*next = n_bits - (bitoff + bitcnt);
return count;
}
}
word <<= 1;
}
{
if (word & BITSET_MSB)
{
list[count++] = bitoff + bitcnt;
if (count >= num)
{
*next = n_bits - (bitoff + bitcnt);
return count;
}
}
word <<= 1;
}
bitoff -= BITSET_WORD_BITS;
bitcnt = BITSET_WORD_BITS - 1;
}
@@ -200,7 +200,7 @@ abitset_list_reverse (bitset src, bitset_bindex *list,
found and with *NEXT indicating where search stopped. */
static bitset_bindex
abitset_list (bitset src, bitset_bindex *list,
bitset_bindex num, bitset_bindex *next)
bitset_bindex num, bitset_bindex *next)
{
bitset_bindex bitno;
bitset_bindex count;
@@ -217,80 +217,80 @@ abitset_list (bitset src, bitset_bindex *list,
{
/* Many bitsets are zero, so make this common case fast. */
for (windex = 0; windex < size && !srcp[windex]; windex++)
continue;
continue;
if (windex >= size)
return 0;
return 0;
/* If num is 1, we could speed things up with a binary search
of the current word. */
of the current word. */
bitoff = windex * BITSET_WORD_BITS;
}
else
{
if (bitno >= BITSET_SIZE_ (src))
return 0;
return 0;
windex = bitno / BITSET_WORD_BITS;
bitno = bitno % BITSET_WORD_BITS;
if (bitno)
{
/* Handle the case where we start within a word.
Most often, this is executed with large bitsets
with many set bits where we filled the array
on the previous call to this function. */
{
/* Handle the case where we start within a word.
Most often, this is executed with large bitsets
with many set bits where we filled the array
on the previous call to this function. */
bitoff = windex * BITSET_WORD_BITS;
word = srcp[windex] >> bitno;
for (bitno = bitoff + bitno; word; bitno++)
{
if (word & 1)
{
list[count++] = bitno;
if (count >= num)
{
*next = bitno + 1;
return count;
}
}
word >>= 1;
}
windex++;
}
bitoff = windex * BITSET_WORD_BITS;
word = srcp[windex] >> bitno;
for (bitno = bitoff + bitno; word; bitno++)
{
if (word & 1)
{
list[count++] = bitno;
if (count >= num)
{
*next = bitno + 1;
return count;
}
}
word >>= 1;
}
windex++;
}
bitoff = windex * BITSET_WORD_BITS;
}
for (; windex < size; windex++, bitoff += BITSET_WORD_BITS)
{
if (!(word = srcp[windex]))
continue;
continue;
if ((count + BITSET_WORD_BITS) < num)
{
for (bitno = bitoff; word; bitno++)
{
if (word & 1)
list[count++] = bitno;
word >>= 1;
}
}
{
for (bitno = bitoff; word; bitno++)
{
if (word & 1)
list[count++] = bitno;
word >>= 1;
}
}
else
{
for (bitno = bitoff; word; bitno++)
{
if (word & 1)
{
list[count++] = bitno;
if (count >= num)
{
*next = bitno + 1;
return count;
}
}
word >>= 1;
}
}
{
for (bitno = bitoff; word; bitno++)
{
if (word & 1)
{
list[count++] = bitno;
if (count >= num)
{
*next = bitno + 1;
return count;
}
}
word >>= 1;
}
}
}
*next = bitoff;
@@ -387,7 +387,7 @@ abitset_equal_p (bitset dst, bitset src)
for (i = 0; i < size; i++)
if (*srcp++ != *dstp++)
return false;
return false;
return true;
}
@@ -402,7 +402,7 @@ abitset_subset_p (bitset dst, bitset src)
for (i = 0; i < size; i++, dstp++, srcp++)
if (*dstp != (*srcp | *dstp))
return false;
return false;
return true;
}
@@ -417,7 +417,7 @@ abitset_disjoint_p (bitset dst, bitset src)
for (i = 0; i < size; i++)
if (*srcp++ & *dstp++)
return false;
return false;
return true;
}
@@ -452,10 +452,10 @@ abitset_and_cmp (bitset dst, bitset src1, bitset src2)
bitset_word tmp = *src1p++ & *src2p++;
if (*dstp != tmp)
{
changed = true;
*dstp = tmp;
}
{
changed = true;
*dstp = tmp;
}
}
return changed;
}
@@ -490,10 +490,10 @@ abitset_andn_cmp (bitset dst, bitset src1, bitset src2)
bitset_word tmp = *src1p++ & ~(*src2p++);
if (*dstp != tmp)
{
changed = true;
*dstp = tmp;
}
{
changed = true;
*dstp = tmp;
}
}
return changed;
}
@@ -528,10 +528,10 @@ abitset_or_cmp (bitset dst, bitset src1, bitset src2)
bitset_word tmp = *src1p++ | *src2p++;
if (*dstp != tmp)
{
changed = true;
*dstp = tmp;
}
{
changed = true;
*dstp = tmp;
}
}
return changed;
}
@@ -566,10 +566,10 @@ abitset_xor_cmp (bitset dst, bitset src1, bitset src2)
bitset_word tmp = *src1p++ ^ *src2p++;
if (*dstp != tmp)
{
changed = true;
*dstp = tmp;
}
{
changed = true;
*dstp = tmp;
}
}
return changed;
}
@@ -606,10 +606,10 @@ abitset_and_or_cmp (bitset dst, bitset src1, bitset src2, bitset src3)
bitset_word tmp = (*src1p++ & *src2p++) | *src3p++;
if (*dstp != tmp)
{
changed = true;
*dstp = tmp;
}
{
changed = true;
*dstp = tmp;
}
}
return changed;
}
@@ -646,10 +646,10 @@ abitset_andn_or_cmp (bitset dst, bitset src1, bitset src2, bitset src3)
bitset_word tmp = (*src1p++ & ~(*src2p++)) | *src3p++;
if (*dstp != tmp)
{
changed = true;
*dstp = tmp;
}
{
changed = true;
*dstp = tmp;
}
}
return changed;
}
@@ -686,10 +686,10 @@ abitset_or_and_cmp (bitset dst, bitset src1, bitset src2, bitset src3)
bitset_word tmp = (*src1p++ | *src2p++) & *src3p++;
if (*dstp != tmp)
{
changed = true;
*dstp = tmp;
}
{
changed = true;
*dstp = tmp;
}
}
return changed;
}
+14 -14
View File
@@ -32,9 +32,9 @@
Memory for bit array and bitset structure allocated
contiguously.
BITSET_LIST: Linked list of arrays of bits (variable size, least storage
for large very sparse sets).
for large very sparse sets).
BITSET_TABLE: Expandable table of pointers to arrays of bits
(variable size, less storage for large sparse sets).
(variable size, less storage for large sparse sets).
Faster than BITSET_LIST for random access.
BITSET_VARRAY: Variable array of bits (variable size, fast for
dense bitsets).
@@ -42,7 +42,7 @@
statistics and/or better run-time checking.
*/
enum bitset_type {BITSET_ARRAY, BITSET_LIST, BITSET_TABLE, BITSET_VARRAY,
BITSET_TYPE_NUM, BITSET_STATS};
BITSET_TYPE_NUM, BITSET_STATS};
#define BITSET_TYPE_NAMES {"abitset", "lbitset", "ebitset", "vbitset"}
extern const char * const bitset_type_names[];
@@ -78,19 +78,19 @@ typedef size_t bitset_windex;
#define BITSET_LIST_SIZE 1024
enum bitset_ops {BITSET_OP_ZERO, BITSET_OP_ONES,
BITSET_OP_COPY, BITSET_OP_NOT,
BITSET_OP_EMPTY_P, BITSET_OP_EQUAL_P,
BITSET_OP_SUBSET_P, BITSET_OP_DISJOINT_P,
BITSET_OP_AND, BITSET_OP_OR, BITSET_OP_XOR, BITSET_OP_ANDN,
BITSET_OP_OR_AND, BITSET_OP_AND_OR, BITSET_OP_ANDN_OR};
BITSET_OP_COPY, BITSET_OP_NOT,
BITSET_OP_EMPTY_P, BITSET_OP_EQUAL_P,
BITSET_OP_SUBSET_P, BITSET_OP_DISJOINT_P,
BITSET_OP_AND, BITSET_OP_OR, BITSET_OP_XOR, BITSET_OP_ANDN,
BITSET_OP_OR_AND, BITSET_OP_AND_OR, BITSET_OP_ANDN_OR};
struct bbitset_struct
{
const struct bitset_vtable *vtable;
bitset_windex cindex; /* Cache word index. */
bitset_windex csize; /* Cache size in words. */
bitset_word *cdata; /* Cache data pointer. */
bitset_bindex n_bits; /* Number of bits. */
bitset_windex cindex; /* Cache word index. */
bitset_windex csize; /* Cache size in words. */
bitset_word *cdata; /* Cache data pointer. */
bitset_bindex n_bits; /* Number of bits. */
/* Perhaps we could sacrifice another word to indicate
that the bitset is known to be zero, that a bit has been set
in the cache, and that a bit has been cleared in the cache.
@@ -148,9 +148,9 @@ struct bitset_vtable
bool (*or_and_cmp) (bitset, bitset, bitset, bitset);
bitset_bindex (*list) (bitset, bitset_bindex *, bitset_bindex,
bitset_bindex *);
bitset_bindex *);
bitset_bindex (*list_reverse) (bitset, bitset_bindex *, bitset_bindex,
bitset_bindex *);
bitset_bindex *);
void (*free) (bitset);
enum bitset_type type;
};
+5 -5
View File
@@ -151,7 +151,7 @@ bitset_alloc (bitset_bindex n_bits, enum bitset_type type)
/* Create a bitset of N_BITS of type TYPE. */
bitset
bitset_obstack_alloc (struct obstack *bobstack,
bitset_bindex n_bits, enum bitset_type type)
bitset_bindex n_bits, enum bitset_type type)
{
size_t bytes;
bitset bset;
@@ -296,15 +296,15 @@ bitset_print (FILE *file, bitset bset, bool verbose)
if (verbose)
fprintf (file, "n_bits = %lu, set = {",
(unsigned long int) bitset_size (bset));
(unsigned long int) bitset_size (bset));
pos = 30;
BITSET_FOR_EACH (iter, bset, i, 0)
{
if (pos > 70)
{
fprintf (file, "\n");
pos = 0;
fprintf (file, "\n");
pos = 0;
}
fprintf (file, "%lu ", (unsigned long int) i);
@@ -407,7 +407,7 @@ bitset_copy_ (bitset dst, bitset src)
four operand operations. */
static inline bool
bitset_op4_cmp (bitset dst, bitset src1, bitset src2, bitset src3,
enum bitset_ops op)
enum bitset_ops op)
{
bool changed = false;
bool stats_enabled_save;
+29 -29
View File
@@ -33,11 +33,11 @@
/* Attributes used to select a bitset implementation. */
enum bitset_attr {BITSET_FIXED = 1, /* Bitset size fixed. */
BITSET_VARIABLE = 2, /* Bitset size variable. */
BITSET_DENSE = 4, /* Bitset dense. */
BITSET_SPARSE = 8, /* Bitset sparse. */
BITSET_FRUGAL = 16, /* Prefer most compact. */
BITSET_GREEDY = 32}; /* Prefer fastest at memory expense. */
BITSET_VARIABLE = 2, /* Bitset size variable. */
BITSET_DENSE = 4, /* Bitset dense. */
BITSET_SPARSE = 8, /* Bitset sparse. */
BITSET_FRUGAL = 16, /* Prefer most compact. */
BITSET_GREEDY = 32}; /* Prefer fastest at memory expense. */
typedef unsigned int bitset_attrs;
@@ -49,26 +49,26 @@ union bitset_union
{
/* This must be the first member of every other structure that is a
member of this union. */
struct bbitset_struct b; /* Base bitset data. */
struct bbitset_struct b; /* Base bitset data. */
struct abitset_struct
{
struct bbitset_struct b;
bitset_word words[1]; /* The array of bits. */
bitset_word words[1]; /* The array of bits. */
} a;
struct ebitset_struct
{
struct bbitset_struct b;
bitset_windex size; /* Number of elements. */
struct ebitset_elt_struct **elts; /* Expanding array of ptrs to elts. */
bitset_windex size; /* Number of elements. */
struct ebitset_elt_struct **elts; /* Expanding array of ptrs to elts. */
} e;
struct lbitset_struct
{
struct bbitset_struct b;
struct lbitset_elt_struct *head; /* First element in linked list. */
struct lbitset_elt_struct *tail; /* Last element in linked list. */
struct lbitset_elt_struct *head; /* First element in linked list. */
struct lbitset_elt_struct *tail; /* Last element in linked list. */
} l;
struct bitset_stats_struct
@@ -80,7 +80,7 @@ union bitset_union
struct vbitset_struct
{
struct bbitset_struct b;
bitset_windex size; /* Allocated size of array. */
bitset_windex size; /* Allocated size of array. */
} v;
};
@@ -116,7 +116,7 @@ extern void bitset_free (bitset);
/* Create a bitset of desired type and size using an obstack. The
bitset is zeroed. */
extern bitset bitset_obstack_alloc (struct obstack *bobstack,
bitset_bindex, enum bitset_type);
bitset_bindex, enum bitset_type);
/* Free bitset allocated on obstack. */
extern void bitset_obstack_free (bitset);
@@ -312,14 +312,14 @@ extern void bitset_dump (FILE *, bitset);
printf ("%lu ", (unsigned long int) i);
};
*/
#define BITSET_FOR_EACH(ITER, BSET, INDEX, MIN) \
for (ITER.next = (MIN), ITER.num = BITSET_LIST_SIZE; \
(ITER.num == BITSET_LIST_SIZE) \
&& (ITER.num = bitset_list (BSET, ITER.list, \
BITSET_LIST_SIZE, &ITER.next));) \
for (ITER.i = 0; \
ITER.i < ITER.num && ((INDEX) = ITER.list[ITER.i], 1); \
ITER.i++)
#define BITSET_FOR_EACH(ITER, BSET, INDEX, MIN) \
for (ITER.next = (MIN), ITER.num = BITSET_LIST_SIZE; \
(ITER.num == BITSET_LIST_SIZE) \
&& (ITER.num = bitset_list (BSET, ITER.list, \
BITSET_LIST_SIZE, &ITER.next));) \
for (ITER.i = 0; \
ITER.i < ITER.num && ((INDEX) = ITER.list[ITER.i], 1); \
ITER.i++)
/* Loop over all elements of BSET, in reverse order starting with
@@ -334,14 +334,14 @@ extern void bitset_dump (FILE *, bitset);
printf ("%lu ", (unsigned long int) i);
};
*/
#define BITSET_FOR_EACH_REVERSE(ITER, BSET, INDEX, MIN) \
for (ITER.next = (MIN), ITER.num = BITSET_LIST_SIZE; \
(ITER.num == BITSET_LIST_SIZE) \
&& (ITER.num = bitset_list_reverse (BSET, ITER.list, \
BITSET_LIST_SIZE, &ITER.next));) \
for (ITER.i = 0; \
ITER.i < ITER.num && ((INDEX) = ITER.list[ITER.i], 1); \
ITER.i++)
#define BITSET_FOR_EACH_REVERSE(ITER, BSET, INDEX, MIN) \
for (ITER.next = (MIN), ITER.num = BITSET_LIST_SIZE; \
(ITER.num == BITSET_LIST_SIZE) \
&& (ITER.num = bitset_list_reverse (BSET, ITER.list, \
BITSET_LIST_SIZE, &ITER.next));) \
for (ITER.i = 0; \
ITER.i < ITER.num && ((INDEX) = ITER.list[ITER.i], 1); \
ITER.i++)
/* Define set operations in terms of logical operations. */
+39 -39
View File
@@ -48,29 +48,29 @@
/* Accessor macros. */
#define BITSET_STATS_ALLOCS_INC(TYPE) \
#define BITSET_STATS_ALLOCS_INC(TYPE) \
bitset_stats_info->types[(TYPE)].allocs++
#define BITSET_STATS_FREES_INC(BSET) \
#define BITSET_STATS_FREES_INC(BSET) \
bitset_stats_info->types[BITSET_TYPE_ (BSET)].frees++
#define BITSET_STATS_SETS_INC(BSET) \
#define BITSET_STATS_SETS_INC(BSET) \
bitset_stats_info->types[BITSET_TYPE_ (BSET)].sets++
#define BITSET_STATS_CACHE_SETS_INC(BSET) \
#define BITSET_STATS_CACHE_SETS_INC(BSET) \
bitset_stats_info->types[BITSET_TYPE_ (BSET)].cache_sets++
#define BITSET_STATS_RESETS_INC(BSET) \
#define BITSET_STATS_RESETS_INC(BSET) \
bitset_stats_info->types[BITSET_TYPE_ (BSET)].resets++
#define BITSET_STATS_CACHE_RESETS_INC(BSET) \
#define BITSET_STATS_CACHE_RESETS_INC(BSET) \
bitset_stats_info->types[BITSET_TYPE_ (BSET)].cache_resets++
#define BITSET_STATS_TESTS_INC(BSET) \
#define BITSET_STATS_TESTS_INC(BSET) \
bitset_stats_info->types[BITSET_TYPE_ (BSET)].tests++
#define BITSET_STATS_CACHE_TESTS_INC(BSET) \
#define BITSET_STATS_CACHE_TESTS_INC(BSET) \
bitset_stats_info->types[BITSET_TYPE_ (BSET)].cache_tests++
#define BITSET_STATS_LISTS_INC(BSET) \
#define BITSET_STATS_LISTS_INC(BSET) \
bitset_stats_info->types[BITSET_TYPE_ (BSET)].lists++
#define BITSET_STATS_LIST_COUNTS_INC(BSET, I) \
#define BITSET_STATS_LIST_COUNTS_INC(BSET, I) \
bitset_stats_info->types[BITSET_TYPE_ (BSET)].list_counts[(I)]++
#define BITSET_STATS_LIST_SIZES_INC(BSET, I) \
#define BITSET_STATS_LIST_SIZES_INC(BSET, I) \
bitset_stats_info->types[BITSET_TYPE_ (BSET)].list_sizes[(I)]++
#define BITSET_STATS_LIST_DENSITY_INC(BSET, I) \
#define BITSET_STATS_LIST_DENSITY_INC(BSET, I) \
bitset_stats_info->types[BITSET_TYPE_ (BSET)].list_density[(I)]++
@@ -105,7 +105,7 @@ bool bitset_stats_enabled = false;
/* Print a percentage histogram with message MSG to FILE. */
static void
bitset_percent_histogram_print (FILE *file, const char *name, const char *msg,
unsigned int n_bins, unsigned int *bins)
unsigned int n_bins, unsigned int *bins)
{
unsigned int i;
unsigned int total;
@@ -120,16 +120,16 @@ bitset_percent_histogram_print (FILE *file, const char *name, const char *msg,
fprintf (file, "%s %s", name, msg);
for (i = 0; i < n_bins; i++)
fprintf (file, "%.0f-%.0f%%\t%8u (%5.1f%%)\n",
i * 100.0 / n_bins,
(i + 1) * 100.0 / n_bins, bins[i],
(100.0 * bins[i]) / total);
i * 100.0 / n_bins,
(i + 1) * 100.0 / n_bins, bins[i],
(100.0 * bins[i]) / total);
}
/* Print a log histogram with message MSG to FILE. */
static void
bitset_log_histogram_print (FILE *file, const char *name, const char *msg,
unsigned int n_bins, unsigned int *bins)
unsigned int n_bins, unsigned int *bins)
{
unsigned int i;
unsigned int total;
@@ -153,50 +153,50 @@ bitset_log_histogram_print (FILE *file, const char *name, const char *msg,
fprintf (file, "%s %s", name, msg);
for (i = 0; i < 2; i++)
fprintf (file, "%*d\t%8u (%5.1f%%)\n",
max_width, i, bins[i], 100.0 * bins[i] / total);
max_width, i, bins[i], 100.0 * bins[i] / total);
for (; i < n_bins; i++)
fprintf (file, "%*lu-%lu\t%8u (%5.1f%%)\n",
max_width - ((unsigned int) (0.30103 * (i) + 0.9999) + 1),
1UL << (i - 1),
(1UL << i) - 1,
bins[i],
(100.0 * bins[i]) / total);
max_width - ((unsigned int) (0.30103 * (i) + 0.9999) + 1),
1UL << (i - 1),
(1UL << i) - 1,
bins[i],
(100.0 * bins[i]) / total);
}
/* Print bitset statistics to FILE. */
static void
bitset_stats_print_1 (FILE *file, const char *name,
struct bitset_type_info_struct *stats)
struct bitset_type_info_struct *stats)
{
if (!stats)
return;
fprintf (file, "%s:\n", name);
fprintf (file, _("%u bitset_allocs, %u freed (%.2f%%).\n"),
stats->allocs, stats->frees,
stats->allocs ? 100.0 * stats->frees / stats->allocs : 0);
stats->allocs, stats->frees,
stats->allocs ? 100.0 * stats->frees / stats->allocs : 0);
fprintf (file, _("%u bitset_sets, %u cached (%.2f%%)\n"),
stats->sets, stats->cache_sets,
stats->sets ? 100.0 * stats->cache_sets / stats->sets : 0);
stats->sets, stats->cache_sets,
stats->sets ? 100.0 * stats->cache_sets / stats->sets : 0);
fprintf (file, _("%u bitset_resets, %u cached (%.2f%%)\n"),
stats->resets, stats->cache_resets,
stats->resets ? 100.0 * stats->cache_resets / stats->resets : 0);
stats->resets, stats->cache_resets,
stats->resets ? 100.0 * stats->cache_resets / stats->resets : 0);
fprintf (file, _("%u bitset_tests, %u cached (%.2f%%)\n"),
stats->tests, stats->cache_tests,
stats->tests ? 100.0 * stats->cache_tests / stats->tests : 0);
stats->tests, stats->cache_tests,
stats->tests ? 100.0 * stats->cache_tests / stats->tests : 0);
fprintf (file, _("%u bitset_lists\n"), stats->lists);
bitset_log_histogram_print (file, name, _("count log histogram\n"),
BITSET_LOG_COUNT_BINS, stats->list_counts);
BITSET_LOG_COUNT_BINS, stats->list_counts);
bitset_log_histogram_print (file, name, _("size log histogram\n"),
BITSET_LOG_SIZE_BINS, stats->list_sizes);
BITSET_LOG_SIZE_BINS, stats->list_sizes);
bitset_percent_histogram_print (file, name, _("density histogram\n"),
BITSET_DENSITY_BINS, stats->list_density);
BITSET_DENSITY_BINS, stats->list_density);
}
@@ -216,7 +216,7 @@ bitset_stats_print (FILE *file, bool verbose ATTRIBUTE_UNUSED)
for (i = 0; i < BITSET_TYPE_NUM; i++)
bitset_stats_print_1 (file, bitset_type_names[i],
&bitset_stats_info->types[i]);
&bitset_stats_info->types[i]);
}
@@ -340,7 +340,7 @@ bitset_stats_reset (bitset dst, bitset_bindex bitno)
if (offset < bset->b.csize)
{
bset->b.cdata[offset] &=
~((bitset_word) 1 << (bitno % BITSET_WORD_BITS));
~((bitset_word) 1 << (bitno % BITSET_WORD_BITS));
BITSET_STATS_CACHE_RESETS_INC (bset);
}
else
@@ -570,7 +570,7 @@ bitset_stats_or_and_cmp (bitset dst, bitset src1, bitset src2, bitset src3)
static bitset_bindex
bitset_stats_list (bitset bset, bitset_bindex *list,
bitset_bindex num, bitset_bindex *next)
bitset_bindex num, bitset_bindex *next)
{
bitset_bindex count;
bitset_bindex tmp;
@@ -607,7 +607,7 @@ bitset_stats_list (bitset bset, bitset_bindex *list,
static bitset_bindex
bitset_stats_list_reverse (bitset bset, bitset_bindex *list,
bitset_bindex num, bitset_bindex *next)
bitset_bindex num, bitset_bindex *next)
{
return BITSET_LIST_REVERSE_ (bset->s.bset, list, num, next);
}
+1 -1
View File
@@ -56,7 +56,7 @@ bitsetv_matrix_dump (FILE * out, const char *title, bitsetv bset)
{
fprintf (out, "%2lu|", (unsigned long int) i);
for (j = 0; j < hsize; ++j)
fputs (bitset_test (bset[i], j) ? "1" : " ", out);
fputs (bitset_test (bset[i], j) ? "1" : " ", out);
fputs ("|\n", out);
}
+3 -3
View File
@@ -27,7 +27,7 @@
type TYPE. */
bitset *
bitsetv_alloc (bitset_bindex n_vecs, bitset_bindex n_bits,
enum bitset_type type)
enum bitset_type type)
{
size_t vector_bytes;
size_t bytes;
@@ -116,7 +116,7 @@ bitsetv_transitive_closure (bitsetv bsetv)
for (i = 0; bsetv[i]; i++)
for (j = 0; bsetv[j]; j++)
if (bitset_test (bsetv[j], i))
bitset_or (bsetv[j], bsetv[j], bsetv[i]);
bitset_or (bsetv[j], bsetv[j], bsetv[i]);
}
@@ -139,7 +139,7 @@ bitsetv_reflexive_transitive_closure (bitsetv bsetv)
FILE. */
void
bitsetv_dump (FILE *file, char const *title, char const *subtitle,
bitsetv bsetv)
bitsetv bsetv)
{
bitset_windex i;
+304 -304
View File
@@ -58,7 +58,7 @@ typedef struct ebitset_elt_struct
{
union
{
bitset_word words[EBITSET_ELT_WORDS]; /* Bits that are set. */
bitset_word words[EBITSET_ELT_WORDS]; /* Bits that are set. */
struct ebitset_elt_struct *next;
}
u;
@@ -84,7 +84,7 @@ static ebitset_elt ebitset_zero_elts[1]; /* Elements of all zero bits. */
/* Obstack to allocate bitset elements from. */
static struct obstack ebitset_obstack;
static bool ebitset_obstack_init = false;
static ebitset_elt *ebitset_free_list; /* Free list of bitset elements. */
static ebitset_elt *ebitset_free_list; /* Free list of bitset elements. */
#define EBITSET_N_ELTS(N) (((N) + EBITSET_ELT_BITS - 1) / EBITSET_ELT_BITS)
#define EBITSET_ELTS(BSET) ((BSET)->e.elts)
@@ -96,7 +96,7 @@ static ebitset_elt *ebitset_free_list; /* Free list of bitset elements. */
/* Disable bitset cache and mark BSET as being zero. */
#define EBITSET_ZERO_SET(BSET) ((BSET)->b.cindex = BITSET_WINDEX_MAX, \
(BSET)->b.cdata = 0)
(BSET)->b.cdata = 0)
#define EBITSET_CACHE_DISABLE(BSET) ((BSET)->b.cindex = BITSET_WINDEX_MAX)
@@ -136,37 +136,37 @@ ebitset_resize (bitset src, bitset_bindex n_bits)
bitset_windex size;
/* The bitset needs to grow. If we already have enough memory
allocated, then just zero what we need. */
allocated, then just zero what we need. */
if (newsize > EBITSET_ASIZE (src))
{
/* We need to allocate more memory. When oldsize is
non-zero this means that we are changing the size, so
grow the bitset 25% larger than requested to reduce
number of reallocations. */
{
/* We need to allocate more memory. When oldsize is
non-zero this means that we are changing the size, so
grow the bitset 25% larger than requested to reduce
number of reallocations. */
if (oldsize == 0)
size = newsize;
else
size = newsize + newsize / 4;
if (oldsize == 0)
size = newsize;
else
size = newsize + newsize / 4;
EBITSET_ELTS (src)
= realloc (EBITSET_ELTS (src), size * sizeof (ebitset_elt *));
EBITSET_ASIZE (src) = size;
}
EBITSET_ELTS (src)
= realloc (EBITSET_ELTS (src), size * sizeof (ebitset_elt *));
EBITSET_ASIZE (src) = size;
}
memset (EBITSET_ELTS (src) + oldsize, 0,
(newsize - oldsize) * sizeof (ebitset_elt *));
(newsize - oldsize) * sizeof (ebitset_elt *));
}
else
{
/* The bitset needs to shrink. There's no point deallocating
the memory unless it is shrinking by a reasonable amount. */
the memory unless it is shrinking by a reasonable amount. */
if ((oldsize - newsize) >= oldsize / 2)
{
EBITSET_ELTS (src)
= realloc (EBITSET_ELTS (src), newsize * sizeof (ebitset_elt *));
EBITSET_ASIZE (src) = newsize;
}
{
EBITSET_ELTS (src)
= realloc (EBITSET_ELTS (src), newsize * sizeof (ebitset_elt *));
EBITSET_ASIZE (src) = newsize;
}
/* Need to prune any excess bits. FIXME. */
}
@@ -190,16 +190,16 @@ ebitset_elt_alloc (void)
else
{
if (!ebitset_obstack_init)
{
ebitset_obstack_init = true;
{
ebitset_obstack_init = true;
/* Let particular systems override the size of a chunk. */
/* Let particular systems override the size of a chunk. */
#ifndef OBSTACK_CHUNK_SIZE
#define OBSTACK_CHUNK_SIZE 0
#endif
/* Let them override the alloc and free routines too. */
/* Let them override the alloc and free routines too. */
#ifndef OBSTACK_CHUNK_ALLOC
#define OBSTACK_CHUNK_ALLOC xmalloc
@@ -213,16 +213,16 @@ ebitset_elt_alloc (void)
#define __alignof__(type) 0
#endif
obstack_specify_allocation (&ebitset_obstack, OBSTACK_CHUNK_SIZE,
__alignof__ (ebitset_elt),
OBSTACK_CHUNK_ALLOC,
OBSTACK_CHUNK_FREE);
}
obstack_specify_allocation (&ebitset_obstack, OBSTACK_CHUNK_SIZE,
__alignof__ (ebitset_elt),
OBSTACK_CHUNK_ALLOC,
OBSTACK_CHUNK_FREE);
}
/* Perhaps we should add a number of new elements to the free
list. */
list. */
elt = (ebitset_elt *) obstack_alloc (&ebitset_obstack,
sizeof (ebitset_elt));
sizeof (ebitset_elt));
}
return elt;
@@ -293,7 +293,7 @@ ebitset_elt_zero_p (ebitset_elt *elt)
static ebitset_elt *
ebitset_elt_find (bitset bset, bitset_bindex bindex,
enum ebitset_find_mode mode)
enum ebitset_find_mode mode)
{
ebitset_elt *elt;
bitset_windex size;
@@ -308,13 +308,13 @@ ebitset_elt_find (bitset bset, bitset_bindex bindex,
if (eindex < size)
{
if ((elt = elts[eindex]))
{
if (EBITSET_WORDS (elt) == bset->b.cdata)
return elt;
{
if (EBITSET_WORDS (elt) == bset->b.cdata)
return elt;
EBITSET_CACHE_SET (bset, eindex);
return elt;
}
EBITSET_CACHE_SET (bset, eindex);
return elt;
}
}
/* The element could not be found. */
@@ -329,7 +329,7 @@ ebitset_elt_find (bitset bset, bitset_bindex bindex,
case EBITSET_CREATE:
if (eindex >= size)
ebitset_resize (bset, bindex);
ebitset_resize (bset, bindex);
/* Create a new element. */
elt = ebitset_elt_calloc ();
@@ -361,22 +361,22 @@ ebitset_weed (bitset bset)
ebitset_elt *elt = elts[j];
if (elt)
{
if (ebitset_elt_zero_p (elt))
{
ebitset_elt_remove (bset, j);
count++;
}
}
{
if (ebitset_elt_zero_p (elt))
{
ebitset_elt_remove (bset, j);
count++;
}
}
else
count++;
count++;
}
count = j - count;
if (!count)
{
/* All the bits are zero. We could shrink the elts.
For now just mark BSET as known to be zero. */
For now just mark BSET as known to be zero. */
EBITSET_ZERO_SET (bset);
}
else
@@ -402,7 +402,7 @@ ebitset_zero (bitset bset)
ebitset_elt *elt = elts[j];
if (elt)
ebitset_elt_remove (bset, j);
ebitset_elt_remove (bset, j);
}
/* All the bits are zero. We could shrink the elts.
@@ -437,13 +437,13 @@ ebitset_equal_p (bitset dst, bitset src)
ebitset_elt *delt = delts[j];
if (!selt && !delt)
continue;
continue;
if ((selt && !delt) || (!selt && delt))
return false;
return false;
for (i = 0; i < EBITSET_ELT_WORDS; i++)
if (EBITSET_WORDS (selt)[i] != EBITSET_WORDS (delt)[i])
return false;
if (EBITSET_WORDS (selt)[i] != EBITSET_WORDS (delt)[i])
return false;
}
return true;
}
@@ -472,14 +472,14 @@ ebitset_copy_ (bitset dst, bitset src)
ebitset_elt *selt = selts[j];
if (selt)
{
ebitset_elt *tmp;
{
ebitset_elt *tmp;
tmp = ebitset_elt_alloc ();
delts[j] = tmp;
memcpy (EBITSET_WORDS (tmp), EBITSET_WORDS (selt),
sizeof (EBITSET_WORDS (selt)));
}
tmp = ebitset_elt_alloc ();
delts[j] = tmp;
memcpy (EBITSET_WORDS (tmp), EBITSET_WORDS (selt),
sizeof (EBITSET_WORDS (selt)));
}
}
EBITSET_NONZERO_SET (dst);
}
@@ -545,9 +545,9 @@ ebitset_test (bitset src, bitset_bindex bitno)
bitset_windex windex = bitno / BITSET_WORD_BITS;
return (ebitset_elt_find (src, bitno, EBITSET_FIND)
&& ((src->b.cdata[windex - src->b.cindex]
>> (bitno % BITSET_WORD_BITS))
& 1));
&& ((src->b.cdata[windex - src->b.cindex]
>> (bitno % BITSET_WORD_BITS))
& 1));
}
@@ -564,7 +564,7 @@ ebitset_free (bitset bset)
found and with *NEXT indicating where search stopped. */
static bitset_bindex
ebitset_list_reverse (bitset bset, bitset_bindex *list,
bitset_bindex num, bitset_bindex *next)
bitset_bindex num, bitset_bindex *next)
{
bitset_bindex n_bits;
bitset_bindex bitno;
@@ -610,33 +610,33 @@ ebitset_list_reverse (bitset bset, bitset_bindex *list,
elt = elts[eindex];
if (elt)
{
srcp = EBITSET_WORDS (elt);
{
srcp = EBITSET_WORDS (elt);
do
{
bitset_word word;
do
{
bitset_word word;
word = srcp[woffset] << (BITSET_WORD_BITS - 1 - bcount);
word = srcp[woffset] << (BITSET_WORD_BITS - 1 - bcount);
for (; word; bcount--)
{
if (word & BITSET_MSB)
{
list[count++] = boffset + bcount;
if (count >= num)
{
*next = n_bits - (boffset + bcount);
return count;
}
}
word <<= 1;
}
boffset -= BITSET_WORD_BITS;
bcount = BITSET_WORD_BITS - 1;
}
while (woffset--);
}
for (; word; bcount--)
{
if (word & BITSET_MSB)
{
list[count++] = boffset + bcount;
if (count >= num)
{
*next = n_bits - (boffset + bcount);
return count;
}
}
word <<= 1;
}
boffset -= BITSET_WORD_BITS;
bcount = BITSET_WORD_BITS - 1;
}
while (woffset--);
}
woffset = EBITSET_ELT_WORDS - 1;
boffset = eindex * EBITSET_ELT_BITS - BITSET_WORD_BITS;
@@ -653,7 +653,7 @@ ebitset_list_reverse (bitset bset, bitset_bindex *list,
found and with *NEXT indicating where search stopped. */
static bitset_bindex
ebitset_list (bitset bset, bitset_bindex *list,
bitset_bindex num, bitset_bindex *next)
bitset_bindex num, bitset_bindex *next)
{
bitset_bindex bitno;
bitset_windex windex;
@@ -680,33 +680,33 @@ ebitset_list (bitset bset, bitset_bindex *list,
elt = elts[eindex];
if (elt)
{
bitset_windex woffset;
bitset_word *srcp = EBITSET_WORDS (elt);
{
bitset_windex woffset;
bitset_word *srcp = EBITSET_WORDS (elt);
windex = bitno / BITSET_WORD_BITS;
woffset = eindex * EBITSET_ELT_WORDS;
windex = bitno / BITSET_WORD_BITS;
woffset = eindex * EBITSET_ELT_WORDS;
for (; (windex - woffset) < EBITSET_ELT_WORDS; windex++)
{
word = srcp[windex - woffset] >> (bitno % BITSET_WORD_BITS);
for (; (windex - woffset) < EBITSET_ELT_WORDS; windex++)
{
word = srcp[windex - woffset] >> (bitno % BITSET_WORD_BITS);
for (; word; bitno++)
{
if (word & 1)
{
list[count++] = bitno;
if (count >= num)
{
*next = bitno + 1;
return count;
}
}
word >>= 1;
}
bitno = (windex + 1) * BITSET_WORD_BITS;
}
}
for (; word; bitno++)
{
if (word & 1)
{
list[count++] = bitno;
if (count >= num)
{
*next = bitno + 1;
return count;
}
}
word >>= 1;
}
bitno = (windex + 1) * BITSET_WORD_BITS;
}
}
/* Skip to next element. */
eindex++;
@@ -722,108 +722,108 @@ ebitset_list (bitset bset, bitset_bindex *list,
elt = elts[eindex];
if (!elt)
continue;
continue;
srcp = EBITSET_WORDS (elt);
windex = eindex * EBITSET_ELT_WORDS;
if ((count + EBITSET_ELT_BITS) < num)
{
/* The coast is clear, plant boot! */
{
/* The coast is clear, plant boot! */
#if EBITSET_ELT_WORDS == 2
word = srcp[0];
if (word)
{
if (!(word & 0xffff))
{
word >>= 16;
bitno += 16;
}
if (!(word & 0xff))
{
word >>= 8;
bitno += 8;
}
for (; word; bitno++)
{
if (word & 1)
list[count++] = bitno;
word >>= 1;
}
}
windex++;
bitno = windex * BITSET_WORD_BITS;
word = srcp[0];
if (word)
{
if (!(word & 0xffff))
{
word >>= 16;
bitno += 16;
}
if (!(word & 0xff))
{
word >>= 8;
bitno += 8;
}
for (; word; bitno++)
{
if (word & 1)
list[count++] = bitno;
word >>= 1;
}
}
windex++;
bitno = windex * BITSET_WORD_BITS;
word = srcp[1];
if (word)
{
if (!(word & 0xffff))
{
word >>= 16;
bitno += 16;
}
for (; word; bitno++)
{
if (word & 1)
list[count++] = bitno;
word >>= 1;
}
}
windex++;
bitno = windex * BITSET_WORD_BITS;
word = srcp[1];
if (word)
{
if (!(word & 0xffff))
{
word >>= 16;
bitno += 16;
}
for (; word; bitno++)
{
if (word & 1)
list[count++] = bitno;
word >>= 1;
}
}
windex++;
bitno = windex * BITSET_WORD_BITS;
#else
for (i = 0; i < EBITSET_ELT_WORDS; i++, windex++)
{
bitno = windex * BITSET_WORD_BITS;
for (i = 0; i < EBITSET_ELT_WORDS; i++, windex++)
{
bitno = windex * BITSET_WORD_BITS;
word = srcp[i];
if (word)
{
if (!(word & 0xffff))
{
word >>= 16;
bitno += 16;
}
if (!(word & 0xff))
{
word >>= 8;
bitno += 8;
}
for (; word; bitno++)
{
if (word & 1)
list[count++] = bitno;
word >>= 1;
}
}
}
word = srcp[i];
if (word)
{
if (!(word & 0xffff))
{
word >>= 16;
bitno += 16;
}
if (!(word & 0xff))
{
word >>= 8;
bitno += 8;
}
for (; word; bitno++)
{
if (word & 1)
list[count++] = bitno;
word >>= 1;
}
}
}
#endif
}
}
else
{
/* Tread more carefully since we need to check
if array overflows. */
{
/* Tread more carefully since we need to check
if array overflows. */
for (i = 0; i < EBITSET_ELT_WORDS; i++, windex++)
{
bitno = windex * BITSET_WORD_BITS;
for (i = 0; i < EBITSET_ELT_WORDS; i++, windex++)
{
bitno = windex * BITSET_WORD_BITS;
for (word = srcp[i]; word; bitno++)
{
if (word & 1)
{
list[count++] = bitno;
if (count >= num)
{
*next = bitno + 1;
return count;
}
}
word >>= 1;
}
}
}
for (word = srcp[i]; word; bitno++)
{
if (word & 1)
{
list[count++] = bitno;
if (count >= num)
{
*next = bitno + 1;
return count;
}
}
word >>= 1;
}
}
}
}
*next = bitno;
@@ -853,19 +853,19 @@ ebitset_unused_clear (bitset dst)
elt = elts[eindex];
if (elt)
{
bitset_windex windex;
bitset_windex woffset;
bitset_word *srcp = EBITSET_WORDS (elt);
{
bitset_windex windex;
bitset_windex woffset;
bitset_word *srcp = EBITSET_WORDS (elt);
windex = n_bits / BITSET_WORD_BITS;
woffset = eindex * EBITSET_ELT_WORDS;
windex = n_bits / BITSET_WORD_BITS;
woffset = eindex * EBITSET_ELT_WORDS;
srcp[windex - woffset] &= ((bitset_word) 1 << last_bit) - 1;
windex++;
for (; (windex - woffset) < EBITSET_ELT_WORDS; windex++)
srcp[windex - woffset] = 0;
}
srcp[windex - woffset] &= ((bitset_word) 1 << last_bit) - 1;
windex++;
for (; (windex - woffset) < EBITSET_ELT_WORDS; windex++)
srcp[windex - woffset] = 0;
}
}
}
@@ -879,9 +879,9 @@ ebitset_ones (bitset dst)
for (j = 0; j < EBITSET_SIZE (dst); j++)
{
/* Create new elements if they cannot be found. Perhaps
we should just add pointers to a ones element? */
we should just add pointers to a ones element? */
elt =
ebitset_elt_find (dst, j * EBITSET_ELT_BITS, EBITSET_CREATE);
ebitset_elt_find (dst, j * EBITSET_ELT_BITS, EBITSET_CREATE);
memset (EBITSET_WORDS (elt), -1, sizeof (EBITSET_WORDS (elt)));
}
EBITSET_NONZERO_SET (dst);
@@ -904,12 +904,12 @@ ebitset_empty_p (bitset dst)
ebitset_elt *elt = elts[j];
if (elt)
{
if (!ebitset_elt_zero_p (elt))
return 0;
/* Do some weeding as we go. */
ebitset_elt_remove (dst, j);
}
{
if (!ebitset_elt_zero_p (elt))
return 0;
/* Do some weeding as we go. */
ebitset_elt_remove (dst, j);
}
}
/* All the bits are zero. We could shrink the elts.
@@ -932,14 +932,14 @@ ebitset_not (bitset dst, bitset src)
for (j = 0; j < EBITSET_SIZE (src); j++)
{
/* Create new elements for dst if they cannot be found
or substitute zero elements if src elements not found. */
or substitute zero elements if src elements not found. */
selt =
ebitset_elt_find (dst, j * EBITSET_ELT_BITS, EBITSET_SUBST);
ebitset_elt_find (dst, j * EBITSET_ELT_BITS, EBITSET_SUBST);
delt =
ebitset_elt_find (dst, j * EBITSET_ELT_BITS, EBITSET_CREATE);
ebitset_elt_find (dst, j * EBITSET_ELT_BITS, EBITSET_CREATE);
for (i = 0; i < EBITSET_ELT_WORDS; i++)
EBITSET_WORDS (delt)[i] = ~EBITSET_WORDS (selt)[i];
EBITSET_WORDS (delt)[i] = ~EBITSET_WORDS (selt)[i];
}
EBITSET_NONZERO_SET (dst);
ebitset_unused_clear (dst);
@@ -972,17 +972,17 @@ ebitset_subset_p (bitset dst, bitset src)
delt = j < dsize ? delts[j] : 0;
if (!selt && !delt)
continue;
continue;
if (!selt)
selt = &ebitset_zero_elts[0];
selt = &ebitset_zero_elts[0];
if (!delt)
delt = &ebitset_zero_elts[0];
delt = &ebitset_zero_elts[0];
for (i = 0; i < EBITSET_ELT_WORDS; i++)
if (EBITSET_WORDS (delt)[i]
!= (EBITSET_WORDS (selt)[i] | EBITSET_WORDS (delt)[i]))
return false;
if (EBITSET_WORDS (delt)[i]
!= (EBITSET_WORDS (selt)[i] | EBITSET_WORDS (delt)[i]))
return false;
}
return true;
}
@@ -1014,11 +1014,11 @@ ebitset_disjoint_p (bitset dst, bitset src)
delt = j < dsize ? delts[j] : 0;
if (!selt || !delt)
continue;
continue;
for (i = 0; i < EBITSET_ELT_WORDS; i++)
if ((EBITSET_WORDS (selt)[i] & EBITSET_WORDS (delt)[i]))
return false;
if ((EBITSET_WORDS (selt)[i] & EBITSET_WORDS (delt)[i]))
return false;
}
return true;
}
@@ -1066,93 +1066,93 @@ ebitset_op3_cmp (bitset dst, bitset src1, bitset src2, enum bitset_ops op)
delt = j < dsize ? delts[j] : 0;
if (!selt1 && !selt2)
{
if (delt)
{
changed = true;
ebitset_elt_remove (dst, j);
}
continue;
}
{
if (delt)
{
changed = true;
ebitset_elt_remove (dst, j);
}
continue;
}
if (!selt1)
selt1 = &ebitset_zero_elts[0];
selt1 = &ebitset_zero_elts[0];
if (!selt2)
selt2 = &ebitset_zero_elts[0];
selt2 = &ebitset_zero_elts[0];
if (!delt)
delt = ebitset_elt_calloc ();
delt = ebitset_elt_calloc ();
else
delts[j] = 0;
delts[j] = 0;
srcp1 = EBITSET_WORDS (selt1);
srcp2 = EBITSET_WORDS (selt2);
dstp = EBITSET_WORDS (delt);
switch (op)
{
default:
abort ();
{
default:
abort ();
case BITSET_OP_OR:
for (i = 0; i < EBITSET_ELT_WORDS; i++, dstp++)
{
bitset_word tmp = *srcp1++ | *srcp2++;
case BITSET_OP_OR:
for (i = 0; i < EBITSET_ELT_WORDS; i++, dstp++)
{
bitset_word tmp = *srcp1++ | *srcp2++;
if (*dstp != tmp)
{
changed = true;
*dstp = tmp;
}
}
break;
if (*dstp != tmp)
{
changed = true;
*dstp = tmp;
}
}
break;
case BITSET_OP_AND:
for (i = 0; i < EBITSET_ELT_WORDS; i++, dstp++)
{
bitset_word tmp = *srcp1++ & *srcp2++;
case BITSET_OP_AND:
for (i = 0; i < EBITSET_ELT_WORDS; i++, dstp++)
{
bitset_word tmp = *srcp1++ & *srcp2++;
if (*dstp != tmp)
{
changed = true;
*dstp = tmp;
}
}
break;
if (*dstp != tmp)
{
changed = true;
*dstp = tmp;
}
}
break;
case BITSET_OP_XOR:
for (i = 0; i < EBITSET_ELT_WORDS; i++, dstp++)
{
bitset_word tmp = *srcp1++ ^ *srcp2++;
case BITSET_OP_XOR:
for (i = 0; i < EBITSET_ELT_WORDS; i++, dstp++)
{
bitset_word tmp = *srcp1++ ^ *srcp2++;
if (*dstp != tmp)
{
changed = true;
*dstp = tmp;
}
}
break;
if (*dstp != tmp)
{
changed = true;
*dstp = tmp;
}
}
break;
case BITSET_OP_ANDN:
for (i = 0; i < EBITSET_ELT_WORDS; i++, dstp++)
{
bitset_word tmp = *srcp1++ & ~(*srcp2++);
case BITSET_OP_ANDN:
for (i = 0; i < EBITSET_ELT_WORDS; i++, dstp++)
{
bitset_word tmp = *srcp1++ & ~(*srcp2++);
if (*dstp != tmp)
{
changed = true;
*dstp = tmp;
}
}
break;
}
if (*dstp != tmp)
{
changed = true;
*dstp = tmp;
}
}
break;
}
if (!ebitset_elt_zero_p (delt))
{
ebitset_elt_add (dst, delt, j);
}
{
ebitset_elt_add (dst, delt, j);
}
else
{
ebitset_elt_free (delt);
}
{
ebitset_elt_free (delt);
}
}
/* If we have elements of DST left over, free them all. */
@@ -1165,7 +1165,7 @@ ebitset_op3_cmp (bitset dst, bitset src1, bitset src2, enum bitset_ops op)
delt = delts[j];
if (delt)
ebitset_elt_remove (dst, j);
ebitset_elt_remove (dst, j);
}
EBITSET_NONZERO_SET (dst);
+360 -360
View File
@@ -60,10 +60,10 @@ typedef bitset_word lbitset_word;
These are linked together in a doubly-linked list. */
typedef struct lbitset_elt_struct
{
struct lbitset_elt_struct *next; /* Next element. */
struct lbitset_elt_struct *prev; /* Previous element. */
bitset_windex index; /* bitno / BITSET_WORD_BITS. */
bitset_word words[LBITSET_ELT_WORDS]; /* Bits that are set. */
struct lbitset_elt_struct *next; /* Next element. */
struct lbitset_elt_struct *prev; /* Previous element. */
bitset_windex index; /* bitno / BITSET_WORD_BITS. */
bitset_word words[LBITSET_ELT_WORDS]; /* Bits that are set. */
}
lbitset_elt;
@@ -76,7 +76,7 @@ static lbitset_elt lbitset_zero_elts[3]; /* Elements of all zero bits. */
/* Obstack to allocate bitset elements from. */
static struct obstack lbitset_obstack;
static bool lbitset_obstack_init = false;
static lbitset_elt *lbitset_free_list; /* Free list of bitset elements. */
static lbitset_elt *lbitset_free_list; /* Free list of bitset elements. */
extern void debug_lbitset (bitset);
@@ -102,16 +102,16 @@ lbitset_elt_alloc (void)
else
{
if (!lbitset_obstack_init)
{
lbitset_obstack_init = true;
{
lbitset_obstack_init = true;
/* Let particular systems override the size of a chunk. */
/* Let particular systems override the size of a chunk. */
#ifndef OBSTACK_CHUNK_SIZE
#define OBSTACK_CHUNK_SIZE 0
#endif
/* Let them override the alloc and free routines too. */
/* Let them override the alloc and free routines too. */
#ifndef OBSTACK_CHUNK_ALLOC
#define OBSTACK_CHUNK_ALLOC xmalloc
@@ -125,16 +125,16 @@ lbitset_elt_alloc (void)
#define __alignof__(type) 0
#endif
obstack_specify_allocation (&lbitset_obstack, OBSTACK_CHUNK_SIZE,
__alignof__ (lbitset_elt),
OBSTACK_CHUNK_ALLOC,
OBSTACK_CHUNK_FREE);
}
obstack_specify_allocation (&lbitset_obstack, OBSTACK_CHUNK_SIZE,
__alignof__ (lbitset_elt),
OBSTACK_CHUNK_ALLOC,
OBSTACK_CHUNK_FREE);
}
/* Perhaps we should add a number of new elements to the free
list. */
list. */
elt = (lbitset_elt *) obstack_alloc (&lbitset_obstack,
sizeof (lbitset_elt));
sizeof (lbitset_elt));
}
return elt;
@@ -185,20 +185,20 @@ lbitset_elt_unlink (bitset bset, lbitset_elt *elt)
if (LBITSET_CURRENT (bset) == elt)
{
if (next)
{
bset->b.cdata = next->words;
bset->b.cindex = next->index;
}
{
bset->b.cdata = next->words;
bset->b.cindex = next->index;
}
else if (prev)
{
bset->b.cdata = prev->words;
bset->b.cindex = prev->index;
}
{
bset->b.cdata = prev->words;
bset->b.cindex = prev->index;
}
else
{
bset->b.csize = 0;
bset->b.cdata = 0;
}
{
bset->b.csize = 0;
bset->b.cdata = 0;
}
}
lbitset_elt_free (elt);
@@ -278,13 +278,13 @@ lbitset_elt_link (bitset bset, lbitset_elt *elt)
else if (windex < bset->b.cindex)
{
for (ptr = current;
ptr->prev && ptr->prev->index > windex; ptr = ptr->prev)
continue;
ptr->prev && ptr->prev->index > windex; ptr = ptr->prev)
continue;
if (ptr->prev)
ptr->prev->next = elt;
ptr->prev->next = elt;
else
LBITSET_HEAD (bset) = elt;
LBITSET_HEAD (bset) = elt;
elt->prev = ptr->prev;
elt->next = ptr;
@@ -295,13 +295,13 @@ lbitset_elt_link (bitset bset, lbitset_elt *elt)
else
{
for (ptr = current;
ptr->next && ptr->next->index < windex; ptr = ptr->next)
continue;
ptr->next && ptr->next->index < windex; ptr = ptr->next)
continue;
if (ptr->next)
ptr->next->prev = elt;
ptr->next->prev = elt;
else
LBITSET_TAIL (bset) = elt;
LBITSET_TAIL (bset) = elt;
elt->next = ptr->next;
elt->prev = ptr;
@@ -317,7 +317,7 @@ lbitset_elt_link (bitset bset, lbitset_elt *elt)
static lbitset_elt *
lbitset_elt_find (bitset bset, bitset_windex windex,
enum lbitset_find_mode mode)
enum lbitset_find_mode mode)
{
lbitset_elt *elt;
lbitset_elt *current;
@@ -327,7 +327,7 @@ lbitset_elt_find (bitset bset, bitset_windex windex,
current = LBITSET_CURRENT (bset);
/* Check if element is the cached element. */
if ((windex - bset->b.cindex) < bset->b.csize)
return current;
return current;
}
else
{
@@ -337,28 +337,28 @@ lbitset_elt_find (bitset bset, bitset_windex windex,
if (current)
{
if (windex < bset->b.cindex)
{
for (elt = current;
elt->prev && elt->index > windex; elt = elt->prev)
continue;
}
{
for (elt = current;
elt->prev && elt->index > windex; elt = elt->prev)
continue;
}
else
{
for (elt = current;
elt->next && (elt->index + LBITSET_ELT_WORDS - 1) < windex;
elt = elt->next)
continue;
}
{
for (elt = current;
elt->next && (elt->index + LBITSET_ELT_WORDS - 1) < windex;
elt = elt->next)
continue;
}
/* ELT is the nearest to the one we want. If it's not the one
we want, the one we want does not exist. */
we want, the one we want does not exist. */
if (windex - elt->index < LBITSET_ELT_WORDS)
{
bset->b.cindex = elt->index;
bset->b.csize = LBITSET_ELT_WORDS;
bset->b.cdata = elt->words;
return elt;
}
{
bset->b.cindex = elt->index;
bset->b.csize = LBITSET_ELT_WORDS;
bset->b.cdata = elt->words;
return elt;
}
}
switch (mode)
@@ -394,7 +394,7 @@ lbitset_weed (bitset bset)
{
next = elt->next;
if (lbitset_elt_zero_p (elt))
lbitset_elt_unlink (bset, elt);
lbitset_elt_unlink (bset, elt);
}
}
@@ -431,11 +431,11 @@ lbitset_equal_p (bitset dst, bitset src)
selt && delt; selt = selt->next, delt = delt->next)
{
if (selt->index != delt->index)
return false;
return false;
for (j = 0; j < LBITSET_ELT_WORDS; j++)
if (delt->words[j] != selt->words[j])
return false;
if (delt->words[j] != selt->words[j])
return false;
}
return !selt && !delt;
}
@@ -467,9 +467,9 @@ lbitset_copy (bitset dst, bitset src)
tmp->prev = prev;
tmp->next = 0;
if (prev)
prev->next = tmp;
prev->next = tmp;
else
LBITSET_HEAD (dst) = tmp;
LBITSET_HEAD (dst) = tmp;
prev = tmp;
memcpy (tmp->words, elt->words, sizeof (elt->words));
@@ -549,9 +549,9 @@ lbitset_test (bitset src, bitset_bindex bitno)
bitset_windex windex = bitno / BITSET_WORD_BITS;
return (lbitset_elt_find (src, windex, LBITSET_FIND)
&& ((src->b.cdata[windex - src->b.cindex]
>> (bitno % BITSET_WORD_BITS))
& 1));
&& ((src->b.cdata[windex - src->b.cindex]
>> (bitno % BITSET_WORD_BITS))
& 1));
}
@@ -567,7 +567,7 @@ lbitset_free (bitset bset)
found and with *NEXT indicating where search stopped. */
static bitset_bindex
lbitset_list_reverse (bitset bset, bitset_bindex *list,
bitset_bindex num, bitset_bindex *next)
bitset_bindex num, bitset_bindex *next)
{
bitset_bindex rbitno;
bitset_bindex bitno;
@@ -603,7 +603,7 @@ lbitset_list_reverse (bitset bset, bitset_bindex *list,
if (windex >= elt->index + LBITSET_ELT_WORDS)
{
/* We are trying to start in no-mans land so start
at end of current elt. */
at end of current elt. */
bcount = BITSET_WORD_BITS - 1;
windex = elt->index + LBITSET_ELT_WORDS - 1;
}
@@ -623,33 +623,33 @@ lbitset_list_reverse (bitset bset, bitset_bindex *list,
bitset_word *srcp = elt->words;
for (; (windex - elt->index) < LBITSET_ELT_WORDS;
windex--, boffset -= BITSET_WORD_BITS,
bcount = BITSET_WORD_BITS - 1)
{
word =
srcp[windex - elt->index] << (BITSET_WORD_BITS - 1 - bcount);
windex--, boffset -= BITSET_WORD_BITS,
bcount = BITSET_WORD_BITS - 1)
{
word =
srcp[windex - elt->index] << (BITSET_WORD_BITS - 1 - bcount);
for (; word; bcount--)
{
if (word & BITSET_MSB)
{
list[count++] = boffset + bcount;
if (count >= num)
{
*next = n_bits - (boffset + bcount);
return count;
}
}
word <<= 1;
}
}
for (; word; bcount--)
{
if (word & BITSET_MSB)
{
list[count++] = boffset + bcount;
if (count >= num)
{
*next = n_bits - (boffset + bcount);
return count;
}
}
word <<= 1;
}
}
elt = elt->prev;
if (elt)
{
windex = elt->index + LBITSET_ELT_WORDS - 1;
boffset = windex * BITSET_WORD_BITS;
}
{
windex = elt->index + LBITSET_ELT_WORDS - 1;
boffset = windex * BITSET_WORD_BITS;
}
}
*next = n_bits - (boffset + 1);
@@ -662,7 +662,7 @@ lbitset_list_reverse (bitset bset, bitset_bindex *list,
found and with *NEXT indicating where search stopped. */
static bitset_bindex
lbitset_list (bitset bset, bitset_bindex *list,
bitset_bindex num, bitset_bindex *next)
bitset_bindex num, bitset_bindex *next)
{
bitset_bindex bitno;
bitset_windex windex;
@@ -693,51 +693,51 @@ lbitset_list (bitset bset, bitset_bindex *list,
/* Skip to starting element. */
for (elt = head;
elt && (elt->index + LBITSET_ELT_WORDS - 1) < windex;
elt = elt->next)
continue;
elt && (elt->index + LBITSET_ELT_WORDS - 1) < windex;
elt = elt->next)
continue;
if (!elt)
return 0;
return 0;
if (windex < elt->index)
{
windex = elt->index;
bitno = windex * BITSET_WORD_BITS;
}
{
windex = elt->index;
bitno = windex * BITSET_WORD_BITS;
}
else
{
bitset_word *srcp = elt->words;
{
bitset_word *srcp = elt->words;
/* We are starting within an element. */
/* We are starting within an element. */
for (; (windex - elt->index) < LBITSET_ELT_WORDS; windex++)
{
word = srcp[windex - elt->index] >> (bitno % BITSET_WORD_BITS);
for (; (windex - elt->index) < LBITSET_ELT_WORDS; windex++)
{
word = srcp[windex - elt->index] >> (bitno % BITSET_WORD_BITS);
for (; word; bitno++)
{
if (word & 1)
{
list[count++] = bitno;
if (count >= num)
{
*next = bitno + 1;
return count;
}
}
word >>= 1;
}
bitno = (windex + 1) * BITSET_WORD_BITS;
}
for (; word; bitno++)
{
if (word & 1)
{
list[count++] = bitno;
if (count >= num)
{
*next = bitno + 1;
return count;
}
}
word >>= 1;
}
bitno = (windex + 1) * BITSET_WORD_BITS;
}
elt = elt->next;
if (elt)
{
windex = elt->index;
bitno = windex * BITSET_WORD_BITS;
}
}
elt = elt->next;
if (elt)
{
windex = elt->index;
bitno = windex * BITSET_WORD_BITS;
}
}
}
@@ -750,109 +750,109 @@ lbitset_list (bitset bset, bitset_bindex *list,
bitset_word *srcp = elt->words;
if ((count + LBITSET_ELT_BITS) < num)
{
/* The coast is clear, plant boot! */
{
/* The coast is clear, plant boot! */
#if LBITSET_ELT_WORDS == 2
word = srcp[0];
if (word)
{
if (!(word & 0xffff))
{
word >>= 16;
bitno += 16;
}
if (!(word & 0xff))
{
word >>= 8;
bitno += 8;
}
for (; word; bitno++)
{
if (word & 1)
list[count++] = bitno;
word >>= 1;
}
}
windex++;
bitno = windex * BITSET_WORD_BITS;
word = srcp[0];
if (word)
{
if (!(word & 0xffff))
{
word >>= 16;
bitno += 16;
}
if (!(word & 0xff))
{
word >>= 8;
bitno += 8;
}
for (; word; bitno++)
{
if (word & 1)
list[count++] = bitno;
word >>= 1;
}
}
windex++;
bitno = windex * BITSET_WORD_BITS;
word = srcp[1];
if (word)
{
if (!(word & 0xffff))
{
word >>= 16;
bitno += 16;
}
for (; word; bitno++)
{
if (word & 1)
list[count++] = bitno;
word >>= 1;
}
}
windex++;
bitno = windex * BITSET_WORD_BITS;
word = srcp[1];
if (word)
{
if (!(word & 0xffff))
{
word >>= 16;
bitno += 16;
}
for (; word; bitno++)
{
if (word & 1)
list[count++] = bitno;
word >>= 1;
}
}
windex++;
bitno = windex * BITSET_WORD_BITS;
#else
for (i = 0; i < LBITSET_ELT_WORDS; i++)
{
word = srcp[i];
if (word)
{
if (!(word & 0xffff))
{
word >>= 16;
bitno += 16;
}
if (!(word & 0xff))
{
word >>= 8;
bitno += 8;
}
for (; word; bitno++)
{
if (word & 1)
list[count++] = bitno;
word >>= 1;
}
}
windex++;
bitno = windex * BITSET_WORD_BITS;
}
for (i = 0; i < LBITSET_ELT_WORDS; i++)
{
word = srcp[i];
if (word)
{
if (!(word & 0xffff))
{
word >>= 16;
bitno += 16;
}
if (!(word & 0xff))
{
word >>= 8;
bitno += 8;
}
for (; word; bitno++)
{
if (word & 1)
list[count++] = bitno;
word >>= 1;
}
}
windex++;
bitno = windex * BITSET_WORD_BITS;
}
#endif
}
}
else
{
/* Tread more carefully since we need to check
if array overflows. */
{
/* Tread more carefully since we need to check
if array overflows. */
for (i = 0; i < LBITSET_ELT_WORDS; i++)
{
for (word = srcp[i]; word; bitno++)
{
if (word & 1)
{
list[count++] = bitno;
if (count >= num)
{
*next = bitno + 1;
return count;
}
}
word >>= 1;
}
windex++;
bitno = windex * BITSET_WORD_BITS;
}
}
for (i = 0; i < LBITSET_ELT_WORDS; i++)
{
for (word = srcp[i]; word; bitno++)
{
if (word & 1)
{
list[count++] = bitno;
if (count >= num)
{
*next = bitno + 1;
return count;
}
}
word >>= 1;
}
windex++;
bitno = windex * BITSET_WORD_BITS;
}
}
elt = elt->next;
if (elt)
{
windex = elt->index;
bitno = windex * BITSET_WORD_BITS;
}
{
windex = elt->index;
bitno = windex * BITSET_WORD_BITS;
}
}
*next = bitno;
@@ -870,7 +870,7 @@ lbitset_empty_p (bitset dst)
{
next = elt->next;
if (!lbitset_elt_zero_p (elt))
return 0;
return 0;
/* Weed as we go. */
lbitset_elt_unlink (dst, elt);
}
@@ -903,7 +903,7 @@ lbitset_unused_clear (bitset dst)
windex++;
for (; (windex - elt->index) < LBITSET_ELT_WORDS; windex++)
srcp[windex - elt->index] = 0;
srcp[windex - elt->index] = 0;
}
}
@@ -947,12 +947,12 @@ lbitset_not (bitset dst, bitset src)
for (i = 0; i < windex; i += LBITSET_ELT_WORDS)
{
/* Create new elements for dst if they cannot be found
or substitute zero elements if src elements not found. */
or substitute zero elements if src elements not found. */
selt = lbitset_elt_find (src, i, LBITSET_SUBST);
delt = lbitset_elt_find (dst, i, LBITSET_CREATE);
for (j = 0; j < LBITSET_ELT_WORDS; j++)
delt->words[j] = ~selt->words[j];
delt->words[j] = ~selt->words[j];
}
lbitset_unused_clear (dst);
lbitset_weed (dst);
@@ -972,26 +972,26 @@ lbitset_subset_p (bitset dst, bitset src)
selt || delt; selt = selt->next, delt = delt->next)
{
if (!selt)
selt = &lbitset_zero_elts[0];
selt = &lbitset_zero_elts[0];
else if (!delt)
delt = &lbitset_zero_elts[0];
delt = &lbitset_zero_elts[0];
else if (selt->index != delt->index)
{
if (selt->index < delt->index)
{
lbitset_zero_elts[2].next = delt;
delt = &lbitset_zero_elts[2];
}
else
{
lbitset_zero_elts[1].next = selt;
selt = &lbitset_zero_elts[1];
}
}
{
if (selt->index < delt->index)
{
lbitset_zero_elts[2].next = delt;
delt = &lbitset_zero_elts[2];
}
else
{
lbitset_zero_elts[1].next = selt;
selt = &lbitset_zero_elts[1];
}
}
for (j = 0; j < LBITSET_ELT_WORDS; j++)
if (delt->words[j] != (selt->words[j] | delt->words[j]))
return false;
if (delt->words[j] != (selt->words[j] | delt->words[j]))
return false;
}
return true;
}
@@ -1009,25 +1009,25 @@ lbitset_disjoint_p (bitset dst, bitset src)
selt && delt; selt = selt->next, delt = delt->next)
{
if (selt->index != delt->index)
{
if (selt->index < delt->index)
{
lbitset_zero_elts[2].next = delt;
delt = &lbitset_zero_elts[2];
}
else
{
lbitset_zero_elts[1].next = selt;
selt = &lbitset_zero_elts[1];
}
/* Since the elements are different, there is no
intersection of these elements. */
continue;
}
{
if (selt->index < delt->index)
{
lbitset_zero_elts[2].next = delt;
delt = &lbitset_zero_elts[2];
}
else
{
lbitset_zero_elts[1].next = selt;
selt = &lbitset_zero_elts[1];
}
/* Since the elements are different, there is no
intersection of these elements. */
continue;
}
for (j = 0; j < LBITSET_ELT_WORDS; j++)
if (selt->words[j] & delt->words[j])
return false;
if (selt->words[j] & delt->words[j])
return false;
}
return true;
}
@@ -1060,124 +1060,124 @@ lbitset_op3_cmp (bitset dst, bitset src1, bitset src2, enum bitset_ops op)
while (selt1 || selt2)
{
/* Figure out whether we need to substitute zero elements for
missing links. */
missing links. */
if (windex1 == windex2)
{
windex = windex1;
stmp1 = selt1;
stmp2 = selt2;
selt1 = selt1->next;
windex1 = (selt1) ? selt1->index : BITSET_WINDEX_MAX;
selt2 = selt2->next;
windex2 = (selt2) ? selt2->index : BITSET_WINDEX_MAX;
}
{
windex = windex1;
stmp1 = selt1;
stmp2 = selt2;
selt1 = selt1->next;
windex1 = (selt1) ? selt1->index : BITSET_WINDEX_MAX;
selt2 = selt2->next;
windex2 = (selt2) ? selt2->index : BITSET_WINDEX_MAX;
}
else if (windex1 < windex2)
{
windex = windex1;
stmp1 = selt1;
stmp2 = &lbitset_zero_elts[0];
selt1 = selt1->next;
windex1 = (selt1) ? selt1->index : BITSET_WINDEX_MAX;
}
{
windex = windex1;
stmp1 = selt1;
stmp2 = &lbitset_zero_elts[0];
selt1 = selt1->next;
windex1 = (selt1) ? selt1->index : BITSET_WINDEX_MAX;
}
else
{
windex = windex2;
stmp1 = &lbitset_zero_elts[0];
stmp2 = selt2;
selt2 = selt2->next;
windex2 = (selt2) ? selt2->index : BITSET_WINDEX_MAX;
}
{
windex = windex2;
stmp1 = &lbitset_zero_elts[0];
stmp2 = selt2;
selt2 = selt2->next;
windex2 = (selt2) ? selt2->index : BITSET_WINDEX_MAX;
}
/* Find the appropriate element from DST. Begin by discarding
elements that we've skipped. */
elements that we've skipped. */
while (delt && delt->index < windex)
{
changed = true;
dtmp = delt;
delt = delt->next;
lbitset_elt_free (dtmp);
}
{
changed = true;
dtmp = delt;
delt = delt->next;
lbitset_elt_free (dtmp);
}
if (delt && delt->index == windex)
{
dtmp = delt;
delt = delt->next;
}
{
dtmp = delt;
delt = delt->next;
}
else
dtmp = lbitset_elt_calloc ();
dtmp = lbitset_elt_calloc ();
/* Do the operation, and if any bits are set, link it into the
linked list. */
linked list. */
srcp1 = stmp1->words;
srcp2 = stmp2->words;
dstp = dtmp->words;
switch (op)
{
default:
abort ();
{
default:
abort ();
case BITSET_OP_OR:
for (i = 0; i < LBITSET_ELT_WORDS; i++, dstp++)
{
bitset_word tmp = *srcp1++ | *srcp2++;
case BITSET_OP_OR:
for (i = 0; i < LBITSET_ELT_WORDS; i++, dstp++)
{
bitset_word tmp = *srcp1++ | *srcp2++;
if (*dstp != tmp)
{
changed = true;
*dstp = tmp;
}
}
break;
if (*dstp != tmp)
{
changed = true;
*dstp = tmp;
}
}
break;
case BITSET_OP_AND:
for (i = 0; i < LBITSET_ELT_WORDS; i++, dstp++)
{
bitset_word tmp = *srcp1++ & *srcp2++;
case BITSET_OP_AND:
for (i = 0; i < LBITSET_ELT_WORDS; i++, dstp++)
{
bitset_word tmp = *srcp1++ & *srcp2++;
if (*dstp != tmp)
{
changed = true;
*dstp = tmp;
}
}
break;
if (*dstp != tmp)
{
changed = true;
*dstp = tmp;
}
}
break;
case BITSET_OP_XOR:
for (i = 0; i < LBITSET_ELT_WORDS; i++, dstp++)
{
bitset_word tmp = *srcp1++ ^ *srcp2++;
case BITSET_OP_XOR:
for (i = 0; i < LBITSET_ELT_WORDS; i++, dstp++)
{
bitset_word tmp = *srcp1++ ^ *srcp2++;
if (*dstp != tmp)
{
changed = true;
*dstp = tmp;
}
}
break;
if (*dstp != tmp)
{
changed = true;
*dstp = tmp;
}
}
break;
case BITSET_OP_ANDN:
for (i = 0; i < LBITSET_ELT_WORDS; i++, dstp++)
{
bitset_word tmp = *srcp1++ & ~(*srcp2++);
case BITSET_OP_ANDN:
for (i = 0; i < LBITSET_ELT_WORDS; i++, dstp++)
{
bitset_word tmp = *srcp1++ & ~(*srcp2++);
if (*dstp != tmp)
{
changed = true;
*dstp = tmp;
}
}
break;
}
if (*dstp != tmp)
{
changed = true;
*dstp = tmp;
}
}
break;
}
if (!lbitset_elt_zero_p (dtmp))
{
dtmp->index = windex;
/* Perhaps this could be optimised... */
lbitset_elt_link (dst, dtmp);
}
{
dtmp->index = windex;
/* Perhaps this could be optimised... */
lbitset_elt_link (dst, dtmp);
}
else
{
lbitset_elt_free (dtmp);
}
{
lbitset_elt_free (dtmp);
}
}
/* If we have elements of DST left over, free them all. */
@@ -1385,17 +1385,17 @@ debug_lbitset (bitset bset)
{
fprintf (stderr, "Elt %lu\n", (unsigned long int) elt->index);
for (i = 0; i < LBITSET_ELT_WORDS; i++)
{
unsigned int j;
bitset_word word;
{
unsigned int j;
bitset_word word;
word = elt->words[i];
word = elt->words[i];
fprintf (stderr, " Word %u:", i);
for (j = 0; j < LBITSET_WORD_BITS; j++)
if ((word & ((bitset_word) 1 << j)))
fprintf (stderr, " %u", j);
fprintf (stderr, "\n");
}
fprintf (stderr, " Word %u:", i);
for (j = 0; j < LBITSET_WORD_BITS; j++)
if ((word & ((bitset_word) 1 << j)))
fprintf (stderr, " %u", j);
fprintf (stderr, "\n");
}
}
}
-56
View File
@@ -1,56 +0,0 @@
# Copyright (C) 2001-2013 Free Software Foundation, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
include lib/gnulib.mk
# Implementation of bitsets.
lib_libbison_a_SOURCES += \
lib/abitset.c \
lib/abitset.h \
lib/bbitset.h \
lib/bitset.c \
lib/bitset.h \
lib/bitset_stats.c \
lib/bitset_stats.h \
lib/bitsetv.c \
lib/bitsetv.h \
lib/ebitset.c \
lib/ebitset.h \
lib/lbitset.c \
lib/lbitset.h \
lib/libiberty.h \
lib/vbitset.c \
lib/vbitset.h
# Additional bitset operations.
lib_libbison_a_SOURCES += \
lib/bitsetv-print.h \
lib/bitsetv-print.c
# timevars, stolen from GCC.
lib_libbison_a_SOURCES += \
lib/timevar.h \
lib/timevar.c \
lib/timevar.def
# Non-gnulib sources in Bison's internal library.
lib_libbison_a_SOURCES += \
lib/get-errno.h \
lib/get-errno.c
# The Yacc compatibility library.
lib_LIBRARIES = $(YACC_LIBRARY)
EXTRA_LIBRARIES = lib/liby.a
lib_liby_a_SOURCES = lib/main.c lib/yyerror.c
+7 -1
View File
@@ -18,7 +18,13 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include <config.h>
#include <locale.h>
#if HAVE_LOCALE_H
# include <locale.h>
#endif
#if ! HAVE_SETLOCALE
# define setlocale(Category, Locale)
#endif
int yyparse (void);
+20 -20
View File
@@ -189,8 +189,8 @@ static struct timevar_time_def start_time;
static void get_time (struct timevar_time_def *);
static void timevar_accumulate (struct timevar_time_def *,
struct timevar_time_def *,
struct timevar_time_def *);
struct timevar_time_def *,
struct timevar_time_def *);
/* Fill the current times into TIME. The definition of this function
also defines any or all of the HAVE_USER_TIME, HAVE_SYS_TIME, and
@@ -479,20 +479,20 @@ timevar_print (fp)
const float tiny = 5e-3;
/* Don't print the total execution time here; that goes at the
end. */
end. */
if ((timevar_id_t) id == TV_TOTAL)
continue;
continue;
/* Don't print timing variables that were never used. */
if (!tv->used)
continue;
continue;
/* Don't print timing variables if we're going to get a row of
zeroes. */
zeroes. */
if (tv->elapsed.user < tiny
&& tv->elapsed.sys < tiny
&& tv->elapsed.wall < tiny)
continue;
&& tv->elapsed.sys < tiny
&& tv->elapsed.wall < tiny)
continue;
/* The timing variable name. */
fprintf (fp, " %-22s:", tv->name);
@@ -500,22 +500,22 @@ timevar_print (fp)
#ifdef HAVE_USER_TIME
/* Print user-mode time for this process. */
fprintf (fp, "%7.2f (%2.0f%%) usr",
tv->elapsed.user,
(total->user == 0 ? 0 : tv->elapsed.user / total->user) * 100);
tv->elapsed.user,
(total->user == 0 ? 0 : tv->elapsed.user / total->user) * 100);
#endif /* HAVE_USER_TIME */
#ifdef HAVE_SYS_TIME
/* Print system-mode time for this process. */
fprintf (fp, "%7.2f (%2.0f%%) sys",
tv->elapsed.sys,
(total->sys == 0 ? 0 : tv->elapsed.sys / total->sys) * 100);
tv->elapsed.sys,
(total->sys == 0 ? 0 : tv->elapsed.sys / total->sys) * 100);
#endif /* HAVE_SYS_TIME */
#ifdef HAVE_WALL_TIME
/* Print wall clock time elapsed. */
fprintf (fp, "%7.2f (%2.0f%%) wall",
tv->elapsed.wall,
(total->wall == 0 ? 0 : tv->elapsed.wall / total->wall) * 100);
tv->elapsed.wall,
(total->wall == 0 ? 0 : tv->elapsed.wall / total->wall) * 100);
#endif /* HAVE_WALL_TIME */
putc ('\n', fp);
@@ -534,7 +534,7 @@ timevar_print (fp)
#endif
#endif /* defined (HAVE_USER_TIME) || defined (HAVE_SYS_TIME)
|| defined (HAVE_WALL_TIME) */
|| defined (HAVE_WALL_TIME) */
}
/* Returns time (user + system) used so far by the compiler process,
@@ -558,8 +558,8 @@ print_time (str, total)
{
long all_time = get_run_time ();
fprintf (stderr,
_("time in %s: %ld.%06ld (%ld%%)\n"),
str, total / 1000000, total % 1000000,
all_time == 0 ? 0
: (long) (((100.0 * (double) total) / (double) all_time) + .5));
_("time in %s: %ld.%06ld (%ld%%)\n"),
str, total / 1000000, total % 1000000,
all_time == 0 ? 0
: (long) (((100.0 * (double) total) / (double) all_time) + .5));
}
+153 -153
View File
@@ -38,9 +38,9 @@ static void vbitset_set (bitset, bitset_bindex);
static void vbitset_reset (bitset, bitset_bindex);
static bool vbitset_test (bitset, bitset_bindex);
static bitset_bindex vbitset_list (bitset, bitset_bindex *,
bitset_bindex, bitset_bindex *);
bitset_bindex, bitset_bindex *);
static bitset_bindex vbitset_list_reverse (bitset, bitset_bindex *,
bitset_bindex, bitset_bindex *);
bitset_bindex, bitset_bindex *);
#define VBITSET_N_WORDS(N) (((N) + BITSET_WORD_BITS - 1) / BITSET_WORD_BITS)
#define VBITSET_WORDS(X) ((X)->b.cdata)
@@ -69,38 +69,38 @@ vbitset_resize (bitset src, bitset_bindex n_bits)
bitset_windex size;
/* The bitset needs to grow. If we already have enough memory
allocated, then just zero what we need. */
allocated, then just zero what we need. */
if (newsize > VBITSET_ASIZE (src))
{
/* We need to allocate more memory. When oldsize is
non-zero this means that we are changing the size, so
grow the bitset 25% larger than requested to reduce
number of reallocations. */
{
/* We need to allocate more memory. When oldsize is
non-zero this means that we are changing the size, so
grow the bitset 25% larger than requested to reduce
number of reallocations. */
if (oldsize == 0)
size = newsize;
else
size = newsize + newsize / 4;
if (oldsize == 0)
size = newsize;
else
size = newsize + newsize / 4;
VBITSET_WORDS (src)
= realloc (VBITSET_WORDS (src), size * sizeof (bitset_word));
VBITSET_ASIZE (src) = size;
}
VBITSET_WORDS (src)
= realloc (VBITSET_WORDS (src), size * sizeof (bitset_word));
VBITSET_ASIZE (src) = size;
}
memset (VBITSET_WORDS (src) + oldsize, 0,
(newsize - oldsize) * sizeof (bitset_word));
(newsize - oldsize) * sizeof (bitset_word));
VBITSET_SIZE (src) = newsize;
}
else
{
/* The bitset needs to shrink. There's no point deallocating
the memory unless it is shrinking by a reasonable amount. */
the memory unless it is shrinking by a reasonable amount. */
if ((oldsize - newsize) >= oldsize / 2)
{
VBITSET_WORDS (src)
= realloc (VBITSET_WORDS (src), newsize * sizeof (bitset_word));
VBITSET_ASIZE (src) = newsize;
}
{
VBITSET_WORDS (src)
= realloc (VBITSET_WORDS (src), newsize * sizeof (bitset_word));
VBITSET_ASIZE (src) = newsize;
}
/* Need to prune any excess bits. FIXME. */
@@ -196,18 +196,18 @@ vbitset_list_reverse (src, list, num, next)
word = srcp[windex] << (BITSET_WORD_BITS - 1 - bitcnt);
for (; word; bitcnt--)
{
if (word & BITSET_MSB)
{
list[count++] = bitoff + bitcnt;
if (count >= num)
{
*next = n_bits - (bitoff + bitcnt);
return count;
}
}
word <<= 1;
}
{
if (word & BITSET_MSB)
{
list[count++] = bitoff + bitcnt;
if (count >= num)
{
*next = n_bits - (bitoff + bitcnt);
return count;
}
}
word <<= 1;
}
bitoff -= BITSET_WORD_BITS;
bitcnt = BITSET_WORD_BITS - 1;
}
@@ -243,80 +243,80 @@ vbitset_list (src, list, num, next)
{
/* Many bitsets are zero, so make this common case fast. */
for (windex = 0; windex < size && !srcp[windex]; windex++)
continue;
continue;
if (windex >= size)
return 0;
return 0;
/* If num is 1, we could speed things up with a binary search
of the current word. */
of the current word. */
bitoff = windex * BITSET_WORD_BITS;
}
else
{
if (bitno >= BITSET_SIZE_ (src))
return 0;
return 0;
windex = bitno / BITSET_WORD_BITS;
bitno = bitno % BITSET_WORD_BITS;
if (bitno)
{
/* Handle the case where we start within a word.
Most often, this is executed with large bitsets
with many set bits where we filled the array
on the previous call to this function. */
{
/* Handle the case where we start within a word.
Most often, this is executed with large bitsets
with many set bits where we filled the array
on the previous call to this function. */
bitoff = windex * BITSET_WORD_BITS;
word = srcp[windex] >> bitno;
for (bitno = bitoff + bitno; word; bitno++)
{
if (word & 1)
{
list[count++] = bitno;
if (count >= num)
{
*next = bitno + 1;
return count;
}
}
word >>= 1;
}
windex++;
}
bitoff = windex * BITSET_WORD_BITS;
word = srcp[windex] >> bitno;
for (bitno = bitoff + bitno; word; bitno++)
{
if (word & 1)
{
list[count++] = bitno;
if (count >= num)
{
*next = bitno + 1;
return count;
}
}
word >>= 1;
}
windex++;
}
bitoff = windex * BITSET_WORD_BITS;
}
for (; windex < size; windex++, bitoff += BITSET_WORD_BITS)
{
if (!(word = srcp[windex]))
continue;
continue;
if ((count + BITSET_WORD_BITS) < num)
{
for (bitno = bitoff; word; bitno++)
{
if (word & 1)
list[count++] = bitno;
word >>= 1;
}
}
{
for (bitno = bitoff; word; bitno++)
{
if (word & 1)
list[count++] = bitno;
word >>= 1;
}
}
else
{
for (bitno = bitoff; word; bitno++)
{
if (word & 1)
{
list[count++] = bitno;
if (count >= num)
{
*next = bitno + 1;
return count;
}
}
word >>= 1;
}
}
{
for (bitno = bitoff; word; bitno++)
{
if (word & 1)
{
list[count++] = bitno;
if (count >= num)
{
*next = bitno + 1;
return count;
}
}
word >>= 1;
}
}
}
*next = bitoff;
@@ -398,7 +398,7 @@ vbitset_copy1 (bitset dst, bitset src)
memcpy (dstp, srcp, sizeof (bitset_word) * ssize);
memset (dstp + sizeof (bitset_word) * ssize, 0,
sizeof (bitset_word) * (dsize - ssize));
sizeof (bitset_word) * (dsize - ssize));
}
@@ -423,7 +423,7 @@ vbitset_not (bitset dst, bitset src)
vbitset_unused_clear (dst);
memset (dstp + sizeof (bitset_word) * ssize, 0,
sizeof (bitset_word) * (dsize - ssize));
sizeof (bitset_word) * (dsize - ssize));
}
@@ -438,19 +438,19 @@ vbitset_equal_p (bitset dst, bitset src)
for (i = 0; i < min (ssize, dsize); i++)
if (*srcp++ != *dstp++)
return 0;
return 0;
if (ssize > dsize)
{
for (; i < ssize; i++)
if (*srcp++)
return 0;
if (*srcp++)
return 0;
}
else
{
for (; i < dsize; i++)
if (*dstp++)
return 0;
if (*dstp++)
return 0;
}
return 1;
@@ -468,13 +468,13 @@ vbitset_subset_p (bitset dst, bitset src)
for (i = 0; i < min (ssize, dsize); i++, dstp++, srcp++)
if (*dstp != (*srcp | *dstp))
return 0;
return 0;
if (ssize > dsize)
{
for (; i < ssize; i++)
if (*srcp++)
return 0;
if (*srcp++)
return 0;
}
return 1;
@@ -492,7 +492,7 @@ vbitset_disjoint_p (bitset dst, bitset src)
for (i = 0; i < min (ssize, dsize); i++)
if (*srcp++ & *dstp++)
return 0;
return 0;
return 1;
}
@@ -551,10 +551,10 @@ vbitset_and_cmp (bitset dst, bitset src1, bitset src2)
bitset_word tmp = *src1p++ & *src2p++;
if (*dstp != tmp)
{
changed = 1;
*dstp = tmp;
}
{
changed = 1;
*dstp = tmp;
}
}
if (ssize2 > ssize1)
@@ -566,10 +566,10 @@ vbitset_and_cmp (bitset dst, bitset src1, bitset src2)
for (; i < ssize1; i++, dstp++)
{
if (*dstp != 0)
{
changed = 1;
*dstp = 0;
}
{
changed = 1;
*dstp = 0;
}
}
memset (dstp, 0, sizeof (bitset_word) * (dsize - ssize1));
@@ -604,14 +604,14 @@ vbitset_andn (bitset dst, bitset src1, bitset src2)
if (ssize2 > ssize1)
{
for (; i < ssize2; i++)
*dstp++ = 0;
*dstp++ = 0;
memset (dstp, 0, sizeof (bitset_word) * (dsize - ssize2));
}
else
{
for (; i < ssize1; i++)
*dstp++ = *src1p++;
*dstp++ = *src1p++;
memset (dstp, 0, sizeof (bitset_word) * (dsize - ssize1));
}
@@ -644,37 +644,37 @@ vbitset_andn_cmp (bitset dst, bitset src1, bitset src2)
bitset_word tmp = *src1p++ & ~(*src2p++);
if (*dstp != tmp)
{
changed = 1;
*dstp = tmp;
}
{
changed = 1;
*dstp = tmp;
}
}
if (ssize2 > ssize1)
{
for (; i < ssize2; i++, dstp++)
{
if (*dstp != 0)
{
changed = 1;
*dstp = 0;
}
}
{
if (*dstp != 0)
{
changed = 1;
*dstp = 0;
}
}
memset (dstp, 0, sizeof (bitset_word) * (dsize - ssize2));
}
else
{
for (; i < ssize1; i++, dstp++)
{
bitset_word tmp = *src1p++;
{
bitset_word tmp = *src1p++;
if (*dstp != tmp)
{
changed = 1;
*dstp = tmp;
}
}
if (*dstp != tmp)
{
changed = 1;
*dstp = tmp;
}
}
memset (dstp, 0, sizeof (bitset_word) * (dsize - ssize1));
}
@@ -745,10 +745,10 @@ vbitset_or_cmp (bitset dst, bitset src1, bitset src2)
bitset_word tmp = *src1p++ | *src2p++;
if (*dstp != tmp)
{
changed = 1;
*dstp = tmp;
}
{
changed = 1;
*dstp = tmp;
}
}
if (ssize2 > ssize1)
@@ -762,10 +762,10 @@ vbitset_or_cmp (bitset dst, bitset src1, bitset src2)
bitset_word tmp = *src1p++;
if (*dstp != tmp)
{
changed = 1;
*dstp = tmp;
}
{
changed = 1;
*dstp = tmp;
}
}
memset (dstp, 0, sizeof (bitset_word) * (dsize - ssize1));
@@ -836,10 +836,10 @@ vbitset_xor_cmp (bitset dst, bitset src1, bitset src2)
bitset_word tmp = *src1p++ ^ *src2p++;
if (*dstp != tmp)
{
changed = 1;
*dstp = tmp;
}
{
changed = 1;
*dstp = tmp;
}
}
if (ssize2 > ssize1)
@@ -853,10 +853,10 @@ vbitset_xor_cmp (bitset dst, bitset src1, bitset src2)
bitset_word tmp = *src1p++;
if (*dstp != tmp)
{
changed = 1;
*dstp = tmp;
}
{
changed = 1;
*dstp = tmp;
}
}
memset (dstp, 0, sizeof (bitset_word) * (dsize - ssize1));
@@ -926,10 +926,10 @@ vbitset_and_or_cmp (bitset dst, bitset src1, bitset src2, bitset src3)
bitset_word tmp = (*src1p++ & *src2p++) | *src3p++;
if (*dstp != tmp)
{
changed = 1;
*dstp = tmp;
}
{
changed = 1;
*dstp = tmp;
}
}
return changed;
}
@@ -993,10 +993,10 @@ vbitset_andn_or_cmp (bitset dst, bitset src1, bitset src2, bitset src3)
bitset_word tmp = (*src1p++ & ~(*src2p++)) | *src3p++;
if (*dstp != tmp)
{
changed = 1;
*dstp = tmp;
}
{
changed = 1;
*dstp = tmp;
}
}
return changed;
}
@@ -1060,10 +1060,10 @@ vbitset_or_and_cmp (bitset dst, bitset src1, bitset src2, bitset src3)
bitset_word tmp = (*src1p++ | *src2p++) & *src3p++;
if (*dstp != tmp)
{
changed = 1;
*dstp = tmp;
}
{
changed = 1;
*dstp = tmp;
}
}
return changed;
}
+5 -3
View File
@@ -50,7 +50,6 @@
/include_next.m4
/intdiv0.m4
/intl.m4
/intl.m4~
/intldir.m4
/intlmacosx.m4
/intmax.m4
@@ -63,6 +62,7 @@
/isnand.m4
/isnanf.m4
/isnanl.m4
/iswblank.m4
/javacomp.m4
/javaexec.m4
/largefile.m4
@@ -81,6 +81,8 @@
/longlong.m4
/malloc.m4
/math_h.m4
/mbchar.m4
/mbiter.m4
/mbrtowc.m4
/mbsinit.m4
/mbstate_t.m4
@@ -99,7 +101,6 @@
/perror.m4
/pipe2.m4
/po.m4
/po.m4~
/posix_spawn.m4
/printf-frexp.m4
/printf-frexpl.m4
@@ -179,4 +180,5 @@
/xstrndup.m4
/obstack-printf.m4
/extern-inline.m4
/non-recursive-gnulib-prefix-hack.m4
/getdelim.m4
/getline.m4
+1 -1
View File
@@ -21,7 +21,7 @@ AC_DEFUN([BISON_TEST_FOR_WORKING_C_COMPILER], [
AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM(
[[#include <limits.h>
int test_array[CHAR_BIT];]])],
int test_array[CHAR_BIT];]])],
[],
[AC_MSG_FAILURE([cannot compile a simple C program])])
AC_SUBST([BISON_C_WORKS], [:])
+16 -16
View File
@@ -26,25 +26,25 @@ AC_DEFUN([BISON_TEST_FOR_WORKING_CXX_COMPILER],
bison_cv_cxx_works=no
AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM(
[#include <cstdlib>
#include <iostream>
#include <map>
#include <string>
using namespace std;],
[#include <cstdlib>
#include <iostream>
#include <map>
#include <string>
using namespace std;],
[std::cerr << "";
cout << "";
typedef std::pair<unsigned int, int> uipair;
std::map<unsigned int, int> m;
std::map<unsigned int, int>::iterator i;
m.insert (uipair (4, -4));
for (i = m.begin (); i != m.end (); ++i)
if (i->first != 4)
return 1;])],
typedef std::pair<unsigned int, int> uipair;
std::map<unsigned int, int> m;
std::map<unsigned int, int>::iterator i;
m.insert (uipair (4, -4));
for (i = m.begin (); i != m.end (); ++i)
if (i->first != 4)
return 1;])],
[AS_IF([AC_TRY_COMMAND([$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_objext $LIBS >&AS_MESSAGE_LOG_FD])],
[AS_IF([test "$cross_compiling" = yes],
[bison_cv_cxx_works=cross],
[AS_IF([AC_TRY_COMMAND(./conftest$ac_exeext)],
[bison_cv_cxx_works=yes])])])
[AS_IF([test "$cross_compiling" = yes],
[bison_cv_cxx_works=cross],
[AS_IF([AC_TRY_COMMAND(./conftest$ac_exeext)],
[bison_cv_cxx_works=yes])])])
rm -f conftest$ac_exeext])
AC_LANG_POP([C++])])
+3 -3
View File
@@ -78,7 +78,7 @@ if test -z "${LEXLIB+set}"; then
for ac_lib in '' -lfl -ll; do
LIBS="$ac_lib $ac_save_LIBS"
AC_LINK_IFELSE([AC_LANG_DEFINES_PROVIDED[`cat $LEX_OUTPUT_ROOT.c`]],
[ac_cv_lib_lex=$ac_lib])
[ac_cv_lib_lex=$ac_lib])
test "$ac_cv_lib_lex" != 'none needed' && break
done
LIBS=$ac_save_LIBS
@@ -104,8 +104,8 @@ LIBS=$ac_save_LIBS
dnl
if test $ac_cv_prog_lex_yytext_pointer = yes; then
AC_DEFINE([YYTEXT_POINTER], [1],
[Define to 1 if `lex' declares `yytext' as a `char *' by default,
not a `char[]'.])
[Define to 1 if `lex' declares `yytext' as a `char *' by default,
not a `char[]'.])
fi
rm -f conftest.l $LEX_OUTPUT_ROOT.c
])# _AC_PROG_LEX_YYTEXT_DECL
-1
View File
@@ -6,7 +6,6 @@
/Makefile
/Makefile.in
/Makefile.in.in
/Makefile.in.in~
/Makevars
/Makevars.template
/POTFILES
-1
View File
@@ -6,7 +6,6 @@
/Makefile
/Makefile.in
/Makefile.in.in
/Makefile.in.in~
/Makevars
/Makevars.template
/POTFILES
+2
View File
@@ -4,6 +4,8 @@
/*.output
/.deps
/.dirstamp
/Makefile
/Makefile.in
/bison
/bison.exe
/scan-code.c
+4 -4
View File
@@ -20,10 +20,10 @@
#ifndef ANNOTATION_LIST_H_
# define ANNOTATION_LIST_H_
# include <bitsetv.h>
# include "Sbitset.h"
# include "InadequacyList.h"
# include "state.h"
#include <bitsetv.h>
#include "Sbitset.h"
#include "InadequacyList.h"
#include "state.h"
typedef unsigned int AnnotationIndex;
+5 -5
View File
@@ -20,10 +20,10 @@
#ifndef INADEQUACY_LIST_H_
# define INADEQUACY_LIST_H_
# include <bitset.h>
# include "gram.h"
# include "state.h"
# include "symtab.h"
#include <bitset.h>
#include "gram.h"
#include "state.h"
#include "symtab.h"
/**
* A unique ID assigned to every \c InadequacyList node.
@@ -90,7 +90,7 @@ typedef struct InadequacyList {
* <tt>manifesting_state->reductions->num + 1</tt>.
* - If the set of all \c InadequacyList nodes with which the new
* \c InadequacyList node might be compared is currently empty, then
* it is best if <tt>*node_count</tt> is zero so that the node count
* it is best if <tt>*node_count</t> is zero so that the node count
* does not eventually overflow. However, if that set is not
* currently empty, then <tt>*node_count</tt> has not been modified
* by any function except \c InadequacyList__new_conflict since the
+37 -36
View File
@@ -1,7 +1,7 @@
/* Generate the LR(0) parser states for Bison.
Copyright (C) 1984, 1986, 1989, 2000-2002, 2004-2013 Free Software
Foundation, Inc.
Copyright (C) 1984, 1986, 1989, 2000-2002, 2004-2007, 2009-2013 Free
Software Foundation, Inc.
This file is part of Bison, the GNU Compiler Compiler.
@@ -32,6 +32,7 @@
#include "complain.h"
#include "getargs.h"
#include "gram.h"
#include "gram.h"
#include "lalr.h"
#include "reader.h"
#include "reduce.h"
@@ -61,7 +62,7 @@ state_list_append (symbol_number sym, size_t core_size, item_number *core)
if (trace_flag & trace_automaton)
fprintf (stderr, "state_list_append (state = %d, symbol = %d (%s))\n",
nstates, sym, symbols[sym]->tag);
nstates, sym, symbols[sym]->tag);
node->next = NULL;
node->state = s;
@@ -99,13 +100,13 @@ allocate_itemsets (void)
symbols. */
size_t count = 0;
size_t *symbol_count = xcalloc (nsyms + nuseless_nonterminals,
sizeof *symbol_count);
sizeof *symbol_count);
for (r = 0; r < nrules; ++r)
for (rhsp = rules[r].rhs; *rhsp >= 0; ++rhsp)
{
count++;
symbol_count[*rhsp]++;
count++;
symbol_count[*rhsp]++;
}
/* See comments before new_itemsets. All the vectors of items
@@ -186,15 +187,15 @@ new_itemsets (state *s)
for (i = 0; i < nitemset; ++i)
if (item_number_is_symbol_number (ritem[itemset[i]]))
{
symbol_number sym = item_number_as_symbol_number (ritem[itemset[i]]);
if (!kernel_size[sym])
{
shift_symbol[nshifts] = sym;
nshifts++;
}
symbol_number sym = item_number_as_symbol_number (ritem[itemset[i]]);
if (!kernel_size[sym])
{
shift_symbol[nshifts] = sym;
nshifts++;
}
kernel_base[sym][kernel_size[sym]] = itemset[i] + 1;
kernel_size[sym]++;
kernel_base[sym][kernel_size[sym]] = itemset[i] + 1;
kernel_size[sym]++;
}
}
@@ -213,7 +214,7 @@ get_state (symbol_number sym, size_t core_size, item_number *core)
if (trace_flag & trace_automaton)
fprintf (stderr, "Entering get_state, symbol = %d (%s)\n",
sym, symbols[sym]->tag);
sym, symbols[sym]->tag);
s = state_hash_lookup (core_size, core);
if (!s)
@@ -227,7 +228,7 @@ get_state (symbol_number sym, size_t core_size, item_number *core)
/*---------------------------------------------------------------.
| Use the information computed by new_itemsets to find the state |
| numbers reached by each shift transition from S. |
| numbers reached by each shift transition from S. |
| |
| SHIFTSET is set up as a vector of those states. |
`---------------------------------------------------------------*/
@@ -247,7 +248,7 @@ append_states (state *s)
symbol_number sym = shift_symbol[i];
int j;
for (j = i; 0 < j && sym < shift_symbol[j - 1]; j--)
shift_symbol[j] = shift_symbol[j - 1];
shift_symbol[j] = shift_symbol[j - 1];
shift_symbol[j] = sym;
}
@@ -276,16 +277,16 @@ save_reductions (state *s)
{
item_number item = ritem[itemset[i]];
if (item_number_is_rule_number (item))
{
rule_number r = item_number_as_rule_number (item);
redset[count++] = &rules[r];
if (r == 0)
{
/* This is "reduce 0", i.e., accept. */
aver (!final_state);
final_state = s;
}
}
{
rule_number r = item_number_as_rule_number (item);
redset[count++] = &rules[r];
if (r == 0)
{
/* This is "reduce 0", i.e., accept. */
aver (!final_state);
final_state = s;
}
}
}
/* Make a reductions structure and copy the data into it. */
@@ -307,14 +308,14 @@ set_states (void)
state_list *this = first_state;
/* Pessimization, but simplification of the code: make sure all
the states have valid transitions and reductions members,
even if reduced to 0. It is too soon for errs, which are
computed later, but set_conflicts. */
the states have valid transitions and reductions members,
even if reduced to 0. It is too soon for errs, which are
computed later, but set_conflicts. */
state *s = this->state;
if (!s->transitions)
state_transitions_set (s, 0, 0);
state_transitions_set (s, 0, 0);
if (!s->reductions)
state_reductions_set (s, 0, 0);
state_reductions_set (s, 0, 0);
states[s->number] = s;
@@ -348,9 +349,9 @@ generate_states (void)
{
state *s = list->state;
if (trace_flag & trace_automaton)
fprintf (stderr, "Processing state %d (reached by %s)\n",
s->number,
symbols[s->accessing_symbol]->tag);
fprintf (stderr, "Processing state %d (reached by %s)\n",
s->number,
symbols[s->accessing_symbol]->tag);
/* Set up itemset for the transitions out of this state. itemset gets a
vector of all the items that could be accepted next. */
closure (s->items, s->nitems);
@@ -362,7 +363,7 @@ generate_states (void)
append_states (s);
/* Create the shifts structures for the shifts to those states,
now that the state numbers transitioning to are known. */
now that the state numbers transitioning to are known. */
state_transitions_set (s, nshifts, shiftset);
}
+117
View File
@@ -0,0 +1,117 @@
# Make bison/src.
# Copyright (C) 2001-2013 Free Software Foundation, Inc.
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
AM_CFLAGS = $(WARN_CFLAGS) $(WERROR_CFLAGS)
AM_CPPFLAGS = -I$(top_srcdir)/lib
BISON = ../tests/bison
# Use our own Bison to build the parser. Of course, you ought to
# keep a sane version of Bison nearby...
YACC = $(BISON) -y
AM_YFLAGS = -d -v --warnings=all,error --report=all
LDADD = ../lib/libbison.a $(LIBINTL)
bin_PROGRAMS = bison
bin_SCRIPTS = $(YACC_SCRIPT)
EXTRA_SCRIPTS = yacc
bison_SOURCES = \
AnnotationList.c AnnotationList.h \
InadequacyList.c InadequacyList.h \
LR0.c LR0.h \
Sbitset.c Sbitset.h \
assoc.c assoc.h \
closure.c closure.h \
complain.c complain.h \
conflicts.c conflicts.h \
derives.c derives.h \
files.c files.h \
flex-scanner.h \
getargs.c getargs.h \
gram.c gram.h \
lalr.h lalr.c \
ielr.h ielr.c \
location.c location.h \
main.c \
muscle-tab.c muscle-tab.h \
named-ref.c named-ref.h \
nullable.c nullable.h \
output.c output.h \
parse-gram.y \
print.c print.h \
print_graph.c print_graph.h \
print-xml.c print-xml.h \
reader.c reader.h \
reduce.c reduce.h \
relation.c relation.h \
scan-code.h scan-code-c.c \
scan-gram.h scan-gram-c.c \
scan-skel.h scan-skel-c.c \
state.c state.h \
symlist.c symlist.h \
symtab.c symtab.h \
system.h \
tables.h tables.c \
uniqstr.c uniqstr.h \
graphviz.c graphviz.h
EXTRA_bison_SOURCES = scan-code.l scan-skel.l scan-gram.l
BUILT_SOURCES = \
parse-gram.c parse-gram.h \
scan-code.c \
scan-skel.c \
scan-gram.c
MOSTLYCLEANFILES = yacc
yacc:
$(AM_V_GEN)echo '#! /bin/sh' >$@
$(AM_V_at)echo "exec '$(bindir)/bison' -y "'"$$@"' >>$@
$(AM_V_at)chmod a+x $@
# The following rule is not designed to be portable,
# and relies on tools that not everyone has.
# Most functions in src/*.c should have static scope.
# Any that don't must be marked with `extern', but `main'
# and `usage' are exceptions. They're always extern, but
# don't need to be marked.
#
# The second nm|grep checks for file-scope variables with `extern' scope.
sc_tight_scope: $(all_programs)
@t=exceptions-$$$$; \
trap 's=$$?; rm -f $$t; exit $$s' 0 1 2 13 15; \
( printf '^main$$\n^usage$$\n'; \
grep -h -A1 '^extern .*[^;]$$' $(SOURCES) \
| grep -vE '^(extern |--)' |sed 's/^/^/;s/ .*/$$/' ) > $$t; \
if nm -e *.$(OBJEXT) \
| sed -n 's/.* T //p' \
| grep -Ev -f $$t; then \
echo 'the above functions should have static scope' 1>&2; \
exit 1; \
fi; \
( printf '^program_name$$\n'; \
sed -n 's/^extern .*[* ]\([a-zA-Z_][a-zA-Z_0-9]*\);$$/^\1$$/p' \
$$(ls $(SOURCES) | grep '\.h$$') /dev/null) > $$t; \
if nm -e *.$(OBJEXT) \
| sed -n 's/.* [BD] //p' \
| grep -Ev -f $$t; then \
echo 'the above variables should have static scope' 1>&2; \
exit 1; \
fi
+39 -39
View File
@@ -22,15 +22,15 @@
typedef unsigned char *Sbitset;
typedef size_t Sbitset__Index;
# define SBITSET__INDEX__CONVERSION_SPEC "zu"
#define SBITSET__INDEX__CONVERSION_SPEC "zu"
# define Sbitset__nbytes(NBITS) \
#define Sbitset__nbytes(NBITS) \
(((NBITS) + CHAR_BIT - 1) / CHAR_BIT)
# define Sbitset__byteAddress(SELF, INDEX) \
#define Sbitset__byteAddress(SELF, INDEX) \
(((SELF) + (INDEX) / CHAR_BIT))
# define Sbitset__bit_mask(INDEX) \
#define Sbitset__bit_mask(INDEX) \
(1 << (CHAR_BIT - 1 - (INDEX) % CHAR_BIT))
# define Sbitset__last_byte_mask(NBITS) \
#define Sbitset__last_byte_mask(NBITS) \
(UCHAR_MAX << (CHAR_BIT - 1 - ((NBITS) - 1) % CHAR_BIT))
/* nbits must not be 0. */
@@ -39,54 +39,54 @@ Sbitset Sbitset__new_on_obstack (Sbitset__Index nbits,
struct obstack *obstackp);
void Sbitset__delete (Sbitset self);
# define Sbitset__test(SELF, INDEX) \
#define Sbitset__test(SELF, INDEX) \
((*Sbitset__byteAddress ((SELF), (INDEX)) & Sbitset__bit_mask (INDEX)) != 0)
bool Sbitset__isEmpty (Sbitset self, Sbitset__Index nbits);
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)
#define Sbitset__set(SELF, INDEX) \
do { \
*Sbitset__byteAddress ((SELF), (INDEX)) = \
*Sbitset__byteAddress ((SELF), (INDEX)) | Sbitset__bit_mask (INDEX); \
} while(0)
# define Sbitset__reset(SELF, INDEX) \
do { \
*Sbitset__byteAddress ((SELF), (INDEX)) = \
*Sbitset__byteAddress ((SELF), (INDEX)) & ~Sbitset__bit_mask (INDEX); \
} while(0)
#define Sbitset__reset(SELF, INDEX) \
do { \
*Sbitset__byteAddress ((SELF), (INDEX)) = \
*Sbitset__byteAddress ((SELF), (INDEX)) & ~Sbitset__bit_mask (INDEX); \
} 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)
#define Sbitset__zero(SELF, NBITS) \
do { \
memset (SELF, 0, Sbitset__nbytes (NBITS)); \
} 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)
#define Sbitset__ones(SELF, NBITS) \
do { \
memset (SELF, UCHAR_MAX, Sbitset__nbytes (NBITS)); \
} while(0)
/* NBITS is the size of every bitset. More than NBITS bits might be set. */
# define Sbitset__or(SELF, OTHER1, OTHER2, NBITS) \
do { \
Sbitset ptr_self = (SELF); \
Sbitset ptr_other1 = (OTHER1); \
Sbitset ptr_other2 = (OTHER2); \
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)
#define Sbitset__or(SELF, OTHER1, OTHER2, NBITS) \
do { \
Sbitset ptr_self = (SELF); \
Sbitset ptr_other1 = (OTHER1); \
Sbitset ptr_other2 = (OTHER2); \
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)
# define SBITSET__FOR_EACH(SELF, NBITS, ITER, INDEX) \
for ((ITER) = (SELF); (ITER) < (SELF) + Sbitset__nbytes (NBITS); ++(ITER)) \
if (*(ITER) != 0) \
for ((INDEX) = ((ITER)-(SELF))*CHAR_BIT; \
(INDEX) < (NBITS) && (SELF)+(INDEX)/CHAR_BIT < (ITER)+1; \
++(INDEX)) \
#define SBITSET__FOR_EACH(SELF, NBITS, ITER, INDEX) \
for ((ITER) = (SELF); (ITER) < (SELF) + Sbitset__nbytes (NBITS); ++(ITER)) \
if (*(ITER) != 0) \
for ((INDEX) = ((ITER)-(SELF))*CHAR_BIT; \
(INDEX) < (NBITS) && (SELF)+(INDEX)/CHAR_BIT < (ITER)+1; \
++(INDEX)) \
if (((*ITER) & Sbitset__bit_mask (INDEX)) != 0)
#endif /* !SBITSET_H_ */
+1 -4
View File
@@ -1,6 +1,6 @@
/* Associativity information.
Copyright (C) 2002, 2005-2006, 2008-2013 Free Software Foundation,
Copyright (C) 2002, 2005-2006, 2009-2013 Free Software Foundation,
Inc.
This file is part of Bison, the GNU Compiler Compiler.
@@ -43,8 +43,5 @@ assoc_to_string (assoc a)
case non_assoc:
return "%nonassoc";
case precedence_assoc:
return "%precedence";
}
}
+5 -6
View File
@@ -1,6 +1,6 @@
/* Associativity information.
Copyright (C) 2002, 2006, 2008-2013 Free Software Foundation, Inc.
Copyright (C) 2002, 2006, 2009-2013 Free Software Foundation, Inc.
This file is part of Bison, the GNU Compiler Compiler.
@@ -23,11 +23,10 @@
/* Associativity values for tokens and rules. */
typedef enum
{
undef_assoc, /** Not defined. */
right_assoc, /** %right */
left_assoc, /** %left */
non_assoc, /** %nonassoc */
precedence_assoc /** %precedence */
undef_assoc,
right_assoc,
left_assoc,
non_assoc
} assoc;
char const *assoc_to_string (assoc a);
+24 -22
View File
@@ -44,7 +44,7 @@ static bitsetv firsts = NULL;
/* Retrieve the FDERIVES/FIRSTS sets of the nonterminals numbered Var. */
#define FDERIVES(Var) fderives[(Var) - ntokens]
#define FIRSTS(Var) firsts[(Var) - ntokens]
#define FIRSTS(Var) firsts[(Var) - ntokens]
/*-----------------.
@@ -52,7 +52,7 @@ static bitsetv firsts = NULL;
`-----------------*/
static void
print_closure (char const *title, item_number const *array, size_t size)
print_closure (char const *title, item_number *array, size_t size)
{
size_t i;
fprintf (stderr, "Closure: %s\n", title);
@@ -61,7 +61,7 @@ print_closure (char const *title, item_number const *array, size_t size)
item_number *rp;
fprintf (stderr, " %2d: .", array[i]);
for (rp = &ritem[array[i]]; *rp >= 0; ++rp)
fprintf (stderr, " %s", symbols[*rp]->tag);
fprintf (stderr, " %s", symbols[*rp]->tag);
fprintf (stderr, " (rule %d)\n", -*rp - 1);
}
fputs ("\n\n", stderr);
@@ -77,9 +77,12 @@ print_firsts (void)
for (i = ntokens; i < nsyms; i++)
{
bitset_iterator iter;
fprintf (stderr, " %s firsts\n", symbols[i]->tag);
fprintf (stderr, "\t%s firsts\n", symbols[i]->tag);
BITSET_FOR_EACH (iter, FIRSTS (i), j, 0)
fprintf (stderr, " %s\n", symbols[j + ntokens]->tag);
{
fprintf (stderr, "\t\t%s\n",
symbols[j + ntokens]->tag);
}
}
fprintf (stderr, "\n\n");
}
@@ -95,13 +98,12 @@ print_fderives (void)
for (i = ntokens; i < nsyms; i++)
{
bitset_iterator iter;
fprintf (stderr, " %s derives\n", symbols[i]->tag);
fprintf (stderr, "\t%s derives\n", symbols[i]->tag);
BITSET_FOR_EACH (iter, FDERIVES (i), r, 0)
{
fprintf (stderr, " %3d ", r);
rule_rhs_print (&rules[r], stderr);
fprintf (stderr, "\n");
}
{
fprintf (stderr, "\t\t%3d ", r);
rule_rhs_print (&rules[r], stderr);
}
}
fprintf (stderr, "\n\n");
}
@@ -127,9 +129,9 @@ set_firsts (void)
for (i = ntokens; i < nsyms; i++)
for (j = 0; derives[i - ntokens][j]; ++j)
{
item_number sym = derives[i - ntokens][j]->rhs[0];
if (ISVAR (sym))
bitset_set (FIRSTS (i), sym - ntokens);
item_number sym = derives[i - ntokens][j]->rhs[0];
if (ISVAR (sym))
bitset_set (FIRSTS (i), sym - ntokens);
}
if (trace_flag & trace_sets)
@@ -165,8 +167,8 @@ set_fderives (void)
for (i = ntokens; i < nsyms; ++i)
for (j = ntokens; j < nsyms; ++j)
if (bitset_test (FIRSTS (i), j - ntokens))
for (k = 0; derives[j - ntokens][k]; ++k)
bitset_set (FDERIVES (i), derives[j - ntokens][k]->number);
for (k = 0; derives[j - ntokens][k]; ++k)
bitset_set (FDERIVES (i), derives[j - ntokens][k]->number);
if (trace_flag & trace_sets)
print_fderives ();
@@ -189,7 +191,7 @@ new_closure (unsigned int n)
void
closure (item_number const *core, size_t n)
closure (item_number *core, size_t n)
{
/* Index over CORE. */
size_t c;
@@ -216,11 +218,11 @@ closure (item_number const *core, size_t n)
{
item_number itemno = rules[ruleno].rhs - ritem;
while (c < n && core[c] < itemno)
{
itemset[nitemset] = core[c];
nitemset++;
c++;
}
{
itemset[nitemset] = core[c];
nitemset++;
c++;
}
itemset[nitemset] = itemno;
nitemset++;
};
+1 -1
View File
@@ -44,7 +44,7 @@ void new_closure (unsigned int n);
significant). CLOSURE places there the indices of all items which
represent units of input that could arrive next. */
void closure (item_number const *items, size_t n);
void closure (item_number *items, size_t n);
/* Frees ITEMSET, RULESET and internal data. */
+118 -107
View File
@@ -28,51 +28,16 @@
#include "complain.h"
#include "files.h"
#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 complaint_issued;
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"
};
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, "]");
}
}
/** Report an error message.
*
* \param loc the location, defaulting to the current file,
* or the program name.
* \param flags the category for this message.
* \param prefix put before the message (e.g., "warning").
* \param message the error message, a printf format string. Iff it
* ends with ": ", then no trailing newline is printed,
@@ -82,21 +47,20 @@ warnings_print_categories (warnings warn_flags)
*/
static
void
error_message (const location *loc, warnings flags, const char *prefix,
const char *message, va_list args)
error_message (location *loc,
const char *prefix,
const char *message, va_list args)
{
unsigned pos = 0;
if (loc)
pos += location_print (stderr, *loc);
else
pos += fprintf (stderr, "%s", current_file ? current_file : program_name);
pos += fprintf (stderr, ": ");
pos += fprintf(stderr, "%s", current_file ? current_file : program_name);
pos += fprintf(stderr, ": ");
if (indent_ptr)
{
if (*indent_ptr)
prefix = NULL;
if (!*indent_ptr)
*indent_ptr = pos;
else if (*indent_ptr > pos)
@@ -108,99 +72,146 @@ error_message (const location *loc, warnings flags, const char *prefix,
fprintf (stderr, "%s: ", prefix);
vfprintf (stderr, message, args);
warnings_print_categories (flags);
{
size_t l = strlen (message);
if (l < 2 || message[l - 2] != ':' || message[l - 1] != ' ')
{
putc ('\n', stderr);
fflush (stderr);
if (loc && feature_flag & feature_caret && !(flags & no_caret))
if (loc && feature_flag & feature_caret)
location_caret (stderr, *loc);
}
}
fflush (stderr);
}
/** Raise a complaint. That can be a fatal error, a complaint or just a
warning. */
static inline 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");
/** Wrap error_message() with varargs handling. */
#define ERROR_MESSAGE(Loc, Prefix, Message) \
{ \
va_list args; \
va_start (args, Message); \
error_message (Loc, Prefix, Message, args); \
va_end (args); \
}
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 (flags & fatal)
exit (EXIT_FAILURE);
/*--------------------------------.
| Report a warning, and proceed. |
`--------------------------------*/
void
set_warning_issued (void)
{
static bool warning_issued = false;
if (!warning_issued && (warnings_flag & warnings_error))
{
fprintf (stderr, "%s: warnings being treated as errors\n", program_name);
complaint_issued = true;
}
warning_issued = true;
}
void
complain (location const *loc, warnings flags, const char *message, ...)
warn_at (location loc, const char *message, ...)
{
va_list args;
va_start (args, message);
complains (loc, flags, message, args);
va_end (args);
if (!(warnings_flag & warnings_other))
return;
set_warning_issued ();
ERROR_MESSAGE (&loc, _("warning"), message);
}
void
complain_indent (location const *loc, warnings flags, unsigned *indent,
const char *message, ...)
warn_at_indent (location loc, unsigned *indent,
const char *message, ...)
{
va_list args;
if (!(warnings_flag & warnings_other))
return;
set_warning_issued ();
indent_ptr = indent;
va_start (args, message);
complains (loc, flags, message, args);
va_end (args);
ERROR_MESSAGE (&loc, *indent ? NULL : _("warning"), message);
}
void
complain_args (location const *loc, warnings w, unsigned *indent,
int argc, char *argv[])
warn (const char *message, ...)
{
switch (argc)
{
case 1:
complain_indent (loc, w, indent, "%s", _(argv[0]));
break;
case 2:
complain_indent (loc, w, indent, _(argv[0]), argv[1]);
break;
case 3:
complain_indent (loc, w, indent, _(argv[0]), argv[1], argv[2]);
break;
case 4:
complain_indent (loc, w, indent, _(argv[0]), argv[1], argv[2], argv[3]);
break;
case 5:
complain_indent (loc, w, indent, _(argv[0]), argv[1], argv[2], argv[3],
argv[4]);
break;
default:
complain (loc, fatal, "too many arguments for complains");
break;
}
if (!(warnings_flag & warnings_other))
return;
set_warning_issued ();
ERROR_MESSAGE (NULL, _("warning"), message);
}
/*-----------------------------------------------------------.
| An error has occurred, but we can proceed, and die later. |
`-----------------------------------------------------------*/
void
complain_at (location loc, const char *message, ...)
{
ERROR_MESSAGE (&loc, _("error"), message);
complaint_issued = true;
}
void
deprecated_directive (location const *loc, char const *old, char const *upd)
complain_at_indent (location loc, unsigned *indent,
const char *message, ...)
{
if (feature_flag & feature_caret)
complain (loc, Wdeprecated,
_("deprecated directive, use %s"),
quote_n (1, upd));
else
complain (loc, Wdeprecated,
_("deprecated directive: %s, use %s"),
quote (old), quote_n (1, upd));
indent_ptr = indent;
ERROR_MESSAGE (&loc, *indent ? NULL : _("error"), message);
complaint_issued = true;
}
void
complain (const char *message, ...)
{
ERROR_MESSAGE (NULL, _("error"), message);
complaint_issued = true;
}
/*--------------------------------------------------------------.
| An incompatibility with POSIX Yacc: mapped either to warn* or |
| complain* depending on yacc_flag. |
`--------------------------------------------------------------*/
void
yacc_at (location loc, const char *message, ...)
{
if (yacc_flag)
{
ERROR_MESSAGE (&loc, NULL, message);
complaint_issued = true;
}
else if (warnings_flag & warnings_yacc)
{
set_warning_issued ();
ERROR_MESSAGE (&loc, _("warning"), message);
}
}
void
midrule_value_at (location loc, const char *message, ...)
{
if (!(warnings_flag & warnings_midrule_values))
return;
set_warning_issued ();
ERROR_MESSAGE (&loc, _("warning"), message);
}
/*-------------------------------------------------.
| A severe error has occurred, we cannot proceed. |
`-------------------------------------------------*/
void
fatal_at (location loc, const char *message, ...)
{
ERROR_MESSAGE (&loc, _("fatal error"), message);
exit (EXIT_FAILURE);
}
void
fatal (const char *message, ...)
{
ERROR_MESSAGE (NULL, _("fatal error"), message);
exit (EXIT_FAILURE);
}
+57 -53
View File
@@ -21,72 +21,76 @@
# include "location.h"
# ifdef __cplusplus
extern "C" {
# endif
/* Sub-messages indent. */
# define SUB_INDENT (4)
#define SUB_INDENT (4)
/*-------------.
| --warnings. |
`-------------*/
/** Record that a warning is about to be issued, and treat it as an
error if <tt>warnings_flag & warnings_error</tt>. This is exported
only for the sake of Yacc-compatible conflict reports in conflicts.c.
All other warnings should be implemented in complain.c and should use
the normal warning format. */
void set_warning_issued (void);
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. */
/** Informative messages, but we proceed. Report iff
<tt>warnings_flag & warnings_other</tt>. */
Werror = 1 << 10, /** This bit is no longer used. */
void warn (char const *format, ...)
__attribute__ ((__format__ (__printf__, 1, 2)));
complaint = 1 << 11, /**< All complaints. */
fatal = 1 << 12, /**< All fatal errors. */
silent = 1 << 13, /**< Do not display the warning type. */
no_caret = 1 << 14, /**< Do not display caret location. */
void warn_at (location loc, char const *format, ...)
__attribute__ ((__format__ (__printf__, 2, 3)));
/**< All above warnings. */
Wall = ~complaint & ~fatal & ~silent
} 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);
/** Make a complaint, with maybe a location. */
void complain (location const *loc, warnings flags, char const *message, ...)
/* Generate a message aligned by an indent.
When *indent == 0, assign message's indent to *indent,
When *indent > 0, align the message by *indent value. */
void warn_at_indent (location loc, unsigned *indent,
char const *format, ...)
__attribute__ ((__format__ (__printf__, 3, 4)));
/** Likewise, but with an \a argc/argv interface. */
void complain_args (location const *loc, warnings w, unsigned *indent,
int argc, char *arg[]);
/** An error, but we continue and die later. */
/** Make a complaint with location and some indentation. */
void complain_indent (location const *loc, warnings flags, unsigned *indent,
char const *message, ...)
__attribute__ ((__format__ (__printf__, 4, 5)));
void complain (char const *format, ...)
__attribute__ ((__format__ (__printf__, 1, 2)));
void complain_at (location loc, char const *format, ...)
__attribute__ ((__format__ (__printf__, 2, 3)));
/** Report an obsolete syntax, suggest the updated one. */
void deprecated_directive (location const *loc,
char const *obsolete, char const *updated);
/* Generate a message aligned by an indent.
When *indent == 0, assign message's indent to *indent,
When *indent > 0, align the message by *indent value. */
void complain_at_indent (location loc, unsigned *indent,
char const *format, ...)
__attribute__ ((__format__ (__printf__, 3, 4)));
/** 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
} err_status;
/** An incompatibility with POSIX Yacc: mapped either to warn* or
complain* depending on yacc_flag. */
void yacc_at (location loc, char const *format, ...)
__attribute__ ((__format__ (__printf__, 2, 3)));
/** A midrule-value warning. Report iff
<tt>warnings_flag & warnings_midrule_values</tt>. */
void midrule_value_at (location loc, char const *format, ...)
__attribute__ ((__format__ (__printf__, 2, 3)));
/** A fatal error, causing immediate exit. */
void fatal (char const *format, ...)
__attribute__ ((__noreturn__, __format__ (__printf__, 1, 2)));
void fatal_at (location loc, char const *format, ...)
__attribute__ ((__noreturn__, __format__ (__printf__, 2, 3)));
/** Whether an error was reported. */
extern err_status complaint_status;
extern bool complaint_issued;
# ifdef __cplusplus
}
# endif
#endif /* !COMPLAIN_H_ */
+222 -214
View File
@@ -1,7 +1,7 @@
/* Find and resolve or report lookahead conflicts for bison,
Copyright (C) 1984, 1989, 1992, 2000-2013 Free Software Foundation,
Inc.
Copyright (C) 1984, 1989, 1992, 2000-2007, 2009-2013 Free Software
Foundation, Inc.
This file is part of Bison, the GNU Compiler Compiler.
@@ -64,75 +64,75 @@ enum conflict_resolution
static inline void
log_resolution (rule *r, symbol_number token,
enum conflict_resolution resolution)
enum conflict_resolution resolution)
{
if (report_flag & report_solved_conflicts)
{
/* The description of the resolution. */
switch (resolution)
{
case shift_resolution:
case right_resolution:
obstack_printf (&solved_conflicts_obstack,
_(" Conflict between rule %d and token %s"
" resolved as shift"),
r->number,
symbols[token]->tag);
break;
{
case shift_resolution:
case right_resolution:
obstack_printf (&solved_conflicts_obstack,
_(" Conflict between rule %d and token %s"
" resolved as shift"),
r->number,
symbols[token]->tag);
break;
case reduce_resolution:
case left_resolution:
obstack_printf (&solved_conflicts_obstack,
_(" Conflict between rule %d and token %s"
" resolved as reduce"),
r->number,
symbols[token]->tag);
break;
case reduce_resolution:
case left_resolution:
obstack_printf (&solved_conflicts_obstack,
_(" Conflict between rule %d and token %s"
" resolved as reduce"),
r->number,
symbols[token]->tag);
break;
case nonassoc_resolution:
obstack_printf (&solved_conflicts_obstack,
_(" Conflict between rule %d and token %s"
" resolved as an error"),
r->number,
symbols[token]->tag);
break;
}
case nonassoc_resolution:
obstack_printf (&solved_conflicts_obstack,
_(" Conflict between rule %d and token %s"
" resolved as an error"),
r->number,
symbols[token]->tag);
break;
}
/* The reason. */
switch (resolution)
{
case shift_resolution:
obstack_printf (&solved_conflicts_obstack,
" (%s < %s)",
r->prec->tag,
symbols[token]->tag);
break;
{
case shift_resolution:
obstack_printf (&solved_conflicts_obstack,
" (%s < %s)",
r->prec->tag,
symbols[token]->tag);
break;
case reduce_resolution:
obstack_printf (&solved_conflicts_obstack,
" (%s < %s)",
symbols[token]->tag,
r->prec->tag);
break;
case reduce_resolution:
obstack_printf (&solved_conflicts_obstack,
" (%s < %s)",
symbols[token]->tag,
r->prec->tag);
break;
case left_resolution:
obstack_printf (&solved_conflicts_obstack,
" (%%left %s)",
symbols[token]->tag);
break;
case left_resolution:
obstack_printf (&solved_conflicts_obstack,
" (%%left %s)",
symbols[token]->tag);
break;
case right_resolution:
obstack_printf (&solved_conflicts_obstack,
" (%%right %s)",
symbols[token]->tag);
break;
case right_resolution:
obstack_printf (&solved_conflicts_obstack,
" (%%right %s)",
symbols[token]->tag);
break;
case nonassoc_resolution:
obstack_printf (&solved_conflicts_obstack,
" (%%nonassoc %s)",
symbols[token]->tag);
break;
}
case nonassoc_resolution:
obstack_printf (&solved_conflicts_obstack,
" (%%nonassoc %s)",
symbols[token]->tag);
break;
}
obstack_sgrow (&solved_conflicts_obstack, ".\n");
}
@@ -226,7 +226,7 @@ flush_shift (state *s, int token)
bitset_reset (lookahead_set, token);
for (i = 0; i < trans->num; i++)
if (!TRANSITION_IS_DISABLED (trans, i)
&& TRANSITION_SYMBOL (trans, i) == token)
&& TRANSITION_SYMBOL (trans, i) == token)
TRANSITION_DISABLE (trans, i);
}
@@ -268,61 +268,51 @@ resolve_sr_conflict (state *s, int ruleno, symbol **errors, int *nerrs)
for (i = 0; i < ntokens; i++)
if (bitset_test (lookahead_tokens, i)
&& bitset_test (lookahead_set, i)
&& symbols[i]->prec)
&& bitset_test (lookahead_set, i)
&& symbols[i]->prec)
{
/* Shift-reduce conflict occurs for token number i
and it has a precedence.
The precedence of shifting is that of token i. */
if (symbols[i]->prec < redprec)
{
register_precedence (redrule->prec->number, i);
log_resolution (redrule, i, reduce_resolution);
flush_shift (s, i);
}
else if (symbols[i]->prec > redprec)
{
register_precedence (i, redrule->prec->number);
log_resolution (redrule, i, shift_resolution);
flush_reduce (lookahead_tokens, i);
}
else
/* Matching precedence levels.
For non-defined associativity, keep both: unexpected
associativity conflict.
For left associativity, keep only the reduction.
For right associativity, keep only the shift.
For nonassociativity, keep neither. */
/* Shift-reduce conflict occurs for token number i
and it has a precedence.
The precedence of shifting is that of token i. */
if (symbols[i]->prec < redprec)
{
log_resolution (redrule, i, reduce_resolution);
flush_shift (s, i);
}
else if (symbols[i]->prec > redprec)
{
log_resolution (redrule, i, shift_resolution);
flush_reduce (lookahead_tokens, i);
}
else
/* Matching precedence levels.
For left association, keep only the reduction.
For right association, keep only the shift.
For nonassociation, keep neither. */
switch (symbols[i]->assoc)
{
case undef_assoc:
abort ();
switch (symbols[i]->assoc)
{
default:
abort ();
case precedence_assoc:
break;
case right_assoc:
log_resolution (redrule, i, right_resolution);
flush_reduce (lookahead_tokens, i);
break;
case right_assoc:
register_assoc (i, redrule->prec->number);
log_resolution (redrule, i, right_resolution);
flush_reduce (lookahead_tokens, i);
break;
case left_assoc:
log_resolution (redrule, i, left_resolution);
flush_shift (s, i);
break;
case left_assoc:
register_assoc (i, redrule->prec->number);
log_resolution (redrule, i, left_resolution);
flush_shift (s, i);
break;
case non_assoc:
register_assoc (i, redrule->prec->number);
log_resolution (redrule, i, nonassoc_resolution);
flush_shift (s, i);
flush_reduce (lookahead_tokens, i);
/* Record an explicit error for this token. */
errors[(*nerrs)++] = symbols[i];
break;
}
case non_assoc:
log_resolution (redrule, i, nonassoc_resolution);
flush_shift (s, i);
flush_reduce (lookahead_tokens, i);
/* Record an explicit error for this token. */
errors[(*nerrs)++] = symbols[i];
break;
}
}
}
@@ -355,7 +345,7 @@ set_conflicts (state *s, symbol **errors)
precedence. */
for (i = 0; i < reds->num; ++i)
if (reds->rules[i]->prec && reds->rules[i]->prec->prec
&& !bitset_disjoint_p (reds->lookahead_tokens[i], lookahead_set))
&& !bitset_disjoint_p (reds->lookahead_tokens[i], lookahead_set))
resolve_sr_conflict (s, i, errors, &nerrs);
if (nerrs)
@@ -365,16 +355,22 @@ set_conflicts (state *s, symbol **errors)
state_errs_set (s, nerrs, errors);
}
if (obstack_object_size (&solved_conflicts_obstack))
s->solved_conflicts = obstack_finish0 (&solved_conflicts_obstack);
{
obstack_1grow (&solved_conflicts_obstack, '\0');
s->solved_conflicts = obstack_finish (&solved_conflicts_obstack);
}
if (obstack_object_size (&solved_conflicts_xml_obstack))
s->solved_conflicts_xml = obstack_finish0 (&solved_conflicts_xml_obstack);
{
obstack_1grow (&solved_conflicts_xml_obstack, '\0');
s->solved_conflicts_xml = obstack_finish (&solved_conflicts_xml_obstack);
}
/* Loop over all rules which require lookahead in this state. Check
for conflicts not resolved above. */
for (i = 0; i < reds->num; ++i)
{
if (!bitset_disjoint_p (reds->lookahead_tokens[i], lookahead_set))
conflicts[s->number] = 1;
conflicts[s->number] = 1;
bitset_or (lookahead_set, lookahead_set, reds->lookahead_tokens[i]);
}
}
@@ -403,9 +399,9 @@ 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);
states[i]->errs = errs_new (0, 0);
}
free (errors);
@@ -427,10 +423,11 @@ conflicts_update_state_numbers (state_number old_to_new[],
| Count the number of shift/reduce conflicts. |
`---------------------------------------------*/
static size_t
count_state_sr_conflicts (state *s)
static int
count_sr_conflicts (state *s)
{
int i;
int src_count = 0;
transitions *trans = s->transitions;
reductions *reds = s->reductions;
@@ -448,66 +445,56 @@ count_state_sr_conflicts (state *s)
bitset_and (lookahead_set, lookahead_set, shift_set);
return bitset_count (lookahead_set);
src_count = bitset_count (lookahead_set);
return src_count;
}
/*---------------------------------------------.
| The total number of shift/reduce conflicts. |
`---------------------------------------------*/
static size_t
count_sr_conflicts (void)
{
size_t res = 0;
state_number i;
/* Conflicts by state. */
for (i = 0; i < nstates; i++)
if (conflicts[i])
res += count_state_sr_conflicts (states[i]);
return res;
}
/*----------------------------------------------------------------.
| Count the number of reduce/reduce conflicts. If ONE_PER_TOKEN, |
| count one conflict for each token that has any reduce/reduce |
| conflicts. Otherwise, count one conflict for each pair of |
| conflicting reductions. |
`----------------------------------------------------------------*/
+`----------------------------------------------------------------*/
static size_t
count_state_rr_conflicts (state *s, bool one_per_token)
static int
count_rr_conflicts (state *s, bool one_per_token)
{
int i;
reductions *reds = s->reductions;
size_t res = 0;
int rrc_count = 0;
for (i = 0; i < ntokens; i++)
{
int count = 0;
int j;
for (j = 0; j < reds->num; ++j)
count += bitset_test (reds->lookahead_tokens[j], i);
if (bitset_test (reds->lookahead_tokens[j], i))
count++;
if (count >= 2)
res += one_per_token ? 1 : count-1;
rrc_count += one_per_token ? 1 : count-1;
}
return res;
return rrc_count;
}
static size_t
count_rr_conflicts (bool one_per_token)
{
size_t res = 0;
state_number i;
/* Conflicts by state. */
for (i = 0; i < nstates; i++)
if (conflicts[i])
res += count_state_rr_conflicts (states[i], one_per_token);
return res;
/*--------------------------------------------------------.
| Report the number of conflicts, using the Yacc format. |
`--------------------------------------------------------*/
static void
conflict_report (FILE *out, int src_num, int rrc_num)
{
if (src_num && rrc_num)
fprintf (out, _("conflicts: %d shift/reduce, %d reduce/reduce\n"),
src_num, rrc_num);
else if (src_num)
fprintf (out, _("conflicts: %d shift/reduce\n"), src_num);
else if (rrc_num)
fprintf (out, _("conflicts: %d reduce/reduce\n"), rrc_num);
}
@@ -524,20 +511,12 @@ conflicts_output (FILE *out)
{
state *s = states[i];
if (conflicts[i])
{
int src = count_state_sr_conflicts (s);
int rrc = count_state_rr_conflicts (s, true);
fprintf (out, _("State %d "), i);
if (src && rrc)
fprintf (out,
_("conflicts: %d shift/reduce, %d reduce/reduce\n"),
src, rrc);
else if (src)
fprintf (out, _("conflicts: %d shift/reduce\n"), src);
else if (rrc)
fprintf (out, _("conflicts: %d reduce/reduce\n"), rrc);
printed_sth = true;
}
{
fprintf (out, _("State %d "), i);
conflict_report (out, count_sr_conflicts (s),
count_rr_conflicts (s, true));
printed_sth = true;
}
}
if (printed_sth)
fputs ("\n\n", out);
@@ -547,13 +526,24 @@ conflicts_output (FILE *out)
| Total the number of S/R and R/R conflicts. Unlike the |
| code in conflicts_output, however, count EACH pair of |
| reductions for the same state and lookahead as one |
| conflict. |
| conflict. |
`--------------------------------------------------------*/
int
conflicts_total_count (void)
{
return count_sr_conflicts () + count_rr_conflicts (false);
state_number i;
int count;
/* Conflicts by state. */
count = 0;
for (i = 0; i < nstates; i++)
if (conflicts[i])
{
count += count_sr_conflicts (states[i]);
count += count_rr_conflicts (states[i], false);
}
return count;
}
@@ -564,57 +554,75 @@ conflicts_total_count (void)
void
conflicts_print (void)
{
if (! glr_parser && expected_rr_conflicts != -1)
/* Is the number of SR conflicts OK? Either EXPECTED_CONFLICTS is
not set, and then we want 0 SR, or else it is specified, in which
case we want equality. */
bool src_ok;
bool rrc_ok;
int src_total = 0;
int rrc_total = 0;
int src_expected;
int rrc_expected;
/* Conflicts by state. */
{
state_number i;
for (i = 0; i < nstates; i++)
if (conflicts[i])
{
src_total += count_sr_conflicts (states[i]);
rrc_total += count_rr_conflicts (states[i], true);
}
}
if (! glr_parser && rrc_total > 0 && expected_rr_conflicts != -1)
{
complain (NULL, Wother, _("%%expect-rr applies only to GLR parsers"));
warn (_("%%expect-rr applies only to GLR parsers"));
expected_rr_conflicts = -1;
}
/* Screams for factoring, but almost useless because of the
different strings to translate. */
{
int total = count_sr_conflicts ();
/* If %expect is not used, but %expect-rr is, then expect 0 sr. */
int expected =
(expected_sr_conflicts == -1 && expected_rr_conflicts != -1)
? 0
: expected_sr_conflicts;
if (expected != -1)
{
if (expected != total)
complain (NULL, complaint,
_("shift/reduce conflicts: %d found, %d expected"),
total, expected);
}
else if (total)
complain (NULL, Wconflicts_sr,
ngettext ("%d shift/reduce conflict",
"%d shift/reduce conflicts",
total),
total);
}
src_expected = expected_sr_conflicts == -1 ? 0 : expected_sr_conflicts;
rrc_expected = expected_rr_conflicts == -1 ? 0 : expected_rr_conflicts;
src_ok = src_total == src_expected;
rrc_ok = rrc_total == rrc_expected;
{
int total = count_rr_conflicts (true);
/* If %expect-rr is not used, but %expect is, then expect 0 rr. */
int expected =
(expected_rr_conflicts == -1 && expected_sr_conflicts != -1)
? 0
: expected_rr_conflicts;
if (expected != -1)
{
if (expected != total)
complain (NULL, complaint,
_("reduce/reduce conflicts: %d found, %d expected"),
total, expected);
}
else if (total)
complain (NULL, Wconflicts_rr,
ngettext ("%d reduce/reduce conflict",
"%d reduce/reduce conflicts",
total),
total);
}
/* If there are as many RR conflicts and SR conflicts as
expected, then there is nothing to report. */
if (rrc_ok & src_ok)
return;
/* Report the total number of conflicts on STDERR. */
if (expected_sr_conflicts == -1 && expected_rr_conflicts == -1)
{
if (!(warnings_flag & warnings_conflicts_sr))
src_total = 0;
if (!(warnings_flag & warnings_conflicts_rr))
rrc_total = 0;
}
if (src_total | rrc_total)
{
if (expected_sr_conflicts == -1 && expected_rr_conflicts == -1)
set_warning_issued ();
if (! yacc_flag)
fprintf (stderr, "%s: ", current_file);
conflict_report (stderr, src_total, rrc_total);
}
if (expected_sr_conflicts != -1 || expected_rr_conflicts != -1)
{
if (! src_ok)
complain (ngettext ("expected %d shift/reduce conflict",
"expected %d shift/reduce conflicts",
src_expected),
src_expected);
if (! rrc_ok)
complain (ngettext ("expected %d reduce/reduce conflict",
"expected %d reduce/reduce conflicts",
rrc_expected),
rrc_expected);
}
}
+9 -10
View File
@@ -47,13 +47,12 @@ print_derives (void)
for (i = ntokens; i < nsyms; i++)
{
rule **rp;
fprintf (stderr, " %s derives\n", symbols[i]->tag);
fprintf (stderr, "\t%s derives\n", symbols[i]->tag);
for (rp = derives[i - ntokens]; *rp; ++rp)
{
fprintf (stderr, " %3d ", (*rp)->user_number);
rule_rhs_print (*rp, stderr);
fprintf (stderr, "\n");
}
{
fprintf (stderr, "\t\t%3d ", (*rp)->user_number);
rule_rhs_print (*rp, stderr);
}
}
fputs ("\n\n", stderr);
@@ -97,10 +96,10 @@ derives_compute (void)
rule_list *p = dset[i - ntokens];
derives[i - ntokens] = q;
while (p)
{
*q++ = p->value;
p = p->next;
}
{
*q++ = p->value;
p = p->next;
}
*q++ = NULL;
}
+39 -50
View File
@@ -134,18 +134,6 @@ xfclose (FILE *ptr)
}
FILE *
xfdopen (int fd, char const *mode)
{
FILE *res = fdopen (fd, mode);
if (! res)
error (EXIT_FAILURE, get_errno (),
/* On a separate line to please the "unmarked_diagnostics"
syntax-check. */
"fdopen");
return res;
}
/*------------------------------------------------------------------.
| Compute ALL_BUT_EXT, ALL_BUT_TAB_EXT and output files extensions. |
`------------------------------------------------------------------*/
@@ -154,7 +142,7 @@ xfdopen (int fd, char const *mode)
static void
compute_exts_from_gf (const char *ext)
{
if (STREQ (ext, ".y"))
if (strcmp (ext, ".y") == 0)
{
src_extension = xstrdup (language->src_extension);
header_extension = xstrdup (language->header_extension);
@@ -214,12 +202,12 @@ compute_exts_from_src (const char *ext)
static void
file_name_split (const char *file_name,
const char **base, const char **tab, const char **ext)
const char **base, const char **tab, const char **ext)
{
*base = last_component (file_name);
/* Look for the extension, i.e., look for the last dot. */
*ext = strrchr (*base, '.');
*ext = mbsrchr (*base, '.');
*tab = NULL;
/* If there is an extension, check if there is a `.tab' part right
@@ -227,10 +215,11 @@ file_name_split (const char *file_name,
if (*ext)
{
size_t baselen = *ext - *base;
size_t dottablen = sizeof (TAB_EXT) - 1;
size_t dottablen = 4;
if (dottablen < baselen
&& STRPREFIX_LIT (TAB_EXT, *ext - dottablen))
*tab = *ext - dottablen;
&& (strncmp (*ext - dottablen, ".tab", dottablen) == 0
|| strncmp (*ext - dottablen, "_tab", dottablen) == 0))
*tab = *ext - dottablen;
}
}
@@ -252,44 +241,44 @@ compute_file_name_parts (void)
/* ALL_BUT_EXT goes up the EXT, excluding it. */
all_but_ext =
xstrndup (spec_outfile,
(strlen (spec_outfile) - (ext ? strlen (ext) : 0)));
xstrndup (spec_outfile,
(strlen (spec_outfile) - (ext ? strlen (ext) : 0)));
/* ALL_BUT_TAB_EXT goes up to TAB, excluding it. */
all_but_tab_ext =
xstrndup (spec_outfile,
(strlen (spec_outfile)
- (tab ? strlen (tab) : (ext ? strlen (ext) : 0))));
xstrndup (spec_outfile,
(strlen (spec_outfile)
- (tab ? strlen (tab) : (ext ? strlen (ext) : 0))));
if (ext)
compute_exts_from_src (ext);
compute_exts_from_src (ext);
}
else
{
file_name_split (grammar_file, &base, &tab, &ext);
if (spec_file_prefix)
{
/* If --file-prefix=foo was specified, ALL_BUT_TAB_EXT = `foo'. */
dir_prefix =
{
/* 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);
all_but_tab_ext = xstrdup (spec_file_prefix);
}
all_but_tab_ext = xstrdup (spec_file_prefix);
}
else if (yacc_flag)
{
/* If --yacc, then the output is `y.tab.c'. */
dir_prefix = xstrdup ("");
all_but_tab_ext = xstrdup ("y");
}
{
/* 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'. */
dir_prefix = xstrdup ("");
all_but_tab_ext =
xstrndup (base, (strlen (base) - (ext ? strlen (ext) : 0)));
}
{
/* Otherwise, ALL_BUT_TAB_EXT is computed from the input
grammar: `foo/bar.yy' => `bar'. */
dir_prefix = xstrdup ("");
all_but_tab_ext =
xstrndup (base, (strlen (base) - (ext ? strlen (ext) : 0)));
}
if (language->add_tab)
all_but_ext = concat2 (all_but_tab_ext, TAB_EXT);
@@ -298,7 +287,7 @@ compute_file_name_parts (void)
/* Compute the extensions from the grammar file name. */
if (ext && !yacc_flag)
compute_exts_from_gf (ext);
compute_exts_from_gf (ext);
}
}
@@ -325,20 +314,20 @@ compute_output_file_names (void)
if (defines_flag)
{
if (! spec_defines_file)
spec_defines_file = concat2 (all_but_ext, header_extension);
spec_defines_file = concat2 (all_but_ext, header_extension);
}
if (graph_flag)
{
if (! spec_graph_file)
spec_graph_file = concat2 (all_but_tab_ext, ".dot");
spec_graph_file = concat2 (all_but_tab_ext, ".dot");
output_file_name_check (&spec_graph_file);
}
if (xml_flag)
{
if (! spec_xml_file)
spec_xml_file = concat2 (all_but_tab_ext, ".xml");
spec_xml_file = concat2 (all_but_tab_ext, ".xml");
output_file_name_check (&spec_xml_file);
}
@@ -358,9 +347,9 @@ void
output_file_name_check (char **file_name)
{
bool conflict = false;
if (STREQ (*file_name, grammar_file))
if (0 == strcmp (*file_name, grammar_file))
{
complain (NULL, complaint, _("refusing to overwrite the input file %s"),
complain (_("refusing to overwrite the input file %s"),
quote (*file_name));
conflict = true;
}
@@ -368,10 +357,10 @@ output_file_name_check (char **file_name)
{
int i;
for (i = 0; i < file_names_count; i++)
if (STREQ (file_names[i], *file_name))
if (0 == strcmp (file_names[i], *file_name))
{
complain (NULL, Wother, _("conflicting outputs to file %s"),
quote (*file_name));
warn (_("conflicting outputs to file %s"),
quote (*file_name));
conflict = true;
}
}

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