mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-08-08 10:15:14 +00:00
Compare commits
218
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a3efd13e44 | ||
|
|
a4122000c6 | ||
|
|
461983270c | ||
|
|
ea99d6e6a0 | ||
|
|
184b42c85b | ||
|
|
be29c71dd8 | ||
|
|
d439985436 | ||
|
|
f3d2a1b2ac | ||
|
|
21cf80399f | ||
|
|
7b0ca050f7 | ||
|
|
a339aef48a | ||
|
|
44186fc4ec | ||
|
|
5c77412162 | ||
|
|
5cf6e669af | ||
|
|
16bb9f1647 | ||
|
|
edb2e90531 | ||
|
|
6d94eebba7 | ||
|
|
c2ecada32b | ||
|
|
458171e6df | ||
|
|
8d0b7cef7d | ||
|
|
afc4457605 | ||
|
|
60dcc936ce | ||
|
|
ad9d4f9f2e | ||
|
|
3cc83855d9 | ||
|
|
5407fc7d76 | ||
|
|
516652b474 | ||
|
|
026816664f | ||
|
|
265640d56e | ||
|
|
ee9cdb8595 | ||
|
|
a810712331 | ||
|
|
1a9646fc91 | ||
|
|
67411a88a0 | ||
|
|
0bfe22b6d5 | ||
|
|
3a684d611e | ||
|
|
a9733794bb | ||
|
|
19fe1aa332 | ||
|
|
39bace5da8 | ||
|
|
071863b3d8 | ||
|
|
e4678430c2 | ||
|
|
2b7fe38c36 | ||
|
|
4c4191cec2 | ||
|
|
ae7cd18c98 | ||
|
|
77482f2783 | ||
|
|
5a6e85fb8d | ||
|
|
9e87ff5472 | ||
|
|
3afe18fd1f | ||
|
|
b51cf830a6 | ||
|
|
66b03e134f | ||
|
|
3dc50b3bc2 | ||
|
|
0a244a2269 | ||
|
|
b5e27aa262 | ||
|
|
0149d39e6e | ||
|
|
1d91bfdf1c | ||
|
|
db40c3f869 | ||
|
|
b663fd5322 | ||
|
|
c4aa4ff541 | ||
|
|
b97bbbaed7 | ||
|
|
e386b50f26 | ||
|
|
534497f54b | ||
|
|
a62a7b014c | ||
|
|
de1a2f20dd | ||
|
|
afcc58c63e | ||
|
|
d3ae5af6ec | ||
|
|
41dfa1cbf0 | ||
|
|
b7171c45f4 | ||
|
|
ac953ff80a | ||
|
|
facb910cbd | ||
|
|
8faace8d1d | ||
|
|
9cdcbdf2cf | ||
|
|
45c64fa627 | ||
|
|
58b465ae5f | ||
|
|
d116722c54 | ||
|
|
1d678854a4 | ||
|
|
28c4075b58 | ||
|
|
aa94def12d | ||
|
|
0fcc2e9a74 | ||
|
|
94a6225578 | ||
|
|
02798ba13d | ||
|
|
8e13c5c03b | ||
|
|
266cdc3025 | ||
|
|
fea2516636 | ||
|
|
c0ef22ab0b | ||
|
|
971ef18e30 | ||
|
|
ec991d74e1 | ||
|
|
c0efa83c0b | ||
|
|
e37054cf27 | ||
|
|
89ff1b5e71 | ||
|
|
f122444873 | ||
|
|
30465cb778 | ||
|
|
f9340b27b2 | ||
|
|
f249e803f0 | ||
|
|
dfb12d6845 | ||
|
|
d8ce703102 | ||
|
|
8782fe26cb | ||
|
|
7ba01e111c | ||
|
|
6ce4b4ff1b | ||
|
|
332019e19a | ||
|
|
9402b62353 | ||
|
|
985d7177e8 | ||
|
|
7dbadca2d0 | ||
|
|
3f21a394f4 | ||
|
|
827aca04eb | ||
|
|
ff2e3d397a | ||
|
|
aba47f5624 | ||
|
|
abcfd805b8 | ||
|
|
1f5542fe2d | ||
|
|
d065cb3853 | ||
|
|
c53b684889 | ||
|
|
5fad4d4f09 | ||
|
|
7956485cd6 | ||
|
|
bb4b189b9c | ||
|
|
d9cfa2bee2 | ||
|
|
0f9583b69b | ||
|
|
c98b5143b0 | ||
|
|
07e65a77aa | ||
|
|
ee616bdc62 | ||
|
|
630a021850 | ||
|
|
75ae829984 | ||
|
|
08cc1a3b18 | ||
|
|
edaa22ec15 | ||
|
|
cc8962bdde | ||
|
|
435575cb5e | ||
|
|
1fa19a7697 | ||
|
|
d1a07886ee | ||
|
|
71846502ae | ||
|
|
90b89dadb2 | ||
|
|
e4d49586b6 | ||
|
|
21e3a2b56c | ||
|
|
cb8d8bb9b6 | ||
|
|
e52ddf820b | ||
|
|
6574576cfb | ||
|
|
dde95ca432 | ||
|
|
6155db81aa | ||
|
|
11872a8372 | ||
|
|
49964a4fe0 | ||
|
|
68f91d58f1 | ||
|
|
42bcf1ce44 | ||
|
|
de7331a075 | ||
|
|
b0db817ff2 | ||
|
|
a565f73276 | ||
|
|
3cf3393bd4 | ||
|
|
e83be476a5 | ||
|
|
80a2826e69 | ||
|
|
eb0e86ac80 | ||
|
|
57597927ef | ||
|
|
de5fb744c9 | ||
|
|
14bfd2e9d9 | ||
|
|
36a17b50b5 | ||
|
|
8a9283494b | ||
|
|
dac72a91d9 | ||
|
|
a17c70f876 | ||
|
|
c56d0037d2 | ||
|
|
9fb61ca8d8 | ||
|
|
3f6e5dd6ac | ||
|
|
2dc8862bab | ||
|
|
5202b6ac1d | ||
|
|
02879b4e81 | ||
|
|
f24695eff9 | ||
|
|
05e25f2384 | ||
|
|
f1526426cd | ||
|
|
7601a471f5 | ||
|
|
6c7022f7d3 | ||
|
|
edd3280b69 | ||
|
|
fe65b14424 | ||
|
|
e39fcdda38 | ||
|
|
5ae8eb3202 | ||
|
|
bbed3fdef6 | ||
|
|
42fef01256 | ||
|
|
29248b4c13 | ||
|
|
361444e419 | ||
|
|
85bc7f5466 | ||
|
|
1282c12476 | ||
|
|
0fe5a72a26 | ||
|
|
4c9b8f1318 | ||
|
|
45eebca42d | ||
|
|
d49751602c | ||
|
|
6240346aa0 | ||
|
|
09add9c24f | ||
|
|
8b807f1177 | ||
|
|
42d101da8d | ||
|
|
f68a49ed49 | ||
|
|
684083f065 | ||
|
|
8ecac08f2d | ||
|
|
fd003416d5 | ||
|
|
ae2b48f5c0 | ||
|
|
9e4917b2a1 | ||
|
|
12bc1c9e47 | ||
|
|
808e523db4 | ||
|
|
4a3c55cf1a | ||
|
|
c017f88fde | ||
|
|
219458e22f | ||
|
|
fec5f3c0cc | ||
|
|
9a9130f26d | ||
|
|
312d0d654f | ||
|
|
848bcc288d | ||
|
|
ec6dc4375e | ||
|
|
c21e515e05 | ||
|
|
1dce289a00 | ||
|
|
66c209cf43 | ||
|
|
efbc95a7e4 | ||
|
|
c5dbd909d0 | ||
|
|
6112cb1802 | ||
|
|
246ff8c1d3 | ||
|
|
f50fa14529 | ||
|
|
2c056d696d | ||
|
|
06505b0c69 | ||
|
|
e96415a54b | ||
|
|
f038e56cdc | ||
|
|
f2e1d4090d | ||
|
|
be6fa942ac | ||
|
|
f29f8af3ed | ||
|
|
74ce3cfbf6 | ||
|
|
b805eca764 | ||
|
|
e6c25014bb | ||
|
|
97ad789d10 | ||
|
|
d2f9ae18be | ||
|
|
cc2235ace2 | ||
|
|
657ed6d3be |
+10
-1
@@ -1,7 +1,16 @@
|
||||
*.eps
|
||||
*.log
|
||||
*.o
|
||||
*.pdf
|
||||
*.png
|
||||
*.stamp
|
||||
*.trs
|
||||
*~
|
||||
.deps
|
||||
.dirstamp
|
||||
/*.cache
|
||||
/*.flc
|
||||
/*.prj
|
||||
/*~
|
||||
/.tarball-version
|
||||
/.version
|
||||
/ABOUT-NLS
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
2.7
|
||||
3.0.1
|
||||
|
||||
+4
-4
@@ -32,8 +32,8 @@ EXTRA_DIST = .prev-version .version \
|
||||
## version of Bison nearby...
|
||||
BISON = $(top_builddir)/tests/bison
|
||||
BISON_IN = $(top_srcdir)/tests/bison.in
|
||||
YACC = $(BISON) -y
|
||||
AM_YFLAGS = -d -v --warnings=all,error --report=all
|
||||
YACC = $(BISON) -o y.tab.c
|
||||
AM_YFLAGS = -d -v -Werror -Wall -Wno-yacc --report=all
|
||||
|
||||
# Initialization before completion by local.mk's.
|
||||
AM_CFLAGS = $(WARN_CFLAGS)
|
||||
@@ -78,11 +78,11 @@ dist-hook: gen-ChangeLog
|
||||
|
||||
.PHONY: update-b4-copyright update-package-copyright-year
|
||||
update-b4-copyright:
|
||||
find $(srcdir)/data -type f \
|
||||
$(AM_V_GEN)find $(srcdir)/data -type f \
|
||||
| xargs $(srcdir)/build-aux/$@
|
||||
@echo 'warning: src/parse-gram.[hc] may need to be regenerated.'
|
||||
update-package-copyright-year:
|
||||
$(srcdir)/build-aux/$@ $(srcdir)/configure.ac
|
||||
$(AM_V_GEN)$(srcdir)/build-aux/$@ $(srcdir)/configure.ac
|
||||
|
||||
gen_start_date = 2012-01-16
|
||||
.PHONY: gen-ChangeLog
|
||||
|
||||
@@ -1,17 +1,64 @@
|
||||
GNU Bison NEWS
|
||||
|
||||
* Noteworthy changes in release ?.? (????-??-??) [?]
|
||||
* Noteworthy changes in release 3.0.2 (2013-12-05) [stable]
|
||||
|
||||
** Bug fixes
|
||||
|
||||
*** Generated source files when errors are reported
|
||||
|
||||
When warnings are issued and -Werror is set, bison would still generate
|
||||
the source files (*.c, *.h...). As a consequence, some runs of "make"
|
||||
could fail the first time, but not the second (as the files were generated
|
||||
anyway).
|
||||
|
||||
This is fixed: bison no longer generates this source files, but, of
|
||||
course, still produces the various reports (*.output, *.xml, etc.).
|
||||
|
||||
*** %empty is used in reports
|
||||
|
||||
Empty right-hand sides are denoted by '%empty' in all the reports (text,
|
||||
dot, XML and formats derived from it).
|
||||
|
||||
*** YYERROR and variants
|
||||
|
||||
When C++ variant support is enabled, an error triggered via YYERROR, but
|
||||
not caught via error recovery, resulted in a double deletion.
|
||||
|
||||
* Noteworthy changes in release 3.0.1 (2013-11-12) [stable]
|
||||
|
||||
** Bug fixes
|
||||
|
||||
*** Errors in caret diagnostics
|
||||
|
||||
On some platforms, some errors could result in endless diagnostics.
|
||||
|
||||
*** Fixes of the -Werror option
|
||||
|
||||
Options such as "-Werror -Wno-error=foo" were still turning "foo"
|
||||
diagnostics into errors instead of warnings. This is fixed.
|
||||
|
||||
Actually, for consistency with GCC, "-Wno-error=foo -Werror" now also
|
||||
leaves "foo" diagnostics as warnings. Similarly, with "-Werror=foo
|
||||
-Wno-error", "foo" diagnostics are now errors.
|
||||
|
||||
*** GLR Predicates
|
||||
|
||||
As demonstrated in the documentation, one can now leave spaces between
|
||||
"%?" and its "{".
|
||||
|
||||
*** Installation
|
||||
|
||||
The yacc.1 man page is no longer installed if --disable-yacc was
|
||||
specified.
|
||||
|
||||
*** Fixes in the test suite
|
||||
|
||||
Bugs and portability issues.
|
||||
|
||||
* Noteworthy changes in release 3.0 (2013-07-25) [stable]
|
||||
|
||||
** WARNING: Future backward-incompatibilities!
|
||||
|
||||
Bison will stop adding a semicolon at the end of the actions (as announced
|
||||
in the release 2.5):
|
||||
|
||||
foo.y:2.22: warning: a ';' might be needed at the end of action code
|
||||
exp: "num" { $$ = $1 }
|
||||
^
|
||||
foo.y:2.22: future versions of Bison will not add the ';'
|
||||
|
||||
Like other GNU packages, Bison will start using some of the C99 features
|
||||
for its own code, especially the definition of variables after statements.
|
||||
The generated C parsers still aim at C90.
|
||||
@@ -28,9 +75,32 @@ GNU Bison NEWS
|
||||
Support for YYLEX_PARAM and YYPARSE_PARAM is removed (deprecated in Bison
|
||||
1.875): use %lex-param, %parse-param, or %param.
|
||||
|
||||
Missing semicolons at the end of actions are no longer added (as announced
|
||||
in the release 2.5).
|
||||
|
||||
*** Use of YACC='bison -y'
|
||||
|
||||
TL;DR: With Autoconf <= 2.69, pass -Wno-yacc to (AM_)YFLAGS if you use
|
||||
Bison extensions.
|
||||
|
||||
Traditional Yacc generates 'y.tab.c' whatever the name of the input file.
|
||||
Therefore Makefiles written for Yacc expect 'y.tab.c' (and possibly
|
||||
'y.tab.h' and 'y.outout') to be generated from 'foo.y'.
|
||||
|
||||
To this end, for ages, AC_PROG_YACC, Autoconf's macro to look for an
|
||||
implementation of Yacc, was using Bison as 'bison -y'. While it does
|
||||
ensure compatible output file names, it also enables warnings for
|
||||
incompatibilities with POSIX Yacc. In other words, 'bison -y' triggers
|
||||
warnings for Bison extensions.
|
||||
|
||||
Autoconf 2.70+ fixes this incompatibility by using YACC='bison -o y.tab.c'
|
||||
(which also generates 'y.tab.h' and 'y.output' when needed).
|
||||
Alternatively, disable Yacc warnings by passing '-Wno-yacc' to your Yacc
|
||||
flags (YFLAGS, or AM_YFLAGS with Automake).
|
||||
|
||||
** Bug fixes
|
||||
|
||||
*** The epilogue is no longer affected by internal #defines
|
||||
*** The epilogue is no longer affected by internal #defines (glr.c)
|
||||
|
||||
The glr.c skeleton uses defines such as #define yylval (yystackp->yyval) in
|
||||
generated code. These weren't properly undefined before the inclusion of
|
||||
@@ -39,7 +109,7 @@ GNU Bison NEWS
|
||||
|
||||
int yylex (YYSTYPE *yylval);
|
||||
|
||||
This is has been fixed: yylval, yynerrs, yychar, and yylloc are now valid
|
||||
This is fixed: yylval, yynerrs, yychar, and yylloc are now valid
|
||||
identifiers for user-provided variables.
|
||||
|
||||
*** stdio.h is no longer needed when locations are enabled (yacc.c)
|
||||
@@ -47,6 +117,8 @@ GNU Bison NEWS
|
||||
Changes in Bison 2.7 introduced a dependency on FILE and fprintf when
|
||||
locations are enabled. This is fixed.
|
||||
|
||||
*** Warnings about useless %pure-parser/%define api.pure are restored
|
||||
|
||||
** Diagnostics reported by Bison
|
||||
|
||||
Most of these features were contributed by Théophile Ranquet and Victor
|
||||
@@ -58,6 +130,29 @@ GNU Bison NEWS
|
||||
activated by default. The old format can still be used by invoking Bison
|
||||
with -fno-caret (or -fnone).
|
||||
|
||||
Some error messages that reproduced excerpts of the grammar are now using
|
||||
the caret information only. For instance on:
|
||||
|
||||
%%
|
||||
exp: 'a' | 'a';
|
||||
|
||||
Bison 2.7 reports:
|
||||
|
||||
in.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
|
||||
in.y:2.12-14: warning: rule useless in parser due to conflicts: exp: 'a' [-Wother]
|
||||
|
||||
Now bison reports:
|
||||
|
||||
in.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
|
||||
in.y:2.12-14: warning: rule useless in parser due to conflicts [-Wother]
|
||||
exp: 'a' | 'a';
|
||||
^^^
|
||||
|
||||
and "bison -fno-caret" reports:
|
||||
|
||||
in.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
|
||||
in.y:2.12-14: warning: rule useless in parser due to conflicts [-Wother]
|
||||
|
||||
*** Enhancements of the -Werror option
|
||||
|
||||
The -Werror=CATEGORY option is now recognized, and will treat specified
|
||||
@@ -198,12 +293,10 @@ GNU Bison NEWS
|
||||
bar.y: error: shift/reduce conflicts: 1 found, 0 expected
|
||||
bar.y: error: reduce/reduce conflicts: 2 found, 0 expected
|
||||
|
||||
*** Useless precedence
|
||||
** Incompatibilities with POSIX Yacc
|
||||
|
||||
Bison now warns about symbols with a declared precedence but no declared
|
||||
associativity (i.e. declared with %precedence), and whose precedence is
|
||||
never used. In that case, the symbol can be safely declared with %token
|
||||
instead, without modifying the parsing tables.
|
||||
The 'yacc' category is no longer part of '-Wall', enable it explicitly
|
||||
with '-Wyacc'.
|
||||
|
||||
** Additional yylex/yyparse arguments
|
||||
|
||||
@@ -220,13 +313,271 @@ GNU Bison NEWS
|
||||
|
||||
%param {arg1_type *arg1} {arg2_type *arg2}
|
||||
|
||||
** Java skeleton improvements
|
||||
** Types of values for %define variables
|
||||
|
||||
Contributed by Paolo Bonzini.
|
||||
Bison used to make no difference between '%define foo bar' and '%define
|
||||
foo "bar"'. The former is now called a 'keyword value', and the latter a
|
||||
'string value'. A third kind was added: 'code values', such as '%define
|
||||
foo {bar}'.
|
||||
|
||||
Keyword variables are used for fixed value sets, e.g.,
|
||||
|
||||
%define lr.type lalr
|
||||
|
||||
Code variables are used for value in the target language, e.g.,
|
||||
|
||||
%define api.value.type {struct semantic_type}
|
||||
|
||||
String variables are used remaining cases, e.g. file names.
|
||||
|
||||
** Variable api.token.prefix
|
||||
|
||||
The variable api.token.prefix changes the way tokens are identified in
|
||||
the generated files. This is especially useful to avoid collisions
|
||||
with identifiers in the target language. For instance
|
||||
|
||||
%token FILE for ERROR
|
||||
%define api.token.prefix {TOK_}
|
||||
%%
|
||||
start: FILE for ERROR;
|
||||
|
||||
will generate the definition of the symbols TOK_FILE, TOK_for, and
|
||||
TOK_ERROR in the generated sources. In particular, the scanner must
|
||||
use these prefixed token names, although the grammar itself still
|
||||
uses the short names (as in the sample rule given above).
|
||||
|
||||
** Variable api.value.type
|
||||
|
||||
This new %define variable supersedes the #define macro YYSTYPE. The use
|
||||
of YYSTYPE is discouraged. In particular, #defining YYSTYPE *and* either
|
||||
using %union or %defining api.value.type results in undefined behavior.
|
||||
|
||||
Either define api.value.type, or use "%union":
|
||||
|
||||
%union
|
||||
{
|
||||
int ival;
|
||||
char *sval;
|
||||
}
|
||||
%token <ival> INT "integer"
|
||||
%token <sval> STRING "string"
|
||||
%printer { fprintf (yyo, "%d", $$); } <ival>
|
||||
%destructor { free ($$); } <sval>
|
||||
|
||||
/* In yylex(). */
|
||||
yylval.ival = 42; return INT;
|
||||
yylval.sval = "42"; return STRING;
|
||||
|
||||
The %define variable api.value.type supports both keyword and code values.
|
||||
|
||||
The keyword value 'union' means that the user provides genuine types, not
|
||||
union member names such as "ival" and "sval" above (WARNING: will fail if
|
||||
-y/--yacc/%yacc is enabled).
|
||||
|
||||
%define api.value.type union
|
||||
%token <int> INT "integer"
|
||||
%token <char *> STRING "string"
|
||||
%printer { fprintf (yyo, "%d", $$); } <int>
|
||||
%destructor { free ($$); } <char *>
|
||||
|
||||
/* In yylex(). */
|
||||
yylval.INT = 42; return INT;
|
||||
yylval.STRING = "42"; return STRING;
|
||||
|
||||
The keyword value variant is somewhat equivalent, but for C++ special
|
||||
provision is made to allow classes to be used (more about this below).
|
||||
|
||||
%define api.value.type variant
|
||||
%token <int> INT "integer"
|
||||
%token <std::string> STRING "string"
|
||||
|
||||
Code values (in braces) denote user defined types. This is where YYSTYPE
|
||||
used to be used.
|
||||
|
||||
%code requires
|
||||
{
|
||||
struct my_value
|
||||
{
|
||||
enum
|
||||
{
|
||||
is_int, is_string
|
||||
} kind;
|
||||
union
|
||||
{
|
||||
int ival;
|
||||
char *sval;
|
||||
} u;
|
||||
};
|
||||
}
|
||||
%define api.value.type {struct my_value}
|
||||
%token <u.ival> INT "integer"
|
||||
%token <u.sval> STRING "string"
|
||||
%printer { fprintf (yyo, "%d", $$); } <u.ival>
|
||||
%destructor { free ($$); } <u.sval>
|
||||
|
||||
/* In yylex(). */
|
||||
yylval.u.ival = 42; return INT;
|
||||
yylval.u.sval = "42"; return STRING;
|
||||
|
||||
** Variable parse.error
|
||||
|
||||
This variable controls the verbosity of error messages. The use of the
|
||||
%error-verbose directive is deprecated in favor of "%define parse.error
|
||||
verbose".
|
||||
|
||||
** Renamed %define variables
|
||||
|
||||
The following variables have been renamed for consistency. Backward
|
||||
compatibility is ensured, but upgrading is recommended.
|
||||
|
||||
lr.default-reductions -> lr.default-reduction
|
||||
lr.keep-unreachable-states -> lr.keep-unreachable-state
|
||||
namespace -> api.namespace
|
||||
stype -> api.value.type
|
||||
|
||||
** Semantic predicates
|
||||
|
||||
Contributed by Paul Hilfinger.
|
||||
|
||||
The new, experimental, semantic-predicate feature allows actions of the
|
||||
form "%?{ BOOLEAN-EXPRESSION }", which cause syntax errors (as for
|
||||
YYERROR) if the expression evaluates to 0, and are evaluated immediately
|
||||
in GLR parsers, rather than being deferred. The result is that they allow
|
||||
the programmer to prune possible parses based on the values of run-time
|
||||
expressions.
|
||||
|
||||
** The directive %expect-rr is now an error in non GLR mode
|
||||
|
||||
It used to be an error only if used in non GLR mode, _and_ if there are
|
||||
reduce/reduce conflicts.
|
||||
|
||||
** Tokens are numbered in their order of appearance
|
||||
|
||||
Contributed by Valentin Tolmer.
|
||||
|
||||
With '%token A B', A had a number less than the one of B. However,
|
||||
precedence declarations used to generate a reversed order. This is now
|
||||
fixed, and introducing tokens with any of %token, %left, %right,
|
||||
%precedence, or %nonassoc yields the same result.
|
||||
|
||||
When mixing declarations of tokens with a litteral character (e.g., 'a')
|
||||
or with an identifier (e.g., B) in a precedence declaration, Bison
|
||||
numbered the litteral characters first. For example
|
||||
|
||||
%right A B 'c' 'd'
|
||||
|
||||
would lead to the tokens declared in this order: 'c' 'd' A B. Again, the
|
||||
input order is now preserved.
|
||||
|
||||
These changes were made so that one can remove useless precedence and
|
||||
associativity declarations (i.e., map %nonassoc, %left or %right to
|
||||
%precedence, or to %token) and get exactly the same output.
|
||||
|
||||
** Useless precedence and associativity
|
||||
|
||||
Contributed by Valentin Tolmer.
|
||||
|
||||
When developing and maintaining a grammar, useless associativity and
|
||||
precedence directives are common. They can be a nuisance: new ambiguities
|
||||
arising are sometimes masked because their conflicts are resolved due to
|
||||
the extra precedence or associativity information. Furthermore, it can
|
||||
hinder the comprehension of a new grammar: one will wonder about the role
|
||||
of a precedence, where in fact it is useless. The following changes aim
|
||||
at detecting and reporting these extra directives.
|
||||
|
||||
*** Precedence warning category
|
||||
|
||||
A new category of warning, -Wprecedence, was introduced. It flags the
|
||||
useless precedence and associativity directives.
|
||||
|
||||
*** Useless associativity
|
||||
|
||||
Bison now warns about symbols with a declared associativity that is never
|
||||
used to resolve conflicts. In that case, using %precedence is sufficient;
|
||||
the parsing tables will remain unchanged. Solving these warnings may raise
|
||||
useless precedence warnings, as the symbols no longer have associativity.
|
||||
For example:
|
||||
|
||||
%left '+'
|
||||
%left '*'
|
||||
%%
|
||||
exp:
|
||||
"number"
|
||||
| exp '+' "number"
|
||||
| exp '*' exp
|
||||
;
|
||||
|
||||
will produce a
|
||||
|
||||
warning: useless associativity for '+', use %precedence [-Wprecedence]
|
||||
%left '+'
|
||||
^^^
|
||||
|
||||
*** Useless precedence
|
||||
|
||||
Bison now warns about symbols with a declared precedence and no declared
|
||||
associativity (i.e., declared with %precedence), and whose precedence is
|
||||
never used. In that case, the symbol can be safely declared with %token
|
||||
instead, without modifying the parsing tables. For example:
|
||||
|
||||
%precedence '='
|
||||
%%
|
||||
exp: "var" '=' "number";
|
||||
|
||||
will produce a
|
||||
|
||||
warning: useless precedence for '=' [-Wprecedence]
|
||||
%precedence '='
|
||||
^^^
|
||||
|
||||
*** Useless precedence and associativity
|
||||
|
||||
In case of both useless precedence and associativity, the issue is flagged
|
||||
as follows:
|
||||
|
||||
%nonassoc '='
|
||||
%%
|
||||
exp: "var" '=' "number";
|
||||
|
||||
The warning is:
|
||||
|
||||
warning: useless precedence and associativity for '=' [-Wprecedence]
|
||||
%nonassoc '='
|
||||
^^^
|
||||
|
||||
** Empty rules
|
||||
|
||||
With help from Joel E. Denny and Gabriel Rassoul.
|
||||
|
||||
Empty rules (i.e., with an empty right-hand side) can now be explicitly
|
||||
marked by the new %empty directive. Using %empty on a non-empty rule is
|
||||
an error. The new -Wempty-rule warning reports empty rules without
|
||||
%empty. On the following grammar:
|
||||
|
||||
%%
|
||||
s: a b c;
|
||||
a: ;
|
||||
b: %empty;
|
||||
c: 'a' %empty;
|
||||
|
||||
bison reports:
|
||||
|
||||
3.4-5: warning: empty rule without %empty [-Wempty-rule]
|
||||
a: {}
|
||||
^^
|
||||
5.8-13: error: %empty on non-empty rule
|
||||
c: 'a' %empty {};
|
||||
^^^^^^
|
||||
|
||||
** Java skeleton improvements
|
||||
|
||||
The constants for token names were moved to the Lexer interface. Also, it
|
||||
is possible to add code to the parser's constructors using "%code init"
|
||||
and "%define init_throws".
|
||||
Contributed by Paolo Bonzini.
|
||||
|
||||
The Java skeleton now supports push parsing.
|
||||
Contributed by Dennis Heimbigner.
|
||||
|
||||
** C++ skeletons improvements
|
||||
|
||||
@@ -249,59 +600,66 @@ GNU Bison NEWS
|
||||
used by the scanner, or rejecting invalid combinations from a
|
||||
factory invoked by the user actions).
|
||||
|
||||
** Renamed %define variables
|
||||
*** %define api.value.type variant
|
||||
|
||||
The following variables have been renamed for consistency. Backward
|
||||
compatibility is ensured, but upgrading is recommended.
|
||||
This is based on a submission from Michiel De Wilde. With help
|
||||
from Théophile Ranquet.
|
||||
|
||||
lr.default-reductions -> lr.default-reduction
|
||||
lr.keep-unreachable-states -> lr.keep-unreachable-state
|
||||
namespace -> api.namespace
|
||||
stype -> api.value.type
|
||||
In this mode, complex C++ objects can be used as semantic values. For
|
||||
instance:
|
||||
|
||||
** Variable api.token.prefix
|
||||
|
||||
The variable api.token.prefix changes the way tokens are identified in
|
||||
the generated files. This is especially useful to avoid collisions
|
||||
with identifiers in the target language. For instance
|
||||
|
||||
%token FILE for ERROR
|
||||
%define api.token.prefix "TOK_"
|
||||
%token <::std::string> TEXT;
|
||||
%token <int> NUMBER;
|
||||
%token SEMICOLON ";"
|
||||
%type <::std::string> item;
|
||||
%type <::std::list<std::string>> list;
|
||||
%%
|
||||
start: FILE for ERROR;
|
||||
result:
|
||||
list { std::cout << $1 << std::endl; }
|
||||
;
|
||||
|
||||
will generate the definition of the symbols TOK_FILE, TOK_for, and
|
||||
TOK_ERROR in the generated sources. In particular, the scanner must
|
||||
use these prefixed token names, although the grammar itself still
|
||||
uses the short names (as in the sample rule given above).
|
||||
list:
|
||||
%empty { /* Generates an empty string list. */ }
|
||||
| list item ";" { std::swap ($$, $1); $$.push_back ($2); }
|
||||
;
|
||||
|
||||
** Variable parse.error
|
||||
item:
|
||||
TEXT { std::swap ($$, $1); }
|
||||
| NUMBER { $$ = string_cast ($1); }
|
||||
;
|
||||
|
||||
This variable controls the verbosity of error messages. The use of the
|
||||
%error-verbose directive is deprecated in favor of "%define parse.error
|
||||
verbose".
|
||||
*** %define api.token.constructor
|
||||
|
||||
** Semantic predicates
|
||||
When variants are enabled, Bison can generate functions to build the
|
||||
tokens. This guarantees that the token type (e.g., NUMBER) is consistent
|
||||
with the semantic value (e.g., int):
|
||||
|
||||
Contributed by Paul Hilfinger.
|
||||
parser::symbol_type yylex ()
|
||||
{
|
||||
parser::location_type loc = ...;
|
||||
...
|
||||
return parser::make_TEXT ("Hello, world!", loc);
|
||||
...
|
||||
return parser::make_NUMBER (42, loc);
|
||||
...
|
||||
return parser::make_SEMICOLON (loc);
|
||||
...
|
||||
}
|
||||
|
||||
The new, experimental, semantic-predicate feature allows actions of the
|
||||
form "%?{ BOOLEAN-EXPRESSION }", which cause syntax errors (as for
|
||||
YYERROR) if the expression evaluates to 0, and are evaluated immediately
|
||||
in GLR parsers, rather than being deferred. The result is that they allow
|
||||
the programmer to prune possible parses based on the values of run-time
|
||||
expressions.
|
||||
*** C++ locations
|
||||
|
||||
** The directive %expect-rr is now an error in non GLR mode
|
||||
There are operator- and operator-= for 'location'. Negative line/column
|
||||
increments can no longer underflow the resulting value.
|
||||
|
||||
It used to be an error only if used in non GLR mode, _and_ if there are
|
||||
reduce/reduce conflicts.
|
||||
* Noteworthy changes in release 2.7.1 (2013-04-15) [stable]
|
||||
|
||||
** Token numbering has changed to preserve the user-defined order
|
||||
** Bug fixes
|
||||
|
||||
When declaring %token A B, the numbering for A is inferior to B. Up to now,
|
||||
when declaring associativity at the same time, with %left (or %right,
|
||||
%precedence, %nonassoc), B was inferior to A.
|
||||
*** Fix compiler attribute portability (yacc.c)
|
||||
|
||||
With locations enabled, __attribute__ was used unprotected.
|
||||
|
||||
*** Fix some compiler warnings (lalr1.cc)
|
||||
|
||||
* Noteworthy changes in release 2.7 (2012-12-12) [stable]
|
||||
|
||||
@@ -353,8 +711,8 @@ GNU Bison NEWS
|
||||
exp: exp '+' exp { $exp = $1 + $3; };
|
||||
^^^
|
||||
|
||||
The default behaviour for now is still not to display these unless
|
||||
explictly asked with -fcaret (or -fall). However, in a later release, it
|
||||
The default behavior for now is still not to display these unless
|
||||
explicitly asked with -fcaret (or -fall). However, in a later release, it
|
||||
will be made the default behavior (but may still be deactivated with
|
||||
-fno-caret).
|
||||
|
||||
@@ -441,7 +799,7 @@ GNU Bison NEWS
|
||||
|
||||
Other issues in the test suite have been addressed.
|
||||
|
||||
Nul characters are correctly displayed in error messages.
|
||||
Null characters are correctly displayed in error messages.
|
||||
|
||||
When possible, yylloc is correctly initialized before calling yylex. It
|
||||
is no longer necessary to initialize it in the %initial-action.
|
||||
@@ -2357,7 +2715,12 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
LocalWords: Automake TMPDIR LESSEQ ylwrap endif yydebug YYTOKEN YYLSP ival hh
|
||||
LocalWords: extern YYTOKENTYPE TOKENTYPE yytokentype tokentype STYPE lval pdf
|
||||
LocalWords: lang yyoutput dvi html ps POSIX lvalp llocp Wother nterm arg init
|
||||
LocalWords: TOK calc yyo fval Wconflicts
|
||||
LocalWords: TOK calc yyo fval Wconflicts parsers yystackp yyval yynerrs
|
||||
LocalWords: Théophile Ranquet Santet fno fnone stype associativity Tolmer
|
||||
LocalWords: Wprecedence Rassoul Wempty Paolo Bonzini parser's Michiel loc
|
||||
LocalWords: redeclaration sval fcaret reentrant XSLT xsl Wmaybe yyvsp Tedi
|
||||
LocalWords: pragmas noreturn untyped Rozenman unexpanded Wojciech Polak
|
||||
LocalWords: Alexandre MERCHANTABILITY yytype
|
||||
|
||||
Local Variables:
|
||||
mode: outline
|
||||
|
||||
@@ -30,7 +30,7 @@ not answer them, please send mail to <[email protected]>.
|
||||
|
||||
* Bug reports
|
||||
Please send bug reports to <[email protected]>. Please include the
|
||||
version number from `bison --version', and a complete, self-contained
|
||||
version number from 'bison --version', and a complete, self-contained
|
||||
test case in each bug report.
|
||||
|
||||
* Copyright statements
|
||||
|
||||
@@ -62,13 +62,22 @@ tools we depend upon, including:
|
||||
- Gettext <http://www.gnu.org/software/gettext/>
|
||||
- Graphviz <http://www.graphviz.org>
|
||||
- Gzip <http://www.gnu.org/software/gzip/>
|
||||
- Help2man <http://www.gnu.org/software/help2man/>
|
||||
- Perl <http://www.cpan.org/>
|
||||
- Rsync <http://samba.anu.edu.au/rsync/>
|
||||
- Tar <http://www.gnu.org/software/tar/>
|
||||
- Texinfo <http://www.gnu.org/software/texinfo/>
|
||||
|
||||
Valgrind <http://valgrind.org/> is also highly recommended, if it supports
|
||||
your architecture.
|
||||
|
||||
If you're using a GNU/Linux distribution, the easiest way to install the
|
||||
above packages depends on your system. The following shell command should
|
||||
work for Debian-based systems such as Ubuntu:
|
||||
|
||||
sudo apt-get install \
|
||||
autoconf automake autopoint flex graphviz help2man texinfo valgrind
|
||||
|
||||
Bison is written using Bison grammars, so there are bootstrapping issues.
|
||||
The bootstrap script attempts to discover when the C code generated from the
|
||||
grammars is out of date, and to bootstrap with an out-of-date version of the
|
||||
|
||||
+1
-1
@@ -9,7 +9,7 @@ Bison supports the @N construction, which gives you access to
|
||||
the starting and ending line number and character number associated
|
||||
with any of the symbols in the current rule.
|
||||
|
||||
Also, Bison supports the command `%expect N' which says not to mention
|
||||
Also, Bison supports the command '%expect N' which says not to mention
|
||||
the conflicts if there are N shift/reduce conflicts and no reduce/reduce
|
||||
conflicts.
|
||||
|
||||
|
||||
@@ -25,10 +25,13 @@ Bruce Lilly [email protected]
|
||||
Bruno Haible [email protected]
|
||||
Charles-Henri de Boysson [email protected]
|
||||
Christian Burger [email protected]
|
||||
Colin Daley [email protected]
|
||||
Cris Bailiff [email protected]
|
||||
Cris van Pelt [email protected]
|
||||
Csaba Raduly [email protected]
|
||||
Dagobert Michelsen [email protected]
|
||||
Daniel Frużyński [email protected]
|
||||
Daniel Galloway [email protected]
|
||||
Daniel Hagerty [email protected]
|
||||
David J. MacKenzie [email protected]
|
||||
David Kastrup [email protected]
|
||||
@@ -37,6 +40,7 @@ Derek M. Jones [email protected]
|
||||
Di-an Jan [email protected]
|
||||
Dick Streefland [email protected]
|
||||
Didier Godefroy [email protected]
|
||||
Efi Fogel [email protected]
|
||||
Enrico Scholz [email protected]
|
||||
Eric Blake [email protected]
|
||||
Evgeny Stambulchik [email protected]
|
||||
@@ -44,6 +48,7 @@ Fabrice Bauzac [email protected]
|
||||
Florian Krohm [email protected]
|
||||
Frank Heckenbach [email protected]
|
||||
Frans Englich [email protected]
|
||||
Gabriel Rassoul [email protected]
|
||||
Georg Sauthoff [email protected]
|
||||
George Neuner [email protected]
|
||||
Gilles Espinasse [email protected]
|
||||
@@ -61,6 +66,7 @@ Johan van Selst [email protected]
|
||||
Jonathan Fabrizio [email protected]
|
||||
Jonathan Nieder [email protected]
|
||||
Juan Manuel Guerrero [email protected]
|
||||
Ken Moffat [email protected]
|
||||
Kees Zeelenberg [email protected]
|
||||
Keith Browne [email protected]
|
||||
Laurent Mascherpa [email protected]
|
||||
@@ -74,6 +80,7 @@ Martin Mokrejs [email protected]
|
||||
Martin Nylin [email protected]
|
||||
Matt Kraai [email protected]
|
||||
Matt Rosing [email protected]
|
||||
Michael Felt [email protected]
|
||||
Michael Hayes [email protected]
|
||||
Michael Raskin [email protected]
|
||||
Michiel De Wilde [email protected]
|
||||
@@ -89,6 +96,7 @@ Odd Arild Olsen [email protected]
|
||||
Oleg Smolsky [email protected]
|
||||
Oleksii Taran [email protected]
|
||||
Paolo Bonzini [email protected]
|
||||
Paolo Simone Gasparello [email protected]
|
||||
Pascal Bart [email protected]
|
||||
Paul Eggert [email protected]
|
||||
Paul Hilfinger [email protected]
|
||||
@@ -97,6 +105,7 @@ Peter Eisentraut [email protected]
|
||||
Peter Fales [email protected]
|
||||
Peter Hamorsky [email protected]
|
||||
Peter Simons [email protected]
|
||||
Petr Machata [email protected]
|
||||
Piotr Gackiewicz [email protected]
|
||||
Quentin Hocquet [email protected]
|
||||
Quoc Peyrot [email protected]
|
||||
@@ -104,8 +113,10 @@ R Blake [email protected]
|
||||
Raja R Harinath [email protected]
|
||||
Ralf Wildenhues [email protected]
|
||||
Richard Stallman [email protected]
|
||||
Rici Lake [email protected]
|
||||
Rob Vermaas [email protected]
|
||||
Robert Anisko [email protected]
|
||||
Rob Conde [email protected]
|
||||
Roland Levillain [email protected]
|
||||
Satya Kiran Popuri [email protected]
|
||||
Sebastian Setzer [email protected]
|
||||
@@ -126,6 +137,7 @@ Tommy Nordgren [email protected]
|
||||
Troy A. Johnson [email protected]
|
||||
Tys Lefering [email protected]
|
||||
Valentin Tolmer [email protected]
|
||||
Victor Khomenko [email protected]
|
||||
Vin Shelton [email protected]
|
||||
W.C.A. Wijngaards [email protected]
|
||||
Wayne Green [email protected]
|
||||
|
||||
@@ -1,16 +1,27 @@
|
||||
* Short term
|
||||
** Graphviz display code thoughts
|
||||
The code for the --graph option is over two files: print_graph, and
|
||||
graphviz. I believe this is because Bison used to also produce VCG graphs,
|
||||
but since this is no longer true, maybe we could consider these files for
|
||||
fusion.
|
||||
graphviz. This is because Bison used to also produce VCG graphs, but since
|
||||
this is no longer true, maybe we could consider these files for fusion.
|
||||
|
||||
Little effort factoring seems to have been given to factoring in these files,
|
||||
and their print-xml and print counterpart. We would very much like to re-use
|
||||
the pretty format of states from .output in the .dot
|
||||
An other consideration worth noting is that print_graph.c (correct me if I
|
||||
am wrong) should contain generic functions, whereas graphviz.c and other
|
||||
potential files should contain just the specific code for that output
|
||||
format. It will probably prove difficult to tell if the implementation is
|
||||
actually generic whilst only having support for a single format, but it
|
||||
would be nice to keep stuff a bit tidier: right now, the construction of the
|
||||
bitset used to show reductions is in the graphviz-specific code, and on the
|
||||
opposite side we have some use of \l, which is graphviz-specific, in what
|
||||
should be generic code.
|
||||
|
||||
Also, the underscore in print_graph.[ch] isn't very fitting considering
|
||||
the dashes in the other filenames.
|
||||
Little effort seems to have been given to factoring these files and their
|
||||
rint{,-xml} counterpart. We would very much like to re-use the pretty format
|
||||
of states from .output for the graphs, etc.
|
||||
|
||||
Also, the underscore in print_graph.[ch] isn't very fitting considering the
|
||||
dashes in the other filenames.
|
||||
|
||||
Since graphviz dies on medium-to-big grammars, maybe consider an other tool?
|
||||
|
||||
** push-parser
|
||||
Check it too when checking the different kinds of parsers. And be
|
||||
@@ -165,13 +176,13 @@ part of $default. Should we make the two reductions explicit, or just
|
||||
keep $default? See the following point.
|
||||
|
||||
** Disabled Reductions
|
||||
See `tests/conflicts.at (Defaulted Conflicted Reduction)', and decide
|
||||
See 'tests/conflicts.at (Defaulted Conflicted Reduction)', and decide
|
||||
what we want to do.
|
||||
|
||||
** Documentation
|
||||
Extend with error productions. The hard part will probably be finding
|
||||
the right rule so that a single state does not exhibit too many yet
|
||||
undocumented ``features''. Maybe an empty action ought to be
|
||||
undocumented ''features''. Maybe an empty action ought to be
|
||||
presented too. Shall we try to make a single grammar with all these
|
||||
features, or should we have several very small grammars?
|
||||
|
||||
@@ -232,9 +243,9 @@ into
|
||||
exp: exp '+' exp | exp '&' exp;
|
||||
|
||||
when there are no actions. This can significantly speed up some
|
||||
grammars. I can't find the papers. In particular the book `LR
|
||||
grammars. I can't find the papers. In particular the book 'LR
|
||||
parsing: Theory and Practice' is impossible to find, but according to
|
||||
`Parsing Techniques: a Practical Guide', it includes information about
|
||||
'Parsing Techniques: a Practical Guide', it includes information about
|
||||
this issue. Does anybody have it?
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#! /bin/sh
|
||||
# Print a version string.
|
||||
scriptversion=2012-12-28.10; # UTC
|
||||
scriptversion=2013-08-15.22; # UTC
|
||||
|
||||
# Bootstrap this package from checked-out sources.
|
||||
|
||||
@@ -140,20 +140,21 @@ po_download_command_format2=\
|
||||
"wget --mirror -nd -q -np -A.po -P '%s' \
|
||||
http://translationproject.org/latest/%s/"
|
||||
|
||||
# Prefer a non-empty tarname (4th argument of AC_INIT if given), else
|
||||
# fall back to the package name (1st argument with munging)
|
||||
extract_package_name='
|
||||
/^AC_INIT(/{
|
||||
/.*,.*,.*, */{
|
||||
s///
|
||||
s/[][]//g
|
||||
s/)$//
|
||||
/^AC_INIT(\[*/{
|
||||
s///
|
||||
/^[^,]*,[^,]*,[^,]*,[ []*\([^][ ,)]\)/{
|
||||
s//\1/
|
||||
s/[],)].*//
|
||||
p
|
||||
q
|
||||
}
|
||||
s/AC_INIT(\[*//
|
||||
s/]*,.*//
|
||||
s/[],)].*//
|
||||
s/^GNU //
|
||||
y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/
|
||||
s/[^A-Za-z0-9_]/-/g
|
||||
s/[^abcdefghijklmnopqrstuvwxyz0123456789_]/-/g
|
||||
p
|
||||
}
|
||||
'
|
||||
@@ -208,12 +209,16 @@ bootstrap_sync=false
|
||||
# Use git to update gnulib sources
|
||||
use_git=true
|
||||
|
||||
check_exists() {
|
||||
($1 --version </dev/null) >/dev/null 2>&1
|
||||
test $? -lt 126
|
||||
}
|
||||
|
||||
# find_tool ENVVAR NAMES...
|
||||
# -------------------------
|
||||
# Search for a required program. Use the value of ENVVAR, if set,
|
||||
# otherwise find the first of the NAMES that can be run (i.e.,
|
||||
# supports --version). If found, set ENVVAR to the program name,
|
||||
# die otherwise.
|
||||
# otherwise find the first of the NAMES that can be run.
|
||||
# If found, set ENVVAR to the program name, die otherwise.
|
||||
#
|
||||
# FIXME: code duplication, see also gnu-web-doc-update.
|
||||
find_tool ()
|
||||
@@ -223,27 +228,21 @@ find_tool ()
|
||||
find_tool_names=$@
|
||||
eval "find_tool_res=\$$find_tool_envvar"
|
||||
if test x"$find_tool_res" = x; then
|
||||
for i
|
||||
do
|
||||
if ($i --version </dev/null) >/dev/null 2>&1; then
|
||||
find_tool_res=$i
|
||||
break
|
||||
for i; do
|
||||
if check_exists $i; then
|
||||
find_tool_res=$i
|
||||
break
|
||||
fi
|
||||
done
|
||||
else
|
||||
find_tool_error_prefix="\$$find_tool_envvar: "
|
||||
fi
|
||||
test x"$find_tool_res" != x \
|
||||
|| die "one of these is required: $find_tool_names"
|
||||
($find_tool_res --version </dev/null) >/dev/null 2>&1 \
|
||||
|| die "${find_tool_error_prefix}cannot run $find_tool_res --version"
|
||||
if test x"$find_tool_res" = x; then
|
||||
warn_ "one of these is required: $find_tool_names;"
|
||||
die "alternatively set $find_tool_envvar to a compatible tool"
|
||||
fi
|
||||
eval "$find_tool_envvar=\$find_tool_res"
|
||||
eval "export $find_tool_envvar"
|
||||
}
|
||||
|
||||
# Find sha1sum, named gsha1sum on MacPorts, and shasum on Mac OS X 10.6.
|
||||
find_tool SHA1SUM sha1sum gsha1sum shasum
|
||||
|
||||
# Override the default configuration, if necessary.
|
||||
# Make sure that bootstrap.conf is sourced from the current directory
|
||||
# if we were invoked as "sh bootstrap".
|
||||
@@ -255,12 +254,12 @@ esac
|
||||
# Extra files from gnulib, which override files from other sources.
|
||||
test -z "${gnulib_extra_files}" && \
|
||||
gnulib_extra_files="
|
||||
$build_aux/install-sh
|
||||
$build_aux/mdate-sh
|
||||
$build_aux/texinfo.tex
|
||||
$build_aux/depcomp
|
||||
$build_aux/config.guess
|
||||
$build_aux/config.sub
|
||||
build-aux/install-sh
|
||||
build-aux/mdate-sh
|
||||
build-aux/texinfo.tex
|
||||
build-aux/depcomp
|
||||
build-aux/config.guess
|
||||
build-aux/config.sub
|
||||
doc/INSTALL
|
||||
"
|
||||
|
||||
@@ -306,34 +305,34 @@ if test -n "$checkout_only_file" && test ! -r "$checkout_only_file"; then
|
||||
die "Bootstrapping from a non-checked-out distribution is risky."
|
||||
fi
|
||||
|
||||
# Ensure that lines starting with ! sort last, per gitignore conventions
|
||||
# for whitelisting exceptions after a more generic blacklist pattern.
|
||||
sort_patterns() {
|
||||
sort -u "$@" | sed '/^!/ {
|
||||
H
|
||||
d
|
||||
}
|
||||
$ {
|
||||
P
|
||||
x
|
||||
s/^\n//
|
||||
}' | sed '/^$/d'
|
||||
# Strip blank and comment lines to leave significant entries.
|
||||
gitignore_entries() {
|
||||
sed '/^#/d; /^$/d' "$@"
|
||||
}
|
||||
|
||||
# If $STR is not already on a line by itself in $FILE, insert it,
|
||||
# sorting the new contents of the file and replacing $FILE with the result.
|
||||
insert_sorted_if_absent() {
|
||||
# If $STR is not already on a line by itself in $FILE, insert it at the start.
|
||||
# Entries are inserted at the start of the ignore list to ensure existing
|
||||
# entries starting with ! are not overridden. Such entries support
|
||||
# whitelisting exceptions after a more generic blacklist pattern.
|
||||
insert_if_absent() {
|
||||
file=$1
|
||||
str=$2
|
||||
test -f $file || touch $file
|
||||
echo "$str" | sort_patterns - $file | cmp -s - $file > /dev/null \
|
||||
|| { echo "$str" | sort_patterns - $file > $file.bak \
|
||||
&& mv $file.bak $file; } \
|
||||
|| die "insert_sorted_if_absent $file $str: failed"
|
||||
test -r $file || die "Error: failed to read ignore file: $file"
|
||||
duplicate_entries=$(gitignore_entries $file | sort | uniq -d)
|
||||
if [ "$duplicate_entries" ] ; then
|
||||
die "Error: Duplicate entries in $file: " $duplicate_entries
|
||||
fi
|
||||
linesold=$(gitignore_entries $file | wc -l)
|
||||
linesnew=$( { echo "$str"; cat $file; } | gitignore_entries | sort -u | wc -l)
|
||||
if [ $linesold != $linesnew ] ; then
|
||||
{ echo "$str" | cat - $file > $file.bak && mv $file.bak $file; } \
|
||||
|| die "insert_if_absent $file $str: failed"
|
||||
fi
|
||||
}
|
||||
|
||||
# Adjust $PATTERN for $VC_IGNORE_FILE and insert it with
|
||||
# insert_sorted_if_absent.
|
||||
# insert_if_absent.
|
||||
insert_vc_ignore() {
|
||||
vc_ignore_file="$1"
|
||||
pattern="$2"
|
||||
@@ -344,7 +343,7 @@ insert_vc_ignore() {
|
||||
# .gitignore entry.
|
||||
pattern=$(echo "$pattern" | sed s,^,/,);;
|
||||
esac
|
||||
insert_sorted_if_absent "$vc_ignore_file" "$pattern"
|
||||
insert_if_absent "$vc_ignore_file" "$pattern"
|
||||
}
|
||||
|
||||
# Die if there is no AC_CONFIG_AUX_DIR($build_aux) line in configure.ac.
|
||||
@@ -468,8 +467,7 @@ check_versions() {
|
||||
if [ "$req_ver" = "-" ]; then
|
||||
# Merely require app to exist; not all prereq apps are well-behaved
|
||||
# so we have to rely on $? rather than get_version.
|
||||
$app --version >/dev/null 2>&1
|
||||
if [ 126 -le $? ]; then
|
||||
if ! check_exists $app; then
|
||||
warn_ "Error: '$app' not found"
|
||||
ret=1
|
||||
fi
|
||||
@@ -502,6 +500,12 @@ print_versions() {
|
||||
# can't depend on column -t
|
||||
}
|
||||
|
||||
# Find sha1sum, named gsha1sum on MacPorts, shasum on Mac OS X 10.6.
|
||||
# Also find the compatible sha1 utility on the BSDs
|
||||
if test x"$SKIP_PO" = x; then
|
||||
find_tool SHA1SUM sha1sum gsha1sum shasum sha1
|
||||
fi
|
||||
|
||||
use_libtool=0
|
||||
# We'd like to use grep -E, to see if any of LT_INIT,
|
||||
# AC_PROG_LIBTOOL, AM_PROG_LIBTOOL is used in configure.ac,
|
||||
@@ -550,10 +554,10 @@ fi
|
||||
echo "$0: Bootstrapping from checked-out $package sources..."
|
||||
|
||||
# See if we can use gnulib's git-merge-changelog merge driver.
|
||||
if test -d .git && (git --version) >/dev/null 2>/dev/null ; then
|
||||
if $use_git && test -d .git && check_exists git; then
|
||||
if git config merge.merge-changelog.driver >/dev/null ; then
|
||||
:
|
||||
elif (git-merge-changelog --version) >/dev/null 2>/dev/null ; then
|
||||
elif check_exists git-merge-changelog; then
|
||||
echo "$0: initializing git-merge-changelog driver"
|
||||
git config merge.merge-changelog.name 'GNU-style ChangeLog merge driver'
|
||||
git config merge.merge-changelog.driver 'git-merge-changelog %O %A %B'
|
||||
@@ -573,13 +577,17 @@ git_modules_config () {
|
||||
test -f .gitmodules && git config --file .gitmodules "$@"
|
||||
}
|
||||
|
||||
gnulib_path=$(git_modules_config submodule.gnulib.path)
|
||||
test -z "$gnulib_path" && gnulib_path=gnulib
|
||||
if $use_git; then
|
||||
gnulib_path=$(git_modules_config submodule.gnulib.path)
|
||||
test -z "$gnulib_path" && gnulib_path=gnulib
|
||||
fi
|
||||
|
||||
# Get gnulib files.
|
||||
# Get gnulib files. Populate $GNULIB_SRCDIR, possibly updating a
|
||||
# submodule, for use in the rest of the script.
|
||||
|
||||
case ${GNULIB_SRCDIR--} in
|
||||
-)
|
||||
# Note that $use_git is necessarily true in this case.
|
||||
if git_modules_config submodule.gnulib.url >/dev/null; then
|
||||
echo "$0: getting gnulib files..."
|
||||
git submodule init || exit $?
|
||||
@@ -600,8 +608,8 @@ case ${GNULIB_SRCDIR--} in
|
||||
GNULIB_SRCDIR=$gnulib_path
|
||||
;;
|
||||
*)
|
||||
# Use GNULIB_SRCDIR as a reference.
|
||||
if test -d "$GNULIB_SRCDIR"/.git && \
|
||||
# Use GNULIB_SRCDIR directly or as a reference.
|
||||
if $use_git && test -d "$GNULIB_SRCDIR"/.git && \
|
||||
git_modules_config submodule.gnulib.url >/dev/null; then
|
||||
echo "$0: getting gnulib files..."
|
||||
if git submodule -h|grep -- --reference > /dev/null; then
|
||||
@@ -627,12 +635,19 @@ case ${GNULIB_SRCDIR--} in
|
||||
;;
|
||||
esac
|
||||
|
||||
# $GNULIB_SRCDIR now points to the version of gnulib to use, and
|
||||
# we no longer need to use git or $gnulib_path below here.
|
||||
|
||||
if $bootstrap_sync; then
|
||||
cmp -s "$0" "$GNULIB_SRCDIR/build-aux/bootstrap" || {
|
||||
echo "$0: updating bootstrap and restarting..."
|
||||
case $(sh -c 'echo "$1"' -- a) in
|
||||
a) ignored=--;;
|
||||
*) ignored=ignored;;
|
||||
esac
|
||||
exec sh -c \
|
||||
'cp "$1" "$2" && shift && exec "${CONFIG_SHELL-/bin/sh}" "$@"' \
|
||||
-- "$GNULIB_SRCDIR/build-aux/bootstrap" \
|
||||
$ignored "$GNULIB_SRCDIR/build-aux/bootstrap" \
|
||||
"$0" "$@" --no-bootstrap-sync
|
||||
}
|
||||
fi
|
||||
@@ -680,11 +695,10 @@ update_po_files() {
|
||||
cksum_file="$ref_po_dir/$po.s1"
|
||||
if ! test -f "$cksum_file" ||
|
||||
! test -f "$po_dir/$po.po" ||
|
||||
! $SHA1SUM -c --status "$cksum_file" \
|
||||
< "$new_po" > /dev/null; then
|
||||
! $SHA1SUM -c "$cksum_file" < "$new_po" > /dev/null 2>&1; then
|
||||
echo "$me: updated $po_dir/$po.po..."
|
||||
cp "$new_po" "$po_dir/$po.po" \
|
||||
&& $SHA1SUM < "$new_po" > "$cksum_file"
|
||||
&& $SHA1SUM < "$new_po" > "$cksum_file" || return
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
+2
-1
@@ -34,7 +34,8 @@ gnulib_modules='
|
||||
readme-release
|
||||
realloc-posix
|
||||
spawn-pipe stdbool stpcpy strdup-posix strerror strtoul strverscmp
|
||||
unistd unistd-safer unlocked-io update-copyright unsetenv verify
|
||||
unistd unistd-safer unlink unlocked-io
|
||||
update-copyright unsetenv verify
|
||||
warnings
|
||||
xalloc
|
||||
xalloc-die
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
# Linux seattle 2.6.32-5-amd64 #1 SMP Thu Mar 22 17:26:33 UTC 2012
|
||||
# x86_64 GNU/Linux
|
||||
{
|
||||
index
|
||||
Memcheck:Cond
|
||||
fun:index
|
||||
fun:expand_dynamic_string_token
|
||||
fun:_dl_map_object
|
||||
fun:map_doit
|
||||
fun:_dl_catch_error
|
||||
fun:do_preload
|
||||
fun:dl_main
|
||||
fun:_dl_sysdep_start
|
||||
fun:_dl_start
|
||||
obj:/lib/ld-2.11.3.so
|
||||
}
|
||||
+1
-2
@@ -1,5 +1,3 @@
|
||||
## Makefile for Bison testsuite.
|
||||
|
||||
# Copyright (C) 2000-2013 Free Software Foundation, Inc.
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
@@ -18,6 +16,7 @@
|
||||
EXTRA_DIST += \
|
||||
build-aux/cross-options.pl \
|
||||
build-aux/darwin11.4.0.valgrind \
|
||||
build-aux/linux-gnu.valgrind \
|
||||
build-aux/move-if-change \
|
||||
build-aux/prev-version.txt \
|
||||
build-aux/update-b4-copyright
|
||||
|
||||
@@ -135,7 +135,7 @@ _sed_rm_comments_q = $(subst ','\'',$(_sed_remove_comments))
|
||||
|
||||
_space_before_paren_exempt =? \\n\\$$
|
||||
_space_before_paren_exempt = \
|
||||
(^ *\#|\\n\\$$|%s\(to %s|(date|group|character)\(s\))
|
||||
(^ *\#|(LA)?LR\([01]\)|percent_(code|define)|b4_syncline|m4_(define|init)|symbol)
|
||||
# Ensure that there is a space before each open parenthesis in C code.
|
||||
sc_space_before_open_paren:
|
||||
@if $(VC_LIST_EXCEPT) | grep -l '\.[ch]$$' > /dev/null; then \
|
||||
@@ -175,5 +175,6 @@ $(call exclude, \
|
||||
prohibit_strcmp=^doc/bison\.texi|tests/local\.at$$ \
|
||||
prohibit_tab_based_indentation=\.(am|mk)$$|^djgpp/|^\.git \
|
||||
require_config_h_first=^(lib/yyerror|data/(glr|yacc))\.c$$ \
|
||||
space_before_open_paren=^(data/|djgpp/) \
|
||||
unmarked_diagnostics=^(djgpp/|doc/bison.texi$$|tests/c\+\+\.at$$) \
|
||||
)
|
||||
|
||||
+25
-25
@@ -18,7 +18,7 @@
|
||||
# In order for some versions of Sun Studio to compile our C++ test cases
|
||||
# correctly, we need Autoconf 2.64 or better to handle the restrict
|
||||
# keyword in at least string.h from gnulib. We need Autoconf 2.68 or
|
||||
# better to avoid a typo in the `configure --help' entry for the YACC
|
||||
# better to avoid a typo in the 'configure --help' entry for the YACC
|
||||
# environment variable.
|
||||
AC_PREREQ([2.68])
|
||||
m4_pattern_forbid([^gl_[A-Z]])
|
||||
@@ -33,11 +33,7 @@ AC_DEFINE_UNQUOTED([PACKAGE_COPYRIGHT_YEAR], [$PACKAGE_COPYRIGHT_YEAR],
|
||||
AC_CONFIG_AUX_DIR([build-aux])
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
|
||||
# Automake 1.10.3 and 1.11.1 fix a security flaw discussed here:
|
||||
#
|
||||
# http://thread.gmane.org/gmane.comp.sysutils.autotools.announce/131
|
||||
#
|
||||
# To avoid 1.11, we make 1.11.1 the minimum version.
|
||||
# We use Automake 1.14's %D% and %C%.
|
||||
#
|
||||
# We want gnits strictness only when rolling a stable release. For
|
||||
# release candidates, we use version strings like 2.4.3_rc1, but gnits
|
||||
@@ -45,7 +41,7 @@ AC_CONFIG_MACRO_DIR([m4])
|
||||
# releases, we want to be able run make dist without being required to
|
||||
# add a bogus NEWS entry. In that case, the version string
|
||||
# automatically contains a dash, which we also let disable gnits.
|
||||
AM_INIT_AUTOMAKE([1.11.1 dist-xz nostdinc
|
||||
AM_INIT_AUTOMAKE([1.14 dist-xz nostdinc
|
||||
color-tests parallel-tests
|
||||
silent-rules]
|
||||
m4_bmatch(m4_defn([AC_PACKAGE_VERSION]), [[-_]],
|
||||
@@ -82,7 +78,7 @@ AC_ARG_ENABLE([gcc-warnings],
|
||||
esac],
|
||||
[enable_gcc_warnings=no])
|
||||
if test "$enable_gcc_warnings" = yes; then
|
||||
warn_common='-Wall -Wextra -Wno-sign-compare -Wcast-align
|
||||
warn_common='-Wall-Wextra -Wno-sign-compare -Wcast-align -Wdocumentation
|
||||
-Wformat -Wpointer-arith -Wwrite-strings'
|
||||
warn_c='-Wbad-function-cast -Wshadow -Wstrict-prototypes'
|
||||
warn_cxx='-Wnoexcept'
|
||||
@@ -91,7 +87,7 @@ if test "$enable_gcc_warnings" = yes; then
|
||||
# -fno-color-diagnostics: Clang's use of colors in the error
|
||||
# messages is confusing the tests looking at the compiler's output
|
||||
# (e.g., synclines.at).
|
||||
warn_tests='-Wundef -pedantic -fno-color-diagnostics'
|
||||
warn_tests='-Wundef -pedantic -Wsign-compare -fno-color-diagnostics'
|
||||
|
||||
AC_LANG_PUSH([C])
|
||||
# Clang supports many of GCC's -W options, but only issues warnings
|
||||
@@ -143,9 +139,11 @@ if test "$enable_gcc_warnings" = yes; then
|
||||
gl_WARN_ADD([$i], [WARN_CXXFLAGS_TEST])
|
||||
done
|
||||
# Clang++ 3.2+ reject C code generated by Flex.
|
||||
gl_WARN_ADD([-Wno-null-conversion], [WARN_NO_NULL_CONVERSION_CXXFLAGS])
|
||||
# Variants break strict aliasing analysis.
|
||||
gl_WARN_ADD([-fno-strict-aliasing], [NO_STRICT_ALIAS_CXXFLAGS])
|
||||
gl_WARN_ADD([-Wno-null-conversion], [FLEX_SCANNER_CXXFLAGS])
|
||||
# So does G++ 4.8...
|
||||
gl_WARN_ADD([-Wno-sign-compare], [FLEX_SCANNER_CXXFLAGS])
|
||||
# ... possiby in std=c++11 mode.
|
||||
gl_WARN_ADD([-Wno-zero-as-null-pointer-constant], [FLEX_SCANNER_CXXFLAGS])
|
||||
CXXFLAGS=$save_CXXFLAGS
|
||||
AC_LANG_POP([C++])
|
||||
fi
|
||||
@@ -159,21 +157,17 @@ AC_ARG_ENABLE([yacc],
|
||||
[AC_HELP_STRING([--disable-yacc],
|
||||
[do not build a yacc command or an -ly library])],
|
||||
, [enable_yacc=yes])
|
||||
case $enable_yacc in
|
||||
yes)
|
||||
YACC_SCRIPT=src/yacc
|
||||
YACC_LIBRARY=lib/liby.a;;
|
||||
*)
|
||||
YACC_SCRIPT=
|
||||
YACC_LIBRARY=;;
|
||||
esac
|
||||
AC_SUBST([YACC_SCRIPT])
|
||||
AC_SUBST([YACC_LIBRARY])
|
||||
AM_CONDITIONAL([ENABLE_YACC], [test "$enable_yacc" = yes])
|
||||
|
||||
# Checks for programs.
|
||||
AM_MISSING_PROG([DOT], [dot])
|
||||
AC_PROG_LEX
|
||||
$LEX_IS_FLEX || AC_MSG_ERROR([Flex is required])
|
||||
$LEX_IS_FLEX || test "X$LEX" = X: || {
|
||||
AC_MSG_WARN([bypassing lex because flex is required])
|
||||
LEX=:
|
||||
}
|
||||
AM_CONDITIONAL([FLEX_CXX_WORKS],
|
||||
[$LEX_IS_FLEX && test $bison_cv_cxx_works = yes])
|
||||
AC_PROG_YACC
|
||||
AC_PROG_RANLIB
|
||||
AC_PROG_GNU_M4
|
||||
@@ -228,10 +222,16 @@ case $VALGRIND:$host_os in
|
||||
'':*) ;;
|
||||
*:darwin*)
|
||||
# See README-hacking.
|
||||
# VALGRIND+=' --suppressions=$(abs_top_srcdir)/build-aux/darwin11.4.0.valgrind'
|
||||
# VALGRIND+='-q --suppressions=$(abs_top_srcdir)/build-aux/darwin11.4.0.valgrind'
|
||||
VALGRIND=;;
|
||||
*:*)
|
||||
AC_SUBST([VALGRIND_PREBISON], ["$VALGRIND -q"]);;
|
||||
suppfile=build-aux/$host_os.valgrind
|
||||
if test -f "$srcdir/$suppfile"; then
|
||||
VALGRIND="$VALGRIND --gen-suppressions=all"
|
||||
VALGRIND="$VALGRIND --suppressions=\$(abs_top_srcdir)/$suppfile"
|
||||
fi
|
||||
AC_SUBST([VALGRIND_PREBISON], ["$VALGRIND -q"])
|
||||
;;
|
||||
esac
|
||||
|
||||
AM_MISSING_PROG([AUTOM4TE], [autom4te])
|
||||
|
||||
+1
-1
@@ -27,7 +27,7 @@ Currently, the supported skeletons are:
|
||||
These skeletons are the only ones supported by the Bison team.
|
||||
Because the interface between skeletons and the bison program is not
|
||||
finished, *we are not bound to it*. In particular, Bison is not
|
||||
mature enough for us to consider that ``foreign skeletons'' are
|
||||
mature enough for us to consider that "foreign skeletons" are
|
||||
supported.
|
||||
|
||||
* m4sugar
|
||||
|
||||
+141
-28
@@ -85,6 +85,20 @@ m4_changecom([#])
|
||||
])
|
||||
|
||||
|
||||
# b4_divert_kill(CODE)
|
||||
# --------------------
|
||||
# Expand CODE for its side effects, discard its output.
|
||||
m4_define([b4_divert_kill],
|
||||
[m4_divert_text([KILL], [$1])])
|
||||
|
||||
|
||||
# b4_define_silent(MACRO, CODE)
|
||||
# -----------------------------
|
||||
# Same as m4_define, but throw away the expansion of CODE.
|
||||
m4_define([b4_define_silent],
|
||||
[m4_define([$1], [b4_divert_kill([$2])])])
|
||||
|
||||
|
||||
## ---------------- ##
|
||||
## Error handling. ##
|
||||
## ---------------- ##
|
||||
@@ -313,7 +327,7 @@ m4_define([b4_define_flag_if],
|
||||
# _b4_define_flag_if($1, $2, FLAG)
|
||||
# --------------------------------
|
||||
# Work around the impossibility to define macros inside macros,
|
||||
# because issuing `[$1]' is not possible in M4. GNU M4 should provide
|
||||
# because issuing '[$1]' is not possible in M4. GNU M4 should provide
|
||||
# $$1 a la M5/TeX.
|
||||
m4_define([_b4_define_flag_if],
|
||||
[m4_if([$1$2], $[1]$[2], [],
|
||||
@@ -347,6 +361,7 @@ b4_define_flag_if([yacc]) # Whether POSIX Yacc is emulated.
|
||||
# Whether the symbol has an id.
|
||||
# - id: string
|
||||
# If has_id, the id. Guaranteed to be usable as a C identifier.
|
||||
# Prefixed by api.token.prefix if defined.
|
||||
# - tag: string.
|
||||
# A representat of the symbol. Can be 'foo', 'foo.id', '"foo"' etc.
|
||||
# - user_number: integer
|
||||
@@ -357,9 +372,13 @@ b4_define_flag_if([yacc]) # Whether POSIX Yacc is emulated.
|
||||
# The internalized number (used after yytranslate).
|
||||
# - has_type: 0, 1
|
||||
# Whether has a semantic value.
|
||||
# - type_tag: string
|
||||
# When api.value.type=union, the generated name for the union member.
|
||||
# yytype_INT etc. for symbols that has_id, otherwise yytype_1 etc.
|
||||
# - type
|
||||
# If it has a semantic value, its type tag, or, if variant are used,
|
||||
# its type.
|
||||
# In the case of api.value.type=union, type is the real type (e.g. int).
|
||||
# - has_printer: 0, 1
|
||||
# - printer: string
|
||||
# - printer_file: string
|
||||
@@ -442,6 +461,24 @@ m4_define([b4_symbol_destructor], [b4_symbol_action([$1], [destructor])])
|
||||
m4_define([b4_symbol_printer], [b4_symbol_action([$1], [printer])])
|
||||
|
||||
|
||||
# b4_symbol_actions(KIND, [TYPE = yytype])
|
||||
# ----------------------------------------
|
||||
# Emit the symbol actions for KIND ("printer" or "destructor").
|
||||
# Dispatch on TYPE.
|
||||
m4_define([b4_symbol_actions],
|
||||
[m4_pushdef([b4_actions_], m4_expand([b4_symbol_foreach([b4_symbol_$1])]))dnl
|
||||
m4_ifval(m4_defn([b4_actions_]),
|
||||
[switch (m4_default([$2], [yytype]))
|
||||
{
|
||||
m4_defn([b4_actions_])
|
||||
default:
|
||||
break;
|
||||
}dnl
|
||||
],
|
||||
[YYUSE (m4_default([$2], [yytype]));])dnl
|
||||
m4_popdef([b4_actions_])dnl
|
||||
])
|
||||
|
||||
# b4_symbol_case_(SYMBOL-NUM)
|
||||
# ---------------------------
|
||||
# Issue a "case NUM" for SYMBOL-NUM.
|
||||
@@ -577,14 +614,14 @@ m4_define([b4_define_user_code],
|
||||
# b4_user_initial_action
|
||||
# b4_user_post_prologue
|
||||
# b4_user_pre_prologue
|
||||
# b4_user_stype
|
||||
# b4_user_union_members
|
||||
# ----------------------
|
||||
# Macros that issue user code, ending with synclines.
|
||||
b4_define_user_code([actions])
|
||||
b4_define_user_code([initial_action])
|
||||
b4_define_user_code([post_prologue])
|
||||
b4_define_user_code([pre_prologue])
|
||||
b4_define_user_code([stype])
|
||||
b4_define_user_code([union_members])
|
||||
|
||||
|
||||
# b4_check_user_names(WHAT, USER-LIST, BISON-NAMESPACE)
|
||||
@@ -665,9 +702,9 @@ m4_define([b4_percent_define_use],
|
||||
# b4_percent_define_get([[foo]])
|
||||
m4_define([b4_percent_define_get],
|
||||
[b4_percent_define_use([$1])dnl
|
||||
m4_ifdef([b4_percent_define(]$1[)],
|
||||
[m4_indir([b4_percent_define(]$1[)])],
|
||||
[$2])])
|
||||
b4_percent_define_ifdef_([$1],
|
||||
[m4_indir([b4_percent_define(]$1[)])],
|
||||
[$2])])
|
||||
|
||||
# b4_percent_define_get_loc(VARIABLE)
|
||||
# -----------------------------------
|
||||
@@ -686,7 +723,21 @@ m4_define([b4_percent_define_get_loc],
|
||||
[m4_pushdef([b4_loc], m4_indir([b4_percent_define_loc(]$1[)]))dnl
|
||||
b4_loc[]dnl
|
||||
m4_popdef([b4_loc])],
|
||||
[b4_fatal([[b4_percent_define_get_loc: undefined %%define variable '%s']], [$1])])])
|
||||
[b4_fatal([[$0: undefined %%define variable '%s']], [$1])])])
|
||||
|
||||
# b4_percent_define_get_kind(VARIABLE)
|
||||
# ------------------------------------
|
||||
# Get the kind (code, keyword, string) of VARIABLE, i.e., how its
|
||||
# value was defined (braces, not delimiters, quotes).
|
||||
#
|
||||
# If the %define variable VARIABLE is undefined, complain fatally
|
||||
# since that's a Bison or skeleton error. Don't record this as a
|
||||
# Bison usage of VARIABLE as there's no reason to suspect that the
|
||||
# user-supplied value has yet influenced the output.
|
||||
m4_define([b4_percent_define_get_kind],
|
||||
[m4_ifdef([b4_percent_define_kind(]$1[)],
|
||||
[m4_indir([b4_percent_define_kind(]$1[)])],
|
||||
[b4_fatal([[$0: undefined %%define variable '%s']], [$1])])])
|
||||
|
||||
# b4_percent_define_get_syncline(VARIABLE)
|
||||
# ----------------------------------------
|
||||
@@ -703,7 +754,20 @@ m4_popdef([b4_loc])],
|
||||
m4_define([b4_percent_define_get_syncline],
|
||||
[m4_ifdef([b4_percent_define_syncline(]$1[)],
|
||||
[m4_indir([b4_percent_define_syncline(]$1[)])],
|
||||
[b4_fatal([[b4_percent_define_get_syncline: undefined %%define variable '%s']], [$1])])])
|
||||
[b4_fatal([[$0: undefined %%define variable '%s']], [$1])])])
|
||||
|
||||
# b4_percent_define_ifdef_(VARIABLE, IF-TRUE, [IF-FALSE])
|
||||
# ------------------------------------------------------
|
||||
# If the %define variable VARIABLE is defined, expand IF-TRUE, else expand
|
||||
# IF-FALSE. Don't record usage of VARIABLE.
|
||||
#
|
||||
# For example:
|
||||
#
|
||||
# b4_percent_define_ifdef_([[foo]], [[it's defined]], [[it's undefined]])
|
||||
m4_define([b4_percent_define_ifdef_],
|
||||
[m4_ifdef([b4_percent_define(]$1[)],
|
||||
[$2],
|
||||
[$3])])
|
||||
|
||||
# b4_percent_define_ifdef(VARIABLE, IF-TRUE, [IF-FALSE])
|
||||
# ------------------------------------------------------
|
||||
@@ -716,9 +780,9 @@ m4_define([b4_percent_define_get_syncline],
|
||||
#
|
||||
# b4_percent_define_ifdef([[foo]], [[it's defined]], [[it's undefined]])
|
||||
m4_define([b4_percent_define_ifdef],
|
||||
[m4_ifdef([b4_percent_define(]$1[)],
|
||||
[b4_percent_define_use([$1])$2],
|
||||
[$3])])
|
||||
[b4_percent_define_ifdef_([$1],
|
||||
[b4_percent_define_use([$1])$2],
|
||||
[$3])])
|
||||
|
||||
|
||||
## --------- ##
|
||||
@@ -747,11 +811,11 @@ m4_define([b4_percent_define_flag_if],
|
||||
[[invalid value for %%define Boolean variable '%s']],
|
||||
[$1])],
|
||||
[[b4_percent_define_flag_if($1)]])])],
|
||||
[b4_fatal([[b4_percent_define_flag_if: undefined %%define variable '%s']], [$1])])])
|
||||
[b4_fatal([[$0: undefined %%define variable '%s']], [$1])])])
|
||||
|
||||
|
||||
# b4_percent_define_default(VARIABLE, DEFAULT)
|
||||
# --------------------------------------------
|
||||
# b4_percent_define_default(VARIABLE, DEFAULT, [KIND = keyword])
|
||||
# --------------------------------------------------------------
|
||||
# Mimic muscle_percent_define_default in ../src/muscle-tab.h exactly. That is,
|
||||
# if the %define variable VARIABLE is undefined, set its value to DEFAULT.
|
||||
# Don't record this as a Bison usage of VARIABLE as there's no reason to
|
||||
@@ -761,8 +825,10 @@ m4_define([b4_percent_define_flag_if],
|
||||
#
|
||||
# b4_percent_define_default([[foo]], [[default value]])
|
||||
m4_define([b4_percent_define_default],
|
||||
[m4_ifndef([b4_percent_define(]$1[)],
|
||||
[b4_percent_define_ifdef_([$1], [],
|
||||
[m4_define([b4_percent_define(]$1[)], [$2])dnl
|
||||
m4_define([b4_percent_define_kind(]$1[)],
|
||||
[m4_default([$3], [keyword])])dnl
|
||||
m4_define([b4_percent_define_loc(]$1[)],
|
||||
[[[[<skeleton default value>:-1.-1]],
|
||||
[[<skeleton default value>:-1.-1]]]])dnl
|
||||
@@ -772,8 +838,8 @@ m4_define([b4_percent_define_default],
|
||||
# b4_percent_define_if_define(NAME, [VARIABLE = NAME])
|
||||
# ----------------------------------------------------
|
||||
# Define b4_NAME_if that executes its $1 or $2 depending whether
|
||||
# VARIABLE was %defined. The characters `.' and `-' in VARIABLE are mapped
|
||||
# to `_'.
|
||||
# VARIABLE was %defined. The characters '.' and `-' in VARIABLE are mapped
|
||||
# to '_'.
|
||||
m4_define([b4_percent_define_if_define_],
|
||||
[m4_define(m4_bpatsubst([b4_$1_if], [[-.]], [_]),
|
||||
[b4_percent_define_flag_if(m4_default([$2], [$1]),
|
||||
@@ -783,6 +849,21 @@ m4_define([b4_percent_define_if_define],
|
||||
b4_percent_define_if_define_([$1], [$2], $[1], $[2])])
|
||||
|
||||
|
||||
# b4_percent_define_check_kind(VARIABLE, KIND, [DIAGNOSTIC = complain])
|
||||
# ---------------------------------------------------------------------
|
||||
m4_define([b4_percent_define_check_kind],
|
||||
[b4_percent_define_ifdef_([$1],
|
||||
[m4_if(b4_percent_define_get_kind([$1]), [$2], [],
|
||||
[b4_error([m4_default([$3], [complain])],
|
||||
b4_percent_define_get_loc([$1]),
|
||||
[m4_case([$2],
|
||||
[code], [[%%define variable '%s' requires '{...}' values]],
|
||||
[keyword], [[%%define variable '%s' requires keyword values]],
|
||||
[string], [[%%define variable '%s' requires '"..."' values]])],
|
||||
[$1])])])dnl
|
||||
])
|
||||
|
||||
|
||||
# b4_percent_define_check_values(VALUES)
|
||||
# --------------------------------------
|
||||
# Mimic muscle_percent_define_check_values in ../src/muscle-tab.h exactly
|
||||
@@ -804,8 +885,9 @@ m4_define([b4_percent_define_check_values],
|
||||
[_b4_percent_define_check_values(b4_sublist)])])
|
||||
|
||||
m4_define([_b4_percent_define_check_values],
|
||||
[m4_ifdef([b4_percent_define(]$1[)],
|
||||
[m4_pushdef([b4_good_value], [0])dnl
|
||||
[b4_percent_define_ifdef_([$1],
|
||||
[b4_percent_define_check_kind(]$1[, [keyword], [deprecated])dnl
|
||||
m4_pushdef([b4_good_value], [0])dnl
|
||||
m4_if($#, 1, [],
|
||||
[m4_foreach([b4_value], m4_dquote(m4_shift($@)),
|
||||
[m4_if(m4_indir([b4_percent_define(]$1[)]), b4_value,
|
||||
@@ -820,7 +902,7 @@ m4_define([_b4_percent_define_check_values],
|
||||
[[accepted value: '%s']],
|
||||
m4_dquote(b4_value))])])dnl
|
||||
m4_popdef([b4_good_value])],
|
||||
[b4_fatal([[b4_percent_define_check_values: undefined %%define variable '%s']], [$1])])])
|
||||
[b4_fatal([[$0: undefined %%define variable '%s']], [$1])])])
|
||||
|
||||
# b4_percent_code_get([QUALIFIER])
|
||||
# --------------------------------
|
||||
@@ -861,10 +943,6 @@ m4_define([b4_percent_code_ifdef],
|
||||
## Common variables. ##
|
||||
## ------------------ ##
|
||||
|
||||
# Default values for %define.
|
||||
# ---------------------------
|
||||
# If the api.token.prefix, it is empty.
|
||||
m4_percent_define_default([[api.token.prefix]], [[]])
|
||||
|
||||
# b4_parse_assert_if([IF-ASSERTIONS-ARE-USED], [IF-NOT])
|
||||
# b4_parse_trace_if([IF-DEBUG-TRACES-ARE-ENABLED], [IF-NOT])
|
||||
@@ -904,9 +982,11 @@ b4_error_verbose_if([m4_define([b4_token_table_flag], [1])])
|
||||
# b4_variant_if([IF-VARIANT-ARE-USED], [IF-NOT])
|
||||
# ----------------------------------------------
|
||||
b4_percent_define_if_define([variant])
|
||||
m4_case(b4_percent_define_get([[api.value.type]]),
|
||||
[variant], [m4_define([b4_variant_flag], [[1]])],
|
||||
[m4_define([b4_variant_flag], [[0]])])
|
||||
m4_define([b4_variant_flag], [[0]])
|
||||
b4_percent_define_ifdef([[api.value.type]],
|
||||
[m4_case(b4_percent_define_get_kind([[api.value.type]]), [keyword],
|
||||
[m4_case(b4_percent_define_get([[api.value.type]]), [variant],
|
||||
[m4_define([b4_variant_flag], [[1]])])])])
|
||||
b4_define_flag_if([variant])
|
||||
|
||||
|
||||
@@ -941,10 +1021,43 @@ m4_define_default([b4_parse_param], [])
|
||||
m4_define_default([b4_location_initial_column], [1])
|
||||
m4_define_default([b4_location_initial_line], [1])
|
||||
|
||||
# Sanity checks.
|
||||
|
||||
## --------------- ##
|
||||
## Sanity checks. ##
|
||||
## --------------- ##
|
||||
|
||||
# api.location.prefix={...} (Java and C++).
|
||||
b4_percent_define_check_kind([api.location.type], [code], [deprecated])
|
||||
|
||||
# api.position.prefix={...} (Java).
|
||||
b4_percent_define_check_kind([api.position.type], [code], [deprecated])
|
||||
|
||||
# api.prefix >< %name-prefix.
|
||||
b4_percent_define_check_kind([api.prefix], [code], [deprecated])
|
||||
b4_percent_define_ifdef([api.prefix],
|
||||
[m4_ifdef([b4_prefix],
|
||||
[b4_complain_at(b4_percent_define_get_loc([api.prefix]),
|
||||
[['%s' and '%s' cannot be used together]],
|
||||
[%name-prefix],
|
||||
[%define api.prefix])])])
|
||||
|
||||
# api.token.prefix={...}
|
||||
# Make it a warning for those who used betas of Bison 3.0.
|
||||
b4_percent_define_check_kind([api.token.prefix], [code], [deprecated])
|
||||
|
||||
# api.value.type >< %union.
|
||||
b4_percent_define_ifdef([api.value.type],
|
||||
[m4_ifdef([b4_union_members],
|
||||
[b4_complain_at(b4_percent_define_get_loc([api.value.type]),
|
||||
[['%s' and '%s' cannot be used together]],
|
||||
[%union],
|
||||
[%define api.value.type])])])
|
||||
|
||||
# api.value.type=union >< %yacc.
|
||||
b4_percent_define_ifdef([api.value.type],
|
||||
[m4_if(b4_percent_define_get([api.value.type]), [union],
|
||||
[b4_yacc_if(dnl
|
||||
[b4_complain_at(b4_percent_define_get_loc([api.value.type]),
|
||||
[['%s' and '%s' cannot be used together]],
|
||||
[%yacc],
|
||||
[%define api.value.type "union"])])])])
|
||||
|
||||
+35
-13
@@ -25,6 +25,12 @@ m4_include(b4_pkgdatadir/[c.m4])
|
||||
m4_define([b4_comment],
|
||||
[b4_comment_([$1], [$2// ], [$2// ])])
|
||||
|
||||
## -------- ##
|
||||
## Checks. ##
|
||||
## -------- ##
|
||||
|
||||
b4_percent_define_check_kind([api.namespace], [code], [deprecated])
|
||||
b4_percent_define_check_kind([parser_class_name], [code], [deprecated])
|
||||
|
||||
## ---------------- ##
|
||||
## Default values. ##
|
||||
@@ -38,6 +44,7 @@ b4_percent_define_default([[parser_class_name]], [[parser]])
|
||||
# b4_percent_define_default([[api.location.type]], [[location]])
|
||||
|
||||
b4_percent_define_default([[filename_type]], [[std::string]])
|
||||
# Make it a warning for those who used betas of Bison 3.0.
|
||||
b4_percent_define_default([[api.namespace]], m4_defn([b4_prefix]))
|
||||
|
||||
b4_percent_define_default([[global_tokens_and_yystype]], [[false]])
|
||||
@@ -54,8 +61,8 @@ b4_percent_define_default([[define_location_comparison]],
|
||||
m4_define([b4_namespace_ref], [b4_percent_define_get([[api.namespace]])])
|
||||
|
||||
|
||||
# Don't permit an empty b4_namespace_ref. Any `::parser::foo' appended to it
|
||||
# would compile as an absolute reference with `parser' in the global namespace.
|
||||
# Don't permit an empty b4_namespace_ref. Any '::parser::foo' appended to it
|
||||
# would compile as an absolute reference with 'parser' in the global namespace.
|
||||
# b4_namespace_open would open an anonymous namespace and thus establish
|
||||
# internal linkage. This would compile. However, it's cryptic, and internal
|
||||
# linkage for the parser would be specified in all translation units that
|
||||
@@ -112,19 +119,24 @@ m4_define([b4_token_enums],
|
||||
## Semantic Values. ##
|
||||
## ----------------- ##
|
||||
|
||||
# b4_semantic_type_declare
|
||||
# ------------------------
|
||||
|
||||
|
||||
# b4_value_type_declare
|
||||
# ---------------------
|
||||
# Declare semantic_type.
|
||||
m4_define([b4_semantic_type_declare],
|
||||
m4_define([b4_value_type_declare],
|
||||
[b4_value_type_setup[]dnl
|
||||
[ /// Symbol semantic values.
|
||||
m4_ifdef([b4_stype],
|
||||
[ union semantic_type
|
||||
]m4_bmatch(b4_percent_define_get_kind([[api.value.type]]),
|
||||
[code],
|
||||
[[ typedef ]b4_percent_define_get([[api.value.type]])[ semantic_type;]],
|
||||
[m4_bmatch(b4_percent_define_get([[api.value.type]]),
|
||||
[union\|union-directive],
|
||||
[[ union semantic_type
|
||||
{
|
||||
b4_user_stype
|
||||
};],
|
||||
[m4_if(b4_tag_seen_flag, 0,
|
||||
[[ typedef int semantic_type;]],
|
||||
[[ typedef ]b4_api_PREFIX[STYPE semantic_type;]])])])
|
||||
]b4_user_union_members[
|
||||
};]])])dnl
|
||||
])
|
||||
|
||||
|
||||
# b4_public_types_declare
|
||||
@@ -133,7 +145,7 @@ b4_user_stype
|
||||
# Depending on %define token_lex, may be output in the header or source file.
|
||||
m4_define([b4_public_types_declare],
|
||||
[[#ifndef ]b4_api_PREFIX[STYPE
|
||||
]b4_semantic_type_declare[
|
||||
]b4_value_type_declare[
|
||||
#else
|
||||
typedef ]b4_api_PREFIX[STYPE semantic_type;
|
||||
#endif]b4_locations_if([
|
||||
@@ -520,3 +532,13 @@ m4_define([b4_yylloc_default_define],
|
||||
while (/*CONSTCOND*/ false)
|
||||
# endif
|
||||
]])
|
||||
|
||||
## -------- ##
|
||||
## Checks. ##
|
||||
## -------- ##
|
||||
|
||||
b4_token_ctor_if([b4_variant_if([],
|
||||
[b4_fatal_at(b4_percent_define_get_loc(api.token.constructor),
|
||||
[cannot use '%s' without '%s'],
|
||||
[%define api.token.constructor],
|
||||
[%define api.value.type variant]))])])
|
||||
|
||||
@@ -150,7 +150,7 @@ m4_popdef([$1])dnl
|
||||
|
||||
# b4_parse_param_use([VAL], [LOC])
|
||||
# --------------------------------
|
||||
# `YYUSE' VAL, LOC if locations are enabled, and all the parse-params.
|
||||
# 'YYUSE' VAL, LOC if locations are enabled, and all the parse-params.
|
||||
m4_define([b4_parse_param_use],
|
||||
[m4_ifvaln([$1], [ YYUSE ([$1]);])dnl
|
||||
b4_locations_if([m4_ifvaln([$2], [ YYUSE ([$2]);])])dnl
|
||||
@@ -182,7 +182,7 @@ m4_define([b4_int_type],
|
||||
# b4_int_type_for(NAME)
|
||||
# ---------------------
|
||||
# Return the smallest int type able to handle numbers ranging from
|
||||
# `NAME_min' to `NAME_max' (included).
|
||||
# 'NAME_min' to 'NAME_max' (included).
|
||||
m4_define([b4_int_type_for],
|
||||
[b4_int_type($1_min, $1_max)])
|
||||
|
||||
@@ -199,6 +199,69 @@ m4_define([b4_table_value_equals],
|
||||
[(!!(($2) == ($3)))])])
|
||||
|
||||
|
||||
## ----------------- ##
|
||||
## Compiler issues. ##
|
||||
## ----------------- ##
|
||||
|
||||
# b4_attribute_define
|
||||
# -------------------
|
||||
# Provide portable compiler "attributes".
|
||||
m4_define([b4_attribute_define],
|
||||
[#ifndef YY_ATTRIBUTE
|
||||
# if (defined __GNUC__ \
|
||||
&& (2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__))) \
|
||||
|| defined __SUNPRO_C && 0x5110 <= __SUNPRO_C
|
||||
# define YY_ATTRIBUTE(Spec) __attribute__(Spec)
|
||||
# else
|
||||
# define YY_ATTRIBUTE(Spec) /* empty */
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef YY_ATTRIBUTE_PURE
|
||||
# define YY_ATTRIBUTE_PURE YY_ATTRIBUTE ((__pure__))
|
||||
#endif
|
||||
|
||||
#ifndef YY_ATTRIBUTE_UNUSED
|
||||
# define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__))
|
||||
#endif
|
||||
|
||||
#if !defined _Noreturn \
|
||||
&& (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112)
|
||||
# if defined _MSC_VER && 1200 <= _MSC_VER
|
||||
# define _Noreturn __declspec (noreturn)
|
||||
# else
|
||||
# define _Noreturn YY_ATTRIBUTE ((__noreturn__))
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Suppress unused-variable warnings by "using" E. */
|
||||
#if ! defined lint || defined __GNUC__
|
||||
# define YYUSE(E) ((void) (E))
|
||||
#else
|
||||
# define YYUSE(E) /* empty */
|
||||
#endif
|
||||
|
||||
#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__
|
||||
/* Suppress an incorrect diagnostic about yylval being uninitialized. */
|
||||
# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
|
||||
_Pragma ("GCC diagnostic push") \
|
||||
_Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\
|
||||
_Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"")
|
||||
# define YY_IGNORE_MAYBE_UNINITIALIZED_END \
|
||||
_Pragma ("GCC diagnostic pop")
|
||||
#else
|
||||
# define YY_INITIAL_VALUE(Value) Value
|
||||
#endif
|
||||
#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
|
||||
# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
|
||||
# define YY_IGNORE_MAYBE_UNINITIALIZED_END
|
||||
#endif
|
||||
#ifndef YY_INITIAL_VALUE
|
||||
# define YY_INITIAL_VALUE(Value) /* Nothing. */
|
||||
#endif
|
||||
])
|
||||
|
||||
|
||||
## ---------##
|
||||
## Values. ##
|
||||
## ---------##
|
||||
@@ -206,14 +269,14 @@ m4_define([b4_table_value_equals],
|
||||
|
||||
# b4_null_define
|
||||
# --------------
|
||||
# Portability issues: define a YY_NULL appropriate for the current
|
||||
# Portability issues: define a YY_NULLPTR appropriate for the current
|
||||
# language (C, C++98, or C++11).
|
||||
m4_define([b4_null_define],
|
||||
[# ifndef YY_NULL
|
||||
[# ifndef YY_NULLPTR
|
||||
# if defined __cplusplus && 201103L <= __cplusplus
|
||||
# define YY_NULL nullptr
|
||||
# define YY_NULLPTR nullptr
|
||||
# else
|
||||
# define YY_NULL 0
|
||||
# define YY_NULLPTR 0
|
||||
# endif
|
||||
# endif[]dnl
|
||||
])
|
||||
@@ -222,7 +285,7 @@ m4_define([b4_null_define],
|
||||
# b4_null
|
||||
# -------
|
||||
# Return a null pointer constant.
|
||||
m4_define([b4_null], [YY_NULL])
|
||||
m4_define([b4_null], [YY_NULLPTR])
|
||||
|
||||
# b4_integral_parser_table_define(TABLE-NAME, CONTENT, COMMENT)
|
||||
# -------------------------------------------------------------
|
||||
@@ -421,12 +484,9 @@ m4_ifset([b4_parse_param], [, b4_parse_param]))[
|
||||
yymsg = "Deleting";
|
||||
YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
|
||||
|
||||
switch (yytype)
|
||||
{
|
||||
]b4_symbol_foreach([b4_symbol_destructor])dnl
|
||||
[ default:
|
||||
break;
|
||||
}
|
||||
YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
|
||||
]b4_symbol_actions([destructor])[
|
||||
YY_IGNORE_MAYBE_UNINITIALIZED_END
|
||||
}]dnl
|
||||
])
|
||||
|
||||
@@ -436,9 +496,9 @@ m4_ifset([b4_parse_param], [, b4_parse_param]))[
|
||||
# Define the "yy_symbol_print" function.
|
||||
m4_define_default([b4_yy_symbol_print_define],
|
||||
[[
|
||||
/*--------------------------------.
|
||||
| Print this symbol on YYOUTPUT. |
|
||||
`--------------------------------*/
|
||||
/*----------------------------------------.
|
||||
| Print this symbol's value on YYOUTPUT. |
|
||||
`----------------------------------------*/
|
||||
|
||||
]b4_function_define([yy_symbol_value_print],
|
||||
[static void],
|
||||
@@ -459,12 +519,7 @@ m4_if(b4_skeleton, ["yacc.c"],
|
||||
YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
|
||||
# endif
|
||||
]])dnl
|
||||
[ switch (yytype)
|
||||
{
|
||||
]b4_symbol_foreach([b4_symbol_printer])dnl
|
||||
[ default:
|
||||
break;
|
||||
}
|
||||
b4_symbol_actions([printer])[
|
||||
}
|
||||
|
||||
|
||||
@@ -492,28 +547,154 @@ b4_locations_if([, yylocationp])[]b4_user_args[);
|
||||
}]dnl
|
||||
])
|
||||
|
||||
|
||||
## ---------------- ##
|
||||
## api.value.type. ##
|
||||
## ---------------- ##
|
||||
|
||||
|
||||
# ---------------------- #
|
||||
# api.value.type=union. #
|
||||
# ---------------------- #
|
||||
|
||||
# b4_symbol_type_register(SYMBOL-NUM)
|
||||
# -----------------------------------
|
||||
# Symbol SYMBOL-NUM has a type (for variant) instead of a type-tag.
|
||||
# Extend the definition of %union's body with a field of that type,
|
||||
# and extend the symbol's "type" field to point to the field name,
|
||||
# instead of the type name.
|
||||
m4_define([b4_symbol_type_register],
|
||||
[m4_define([b4_symbol($1, type_tag)],
|
||||
[b4_symbol_if([$1], [has_id],
|
||||
[b4_symbol([$1], [id])],
|
||||
[yytype_[]b4_symbol([$1], [number])])])dnl
|
||||
m4_append([b4_user_union_members],
|
||||
m4_expand([
|
||||
b4_symbol_tag_comment([$1])dnl
|
||||
b4_symbol([$1], [type]) b4_symbol([$1], [type_tag]);]))
|
||||
])
|
||||
|
||||
|
||||
# b4_type_define_tag(SYMBOL1-NUM, ...)
|
||||
# ------------------------------------
|
||||
# For the batch of symbols SYMBOL1-NUM... (which all have the same
|
||||
# type), enhance the %union definition for each of them, and set
|
||||
# there "type" field to the field tag name, instead of the type name.
|
||||
m4_define([b4_type_define_tag],
|
||||
[b4_symbol_if([$1], [has_type],
|
||||
[m4_map([b4_symbol_type_register], [$@])])
|
||||
])
|
||||
|
||||
|
||||
# b4_symbol_value_union(VAL, [TYPE])
|
||||
# ----------------------------------
|
||||
# Same of b4_symbol_value, but when api.value.type=union.
|
||||
m4_define([b4_symbol_value_union],
|
||||
[m4_ifval([$2],
|
||||
[(*($2*)(&$1))],
|
||||
[$1])])
|
||||
])
|
||||
|
||||
|
||||
# b4_value_type_setup_union
|
||||
# -------------------------
|
||||
# Setup support for api.value.type=union. Symbols are defined with a
|
||||
# type instead of a union member name: build the corresponding union,
|
||||
# and give the symbols their tag.
|
||||
m4_define([b4_value_type_setup_union],
|
||||
[m4_define([b4_union_members])
|
||||
b4_type_foreach([b4_type_define_tag])
|
||||
m4_copy_force([b4_symbol_value_union], [b4_symbol_value])
|
||||
])
|
||||
|
||||
|
||||
# ---------------- #
|
||||
# api.value.type. #
|
||||
# ---------------- #
|
||||
|
||||
|
||||
# b4_value_type_setup_variant
|
||||
# ---------------------------
|
||||
# Setup support for api.value.type=variant. By default, fail, specialized
|
||||
# by other skeletons.
|
||||
m4_define([b4_value_type_setup_variant],
|
||||
[b4_complain_at(b4_percent_define_get_loc([[api.value.type]]),
|
||||
[['%s' does not support '%s']],
|
||||
[b4_skeleton],
|
||||
[%define api.value.type variant])])
|
||||
|
||||
|
||||
# _b4_value_type_setup_keyword
|
||||
# ----------------------------
|
||||
# api.value.type is defined with a keyword/string syntax. Check if
|
||||
# that is properly defined, and prepare its use.
|
||||
m4_define([_b4_value_type_setup_keyword],
|
||||
[b4_percent_define_check_values([[[[api.value.type]],
|
||||
[[none]],
|
||||
[[union]],
|
||||
[[union-directive]],
|
||||
[[variant]],
|
||||
[[yystype]]]])dnl
|
||||
m4_case(b4_percent_define_get([[api.value.type]]),
|
||||
[union], [b4_value_type_setup_union],
|
||||
[variant], [b4_value_type_setup_variant])])
|
||||
|
||||
|
||||
# b4_value_type_setup
|
||||
# -------------------
|
||||
# Check if api.value.type is properly defined, and possibly prepare
|
||||
# its use.
|
||||
b4_define_silent([b4_value_type_setup],
|
||||
[# Define default value.
|
||||
b4_percent_define_ifdef([[api.value.type]], [],
|
||||
[# %union => api.value.type=union-directive
|
||||
m4_ifdef([b4_union_members],
|
||||
[m4_define([b4_percent_define_kind(api.value.type)], [keyword])
|
||||
m4_define([b4_percent_define(api.value.type)], [union-directive])],
|
||||
[# no tag seen => api.value.type={int}
|
||||
m4_if(b4_tag_seen_flag, 0,
|
||||
[m4_define([b4_percent_define_kind(api.value.type)], [code])
|
||||
m4_define([b4_percent_define(api.value.type)], [int])],
|
||||
[# otherwise api.value.type=yystype
|
||||
m4_define([b4_percent_define_kind(api.value.type)], [keyword])
|
||||
m4_define([b4_percent_define(api.value.type)], [yystype])])])])
|
||||
|
||||
# Set up.
|
||||
m4_bmatch(b4_percent_define_get_kind([[api.value.type]]),
|
||||
[keyword\|string], [_b4_value_type_setup_keyword])
|
||||
])
|
||||
|
||||
|
||||
## -------------- ##
|
||||
## Declarations. ##
|
||||
## -------------- ##
|
||||
|
||||
|
||||
# b4_value_type_define
|
||||
# --------------------
|
||||
m4_define([b4_value_type_define],
|
||||
[[/* Value type. */
|
||||
#if ! defined ]b4_api_PREFIX[STYPE && ! defined ]b4_api_PREFIX[STYPE_IS_DECLARED
|
||||
]m4_ifdef([b4_stype],
|
||||
[[typedef union ]b4_union_name[ ]b4_api_PREFIX[STYPE;
|
||||
union ]b4_union_name[
|
||||
{
|
||||
]b4_user_stype[
|
||||
};
|
||||
# define ]b4_api_PREFIX[STYPE_IS_TRIVIAL 1]],
|
||||
[m4_if(b4_tag_seen_flag, 0,
|
||||
[[typedef int ]b4_api_PREFIX[STYPE;
|
||||
# define ]b4_api_PREFIX[STYPE_IS_TRIVIAL 1]])])[
|
||||
[b4_value_type_setup[]dnl
|
||||
/* Value type. */
|
||||
m4_bmatch(b4_percent_define_get_kind([[api.value.type]]),
|
||||
[code],
|
||||
[[#if ! defined ]b4_api_PREFIX[STYPE && ! defined ]b4_api_PREFIX[STYPE_IS_DECLARED
|
||||
typedef ]b4_percent_define_get([[api.value.type]])[ ]b4_api_PREFIX[STYPE;
|
||||
# define ]b4_api_PREFIX[STYPE_IS_TRIVIAL 1
|
||||
# define ]b4_api_PREFIX[STYPE_IS_DECLARED 1
|
||||
#endif
|
||||
]])
|
||||
]],
|
||||
[m4_bmatch(b4_percent_define_get([[api.value.type]]),
|
||||
[union\|union-directive],
|
||||
[[#if ! defined ]b4_api_PREFIX[STYPE && ! defined ]b4_api_PREFIX[STYPE_IS_DECLARED
|
||||
typedef union ]b4_union_name[ ]b4_api_PREFIX[STYPE;
|
||||
union ]b4_union_name[
|
||||
{
|
||||
]b4_user_union_members[
|
||||
};
|
||||
# define ]b4_api_PREFIX[STYPE_IS_TRIVIAL 1
|
||||
# define ]b4_api_PREFIX[STYPE_IS_DECLARED 1
|
||||
#endif
|
||||
]])])])
|
||||
|
||||
|
||||
# b4_location_type_define
|
||||
@@ -549,7 +730,7 @@ b4_pure_if([], [[extern ]b4_api_PREFIX[STYPE ]b4_prefix[lval;
|
||||
|
||||
|
||||
# b4_YYDEBUG_define
|
||||
# ------------------
|
||||
# -----------------
|
||||
m4_define([b4_YYDEBUG_define],
|
||||
[[/* Debug traces. */
|
||||
]m4_if(b4_api_prefix, [yy],
|
||||
@@ -621,7 +802,7 @@ m4_define([b4_yy_location_print_define],
|
||||
|
||||
/* Print *YYLOCP on YYO. Private, do not rely on its existence. */
|
||||
|
||||
__attribute__((__unused__))
|
||||
YY_ATTRIBUTE_UNUSED
|
||||
]b4_function_define([yy_location_print_],
|
||||
[static unsigned],
|
||||
[[FILE *yyo], [yyo]],
|
||||
|
||||
+82
-97
@@ -246,13 +246,6 @@ b4_percent_code_get[]dnl
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Suppress unused-variable warnings by "using" E. */
|
||||
#ifdef __GNUC__
|
||||
# define YYUSE(E) ((void) (E))
|
||||
#else
|
||||
# define YYUSE(E) /* empty */
|
||||
#endif
|
||||
|
||||
#ifndef YYFREE
|
||||
# define YYFREE free
|
||||
#endif
|
||||
@@ -281,17 +274,7 @@ b4_percent_code_get[]dnl
|
||||
# define YYLONGJMP(Env, Val) (longjmp (Env, Val), YYASSERT (0))
|
||||
#endif
|
||||
|
||||
/*-----------------.
|
||||
| GCC extensions. |
|
||||
`-----------------*/
|
||||
|
||||
#ifndef __attribute__
|
||||
/* This feature is available in gcc versions 2.5 and later. */
|
||||
# if (! defined __GNUC__ || __GNUC__ < 2 \
|
||||
|| (__GNUC__ == 2 && __GNUC_MINOR__ < 5))
|
||||
# define __attribute__(Spec) /* empty */
|
||||
# endif
|
||||
#endif
|
||||
]b4_attribute_define[
|
||||
|
||||
#ifndef YYASSERT
|
||||
# define YYASSERT(Condition) ((void) ((Condition) || (abort (), 0)))
|
||||
@@ -462,9 +445,9 @@ int yydebug;
|
||||
|
||||
struct yyGLRStack;
|
||||
static void yypstack (struct yyGLRStack* yystackp, size_t yyk)
|
||||
__attribute__ ((__unused__));
|
||||
YY_ATTRIBUTE_UNUSED;
|
||||
static void yypdumpstack (struct yyGLRStack* yystackp)
|
||||
__attribute__ ((__unused__));
|
||||
YY_ATTRIBUTE_UNUSED;
|
||||
|
||||
#else /* !]b4_api_PREFIX[DEBUG */
|
||||
|
||||
@@ -686,19 +669,15 @@ struct yyGLRStack {
|
||||
static void yyexpandGLRStack (yyGLRStack* yystackp);
|
||||
#endif
|
||||
|
||||
static void yyFail (yyGLRStack* yystackp]b4_pure_formals[, const char* yymsg)
|
||||
__attribute__ ((__noreturn__));
|
||||
static void
|
||||
static _Noreturn void
|
||||
yyFail (yyGLRStack* yystackp]b4_pure_formals[, const char* yymsg)
|
||||
{
|
||||
if (yymsg != YY_NULL)
|
||||
if (yymsg != YY_NULLPTR)
|
||||
yyerror (]b4_yyerror_args[yymsg);
|
||||
YYLONGJMP (yystackp->yyexception_buffer, 1);
|
||||
}
|
||||
|
||||
static void yyMemoryExhausted (yyGLRStack* yystackp)
|
||||
__attribute__ ((__noreturn__));
|
||||
static void
|
||||
static _Noreturn void
|
||||
yyMemoryExhausted (yyGLRStack* yystackp)
|
||||
{
|
||||
YYLONGJMP (yystackp->yyexception_buffer, 2);
|
||||
@@ -719,7 +698,7 @@ yytokenName (yySymbol yytoken)
|
||||
/** Fill in YYVSP[YYLOW1 .. YYLOW0-1] from the chain of states starting
|
||||
* at YYVSP[YYLOW0].yystate.yypred. Leaves YYVSP[YYLOW1].yystate.yypred
|
||||
* containing the pointer to the next state in the chain. */
|
||||
static void yyfillin (yyGLRStackItem *, int, int) __attribute__ ((__unused__));
|
||||
static void yyfillin (yyGLRStackItem *, int, int) YY_ATTRIBUTE_UNUSED;
|
||||
static void
|
||||
yyfillin (yyGLRStackItem *yyvsp, int yylow0, int yylow1)
|
||||
{
|
||||
@@ -736,7 +715,7 @@ yyfillin (yyGLRStackItem *yyvsp, int yylow0, int yylow1)
|
||||
else
|
||||
/* The effect of using yysval or yyloc (in an immediate rule) is
|
||||
* undefined. */
|
||||
yyvsp[i].yystate.yysemantics.yyfirstVal = YY_NULL;]b4_locations_if([[
|
||||
yyvsp[i].yystate.yysemantics.yyfirstVal = YY_NULLPTR;]b4_locations_if([[
|
||||
yyvsp[i].yystate.yyloc = s->yyloc;]])[
|
||||
s = yyvsp[i].yystate.yypred = s->yypred;
|
||||
}
|
||||
@@ -746,7 +725,7 @@ yyfillin (yyGLRStackItem *yyvsp, int yylow0, int yylow1)
|
||||
* YYVSP[YYLOW1 .. *YYLOW-1] as in yyfillin and set *YYLOW = YYLOW1.
|
||||
* For convenience, always return YYLOW1. */
|
||||
static inline int yyfill (yyGLRStackItem *, int *, int, yybool)
|
||||
__attribute__ ((__unused__));
|
||||
YY_ATTRIBUTE_UNUSED;
|
||||
static inline int
|
||||
yyfill (yyGLRStackItem *yyvsp, int *yylow, int yylow1, yybool yynormal)
|
||||
{
|
||||
@@ -768,8 +747,7 @@ yyuserAction (yyRuleNum yyn, size_t yyrhslen, yyGLRStackItem* yyvsp,
|
||||
yyGLRStack* yystackp,
|
||||
YYSTYPE* yyvalp]b4_locuser_formals[)
|
||||
{
|
||||
yybool yynormal __attribute__ ((__unused__)) =
|
||||
(yystackp->yysplitPoint == YY_NULL);
|
||||
yybool yynormal YY_ATTRIBUTE_UNUSED = (yystackp->yysplitPoint == YY_NULLPTR);
|
||||
int yylow;
|
||||
]b4_parse_param_use([yyvalp], [yylocp])dnl
|
||||
[ YYUSE (yyrhslen);
|
||||
@@ -853,12 +831,10 @@ yydestroyGLRState (char const *yymsg, yyGLRState *yys]b4_user_formals[)
|
||||
if (yydebug)
|
||||
{
|
||||
if (yys->yysemantics.yyfirstVal)
|
||||
YYFPRINTF (stderr, "%s unresolved ", yymsg);
|
||||
YYFPRINTF (stderr, "%s unresolved", yymsg);
|
||||
else
|
||||
YYFPRINTF (stderr, "%s incomplete ", yymsg);
|
||||
yy_symbol_print (stderr, yystos[yys->yylrState],
|
||||
YY_NULL]b4_locuser_args([&yys->yyloc])[);
|
||||
YYFPRINTF (stderr, "\n");
|
||||
YYFPRINTF (stderr, "%s incomplete", yymsg);
|
||||
YY_SYMBOL_PRINT ("", yystos[yys->yylrState], YY_NULLPTR, &yys->yyloc);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -934,14 +910,18 @@ yygetLRActions (yyStateNum yystate, int yytoken,
|
||||
}
|
||||
}
|
||||
|
||||
/** Compute post-reduction state.
|
||||
* \param yystate the current state
|
||||
* \param yysym the nonterminal to push on the stack
|
||||
*/
|
||||
static inline yyStateNum
|
||||
yyLRgotoState (yyStateNum yystate, yySymbol yylhs)
|
||||
yyLRgotoState (yyStateNum yystate, yySymbol yysym)
|
||||
{
|
||||
int yyr = yypgoto[yylhs - YYNTOKENS] + yystate;
|
||||
int yyr = yypgoto[yysym - YYNTOKENS] + yystate;
|
||||
if (0 <= yyr && yyr <= YYLAST && yycheck[yyr] == yystate)
|
||||
return yytable[yyr];
|
||||
else
|
||||
return yydefgoto[yylhs - YYNTOKENS];
|
||||
return yydefgoto[yysym - YYNTOKENS];
|
||||
}
|
||||
|
||||
static inline yybool
|
||||
@@ -983,6 +963,7 @@ yyaddDeferredAction (yyGLRStack* yystackp, size_t yyk, yyGLRState* yystate,
|
||||
{
|
||||
yySemanticOption* yynewOption =
|
||||
&yynewGLRStackItem (yystackp, yyfalse)->yyoption;
|
||||
YYASSERT (!yynewOption->yyisState);
|
||||
yynewOption->yystate = yyrhs;
|
||||
yynewOption->yyrule = yyrule;
|
||||
if (yystackp->yytops.yylookaheadNeeds[yyk])
|
||||
@@ -1010,7 +991,7 @@ yyinitStateSet (yyGLRStateSet* yyset)
|
||||
yyset->yystates = (yyGLRState**) YYMALLOC (16 * sizeof yyset->yystates[0]);
|
||||
if (! yyset->yystates)
|
||||
return yyfalse;
|
||||
yyset->yystates[0] = YY_NULL;
|
||||
yyset->yystates[0] = YY_NULLPTR;
|
||||
yyset->yylookaheadNeeds =
|
||||
(yybool*) YYMALLOC (16 * sizeof yyset->yylookaheadNeeds[0]);
|
||||
if (! yyset->yylookaheadNeeds)
|
||||
@@ -1040,8 +1021,8 @@ yyinitGLRStack (yyGLRStack* yystackp, size_t yysize)
|
||||
if (!yystackp->yyitems)
|
||||
return yyfalse;
|
||||
yystackp->yynextFree = yystackp->yyitems;
|
||||
yystackp->yysplitPoint = YY_NULL;
|
||||
yystackp->yylastDeleted = YY_NULL;
|
||||
yystackp->yysplitPoint = YY_NULLPTR;
|
||||
yystackp->yylastDeleted = YY_NULLPTR;
|
||||
return yyinitStateSet (&yystackp->yytops);
|
||||
}
|
||||
|
||||
@@ -1080,10 +1061,10 @@ yyexpandGLRStack (yyGLRStack* yystackp)
|
||||
{
|
||||
yyGLRState* yys0 = &yyp0->yystate;
|
||||
yyGLRState* yys1 = &yyp1->yystate;
|
||||
if (yys0->yypred != YY_NULL)
|
||||
if (yys0->yypred != YY_NULLPTR)
|
||||
yys1->yypred =
|
||||
YYRELOC (yyp0, yyp1, yys0->yypred, yystate);
|
||||
if (! yys0->yyresolved && yys0->yysemantics.yyfirstVal != YY_NULL)
|
||||
if (! yys0->yyresolved && yys0->yysemantics.yyfirstVal != YY_NULLPTR)
|
||||
yys1->yysemantics.yyfirstVal =
|
||||
YYRELOC (yyp0, yyp1, yys0->yysemantics.yyfirstVal, yyoption);
|
||||
}
|
||||
@@ -1091,18 +1072,18 @@ yyexpandGLRStack (yyGLRStack* yystackp)
|
||||
{
|
||||
yySemanticOption* yyv0 = &yyp0->yyoption;
|
||||
yySemanticOption* yyv1 = &yyp1->yyoption;
|
||||
if (yyv0->yystate != YY_NULL)
|
||||
if (yyv0->yystate != YY_NULLPTR)
|
||||
yyv1->yystate = YYRELOC (yyp0, yyp1, yyv0->yystate, yystate);
|
||||
if (yyv0->yynext != YY_NULL)
|
||||
if (yyv0->yynext != YY_NULLPTR)
|
||||
yyv1->yynext = YYRELOC (yyp0, yyp1, yyv0->yynext, yyoption);
|
||||
}
|
||||
}
|
||||
if (yystackp->yysplitPoint != YY_NULL)
|
||||
if (yystackp->yysplitPoint != YY_NULLPTR)
|
||||
yystackp->yysplitPoint = YYRELOC (yystackp->yyitems, yynewItems,
|
||||
yystackp->yysplitPoint, yystate);
|
||||
yystackp->yysplitPoint, yystate);
|
||||
|
||||
for (yyn = 0; yyn < yystackp->yytops.yysize; yyn += 1)
|
||||
if (yystackp->yytops.yystates[yyn] != YY_NULL)
|
||||
if (yystackp->yytops.yystates[yyn] != YY_NULLPTR)
|
||||
yystackp->yytops.yystates[yyn] =
|
||||
YYRELOC (yystackp->yyitems, yynewItems,
|
||||
yystackp->yytops.yystates[yyn], yystate);
|
||||
@@ -1126,7 +1107,7 @@ yyfreeGLRStack (yyGLRStack* yystackp)
|
||||
static inline void
|
||||
yyupdateSplit (yyGLRStack* yystackp, yyGLRState* yys)
|
||||
{
|
||||
if (yystackp->yysplitPoint != YY_NULL && yystackp->yysplitPoint > yys)
|
||||
if (yystackp->yysplitPoint != YY_NULLPTR && yystackp->yysplitPoint > yys)
|
||||
yystackp->yysplitPoint = yys;
|
||||
}
|
||||
|
||||
@@ -1134,9 +1115,9 @@ yyupdateSplit (yyGLRStack* yystackp, yyGLRState* yys)
|
||||
static inline void
|
||||
yymarkStackDeleted (yyGLRStack* yystackp, size_t yyk)
|
||||
{
|
||||
if (yystackp->yytops.yystates[yyk] != YY_NULL)
|
||||
if (yystackp->yytops.yystates[yyk] != YY_NULLPTR)
|
||||
yystackp->yylastDeleted = yystackp->yytops.yystates[yyk];
|
||||
yystackp->yytops.yystates[yyk] = YY_NULL;
|
||||
yystackp->yytops.yystates[yyk] = YY_NULLPTR;
|
||||
}
|
||||
|
||||
/** Undelete the last stack in *YYSTACKP that was marked as deleted. Can
|
||||
@@ -1145,12 +1126,12 @@ yymarkStackDeleted (yyGLRStack* yystackp, size_t yyk)
|
||||
static void
|
||||
yyundeleteLastStack (yyGLRStack* yystackp)
|
||||
{
|
||||
if (yystackp->yylastDeleted == YY_NULL || yystackp->yytops.yysize != 0)
|
||||
if (yystackp->yylastDeleted == YY_NULLPTR || yystackp->yytops.yysize != 0)
|
||||
return;
|
||||
yystackp->yytops.yystates[0] = yystackp->yylastDeleted;
|
||||
yystackp->yytops.yysize = 1;
|
||||
YYDPRINTF ((stderr, "Restoring last deleted stack as stack #0.\n"));
|
||||
yystackp->yylastDeleted = YY_NULL;
|
||||
yystackp->yylastDeleted = YY_NULLPTR;
|
||||
}
|
||||
|
||||
static inline void
|
||||
@@ -1160,7 +1141,7 @@ yyremoveDeletes (yyGLRStack* yystackp)
|
||||
yyi = yyj = 0;
|
||||
while (yyj < yystackp->yytops.yysize)
|
||||
{
|
||||
if (yystackp->yytops.yystates[yyi] == YY_NULL)
|
||||
if (yystackp->yytops.yystates[yyi] == YY_NULLPTR)
|
||||
{
|
||||
if (yyi == yyj)
|
||||
{
|
||||
@@ -1218,12 +1199,13 @@ yyglrShiftDefer (yyGLRStack* yystackp, size_t yyk, yyStateNum yylrState,
|
||||
size_t yyposn, yyGLRState* yyrhs, yyRuleNum yyrule)
|
||||
{
|
||||
yyGLRState* yynewState = &yynewGLRStackItem (yystackp, yytrue)->yystate;
|
||||
YYASSERT (yynewState->yyisState);
|
||||
|
||||
yynewState->yylrState = yylrState;
|
||||
yynewState->yyposn = yyposn;
|
||||
yynewState->yyresolved = yyfalse;
|
||||
yynewState->yypred = yystackp->yytops.yystates[yyk];
|
||||
yynewState->yysemantics.yyfirstVal = YY_NULL;
|
||||
yynewState->yysemantics.yyfirstVal = YY_NULLPTR;
|
||||
yystackp->yytops.yystates[yyk] = yynewState;
|
||||
|
||||
/* Invokes YY_RESERVE_GLRSTACK. */
|
||||
@@ -1283,7 +1265,7 @@ yydoAction (yyGLRStack* yystackp, size_t yyk, yyRuleNum yyrule,
|
||||
{
|
||||
int yynrhs = yyrhsLength (yyrule);
|
||||
|
||||
if (yystackp->yysplitPoint == YY_NULL)
|
||||
if (yystackp->yysplitPoint == YY_NULLPTR)
|
||||
{
|
||||
/* Standard special case: single stack. */
|
||||
yyGLRStackItem* yyrhs = (yyGLRStackItem*) yystackp->yytops.yystates[yyk];
|
||||
@@ -1335,14 +1317,13 @@ yyglrReduce (yyGLRStack* yystackp, size_t yyk, yyRuleNum yyrule,
|
||||
{
|
||||
size_t yyposn = yystackp->yytops.yystates[yyk]->yyposn;
|
||||
|
||||
if (yyforceEval || yystackp->yysplitPoint == YY_NULL)
|
||||
if (yyforceEval || yystackp->yysplitPoint == YY_NULLPTR)
|
||||
{
|
||||
YYRESULTTAG yyflag;
|
||||
YYSTYPE yysval;]b4_locations_if([
|
||||
YYLTYPE yyloc;])[
|
||||
YYSTYPE yysval;]b4_locations_if([[
|
||||
YYLTYPE yyloc;]])[
|
||||
|
||||
yyflag = yydoAction (yystackp, yyk, yyrule, &yysval]b4_locuser_args([&yyloc])[);
|
||||
if (yyflag == yyerr && yystackp->yysplitPoint != YY_NULL)
|
||||
YYRESULTTAG yyflag = yydoAction (yystackp, yyk, yyrule, &yysval]b4_locuser_args([&yyloc])[);
|
||||
if (yyflag == yyerr && yystackp->yysplitPoint != YY_NULLPTR)
|
||||
{
|
||||
YYDPRINTF ((stderr, "Parse on stack %lu rejected by rule #%d.\n",
|
||||
(unsigned long int) yyk, yyrule - 1));
|
||||
@@ -1375,7 +1356,7 @@ yyglrReduce (yyGLRStack* yystackp, size_t yyk, yyRuleNum yyrule,
|
||||
"Now in state %d.\n",
|
||||
(unsigned long int) yyk, yyrule - 1, yynewLRState));
|
||||
for (yyi = 0; yyi < yystackp->yytops.yysize; yyi += 1)
|
||||
if (yyi != yyk && yystackp->yytops.yystates[yyi] != YY_NULL)
|
||||
if (yyi != yyk && yystackp->yytops.yystates[yyi] != YY_NULLPTR)
|
||||
{
|
||||
yyGLRState *yysplit = yystackp->yysplitPoint;
|
||||
yyGLRState *yyp = yystackp->yytops.yystates[yyi];
|
||||
@@ -1402,7 +1383,7 @@ yyglrReduce (yyGLRStack* yystackp, size_t yyk, yyRuleNum yyrule,
|
||||
static size_t
|
||||
yysplitStack (yyGLRStack* yystackp, size_t yyk)
|
||||
{
|
||||
if (yystackp->yysplitPoint == YY_NULL)
|
||||
if (yystackp->yysplitPoint == YY_NULLPTR)
|
||||
{
|
||||
YYASSERT (yyk == 0);
|
||||
yystackp->yysplitPoint = yystackp->yytops.yystates[yyk];
|
||||
@@ -1412,7 +1393,7 @@ yysplitStack (yyGLRStack* yystackp, size_t yyk)
|
||||
yyGLRState** yynewStates;
|
||||
yybool* yynewLookaheadNeeds;
|
||||
|
||||
yynewStates = YY_NULL;
|
||||
yynewStates = YY_NULLPTR;
|
||||
|
||||
if (yystackp->yytops.yycapacity
|
||||
> (YYSIZEMAX / (2 * sizeof yynewStates[0])))
|
||||
@@ -1423,7 +1404,7 @@ yysplitStack (yyGLRStack* yystackp, size_t yyk)
|
||||
(yyGLRState**) YYREALLOC (yystackp->yytops.yystates,
|
||||
(yystackp->yytops.yycapacity
|
||||
* sizeof yynewStates[0]));
|
||||
if (yynewStates == YY_NULL)
|
||||
if (yynewStates == YY_NULLPTR)
|
||||
yyMemoryExhausted (yystackp);
|
||||
yystackp->yytops.yystates = yynewStates;
|
||||
|
||||
@@ -1431,7 +1412,7 @@ yysplitStack (yyGLRStack* yystackp, size_t yyk)
|
||||
(yybool*) YYREALLOC (yystackp->yytops.yylookaheadNeeds,
|
||||
(yystackp->yytops.yycapacity
|
||||
* sizeof yynewLookaheadNeeds[0]));
|
||||
if (yynewLookaheadNeeds == YY_NULL)
|
||||
if (yynewLookaheadNeeds == YY_NULLPTR)
|
||||
yyMemoryExhausted (yystackp);
|
||||
yystackp->yytops.yylookaheadNeeds = yynewLookaheadNeeds;
|
||||
}
|
||||
@@ -1495,9 +1476,9 @@ yymergeOptionSets (yySemanticOption* yyy0, yySemanticOption* yyy1)
|
||||
yySemanticOption* yyz1 = yys1->yysemantics.yyfirstVal;
|
||||
while (yytrue)
|
||||
{
|
||||
if (yyz1 == *yyz0p || yyz1 == YY_NULL)
|
||||
if (yyz1 == *yyz0p || yyz1 == YY_NULLPTR)
|
||||
break;
|
||||
else if (*yyz0p == YY_NULL)
|
||||
else if (*yyz0p == YY_NULLPTR)
|
||||
{
|
||||
*yyz0p = yyz1;
|
||||
break;
|
||||
@@ -1618,7 +1599,7 @@ yyreportTree (yySemanticOption* yyx, int yyindent)
|
||||
|
||||
for (yyi = yynrhs, yys = yyx->yystate; 0 < yyi; yyi -= 1, yys = yys->yypred)
|
||||
yystates[yyi] = yys;
|
||||
if (yys == YY_NULL)
|
||||
if (yys == YY_NULLPTR)
|
||||
{
|
||||
yyleftmost_state.yyposn = 0;
|
||||
yystates[0] = &yyleftmost_state;
|
||||
@@ -1689,7 +1670,7 @@ yyresolveLocations (yyGLRState* yys1, int yyn1,
|
||||
yyGLRStackItem yyrhsloc[1 + YYMAXRHS];
|
||||
int yynrhs;
|
||||
yySemanticOption *yyoption = yys1->yysemantics.yyfirstVal;
|
||||
YYASSERT (yyoption != YY_NULL);
|
||||
YYASSERT (yyoption != YY_NULLPTR);
|
||||
yynrhs = yyrhsLength (yyoption->yyrule);
|
||||
if (yynrhs > 0)
|
||||
{
|
||||
@@ -1748,7 +1729,7 @@ yyresolveValue (yyGLRState* yys, yyGLRStack* yystackp]b4_user_formals[)
|
||||
YYRESULTTAG yyflag;]b4_locations_if([
|
||||
YYLTYPE *yylocp = &yys->yyloc;])[
|
||||
|
||||
for (yypp = &yyoptionList->yynext; *yypp != YY_NULL; )
|
||||
for (yypp = &yyoptionList->yynext; *yypp != YY_NULLPTR; )
|
||||
{
|
||||
yySemanticOption* yyp = *yypp;
|
||||
|
||||
@@ -1790,7 +1771,7 @@ yyresolveValue (yyGLRState* yys, yyGLRStack* yystackp]b4_user_formals[)
|
||||
int yyprec = yydprec[yybest->yyrule];
|
||||
yyflag = yyresolveAction (yybest, yystackp, &yysval]b4_locuser_args[);
|
||||
if (yyflag == yyok)
|
||||
for (yyp = yybest->yynext; yyp != YY_NULL; yyp = yyp->yynext)
|
||||
for (yyp = yybest->yynext; yyp != YY_NULLPTR; yyp = yyp->yynext)
|
||||
{
|
||||
if (yyprec == yydprec[yyp->yyrule])
|
||||
{
|
||||
@@ -1817,14 +1798,14 @@ yyresolveValue (yyGLRState* yys, yyGLRStack* yystackp]b4_user_formals[)
|
||||
yys->yysemantics.yysval = yysval;
|
||||
}
|
||||
else
|
||||
yys->yysemantics.yyfirstVal = YY_NULL;
|
||||
yys->yysemantics.yyfirstVal = YY_NULLPTR;
|
||||
return yyflag;
|
||||
}
|
||||
|
||||
static YYRESULTTAG
|
||||
yyresolveStack (yyGLRStack* yystackp]b4_user_formals[)
|
||||
{
|
||||
if (yystackp->yysplitPoint != YY_NULL)
|
||||
if (yystackp->yysplitPoint != YY_NULLPTR)
|
||||
{
|
||||
yyGLRState* yys;
|
||||
int yyn;
|
||||
@@ -1844,10 +1825,10 @@ yycompressStack (yyGLRStack* yystackp)
|
||||
{
|
||||
yyGLRState* yyp, *yyq, *yyr;
|
||||
|
||||
if (yystackp->yytops.yysize != 1 || yystackp->yysplitPoint == YY_NULL)
|
||||
if (yystackp->yytops.yysize != 1 || yystackp->yysplitPoint == YY_NULLPTR)
|
||||
return;
|
||||
|
||||
for (yyp = yystackp->yytops.yystates[0], yyq = yyp->yypred, yyr = YY_NULL;
|
||||
for (yyp = yystackp->yytops.yystates[0], yyq = yyp->yypred, yyr = YY_NULLPTR;
|
||||
yyp != yystackp->yysplitPoint;
|
||||
yyr = yyp, yyp = yyq, yyq = yyp->yypred)
|
||||
yyp->yypred = yyr;
|
||||
@@ -1855,10 +1836,10 @@ yycompressStack (yyGLRStack* yystackp)
|
||||
yystackp->yyspaceLeft += yystackp->yynextFree - yystackp->yyitems;
|
||||
yystackp->yynextFree = ((yyGLRStackItem*) yystackp->yysplitPoint) + 1;
|
||||
yystackp->yyspaceLeft -= yystackp->yynextFree - yystackp->yyitems;
|
||||
yystackp->yysplitPoint = YY_NULL;
|
||||
yystackp->yylastDeleted = YY_NULL;
|
||||
yystackp->yysplitPoint = YY_NULLPTR;
|
||||
yystackp->yylastDeleted = YY_NULLPTR;
|
||||
|
||||
while (yyr != YY_NULL)
|
||||
while (yyr != YY_NULLPTR)
|
||||
{
|
||||
yystackp->yynextFree->yystate = *yyr;
|
||||
yyr = yyr->yypred;
|
||||
@@ -1873,7 +1854,7 @@ static YYRESULTTAG
|
||||
yyprocessOneStack (yyGLRStack* yystackp, size_t yyk,
|
||||
size_t yyposn]b4_pure_formals[)
|
||||
{
|
||||
while (yystackp->yytops.yystates[yyk] != YY_NULL)
|
||||
while (yystackp->yytops.yystates[yyk] != YY_NULLPTR)
|
||||
{
|
||||
yyStateNum yystate = yystackp->yytops.yystates[yyk]->yylrState;
|
||||
YYDPRINTF ((stderr, "Stack %lu Entering state %d\n",
|
||||
@@ -1995,13 +1976,13 @@ yyreportSyntaxError (yyGLRStack* yystackp]b4_user_formals[)
|
||||
#else
|
||||
{
|
||||
yySymbol yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar);
|
||||
size_t yysize0 = yytnamerr (YY_NULL, yytokenName (yytoken));
|
||||
size_t yysize0 = yytnamerr (YY_NULLPTR, yytokenName (yytoken));
|
||||
size_t yysize = yysize0;
|
||||
yybool yysize_overflow = yyfalse;
|
||||
char* yymsg = YY_NULL;
|
||||
char* yymsg = YY_NULLPTR;
|
||||
enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
|
||||
/* Internationalized format string. */
|
||||
const char *yyformat = YY_NULL;
|
||||
const char *yyformat = YY_NULLPTR;
|
||||
/* Arguments of yyformat. */
|
||||
char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
|
||||
/* Number of reported tokens (one for the "unexpected", one per
|
||||
@@ -2057,7 +2038,7 @@ yyreportSyntaxError (yyGLRStack* yystackp]b4_user_formals[)
|
||||
}
|
||||
yyarg[yycount++] = yytokenName (yyx);
|
||||
{
|
||||
size_t yysz = yysize + yytnamerr (YY_NULL, yytokenName (yyx));
|
||||
size_t yysz = yysize + yytnamerr (YY_NULLPTR, yytokenName (yyx));
|
||||
yysize_overflow |= yysz < yysize;
|
||||
yysize = yysz;
|
||||
}
|
||||
@@ -2135,7 +2116,7 @@ yyrecoverSyntaxError (yyGLRStack* yystackp]b4_user_formals[)
|
||||
{
|
||||
yySymbol yytoken;
|
||||
if (yychar == YYEOF)
|
||||
yyFail (yystackp][]b4_lpure_args[, YY_NULL);
|
||||
yyFail (yystackp][]b4_lpure_args[, YY_NULLPTR);
|
||||
if (yychar != YYEMPTY)
|
||||
{]b4_locations_if([[
|
||||
/* We throw away the lookahead, but the error range
|
||||
@@ -2176,10 +2157,10 @@ yyrecoverSyntaxError (yyGLRStack* yystackp]b4_user_formals[)
|
||||
|
||||
/* Reduce to one stack. */
|
||||
for (yyk = 0; yyk < yystackp->yytops.yysize; yyk += 1)
|
||||
if (yystackp->yytops.yystates[yyk] != YY_NULL)
|
||||
if (yystackp->yytops.yystates[yyk] != YY_NULLPTR)
|
||||
break;
|
||||
if (yyk >= yystackp->yytops.yysize)
|
||||
yyFail (yystackp][]b4_lpure_args[, YY_NULL);
|
||||
yyFail (yystackp][]b4_lpure_args[, YY_NULLPTR);
|
||||
for (yyk += 1; yyk < yystackp->yytops.yysize; yyk += 1)
|
||||
yymarkStackDeleted (yystackp, yyk);
|
||||
yyremoveDeletes (yystackp);
|
||||
@@ -2187,7 +2168,7 @@ yyrecoverSyntaxError (yyGLRStack* yystackp]b4_user_formals[)
|
||||
|
||||
/* Now pop stack until we find a state that shifts the error token. */
|
||||
yystackp->yyerrState = 3;
|
||||
while (yystackp->yytops.yystates[0] != YY_NULL)
|
||||
while (yystackp->yytops.yystates[0] != YY_NULLPTR)
|
||||
{
|
||||
yyGLRState *yys = yystackp->yytops.yystates[0];
|
||||
yyj = yypact[yys->yylrState];
|
||||
@@ -2211,14 +2192,14 @@ yyrecoverSyntaxError (yyGLRStack* yystackp]b4_user_formals[)
|
||||
}
|
||||
}]b4_locations_if([[
|
||||
yystackp->yyerror_range[1].yystate.yyloc = yys->yyloc;]])[
|
||||
if (yys->yypred != YY_NULL)
|
||||
if (yys->yypred != YY_NULLPTR)
|
||||
yydestroyGLRState ("Error: popping", yys]b4_user_args[);
|
||||
yystackp->yytops.yystates[0] = yys->yypred;
|
||||
yystackp->yynextFree -= 1;
|
||||
yystackp->yyspaceLeft += 1;
|
||||
}
|
||||
if (yystackp->yytops.yystates[0] == YY_NULL)
|
||||
yyFail (yystackp][]b4_lpure_args[, YY_NULL);
|
||||
if (yystackp->yytops.yystates[0] == YY_NULLPTR)
|
||||
yyFail (yystackp][]b4_lpure_args[, YY_NULLPTR);
|
||||
}
|
||||
|
||||
#define YYCHK1(YYE) \
|
||||
@@ -2461,7 +2442,7 @@ b4_dollar_popdef])[]dnl
|
||||
{
|
||||
yyGLRState *yys = yystates[yyk];
|
||||
]b4_locations_if([[ yystack.yyerror_range[1].yystate.yyloc = yys->yyloc;]]
|
||||
)[ if (yys->yypred != YY_NULL)
|
||||
)[ if (yys->yypred != YY_NULLPTR)
|
||||
yydestroyGLRState ("Cleanup: popping", yys]b4_user_args[);
|
||||
yystates[yyk] = yys->yypred;
|
||||
yystack.yynextFree -= 1;
|
||||
@@ -2493,7 +2474,7 @@ yy_yypstack (yyGLRState* yys)
|
||||
static void
|
||||
yypstates (yyGLRState* yyst)
|
||||
{
|
||||
if (yyst == YY_NULL)
|
||||
if (yyst == YY_NULLPTR)
|
||||
YYFPRINTF (stderr, "<null>");
|
||||
else
|
||||
yy_yypstack (yyst);
|
||||
@@ -2507,7 +2488,7 @@ yypstack (yyGLRStack* yystackp, size_t yyk)
|
||||
}
|
||||
|
||||
#define YYINDEX(YYX) \
|
||||
((YYX) == YY_NULL ? -1 : (yyGLRStackItem*) (YYX) - yystackp->yyitems)
|
||||
((YYX) == YY_NULLPTR ? -1 : (yyGLRStackItem*) (YYX) - yystackp->yyitems)
|
||||
|
||||
|
||||
static void
|
||||
@@ -2521,6 +2502,8 @@ yypdumpstack (yyGLRStack* yystackp)
|
||||
(unsigned long int) (yyp - yystackp->yyitems));
|
||||
if (*(yybool *) yyp)
|
||||
{
|
||||
YYASSERT (yyp->yystate.yyisState);
|
||||
YYASSERT (yyp->yyoption.yyisState);
|
||||
YYFPRINTF (stderr, "Res: %d, LR State: %d, posn: %lu, pred: %ld",
|
||||
yyp->yystate.yyresolved, yyp->yystate.yylrState,
|
||||
(unsigned long int) yyp->yystate.yyposn,
|
||||
@@ -2532,6 +2515,8 @@ yypdumpstack (yyGLRStack* yystackp)
|
||||
}
|
||||
else
|
||||
{
|
||||
YYASSERT (!yyp->yystate.yyisState);
|
||||
YYASSERT (!yyp->yyoption.yyisState);
|
||||
YYFPRINTF (stderr, "Option. rule: %d, state: %ld, next: %ld",
|
||||
yyp->yyoption.yyrule - 1,
|
||||
(long int) YYINDEX (yyp->yyoption.yystate),
|
||||
|
||||
+1
-12
@@ -43,12 +43,6 @@
|
||||
# user must initialize the first positions (in particular the
|
||||
# filename member).
|
||||
|
||||
b4_token_ctor_if([b4_variant_if([],
|
||||
[b4_fatal_at(b4_percent_define_get_loc(api.token.constructor),
|
||||
[cannot use '%s' without '%s'],
|
||||
[%define api.token.constructor],
|
||||
[%define api.value.type variant]))])])
|
||||
|
||||
# We require a pure interface.
|
||||
m4_define([b4_pure_flag], [1])
|
||||
|
||||
@@ -193,12 +187,7 @@ m4_pushdef([b4_parse_param], m4_defn([b4_parse_param_orig]))dnl
|
||||
std::ostream& yyoutput = debug_stream ();
|
||||
std::ostream& yyo = yyoutput;
|
||||
YYUSE (yyo);
|
||||
switch (yytype)
|
||||
{
|
||||
]b4_symbol_foreach([b4_symbol_printer])dnl
|
||||
[ default:
|
||||
break;
|
||||
}
|
||||
]b4_symbol_actions([printer])[
|
||||
}
|
||||
|
||||
|
||||
|
||||
+17
-1
@@ -103,7 +103,7 @@ m4_define([b4_int_type],
|
||||
# b4_int_type_for(NAME)
|
||||
# ---------------------
|
||||
# Return the smallest int type able to handle numbers ranging from
|
||||
# `NAME_min' to `NAME_max' (included).
|
||||
# 'NAME_min' to 'NAME_max' (included).
|
||||
m4_define([b4_int_type_for],
|
||||
[b4_int_type($1_min, $1_max)])
|
||||
|
||||
@@ -169,6 +169,22 @@ m4_define([b4_predicate_case], [ case $1:
|
||||
])
|
||||
|
||||
|
||||
## -------- ##
|
||||
## Checks. ##
|
||||
## -------- ##
|
||||
|
||||
b4_percent_define_check_kind([[api.value.type]], [code], [deprecated])
|
||||
|
||||
b4_percent_define_check_kind([[annotations]], [code], [deprecated])
|
||||
b4_percent_define_check_kind([[extends]], [code], [deprecated])
|
||||
b4_percent_define_check_kind([[implements]], [code], [deprecated])
|
||||
b4_percent_define_check_kind([[init_throws]], [code], [deprecated])
|
||||
b4_percent_define_check_kind([[lex_throws]], [code], [deprecated])
|
||||
b4_percent_define_check_kind([[parser_class_name]], [code], [deprecated])
|
||||
b4_percent_define_check_kind([[throws]], [code], [deprecated])
|
||||
|
||||
|
||||
|
||||
## ---------------- ##
|
||||
## Default values. ##
|
||||
## ---------------- ##
|
||||
|
||||
+75
-80
@@ -17,6 +17,8 @@
|
||||
|
||||
m4_include(b4_pkgdatadir/[c++.m4])
|
||||
|
||||
# api.value.type=variant is valid.
|
||||
m4_define([b4_value_type_setup_variant])
|
||||
|
||||
# b4_integral_parser_table_declare(TABLE-NAME, CONTENT, COMMENT)
|
||||
# --------------------------------------------------------------
|
||||
@@ -38,13 +40,14 @@ m4_define([b4_integral_parser_table_define],
|
||||
};dnl
|
||||
])
|
||||
|
||||
|
||||
# b4_symbol_value_template(VAL, [TYPE])
|
||||
# -------------------------------------
|
||||
# Same as b4_symbol_value, but used in a template method. It makes
|
||||
# a difference when using variants.
|
||||
# a difference when using variants. Note that b4_value_type_setup_union
|
||||
# overrides b4_symbol_value, so we must override it again.
|
||||
m4_copy([b4_symbol_value], [b4_symbol_value_template])
|
||||
|
||||
m4_append([b4_value_type_setup_union],
|
||||
[m4_copy_force([b4_symbol_value_union], [b4_symbol_value_template])])
|
||||
|
||||
# b4_lhs_value([TYPE])
|
||||
# --------------------
|
||||
@@ -154,6 +157,7 @@ m4_define([b4_shared_declarations],
|
||||
]b4_bison_locations_if([[# include "location.hh"]])])[
|
||||
]b4_variant_if([b4_variant_includes])[
|
||||
|
||||
]b4_attribute_define[
|
||||
]b4_YYDEBUG_define[
|
||||
|
||||
]b4_namespace_open[
|
||||
@@ -180,14 +184,14 @@ b4_location_define])])[
|
||||
|
||||
#if ]b4_api_PREFIX[DEBUG
|
||||
/// The current debugging stream.
|
||||
std::ostream& debug_stream () const;
|
||||
std::ostream& debug_stream () const YY_ATTRIBUTE_PURE;
|
||||
/// Set the current debugging stream.
|
||||
void set_debug_stream (std::ostream &);
|
||||
|
||||
/// Type for debugging levels.
|
||||
typedef int debug_level_type;
|
||||
/// The current debugging level.
|
||||
debug_level_type debug_level () const;
|
||||
debug_level_type debug_level () const YY_ATTRIBUTE_PURE;
|
||||
/// Set the current debugging level.
|
||||
void set_debug_level (debug_level_type l);
|
||||
#endif
|
||||
@@ -201,6 +205,10 @@ b4_location_define])])[
|
||||
void error (const syntax_error& err);
|
||||
|
||||
private:
|
||||
/// This class is not copyable.
|
||||
]b4_parser_class_name[ (const ]b4_parser_class_name[&);
|
||||
]b4_parser_class_name[& operator= (const ]b4_parser_class_name[&);
|
||||
|
||||
/// State numbers.
|
||||
typedef int state_type;
|
||||
|
||||
@@ -212,8 +220,8 @@ b4_location_define])])[
|
||||
|
||||
/// Compute post-reduction state.
|
||||
/// \param yystate the current state
|
||||
/// \param yylhs the nonterminal to push on the stack
|
||||
state_type yy_lr_goto_state_ (state_type yystate, int yylhs);
|
||||
/// \param yysym the nonterminal to push on the stack
|
||||
state_type yy_lr_goto_state_ (state_type yystate, int yysym);
|
||||
|
||||
/// Whether the given \c yypact_ value indicates a defaulted state.
|
||||
/// \param yyvalue the value to check
|
||||
@@ -260,7 +268,7 @@ b4_location_define])])[
|
||||
/// \brief Reclaim the memory associated to a symbol.
|
||||
/// \param yymsg Why this token is reclaimed.
|
||||
/// If null, print nothing.
|
||||
/// \param s The symbol.
|
||||
/// \param yysym The symbol.
|
||||
template <typename Base>
|
||||
void yy_destroy_ (const char* yymsg, basic_symbol<Base>& yysym) const;
|
||||
|
||||
@@ -334,13 +342,13 @@ b4_location_define])])[
|
||||
enum
|
||||
{
|
||||
yyeof_ = 0,
|
||||
yylast_ = ]b4_last[, //< Last index in yytable_.
|
||||
yynnts_ = ]b4_nterms_number[, //< Number of nonterminal symbols.
|
||||
yylast_ = ]b4_last[, ///< Last index in yytable_.
|
||||
yynnts_ = ]b4_nterms_number[, ///< Number of nonterminal symbols.
|
||||
yyempty_ = -2,
|
||||
yyfinal_ = ]b4_final_state_number[, //< Termination state number.
|
||||
yyfinal_ = ]b4_final_state_number[, ///< Termination state number.
|
||||
yyterror_ = 1,
|
||||
yyerrcode_ = 256,
|
||||
yyntokens_ = ]b4_tokens_number[ //< Number of tokens.
|
||||
yyntokens_ = ]b4_tokens_number[ ///< Number of tokens.
|
||||
};
|
||||
|
||||
]b4_parse_param_vars[
|
||||
@@ -591,13 +599,7 @@ m4_if(b4_prefix, [yy], [],
|
||||
YY_SYMBOL_PRINT (yymsg, yysym);]b4_variant_if([], [
|
||||
|
||||
// User destructor.
|
||||
symbol_number_type yytype = yysym.type_get ();
|
||||
switch (yytype)
|
||||
{
|
||||
]b4_symbol_foreach([b4_symbol_destructor])dnl
|
||||
[ default:
|
||||
break;
|
||||
}])[
|
||||
b4_symbol_actions([destructor], [yysym.type_get ()])])[
|
||||
}
|
||||
|
||||
#if ]b4_api_PREFIX[DEBUG
|
||||
@@ -612,12 +614,7 @@ m4_if(b4_prefix, [yy], [],
|
||||
yyo << (yytype < yyntokens_ ? "token" : "nterm")
|
||||
<< ' ' << yytname_[yytype] << " ("]b4_locations_if([
|
||||
<< yysym.location << ": "])[;
|
||||
switch (yytype)
|
||||
{
|
||||
]b4_symbol_foreach([b4_symbol_printer])dnl
|
||||
[ default:
|
||||
break;
|
||||
}
|
||||
]b4_symbol_actions([printer])[
|
||||
yyo << ')';
|
||||
}
|
||||
#endif
|
||||
@@ -674,13 +671,13 @@ m4_if(b4_prefix, [yy], [],
|
||||
#endif // ]b4_api_PREFIX[DEBUG
|
||||
|
||||
inline ]b4_parser_class_name[::state_type
|
||||
]b4_parser_class_name[::yy_lr_goto_state_ (state_type yystate, int yylhs)
|
||||
]b4_parser_class_name[::yy_lr_goto_state_ (state_type yystate, int yysym)
|
||||
{
|
||||
int yyr = yypgoto_[yylhs - yyntokens_] + yystate;
|
||||
int yyr = yypgoto_[yysym - yyntokens_] + yystate;
|
||||
if (0 <= yyr && yyr <= yylast_ && yycheck_[yyr] == yystate)
|
||||
return yytable_[yyr];
|
||||
else
|
||||
return yydefgoto_[yylhs - yyntokens_];
|
||||
return yydefgoto_[yysym - yyntokens_];
|
||||
}
|
||||
|
||||
inline bool
|
||||
@@ -703,6 +700,7 @@ m4_if(b4_prefix, [yy], [],
|
||||
|
||||
// State.
|
||||
int yyn;
|
||||
/// Length of the RHS of the rule being reduced.
|
||||
int yylen = 0;
|
||||
|
||||
// Error handling.
|
||||
@@ -715,9 +713,6 @@ m4_if(b4_prefix, [yy], [],
|
||||
/// The locations where the error started and ended.
|
||||
stack_symbol_type yyerror_range[3];]])[
|
||||
|
||||
/// $$ and @@$.
|
||||
stack_symbol_type yylhs;
|
||||
|
||||
/// The return value of parse ().
|
||||
int yyresult;
|
||||
|
||||
@@ -737,8 +732,8 @@ b4_dollar_popdef])[]dnl
|
||||
yynewstate, since the latter expects the semantical and the
|
||||
location values to have been already stored, initialize these
|
||||
stacks with a primary value. */
|
||||
yystack_ = stack_type (0);
|
||||
yypush_ (YY_NULL, 0, yyla);
|
||||
yystack_.clear ();
|
||||
yypush_ (YY_NULLPTR, 0, yyla);
|
||||
|
||||
// A new symbol was pushed on the stack.
|
||||
yynewstate:
|
||||
@@ -818,52 +813,55 @@ b4_dollar_popdef])[]dnl
|
||||
`-----------------------------*/
|
||||
yyreduce:
|
||||
yylen = yyr2_[yyn];
|
||||
yylhs.state = yy_lr_goto_state_(yystack_[yylen].state, yyr1_[yyn]);]b4_variant_if([
|
||||
/* Variants are always initialized to an empty instance of the
|
||||
correct type. The default $$=$1 action is NOT applied when using
|
||||
variants. */
|
||||
b4_symbol_variant([[yyr1_@{yyn@}]], [yylhs.value], [build])],[
|
||||
/* If YYLEN is nonzero, implement the default value of the action:
|
||||
`$$ = $1'. Otherwise, use the top of the stack.
|
||||
{
|
||||
stack_symbol_type yylhs;
|
||||
yylhs.state = yy_lr_goto_state_(yystack_[yylen].state, yyr1_[yyn]);]b4_variant_if([
|
||||
/* Variants are always initialized to an empty instance of the
|
||||
correct type. The default '$$ = $1' action is NOT applied
|
||||
when using variants. */
|
||||
b4_symbol_variant([[yyr1_@{yyn@}]], [yylhs.value], [build])], [
|
||||
/* If YYLEN is nonzero, implement the default value of the
|
||||
action: '$$ = $1'. Otherwise, use the top of the stack.
|
||||
|
||||
Otherwise, the following line sets YYLHS.VALUE to garbage.
|
||||
This behavior is undocumented and Bison
|
||||
users should not rely upon it. */
|
||||
if (yylen)
|
||||
yylhs.value = yystack_@{yylen - 1@}.value;
|
||||
else
|
||||
yylhs.value = yystack_@{0@}.value;])[
|
||||
Otherwise, the following line sets YYLHS.VALUE to garbage.
|
||||
This behavior is undocumented and Bison users should not rely
|
||||
upon it. */
|
||||
if (yylen)
|
||||
yylhs.value = yystack_@{yylen - 1@}.value;
|
||||
else
|
||||
yylhs.value = yystack_@{0@}.value;])[
|
||||
]b4_locations_if([dnl
|
||||
[
|
||||
// Compute the default @@$.
|
||||
{
|
||||
slice<stack_symbol_type, stack_type> slice (yystack_, yylen);
|
||||
YYLLOC_DEFAULT (yylhs.location, slice, yylen);
|
||||
}]])[
|
||||
|
||||
// Perform the reduction.
|
||||
YY_REDUCE_PRINT (yyn);
|
||||
try
|
||||
// Compute the default @@$.
|
||||
{
|
||||
switch (yyn)
|
||||
{
|
||||
slice<stack_symbol_type, stack_type> slice (yystack_, yylen);
|
||||
YYLLOC_DEFAULT (yylhs.location, slice, yylen);
|
||||
}]])[
|
||||
|
||||
// Perform the reduction.
|
||||
YY_REDUCE_PRINT (yyn);
|
||||
try
|
||||
{
|
||||
switch (yyn)
|
||||
{
|
||||
]b4_user_actions[
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (const syntax_error& yyexc)
|
||||
{
|
||||
error (yyexc);
|
||||
YYERROR;
|
||||
}
|
||||
YY_SYMBOL_PRINT ("-> $$ =", yylhs);
|
||||
yypop_ (yylen);
|
||||
yylen = 0;
|
||||
YY_STACK_PRINT ();
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (const syntax_error& yyexc)
|
||||
{
|
||||
error (yyexc);
|
||||
YYERROR;
|
||||
}
|
||||
YY_SYMBOL_PRINT ("-> $$ =", yylhs);
|
||||
yypop_ (yylen);
|
||||
yylen = 0;
|
||||
YY_STACK_PRINT ();
|
||||
|
||||
// Shift the result of the reduction.
|
||||
yypush_ (YY_NULL, yylhs);
|
||||
// Shift the result of the reduction.
|
||||
yypush_ (YY_NULLPTR, yylhs);
|
||||
}
|
||||
goto yynewstate;
|
||||
|
||||
/*--------------------------------------.
|
||||
@@ -910,10 +908,7 @@ b4_dollar_popdef])[]dnl
|
||||
code. */
|
||||
if (false)
|
||||
goto yyerrorlab;]b4_locations_if([[
|
||||
yyerror_range[1].location = yystack_[yylen - 1].location;]])b4_variant_if([[
|
||||
/* $$ was initialized before running the user action. */
|
||||
YY_SYMBOL_PRINT ("Error: discarding", yylhs);
|
||||
yylhs.~stack_symbol_type();]])[
|
||||
yyerror_range[1].location = yystack_[yylen - 1].location;]])[
|
||||
/* Do not reclaim the symbols of the rule whose action triggered
|
||||
this YYERROR. */
|
||||
yypop_ (yylen);
|
||||
@@ -992,11 +987,11 @@ b4_dollar_popdef])[]dnl
|
||||
// Do not try to display the values of the reclaimed symbols,
|
||||
// as their printer might throw an exception.
|
||||
if (!yyempty)
|
||||
yy_destroy_ (YY_NULL, yyla);
|
||||
yy_destroy_ (YY_NULLPTR, yyla);
|
||||
|
||||
while (1 < yystack_.size ())
|
||||
{
|
||||
yy_destroy_ (YY_NULL, yystack_[0]);
|
||||
yy_destroy_ (YY_NULLPTR, yystack_[0]);
|
||||
yypop_ ();
|
||||
}
|
||||
throw;
|
||||
@@ -1078,7 +1073,7 @@ b4_error_verbose_if([state_type yystate, symbol_number_type yytoken],
|
||||
}
|
||||
}
|
||||
|
||||
char const* yyformat = YY_NULL;
|
||||
char const* yyformat = YY_NULLPTR;
|
||||
switch (yycount)
|
||||
{
|
||||
#define YYCASE_(N, S) \
|
||||
|
||||
+274
-79
@@ -20,7 +20,8 @@ m4_include(b4_pkgdatadir/[java.m4])
|
||||
b4_defines_if([b4_fatal([%s: %%defines does not make sense in Java],
|
||||
[b4_skeleton])])
|
||||
|
||||
# We don't depend on %debug in Java, but pacify warnings about non-used flags.
|
||||
# We do not depend on %debug in Java, but pacify warnings about
|
||||
# non-used flags.
|
||||
b4_parse_trace_if([0], [0])
|
||||
|
||||
m4_define([b4_symbol_no_destructor_assert],
|
||||
@@ -30,6 +31,57 @@ m4_define([b4_symbol_no_destructor_assert],
|
||||
[b4_symbol_action_location([$1], [destructor])])])])
|
||||
b4_symbol_foreach([b4_symbol_no_destructor_assert])
|
||||
|
||||
# Setup some macros for api.push-pull.
|
||||
b4_percent_define_default([[api.push-pull]], [[pull]])
|
||||
b4_percent_define_check_values([[[[api.push-pull]],
|
||||
[[pull]], [[push]], [[both]]]])
|
||||
|
||||
# Define m4 conditional macros that encode the value
|
||||
# of the api.push-pull flag.
|
||||
b4_define_flag_if([pull]) m4_define([b4_pull_flag], [[1]])
|
||||
b4_define_flag_if([push]) m4_define([b4_push_flag], [[1]])
|
||||
m4_case(b4_percent_define_get([[api.push-pull]]),
|
||||
[pull], [m4_define([b4_push_flag], [[0]])],
|
||||
[push], [m4_define([b4_pull_flag], [[0]])])
|
||||
|
||||
# Define a macro to be true when api.push-pull has the value "both".
|
||||
m4_define([b4_both_if],[b4_push_if([b4_pull_if([$1],[$2])],[$2])])
|
||||
|
||||
# Handle BISON_USE_PUSH_FOR_PULL for the test suite. So that push parsing
|
||||
# tests function as written, do not let BISON_USE_PUSH_FOR_PULL modify the
|
||||
# behavior of Bison at all when push parsing is already requested.
|
||||
b4_define_flag_if([use_push_for_pull])
|
||||
b4_use_push_for_pull_if([
|
||||
b4_push_if([m4_define([b4_use_push_for_pull_flag], [[0]])],
|
||||
[m4_define([b4_push_flag], [[1]])])])
|
||||
|
||||
# Define a macro to encapsulate the parse state variables.
|
||||
# This allows them to be defined either in parse() when doing
|
||||
# pull parsing, or as class instance variable when doing push parsing.
|
||||
m4_define([b4_define_state],[[
|
||||
/* Lookahead and lookahead in internal form. */
|
||||
int yychar = yyempty_;
|
||||
int yytoken = 0;
|
||||
|
||||
/* State. */
|
||||
int yyn = 0;
|
||||
int yylen = 0;
|
||||
int yystate = 0;
|
||||
YYStack yystack = new YYStack ();
|
||||
int label = YYNEWSTATE;
|
||||
|
||||
/* Error handling. */
|
||||
int yynerrs_ = 0;
|
||||
]b4_locations_if([/* The location where the error started. */
|
||||
b4_location_type yyerrloc = null;
|
||||
|
||||
/* Location. */
|
||||
b4_location_type yylloc = new b4_location_type (null, null);])[
|
||||
|
||||
/* Semantic value of the lookahead. */
|
||||
]b4_yystype[ yylval = null;
|
||||
]])
|
||||
|
||||
b4_output_begin([b4_parser_file_name])
|
||||
b4_copyright([Skeleton implementation for Bison LALR(1) parsers in Java],
|
||||
[2007-2013])
|
||||
@@ -55,7 +107,9 @@ b4_percent_define_get3([implements], [ implements ])[
|
||||
{
|
||||
]b4_identification[
|
||||
]b4_error_verbose_if([[
|
||||
/** True if verbose error messages are enabled. */
|
||||
/**
|
||||
* True if verbose error messages are enabled.
|
||||
*/
|
||||
private boolean yyErrorVerbose = true;
|
||||
|
||||
/**
|
||||
@@ -76,18 +130,24 @@ b4_locations_if([[
|
||||
* A class defining a pair of positions. Positions, defined by the
|
||||
* <code>]b4_position_type[</code> class, denote a point in the input.
|
||||
* Locations represent a part of the input through the beginning
|
||||
* and ending positions. */
|
||||
* and ending positions.
|
||||
*/
|
||||
public class ]b4_location_type[ {
|
||||
/** The first, inclusive, position in the range. */
|
||||
/**
|
||||
* The first, inclusive, position in the range.
|
||||
*/
|
||||
public ]b4_position_type[ begin;
|
||||
|
||||
/** The first position beyond the range. */
|
||||
/**
|
||||
* The first position beyond the range.
|
||||
*/
|
||||
public ]b4_position_type[ end;
|
||||
|
||||
/**
|
||||
* Create a <code>]b4_location_type[</code> denoting an empty range located at
|
||||
* a given point.
|
||||
* @@param loc The position at which the range is anchored. */
|
||||
* @@param loc The position at which the range is anchored.
|
||||
*/
|
||||
public ]b4_location_type[ (]b4_position_type[ loc) {
|
||||
this.begin = this.end = loc;
|
||||
}
|
||||
@@ -95,7 +155,8 @@ b4_locations_if([[
|
||||
/**
|
||||
* Create a <code>]b4_location_type[</code> from the endpoints of the range.
|
||||
* @@param begin The first position included in the range.
|
||||
* @@param end The first position beyond the range. */
|
||||
* @@param end The first position beyond the range.
|
||||
*/
|
||||
public ]b4_location_type[ (]b4_position_type[ begin, ]b4_position_type[ end) {
|
||||
this.begin = begin;
|
||||
this.end = end;
|
||||
@@ -104,7 +165,8 @@ b4_locations_if([[
|
||||
/**
|
||||
* Print a representation of the location. For this to be correct,
|
||||
* <code>]b4_position_type[</code> should override the <code>equals</code>
|
||||
* method. */
|
||||
* method.
|
||||
*/
|
||||
public String toString () {
|
||||
if (begin.equals (end))
|
||||
return begin.toString ();
|
||||
@@ -136,24 +198,28 @@ b4_locations_if([[
|
||||
|
||||
]b4_locations_if([[/**
|
||||
* Method to retrieve the beginning position of the last scanned token.
|
||||
* @@return the position at which the last scanned token starts. */
|
||||
* @@return the position at which the last scanned token starts.
|
||||
*/
|
||||
]b4_position_type[ getStartPos ();
|
||||
|
||||
/**
|
||||
* Method to retrieve the ending position of the last scanned token.
|
||||
* @@return the first position beyond the last scanned token. */
|
||||
* @@return the first position beyond the last scanned token.
|
||||
*/
|
||||
]b4_position_type[ getEndPos ();]])[
|
||||
|
||||
/**
|
||||
* Method to retrieve the semantic value of the last scanned token.
|
||||
* @@return the semantic value of the last scanned token. */
|
||||
* @@return the semantic value of the last scanned token.
|
||||
*/
|
||||
]b4_yystype[ getLVal ();
|
||||
|
||||
/**
|
||||
* Entry point for the scanner. Returns the token identifier corresponding
|
||||
* to the next token and prepares to return the semantic value
|
||||
* ]b4_locations_if([and beginning/ending positions ])[of the token.
|
||||
* @@return the token identifier corresponding to the next token. */
|
||||
* @@return the token identifier corresponding to the next token.
|
||||
*/
|
||||
int yylex () ]b4_maybe_throws([b4_lex_throws])[;
|
||||
|
||||
/**
|
||||
@@ -162,7 +228,8 @@ b4_locations_if([[
|
||||
*
|
||||
* ]b4_locations_if([[@@param loc The location of the element to which the
|
||||
* error message is related]])[
|
||||
* @@param msg The string for the error message. */
|
||||
* @@param msg The string for the error message.
|
||||
*/
|
||||
void yyerror (]b4_locations_if([b4_location_type[ loc, ]])[String msg);]
|
||||
}
|
||||
|
||||
@@ -170,7 +237,9 @@ b4_locations_if([[
|
||||
]b4_percent_code_get([[lexer]])[
|
||||
}
|
||||
|
||||
]])[/** The object doing lexical analysis for us. */
|
||||
]])[/**
|
||||
* The object doing lexical analysis for us.
|
||||
*/
|
||||
private Lexer yylexer;
|
||||
]
|
||||
b4_parse_param_vars
|
||||
@@ -336,46 +405,74 @@ b4_lexer_if([[
|
||||
|
||||
/**
|
||||
* Returned by a Bison action in order to stop the parsing process and
|
||||
* return success (<tt>true</tt>). */
|
||||
* return success (<tt>true</tt>).
|
||||
*/
|
||||
public static final int YYACCEPT = 0;
|
||||
|
||||
/**
|
||||
* Returned by a Bison action in order to stop the parsing process and
|
||||
* return failure (<tt>false</tt>). */
|
||||
* return failure (<tt>false</tt>).
|
||||
*/
|
||||
public static final int YYABORT = 1;
|
||||
|
||||
]b4_push_if([
|
||||
/**
|
||||
* Returned by a Bison action in order to request a new token.
|
||||
*/
|
||||
public static final int YYPUSH_MORE = 4;])[
|
||||
|
||||
/**
|
||||
* Returned by a Bison action in order to start error recovery without
|
||||
* printing an error message. */
|
||||
* printing an error message.
|
||||
*/
|
||||
public static final int YYERROR = 2;
|
||||
|
||||
// Internal return codes that are not supported for user semantic
|
||||
// actions.
|
||||
/**
|
||||
* Internal return codes that are not supported for user semantic
|
||||
* actions.
|
||||
*/
|
||||
private static final int YYERRLAB = 3;
|
||||
private static final int YYNEWSTATE = 4;
|
||||
private static final int YYDEFAULT = 5;
|
||||
private static final int YYREDUCE = 6;
|
||||
private static final int YYERRLAB1 = 7;
|
||||
private static final int YYRETURN = 8;
|
||||
]b4_push_if([[ private static final int YYGETTOKEN = 9; /* Signify that a new token is expected when doing push-parsing. */]])[
|
||||
|
||||
private int yyerrstatus_ = 0;
|
||||
|
||||
]b4_push_if([dnl
|
||||
b4_define_state])[
|
||||
/**
|
||||
* Return whether error recovery is being done. In this state, the parser
|
||||
* reads token until it reaches a known state, and then restarts normal
|
||||
* operation. */
|
||||
* operation.
|
||||
*/
|
||||
public final boolean recovering ()
|
||||
{
|
||||
return yyerrstatus_ == 0;
|
||||
}
|
||||
|
||||
/** Compute post-reduction state.
|
||||
* @@param yystate the current state
|
||||
* @@param yysym the nonterminal to push on the stack
|
||||
*/
|
||||
private int yy_lr_goto_state_ (int yystate, int yysym)
|
||||
{
|
||||
int yyr = yypgoto_[yysym - yyntokens_] + yystate;
|
||||
if (0 <= yyr && yyr <= yylast_ && yycheck_[yyr] == yystate)
|
||||
return yytable_[yyr];
|
||||
else
|
||||
return yydefgoto_[yysym - yyntokens_];
|
||||
}
|
||||
|
||||
private int yyaction (int yyn, YYStack yystack, int yylen) ]b4_maybe_throws([b4_throws])[
|
||||
{
|
||||
]b4_yystype[ yyval;
|
||||
]b4_locations_if([b4_location_type[ yyloc = yylloc (yystack, yylen);]])[
|
||||
|
||||
/* If YYLEN is nonzero, implement the default value of the action:
|
||||
`$$ = $1'. Otherwise, use the top of the stack.
|
||||
'$$ = $1'. Otherwise, use the top of the stack.
|
||||
|
||||
Otherwise, the following line sets YYVAL to garbage.
|
||||
This behavior is undocumented and Bison
|
||||
@@ -399,14 +496,7 @@ b4_lexer_if([[
|
||||
yylen = 0;
|
||||
|
||||
/* Shift the result of the reduction. */
|
||||
yyn = yyr1_[yyn];
|
||||
int yystate = yypgoto_[yyn - yyntokens_] + yystack.stateAt (0);
|
||||
if (0 <= yystate && yystate <= yylast_
|
||||
&& yycheck_[yystate] == yystack.stateAt (0))
|
||||
yystate = yytable_[yystate];
|
||||
else
|
||||
yystate = yydefgoto_[yyn - yyntokens_];
|
||||
|
||||
int yystate = yy_lr_goto_state_ (yystack.stateAt (0), yyr1_[yyn]);
|
||||
yystack.push (yystate, yyval]b4_locations_if([, yyloc])[);
|
||||
return YYNEWSTATE;
|
||||
}
|
||||
@@ -463,6 +553,7 @@ b4_lexer_if([[
|
||||
+ (yyvaluep == null ? "(null)" : yyvaluep.toString ()) + ")");
|
||||
}
|
||||
|
||||
]b4_push_if([],[[
|
||||
/**
|
||||
* Parse input from the scanner that was specified at object construction
|
||||
* time. Return whether the end of the input was reached successfully.
|
||||
@@ -470,46 +561,53 @@ b4_lexer_if([[
|
||||
* @@return <tt>true</tt> if the parsing succeeds. Note that this does not
|
||||
* imply that there were no syntax errors.
|
||||
*/
|
||||
public boolean parse () ]b4_maybe_throws([b4_list2([b4_lex_throws], [b4_throws])])[
|
||||
public boolean parse () ]b4_maybe_throws([b4_list2([b4_lex_throws], [b4_throws])])[]])[
|
||||
]b4_push_if([
|
||||
/**
|
||||
* Push Parse input from external lexer
|
||||
*
|
||||
* @@param yylextoken current token
|
||||
* @@param yylexval current lval
|
||||
]b4_locations_if([ * @@param yylexloc current position])[
|
||||
*
|
||||
* @@return <tt>YYACCEPT, YYABORT, YYPUSH_MORE</tt>
|
||||
*/
|
||||
public int push_parse (int yylextoken, b4_yystype yylexval[]b4_locations_if([, b4_location_type yylexloc]))
|
||||
b4_maybe_throws([b4_list2([b4_lex_throws], [b4_throws])])])[
|
||||
{
|
||||
/// Lookahead and lookahead in internal form.
|
||||
int yychar = yyempty_;
|
||||
int yytoken = 0;
|
||||
|
||||
/* State. */
|
||||
int yyn = 0;
|
||||
int yylen = 0;
|
||||
int yystate = 0;
|
||||
|
||||
YYStack yystack = new YYStack ();
|
||||
|
||||
/* Error handling. */
|
||||
int yynerrs_ = 0;
|
||||
]b4_locations_if([/// The location where the error started.
|
||||
]b4_location_type[ yyerrloc = null;
|
||||
|
||||
/// ]b4_location_type[ of the lookahead.
|
||||
]b4_location_type[ yylloc = new ]b4_location_type[ (null, null);
|
||||
|
||||
/// @@$.
|
||||
]b4_location_type[ yyloc;])
|
||||
|
||||
/// Semantic value of the lookahead.
|
||||
b4_yystype[ yylval = null;
|
||||
|
||||
]b4_locations_if([/* @@$. */
|
||||
b4_location_type yyloc;])[
|
||||
]b4_push_if([],[[
|
||||
]b4_define_state[
|
||||
yycdebug ("Starting parse\n");
|
||||
yyerrstatus_ = 0;
|
||||
|
||||
/* Initialize the stack. */
|
||||
yystack.push (yystate, yylval ]b4_locations_if([, yylloc])[);
|
||||
]m4_ifdef([b4_initial_action], [
|
||||
b4_dollar_pushdef([yylval], [], [yylloc])dnl
|
||||
/* User initialization code. */
|
||||
b4_user_initial_action
|
||||
b4_dollar_popdef])[]dnl
|
||||
b4_dollar_popdef[]dnl
|
||||
])[
|
||||
]])[
|
||||
]b4_push_if([[
|
||||
if (!this.push_parse_initialized)
|
||||
{
|
||||
push_parse_initialize ();
|
||||
]m4_ifdef([b4_initial_action], [
|
||||
b4_dollar_pushdef([yylval], [], [yylloc])dnl
|
||||
/* User initialization code. */
|
||||
b4_user_initial_action
|
||||
b4_dollar_popdef[]dnl
|
||||
])[
|
||||
yycdebug ("Starting parse\n");
|
||||
yyerrstatus_ = 0;
|
||||
} else
|
||||
label = YYGETTOKEN;
|
||||
|
||||
[ /* Initialize the stack. */
|
||||
yystack.push (yystate, yylval]b4_locations_if([, yylloc])[);
|
||||
|
||||
int label = YYNEWSTATE;
|
||||
boolean push_token_consumed = true;
|
||||
]])[
|
||||
for (;;)
|
||||
switch (label)
|
||||
{
|
||||
@@ -522,7 +620,8 @@ b4_dollar_popdef])[]dnl
|
||||
|
||||
/* Accept? */
|
||||
if (yystate == yyfinal_)
|
||||
return true;
|
||||
]b4_push_if([{label = YYACCEPT; break;}],
|
||||
[return true;])[
|
||||
|
||||
/* Take a decision. First try without lookahead. */
|
||||
yyn = yypact_[yystate];
|
||||
@@ -531,16 +630,27 @@ b4_dollar_popdef])[]dnl
|
||||
label = YYDEFAULT;
|
||||
break;
|
||||
}
|
||||
]b4_push_if([ /* Fall Through */
|
||||
|
||||
case YYGETTOKEN:])[
|
||||
/* Read a lookahead token. */
|
||||
if (yychar == yyempty_)
|
||||
{
|
||||
]b4_push_if([[
|
||||
if (!push_token_consumed)
|
||||
return YYPUSH_MORE;
|
||||
yycdebug ("Reading a token: ");
|
||||
yychar = yylexer.yylex ();]
|
||||
b4_locations_if([[
|
||||
yylloc = new ]b4_location_type[(yylexer.getStartPos (),
|
||||
yylexer.getEndPos ());]])
|
||||
yylval = yylexer.getLVal ();[
|
||||
yychar = yylextoken;
|
||||
yylval = yylexval;]b4_locations_if([
|
||||
yylloc = yylexloc;])[
|
||||
push_token_consumed = false;]])[
|
||||
]b4_push_if([],[[
|
||||
yycdebug ("Reading a token: ");
|
||||
yychar = yylexer.yylex ();
|
||||
yylval = yylexer.getLVal ();]b4_locations_if([
|
||||
yylloc = new b4_location_type (yylexer.getStartPos (),
|
||||
yylexer.getEndPos ());])[
|
||||
]])[
|
||||
}
|
||||
|
||||
/* Convert token to internal form. */
|
||||
@@ -637,10 +747,10 @@ b4_dollar_popdef])[]dnl
|
||||
{
|
||||
/* Return failure if at end of input. */
|
||||
if (yychar == Lexer.EOF)
|
||||
return false;
|
||||
]b4_push_if([{label = YYABORT; break;}],[return false;])[
|
||||
}
|
||||
else
|
||||
yychar = yyempty_;
|
||||
yychar = yyempty_;
|
||||
}
|
||||
|
||||
/* Else will try to reuse lookahead token after shifting the error
|
||||
@@ -648,9 +758,9 @@ b4_dollar_popdef])[]dnl
|
||||
label = YYERRLAB1;
|
||||
break;
|
||||
|
||||
/*---------------------------------------------------.
|
||||
/*-------------------------------------------------.
|
||||
| errorlab -- error raised explicitly by YYERROR. |
|
||||
`---------------------------------------------------*/
|
||||
`-------------------------------------------------*/
|
||||
case YYERROR:
|
||||
|
||||
]b4_locations_if([yyerrloc = yystack.locationAt (yylen - 1);])[
|
||||
@@ -682,9 +792,10 @@ b4_dollar_popdef])[]dnl
|
||||
}
|
||||
}
|
||||
|
||||
/* Pop the current state because it cannot handle the error token. */
|
||||
/* Pop the current state because it cannot handle the
|
||||
* error token. */
|
||||
if (yystack.height == 0)
|
||||
return false;
|
||||
]b4_push_if([{label = YYABORT; break;}],[return false;])[
|
||||
|
||||
]b4_locations_if([yyerrloc = yystack.locationAt (0);])[
|
||||
yystack.pop ();
|
||||
@@ -693,7 +804,11 @@ b4_dollar_popdef])[]dnl
|
||||
yystack.print (yyDebugStream);
|
||||
}
|
||||
|
||||
]b4_locations_if([
|
||||
if (label == YYABORT)
|
||||
/* Leave the switch. */
|
||||
break;
|
||||
|
||||
]b4_locations_if([
|
||||
/* Muck with the stack to setup for yylloc. */
|
||||
yystack.push (0, null, yylloc);
|
||||
yystack.push (0, null, yyerrloc);
|
||||
@@ -711,13 +826,91 @@ b4_dollar_popdef])[]dnl
|
||||
|
||||
/* Accept. */
|
||||
case YYACCEPT:
|
||||
return true;
|
||||
]b4_push_if([this.push_parse_initialized = false; return YYACCEPT;],
|
||||
[return true;])[
|
||||
|
||||
/* Abort. */
|
||||
case YYABORT:
|
||||
return false;
|
||||
]b4_push_if([this.push_parse_initialized = false; return YYABORT;],
|
||||
[return false;])[
|
||||
}
|
||||
}
|
||||
]b4_push_if([[
|
||||
boolean push_parse_initialized = false;
|
||||
|
||||
/**
|
||||
* (Re-)Initialize the state of the push parser.
|
||||
*/
|
||||
public void push_parse_initialize()
|
||||
{
|
||||
/* Lookahead and lookahead in internal form. */
|
||||
this.yychar = yyempty_;
|
||||
this.yytoken = 0;
|
||||
|
||||
/* State. */
|
||||
this.yyn = 0;
|
||||
this.yylen = 0;
|
||||
this.yystate = 0;
|
||||
this.yystack = new YYStack ();
|
||||
this.label = YYNEWSTATE;
|
||||
|
||||
/* Error handling. */
|
||||
this.yynerrs_ = 0;
|
||||
]b4_locations_if([/* The location where the error started. */
|
||||
this.yyerrloc = null;
|
||||
this.yylloc = new b4_location_type (null, null);])[
|
||||
|
||||
/* Semantic value of the lookahead. */
|
||||
this.yylval = null;
|
||||
|
||||
yystack.push (this.yystate, this.yylval]b4_locations_if([, this.yylloc])[);
|
||||
|
||||
this.push_parse_initialized = true;
|
||||
|
||||
}
|
||||
]b4_locations_if([
|
||||
/**
|
||||
* Push parse given input from an external lexer.
|
||||
*
|
||||
* @@param yylextoken current token
|
||||
* @@param yylexval current lval
|
||||
* @@param yyylexpos current position
|
||||
*
|
||||
* @@return <tt>YYACCEPT, YYABORT, YYPUSH_MORE</tt>
|
||||
*/
|
||||
public int push_parse (int yylextoken, b4_yystype yylexval, b4_position_type yylexpos)
|
||||
b4_maybe_throws([b4_list2([b4_lex_throws], [b4_throws])])
|
||||
{
|
||||
return push_parse (yylextoken, yylexval, new b4_location_type (yylexpos));
|
||||
}
|
||||
])[]])
|
||||
|
||||
b4_both_if([[
|
||||
/**
|
||||
* Parse input from the scanner that was specified at object construction
|
||||
* time. Return whether the end of the input was reached successfully.
|
||||
* This version of parse () is defined only when api.push-push=both.
|
||||
*
|
||||
* @@return <tt>true</tt> if the parsing succeeds. Note that this does not
|
||||
* imply that there were no syntax errors.
|
||||
*/
|
||||
public boolean parse () ]b4_maybe_throws([b4_list2([b4_lex_throws], [b4_throws])])[
|
||||
{
|
||||
if (yylexer == null)
|
||||
throw new NullPointerException("Null Lexer");
|
||||
int status;
|
||||
do {
|
||||
int token = yylexer.yylex();
|
||||
]b4_yystype[ lval = yylexer.getLVal();
|
||||
]b4_locations_if([dnl
|
||||
b4_location_type yyloc = new b4_location_type (yylexer.getStartPos (),
|
||||
yylexer.getEndPos ());])[
|
||||
]b4_locations_if([status = push_parse(token,lval,yyloc);],[
|
||||
status = push_parse(token,lval);])[
|
||||
} while (status == YYPUSH_MORE);
|
||||
return (status == YYACCEPT);
|
||||
}
|
||||
]])[
|
||||
|
||||
// Generate an error message.
|
||||
private String yysyntax_error (int yystate, int tok)
|
||||
@@ -752,8 +945,8 @@ b4_dollar_popdef])[]dnl
|
||||
*/
|
||||
if (tok != yyempty_)
|
||||
{
|
||||
// FIXME: This method of building the message is not compatible
|
||||
// with internationalization.
|
||||
/* FIXME: This method of building the message is not compatible
|
||||
with internationalization. */
|
||||
StringBuffer res =
|
||||
new StringBuffer ("syntax error, unexpected ");
|
||||
res.append (yytnamerr_ (yytname_[tok]));
|
||||
@@ -802,8 +995,9 @@ b4_dollar_popdef])[]dnl
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the given <code>yytable_</code> value indicates a syntax error.
|
||||
* @@param yyvalue the value to check
|
||||
* Whether the given <code>yytable_</code>
|
||||
* value indicates a syntax error.
|
||||
* @@param yyvalue the value to check
|
||||
*/
|
||||
private static boolean yy_table_value_is_error_ (int yyvalue)
|
||||
{
|
||||
@@ -825,6 +1019,7 @@ b4_dollar_popdef])[]dnl
|
||||
]b4_integral_parser_table_define([rline], [b4_rline],
|
||||
[[YYRLINE[YYN] -- Source line where rule number YYN was defined.]])[
|
||||
|
||||
|
||||
// Report on the debug stream that the rule yyrule is going to be reduced.
|
||||
private void yy_reduce_print (int yyrule, YYStack yystack)
|
||||
{
|
||||
|
||||
+46
-27
@@ -25,10 +25,9 @@ m4_define([b4_position_define],
|
||||
[[ /// Abstract a position.
|
||||
class position
|
||||
{
|
||||
public:
|
||||
]m4_ifdef([b4_location_constructors], [[
|
||||
public:]m4_ifdef([b4_location_constructors], [[
|
||||
/// Construct a position.
|
||||
explicit position (]b4_percent_define_get([[filename_type]])[* f = YY_NULL,
|
||||
explicit position (]b4_percent_define_get([[filename_type]])[* f = YY_NULLPTR,
|
||||
unsigned int l = ]b4_location_initial_line[u,
|
||||
unsigned int c = ]b4_location_initial_column[u)
|
||||
: filename (f)
|
||||
@@ -39,7 +38,7 @@ m4_define([b4_position_define],
|
||||
|
||||
]])[
|
||||
/// Initialization.
|
||||
void initialize (]b4_percent_define_get([[filename_type]])[* fn = YY_NULL,
|
||||
void initialize (]b4_percent_define_get([[filename_type]])[* fn = YY_NULLPTR,
|
||||
unsigned int l = ]b4_location_initial_line[u,
|
||||
unsigned int c = ]b4_location_initial_column[u)
|
||||
{
|
||||
@@ -53,14 +52,17 @@ m4_define([b4_position_define],
|
||||
/// (line related) Advance to the COUNT next lines.
|
||||
void lines (int count = 1)
|
||||
{
|
||||
column = ]b4_location_initial_column[u;
|
||||
line += count;
|
||||
if (count)
|
||||
{
|
||||
column = ]b4_location_initial_column[u;
|
||||
line = add_ (line, count, ]b4_location_initial_line[);
|
||||
}
|
||||
}
|
||||
|
||||
/// (column related) Advance to the COUNT next columns.
|
||||
void columns (int count = 1)
|
||||
{
|
||||
column = std::max (]b4_location_initial_column[u, column + count);
|
||||
column = add_ (column, count, ]b4_location_initial_column[);
|
||||
}
|
||||
/** \} */
|
||||
|
||||
@@ -70,36 +72,44 @@ m4_define([b4_position_define],
|
||||
unsigned int line;
|
||||
/// Current column number.
|
||||
unsigned int column;
|
||||
|
||||
private:
|
||||
/// Compute max(min, lhs+rhs) (provided min <= lhs).
|
||||
static unsigned int add_ (unsigned int lhs, int rhs, unsigned int min)
|
||||
{
|
||||
return (0 < rhs || -static_cast<unsigned int>(rhs) < lhs
|
||||
? rhs + lhs
|
||||
: min);
|
||||
}
|
||||
};
|
||||
|
||||
/// Add and assign a position.
|
||||
inline position&
|
||||
operator+= (position& res, const int width)
|
||||
operator+= (position& res, int width)
|
||||
{
|
||||
res.columns (width);
|
||||
return res;
|
||||
}
|
||||
|
||||
/// Add two position objects.
|
||||
inline const position
|
||||
operator+ (const position& begin, const int width)
|
||||
inline position
|
||||
operator+ (position res, int width)
|
||||
{
|
||||
position res = begin;
|
||||
return res += width;
|
||||
}
|
||||
|
||||
/// Add and assign a position.
|
||||
inline position&
|
||||
operator-= (position& res, const int width)
|
||||
operator-= (position& res, int width)
|
||||
{
|
||||
return res += -width;
|
||||
}
|
||||
|
||||
/// Add two position objects.
|
||||
inline const position
|
||||
operator- (const position& begin, const int width)
|
||||
inline position
|
||||
operator- (position res, int width)
|
||||
{
|
||||
return begin + -width;
|
||||
return res -= width;
|
||||
}
|
||||
]b4_percent_define_flag_if([[define_location_comparison]], [[
|
||||
/// Compare two position objects.
|
||||
@@ -168,7 +178,7 @@ m4_define([b4_location_define],
|
||||
|
||||
])[
|
||||
/// Initialization.
|
||||
void initialize (]b4_percent_define_get([[filename_type]])[* f = YY_NULL,
|
||||
void initialize (]b4_percent_define_get([[filename_type]])[* f = YY_NULLPTR,
|
||||
unsigned int l = ]b4_location_initial_line[u,
|
||||
unsigned int c = ]b4_location_initial_column[u)
|
||||
{
|
||||
@@ -186,13 +196,13 @@ m4_define([b4_location_define],
|
||||
}
|
||||
|
||||
/// Extend the current location to the COUNT next columns.
|
||||
void columns (unsigned int count = 1)
|
||||
void columns (int count = 1)
|
||||
{
|
||||
end += count;
|
||||
}
|
||||
|
||||
/// Extend the current location to the COUNT next lines.
|
||||
void lines (unsigned int count = 1)
|
||||
void lines (int count = 1)
|
||||
{
|
||||
end.lines (count);
|
||||
}
|
||||
@@ -207,26 +217,35 @@ m4_define([b4_location_define],
|
||||
};
|
||||
|
||||
/// Join two location objects to create a location.
|
||||
inline const location operator+ (const location& begin, const location& end)
|
||||
inline location operator+ (location res, const location& end)
|
||||
{
|
||||
location res = begin;
|
||||
res.end = end.end;
|
||||
return res;
|
||||
}
|
||||
|
||||
/// Add two location objects.
|
||||
inline const location operator+ (const location& begin, unsigned int width)
|
||||
/// Change end position in place.
|
||||
inline location& operator+= (location& res, int width)
|
||||
{
|
||||
location res = begin;
|
||||
res.columns (width);
|
||||
return res;
|
||||
}
|
||||
|
||||
/// Add and assign a location.
|
||||
inline location& operator+= (location& res, unsigned int width)
|
||||
/// Change end position.
|
||||
inline location operator+ (location res, int width)
|
||||
{
|
||||
res.columns (width);
|
||||
return res;
|
||||
return res += width;
|
||||
}
|
||||
|
||||
/// Change end position in place.
|
||||
inline location& operator-= (location& res, int width)
|
||||
{
|
||||
return res += -width;
|
||||
}
|
||||
|
||||
/// Change end position.
|
||||
inline location operator- (const location& begin, int width)
|
||||
{
|
||||
return begin + -width;
|
||||
}
|
||||
]b4_percent_define_flag_if([[define_location_comparison]], [[
|
||||
/// Compare two location objects.
|
||||
|
||||
@@ -72,6 +72,12 @@ m4_define([b4_stack_define],
|
||||
seq_.pop_back ();
|
||||
}
|
||||
|
||||
void
|
||||
clear ()
|
||||
{
|
||||
seq_.clear ();
|
||||
}
|
||||
|
||||
inline
|
||||
typename S::size_type
|
||||
size () const
|
||||
@@ -94,6 +100,8 @@ m4_define([b4_stack_define],
|
||||
}
|
||||
|
||||
private:
|
||||
stack (const stack&);
|
||||
stack& operator= (const stack&);
|
||||
/// The wrapped container.
|
||||
S seq_;
|
||||
};
|
||||
|
||||
+56
-41
@@ -26,7 +26,7 @@
|
||||
# YYTYPE.
|
||||
m4_define([b4_symbol_variant],
|
||||
[m4_pushdef([b4_dollar_dollar],
|
||||
[$2.$3< $][3 >(m4_shift3($@))])dnl
|
||||
[$2.$3< $][3 > (m4_shift3($@))])dnl
|
||||
switch ($1)
|
||||
{
|
||||
b4_type_foreach([b4_type_action_])[]dnl
|
||||
@@ -63,7 +63,7 @@ m4_define([b4_char_sizeof],
|
||||
[b4_symbol_if([$1], [has_type],
|
||||
[
|
||||
m4_map([ b4_symbol_tag_comment], [$@])dnl
|
||||
char _b4_char_sizeof_dummy@{sizeof([b4_symbol([$1], [type])])@};
|
||||
char _b4_char_sizeof_dummy@{sizeof(b4_symbol([$1], [type]))@};
|
||||
])])
|
||||
|
||||
|
||||
@@ -95,22 +95,22 @@ m4_define([b4_variant_define],
|
||||
|
||||
/// Empty construction.
|
||||
variant ()]b4_parse_assert_if([
|
||||
: tname (YY_NULL)])[
|
||||
: yytname_ (YY_NULLPTR)])[
|
||||
{}
|
||||
|
||||
/// Construct and fill.
|
||||
template <typename T>
|
||||
variant (const T& t)]b4_parse_assert_if([
|
||||
: tname (typeid (T).name ())])[
|
||||
: yytname_ (typeid (T).name ())])[
|
||||
{
|
||||
YYASSERT (sizeof (T) <= S);
|
||||
new (buffer.raw) T (t);
|
||||
new (yyas_<T> ()) T (t);
|
||||
}
|
||||
|
||||
/// Destruction, allowed only if empty.
|
||||
~variant ()
|
||||
{]b4_parse_assert_if([
|
||||
YYASSERT (!tname);
|
||||
YYASSERT (!yytname_);
|
||||
])[}
|
||||
|
||||
/// Instantiate an empty \a T in here.
|
||||
@@ -118,10 +118,10 @@ m4_define([b4_variant_define],
|
||||
T&
|
||||
build ()
|
||||
{]b4_parse_assert_if([
|
||||
YYASSERT (!tname);
|
||||
YYASSERT (!yytname_);
|
||||
YYASSERT (sizeof (T) <= S);
|
||||
tname = typeid (T).name ();])[
|
||||
return *new (buffer.raw) T;
|
||||
yytname_ = typeid (T).name ();])[
|
||||
return *new (yyas_<T> ()) T;
|
||||
}
|
||||
|
||||
/// Instantiate a \a T in here from \a t.
|
||||
@@ -129,10 +129,10 @@ m4_define([b4_variant_define],
|
||||
T&
|
||||
build (const T& t)
|
||||
{]b4_parse_assert_if([
|
||||
YYASSERT (!tname);
|
||||
YYASSERT (!yytname_);
|
||||
YYASSERT (sizeof (T) <= S);
|
||||
tname = typeid (T).name ();])[
|
||||
return *new (buffer.raw) T (t);
|
||||
yytname_ = typeid (T).name ();])[
|
||||
return *new (yyas_<T> ()) T (t);
|
||||
}
|
||||
|
||||
/// Accessor to a built \a T.
|
||||
@@ -140,9 +140,9 @@ m4_define([b4_variant_define],
|
||||
T&
|
||||
as ()
|
||||
{]b4_parse_assert_if([
|
||||
YYASSERT (tname == typeid (T).name ());
|
||||
YYASSERT (yytname_ == typeid (T).name ());
|
||||
YYASSERT (sizeof (T) <= S);])[
|
||||
return reinterpret_cast<T&> (buffer.raw);
|
||||
return *yyas_<T> ();
|
||||
}
|
||||
|
||||
/// Const accessor to a built \a T (for %printer).
|
||||
@@ -150,9 +150,9 @@ m4_define([b4_variant_define],
|
||||
const T&
|
||||
as () const
|
||||
{]b4_parse_assert_if([
|
||||
YYASSERT (tname == typeid (T).name ());
|
||||
YYASSERT (yytname_ == typeid (T).name ());
|
||||
YYASSERT (sizeof (T) <= S);])[
|
||||
return reinterpret_cast<const T&> (buffer.raw);
|
||||
return *yyas_<T> ();
|
||||
}
|
||||
|
||||
/// Swap the content with \a other, of same type.
|
||||
@@ -167,9 +167,9 @@ m4_define([b4_variant_define],
|
||||
void
|
||||
swap (self_type& other)
|
||||
{]b4_parse_assert_if([
|
||||
YYASSERT (tname);
|
||||
YYASSERT (tname == other.tname);])[
|
||||
std::swap (as<T>(), other.as<T>());
|
||||
YYASSERT (yytname_);
|
||||
YYASSERT (yytname_ == other.yytname_);])[
|
||||
std::swap (as<T> (), other.as<T> ());
|
||||
}
|
||||
|
||||
/// Move the content of \a other to this.
|
||||
@@ -178,11 +178,10 @@ m4_define([b4_variant_define],
|
||||
template <typename T>
|
||||
void
|
||||
move (self_type& other)
|
||||
{]b4_parse_assert_if([
|
||||
YYASSERT (!tname);])[
|
||||
build<T>();
|
||||
swap<T>(other);
|
||||
other.destroy<T>();
|
||||
{
|
||||
build<T> ();
|
||||
swap<T> (other);
|
||||
other.destroy<T> ();
|
||||
}
|
||||
|
||||
/// Copy the content of \a other to this.
|
||||
@@ -199,7 +198,7 @@ m4_define([b4_variant_define],
|
||||
destroy ()
|
||||
{
|
||||
as<T> ().~T ();]b4_parse_assert_if([
|
||||
tname = YY_NULL;])[
|
||||
yytname_ = YY_NULLPTR;])[
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -207,17 +206,34 @@ m4_define([b4_variant_define],
|
||||
self_type& operator=(const self_type&);
|
||||
variant (const self_type&);
|
||||
|
||||
/// A buffer large enough to store any of the semantic values.
|
||||
/// Long double is chosen as it has the strongest alignment
|
||||
/// constraints.
|
||||
/// Accessor to raw memory as \a T.
|
||||
template <typename T>
|
||||
T*
|
||||
yyas_ ()
|
||||
{
|
||||
void *yyp = yybuffer_.yyraw;
|
||||
return static_cast<T*> (yyp);
|
||||
}
|
||||
|
||||
/// Const accessor to raw memory as \a T.
|
||||
template <typename T>
|
||||
const T*
|
||||
yyas_ () const
|
||||
{
|
||||
const void *yyp = yybuffer_.yyraw;
|
||||
return static_cast<const T*> (yyp);
|
||||
}
|
||||
|
||||
union
|
||||
{
|
||||
long double align_me;
|
||||
char raw[S];
|
||||
} buffer;]b4_parse_assert_if([
|
||||
/// Strongest alignment constraints.
|
||||
long double yyalign_me;
|
||||
/// A buffer large enough to store any of the semantic values.
|
||||
char yyraw[S];
|
||||
} yybuffer_;]b4_parse_assert_if([
|
||||
|
||||
/// Whether the content is built: if defined, the name of the stored type.
|
||||
const char* tname;])[
|
||||
const char *yytname_;])[
|
||||
};
|
||||
]])
|
||||
|
||||
@@ -227,16 +243,16 @@ m4_define([b4_variant_define],
|
||||
## -------------------------- ##
|
||||
|
||||
|
||||
# b4_semantic_type_declare
|
||||
# ------------------------
|
||||
# b4_value_type_declare
|
||||
# ---------------------
|
||||
# Declare semantic_type.
|
||||
m4_define([b4_semantic_type_declare],
|
||||
[ /// An auxiliary type to compute the largest semantic type.
|
||||
m4_define([b4_value_type_declare],
|
||||
[[ /// An auxiliary type to compute the largest semantic type.
|
||||
union union_type
|
||||
{]b4_type_foreach([b4_char_sizeof])[};
|
||||
|
||||
/// Symbol semantic values.
|
||||
typedef variant<sizeof(union_type)> semantic_type;dnl
|
||||
typedef variant<sizeof(union_type)> semantic_type;][]dnl
|
||||
])
|
||||
|
||||
|
||||
@@ -246,7 +262,7 @@ m4_define([b4_semantic_type_declare],
|
||||
# ----------------------------
|
||||
m4_define([b4_symbol_value],
|
||||
[m4_ifval([$2],
|
||||
[$1.as< $2 >()],
|
||||
[$1.as< $2 > ()],
|
||||
[$1])])
|
||||
|
||||
# b4_symbol_value_template(VAL, [TYPE])
|
||||
@@ -254,7 +270,7 @@ m4_define([b4_symbol_value],
|
||||
# Same as b4_symbol_value, but used in a template method.
|
||||
m4_define([b4_symbol_value_template],
|
||||
[m4_ifval([$2],
|
||||
[$1.template as< $2 >()],
|
||||
[$1.template as< $2 > ()],
|
||||
[$1])])
|
||||
|
||||
|
||||
@@ -304,14 +320,13 @@ b4_join(b4_symbol_if([$1], [has_type],
|
||||
return symbol_type (b4_join([token::b4_symbol([$1], [id])],
|
||||
b4_symbol_if([$1], [has_type], [v]),
|
||||
b4_locations_if([l])));
|
||||
|
||||
}
|
||||
|
||||
])])])
|
||||
|
||||
|
||||
# b4_basic_symbol_constructor_declare
|
||||
# ----------------------------------
|
||||
# -----------------------------------
|
||||
# Generate a constructor declaration for basic_symbol from given type.
|
||||
m4_define([b4_basic_symbol_constructor_declare],
|
||||
[[
|
||||
|
||||
@@ -201,6 +201,8 @@
|
||||
<xsl:if test="$point = 0">
|
||||
<xsl:text> .</xsl:text>
|
||||
</xsl:if>
|
||||
|
||||
<!-- RHS -->
|
||||
<xsl:for-each select="rhs/symbol|rhs/empty">
|
||||
<xsl:apply-templates select="."/>
|
||||
<xsl:if test="$point = position()">
|
||||
@@ -214,7 +216,9 @@
|
||||
<xsl:value-of select="."/>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="empty"/>
|
||||
<xsl:template match="empty">
|
||||
<xsl:text> %empty</xsl:text>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="lookaheads">
|
||||
<xsl:text> [</xsl:text>
|
||||
|
||||
@@ -350,12 +350,7 @@
|
||||
<xsl:if test="position() = $point + 1">
|
||||
<xsl:text> .</xsl:text>
|
||||
</xsl:if>
|
||||
<xsl:if test="$itemset = 'true' and name(.) != 'empty'">
|
||||
<xsl:apply-templates select="."/>
|
||||
</xsl:if>
|
||||
<xsl:if test="$itemset != 'true'">
|
||||
<xsl:apply-templates select="."/>
|
||||
</xsl:if>
|
||||
<xsl:apply-templates select="."/>
|
||||
<xsl:if test="position() = last() and position() = $point">
|
||||
<xsl:text> .</xsl:text>
|
||||
</xsl:if>
|
||||
@@ -373,7 +368,7 @@
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="empty">
|
||||
<xsl:text> /* empty */</xsl:text>
|
||||
<xsl:text> %empty</xsl:text>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="lookaheads">
|
||||
|
||||
@@ -532,12 +532,7 @@
|
||||
<xsl:text> </xsl:text>
|
||||
<span class="point">.</span>
|
||||
</xsl:if>
|
||||
<xsl:if test="$itemset = 'true' and name(.) != 'empty'">
|
||||
<xsl:apply-templates select="."/>
|
||||
</xsl:if>
|
||||
<xsl:if test="$itemset != 'true'">
|
||||
<xsl:apply-templates select="."/>
|
||||
</xsl:if>
|
||||
<xsl:apply-templates select="."/>
|
||||
<xsl:if test="position() = last() and position() = $point">
|
||||
<xsl:text> </xsl:text>
|
||||
<span class="point">.</span>
|
||||
@@ -563,7 +558,7 @@
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="empty">
|
||||
<xsl:text> ε</xsl:text>
|
||||
<xsl:text> %empty</xsl:text>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="lookaheads">
|
||||
|
||||
+22
-45
@@ -143,7 +143,6 @@ m4_define([b4_rhs_value],
|
||||
[b4_symbol_value([yyvsp@{b4_subtract([$2], [$1])@}], [$3])])
|
||||
|
||||
|
||||
|
||||
## ----------- ##
|
||||
## Locations. ##
|
||||
## ----------- ##
|
||||
@@ -176,36 +175,19 @@ m4_define([b4_declare_scanner_communication_variables], [[
|
||||
int yychar;
|
||||
|
||||
]b4_pure_if([[
|
||||
#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__
|
||||
/* Suppress an incorrect diagnostic about yylval being uninitialized. */
|
||||
# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
|
||||
_Pragma ("GCC diagnostic push") \
|
||||
_Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\
|
||||
_Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"")
|
||||
# define YY_IGNORE_MAYBE_UNINITIALIZED_END \
|
||||
_Pragma ("GCC diagnostic pop")
|
||||
#else
|
||||
/* The semantic value of the lookahead symbol. */
|
||||
/* Default value used for initialization, for pacifying older GCCs
|
||||
or non-GCC compilers. */
|
||||
static YYSTYPE yyval_default;
|
||||
# define YY_INITIAL_VALUE(Value) = Value
|
||||
#endif]b4_locations_if([[
|
||||
static YYLTYPE yyloc_default][]b4_yyloc_default[;]])])[
|
||||
#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
|
||||
# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
|
||||
# define YY_IGNORE_MAYBE_UNINITIALIZED_END
|
||||
#endif
|
||||
#ifndef YY_INITIAL_VALUE
|
||||
# define YY_INITIAL_VALUE(Value) /* Nothing. */
|
||||
#endif
|
||||
|
||||
/* The semantic value of the lookahead symbol. */
|
||||
YYSTYPE yylval YY_INITIAL_VALUE(yyval_default);]b4_locations_if([[
|
||||
YY_INITIAL_VALUE (static YYSTYPE yyval_default;)
|
||||
YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);]b4_locations_if([[
|
||||
|
||||
/* Location data for the lookahead symbol. */
|
||||
YYLTYPE yylloc]b4_pure_if([ = yyloc_default], [b4_yyloc_default])[;
|
||||
]])b4_pure_if([], [[
|
||||
|
||||
static YYLTYPE yyloc_default]b4_yyloc_default[;
|
||||
YYLTYPE yylloc = yyloc_default;]])],
|
||||
[[/* The semantic value of the lookahead symbol. */
|
||||
YYSTYPE yylval;]b4_locations_if([[
|
||||
/* Location data for the lookahead symbol. */
|
||||
YYLTYPE yylloc]b4_yyloc_default[;]])[
|
||||
/* Number of syntax errors so far. */
|
||||
int yynerrs;]])])
|
||||
|
||||
@@ -223,9 +205,9 @@ m4_define([b4_declare_parser_state_variables], [b4_pure_if([[
|
||||
int yyerrstatus;
|
||||
|
||||
/* The stacks and their tools:
|
||||
`yyss': related to states.
|
||||
`yyvs': related to semantic values.]b4_locations_if([[
|
||||
`yyls': related to locations.]])[
|
||||
'yyss': related to states.
|
||||
'yyvs': related to semantic values.]b4_locations_if([[
|
||||
'yyls': related to locations.]])[
|
||||
|
||||
Refer to the stacks through separate pointers, to allow yyoverflow
|
||||
to reallocate them elsewhere. */
|
||||
@@ -431,12 +413,7 @@ typedef short int yytype_int16;
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Suppress unused-variable warnings by "using" E. */
|
||||
#ifdef __GNUC__
|
||||
# define YYUSE(E) ((void) (E))
|
||||
#else
|
||||
# define YYUSE(E) /* empty */
|
||||
#endif
|
||||
]b4_attribute_define[
|
||||
|
||||
#if ]b4_lac_if([[1]], [[! defined yyoverflow || YYERROR_VERBOSE]])[
|
||||
|
||||
@@ -468,7 +445,7 @@ b4_push_if([], [b4_lac_if([], [[
|
||||
# endif]])])[
|
||||
|
||||
# ifdef YYSTACK_ALLOC
|
||||
/* Pacify GCC's `empty if-body' warning. */
|
||||
/* Pacify GCC's 'empty if-body' warning. */
|
||||
# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
|
||||
# ifndef YYSTACK_ALLOC_MAXIMUM
|
||||
/* The OS might guarantee only one guard page at the bottom of the stack,
|
||||
@@ -1131,11 +1108,11 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
|
||||
]b4_lac_if([[yytype_int16 *yyesa, yytype_int16 **yyes,
|
||||
YYSIZE_T *yyes_capacity, ]])[yytype_int16 *yyssp, int yytoken)
|
||||
{
|
||||
YYSIZE_T yysize0 = yytnamerr (YY_NULL, yytname[yytoken]);
|
||||
YYSIZE_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]);
|
||||
YYSIZE_T yysize = yysize0;
|
||||
enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
|
||||
/* Internationalized format string. */
|
||||
const char *yyformat = YY_NULL;
|
||||
const char *yyformat = YY_NULLPTR;
|
||||
/* Arguments of yyformat. */
|
||||
char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
|
||||
/* Number of reported tokens (one for the "unexpected", one per
|
||||
@@ -1210,7 +1187,7 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
|
||||
}
|
||||
yyarg[yycount++] = yytname[yyx];
|
||||
{
|
||||
YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULL, yytname[yyx]);
|
||||
YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]);
|
||||
if (! (yysize <= yysize1
|
||||
&& yysize1 <= YYSTACK_ALLOC_MAXIMUM))
|
||||
return 2;
|
||||
@@ -1294,7 +1271,7 @@ static char yypstate_allocated = 0;]])b4_pull_if([
|
||||
|
||||
b4_function_define([[yyparse]], [[int]], b4_parse_param)[
|
||||
{
|
||||
return yypull_parse (YY_NULL]m4_ifset([b4_parse_param],
|
||||
return yypull_parse (YY_NULLPTR]m4_ifset([b4_parse_param],
|
||||
[[, ]b4_args(b4_parse_param)])[);
|
||||
}
|
||||
|
||||
@@ -1336,10 +1313,10 @@ b4_function_define([[yyparse]], [[int]], b4_parse_param)[
|
||||
{
|
||||
yypstate *yyps;]b4_pure_if([], [[
|
||||
if (yypstate_allocated)
|
||||
return YY_NULL;]])[
|
||||
return YY_NULLPTR;]])[
|
||||
yyps = (yypstate *) malloc (sizeof *yyps);
|
||||
if (!yyps)
|
||||
return YY_NULL;
|
||||
return YY_NULLPTR;
|
||||
yyps->yynew = 1;]b4_pure_if([], [[
|
||||
yypstate_allocated = 1;]])[
|
||||
return yyps;
|
||||
@@ -1654,7 +1631,7 @@ yyreduce:
|
||||
yylen = yyr2[yyn];
|
||||
|
||||
/* If YYLEN is nonzero, implement the default value of the action:
|
||||
`$$ = $1'.
|
||||
'$$ = $1'.
|
||||
|
||||
Otherwise, the following line sets YYVAL to garbage.
|
||||
This behavior is undocumented and Bison
|
||||
@@ -1702,7 +1679,7 @@ yyreduce:
|
||||
*++yyvsp = yyval;]b4_locations_if([
|
||||
*++yylsp = yyloc;])[
|
||||
|
||||
/* Now `shift' the result of the reduction. Determine what state
|
||||
/* Now 'shift' the result of the reduction. Determine what state
|
||||
that goes to, based on the state we popped back to and the rule
|
||||
number reduced by. */
|
||||
|
||||
|
||||
+716
-310
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,2 @@
|
||||
This file is a stub, not used by the documentation. If you feel like
|
||||
contributing ASCII art for example.gv, please step forward!
|
||||
+17
-14
@@ -23,9 +23,10 @@ doc_bison_TEXINFOS = \
|
||||
# Cannot express dependencies directly on file names because of Automake.
|
||||
# Obfuscate with a variable.
|
||||
doc_bison = doc/bison
|
||||
$(doc_bison).dvi: $(FIGS_DOT:.dot=.eps)
|
||||
$(doc_bison).pdf: $(FIGS_DOT:.dot=.pdf)
|
||||
$(doc_bison).html: $(FIGS_DOT:.dot=.png)
|
||||
$(doc_bison).dvi: $(FIGS_GV:.gv=.eps)
|
||||
$(doc_bison).info: $(FIGS_GV:.gv=.txt)
|
||||
$(doc_bison).pdf: $(FIGS_GV:.gv=.pdf)
|
||||
$(doc_bison).html: $(FIGS_GV:.gv=.png)
|
||||
|
||||
TEXI2DVI = texi2dvi --build-dir=doc/bison.t2d -I doc
|
||||
CLEANDIRS = doc/bison.t2d
|
||||
@@ -37,7 +38,7 @@ MOSTLYCLEANFILES += $(top_srcdir)/doc/*.t
|
||||
CROSS_OPTIONS_PL = $(top_srcdir)/build-aux/cross-options.pl
|
||||
CROSS_OPTIONS_TEXI = $(top_srcdir)/doc/cross-options.texi
|
||||
$(CROSS_OPTIONS_TEXI): doc/bison.help $(CROSS_OPTIONS_PL)
|
||||
# Create $@~ which is the previous contents. Don't use `mv' here so
|
||||
# Create $@~ which is the previous contents. Don't use 'mv' here so
|
||||
# that even if we are interrupted, the file is still available for
|
||||
# diff in the next run. Note that $@ might not exist yet.
|
||||
$(AM_V_GEN){ test ! -f $@ || cat $@; } >$@~
|
||||
@@ -117,32 +118,34 @@ $(top_srcdir)/doc/bison.1: doc/bison.help doc/bison.x $(top_srcdir)/configure
|
||||
fi
|
||||
$(AM_V_at)rm -f $@*.t
|
||||
|
||||
if ENABLE_YACC
|
||||
nodist_man_MANS = doc/yacc.1
|
||||
endif
|
||||
|
||||
## ----------------------------- ##
|
||||
## Graphviz examples generation. ##
|
||||
## ----------------------------- ##
|
||||
|
||||
CLEANDIRS += doc/figs
|
||||
FIGS_DOT = \
|
||||
doc/figs/example.dot \
|
||||
doc/figs/example-reduce.dot doc/figs/example-shift.dot
|
||||
EXTRA_DIST += \
|
||||
$(FIGS_DOT) \
|
||||
$(FIGS_DOT:.dot=.eps) $(FIGS_DOT:.dot=.pdf) $(FIGS_DOT:.dot=.png)
|
||||
SUFFIXES += .dot .eps .pdf .png
|
||||
FIGS_GV = \
|
||||
doc/figs/example.gv \
|
||||
doc/figs/example-reduce.gv doc/figs/example-shift.gv
|
||||
EXTRA_DIST += \
|
||||
$(FIGS_GV) $(FIGS_GV:.gv=.txt) \
|
||||
$(FIGS_GV:.gv=.eps) $(FIGS_GV:.gv=.pdf) $(FIGS_GV:.gv=.png)
|
||||
SUFFIXES += .gv .eps .pdf .png
|
||||
|
||||
.dot.eps:
|
||||
.gv.eps:
|
||||
$(AM_V_GEN) $(MKDIR_P) `echo "./$@" | sed -e 's,/[^/]*$$,,'`
|
||||
$(AM_V_at) $(DOT) -Gmargin=0 -Teps $< >$@.tmp
|
||||
$(AM_V_at) mv $@.tmp $@
|
||||
|
||||
.dot.pdf:
|
||||
.gv.pdf:
|
||||
$(AM_V_GEN) $(MKDIR_P) `echo "./$@" | sed -e 's,/[^/]*$$,,'`
|
||||
$(AM_V_at) $(DOT) -Gmargin=0 -Tpdf $< >$@.tmp
|
||||
$(AM_V_at) mv $@.tmp $@
|
||||
|
||||
.dot.png:
|
||||
.gv.png:
|
||||
$(AM_V_GEN) $(MKDIR_P) `echo "./$@" | sed -e 's,/[^/]*$$,,'`
|
||||
$(AM_V_at) $(DOT) -Gmargin=0 -Tpng $< >$@.tmp
|
||||
$(AM_V_at) mv $@.tmp $@
|
||||
|
||||
+2
-2
@@ -204,9 +204,9 @@ Format the list of directives for Bison for bench named C<$bench>.
|
||||
sub directives($@)
|
||||
{
|
||||
my ($bench, @directive) = @_;
|
||||
my $res = "/* Directives for bench `$bench'. */\n";
|
||||
my $res = "/* Directives for bench '$bench'. */\n";
|
||||
$res .= join ("\n", @directive) . "\n";
|
||||
$res .= "/* End of directives for bench `$bench'. */\n";
|
||||
$res .= "/* End of directives for bench '$bench'. */\n";
|
||||
return $res;
|
||||
}
|
||||
|
||||
|
||||
+32
-31
@@ -19,7 +19,7 @@
|
||||
|
||||
# Don't depend on $(BISON) otherwise we would rebuild these files
|
||||
# in srcdir, including during distcheck, which is forbidden.
|
||||
examples/calc++/calc++-parser.stamp: $(BISON_IN)
|
||||
%D%/calc++-parser.stamp: $(BISON_IN)
|
||||
SUFFIXES += .yy .stamp
|
||||
.yy.stamp:
|
||||
$(AM_V_YACC)rm -f $@
|
||||
@@ -27,14 +27,14 @@ SUFFIXES += .yy .stamp
|
||||
$(AM_V_at)$(YACCCOMPILE) -o $*.cc $<
|
||||
$(AM_V_at)mv -f $@.tmp $@
|
||||
|
||||
$(calc_sources_generated): examples/calc++/calc++-parser.stamp
|
||||
@test -f $@ || rm -f examples/calc++/calc++-parser.stamp
|
||||
@test -f $@ || $(MAKE) $(AM_MAKEFLAGS) examples/calc++/calc++-parser.stamp
|
||||
$(calc_sources_generated): %D%/calc++-parser.stamp
|
||||
@test -f $@ || rm -f %D%/calc++-parser.stamp
|
||||
@test -f $@ || $(MAKE) $(AM_MAKEFLAGS) %D%/calc++-parser.stamp
|
||||
CLEANFILES += \
|
||||
$(calc_sources_generated) \
|
||||
examples/calc++/calc++-parser.output \
|
||||
examples/calc++/calc++-parser.stamp \
|
||||
examples/calc++/calc++-scanner.cc
|
||||
%D%/calc++-parser.output \
|
||||
%D%/calc++-parser.stamp \
|
||||
%D%/calc++-scanner.cc
|
||||
|
||||
|
||||
## -------------------- ##
|
||||
@@ -42,34 +42,35 @@ CLEANFILES += \
|
||||
## -------------------- ##
|
||||
|
||||
# Avoid using BUILT_SOURCES which is too global.
|
||||
$(examples_calc___calc___OBJECTS): $(calc_sources_generated)
|
||||
$(%C%_calc___OBJECTS): $(calc_sources_generated)
|
||||
|
||||
calc_sources_extracted = \
|
||||
examples/calc++/calc++-driver.cc \
|
||||
examples/calc++/calc++-driver.hh \
|
||||
examples/calc++/calc++-scanner.ll \
|
||||
examples/calc++/calc++.cc
|
||||
calc_extracted = \
|
||||
$(calc_sources_extracted) \
|
||||
examples/calc++/calc++-parser.yy
|
||||
calc_sources_extracted = \
|
||||
%D%/calc++-driver.cc \
|
||||
%D%/calc++-driver.hh \
|
||||
%D%/calc++-scanner.ll \
|
||||
%D%/calc++.cc
|
||||
calc_extracted = \
|
||||
$(calc_sources_extracted) \
|
||||
%D%/calc++-parser.yy
|
||||
extracted += $(calc_extracted)
|
||||
calc_sources_generated = \
|
||||
examples/calc++/calc++-parser.cc \
|
||||
examples/calc++/calc++-parser.hh \
|
||||
examples/calc++/location.hh \
|
||||
examples/calc++/position.hh \
|
||||
examples/calc++/stack.hh
|
||||
calc_sources = \
|
||||
$(calc_sources_extracted) \
|
||||
calc_sources_generated = \
|
||||
%D%/calc++-parser.cc \
|
||||
%D%/calc++-parser.hh \
|
||||
%D%/location.hh \
|
||||
%D%/position.hh \
|
||||
%D%/stack.hh
|
||||
calc_sources = \
|
||||
$(calc_sources_extracted) \
|
||||
$(calc_sources_generated)
|
||||
|
||||
if BISON_CXX_WORKS
|
||||
check_PROGRAMS += examples/calc++/calc++
|
||||
nodist_examples_calc___calc___SOURCES = \
|
||||
if FLEX_CXX_WORKS
|
||||
check_PROGRAMS += %D%/calc++
|
||||
nodist_%C%_calc___SOURCES = \
|
||||
$(calc_sources)
|
||||
|
||||
examples_calc___calc___CPPFLAGS = -I$(top_builddir)/examples/calc++
|
||||
examples_calc___calc___CXXFLAGS = \
|
||||
$(AM_CXXFLAGS) $(WARN_NO_NULL_CONVERSION_CXXFLAGS)
|
||||
dist_TESTS += examples/calc++/calc++.test
|
||||
%C%_calc___CPPFLAGS = -I$(top_builddir)/%D%
|
||||
%C%_calc___CXXFLAGS = $(AM_CXXFLAGS) $(FLEX_SCANNER_CXXFLAGS)
|
||||
dist_TESTS += %D%/calc++.test
|
||||
else
|
||||
EXTRA_DIST += %D%/calc++.test
|
||||
endif
|
||||
|
||||
+12
-13
@@ -13,11 +13,10 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
dist_noinst_SCRIPTS = examples/extexi examples/test
|
||||
TEST_LOG_COMPILER = $(top_srcdir)/examples/test
|
||||
dist_noinst_SCRIPTS = %D%/extexi %D%/test
|
||||
TEST_LOG_COMPILER = $(top_srcdir)/%D%/test
|
||||
|
||||
AM_CXXFLAGS = \
|
||||
$(NO_STRICT_ALIAS_CXXFLAGS) \
|
||||
$(WARN_CXXFLAGS) $(WARN_CXXFLAGS_TEST) $(WERROR_CXXFLAGS)
|
||||
|
||||
## ------------ ##
|
||||
@@ -25,20 +24,20 @@ AM_CXXFLAGS = \
|
||||
## ------------ ##
|
||||
|
||||
doc = $(top_srcdir)/doc/bison.texi
|
||||
extexi = $(top_srcdir)/examples/extexi
|
||||
extract = VERSION="$(VERSION)" $(PERL) -f $(extexi) $(doc) --
|
||||
extexi = $(top_srcdir)/%D%/extexi
|
||||
extract = VERSION="$(VERSION)" $(PERL) $(extexi) $(doc) --
|
||||
extracted =
|
||||
CLEANFILES += $(extracted) examples/extracted.stamp
|
||||
examples/extracted.stamp: $(doc) $(extexi)
|
||||
CLEANFILES += $(extracted) %D%/extracted.stamp
|
||||
%D%/extracted.stamp: $(doc) $(extexi)
|
||||
$(AM_V_GEN)rm -f $@ $@.tmp
|
||||
$(AM_V_at)touch $@.tmp
|
||||
$(AM_V_at)$(extract) $(extracted)
|
||||
$(AM_V_at)mv $@.tmp $@
|
||||
|
||||
$(extracted): examples/extracted.stamp
|
||||
@test -f $@ || rm -f examples/extracted.stamp
|
||||
@test -f $@ || $(MAKE) $(AM_MAKEFLAGS) examples/extracted.stamp
|
||||
$(extracted): %D%/extracted.stamp
|
||||
@test -f $@ || rm -f %D%/extracted.stamp
|
||||
@test -f $@ || $(MAKE) $(AM_MAKEFLAGS) %D%/extracted.stamp
|
||||
|
||||
include examples/calc++/local.mk
|
||||
include examples/mfcalc/local.mk
|
||||
include examples/rpcalc/local.mk
|
||||
include %D%/calc++/local.mk
|
||||
include %D%/mfcalc/local.mk
|
||||
include %D%/rpcalc/local.mk
|
||||
|
||||
@@ -18,19 +18,15 @@
|
||||
## -------------------- ##
|
||||
|
||||
BUILT_SOURCES += $(mfcalc_sources)
|
||||
CLEANFILES += examples/mfcalc/mfcalc.[ch] examples/mfcalc/mfcalc.output
|
||||
CLEANFILES += %D%/mfcalc.[ch] %D%/mfcalc.output
|
||||
|
||||
mfcalc_extracted = \
|
||||
examples/mfcalc/calc.h \
|
||||
examples/mfcalc/mfcalc.y
|
||||
mfcalc_sources = \
|
||||
$(mfcalc_extracted)
|
||||
mfcalc_extracted = %D%/calc.h %D%/mfcalc.y
|
||||
mfcalc_sources = $(mfcalc_extracted)
|
||||
extracted += $(mfcalc_extracted)
|
||||
|
||||
check_PROGRAMS += examples/mfcalc/mfcalc
|
||||
examples_mfcalc_mfcalc_LDADD = -lm
|
||||
nodist_examples_mfcalc_mfcalc_SOURCES = \
|
||||
$(mfcalc_sources)
|
||||
check_PROGRAMS += %D%/mfcalc
|
||||
%C%_mfcalc_LDADD = -lm
|
||||
nodist_%C%_mfcalc_SOURCES = $(mfcalc_sources)
|
||||
|
||||
examples_mfcalc_mfcalc_CPPFLAGS = -I$(top_builddir)/examples/mfcalc
|
||||
dist_TESTS += examples/mfcalc/mfcalc.test
|
||||
%C%_mfcalc_CPPFLAGS = -I$(top_builddir)/%D%
|
||||
dist_TESTS += %D%/mfcalc.test
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
/calc.h
|
||||
/rpcalc
|
||||
/rpcalc.c
|
||||
/rpcalc.h
|
||||
/rpcalc.output
|
||||
|
||||
@@ -18,18 +18,15 @@
|
||||
## -------------------- ##
|
||||
|
||||
BUILT_SOURCES += $(rpcalc_sources)
|
||||
CLEANFILES += examples/rpcalc/rpcalc.[ch] examples/rpcalc/rpcalc.output
|
||||
CLEANFILES += %D%/rpcalc.[ch] %D%/rpcalc.output
|
||||
|
||||
rpcalc_extracted = \
|
||||
examples/rpcalc/rpcalc.y
|
||||
rpcalc_sources = \
|
||||
$(rpcalc_extracted)
|
||||
rpcalc_extracted = %D%/rpcalc.y
|
||||
rpcalc_sources = $(rpcalc_extracted)
|
||||
extracted += $(rpcalc_extracted)
|
||||
|
||||
check_PROGRAMS += examples/rpcalc/rpcalc
|
||||
examples_rpcalc_rpcalc_LDADD = -lm
|
||||
nodist_examples_rpcalc_rpcalc_SOURCES = \
|
||||
$(rpcalc_sources)
|
||||
check_PROGRAMS += %D%/rpcalc
|
||||
%C%_rpcalc_LDADD = -lm
|
||||
nodist_%C%_rpcalc_SOURCES = $(rpcalc_sources)
|
||||
|
||||
examples_rpcalc_rpcalc_CPPFLAGS = -I$(top_builddir)/examples/rpcalc
|
||||
dist_TESTS += examples/rpcalc/rpcalc.test
|
||||
%C%_rpcalc_CPPFLAGS = -I$(top_builddir)/%D%
|
||||
dist_TESTS += %D%/rpcalc.test
|
||||
|
||||
+11
-5
@@ -16,7 +16,7 @@
|
||||
*/
|
||||
|
||||
%debug
|
||||
%skeleton "lalr1.cc"
|
||||
%language "c++"
|
||||
%defines
|
||||
%define api.token.constructor
|
||||
%define api.value.type variant
|
||||
@@ -48,11 +48,17 @@ typedef std::list<std::string> strings_type;
|
||||
namespace std
|
||||
{
|
||||
std::ostream&
|
||||
operator<< (std::ostream& o, const strings_type& s)
|
||||
operator<< (std::ostream& o, const strings_type& ss)
|
||||
{
|
||||
std::copy (s.begin (), s.end (),
|
||||
std::ostream_iterator<strings_type::value_type> (o, "\n"));
|
||||
return o;
|
||||
o << "(" << &ss << ") {";
|
||||
const char *sep = "";
|
||||
for (strings_type::const_iterator i = ss.begin(), end = ss.end();
|
||||
i != end; ++i)
|
||||
{
|
||||
o << sep << *i;
|
||||
sep = ", ";
|
||||
}
|
||||
return o << "}";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
Submodule gnulib updated: c67e3c0414...74540d44dc
@@ -272,3 +272,5 @@
|
||||
/sig-handler.c
|
||||
/unistd.c
|
||||
/wctype-h.c
|
||||
/lstat.c
|
||||
/unlink.c
|
||||
|
||||
+1
-1
@@ -17,7 +17,7 @@
|
||||
|
||||
|
||||
/* Bison depends on libiberty's implementation of bitsets, which
|
||||
requires a `libiberty.h' file. This file provides the minimum
|
||||
requires a 'libiberty.h' file. This file provides the minimum
|
||||
services. */
|
||||
|
||||
#ifndef BISON_LIBIBERTY_H_
|
||||
|
||||
+3
-1
@@ -51,6 +51,8 @@ lib_libbison_a_SOURCES += \
|
||||
lib/get-errno.c
|
||||
|
||||
# The Yacc compatibility library.
|
||||
lib_LIBRARIES = $(YACC_LIBRARY)
|
||||
if ENABLE_YACC
|
||||
lib_LIBRARIES = lib/liby.a
|
||||
EXTRA_LIBRARIES = lib/liby.a
|
||||
lib_liby_a_SOURCES = lib/main.c lib/yyerror.c
|
||||
endif
|
||||
|
||||
+1
-1
@@ -36,7 +36,7 @@
|
||||
Timing variables may be pushed onto the stack; elapsed time is
|
||||
attributed to the topmost timing variable on the stack. When
|
||||
another variable is pushed on, the previous topmost variable is
|
||||
`paused' until the pushed variable is popped back off.
|
||||
'paused' until the pushed variable is popped back off.
|
||||
|
||||
- As a standalone timer, using timevar_start and timevar_stop.
|
||||
All time elapsed between the two calls is attributed to the
|
||||
|
||||
@@ -180,3 +180,6 @@
|
||||
/obstack-printf.m4
|
||||
/extern-inline.m4
|
||||
/non-recursive-gnulib-prefix-hack.m4
|
||||
/absolute-header.m4
|
||||
/lstat.m4
|
||||
/unlink.m4
|
||||
|
||||
@@ -541,9 +541,13 @@ AnnotationList__compute_from_inadequacies (
|
||||
{
|
||||
InadequacyList__prependTo (conflict_node,
|
||||
&inadequacy_lists[s->number]);
|
||||
aver (AnnotationList__insertInto (
|
||||
annotation_node, &annotation_lists[s->number],
|
||||
s->nitems));
|
||||
{
|
||||
bool b =
|
||||
AnnotationList__insertInto (annotation_node,
|
||||
&annotation_lists[s->number],
|
||||
s->nitems);
|
||||
aver (b);
|
||||
}
|
||||
/* This aver makes sure the
|
||||
AnnotationList__computeDominantContribution check above
|
||||
does discard annotations in the simplest case of a S/R
|
||||
|
||||
+1
-1
@@ -60,7 +60,7 @@ Sbitset__isEmpty (Sbitset self, Sbitset__Index nbits)
|
||||
}
|
||||
|
||||
void
|
||||
Sbitset__fprint(Sbitset self, Sbitset__Index nbits, FILE *file)
|
||||
Sbitset__fprint (Sbitset self, Sbitset__Index nbits, FILE *file)
|
||||
{
|
||||
Sbitset__Index i;
|
||||
Sbitset itr;
|
||||
|
||||
+6
-6
@@ -44,31 +44,31 @@ void Sbitset__delete (Sbitset self);
|
||||
|
||||
bool Sbitset__isEmpty (Sbitset self, Sbitset__Index nbits);
|
||||
|
||||
void Sbitset__fprint(Sbitset self, Sbitset__Index nbits, FILE *file);
|
||||
void Sbitset__fprint (Sbitset self, Sbitset__Index nbits, FILE *file);
|
||||
|
||||
# define Sbitset__set(SELF, INDEX) \
|
||||
do { \
|
||||
*Sbitset__byteAddress ((SELF), (INDEX)) = \
|
||||
*Sbitset__byteAddress ((SELF), (INDEX)) | Sbitset__bit_mask (INDEX); \
|
||||
} while(0)
|
||||
} while (0)
|
||||
|
||||
# define Sbitset__reset(SELF, INDEX) \
|
||||
do { \
|
||||
*Sbitset__byteAddress ((SELF), (INDEX)) = \
|
||||
*Sbitset__byteAddress ((SELF), (INDEX)) & ~Sbitset__bit_mask (INDEX); \
|
||||
} while(0)
|
||||
} while (0)
|
||||
|
||||
/* NBITS is the size of the bitset. More than NBITS bits might be reset. */
|
||||
# define Sbitset__zero(SELF, NBITS) \
|
||||
do { \
|
||||
memset (SELF, 0, Sbitset__nbytes (NBITS)); \
|
||||
} while(0)
|
||||
} while (0)
|
||||
|
||||
/* NBITS is the size of the bitset. More than NBITS bits might be set. */
|
||||
# define Sbitset__ones(SELF, NBITS) \
|
||||
do { \
|
||||
memset (SELF, UCHAR_MAX, Sbitset__nbytes (NBITS)); \
|
||||
} while(0)
|
||||
} while (0)
|
||||
|
||||
/* NBITS is the size of every bitset. More than NBITS bits might be set. */
|
||||
# define Sbitset__or(SELF, OTHER1, OTHER2, NBITS) \
|
||||
@@ -79,7 +79,7 @@ void Sbitset__fprint(Sbitset self, Sbitset__Index nbits, FILE *file);
|
||||
Sbitset end_self = ptr_self + Sbitset__nbytes (NBITS); \
|
||||
for (; ptr_self < end_self; ++ptr_self, ++ptr_other1, ++ptr_other2) \
|
||||
*ptr_self = *ptr_other1 | *ptr_other2; \
|
||||
} while(0)
|
||||
} while (0)
|
||||
|
||||
# define SBITSET__FOR_EACH(SELF, NBITS, ITER, INDEX) \
|
||||
for ((ITER) = (SELF); (ITER) < (SELF) + Sbitset__nbytes (NBITS); ++(ITER)) \
|
||||
|
||||
+243
-46
@@ -22,6 +22,7 @@
|
||||
#include <config.h>
|
||||
#include "system.h"
|
||||
|
||||
#include <argmatch.h>
|
||||
#include <stdarg.h>
|
||||
#include <progname.h>
|
||||
|
||||
@@ -30,42 +31,223 @@
|
||||
#include "getargs.h"
|
||||
#include "quote.h"
|
||||
|
||||
warnings warnings_flag =
|
||||
Wconflicts_sr | Wconflicts_rr | Wdeprecated | Wother;
|
||||
|
||||
warnings errors_flag;
|
||||
|
||||
err_status complaint_status = status_none;
|
||||
|
||||
bool warnings_are_errors = false;
|
||||
|
||||
/** Whether -Werror/-Wno-error was applied to a warning. */
|
||||
typedef enum
|
||||
{
|
||||
errority_unset = 0, /** No explict status. */
|
||||
errority_disabled = 1, /** Explictly disabled with -Wno-error=foo. */
|
||||
errority_enabled = 2 /** Explictly enabled with -Werror=foo. */
|
||||
} errority;
|
||||
|
||||
/** For each warning type, its errority. */
|
||||
static errority errority_flag[warnings_size];
|
||||
|
||||
/** Diagnostics severity. */
|
||||
typedef enum
|
||||
{
|
||||
severity_disabled = 0, /**< Explicitly disabled via -Wno-foo. */
|
||||
severity_unset = 1, /**< Unspecified status. */
|
||||
severity_warning = 2, /**< A warning. */
|
||||
severity_error = 3, /**< An error (continue, but die soon). */
|
||||
severity_fatal = 4 /**< Fatal error (die now). */
|
||||
} severity;
|
||||
|
||||
|
||||
/** For each warning type, its severity. */
|
||||
static severity warnings_flag[warnings_size];
|
||||
|
||||
static unsigned *indent_ptr = 0;
|
||||
|
||||
void
|
||||
warnings_print_categories (warnings warn_flags)
|
||||
{
|
||||
if (! (warn_flags & silent))
|
||||
{
|
||||
char const *warn_names[] =
|
||||
{
|
||||
"midrule-values",
|
||||
"yacc",
|
||||
"conflicts-sr",
|
||||
"conflicts-rr",
|
||||
"deprecated",
|
||||
"other"
|
||||
};
|
||||
/*------------------------.
|
||||
| --warnings's handling. |
|
||||
`------------------------*/
|
||||
|
||||
bool any = false;
|
||||
int i;
|
||||
for (i = 0; i < ARRAY_CARDINALITY (warn_names); ++i)
|
||||
if (warn_flags & 1 << i)
|
||||
{
|
||||
bool err = warn_flags & errors_flag;
|
||||
fprintf (stderr, "%s-W", any ? ", " : " [");
|
||||
fprintf (stderr, "%s%s", err ? "error=" : "" , warn_names[i]);
|
||||
any = true;
|
||||
}
|
||||
if (any)
|
||||
fprintf (stderr, "]");
|
||||
static const char * const warnings_args[] =
|
||||
{
|
||||
"none",
|
||||
"midrule-values",
|
||||
"yacc",
|
||||
"conflicts-sr",
|
||||
"conflicts-rr",
|
||||
"deprecated",
|
||||
"empty-rule",
|
||||
"precedence",
|
||||
"other",
|
||||
"all",
|
||||
"error",
|
||||
"everything",
|
||||
0
|
||||
};
|
||||
|
||||
static const int warnings_types[] =
|
||||
{
|
||||
Wnone,
|
||||
Wmidrule_values,
|
||||
Wyacc,
|
||||
Wconflicts_sr,
|
||||
Wconflicts_rr,
|
||||
Wdeprecated,
|
||||
Wempty_rule,
|
||||
Wprecedence,
|
||||
Wother,
|
||||
Wall,
|
||||
Werror,
|
||||
Weverything
|
||||
};
|
||||
|
||||
ARGMATCH_VERIFY (warnings_args, warnings_types);
|
||||
|
||||
void
|
||||
warning_argmatch (char const *arg, size_t no, size_t err)
|
||||
{
|
||||
int value = XARGMATCH ("--warning", arg + no + err,
|
||||
warnings_args, warnings_types);
|
||||
|
||||
/* -Wnone == -Wno-everything, and -Wno-none == -Weverything. */
|
||||
if (!value)
|
||||
{
|
||||
value = Weverything;
|
||||
no = !no;
|
||||
}
|
||||
|
||||
size_t b;
|
||||
for (b = 0; b < warnings_size; ++b)
|
||||
if (value & 1 << b)
|
||||
{
|
||||
if (err && no)
|
||||
/* -Wno-error=foo. */
|
||||
errority_flag[b] = errority_disabled;
|
||||
else if (err && !no)
|
||||
{
|
||||
/* -Werror=foo: enables -Wfoo. */
|
||||
errority_flag[b] = errority_enabled;
|
||||
warnings_flag[b] = severity_warning;
|
||||
}
|
||||
else if (no)
|
||||
/* -Wno-foo. */
|
||||
warnings_flag[b] = severity_disabled;
|
||||
else
|
||||
/* -Wfoo. */
|
||||
warnings_flag[b] = severity_warning;
|
||||
}
|
||||
}
|
||||
|
||||
/** Decode a comma-separated list of arguments from -W.
|
||||
*
|
||||
* \param args comma separated list of effective subarguments to decode.
|
||||
* If 0, then activate all the flags.
|
||||
*/
|
||||
|
||||
void
|
||||
warnings_argmatch (char *args)
|
||||
{
|
||||
if (args)
|
||||
for (args = strtok (args, ","); args; args = strtok (NULL, ","))
|
||||
if (STREQ (args, "error"))
|
||||
warnings_are_errors = true;
|
||||
else if (STREQ (args, "no-error"))
|
||||
warnings_are_errors = false;
|
||||
else
|
||||
{
|
||||
/* The length of the possible 'no-' prefix: 3, or 0. */
|
||||
size_t no = STRPREFIX_LIT ("no-", args) ? 3 : 0;
|
||||
/* The length of the possible 'error=' (possibly after
|
||||
'no-') prefix: 6, or 0. */
|
||||
size_t err = STRPREFIX_LIT ("error=", args + no) ? 6 : 0;
|
||||
|
||||
warning_argmatch (args, no, err);
|
||||
}
|
||||
else
|
||||
warning_argmatch ("all", 0, 0);
|
||||
}
|
||||
|
||||
|
||||
/*-----------.
|
||||
| complain. |
|
||||
`-----------*/
|
||||
|
||||
void
|
||||
complain_init (void)
|
||||
{
|
||||
warnings warnings_default =
|
||||
Wconflicts_sr | Wconflicts_rr | Wdeprecated | Wother;
|
||||
|
||||
size_t b;
|
||||
for (b = 0; b < warnings_size; ++b)
|
||||
{
|
||||
warnings_flag[b] = (1 << b & warnings_default
|
||||
? severity_warning
|
||||
: severity_unset);
|
||||
errority_flag[b] = errority_unset;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* A diagnostic with FLAGS is about to be issued. With what severity?
|
||||
(severity_fatal, severity_error, severity_disabled, or
|
||||
severity_warning.) */
|
||||
|
||||
static severity
|
||||
warning_severity (warnings flags)
|
||||
{
|
||||
if (flags & fatal)
|
||||
/* Diagnostics about fatal errors. */
|
||||
return severity_fatal;
|
||||
else if (flags & complaint)
|
||||
/* Diagnostics about errors. */
|
||||
return severity_error;
|
||||
else
|
||||
{
|
||||
/* Diagnostics about warnings. */
|
||||
severity res = severity_disabled;
|
||||
size_t b;
|
||||
for (b = 0; b < warnings_size; ++b)
|
||||
if (flags & 1 << b)
|
||||
{
|
||||
res = res < warnings_flag[b] ? warnings_flag[b] : res;
|
||||
/* If the diagnostic is enabled, and -Werror is enabled,
|
||||
and -Wno-error=foo was not explicitly requested, this
|
||||
is an error. */
|
||||
if (res == severity_warning
|
||||
&& (errority_flag[b] == errority_enabled
|
||||
|| (warnings_are_errors
|
||||
&& errority_flag[b] != errority_disabled)))
|
||||
res = severity_error;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
warning_is_unset (warnings flags)
|
||||
{
|
||||
size_t b;
|
||||
for (b = 0; b < warnings_size; ++b)
|
||||
if (flags & 1 << b && warnings_flag[b] != severity_unset)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Display a "[-Wyacc]" like message on \a f. */
|
||||
|
||||
static void
|
||||
warnings_print_categories (warnings warn_flags, FILE *f)
|
||||
{
|
||||
/* Display only the first match, the second is "-Wall". */
|
||||
size_t i;
|
||||
for (i = 0; warnings_args[i]; ++i)
|
||||
if (warn_flags & warnings_types[i])
|
||||
{
|
||||
severity s = warning_severity (warnings_types[i]);
|
||||
fprintf (f, " [-W%s%s]",
|
||||
s == severity_error ? "error=" : "",
|
||||
warnings_args[i]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/** Report an error message.
|
||||
@@ -88,7 +270,7 @@ error_message (const location *loc, warnings flags, const char *prefix,
|
||||
unsigned pos = 0;
|
||||
|
||||
if (loc)
|
||||
pos += location_print (stderr, *loc);
|
||||
pos += location_print (*loc, stderr);
|
||||
else
|
||||
pos += fprintf (stderr, "%s", current_file ? current_file : program_name);
|
||||
pos += fprintf (stderr, ": ");
|
||||
@@ -108,7 +290,8 @@ error_message (const location *loc, warnings flags, const char *prefix,
|
||||
fprintf (stderr, "%s: ", prefix);
|
||||
|
||||
vfprintf (stderr, message, args);
|
||||
warnings_print_categories (flags);
|
||||
if (! (flags & silent))
|
||||
warnings_print_categories (flags, stderr);
|
||||
{
|
||||
size_t l = strlen (message);
|
||||
if (l < 2 || message[l - 2] != ':' || message[l - 1] != ' ')
|
||||
@@ -116,29 +299,34 @@ error_message (const location *loc, warnings flags, const char *prefix,
|
||||
putc ('\n', stderr);
|
||||
fflush (stderr);
|
||||
if (loc && feature_flag & feature_caret && !(flags & no_caret))
|
||||
location_caret (stderr, *loc);
|
||||
location_caret (*loc, stderr);
|
||||
}
|
||||
}
|
||||
fflush (stderr);
|
||||
}
|
||||
|
||||
/** Raise a complaint. That can be a fatal error, a complaint or just a
|
||||
/** Raise a complaint. That can be a fatal error, an error or just a
|
||||
warning. */
|
||||
static inline void
|
||||
|
||||
static void
|
||||
complains (const location *loc, warnings flags, const char *message,
|
||||
va_list args)
|
||||
{
|
||||
const char* prefix =
|
||||
flags & fatal ? _("fatal error")
|
||||
: flags & (errors_flag | complaint) ? _("error")
|
||||
: _("warning");
|
||||
|
||||
severity s = warning_severity (flags);
|
||||
if ((flags & complaint) && complaint_status < status_complaint)
|
||||
complaint_status = status_complaint;
|
||||
else if ((flags & (warnings_flag & errors_flag)) && ! complaint_status)
|
||||
complaint_status = status_warning_as_error;
|
||||
if (flags & (warnings_flag | fatal | complaint))
|
||||
error_message (loc, flags, prefix, message, args);
|
||||
|
||||
if (severity_warning <= s)
|
||||
{
|
||||
const char* prefix =
|
||||
s == severity_fatal ? _("fatal error")
|
||||
: s == severity_error ? _("error")
|
||||
: _("warning");
|
||||
if (severity_error <= s && ! complaint_status)
|
||||
complaint_status = status_warning_as_error;
|
||||
error_message (loc, flags, prefix, message, args);
|
||||
}
|
||||
|
||||
if (flags & fatal)
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
@@ -189,7 +377,6 @@ complain_args (location const *loc, warnings w, unsigned *indent,
|
||||
complain (loc, fatal, "too many arguments for complains");
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
@@ -204,3 +391,13 @@ deprecated_directive (location const *loc, char const *old, char const *upd)
|
||||
_("deprecated directive: %s, use %s"),
|
||||
quote (old), quote_n (1, upd));
|
||||
}
|
||||
|
||||
void
|
||||
duplicate_directive (char const *directive,
|
||||
location first, location second)
|
||||
{
|
||||
unsigned i = 0;
|
||||
complain (&second, complaint, _("only one %s allowed per rule"), directive);
|
||||
i += SUB_INDENT;
|
||||
complain_indent (&first, complaint, &i, _("previous declaration"));
|
||||
}
|
||||
|
||||
+74
-22
@@ -28,15 +28,67 @@
|
||||
| --warnings. |
|
||||
`-------------*/
|
||||
|
||||
/** The bits assigned to each warning type. */
|
||||
typedef enum
|
||||
{
|
||||
Wnone = 0, /**< Issue no warnings. */
|
||||
Wmidrule_values = 1 << 0, /**< Unset or unused midrule values. */
|
||||
Wyacc = 1 << 1, /**< POSIXME. */
|
||||
Wconflicts_sr = 1 << 2, /**< S/R conflicts. */
|
||||
Wconflicts_rr = 1 << 3, /**< R/R conflicts. */
|
||||
Wdeprecated = 1 << 4, /**< Obsolete constructs. */
|
||||
Wother = 1 << 5, /**< All other warnings. */
|
||||
warning_midrule_values, /**< Unset or unused midrule values. */
|
||||
warning_yacc, /**< POSIXME. */
|
||||
warning_conflicts_sr, /**< S/R conflicts. */
|
||||
warning_conflicts_rr, /**< R/R conflicts. */
|
||||
warning_empty_rule, /**< Implicitly empty rules. */
|
||||
warning_deprecated, /**< Obsolete constructs. */
|
||||
warning_precedence, /**< Useless precedence and associativity. */
|
||||
warning_other, /**< All other warnings. */
|
||||
|
||||
warnings_size /**< The number of warnings. Must be last. */
|
||||
} warning_bit;
|
||||
|
||||
/** Whether -Werror was set. */
|
||||
extern bool warnings_are_errors;
|
||||
|
||||
/** Decode a single argument from -W.
|
||||
*
|
||||
* \param arg the subarguments to decode.
|
||||
* If null, then activate all the flags.
|
||||
* \param no length of the potential "no-" prefix.
|
||||
* Can be 0 or 3. If 3, negate the action of the subargument.
|
||||
* \param err length of a potential "error=".
|
||||
* Can be 0 or 6. If 6, treat the subargument as a CATEGORY.
|
||||
*
|
||||
* If VALUE != 0 then KEY sets flags and no-KEY clears them.
|
||||
* If VALUE == 0 then KEY clears all flags from \c all and no-KEY sets all
|
||||
* flags from \c all. Thus no-none = all and no-all = none.
|
||||
*/
|
||||
void warning_argmatch (char const *arg, size_t no, size_t err);
|
||||
|
||||
/** Decode a comma-separated list of arguments from -W.
|
||||
*
|
||||
* \param args comma separated list of effective subarguments to decode.
|
||||
* If 0, then activate all the flags.
|
||||
*/
|
||||
void warnings_argmatch (char *args);
|
||||
|
||||
|
||||
/*-----------.
|
||||
| complain. |
|
||||
`-----------*/
|
||||
|
||||
/** Initialize this module. */
|
||||
void complain_init (void);
|
||||
|
||||
typedef enum
|
||||
{
|
||||
/**< Issue no warnings. */
|
||||
Wnone = 0,
|
||||
|
||||
Wmidrule_values = 1 << warning_midrule_values,
|
||||
Wyacc = 1 << warning_yacc,
|
||||
Wconflicts_sr = 1 << warning_conflicts_sr,
|
||||
Wconflicts_rr = 1 << warning_conflicts_rr,
|
||||
Wdeprecated = 1 << warning_deprecated,
|
||||
Wempty_rule = 1 << warning_empty_rule,
|
||||
Wprecedence = 1 << warning_precedence,
|
||||
Wother = 1 << warning_other,
|
||||
|
||||
Werror = 1 << 10, /** This bit is no longer used. */
|
||||
|
||||
@@ -46,17 +98,13 @@ typedef enum
|
||||
no_caret = 1 << 14, /**< Do not display caret location. */
|
||||
|
||||
/**< All above warnings. */
|
||||
Wall = ~complaint & ~fatal & ~silent
|
||||
Weverything = ~complaint & ~fatal & ~silent,
|
||||
Wall = Weverything & ~Wyacc
|
||||
} warnings;
|
||||
|
||||
/** What warnings are issued. */
|
||||
extern warnings warnings_flag;
|
||||
|
||||
/** What warnings are made errors. */
|
||||
extern warnings errors_flag;
|
||||
|
||||
/** Display a "[-Wyacc]" like message on stderr. */
|
||||
void warnings_print_categories (warnings warn_flags);
|
||||
/** Whether the warnings of \a flags are all unset.
|
||||
(Never enabled, never disabled). */
|
||||
bool warning_is_unset (warnings flags);
|
||||
|
||||
/** Make a complaint, with maybe a location. */
|
||||
void complain (location const *loc, warnings flags, char const *message, ...)
|
||||
@@ -76,14 +124,18 @@ void complain_indent (location const *loc, warnings flags, unsigned *indent,
|
||||
void deprecated_directive (location const *loc,
|
||||
char const *obsolete, char const *updated);
|
||||
|
||||
/** Warnings treated as errors shouldn't stop the execution as regular errors
|
||||
should (because due to their nature, it is safe to go on). Thus, there are
|
||||
three possible execution statuses. */
|
||||
/** Report a repeated directive for a rule. */
|
||||
void duplicate_directive (char const *directive,
|
||||
location first, location second);
|
||||
|
||||
/** Warnings treated as errors shouldn't stop the execution as regular
|
||||
errors should (because due to their nature, it is safe to go
|
||||
on). Thus, there are three possible execution statuses. */
|
||||
typedef enum
|
||||
{
|
||||
status_none,
|
||||
status_warning_as_error,
|
||||
status_complaint
|
||||
status_none, /**< No diagnostic issued so far. */
|
||||
status_warning_as_error, /**< A warning was issued (but no error). */
|
||||
status_complaint /**< An error was issued. */
|
||||
} err_status;
|
||||
|
||||
/** Whether an error was reported. */
|
||||
|
||||
+1
-1
@@ -403,7 +403,7 @@ conflicts_solve (void)
|
||||
set_conflicts (states[i], errors);
|
||||
|
||||
/* For uniformity of the code, make sure all the states have a valid
|
||||
`errs' member. */
|
||||
'errs' member. */
|
||||
if (!states[i]->errs)
|
||||
states[i]->errs = errs_new (0, 0);
|
||||
}
|
||||
|
||||
+48
-28
@@ -34,7 +34,7 @@
|
||||
#include "getargs.h"
|
||||
#include "gram.h"
|
||||
|
||||
/* Initializing some values below (such SPEC_NAME_PREFIX to `yy') is
|
||||
/* Initializing some values below (such SPEC_NAME_PREFIX to 'yy') is
|
||||
tempting, but don't do that: for the time being our handling of the
|
||||
%directive vs --option leaves precedence to the options by deciding
|
||||
that if a %directive sets a variable which is really set (i.e., not
|
||||
@@ -51,27 +51,36 @@ char *spec_defines_file = NULL; /* for --defines. */
|
||||
char *parser_file_name;
|
||||
|
||||
/* All computed output file names. */
|
||||
static char **file_names = NULL;
|
||||
static int file_names_count = 0;
|
||||
typedef struct generated_file
|
||||
{
|
||||
/** File name. */
|
||||
char *name;
|
||||
/** Whether is a generated source file (e.g., *.c, *.java...), as
|
||||
opposed to the report file (e.g., *.output). When late errors
|
||||
are detected, generated source files are removed. */
|
||||
bool is_source;
|
||||
} generated_file;
|
||||
static generated_file *generated_files = NULL;
|
||||
static int generated_files_size = 0;
|
||||
|
||||
uniqstr grammar_file = NULL;
|
||||
uniqstr current_file = NULL;
|
||||
|
||||
/* If --output=dir/foo.c was specified,
|
||||
DIR_PREFIX is `dir/' and ALL_BUT_EXT and ALL_BUT_TAB_EXT are `dir/foo'.
|
||||
DIR_PREFIX is 'dir/' and ALL_BUT_EXT and ALL_BUT_TAB_EXT are 'dir/foo'.
|
||||
|
||||
If --output=dir/foo.tab.c was specified, DIR_PREFIX is `dir/',
|
||||
ALL_BUT_EXT is `dir/foo.tab', and ALL_BUT_TAB_EXT is `dir/foo'.
|
||||
If --output=dir/foo.tab.c was specified, DIR_PREFIX is 'dir/',
|
||||
ALL_BUT_EXT is 'dir/foo.tab', and ALL_BUT_TAB_EXT is 'dir/foo'.
|
||||
|
||||
If --output was not specified but --file-prefix=dir/foo was specified,
|
||||
ALL_BUT_EXT = `foo.tab' and ALL_BUT_TAB_EXT = `foo'.
|
||||
ALL_BUT_EXT = 'foo.tab' and ALL_BUT_TAB_EXT = 'foo'.
|
||||
|
||||
If neither --output nor --file was specified but the input grammar
|
||||
is name dir/foo.y, ALL_BUT_EXT and ALL_BUT_TAB_EXT are `foo'.
|
||||
is name dir/foo.y, ALL_BUT_EXT and ALL_BUT_TAB_EXT are 'foo'.
|
||||
|
||||
If neither --output nor --file was specified, DIR_PREFIX is the
|
||||
empty string (meaning the current directory); otherwise it is
|
||||
`dir/'. */
|
||||
'dir/'. */
|
||||
|
||||
char *all_but_ext;
|
||||
static char *all_but_tab_ext;
|
||||
@@ -79,7 +88,7 @@ char *dir_prefix;
|
||||
|
||||
/* C source file extension (the parser source). */
|
||||
static char *src_extension = NULL;
|
||||
/* Header file extension (if option ``-d'' is specified). */
|
||||
/* Header file extension (if option '`-d'' is specified). */
|
||||
static char *header_extension = NULL;
|
||||
|
||||
/*-----------------------------------------------------------------.
|
||||
@@ -191,7 +200,7 @@ compute_exts_from_src (const char *ext)
|
||||
*EXT points to the last period in the basename, or NULL if none.
|
||||
|
||||
If there is no *EXT, *TAB is NULL. Otherwise, *TAB points to
|
||||
`.tab' or `_tab' if present right before *EXT, or is NULL. *TAB
|
||||
'.tab' or '_tab' if present right before *EXT, or is NULL. *TAB
|
||||
cannot be equal to *BASE.
|
||||
|
||||
None are allocated, they are simply pointers to parts of FILE_NAME.
|
||||
@@ -222,7 +231,7 @@ file_name_split (const char *file_name,
|
||||
*ext = strrchr (*base, '.');
|
||||
*tab = NULL;
|
||||
|
||||
/* If there is an extension, check if there is a `.tab' part right
|
||||
/* If there is an extension, check if there is a '.tab' part right
|
||||
before. */
|
||||
if (*ext)
|
||||
{
|
||||
@@ -270,7 +279,7 @@ compute_file_name_parts (void)
|
||||
|
||||
if (spec_file_prefix)
|
||||
{
|
||||
/* If --file-prefix=foo was specified, ALL_BUT_TAB_EXT = `foo'. */
|
||||
/* If --file-prefix=foo was specified, ALL_BUT_TAB_EXT = 'foo'. */
|
||||
dir_prefix =
|
||||
xstrndup (spec_file_prefix,
|
||||
last_component (spec_file_prefix) - spec_file_prefix);
|
||||
@@ -278,14 +287,14 @@ compute_file_name_parts (void)
|
||||
}
|
||||
else if (yacc_flag)
|
||||
{
|
||||
/* If --yacc, then the output is `y.tab.c'. */
|
||||
/* If --yacc, then the output is 'y.tab.c'. */
|
||||
dir_prefix = xstrdup ("");
|
||||
all_but_tab_ext = xstrdup ("y");
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Otherwise, ALL_BUT_TAB_EXT is computed from the input
|
||||
grammar: `foo/bar.yy' => `bar'. */
|
||||
grammar: 'foo/bar.yy' => 'bar'. */
|
||||
dir_prefix = xstrdup ("");
|
||||
all_but_tab_ext =
|
||||
xstrndup (base, (strlen (base) - (ext ? strlen (ext) : 0)));
|
||||
@@ -332,21 +341,21 @@ compute_output_file_names (void)
|
||||
{
|
||||
if (! spec_graph_file)
|
||||
spec_graph_file = concat2 (all_but_tab_ext, ".dot");
|
||||
output_file_name_check (&spec_graph_file);
|
||||
output_file_name_check (&spec_graph_file, false);
|
||||
}
|
||||
|
||||
if (xml_flag)
|
||||
{
|
||||
if (! spec_xml_file)
|
||||
spec_xml_file = concat2 (all_but_tab_ext, ".xml");
|
||||
output_file_name_check (&spec_xml_file);
|
||||
output_file_name_check (&spec_xml_file, false);
|
||||
}
|
||||
|
||||
if (report_flag)
|
||||
{
|
||||
if (!spec_verbose_file)
|
||||
spec_verbose_file = concat2 (all_but_tab_ext, OUTPUT_EXT);
|
||||
output_file_name_check (&spec_verbose_file);
|
||||
output_file_name_check (&spec_verbose_file, false);
|
||||
}
|
||||
|
||||
free (all_but_tab_ext);
|
||||
@@ -355,7 +364,7 @@ compute_output_file_names (void)
|
||||
}
|
||||
|
||||
void
|
||||
output_file_name_check (char **file_name)
|
||||
output_file_name_check (char **file_name, bool source)
|
||||
{
|
||||
bool conflict = false;
|
||||
if (STREQ (*file_name, grammar_file))
|
||||
@@ -367,11 +376,11 @@ output_file_name_check (char **file_name)
|
||||
else
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < file_names_count; i++)
|
||||
if (STREQ (file_names[i], *file_name))
|
||||
for (i = 0; i < generated_files_size; i++)
|
||||
if (STREQ (generated_files[i].name, *file_name))
|
||||
{
|
||||
complain (NULL, Wother, _("conflicting outputs to file %s"),
|
||||
quote (*file_name));
|
||||
quote (generated_files[i].name));
|
||||
conflict = true;
|
||||
}
|
||||
}
|
||||
@@ -382,12 +391,23 @@ output_file_name_check (char **file_name)
|
||||
}
|
||||
else
|
||||
{
|
||||
file_names = xnrealloc (file_names, ++file_names_count,
|
||||
sizeof *file_names);
|
||||
file_names[file_names_count-1] = xstrdup (*file_name);
|
||||
generated_files = xnrealloc (generated_files, ++generated_files_size,
|
||||
sizeof *generated_files);
|
||||
generated_files[generated_files_size-1].name = xstrdup (*file_name);
|
||||
generated_files[generated_files_size-1].is_source = source;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
unlink_generated_sources (void)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < generated_files_size; i++)
|
||||
if (generated_files[i].is_source)
|
||||
/* Ignore errors. The file might not even exist. */
|
||||
unlink (generated_files[i].name);
|
||||
}
|
||||
|
||||
void
|
||||
output_file_names_free (void)
|
||||
{
|
||||
@@ -400,8 +420,8 @@ output_file_names_free (void)
|
||||
free (dir_prefix);
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < file_names_count; i++)
|
||||
free (file_names[i]);
|
||||
for (i = 0; i < generated_files_size; i++)
|
||||
free (generated_files[i].name);
|
||||
}
|
||||
free (file_names);
|
||||
free (generated_files);
|
||||
}
|
||||
|
||||
+9
-1
@@ -63,7 +63,15 @@ extern char *all_but_ext;
|
||||
|
||||
void compute_output_file_names (void);
|
||||
void output_file_names_free (void);
|
||||
void output_file_name_check (char **file_name);
|
||||
|
||||
/** Record that we generate file \a file_name.
|
||||
* \param source whether this is a source file (*c, *.java...)
|
||||
* as opposed to a report (*.output, *.dot...).
|
||||
*/
|
||||
void output_file_name_check (char **file_name, bool source);
|
||||
|
||||
/** Remove all the generated source files. */
|
||||
void unlink_generated_sources (void);
|
||||
|
||||
FILE *xfopen (const char *name, char const *mode);
|
||||
void xfclose (FILE *ptr);
|
||||
|
||||
+64
-109
@@ -61,7 +61,6 @@ int skeleton_prio = default_prio;
|
||||
const char *skeleton = NULL;
|
||||
int language_prio = default_prio;
|
||||
struct bison_language const *language = &valid_languages[0];
|
||||
const char *include = NULL;
|
||||
|
||||
/** Decode an option's key.
|
||||
*
|
||||
@@ -74,8 +73,6 @@ const char *include = NULL;
|
||||
* If null, then activate all the flags.
|
||||
* \param no length of the potential "no-" prefix.
|
||||
* Can be 0 or 3. If 3, negate the action of the subargument.
|
||||
* \param err length of a potential "error=".
|
||||
* Can be 0 or 6. If 6, treat the subargument as a CATEGORY
|
||||
*
|
||||
* If VALUE != 0 then KEY sets flags and no-KEY clears them.
|
||||
* If VALUE == 0 then KEY clears all flags from \c all and no-KEY sets all
|
||||
@@ -84,36 +81,23 @@ const char *include = NULL;
|
||||
static void
|
||||
flag_argmatch (const char *option,
|
||||
const char * const keys[], const int values[],
|
||||
int all, int *flags, char *arg, size_t no, size_t err)
|
||||
int all, int *flags, char *arg, size_t no)
|
||||
{
|
||||
int value = 0;
|
||||
if (!err || arg[no + err++] != '\0')
|
||||
value = XARGMATCH (option, arg + no + err, keys, values);
|
||||
int value = XARGMATCH (option, arg + no, keys, values);
|
||||
|
||||
if (value)
|
||||
/* -rnone == -rno-all, and -rno-none == -rall. */
|
||||
if (!value)
|
||||
{
|
||||
if (no)
|
||||
*flags &= ~value;
|
||||
else
|
||||
{
|
||||
if (err)
|
||||
warnings_flag |= value;
|
||||
*flags |= value;
|
||||
}
|
||||
value = all;
|
||||
no = !no;
|
||||
}
|
||||
|
||||
if (no)
|
||||
*flags &= ~value;
|
||||
else
|
||||
{
|
||||
/* With a simpler 'if (no)' version, -Werror means -Werror=all
|
||||
(or rather, -Werror=no-none, but that syntax is invalid).
|
||||
The difference is:
|
||||
- Werror activates all errors, but not the warnings
|
||||
- Werror=all activates errors, and all warnings */
|
||||
if (no ? !err : err)
|
||||
*flags |= all;
|
||||
else
|
||||
*flags &= ~all;
|
||||
}
|
||||
*flags |= value;
|
||||
}
|
||||
|
||||
/** Decode an option's set of keys.
|
||||
*
|
||||
* \param option option being decoded.
|
||||
@@ -133,16 +117,14 @@ flags_argmatch (const char *option,
|
||||
for (args = strtok (args, ","); args; args = strtok (NULL, ","))
|
||||
{
|
||||
size_t no = STRPREFIX_LIT ("no-", args) ? 3 : 0;
|
||||
size_t err = STRPREFIX_LIT ("error", args + no) ? 5 : 0;
|
||||
|
||||
flag_argmatch (option, keys,
|
||||
values, all, err ? &errors_flag : flags,
|
||||
args, no, err);
|
||||
values, all, flags, args, no);
|
||||
}
|
||||
else
|
||||
*flags |= all;
|
||||
}
|
||||
|
||||
|
||||
/** Decode a set of sub arguments.
|
||||
*
|
||||
* \param FlagName the flag familly to update.
|
||||
@@ -196,8 +178,6 @@ ARGMATCH_VERIFY (report_args, report_types);
|
||||
|
||||
static const char * const trace_args[] =
|
||||
{
|
||||
/* In a series of synonyms, present the most meaningful first, so
|
||||
that argmatch_valid be more readable. */
|
||||
"none - no traces",
|
||||
"scan - grammar scanner traces",
|
||||
"parse - grammar parser traces",
|
||||
@@ -238,41 +218,6 @@ static const int trace_types[] =
|
||||
ARGMATCH_VERIFY (trace_args, trace_types);
|
||||
|
||||
|
||||
/*------------------------.
|
||||
| --warnings's handling. |
|
||||
`------------------------*/
|
||||
|
||||
static const char * const warnings_args[] =
|
||||
{
|
||||
/* In a series of synonyms, present the most meaningful first, so
|
||||
that argmatch_valid be more readable. */
|
||||
"none - no warnings",
|
||||
"midrule-values - unset or unused midrule values",
|
||||
"yacc - incompatibilities with POSIX Yacc",
|
||||
"conflicts-sr - S/R conflicts",
|
||||
"conflicts-rr - R/R conflicts",
|
||||
"deprecated - obsolete constructs",
|
||||
"other - all other warnings",
|
||||
"all - all of the above",
|
||||
"error - warnings are errors",
|
||||
0
|
||||
};
|
||||
|
||||
static const int warnings_types[] =
|
||||
{
|
||||
Wnone,
|
||||
Wmidrule_values,
|
||||
Wyacc,
|
||||
Wconflicts_sr,
|
||||
Wconflicts_rr,
|
||||
Wdeprecated,
|
||||
Wother,
|
||||
Wall,
|
||||
Werror
|
||||
};
|
||||
|
||||
ARGMATCH_VERIFY (warnings_args, warnings_types);
|
||||
|
||||
/*-----------------------.
|
||||
| --feature's handling. |
|
||||
`-----------------------*/
|
||||
@@ -304,7 +249,7 @@ static void
|
||||
usage (int status)
|
||||
{
|
||||
if (status != 0)
|
||||
fprintf (stderr, _("Try `%s --help' for more information.\n"),
|
||||
fprintf (stderr, _("Try '%s --help' for more information.\n"),
|
||||
program_name);
|
||||
else
|
||||
{
|
||||
@@ -346,7 +291,7 @@ Parser:\n\
|
||||
-L, --language=LANGUAGE specify the output programming language\n\
|
||||
-S, --skeleton=FILE specify the skeleton to use\n\
|
||||
-t, --debug instrument the parser for tracing\n\
|
||||
same as `-Dparse.trace'\n\
|
||||
same as '-Dparse.trace'\n\
|
||||
--locations enable location support\n\
|
||||
-D, --define=NAME[=VALUE] similar to '%define NAME \"VALUE\"'\n\
|
||||
-F, --force-define=NAME[=VALUE] override '%define NAME \"VALUE\"'\n\
|
||||
@@ -365,7 +310,7 @@ Output:\n\
|
||||
-d likewise but cannot specify FILE (for POSIX Yacc)\n\
|
||||
-r, --report=THINGS also produce details on the automaton\n\
|
||||
--report-file=FILE write report to FILE\n\
|
||||
-v, --verbose same as `--report=state'\n\
|
||||
-v, --verbose same as '--report=state'\n\
|
||||
-b, --file-prefix=PREFIX specify a PREFIX for output files\n\
|
||||
-o, --output=FILE leave output to FILE\n\
|
||||
-g, --graph[=FILE] also output a graph of the automaton\n\
|
||||
@@ -376,35 +321,37 @@ Output:\n\
|
||||
|
||||
fputs (_("\
|
||||
Warning categories include:\n\
|
||||
`midrule-values' unset or unused midrule values\n\
|
||||
`yacc' incompatibilities with POSIX Yacc\n\
|
||||
`conflicts-sr' S/R conflicts (enabled by default)\n\
|
||||
`conflicts-rr' R/R conflicts (enabled by default)\n\
|
||||
`deprecated' obsolete constructs\n\
|
||||
`other' all other warnings (enabled by default)\n\
|
||||
`all' all the warnings\n\
|
||||
`no-CATEGORY' turn off warnings in CATEGORY\n\
|
||||
`none' turn off all the warnings\n\
|
||||
`error[=CATEGORY]' treat warnings as errors\n\
|
||||
'midrule-values' unset or unused midrule values\n\
|
||||
'yacc' incompatibilities with POSIX Yacc\n\
|
||||
'conflicts-sr' S/R conflicts (enabled by default)\n\
|
||||
'conflicts-rr' R/R conflicts (enabled by default)\n\
|
||||
'deprecated' obsolete constructs\n\
|
||||
'empty-rule' empty rules without %empty\n\
|
||||
'precedence' useless precedence and associativity\n\
|
||||
'other' all other warnings (enabled by default)\n\
|
||||
'all' all the warnings except 'yacc'\n\
|
||||
'no-CATEGORY' turn off warnings in CATEGORY\n\
|
||||
'none' turn off all the warnings\n\
|
||||
'error[=CATEGORY]' treat warnings as errors\n\
|
||||
"), stdout);
|
||||
putc ('\n', stdout);
|
||||
|
||||
fputs (_("\
|
||||
THINGS is a list of comma separated words that can include:\n\
|
||||
`state' describe the states\n\
|
||||
`itemset' complete the core item sets with their closure\n\
|
||||
`lookahead' explicitly associate lookahead tokens to items\n\
|
||||
`solved' describe shift/reduce conflicts solving\n\
|
||||
`all' include all the above information\n\
|
||||
`none' disable the report\n\
|
||||
'state' describe the states\n\
|
||||
'itemset' complete the core item sets with their closure\n\
|
||||
'lookahead' explicitly associate lookahead tokens to items\n\
|
||||
'solved' describe shift/reduce conflicts solving\n\
|
||||
'all' include all the above information\n\
|
||||
'none' disable the report\n\
|
||||
"), stdout);
|
||||
putc ('\n', stdout);
|
||||
|
||||
fputs (_("\
|
||||
FEATURE is a list of comma separated words that can include:\n\
|
||||
`caret' show errors with carets\n\
|
||||
`all' all of the above\n\
|
||||
`none' disable all of the above\n\
|
||||
'caret' show errors with carets\n\
|
||||
'all' all of the above\n\
|
||||
'none' disable all of the above\n\
|
||||
"), stdout);
|
||||
|
||||
putc ('\n', stdout);
|
||||
@@ -517,12 +464,10 @@ static char const short_options[] =
|
||||
"b:"
|
||||
"d"
|
||||
"f::"
|
||||
"e"
|
||||
"g::"
|
||||
"h"
|
||||
"k"
|
||||
"l"
|
||||
"n"
|
||||
"o:"
|
||||
"p:"
|
||||
"r:"
|
||||
@@ -552,7 +497,6 @@ static struct option const long_options[] =
|
||||
|
||||
/* Parser. */
|
||||
{ "name-prefix", required_argument, 0, 'p' },
|
||||
{ "include", required_argument, 0, 'I' },
|
||||
|
||||
/* Output. */
|
||||
{ "file-prefix", required_argument, 0, 'b' },
|
||||
@@ -581,7 +525,6 @@ static struct option const long_options[] =
|
||||
{ "force-define", required_argument, 0, 'F' },
|
||||
{ "locations", no_argument, 0, LOCATIONS_OPTION },
|
||||
{ "no-lines", no_argument, 0, 'l' },
|
||||
{ "raw", no_argument, 0, 0 },
|
||||
{ "skeleton", required_argument, 0, 'S' },
|
||||
{ "language", required_argument, 0, 'L' },
|
||||
{ "token-table", no_argument, 0, 'k' },
|
||||
@@ -590,7 +533,7 @@ static struct option const long_options[] =
|
||||
};
|
||||
|
||||
/* Under DOS, there is no difference on the case. This can be
|
||||
troublesome when looking for `.tab' etc. */
|
||||
troublesome when looking for '.tab' etc. */
|
||||
#ifdef MSDOS
|
||||
# define AS_FILE_NAME(File) (strlwr (File), (File))
|
||||
#else
|
||||
@@ -626,24 +569,36 @@ getargs (int argc, char *argv[])
|
||||
/* Certain long options cause getopt_long to return 0. */
|
||||
break;
|
||||
|
||||
case 'D': /* -DNAME[=VALUE]. */
|
||||
case 'F': /* -FNAME[=VALUE]. */
|
||||
case 'D': /* -DNAME[=(VALUE|"VALUE"|{VALUE})]. */
|
||||
case 'F': /* -FNAME[=(VALUE|"VALUE"|{VALUE})]. */
|
||||
{
|
||||
char* name = optarg;
|
||||
char* value = strchr (optarg, '=');
|
||||
char *name = optarg;
|
||||
char *value = strchr (optarg, '=');
|
||||
muscle_kind kind = muscle_keyword;
|
||||
if (value)
|
||||
*value++ = 0;
|
||||
{
|
||||
char *end = value + strlen (value) - 1;
|
||||
*value++ = 0;
|
||||
if (*value == '{' && *end == '}')
|
||||
{
|
||||
kind = muscle_code;
|
||||
++value;
|
||||
*end = 0;
|
||||
}
|
||||
else if (*value == '"' && *end == '"')
|
||||
{
|
||||
kind = muscle_string;
|
||||
++value;
|
||||
*end = 0;
|
||||
}
|
||||
}
|
||||
muscle_percent_define_insert (name, command_line_location (),
|
||||
value ? value : "",
|
||||
kind, value ? value : "",
|
||||
c == 'D' ? MUSCLE_PERCENT_DEFINE_D
|
||||
: MUSCLE_PERCENT_DEFINE_F);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'I':
|
||||
include = AS_FILE_NAME (optarg);
|
||||
break;
|
||||
|
||||
case 'L':
|
||||
language_argmatch (optarg, command_line_prio,
|
||||
command_line_location ());
|
||||
@@ -667,7 +622,7 @@ getargs (int argc, char *argv[])
|
||||
break;
|
||||
|
||||
case 'W':
|
||||
FLAGS_ARGMATCH (warnings, optarg, Wall);
|
||||
warnings_argmatch (optarg);
|
||||
break;
|
||||
|
||||
case 'b':
|
||||
@@ -718,7 +673,8 @@ getargs (int argc, char *argv[])
|
||||
|
||||
case 't':
|
||||
muscle_percent_define_insert ("parse.trace",
|
||||
command_line_location (), "",
|
||||
command_line_location (),
|
||||
muscle_keyword, "",
|
||||
MUSCLE_PERCENT_DEFINE_D);
|
||||
break;
|
||||
|
||||
@@ -736,8 +692,7 @@ getargs (int argc, char *argv[])
|
||||
break;
|
||||
|
||||
case 'y':
|
||||
warnings_flag |= Wyacc;
|
||||
errors_flag |= Wyacc;
|
||||
warning_argmatch ("error=yacc", 0, 6);
|
||||
yacc_flag = true;
|
||||
break;
|
||||
|
||||
|
||||
@@ -121,6 +121,7 @@ enum feature
|
||||
/** What additional features to use. */
|
||||
extern int feature_flag;
|
||||
|
||||
|
||||
/** Process the command line arguments.
|
||||
*
|
||||
* \param argc size of \a argv
|
||||
|
||||
+8
-31
@@ -93,16 +93,14 @@ rule_rhs_length (rule const *r)
|
||||
void
|
||||
rule_rhs_print (rule const *r, FILE *out)
|
||||
{
|
||||
if (*r->rhs >= 0)
|
||||
if (0 <= *r->rhs)
|
||||
{
|
||||
item_number *rp;
|
||||
for (rp = r->rhs; *rp >= 0; rp++)
|
||||
fprintf (out, " %s", symbols[*rp]->tag);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf (out, " /* %s */", _("empty"));
|
||||
}
|
||||
fputs (" %empty", out);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -125,13 +123,6 @@ rule_rhs_print_xml (rule const *r, FILE *out, int level)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
rule_print (rule const *r, FILE *out)
|
||||
{
|
||||
fprintf (out, "%s:", r->lhs->tag);
|
||||
rule_rhs_print (r, out);
|
||||
}
|
||||
|
||||
void
|
||||
ritem_print (FILE *out)
|
||||
{
|
||||
@@ -289,8 +280,8 @@ grammar_dump (FILE *out, const char *title)
|
||||
rule_number r;
|
||||
for (r = 0; r < nrules + nuseless_productions; r++)
|
||||
{
|
||||
fprintf (out, "%-5d ", r);
|
||||
rule_print (&rules[r], out);
|
||||
fprintf (out, "%-5d %s:", r, rules[r].lhs->tag);
|
||||
rule_rhs_print (&rules[r], out);
|
||||
fprintf (out, "\n");
|
||||
}
|
||||
}
|
||||
@@ -300,24 +291,10 @@ grammar_dump (FILE *out, const char *title)
|
||||
void
|
||||
grammar_rules_useless_report (const char *message)
|
||||
{
|
||||
warnings w = Wother;
|
||||
if (warnings_flag & w)
|
||||
{
|
||||
rule_number r;
|
||||
for (r = 0; r < nrules ; ++r)
|
||||
if (!rules[r].useful)
|
||||
{
|
||||
if (feature_flag & feature_caret)
|
||||
complain (&rules[r].location, w, "%s", message);
|
||||
else
|
||||
{
|
||||
complain (&rules[r].location, w | silent, "%s: ", message);
|
||||
rule_print (&rules[r], stderr);
|
||||
warnings_print_categories (w);
|
||||
fprintf (stderr, "\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
rule_number r;
|
||||
for (r = 0; r < nrules ; ++r)
|
||||
if (!rules[r].useful)
|
||||
complain (&rules[r].location, Wother, "%s", message);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
+6
-6
@@ -35,7 +35,7 @@
|
||||
|
||||
The rules receive rule numbers 1 to NRULES in the order they are
|
||||
written. More precisely Bison augments the grammar with the
|
||||
initial rule, `$accept: START-SYMBOL $end', which is numbered 1,
|
||||
initial rule, '$accept: START-SYMBOL $end', which is numbered 1,
|
||||
all the user rules are 2, 3 etc. Each time a rule number is
|
||||
presented to the user, we subtract 1, so *displayed* rule numbers
|
||||
are 0, 1, 2...
|
||||
@@ -61,7 +61,7 @@
|
||||
RULES[R].prec -- the symbol providing the precedence level of R.
|
||||
|
||||
RULES[R].precsym -- the symbol attached (via %prec) to give its
|
||||
precedence to R. Of course, if set, it is equal to `prec', but we
|
||||
precedence to R. Of course, if set, it is equal to 'prec', but we
|
||||
need to distinguish one from the other when reducing: a symbol used
|
||||
in a %prec is not useless.
|
||||
|
||||
@@ -205,11 +205,11 @@ extern rule *rules;
|
||||
/* A function that selects a rule. */
|
||||
typedef bool (*rule_filter) (rule const *);
|
||||
|
||||
/* Return true IFF the rule has a `number' smaller than NRULES. That is, it is
|
||||
/* Return true IFF the rule has a 'number' smaller than NRULES. That is, it is
|
||||
useful in the grammar. */
|
||||
bool rule_useful_in_grammar_p (rule const *r);
|
||||
|
||||
/* Return true IFF the rule has a `number' higher than NRULES. That is, it is
|
||||
/* Return true IFF the rule has a 'number' higher than NRULES. That is, it is
|
||||
useless in the grammar. */
|
||||
bool rule_useless_in_grammar_p (rule const *r);
|
||||
|
||||
@@ -262,8 +262,8 @@ void grammar_rules_print_xml (FILE *out, int level);
|
||||
void grammar_dump (FILE *out, const char *title);
|
||||
|
||||
/* Report on STDERR the rules that are not flagged USEFUL, using the
|
||||
MESSAGE (which can be `rule useless in grammar' when invoked after grammar
|
||||
reduction, or `rule useless in parser due to conflicts' after conflicts
|
||||
MESSAGE (which can be 'rule useless in grammar' when invoked after grammar
|
||||
reduction, or 'rule useless in parser due to conflicts' after conflicts
|
||||
were taken into account). */
|
||||
void grammar_rules_useless_report (const char *message);
|
||||
|
||||
|
||||
+20
-24
@@ -67,17 +67,13 @@ static goto_number **includes;
|
||||
static goto_list **lookback;
|
||||
|
||||
|
||||
|
||||
|
||||
void
|
||||
set_goto_map (void)
|
||||
{
|
||||
state_number s;
|
||||
goto_number *temp_map;
|
||||
goto_number *temp_map = xnmalloc (nvars + 1, sizeof *temp_map);
|
||||
|
||||
goto_map = xcalloc (nvars + 1, sizeof *goto_map);
|
||||
temp_map = xnmalloc (nvars + 1, sizeof *temp_map);
|
||||
|
||||
ngotos = 0;
|
||||
for (s = 0; s < nstates; ++s)
|
||||
{
|
||||
@@ -132,16 +128,13 @@ set_goto_map (void)
|
||||
goto_number
|
||||
map_goto (state_number s0, symbol_number sym)
|
||||
{
|
||||
goto_number high;
|
||||
goto_number low;
|
||||
goto_number middle;
|
||||
state_number s;
|
||||
|
||||
low = goto_map[sym - ntokens];
|
||||
high = goto_map[sym - ntokens + 1] - 1;
|
||||
goto_number low = goto_map[sym - ntokens];
|
||||
goto_number high = goto_map[sym - ntokens + 1] - 1;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
goto_number middle;
|
||||
state_number s;
|
||||
aver (low <= high);
|
||||
middle = (low + high) / 2;
|
||||
s = from_state[middle];
|
||||
@@ -342,7 +335,7 @@ state_lookahead_tokens_count (state *s, bool default_reduction_only_for_accept)
|
||||
/* We need a lookahead either to distinguish different reductions
|
||||
(i.e., there are two or more), or to distinguish a reduction from a
|
||||
shift. Otherwise, it is straightforward, and the state is
|
||||
`consistent'. However, do not treat a state with any reductions as
|
||||
'consistent'. However, do not treat a state with any reductions as
|
||||
consistent unless it is the accepting state (because there is never
|
||||
a lookahead token that makes sense there, and so no lookahead token
|
||||
should be read) if the user has otherwise disabled default
|
||||
@@ -412,7 +405,6 @@ static void
|
||||
lookahead_tokens_print (FILE *out)
|
||||
{
|
||||
state_number i;
|
||||
int j, k;
|
||||
fprintf (out, "Lookahead tokens: BEGIN\n");
|
||||
for (i = 0; i < nstates; ++i)
|
||||
{
|
||||
@@ -421,21 +413,25 @@ lookahead_tokens_print (FILE *out)
|
||||
int n_lookahead_tokens = 0;
|
||||
|
||||
if (reds->lookahead_tokens)
|
||||
for (k = 0; k < reds->num; ++k)
|
||||
if (reds->lookahead_tokens[k])
|
||||
++n_lookahead_tokens;
|
||||
{
|
||||
int j;
|
||||
for (j = 0; j < reds->num; ++j)
|
||||
if (reds->lookahead_tokens[j])
|
||||
++n_lookahead_tokens;
|
||||
}
|
||||
|
||||
fprintf (out, "State %d: %d lookahead tokens\n",
|
||||
i, n_lookahead_tokens);
|
||||
|
||||
if (reds->lookahead_tokens)
|
||||
for (j = 0; j < reds->num; ++j)
|
||||
BITSET_FOR_EACH (iter, reds->lookahead_tokens[j], k, 0)
|
||||
{
|
||||
fprintf (out, " on %d (%s) -> rule %d\n",
|
||||
k, symbols[k]->tag,
|
||||
reds->rules[j]->number);
|
||||
};
|
||||
{
|
||||
int j, k;
|
||||
for (j = 0; j < reds->num; ++j)
|
||||
BITSET_FOR_EACH (iter, reds->lookahead_tokens[j], k, 0)
|
||||
fprintf (out, " on %d (%s) -> rule %d\n",
|
||||
k, symbols[k]->tag,
|
||||
reds->rules[j]->number);
|
||||
}
|
||||
}
|
||||
fprintf (out, "Lookahead tokens: END\n");
|
||||
}
|
||||
|
||||
+3
-1
@@ -111,7 +111,9 @@ BUILT_SOURCES += \
|
||||
## yacc. ##
|
||||
## ------ ##
|
||||
|
||||
bin_SCRIPTS = $(YACC_SCRIPT)
|
||||
if ENABLE_YACC
|
||||
bin_SCRIPTS = src/yacc
|
||||
endif
|
||||
EXTRA_SCRIPTS = src/yacc
|
||||
MOSTLYCLEANFILES += src/yacc
|
||||
|
||||
|
||||
+4
-6
@@ -96,10 +96,8 @@ location_compute (location *loc, boundary *cur, char const *token, size_t size)
|
||||
}
|
||||
|
||||
|
||||
/* Output to OUT the location LOC.
|
||||
Warning: it uses quotearg's slot 3. */
|
||||
unsigned
|
||||
location_print (FILE *out, location loc)
|
||||
location_print (location loc, FILE *out)
|
||||
{
|
||||
unsigned res = 0;
|
||||
int end_col = 0 != loc.end.column ? loc.end.column - 1 : 0;
|
||||
@@ -161,7 +159,7 @@ cleanup_caret ()
|
||||
}
|
||||
|
||||
void
|
||||
location_caret (FILE *out, location loc)
|
||||
location_caret (location loc, FILE *out)
|
||||
{
|
||||
/* FIXME: find a way to support multifile locations, and only open once each
|
||||
file. That would make the procedure future-proof. */
|
||||
@@ -190,7 +188,7 @@ location_caret (FILE *out, location loc)
|
||||
/* Read the actual line. Don't update the offset, so that we keep a pointer
|
||||
to the start of the line. */
|
||||
{
|
||||
char c = getc (caret_info.source);
|
||||
int c = getc (caret_info.source);
|
||||
if (c != EOF)
|
||||
{
|
||||
/* Quote the file, indent by a single column. */
|
||||
@@ -221,7 +219,7 @@ void
|
||||
boundary_set_from_string (boundary *bound, char *loc_str)
|
||||
{
|
||||
/* Must search in reverse since the file name field may
|
||||
* contain `.' or `:'. */
|
||||
* contain '.' or ':'. */
|
||||
char *delim = strrchr (loc_str, '.');
|
||||
aver (delim);
|
||||
*delim = '\0';
|
||||
|
||||
+10
-5
@@ -20,6 +20,10 @@
|
||||
#ifndef LOCATION_H_
|
||||
# define LOCATION_H_
|
||||
|
||||
# include <stdbool.h>
|
||||
# include <stdio.h>
|
||||
# include <string.h> /* strcmp */
|
||||
|
||||
# include "uniqstr.h"
|
||||
|
||||
/* A boundary between two characters. */
|
||||
@@ -98,16 +102,17 @@ extern location const empty_location;
|
||||
void location_compute (location *loc,
|
||||
boundary *cur, char const *token, size_t size);
|
||||
|
||||
/* Print location to file. Return number of actually printed
|
||||
characters. */
|
||||
unsigned location_print (FILE *out, location loc);
|
||||
/* Print location to file.
|
||||
Return number of actually printed characters.
|
||||
Warning: uses quotearg's slot 3. */
|
||||
unsigned location_print (location loc, FILE *out);
|
||||
|
||||
/* Free any allocated ressources and close any open file handles that are
|
||||
left-over by the usage of location_caret. */
|
||||
void cleanup_caret (void);
|
||||
|
||||
/* Output to OUT the line and caret corresponding to location LOC. */
|
||||
void location_caret (FILE *out, location loc);
|
||||
void location_caret (location loc, FILE *out);
|
||||
|
||||
/* Return -1, 0, 1, depending whether a is before, equal, or
|
||||
after b. */
|
||||
@@ -120,7 +125,7 @@ location_cmp (location a, location b)
|
||||
return res;
|
||||
}
|
||||
|
||||
/* LOC_STR must be formatted as `file:line.column', it will be modified. */
|
||||
/* LOC_STR must be formatted as 'file:line.column', it will be modified. */
|
||||
void boundary_set_from_string (boundary *bound, char *loc_str);
|
||||
|
||||
#endif /* ! defined LOCATION_H_ */
|
||||
|
||||
+1
-2
@@ -76,6 +76,7 @@ main (int argc, char *argv[])
|
||||
|
||||
uniqstrs_new ();
|
||||
muscle_init ();
|
||||
complain_init ();
|
||||
|
||||
getargs (argc, argv);
|
||||
|
||||
@@ -146,8 +147,6 @@ main (int argc, char *argv[])
|
||||
|
||||
print_precedence_warnings ();
|
||||
|
||||
print_assoc_warnings ();
|
||||
|
||||
/* Output file names. */
|
||||
compute_output_file_names ();
|
||||
|
||||
|
||||
+216
-167
@@ -28,6 +28,31 @@
|
||||
#include "muscle-tab.h"
|
||||
#include "quote.h"
|
||||
|
||||
muscle_kind
|
||||
muscle_kind_new (char const *k)
|
||||
{
|
||||
if (STREQ (k, "code"))
|
||||
return muscle_code;
|
||||
else if (STREQ (k, "keyword"))
|
||||
return muscle_keyword;
|
||||
else if (STREQ (k, "string"))
|
||||
return muscle_string;
|
||||
aver (0);
|
||||
}
|
||||
|
||||
char const *
|
||||
muscle_kind_string (muscle_kind k)
|
||||
{
|
||||
switch (k)
|
||||
{
|
||||
case muscle_code: return "code";
|
||||
case muscle_keyword: return "keyword";
|
||||
case muscle_string: return "string";
|
||||
}
|
||||
aver (0);
|
||||
}
|
||||
|
||||
|
||||
/* A key-value pair, along with storage that can be reclaimed when
|
||||
this pair is no longer needed. */
|
||||
typedef struct
|
||||
@@ -35,8 +60,21 @@ typedef struct
|
||||
char const *key;
|
||||
char const *value;
|
||||
char *storage;
|
||||
muscle_kind kind;
|
||||
} muscle_entry;
|
||||
|
||||
|
||||
/* The name of muscle for the %define variable VAR (corresponding to
|
||||
FIELD, if defined). */
|
||||
static uniqstr
|
||||
muscle_name (char const *var, char const *field)
|
||||
{
|
||||
if (field)
|
||||
return UNIQSTR_CONCAT ("percent_define_", field, "(", var, ")");
|
||||
else
|
||||
return UNIQSTR_CONCAT ("percent_define(", var, ")");
|
||||
}
|
||||
|
||||
/* An obstack used to create some entries. */
|
||||
struct obstack muscle_obstack;
|
||||
|
||||
@@ -60,10 +98,18 @@ hash_muscle (const void *x, size_t tablesize)
|
||||
return hash_string (m->key, tablesize);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------.
|
||||
| Create the MUSCLE_TABLE, and initialize it with default values. |
|
||||
| Also set up the MUSCLE_OBSTACK. |
|
||||
`-----------------------------------------------------------------*/
|
||||
/* Create a fresh muscle name KEY, and insert in the hash table. */
|
||||
static void *
|
||||
muscle_entry_new (char const *key)
|
||||
{
|
||||
muscle_entry *res = xmalloc (sizeof *res);
|
||||
res->key = key;
|
||||
res->value = NULL;
|
||||
res->storage = NULL;
|
||||
if (!hash_insert (muscle_table, res))
|
||||
xalloc_die ();
|
||||
return res;
|
||||
}
|
||||
|
||||
static void
|
||||
muscle_entry_free (void *entry)
|
||||
@@ -87,10 +133,6 @@ muscle_init (void)
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------.
|
||||
| Free all the memory consumed by the muscle machinery only. |
|
||||
`------------------------------------------------------------*/
|
||||
|
||||
void
|
||||
muscle_free (void)
|
||||
{
|
||||
@@ -98,71 +140,64 @@ muscle_free (void)
|
||||
obstack_free (&muscle_obstack, NULL);
|
||||
}
|
||||
|
||||
/* Look for the muscle named KEY. Return NULL if does not exist. */
|
||||
static
|
||||
muscle_entry *
|
||||
muscle_lookup (char const *key)
|
||||
{
|
||||
muscle_entry probe;
|
||||
probe.key = key;
|
||||
return hash_lookup (muscle_table, &probe);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------.
|
||||
| Insert (KEY, VALUE). If KEY already existed, overwrite the |
|
||||
| previous value. |
|
||||
`------------------------------------------------------------*/
|
||||
|
||||
void
|
||||
muscle_insert (char const *key, char const *value)
|
||||
{
|
||||
muscle_entry probe;
|
||||
muscle_entry *entry;
|
||||
|
||||
probe.key = key;
|
||||
entry = hash_lookup (muscle_table, &probe);
|
||||
|
||||
if (!entry)
|
||||
{
|
||||
/* First insertion in the hash. */
|
||||
entry = xmalloc (sizeof *entry);
|
||||
entry->key = key;
|
||||
if (!hash_insert (muscle_table, entry))
|
||||
xalloc_die ();
|
||||
}
|
||||
else
|
||||
muscle_entry *entry = muscle_lookup (key);
|
||||
if (entry)
|
||||
free (entry->storage);
|
||||
else
|
||||
/* First insertion in the hash. */
|
||||
entry = muscle_entry_new (key);
|
||||
entry->value = value;
|
||||
entry->storage = NULL;
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------.
|
||||
| Append VALUE to the current value of KEY. If KEY did not already |
|
||||
| exist, create it. Use MUSCLE_OBSTACK. De-allocate the previously |
|
||||
| associated value. Copy VALUE and SEPARATOR. |
|
||||
`-------------------------------------------------------------------*/
|
||||
/* Append VALUE to the current value of KEY. If KEY did not already
|
||||
exist, create it. Use MUSCLE_OBSTACK. De-allocate the previously
|
||||
associated value. Copy VALUE and SEPARATOR. If VALUE does not end
|
||||
with TERMINATOR, append one. */
|
||||
|
||||
void
|
||||
muscle_grow (const char *key, const char *val, const char *separator)
|
||||
static void
|
||||
muscle_grow (const char *key, const char *val,
|
||||
const char *separator, const char *terminator)
|
||||
{
|
||||
muscle_entry probe;
|
||||
muscle_entry *entry = NULL;
|
||||
muscle_entry *entry = muscle_lookup (key);
|
||||
size_t vals = strlen (val);
|
||||
size_t terms = strlen (terminator);
|
||||
|
||||
probe.key = key;
|
||||
entry = hash_lookup (muscle_table, &probe);
|
||||
|
||||
if (!entry)
|
||||
if (entry)
|
||||
{
|
||||
/* First insertion in the hash. */
|
||||
entry = xmalloc (sizeof *entry);
|
||||
entry->key = key;
|
||||
if (!hash_insert (muscle_table, entry))
|
||||
xalloc_die ();
|
||||
entry->value = entry->storage = xstrdup (val);
|
||||
obstack_sgrow (&muscle_obstack, entry->value);
|
||||
obstack_sgrow (&muscle_obstack, separator);
|
||||
free (entry->storage);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Grow the current value. */
|
||||
char *new_val;
|
||||
obstack_printf (&muscle_obstack, "%s%s%s", entry->value, separator, val);
|
||||
free (entry->storage);
|
||||
new_val = obstack_finish0 (&muscle_obstack);
|
||||
entry->value = entry->storage = xstrdup (new_val);
|
||||
obstack_free (&muscle_obstack, new_val);
|
||||
}
|
||||
entry = muscle_entry_new (key);
|
||||
|
||||
obstack_sgrow (&muscle_obstack, val);
|
||||
|
||||
if (terms <= vals
|
||||
&& STRNEQ (val + vals - terms, terminator))
|
||||
obstack_sgrow (&muscle_obstack, terminator);
|
||||
|
||||
{
|
||||
char *new_val = obstack_finish0 (&muscle_obstack);
|
||||
entry->value = entry->storage = xstrdup (new_val);
|
||||
obstack_free (&muscle_obstack, new_val);
|
||||
}
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------.
|
||||
@@ -179,7 +214,7 @@ muscle_syncline_grow (char const *key, location loc)
|
||||
quotearg_style (c_quoting_style, loc.start.file));
|
||||
obstack_sgrow (&muscle_obstack, ")[");
|
||||
extension = obstack_finish0 (&muscle_obstack);
|
||||
muscle_grow (key, extension, "");
|
||||
muscle_grow (key, extension, "", "");
|
||||
obstack_free (&muscle_obstack, extension);
|
||||
}
|
||||
|
||||
@@ -193,12 +228,13 @@ void
|
||||
muscle_code_grow (const char *key, const char *val, location loc)
|
||||
{
|
||||
muscle_syncline_grow (key, loc);
|
||||
muscle_grow (key, val, "\n");
|
||||
muscle_grow (key, val, "\n", "\n");
|
||||
}
|
||||
|
||||
|
||||
void muscle_pair_list_grow (const char *muscle,
|
||||
const char *a1, const char *a2)
|
||||
void
|
||||
muscle_pair_list_grow (const char *muscle,
|
||||
const char *a1, const char *a2)
|
||||
{
|
||||
char *pair;
|
||||
obstack_sgrow (&muscle_obstack, "[");
|
||||
@@ -207,54 +243,33 @@ void muscle_pair_list_grow (const char *muscle,
|
||||
obstack_quote (&muscle_obstack, a2);
|
||||
obstack_sgrow (&muscle_obstack, "]");
|
||||
pair = obstack_finish0 (&muscle_obstack);
|
||||
muscle_grow (muscle, pair, ",\n");
|
||||
muscle_grow (muscle, pair, ",\n", "");
|
||||
obstack_free (&muscle_obstack, pair);
|
||||
}
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------.
|
||||
| Find the value of muscle KEY. Unlike MUSCLE_FIND, this is always reliable |
|
||||
| to determine whether KEY has a value. |
|
||||
`----------------------------------------------------------------------------*/
|
||||
|
||||
char const *
|
||||
muscle_find_const (char const *key)
|
||||
{
|
||||
muscle_entry probe;
|
||||
muscle_entry *result = NULL;
|
||||
|
||||
probe.key = key;
|
||||
result = hash_lookup (muscle_table, &probe);
|
||||
if (result)
|
||||
return result->value;
|
||||
return NULL;
|
||||
muscle_entry *entry = muscle_lookup (key);
|
||||
return entry ? entry->value : NULL;
|
||||
}
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------.
|
||||
| Find the value of muscle KEY. Abort if muscle_insert was invoked more |
|
||||
| recently than muscle_grow for KEY since muscle_find can't return a |
|
||||
| char const *. |
|
||||
`----------------------------------------------------------------------------*/
|
||||
|
||||
char *
|
||||
muscle_find (char const *key)
|
||||
{
|
||||
muscle_entry probe;
|
||||
muscle_entry *result = NULL;
|
||||
|
||||
probe.key = key;
|
||||
result = hash_lookup (muscle_table, &probe);
|
||||
if (result)
|
||||
muscle_entry *entry = muscle_lookup (key);
|
||||
if (entry)
|
||||
{
|
||||
aver (result->value == result->storage);
|
||||
return result->storage;
|
||||
aver (entry->value == entry->storage);
|
||||
return entry->storage;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/* In the format `file_name:line.column', append BOUND to MUSCLE. Use
|
||||
/* In the format 'file_name:line.column', append BOUND to MUSCLE. Use
|
||||
digraphs for special characters in the file name. */
|
||||
|
||||
static void
|
||||
@@ -265,12 +280,12 @@ muscle_boundary_grow (char const *key, boundary bound)
|
||||
obstack_escape (&muscle_obstack, bound.file);
|
||||
obstack_printf (&muscle_obstack, ":%d.%d]]", bound.line, bound.column);
|
||||
extension = obstack_finish0 (&muscle_obstack);
|
||||
muscle_grow (key, extension, "");
|
||||
muscle_grow (key, extension, "", "");
|
||||
obstack_free (&muscle_obstack, extension);
|
||||
}
|
||||
|
||||
|
||||
/* In the format `[[file_name:line.column]], [[file_name:line.column]]',
|
||||
/* In the format '[[file_name:line.column]], [[file_name:line.column]]',
|
||||
append LOC to MUSCLE. Use digraphs for special characters in each
|
||||
file name. */
|
||||
|
||||
@@ -278,14 +293,15 @@ static void
|
||||
muscle_location_grow (char const *key, location loc)
|
||||
{
|
||||
muscle_boundary_grow (key, loc.start);
|
||||
muscle_grow (key, "", ", ");
|
||||
muscle_grow (key, "", ", ", "");
|
||||
muscle_boundary_grow (key, loc.end);
|
||||
}
|
||||
|
||||
#define COMMON_DECODE(Value) \
|
||||
case '$': \
|
||||
aver (*++(Value) == ']'); \
|
||||
aver (*++(Value) == '['); \
|
||||
++(Value); aver (*(Value) == '['); \
|
||||
++(Value); aver (*(Value) == ']'); \
|
||||
++(Value); aver (*(Value) == '['); \
|
||||
obstack_sgrow (&muscle_obstack, "$"); \
|
||||
break; \
|
||||
case '@': \
|
||||
@@ -329,13 +345,12 @@ string_decode (char const *key)
|
||||
|
||||
/* Reverse of muscle_location_grow. */
|
||||
static location
|
||||
location_decode (char const *key)
|
||||
location_decode (char const *value)
|
||||
{
|
||||
location loc;
|
||||
char const *value = muscle_find_const (key);
|
||||
aver (value);
|
||||
aver (*value == '[');
|
||||
aver (*++value == '[');
|
||||
++value; aver (*value == '[');
|
||||
while (*++value)
|
||||
switch (*value)
|
||||
{
|
||||
@@ -346,16 +361,16 @@ location_decode (char const *key)
|
||||
case ']':
|
||||
{
|
||||
char *boundary_str;
|
||||
aver (*++value == ']');
|
||||
++value; aver (*value == ']');
|
||||
boundary_str = obstack_finish0 (&muscle_obstack);
|
||||
switch (*++value)
|
||||
{
|
||||
case ',':
|
||||
boundary_set_from_string (&loc.start, boundary_str);
|
||||
obstack_free (&muscle_obstack, boundary_str);
|
||||
aver (*++value == ' ');
|
||||
aver (*++value == '[');
|
||||
aver (*++value == '[');
|
||||
++value; aver (*value == ' ');
|
||||
++value; aver (*value == '[');
|
||||
++value; aver (*value == '[');
|
||||
break;
|
||||
case '\0':
|
||||
boundary_set_from_string (&loc.end, boundary_str);
|
||||
@@ -377,11 +392,11 @@ void
|
||||
muscle_user_name_list_grow (char const *key, char const *user_name,
|
||||
location loc)
|
||||
{
|
||||
muscle_grow (key, "[[[[", ",");
|
||||
muscle_grow (key, user_name, "");
|
||||
muscle_grow (key, "]], ", "");
|
||||
muscle_grow (key, "[[[[", ",", "");
|
||||
muscle_grow (key, user_name, "", "");
|
||||
muscle_grow (key, "]], ", "", "");
|
||||
muscle_location_grow (key, loc);
|
||||
muscle_grow (key, "]]", "");
|
||||
muscle_grow (key, "]]", "", "");
|
||||
}
|
||||
|
||||
|
||||
@@ -475,16 +490,17 @@ muscle_percent_variable_update (char const *variable, location variable_loc,
|
||||
|
||||
void
|
||||
muscle_percent_define_insert (char const *var, location variable_loc,
|
||||
muscle_kind kind,
|
||||
char const *value,
|
||||
muscle_percent_define_how how)
|
||||
{
|
||||
/* Backward compatibility. */
|
||||
char *variable = muscle_percent_variable_update (var, variable_loc, &value);
|
||||
char const *name = UNIQSTR_CONCAT ("percent_define(", variable, ")");
|
||||
char const *loc_name = UNIQSTR_CONCAT ("percent_define_loc(", variable, ")");
|
||||
char const *syncline_name =
|
||||
UNIQSTR_CONCAT ("percent_define_syncline(", variable, ")");
|
||||
char const *how_name = UNIQSTR_CONCAT ("percent_define_how(", variable, ")");
|
||||
uniqstr name = muscle_name (variable, NULL);
|
||||
uniqstr loc_name = muscle_name (variable, "loc");
|
||||
uniqstr syncline_name = muscle_name (variable, "syncline");
|
||||
uniqstr how_name = muscle_name (variable, "how");
|
||||
uniqstr kind_name = muscle_name (variable, "kind");
|
||||
|
||||
/* Command-line options are processed before the grammar file. */
|
||||
if (how == MUSCLE_PERCENT_DEFINE_GRAMMAR_FILE
|
||||
@@ -510,6 +526,7 @@ muscle_percent_define_insert (char const *var, location variable_loc,
|
||||
muscle_user_name_list_grow ("percent_define_user_variables", variable,
|
||||
variable_loc);
|
||||
MUSCLE_INSERT_INT (how_name, how);
|
||||
MUSCLE_INSERT_STRING (kind_name, muscle_kind_string (kind));
|
||||
end:
|
||||
free (variable);
|
||||
}
|
||||
@@ -520,85 +537,120 @@ void
|
||||
muscle_percent_define_ensure (char const *variable, location loc,
|
||||
bool value)
|
||||
{
|
||||
uniqstr name = muscle_name (variable, NULL);
|
||||
char const *val = value ? "" : "false";
|
||||
char const *name = UNIQSTR_CONCAT ("percent_define(", variable, ")");
|
||||
|
||||
/* %pure-parser is deprecated in favor of `%define api.pure', so use
|
||||
`%define api.pure' in a backward-compatible manner here. First,
|
||||
don't complain if %pure-parser is specified multiple times. */
|
||||
if (!muscle_find_const (name))
|
||||
muscle_percent_define_insert (variable, loc, val,
|
||||
MUSCLE_PERCENT_DEFINE_GRAMMAR_FILE);
|
||||
/* In all cases, use api.pure now so that the backend doesn't complain if
|
||||
the skeleton ignores api.pure, but do warn now if there's a previous
|
||||
conflicting definition from an actual %define. */
|
||||
if (muscle_percent_define_flag_if (variable) != value)
|
||||
muscle_percent_define_insert (variable, loc, val,
|
||||
/* Don't complain is VARIABLE is already defined, but be sure to set
|
||||
its value to VAL. */
|
||||
if (!muscle_find_const (name)
|
||||
|| muscle_percent_define_flag_if (variable) != value)
|
||||
muscle_percent_define_insert (variable, loc, muscle_keyword, val,
|
||||
MUSCLE_PERCENT_DEFINE_GRAMMAR_FILE);
|
||||
}
|
||||
|
||||
/* Mark %define VARIABLE as used. */
|
||||
static void
|
||||
muscle_percent_define_use (char const *variable)
|
||||
{
|
||||
muscle_insert (muscle_name (variable, "bison_variables"), "");
|
||||
}
|
||||
|
||||
/* The value of %define variable VARIABLE (corresponding to FIELD, if
|
||||
defined). Do not register as used, but diagnose unset variables. */
|
||||
|
||||
static
|
||||
char const *
|
||||
muscle_percent_define_get_raw (char const *variable, char const *field)
|
||||
{
|
||||
uniqstr name = muscle_name (variable, field);
|
||||
char const *res = muscle_find_const (name);
|
||||
if (!res)
|
||||
complain (NULL, fatal, _("%s: undefined %%define variable %s"),
|
||||
"muscle_percent_define_get_raw", quote (variable));
|
||||
return res;
|
||||
}
|
||||
|
||||
char *
|
||||
muscle_percent_define_get (char const *variable)
|
||||
{
|
||||
char const *name = UNIQSTR_CONCAT ("percent_define(", variable, ")");
|
||||
char const *usage_name =
|
||||
UNIQSTR_CONCAT ("percent_define_bison_variables(", variable, ")");
|
||||
uniqstr name = muscle_name (variable, NULL);
|
||||
char *value = string_decode (name);
|
||||
if (!value)
|
||||
value = xstrdup ("");
|
||||
|
||||
muscle_insert (usage_name, "");
|
||||
muscle_percent_define_use (variable);
|
||||
return value;
|
||||
}
|
||||
|
||||
/* The kind of VARIABLE. An error if undefined. */
|
||||
static muscle_kind
|
||||
muscle_percent_define_get_kind (char const *variable)
|
||||
{
|
||||
return muscle_kind_new (muscle_percent_define_get_raw (variable, "kind"));
|
||||
}
|
||||
|
||||
/* Check the kind of VARIABLE. An error if undefined. */
|
||||
static void
|
||||
muscle_percent_define_check_kind (char const *variable, muscle_kind kind)
|
||||
{
|
||||
if (muscle_percent_define_get_kind (variable) != kind)
|
||||
{
|
||||
location loc = muscle_percent_define_get_loc (variable);
|
||||
switch (kind)
|
||||
{
|
||||
case muscle_code:
|
||||
complain (&loc, Wdeprecated,
|
||||
"%%define variable '%s' requires '{...}' values",
|
||||
variable);
|
||||
break;
|
||||
case muscle_keyword:
|
||||
complain (&loc, Wdeprecated,
|
||||
"%%define variable '%s' requires keyword values",
|
||||
variable);
|
||||
break;
|
||||
case muscle_string:
|
||||
complain (&loc, Wdeprecated,
|
||||
"%%define variable '%s' requires '\"...\"' values",
|
||||
variable);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
location
|
||||
muscle_percent_define_get_loc (char const *variable)
|
||||
{
|
||||
char const *loc_name = UNIQSTR_CONCAT ("percent_define_loc(", variable, ")");
|
||||
if (!muscle_find_const (loc_name))
|
||||
complain (NULL, fatal, _("%s: undefined %%define variable %s"),
|
||||
"muscle_percent_define_get_loc", quote (variable));
|
||||
return location_decode (loc_name);
|
||||
return location_decode (muscle_percent_define_get_raw (variable, "loc"));
|
||||
}
|
||||
|
||||
char const *
|
||||
muscle_percent_define_get_syncline (char const *variable)
|
||||
{
|
||||
char const *syncline_name =
|
||||
UNIQSTR_CONCAT ("percent_define_syncline(", variable, ")");
|
||||
char const *syncline = muscle_find_const (syncline_name);
|
||||
if (!syncline)
|
||||
complain (NULL, fatal, _("%s: undefined %%define variable %s"),
|
||||
"muscle_percent_define_get_syncline", quote (variable));
|
||||
return syncline;
|
||||
return muscle_percent_define_get_raw (variable, "syncline");
|
||||
}
|
||||
|
||||
bool
|
||||
muscle_percent_define_ifdef (char const *variable)
|
||||
{
|
||||
char const *name = UNIQSTR_CONCAT ("percent_define(", variable, ")");
|
||||
char const *usage_name =
|
||||
UNIQSTR_CONCAT ("percent_define_bison_variables(", variable, ")");
|
||||
char const *value = muscle_find_const (name);
|
||||
if (value)
|
||||
if (muscle_find_const (muscle_name (variable, NULL)))
|
||||
{
|
||||
muscle_insert (usage_name, "");
|
||||
muscle_percent_define_use (variable);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
muscle_percent_define_flag_if (char const *variable)
|
||||
{
|
||||
char const *invalid_boolean_name =
|
||||
UNIQSTR_CONCAT ("percent_define_invalid_boolean(", variable, ")");
|
||||
uniqstr invalid_boolean_name = muscle_name (variable, "invalid_boolean");
|
||||
bool result = false;
|
||||
|
||||
if (muscle_percent_define_ifdef (variable))
|
||||
{
|
||||
char *value = muscle_percent_define_get (variable);
|
||||
muscle_percent_define_check_kind (variable, muscle_keyword);
|
||||
if (value[0] == '\0' || STREQ (value, "true"))
|
||||
result = true;
|
||||
else if (STREQ (value, "false"))
|
||||
@@ -623,20 +675,21 @@ muscle_percent_define_flag_if (char const *variable)
|
||||
void
|
||||
muscle_percent_define_default (char const *variable, char const *value)
|
||||
{
|
||||
char const *name = UNIQSTR_CONCAT ("percent_define(", variable, ")");
|
||||
char const *loc_name = UNIQSTR_CONCAT ("percent_define_loc(", variable, ")");
|
||||
char const *syncline_name =
|
||||
UNIQSTR_CONCAT ("percent_define_syncline(", variable, ")");
|
||||
uniqstr name = muscle_name (variable, NULL);
|
||||
if (!muscle_find_const (name))
|
||||
{
|
||||
location loc;
|
||||
MUSCLE_INSERT_STRING (name, value);
|
||||
loc.start.file = loc.end.file = "<default value>";
|
||||
loc.start.line = loc.end.line = -1;
|
||||
loc.start.column = loc.end.column = -1;
|
||||
muscle_insert (loc_name, "");
|
||||
muscle_location_grow (loc_name, loc);
|
||||
muscle_insert (syncline_name, "");
|
||||
MUSCLE_INSERT_STRING (muscle_name (variable, "kind"), "keyword");
|
||||
{
|
||||
uniqstr loc_name = muscle_name (variable, "loc");
|
||||
location loc;
|
||||
loc.start.file = loc.end.file = "<default value>";
|
||||
loc.start.line = loc.end.line = -1;
|
||||
loc.start.column = loc.end.column = -1;
|
||||
muscle_insert (loc_name, "");
|
||||
muscle_location_grow (loc_name, loc);
|
||||
}
|
||||
muscle_insert (muscle_name (variable, "syncline"), "");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -646,8 +699,9 @@ muscle_percent_define_check_values (char const * const *values)
|
||||
for (; *values; ++values)
|
||||
{
|
||||
char const * const *variablep = values;
|
||||
char const *name = UNIQSTR_CONCAT ("percent_define(", *variablep, ")");
|
||||
uniqstr name = muscle_name (*variablep, NULL);
|
||||
char *value = string_decode (name);
|
||||
muscle_percent_define_check_kind (*variablep, muscle_keyword);
|
||||
if (value)
|
||||
{
|
||||
for (++values; *values; ++values)
|
||||
@@ -664,7 +718,7 @@ muscle_percent_define_check_values (char const * const *values)
|
||||
quote (*variablep), quote_n (1, value));
|
||||
i += SUB_INDENT;
|
||||
for (values = variablep + 1; *values; ++values)
|
||||
complain_indent (&loc, complaint | no_caret, &i,
|
||||
complain_indent (&loc, complaint | no_caret | silent, &i,
|
||||
_("accepted value: %s"), quote (*values));
|
||||
}
|
||||
else
|
||||
@@ -711,11 +765,6 @@ muscle_m4_output_processor (void *entry, void *out)
|
||||
}
|
||||
|
||||
|
||||
/*----------------------------------------------------------------.
|
||||
| Output the definition of all the current muscles into a list of |
|
||||
| m4_defines. |
|
||||
`----------------------------------------------------------------*/
|
||||
|
||||
void
|
||||
muscles_m4_output (FILE *out)
|
||||
{
|
||||
|
||||
+44
-18
@@ -24,10 +24,41 @@
|
||||
|
||||
# include "location.h"
|
||||
|
||||
/* The kind of value associated to this muscle, depending on the
|
||||
syntax of the value: keyword (no delimiter, e.g., true), string
|
||||
(double quotes, e.g., "foo.h"), or code (braces, e.g., {int}). */
|
||||
typedef enum
|
||||
{
|
||||
muscle_code,
|
||||
muscle_keyword,
|
||||
muscle_string
|
||||
} muscle_kind;
|
||||
|
||||
/* Conversion from string. */
|
||||
muscle_kind muscle_kind_new (char const *k);
|
||||
|
||||
/* Conversion to string. */
|
||||
char const *muscle_kind_string (muscle_kind k);
|
||||
|
||||
|
||||
/* Create the MUSCLE_TABLE, and initialize it with default values.
|
||||
Also set up the MUSCLE_OBSTACK. */
|
||||
void muscle_init (void);
|
||||
|
||||
/* Insert (KEY, VALUE). If KEY already existed, overwrite the
|
||||
previous value. Otherwise create as a muscle_string type. */
|
||||
void muscle_insert (char const *key, char const *value);
|
||||
|
||||
/* Find the value of muscle KEY. Unlike MUSCLE_FIND, this is always
|
||||
reliable to determine whether KEY has a value. */
|
||||
char const *muscle_find_const (char const *key);
|
||||
|
||||
/* Find the value of muscle KEY. Abort if muscle_insert was invoked
|
||||
more recently than muscle_grow for KEY since muscle_find can't
|
||||
return a char const *. */
|
||||
char *muscle_find (char const *key);
|
||||
|
||||
/* Free all the memory consumed by the muscle machinery only. */
|
||||
void muscle_free (void);
|
||||
|
||||
|
||||
@@ -47,14 +78,14 @@ extern struct obstack muscle_obstack;
|
||||
} while (0)
|
||||
|
||||
# define MUSCLE_INSERT_INT(Key, Value) \
|
||||
MUSCLE_INSERTF(Key, "%d", Value)
|
||||
MUSCLE_INSERTF (Key, "%d", Value)
|
||||
|
||||
# define MUSCLE_INSERT_LONG_INT(Key, Value) \
|
||||
MUSCLE_INSERTF(Key, "%ld", Value)
|
||||
MUSCLE_INSERTF (Key, "%ld", Value)
|
||||
|
||||
/* Key -> Value, but don't apply escaping to Value. */
|
||||
# define MUSCLE_INSERT_STRING_RAW(Key, Value) \
|
||||
MUSCLE_INSERTF(Key, "%s", Value)
|
||||
MUSCLE_INSERTF (Key, "%s", Value)
|
||||
|
||||
/* Key -> Value, applying M4 escaping to Value. */
|
||||
# define MUSCLE_INSERT_STRING(Key, Value) \
|
||||
@@ -63,23 +94,14 @@ extern struct obstack muscle_obstack;
|
||||
muscle_insert (Key, obstack_finish0 (&muscle_obstack)); \
|
||||
} while (0)
|
||||
|
||||
/* Key -> Value, applying C escaping to Value (and then M4). */
|
||||
# define MUSCLE_INSERT_C_STRING(Key, Value) \
|
||||
do { \
|
||||
obstack_escape (&muscle_obstack, \
|
||||
quotearg_style (c_quoting_style, Value)); \
|
||||
muscle_insert (Key, obstack_finish0 (&muscle_obstack)); \
|
||||
} while (0)
|
||||
|
||||
/* Append VALUE to the current value of KEY. If KEY did not already
|
||||
exist, create it. Use MUSCLE_OBSTACK. De-allocate the previously
|
||||
associated value. Copy VALUE and SEPARATOR. */
|
||||
|
||||
void muscle_grow (const char *key, const char *value, const char *separator);
|
||||
MUSCLE_INSERT_STRING (Key, quotearg_style (c_quoting_style, Value))
|
||||
|
||||
|
||||
/* Append VALUE to the current value of KEY, using muscle_grow. But
|
||||
in addition, issue a synchronization line for the location LOC. */
|
||||
|
||||
in addition, issue a synchronization line for the location LOC.
|
||||
Be sure to append on a new line. */
|
||||
void muscle_code_grow (const char *key, const char *value, location loc);
|
||||
|
||||
|
||||
@@ -92,14 +114,15 @@ void muscle_pair_list_grow (const char *muscle,
|
||||
|
||||
/* Grow KEY for the occurrence of the name USER_NAME at LOC appropriately for
|
||||
use with b4_check_user_names in ../data/bison.m4. USER_NAME is not escaped
|
||||
with digraphs, so it must not contain `[' or `]'. */
|
||||
with digraphs, so it must not contain '[' or ']'. */
|
||||
void muscle_user_name_list_grow (char const *key, char const *user_name,
|
||||
location loc);
|
||||
|
||||
/* Indicates whether a variable's value was specified with -D/--define, with
|
||||
-F/--force-define, or in the grammar file. */
|
||||
typedef enum {
|
||||
MUSCLE_PERCENT_DEFINE_D = 0, MUSCLE_PERCENT_DEFINE_F,
|
||||
MUSCLE_PERCENT_DEFINE_D = 0,
|
||||
MUSCLE_PERCENT_DEFINE_F,
|
||||
MUSCLE_PERCENT_DEFINE_GRAMMAR_FILE
|
||||
} muscle_percent_define_how;
|
||||
|
||||
@@ -113,6 +136,7 @@ typedef enum {
|
||||
this as a user occurrence of VARIABLE by invoking
|
||||
muscle_user_name_list_grow. */
|
||||
void muscle_percent_define_insert (char const *variable, location variable_loc,
|
||||
muscle_kind kind,
|
||||
char const *value,
|
||||
muscle_percent_define_how how);
|
||||
|
||||
@@ -186,6 +210,8 @@ void muscle_percent_define_check_values (char const * const *values);
|
||||
void muscle_percent_code_grow (char const *qualifier, location qualifier_loc,
|
||||
char const *code, location code_loc);
|
||||
|
||||
/* Output the definition of all the current muscles into a list of
|
||||
m4_defines. */
|
||||
void muscles_m4_output (FILE *out);
|
||||
|
||||
#endif /* not MUSCLE_TAB_H_ */
|
||||
|
||||
+25
-21
@@ -90,20 +90,19 @@ Name (char const *name, \
|
||||
\
|
||||
lmin = min; \
|
||||
lmax = max; \
|
||||
/* Build `NAME_min' and `NAME_max' in the obstack. */ \
|
||||
/* Build 'NAME_min' and 'NAME_max' in the obstack. */ \
|
||||
obstack_printf (&format_obstack, "%s_min", name); \
|
||||
MUSCLE_INSERT_LONG_INT (obstack_finish0 (&format_obstack), lmin); \
|
||||
obstack_printf (&format_obstack, "%s_max", name); \
|
||||
MUSCLE_INSERT_LONG_INT (obstack_finish0 (&format_obstack), lmax); \
|
||||
}
|
||||
|
||||
GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_unsigned_int_table, unsigned int)
|
||||
GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_int_table, int)
|
||||
GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_base_table, base_number)
|
||||
GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_rule_number_table, rule_number)
|
||||
GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_symbol_number_table, symbol_number)
|
||||
GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_state_number_table, state_number)
|
||||
|
||||
GENERATE_MUSCLE_INSERT_TABLE (muscle_insert_unsigned_int_table, unsigned int)
|
||||
GENERATE_MUSCLE_INSERT_TABLE (muscle_insert_int_table, int)
|
||||
GENERATE_MUSCLE_INSERT_TABLE (muscle_insert_base_table, base_number)
|
||||
GENERATE_MUSCLE_INSERT_TABLE (muscle_insert_rule_number_table, rule_number)
|
||||
GENERATE_MUSCLE_INSERT_TABLE (muscle_insert_symbol_number_table, symbol_number)
|
||||
GENERATE_MUSCLE_INSERT_TABLE (muscle_insert_state_number_table, state_number)
|
||||
|
||||
/*----------------------------------------------------------------.
|
||||
| Print to OUT a representation of CP quoted and escaped for M4. |
|
||||
@@ -227,7 +226,7 @@ prepare_rules (void)
|
||||
/* LHS of the rule R. */
|
||||
r1[r] = rules[r].lhs->number;
|
||||
/* Length of rule R's RHS. */
|
||||
r2[r] = rule_rhs_length(&rules[r]);
|
||||
r2[r] = rule_rhs_length (&rules[r]);
|
||||
/* Line where rule was defined. */
|
||||
rline[r] = rules[r].location.start.line;
|
||||
/* Dynamic precedence (GLR). */
|
||||
@@ -417,31 +416,31 @@ prepare_symbol_definitions (void)
|
||||
|
||||
/* Whether the symbol has an identifier. */
|
||||
value = symbol_id_get (sym);
|
||||
SET_KEY("has_id");
|
||||
SET_KEY ("has_id");
|
||||
MUSCLE_INSERT_INT (key, !!value);
|
||||
|
||||
/* Its identifier. */
|
||||
SET_KEY("id");
|
||||
SET_KEY ("id");
|
||||
MUSCLE_INSERT_STRING (key, value ? value : "");
|
||||
|
||||
/* Its tag. Typically for documentation purpose. */
|
||||
SET_KEY("tag");
|
||||
SET_KEY ("tag");
|
||||
MUSCLE_INSERT_STRING (key, sym->tag);
|
||||
|
||||
SET_KEY("user_number");
|
||||
SET_KEY ("user_number");
|
||||
MUSCLE_INSERT_INT (key, sym->user_token_number);
|
||||
|
||||
SET_KEY("is_token");
|
||||
SET_KEY ("is_token");
|
||||
MUSCLE_INSERT_INT (key,
|
||||
i < ntokens && sym != errtoken && sym != undeftoken);
|
||||
|
||||
SET_KEY("number");
|
||||
SET_KEY ("number");
|
||||
MUSCLE_INSERT_INT (key, sym->number);
|
||||
|
||||
SET_KEY("has_type");
|
||||
SET_KEY ("has_type");
|
||||
MUSCLE_INSERT_INT (key, !!sym->type_name);
|
||||
|
||||
SET_KEY("type");
|
||||
SET_KEY ("type");
|
||||
MUSCLE_INSERT_STRING (key, sym->type_name ? sym->type_name : "");
|
||||
|
||||
{
|
||||
@@ -451,18 +450,18 @@ prepare_symbol_definitions (void)
|
||||
/* "printer", not "%printer". */
|
||||
char const *pname = code_props_type_string (j) + 1;
|
||||
code_props const *p = symbol_code_props_get (sym, j);
|
||||
SET_KEY2("has", pname);
|
||||
SET_KEY2 ("has", pname);
|
||||
MUSCLE_INSERT_INT (key, !!p->code);
|
||||
|
||||
if (p->code)
|
||||
{
|
||||
SET_KEY2(pname, "file");
|
||||
SET_KEY2 (pname, "file");
|
||||
MUSCLE_INSERT_STRING (key, p->location.start.file);
|
||||
|
||||
SET_KEY2(pname, "line");
|
||||
SET_KEY2 (pname, "line");
|
||||
MUSCLE_INSERT_INT (key, p->location.start.line);
|
||||
|
||||
SET_KEY(pname);
|
||||
SET_KEY (pname);
|
||||
MUSCLE_INSERT_STRING_RAW (key, p->code);
|
||||
}
|
||||
}
|
||||
@@ -705,6 +704,11 @@ output (void)
|
||||
/* Process the selected skeleton file. */
|
||||
output_skeleton ();
|
||||
|
||||
/* If late errors were generated, destroy the generated source
|
||||
files. */
|
||||
if (complaint_status)
|
||||
unlink_generated_sources ();
|
||||
|
||||
obstack_free (&format_obstack, NULL);
|
||||
}
|
||||
|
||||
|
||||
+704
-702
File diff suppressed because it is too large
Load Diff
+89
-133
@@ -1,4 +1,4 @@
|
||||
/* A Bison parser, made by GNU Bison 2.7.1021-bb417-dirty. */
|
||||
/* A Bison parser, made by GNU Bison 3.0. */
|
||||
|
||||
/* Bison interface for Yacc-like parsers in C
|
||||
|
||||
@@ -48,10 +48,12 @@
|
||||
extern int gram_debug;
|
||||
#endif
|
||||
/* "%code requires" blocks. */
|
||||
#line 223 "src/parse-gram.y" /* yacc.c:1932 */
|
||||
#line 21 "src/parse-gram.y" /* yacc.c:1909 */
|
||||
|
||||
#include "symlist.h"
|
||||
#include "symtab.h"
|
||||
#line 221 "src/parse-gram.y" /* yacc.c:1909 */
|
||||
|
||||
# ifndef PARAM_TYPE
|
||||
# define PARAM_TYPE
|
||||
typedef enum
|
||||
{
|
||||
param_none = 0,
|
||||
@@ -59,10 +61,10 @@ extern int gram_debug;
|
||||
param_parse = 1 << 1,
|
||||
param_both = param_lex | param_parse
|
||||
} param_type;
|
||||
# endif
|
||||
#line 645 "src/parse-gram.y" /* yacc.c:1909 */
|
||||
#include "muscle-tab.h"
|
||||
|
||||
|
||||
#line 66 "src/parse-gram.h" /* yacc.c:1932 */
|
||||
#line 68 "src/parse-gram.h" /* yacc.c:1909 */
|
||||
|
||||
/* Token type. */
|
||||
#ifndef GRAM_TOKENTYPE
|
||||
@@ -71,143 +73,97 @@ extern int gram_debug;
|
||||
{
|
||||
GRAM_EOF = 0,
|
||||
STRING = 258,
|
||||
INT = 259,
|
||||
PERCENT_TOKEN = 260,
|
||||
PERCENT_NTERM = 261,
|
||||
PERCENT_TYPE = 262,
|
||||
PERCENT_DESTRUCTOR = 263,
|
||||
PERCENT_PRINTER = 264,
|
||||
PERCENT_LEFT = 265,
|
||||
PERCENT_RIGHT = 266,
|
||||
PERCENT_NONASSOC = 267,
|
||||
PERCENT_PRECEDENCE = 268,
|
||||
PERCENT_PREC = 269,
|
||||
PERCENT_DPREC = 270,
|
||||
PERCENT_MERGE = 271,
|
||||
PERCENT_CODE = 272,
|
||||
PERCENT_DEFAULT_PREC = 273,
|
||||
PERCENT_DEFINE = 274,
|
||||
PERCENT_DEFINES = 275,
|
||||
PERCENT_ERROR_VERBOSE = 276,
|
||||
PERCENT_EXPECT = 277,
|
||||
PERCENT_EXPECT_RR = 278,
|
||||
PERCENT_FLAG = 279,
|
||||
PERCENT_FILE_PREFIX = 280,
|
||||
PERCENT_GLR_PARSER = 281,
|
||||
PERCENT_INITIAL_ACTION = 282,
|
||||
PERCENT_LANGUAGE = 283,
|
||||
PERCENT_NAME_PREFIX = 284,
|
||||
PERCENT_NO_DEFAULT_PREC = 285,
|
||||
PERCENT_NO_LINES = 286,
|
||||
PERCENT_NONDETERMINISTIC_PARSER = 287,
|
||||
PERCENT_OUTPUT = 288,
|
||||
PERCENT_REQUIRE = 289,
|
||||
PERCENT_SKELETON = 290,
|
||||
PERCENT_START = 291,
|
||||
PERCENT_TOKEN_TABLE = 292,
|
||||
PERCENT_VERBOSE = 293,
|
||||
PERCENT_YACC = 294,
|
||||
BRACED_CODE = 295,
|
||||
BRACED_PREDICATE = 296,
|
||||
BRACKETED_ID = 297,
|
||||
CHAR = 298,
|
||||
EPILOGUE = 299,
|
||||
EQUAL = 300,
|
||||
ID = 301,
|
||||
ID_COLON = 302,
|
||||
PERCENT_PERCENT = 303,
|
||||
PIPE = 304,
|
||||
PROLOGUE = 305,
|
||||
SEMICOLON = 306,
|
||||
TAG = 307,
|
||||
TAG_ANY = 308,
|
||||
TAG_NONE = 309,
|
||||
PERCENT_TOKEN = 259,
|
||||
PERCENT_NTERM = 260,
|
||||
PERCENT_TYPE = 261,
|
||||
PERCENT_DESTRUCTOR = 262,
|
||||
PERCENT_PRINTER = 263,
|
||||
PERCENT_LEFT = 264,
|
||||
PERCENT_RIGHT = 265,
|
||||
PERCENT_NONASSOC = 266,
|
||||
PERCENT_PRECEDENCE = 267,
|
||||
PERCENT_PREC = 268,
|
||||
PERCENT_DPREC = 269,
|
||||
PERCENT_MERGE = 270,
|
||||
PERCENT_CODE = 271,
|
||||
PERCENT_DEFAULT_PREC = 272,
|
||||
PERCENT_DEFINE = 273,
|
||||
PERCENT_DEFINES = 274,
|
||||
PERCENT_ERROR_VERBOSE = 275,
|
||||
PERCENT_EXPECT = 276,
|
||||
PERCENT_EXPECT_RR = 277,
|
||||
PERCENT_FLAG = 278,
|
||||
PERCENT_FILE_PREFIX = 279,
|
||||
PERCENT_GLR_PARSER = 280,
|
||||
PERCENT_INITIAL_ACTION = 281,
|
||||
PERCENT_LANGUAGE = 282,
|
||||
PERCENT_NAME_PREFIX = 283,
|
||||
PERCENT_NO_DEFAULT_PREC = 284,
|
||||
PERCENT_NO_LINES = 285,
|
||||
PERCENT_NONDETERMINISTIC_PARSER = 286,
|
||||
PERCENT_OUTPUT = 287,
|
||||
PERCENT_REQUIRE = 288,
|
||||
PERCENT_SKELETON = 289,
|
||||
PERCENT_START = 290,
|
||||
PERCENT_TOKEN_TABLE = 291,
|
||||
PERCENT_VERBOSE = 292,
|
||||
PERCENT_YACC = 293,
|
||||
BRACED_CODE = 294,
|
||||
BRACED_PREDICATE = 295,
|
||||
BRACKETED_ID = 296,
|
||||
CHAR = 297,
|
||||
EPILOGUE = 298,
|
||||
EQUAL = 299,
|
||||
ID = 300,
|
||||
ID_COLON = 301,
|
||||
PERCENT_PERCENT = 302,
|
||||
PIPE = 303,
|
||||
PROLOGUE = 304,
|
||||
SEMICOLON = 305,
|
||||
TAG = 306,
|
||||
TAG_ANY = 307,
|
||||
TAG_NONE = 308,
|
||||
INT = 309,
|
||||
PERCENT_PARAM = 310,
|
||||
PERCENT_UNION = 311
|
||||
PERCENT_UNION = 311,
|
||||
PERCENT_EMPTY = 312
|
||||
};
|
||||
#endif
|
||||
/* Tokens. */
|
||||
#define GRAM_EOF 0
|
||||
#define STRING 258
|
||||
#define INT 259
|
||||
#define PERCENT_TOKEN 260
|
||||
#define PERCENT_NTERM 261
|
||||
#define PERCENT_TYPE 262
|
||||
#define PERCENT_DESTRUCTOR 263
|
||||
#define PERCENT_PRINTER 264
|
||||
#define PERCENT_LEFT 265
|
||||
#define PERCENT_RIGHT 266
|
||||
#define PERCENT_NONASSOC 267
|
||||
#define PERCENT_PRECEDENCE 268
|
||||
#define PERCENT_PREC 269
|
||||
#define PERCENT_DPREC 270
|
||||
#define PERCENT_MERGE 271
|
||||
#define PERCENT_CODE 272
|
||||
#define PERCENT_DEFAULT_PREC 273
|
||||
#define PERCENT_DEFINE 274
|
||||
#define PERCENT_DEFINES 275
|
||||
#define PERCENT_ERROR_VERBOSE 276
|
||||
#define PERCENT_EXPECT 277
|
||||
#define PERCENT_EXPECT_RR 278
|
||||
#define PERCENT_FLAG 279
|
||||
#define PERCENT_FILE_PREFIX 280
|
||||
#define PERCENT_GLR_PARSER 281
|
||||
#define PERCENT_INITIAL_ACTION 282
|
||||
#define PERCENT_LANGUAGE 283
|
||||
#define PERCENT_NAME_PREFIX 284
|
||||
#define PERCENT_NO_DEFAULT_PREC 285
|
||||
#define PERCENT_NO_LINES 286
|
||||
#define PERCENT_NONDETERMINISTIC_PARSER 287
|
||||
#define PERCENT_OUTPUT 288
|
||||
#define PERCENT_REQUIRE 289
|
||||
#define PERCENT_SKELETON 290
|
||||
#define PERCENT_START 291
|
||||
#define PERCENT_TOKEN_TABLE 292
|
||||
#define PERCENT_VERBOSE 293
|
||||
#define PERCENT_YACC 294
|
||||
#define BRACED_CODE 295
|
||||
#define BRACED_PREDICATE 296
|
||||
#define BRACKETED_ID 297
|
||||
#define CHAR 298
|
||||
#define EPILOGUE 299
|
||||
#define EQUAL 300
|
||||
#define ID 301
|
||||
#define ID_COLON 302
|
||||
#define PERCENT_PERCENT 303
|
||||
#define PIPE 304
|
||||
#define PROLOGUE 305
|
||||
#define SEMICOLON 306
|
||||
#define TAG 307
|
||||
#define TAG_ANY 308
|
||||
#define TAG_NONE 309
|
||||
#define PERCENT_PARAM 310
|
||||
#define PERCENT_UNION 311
|
||||
|
||||
/* Value type. */
|
||||
#if ! defined GRAM_STYPE && ! defined GRAM_STYPE_IS_DECLARED
|
||||
typedef union GRAM_STYPE GRAM_STYPE;
|
||||
union GRAM_STYPE
|
||||
{
|
||||
#line 109 "src/parse-gram.y" /* yacc.c:1932 */
|
||||
|
||||
assoc assoc;
|
||||
char *code;
|
||||
char const *chars;
|
||||
int integer;
|
||||
named_ref *named_ref;
|
||||
symbol *symbol;
|
||||
symbol_list *list;
|
||||
uniqstr uniqstr;
|
||||
unsigned char character;
|
||||
|
||||
#line 247 "src/parse-gram.y" /* yacc.c:1932 */
|
||||
|
||||
param_type param;
|
||||
|
||||
#line 423 "src/parse-gram.y" /* yacc.c:1932 */
|
||||
#line 182 "src/parse-gram.y" /* yacc.c:1909 */
|
||||
unsigned char character;
|
||||
#line 186 "src/parse-gram.y" /* yacc.c:1909 */
|
||||
char *code;
|
||||
#line 191 "src/parse-gram.y" /* yacc.c:1909 */
|
||||
uniqstr uniqstr;
|
||||
#line 199 "src/parse-gram.y" /* yacc.c:1909 */
|
||||
int integer;
|
||||
#line 203 "src/parse-gram.y" /* yacc.c:1909 */
|
||||
symbol *symbol;
|
||||
#line 208 "src/parse-gram.y" /* yacc.c:1909 */
|
||||
assoc assoc;
|
||||
#line 211 "src/parse-gram.y" /* yacc.c:1909 */
|
||||
symbol_list *list;
|
||||
#line 214 "src/parse-gram.y" /* yacc.c:1909 */
|
||||
named_ref *named_ref;
|
||||
#line 241 "src/parse-gram.y" /* yacc.c:1909 */
|
||||
param_type param;
|
||||
#line 409 "src/parse-gram.y" /* yacc.c:1909 */
|
||||
code_props_type code_type;
|
||||
#line 647 "src/parse-gram.y" /* yacc.c:1909 */
|
||||
|
||||
#line 211 "src/parse-gram.h" /* yacc.c:1932 */
|
||||
struct
|
||||
{
|
||||
char const *chars;
|
||||
muscle_kind kind;
|
||||
} value;
|
||||
|
||||
#line 167 "src/parse-gram.h" /* yacc.c:1909 */
|
||||
};
|
||||
# define GRAM_STYPE_IS_TRIVIAL 1
|
||||
# define GRAM_STYPE_IS_DECLARED 1
|
||||
|
||||
+184
-145
@@ -1,4 +1,4 @@
|
||||
%{/* Bison Grammar Parser -*- C -*-
|
||||
/* Bison Grammar Parser -*- C -*-
|
||||
|
||||
Copyright (C) 2002-2013 Free Software Foundation, Inc.
|
||||
|
||||
@@ -17,45 +17,35 @@
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
%code requires
|
||||
{
|
||||
#include "symlist.h"
|
||||
#include "symtab.h"
|
||||
}
|
||||
|
||||
%code top
|
||||
{
|
||||
/* On column 0 to please syntax-check. */
|
||||
#include <config.h>
|
||||
#include "system.h"
|
||||
|
||||
#include "c-ctype.h"
|
||||
#include "complain.h"
|
||||
#include "conflicts.h"
|
||||
#include "files.h"
|
||||
#include "getargs.h"
|
||||
#include "gram.h"
|
||||
#include "muscle-tab.h"
|
||||
#include "named-ref.h"
|
||||
#include "quotearg.h"
|
||||
#include "reader.h"
|
||||
#include "symlist.h"
|
||||
#include "symtab.h"
|
||||
#include "scan-gram.h"
|
||||
#include "scan-code.h"
|
||||
#include "xmemdup0.h"
|
||||
|
||||
#define YYLLOC_DEFAULT(Current, Rhs, N) (Current) = lloc_default (Rhs, N)
|
||||
static YYLTYPE lloc_default (YYLTYPE const *, int);
|
||||
|
||||
#define YY_LOCATION_PRINT(File, Loc) \
|
||||
location_print (File, Loc)
|
||||
|
||||
static void version_check (location const *loc, char const *version);
|
||||
|
||||
/* Request detailed syntax error messages, and pass them to GRAM_ERROR.
|
||||
FIXME: depends on the undocumented availability of YYLLOC. */
|
||||
#undef yyerror
|
||||
#define yyerror(Msg) \
|
||||
gram_error (&yylloc, Msg)
|
||||
static void gram_error (location const *, char const *);
|
||||
|
||||
static char const *char_name (char);
|
||||
%}
|
||||
}
|
||||
|
||||
%code
|
||||
{
|
||||
#include "system.h"
|
||||
|
||||
#include "c-ctype.h"
|
||||
#include "complain.h"
|
||||
#include "conflicts.h"
|
||||
#include "files.h"
|
||||
#include "getargs.h"
|
||||
#include "gram.h"
|
||||
#include "named-ref.h"
|
||||
#include "quotearg.h"
|
||||
#include "reader.h"
|
||||
#include "scan-gram.h"
|
||||
#include "scan-code.h"
|
||||
#include "xmemdup0.h"
|
||||
|
||||
static int current_prec = 0;
|
||||
static location current_lhs_location;
|
||||
static named_ref *current_lhs_named_ref;
|
||||
@@ -66,20 +56,37 @@ static char const *char_name (char);
|
||||
/** Set the new current left-hand side symbol, possibly common
|
||||
* to several right-hand side parts of rule.
|
||||
*/
|
||||
static
|
||||
void
|
||||
current_lhs(symbol *sym, location loc, named_ref *ref)
|
||||
{
|
||||
current_lhs_symbol = sym;
|
||||
current_lhs_location = loc;
|
||||
/* In order to simplify memory management, named references for lhs
|
||||
are always assigned by deep copy into the current symbol_list
|
||||
node. This is because a single named-ref in the grammar may
|
||||
result in several uses when the user factors lhs between several
|
||||
rules using "|". Therefore free the parser's original copy. */
|
||||
free (current_lhs_named_ref);
|
||||
current_lhs_named_ref = ref;
|
||||
}
|
||||
static void current_lhs (symbol *sym, location loc, named_ref *ref);
|
||||
|
||||
#define YYLLOC_DEFAULT(Current, Rhs, N) \
|
||||
(Current) = lloc_default (Rhs, N)
|
||||
static YYLTYPE lloc_default (YYLTYPE const *, int);
|
||||
|
||||
#define YY_LOCATION_PRINT(File, Loc) \
|
||||
location_print (Loc, File)
|
||||
|
||||
/* Strip initial '{' and final '}' (must be first and last characters).
|
||||
Return the result. */
|
||||
static char *strip_braces (char *code);
|
||||
|
||||
/* Convert CODE by calling code_props_plain_init if PLAIN, otherwise
|
||||
code_props_symbol_action_init. Call
|
||||
gram_scanner_last_string_free to release the latest string from
|
||||
the scanner (should be CODE). */
|
||||
static char const *translate_code (char *code, location loc, bool plain);
|
||||
|
||||
/* Convert CODE by calling code_props_plain_init after having
|
||||
stripped the first and last characters (expected to be '{', and
|
||||
'}'). Call gram_scanner_last_string_free to release the latest
|
||||
string from the scanner (should be CODE). */
|
||||
static char const *translate_code_braceless (char *code, location loc);
|
||||
|
||||
static void version_check (location const *loc, char const *version);
|
||||
|
||||
static void gram_error (location const *, char const *);
|
||||
|
||||
/* A string that describes a char (e.g., 'a' -> "'a'"). */
|
||||
static char const *char_name (char);
|
||||
|
||||
#define YYTYPE_INT16 int_fast16_t
|
||||
#define YYTYPE_INT8 int_fast8_t
|
||||
@@ -87,8 +94,8 @@ static char const *char_name (char);
|
||||
#define YYTYPE_UINT8 uint_fast8_t
|
||||
}
|
||||
|
||||
%define api.prefix "gram_"
|
||||
%define api.pure
|
||||
%define api.prefix {gram_}
|
||||
%define api.pure full
|
||||
%define locations
|
||||
%define parse.error verbose
|
||||
%define parse.lac full
|
||||
@@ -105,23 +112,9 @@ static char const *char_name (char);
|
||||
boundary_set (&@$.end, current_file, 1, 1);
|
||||
}
|
||||
|
||||
%union
|
||||
{
|
||||
assoc assoc;
|
||||
char *code;
|
||||
char const *chars;
|
||||
int integer;
|
||||
named_ref *named_ref;
|
||||
symbol *symbol;
|
||||
symbol_list *list;
|
||||
uniqstr uniqstr;
|
||||
unsigned char character;
|
||||
};
|
||||
|
||||
/* Define the tokens together with their human representation. */
|
||||
%token GRAM_EOF 0 "end of file"
|
||||
%token STRING "string"
|
||||
%token INT "integer"
|
||||
|
||||
%token PERCENT_TOKEN "%token"
|
||||
%token PERCENT_NTERM "%nterm"
|
||||
@@ -186,18 +179,16 @@ static char const *char_name (char);
|
||||
%token TAG_ANY "<*>"
|
||||
%token TAG_NONE "<>"
|
||||
|
||||
%union {unsigned char character;}
|
||||
%type <character> CHAR
|
||||
%printer { fputs (char_name ($$), yyo); } CHAR
|
||||
|
||||
/* braceless is not to be used for rule or symbol actions, as it
|
||||
calls code_props_plain_init. */
|
||||
%type <chars> STRING "%{...%}" EPILOGUE braceless content.opt
|
||||
%type <code> "{...}" "%?{...}"
|
||||
%printer { fputs (quotearg_style (c_quoting_style, $$), yyo); }
|
||||
STRING
|
||||
%printer { fprintf (yyo, "{\n%s\n}", $$); }
|
||||
braceless content.opt "{...}" "%{...%}" EPILOGUE
|
||||
%union {char *code;};
|
||||
%type <code> "{...}" "%?{...}" "%{...%}" EPILOGUE STRING
|
||||
%printer { fputs (quotearg_style (c_quoting_style, $$), yyo); } STRING
|
||||
%printer { fprintf (yyo, "{\n%s\n}", $$); } <code>
|
||||
|
||||
%union {uniqstr uniqstr;}
|
||||
%type <uniqstr> BRACKETED_ID ID ID_COLON PERCENT_FLAG TAG tag variable
|
||||
%printer { fputs ($$, yyo); } <uniqstr>
|
||||
%printer { fprintf (yyo, "[%s]", $$); } BRACKETED_ID
|
||||
@@ -205,15 +196,22 @@ static char const *char_name (char);
|
||||
%printer { fprintf (yyo, "%%%s", $$); } PERCENT_FLAG
|
||||
%printer { fprintf (yyo, "<%s>", $$); } TAG tag
|
||||
|
||||
%type <integer> INT
|
||||
%union {int integer;};
|
||||
%token <integer> INT "integer"
|
||||
%printer { fprintf (yyo, "%d", $$); } <integer>
|
||||
|
||||
%union {symbol *symbol;}
|
||||
%type <symbol> id id_colon string_as_id symbol symbol.prec
|
||||
%printer { fprintf (yyo, "%s", $$->tag); } <symbol>
|
||||
%printer { fprintf (yyo, "%s:", $$->tag); } id_colon
|
||||
|
||||
%union {assoc assoc;};
|
||||
%type <assoc> precedence_declarator
|
||||
|
||||
%union {symbol_list *list;}
|
||||
%type <list> symbols.1 symbols.prec generic_symlist generic_symlist_item
|
||||
|
||||
%union {named_ref *named_ref;}
|
||||
%type <named_ref> named_ref.opt
|
||||
|
||||
/*---------.
|
||||
@@ -221,8 +219,6 @@ static char const *char_name (char);
|
||||
`---------*/
|
||||
%code requires
|
||||
{
|
||||
# ifndef PARAM_TYPE
|
||||
# define PARAM_TYPE
|
||||
typedef enum
|
||||
{
|
||||
param_none = 0,
|
||||
@@ -230,7 +226,6 @@ static char const *char_name (char);
|
||||
param_parse = 1 << 1,
|
||||
param_both = param_lex | param_parse
|
||||
} param_type;
|
||||
# endif
|
||||
};
|
||||
%code
|
||||
{
|
||||
@@ -243,20 +238,17 @@ static char const *char_name (char);
|
||||
static void add_param (param_type type, char *decl, location loc);
|
||||
static param_type current_param = param_none;
|
||||
};
|
||||
%union
|
||||
{
|
||||
param_type param;
|
||||
}
|
||||
%union {param_type param;}
|
||||
%token <param> PERCENT_PARAM "%param";
|
||||
%printer
|
||||
{
|
||||
switch ($$)
|
||||
{
|
||||
#define CASE(In, Out) \
|
||||
case param_ ## In: fputs ("%" #Out, stderr); break
|
||||
CASE(lex, lex-param);
|
||||
CASE(parse, parse-param);
|
||||
CASE(both, param);
|
||||
case param_ ## In: fputs ("%" #Out, yyo); break
|
||||
CASE (lex, lex-param);
|
||||
CASE (parse, parse-param);
|
||||
CASE (both, param);
|
||||
#undef CASE
|
||||
case param_none: aver (false); break;
|
||||
}
|
||||
@@ -278,7 +270,7 @@ input:
|
||||
`------------------------------------*/
|
||||
|
||||
prologue_declarations:
|
||||
/* Nothing */
|
||||
%empty
|
||||
| prologue_declarations prologue_declaration
|
||||
;
|
||||
|
||||
@@ -286,21 +278,17 @@ prologue_declaration:
|
||||
grammar_declaration
|
||||
| "%{...%}"
|
||||
{
|
||||
code_props plain_code;
|
||||
code_props_plain_init (&plain_code, $1, @1);
|
||||
code_props_translate_code (&plain_code);
|
||||
gram_scanner_last_string_free ();
|
||||
muscle_code_grow (union_seen ? "post_prologue" : "pre_prologue",
|
||||
plain_code.code, @1);
|
||||
translate_code ($1, @1, true), @1);
|
||||
code_scanner_last_string_free ();
|
||||
}
|
||||
| "%<flag>"
|
||||
{
|
||||
muscle_percent_define_ensure ($1, @1, true);
|
||||
}
|
||||
| "%define" variable content.opt
|
||||
| "%define" variable value
|
||||
{
|
||||
muscle_percent_define_insert ($2, @2, $3,
|
||||
muscle_percent_define_insert ($2, @2, $3.kind, $3.chars,
|
||||
MUSCLE_PERCENT_DEFINE_GRAMMAR_FILE);
|
||||
}
|
||||
| "%defines" { defines_flag = true; }
|
||||
@@ -311,7 +299,8 @@ prologue_declaration:
|
||||
}
|
||||
| "%error-verbose"
|
||||
{
|
||||
muscle_percent_define_insert ("parse.error", @1, "verbose",
|
||||
muscle_percent_define_insert ("parse.error", @1, muscle_keyword,
|
||||
"verbose",
|
||||
MUSCLE_PERCENT_DEFINE_GRAMMAR_FILE);
|
||||
}
|
||||
| "%expect" INT { expected_sr_conflicts = $2; }
|
||||
@@ -324,11 +313,7 @@ prologue_declaration:
|
||||
}
|
||||
| "%initial-action" "{...}"
|
||||
{
|
||||
code_props action;
|
||||
code_props_symbol_action_init (&action, $2, @2);
|
||||
code_props_translate_code (&action);
|
||||
gram_scanner_last_string_free ();
|
||||
muscle_code_grow ("initial_action", action.code, @2);
|
||||
muscle_code_grow ("initial_action", translate_code ($2, @2, false), @2);
|
||||
code_scanner_last_string_free ();
|
||||
}
|
||||
| "%language" STRING { language_argmatch ($2, grammar_prio, @1); }
|
||||
@@ -405,16 +390,17 @@ grammar_declaration:
|
||||
{
|
||||
default_prec = false;
|
||||
}
|
||||
| "%code" braceless
|
||||
| "%code" "{...}"
|
||||
{
|
||||
/* Do not invoke muscle_percent_code_grow here since it invokes
|
||||
muscle_user_name_list_grow. */
|
||||
muscle_code_grow ("percent_code()", $2, @2);
|
||||
muscle_code_grow ("percent_code()",
|
||||
translate_code_braceless ($2, @2), @2);
|
||||
code_scanner_last_string_free ();
|
||||
}
|
||||
| "%code" ID braceless
|
||||
| "%code" ID "{...}"
|
||||
{
|
||||
muscle_percent_code_grow ($2, @2, $3, @3);
|
||||
muscle_percent_code_grow ($2, @2, translate_code_braceless ($3, @3), @3);
|
||||
code_scanner_last_string_free ();
|
||||
}
|
||||
;
|
||||
@@ -434,15 +420,15 @@ code_props_type:
|
||||
%token PERCENT_UNION "%union";
|
||||
|
||||
union_name:
|
||||
/* Nothing. */ {}
|
||||
| ID { muscle_code_grow ("union_name", $1, @1); }
|
||||
%empty {}
|
||||
| ID { muscle_code_grow ("union_name", $1, @1); }
|
||||
;
|
||||
|
||||
grammar_declaration:
|
||||
"%union" union_name braceless
|
||||
"%union" union_name "{...}"
|
||||
{
|
||||
union_seen = true;
|
||||
muscle_code_grow ("stype", $3, @3);
|
||||
muscle_code_grow ("union_members", translate_code_braceless ($3, @3), @3);
|
||||
code_scanner_last_string_free ();
|
||||
}
|
||||
;
|
||||
@@ -494,8 +480,8 @@ precedence_declarator:
|
||||
;
|
||||
|
||||
tag.opt:
|
||||
/* Nothing. */ { current_type = NULL; }
|
||||
| TAG { current_type = $1; tag_seen = true; }
|
||||
%empty { current_type = NULL; }
|
||||
| TAG { current_type = $1; tag_seen = true; }
|
||||
;
|
||||
|
||||
/* Just like symbols.1 but accept INT for the sake of POSIX. */
|
||||
@@ -507,8 +493,17 @@ symbols.prec:
|
||||
;
|
||||
|
||||
symbol.prec:
|
||||
symbol { $$ = $1; }
|
||||
| symbol INT { $$ = $1; symbol_user_token_number_set ($1, $2, @2); }
|
||||
symbol
|
||||
{
|
||||
$$ = $1;
|
||||
symbol_class_set ($1, token_sym, @1, false);
|
||||
}
|
||||
| symbol INT
|
||||
{
|
||||
$$ = $1;
|
||||
symbol_user_token_number_set ($1, $2, @2);
|
||||
symbol_class_set ($1, token_sym, @1, false);
|
||||
}
|
||||
;
|
||||
|
||||
/* One or more symbols to be %typed. */
|
||||
@@ -609,8 +604,9 @@ rhses.1:
|
||||
| rhses.1 ";"
|
||||
;
|
||||
|
||||
%token PERCENT_EMPTY "%empty";
|
||||
rhs:
|
||||
/* Nothing. */
|
||||
%empty
|
||||
{ grammar_current_rule_begin (current_lhs_symbol, current_lhs_location,
|
||||
current_lhs_named_ref); }
|
||||
| rhs symbol named_ref.opt
|
||||
@@ -619,6 +615,8 @@ rhs:
|
||||
{ grammar_current_rule_action_append ($2, @2, $3, false); }
|
||||
| rhs "%?{...}"
|
||||
{ grammar_current_rule_action_append ($2, @2, NULL, true); }
|
||||
| rhs "%empty"
|
||||
{ grammar_current_rule_empty_set (@2); }
|
||||
| rhs "%prec" symbol
|
||||
{ grammar_current_rule_prec_set ($3, @3); }
|
||||
| rhs "%dprec" INT
|
||||
@@ -628,44 +626,47 @@ rhs:
|
||||
;
|
||||
|
||||
named_ref.opt:
|
||||
/* Nothing. */ { $$ = 0; }
|
||||
|
|
||||
BRACKETED_ID { $$ = named_ref_new($1, @1); }
|
||||
%empty { $$ = 0; }
|
||||
| BRACKETED_ID { $$ = named_ref_new ($1, @1); }
|
||||
;
|
||||
|
||||
/*---------------------------.
|
||||
| variable and content.opt. |
|
||||
`---------------------------*/
|
||||
/*---------------------.
|
||||
| variable and value. |
|
||||
`---------------------*/
|
||||
|
||||
/* The STRING form of variable is deprecated and is not M4-friendly.
|
||||
For example, M4 fails for `%define "[" "value"'. */
|
||||
For example, M4 fails for '%define "[" "value"'. */
|
||||
variable:
|
||||
ID
|
||||
| STRING { $$ = uniqstr_new ($1); }
|
||||
;
|
||||
|
||||
/* Some content or empty by default. */
|
||||
content.opt:
|
||||
/* Nothing. */ { $$ = ""; }
|
||||
| ID { $$ = $1; }
|
||||
| STRING
|
||||
;
|
||||
|
||||
|
||||
/*------------.
|
||||
| braceless. |
|
||||
`------------*/
|
||||
|
||||
braceless:
|
||||
"{...}"
|
||||
%code requires {#include "muscle-tab.h"};
|
||||
%union
|
||||
{
|
||||
struct
|
||||
{
|
||||
char const *chars;
|
||||
muscle_kind kind;
|
||||
} value;
|
||||
};
|
||||
%type <value> value;
|
||||
%printer
|
||||
{
|
||||
switch ($$.kind)
|
||||
{
|
||||
code_props plain_code;
|
||||
$1[strlen ($1) - 1] = '\n';
|
||||
code_props_plain_init (&plain_code, $1+1, @1);
|
||||
code_props_translate_code (&plain_code);
|
||||
gram_scanner_last_string_free ();
|
||||
$$ = plain_code.code;
|
||||
case muscle_code: fprintf (yyo, "{%s}", $$.chars); break;
|
||||
case muscle_keyword: fprintf (yyo, "%s", $$.chars); break;
|
||||
case muscle_string: fprintf (yyo, "\"%s\"", $$.chars); break;
|
||||
}
|
||||
} <value>;
|
||||
|
||||
value:
|
||||
%empty { $$.kind = muscle_keyword; $$.chars = ""; }
|
||||
| ID { $$.kind = muscle_keyword; $$.chars = $1; }
|
||||
| STRING { $$.kind = muscle_string; $$.chars = $1; }
|
||||
| "{...}" { $$.kind = muscle_code; $$.chars = strip_braces ($1); }
|
||||
;
|
||||
|
||||
|
||||
@@ -707,14 +708,10 @@ string_as_id:
|
||||
;
|
||||
|
||||
epilogue.opt:
|
||||
/* Nothing. */
|
||||
%empty
|
||||
| "%%" EPILOGUE
|
||||
{
|
||||
code_props plain_code;
|
||||
code_props_plain_init (&plain_code, $2, @2);
|
||||
code_props_translate_code (&plain_code);
|
||||
gram_scanner_last_string_free ();
|
||||
muscle_code_grow ("epilogue", plain_code.code, @2);
|
||||
muscle_code_grow ("epilogue", translate_code ($2, @2, true), @2);
|
||||
code_scanner_last_string_free ();
|
||||
}
|
||||
;
|
||||
@@ -750,6 +747,33 @@ lloc_default (YYLTYPE const *rhs, int n)
|
||||
return loc;
|
||||
}
|
||||
|
||||
static
|
||||
char *strip_braces (char *code)
|
||||
{
|
||||
code[strlen (code) - 1] = 0;
|
||||
return code + 1;
|
||||
}
|
||||
|
||||
static
|
||||
char const *
|
||||
translate_code (char *code, location loc, bool plain)
|
||||
{
|
||||
code_props plain_code;
|
||||
if (plain)
|
||||
code_props_plain_init (&plain_code, code, loc);
|
||||
else
|
||||
code_props_symbol_action_init (&plain_code, code, loc);
|
||||
code_props_translate_code (&plain_code);
|
||||
gram_scanner_last_string_free ();
|
||||
return plain_code.code;
|
||||
}
|
||||
|
||||
static
|
||||
char const *
|
||||
translate_code_braceless (char *code, location loc)
|
||||
{
|
||||
return translate_code (strip_braces (code), loc, true);
|
||||
}
|
||||
|
||||
static void
|
||||
add_param (param_type type, char *decl, location loc)
|
||||
@@ -832,3 +856,18 @@ char_name (char c)
|
||||
return quotearg_style (escape_quoting_style, buf);
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
current_lhs (symbol *sym, location loc, named_ref *ref)
|
||||
{
|
||||
current_lhs_symbol = sym;
|
||||
current_lhs_location = loc;
|
||||
/* In order to simplify memory management, named references for lhs
|
||||
are always assigned by deep copy into the current symbol_list
|
||||
node. This is because a single named-ref in the grammar may
|
||||
result in several uses when the user factors lhs between several
|
||||
rules using "|". Therefore free the parser's original copy. */
|
||||
free (current_lhs_named_ref);
|
||||
current_lhs_named_ref = ref;
|
||||
}
|
||||
|
||||
+46
-40
@@ -45,7 +45,8 @@ struct escape_buf
|
||||
char *ptr;
|
||||
size_t size;
|
||||
};
|
||||
static struct escape_buf escape_bufs[3];
|
||||
enum { num_escape_bufs = 3 };
|
||||
static struct escape_buf escape_bufs[num_escape_bufs];
|
||||
|
||||
|
||||
/*--------------------------------.
|
||||
@@ -64,40 +65,39 @@ print_core (FILE *out, int level, state *s)
|
||||
sitems = itemset;
|
||||
snritems = nitemset;
|
||||
|
||||
if (!snritems) {
|
||||
xml_puts (out, level, "<itemset/>");
|
||||
return;
|
||||
}
|
||||
if (!snritems)
|
||||
{
|
||||
xml_puts (out, level, "<itemset/>");
|
||||
return;
|
||||
}
|
||||
|
||||
xml_puts (out, level, "<itemset>");
|
||||
|
||||
for (i = 0; i < snritems; i++)
|
||||
{
|
||||
bool printed = false;
|
||||
item_number *sp;
|
||||
item_number *sp1;
|
||||
rule_number r;
|
||||
item_number *sp1 = ritem + sitems[i];
|
||||
item_number *sp = sp1;
|
||||
rule *r;
|
||||
|
||||
sp1 = sp = ritem + sitems[i];
|
||||
|
||||
while (*sp >= 0)
|
||||
while (0 <= *sp)
|
||||
sp++;
|
||||
|
||||
r = item_number_as_rule_number (*sp);
|
||||
sp = rules[r].rhs;
|
||||
r = &rules[item_number_as_rule_number (*sp)];
|
||||
sp = r->rhs;
|
||||
|
||||
/* Display the lookahead tokens? */
|
||||
if (item_number_is_rule_number (*sp1))
|
||||
{
|
||||
reductions *reds = s->reductions;
|
||||
int red = state_reduction_find (s, &rules[r]);
|
||||
int red = state_reduction_find (s, r);
|
||||
/* Print item with lookaheads if there are. */
|
||||
if (reds->lookahead_tokens && red != -1)
|
||||
{
|
||||
xml_printf (out, level + 1,
|
||||
"<item rule-number=\"%d\" point=\"%d\">",
|
||||
rules[r].number, sp1 - sp);
|
||||
state_rule_lookahead_tokens_print_xml (s, &rules[r],
|
||||
r->number, sp1 - sp);
|
||||
state_rule_lookahead_tokens_print_xml (s, r,
|
||||
out, level + 2);
|
||||
xml_puts (out, level + 1, "</item>");
|
||||
printed = true;
|
||||
@@ -105,12 +105,10 @@ print_core (FILE *out, int level, state *s)
|
||||
}
|
||||
|
||||
if (!printed)
|
||||
{
|
||||
xml_printf (out, level + 1,
|
||||
"<item rule-number=\"%d\" point=\"%d\"/>",
|
||||
rules[r].number,
|
||||
sp1 - sp);
|
||||
}
|
||||
xml_printf (out, level + 1,
|
||||
"<item rule-number=\"%d\" point=\"%d\"/>",
|
||||
r->number,
|
||||
sp1 - sp);
|
||||
}
|
||||
xml_puts (out, level, "</itemset>");
|
||||
}
|
||||
@@ -135,10 +133,11 @@ print_transitions (state *s, FILE *out, int level)
|
||||
}
|
||||
|
||||
/* Nothing to report. */
|
||||
if (!n) {
|
||||
xml_puts (out, level, "<transitions/>");
|
||||
return;
|
||||
}
|
||||
if (!n)
|
||||
{
|
||||
xml_puts (out, level, "<transitions/>");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Report lookahead tokens and shifts. */
|
||||
xml_puts (out, level, "<transitions>");
|
||||
@@ -189,10 +188,11 @@ print_errs (FILE *out, int level, state *s)
|
||||
count = true;
|
||||
|
||||
/* Nothing to report. */
|
||||
if (!count) {
|
||||
xml_puts (out, level, "<errors/>");
|
||||
return;
|
||||
}
|
||||
if (!count)
|
||||
{
|
||||
xml_puts (out, level, "<errors/>");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Report lookahead tokens and errors. */
|
||||
xml_puts (out, level, "<errors>");
|
||||
@@ -209,7 +209,7 @@ print_errs (FILE *out, int level, state *s)
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------.
|
||||
| Report a reduction of RULE on LOOKAHEAD_TOKEN (which can be `default'). |
|
||||
| Report a reduction of RULE on LOOKAHEAD_TOKEN (which can be 'default'). |
|
||||
| If not ENABLED, the rule is masked by a shift or a reduce (S/R and |
|
||||
| R/R conflicts). |
|
||||
`-------------------------------------------------------------------------*/
|
||||
@@ -286,10 +286,11 @@ print_reductions (FILE *out, int level, state *s)
|
||||
}
|
||||
|
||||
/* Nothing to report. */
|
||||
if (!report) {
|
||||
xml_puts (out, level, "<reductions/>");
|
||||
return;
|
||||
}
|
||||
if (!report)
|
||||
{
|
||||
xml_puts (out, level, "<reductions/>");
|
||||
return;
|
||||
}
|
||||
|
||||
xml_puts (out, level, "<reductions>");
|
||||
|
||||
@@ -496,7 +497,6 @@ xml_escape (char const *str)
|
||||
void
|
||||
print_xml (void)
|
||||
{
|
||||
state_number i;
|
||||
int level = 0;
|
||||
|
||||
FILE *out = xfopen (spec_xml_file, "w");
|
||||
@@ -522,8 +522,11 @@ print_xml (void)
|
||||
/* print automaton */
|
||||
fputc ('\n', out);
|
||||
xml_puts (out, level + 1, "<automaton>");
|
||||
for (i = 0; i < nstates; i++)
|
||||
print_state (out, level + 2, states[i]);
|
||||
{
|
||||
state_number i;
|
||||
for (i = 0; i < nstates; i++)
|
||||
print_state (out, level + 2, states[i]);
|
||||
}
|
||||
xml_puts (out, level + 1, "</automaton>");
|
||||
|
||||
bitset_free (no_reduce_set);
|
||||
@@ -531,8 +534,11 @@ print_xml (void)
|
||||
|
||||
xml_puts (out, 0, "</bison-xml-report>");
|
||||
|
||||
free (escape_bufs[0].ptr);
|
||||
free (escape_bufs[1].ptr);
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < num_escape_bufs; ++i)
|
||||
free (escape_bufs[i].ptr);
|
||||
}
|
||||
|
||||
xfclose (out);
|
||||
}
|
||||
|
||||
+7
-4
@@ -106,8 +106,11 @@ print_core (FILE *out, state *s)
|
||||
for (sp = rules[r].rhs; sp < sp1; sp++)
|
||||
fprintf (out, " %s", symbols[*sp]->tag);
|
||||
fputs (" .", out);
|
||||
for (/* Nothing */; *sp >= 0; ++sp)
|
||||
fprintf (out, " %s", symbols[*sp]->tag);
|
||||
if (0 <= *rules[r].rhs)
|
||||
for (/* Nothing */; 0 <= *sp; ++sp)
|
||||
fprintf (out, " %s", symbols[*sp]->tag);
|
||||
else
|
||||
fprintf (out, " %%empty");
|
||||
|
||||
/* Display the lookahead tokens? */
|
||||
if (report_flag & report_lookahead_tokens
|
||||
@@ -206,7 +209,7 @@ print_errs (FILE *out, state *s)
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------.
|
||||
| Report a reduction of RULE on LOOKAHEAD_TOKEN (which can be `default'). |
|
||||
| Report a reduction of RULE on LOOKAHEAD_TOKEN (which can be 'default'). |
|
||||
| If not ENABLED, the rule is masked by a shift or a reduce (S/R and |
|
||||
| R/R conflicts). |
|
||||
`-------------------------------------------------------------------------*/
|
||||
@@ -514,7 +517,7 @@ print_results (void)
|
||||
print_grammar (out);
|
||||
|
||||
/* If the whole state item sets, not only the kernels, are wanted,
|
||||
`closure' will be run, which needs memory allocation/deallocation. */
|
||||
'closure' will be run, which needs memory allocation/deallocation. */
|
||||
if (report_flag & report_itemsets)
|
||||
new_closure (nritems);
|
||||
/* Storage for print_reductions. */
|
||||
|
||||
+5
-2
@@ -84,8 +84,11 @@ print_core (struct obstack *oout, state *s)
|
||||
|
||||
obstack_1grow (oout, '.');
|
||||
|
||||
for (/* Nothing */; *sp >= 0; ++sp)
|
||||
obstack_printf (oout, " %s", escape (symbols[*sp]->tag));
|
||||
if (0 <= *r->rhs)
|
||||
for (/* Nothing */; *sp >= 0; ++sp)
|
||||
obstack_printf (oout, " %s", escape (symbols[*sp]->tag));
|
||||
else
|
||||
obstack_printf (oout, " %%empty");
|
||||
|
||||
/* Experimental feature: display the lookahead tokens. */
|
||||
if (report_flag & report_lookahead_tokens
|
||||
|
||||
+82
-43
@@ -267,9 +267,9 @@ symbol_should_be_used (symbol_list const *s, bool *midrule_warning)
|
||||
return true;
|
||||
if ((s->midrule && s->midrule->action_props.is_value_used)
|
||||
|| (s->midrule_parent_rule
|
||||
&& symbol_list_n_get (s->midrule_parent_rule,
|
||||
s->midrule_parent_rhs_index)
|
||||
->action_props.is_value_used))
|
||||
&& (symbol_list_n_get (s->midrule_parent_rule,
|
||||
s->midrule_parent_rhs_index)
|
||||
->action_props.is_value_used)))
|
||||
{
|
||||
*midrule_warning = true;
|
||||
return true;
|
||||
@@ -321,7 +321,7 @@ grammar_rule_check (const symbol_list *r)
|
||||
bool midrule_warning = false;
|
||||
if (!l->action_props.is_value_used
|
||||
&& symbol_should_be_used (l, &midrule_warning)
|
||||
/* The default action, $$ = $1, `uses' both. */
|
||||
/* The default action, $$ = $1, 'uses' both. */
|
||||
&& (r->action_props.code || (n != 0 && n != 1)))
|
||||
{
|
||||
warnings warn_flag = midrule_warning ? Wmidrule_values : Wother;
|
||||
@@ -333,6 +333,18 @@ grammar_rule_check (const symbol_list *r)
|
||||
}
|
||||
}
|
||||
|
||||
/* Check that %empty => empty rule. */
|
||||
if (r->percent_empty_loc.start.file
|
||||
&& r->next && r->next->content.sym)
|
||||
complain (&r->percent_empty_loc, complaint,
|
||||
_("%%empty on non-empty rule"));
|
||||
|
||||
/* Check that empty rule => %empty. */
|
||||
if (!(r->next && r->next->content.sym)
|
||||
&& !r->midrule_parent_rule
|
||||
&& !r->percent_empty_loc.start.file)
|
||||
complain (&r->location, Wempty_rule, _("empty rule without %%empty"));
|
||||
|
||||
/* See comments in grammar_current_rule_prec_set for how POSIX
|
||||
mandates this complaint. It's only for identifiers, so skip
|
||||
it for char literals and strings, which are always tokens. */
|
||||
@@ -430,8 +442,26 @@ grammar_current_rule_prec_set (symbol *precsym, location loc)
|
||||
token. */
|
||||
symbol_class_set (precsym, token_sym, loc, false);
|
||||
if (current_rule->ruleprec)
|
||||
complain (&loc, complaint, _("only one %s allowed per rule"), "%prec");
|
||||
current_rule->ruleprec = precsym;
|
||||
duplicate_directive ("%prec",
|
||||
current_rule->ruleprec->location, loc);
|
||||
else
|
||||
current_rule->ruleprec = precsym;
|
||||
}
|
||||
|
||||
/* Set %empty for the current rule. */
|
||||
|
||||
void
|
||||
grammar_current_rule_empty_set (location loc)
|
||||
{
|
||||
/* If %empty is used and -Wno-empty-rule is not, then enable
|
||||
-Wempty-rule. */
|
||||
if (warning_is_unset (Wempty_rule))
|
||||
warning_argmatch ("empty-rule", 0, 0);
|
||||
if (current_rule->percent_empty_loc.start.file)
|
||||
duplicate_directive ("%empty",
|
||||
current_rule->percent_empty_loc, loc);
|
||||
else
|
||||
current_rule->percent_empty_loc = loc;
|
||||
}
|
||||
|
||||
/* Attach dynamic precedence DPREC to the current rule. */
|
||||
@@ -446,8 +476,13 @@ grammar_current_rule_dprec_set (int dprec, location loc)
|
||||
complain (&loc, complaint, _("%s must be followed by positive number"),
|
||||
"%dprec");
|
||||
else if (current_rule->dprec != 0)
|
||||
complain (&loc, complaint, _("only one %s allowed per rule"), "%dprec");
|
||||
current_rule->dprec = dprec;
|
||||
duplicate_directive ("%dprec",
|
||||
current_rule->dprec_location, loc);
|
||||
else
|
||||
{
|
||||
current_rule->dprec = dprec;
|
||||
current_rule->dprec_location = loc;
|
||||
}
|
||||
}
|
||||
|
||||
/* Attach a merge function NAME with argument type TYPE to current
|
||||
@@ -460,9 +495,13 @@ grammar_current_rule_merge_set (uniqstr name, location loc)
|
||||
complain (&loc, Wother, _("%s affects only GLR parsers"),
|
||||
"%merge");
|
||||
if (current_rule->merger != 0)
|
||||
complain (&loc, complaint, _("only one %s allowed per rule"), "%merge");
|
||||
current_rule->merger = get_merge_function (name);
|
||||
current_rule->merger_declaration_location = loc;
|
||||
duplicate_directive ("%merge",
|
||||
current_rule->merger_declaration_location, loc);
|
||||
else
|
||||
{
|
||||
current_rule->merger = get_merge_function (name);
|
||||
current_rule->merger_declaration_location = loc;
|
||||
}
|
||||
}
|
||||
|
||||
/* Attach SYM to the current rule. If needed, move the previous
|
||||
@@ -477,7 +516,7 @@ grammar_current_rule_symbol_append (symbol *sym, location loc,
|
||||
grammar_midrule_action ();
|
||||
p = grammar_symbol_append (sym, loc);
|
||||
if (name)
|
||||
assign_named_ref(p, name);
|
||||
assign_named_ref (p, name);
|
||||
if (sym->status == undeclared || sym->status == used)
|
||||
sym->status = needed;
|
||||
}
|
||||
@@ -507,7 +546,7 @@ packgram (void)
|
||||
{
|
||||
unsigned int itemno = 0;
|
||||
rule_number ruleno = 0;
|
||||
symbol_list *p = grammar;
|
||||
symbol_list *p;
|
||||
|
||||
ritem = xnmalloc (nritems + 1, sizeof *ritem);
|
||||
|
||||
@@ -516,9 +555,8 @@ packgram (void)
|
||||
|
||||
rules = xnmalloc (nrules, sizeof *rules);
|
||||
|
||||
while (p)
|
||||
for (p = grammar; p; p = p->next)
|
||||
{
|
||||
int rule_length = 0;
|
||||
symbol *ruleprec = p->ruleprec;
|
||||
record_merge_function_type (p->merger, p->content.sym->type_name,
|
||||
p->merger_declaration_location);
|
||||
@@ -536,14 +574,14 @@ packgram (void)
|
||||
rules[ruleno].action_location = p->action_props.location;
|
||||
rules[ruleno].is_predicate = p->action_props.is_predicate;
|
||||
|
||||
/* If the midrule's $$ is set or its $n is used, remove the `$' from the
|
||||
/* If the midrule's $$ is set or its $n is used, remove the '$' from the
|
||||
symbol name so that it's a user-defined symbol so that the default
|
||||
%destructor and %printer apply. */
|
||||
if (p->midrule_parent_rule
|
||||
&& (p->action_props.is_value_used
|
||||
|| symbol_list_n_get (p->midrule_parent_rule,
|
||||
p->midrule_parent_rhs_index)
|
||||
->action_props.is_value_used))
|
||||
|| (symbol_list_n_get (p->midrule_parent_rule,
|
||||
p->midrule_parent_rhs_index)
|
||||
->action_props.is_value_used)))
|
||||
p->content.sym->tag += 1;
|
||||
|
||||
/* Don't check the generated rule 0. It has no action, so some rhs
|
||||
@@ -552,24 +590,27 @@ packgram (void)
|
||||
if (p != grammar)
|
||||
grammar_rule_check (p);
|
||||
|
||||
for (p = p->next; p && p->content.sym; p = p->next)
|
||||
{
|
||||
++rule_length;
|
||||
{
|
||||
size_t rule_length = 0;
|
||||
for (p = p->next; p->content.sym; p = p->next)
|
||||
{
|
||||
++rule_length;
|
||||
|
||||
/* Don't allow rule_length == INT_MAX, since that might
|
||||
cause confusion with strtol if INT_MAX == LONG_MAX. */
|
||||
if (rule_length == INT_MAX)
|
||||
complain (&rules[ruleno].location, fatal, _("rule is too long"));
|
||||
/* Don't allow rule_length == INT_MAX, since that might
|
||||
cause confusion with strtol if INT_MAX == LONG_MAX. */
|
||||
if (rule_length == INT_MAX)
|
||||
complain (&rules[ruleno].location, fatal, _("rule is too long"));
|
||||
|
||||
/* item_number = symbol_number.
|
||||
But the former needs to contain more: negative rule numbers. */
|
||||
ritem[itemno++] =
|
||||
symbol_number_as_item_number (p->content.sym->number);
|
||||
/* A rule gets by default the precedence and associativity
|
||||
of its last token. */
|
||||
if (p->content.sym->class == token_sym && default_prec)
|
||||
rules[ruleno].prec = p->content.sym;
|
||||
}
|
||||
/* item_number = symbol_number.
|
||||
But the former needs to contain more: negative rule numbers. */
|
||||
ritem[itemno++] =
|
||||
symbol_number_as_item_number (p->content.sym->number);
|
||||
/* A rule gets by default the precedence and associativity
|
||||
of its last token. */
|
||||
if (p->content.sym->class == token_sym && default_prec)
|
||||
rules[ruleno].prec = p->content.sym;
|
||||
}
|
||||
}
|
||||
|
||||
/* If this rule has a %prec,
|
||||
the specified symbol's precedence replaces the default. */
|
||||
@@ -583,9 +624,6 @@ packgram (void)
|
||||
aver (itemno < ITEM_NUMBER_MAX);
|
||||
++ruleno;
|
||||
aver (ruleno < RULE_NUMBER_MAX);
|
||||
|
||||
if (p)
|
||||
p = p->next;
|
||||
}
|
||||
|
||||
aver (itemno == nritems);
|
||||
@@ -713,7 +751,7 @@ check_and_convert_grammar (void)
|
||||
/* Insert the initial rule, whose line is that of the first rule
|
||||
(not that of the start symbol):
|
||||
|
||||
accept: %start EOF. */
|
||||
$accept: %start $end. */
|
||||
{
|
||||
symbol_list *p = symbol_list_sym_new (accept, empty_location);
|
||||
p->location = grammar->location;
|
||||
@@ -726,7 +764,8 @@ check_and_convert_grammar (void)
|
||||
grammar = p;
|
||||
}
|
||||
|
||||
aver (nsyms <= SYMBOL_NUMBER_MAXIMUM && nsyms == ntokens + nvars);
|
||||
aver (nsyms <= SYMBOL_NUMBER_MAXIMUM);
|
||||
aver (nsyms == ntokens + nvars);
|
||||
|
||||
/* Assign the symbols their symbol numbers. Write #defines for the
|
||||
token symbols into FDEFINES if requested. */
|
||||
@@ -737,11 +776,11 @@ check_and_convert_grammar (void)
|
||||
action type checking.
|
||||
|
||||
Before invoking grammar_rule_check (in packgram below) on any rule, make
|
||||
sure all actions have already been scanned in order to set `used' flags.
|
||||
sure all actions have already been scanned in order to set 'used' flags.
|
||||
Otherwise, checking that a midrule's $$ should be set will not always work
|
||||
properly because the check must forward-reference the midrule's parent
|
||||
rule. For the same reason, all the `used' flags must be set before
|
||||
checking whether to remove `$' from any midrule symbol name (also in
|
||||
rule. For the same reason, all the 'used' flags must be set before
|
||||
checking whether to remove '$' from any midrule symbol name (also in
|
||||
packgram). */
|
||||
{
|
||||
symbol_list *sym;
|
||||
|
||||
@@ -47,6 +47,8 @@ void grammar_current_rule_begin (symbol *lhs, location loc,
|
||||
named_ref *lhs_named_ref);
|
||||
void grammar_current_rule_end (location loc);
|
||||
void grammar_midrule_action (void);
|
||||
/* Apply %empty to the current rule. */
|
||||
void grammar_current_rule_empty_set (location loc);
|
||||
void grammar_current_rule_prec_set (symbol *precsym, location loc);
|
||||
void grammar_current_rule_dprec_set (int dprec, location loc);
|
||||
void grammar_current_rule_merge_set (uniqstr name, location loc);
|
||||
|
||||
+1
-1
@@ -49,7 +49,7 @@ static bitset P;
|
||||
static bitset V;
|
||||
|
||||
/* Set of symbols used to define rule precedence (so they are
|
||||
`useless', but no warning should be issued). */
|
||||
'useless', but no warning should be issued). */
|
||||
static bitset V1;
|
||||
|
||||
static rule_number nuseful_productions;
|
||||
|
||||
+23
-89
@@ -78,8 +78,9 @@ static bool untyped_var_seen;
|
||||
|
||||
/* POSIX says that a tag must be both an id and a C union member, but
|
||||
historically almost any character is allowed in a tag. We disallow
|
||||
NUL and newline, as this simplifies our implementation. */
|
||||
tag [^\0\n>]+
|
||||
NUL and newline, as this simplifies our implementation. We allow
|
||||
"->" as a means to dereference a pointer. */
|
||||
tag ([^\0\n>]|->)+
|
||||
|
||||
/* Zero or more instances of backslash-newline. Following GCC, allow
|
||||
white space between the backslash and the newline. */
|
||||
@@ -95,26 +96,6 @@ ref -?[0-9]+|{id}|"["{id}"]"|"$"
|
||||
%%
|
||||
|
||||
%{
|
||||
/* Nesting level of the current code in braces. */
|
||||
int braces_level = 0;
|
||||
|
||||
/* Whether a semicolon is probably needed.
|
||||
|
||||
The heuristic is that a semicolon is not needed after '{', '}',
|
||||
';', or a C preprocessor directive, and that whitespaces and
|
||||
comments do not affect this flag. Note that '{' does not need a
|
||||
semicolon because of '{}'. A semicolon may be needed before a
|
||||
cpp directive, but don't bother.
|
||||
|
||||
While it is maintained in several start-conditions (factoring
|
||||
opportunities), it is meaningful only for SC_RULE_ACTION. */
|
||||
bool need_semicolon = false;
|
||||
|
||||
/* Whether in a C preprocessor directive. Don't use a start condition
|
||||
for this because, at the end of strings and comments, we still need
|
||||
to know whether we're in a directive. */
|
||||
bool in_cpp = false;
|
||||
|
||||
/* This scanner is special: it is invoked only once, henceforth
|
||||
is expected to return only once. This initialization is
|
||||
therefore done once per action to translate. */
|
||||
@@ -167,32 +148,14 @@ ref -?[0-9]+|{id}|"["{id}"]"|"$"
|
||||
|
||||
<SC_RULE_ACTION,SC_SYMBOL_ACTION>
|
||||
{
|
||||
"'" {
|
||||
STRING_GROW;
|
||||
BEGIN SC_CHARACTER;
|
||||
need_semicolon = true;
|
||||
}
|
||||
"\"" {
|
||||
STRING_GROW;
|
||||
BEGIN SC_STRING;
|
||||
need_semicolon = true;
|
||||
}
|
||||
"/"{splice}"*" {
|
||||
STRING_GROW;
|
||||
BEGIN SC_COMMENT;
|
||||
}
|
||||
"/"{splice}"/" {
|
||||
STRING_GROW;
|
||||
BEGIN SC_LINE_COMMENT;
|
||||
}
|
||||
"'" STRING_GROW; BEGIN SC_CHARACTER;
|
||||
"\"" STRING_GROW; BEGIN SC_STRING;
|
||||
"/"{splice}"*" STRING_GROW; BEGIN SC_COMMENT;
|
||||
"/"{splice}"/" STRING_GROW; BEGIN SC_LINE_COMMENT;
|
||||
|
||||
[$@] {
|
||||
complain (loc, Wother, _("stray '%s'"), yytext);
|
||||
obstack_escape (&obstack_for_string, yytext);
|
||||
need_semicolon = true;
|
||||
}
|
||||
[\[\]] {
|
||||
obstack_escape (&obstack_for_string, yytext);
|
||||
need_semicolon = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -203,51 +166,13 @@ ref -?[0-9]+|{id}|"["{id}"]"|"$"
|
||||
handle_action_dollar (self->rule, yytext, *loc);
|
||||
if (ref_tail_fields)
|
||||
obstack_sgrow (&obstack_for_string, ref_tail_fields);
|
||||
need_semicolon = true;
|
||||
}
|
||||
"@"{ref} {
|
||||
ref_tail_fields = NULL;
|
||||
handle_action_at (self->rule, yytext, *loc);
|
||||
if (ref_tail_fields)
|
||||
obstack_sgrow (&obstack_for_string, ref_tail_fields);
|
||||
need_semicolon = true;
|
||||
}
|
||||
|
||||
";" STRING_GROW; need_semicolon = false;
|
||||
"{" STRING_GROW; ++braces_level; need_semicolon = false;
|
||||
"}" {
|
||||
bool outer_brace = --braces_level == 0;
|
||||
|
||||
/* As an undocumented Bison extension, append ';' before the last
|
||||
brace in braced code, so that the user code can omit trailing
|
||||
';'. But do not append ';' if emulating Yacc, since Yacc does
|
||||
not append one. This is deprecated since release 2.4.1. */
|
||||
if (outer_brace && !yacc_flag && language_prio == default_prio
|
||||
&& skeleton_prio == default_prio && need_semicolon && ! in_cpp)
|
||||
{
|
||||
unsigned int indent = 0;
|
||||
complain_indent (loc, Wdeprecated, &indent,
|
||||
_("a ';' might be needed at the end of action code"));
|
||||
indent += SUB_INDENT;
|
||||
complain_indent (loc, Wdeprecated | silent | no_caret, &indent,
|
||||
_("future versions of Bison will not add the ';'"));
|
||||
obstack_1grow (&obstack_for_string, ';');
|
||||
}
|
||||
|
||||
STRING_GROW;
|
||||
need_semicolon = false;
|
||||
}
|
||||
|
||||
/* Preprocessing directives should only be recognized at the beginning
|
||||
of lines, allowing whitespace including comments, but in C/C++,
|
||||
'#' can only be the start of preprocessor directives or within
|
||||
'#define' directives anyway, so don't bother with begin of line. */
|
||||
"#" STRING_GROW; in_cpp = true;
|
||||
|
||||
{splice} STRING_GROW;
|
||||
[\n\r] STRING_GROW; if (in_cpp) in_cpp = need_semicolon = false;
|
||||
[ \t\f] STRING_GROW;
|
||||
. STRING_GROW; need_semicolon = true;
|
||||
}
|
||||
|
||||
<SC_SYMBOL_ACTION>
|
||||
@@ -417,8 +342,19 @@ show_sub_message (warnings warning,
|
||||
{
|
||||
static struct obstack msg_buf;
|
||||
const char *tail = explicit_bracketing ? "" : cp + strlen (var->id);
|
||||
const char *id = var->hidden_by ? var->hidden_by->id : var->id;
|
||||
location id_loc = var->hidden_by ? var->hidden_by->loc : var->loc;
|
||||
const char *id;
|
||||
location id_loc;
|
||||
|
||||
if (var->hidden_by)
|
||||
{
|
||||
id = var->hidden_by->id;
|
||||
id_loc = var->hidden_by->loc;
|
||||
}
|
||||
else
|
||||
{
|
||||
id = var->id;
|
||||
id_loc = var->loc;
|
||||
}
|
||||
|
||||
/* Create the explanation message. */
|
||||
obstack_init (&msg_buf);
|
||||
@@ -648,9 +584,6 @@ parse_ref (char *cp, symbol_list *rule, int rule_length,
|
||||
return INVALID_REF;
|
||||
}
|
||||
}
|
||||
|
||||
/* Not reachable. */
|
||||
return INVALID_REF;
|
||||
}
|
||||
|
||||
/* Keeps track of the maximum number of semantic values to the left of
|
||||
@@ -671,7 +604,8 @@ fetch_type_name (char *cp, char const **type_name,
|
||||
if (*cp == '<')
|
||||
{
|
||||
*type_name = ++cp;
|
||||
while (*cp != '>')
|
||||
/* Series of non-'>' or "->". */
|
||||
while (*cp != '>' || cp[-1] == '-')
|
||||
++cp;
|
||||
|
||||
/* The '>' symbol will be later replaced by '\0'. Original
|
||||
|
||||
+17
-24
@@ -112,7 +112,12 @@ static void unexpected_newline (boundary, char const *);
|
||||
/* A identifier was just read in directives/rules. Special state
|
||||
to capture the sequence 'identifier :'. */
|
||||
%x SC_AFTER_IDENTIFIER
|
||||
/* A complex tag, with nested angles brackets. */
|
||||
|
||||
/* POSIX says that a tag must be both an id and a C union member, but
|
||||
historically almost any character is allowed in a tag. We
|
||||
disallow NUL, as this simplifies our implementation. We match
|
||||
angle brackets in nested pairs: several languages use them for
|
||||
generics/template types. */
|
||||
%x SC_TAG
|
||||
|
||||
/* Four types of user code:
|
||||
@@ -133,13 +138,6 @@ notletter [^.abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_]{-}[%\{]
|
||||
id {letter}({letter}|[-0-9])*
|
||||
int [0-9]+
|
||||
|
||||
/* POSIX says that a tag must be both an id and a C union member, but
|
||||
historically almost any character is allowed in a tag. We disallow
|
||||
NUL, as this simplifies our implementation. We disallow angle
|
||||
bracket to match them in nested pairs: several languages use them
|
||||
for generics/template types. */
|
||||
tag [^\0<>]+
|
||||
|
||||
/* Zero or more instances of backslash-newline. Following GCC, allow
|
||||
white space between the backslash and the newline. */
|
||||
splice (\\[ \f\t\v]*\n)*
|
||||
@@ -217,6 +215,7 @@ eqopt ([[:space:]]*=)?
|
||||
"%defines" return PERCENT_DEFINES;
|
||||
"%destructor" return PERCENT_DESTRUCTOR;
|
||||
"%dprec" return PERCENT_DPREC;
|
||||
"%empty" return PERCENT_EMPTY;
|
||||
"%error-verbose" return PERCENT_ERROR_VERBOSE;
|
||||
"%expect" return PERCENT_EXPECT;
|
||||
"%expect-rr" return PERCENT_EXPECT_RR;
|
||||
@@ -267,7 +266,7 @@ eqopt ([[:space:]]*=)?
|
||||
"%pure"[-_]"parser" DEPRECATED("%pure-parser");
|
||||
"%token"[-_]"table" DEPRECATED("%token-table");
|
||||
|
||||
"%"{id}|"%"{notletter}([[:graph:]])+ {
|
||||
"%"{id} {
|
||||
complain (loc, complaint, _("invalid directive: %s"), quote (yytext));
|
||||
}
|
||||
|
||||
@@ -324,13 +323,6 @@ eqopt ([[:space:]]*=)?
|
||||
/* A type. */
|
||||
"<*>" return TAG_ANY;
|
||||
"<>" return TAG_NONE;
|
||||
"<"{tag}">" {
|
||||
obstack_grow (&obstack_for_string, yytext + 1, yyleng - 2);
|
||||
STRING_FINISH;
|
||||
val->uniqstr = uniqstr_new (last_string);
|
||||
STRING_FREE;
|
||||
return TAG;
|
||||
}
|
||||
"<" {
|
||||
nesting = 0;
|
||||
token_start = loc->start;
|
||||
@@ -520,7 +512,7 @@ eqopt ([[:space:]]*=)?
|
||||
"\"" {
|
||||
STRING_FINISH;
|
||||
loc->start = token_start;
|
||||
val->chars = last_string;
|
||||
val->code = last_string;
|
||||
BEGIN INITIAL;
|
||||
return STRING;
|
||||
}
|
||||
@@ -558,10 +550,11 @@ eqopt ([[:space:]]*=)?
|
||||
<<EOF>> unexpected_eof (token_start, "'");
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------.
|
||||
| Scanning a Bison nested tag. The initial angle bracket is |
|
||||
| already eaten. |
|
||||
`-----------------------------------------------------------*/
|
||||
|
||||
|
||||
/*--------------------------------------------------------------.
|
||||
| Scanning a tag. The initial angle bracket is already eaten. |
|
||||
`--------------------------------------------------------------*/
|
||||
|
||||
<SC_TAG>
|
||||
{
|
||||
@@ -579,7 +572,7 @@ eqopt ([[:space:]]*=)?
|
||||
STRING_GROW;
|
||||
}
|
||||
|
||||
[^<>]+ STRING_GROW;
|
||||
([^<>]|->)+ STRING_GROW;
|
||||
"<"+ STRING_GROW; nesting += yyleng;
|
||||
|
||||
<<EOF>> unexpected_eof (token_start, ">");
|
||||
@@ -758,7 +751,7 @@ eqopt ([[:space:]]*=)?
|
||||
"%}" {
|
||||
STRING_FINISH;
|
||||
loc->start = code_start;
|
||||
val->chars = last_string;
|
||||
val->code = last_string;
|
||||
BEGIN INITIAL;
|
||||
return PROLOGUE;
|
||||
}
|
||||
@@ -777,7 +770,7 @@ eqopt ([[:space:]]*=)?
|
||||
<<EOF>> {
|
||||
STRING_FINISH;
|
||||
loc->start = code_start;
|
||||
val->chars = last_string;
|
||||
val->code = last_string;
|
||||
BEGIN INITIAL;
|
||||
return EPILOGUE;
|
||||
}
|
||||
|
||||
+8
-5
@@ -72,7 +72,7 @@ static void fail_for_invalid_at (char const *at);
|
||||
"@@" fputc ('@', yyout);
|
||||
"@{" fputc ('[', yyout);
|
||||
"@}" fputc (']', yyout);
|
||||
"@`" continue; /* Used by b4_cat in ../data/bison.m4. */
|
||||
"@'" continue; /* Used by b4_cat in ../data/bison.m4. */
|
||||
@\n continue;
|
||||
|
||||
"@oline@" fprintf (yyout, "%d", out_lineno + 1);
|
||||
@@ -83,7 +83,7 @@ static void fail_for_invalid_at (char const *at);
|
||||
"@output(" at_init (&argc, argv, &at_ptr, &at_output);
|
||||
|
||||
/* This pattern must not match more than the previous @ patterns. */
|
||||
@[^@{}`(\n]* fail_for_invalid_at (yytext);
|
||||
@[^@{}\'(\n]* fail_for_invalid_at (yytext);
|
||||
\n out_lineno++; ECHO;
|
||||
[^@\n]+ ECHO;
|
||||
|
||||
@@ -103,7 +103,7 @@ static void fail_for_invalid_at (char const *at);
|
||||
"@@" obstack_1grow (&obstack_for_string, '@');
|
||||
"@{" obstack_1grow (&obstack_for_string, '[');
|
||||
"@}" obstack_1grow (&obstack_for_string, ']');
|
||||
"@`" continue; /* For starting an argument that begins with whitespace. */
|
||||
"@'" continue; /* For starting an argument that begins with whitespace. */
|
||||
@\n continue;
|
||||
|
||||
@[,)] {
|
||||
@@ -183,6 +183,8 @@ flag (const char *arg)
|
||||
/* compare with values issued from b4_error */
|
||||
if (STREQ (arg, "complain"))
|
||||
return complaint;
|
||||
else if (STREQ (arg, "deprecated"))
|
||||
return Wdeprecated;
|
||||
else if (STREQ (arg, "fatal"))
|
||||
return fatal;
|
||||
else if (STREQ (arg, "note"))
|
||||
@@ -242,8 +244,9 @@ at_output (int argc, char *argv[], char **out_namep, int *out_linenop)
|
||||
xfclose (yyout);
|
||||
}
|
||||
*out_namep = xstrdup (argv[1]);
|
||||
output_file_name_check (out_namep);
|
||||
yyout = xfopen (*out_namep, "w");
|
||||
output_file_name_check (out_namep, true);
|
||||
/* If there were errors, do not generate the output. */
|
||||
yyout = xfopen (complaint_status ? "/dev/null" : *out_namep, "w");
|
||||
*out_linenop = 1;
|
||||
}
|
||||
|
||||
|
||||
+14
-7
@@ -36,18 +36,20 @@ symbol_list_sym_new (symbol *sym, location loc)
|
||||
res->content_type = SYMLIST_SYMBOL;
|
||||
res->content.sym = sym;
|
||||
res->location = res->sym_loc = loc;
|
||||
res->named_ref = NULL;
|
||||
|
||||
res->midrule = NULL;
|
||||
res->midrule_parent_rule = NULL;
|
||||
res->midrule_parent_rhs_index = 0;
|
||||
|
||||
code_props_none_init (&res->action_props);
|
||||
|
||||
/* Members used for LHS only. */
|
||||
res->ruleprec = NULL;
|
||||
res->percent_empty_loc = empty_location;
|
||||
code_props_none_init (&res->action_props);
|
||||
res->dprec = 0;
|
||||
res->dprec_location = empty_location;
|
||||
res->merger = 0;
|
||||
|
||||
res->named_ref = NULL;
|
||||
res->merger_declaration_location = empty_location;
|
||||
|
||||
res->next = NULL;
|
||||
|
||||
@@ -85,12 +87,17 @@ symbol_list_type_new (uniqstr type_name, location loc)
|
||||
void
|
||||
symbol_list_syms_print (const symbol_list *l, FILE *f)
|
||||
{
|
||||
char const *sep = "";
|
||||
for (/* Nothing. */; l && l->content.sym; l = l->next)
|
||||
{
|
||||
fputs (sep, f);
|
||||
fputs (l->content_type == SYMLIST_SYMBOL ? "symbol: "
|
||||
: l->content_type == SYMLIST_TYPE ? "type: "
|
||||
: "invalid content_type: ",
|
||||
f);
|
||||
symbol_print (l->content.sym, f);
|
||||
fprintf (stderr, l->action_props.is_value_used ? " used" : " unused");
|
||||
if (l && l->content.sym)
|
||||
fprintf (f, ", ");
|
||||
fputs (l->action_props.is_value_used ? " used" : " unused", f);
|
||||
sep = ", ";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+15
-5
@@ -50,6 +50,9 @@ typedef struct symbol_list
|
||||
} content;
|
||||
location location;
|
||||
|
||||
/* Named reference. */
|
||||
named_ref *named_ref;
|
||||
|
||||
/* Proper location of the symbol, not all the rule */
|
||||
location sym_loc;
|
||||
|
||||
@@ -64,19 +67,26 @@ typedef struct symbol_list
|
||||
struct symbol_list *midrule_parent_rule;
|
||||
int midrule_parent_rhs_index;
|
||||
|
||||
/* ---------------------------------------------- */
|
||||
/* Apply to the rule (attached to the LHS only). */
|
||||
/* ---------------------------------------------- */
|
||||
|
||||
/* Precedence/associativity. */
|
||||
symbol *ruleprec;
|
||||
|
||||
/* The action is attached to the LHS of a rule, but action properties for
|
||||
* each RHS are also stored here. */
|
||||
code_props action_props;
|
||||
|
||||
/* Precedence/associativity. */
|
||||
symbol *ruleprec;
|
||||
/* The location of the first %empty for this rule, or \a
|
||||
empty_location. */
|
||||
location percent_empty_loc;
|
||||
|
||||
int dprec;
|
||||
location dprec_location;
|
||||
int merger;
|
||||
location merger_declaration_location;
|
||||
|
||||
/* Named reference. */
|
||||
named_ref *named_ref;
|
||||
|
||||
/* The list. */
|
||||
struct symbol_list *next;
|
||||
} symbol_list;
|
||||
|
||||
+77
-39
@@ -153,13 +153,13 @@ symbol_print (symbol const *s, FILE *f)
|
||||
{
|
||||
if (s)
|
||||
{
|
||||
fprintf (f, "\"%s\"", s->tag);
|
||||
fputs (s->tag, f);
|
||||
SYMBOL_ATTR_PRINT (type_name);
|
||||
SYMBOL_CODE_PRINT (destructor);
|
||||
SYMBOL_CODE_PRINT (printer);
|
||||
}
|
||||
else
|
||||
fprintf (f, "<NULL>");
|
||||
fputs ("<NULL>", f);
|
||||
}
|
||||
|
||||
#undef SYMBOL_ATTR_PRINT
|
||||
@@ -243,9 +243,12 @@ symbol_type_set (symbol *sym, uniqstr type_name, location loc)
|
||||
{
|
||||
if (sym->type_name)
|
||||
symbol_redeclaration (sym, "%type", sym->type_location, loc);
|
||||
uniqstr_assert (type_name);
|
||||
sym->type_name = type_name;
|
||||
sym->type_location = loc;
|
||||
else
|
||||
{
|
||||
uniqstr_assert (type_name);
|
||||
sym->type_name = type_name;
|
||||
sym->type_location = loc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -261,7 +264,8 @@ symbol_code_props_set (symbol *sym, code_props_type kind,
|
||||
symbol_redeclaration (sym, code_props_type_string (kind),
|
||||
sym->props[kind].location,
|
||||
code->location);
|
||||
sym->props[kind] = *code;
|
||||
else
|
||||
sym->props[kind] = *code;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------.
|
||||
@@ -277,7 +281,8 @@ semantic_type_code_props_set (semantic_type *type,
|
||||
semantic_type_redeclaration (type, code_props_type_string (kind),
|
||||
type->props[kind].location,
|
||||
code->location);
|
||||
type->props[kind] = *code;
|
||||
else
|
||||
type->props[kind] = *code;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------.
|
||||
@@ -321,12 +326,15 @@ symbol_precedence_set (symbol *sym, int prec, assoc a, location loc)
|
||||
{
|
||||
if (a != undef_assoc)
|
||||
{
|
||||
if (sym->prec != 0)
|
||||
if (sym->prec)
|
||||
symbol_redeclaration (sym, assoc_to_string (a), sym->prec_location,
|
||||
loc);
|
||||
sym->prec = prec;
|
||||
sym->assoc = a;
|
||||
sym->prec_location = loc;
|
||||
else
|
||||
{
|
||||
sym->prec = prec;
|
||||
sym->assoc = a;
|
||||
sym->prec_location = loc;
|
||||
}
|
||||
}
|
||||
|
||||
/* Only terminals have a precedence. */
|
||||
@@ -360,7 +368,8 @@ symbol_class_set (symbol *sym, symbol_class class, location loc, bool declaring)
|
||||
{
|
||||
if (sym->status == declared && !warned)
|
||||
complain (&loc, Wother, _("symbol %s redeclared"), sym->tag);
|
||||
sym->status = declared;
|
||||
else
|
||||
sym->status = declared;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -441,7 +450,7 @@ semantic_type_check_defined (semantic_type *sem_type)
|
||||
/* <*> and <> do not have to be "declared". */
|
||||
if (sem_type->status == declared
|
||||
|| !*sem_type->tag
|
||||
|| STREQ(sem_type->tag, "*"))
|
||||
|| STREQ (sem_type->tag, "*"))
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < 2; ++i)
|
||||
@@ -615,8 +624,8 @@ symbol_translation (symbol *this)
|
||||
(this->user_token_number,
|
||||
symbols[token_translations[this->user_token_number]],
|
||||
this);
|
||||
|
||||
token_translations[this->user_token_number] = this->number;
|
||||
else
|
||||
token_translations[this->user_token_number] = this->number;
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -1057,27 +1066,40 @@ register_precedence (graphid first, graphid snd)
|
||||
}
|
||||
|
||||
|
||||
/*--------------------------------------------------.
|
||||
| Print a warning for unused precedence relations. |
|
||||
`--------------------------------------------------*/
|
||||
/*---------------------------------------.
|
||||
| Deep clear a linked / adjacency list). |
|
||||
`---------------------------------------*/
|
||||
|
||||
void
|
||||
print_precedence_warnings (void)
|
||||
static void
|
||||
linkedlist_free (symgraphlink *node)
|
||||
{
|
||||
if (node)
|
||||
{
|
||||
while (node->next)
|
||||
{
|
||||
symgraphlink *tmp = node->next;
|
||||
free (node);
|
||||
node = tmp;
|
||||
}
|
||||
free (node);
|
||||
}
|
||||
}
|
||||
|
||||
/*----------------------------------------------.
|
||||
| Clear and destroy association tracking table. |
|
||||
`----------------------------------------------*/
|
||||
|
||||
static void
|
||||
assoc_free (void)
|
||||
{
|
||||
int i;
|
||||
if (!prec_nodes)
|
||||
init_prec_nodes ();
|
||||
for (i = 0; i < nsyms; ++i)
|
||||
{
|
||||
symbol *s = symbols[i];
|
||||
if (s
|
||||
&& s->prec != 0
|
||||
&& !prec_nodes[i]->pred
|
||||
&& !prec_nodes[i]->succ
|
||||
&& s->assoc == precedence_assoc)
|
||||
complain (&s->location, Wother,
|
||||
_("useless precedence for %s"), s->tag);
|
||||
linkedlist_free (prec_nodes[i]->pred);
|
||||
linkedlist_free (prec_nodes[i]->succ);
|
||||
free (prec_nodes[i]);
|
||||
}
|
||||
free (prec_nodes);
|
||||
}
|
||||
|
||||
/*---------------------------------------.
|
||||
@@ -1088,7 +1110,7 @@ static void
|
||||
init_assoc (void)
|
||||
{
|
||||
graphid i;
|
||||
used_assoc = xcalloc(nsyms, sizeof(*used_assoc));
|
||||
used_assoc = xcalloc (nsyms, sizeof *used_assoc);
|
||||
for (i = 0; i < nsyms; ++i)
|
||||
used_assoc[i] = false;
|
||||
}
|
||||
@@ -1119,21 +1141,37 @@ register_assoc (graphid i, graphid j)
|
||||
used_assoc[j] = true;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------.
|
||||
| Print a warning for each unused symbol associativity. |
|
||||
`------------------------------------------------------*/
|
||||
/*--------------------------------------------------.
|
||||
| Print a warning for unused precedence relations. |
|
||||
`--------------------------------------------------*/
|
||||
|
||||
void
|
||||
print_assoc_warnings (void)
|
||||
print_precedence_warnings (void)
|
||||
{
|
||||
graphid i;
|
||||
int i;
|
||||
if (!prec_nodes)
|
||||
init_prec_nodes ();
|
||||
if (!used_assoc)
|
||||
init_assoc ();
|
||||
for (i = 0; i < nsyms; ++i)
|
||||
{
|
||||
symbol *s = symbols[i];
|
||||
if (is_assoc_useless (s))
|
||||
complain (&s->location, Wother,
|
||||
_("useless associativity for %s"), s->tag);
|
||||
if (s
|
||||
&& s->prec != 0
|
||||
&& !prec_nodes[i]->pred
|
||||
&& !prec_nodes[i]->succ)
|
||||
{
|
||||
if (is_assoc_useless (s))
|
||||
complain (&s->prec_location, Wprecedence,
|
||||
_("useless precedence and associativity for %s"), s->tag);
|
||||
else if (s->assoc == precedence_assoc)
|
||||
complain (&s->prec_location, Wprecedence,
|
||||
_("useless precedence for %s"), s->tag);
|
||||
}
|
||||
else if (is_assoc_useless (s))
|
||||
complain (&s->prec_location, Wprecedence,
|
||||
_("useless associativity for %s, use %%precedence"), s->tag);
|
||||
}
|
||||
free (used_assoc);
|
||||
assoc_free ();
|
||||
}
|
||||
|
||||
+6
-7
@@ -128,9 +128,9 @@ struct symbol
|
||||
/** Undefined user number. */
|
||||
# define USER_NUMBER_UNDEFINED -1
|
||||
|
||||
/* `symbol->user_token_number == USER_NUMBER_HAS_STRING_ALIAS' means
|
||||
this symbol has a literal string alias. For instance, `%token foo
|
||||
"foo"' has `"foo"' numbered regularly, and `foo' numbered as
|
||||
/* 'symbol->user_token_number == USER_NUMBER_HAS_STRING_ALIAS' means
|
||||
this symbol has a literal string alias. For instance, '%token foo
|
||||
"foo"' has '"foo"' numbered regularly, and 'foo' numbered as
|
||||
USER_NUMBER_HAS_STRING_ALIAS. */
|
||||
# define USER_NUMBER_HAS_STRING_ALIAS -9991
|
||||
|
||||
@@ -266,7 +266,8 @@ struct symgraph
|
||||
|
||||
void register_precedence (graphid first, graphid snd);
|
||||
|
||||
/** Print a warning for each symbol whose precedence is useless. */
|
||||
/** Print a warning for each symbol whose precedence and/or associativity
|
||||
* is useless. */
|
||||
|
||||
void print_precedence_warnings (void);
|
||||
|
||||
@@ -274,9 +275,7 @@ void print_precedence_warnings (void);
|
||||
| Symbol associativity |
|
||||
`----------------------*/
|
||||
|
||||
void register_assoc (int i, int j);
|
||||
|
||||
void print_assoc_warnings (void);
|
||||
void register_assoc (graphid i, graphid j);
|
||||
|
||||
/*-----------------.
|
||||
| Semantic types. |
|
||||
|
||||
+1
-1
@@ -99,7 +99,7 @@ typedef size_t uintptr_t;
|
||||
# endif
|
||||
# endif
|
||||
|
||||
/* The __-protected variants of `format' and `printf' attributes
|
||||
/* The __-protected variants of 'format' and 'printf' attributes
|
||||
are accepted by gcc versions 2.6.4 (effectively 2.7) and later. */
|
||||
# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7)
|
||||
# define __format__ format
|
||||
|
||||
+7
-7
@@ -35,7 +35,7 @@
|
||||
#include "tables.h"
|
||||
|
||||
/* Several tables are indexed both by state and nonterminal numbers.
|
||||
We call such an index a `vector'; i.e., a vector is either a state
|
||||
We call such an index a 'vector'; i.e., a vector is either a state
|
||||
or a nonterminal number.
|
||||
|
||||
Of course vector_number_t ought to be wide enough to contain
|
||||
@@ -90,18 +90,18 @@ static base_number *width;
|
||||
|
||||
/* For a given state, N = ACTROW[SYMBOL]:
|
||||
|
||||
If N = 0, stands for `run the default action'.
|
||||
If N = MIN, stands for `raise a syntax error'.
|
||||
If N > 0, stands for `shift SYMBOL and go to n'.
|
||||
If N < 0, stands for `reduce -N'. */
|
||||
If N = 0, stands for 'run the default action'.
|
||||
If N = MIN, stands for 'raise a syntax error'.
|
||||
If N > 0, stands for 'shift SYMBOL and go to n'.
|
||||
If N < 0, stands for 'reduce -N'. */
|
||||
typedef int action_number;
|
||||
#define ACTION_NUMBER_MINIMUM INT_MIN
|
||||
|
||||
static action_number *actrow;
|
||||
|
||||
/* FROMS and TOS are reordered to be compressed. ORDER[VECTOR] is the
|
||||
new vector number of VECTOR. We skip `empty' vectors (i.e.,
|
||||
TALLY[VECTOR] = 0), and call these `entries'. */
|
||||
new vector number of VECTOR. We skip 'empty' vectors (i.e.,
|
||||
TALLY[VECTOR] = 0), and call these 'entries'. */
|
||||
static vector_number *order;
|
||||
static int nentries;
|
||||
|
||||
|
||||
+3
-2
@@ -77,7 +77,8 @@ uniqstr_vsprintf (char const *format, ...)
|
||||
void
|
||||
uniqstr_assert (char const *str)
|
||||
{
|
||||
if (!hash_lookup (uniqstrs_table, str))
|
||||
uniqstr s = hash_lookup (uniqstrs_table, str);
|
||||
if (!s || s != str)
|
||||
{
|
||||
error (0, 0,
|
||||
"not a uniqstr: %s", quotearg (str));
|
||||
@@ -105,7 +106,7 @@ uniqstr_print_processor (void *ustr, void *null ATTRIBUTE_UNUSED)
|
||||
|
||||
|
||||
int
|
||||
uniqstr_cmp(uniqstr l, uniqstr r)
|
||||
uniqstr_cmp (uniqstr l, uniqstr r)
|
||||
{
|
||||
return (l == r ? 0
|
||||
: !l ? -1
|
||||
|
||||
+4
-2
@@ -20,6 +20,8 @@
|
||||
#ifndef UNIQSTR_H_
|
||||
# define UNIQSTR_H_
|
||||
|
||||
# include <stdio.h>
|
||||
|
||||
/*-----------------------------------------.
|
||||
| Pointers to unique copies of C strings. |
|
||||
`-----------------------------------------*/
|
||||
@@ -33,14 +35,14 @@ uniqstr uniqstr_new (char const *str);
|
||||
strings, use UNIQSTR_CONCAT, which is a convenient wrapper around
|
||||
this function. */
|
||||
uniqstr uniqstr_vsprintf (char const *format, ...)
|
||||
__attribute__ ((__format__ (__printf__, 1, 2)));
|
||||
_GL_ATTRIBUTE_FORMAT_PRINTF (1, 2);
|
||||
|
||||
/* Two uniqstr values have the same value iff they are the same. */
|
||||
# define UNIQSTR_EQ(Ustr1, Ustr2) (!!((Ustr1) == (Ustr2)))
|
||||
|
||||
/* Compare two uniqstr a la strcmp: negative for <, nul for =, and
|
||||
positive for >. Undefined order, relies on addresses. */
|
||||
int uniqstr_cmp(uniqstr u1, uniqstr u2);
|
||||
int uniqstr_cmp (uniqstr u1, uniqstr u2);
|
||||
|
||||
/* Die if STR is not a uniqstr. */
|
||||
void uniqstr_assert (char const *str);
|
||||
|
||||
+1
-1
Submodule submodules/autoconf updated: 26cb0918d3...9e087dd343
+126
-122
@@ -64,6 +64,119 @@ AT_PARSER_CHECK([./input], 0,
|
||||
|
||||
AT_CLEANUP
|
||||
|
||||
## ----------------------- ##
|
||||
## Implicitly empty rule. ##
|
||||
## ----------------------- ##
|
||||
|
||||
AT_SETUP([Implicitly empty rule])
|
||||
|
||||
AT_DATA_GRAMMAR([[1.y]],
|
||||
[[%%
|
||||
exp: a b;
|
||||
a: /* empty. */ {};
|
||||
// A mid-rule action does not count as an empty rule.
|
||||
b: {} {};
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK([-fcaret -Wempty-rule 1.y], [0], [],
|
||||
[[1.y:11.17-18: warning: empty rule without %empty [-Wempty-rule]
|
||||
a: /* empty. */ {};
|
||||
^^
|
||||
]])
|
||||
|
||||
AT_DATA_GRAMMAR([[2.y]],
|
||||
[[%%
|
||||
exp: a b c;
|
||||
a: /* empty. */ {};
|
||||
b: %empty {};
|
||||
c: /* empty. */ {};
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK([-fcaret 2.y], [0], [],
|
||||
[[2.y:11.17-18: warning: empty rule without %empty [-Wempty-rule]
|
||||
a: /* empty. */ {};
|
||||
^^
|
||||
2.y:13.17-18: warning: empty rule without %empty [-Wempty-rule]
|
||||
c: /* empty. */ {};
|
||||
^^
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK([-fcaret -Wno-empty-rule 2.y], [0])
|
||||
|
||||
AT_CLEANUP
|
||||
|
||||
## ------------------------ ##
|
||||
## Invalid uses of %empty. ##
|
||||
## ------------------------ ##
|
||||
|
||||
AT_SETUP([Invalid uses of %empty])
|
||||
|
||||
AT_DATA_GRAMMAR([[one.y]],
|
||||
[[%%
|
||||
exp:
|
||||
%empty {} %empty
|
||||
;
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK([-fcaret one.y], [1], [],
|
||||
[[one.y:11.13-18: error: only one %empty allowed per rule
|
||||
%empty {} %empty
|
||||
^^^^^^
|
||||
one.y:11.3-8: previous declaration
|
||||
%empty {} %empty
|
||||
^^^^^^
|
||||
]])
|
||||
|
||||
AT_DATA_GRAMMAR([[two.y]],
|
||||
[[%%
|
||||
exp:
|
||||
'a' %empty {}
|
||||
| %empty 'a' {}
|
||||
| %empty {} {}
|
||||
;
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK([-fcaret two.y], [1], [],
|
||||
[[two.y:11.7-12: error: %empty on non-empty rule
|
||||
'a' %empty {}
|
||||
^^^^^^
|
||||
two.y:12.3-8: error: %empty on non-empty rule
|
||||
| %empty 'a' {}
|
||||
^^^^^^
|
||||
two.y:13.3-8: error: %empty on non-empty rule
|
||||
| %empty {} {}
|
||||
^^^^^^
|
||||
]])
|
||||
|
||||
AT_CLEANUP
|
||||
|
||||
## ---------------------- ##
|
||||
## Valid uses of %empty. ##
|
||||
## ---------------------- ##
|
||||
|
||||
AT_SETUP([Valid uses of %empty])
|
||||
|
||||
AT_BISON_OPTION_PUSHDEFS
|
||||
AT_DATA_GRAMMAR([[input.y]],
|
||||
[[
|
||||
%debug
|
||||
%code
|
||||
{
|
||||
]AT_YYERROR_DECLARE[
|
||||
]AT_YYLEX_DECLARE[
|
||||
}
|
||||
%%
|
||||
exp: %empty {}
|
||||
%%
|
||||
]AT_YYERROR_DEFINE[
|
||||
]AT_YYLEX_DEFINE[
|
||||
]AT_MAIN_DEFINE[
|
||||
]])
|
||||
|
||||
AT_FULL_COMPILE([input])
|
||||
AT_PARSER_CHECK([./input])
|
||||
AT_BISON_OPTION_POPDEFS
|
||||
AT_CLEANUP
|
||||
|
||||
## ------------------ ##
|
||||
## Initial location. ##
|
||||
@@ -173,8 +286,8 @@ m4_popdef([AT_TEST])
|
||||
## Location Print. ##
|
||||
## ---------------- ##
|
||||
|
||||
# AT_TEST(SKELETON-NAME, DIRECTIVES, [MORE-DIRECTIVES], [LOCATION = 1.1])
|
||||
# -----------------------------------------------------------------------
|
||||
# AT_TEST(SKELETON-NAME, DIRECTIVES, [MORE-DIRECTIVES])
|
||||
# -----------------------------------------------------
|
||||
# Check that the initial location is correct.
|
||||
m4_pushdef([AT_TEST],
|
||||
[AT_SETUP([Location print: $1 $2])
|
||||
@@ -192,7 +305,7 @@ AT_DATA_GRAMMAR([[input.y]],
|
||||
]AT_YYLEX_DECLARE[
|
||||
}
|
||||
%%
|
||||
exp: /* empty */;
|
||||
exp: %empty;
|
||||
%%
|
||||
]AT_YYERROR_DEFINE[
|
||||
]AT_YYLEX_DEFINE[
|
||||
@@ -415,7 +528,7 @@ AT_LALR1_CC_IF([typedef yy::location YYLTYPE;])[
|
||||
%%
|
||||
/*
|
||||
This grammar is made to exercise error recovery.
|
||||
"Lines" starting with `(' support error recovery, with
|
||||
"Lines" starting with '(' support error recovery, with
|
||||
')' as synchronizing token. Lines starting with 'x' can never
|
||||
be recovered from if in error.
|
||||
*/
|
||||
@@ -483,7 +596,7 @@ thing:
|
||||
;
|
||||
%%
|
||||
/* Alias to ARGV[1]. */
|
||||
const char *source = YY_NULL;
|
||||
const char *source = YY_NULLPTR;
|
||||
|
||||
]AT_YYERROR_DEFINE[
|
||||
|
||||
@@ -492,11 +605,11 @@ static
|
||||
{
|
||||
static unsigned int counter = 0;
|
||||
|
||||
int c = ]AT_VAL[]m4_ifval([$6], [.ival])[ = counter++;
|
||||
unsigned int c = ]AT_VAL[]m4_ifval([$6], [.ival])[ = counter++;
|
||||
/* As in BASIC, line numbers go from 10 to 10. */
|
||||
]AT_LOC_FIRST_LINE[ = ]AT_LOC_FIRST_COLUMN[ = 10 * c;
|
||||
]AT_LOC_LAST_LINE[ = ]AT_LOC_LAST_COLUMN[ = ]AT_LOC_FIRST_LINE[ + 9;
|
||||
assert (0 <= c && c <= strlen (source));
|
||||
assert (c <= strlen (source));
|
||||
if (source[c])
|
||||
fprintf (stderr, "sending: '%c'", source[c]);
|
||||
else
|
||||
@@ -578,7 +691,7 @@ Successful parse.
|
||||
|
||||
# Syntax errors caught by the parser
|
||||
# ----------------------------------
|
||||
# Exercise the discarding of stack top and input until `error'
|
||||
# Exercise the discarding of stack top and input until 'error'
|
||||
# can be reduced.
|
||||
#
|
||||
# '(', 'x', 'x', 'x', 'x', 'x', ')',
|
||||
@@ -735,13 +848,13 @@ AT_CLEANUP
|
||||
|
||||
|
||||
AT_CHECK_PRINTER_AND_DESTRUCTOR([])
|
||||
AT_CHECK_PRINTER_AND_DESTRUCTOR([], [with union])
|
||||
AT_CHECK_PRINTER_AND_DESTRUCTOR([], [ with union])
|
||||
|
||||
AT_CHECK_PRINTER_AND_DESTRUCTOR([%defines %skeleton "lalr1.cc"])
|
||||
AT_CHECK_PRINTER_AND_DESTRUCTOR([%defines %skeleton "lalr1.cc"], [with union])
|
||||
AT_CHECK_PRINTER_AND_DESTRUCTOR([%defines %skeleton "lalr1.cc"], [ with union])
|
||||
|
||||
AT_CHECK_PRINTER_AND_DESTRUCTOR([%glr-parser])
|
||||
AT_CHECK_PRINTER_AND_DESTRUCTOR([%glr-parser], [with union])
|
||||
AT_CHECK_PRINTER_AND_DESTRUCTOR([%glr-parser], [ with union])
|
||||
|
||||
|
||||
|
||||
@@ -1174,7 +1287,7 @@ AT_SETUP([Default %printer and %destructor are not for $accept])
|
||||
# - The %printer and %destructor code generated for $accept would always be
|
||||
# dead code because $accept is currently never shifted onto the stack.
|
||||
# - $$ for $accept would always be of type YYSTYPE because it's not possible
|
||||
# to declare `%type <field> $accept'. (Also true for $undefined.)
|
||||
# to declare '%type <field> $accept'. (Also true for $undefined.)
|
||||
# - Thus, the compiler might complain that the user code assumes the wrong
|
||||
# type for $$ since the code might assume the type associated with a
|
||||
# specific union field, which is especially reasonable in C++ since that
|
||||
@@ -1494,115 +1607,6 @@ AT_TEST([glr.cc])
|
||||
|
||||
m4_popdef([AT_TEST])
|
||||
|
||||
## ----------------------------------------------- ##
|
||||
## Fix user actions without a trailing semicolon. ##
|
||||
## ----------------------------------------------- ##
|
||||
|
||||
AT_SETUP([[Fix user actions without a trailing semicolon]])
|
||||
|
||||
# This feature is undocumented, but we accidentally broke it in 2.3a,
|
||||
# and there was a complaint at:
|
||||
# <http://lists.gnu.org/archive/html/bug-bison/2008-11/msg00001.html>.
|
||||
AT_BISON_OPTION_PUSHDEFS
|
||||
AT_DATA([input.y],
|
||||
[[%%
|
||||
start: test2 test1 test0 testc;
|
||||
|
||||
test2
|
||||
: 'a' { semi; /* TEST:N:2 */ }
|
||||
| 'b' { if (0) {no_semi} /* TEST:N:2 */ }
|
||||
| 'c' { if (0) {semi;} /* TEST:N:2 */ }
|
||||
| 'd' { semi; no_semi /* TEST:Y:2 */ }
|
||||
| 'e' { semi(); no_semi() /* TEST:Y:2 */ }
|
||||
| 'f' { semi[]; no_semi[] /* TEST:Y:2 */ }
|
||||
| 'g' { semi++; no_semi++ /* TEST:Y:2 */ }
|
||||
| 'h' { {no_semi} no_semi /* TEST:Y:2 */ }
|
||||
| 'i' { {semi;} no_semi /* TEST:Y:2 */ }
|
||||
;
|
||||
test1
|
||||
: 'a' { semi; // TEST:N:1 ;
|
||||
} | 'b' { if (0) {no_semi} // TEST:N:1 ;
|
||||
} | 'c' { if (0) {semi;} // TEST:N:1 ;
|
||||
} | 'd' { semi; no_semi // TEST:Y:1 ;
|
||||
} | 'e' { semi(); no_semi() // TEST:Y:1 ;
|
||||
} | 'f' { semi[]; no_semi[] // TEST:Y:1 ;
|
||||
} | 'g' { semi++; no_semi++ // TEST:Y:1 ;
|
||||
} | 'h' { {no_semi} no_semi // TEST:Y:1 ;
|
||||
} | 'i' { {semi;} no_semi // TEST:Y:1 ;
|
||||
} ;
|
||||
test0
|
||||
: 'a' { semi; // TEST:N:1 {}
|
||||
} | 'b' { if (0) {no_semi} // TEST:N:1 {}
|
||||
} | 'c' { if (0) {semi;} // TEST:N:1 {}
|
||||
} | 'd' { semi; no_semi // TEST:Y:1 {}
|
||||
} | 'e' { semi(); no_semi() // TEST:Y:1 {}
|
||||
} | 'f' { semi[]; no_semi[] // TEST:Y:1 {}
|
||||
} | 'g' { semi++; no_semi++ // TEST:Y:1 {}
|
||||
} | 'h' { {no_semi} no_semi // TEST:Y:1 {}
|
||||
} | 'i' { {semi;} no_semi // TEST:Y:1 {}
|
||||
} ;
|
||||
|
||||
testc
|
||||
: 'a' {
|
||||
#define TEST_MACRO_N \
|
||||
[]"broken\" $ @ $$ @$ [];\
|
||||
string;"}
|
||||
| 'b' {
|
||||
no_semi
|
||||
#define TEST_MACRO_N \
|
||||
[]"broken\" $ @ $$ @$ [];\
|
||||
string;"}
|
||||
]])
|
||||
AT_BISON_OPTION_POPDEFS
|
||||
|
||||
AT_BISON_CHECK([[-o input.c input.y]], [0], [],
|
||||
[[input.y:8.48: warning: a ';' might be needed at the end of action code [-Wdeprecated]
|
||||
input.y:8.48: future versions of Bison will not add the ';'
|
||||
input.y:9.48: warning: a ';' might be needed at the end of action code [-Wdeprecated]
|
||||
input.y:9.48: future versions of Bison will not add the ';'
|
||||
input.y:10.48: warning: a ';' might be needed at the end of action code [-Wdeprecated]
|
||||
input.y:10.48: future versions of Bison will not add the ';'
|
||||
input.y:11.48: warning: a ';' might be needed at the end of action code [-Wdeprecated]
|
||||
input.y:11.48: future versions of Bison will not add the ';'
|
||||
input.y:12.48: warning: a ';' might be needed at the end of action code [-Wdeprecated]
|
||||
input.y:12.48: future versions of Bison will not add the ';'
|
||||
input.y:13.48: warning: a ';' might be needed at the end of action code [-Wdeprecated]
|
||||
input.y:13.48: future versions of Bison will not add the ';'
|
||||
input.y:20.1: warning: a ';' might be needed at the end of action code [-Wdeprecated]
|
||||
input.y:20.1: future versions of Bison will not add the ';'
|
||||
input.y:21.1: warning: a ';' might be needed at the end of action code [-Wdeprecated]
|
||||
input.y:21.1: future versions of Bison will not add the ';'
|
||||
input.y:22.1: warning: a ';' might be needed at the end of action code [-Wdeprecated]
|
||||
input.y:22.1: future versions of Bison will not add the ';'
|
||||
input.y:23.1: warning: a ';' might be needed at the end of action code [-Wdeprecated]
|
||||
input.y:23.1: future versions of Bison will not add the ';'
|
||||
input.y:24.1: warning: a ';' might be needed at the end of action code [-Wdeprecated]
|
||||
input.y:24.1: future versions of Bison will not add the ';'
|
||||
input.y:25.1: warning: a ';' might be needed at the end of action code [-Wdeprecated]
|
||||
input.y:25.1: future versions of Bison will not add the ';'
|
||||
input.y:31.1: warning: a ';' might be needed at the end of action code [-Wdeprecated]
|
||||
input.y:31.1: future versions of Bison will not add the ';'
|
||||
input.y:32.1: warning: a ';' might be needed at the end of action code [-Wdeprecated]
|
||||
input.y:32.1: future versions of Bison will not add the ';'
|
||||
input.y:33.1: warning: a ';' might be needed at the end of action code [-Wdeprecated]
|
||||
input.y:33.1: future versions of Bison will not add the ';'
|
||||
input.y:34.1: warning: a ';' might be needed at the end of action code [-Wdeprecated]
|
||||
input.y:34.1: future versions of Bison will not add the ';'
|
||||
input.y:35.1: warning: a ';' might be needed at the end of action code [-Wdeprecated]
|
||||
input.y:35.1: future versions of Bison will not add the ';'
|
||||
input.y:36.1: warning: a ';' might be needed at the end of action code [-Wdeprecated]
|
||||
input.y:36.1: future versions of Bison will not add the ';'
|
||||
]])
|
||||
|
||||
AT_MATCHES_CHECK([input.c], [[/\* TEST:N:2 \*/ \}$]], [[3]])
|
||||
AT_MATCHES_CHECK([input.c], [[/\* TEST:Y:2 \*/ ;\}$]], [[6]])
|
||||
AT_MATCHES_CHECK([input.c], [[// TEST:N:1 [;{}]*\n\}$]], [[6]])
|
||||
AT_MATCHES_CHECK([input.c], [[// TEST:Y:1 [;{}]*\n;\}$]], [[12]])
|
||||
AT_MATCHES_CHECK([input.c], [[#define TEST_MACRO_N \\\n\[\]"broken\\" \$ \@ \$\$ \@\$ \[\];\\\nstring;"\}]], [[2]])
|
||||
|
||||
AT_CLEANUP
|
||||
|
||||
|
||||
## -------------------------------------------------- ##
|
||||
## Destroying lookahead assigned by semantic action. ##
|
||||
## -------------------------------------------------- ##
|
||||
@@ -1637,7 +1641,7 @@ AT_DATA_GRAMMAR([input.y],
|
||||
// that has set yychar might not always return normally. Instead,
|
||||
// skeletons must translate before every use of yytoken.
|
||||
start: 'a' accept { USE($1); } ;
|
||||
accept: /*empty*/ {
|
||||
accept: %empty {
|
||||
assert (yychar == YYEMPTY);
|
||||
yychar = 'b';
|
||||
YYACCEPT;
|
||||
|
||||
+31
-4
@@ -16,7 +16,7 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# We need `config.h'.
|
||||
# We need 'config.h'.
|
||||
CPPFLAGS="-I$abs_top_builddir/lib @CPPFLAGS@"
|
||||
|
||||
# Don't just check if $POSIXLY_CORRECT is set, as Bash, when launched
|
||||
@@ -47,12 +47,39 @@ NO_WERROR_CXXFLAGS='@CXXFLAGS@ @WARN_CXXFLAGS@ @WARN_CXXFLAGS_TEST@'
|
||||
CFLAGS="$NO_WERROR_CFLAGS @WERROR_CFLAGS@"
|
||||
CXXFLAGS="$NO_WERROR_CXXFLAGS @WERROR_CXXFLAGS@"
|
||||
|
||||
# C++ variants break strict aliasing analysis.
|
||||
NO_STRICT_ALIAS_CXXFLAGS='@NO_STRICT_ALIAS_CXXFLAGS@'
|
||||
|
||||
# If 'exit 77'; skip all C++ tests; otherwise ':'.
|
||||
BISON_CXX_WORKS='@BISON_CXX_WORKS@'
|
||||
|
||||
# Be sure that the C++ compiler is not broken because of gnulib. This
|
||||
# cannot be checked in configure (gnulib is not parameterized yet),
|
||||
# and checking this in every C++ test in AC_COMPILE_CXX is too costly.
|
||||
#
|
||||
# http://lists.gnu.org/archive/html/bug-bison/2013-06/msg00001.html
|
||||
#
|
||||
# FIXME: Check (say 2014) whether this is still needed.
|
||||
if $BISON_CXX_WORKS; then
|
||||
# See AT_DATA_SOURCE_PROLOGUE.
|
||||
cat >conftest.cc <<EOF
|
||||
#include <config.h>
|
||||
/* We don't need perfect functions for these tests. */
|
||||
#undef malloc
|
||||
#undef memcmp
|
||||
#undef realloc
|
||||
#include <iostream>
|
||||
|
||||
int main ()
|
||||
{
|
||||
std::cout << "Works" << std::endl;
|
||||
}
|
||||
EOF
|
||||
$CXX $CXXFLAGS $CPPFLAGS $LDFLAGS $LIBS -o conftest conftest.cc
|
||||
case $? in
|
||||
0);;
|
||||
*) BISON_CXX_WORKS="as_fn_error 77 cannot-compile-simple-program";;
|
||||
esac
|
||||
rm -fr conftest*
|
||||
fi
|
||||
|
||||
# Whether the compiler supports POSIXLY_CORRECT defined.
|
||||
: ${C_COMPILER_POSIXLY_CORRECT='@C_COMPILER_POSIXLY_CORRECT@'}
|
||||
: ${CXX_COMPILER_POSIXLY_CORRECT='@CXX_COMPILER_POSIXLY_CORRECT@'}
|
||||
|
||||
+152
-69
@@ -18,6 +18,68 @@
|
||||
AT_BANNER([[C++ Features.]])
|
||||
|
||||
|
||||
## --------------- ##
|
||||
## C++ Locations. ##
|
||||
## --------------- ##
|
||||
|
||||
AT_SETUP([C++ Locations])
|
||||
|
||||
AT_BISON_OPTION_PUSHDEFS([%locations %skeleton "lalr1.cc"])
|
||||
AT_DATA_GRAMMAR([[input.y]],
|
||||
[[%code {#include <sstream>}
|
||||
%locations
|
||||
%debug
|
||||
%skeleton "lalr1.cc"
|
||||
%code
|
||||
{
|
||||
]AT_YYERROR_DECLARE[
|
||||
]AT_YYLEX_DECLARE[
|
||||
}
|
||||
%%
|
||||
exp: %empty;
|
||||
%%
|
||||
]AT_YYERROR_DEFINE[
|
||||
]AT_YYLEX_DEFINE[
|
||||
|
||||
template <typename T>
|
||||
bool
|
||||
check (const T& in, const std::string& s)
|
||||
{
|
||||
std::stringstream os;
|
||||
os << in;
|
||||
if (os.str () != s)
|
||||
{
|
||||
std::cerr << "fail: " << os.str () << ", expected: " << s << std::endl;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
int fail = 0;
|
||||
]AT_YYLTYPE[ loc; fail += check (loc, "1.1");
|
||||
loc += 10; fail += check (loc, "1.1-10");
|
||||
loc += -5; fail += check (loc, "1.1-5");
|
||||
loc -= 5; fail += check (loc, "1.1");
|
||||
// Check that we don't go below.
|
||||
// http://lists.gnu.org/archive/html/bug-bison/2013-02/msg00000.html
|
||||
loc -= 10; fail += check (loc, "1.1");
|
||||
|
||||
loc.columns (10); loc.lines (10); fail += check (loc, "1.1-11.0");
|
||||
loc.lines (-2); fail += check (loc, "1.1-9.0");
|
||||
loc.lines (-10); fail += check (loc, "1.1");
|
||||
return !fail;
|
||||
}
|
||||
]])
|
||||
|
||||
AT_FULL_COMPILE([input])
|
||||
AT_PARSER_CHECK([./input], 0)
|
||||
AT_BISON_OPTION_POPDEFS
|
||||
AT_CLEANUP
|
||||
|
||||
|
||||
## --------------------------- ##
|
||||
## C++ Variant-based Symbols. ##
|
||||
## --------------------------- ##
|
||||
@@ -28,7 +90,7 @@ AT_KEYWORDS([variant])
|
||||
|
||||
AT_BISON_OPTION_PUSHDEFS([%skeleton "lalr1.cc" %debug $1])
|
||||
# Store strings and integers in a list of strings.
|
||||
AT_DATA_GRAMMAR([list.yy],
|
||||
AT_DATA_GRAMMAR([list.y],
|
||||
[[%skeleton "lalr1.cc"
|
||||
%define api.value.type variant
|
||||
%define parse.assert
|
||||
@@ -92,8 +154,7 @@ int main()
|
||||
}
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK([-o list.cc list.yy])
|
||||
AT_COMPILE_CXX([list], [$NO_STRICT_ALIAS_CXXFLAGS list.cc])
|
||||
AT_FULL_COMPILE([list])
|
||||
AT_PARSER_CHECK([./list], 0, [],
|
||||
[12
|
||||
123
|
||||
@@ -113,11 +174,10 @@ AT_CLEANUP
|
||||
m4_pushdef([AT_TEST],
|
||||
[AT_SETUP([Variants $1])
|
||||
|
||||
AT_BISON_OPTION_PUSHDEFS([%skeleton "lalr1.cc" %debug $1])
|
||||
AT_BISON_OPTION_PUSHDEFS([%debug $1])
|
||||
# Store strings and integers in a list of strings.
|
||||
AT_DATA_GRAMMAR([list.yy],
|
||||
AT_DATA_GRAMMAR([list.y],
|
||||
[[%debug
|
||||
%skeleton "lalr1.cc"
|
||||
%define api.value.type variant
|
||||
]m4_bpatsubst([$1], [\\n], [
|
||||
])[
|
||||
@@ -183,7 +243,7 @@ typedef std::list<std::string> strings_type;
|
||||
// digraph for the left square bracket.
|
||||
%type <::std::list<std::string>> list result;
|
||||
|
||||
%printer { yyo << $][$; }
|
||||
%printer { yyo << $$; }
|
||||
<int> <::std::string> <::std::list<std::string>>;
|
||||
%%
|
||||
|
||||
@@ -193,13 +253,13 @@ result:
|
||||
|
||||
list:
|
||||
/* nothing */ { /* Generates an empty string list */ }
|
||||
| list item { std::swap ($][$,$][1); $$.push_back ($][2); }
|
||||
| list error { std::swap ($][$,$][1); }
|
||||
| list item { std::swap ($$,$][1); $$.push_back ($][2); }
|
||||
| list error { std::swap ($$,$][1); }
|
||||
;
|
||||
|
||||
item:
|
||||
TEXT { std::swap ($][$,$][1); }
|
||||
| NUMBER { if ($][1 == 3) YYERROR; else $][$ = string_cast ($][1); }
|
||||
TEXT { std::swap ($$,$][1); }
|
||||
| NUMBER { if ($][1 == 3) YYERROR; else $$ = string_cast ($][1); }
|
||||
;
|
||||
%%
|
||||
]AT_TOKEN_CTOR_IF([],
|
||||
@@ -250,8 +310,7 @@ namespace yy
|
||||
]AT_MAIN_DEFINE[
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK([-o list.cc list.yy])
|
||||
AT_COMPILE_CXX([list], [$NO_STRICT_ALIAS_CXXFLAGS list.cc])
|
||||
AT_FULL_COMPILE([list])
|
||||
AT_PARSER_CHECK([./list], 0,
|
||||
[(0, 1, 2, 4)
|
||||
])
|
||||
@@ -260,13 +319,13 @@ AT_BISON_OPTION_POPDEFS
|
||||
AT_CLEANUP
|
||||
])
|
||||
|
||||
AT_TEST([])
|
||||
AT_TEST([%define parse.assert])
|
||||
AT_TEST([%locations %define parse.assert])
|
||||
AT_TEST([[%define parse.assert %code {\n#define TWO_STAGE_BUILD\n}]])
|
||||
AT_TEST([[%define parse.assert %define api.token.constructor]])
|
||||
AT_TEST([[%define parse.assert %define api.token.constructor %define api.token.prefix "TOK_"]])
|
||||
AT_TEST([[%locations %define parse.assert %define api.token.constructor %define api.token.prefix "TOK_"]])
|
||||
AT_TEST([[%skeleton "lalr1.cc" ]])
|
||||
AT_TEST([[%skeleton "lalr1.cc" %define parse.assert]])
|
||||
AT_TEST([[%skeleton "lalr1.cc" %locations %define parse.assert]])
|
||||
AT_TEST([[%skeleton "lalr1.cc" %define parse.assert %code {\n#define TWO_STAGE_BUILD\n}]])
|
||||
AT_TEST([[%skeleton "lalr1.cc" %define parse.assert %define api.token.constructor]])
|
||||
AT_TEST([[%skeleton "lalr1.cc" %define parse.assert %define api.token.constructor %define api.token.prefix {TOK_}]])
|
||||
AT_TEST([[%skeleton "lalr1.cc" %locations %define parse.assert %define api.token.constructor %define api.token.prefix {TOK_}]])
|
||||
|
||||
m4_popdef([AT_TEST])
|
||||
|
||||
@@ -363,10 +422,10 @@ AT_CHECK_DOXYGEN([Private])
|
||||
# is specified, then Bison should accept the input, but compilation will fail,
|
||||
# so don't check compilation.
|
||||
m4_pushdef([AT_TEST],
|
||||
[AT_BISON_OPTION_PUSHDEFS([%language "C++" %define api.namespace "$1"])
|
||||
[AT_BISON_OPTION_PUSHDEFS([%language "C++" %define api.namespace {$1}])
|
||||
AT_DATA_GRAMMAR([[input.y]],
|
||||
[[%language "C++"
|
||||
%define api.namespace "]$1["
|
||||
%define api.namespace {]$1[}
|
||||
%union { int i; }
|
||||
%define global_tokens_and_yystype
|
||||
%locations
|
||||
@@ -422,8 +481,8 @@ AT_CLEANUP
|
||||
AT_SETUP([[Syntactically invalid namespace references]])
|
||||
AT_TEST([[:foo:bar]], [[-]])
|
||||
AT_TEST([[foo: :bar]], [[-]])
|
||||
# This one is interesting because `[3]' is encoded as `@<:@3@:>@', which
|
||||
# contains single occurrences of `:'.
|
||||
# This one is interesting because '[3]' is encoded as '@<:@3@:>@', which
|
||||
# contains single occurrences of ':'.
|
||||
AT_TEST([[foo[3]::bar::baz]], [[-]])
|
||||
AT_TEST([[foo::bar,baz]], [[-]])
|
||||
AT_TEST([[foo::bar::(baz /* Pacify Emacs ) */]], [[-]])
|
||||
@@ -590,11 +649,14 @@ AT_CLEANUP
|
||||
## Exception safety. ##
|
||||
## ------------------ ##
|
||||
|
||||
# AT_TEST([BISON-DIRECTIVES])
|
||||
# ---------------------------
|
||||
# AT_TEST([BISON-DIRECTIVES = ''], [WITH-RECOVERY = "with"])
|
||||
# ----------------------------------------------------------
|
||||
# Check that no object is leaked when exceptions are thrown.
|
||||
# WITH-RECOVERY = "with" or "without".
|
||||
m4_pushdef([AT_TEST],
|
||||
[AT_SETUP([[Exception safety $1]])
|
||||
[AT_SETUP([[Exception safety $2 error recovery $1]])
|
||||
|
||||
AT_SKIP_IF_EXCEPTION_SUPPORT_IS_POOR
|
||||
|
||||
AT_BISON_OPTION_PUSHDEFS([%skeleton "lalr1.cc" $1])
|
||||
|
||||
@@ -608,21 +670,59 @@ $1
|
||||
#include <cassert>
|
||||
#include <cstdlib> // size_t and getenv.
|
||||
#include <iostream>
|
||||
#include <list>
|
||||
#include <set>
|
||||
|
||||
bool debug = false;
|
||||
|
||||
/// A class that counts its number of instances.
|
||||
/// A class that tracks its instances.
|
||||
struct Object
|
||||
{
|
||||
typedef std::list<const Object*> objects;
|
||||
static objects instances;
|
||||
char val;
|
||||
|
||||
Object ()
|
||||
: val ('?')
|
||||
{
|
||||
log (this, "Object::Object");
|
||||
Object::instances.insert (this);
|
||||
}
|
||||
|
||||
Object (const Object& that)
|
||||
: val (that.val)
|
||||
{
|
||||
log (this, "Object::Object");
|
||||
Object::instances.insert (this);
|
||||
}
|
||||
|
||||
Object (char v)
|
||||
: val (v)
|
||||
{
|
||||
log (this, "Object::Object");
|
||||
Object::instances.insert (this);
|
||||
}
|
||||
|
||||
~Object ()
|
||||
{
|
||||
log (this, "Object::~Object");
|
||||
objects::const_iterator i = instances.find (this);
|
||||
// Make sure this object is alive.
|
||||
assert (i != instances.end ());
|
||||
Object::instances.erase (i);
|
||||
}
|
||||
|
||||
Object& operator= (char v)
|
||||
{
|
||||
val = v;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Static part.
|
||||
typedef std::set<const Object*> objects;
|
||||
static objects instances;
|
||||
|
||||
static bool
|
||||
empty ()
|
||||
{
|
||||
return instances.empty();
|
||||
return instances.empty ();
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -645,26 +745,6 @@ $1
|
||||
std::cerr << " }" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
Object (char v)
|
||||
: val (v)
|
||||
{
|
||||
instances.push_back(this);
|
||||
log (this, "Object::Object");
|
||||
}
|
||||
|
||||
Object ()
|
||||
: val ('?')
|
||||
{
|
||||
instances.push_back(this);
|
||||
log (this, "Object::Object");
|
||||
}
|
||||
|
||||
~Object ()
|
||||
{
|
||||
instances.remove(this);
|
||||
log (this, "Object::~Object");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -716,22 +796,23 @@ $1
|
||||
start: list {]AT_VARIANT_IF([], [ delete $][1]; )[};
|
||||
|
||||
list:
|
||||
item { $][$ = $][1; }
|
||||
item { $$ = $][1; }
|
||||
// Right recursion to load the stack.
|
||||
| item list { $][$ = $][1; ]AT_VARIANT_IF([], [delete $][2]; )[}
|
||||
| item list { $$ = $][1; ]AT_VARIANT_IF([], [delete $][2]; )[}
|
||||
;
|
||||
|
||||
item:
|
||||
'a' { $$][ = $][1; }
|
||||
| 'e' { YYUSE ($][$); YYUSE($][1); error ("syntax error"); }
|
||||
'a' { $$ = $][1; }
|
||||
| 'e' { YYUSE ($$); YYUSE($][1); error ("syntax error"); }
|
||||
// Not just 'E', otherwise we reduce when 'E' is the lookahead, and
|
||||
// then the stack is emptied, defeating the point of the test.
|
||||
| 'E' 'a' { YYUSE($][1); $][$ = $][2; }
|
||||
| 'R' { $][$ = YY_NULL; ]AT_VARIANT_IF([], [delete $][1]; )[YYERROR; }
|
||||
| 'p' { $][$ = $][1; }
|
||||
| 's' { $][$ = $][1; throw std::runtime_error ("reduction"); }
|
||||
| 'T' { $][$ = YY_NULL; ]AT_VARIANT_IF([], [delete $][1]; )[YYABORT; }
|
||||
| error { $][$ = YY_NULL; yyerrok; }
|
||||
| 'E' 'a' { YYUSE($][1); $$ = $][2; }
|
||||
| 'R' { ]AT_VARIANT_IF([], [$$ = YY_NULLPTR; delete $][1]; )[YYERROR; }
|
||||
| 'p' { $$ = $][1; }
|
||||
| 's' { $$ = $][1; throw std::runtime_error ("reduction"); }
|
||||
| 'T' { ]AT_VARIANT_IF([], [$$ = YY_NULLPTR; delete $][1]; )[YYABORT; }
|
||||
]m4_if([$2], [with],
|
||||
[[| error { $$ = ]AT_VARIANT_IF([], [new ])[Object ('R'); yyerrok; }]])[
|
||||
;
|
||||
%%
|
||||
|
||||
@@ -751,7 +832,8 @@ yylex (yy::parser::semantic_type *lvalp)
|
||||
case 'l':
|
||||
throw std::runtime_error ("yylex");
|
||||
default:
|
||||
lvalp]AT_VARIANT_IF([->build (res)], [->obj = new Object (res)])[;
|
||||
lvalp->]AT_VARIANT_IF([build (Object (res))],
|
||||
[obj = new Object (res)])[;
|
||||
// Fall through.
|
||||
case 0:
|
||||
return res;
|
||||
@@ -798,13 +880,13 @@ main (int argc, const char *argv[])
|
||||
{
|
||||
std::cerr << "unknown exception caught" << std::endl;
|
||||
}
|
||||
Object::log (YY_NULL, "end");
|
||||
Object::log (YY_NULLPTR, "end");
|
||||
assert (Object::empty());
|
||||
return res;
|
||||
}
|
||||
]])
|
||||
AT_BISON_CHECK([[-o input.cc --report=all input.yy]])
|
||||
AT_COMPILE_CXX([input], [[$NO_STRICT_ALIAS_CXXFLAGS input.cc]])
|
||||
AT_COMPILE_CXX([[input]])
|
||||
|
||||
AT_PARSER_CHECK([[./input aaaas]], [[2]], [[]],
|
||||
[[exception caught: reduction
|
||||
@@ -833,16 +915,17 @@ AT_PARSER_CHECK([[./input aaaaE]], [[2]], [[]],
|
||||
|
||||
AT_PARSER_CHECK([[./input aaaaT]], [[1]])
|
||||
|
||||
# There is error-recovery, so exit success.
|
||||
AT_PARSER_CHECK([[./input aaaaR]], [[0]])
|
||||
AT_PARSER_CHECK([[./input aaaaR]], [m4_if([$2], [with], [0], [1])])
|
||||
|
||||
AT_BISON_OPTION_POPDEFS
|
||||
|
||||
AT_CLEANUP
|
||||
])
|
||||
|
||||
AT_TEST
|
||||
AT_TEST([%define api.value.type variant])
|
||||
AT_TEST([], [with])
|
||||
AT_TEST([], [without])
|
||||
AT_TEST([%define api.value.type variant], [with])
|
||||
AT_TEST([%define api.value.type variant], [without])
|
||||
|
||||
m4_popdef([AT_TEST])
|
||||
|
||||
|
||||
+48
-48
@@ -27,11 +27,11 @@
|
||||
|
||||
# _AT_DATA_CALC_Y($1, $2, $3, [BISON-DIRECTIVES])
|
||||
# -----------------------------------------------
|
||||
# Produce `calc.y' and, if %defines was specified, `calc-lex.c' or
|
||||
# `calc-lex.cc'.
|
||||
# Produce 'calc.y' and, if %defines was specified, 'calc-lex.c' or
|
||||
# 'calc-lex.cc'.
|
||||
#
|
||||
# Don't call this macro directly, because it contains some occurrences
|
||||
# of `$1' etc. which will be interpreted by m4. So you should call it
|
||||
# of '$1' etc. which will be interpreted by m4. So you should call it
|
||||
# with $1, $2, and $3 as arguments, which is what AT_DATA_CALC_Y does.
|
||||
#
|
||||
# When %defines is not passed, generate a single self-contained file.
|
||||
@@ -72,10 +72,12 @@ main (int argc, const char **argv)
|
||||
int count = 0;
|
||||
int status;
|
||||
|
||||
/* This used to be alarm (10), but that isn't enough time for
|
||||
a July 1995 vintage DEC Alphastation 200 4/100 system,
|
||||
according to Nelson H. F. Beebe. 100 seconds is enough. */
|
||||
alarm (100);
|
||||
/* This used to be alarm (10), but that isn't enough time for a July
|
||||
1995 vintage DEC Alphastation 200 4/100 system, according to
|
||||
Nelson H. F. Beebe. 100 seconds was enough for regular users,
|
||||
but the Hydra build farm, which is heavily loaded needs more. */
|
||||
|
||||
alarm (200);
|
||||
|
||||
if (argc == 2)
|
||||
input = fopen (argv[1], "r");
|
||||
@@ -88,8 +90,7 @@ main (int argc, const char **argv)
|
||||
return 3;
|
||||
}
|
||||
|
||||
]AT_SKEL_CC_IF([], [m4_bmatch([$4], [%debug],
|
||||
[ ]AT_NAME_PREFIX[debug = 1;])])[
|
||||
]AT_SKEL_CC_IF([], [AT_DEBUG_IF([ ]AT_NAME_PREFIX[debug = 1;])])[
|
||||
status = ]AT_NAME_PREFIX[parse (]AT_PARAM_IF([[&result, &count]])[);
|
||||
if (fclose (input))
|
||||
perror ("fclose");
|
||||
@@ -133,7 +134,7 @@ unget_char (]AT_YYLEX_PRE_FORMALS[ int c)
|
||||
{
|
||||
]AT_USE_LEX_ARGS[;
|
||||
]AT_LOCATION_IF([
|
||||
/* Wrong when C == `\n'. */
|
||||
/* Wrong when C == '\n'. */
|
||||
AT_LOC = last_yylloc;
|
||||
])[
|
||||
ungetc (c, input);
|
||||
@@ -365,8 +366,8 @@ m4_popdef([AT_CALC_LEX])
|
||||
|
||||
# AT_DATA_CALC_Y([BISON-OPTIONS])
|
||||
# -------------------------------
|
||||
# Produce `calc.y' and, if %defines was specified, `calc-lex.c' or
|
||||
# `calc-lex.cc'.
|
||||
# Produce 'calc.y' and, if %defines was specified, 'calc-lex.c' or
|
||||
# 'calc-lex.cc'.
|
||||
m4_define([AT_DATA_CALC_Y],
|
||||
[_AT_DATA_CALC_Y($[1], $[2], $[3], [$1])
|
||||
])
|
||||
@@ -375,9 +376,9 @@ m4_define([AT_DATA_CALC_Y],
|
||||
|
||||
# _AT_CHECK_CALC(BISON-OPTIONS, INPUT, [NUM-STDERR-LINES])
|
||||
# --------------------------------------------------------
|
||||
# Run `calc' on INPUT and expect no STDOUT nor STDERR.
|
||||
# Run 'calc' on INPUT and expect no STDOUT nor STDERR.
|
||||
#
|
||||
# If BISON-OPTIONS contains `%debug' but not `%glr-parser', then
|
||||
# If BISON-OPTIONS contains '%debug' but not '%glr-parser', then
|
||||
#
|
||||
# NUM-STDERR-LINES is the number of expected lines on stderr.
|
||||
# Currently this is ignored, though, since the output format is fluctuating.
|
||||
@@ -396,7 +397,7 @@ AT_PARSER_CHECK([./calc input], 0, [], [stderr])
|
||||
# [NUM-STDERR-LINES],
|
||||
# [VERBOSE-AND-LOCATED-ERROR-MESSAGE])
|
||||
# ---------------------------------------------------------
|
||||
# Run `calc' on INPUT, and expect a `syntax error' message.
|
||||
# Run 'calc' on INPUT, and expect a 'syntax error' message.
|
||||
#
|
||||
# If INPUT starts with a slash, it is used as absolute input file name,
|
||||
# otherwise as contents.
|
||||
@@ -404,14 +405,14 @@ AT_PARSER_CHECK([./calc input], 0, [], [stderr])
|
||||
# NUM-STDERR-LINES is the number of expected lines on stderr.
|
||||
# Currently this is ignored, though, since the output format is fluctuating.
|
||||
#
|
||||
# If BISON-OPTIONS contains `%location', then make sure the ERROR-LOCATION
|
||||
# If BISON-OPTIONS contains '%location', then make sure the ERROR-LOCATION
|
||||
# is correctly output on stderr.
|
||||
#
|
||||
# If BISON-OPTIONS contains `%define parse.error verbose', then make sure the
|
||||
# IF-YYERROR-VERBOSE message is properly output after `syntax error, '
|
||||
# If BISON-OPTIONS contains '%define parse.error verbose', then make sure the
|
||||
# IF-YYERROR-VERBOSE message is properly output after 'syntax error, '
|
||||
# on STDERR.
|
||||
#
|
||||
# If BISON-OPTIONS contains `%debug' but not `%glr', then NUM-STDERR-LINES
|
||||
# If BISON-OPTIONS contains '%debug' but not '%glr', then NUM-STDERR-LINES
|
||||
# is the number of expected lines on stderr.
|
||||
m4_define([_AT_CHECK_CALC_ERROR],
|
||||
[m4_bmatch([$3], [^/],
|
||||
@@ -448,7 +449,7 @@ AT_DATA([[expout]],
|
||||
AT_YYERROR_SEES_LOC_IF([],
|
||||
[[sed 's/^[-0-9.]*: //' expout >at-expout
|
||||
mv at-expout expout]])
|
||||
# 4. If error-verbose is not used, strip the`, unexpected....' part.
|
||||
# 4. If error-verbose is not used, strip the', unexpected....' part.
|
||||
m4_bmatch([$1], [%define parse.error verbose], [],
|
||||
[[sed 's/syntax error, .*$/syntax error/' expout >at-expout
|
||||
mv at-expout expout]])
|
||||
@@ -478,7 +479,7 @@ m4_define([AT_CHECK_SPACES],
|
||||
|
||||
# AT_CHECK_CALC([BISON-OPTIONS])
|
||||
# ------------------------------
|
||||
# Start a testing chunk which compiles `calc' grammar with
|
||||
# Start a testing chunk which compiles 'calc' grammar with
|
||||
# BISON-OPTIONS, and performs several tests over the parser.
|
||||
m4_define([AT_CHECK_CALC],
|
||||
[m4_ifval([$2], [m4_fatal([$0: expected a single argument])])
|
||||
@@ -538,7 +539,7 @@ _AT_CHECK_CALC_ERROR([$1], [1], [/dev/null], [4],
|
||||
# - (* * *): nothing to pop, a lot to discard
|
||||
# - (1 + 2 * *): some to pop and discard
|
||||
#
|
||||
# - test the action associated to `error'
|
||||
# - test the action associated to 'error'
|
||||
#
|
||||
# - check the lookahead that triggers an error is not discarded
|
||||
# when we enter error recovery. Below, the lookahead causing the
|
||||
@@ -587,7 +588,7 @@ AT_BANNER([[Simple LALR(1) Calculator.]])
|
||||
|
||||
# AT_CHECK_CALC_LALR([BISON-OPTIONS])
|
||||
# -----------------------------------
|
||||
# Start a testing chunk which compiles `calc' grammar with
|
||||
# Start a testing chunk which compiles 'calc' grammar with
|
||||
# BISON-OPTIONS, and performs several tests over the parser.
|
||||
m4_define([AT_CHECK_CALC_LALR],
|
||||
[AT_CHECK_CALC($@)])
|
||||
@@ -606,17 +607,17 @@ AT_CHECK_CALC_LALR([%define api.pure full %locations])
|
||||
AT_CHECK_CALC_LALR([%define api.push-pull both %define api.pure full %locations])
|
||||
AT_CHECK_CALC_LALR([%define parse.error verbose %locations])
|
||||
|
||||
AT_CHECK_CALC_LALR([%define parse.error verbose %locations %defines %define api.prefix "calc" %verbose %yacc])
|
||||
AT_CHECK_CALC_LALR([%define parse.error verbose %locations %defines %name-prefix "calc" %define api.token.prefix "TOK_" %verbose %yacc])
|
||||
AT_CHECK_CALC_LALR([%define parse.error verbose %locations %defines %define api.prefix {calc} %verbose %yacc])
|
||||
AT_CHECK_CALC_LALR([%define parse.error verbose %locations %defines %name-prefix "calc" %define api.token.prefix {TOK_} %verbose %yacc])
|
||||
|
||||
AT_CHECK_CALC_LALR([%debug])
|
||||
AT_CHECK_CALC_LALR([%define parse.error verbose %debug %locations %defines %name-prefix "calc" %verbose %yacc])
|
||||
AT_CHECK_CALC_LALR([%define parse.error verbose %debug %locations %defines %define api.prefix "calc" %verbose %yacc])
|
||||
AT_CHECK_CALC_LALR([%define parse.error verbose %debug %locations %defines %define api.prefix {calc} %verbose %yacc])
|
||||
|
||||
AT_CHECK_CALC_LALR([%define api.pure full %define parse.error verbose %debug %locations %defines %name-prefix "calc" %verbose %yacc])
|
||||
AT_CHECK_CALC_LALR([%define api.push-pull both %define api.pure full %define parse.error verbose %debug %locations %defines %define api.prefix "calc" %verbose %yacc])
|
||||
AT_CHECK_CALC_LALR([%define api.push-pull both %define api.pure full %define parse.error verbose %debug %locations %defines %define api.prefix {calc} %verbose %yacc])
|
||||
|
||||
AT_CHECK_CALC_LALR([%define api.pure %define parse.error verbose %debug %locations %defines %define api.prefix "calc" %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}])
|
||||
AT_CHECK_CALC_LALR([%define api.pure %define parse.error verbose %debug %locations %defines %define api.prefix {calc} %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}])
|
||||
|
||||
|
||||
# ----------------------- #
|
||||
@@ -627,7 +628,7 @@ AT_BANNER([[Simple GLR Calculator.]])
|
||||
|
||||
# AT_CHECK_CALC_GLR([BISON-OPTIONS])
|
||||
# ----------------------------------
|
||||
# Start a testing chunk which compiles `calc' grammar with
|
||||
# Start a testing chunk which compiles 'calc' grammar with
|
||||
# BISON-OPTIONS and %glr-parser, and performs several tests over the parser.
|
||||
m4_define([AT_CHECK_CALC_GLR],
|
||||
[AT_CHECK_CALC([%glr-parser] $@)])
|
||||
@@ -638,7 +639,7 @@ AT_CHECK_CALC_GLR()
|
||||
AT_CHECK_CALC_GLR([%defines])
|
||||
AT_CHECK_CALC_GLR([%locations])
|
||||
AT_CHECK_CALC_GLR([%name-prefix "calc"])
|
||||
AT_CHECK_CALC_GLR([%define api.prefix "calc"])
|
||||
AT_CHECK_CALC_GLR([%define api.prefix {calc}])
|
||||
AT_CHECK_CALC_GLR([%verbose])
|
||||
AT_CHECK_CALC_GLR([%yacc])
|
||||
AT_CHECK_CALC_GLR([%define parse.error verbose])
|
||||
@@ -650,12 +651,12 @@ AT_CHECK_CALC_GLR([%define parse.error verbose %locations %defines %name-prefix
|
||||
|
||||
AT_CHECK_CALC_GLR([%debug])
|
||||
AT_CHECK_CALC_GLR([%define parse.error verbose %debug %locations %defines %name-prefix "calc" %verbose %yacc])
|
||||
AT_CHECK_CALC_GLR([%define parse.error verbose %debug %locations %defines %define api.prefix "calc" %define api.token.prefix "TOK_" %verbose %yacc])
|
||||
AT_CHECK_CALC_GLR([%define parse.error verbose %debug %locations %defines %define api.prefix {calc} %define api.token.prefix {TOK_} %verbose %yacc])
|
||||
|
||||
AT_CHECK_CALC_GLR([%define api.pure %define parse.error verbose %debug %locations %defines %name-prefix "calc" %verbose %yacc])
|
||||
|
||||
AT_CHECK_CALC_GLR([%define api.pure %define parse.error verbose %debug %locations %defines %name-prefix "calc" %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}])
|
||||
AT_CHECK_CALC_GLR([%define api.pure %define parse.error verbose %debug %locations %defines %define api.prefix "calc" %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}])
|
||||
AT_CHECK_CALC_GLR([%define api.pure %define parse.error verbose %debug %locations %defines %define api.prefix {calc} %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}])
|
||||
|
||||
|
||||
# ----------------------------- #
|
||||
@@ -669,26 +670,26 @@ AT_CHECK_CALC([%skeleton "lalr1.cc" %defines])
|
||||
|
||||
# AT_CHECK_CALC_LALR1_CC([BISON-OPTIONS])
|
||||
# ---------------------------------------
|
||||
# Start a testing chunk which compiles `calc' grammar with
|
||||
# Start a testing chunk which compiles 'calc' grammar with
|
||||
# the C++ skeleton, and performs several tests over the parser.
|
||||
m4_define([AT_CHECK_CALC_LALR1_CC],
|
||||
[AT_CHECK_CALC([%language "C++"] $@)])
|
||||
|
||||
AT_CHECK_CALC_LALR1_CC([])
|
||||
AT_CHECK_CALC_LALR1_CC([%locations])
|
||||
AT_CHECK_CALC_LALR1_CC([%locations %define api.location.type Span])
|
||||
AT_CHECK_CALC_LALR1_CC([%locations %define api.location.type {Span}])
|
||||
AT_CHECK_CALC_LALR1_CC([%defines %locations %define parse.error verbose %name-prefix "calc" %verbose %yacc])
|
||||
|
||||
AT_CHECK_CALC_LALR1_CC([%locations %define parse.error verbose %define api.prefix "calc" %verbose %yacc])
|
||||
AT_CHECK_CALC_LALR1_CC([%locations %define parse.error verbose %define api.prefix {calc} %verbose %yacc])
|
||||
AT_CHECK_CALC_LALR1_CC([%locations %define parse.error verbose %debug %name-prefix "calc" %verbose %yacc])
|
||||
|
||||
AT_CHECK_CALC_LALR1_CC([%locations %pure-parser %define parse.error verbose %debug %define api.prefix "calc" %verbose %yacc])
|
||||
AT_CHECK_CALC_LALR1_CC([%locations %pure-parser %define parse.error verbose %debug %define api.prefix "calc" %define api.token.prefix "TOK_" %verbose %yacc])
|
||||
AT_CHECK_CALC_LALR1_CC([%locations %define parse.error verbose %debug %define api.prefix {calc} %verbose %yacc])
|
||||
AT_CHECK_CALC_LALR1_CC([%locations %define parse.error verbose %debug %define api.prefix {calc} %define api.token.prefix {TOK_} %verbose %yacc])
|
||||
|
||||
AT_CHECK_CALC_LALR1_CC([%defines %locations %pure-parser %define parse.error verbose %debug %name-prefix "calc" %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}])
|
||||
AT_CHECK_CALC_LALR1_CC([%defines %locations %define parse.error verbose %debug %name-prefix "calc" %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}])
|
||||
|
||||
AT_CHECK_CALC_LALR1_CC([%pure-parser %define parse.error verbose %debug %define api.prefix "calc" %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}])
|
||||
AT_CHECK_CALC_LALR1_CC([%defines %locations %pure-parser %define parse.error verbose %debug %define api.prefix "calc" %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}])
|
||||
AT_CHECK_CALC_LALR1_CC([%define parse.error verbose %debug %define api.prefix {calc} %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}])
|
||||
AT_CHECK_CALC_LALR1_CC([%defines %locations %define parse.error verbose %debug %define api.prefix {calc} %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}])
|
||||
|
||||
|
||||
|
||||
@@ -703,22 +704,21 @@ AT_CHECK_CALC([%skeleton "glr.cc"])
|
||||
|
||||
# AT_CHECK_CALC_GLR_CC([BISON-OPTIONS])
|
||||
# -------------------------------------
|
||||
# Start a testing chunk which compiles `calc' grammar with
|
||||
# Start a testing chunk which compiles 'calc' grammar with
|
||||
# the GLR C++ skeleton, and performs several tests over the parser.
|
||||
m4_define([AT_CHECK_CALC_GLR_CC],
|
||||
[AT_CHECK_CALC([%language "C++" %glr-parser] $@)])
|
||||
|
||||
AT_CHECK_CALC_GLR_CC([])
|
||||
AT_CHECK_CALC_GLR_CC([%locations])
|
||||
AT_CHECK_CALC_GLR_CC([%locations %define api.location.type Span])
|
||||
AT_CHECK_CALC_GLR_CC([%locations %define api.location.type {Span}])
|
||||
AT_CHECK_CALC_GLR_CC([%defines %define parse.error verbose %name-prefix "calc" %verbose %yacc])
|
||||
AT_CHECK_CALC_GLR_CC([%define parse.error verbose %define api.prefix "calc" %verbose %yacc])
|
||||
AT_CHECK_CALC_GLR_CC([%define parse.error verbose %define api.prefix {calc} %verbose %yacc])
|
||||
|
||||
AT_CHECK_CALC_GLR_CC([%debug])
|
||||
|
||||
AT_CHECK_CALC_GLR_CC([%define parse.error verbose %debug %name-prefix "calc" %verbose %yacc])
|
||||
AT_CHECK_CALC_GLR_CC([%define parse.error verbose %debug %name-prefix "calc" %define api.token.prefix {TOK_} %verbose %yacc])
|
||||
|
||||
AT_CHECK_CALC_GLR_CC([%pure-parser %define parse.error verbose %debug %name-prefix "calc" %verbose %yacc])
|
||||
AT_CHECK_CALC_GLR_CC([%pure-parser %define parse.error verbose %debug %name-prefix "calc" %define api.token.prefix "TOK_" %verbose %yacc])
|
||||
|
||||
AT_CHECK_CALC_GLR_CC([%locations %defines %pure-parser %define parse.error verbose %debug %name-prefix "calc" %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}])
|
||||
AT_CHECK_CALC_GLR_CC([%locations %defines %pure-parser %define parse.error verbose %debug %define api.prefix "calc" %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}])
|
||||
AT_CHECK_CALC_GLR_CC([%locations %defines %define parse.error verbose %debug %name-prefix "calc" %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}])
|
||||
AT_CHECK_CALC_GLR_CC([%locations %defines %define parse.error verbose %debug %define api.prefix {calc} %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}])
|
||||
|
||||
+179
-111
@@ -17,42 +17,9 @@
|
||||
|
||||
AT_BANNER([[Conflicts.]])
|
||||
|
||||
## ------------------------------ ##
|
||||
## Useless associativity warning. ##
|
||||
## ------------------------------ ##
|
||||
|
||||
AT_SETUP([Useless associativity warning])
|
||||
|
||||
AT_DATA([[input.y]],
|
||||
[[%token T
|
||||
%left A B
|
||||
%right C
|
||||
%nonassoc D
|
||||
%precedence E
|
||||
|
||||
%%
|
||||
e: T A T
|
||||
| T B T
|
||||
| T C T
|
||||
| T D T
|
||||
| T E T
|
||||
;
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK([input.y], 0, [],
|
||||
[[input.y:5.13: warning: useless precedence for E [-Wother]
|
||||
input.y:2.7: warning: useless associativity for A [-Wother]
|
||||
input.y:2.9: warning: useless associativity for B [-Wother]
|
||||
input.y:3.8: warning: useless associativity for C [-Wother]
|
||||
input.y:4.11: warning: useless associativity for D [-Wother]
|
||||
]])
|
||||
|
||||
AT_CLEANUP
|
||||
|
||||
|
||||
## ------------------------ ##
|
||||
## Token declaration order. ##
|
||||
## ------------------------ ##
|
||||
## ------------------------- ##
|
||||
## Token declaration order. ##
|
||||
## ------------------------- ##
|
||||
|
||||
# This test checks that token are declared left to right when in a precedence
|
||||
# statement.
|
||||
@@ -110,27 +77,7 @@ int main (void)
|
||||
}
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK([-o input.c input.y], [], [],
|
||||
[[input.y:24.13: warning: useless precedence for R [-Wother]
|
||||
input.y:24.15: warning: useless precedence for S [-Wother]
|
||||
input.y:24.17: warning: useless precedence for T [-Wother]
|
||||
input.y:24.19: warning: useless precedence for U [-Wother]
|
||||
input.y:25.13: warning: useless precedence for V [-Wother]
|
||||
input.y:25.15: warning: useless precedence for W [-Wother]
|
||||
input.y:18.8: warning: useless associativity for E [-Wother]
|
||||
input.y:18.10: warning: useless associativity for F [-Wother]
|
||||
input.y:18.12: warning: useless associativity for G [-Wother]
|
||||
input.y:19.8: warning: useless associativity for H [-Wother]
|
||||
input.y:19.10: warning: useless associativity for I [-Wother]
|
||||
input.y:20.8: warning: useless associativity for J [-Wother]
|
||||
input.y:21.8: warning: useless associativity for K [-Wother]
|
||||
input.y:22.8: warning: useless associativity for L [-Wother]
|
||||
input.y:22.10: warning: useless associativity for M [-Wother]
|
||||
input.y:22.12: warning: useless associativity for N [-Wother]
|
||||
input.y:23.11: warning: useless associativity for O [-Wother]
|
||||
input.y:23.13: warning: useless associativity for P [-Wother]
|
||||
input.y:23.15: warning: useless associativity for Q [-Wother]
|
||||
]])
|
||||
AT_BISON_CHECK([-o input.c input.y])
|
||||
AT_COMPILE([input])
|
||||
|
||||
AT_PARSER_CHECK([./input])
|
||||
@@ -140,6 +87,127 @@ AT_BISON_OPTION_POPDEFS
|
||||
AT_CLEANUP
|
||||
|
||||
|
||||
## --------------------------------------------------- ##
|
||||
## Token declaration order: literals vs. identifiers. ##
|
||||
## --------------------------------------------------- ##
|
||||
|
||||
# This test checks that when several tokens are declared by the same keyword,
|
||||
# some of them defined as a character ('a'), others as simple textual reference
|
||||
# (A), they are declared correctly left to right.
|
||||
# Previously, the following test would declare the states in the order 'o' 'p'
|
||||
# M N, instead of M N 'o' 'p'.
|
||||
|
||||
AT_SETUP([Token declaration order: literals vs. identifiers])
|
||||
|
||||
AT_DATA_GRAMMAR([[input.y]],
|
||||
[[%token 'a' 'b' C D
|
||||
%token E F 'g' 'h'
|
||||
%right 'i' 'j' K L
|
||||
%right M N 'o' 'p'
|
||||
%%
|
||||
exp: 'a'
|
||||
| 'b'
|
||||
| C
|
||||
| D
|
||||
| E
|
||||
| F
|
||||
| 'g'
|
||||
| 'h'
|
||||
| 'i'
|
||||
| 'j'
|
||||
| K
|
||||
| L
|
||||
| M
|
||||
| N
|
||||
| 'o'
|
||||
| 'p'
|
||||
;
|
||||
%%
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK([[--report=all -o input.c input.y]], 0, [], [ignore])
|
||||
AT_CHECK([[cat input.output | sed -n '/^State 0$/,/^State 1$/p']], 0,
|
||||
[[State 0
|
||||
|
||||
0 $accept: . exp $end
|
||||
1 exp: . 'a'
|
||||
2 | . 'b'
|
||||
3 | . C
|
||||
4 | . D
|
||||
5 | . E
|
||||
6 | . F
|
||||
7 | . 'g'
|
||||
8 | . 'h'
|
||||
9 | . 'i'
|
||||
10 | . 'j'
|
||||
11 | . K
|
||||
12 | . L
|
||||
13 | . M
|
||||
14 | . N
|
||||
15 | . 'o'
|
||||
16 | . 'p'
|
||||
|
||||
'a' shift, and go to state 1
|
||||
'b' shift, and go to state 2
|
||||
C shift, and go to state 3
|
||||
D shift, and go to state 4
|
||||
E shift, and go to state 5
|
||||
F shift, and go to state 6
|
||||
'g' shift, and go to state 7
|
||||
'h' shift, and go to state 8
|
||||
'i' shift, and go to state 9
|
||||
'j' shift, and go to state 10
|
||||
K shift, and go to state 11
|
||||
L shift, and go to state 12
|
||||
M shift, and go to state 13
|
||||
N shift, and go to state 14
|
||||
'o' shift, and go to state 15
|
||||
'p' shift, and go to state 16
|
||||
|
||||
exp go to state 17
|
||||
|
||||
|
||||
State 1
|
||||
]])
|
||||
|
||||
AT_CLEANUP
|
||||
|
||||
|
||||
## ------------------------------- ##
|
||||
## Useless associativity warning. ##
|
||||
## ------------------------------- ##
|
||||
|
||||
AT_SETUP([Useless associativity warning])
|
||||
|
||||
AT_DATA([[input.y]],
|
||||
[[%token EQ "=" PL "+" ST "*" LP "("
|
||||
%nonassoc "="
|
||||
%left "+"
|
||||
%left "*"
|
||||
%precedence "("
|
||||
%%
|
||||
stmt:
|
||||
exp
|
||||
| "var" "=" exp
|
||||
;
|
||||
|
||||
exp:
|
||||
exp "+" exp
|
||||
| exp "*" "num"
|
||||
| "(" exp ")"
|
||||
| "num"
|
||||
;
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK([-Wprecedence input.y], 0, [],
|
||||
[[input.y:2.1-9: warning: useless precedence and associativity for "=" [-Wprecedence]
|
||||
input.y:4.1-5: warning: useless associativity for "*", use %precedence [-Wprecedence]
|
||||
input.y:5.1-11: warning: useless precedence for "(" [-Wprecedence]
|
||||
]])
|
||||
|
||||
AT_CLEANUP
|
||||
|
||||
|
||||
## ---------------------------- ##
|
||||
## Useless precedence warning. ##
|
||||
## ---------------------------- ##
|
||||
@@ -147,7 +215,7 @@ AT_CLEANUP
|
||||
AT_SETUP([Useless precedence warning])
|
||||
|
||||
AT_DATA([[input.y]],
|
||||
[[%token A B
|
||||
[[%token A B U V W X Y Z
|
||||
%precedence Z
|
||||
%left X
|
||||
%precedence Y
|
||||
@@ -174,19 +242,19 @@ f: B
|
||||
;
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK([-fcaret -o input.c input.y], 0, [],
|
||||
[[input.y:2.13: warning: useless precedence for Z [-Wother]
|
||||
%precedence Z
|
||||
^
|
||||
input.y:5.7: warning: useless associativity for W [-Wother]
|
||||
%left W
|
||||
^
|
||||
input.y:6.8: warning: useless associativity for V [-Wother]
|
||||
%right V
|
||||
^
|
||||
input.y:7.11: warning: useless associativity for U [-Wother]
|
||||
AT_BISON_CHECK([-Wprecedence -fcaret -o input.c input.y], 0, [],
|
||||
[[input.y:7.1-9: warning: useless precedence and associativity for U [-Wprecedence]
|
||||
%nonassoc U
|
||||
^
|
||||
^^^^^^^^^
|
||||
input.y:6.1-6: warning: useless precedence and associativity for V [-Wprecedence]
|
||||
%right V
|
||||
^^^^^^
|
||||
input.y:5.1-5: warning: useless precedence and associativity for W [-Wprecedence]
|
||||
%left W
|
||||
^^^^^
|
||||
input.y:2.1-11: warning: useless precedence for Z [-Wprecedence]
|
||||
%precedence Z
|
||||
^^^^^^^^^^^
|
||||
]])
|
||||
|
||||
AT_CLEANUP
|
||||
@@ -211,7 +279,7 @@ e: 'e' | /* Nothing. */;
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK([-o input.c input.y], 0, [],
|
||||
[[input.y:4.9: warning: rule useless in parser due to conflicts: e: /* empty */ [-Wother]
|
||||
[[input.y:4.9: warning: rule useless in parser due to conflicts [-Wother]
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK([-fcaret -o input.c input.y], 0, [],
|
||||
@@ -939,7 +1007,7 @@ cond:
|
||||
|
||||
AT_BISON_CHECK([-o input.c input.y], 0, [],
|
||||
[[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
|
||||
input.y:12.3-18: warning: rule useless in parser due to conflicts: cond: cond "then" cond [-Wother]
|
||||
input.y:12.3-18: warning: rule useless in parser due to conflicts [-Wother]
|
||||
]])
|
||||
|
||||
AT_CLEANUP
|
||||
@@ -955,13 +1023,13 @@ AT_CLEANUP
|
||||
# $end reduce using rule 3 (num)
|
||||
# $end [reduce using rule 4 (id)]
|
||||
#
|
||||
# But when `reduce 3' is the default action, we'd produce:
|
||||
# But when 'reduce 3' is the default action, we'd produce:
|
||||
#
|
||||
# $end [reduce using rule 4 (id)]
|
||||
# $default reduce using rule 3 (num)
|
||||
#
|
||||
# In this precise case (a reduction is masked by the default
|
||||
# reduction), we make the `reduce 3' explicit:
|
||||
# reduction), we make the 'reduce 3' explicit:
|
||||
#
|
||||
# $end reduce using rule 3 (num)
|
||||
# $end [reduce using rule 4 (id)]
|
||||
@@ -983,7 +1051,7 @@ id : '0';
|
||||
|
||||
AT_BISON_CHECK([-o input.c --report=all input.y], 0, [],
|
||||
[[input.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
|
||||
input.y:4.6-8: warning: rule useless in parser due to conflicts: id: '0' [-Wother]
|
||||
input.y:4.6-8: warning: rule useless in parser due to conflicts [-Wother]
|
||||
]])
|
||||
|
||||
# Check the contents of the report.
|
||||
@@ -1196,10 +1264,10 @@ e: e '+' e
|
||||
;
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK([-o input.c input.y], 0, [],
|
||||
AT_BISON_CHECK([-Wall -o input.c input.y], 0, [],
|
||||
[[input.y: warning: 4 shift/reduce conflicts [-Wconflicts-sr]
|
||||
input.y:1.7-9: warning: useless associativity for '+' [-Wother]
|
||||
input.y:2.7-9: warning: useless associativity for '*' [-Wother]
|
||||
input.y:1.1-5: warning: useless precedence and associativity for '+' [-Wprecedence]
|
||||
input.y:2.1-5: warning: useless precedence and associativity for '*' [-Wprecedence]
|
||||
]])
|
||||
AT_CLEANUP
|
||||
|
||||
@@ -1303,13 +1371,13 @@ reported_conflicts:
|
||||
AT_BISON_CHECK([[--report=all input.y]], 0, [],
|
||||
[[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
|
||||
input.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
|
||||
input.y:12.5-20: warning: rule useless in parser due to conflicts: resolved_conflict: 'a' unreachable1 [-Wother]
|
||||
input.y:20.5-20: warning: rule useless in parser due to conflicts: unreachable1: 'a' unreachable2 [-Wother]
|
||||
input.y:21.4: warning: rule useless in parser due to conflicts: unreachable1: /* empty */ [-Wother]
|
||||
input.y:25.13: warning: rule useless in parser due to conflicts: unreachable2: /* empty */ [-Wother]
|
||||
input.y:25.16: warning: rule useless in parser due to conflicts: unreachable2: /* empty */ [-Wother]
|
||||
input.y:31.5-7: warning: rule useless in parser due to conflicts: reported_conflicts: 'a' [-Wother]
|
||||
input.y:32.4: warning: rule useless in parser due to conflicts: reported_conflicts: /* empty */ [-Wother]
|
||||
input.y:12.5-20: warning: rule useless in parser due to conflicts [-Wother]
|
||||
input.y:20.5-20: warning: rule useless in parser due to conflicts [-Wother]
|
||||
input.y:21.4: warning: rule useless in parser due to conflicts [-Wother]
|
||||
input.y:25.13: warning: rule useless in parser due to conflicts [-Wother]
|
||||
input.y:25.16: warning: rule useless in parser due to conflicts [-Wother]
|
||||
input.y:31.5-7: warning: rule useless in parser due to conflicts [-Wother]
|
||||
input.y:32.4: warning: rule useless in parser due to conflicts [-Wother]
|
||||
]])
|
||||
|
||||
AT_CHECK([[cat input.output]], 0,
|
||||
@@ -1318,13 +1386,13 @@ AT_CHECK([[cat input.output]], 0,
|
||||
2 resolved_conflict: 'a' unreachable1
|
||||
|
||||
4 unreachable1: 'a' unreachable2
|
||||
5 | /* empty */
|
||||
5 | %empty
|
||||
|
||||
6 unreachable2: /* empty */
|
||||
7 | /* empty */
|
||||
6 unreachable2: %empty
|
||||
7 | %empty
|
||||
|
||||
9 reported_conflicts: 'a'
|
||||
10 | /* empty */
|
||||
10 | %empty
|
||||
|
||||
|
||||
State 4 conflicts: 1 shift/reduce
|
||||
@@ -1338,17 +1406,17 @@ Grammar
|
||||
1 start: resolved_conflict 'a' reported_conflicts 'a'
|
||||
|
||||
2 resolved_conflict: 'a' unreachable1
|
||||
3 | /* empty */
|
||||
3 | %empty
|
||||
|
||||
4 unreachable1: 'a' unreachable2
|
||||
5 | /* empty */
|
||||
5 | %empty
|
||||
|
||||
6 unreachable2: /* empty */
|
||||
7 | /* empty */
|
||||
6 unreachable2: %empty
|
||||
7 | %empty
|
||||
|
||||
8 reported_conflicts: 'a'
|
||||
9 | 'a'
|
||||
10 | /* empty */
|
||||
10 | %empty
|
||||
|
||||
|
||||
Terminals, with rules where they appear
|
||||
@@ -1379,7 +1447,7 @@ State 0
|
||||
0 $accept: . start $end
|
||||
1 start: . resolved_conflict 'a' reported_conflicts 'a'
|
||||
2 resolved_conflict: . 'a' unreachable1
|
||||
3 | . ['a']
|
||||
3 | . %empty ['a']
|
||||
|
||||
$default reduce using rule 3 (resolved_conflict)
|
||||
|
||||
@@ -1415,7 +1483,7 @@ State 4
|
||||
1 start: resolved_conflict 'a' . reported_conflicts 'a'
|
||||
8 reported_conflicts: . 'a'
|
||||
9 | . 'a'
|
||||
10 | . ['a']
|
||||
10 | . %empty ['a']
|
||||
|
||||
'a' shift, and go to state 5
|
||||
|
||||
@@ -1456,10 +1524,10 @@ AT_CHECK([[cat input.y >> input-keep.y]])
|
||||
AT_BISON_CHECK([[input-keep.y]], 0, [],
|
||||
[[input-keep.y: warning: 2 shift/reduce conflicts [-Wconflicts-sr]
|
||||
input-keep.y: warning: 2 reduce/reduce conflicts [-Wconflicts-rr]
|
||||
input-keep.y:22.4: warning: rule useless in parser due to conflicts: unreachable1: /* empty */ [-Wother]
|
||||
input-keep.y:26.16: warning: rule useless in parser due to conflicts: unreachable2: /* empty */ [-Wother]
|
||||
input-keep.y:32.5-7: warning: rule useless in parser due to conflicts: reported_conflicts: 'a' [-Wother]
|
||||
input-keep.y:33.4: warning: rule useless in parser due to conflicts: reported_conflicts: /* empty */ [-Wother]
|
||||
input-keep.y:22.4: warning: rule useless in parser due to conflicts [-Wother]
|
||||
input-keep.y:26.16: warning: rule useless in parser due to conflicts [-Wother]
|
||||
input-keep.y:32.5-7: warning: rule useless in parser due to conflicts [-Wother]
|
||||
input-keep.y:33.4: warning: rule useless in parser due to conflicts [-Wother]
|
||||
]])
|
||||
|
||||
AT_CLEANUP
|
||||
@@ -1508,11 +1576,11 @@ AT_CHECK([[cat input.output | sed -n '/^State 0$/,/^State 1$/p']], 0,
|
||||
6 | . empty_c1 'c'
|
||||
7 | . empty_c2 'c'
|
||||
8 | . empty_c3 'c'
|
||||
9 empty_a: . ['a']
|
||||
10 empty_b: . []
|
||||
11 empty_c1: . []
|
||||
12 empty_c2: . []
|
||||
13 empty_c3: . ['c']
|
||||
9 empty_a: . %empty ['a']
|
||||
10 empty_b: . %empty []
|
||||
11 empty_c1: . %empty []
|
||||
12 empty_c2: . %empty []
|
||||
13 empty_c3: . %empty ['c']
|
||||
|
||||
'b' shift, and go to state 1
|
||||
|
||||
@@ -1584,11 +1652,11 @@ AT_CHECK([[cat input.output | sed -n '/^State 0$/,/^State 1$/p']], 0,
|
||||
6 | . empty_c1 'c'
|
||||
7 | . empty_c2 'c'
|
||||
8 | . empty_c3 'c'
|
||||
9 empty_a: . []
|
||||
10 empty_b: . []
|
||||
11 empty_c1: . []
|
||||
12 empty_c2: . ['c']
|
||||
13 empty_c3: . ['c']
|
||||
9 empty_a: . %empty []
|
||||
10 empty_b: . %empty []
|
||||
11 empty_c1: . %empty []
|
||||
12 empty_c2: . %empty ['c']
|
||||
13 empty_c3: . %empty ['c']
|
||||
|
||||
'a' error (nonassociative)
|
||||
'b' error (nonassociative)
|
||||
@@ -1639,7 +1707,7 @@ exp: 'a' | 'a';
|
||||
AT_BISON_CHECK([[2.y]], [[0]], [],
|
||||
[[2.y: warning: %expect-rr applies only to GLR parsers [-Wother]
|
||||
2.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
|
||||
2.y:3.12-14: warning: rule useless in parser due to conflicts: exp: 'a' [-Wother]
|
||||
2.y:3.12-14: warning: rule useless in parser due to conflicts [-Wother]
|
||||
]])
|
||||
|
||||
AT_CLEANUP
|
||||
|
||||
+7
-7
@@ -94,19 +94,19 @@ prog :
|
||||
|
||||
stmt : expr ';' $2 { $$ = ]$[1; }
|
||||
| decl $3
|
||||
| error ';' { $$ = new_nterm ("<error>", YY_NULL, YY_NULL, YY_NULL); }
|
||||
| error ';' { $$ = new_nterm ("<error>", YY_NULLPTR, YY_NULLPTR, YY_NULLPTR); }
|
||||
| '@' { YYACCEPT; }
|
||||
;
|
||||
|
||||
expr : ID
|
||||
| TYPENAME '(' expr ')'
|
||||
{ $$ = new_nterm ("<cast>(%s,%s)", ]$[3, ]$[1, YY_NULL); }
|
||||
| expr '+' expr { $$ = new_nterm ("+(%s,%s)", ]$[1, ]$[3, YY_NULL); }
|
||||
| expr '=' expr { $$ = new_nterm ("=(%s,%s)", ]$[1, ]$[3, YY_NULL); }
|
||||
{ $$ = new_nterm ("<cast>(%s,%s)", ]$[3, ]$[1, YY_NULLPTR); }
|
||||
| expr '+' expr { $$ = new_nterm ("+(%s,%s)", ]$[1, ]$[3, YY_NULLPTR); }
|
||||
| expr '=' expr { $$ = new_nterm ("=(%s,%s)", ]$[1, ]$[3, YY_NULLPTR); }
|
||||
;
|
||||
|
||||
decl : TYPENAME declarator ';'
|
||||
{ $$ = new_nterm ("<declare>(%s,%s)", ]$[1, ]$[2, YY_NULL); }
|
||||
{ $$ = new_nterm ("<declare>(%s,%s)", ]$[1, ]$[2, YY_NULLPTR); }
|
||||
| TYPENAME declarator '=' expr ';'
|
||||
{ $$ = new_nterm ("<init-declare>(%s,%s,%s)", ]$[1,
|
||||
]$[2, ]$[4); }
|
||||
@@ -195,7 +195,7 @@ main (int argc, char **argv)
|
||||
{
|
||||
colNum += 1;
|
||||
tok = c;
|
||||
yylval = YY_NULL;
|
||||
yylval = YY_NULLPTR;
|
||||
}]AT_LOCATION_IF([[
|
||||
yylloc.last_column = colNum-1;]])[
|
||||
return tok;
|
||||
@@ -287,7 +287,7 @@ m4_bmatch([$2], [stmtMerge],
|
||||
[[static YYSTYPE
|
||||
stmtMerge (YYSTYPE x0, YYSTYPE x1)
|
||||
{
|
||||
return new_nterm ("<OR>(%s,%s)", x0, x1, YY_NULL);
|
||||
return new_nterm ("<OR>(%s,%s)", x0, x1, YY_NULLPTR);
|
||||
}
|
||||
]])
|
||||
)
|
||||
|
||||
+156
-143
@@ -403,68 +403,60 @@ dnl parses it as:
|
||||
dnl
|
||||
dnl getline $!(4*0);
|
||||
dnl
|
||||
dnl That is, they shift `*' immediately and make it part of the getline
|
||||
dnl That is, they shift '*' immediately and make it part of the getline
|
||||
dnl argument.
|
||||
dnl
|
||||
dnl The grammar below using LALR(1) parses it as a syntax error. So does
|
||||
dnl GNU AWK 3.0.6, 3.1.0, and 3.1.1. They reduce the full getline expression
|
||||
dnl before shifting `*' even though `*' is not a valid lookahead.
|
||||
dnl before shifting '*' even though '*' is not a valid lookahead.
|
||||
dnl
|
||||
dnl GNU AWK 3.1.2, 3.1.3, 3.1.4, and 3.1.5 parse it as:
|
||||
dnl
|
||||
dnl (getline $!4)*0;
|
||||
dnl
|
||||
dnl That is, like the other versions of GNU AWK, they reduce the full getline
|
||||
dnl expression before shifting `*'. However, because of a different LHS on the
|
||||
dnl getline rule, `*' actually is a valid lookahead. Solaris /usr/xpg4/bin/awk
|
||||
dnl expression before shifting '*'. However, because of a different LHS on the
|
||||
dnl getline rule, '*' actually is a valid lookahead. Solaris /usr/xpg4/bin/awk
|
||||
dnl and the Open Group awk specification seem to agree:
|
||||
dnl
|
||||
dnl http://www.opengroup.org/pubs/online/7908799/xcu/awk.html
|
||||
dnl
|
||||
dnl /bin/nawk and /bin/awk on Solaris 10 report it as a syntax error, but they
|
||||
dnl don't like even `print $!4;'.
|
||||
dnl don't like even 'print $!4;'.
|
||||
[[LEX_GETLINE, '$', '!', YNUMBER, '*', YNUMBER, ';']],
|
||||
|
||||
dnl BISON-STDERR
|
||||
[AT_COND_CASE([[canonical LR]],
|
||||
[[input.y: warning: 265 shift/reduce conflicts [-Wconflicts-sr]
|
||||
input.y:19.8-16: warning: useless associativity for FUNC_CALL [-Wother]
|
||||
input.y:21.8-14: warning: useless associativity for YNUMBER [-Wother]
|
||||
input.y:21.16-22: warning: useless associativity for YSTRING [-Wother]
|
||||
input.y:22.14-22: warning: useless associativity for APPEND_OP [-Wother]
|
||||
input.y:23.8-15: warning: useless associativity for ASSIGNOP [-Wother]
|
||||
input.y:23.33-41: warning: useless associativity for CONCAT_OP [-Wother]
|
||||
input.y:27.8-18: warning: useless associativity for LEX_GETLINE [-Wother]
|
||||
input.y:28.8-13: warning: useless associativity for LEX_IN [-Wother]
|
||||
input.y:29.23-31: warning: useless associativity for INCREMENT [-Wother]
|
||||
input.y:29.33-41: warning: useless associativity for DECREMENT [-Wother]
|
||||
input.y:30.8-18: warning: useless associativity for LEX_BUILTIN [-Wother]
|
||||
input.y:30.20-29: warning: useless associativity for LEX_LENGTH [-Wother]
|
||||
input.y:40.11-13: warning: useless associativity for ',' [-Wother]
|
||||
input.y:47.8-10: warning: useless associativity for '!' [-Wother]
|
||||
input.y:47.12-16: warning: useless associativity for UNARY [-Wother]
|
||||
input.y:50.7-9: warning: useless associativity for '$' [-Wother]
|
||||
input.y:51.7-9: warning: useless associativity for '(' [-Wother]
|
||||
input.y:51.11-13: warning: useless associativity for ')' [-Wother]]],
|
||||
[[input.y: warning: 65 shift/reduce conflicts [-Wconflicts-sr]
|
||||
input.y:19.8-16: warning: useless associativity for FUNC_CALL [-Wother]
|
||||
input.y:21.8-14: warning: useless associativity for YNUMBER [-Wother]
|
||||
input.y:21.16-22: warning: useless associativity for YSTRING [-Wother]
|
||||
input.y:22.14-22: warning: useless associativity for APPEND_OP [-Wother]
|
||||
input.y:23.8-15: warning: useless associativity for ASSIGNOP [-Wother]
|
||||
input.y:23.33-41: warning: useless associativity for CONCAT_OP [-Wother]
|
||||
input.y:27.8-18: warning: useless associativity for LEX_GETLINE [-Wother]
|
||||
input.y:28.8-13: warning: useless associativity for LEX_IN [-Wother]
|
||||
input.y:29.23-31: warning: useless associativity for INCREMENT [-Wother]
|
||||
input.y:29.33-41: warning: useless associativity for DECREMENT [-Wother]
|
||||
input.y:30.8-18: warning: useless associativity for LEX_BUILTIN [-Wother]
|
||||
input.y:30.20-29: warning: useless associativity for LEX_LENGTH [-Wother]
|
||||
input.y:40.11-13: warning: useless associativity for ',' [-Wother]
|
||||
input.y:47.8-10: warning: useless associativity for '!' [-Wother]
|
||||
input.y:47.12-16: warning: useless associativity for UNARY [-Wother]
|
||||
input.y:50.7-9: warning: useless associativity for '$' [-Wother]
|
||||
input.y:51.7-9: warning: useless associativity for '(' [-Wother]
|
||||
input.y:51.11-13: warning: useless associativity for ')' [-Wother]]])[
|
||||
[[input.y:66.10: warning: empty rule without %empty [-Wempty-rule]
|
||||
input.y:169.8: warning: empty rule without %empty [-Wempty-rule]
|
||||
input.y:174.12: warning: empty rule without %empty [-Wempty-rule]
|
||||
input.y:179.13: warning: empty rule without %empty [-Wempty-rule]
|
||||
input.y:187.15: warning: empty rule without %empty [-Wempty-rule]
|
||||
input.y:201.8: warning: empty rule without %empty [-Wempty-rule]
|
||||
input.y:206.21: warning: empty rule without %empty [-Wempty-rule]
|
||||
input.y:220.20: warning: empty rule without %empty [-Wempty-rule]
|
||||
input.y:299.13: warning: empty rule without %empty [-Wempty-rule]
|
||||
input.y:322.9: warning: empty rule without %empty [-Wempty-rule]
|
||||
]AT_COND_CASE([[canonical LR]],
|
||||
[[input.y: warning: 265 shift/reduce conflicts [-Wconflicts-sr]]],
|
||||
[[input.y: warning: 65 shift/reduce conflicts [-Wconflicts-sr]]])[
|
||||
input.y:39.1-5: warning: useless associativity for FUNC_CALL, use %precedence [-Wprecedence]
|
||||
input.y:44.1-5: warning: useless associativity for YNUMBER, use %precedence [-Wprecedence]
|
||||
input.y:44.1-5: warning: useless associativity for YSTRING, use %precedence [-Wprecedence]
|
||||
input.y:42.1-9: warning: useless precedence and associativity for APPEND_OP [-Wprecedence]
|
||||
input.y:33.1-6: warning: useless associativity for ASSIGNOP, use %precedence [-Wprecedence]
|
||||
input.y:43.1-5: warning: useless associativity for CONCAT_OP, use %precedence [-Wprecedence]
|
||||
input.y:37.1-5: warning: useless precedence and associativity for LEX_GETLINE [-Wprecedence]
|
||||
input.y:38.1-9: warning: useless associativity for LEX_IN, use %precedence [-Wprecedence]
|
||||
input.y:49.1-5: warning: useless associativity for INCREMENT, use %precedence [-Wprecedence]
|
||||
input.y:49.1-5: warning: useless associativity for DECREMENT, use %precedence [-Wprecedence]
|
||||
input.y:39.1-5: warning: useless associativity for LEX_BUILTIN, use %precedence [-Wprecedence]
|
||||
input.y:39.1-5: warning: useless associativity for LEX_LENGTH, use %precedence [-Wprecedence]
|
||||
input.y:40.1-9: warning: useless precedence and associativity for ',' [-Wprecedence]
|
||||
input.y:47.1-6: warning: useless associativity for '!', use %precedence [-Wprecedence]
|
||||
input.y:47.1-6: warning: useless associativity for UNARY, use %precedence [-Wprecedence]
|
||||
input.y:50.1-5: warning: useless associativity for '$', use %precedence [-Wprecedence]
|
||||
input.y:51.1-5: warning: useless associativity for '(', use %precedence [-Wprecedence]
|
||||
input.y:51.1-5: warning: useless precedence and associativity for ')' [-Wprecedence]
|
||||
]],
|
||||
|
||||
dnl LAST-STATE
|
||||
@@ -1403,23 +1395,39 @@ dnl INPUT
|
||||
[[]],
|
||||
|
||||
dnl BISON-STDERR
|
||||
[AT_COND_CASE([[canonical LR]],
|
||||
[[input.y:128.12: warning: empty rule without %empty [-Wempty-rule]
|
||||
input.y:137.10: warning: empty rule without %empty [-Wempty-rule]
|
||||
input.y:142.8: warning: empty rule without %empty [-Wempty-rule]
|
||||
input.y:161.15: warning: empty rule without %empty [-Wempty-rule]
|
||||
input.y:179.17: warning: empty rule without %empty [-Wempty-rule]
|
||||
input.y:205.16: warning: empty rule without %empty [-Wempty-rule]
|
||||
input.y:213.9: warning: empty rule without %empty [-Wempty-rule]
|
||||
input.y:225.6: warning: empty rule without %empty [-Wempty-rule]
|
||||
input.y:292.18: warning: empty rule without %empty [-Wempty-rule]
|
||||
input.y:294.19: warning: empty rule without %empty [-Wempty-rule]
|
||||
input.y:367.16: warning: empty rule without %empty [-Wempty-rule]
|
||||
input.y:373.11: warning: empty rule without %empty [-Wempty-rule]
|
||||
input.y:387.15: warning: empty rule without %empty [-Wempty-rule]
|
||||
input.y:401.18: warning: empty rule without %empty [-Wempty-rule]
|
||||
input.y:413.15: warning: empty rule without %empty [-Wempty-rule]
|
||||
input.y:443.15: warning: empty rule without %empty [-Wempty-rule]
|
||||
input.y:471.15: warning: empty rule without %empty [-Wempty-rule]
|
||||
input.y:474.15: warning: empty rule without %empty [-Wempty-rule]
|
||||
input.y:489.15: warning: empty rule without %empty [-Wempty-rule]
|
||||
input.y:506.14: warning: empty rule without %empty [-Wempty-rule]
|
||||
input.y:587.9: warning: empty rule without %empty [-Wempty-rule]
|
||||
input.y:591.14: warning: empty rule without %empty [-Wempty-rule]
|
||||
]AT_COND_CASE([[canonical LR]],
|
||||
[[input.y: warning: 1876 shift/reduce conflicts [-Wconflicts-sr]
|
||||
input.y: warning: 144 reduce/reduce conflicts [-Wconflicts-rr]
|
||||
input.y:32.9-12: warning: useless associativity for HQUA [-Wother]
|
||||
input.y:53.8-14: warning: useless associativity for HASSIGN [-Wother]
|
||||
input.y:54.9-15: warning: useless associativity for HORELSE [-Wother]
|
||||
input.y:55.9-16: warning: useless associativity for HANDTHEN [-Wother]
|
||||
input.y:61.9-12: warning: useless associativity for HNOT [-Wother]
|
||||
input.y:68.7-11: warning: useless associativity for UNEAR [-Wother]]],
|
||||
input.y: warning: 144 reduce/reduce conflicts [-Wconflicts-rr]]],
|
||||
[[input.y: warning: 78 shift/reduce conflicts [-Wconflicts-sr]
|
||||
input.y: warning: 10 reduce/reduce conflicts [-Wconflicts-rr]
|
||||
input.y:32.9-12: warning: useless associativity for HQUA [-Wother]
|
||||
input.y:53.8-14: warning: useless associativity for HASSIGN [-Wother]
|
||||
input.y:54.9-15: warning: useless associativity for HORELSE [-Wother]
|
||||
input.y:55.9-16: warning: useless associativity for HANDTHEN [-Wother]
|
||||
input.y:61.9-12: warning: useless associativity for HNOT [-Wother]
|
||||
input.y:68.7-11: warning: useless associativity for UNEAR [-Wother]]])[
|
||||
input.y: warning: 10 reduce/reduce conflicts [-Wconflicts-rr]]])[
|
||||
input.y:72.1-5: warning: useless associativity for HQUA, use %precedence [-Wprecedence]
|
||||
input.y:53.1-6: warning: useless associativity for HASSIGN, use %precedence [-Wprecedence]
|
||||
input.y:54.1-5: warning: useless associativity for HORELSE, use %precedence [-Wprecedence]
|
||||
input.y:55.1-5: warning: useless associativity for HANDTHEN, use %precedence [-Wprecedence]
|
||||
input.y:61.1-5: warning: useless associativity for HNOT, use %precedence [-Wprecedence]
|
||||
input.y:68.1-5: warning: useless associativity for UNEAR, use %precedence [-Wprecedence]
|
||||
]],
|
||||
|
||||
dnl LAST-STATE
|
||||
@@ -1585,7 +1593,7 @@ box "foo" above ljust == box ("foo" above ljust)
|
||||
|
||||
%left LEFT RIGHT
|
||||
/* Give attributes that take an optional expression a higher
|
||||
precedence than left and right, so that eg `line chop left'
|
||||
precedence than left and right, so that eg 'line chop left'
|
||||
parses properly. */
|
||||
%left CHOP SOLID DASHED DOTTED UP DOWN FILL COLORED OUTLINED
|
||||
%left LABEL
|
||||
@@ -1598,7 +1606,7 @@ parses properly. */
|
||||
/* these need to be lower than '-' */
|
||||
%left HEIGHT RADIUS WIDTH DIAMETER FROM TO AT THICKNESS
|
||||
|
||||
/* these must have higher precedence than CHOP so that `label %prec CHOP'
|
||||
/* these must have higher precedence than CHOP so that 'label %prec CHOP'
|
||||
works */
|
||||
%left DOT_N DOT_E DOT_W DOT_S DOT_NE DOT_SE DOT_NW DOT_SW DOT_C
|
||||
%left DOT_START DOT_END TOP BOTTOM LEFT_CORNER RIGHT_CORNER
|
||||
@@ -2001,88 +2009,93 @@ dnl without being followed by "of".)
|
||||
[[VARIABLE, '=', LABEL, LEFT, DOT_X]],
|
||||
|
||||
dnl BISON-STDERR
|
||||
[[input.y:471.11-48: warning: rule useless in parser due to conflicts: path: ORDINAL LAST object_type relative_path [-Wother]
|
||||
input.y:19.8-12: warning: useless associativity for LABEL [-Wother]
|
||||
input.y:20.8-15: warning: useless associativity for VARIABLE [-Wother]
|
||||
input.y:21.8-13: warning: useless associativity for NUMBER [-Wother]
|
||||
input.y:22.8-11: warning: useless associativity for TEXT [-Wother]
|
||||
input.y:25.8-14: warning: useless associativity for ORDINAL [-Wother]
|
||||
input.y:30.8-11: warning: useless associativity for LAST [-Wother]
|
||||
input.y:31.8-9: warning: useless associativity for UP [-Wother]
|
||||
input.y:32.8-11: warning: useless associativity for DOWN [-Wother]
|
||||
input.y:35.8-10: warning: useless associativity for BOX [-Wother]
|
||||
input.y:36.8-13: warning: useless associativity for CIRCLE [-Wother]
|
||||
input.y:37.8-14: warning: useless associativity for ELLIPSE [-Wother]
|
||||
input.y:38.8-10: warning: useless associativity for ARC [-Wother]
|
||||
input.y:39.8-11: warning: useless associativity for LINE [-Wother]
|
||||
input.y:40.8-12: warning: useless associativity for ARROW [-Wother]
|
||||
input.y:42.8-13: warning: useless associativity for SPLINE [-Wother]
|
||||
input.y:43.8-13: warning: useless associativity for HEIGHT [-Wother]
|
||||
input.y:44.8-13: warning: useless associativity for RADIUS [-Wother]
|
||||
input.y:45.8-12: warning: useless associativity for WIDTH [-Wother]
|
||||
input.y:46.8-15: warning: useless associativity for DIAMETER [-Wother]
|
||||
input.y:47.8-11: warning: useless associativity for FROM [-Wother]
|
||||
input.y:48.8-9: warning: useless associativity for TO [-Wother]
|
||||
input.y:49.8-9: warning: useless associativity for AT [-Wother]
|
||||
input.y:53.8-12: warning: useless associativity for SOLID [-Wother]
|
||||
input.y:54.8-13: warning: useless associativity for DOTTED [-Wother]
|
||||
input.y:55.8-13: warning: useless associativity for DASHED [-Wother]
|
||||
input.y:56.8-11: warning: useless associativity for CHOP [-Wother]
|
||||
input.y:59.8-12: warning: useless associativity for LJUST [-Wother]
|
||||
input.y:60.8-12: warning: useless associativity for RJUST [-Wother]
|
||||
input.y:61.8-12: warning: useless associativity for ABOVE [-Wother]
|
||||
input.y:62.8-12: warning: useless associativity for BELOW [-Wother]
|
||||
input.y:63.8-9: warning: useless associativity for OF [-Wother]
|
||||
input.y:66.8-14: warning: useless associativity for BETWEEN [-Wother]
|
||||
input.y:67.8-10: warning: useless associativity for AND [-Wother]
|
||||
input.y:68.8-11: warning: useless associativity for HERE [-Wother]
|
||||
input.y:69.8-12: warning: useless associativity for DOT_N [-Wother]
|
||||
input.y:70.8-12: warning: useless associativity for DOT_E [-Wother]
|
||||
input.y:71.8-12: warning: useless associativity for DOT_W [-Wother]
|
||||
input.y:72.8-12: warning: useless associativity for DOT_S [-Wother]
|
||||
input.y:73.8-13: warning: useless associativity for DOT_NE [-Wother]
|
||||
input.y:74.8-13: warning: useless associativity for DOT_SE [-Wother]
|
||||
input.y:75.8-13: warning: useless associativity for DOT_NW [-Wother]
|
||||
input.y:76.8-13: warning: useless associativity for DOT_SW [-Wother]
|
||||
input.y:77.8-12: warning: useless associativity for DOT_C [-Wother]
|
||||
input.y:78.8-16: warning: useless associativity for DOT_START [-Wother]
|
||||
input.y:79.8-14: warning: useless associativity for DOT_END [-Wother]
|
||||
input.y:85.8-10: warning: useless associativity for SIN [-Wother]
|
||||
input.y:86.8-10: warning: useless associativity for COS [-Wother]
|
||||
input.y:87.8-12: warning: useless associativity for ATAN2 [-Wother]
|
||||
input.y:88.8-10: warning: useless associativity for LOG [-Wother]
|
||||
input.y:89.8-10: warning: useless associativity for EXP [-Wother]
|
||||
input.y:90.8-11: warning: useless associativity for SQRT [-Wother]
|
||||
input.y:91.8-12: warning: useless associativity for K_MAX [-Wother]
|
||||
input.y:92.8-12: warning: useless associativity for K_MIN [-Wother]
|
||||
input.y:93.8-10: warning: useless associativity for INT [-Wother]
|
||||
input.y:94.8-11: warning: useless associativity for RAND [-Wother]
|
||||
input.y:95.8-12: warning: useless associativity for SRAND [-Wother]
|
||||
input.y:98.8-10: warning: useless associativity for TOP [-Wother]
|
||||
input.y:99.8-13: warning: useless associativity for BOTTOM [-Wother]
|
||||
input.y:100.8-12: warning: useless associativity for UPPER [-Wother]
|
||||
input.y:101.8-12: warning: useless associativity for LOWER [-Wother]
|
||||
input.y:116.8-18: warning: useless associativity for LEFT_CORNER [-Wother]
|
||||
input.y:117.8-19: warning: useless associativity for RIGHT_CORNER [-Wother]
|
||||
input.y:118.8-12: warning: useless associativity for NORTH [-Wother]
|
||||
input.y:119.8-12: warning: useless associativity for SOUTH [-Wother]
|
||||
input.y:120.8-11: warning: useless associativity for EAST [-Wother]
|
||||
input.y:121.8-11: warning: useless associativity for WEST [-Wother]
|
||||
input.y:122.8-13: warning: useless associativity for CENTER [-Wother]
|
||||
input.y:123.8-10: warning: useless associativity for END [-Wother]
|
||||
input.y:124.8-12: warning: useless associativity for START [-Wother]
|
||||
input.y:127.8-11: warning: useless associativity for PLOT [-Wother]
|
||||
input.y:128.8-16: warning: useless associativity for THICKNESS [-Wother]
|
||||
input.y:129.8-11: warning: useless associativity for FILL [-Wother]
|
||||
input.y:130.8-14: warning: useless associativity for COLORED [-Wother]
|
||||
input.y:131.8-15: warning: useless associativity for OUTLINED [-Wother]
|
||||
input.y:134.8-14: warning: useless associativity for SPRINTF [-Wother]
|
||||
input.y:137.7-9: warning: useless associativity for '.' [-Wother]
|
||||
input.y:156.23-25: warning: useless associativity for '(' [-Wother]
|
||||
input.y:157.20-22: warning: useless associativity for '`' [-Wother]
|
||||
input.y:159.48-50: warning: useless associativity for '@<:@' [-Wother]
|
||||
input.y:170.7-9: warning: useless associativity for ',' [-Wother]
|
||||
input.y:181.8-10: warning: useless associativity for '!' [-Wother]
|
||||
[[input.y:202.19: warning: empty rule without %empty [-Wempty-rule]
|
||||
input.y:270.6: warning: empty rule without %empty [-Wempty-rule]
|
||||
input.y:292.12: warning: empty rule without %empty [-Wempty-rule]
|
||||
input.y:309.17: warning: empty rule without %empty [-Wempty-rule]
|
||||
input.y:382.13: warning: empty rule without %empty [-Wempty-rule]
|
||||
input.y:471.11-48: warning: rule useless in parser due to conflicts [-Wother]
|
||||
input.y:154.1-5: warning: useless associativity for LABEL, use %precedence [-Wprecedence]
|
||||
input.y:156.1-5: warning: useless associativity for VARIABLE, use %precedence [-Wprecedence]
|
||||
input.y:156.1-5: warning: useless associativity for NUMBER, use %precedence [-Wprecedence]
|
||||
input.y:141.1-5: warning: useless associativity for TEXT, use %precedence [-Wprecedence]
|
||||
input.y:157.1-5: warning: useless associativity for ORDINAL, use %precedence [-Wprecedence]
|
||||
input.y:156.1-5: warning: useless associativity for LAST, use %precedence [-Wprecedence]
|
||||
input.y:153.1-5: warning: useless associativity for UP, use %precedence [-Wprecedence]
|
||||
input.y:153.1-5: warning: useless associativity for DOWN, use %precedence [-Wprecedence]
|
||||
input.y:159.1-5: warning: useless associativity for BOX, use %precedence [-Wprecedence]
|
||||
input.y:159.1-5: warning: useless associativity for CIRCLE, use %precedence [-Wprecedence]
|
||||
input.y:159.1-5: warning: useless associativity for ELLIPSE, use %precedence [-Wprecedence]
|
||||
input.y:159.1-5: warning: useless associativity for ARC, use %precedence [-Wprecedence]
|
||||
input.y:159.1-5: warning: useless associativity for LINE, use %precedence [-Wprecedence]
|
||||
input.y:159.1-5: warning: useless associativity for ARROW, use %precedence [-Wprecedence]
|
||||
input.y:159.1-5: warning: useless associativity for SPLINE, use %precedence [-Wprecedence]
|
||||
input.y:162.1-5: warning: useless associativity for HEIGHT, use %precedence [-Wprecedence]
|
||||
input.y:162.1-5: warning: useless associativity for RADIUS, use %precedence [-Wprecedence]
|
||||
input.y:162.1-5: warning: useless associativity for WIDTH, use %precedence [-Wprecedence]
|
||||
input.y:162.1-5: warning: useless associativity for DIAMETER, use %precedence [-Wprecedence]
|
||||
input.y:162.1-5: warning: useless associativity for FROM, use %precedence [-Wprecedence]
|
||||
input.y:162.1-5: warning: useless associativity for TO, use %precedence [-Wprecedence]
|
||||
input.y:162.1-5: warning: useless associativity for AT, use %precedence [-Wprecedence]
|
||||
input.y:153.1-5: warning: useless precedence and associativity for SOLID [-Wprecedence]
|
||||
input.y:153.1-5: warning: useless associativity for DOTTED, use %precedence [-Wprecedence]
|
||||
input.y:153.1-5: warning: useless associativity for DASHED, use %precedence [-Wprecedence]
|
||||
input.y:153.1-5: warning: useless associativity for CHOP, use %precedence [-Wprecedence]
|
||||
input.y:147.1-5: warning: useless precedence and associativity for LJUST [-Wprecedence]
|
||||
input.y:147.1-5: warning: useless precedence and associativity for RJUST [-Wprecedence]
|
||||
input.y:147.1-5: warning: useless precedence and associativity for ABOVE [-Wprecedence]
|
||||
input.y:147.1-5: warning: useless precedence and associativity for BELOW [-Wprecedence]
|
||||
input.y:176.1-5: warning: useless associativity for OF, use %precedence [-Wprecedence]
|
||||
input.y:176.1-5: warning: useless associativity for BETWEEN, use %precedence [-Wprecedence]
|
||||
input.y:177.1-5: warning: useless associativity for AND, use %precedence [-Wprecedence]
|
||||
input.y:157.1-5: warning: useless associativity for HERE, use %precedence [-Wprecedence]
|
||||
input.y:166.1-5: warning: useless associativity for DOT_N, use %precedence [-Wprecedence]
|
||||
input.y:166.1-5: warning: useless associativity for DOT_E, use %precedence [-Wprecedence]
|
||||
input.y:166.1-5: warning: useless associativity for DOT_W, use %precedence [-Wprecedence]
|
||||
input.y:166.1-5: warning: useless associativity for DOT_S, use %precedence [-Wprecedence]
|
||||
input.y:166.1-5: warning: useless associativity for DOT_NE, use %precedence [-Wprecedence]
|
||||
input.y:166.1-5: warning: useless associativity for DOT_SE, use %precedence [-Wprecedence]
|
||||
input.y:166.1-5: warning: useless associativity for DOT_NW, use %precedence [-Wprecedence]
|
||||
input.y:166.1-5: warning: useless associativity for DOT_SW, use %precedence [-Wprecedence]
|
||||
input.y:166.1-5: warning: useless associativity for DOT_C, use %precedence [-Wprecedence]
|
||||
input.y:167.1-5: warning: useless associativity for DOT_START, use %precedence [-Wprecedence]
|
||||
input.y:167.1-5: warning: useless associativity for DOT_END, use %precedence [-Wprecedence]
|
||||
input.y:156.1-5: warning: useless associativity for SIN, use %precedence [-Wprecedence]
|
||||
input.y:156.1-5: warning: useless associativity for COS, use %precedence [-Wprecedence]
|
||||
input.y:156.1-5: warning: useless associativity for ATAN2, use %precedence [-Wprecedence]
|
||||
input.y:156.1-5: warning: useless associativity for LOG, use %precedence [-Wprecedence]
|
||||
input.y:156.1-5: warning: useless associativity for EXP, use %precedence [-Wprecedence]
|
||||
input.y:156.1-5: warning: useless associativity for SQRT, use %precedence [-Wprecedence]
|
||||
input.y:156.1-5: warning: useless associativity for K_MAX, use %precedence [-Wprecedence]
|
||||
input.y:156.1-5: warning: useless associativity for K_MIN, use %precedence [-Wprecedence]
|
||||
input.y:156.1-5: warning: useless associativity for INT, use %precedence [-Wprecedence]
|
||||
input.y:156.1-5: warning: useless associativity for RAND, use %precedence [-Wprecedence]
|
||||
input.y:156.1-5: warning: useless associativity for SRAND, use %precedence [-Wprecedence]
|
||||
input.y:167.1-5: warning: useless associativity for TOP, use %precedence [-Wprecedence]
|
||||
input.y:167.1-5: warning: useless associativity for BOTTOM, use %precedence [-Wprecedence]
|
||||
input.y:168.1-5: warning: useless associativity for UPPER, use %precedence [-Wprecedence]
|
||||
input.y:168.1-5: warning: useless associativity for LOWER, use %precedence [-Wprecedence]
|
||||
input.y:167.1-5: warning: useless associativity for LEFT_CORNER, use %precedence [-Wprecedence]
|
||||
input.y:167.1-5: warning: useless associativity for RIGHT_CORNER, use %precedence [-Wprecedence]
|
||||
input.y:168.1-5: warning: useless associativity for NORTH, use %precedence [-Wprecedence]
|
||||
input.y:168.1-5: warning: useless associativity for SOUTH, use %precedence [-Wprecedence]
|
||||
input.y:168.1-5: warning: useless associativity for EAST, use %precedence [-Wprecedence]
|
||||
input.y:168.1-5: warning: useless associativity for WEST, use %precedence [-Wprecedence]
|
||||
input.y:168.1-5: warning: useless associativity for CENTER, use %precedence [-Wprecedence]
|
||||
input.y:168.1-5: warning: useless associativity for END, use %precedence [-Wprecedence]
|
||||
input.y:168.1-5: warning: useless associativity for START, use %precedence [-Wprecedence]
|
||||
input.y:140.1-5: warning: useless associativity for PLOT, use %precedence [-Wprecedence]
|
||||
input.y:162.1-5: warning: useless associativity for THICKNESS, use %precedence [-Wprecedence]
|
||||
input.y:153.1-5: warning: useless associativity for FILL, use %precedence [-Wprecedence]
|
||||
input.y:153.1-5: warning: useless precedence and associativity for COLORED [-Wprecedence]
|
||||
input.y:153.1-5: warning: useless precedence and associativity for OUTLINED [-Wprecedence]
|
||||
input.y:141.1-5: warning: useless associativity for SPRINTF, use %precedence [-Wprecedence]
|
||||
input.y:137.1-5: warning: useless associativity for '.', use %precedence [-Wprecedence]
|
||||
input.y:156.1-5: warning: useless associativity for '(', use %precedence [-Wprecedence]
|
||||
input.y:157.1-5: warning: useless associativity for '`', use %precedence [-Wprecedence]
|
||||
input.y:159.1-5: warning: useless associativity for '@<:@', use %precedence [-Wprecedence]
|
||||
input.y:170.1-5: warning: useless associativity for ',', use %precedence [-Wprecedence]
|
||||
input.y:181.1-6: warning: useless associativity for '!', use %precedence [-Wprecedence]
|
||||
]],
|
||||
|
||||
dnl LAST-STATE
|
||||
|
||||
+38
-8
@@ -67,7 +67,7 @@ static YYSTYPE exprMerge (YYSTYPE x0, YYSTYPE x1)
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *input = YY_NULL;
|
||||
const char *input = YY_NULLPTR;
|
||||
|
||||
int
|
||||
main (int argc, const char* argv[])
|
||||
@@ -304,7 +304,7 @@ MergeRule (int x0, int x1)
|
||||
}
|
||||
]AT_YYERROR_DEFINE[
|
||||
|
||||
FILE *input = YY_NULL;
|
||||
FILE *input = YY_NULLPTR;
|
||||
|
||||
int P[] = { P1, P2 };
|
||||
int O[] = { O1, O2 };
|
||||
@@ -486,8 +486,8 @@ start:
|
||||
;
|
||||
|
||||
%%
|
||||
]AT_YYLEX_DEFINE(["a"])[
|
||||
]AT_YYERROR_DEFINE[
|
||||
]AT_YYLEX_DEFINE(["a"])[
|
||||
]AT_MAIN_DEFINE[
|
||||
]])
|
||||
AT_BISON_OPTION_POPDEFS
|
||||
@@ -1015,17 +1015,17 @@ main (void)
|
||||
int exit_status = yyparse ();
|
||||
if (parent_rhs_before_value)
|
||||
{
|
||||
fprintf (stderr, "`parent_rhs_before' destructor not called.\n");
|
||||
fprintf (stderr, "'parent_rhs_before' destructor not called.\n");
|
||||
exit_status = 1;
|
||||
}
|
||||
if (merged_value)
|
||||
{
|
||||
fprintf (stderr, "`merged' destructor not called.\n");
|
||||
fprintf (stderr, "'merged' destructor not called.\n");
|
||||
exit_status = 1;
|
||||
}
|
||||
if (parent_rhs_after_value)
|
||||
{
|
||||
fprintf (stderr, "`PARENT_RHS_AFTER' destructor not called.\n");
|
||||
fprintf (stderr, "'PARENT_RHS_AFTER' destructor not called.\n");
|
||||
exit_status = 1;
|
||||
}
|
||||
return exit_status;
|
||||
@@ -1449,7 +1449,7 @@ main (void)
|
||||
int exit_status = yyparse () != 1;
|
||||
if (parent_rhs_before_value)
|
||||
{
|
||||
fprintf (stderr, "`parent_rhs_before' destructor not called.\n");
|
||||
fprintf (stderr, "'parent_rhs_before' destructor not called.\n");
|
||||
exit_status = 1;
|
||||
}
|
||||
return exit_status;
|
||||
@@ -1679,8 +1679,8 @@ start:
|
||||
b: 'b';
|
||||
d: /* nada. */;
|
||||
%%
|
||||
]AT_YYLEX_DEFINE(["abc"])[
|
||||
]AT_YYERROR_DEFINE[
|
||||
]AT_YYLEX_DEFINE(["abc"])[
|
||||
]AT_MAIN_DEFINE[
|
||||
]])
|
||||
AT_BISON_OPTION_POPDEFS
|
||||
@@ -1749,3 +1749,33 @@ Cleanup: popping token 'a' ()
|
||||
])
|
||||
|
||||
AT_CLEANUP
|
||||
|
||||
|
||||
## ----------------------------------------------------------------- ##
|
||||
## Predicates. ##
|
||||
## ##
|
||||
## http://lists.gnu.org/archive/html/bug-bison/2013-10/msg00004.html ##
|
||||
## ----------------------------------------------------------------- ##
|
||||
|
||||
AT_SETUP([Predicates])
|
||||
|
||||
# FIXME: We need genuine test cases with uses of %?.
|
||||
|
||||
AT_DATA_GRAMMAR([input.y],
|
||||
[[%glr-parser
|
||||
%expect-rr 1
|
||||
%%
|
||||
// Exercise "%?{...}" and "%? {...}".
|
||||
widget:
|
||||
%? {new_syntax} "widget" id new_args { $$ = f($3, $4); }
|
||||
| %?{!new_syntax} "widget" id old_args { $$ = f($3, $4); }
|
||||
;
|
||||
id:;
|
||||
new_args:;
|
||||
old_args:;
|
||||
%%
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK([[input.y]])
|
||||
|
||||
AT_CLEANUP
|
||||
|
||||
+8
-4
@@ -117,9 +117,9 @@ AT_SETUP([Several parsers])
|
||||
# nor yy* identifiers in the header. Check that headers are
|
||||
# self-contained, and can be compiled by a C++ compiler.
|
||||
m4_pushdef([AT_TEST],
|
||||
[AT_BISON_OPTION_PUSHDEFS([%define api.prefix "$1_" $2])
|
||||
[AT_BISON_OPTION_PUSHDEFS([%define api.prefix {$1_} $2])
|
||||
AT_DATA_GRAMMAR([$1.y],
|
||||
[[%define api.prefix "$1_"
|
||||
[[%define api.prefix {$1_}
|
||||
$2
|
||||
%error-verbose
|
||||
%union
|
||||
@@ -223,9 +223,13 @@ AT_CHECK([[$PERL -n -0777 -e '
|
||||
s{/\*.*?\*/}{}gs;
|
||||
s{//.*}{}g;
|
||||
s{\b(YYChar
|
||||
|YYPUSH_MORE(_DEFINED)?
|
||||
|YYPUSH_MORE(?:_DEFINED)?
|
||||
|YYUSE
|
||||
|YY_ATTRIBUTE(?:_PURE|_UNUSED)?
|
||||
|YY_IGNORE_MAYBE_UNINITIALIZED_(?:BEGIN|END)
|
||||
|YY_INITIAL_VALUE
|
||||
|YY_\w+_INCLUDED
|
||||
|YY_NULL
|
||||
|YY_NULLPTR
|
||||
|(defined|if)\ YYDEBUG
|
||||
)\b}{}gx;
|
||||
while (/^(.*YY.*)$/gm)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user