mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-08-08 18:25:13 +00:00
Compare commits
138
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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 |
+1
-1
@@ -1 +1 @@
|
||||
2.7
|
||||
2.7.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,9 @@
|
||||
GNU Bison NEWS
|
||||
|
||||
* Noteworthy changes in release ?.? (????-??-??) [?]
|
||||
* Noteworthy changes in release 2.7.90 (2013-05-30) [beta]
|
||||
|
||||
** 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 +20,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 +54,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 +62,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 +75,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 +238,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,6 +258,262 @@ GNU Bison NEWS
|
||||
|
||||
%param {arg1_type *arg1} {arg2_type *arg2}
|
||||
|
||||
** Types of values for %define variables
|
||||
|
||||
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
|
||||
|
||||
Contributed by Paolo Bonzini.
|
||||
@@ -249,59 +543,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 +654,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 +742,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 +2658,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
|
||||
|
||||
+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.
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@ Cris Bailiff [email protected]
|
||||
Cris van Pelt [email protected]
|
||||
Csaba Raduly [email protected]
|
||||
Dagobert Michelsen [email protected]
|
||||
Daniel Frużyński [email protected]
|
||||
Daniel Hagerty [email protected]
|
||||
David J. MacKenzie [email protected]
|
||||
David Kastrup [email protected]
|
||||
@@ -37,6 +38,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 +46,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]
|
||||
@@ -97,6 +100,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]
|
||||
@@ -106,6 +110,7 @@ Ralf Wildenhues [email protected]
|
||||
Richard Stallman [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 +131,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-05-08.20; # 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
|
||||
}
|
||||
'
|
||||
@@ -306,34 +307,34 @@ if test -n "$checkout_only_file" && test ! -r "$checkout_only_file"; then
|
||||
die "Bootstrapping from a non-checked-out distribution is risky."
|
||||
fi
|
||||
|
||||
# Ensure that lines starting with ! sort last, per gitignore conventions
|
||||
# for whitelisting exceptions after a more generic blacklist pattern.
|
||||
sort_patterns() {
|
||||
sort -u "$@" | sed '/^!/ {
|
||||
H
|
||||
d
|
||||
}
|
||||
$ {
|
||||
P
|
||||
x
|
||||
s/^\n//
|
||||
}' | sed '/^$/d'
|
||||
# Strip blank and comment lines to leave significant entries.
|
||||
gitignore_entries() {
|
||||
sed '/^#/d; /^$/d' "$@"
|
||||
}
|
||||
|
||||
# If $STR is not already on a line by itself in $FILE, insert it,
|
||||
# sorting the new contents of the file and replacing $FILE with the result.
|
||||
insert_sorted_if_absent() {
|
||||
# If $STR is not already on a line by itself in $FILE, insert it at the start.
|
||||
# Entries are inserted at the start of the ignore list to ensure existing
|
||||
# entries starting with ! are not overridden. Such entries support
|
||||
# whitelisting exceptions after a more generic blacklist pattern.
|
||||
insert_if_absent() {
|
||||
file=$1
|
||||
str=$2
|
||||
test -f $file || touch $file
|
||||
echo "$str" | sort_patterns - $file | cmp -s - $file > /dev/null \
|
||||
|| { echo "$str" | sort_patterns - $file > $file.bak \
|
||||
&& mv $file.bak $file; } \
|
||||
|| die "insert_sorted_if_absent $file $str: failed"
|
||||
test -r $file || die "Error: failed to read ignore file: $file"
|
||||
duplicate_entries=$(gitignore_entries $file | sort | uniq -d)
|
||||
if [ "$duplicate_entries" ] ; then
|
||||
die "Error: Duplicate entries in $file: " $duplicate_entries
|
||||
fi
|
||||
linesold=$(gitignore_entries $file | wc -l)
|
||||
linesnew=$(echo "$str" | gitignore_entries - $file | sort -u | wc -l)
|
||||
if [ $linesold != $linesnew ] ; then
|
||||
{ echo "$str" | cat - $file > $file.bak && mv $file.bak $file; } \
|
||||
|| die "insert_if_absent $file $str: failed"
|
||||
fi
|
||||
}
|
||||
|
||||
# Adjust $PATTERN for $VC_IGNORE_FILE and insert it with
|
||||
# insert_sorted_if_absent.
|
||||
# insert_if_absent.
|
||||
insert_vc_ignore() {
|
||||
vc_ignore_file="$1"
|
||||
pattern="$2"
|
||||
@@ -344,7 +345,7 @@ insert_vc_ignore() {
|
||||
# .gitignore entry.
|
||||
pattern=$(echo "$pattern" | sed s,^,/,);;
|
||||
esac
|
||||
insert_sorted_if_absent "$vc_ignore_file" "$pattern"
|
||||
insert_if_absent "$vc_ignore_file" "$pattern"
|
||||
}
|
||||
|
||||
# Die if there is no AC_CONFIG_AUX_DIR($build_aux) line in configure.ac.
|
||||
@@ -630,9 +631,13 @@ esac
|
||||
if $bootstrap_sync; then
|
||||
cmp -s "$0" "$GNULIB_SRCDIR/build-aux/bootstrap" || {
|
||||
echo "$0: updating bootstrap and restarting..."
|
||||
case $(sh -c 'echo "$1"' -- a) in
|
||||
a) ignored=--;;
|
||||
*) ignored=ignored;;
|
||||
esac
|
||||
exec sh -c \
|
||||
'cp "$1" "$2" && shift && exec "${CONFIG_SHELL-/bin/sh}" "$@"' \
|
||||
-- "$GNULIB_SRCDIR/build-aux/bootstrap" \
|
||||
$ignored "$GNULIB_SRCDIR/build-aux/bootstrap" \
|
||||
"$0" "$@" --no-bootstrap-sync
|
||||
}
|
||||
fi
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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$$) \
|
||||
)
|
||||
|
||||
+8
-6
@@ -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]])
|
||||
@@ -91,7 +91,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 +143,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
|
||||
@@ -220,7 +222,7 @@ AC_SUBST([aclocaldir])
|
||||
AC_CONFIG_FILES([etc/bench.pl], [chmod +x etc/bench.pl])
|
||||
|
||||
# Initialize the test suite.
|
||||
AC_CONFIG_TESTDIR([tests], [$ac_abs_top_builddir/tests])
|
||||
AC_CONFIG_TESTDIR(tests)
|
||||
AC_CONFIG_FILES([tests/atlocal])
|
||||
AC_CONFIG_FILES([tests/bison], [chmod +x tests/bison])
|
||||
AC_CHECK_PROGS([VALGRIND], [valgrind])
|
||||
|
||||
+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,31 @@ m4_define([b4_table_value_equals],
|
||||
[(!!(($2) == ($3)))])])
|
||||
|
||||
|
||||
## ----------------- ##
|
||||
## Compiler issues. ##
|
||||
## ----------------- ##
|
||||
|
||||
# b4_attribute_define
|
||||
# -------------------
|
||||
# Provide portability for __attribute__.
|
||||
m4_define([b4_attribute_define],
|
||||
[#ifndef __attribute__
|
||||
/* This feature is available in gcc versions 2.5 and later. */
|
||||
# if (! defined __GNUC__ || __GNUC__ < 2 \
|
||||
|| (__GNUC__ == 2 && __GNUC_MINOR__ < 5))
|
||||
# define __attribute__(Spec) /* empty */
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Suppress unused-variable warnings by "using" E. */
|
||||
#if ! defined lint || defined __GNUC__
|
||||
# define YYUSE(E) ((void) (E))
|
||||
#else
|
||||
# define YYUSE(E) /* empty */
|
||||
#endif
|
||||
])
|
||||
|
||||
|
||||
## ---------##
|
||||
## Values. ##
|
||||
## ---------##
|
||||
@@ -421,12 +446,7 @@ 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;
|
||||
}
|
||||
]b4_symbol_actions([destructor])[
|
||||
}]dnl
|
||||
])
|
||||
|
||||
@@ -459,12 +479,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 +507,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 +690,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],
|
||||
|
||||
+1
-18
@@ -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)))
|
||||
|
||||
+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. ##
|
||||
## ---------------- ##
|
||||
|
||||
+14
-18
@@ -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])
|
||||
# --------------------
|
||||
@@ -201,6 +204,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;
|
||||
|
||||
@@ -591,13 +598,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 +613,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
|
||||
@@ -737,7 +733,7 @@ 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);
|
||||
yystack_.clear ();
|
||||
yypush_ (YY_NULL, 0, yyla);
|
||||
|
||||
// A new symbol was pushed on the stack.
|
||||
@@ -824,7 +820,7 @@ b4_dollar_popdef])[]dnl
|
||||
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.
|
||||
'$$ = $1'. Otherwise, use the top of the stack.
|
||||
|
||||
Otherwise, the following line sets YYLHS.VALUE to garbage.
|
||||
This behavior is undocumented and Bison
|
||||
|
||||
+1
-1
@@ -375,7 +375,7 @@ b4_lexer_if([[
|
||||
]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
|
||||
|
||||
+43
-24
@@ -25,8 +25,7 @@ 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,
|
||||
unsigned int l = ]b4_location_initial_line[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.
|
||||
@@ -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
-39
@@ -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_NULL)])[
|
||||
{}
|
||||
|
||||
/// 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.
|
||||
@@ -179,10 +179,10 @@ m4_define([b4_variant_define],
|
||||
void
|
||||
move (self_type& other)
|
||||
{]b4_parse_assert_if([
|
||||
YYASSERT (!tname);])[
|
||||
build<T>();
|
||||
swap<T>(other);
|
||||
other.destroy<T>();
|
||||
YYASSERT (!yytname_);])[
|
||||
build<T> ();
|
||||
swap<T> (other);
|
||||
other.destroy<T> ();
|
||||
}
|
||||
|
||||
/// Copy the content of \a other to this.
|
||||
@@ -199,7 +199,7 @@ m4_define([b4_variant_define],
|
||||
destroy ()
|
||||
{
|
||||
as<T> ().~T ();]b4_parse_assert_if([
|
||||
tname = YY_NULL;])[
|
||||
yytname_ = YY_NULL;])[
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -207,17 +207,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 +244,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 +263,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 +271,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])])
|
||||
|
||||
|
||||
@@ -311,7 +328,7 @@ b4_join(b4_symbol_if([$1], [has_type],
|
||||
|
||||
|
||||
# b4_basic_symbol_constructor_declare
|
||||
# ----------------------------------
|
||||
# -----------------------------------
|
||||
# Generate a constructor declaration for basic_symbol from given type.
|
||||
m4_define([b4_basic_symbol_constructor_declare],
|
||||
[[
|
||||
|
||||
@@ -373,7 +373,7 @@
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="empty">
|
||||
<xsl:text> /* empty */</xsl:text>
|
||||
<xsl:text> %empty</xsl:text>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="lookaheads">
|
||||
|
||||
+8
-14
@@ -143,7 +143,6 @@ m4_define([b4_rhs_value],
|
||||
[b4_symbol_value([yyvsp@{b4_subtract([$2], [$1])@}], [$3])])
|
||||
|
||||
|
||||
|
||||
## ----------- ##
|
||||
## Locations. ##
|
||||
## ----------- ##
|
||||
@@ -200,7 +199,7 @@ static YYLTYPE yyloc_default][]b4_yyloc_default[;]])])[
|
||||
#endif
|
||||
|
||||
/* The semantic value of the lookahead symbol. */
|
||||
YYSTYPE yylval YY_INITIAL_VALUE(yyval_default);]b4_locations_if([[
|
||||
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])[;
|
||||
@@ -223,9 +222,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 +430,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 +462,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,
|
||||
@@ -1654,7 +1648,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 +1696,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. */
|
||||
|
||||
|
||||
+633
-301
File diff suppressed because it is too large
Load Diff
+1
-1
@@ -37,7 +37,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 $@; } >$@~
|
||||
|
||||
+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;
|
||||
}
|
||||
|
||||
|
||||
+15
-16
@@ -44,32 +44,31 @@ CLEANFILES += \
|
||||
# Avoid using BUILT_SOURCES which is too global.
|
||||
$(examples_calc___calc___OBJECTS): $(calc_sources_generated)
|
||||
|
||||
calc_sources_extracted = \
|
||||
examples/calc++/calc++-driver.cc \
|
||||
examples/calc++/calc++-driver.hh \
|
||||
examples/calc++/calc++-scanner.ll \
|
||||
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) \
|
||||
calc_extracted = \
|
||||
$(calc_sources_extracted) \
|
||||
examples/calc++/calc++-parser.yy
|
||||
extracted += $(calc_extracted)
|
||||
calc_sources_generated = \
|
||||
examples/calc++/calc++-parser.cc \
|
||||
examples/calc++/calc++-parser.hh \
|
||||
examples/calc++/location.hh \
|
||||
examples/calc++/position.hh \
|
||||
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 = \
|
||||
$(calc_sources_extracted) \
|
||||
$(calc_sources_generated)
|
||||
|
||||
if BISON_CXX_WORKS
|
||||
check_PROGRAMS += examples/calc++/calc++
|
||||
nodist_examples_calc___calc___SOURCES = \
|
||||
nodist_examples_calc___calc___SOURCES = \
|
||||
$(calc_sources)
|
||||
|
||||
examples_calc___calc___CPPFLAGS = -I$(top_builddir)/examples/calc++
|
||||
examples_calc___calc___CXXFLAGS = \
|
||||
$(AM_CXXFLAGS) $(WARN_NO_NULL_CONVERSION_CXXFLAGS)
|
||||
examples_calc___calc___CXXFLAGS = $(AM_CXXFLAGS) $(FLEX_SCANNER_CXXFLAGS)
|
||||
dist_TESTS += examples/calc++/calc++.test
|
||||
endif
|
||||
|
||||
@@ -17,7 +17,6 @@ dist_noinst_SCRIPTS = examples/extexi examples/test
|
||||
TEST_LOG_COMPILER = $(top_srcdir)/examples/test
|
||||
|
||||
AM_CXXFLAGS = \
|
||||
$(NO_STRICT_ALIAS_CXXFLAGS) \
|
||||
$(WARN_CXXFLAGS) $(WARN_CXXFLAGS_TEST) $(WERROR_CXXFLAGS)
|
||||
|
||||
## ------------ ##
|
||||
|
||||
+1
-1
Submodule gnulib updated: c67e3c0414...e28fbd787c
+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_
|
||||
|
||||
+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
|
||||
|
||||
+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)) \
|
||||
|
||||
+219
-46
@@ -22,6 +22,7 @@
|
||||
#include <config.h>
|
||||
#include "system.h"
|
||||
|
||||
#include <argmatch.h>
|
||||
#include <stdarg.h>
|
||||
#include <progname.h>
|
||||
|
||||
@@ -30,42 +31,199 @@
|
||||
#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;
|
||||
|
||||
/** Diagnostics severity. */
|
||||
typedef enum
|
||||
{
|
||||
severity_disabled = 0,
|
||||
severity_unset = 1,
|
||||
severity_warning = 2,
|
||||
severity_error = 3,
|
||||
severity_fatal = 4
|
||||
} 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;
|
||||
}
|
||||
|
||||
if (no)
|
||||
{
|
||||
size_t b;
|
||||
for (b = 0; b < warnings_size; ++b)
|
||||
if (value & 1 << b)
|
||||
{
|
||||
if (err)
|
||||
{
|
||||
/* -Wno-error=foo: if foo enabled as an error,
|
||||
make it a warning. */
|
||||
if (warnings_flag[b] == severity_error)
|
||||
warnings_flag[b] = severity_warning;
|
||||
}
|
||||
else
|
||||
/* -Wno-foo. */
|
||||
warnings_flag[b] = severity_disabled;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t b;
|
||||
for (b = 0; b < warnings_size; ++b)
|
||||
if (value & 1 << b)
|
||||
/* -Wfoo and -Werror=foo. */
|
||||
warnings_flag[b] = err ? severity_error : 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;
|
||||
warning_argmatch ("no-error=everything", 3, 6);
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t no = STRPREFIX_LIT ("no-", args) ? 3 : 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);
|
||||
}
|
||||
|
||||
static severity
|
||||
warning_severity (warnings flags)
|
||||
{
|
||||
if (flags & fatal)
|
||||
return severity_fatal;
|
||||
else if (flags & complaint)
|
||||
return severity_error;
|
||||
else
|
||||
{
|
||||
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 (res == severity_warning && warnings_are_errors)
|
||||
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 +246,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 +266,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 +275,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 +353,6 @@ complain_args (location const *loc, warnings w, unsigned *indent,
|
||||
complain (loc, fatal, "too many arguments for complains");
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
@@ -204,3 +367,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"));
|
||||
}
|
||||
|
||||
+68
-16
@@ -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,6 +124,10 @@ void complain_indent (location const *loc, warnings flags, unsigned *indent,
|
||||
void deprecated_directive (location const *loc,
|
||||
char const *obsolete, char const *updated);
|
||||
|
||||
/** 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. */
|
||||
|
||||
+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);
|
||||
}
|
||||
|
||||
+13
-13
@@ -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
|
||||
@@ -58,20 +58,20 @@ 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 +79,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 +191,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 +222,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 +270,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 +278,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)));
|
||||
|
||||
+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);
|
||||
|
||||
|
||||
+1
-1
@@ -342,7 +342,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
|
||||
|
||||
+3
-5
@@ -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. */
|
||||
@@ -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 ();
|
||||
|
||||
|
||||
+207
-160
@@ -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,7 +293,7 @@ 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);
|
||||
}
|
||||
|
||||
@@ -329,10 +344,9 @@ 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 == '[');
|
||||
@@ -377,11 +391,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 +489,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 +525,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 +536,119 @@ 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. */
|
||||
|
||||
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 +673,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 +697,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 +716,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 +763,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_ */
|
||||
|
||||
+20
-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);
|
||||
}
|
||||
}
|
||||
|
||||
+670
-669
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 2.7.90. */
|
||||
|
||||
/* 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:1926 */
|
||||
|
||||
#include "symlist.h"
|
||||
#include "symtab.h"
|
||||
#line 221 "src/parse-gram.y" /* yacc.c:1926 */
|
||||
|
||||
# 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:1926 */
|
||||
#include "muscle-tab.h"
|
||||
|
||||
|
||||
#line 66 "src/parse-gram.h" /* yacc.c:1932 */
|
||||
#line 68 "src/parse-gram.h" /* yacc.c:1926 */
|
||||
|
||||
/* 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:1926 */
|
||||
unsigned char character;
|
||||
#line 186 "src/parse-gram.y" /* yacc.c:1926 */
|
||||
char *code;
|
||||
#line 191 "src/parse-gram.y" /* yacc.c:1926 */
|
||||
uniqstr uniqstr;
|
||||
#line 199 "src/parse-gram.y" /* yacc.c:1926 */
|
||||
int integer;
|
||||
#line 203 "src/parse-gram.y" /* yacc.c:1926 */
|
||||
symbol *symbol;
|
||||
#line 208 "src/parse-gram.y" /* yacc.c:1926 */
|
||||
assoc assoc;
|
||||
#line 211 "src/parse-gram.y" /* yacc.c:1926 */
|
||||
symbol_list *list;
|
||||
#line 214 "src/parse-gram.y" /* yacc.c:1926 */
|
||||
named_ref *named_ref;
|
||||
#line 241 "src/parse-gram.y" /* yacc.c:1926 */
|
||||
param_type param;
|
||||
#line 409 "src/parse-gram.y" /* yacc.c:1926 */
|
||||
code_props_type code_type;
|
||||
#line 647 "src/parse-gram.y" /* yacc.c:1926 */
|
||||
|
||||
#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:1926 */
|
||||
};
|
||||
# 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;
|
||||
}
|
||||
|
||||
+13
-7
@@ -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];
|
||||
|
||||
|
||||
/*--------------------------------.
|
||||
@@ -209,7 +210,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). |
|
||||
`-------------------------------------------------------------------------*/
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
+2
-2
@@ -206,7 +206,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 +514,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. */
|
||||
|
||||
+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;
|
||||
|
||||
+10
-84
@@ -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>
|
||||
@@ -671,7 +596,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
|
||||
|
||||
+16
-23
@@ -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;
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
+5
-3
@@ -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"))
|
||||
|
||||
+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;
|
||||
|
||||
|
||||
+1
-1
@@ -105,7 +105,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
|
||||
|
||||
+1
-1
@@ -40,7 +40,7 @@ uniqstr uniqstr_vsprintf (char const *format, ...)
|
||||
|
||||
/* 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
+125
-121
@@ -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.
|
||||
*/
|
||||
@@ -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;
|
||||
|
||||
+1
-13
@@ -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,9 +47,6 @@ 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@'
|
||||
|
||||
@@ -75,15 +72,6 @@ else
|
||||
CC_IS_CXX=0
|
||||
fi
|
||||
|
||||
# In a similar way, handle --release
|
||||
if "$at_arg_release"; then
|
||||
BISON_USE_PUSH_FOR_PULL=1
|
||||
BISON_TEST_XML=1
|
||||
else
|
||||
BISON_USE_PUSH_FOR_PULL=0
|
||||
BISON_TEST_XML=0
|
||||
fi
|
||||
|
||||
|
||||
## ------- ##
|
||||
## Other. ##
|
||||
|
||||
+106
-38
@@ -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
|
||||
@@ -115,7 +176,7 @@ m4_pushdef([AT_TEST],
|
||||
|
||||
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],
|
||||
[[%debug
|
||||
%skeleton "lalr1.cc"
|
||||
%define api.value.type variant
|
||||
@@ -250,8 +311,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)
|
||||
])
|
||||
@@ -265,8 +325,8 @@ 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([[%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_}]])
|
||||
|
||||
m4_popdef([AT_TEST])
|
||||
|
||||
@@ -363,10 +423,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 +482,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 ) */]], [[-]])
|
||||
@@ -615,14 +675,42 @@ $1
|
||||
/// A class that counts its number of instances.
|
||||
struct Object
|
||||
{
|
||||
char val;
|
||||
|
||||
Object (char v)
|
||||
: val (v)
|
||||
{
|
||||
Object::instances.push_back(this);
|
||||
log (this, "Object::Object");
|
||||
}
|
||||
|
||||
Object ()
|
||||
: val ('?')
|
||||
{
|
||||
Object::instances.push_back(this);
|
||||
log (this, "Object::Object");
|
||||
}
|
||||
|
||||
Object& operator= (char v)
|
||||
{
|
||||
val = v;
|
||||
return *this;
|
||||
}
|
||||
|
||||
~Object ()
|
||||
{
|
||||
Object::instances.remove (this);
|
||||
log (this, "Object::~Object");
|
||||
}
|
||||
|
||||
// Static part.
|
||||
typedef std::list<const Object*> objects;
|
||||
static objects instances;
|
||||
char val;
|
||||
|
||||
static bool
|
||||
empty ()
|
||||
{
|
||||
return instances.empty();
|
||||
return instances.empty ();
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -645,26 +733,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");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -727,11 +795,11 @@ item:
|
||||
// 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; }
|
||||
| 'R' { $][$ = 0; ]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; }
|
||||
| 'T' { $][$ = 0; ]AT_VARIANT_IF([], [delete $][1]; )[YYABORT; }
|
||||
| error { $][$ = 0; yyerrok; }
|
||||
;
|
||||
%%
|
||||
|
||||
@@ -804,7 +872,7 @@ main (int argc, const char *argv[])
|
||||
}
|
||||
]])
|
||||
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
|
||||
|
||||
+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}])
|
||||
|
||||
+167
-99
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
+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
|
||||
|
||||
@@ -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
|
||||
|
||||
+2
-2
@@ -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
-132
@@ -20,6 +20,29 @@ AT_BANNER([[Input Processing.]])
|
||||
# Mostly test that we are robust to mistakes.
|
||||
|
||||
|
||||
## ----------------- ##
|
||||
## Invalid options. ##
|
||||
## ----------------- ##
|
||||
|
||||
AT_SETUP([Invalid options])
|
||||
|
||||
AT_DATA([input.y],
|
||||
[[%%
|
||||
exp: '0'
|
||||
]])
|
||||
|
||||
# We used to accept these, as -f, --report and others were sharing
|
||||
# their code with -W.
|
||||
AT_BISON_CHECK([-ferror=caret input.y], [1], [], [ignore])
|
||||
AT_BISON_CHECK([--report=error=itemsets input.y], [1], [], [ignore])
|
||||
|
||||
# We used to accept any character after "-Werror", instead of ensuring
|
||||
# this is "=".
|
||||
AT_BISON_CHECK([-Werror?all input.y], [1], [], [ignore])
|
||||
|
||||
AT_CLEANUP
|
||||
|
||||
|
||||
## ---------------- ##
|
||||
## Invalid inputs. ##
|
||||
## ---------------- ##
|
||||
@@ -85,17 +108,17 @@ AT_SETUP([Invalid $n and @n])
|
||||
|
||||
AT_DATA([input.y],
|
||||
[[%%
|
||||
exp: { $$ = $1 ; };
|
||||
exp: { @$ = @1 ; };
|
||||
exp: %empty { $$ = $1 ; };
|
||||
exp: %empty { @$ = @1 ; };
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK([-fcaret input.y], [1], [],
|
||||
[[input.y:2.13-14: error: integer out of range: '$1'
|
||||
exp: { $$ = $1 ; };
|
||||
^^
|
||||
input.y:3.13-14: error: integer out of range: '@1'
|
||||
exp: { @$ = @1 ; };
|
||||
^^
|
||||
[[input.y:2.20-21: error: integer out of range: '$1'
|
||||
exp: %empty { $$ = $1 ; };
|
||||
^^
|
||||
input.y:3.20-21: error: integer out of range: '@1'
|
||||
exp: %empty { @$ = @1 ; };
|
||||
^^
|
||||
]])
|
||||
|
||||
AT_CLEANUP
|
||||
@@ -114,7 +137,7 @@ AT_DATA([input.y],
|
||||
%%
|
||||
exp: foo { $$; } foo { $2; } foo
|
||||
| foo
|
||||
| /* empty. */
|
||||
| %empty
|
||||
;
|
||||
]])
|
||||
|
||||
@@ -131,9 +154,9 @@ input.y:5.6-32: warning: type clash on default action: <bar> != <> [-Wother]
|
||||
input.y:6.6-8: warning: type clash on default action: <bar> != <> [-Wother]
|
||||
| foo
|
||||
^^^
|
||||
input.y:7.5: warning: empty rule for typed nonterminal, and no action [-Wother]
|
||||
| /* empty. */
|
||||
^
|
||||
input.y:7.6-11: warning: empty rule for typed nonterminal, and no action [-Wother]
|
||||
| %empty
|
||||
^^^^^^
|
||||
]])
|
||||
|
||||
AT_CLEANUP
|
||||
@@ -169,7 +192,7 @@ start:
|
||||
;
|
||||
|
||||
a: INT | INT { } INT { } INT { };
|
||||
b: INT | /* empty */;
|
||||
b: INT | %empty;
|
||||
c: INT | INT { $]1[; } INT { $<integer>2; } INT { $<integer>4; };
|
||||
d: INT | INT { } INT { $]1[; } INT { $<integer>2; };
|
||||
e: INT | INT { } INT { } INT { $]1[; };
|
||||
@@ -197,9 +220,9 @@ input.y:11.18-20: warning: unused value: $][3 [-Wother]
|
||||
input.y:11.26-28: warning: unused value: $][5 [-Wother]
|
||||
a: INT | INT { } INT { } INT { };
|
||||
^^^
|
||||
input.y:12.9: warning: empty rule for typed nonterminal, and no action [-Wother]
|
||||
b: INT | /* empty */;
|
||||
^
|
||||
input.y:12.10-15: warning: empty rule for typed nonterminal, and no action [-Wother]
|
||||
b: INT | %empty;
|
||||
^^^^^^
|
||||
]]m4_ifval($2, [[[input.y:13.14-20: warning: unset value: $][$ [-Wmidrule-values]
|
||||
c: INT | INT { $][1; } INT { $<integer>2; } INT { $<integer>4; };
|
||||
^^^^^^^
|
||||
@@ -313,104 +336,67 @@ AT_CLEANUP
|
||||
|
||||
AT_SETUP([Default %printer and %destructor redeclared])
|
||||
|
||||
AT_DATA([[input.y]],
|
||||
[[%destructor { destroy ($$); } <*> <*>
|
||||
%printer { print ($$); } <*> <*>
|
||||
# AT_TEST([*])
|
||||
# ------------
|
||||
m4_pushdef([AT_TEST],
|
||||
[AT_DATA([[input.y]],
|
||||
[[%destructor { destroy ($$); } <$1> <$1>
|
||||
%printer { print ($$); } <$1> <$1>
|
||||
|
||||
%destructor { destroy ($$); } <*>
|
||||
%printer { print ($$); } <*>
|
||||
|
||||
%destructor { destroy ($$); } <> <>
|
||||
%printer { print ($$); } <> <>
|
||||
|
||||
%destructor { destroy ($$); } <>
|
||||
%printer { print ($$); } <>
|
||||
%destructor { destroy ($$); } <$1>
|
||||
%printer { print ($$); } <$1>
|
||||
|
||||
%%
|
||||
|
||||
start: ;
|
||||
start: %empty;
|
||||
|
||||
%destructor { destroy ($$); } <*>;
|
||||
%printer { print ($$); } <*>;
|
||||
|
||||
%destructor { destroy ($$); } <>;
|
||||
%printer { print ($$); } <>;
|
||||
%destructor { destroy ($$); } <$1>;
|
||||
%printer { print ($$); } <$1>;
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK([-fcaret input.y], [1], [],
|
||||
[[input.y:1.13-29: error: %destructor redeclaration for <*>
|
||||
%destructor { destroy ($$); } <*> <*>
|
||||
^^^^^^^^^^^^^^^^^
|
||||
input.y:1.13-29: previous declaration
|
||||
%destructor { destroy ($$); } <*> <*>
|
||||
^^^^^^^^^^^^^^^^^
|
||||
input.y:2.10-24: error: %printer redeclaration for <*>
|
||||
%printer { print ($$); } <*> <*>
|
||||
^^^^^^^^^^^^^^^
|
||||
input.y:2.10-24: previous declaration
|
||||
%printer { print ($$); } <*> <*>
|
||||
^^^^^^^^^^^^^^^
|
||||
input.y:4.13-29: error: %destructor redeclaration for <*>
|
||||
%destructor { destroy ($$); } <*>
|
||||
^^^^^^^^^^^^^^^^^
|
||||
input.y:1.13-29: previous declaration
|
||||
%destructor { destroy ($$); } <*> <*>
|
||||
^^^^^^^^^^^^^^^^^
|
||||
input.y:5.10-24: error: %printer redeclaration for <*>
|
||||
%printer { print ($$); } <*>
|
||||
^^^^^^^^^^^^^^^
|
||||
input.y:2.10-24: previous declaration
|
||||
%printer { print ($$); } <*> <*>
|
||||
^^^^^^^^^^^^^^^
|
||||
input.y:7.13-29: error: %destructor redeclaration for <>
|
||||
[[input.y:1.13-29: error: %destructor redeclaration for <>
|
||||
%destructor { destroy ($$); } <> <>
|
||||
^^^^^^^^^^^^^^^^^
|
||||
input.y:7.13-29: previous declaration
|
||||
input.y:1.13-29: previous declaration
|
||||
%destructor { destroy ($$); } <> <>
|
||||
^^^^^^^^^^^^^^^^^
|
||||
input.y:8.10-24: error: %printer redeclaration for <>
|
||||
input.y:2.10-24: error: %printer redeclaration for <>
|
||||
%printer { print ($$); } <> <>
|
||||
^^^^^^^^^^^^^^^
|
||||
input.y:8.10-24: previous declaration
|
||||
input.y:2.10-24: previous declaration
|
||||
%printer { print ($$); } <> <>
|
||||
^^^^^^^^^^^^^^^
|
||||
input.y:10.13-29: error: %destructor redeclaration for <>
|
||||
input.y:4.13-29: error: %destructor redeclaration for <>
|
||||
%destructor { destroy ($$); } <>
|
||||
^^^^^^^^^^^^^^^^^
|
||||
input.y:7.13-29: previous declaration
|
||||
input.y:1.13-29: previous declaration
|
||||
%destructor { destroy ($$); } <> <>
|
||||
^^^^^^^^^^^^^^^^^
|
||||
input.y:11.10-24: error: %printer redeclaration for <>
|
||||
input.y:5.10-24: error: %printer redeclaration for <>
|
||||
%printer { print ($$); } <>
|
||||
^^^^^^^^^^^^^^^
|
||||
input.y:8.10-24: previous declaration
|
||||
input.y:2.10-24: previous declaration
|
||||
%printer { print ($$); } <> <>
|
||||
^^^^^^^^^^^^^^^
|
||||
input.y:17.13-29: error: %destructor redeclaration for <*>
|
||||
%destructor { destroy ($$); } <*>;
|
||||
^^^^^^^^^^^^^^^^^
|
||||
input.y:4.13-29: previous declaration
|
||||
%destructor { destroy ($$); } <*>
|
||||
^^^^^^^^^^^^^^^^^
|
||||
input.y:18.10-24: error: %printer redeclaration for <*>
|
||||
%printer { print ($$); } <*>;
|
||||
^^^^^^^^^^^^^^^
|
||||
input.y:5.10-24: previous declaration
|
||||
%printer { print ($$); } <*>
|
||||
^^^^^^^^^^^^^^^
|
||||
input.y:20.13-29: error: %destructor redeclaration for <>
|
||||
input.y:11.13-29: error: %destructor redeclaration for <>
|
||||
%destructor { destroy ($$); } <>;
|
||||
^^^^^^^^^^^^^^^^^
|
||||
input.y:10.13-29: previous declaration
|
||||
%destructor { destroy ($$); } <>
|
||||
input.y:1.13-29: previous declaration
|
||||
%destructor { destroy ($$); } <> <>
|
||||
^^^^^^^^^^^^^^^^^
|
||||
input.y:21.10-24: error: %printer redeclaration for <>
|
||||
input.y:12.10-24: error: %printer redeclaration for <>
|
||||
%printer { print ($$); } <>;
|
||||
^^^^^^^^^^^^^^^
|
||||
input.y:11.10-24: previous declaration
|
||||
%printer { print ($$); } <>
|
||||
input.y:2.10-24: previous declaration
|
||||
%printer { print ($$); } <> <>
|
||||
^^^^^^^^^^^^^^^
|
||||
]])
|
||||
])
|
||||
|
||||
AT_TEST([], [], [])
|
||||
AT_TEST([], [*], [*])
|
||||
m4_popdef([AT_TEST])
|
||||
|
||||
AT_CLEANUP
|
||||
|
||||
@@ -430,7 +416,7 @@ AT_DATA([[input.y]],
|
||||
|
||||
%%
|
||||
|
||||
start: ;
|
||||
start: %empty;
|
||||
|
||||
%destructor { destroy ($$); } <field2> <field1>;
|
||||
%printer { print ($$); } <field2> <field1>;
|
||||
@@ -440,17 +426,17 @@ AT_BISON_CHECK([input.y], [1], [],
|
||||
[[input.y:4.13-29: error: %destructor redeclaration for <field1>
|
||||
input.y:1.13-29: previous declaration
|
||||
input.y:4.13-29: error: %destructor redeclaration for <field1>
|
||||
input.y:4.13-29: previous declaration
|
||||
input.y:1.13-29: previous declaration
|
||||
input.y:5.10-24: error: %printer redeclaration for <field2>
|
||||
input.y:2.10-24: previous declaration
|
||||
input.y:5.10-24: error: %printer redeclaration for <field2>
|
||||
input.y:5.10-24: previous declaration
|
||||
input.y:2.10-24: previous declaration
|
||||
input.y:11.13-29: error: %destructor redeclaration for <field2>
|
||||
input.y:1.13-29: previous declaration
|
||||
input.y:11.13-29: error: %destructor redeclaration for <field1>
|
||||
input.y:4.13-29: previous declaration
|
||||
input.y:1.13-29: previous declaration
|
||||
input.y:12.10-24: error: %printer redeclaration for <field2>
|
||||
input.y:5.10-24: previous declaration
|
||||
input.y:2.10-24: previous declaration
|
||||
input.y:12.10-24: error: %printer redeclaration for <field1>
|
||||
input.y:2.10-24: previous declaration
|
||||
]])
|
||||
@@ -826,7 +812,7 @@ exp: '@<:@' '\1' two '$' '@' '{' oline output.or.oline.opt
|
||||
|
||||
two: '\x000000000000000000000000000000000000000000000000000000000000000000002';
|
||||
oline: '@' 'o' 'l' 'i' 'n' 'e' '@' '_' '_' 'o' 'l' 'i' 'n' 'e' '_' '_';
|
||||
output.or.oline.opt: ;|oline;;|output;;;
|
||||
output.or.oline.opt: %empty;|oline;;|output;;;
|
||||
output: '#' 'o' 'u' 't' 'p' 'u' 't' ' ';
|
||||
%%
|
||||
/* Exercise M4 quoting: '@:>@@:>@', @<:@, 2. */
|
||||
@@ -908,7 +894,7 @@ m4_define([AT_CHECK_REQUIRE],
|
||||
AT_DATA_GRAMMAR([input.y],
|
||||
[[%require "$1";
|
||||
%%
|
||||
empty_file: /* empty */;
|
||||
empty_file: %empty;
|
||||
]])
|
||||
AT_BISON_CHECK([-o input.c input.y], $2, [], ignore)
|
||||
AT_CLEANUP
|
||||
@@ -1066,7 +1052,7 @@ AT_DATA([input.y],
|
||||
|
||||
%%
|
||||
|
||||
start: ;
|
||||
start: %empty;
|
||||
|
||||
// Used to report a syntax error because it didn't see any kind of symbol
|
||||
// identifier.
|
||||
@@ -1111,7 +1097,7 @@ AT_SETUP([%start after first rule])
|
||||
|
||||
AT_DATA([input.y],
|
||||
[[%%
|
||||
false_start: ;
|
||||
false_start: %empty;
|
||||
start: false_start ;
|
||||
%start start;
|
||||
]])
|
||||
@@ -1132,7 +1118,7 @@ AT_SETUP([%prec takes a token])
|
||||
AT_DATA([input.y],
|
||||
[[%%
|
||||
start: PREC %prec PREC ;
|
||||
PREC: ;
|
||||
PREC: %empty;
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK([input.y], [1], [],
|
||||
@@ -1174,7 +1160,7 @@ AT_DATA([input-c.y],
|
||||
%code bad {}
|
||||
%code format {}
|
||||
%%
|
||||
start: ;
|
||||
start: %empty;
|
||||
]])
|
||||
AT_BISON_CHECK([[input-c.y]], [[1]], [],
|
||||
[[input-c.y:1.7: error: %code qualifier 'q' is not used
|
||||
@@ -1188,7 +1174,7 @@ AT_DATA([input-c-glr.y],
|
||||
%code bad {}
|
||||
%code bad {}
|
||||
%%
|
||||
start: ;
|
||||
start: %empty;
|
||||
]])
|
||||
AT_BISON_CHECK([[input-c-glr.y]], [[1]], [],
|
||||
[[input-c-glr.y:1.7: error: %code qualifier 'q' is not used
|
||||
@@ -1201,7 +1187,7 @@ AT_DATA([input-c++.y],
|
||||
%code bad {}
|
||||
%code q {}
|
||||
%%
|
||||
start: ;
|
||||
start: %empty;
|
||||
]])
|
||||
AT_BISON_CHECK([[input-c++.y]], [[1]], [],
|
||||
[[input-c++.y:1.7: error: %code qualifier 'q' is not used
|
||||
@@ -1214,7 +1200,7 @@ AT_DATA([input-c++-glr.y],
|
||||
%code q {}
|
||||
%code q {}
|
||||
%%
|
||||
start: ;
|
||||
start: %empty;
|
||||
]])
|
||||
AT_BISON_CHECK([[input-c++-glr.y]], [[1]], [],
|
||||
[[input-c++-glr.y:1.7-9: error: %code qualifier 'bad' is not used
|
||||
@@ -1227,7 +1213,7 @@ AT_DATA([special-char-@@.y],
|
||||
%code q {}
|
||||
%code q {}
|
||||
%%
|
||||
start: ;
|
||||
start: %empty;
|
||||
]])
|
||||
AT_BISON_CHECK([[special-char-@@.y]], [[1]], [],
|
||||
[[special-char-@@.y:1.7-9: error: %code qualifier 'bad' is not used
|
||||
@@ -1240,7 +1226,7 @@ AT_DATA([special-char-@:>@.y],
|
||||
%code q {}
|
||||
%code q {}
|
||||
%%
|
||||
start: ;
|
||||
start: %empty;
|
||||
]])
|
||||
AT_BISON_CHECK([[special-char-@:>@.y]], [[1]], [],
|
||||
[[special-char-@:>@.y:1.7-9: error: %code qualifier 'bad' is not used
|
||||
@@ -1251,6 +1237,45 @@ special-char-@:>@.y:3.7: error: %code qualifier 'q' is not used
|
||||
AT_CLEANUP
|
||||
|
||||
|
||||
## ---------------- ##
|
||||
## Multiple %code. ##
|
||||
## ---------------- ##
|
||||
|
||||
AT_SETUP([Multiple %code])
|
||||
|
||||
# Make sure that repeated arguments to %code are separated by
|
||||
# end-of-lines. At some point, a missing eol would leave synclines
|
||||
# appended to the previous value. Here, we use CPP directive to
|
||||
# introduce dependency on the absence/presence of the eol.
|
||||
AT_BISON_OPTION_PUSHDEFS
|
||||
|
||||
AT_DATA([input.y],
|
||||
[[%code {#include <assert.h>}
|
||||
%code {#define A B}
|
||||
%code {#define B C}
|
||||
%code {#define C D}
|
||||
%code {#define D 42}
|
||||
%code {
|
||||
]AT_YYERROR_DECLARE[
|
||||
]AT_YYLEX_DECLARE[
|
||||
}
|
||||
%%
|
||||
start: %empty;
|
||||
%%
|
||||
]AT_YYERROR_DEFINE[
|
||||
]AT_YYLEX_DEFINE[
|
||||
int main (void)
|
||||
{
|
||||
assert (A == 42);
|
||||
return 0;
|
||||
}
|
||||
]])
|
||||
AT_FULL_COMPILE([input])
|
||||
AT_PARSER_CHECK([./input])
|
||||
|
||||
AT_BISON_OPTION_POPDEFS
|
||||
AT_CLEANUP()
|
||||
|
||||
## ---------------- ##
|
||||
## %define errors. ##
|
||||
## ---------------- ##
|
||||
@@ -1264,7 +1289,7 @@ AT_DATA([input-redefined.y],
|
||||
%define special1 "@:>@"
|
||||
%define special2 "@<:@"
|
||||
%%
|
||||
start: ;
|
||||
start: %empty;
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK([[input-redefined.y]], [[1]], [],
|
||||
@@ -1277,7 +1302,7 @@ input-redefined.y:2.9-11: previous definition
|
||||
AT_DATA([input-unused.y],
|
||||
[[%define var "value"
|
||||
%%
|
||||
start: ;
|
||||
start: %empty;
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK([[input-unused.y]], [[1]], [],
|
||||
@@ -1305,7 +1330,7 @@ m4@&t@_divert_pop(0)
|
||||
AT_DATA([[input.y]],
|
||||
[[%define var-dfg "gram"
|
||||
%%
|
||||
start: ;
|
||||
start: %empty;
|
||||
]])
|
||||
AT_BISON_CHECK([[-Dvar-dd=cmd-d1 -Dvar-dd=cmd-d2 \
|
||||
-Fvar-ff=cmd-f1 -Fvar-ff=cmd-f2 \
|
||||
@@ -1322,7 +1347,7 @@ var-fd: cmd-d
|
||||
AT_DATA([[input-dg.y]],
|
||||
[[%define var "gram"
|
||||
%%
|
||||
start: ;
|
||||
start: %empty;
|
||||
]])
|
||||
AT_BISON_CHECK([[-Dvar=cmd-d input-dg.y]], [[1]], [],
|
||||
[[input-dg.y:1.9-11: error: %define variable 'var' redefined
|
||||
@@ -1332,7 +1357,7 @@ AT_BISON_CHECK([[-Dvar=cmd-d input-dg.y]], [[1]], [],
|
||||
AT_DATA([[input-dg.y]],
|
||||
[[%define var "gram"
|
||||
%%
|
||||
start: ;
|
||||
start: %empty;
|
||||
]])
|
||||
AT_BISON_CHECK([[-fcaret -Dvar=cmd-d input-dg.y]], [[1]], [],
|
||||
[[input-dg.y:1.9-11: error: %define variable 'var' redefined
|
||||
@@ -1343,7 +1368,7 @@ AT_BISON_CHECK([[-fcaret -Dvar=cmd-d input-dg.y]], [[1]], [],
|
||||
|
||||
AT_DATA([[input-unused.y]],
|
||||
[[%%
|
||||
start: ;
|
||||
start: %empty;
|
||||
]])
|
||||
AT_BISON_CHECK([[-Dunused-d -Funused-f input-unused.y]], [[1]], [],
|
||||
[[<command line>:2: error: %define variable 'unused-d' is not used
|
||||
@@ -1360,10 +1385,10 @@ AT_SETUP([["%define" Boolean variables]])
|
||||
|
||||
AT_DATA([Input.y],
|
||||
[[%language "Java"
|
||||
%define public "maybe"
|
||||
%define parser_class_name "Input"
|
||||
%define public maybe
|
||||
%define parser_class_name {Input}
|
||||
%%
|
||||
start: ;
|
||||
start: %empty;
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK([[Input.y]], [1], [],
|
||||
@@ -1372,6 +1397,72 @@ AT_BISON_CHECK([[Input.y]], [1], [],
|
||||
|
||||
AT_CLEANUP
|
||||
|
||||
## ------------------------ ##
|
||||
## %define code variables. ##
|
||||
## ------------------------ ##
|
||||
|
||||
AT_SETUP([["%define" code variables]])
|
||||
|
||||
m4_pushdef([AT_TEST],
|
||||
[AT_DATA([input.yy],
|
||||
[[%skeleton "lalr1.cc" %locations
|
||||
%define api.location.type ]$1[quux]$2[
|
||||
%define api.namespace ]$1[quux]$2[
|
||||
%define api.prefix ]$1[quux]$2[
|
||||
%define api.token.prefix ]$1[quux]$2[
|
||||
%token TOK // Otherwise api.token.prefix is unused.
|
||||
%%
|
||||
start: TOK;
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK([[input.yy]], [0], [],
|
||||
[[input.yy:2.9-25: warning: %define variable 'api.location.type' requires '{...}' values [-Wdeprecated]
|
||||
input.yy:4.9-18: warning: %define variable 'api.prefix' requires '{...}' values [-Wdeprecated]
|
||||
input.yy:5.9-24: warning: %define variable 'api.token.prefix' requires '{...}' values [-Wdeprecated]
|
||||
input.yy:3.9-21: warning: %define variable 'api.namespace' requires '{...}' values [-Wdeprecated]
|
||||
]])
|
||||
])
|
||||
|
||||
AT_TEST([], [])
|
||||
AT_TEST(["], ["])
|
||||
m4_popdef([AT_TEST])
|
||||
|
||||
AT_CLEANUP
|
||||
|
||||
|
||||
## --------------------------- ##
|
||||
## %define keyword variables. ##
|
||||
## --------------------------- ##
|
||||
|
||||
AT_SETUP([["%define" keyword variables]])
|
||||
|
||||
m4_pushdef([AT_TEST],
|
||||
[AT_DATA([input.y],
|
||||
[[%define api.pure ]$1[true]$2[
|
||||
%define api.push-pull ]$1[both]$2[
|
||||
%define lr.default-reduction ]$1[most]$2[
|
||||
%define lr.keep-unreachable-state ]$1[true]$2[
|
||||
%define lr.type ]$1[lalr]$2[
|
||||
%%
|
||||
exp: %empty
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK([[input.y]], [0], [],
|
||||
[[input.y:5.9-15: warning: %define variable 'lr.type' requires keyword values [-Wdeprecated]
|
||||
input.y:3.9-28: warning: %define variable 'lr.default-reduction' requires keyword values [-Wdeprecated]
|
||||
input.y:4.9-33: warning: %define variable 'lr.keep-unreachable-state' requires keyword values [-Wdeprecated]
|
||||
input.y:2.9-21: warning: %define variable 'api.push-pull' requires keyword values [-Wdeprecated]
|
||||
input.y:1.9-16: warning: %define variable 'api.pure' requires keyword values [-Wdeprecated]
|
||||
]])
|
||||
])
|
||||
|
||||
AT_TEST(["], ["])
|
||||
AT_TEST([{], [}])
|
||||
m4_popdef([AT_TEST])
|
||||
|
||||
AT_CLEANUP
|
||||
|
||||
|
||||
## ------------------------ ##
|
||||
## %define enum variables. ##
|
||||
## ------------------------ ##
|
||||
@@ -1386,7 +1477,7 @@ AT_SETUP([["%define" enum variables]])
|
||||
AT_DATA([[input.y]],
|
||||
[[%define lr.default-reduction bogus
|
||||
%%
|
||||
start: ;
|
||||
start: %empty;
|
||||
]])
|
||||
AT_BISON_CHECK([[-fcaret input.y]], [[1]], [[]],
|
||||
[[input.y:1.9-28: error: invalid value for %define variable 'lr.default-reduction': 'bogus'
|
||||
@@ -1401,7 +1492,7 @@ input.y:1.9-28: accepted value: 'accepting'
|
||||
AT_DATA([[input.y]],
|
||||
[[%define api.push-pull neither
|
||||
%%
|
||||
start: ;
|
||||
start: %empty;
|
||||
]])
|
||||
AT_BISON_CHECK([[-fcaret input.y]], [[1]], [[]],
|
||||
[[input.y:1.9-21: error: invalid value for %define variable 'api.push-pull': 'neither'
|
||||
@@ -1425,10 +1516,10 @@ AT_DATA([[input.y]],
|
||||
[[%define api.push_pull both
|
||||
%define lr.keep_unreachable_states maybe
|
||||
%define namespace "foo"
|
||||
%define api.namespace "foo"
|
||||
%define api.namespace {foo}
|
||||
%define variant
|
||||
%%
|
||||
start: ;
|
||||
start: %empty;
|
||||
]])
|
||||
AT_BISON_CHECK([[-fcaret input.y]], [1], [],
|
||||
[[input.y:1.9-21: warning: deprecated directive, use '%define api.push-pull both' [-Wdeprecated]
|
||||
@@ -1441,7 +1532,7 @@ input.y:3.9-17: warning: deprecated directive, use '%define api.namespace foo' [
|
||||
%define namespace "foo"
|
||||
^^^^^^^^^
|
||||
input.y:4.9-21: error: %define variable 'api.namespace' redefined
|
||||
%define api.namespace "foo"
|
||||
%define api.namespace {foo}
|
||||
^^^^^^^^^^^^^
|
||||
input.y:3.9-17: previous definition
|
||||
%define namespace "foo"
|
||||
@@ -1461,7 +1552,7 @@ AT_SETUP([[Unused %define api.pure]])
|
||||
|
||||
# AT_CHECK_API_PURE(DECLS, VALUE)
|
||||
# -------------------------------
|
||||
# Make sure Bison reports that `%define api.pure VALUE' is unused when DECLS
|
||||
# Make sure Bison reports that '%define api.pure VALUE' is unused when DECLS
|
||||
# are specified.
|
||||
m4_define([AT_CHECK_API_PURE],
|
||||
[
|
||||
@@ -1469,7 +1560,7 @@ AT_DATA([[input.y]],
|
||||
[[%define api.pure ]$2[
|
||||
]$1[
|
||||
%%
|
||||
start: ;
|
||||
start: %empty;
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK([[input.y]], [[1]], [],
|
||||
@@ -1500,9 +1591,9 @@ m4_define([AT_CHECK_NAMESPACE_ERROR],
|
||||
AT_DATA([[input.y]],
|
||||
[[%language "C++"
|
||||
%defines
|
||||
%define api.namespace "]$1["
|
||||
%define api.namespace {]$1[}
|
||||
%%
|
||||
start: ;
|
||||
start: %empty;
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK([[input.y]], [1], [],
|
||||
@@ -1662,7 +1753,7 @@ AT_SETUP([[LAC: Errors for %define]])
|
||||
|
||||
AT_DATA([[input.y]],
|
||||
[[%%
|
||||
start: ;
|
||||
start: %empty;
|
||||
]])
|
||||
|
||||
# parse.lac.* options are useless if LAC isn't actually activated.
|
||||
@@ -1685,27 +1776,27 @@ AT_SETUP([[-Werror is not affected by -Wnone and -Wall]])
|
||||
|
||||
AT_DATA([[input.y]],
|
||||
[[%%
|
||||
foo-bar: ;
|
||||
a: '0' { $$ = $; };
|
||||
]])
|
||||
|
||||
# -Werror is not enabled by -Wall or equivalent.
|
||||
AT_BISON_CHECK([[-Wall input.y]], [[0]], [[]],
|
||||
[[input.y:2.1-7: warning: POSIX Yacc forbids dashes in symbol names: foo-bar [-Wyacc]
|
||||
[[input.y:2.15: warning: stray '$' [-Wother]
|
||||
]])
|
||||
AT_BISON_CHECK([[-W input.y]], [[0]], [[]],
|
||||
[[input.y:2.1-7: warning: POSIX Yacc forbids dashes in symbol names: foo-bar [-Wyacc]
|
||||
[[input.y:2.15: warning: stray '$' [-Wother]
|
||||
]])
|
||||
AT_BISON_CHECK([[-Wno-none input.y]], [[0]], [[]],
|
||||
[[input.y:2.1-7: warning: POSIX Yacc forbids dashes in symbol names: foo-bar [-Wyacc]
|
||||
[[input.y:2.15: warning: stray '$' [-Wother]
|
||||
]])
|
||||
|
||||
# -Werror is not disabled by -Wnone or equivalent.
|
||||
AT_BISON_CHECK([[-Werror,none,yacc input.y]], [[1]], [[]], [[stderr]])
|
||||
AT_CHECK([[sed 's/^.*bison:/bison:/' stderr]], [[0]],
|
||||
[[input.y:2.1-7: error: POSIX Yacc forbids dashes in symbol names: foo-bar [-Werror=yacc]
|
||||
AT_BISON_CHECK([[-Werror,none,other input.y]], [[1]], [[]],
|
||||
[[input.y:2.15: error: stray '$' [-Werror=other]
|
||||
]])
|
||||
AT_BISON_CHECK([[-Werror,no-all,other input.y]], [[1]], [[]],
|
||||
[[input.y:2.15: error: stray '$' [-Werror=other]
|
||||
]])
|
||||
[mv stderr experr]
|
||||
AT_BISON_CHECK([[-Werror,no-all,yacc input.y]], [[1]], [[]], [[experr]])
|
||||
|
||||
AT_CLEANUP
|
||||
|
||||
@@ -1722,17 +1813,17 @@ m4_pushdef([AT_TEST],
|
||||
[AT_DATA([[input.y]],
|
||||
[[$1
|
||||
%%
|
||||
exp: /* empty */;
|
||||
exp: %empty;
|
||||
]])
|
||||
AT_BISON_CHECK([[$2 input.y]], [[1]], [[]],
|
||||
[[$3: error: '%name-prefix' and '%define api.prefix' cannot be used together
|
||||
]])
|
||||
])
|
||||
|
||||
AT_TEST([%define api.prefix foo %name-prefix "bar"], [], [input.y:1.9-18])
|
||||
AT_TEST([], [-Dapi.prefix=foo -p bar], [<command line>:2])
|
||||
AT_TEST([%name-prefix "bar"], [-Dapi.prefix=foo], [<command line>:2])
|
||||
AT_TEST([%define api.prefix foo], [-p bar], [input.y:1.9-18])
|
||||
AT_TEST([%define api.prefix {foo} %name-prefix "bar"], [], [input.y:1.9-18])
|
||||
AT_TEST([], [-Dapi.prefix={foo} -p bar], [<command line>:2])
|
||||
AT_TEST([%name-prefix "bar"], [-Dapi.prefix={foo}], [<command line>:2])
|
||||
AT_TEST([%define api.prefix {foo}], [-p bar], [input.y:1.9-18])
|
||||
|
||||
m4_popdef([AT_TEST])
|
||||
|
||||
|
||||
+33
-33
@@ -25,8 +25,8 @@ AT_BANNER([[Java Calculator.]])
|
||||
|
||||
# _AT_DATA_JAVA_CALC_Y($1, $2, $3, [BISON-DIRECTIVES])
|
||||
# ----------------------------------------------------
|
||||
# Produce `calc.y'. Don't call this macro directly, because it contains
|
||||
# some occurrences of `$1' etc. which will be interpreted by m4. So
|
||||
# Produce 'calc.y'. 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 with $1, $2, and $3 as arguments, which is what
|
||||
# AT_DATA_JAVA_CALC_Y does.
|
||||
m4_define([_AT_DATA_JAVA_CALC_Y],
|
||||
@@ -37,7 +37,7 @@ AT_DATA([Calc.y],
|
||||
[[/* Infix notation calculator--calc */
|
||||
%language "Java"
|
||||
%name-prefix "Calc"
|
||||
%define parser_class_name "Calc"
|
||||
%define parser_class_name {Calc}
|
||||
%define public
|
||||
|
||||
]$4[
|
||||
@@ -206,7 +206,7 @@ AT_BISON_OPTION_POPDEFS
|
||||
|
||||
# AT_DATA_CALC_Y([BISON-OPTIONS])
|
||||
# -------------------------------
|
||||
# Produce `calc.y'.
|
||||
# Produce 'calc.y'.
|
||||
m4_define([AT_DATA_JAVA_CALC_Y],
|
||||
[_AT_DATA_JAVA_CALC_Y($[1], $[2], $[3], [$1])
|
||||
])
|
||||
@@ -215,7 +215,7 @@ m4_define([AT_DATA_JAVA_CALC_Y],
|
||||
# _AT_CHECK_JAVA_CALC_ERROR(BISON-OPTIONS, INPUT,
|
||||
# [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.
|
||||
@@ -240,7 +240,7 @@ AT_DATA([[expout]],
|
||||
AT_YYERROR_SEES_LOC_IF([],
|
||||
[[sed 's/^[-0-9.]*: //' expout >at-expout
|
||||
mv at-expout expout]])
|
||||
# 3. If error-verbose is not used, strip the`, unexpected....' part.
|
||||
# 3. If error-verbose is not used, strip the', unexpected....' part.
|
||||
m4_bmatch([$1], [%error-verbose], [],
|
||||
[[sed 's/syntax error, .*$/syntax error/' expout >at-expout
|
||||
mv at-expout expout]])
|
||||
@@ -250,7 +250,7 @@ AT_CHECK([cat stderr], 0, [expout])
|
||||
|
||||
# _AT_CHECK_JAVA_CALC([BISON-DIRECTIVES], [BISON-CODE])
|
||||
# -----------------------------------------------------
|
||||
# Start a testing chunk which compiles `calc' grammar with
|
||||
# Start a testing chunk which compiles 'calc' grammar with
|
||||
# BISON-DIRECTIVES, and performs several tests over the parser.
|
||||
m4_define([_AT_CHECK_JAVA_CALC],
|
||||
[# We use integers to avoid dependencies upon the precision of doubles.
|
||||
@@ -310,7 +310,7 @@ _AT_CHECK_JAVA_CALC_ERROR([$1], [/dev/null],
|
||||
# - (* * *): 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
|
||||
@@ -342,7 +342,7 @@ AT_CLEANUP
|
||||
|
||||
# AT_CHECK_JAVA_CALC([BISON-DIRECTIVES])
|
||||
# --------------------------------------
|
||||
# Start a testing chunk which compiles `calc' grammar with
|
||||
# Start a testing chunk which compiles 'calc' grammar with
|
||||
# BISON-DIRECTIVES, and performs several tests over the parser.
|
||||
# Run the test with and without %error-verbose.
|
||||
m4_define([AT_CHECK_JAVA_CALC],
|
||||
@@ -461,13 +461,13 @@ AT_CHECK_JAVA_GREP([[class YYParser]])
|
||||
AT_CHECK_JAVA_MINIMAL([[%name-prefix "Prefix"]])
|
||||
AT_CHECK_JAVA_GREP([[class PrefixParser]])
|
||||
|
||||
AT_CHECK_JAVA_MINIMAL([[%define api.token.prefix "TOK_"]])
|
||||
AT_CHECK_JAVA_MINIMAL([[%define api.token.prefix {TOK_}]])
|
||||
AT_CHECK_JAVA_GREP([[.*TOK_END.*]])
|
||||
|
||||
AT_CHECK_JAVA_MINIMAL([[%define parser_class_name "ParserClassName"]])
|
||||
AT_CHECK_JAVA_MINIMAL([[%define parser_class_name {ParserClassName}]])
|
||||
AT_CHECK_JAVA_GREP([[class ParserClassName]])
|
||||
|
||||
AT_CHECK_JAVA_MINIMAL([[%define package "user_java_package"]])
|
||||
AT_CHECK_JAVA_MINIMAL([[%define package {user_java_package}]])
|
||||
AT_CHECK_JAVA_GREP([[package user_java_package;]])
|
||||
|
||||
AT_CLEANUP
|
||||
@@ -530,7 +530,7 @@ AT_CHECK_JAVA_GREP([[public final strictfp class YYParser]])
|
||||
|
||||
# FIXME: Can't do a Java compile because javacomp.sh is configured for 1.3
|
||||
AT_CHECK_JAVA_MINIMAL([[
|
||||
%define annotations "/*@Deprecated @SupressWarnings(\"unchecked\") @SupressWarnings({\"unchecked\", \"deprecation\"}) @SupressWarnings(value={\"unchecked\", \"deprecation\"})*/"
|
||||
%define annotations {/*@Deprecated @SupressWarnings("unchecked") @SupressWarnings({"unchecked", "deprecation"}) @SupressWarnings(value={"unchecked", "deprecation"})*/}
|
||||
%define public]])
|
||||
AT_CHECK_JAVA_GREP([[/\*@Deprecated @SupressWarnings("unchecked") @SupressWarnings({"unchecked", "deprecation"}) @SupressWarnings(value={"unchecked", "deprecation"})\*/ public class YYParser]])
|
||||
|
||||
@@ -543,15 +543,15 @@ AT_CLEANUP
|
||||
|
||||
AT_SETUP([Java parser class extends and implements])
|
||||
|
||||
AT_CHECK_JAVA_MINIMAL([[%define extends "Thread"]])
|
||||
AT_CHECK_JAVA_MINIMAL([[%define extends {Thread}]])
|
||||
AT_CHECK_JAVA_GREP([[class YYParser extends Thread]])
|
||||
|
||||
AT_CHECK_JAVA_MINIMAL([[%define implements "Cloneable"]])
|
||||
AT_CHECK_JAVA_MINIMAL([[%define implements {Cloneable}]])
|
||||
AT_CHECK_JAVA_GREP([[class YYParser implements Cloneable]])
|
||||
|
||||
AT_CHECK_JAVA_MINIMAL([[
|
||||
%define extends "Thread"
|
||||
%define implements "Cloneable"]])
|
||||
%define extends {Thread}
|
||||
%define implements {Cloneable}]])
|
||||
AT_CHECK_JAVA_GREP([[class YYParser extends Thread implements Cloneable]])
|
||||
|
||||
AT_CLEANUP
|
||||
@@ -643,9 +643,9 @@ AT_SETUP([Java throws specifications])
|
||||
|
||||
m4_define([AT_JT_lex_throws_define], [m4_case(AT_JT_lex_throws,
|
||||
-1, [],
|
||||
0, [[%define lex_throws ""]],
|
||||
1, [[%define lex_throws "InterruptedException"]],
|
||||
2, [[%define lex_throws "InterruptedException, IllegalAccessException"]])])
|
||||
0, [[%define lex_throws {}]],
|
||||
1, [[%define lex_throws {InterruptedException}]],
|
||||
2, [[%define lex_throws {InterruptedException, IllegalAccessException}]])])
|
||||
|
||||
m4_define([AT_JT_yylex_throws], [m4_case(AT_JT_lex_throws,
|
||||
-1, [[ throws java.io.IOException]],
|
||||
@@ -662,9 +662,9 @@ m4_define([AT_JT_yylex_action], [m4_case(AT_JT_lex_throws,
|
||||
|
||||
m4_define([AT_JT_throws_define], [m4_case(AT_JT_throws,
|
||||
-1, [],
|
||||
0, [[%define throws ""]],
|
||||
1, [[%define throws "ClassNotFoundException"]],
|
||||
2, [[%define throws "ClassNotFoundException, InstantiationException"]])])
|
||||
0, [[%define throws {}]],
|
||||
1, [[%define throws {ClassNotFoundException}]],
|
||||
2, [[%define throws {ClassNotFoundException, InstantiationException}]])])
|
||||
|
||||
m4_define([AT_JT_yyaction_throws], [m4_case(AT_JT_throws,
|
||||
-1, [],
|
||||
@@ -727,16 +727,16 @@ AT_CLEANUP
|
||||
AT_SETUP([Java constructor init and init_throws])
|
||||
|
||||
AT_CHECK_JAVA_MINIMAL([[
|
||||
%define extends "Thread"
|
||||
%define extends {Thread}
|
||||
%code init { super("Test Thread"); if (true) throw new InterruptedException(); }
|
||||
%define init_throws "InterruptedException"
|
||||
%define init_throws {InterruptedException}
|
||||
%lex-param {int lex_param}]])
|
||||
AT_CHECK([[grep -q 'super("Test Thread"); if (true) throw new InterruptedException();' YYParser.java]])
|
||||
|
||||
AT_CHECK_JAVA_MINIMAL_W_LEXER([[
|
||||
%define extends "Thread"
|
||||
%define extends {Thread}
|
||||
%code init { super("Test Thread"); if (true) throw new InterruptedException(); }
|
||||
%define init_throws "InterruptedException"]], [], [[return EOF;]])
|
||||
%define init_throws {InterruptedException}]], [], [[return EOF;]])
|
||||
AT_CHECK([[grep -q 'super("Test Thread"); if (true) throw new InterruptedException();' YYParser.java]])
|
||||
|
||||
AT_CLEANUP
|
||||
@@ -749,20 +749,20 @@ AT_CLEANUP
|
||||
AT_SETUP([Java value, position, and location types])
|
||||
|
||||
AT_CHECK_JAVA_MINIMAL([[
|
||||
%define api.value.type "java.awt.Color"
|
||||
%define api.value.type {java.awt.Color}
|
||||
%type<java.awt.Color> start;
|
||||
%define api.location.type "MyLoc"
|
||||
%define api.position.type "MyPos"
|
||||
%define api.location.type {MyLoc}
|
||||
%define api.position.type {MyPos}
|
||||
%code { class MyPos {} }]], [[$$ = $<java.awt.Color>1;]], [[MyPos]])
|
||||
AT_CHECK([[grep 'java.awt.Color' YYParser.java]], [0], [ignore])
|
||||
AT_CHECK([[$EGREP -v ' */?\*' YYParser.java | grep 'Position']], [1], [ignore])
|
||||
AT_CHECK([[$EGREP -v ' */?\*' YYParser.java | grep 'Location']], [1], [ignore])
|
||||
|
||||
AT_CHECK_JAVA_MINIMAL_W_LEXER([[
|
||||
%define api.value.type "java.awt.Color"
|
||||
%define api.value.type {java.awt.Color}
|
||||
%type<java.awt.Color> start;
|
||||
%define api.location.type "MyLoc"
|
||||
%define api.position.type "MyPos"
|
||||
%define api.location.type {MyLoc}
|
||||
%define api.position.type {MyPos}
|
||||
%code { class MyPos {} }]], [], [[return EOF;]], [],
|
||||
[[$$ = $<java.awt.Color>1;]],
|
||||
[[java.awt.Color]], [[MyPos]], [[MyLoc]])
|
||||
|
||||
+151
-106
@@ -37,7 +37,7 @@ m4_define([AT_SETUP_STRIP],
|
||||
[m4_bpatsubsts([$1],
|
||||
[%\(language\|skeleton\) "?\([^\" ]*\)"?],
|
||||
[\2],
|
||||
[%define "?\([-A-Za-z0-9_.]+\)"? \("[^\"]+"\|[-A-Za-z0-9_.]+\)],
|
||||
[%define "?\([-A-Za-z0-9_.]+\)"? \({[^\}]+}\|"[^\"]+"\|[-A-Za-z0-9_.]+\)],
|
||||
[\1=\2],
|
||||
[%define "?\([-A-Za-z0-9_.]+\)"?],
|
||||
[\1],
|
||||
@@ -134,7 +134,7 @@ m4_define([AT_BISON_OPTION_PUSHDEFS],
|
||||
# _AT_BISON_OPTION_PUSHDEFS($1, $2, [BISON-OPTIONS])
|
||||
# --------------------------------------------------
|
||||
# This macro works around the impossibility to define macros
|
||||
# inside macros, because issuing `[$1]' is not possible in M4 :(.
|
||||
# inside macros, because issuing '[$1]' is not possible in M4 :(.
|
||||
# This sucks hard, GNU M4 should really provide M5-like $$1.
|
||||
m4_define([_AT_BISON_OPTION_PUSHDEFS],
|
||||
[m4_if([$1$2], $[1]$[2], [],
|
||||
@@ -178,23 +178,25 @@ m4_bpatsubst([$3], [%parse-param { *\([^{}]*[^{} ]\) *}],
|
||||
|
||||
m4_pushdef([AT_PURE_IF],
|
||||
[m4_bmatch([$3], [%define *api\.pure\|%pure-parser],
|
||||
[m4_bmatch([$3], [%define *api\.pure *"?false"?], [$2], [$1])],
|
||||
[m4_bmatch([$3], [%define *api\.pure *false], [$2], [$1])],
|
||||
[$2])])
|
||||
# AT_NAME_PREFIX: also consider api.namespace.
|
||||
m4_pushdef([AT_NAME_PREFIX],
|
||||
[m4_bmatch([$3], [\(%define api\.\(namespace\|prefix\)\|%name-prefix\) ".*"],
|
||||
[m4_bregexp([$3], [\(%define api\.\(namespace\|prefix\)\|%name-prefix\) "\([^""]*\)"], [\3])],
|
||||
[yy])])
|
||||
[m4_bmatch([$3], [\(%define api\.\(namespace\|prefix\)\|%name-prefix\) .*],
|
||||
[m4_bregexp([$3],
|
||||
[\(%define api\.\(namespace\|prefix\)\|%name-prefix\) [\{\"]\([^\"\}]*\)[\"\}]],
|
||||
[\3])],
|
||||
[yy])])
|
||||
m4_pushdef([AT_TOKEN_CTOR_IF],
|
||||
[m4_bmatch([$3], [%define api\.token\.constructor], [$1], [$2])])
|
||||
m4_pushdef([AT_TOKEN_PREFIX],
|
||||
[m4_bmatch([$3], [%define api\.token\.prefix ".*"],
|
||||
[m4_bregexp([$3], [%define api\.token\.prefix "\(.*\)"], [\1])])])
|
||||
[m4_bmatch([$3], [%define api\.token\.prefix {.*}],
|
||||
[m4_bregexp([$3], [%define api\.token\.prefix {\(.*\)}], [\1])])])
|
||||
m4_pushdef([AT_VARIANT_IF],
|
||||
[m4_bmatch([$3], [%define api\.value\.type "?variant"?], [$1], [$2])])
|
||||
[m4_bmatch([$3], [%define api\.value\.type variant], [$1], [$2])])
|
||||
m4_pushdef([AT_API_prefix],
|
||||
[m4_bmatch([$3], [%define api\.prefix ".*"],
|
||||
[m4_bregexp([$3], [%define api\.prefix "\([^""]*\)"], [\1])],
|
||||
[m4_bmatch([$3], [%define api\.prefix {.*}],
|
||||
[m4_bregexp([$3], [%define api\.prefix {\([^\}]*\)}], [\1])],
|
||||
[yy])])
|
||||
m4_pushdef([AT_API_PREFIX],
|
||||
[m4_toupper(AT_API_prefix)])
|
||||
@@ -205,7 +207,7 @@ m4_pushdef([AT_API_PREFIX],
|
||||
m4_pushdef([AT_YYERROR_ARG_LOC_IF],
|
||||
[AT_LOCATION_IF([AT_PURE_IF([m4_bmatch([$3],
|
||||
m4_quote(m4_join([\|],
|
||||
[%define api\.pure "?full"?],
|
||||
[%define api\.pure full],
|
||||
[%glr-parser],
|
||||
[%parse-param],
|
||||
[%skeleton "?glr.c"?])),
|
||||
@@ -317,6 +319,25 @@ AT_LOC_POPDEF])dnl
|
||||
## Generating Grammar Files. ##
|
||||
## -------------------------- ##
|
||||
|
||||
# _AT_LANG_DISPATCH(LANG, MACRO, ARGS)
|
||||
# ------------------------------------
|
||||
# Call the specialization of MACRO for LANG with ARGS. Complain if
|
||||
# unavailable.
|
||||
m4_define([_AT_LANG_DISPATCH],
|
||||
[m4_ifdef([$2($1)],
|
||||
[m4_indir([$2($1)], m4_shift2($@))],
|
||||
[m4_fatal([$2: unknown language: $1])])])
|
||||
|
||||
|
||||
# AT_LANG_DISPATCH(MACRO, ARGS)
|
||||
# -----------------------------
|
||||
# Call the specialization of MACRO for AT_LANG with ARGS. Complain if
|
||||
# unavailable.
|
||||
m4_define([AT_LANG_DISPATCH],
|
||||
[_AT_LANG_DISPATCH(AT_LANG, $@)])
|
||||
|
||||
|
||||
|
||||
# AT_DATA_SOURCE_PROLOGUE
|
||||
# ------------------------
|
||||
# The prologue that should be included in any source code that is
|
||||
@@ -406,24 +427,33 @@ static
|
||||
# AT_YYERROR_DEFINE
|
||||
# -------------------------
|
||||
# Must be called inside a AT_BISON_OPTION_PUSHDEFS/POPDEFS pair.
|
||||
m4_define([AT_YYERROR_FORMALS],
|
||||
[m4_case(AT_LANG,
|
||||
[c], [AT_YYERROR_ARG_LOC_IF([AT_YYLTYPE const * const llocp, ])AT_PARSE_PARAMS [const char *msg]])[]dnl
|
||||
])
|
||||
m4_define([AT_YYERROR_FORMALS], [AT_LANG_DISPATCH([$0], $@)])
|
||||
m4_define([AT_YYERROR_PROTOTYPE],[AT_LANG_DISPATCH([$0], $@)])
|
||||
m4_define([AT_YYERROR_DECLARE_EXTERN], [AT_LANG_DISPATCH([$0], $@)])
|
||||
m4_define([AT_YYERROR_DECLARE], [AT_LANG_DISPATCH([$0], $@)])
|
||||
m4_define([AT_YYERROR_DEFINE], [AT_LANG_DISPATCH([$0], $@)])
|
||||
|
||||
m4_define([AT_YYERROR_PROTOTYPE],
|
||||
[m4_case(AT_LANG,
|
||||
[c], [[void ]AT_NAME_PREFIX[error (]AT_YYERROR_FORMALS[)]])[]dnl
|
||||
])
|
||||
# AT_MAIN_DEFINE
|
||||
# --------------
|
||||
m4_define([AT_MAIN_DEFINE], [AT_LANG_DISPATCH([$0], $@)])
|
||||
|
||||
m4_define([AT_YYERROR_DECLARE_EXTERN],
|
||||
[m4_case(AT_LANG,
|
||||
[c], [AT_YYERROR_PROTOTYPE;])[]dnl
|
||||
])
|
||||
|
||||
m4_define([AT_YYERROR_DECLARE],
|
||||
[m4_case(AT_LANG,
|
||||
[c], [#include <stdio.h>
|
||||
|
||||
## --- ##
|
||||
## C. ##
|
||||
## --- ##
|
||||
|
||||
m4_define([AT_YYERROR_FORMALS(c)],
|
||||
[AT_YYERROR_ARG_LOC_IF([AT_YYLTYPE const * const llocp, ])AT_PARSE_PARAMS[const char *msg]])
|
||||
|
||||
m4_define([AT_YYERROR_PROTOTYPE(c)],
|
||||
[[void ]AT_NAME_PREFIX[error (]AT_YYERROR_FORMALS[)]])
|
||||
|
||||
m4_define([AT_YYERROR_DECLARE_EXTERN(c)],
|
||||
[AT_YYERROR_PROTOTYPE;])
|
||||
|
||||
m4_define([AT_YYERROR_DECLARE(c)],
|
||||
[#include <stdio.h>
|
||||
]AT_LOCATION_IF([[
|
||||
#if defined ]AT_YYLTYPE[_IS_TRIVIAL && ]AT_YYLTYPE[_IS_TRIVIAL
|
||||
static unsigned location_print (FILE *yyo, ]AT_YYLTYPE[ const * const yylocp);
|
||||
@@ -432,12 +462,11 @@ static unsigned location_print (FILE *yyo, ]AT_YYLTYPE[ const * const yylocp);
|
||||
# endif
|
||||
#endif
|
||||
]])[
|
||||
static AT_YYERROR_DECLARE_EXTERN])[]dnl
|
||||
])
|
||||
static AT_YYERROR_DECLARE_EXTERN])
|
||||
|
||||
m4_define([AT_YYERROR_DEFINE],
|
||||
[m4_case(AT_LANG,
|
||||
[c], [[
|
||||
|
||||
m4_define([AT_YYERROR_DEFINE(c)],
|
||||
[[
|
||||
]AT_LOCATION_IF([[
|
||||
# if defined ]AT_YYLTYPE[_IS_TRIVIAL && ]AT_YYLTYPE[_IS_TRIVIAL
|
||||
/* Print *YYLOCP on YYO. */
|
||||
@@ -478,34 +507,10 @@ AT_YYERROR_SEES_LOC_IF([[
|
||||
LOCATION_PRINT (stderr, ]AT_LOC[);
|
||||
fprintf (stderr, ": ");]])[
|
||||
fprintf (stderr, "%s\n", msg);
|
||||
}]],
|
||||
[c++], [[/* A C++ error reporting function. */
|
||||
void
|
||||
]AT_NAME_PREFIX[::parser::error (]AT_LOCATION_IF([[const location_type& l, ]])[const std::string& m)
|
||||
{
|
||||
std::cerr << ]AT_LOCATION_IF([l << ": " << ])[m << std::endl;
|
||||
}]],
|
||||
[java], [AT_LOCATION_IF([[public void yyerror (Calc.Location l, String s)
|
||||
{
|
||||
if (l == null)
|
||||
System.err.println (s);
|
||||
else
|
||||
System.err.println (l + ": " + s);
|
||||
}
|
||||
]], [[
|
||||
public void yyerror (String s)
|
||||
{
|
||||
System.err.println (s);
|
||||
}]])],
|
||||
[m4_fatal([$0: invalid language: ]AT_LANG)])dnl
|
||||
])
|
||||
}]])
|
||||
|
||||
|
||||
# AT_MAIN_DEFINE
|
||||
# --------------
|
||||
m4_define([AT_MAIN_DEFINE],
|
||||
[m4_case(AT_LANG,
|
||||
[c],
|
||||
m4_define([AT_MAIN_DEFINE(c)],
|
||||
[[#include <stdlib.h> /* getenv. */
|
||||
#include <string.h> /* strcmp. */
|
||||
int
|
||||
@@ -518,8 +523,27 @@ main (int argc, char const* argv[])
|
||||
(void) argc;
|
||||
(void) argv;]])[
|
||||
return ]AT_NAME_PREFIX[parse ();
|
||||
}]],
|
||||
[c++],
|
||||
}]])
|
||||
|
||||
|
||||
## ----- ##
|
||||
## C++. ##
|
||||
## ----- ##
|
||||
|
||||
# No need to declare, it's part of the class interface.
|
||||
m4_define([AT_YYERROR_DECLARE(c++)], [])
|
||||
m4_define([AT_YYERROR_DECLARE_EXTERN(c++)], [])
|
||||
|
||||
m4_define([AT_YYERROR_DEFINE(c++)],
|
||||
[[/* A C++ error reporting function. */
|
||||
void
|
||||
]AT_NAME_PREFIX[::parser::error (]AT_LOCATION_IF([[const location_type& l, ]])[const std::string& m)
|
||||
{
|
||||
std::cerr << ]AT_LOCATION_IF([l << ": " << ])[m << std::endl;
|
||||
}]])
|
||||
|
||||
|
||||
m4_define([AT_MAIN_DEFINE(c++)],
|
||||
[[#include <cstdlib> // getenv.
|
||||
#include <cstring> // strcmp.
|
||||
int
|
||||
@@ -533,8 +557,30 @@ main (int argc, char const* argv[])
|
||||
(void) argc;
|
||||
(void) argv;]])[
|
||||
return p.parse ();
|
||||
}]],
|
||||
[java],
|
||||
}]])
|
||||
|
||||
|
||||
|
||||
## ------ ##
|
||||
## Java. ##
|
||||
## ------ ##
|
||||
|
||||
m4_define([AT_YYERROR_DEFINE(java)],
|
||||
[AT_LOCATION_IF([[public void yyerror (Calc.Location l, String s)
|
||||
{
|
||||
if (l == null)
|
||||
System.err.println (s);
|
||||
else
|
||||
System.err.println (l + ": " + s);
|
||||
}
|
||||
]], [[
|
||||
public void yyerror (String s)
|
||||
{
|
||||
System.err.println (s);
|
||||
}
|
||||
]])])
|
||||
|
||||
m4_define([AT_MAIN_DEFINE(java)],
|
||||
[[class input
|
||||
{
|
||||
public static void main (String args[]) throws IOException
|
||||
@@ -542,7 +588,8 @@ main (int argc, char const* argv[])
|
||||
YYParser p = new YYParser ();
|
||||
p.parse ();
|
||||
}
|
||||
}]])])
|
||||
}]])
|
||||
|
||||
|
||||
|
||||
## --------------- ##
|
||||
@@ -554,7 +601,7 @@ main (int argc, char const* argv[])
|
||||
# High-level routine that may call bison several times, under different
|
||||
# conditions.
|
||||
#
|
||||
# Check Bison by invoking `bison BISON_ARGS'. BISON_ARGS should not contain
|
||||
# Check Bison by invoking 'bison BISON_ARGS'. BISON_ARGS should not contain
|
||||
# shell constructs (such as redirection or pipes) that would prevent
|
||||
# appending additional command-line arguments for bison. OTHER_AT_CHECK_ARGS
|
||||
# are the usual remaining arguments to AT_CHECK: STATUS, STDOUT, etc.
|
||||
@@ -726,6 +773,7 @@ AT_CHECK(m4_join([ ],
|
||||
[m4_bmatch([$1], [[.]], [], [$LIBS])]),
|
||||
0, [ignore], [ignore])])
|
||||
|
||||
|
||||
# AT_JAVA_COMPILE(SOURCES)
|
||||
# ------------------------
|
||||
# Compile SOURCES into Java class files. Skip the test if java or javac
|
||||
@@ -734,9 +782,10 @@ m4_define([AT_JAVA_COMPILE],
|
||||
[AT_KEYWORDS(java)
|
||||
AT_SKIP_IF([[test -z "$CONF_JAVAC"]])
|
||||
AT_SKIP_IF([[test -z "$CONF_JAVA"]])
|
||||
AT_CHECK([[$SHELL $abs_top_builddir/javacomp.sh ]$1],
|
||||
AT_CHECK([[$SHELL ../../../javacomp.sh ]$1],
|
||||
[[0]], [ignore], [ignore])])
|
||||
|
||||
|
||||
# AT_LANG_COMPILE(OUTPUT, [SOURCES = OUTPUT.c]
|
||||
# --------------------------------------------
|
||||
# Compile SOURCES into OUTPUT. Skip if compiler does not work.
|
||||
@@ -744,13 +793,11 @@ AT_CHECK([[$SHELL $abs_top_builddir/javacomp.sh ]$1],
|
||||
# If OUTPUT does not contain '.', assume that we are linking too,
|
||||
# otherwise pass "-c"; this is a hack. The default SOURCES is OUTPUT
|
||||
# with trailing .o removed, and ".c"/".cc" appended.
|
||||
m4_define([AT_LANG_COMPILE],
|
||||
[m4_case(AT_LANG,
|
||||
[c], [AT_COMPILE([$1], [$2])],
|
||||
[c++], [AT_COMPILE_CXX([$1], [$2])],
|
||||
[java], [AT_JAVA_COMPILE([$1.java], [$2])],
|
||||
[m4_fatal([unknown language: ]m4_defn([AT_LANG]))])[]dnl
|
||||
])
|
||||
m4_define([AT_LANG_COMPILE], [AT_LANG_DISPATCH([$0], $@)])
|
||||
m4_define([AT_LANG_COMPILE(c)], [AT_COMPILE([$1], [$2])])
|
||||
m4_define([AT_LANG_COMPILE(c++)], [AT_COMPILE_CXX([$1], [$2])])
|
||||
m4_define([AT_LANG_COMPILE(java)], [AT_JAVA_COMPILE([$1.java], [$2])])
|
||||
|
||||
|
||||
# AT_FULL_COMPILE(OUTPUT, [OTHER1], [OTHER2])
|
||||
# -------------------------------------------
|
||||
@@ -759,30 +806,31 @@ m4_define([AT_LANG_COMPILE],
|
||||
# OUTPUT-OTHER.c, OUTPUT-OTHER.cc, or OUTPUT-OTHER.java to OUTPUT or
|
||||
# OUTPUT.java along with it. Relies on AT_SKEL_CC_IF and
|
||||
# AT_SKEL_JAVA_IF.
|
||||
m4_define([AT_FULL_COMPILE],
|
||||
[m4_case(AT_LANG,
|
||||
[java],
|
||||
[AT_BISON_CHECK([-o $1.java $1.y])
|
||||
AT_LANG_COMPILE([$1],
|
||||
m4_join([ ],
|
||||
[$1.java],
|
||||
m4_ifval($2, [[$1-$2.java]]),
|
||||
m4_ifval($3, [[$1-$3.java]])))],
|
||||
[c++],
|
||||
[AT_BISON_CHECK([-o $1.cc $1.y])
|
||||
AT_LANG_COMPILE([$1],
|
||||
m4_join([ ],
|
||||
[$1.cc],
|
||||
m4_ifval($2, [[$1-$2.cc]]),
|
||||
m4_ifval($3, [[$1-$3.cc]])))],
|
||||
[c],
|
||||
[AT_BISON_CHECK([-o $1.c $1.y])
|
||||
AT_LANG_COMPILE([$1],
|
||||
m4_join([ ],
|
||||
[$1.c],
|
||||
m4_ifval($2, [[$1-$2.c]]),
|
||||
m4_ifval($3, [[$1-$3.c]])))])
|
||||
])
|
||||
m4_define([AT_FULL_COMPILE], [AT_LANG_DISPATCH([$0], $@)])
|
||||
m4_define([AT_FULL_COMPILE(c)],
|
||||
[AT_BISON_CHECK([-o $1.c $1.y])
|
||||
AT_LANG_COMPILE([$1],
|
||||
m4_join([ ],
|
||||
[$1.c],
|
||||
m4_ifval($2, [[$1-$2.c]]),
|
||||
m4_ifval($3, [[$1-$3.c]])))])
|
||||
|
||||
m4_define([AT_FULL_COMPILE(c++)],
|
||||
[AT_BISON_CHECK([-o $1.cc $1.y])
|
||||
AT_LANG_COMPILE([$1],
|
||||
m4_join([ ],
|
||||
[$1.cc],
|
||||
m4_ifval($2, [[$1-$2.cc]]),
|
||||
m4_ifval($3, [[$1-$3.cc]])))])
|
||||
|
||||
m4_define([AT_FULL_COMPILE(java)],
|
||||
[AT_BISON_CHECK([-o $1.java $1.y])
|
||||
AT_LANG_COMPILE([$1],
|
||||
m4_join([ ],
|
||||
[$1.java],
|
||||
m4_ifval($2, [[$1-$2.java]]),
|
||||
m4_ifval($3, [[$1-$3.java]])))])
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -830,7 +878,7 @@ AT_PARSER_CHECK([./c-and-cxx])
|
||||
|
||||
# AT_PARSER_CHECK(COMMAND, EXIT-STATUS, EXPOUT, EXPERR, [PRE])
|
||||
# ------------------------------------------------------------
|
||||
# So that we can run `./testsuite PREPARSER='valgrind -q' for instance.
|
||||
# So that we can run './testsuite PREPARSER='valgrind -q' for instance.
|
||||
#
|
||||
# Get rid of spurious messages when compiled with --coverage:
|
||||
# +profiling:/[...]/lib/fprintf.gcda:Merge mismatch for summaries
|
||||
@@ -844,7 +892,7 @@ AT_CHECK([sed >&2 -e '/^profiling:.*:Merge mismatch for summaries/d' stderr],
|
||||
# AT_JAVA_PARSER_CHECK(COMMAND, EXIT-STATUS, EXPOUT, EXPERR, [PRE])
|
||||
# -----------------------------------------------------------------
|
||||
m4_define([AT_JAVA_PARSER_CHECK],
|
||||
[AT_CHECK([$5[ $SHELL $abs_top_builddir/javaexec.sh ]$1], [$2], [$3], [$4])])
|
||||
[AT_CHECK([$5[ $SHELL ../../../javaexec.sh ]$1], [$2], [$3], [$4])])
|
||||
|
||||
|
||||
# AT_TEST_TABLES_AND_PARSE(TITLE, COND-VALUE, TEST-SPEC,
|
||||
@@ -872,16 +920,16 @@ m4_define([AT_JAVA_PARSER_CHECK],
|
||||
# that Bison exits with value 0, has no stdout, and has stderr
|
||||
# BISON-STDERR.
|
||||
#
|
||||
# If TEST-SPEC contains the attribute `last-state', check that the value
|
||||
# If TEST-SPEC contains the attribute 'last-state', check that the value
|
||||
# of TABLES-OR-LAST-STATE is the index of the last state generated for
|
||||
# the grammar; in other words, check the number of states (minus one).
|
||||
# Otherwise, check that everything in the `.output' file starting with
|
||||
# Otherwise, check that everything in the '.output' file starting with
|
||||
# the definition of state 0 is the same as the entire value of
|
||||
# TABLES-OR-LAST-STATE.
|
||||
#
|
||||
# Expand the M4 in OTHER-CHECKS to perform additional checks of the
|
||||
# `.output' file, which is named `input.output', and/or grammar file,
|
||||
# which is named `input.y'.
|
||||
# '.output' file, which is named 'input.output', and/or grammar file,
|
||||
# which is named 'input.y'.
|
||||
#
|
||||
# Finally, compile the generated parser and then run it using
|
||||
# AT_PARSER_CHECK with PARSER-EXIT-VALUE, PARSER-STDOUT, and
|
||||
@@ -962,7 +1010,7 @@ yylex (void)
|
||||
|
||||
m4_if(m4_index(m4_quote($3), [no-xml]), -1,
|
||||
[AT_BISON_CHECK],
|
||||
[AT_BISON_CHECK_NO_XML])([[--report=all --defines -o input.c input.y]],
|
||||
[AT_BISON_CHECK_NO_XML])([[-Wall --report=all --defines -o input.c input.y]],
|
||||
[0], [], m4_dquote($7))
|
||||
|
||||
m4_if(m4_index(m4_quote($3), [last-state]), -1,
|
||||
@@ -1022,9 +1070,6 @@ m4_define([AT_SETUP],
|
||||
AT_ARG_OPTION([compile-c-with-cxx],
|
||||
[compile C parsers with the C++ compiler])
|
||||
|
||||
AT_ARG_OPTION([release],
|
||||
[check xml and use push for pull])
|
||||
|
||||
AT_COLOR_TESTS
|
||||
|
||||
AT_TESTED([bison])
|
||||
|
||||
+16
-22
@@ -63,7 +63,8 @@ TESTSUITE_AT = \
|
||||
tests/sets.at \
|
||||
tests/skeletons.at \
|
||||
tests/synclines.at \
|
||||
tests/torture.at
|
||||
tests/torture.at \
|
||||
tests/types.at
|
||||
|
||||
TESTSUITE = $(top_srcdir)/tests/testsuite
|
||||
|
||||
@@ -80,17 +81,8 @@ $(TESTSUITE): $(TESTSUITE_AT)
|
||||
## Run the test suite. ##
|
||||
## -------------------- ##
|
||||
|
||||
# Move into tests/ so that testsuite.dir etc. be created there. If a suffix is
|
||||
# specified, create it in a corresponding subdirectory of tests/.
|
||||
RUN_TESTSUITE = dir=tests/$$suf \
|
||||
&& { test -d $$dir || mkdir $$dir; } \
|
||||
&& { test -f $$dir/atconfig \
|
||||
&& diff -q $$dir/atconfig tests/atconfig \
|
||||
|| cp tests/atconfig $$dir; } \
|
||||
&& { test -f $$dir/atlocal \
|
||||
&& diff -q $$dir/atlocal tests/atlocal \
|
||||
|| cp tests/atlocal $$dir; } \
|
||||
&& $(TESTSUITE) -C $$dir $$TESTSUITEFLAGS
|
||||
# Move into tests/ so that testsuite.dir etc. be created there.
|
||||
RUN_TESTSUITE = $(TESTSUITE) -C tests $(TESTSUITEFLAGS)
|
||||
check_SCRIPTS = $(BISON) tests/atconfig tests/atlocal
|
||||
RUN_TESTSUITE_deps = $(TESTSUITE) $(check_SCRIPTS)
|
||||
|
||||
@@ -108,26 +100,28 @@ installcheck-local: $(RUN_TESTSUITE_deps)
|
||||
# Be real mean with it.
|
||||
.PHONY: maintainer-check-g++
|
||||
maintainer-check-g++: $(RUN_TESTSUITE_deps)
|
||||
suf=$@ $(RUN_TESTSUITE) --compile-c-with-cxx
|
||||
$(RUN_TESTSUITE) --compile-c-with-cxx
|
||||
|
||||
.PHONY: maintainer-check-posix
|
||||
maintainer-check-posix: $(RUN_TESTSUITE_deps)
|
||||
suf=$@ $(RUN_TESTSUITE) POSIXLY_CORRECT=1 _POSIX2_VERSION=200112
|
||||
$(RUN_TESTSUITE) POSIXLY_CORRECT=1 _POSIX2_VERSION=200112
|
||||
|
||||
.PHONY: maintainer-check-valgrind
|
||||
maintainer-check-valgrind: $(RUN_TESTSUITE_deps)
|
||||
test -z '$(VALGRIND)' || \
|
||||
suf=$@ $(RUN_TESTSUITE) \
|
||||
$(RUN_TESTSUITE) \
|
||||
PREBISON='$(VALGRIND_PREBISON)' PREPARSER='$(VALGRIND) -q' \
|
||||
VALGRIND_OPTS='--leak-check=full --show-reachable=yes'
|
||||
|
||||
.PHONY: maintainer-check
|
||||
maintainer-check: maintainer-check-posix maintainer-check-valgrind maintainer-check-g++
|
||||
|
||||
.PHONY: maintainer-release-check
|
||||
maintainer-release-check:
|
||||
$(MAKE) $(AM_MAKEFLAGS) \
|
||||
maintainer-check-g++ \
|
||||
maintainer-check-posix \
|
||||
maintainer-check-valgrind \
|
||||
TESTSUITEFLAGS+='--release'
|
||||
.PHONY: maintainer-push-check
|
||||
maintainer-push-check:
|
||||
$(MAKE) $(AM_MAKEFLAGS) maintainer-check \
|
||||
TESTSUITEFLAGS='BISON_USE_PUSH_FOR_PULL=1 $(TESTSUITEFLAGS)'
|
||||
|
||||
.PHONY: maintainer-xml-check
|
||||
maintainer-xml-check:
|
||||
$(MAKE) $(AM_MAKEFLAGS) maintainer-check \
|
||||
TESTSUITEFLAGS='BISON_TEST_XML=1 $(TESTSUITEFLAGS)'
|
||||
|
||||
+7
-2
@@ -62,8 +62,13 @@ AT_CHECK_OUTPUT([foo.y], [], [-dv -o foo.c],
|
||||
[foo.c foo.h foo.output])
|
||||
AT_CHECK_OUTPUT([foo.y], [], [-dv -o foo.tab.c],
|
||||
[foo.output foo.tab.c foo.tab.h])
|
||||
AT_CHECK_OUTPUT([foo.y], [], [-dv -y],
|
||||
[y.output y.tab.c y.tab.h])
|
||||
|
||||
AT_CHECK_OUTPUT([foo.y], [], [-dv -g --xml -y],
|
||||
[y.dot y.output y.tab.c y.tab.h y.xml])
|
||||
# With '-o y.tab.c', we expect 'y.output' etc. (for compatility with Yacc).
|
||||
AT_CHECK_OUTPUT([foo.y], [], [-dv -g --xml -o y.tab.c],
|
||||
[y.dot y.output y.tab.c y.tab.h y.xml])
|
||||
|
||||
AT_CHECK_OUTPUT([foo.y], [], [-dv -b bar],
|
||||
[bar.output bar.tab.c bar.tab.h])
|
||||
AT_CHECK_OUTPUT([foo.y], [], [-dv -g -o foo.c],
|
||||
|
||||
+6
-38
@@ -201,28 +201,6 @@ input.y:14.11-13: warning: rule useless in grammar [-Wother]
|
||||
^^^
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK([[input.y]], 0, [],
|
||||
[[input.y: warning: 9 nonterminals useless in grammar [-Wother]
|
||||
input.y: warning: 9 rules useless in grammar [-Wother]
|
||||
input.y:6.1-8: warning: nonterminal useless in grammar: useless1 [-Wother]
|
||||
input.y:7.1-8: warning: nonterminal useless in grammar: useless2 [-Wother]
|
||||
input.y:8.1-8: warning: nonterminal useless in grammar: useless3 [-Wother]
|
||||
input.y:9.1-8: warning: nonterminal useless in grammar: useless4 [-Wother]
|
||||
input.y:10.1-8: warning: nonterminal useless in grammar: useless5 [-Wother]
|
||||
input.y:11.1-8: warning: nonterminal useless in grammar: useless6 [-Wother]
|
||||
input.y:12.1-8: warning: nonterminal useless in grammar: useless7 [-Wother]
|
||||
input.y:13.1-8: warning: nonterminal useless in grammar: useless8 [-Wother]
|
||||
input.y:14.1-8: warning: nonterminal useless in grammar: useless9 [-Wother]
|
||||
input.y:6.11-13: warning: rule useless in grammar: useless1: '1' [-Wother]
|
||||
input.y:7.11-13: warning: rule useless in grammar: useless2: '2' [-Wother]
|
||||
input.y:8.11-13: warning: rule useless in grammar: useless3: '3' [-Wother]
|
||||
input.y:9.11-13: warning: rule useless in grammar: useless4: '4' [-Wother]
|
||||
input.y:10.11-13: warning: rule useless in grammar: useless5: '5' [-Wother]
|
||||
input.y:11.11-13: warning: rule useless in grammar: useless6: '6' [-Wother]
|
||||
input.y:12.11-13: warning: rule useless in grammar: useless7: '7' [-Wother]
|
||||
input.y:13.11-13: warning: rule useless in grammar: useless8: '8' [-Wother]
|
||||
input.y:14.11-13: warning: rule useless in grammar: useless9: '9' [-Wother]
|
||||
]])
|
||||
|
||||
AT_CHECK([[sed -n '/^Grammar/q;/^$/!p' input.output]], 0,
|
||||
[[Nonterminals useless in grammar
|
||||
@@ -317,16 +295,6 @@ not-reduced.y:17.17-18.63: warning: rule useless in grammar [-Wother]
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK([[not-reduced.y]], 0, [],
|
||||
[[not-reduced.y: warning: 2 nonterminals useless in grammar [-Wother]
|
||||
not-reduced.y: warning: 3 rules useless in grammar [-Wother]
|
||||
not-reduced.y:14.1-13: warning: nonterminal useless in grammar: not_reachable [-Wother]
|
||||
not-reduced.y:11.6-19: warning: nonterminal useless in grammar: non_productive [-Wother]
|
||||
not-reduced.y:11.6-57: warning: rule useless in grammar: exp: non_productive [-Wother]
|
||||
not-reduced.y:14.16-56: warning: rule useless in grammar: not_reachable: useful [-Wother]
|
||||
not-reduced.y:17.17-18.63: warning: rule useless in grammar: non_productive: non_productive useless_token [-Wother]
|
||||
]])
|
||||
|
||||
AT_CHECK([[sed -n '/^Grammar/q;/^$/!p' not-reduced.output]], 0,
|
||||
[[Nonterminals useless in grammar
|
||||
not_reachable
|
||||
@@ -397,9 +365,9 @@ AT_BISON_CHECK([[input.y]], 0, [],
|
||||
input.y: warning: 3 rules useless in grammar [-Wother]
|
||||
input.y:5.15-25: warning: nonterminal useless in grammar: underivable [-Wother]
|
||||
input.y:6.14-24: warning: nonterminal useless in grammar: indirection [-Wother]
|
||||
input.y:5.15-25: warning: rule useless in grammar: exp: underivable [-Wother]
|
||||
input.y:6.14-24: warning: rule useless in grammar: underivable: indirection [-Wother]
|
||||
input.y:7.14-24: warning: rule useless in grammar: indirection: underivable [-Wother]
|
||||
input.y:5.15-25: warning: rule useless in grammar [-Wother]
|
||||
input.y:6.14-24: warning: rule useless in grammar [-Wother]
|
||||
input.y:7.14-24: warning: rule useless in grammar [-Wother]
|
||||
]])
|
||||
|
||||
AT_CHECK([[sed -n '/^Grammar/q;/^$/!p' input.output]], 0,
|
||||
@@ -965,7 +933,7 @@ S: 'a' A 'a'
|
||||
A: 'a' 'a' B
|
||||
;
|
||||
B: 'a'
|
||||
| %prec 'a'
|
||||
| %empty %prec 'a'
|
||||
;
|
||||
c: 'a' 'a' 'b'
|
||||
| A
|
||||
@@ -1565,8 +1533,8 @@ a: 'a' ;
|
||||
and multiple reductions. The first reduction has more lookaheads than the
|
||||
second, so the first should always be preferred as the default reduction if
|
||||
enabled. The second reduction has one lookahead. */
|
||||
b: ;
|
||||
c: ;
|
||||
b: %empty;
|
||||
c: %empty;
|
||||
]],
|
||||
dnl Visit each state mentioned above.
|
||||
[['a', 'a']],
|
||||
|
||||
+15
-15
@@ -263,11 +263,11 @@ AT_CHECK([cat input.output], [],
|
||||
|
||||
0 $accept: expr $end
|
||||
|
||||
1 $@1: /* empty */
|
||||
1 $@1: %empty
|
||||
|
||||
2 expr: 'a' $@1 'b'
|
||||
|
||||
3 $@2: /* empty */
|
||||
3 $@2: %empty
|
||||
|
||||
4 expr: $@2 'c'
|
||||
|
||||
@@ -373,13 +373,13 @@ AT_DATA([input.y],
|
||||
%token <operator> LE 134 "<="
|
||||
%left OR "<="
|
||||
%%
|
||||
exp: ;
|
||||
exp: %empty;
|
||||
%%
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK([-v -o input.c input.y], 0, [],
|
||||
[[input.y:1.29-32: warning: useless associativity for "||" [-Wother]
|
||||
input.y:2.29-32: warning: useless associativity for "<=" [-Wother]
|
||||
AT_BISON_CHECK([-v -Wall -o input.c input.y], 0, [],
|
||||
[[input.y:3.1-5: warning: useless precedence and associativity for "||" [-Wprecedence]
|
||||
input.y:3.1-5: warning: useless precedence and associativity for "<=" [-Wprecedence]
|
||||
]])
|
||||
|
||||
AT_CLEANUP
|
||||
@@ -573,7 +573,7 @@ AT_CHECK([cat input.output], 0,
|
||||
2 CONST_DEC_LIST: CONST_DEC
|
||||
3 | CONST_DEC_LIST CONST_DEC
|
||||
|
||||
4 $@1: /* empty */
|
||||
4 $@1: %empty
|
||||
|
||||
5 CONST_DEC: $@1 undef_id_tok '=' const_id_tok ';'
|
||||
|
||||
@@ -721,7 +721,7 @@ AT_KEYWORDS([report])
|
||||
AT_DATA([input.y],
|
||||
[[%%
|
||||
statement: struct_stat;
|
||||
struct_stat: /* empty. */ | if else;
|
||||
struct_stat: %empty | if else;
|
||||
if: "if" "const" "then" statement;
|
||||
else: "else" statement;
|
||||
%%
|
||||
@@ -869,7 +869,7 @@ type: DATA
|
||||
| INVALID
|
||||
;
|
||||
|
||||
body: /* empty */
|
||||
body: %empty
|
||||
| body member
|
||||
;
|
||||
|
||||
@@ -929,7 +929,7 @@ $1
|
||||
%token B
|
||||
|
||||
%%
|
||||
program: /* empty */
|
||||
program: %empty
|
||||
| program e ';'
|
||||
| program error ';';
|
||||
|
||||
@@ -1145,15 +1145,15 @@ sr_conflict:
|
||||
]AT_YYLEX_DEFINE([{ 1, 2, 3, 0 }])[
|
||||
]AT_MAIN_DEFINE[
|
||||
]])
|
||||
AT_BISON_OPTION_POPDEFS
|
||||
|
||||
AT_BISON_CHECK([[-o input.c input.y]], [[0]],,
|
||||
[[input.y:24.5-19: warning: rule useless in parser due to conflicts: start: start [-Wother]
|
||||
input.y:28.5-19: warning: rule useless in parser due to conflicts: sr_conflict: TK2 "tok alias" [-Wother]
|
||||
input.y:18.7-9: warning: useless associativity for TK1 [-Wother]
|
||||
AT_BISON_CHECK([[-Wall -o input.c input.y]], [[0]],,
|
||||
[[input.y:24.5-19: warning: rule useless in parser due to conflicts [-Wother]
|
||||
input.y:28.5-19: warning: rule useless in parser due to conflicts [-Wother]
|
||||
input.y:18.1-5: warning: useless precedence and associativity for TK1 [-Wprecedence]
|
||||
]])
|
||||
AT_COMPILE([[input]])
|
||||
AT_PARSER_CHECK([[./input]])
|
||||
AT_BISON_OPTION_POPDEFS
|
||||
|
||||
AT_CLEANUP
|
||||
|
||||
|
||||
+5
-5
@@ -86,7 +86,7 @@ AT_CHECK([[cat sets]], [],
|
||||
0 e $end
|
||||
e derives
|
||||
1 'e'
|
||||
2 /* empty */
|
||||
2 %empty
|
||||
NULLABLE
|
||||
$accept: no
|
||||
e: yes
|
||||
@@ -100,10 +100,10 @@ FDERIVES
|
||||
$accept derives
|
||||
0 e $end
|
||||
1 'e'
|
||||
2 /* empty */
|
||||
2 %empty
|
||||
e derives
|
||||
1 'e'
|
||||
2 /* empty */
|
||||
2 %empty
|
||||
]])
|
||||
|
||||
AT_CLEANUP
|
||||
@@ -113,7 +113,7 @@ AT_CLEANUP
|
||||
## Broken Closure. ##
|
||||
## ---------------- ##
|
||||
|
||||
# TC was once broken during a massive `simplification' of the code.
|
||||
# TC was once broken during a massive 'simplification' of the code.
|
||||
# It resulted in bison dumping core on the following grammar (the
|
||||
# computation of FIRSTS uses TC). It managed to produce a pretty
|
||||
# exotic closure:
|
||||
@@ -263,7 +263,7 @@ AT_CLEANUP
|
||||
# In some weird cases Bison could compute an incorrect final state
|
||||
# number. This happens only if the $end token is used in the user
|
||||
# grammar, which is a very suspicious accidental feature introduced as
|
||||
# a side effect of allowing the user to name $end using `%token END 0
|
||||
# a side effect of allowing the user to name $end using '%token END 0
|
||||
# "end of file"'.
|
||||
|
||||
AT_SETUP([Accept])
|
||||
|
||||
+1
-1
@@ -23,7 +23,7 @@ AT_BANNER([[User Actions.]])
|
||||
# --------------------------
|
||||
# Compile FILE expecting an error, and save in the file stdout the
|
||||
# normalized output. Ignore the exit status, since some compilers
|
||||
# (e.g. c89 on IRIX 6.5) trigger warnings on `#error', instead of
|
||||
# (e.g. c89 on IRIX 6.5) trigger warnings on '#error', instead of
|
||||
# errors.
|
||||
m4_define([AT_SYNCLINES_COMPILE],
|
||||
[AT_CHECK([$CC $CFLAGS $CPPFLAGS -c $1], [ignore], [], [stderr])
|
||||
|
||||
+5
-2
@@ -35,6 +35,9 @@ m4_include([sets.at])
|
||||
# Testing grammar reduction.
|
||||
m4_include([reduce.at])
|
||||
|
||||
# Testing conflicts detection and resolution.
|
||||
m4_include([conflicts.at])
|
||||
|
||||
# Testing that #lines are correct.
|
||||
m4_include([synclines.at])
|
||||
|
||||
@@ -44,8 +47,8 @@ m4_include([headers.at])
|
||||
# Testing that user actions are properly performed.
|
||||
m4_include([actions.at])
|
||||
|
||||
# Testing conflicts detection and resolution.
|
||||
m4_include([conflicts.at])
|
||||
# Testing semantic types support.
|
||||
m4_include([types.at])
|
||||
|
||||
# Fulling testing (compilation and execution of the parser) on calc.
|
||||
m4_include([calc.at])
|
||||
|
||||
+230
@@ -0,0 +1,230 @@
|
||||
# Value type. -*- Autotest -*-
|
||||
|
||||
# Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
AT_BANNER([[Value type tests.]])
|
||||
|
||||
|
||||
## ----------------------------------- ##
|
||||
## %union vs. %define api.value.type. ##
|
||||
## ----------------------------------- ##
|
||||
|
||||
AT_SETUP([[%union vs. %define api.value.type]])
|
||||
|
||||
AT_DATA([[input.y]],
|
||||
[[%union { int ival; }
|
||||
%define api.value.type union-directive
|
||||
%%
|
||||
exp: %empty;
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK([[input.y]], [[1]], [[]],
|
||||
[[input.y:2.9-22: error: '%union' and '%define api.value.type' cannot be used together
|
||||
]])
|
||||
|
||||
AT_CLEANUP
|
||||
|
||||
## ---------------------------------------- ##
|
||||
## %yacc vs. %define api.value.type union. ##
|
||||
## ---------------------------------------- ##
|
||||
|
||||
AT_SETUP([[%yacc vs. %define api.value.type union]])
|
||||
|
||||
AT_DATA([[input.y]],
|
||||
[[%yacc
|
||||
%define api.value.type union
|
||||
%%
|
||||
exp: %empty;
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK([[input.y]], [[1]], [[]],
|
||||
[[input.y:2.9-22: error: '%yacc' and '%define api.value.type "union"' cannot be used together
|
||||
]])
|
||||
|
||||
AT_CLEANUP
|
||||
|
||||
|
||||
## ---------------- ##
|
||||
## api.value.type. ##
|
||||
## ---------------- ##
|
||||
|
||||
# AT_TEST($1: BISON-DIRECTIVES,
|
||||
# $2: MORE-BISON-DIRECTIVES,
|
||||
# $3: PARSER-ACTION,
|
||||
# $4: INPUT, $5: SCANNER-ACTION,
|
||||
# $6: RESULT)
|
||||
# --------------------------------------
|
||||
# Compile the grammar and check the expected result.
|
||||
# BISON-DIRECTIVES are passed to AT_SETUP, contrary to MORE-BISON-DIRECTIVES.
|
||||
m4_pushdef([AT_TEST],
|
||||
[
|
||||
AT_SETUP([$1])
|
||||
AT_KEYWORDS([api.value.type])
|
||||
AT_BISON_OPTION_PUSHDEFS([%debug $1 $2])
|
||||
AT_DATA_GRAMMAR([test.y],
|
||||
[[%debug
|
||||
|
||||
%code
|
||||
{
|
||||
# include <stdio.h>
|
||||
# include <stdlib.h>
|
||||
]AT_YYERROR_DECLARE[
|
||||
]AT_YYLEX_DECLARE[
|
||||
}
|
||||
|
||||
]$1[
|
||||
]$2[
|
||||
|
||||
%%
|
||||
|
||||
start: $3;
|
||||
|
||||
%%
|
||||
]AT_YYERROR_DEFINE[
|
||||
]AT_YYLEX_DEFINE([$4], [$5])[
|
||||
]AT_MAIN_DEFINE[
|
||||
]])
|
||||
|
||||
AT_FULL_COMPILE([[test]])
|
||||
AT_PARSER_CHECK([./test], 0, [$6
|
||||
], [stderr])
|
||||
AT_BISON_OPTION_POPDEFS
|
||||
AT_CLEANUP
|
||||
])
|
||||
|
||||
m4_foreach([b4_skel], [[yacc.c], [glr.c], [lalr1.cc], [glr.cc]],
|
||||
[# A built-in type.
|
||||
AT_TEST([%skeleton "]b4_skel["
|
||||
%define api.value.type {double}],
|
||||
[],
|
||||
['1' '2' { printf ("%2.1f\n", $1 + $2); }],
|
||||
["12"],
|
||||
[AT_VAL = (res - '0') / 10.0],
|
||||
[0.3])
|
||||
|
||||
# A typedef which looks like a Bison keyword, but it's using braces.
|
||||
AT_TEST([%skeleton "]b4_skel["
|
||||
%define api.value.type {variant}],
|
||||
[%code requires { typedef double variant; }],
|
||||
['1' '2' { printf ("%2.1f\n", $1 + $2); }],
|
||||
["12"],
|
||||
[AT_VAL = (res - '0') / 10.0],
|
||||
[0.3])
|
||||
|
||||
# A user defined struct.
|
||||
AT_TEST([%skeleton "]b4_skel["
|
||||
%define api.value.type {struct foo}],
|
||||
[%code requires { struct foo { float fval; int ival; }; }],
|
||||
['1' '2'
|
||||
{ printf ("%d %2.1f\n", $1.ival + $2.ival, $1.fval + $2.fval); }],
|
||||
["12"],
|
||||
[AT_VAL.ival = (res - '0') * 10;
|
||||
AT_VAL.fval = (res - '0') / 10.f],
|
||||
[30 0.3])
|
||||
|
||||
# A user defined struct that uses pointers.
|
||||
AT_TEST([%skeleton "]b4_skel["
|
||||
%define api.value.type {struct bar}],
|
||||
[%code requires
|
||||
{
|
||||
struct u
|
||||
{
|
||||
int ival;
|
||||
};
|
||||
struct bar
|
||||
{
|
||||
struct u *up;
|
||||
};
|
||||
}
|
||||
%token <up->ival> '1' '2'
|
||||
%printer { ]AT_SKEL_CC_IF([[yyoutput << $$]],
|
||||
[[fprintf (yyo, "%d", $$)]])[; } <up->ival>
|
||||
],
|
||||
['1' '2'
|
||||
{
|
||||
printf ("%d %d\n", $1, $<up->ival>2);
|
||||
free ($<up>1);
|
||||
free ($<up>2);
|
||||
}],
|
||||
["12"],
|
||||
[AT_VAL.up = (struct u *) malloc (sizeof *AT_VAL.up);
|
||||
assert (AT_VAL.up);
|
||||
AT_VAL.up->ival = res - '0';],
|
||||
[1 2])
|
||||
|
||||
# A user defined union.
|
||||
AT_TEST([%skeleton "]b4_skel["
|
||||
%define api.value.type {union foo}],
|
||||
[%code requires { union foo { float fval; int ival; }; }],
|
||||
['1' '2' { printf ("%d %2.1f\n", $1.ival, $2.fval); }],
|
||||
["12"],
|
||||
[if (res == '1')
|
||||
AT_VAL.ival = 10;
|
||||
else
|
||||
AT_VAL.fval = .2f],
|
||||
[10 0.2])
|
||||
|
||||
# A %union.
|
||||
AT_TEST([%skeleton "]b4_skel["
|
||||
%union { float fval; int ival; };],
|
||||
[%token <ival> '1';
|
||||
%token <fval> '2';],
|
||||
['1' '2' { printf ("%d %2.1f\n", $1, $2); }],
|
||||
["12"],
|
||||
[if (res == '1')
|
||||
AT_VAL.ival = 10;
|
||||
else
|
||||
AT_VAL.fval = 0.2f],
|
||||
[10 0.2])
|
||||
|
||||
# A Bison-defined union.
|
||||
# The tokens names are not available directly in C++, we use their
|
||||
# user number to keep it simple between C and C++.
|
||||
AT_TEST([%skeleton "]b4_skel["
|
||||
%define api.value.type union],
|
||||
[%token <int> ONE 101;
|
||||
%token <float> TWO 102 THREE 103;
|
||||
%printer { ]AT_SKEL_CC_IF([[yyoutput << $$]],
|
||||
[[fprintf (yyo, "%d", $$)]])[; } <int>
|
||||
%printer { ]AT_SKEL_CC_IF([[yyoutput << $$]],
|
||||
[[fprintf (yyo, "%f", $$)]])[; } <float>
|
||||
],
|
||||
[ONE TWO THREE { printf ("%d %2.1f %2.1f\n", $1, $2, $3); }],
|
||||
[{ 101, 102, 103, EOF }],
|
||||
[if (res == 101)
|
||||
AT_VAL.ONE = 10;
|
||||
else if (res == 102)
|
||||
AT_VAL.TWO = .2f;
|
||||
else if (res == 103)
|
||||
AT_VAL.THREE = 3.3f],
|
||||
[10 0.2 3.3])
|
||||
|
||||
# A Bison-defined variant, for lalr1.cc only.
|
||||
m4_if(b4_skel, [lalr1.cc], [
|
||||
AT_TEST([%skeleton "]b4_skel["
|
||||
%define api.value.type variant],
|
||||
[%token <int> '1';
|
||||
%token <std::string> '2';],
|
||||
['1' '2' { std::cout << $1 << ", " << $2 << std::endl; }],
|
||||
["12"],
|
||||
[if (res == '1')
|
||||
AT_VAL.build(10);
|
||||
else
|
||||
AT_VAL.build<std::string>("two");],
|
||||
[10, two])])
|
||||
])
|
||||
|
||||
m4_popdef([AT_TEST])
|
||||
Reference in New Issue
Block a user