Compare commits

..
Author SHA1 Message Date
Theophile Ranquet fcf845a716 testsuite: introduce --release
* tests/atlocal.in, tests/local.at: Support option --release, which sets
BISON_USE_PUSH_FOR_PULL and BISON_TEST_XML.
* tests/local.mk: Use it for maintainer-release-check.
2013-01-31 17:48:52 +01:00
Theophile Ranquet 3158164614 build: run checks in distinct directories
* tests/local.mk (maintainer-release-check) Import this rule from maint. Run
maintainer-checks in separate directories.
* configure.ac (AC_CONFIG_TESTDIR), tests/local.at: Adjust paths.
2013-01-31 17:48:52 +01:00
89 changed files with 3104 additions and 4788 deletions
+1 -1
View File
@@ -1 +1 @@
2.7.1 2.7
+4 -4
View File
@@ -32,8 +32,8 @@ EXTRA_DIST = .prev-version .version \
## version of Bison nearby... ## version of Bison nearby...
BISON = $(top_builddir)/tests/bison BISON = $(top_builddir)/tests/bison
BISON_IN = $(top_srcdir)/tests/bison.in BISON_IN = $(top_srcdir)/tests/bison.in
YACC = $(BISON) -o y.tab.c YACC = $(BISON) -y
AM_YFLAGS = -d -v -Werror -Wall -Wno-yacc --report=all AM_YFLAGS = -d -v --warnings=all,error --report=all
# Initialization before completion by local.mk's. # Initialization before completion by local.mk's.
AM_CFLAGS = $(WARN_CFLAGS) AM_CFLAGS = $(WARN_CFLAGS)
@@ -78,11 +78,11 @@ dist-hook: gen-ChangeLog
.PHONY: update-b4-copyright update-package-copyright-year .PHONY: update-b4-copyright update-package-copyright-year
update-b4-copyright: update-b4-copyright:
$(AM_V_GEN)find $(srcdir)/data -type f \ find $(srcdir)/data -type f \
| xargs $(srcdir)/build-aux/$@ | xargs $(srcdir)/build-aux/$@
@echo 'warning: src/parse-gram.[hc] may need to be regenerated.' @echo 'warning: src/parse-gram.[hc] may need to be regenerated.'
update-package-copyright-year: update-package-copyright-year:
$(AM_V_GEN)$(srcdir)/build-aux/$@ $(srcdir)/configure.ac $(srcdir)/build-aux/$@ $(srcdir)/configure.ac
gen_start_date = 2012-01-16 gen_start_date = 2012-01-16
.PHONY: gen-ChangeLog .PHONY: gen-ChangeLog
+59 -365
View File
@@ -1,9 +1,17 @@
GNU Bison NEWS GNU Bison NEWS
* Noteworthy changes in release 2.7.90 (2013-05-30) [beta] * Noteworthy changes in release ?.? (????-??-??) [?]
** WARNING: Future backward-incompatibilities! ** 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 Like other GNU packages, Bison will start using some of the C99 features
for its own code, especially the definition of variables after statements. for its own code, especially the definition of variables after statements.
The generated C parsers still aim at C90. The generated C parsers still aim at C90.
@@ -20,32 +28,9 @@ GNU Bison NEWS
Support for YYLEX_PARAM and YYPARSE_PARAM is removed (deprecated in Bison Support for YYLEX_PARAM and YYPARSE_PARAM is removed (deprecated in Bison
1.875): use %lex-param, %parse-param, or %param. 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 ** Bug fixes
*** The epilogue is no longer affected by internal #defines (glr.c) *** The epilogue is no longer affected by internal #defines
The glr.c skeleton uses defines such as #define yylval (yystackp->yyval) in The glr.c skeleton uses defines such as #define yylval (yystackp->yyval) in
generated code. These weren't properly undefined before the inclusion of generated code. These weren't properly undefined before the inclusion of
@@ -54,7 +39,7 @@ GNU Bison NEWS
int yylex (YYSTYPE *yylval); int yylex (YYSTYPE *yylval);
This is fixed: yylval, yynerrs, yychar, and yylloc are now valid This is has been fixed: yylval, yynerrs, yychar, and yylloc are now valid
identifiers for user-provided variables. identifiers for user-provided variables.
*** stdio.h is no longer needed when locations are enabled (yacc.c) *** stdio.h is no longer needed when locations are enabled (yacc.c)
@@ -62,8 +47,6 @@ GNU Bison NEWS
Changes in Bison 2.7 introduced a dependency on FILE and fprintf when Changes in Bison 2.7 introduced a dependency on FILE and fprintf when
locations are enabled. This is fixed. locations are enabled. This is fixed.
*** Warnings about useless %pure-parser/%define api.pure are restored
** Diagnostics reported by Bison ** Diagnostics reported by Bison
Most of these features were contributed by Théophile Ranquet and Victor Most of these features were contributed by Théophile Ranquet and Victor
@@ -75,29 +58,6 @@ GNU Bison NEWS
activated by default. The old format can still be used by invoking Bison activated by default. The old format can still be used by invoking Bison
with -fno-caret (or -fnone). 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 *** Enhancements of the -Werror option
The -Werror=CATEGORY option is now recognized, and will treat specified The -Werror=CATEGORY option is now recognized, and will treat specified
@@ -238,10 +198,12 @@ GNU Bison NEWS
bar.y: error: shift/reduce conflicts: 1 found, 0 expected bar.y: error: shift/reduce conflicts: 1 found, 0 expected
bar.y: error: reduce/reduce conflicts: 2 found, 0 expected bar.y: error: reduce/reduce conflicts: 2 found, 0 expected
** Incompatibilities with POSIX Yacc *** Useless precedence
The 'yacc' category is no longer part of '-Wall', enable it explicitly Bison now warns about symbols with a declared precedence but no declared
with '-Wyacc'. associativity (i.e. declared with %precedence), and whose precedence is
never used. In that case, the symbol can be safely declared with %token
instead, without modifying the parsing tables.
** Additional yylex/yyparse arguments ** Additional yylex/yyparse arguments
@@ -258,262 +220,6 @@ GNU Bison NEWS
%param {arg1_type *arg1} {arg2_type *arg2} %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 ** Java skeleton improvements
Contributed by Paolo Bonzini. Contributed by Paolo Bonzini.
@@ -543,66 +249,59 @@ GNU Bison NEWS
used by the scanner, or rejecting invalid combinations from a used by the scanner, or rejecting invalid combinations from a
factory invoked by the user actions). factory invoked by the user actions).
*** %define api.value.type variant ** Renamed %define variables
This is based on a submission from Michiel De Wilde. With help The following variables have been renamed for consistency. Backward
from Théophile Ranquet. compatibility is ensured, but upgrading is recommended.
In this mode, complex C++ objects can be used as semantic values. For lr.default-reductions -> lr.default-reduction
instance: lr.keep-unreachable-states -> lr.keep-unreachable-state
namespace -> api.namespace
stype -> api.value.type
%token <::std::string> TEXT; ** Variable api.token.prefix
%token <int> NUMBER;
%token SEMICOLON ";" The variable api.token.prefix changes the way tokens are identified in
%type <::std::string> item; the generated files. This is especially useful to avoid collisions
%type <::std::list<std::string>> list; with identifiers in the target language. For instance
%token FILE for ERROR
%define api.token.prefix "TOK_"
%% %%
result: start: FILE for ERROR;
list { std::cout << $1 << std::endl; }
;
list: will generate the definition of the symbols TOK_FILE, TOK_for, and
%empty { /* Generates an empty string list. */ } TOK_ERROR in the generated sources. In particular, the scanner must
| list item ";" { std::swap ($$, $1); $$.push_back ($2); } use these prefixed token names, although the grammar itself still
; uses the short names (as in the sample rule given above).
item: ** Variable parse.error
TEXT { std::swap ($$, $1); }
| NUMBER { $$ = string_cast ($1); }
;
*** %define api.token.constructor This variable controls the verbosity of error messages. The use of the
%error-verbose directive is deprecated in favor of "%define parse.error
verbose".
When variants are enabled, Bison can generate functions to build the ** Semantic predicates
tokens. This guarantees that the token type (e.g., NUMBER) is consistent
with the semantic value (e.g., int):
parser::symbol_type yylex () Contributed by Paul Hilfinger.
{
parser::location_type loc = ...;
...
return parser::make_TEXT ("Hello, world!", loc);
...
return parser::make_NUMBER (42, loc);
...
return parser::make_SEMICOLON (loc);
...
}
*** C++ locations 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.
There are operator- and operator-= for 'location'. Negative line/column ** The directive %expect-rr is now an error in non GLR mode
increments can no longer underflow the resulting value.
* Noteworthy changes in release 2.7.1 (2013-04-15) [stable] It used to be an error only if used in non GLR mode, _and_ if there are
reduce/reduce conflicts.
** Bug fixes ** Token numbering has changed to preserve the user-defined order
*** Fix compiler attribute portability (yacc.c) 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,
With locations enabled, __attribute__ was used unprotected. %precedence, %nonassoc), B was inferior to A.
*** Fix some compiler warnings (lalr1.cc)
* Noteworthy changes in release 2.7 (2012-12-12) [stable] * Noteworthy changes in release 2.7 (2012-12-12) [stable]
@@ -654,8 +353,8 @@ GNU Bison NEWS
exp: exp '+' exp { $exp = $1 + $3; }; exp: exp '+' exp { $exp = $1 + $3; };
^^^ ^^^
The default behavior for now is still not to display these unless The default behaviour for now is still not to display these unless
explicitly asked with -fcaret (or -fall). However, in a later release, it explictly asked with -fcaret (or -fall). However, in a later release, it
will be made the default behavior (but may still be deactivated with will be made the default behavior (but may still be deactivated with
-fno-caret). -fno-caret).
@@ -742,7 +441,7 @@ GNU Bison NEWS
Other issues in the test suite have been addressed. Other issues in the test suite have been addressed.
Null characters are correctly displayed in error messages. Nul characters are correctly displayed in error messages.
When possible, yylloc is correctly initialized before calling yylex. It When possible, yylloc is correctly initialized before calling yylex. It
is no longer necessary to initialize it in the %initial-action. is no longer necessary to initialize it in the %initial-action.
@@ -2658,12 +2357,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
LocalWords: Automake TMPDIR LESSEQ ylwrap endif yydebug YYTOKEN YYLSP ival hh LocalWords: Automake TMPDIR LESSEQ ylwrap endif yydebug YYTOKEN YYLSP ival hh
LocalWords: extern YYTOKENTYPE TOKENTYPE yytokentype tokentype STYPE lval pdf LocalWords: extern YYTOKENTYPE TOKENTYPE yytokentype tokentype STYPE lval pdf
LocalWords: lang yyoutput dvi html ps POSIX lvalp llocp Wother nterm arg init LocalWords: lang yyoutput dvi html ps POSIX lvalp llocp Wother nterm arg init
LocalWords: TOK calc yyo fval Wconflicts parsers yystackp yyval yynerrs LocalWords: TOK calc yyo fval Wconflicts
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: Local Variables:
mode: outline mode: outline
+1 -1
View File
@@ -30,7 +30,7 @@ not answer them, please send mail to <[email protected]>.
* Bug reports * Bug reports
Please send bug reports to <[email protected]>. Please include the 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. test case in each bug report.
* Copyright statements * Copyright statements
+1 -1
View File
@@ -9,7 +9,7 @@ Bison supports the @N construction, which gives you access to
the starting and ending line number and character number associated the starting and ending line number and character number associated
with any of the symbols in the current rule. 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 the conflicts if there are N shift/reduce conflicts and no reduce/reduce
conflicts. conflicts.
-6
View File
@@ -29,7 +29,6 @@ Cris Bailiff [email protected]
Cris van Pelt [email protected] Cris van Pelt [email protected]
Csaba Raduly [email protected] Csaba Raduly [email protected]
Dagobert Michelsen [email protected] Dagobert Michelsen [email protected]
Daniel Frużyński [email protected]
Daniel Hagerty [email protected] Daniel Hagerty [email protected]
David J. MacKenzie [email protected] David J. MacKenzie [email protected]
David Kastrup [email protected] David Kastrup [email protected]
@@ -38,7 +37,6 @@ Derek M. Jones [email protected]
Di-an Jan [email protected] Di-an Jan [email protected]
Dick Streefland [email protected] Dick Streefland [email protected]
Didier Godefroy [email protected] Didier Godefroy [email protected]
Efi Fogel [email protected]
Enrico Scholz [email protected] Enrico Scholz [email protected]
Eric Blake [email protected] Eric Blake [email protected]
Evgeny Stambulchik [email protected] Evgeny Stambulchik [email protected]
@@ -46,7 +44,6 @@ Fabrice Bauzac [email protected]
Florian Krohm [email protected] Florian Krohm [email protected]
Frank Heckenbach [email protected] Frank Heckenbach [email protected]
Frans Englich [email protected] Frans Englich [email protected]
Gabriel Rassoul [email protected]
Georg Sauthoff [email protected] Georg Sauthoff [email protected]
George Neuner [email protected] George Neuner [email protected]
Gilles Espinasse [email protected] Gilles Espinasse [email protected]
@@ -100,7 +97,6 @@ Peter Eisentraut [email protected]
Peter Fales [email protected] Peter Fales [email protected]
Peter Hamorsky [email protected] Peter Hamorsky [email protected]
Peter Simons [email protected] Peter Simons [email protected]
Petr Machata [email protected]
Piotr Gackiewicz [email protected] Piotr Gackiewicz [email protected]
Quentin Hocquet [email protected] Quentin Hocquet [email protected]
Quoc Peyrot [email protected] Quoc Peyrot [email protected]
@@ -110,7 +106,6 @@ Ralf Wildenhues [email protected]
Richard Stallman [email protected] Richard Stallman [email protected]
Rob Vermaas [email protected] Rob Vermaas [email protected]
Robert Anisko [email protected] Robert Anisko [email protected]
Rob Conde [email protected]
Roland Levillain [email protected] Roland Levillain [email protected]
Satya Kiran Popuri [email protected] Satya Kiran Popuri [email protected]
Sebastian Setzer [email protected] Sebastian Setzer [email protected]
@@ -131,7 +126,6 @@ Tommy Nordgren [email protected]
Troy A. Johnson [email protected] Troy A. Johnson [email protected]
Tys Lefering [email protected] Tys Lefering [email protected]
Valentin Tolmer [email protected] Valentin Tolmer [email protected]
Victor Khomenko [email protected]
Vin Shelton [email protected] Vin Shelton [email protected]
W.C.A. Wijngaards [email protected] W.C.A. Wijngaards [email protected]
Wayne Green [email protected] Wayne Green [email protected]
+12 -23
View File
@@ -1,27 +1,16 @@
* Short term * Short term
** Graphviz display code thoughts ** Graphviz display code thoughts
The code for the --graph option is over two files: print_graph, and The code for the --graph option is over two files: print_graph, and
graphviz. This is because Bison used to also produce VCG graphs, but since graphviz. I believe this is because Bison used to also produce VCG graphs,
this is no longer true, maybe we could consider these files for fusion. but since this is no longer true, maybe we could consider these files for
fusion.
An other consideration worth noting is that print_graph.c (correct me if I Little effort factoring seems to have been given to factoring in these files,
am wrong) should contain generic functions, whereas graphviz.c and other and their print-xml and print counterpart. We would very much like to re-use
potential files should contain just the specific code for that output the pretty format of states from .output in the .dot
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.
Little effort seems to have been given to factoring these files and their Also, the underscore in print_graph.[ch] isn't very fitting considering
rint{,-xml} counterpart. We would very much like to re-use the pretty format the dashes in the other filenames.
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 ** push-parser
Check it too when checking the different kinds of parsers. And be Check it too when checking the different kinds of parsers. And be
@@ -176,13 +165,13 @@ part of $default. Should we make the two reductions explicit, or just
keep $default? See the following point. keep $default? See the following point.
** Disabled Reductions ** 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. what we want to do.
** Documentation ** Documentation
Extend with error productions. The hard part will probably be finding 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 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 presented too. Shall we try to make a single grammar with all these
features, or should we have several very small grammars? features, or should we have several very small grammars?
@@ -243,9 +232,9 @@ into
exp: exp '+' exp | exp '&' exp; exp: exp '+' exp | exp '&' exp;
when there are no actions. This can significantly speed up some 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: 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? this issue. Does anybody have it?
+31 -36
View File
@@ -1,6 +1,6 @@
#! /bin/sh #! /bin/sh
# Print a version string. # Print a version string.
scriptversion=2013-05-08.20; # UTC scriptversion=2012-12-28.10; # UTC
# Bootstrap this package from checked-out sources. # Bootstrap this package from checked-out sources.
@@ -140,21 +140,20 @@ po_download_command_format2=\
"wget --mirror -nd -q -np -A.po -P '%s' \ "wget --mirror -nd -q -np -A.po -P '%s' \
http://translationproject.org/latest/%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=' extract_package_name='
/^AC_INIT(\[*/{ /^AC_INIT(/{
s/// /.*,.*,.*, */{
/^[^,]*,[^,]*,[^,]*,[ []*\([^][ ,)]\)/{ s///
s//\1/ s/[][]//g
s/[],)].*// s/)$//
p p
q q
} }
s/[],)].*// s/AC_INIT(\[*//
s/]*,.*//
s/^GNU // s/^GNU //
y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/
s/[^abcdefghijklmnopqrstuvwxyz0123456789_]/-/g s/[^A-Za-z0-9_]/-/g
p p
} }
' '
@@ -307,34 +306,34 @@ if test -n "$checkout_only_file" && test ! -r "$checkout_only_file"; then
die "Bootstrapping from a non-checked-out distribution is risky." die "Bootstrapping from a non-checked-out distribution is risky."
fi fi
# Strip blank and comment lines to leave significant entries. # Ensure that lines starting with ! sort last, per gitignore conventions
gitignore_entries() { # for whitelisting exceptions after a more generic blacklist pattern.
sed '/^#/d; /^$/d' "$@" sort_patterns() {
sort -u "$@" | sed '/^!/ {
H
d
}
$ {
P
x
s/^\n//
}' | sed '/^$/d'
} }
# If $STR is not already on a line by itself in $FILE, insert it at the start. # If $STR is not already on a line by itself in $FILE, insert it,
# Entries are inserted at the start of the ignore list to ensure existing # sorting the new contents of the file and replacing $FILE with the result.
# entries starting with ! are not overridden. Such entries support insert_sorted_if_absent() {
# whitelisting exceptions after a more generic blacklist pattern.
insert_if_absent() {
file=$1 file=$1
str=$2 str=$2
test -f $file || touch $file test -f $file || touch $file
test -r $file || die "Error: failed to read ignore file: $file" echo "$str" | sort_patterns - $file | cmp -s - $file > /dev/null \
duplicate_entries=$(gitignore_entries $file | sort | uniq -d) || { echo "$str" | sort_patterns - $file > $file.bak \
if [ "$duplicate_entries" ] ; then && mv $file.bak $file; } \
die "Error: Duplicate entries in $file: " $duplicate_entries || die "insert_sorted_if_absent $file $str: failed"
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 # Adjust $PATTERN for $VC_IGNORE_FILE and insert it with
# insert_if_absent. # insert_sorted_if_absent.
insert_vc_ignore() { insert_vc_ignore() {
vc_ignore_file="$1" vc_ignore_file="$1"
pattern="$2" pattern="$2"
@@ -345,7 +344,7 @@ insert_vc_ignore() {
# .gitignore entry. # .gitignore entry.
pattern=$(echo "$pattern" | sed s,^,/,);; pattern=$(echo "$pattern" | sed s,^,/,);;
esac esac
insert_if_absent "$vc_ignore_file" "$pattern" insert_sorted_if_absent "$vc_ignore_file" "$pattern"
} }
# Die if there is no AC_CONFIG_AUX_DIR($build_aux) line in configure.ac. # Die if there is no AC_CONFIG_AUX_DIR($build_aux) line in configure.ac.
@@ -631,13 +630,9 @@ esac
if $bootstrap_sync; then if $bootstrap_sync; then
cmp -s "$0" "$GNULIB_SRCDIR/build-aux/bootstrap" || { cmp -s "$0" "$GNULIB_SRCDIR/build-aux/bootstrap" || {
echo "$0: updating bootstrap and restarting..." echo "$0: updating bootstrap and restarting..."
case $(sh -c 'echo "$1"' -- a) in
a) ignored=--;;
*) ignored=ignored;;
esac
exec sh -c \ exec sh -c \
'cp "$1" "$2" && shift && exec "${CONFIG_SHELL-/bin/sh}" "$@"' \ 'cp "$1" "$2" && shift && exec "${CONFIG_SHELL-/bin/sh}" "$@"' \
$ignored "$GNULIB_SRCDIR/build-aux/bootstrap" \ -- "$GNULIB_SRCDIR/build-aux/bootstrap" \
"$0" "$@" --no-bootstrap-sync "$0" "$@" --no-bootstrap-sync
} }
fi fi
+2
View File
@@ -1,3 +1,5 @@
## Makefile for Bison testsuite.
# Copyright (C) 2000-2013 Free Software Foundation, Inc. # Copyright (C) 2000-2013 Free Software Foundation, Inc.
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
+1 -2
View File
@@ -135,7 +135,7 @@ _sed_rm_comments_q = $(subst ','\'',$(_sed_remove_comments))
_space_before_paren_exempt =? \\n\\$$ _space_before_paren_exempt =? \\n\\$$
_space_before_paren_exempt = \ _space_before_paren_exempt = \
(^ *\#|(LA)?LR\([01]\)|percent_(code|define)|b4_syncline|m4_(define|init)|symbol) (^ *\#|\\n\\$$|%s\(to %s|(date|group|character)\(s\))
# Ensure that there is a space before each open parenthesis in C code. # Ensure that there is a space before each open parenthesis in C code.
sc_space_before_open_paren: sc_space_before_open_paren:
@if $(VC_LIST_EXCEPT) | grep -l '\.[ch]$$' > /dev/null; then \ @if $(VC_LIST_EXCEPT) | grep -l '\.[ch]$$' > /dev/null; then \
@@ -175,6 +175,5 @@ $(call exclude, \
prohibit_strcmp=^doc/bison\.texi|tests/local\.at$$ \ prohibit_strcmp=^doc/bison\.texi|tests/local\.at$$ \
prohibit_tab_based_indentation=\.(am|mk)$$|^djgpp/|^\.git \ prohibit_tab_based_indentation=\.(am|mk)$$|^djgpp/|^\.git \
require_config_h_first=^(lib/yyerror|data/(glr|yacc))\.c$$ \ 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$$) \ unmarked_diagnostics=^(djgpp/|doc/bison.texi$$|tests/c\+\+\.at$$) \
) )
+6 -8
View File
@@ -18,7 +18,7 @@
# In order for some versions of Sun Studio to compile our C++ test cases # 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 # 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 # 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. # environment variable.
AC_PREREQ([2.68]) AC_PREREQ([2.68])
m4_pattern_forbid([^gl_[A-Z]]) 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 # -fno-color-diagnostics: Clang's use of colors in the error
# messages is confusing the tests looking at the compiler's output # messages is confusing the tests looking at the compiler's output
# (e.g., synclines.at). # (e.g., synclines.at).
warn_tests='-Wundef -pedantic -Wsign-compare -fno-color-diagnostics' warn_tests='-Wundef -pedantic -fno-color-diagnostics'
AC_LANG_PUSH([C]) AC_LANG_PUSH([C])
# Clang supports many of GCC's -W options, but only issues warnings # Clang supports many of GCC's -W options, but only issues warnings
@@ -143,11 +143,9 @@ if test "$enable_gcc_warnings" = yes; then
gl_WARN_ADD([$i], [WARN_CXXFLAGS_TEST]) gl_WARN_ADD([$i], [WARN_CXXFLAGS_TEST])
done done
# Clang++ 3.2+ reject C code generated by Flex. # Clang++ 3.2+ reject C code generated by Flex.
gl_WARN_ADD([-Wno-null-conversion], [FLEX_SCANNER_CXXFLAGS]) gl_WARN_ADD([-Wno-null-conversion], [WARN_NO_NULL_CONVERSION_CXXFLAGS])
# So does G++ 4.8... # Variants break strict aliasing analysis.
gl_WARN_ADD([-Wno-sign-compare], [FLEX_SCANNER_CXXFLAGS]) gl_WARN_ADD([-fno-strict-aliasing], [NO_STRICT_ALIAS_CXXFLAGS])
# ... possiby in std=c++11 mode.
gl_WARN_ADD([-Wno-zero-as-null-pointer-constant], [FLEX_SCANNER_CXXFLAGS])
CXXFLAGS=$save_CXXFLAGS CXXFLAGS=$save_CXXFLAGS
AC_LANG_POP([C++]) AC_LANG_POP([C++])
fi fi
@@ -222,7 +220,7 @@ AC_SUBST([aclocaldir])
AC_CONFIG_FILES([etc/bench.pl], [chmod +x etc/bench.pl]) AC_CONFIG_FILES([etc/bench.pl], [chmod +x etc/bench.pl])
# Initialize the test suite. # Initialize the test suite.
AC_CONFIG_TESTDIR(tests) AC_CONFIG_TESTDIR([tests], [$ac_abs_top_builddir/tests])
AC_CONFIG_FILES([tests/atlocal]) AC_CONFIG_FILES([tests/atlocal])
AC_CONFIG_FILES([tests/bison], [chmod +x tests/bison]) AC_CONFIG_FILES([tests/bison], [chmod +x tests/bison])
AC_CHECK_PROGS([VALGRIND], [valgrind]) AC_CHECK_PROGS([VALGRIND], [valgrind])
+1 -1
View File
@@ -27,7 +27,7 @@ Currently, the supported skeletons are:
These skeletons are the only ones supported by the Bison team. These skeletons are the only ones supported by the Bison team.
Because the interface between skeletons and the bison program is not Because the interface between skeletons and the bison program is not
finished, *we are not bound to it*. In particular, Bison 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. supported.
* m4sugar * m4sugar
+28 -141
View File
@@ -85,20 +85,6 @@ 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. ## ## Error handling. ##
## ---------------- ## ## ---------------- ##
@@ -327,7 +313,7 @@ m4_define([b4_define_flag_if],
# _b4_define_flag_if($1, $2, FLAG) # _b4_define_flag_if($1, $2, FLAG)
# -------------------------------- # --------------------------------
# Work around the impossibility to define macros inside macros, # 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. # $$1 a la M5/TeX.
m4_define([_b4_define_flag_if], m4_define([_b4_define_flag_if],
[m4_if([$1$2], $[1]$[2], [], [m4_if([$1$2], $[1]$[2], [],
@@ -361,7 +347,6 @@ b4_define_flag_if([yacc]) # Whether POSIX Yacc is emulated.
# Whether the symbol has an id. # Whether the symbol has an id.
# - id: string # - id: string
# If has_id, the id. Guaranteed to be usable as a C identifier. # If has_id, the id. Guaranteed to be usable as a C identifier.
# Prefixed by api.token.prefix if defined.
# - tag: string. # - tag: string.
# A representat of the symbol. Can be 'foo', 'foo.id', '"foo"' etc. # A representat of the symbol. Can be 'foo', 'foo.id', '"foo"' etc.
# - user_number: integer # - user_number: integer
@@ -372,13 +357,9 @@ b4_define_flag_if([yacc]) # Whether POSIX Yacc is emulated.
# The internalized number (used after yytranslate). # The internalized number (used after yytranslate).
# - has_type: 0, 1 # - has_type: 0, 1
# Whether has a semantic value. # 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 # - type
# If it has a semantic value, its type tag, or, if variant are used, # If it has a semantic value, its type tag, or, if variant are used,
# its type. # its type.
# In the case of api.value.type=union, type is the real type (e.g. int).
# - has_printer: 0, 1 # - has_printer: 0, 1
# - printer: string # - printer: string
# - printer_file: string # - printer_file: string
@@ -461,24 +442,6 @@ m4_define([b4_symbol_destructor], [b4_symbol_action([$1], [destructor])])
m4_define([b4_symbol_printer], [b4_symbol_action([$1], [printer])]) 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) # b4_symbol_case_(SYMBOL-NUM)
# --------------------------- # ---------------------------
# Issue a "case NUM" for SYMBOL-NUM. # Issue a "case NUM" for SYMBOL-NUM.
@@ -614,14 +577,14 @@ m4_define([b4_define_user_code],
# b4_user_initial_action # b4_user_initial_action
# b4_user_post_prologue # b4_user_post_prologue
# b4_user_pre_prologue # b4_user_pre_prologue
# b4_user_union_members # b4_user_stype
# ---------------------- # ----------------------
# Macros that issue user code, ending with synclines. # Macros that issue user code, ending with synclines.
b4_define_user_code([actions]) b4_define_user_code([actions])
b4_define_user_code([initial_action]) b4_define_user_code([initial_action])
b4_define_user_code([post_prologue]) b4_define_user_code([post_prologue])
b4_define_user_code([pre_prologue]) b4_define_user_code([pre_prologue])
b4_define_user_code([union_members]) b4_define_user_code([stype])
# b4_check_user_names(WHAT, USER-LIST, BISON-NAMESPACE) # b4_check_user_names(WHAT, USER-LIST, BISON-NAMESPACE)
@@ -702,9 +665,9 @@ m4_define([b4_percent_define_use],
# b4_percent_define_get([[foo]]) # b4_percent_define_get([[foo]])
m4_define([b4_percent_define_get], m4_define([b4_percent_define_get],
[b4_percent_define_use([$1])dnl [b4_percent_define_use([$1])dnl
b4_percent_define_ifdef_([$1], m4_ifdef([b4_percent_define(]$1[)],
[m4_indir([b4_percent_define(]$1[)])], [m4_indir([b4_percent_define(]$1[)])],
[$2])]) [$2])])
# b4_percent_define_get_loc(VARIABLE) # b4_percent_define_get_loc(VARIABLE)
# ----------------------------------- # -----------------------------------
@@ -723,21 +686,7 @@ m4_define([b4_percent_define_get_loc],
[m4_pushdef([b4_loc], m4_indir([b4_percent_define_loc(]$1[)]))dnl [m4_pushdef([b4_loc], m4_indir([b4_percent_define_loc(]$1[)]))dnl
b4_loc[]dnl b4_loc[]dnl
m4_popdef([b4_loc])], m4_popdef([b4_loc])],
[b4_fatal([[$0: undefined %%define variable '%s']], [$1])])]) [b4_fatal([[b4_percent_define_get_loc: 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) # b4_percent_define_get_syncline(VARIABLE)
# ---------------------------------------- # ----------------------------------------
@@ -754,20 +703,7 @@ m4_define([b4_percent_define_get_kind],
m4_define([b4_percent_define_get_syncline], m4_define([b4_percent_define_get_syncline],
[m4_ifdef([b4_percent_define_syncline(]$1[)], [m4_ifdef([b4_percent_define_syncline(]$1[)],
[m4_indir([b4_percent_define_syncline(]$1[)])], [m4_indir([b4_percent_define_syncline(]$1[)])],
[b4_fatal([[$0: undefined %%define variable '%s']], [$1])])]) [b4_fatal([[b4_percent_define_get_syncline: 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]) # b4_percent_define_ifdef(VARIABLE, IF-TRUE, [IF-FALSE])
# ------------------------------------------------------ # ------------------------------------------------------
@@ -780,9 +716,9 @@ m4_define([b4_percent_define_ifdef_],
# #
# b4_percent_define_ifdef([[foo]], [[it's defined]], [[it's undefined]]) # b4_percent_define_ifdef([[foo]], [[it's defined]], [[it's undefined]])
m4_define([b4_percent_define_ifdef], m4_define([b4_percent_define_ifdef],
[b4_percent_define_ifdef_([$1], [m4_ifdef([b4_percent_define(]$1[)],
[b4_percent_define_use([$1])$2], [b4_percent_define_use([$1])$2],
[$3])]) [$3])])
## --------- ## ## --------- ##
@@ -811,11 +747,11 @@ m4_define([b4_percent_define_flag_if],
[[invalid value for %%define Boolean variable '%s']], [[invalid value for %%define Boolean variable '%s']],
[$1])], [$1])],
[[b4_percent_define_flag_if($1)]])])], [[b4_percent_define_flag_if($1)]])])],
[b4_fatal([[$0: undefined %%define variable '%s']], [$1])])]) [b4_fatal([[b4_percent_define_flag_if: undefined %%define variable '%s']], [$1])])])
# b4_percent_define_default(VARIABLE, DEFAULT, [KIND = keyword]) # b4_percent_define_default(VARIABLE, DEFAULT)
# -------------------------------------------------------------- # --------------------------------------------
# Mimic muscle_percent_define_default in ../src/muscle-tab.h exactly. That is, # 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. # 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 # Don't record this as a Bison usage of VARIABLE as there's no reason to
@@ -825,10 +761,8 @@ m4_define([b4_percent_define_flag_if],
# #
# b4_percent_define_default([[foo]], [[default value]]) # b4_percent_define_default([[foo]], [[default value]])
m4_define([b4_percent_define_default], m4_define([b4_percent_define_default],
[b4_percent_define_ifdef_([$1], [], [m4_ifndef([b4_percent_define(]$1[)],
[m4_define([b4_percent_define(]$1[)], [$2])dnl [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[)], m4_define([b4_percent_define_loc(]$1[)],
[[[[<skeleton default value>:-1.-1]], [[[[<skeleton default value>:-1.-1]],
[[<skeleton default value>:-1.-1]]]])dnl [[<skeleton default value>:-1.-1]]]])dnl
@@ -838,8 +772,8 @@ m4_define([b4_percent_define_default],
# b4_percent_define_if_define(NAME, [VARIABLE = NAME]) # b4_percent_define_if_define(NAME, [VARIABLE = NAME])
# ---------------------------------------------------- # ----------------------------------------------------
# Define b4_NAME_if that executes its $1 or $2 depending whether # Define b4_NAME_if that executes its $1 or $2 depending whether
# VARIABLE was %defined. The characters '.' and `-' in VARIABLE are mapped # VARIABLE was %defined. The characters `.' and `-' in VARIABLE are mapped
# to '_'. # to `_'.
m4_define([b4_percent_define_if_define_], m4_define([b4_percent_define_if_define_],
[m4_define(m4_bpatsubst([b4_$1_if], [[-.]], [_]), [m4_define(m4_bpatsubst([b4_$1_if], [[-.]], [_]),
[b4_percent_define_flag_if(m4_default([$2], [$1]), [b4_percent_define_flag_if(m4_default([$2], [$1]),
@@ -849,21 +783,6 @@ m4_define([b4_percent_define_if_define],
b4_percent_define_if_define_([$1], [$2], $[1], $[2])]) 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) # b4_percent_define_check_values(VALUES)
# -------------------------------------- # --------------------------------------
# Mimic muscle_percent_define_check_values in ../src/muscle-tab.h exactly # Mimic muscle_percent_define_check_values in ../src/muscle-tab.h exactly
@@ -885,9 +804,8 @@ m4_define([b4_percent_define_check_values],
[_b4_percent_define_check_values(b4_sublist)])]) [_b4_percent_define_check_values(b4_sublist)])])
m4_define([_b4_percent_define_check_values], m4_define([_b4_percent_define_check_values],
[b4_percent_define_ifdef_([$1], [m4_ifdef([b4_percent_define(]$1[)],
[b4_percent_define_check_kind(]$1[, [keyword], [deprecated])dnl [m4_pushdef([b4_good_value], [0])dnl
m4_pushdef([b4_good_value], [0])dnl
m4_if($#, 1, [], m4_if($#, 1, [],
[m4_foreach([b4_value], m4_dquote(m4_shift($@)), [m4_foreach([b4_value], m4_dquote(m4_shift($@)),
[m4_if(m4_indir([b4_percent_define(]$1[)]), b4_value, [m4_if(m4_indir([b4_percent_define(]$1[)]), b4_value,
@@ -902,7 +820,7 @@ m4_define([_b4_percent_define_check_values],
[[accepted value: '%s']], [[accepted value: '%s']],
m4_dquote(b4_value))])])dnl m4_dquote(b4_value))])])dnl
m4_popdef([b4_good_value])], m4_popdef([b4_good_value])],
[b4_fatal([[$0: undefined %%define variable '%s']], [$1])])]) [b4_fatal([[b4_percent_define_check_values: undefined %%define variable '%s']], [$1])])])
# b4_percent_code_get([QUALIFIER]) # b4_percent_code_get([QUALIFIER])
# -------------------------------- # --------------------------------
@@ -943,6 +861,10 @@ m4_define([b4_percent_code_ifdef],
## Common variables. ## ## 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_assert_if([IF-ASSERTIONS-ARE-USED], [IF-NOT])
# b4_parse_trace_if([IF-DEBUG-TRACES-ARE-ENABLED], [IF-NOT]) # b4_parse_trace_if([IF-DEBUG-TRACES-ARE-ENABLED], [IF-NOT])
@@ -982,11 +904,9 @@ b4_error_verbose_if([m4_define([b4_token_table_flag], [1])])
# b4_variant_if([IF-VARIANT-ARE-USED], [IF-NOT]) # b4_variant_if([IF-VARIANT-ARE-USED], [IF-NOT])
# ---------------------------------------------- # ----------------------------------------------
b4_percent_define_if_define([variant]) b4_percent_define_if_define([variant])
m4_define([b4_variant_flag], [[0]]) m4_case(b4_percent_define_get([[api.value.type]]),
b4_percent_define_ifdef([[api.value.type]], [variant], [m4_define([b4_variant_flag], [[1]])],
[m4_case(b4_percent_define_get_kind([[api.value.type]]), [keyword], [m4_define([b4_variant_flag], [[0]])])
[m4_case(b4_percent_define_get([[api.value.type]]), [variant],
[m4_define([b4_variant_flag], [[1]])])])])
b4_define_flag_if([variant]) b4_define_flag_if([variant])
@@ -1021,43 +941,10 @@ m4_define_default([b4_parse_param], [])
m4_define_default([b4_location_initial_column], [1]) m4_define_default([b4_location_initial_column], [1])
m4_define_default([b4_location_initial_line], [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], b4_percent_define_ifdef([api.prefix],
[m4_ifdef([b4_prefix], [m4_ifdef([b4_prefix],
[b4_complain_at(b4_percent_define_get_loc([api.prefix]), [b4_complain_at(b4_percent_define_get_loc([api.prefix]),
[['%s' and '%s' cannot be used together]], [['%s' and '%s' cannot be used together]],
[%name-prefix], [%name-prefix],
[%define api.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"])])])])
+13 -35
View File
@@ -25,12 +25,6 @@ m4_include(b4_pkgdatadir/[c.m4])
m4_define([b4_comment], m4_define([b4_comment],
[b4_comment_([$1], [$2// ], [$2// ])]) [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. ## ## Default values. ##
@@ -44,7 +38,6 @@ b4_percent_define_default([[parser_class_name]], [[parser]])
# b4_percent_define_default([[api.location.type]], [[location]]) # b4_percent_define_default([[api.location.type]], [[location]])
b4_percent_define_default([[filename_type]], [[std::string]]) 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([[api.namespace]], m4_defn([b4_prefix]))
b4_percent_define_default([[global_tokens_and_yystype]], [[false]]) b4_percent_define_default([[global_tokens_and_yystype]], [[false]])
@@ -61,8 +54,8 @@ b4_percent_define_default([[define_location_comparison]],
m4_define([b4_namespace_ref], [b4_percent_define_get([[api.namespace]])]) 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 # 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. # would compile as an absolute reference with `parser' in the global namespace.
# b4_namespace_open would open an anonymous namespace and thus establish # b4_namespace_open would open an anonymous namespace and thus establish
# internal linkage. This would compile. However, it's cryptic, and internal # internal linkage. This would compile. However, it's cryptic, and internal
# linkage for the parser would be specified in all translation units that # linkage for the parser would be specified in all translation units that
@@ -119,24 +112,19 @@ m4_define([b4_token_enums],
## Semantic Values. ## ## Semantic Values. ##
## ----------------- ## ## ----------------- ##
# b4_semantic_type_declare
# ------------------------
# b4_value_type_declare
# ---------------------
# Declare semantic_type. # Declare semantic_type.
m4_define([b4_value_type_declare], m4_define([b4_semantic_type_declare],
[b4_value_type_setup[]dnl
[ /// Symbol semantic values. [ /// Symbol semantic values.
]m4_bmatch(b4_percent_define_get_kind([[api.value.type]]), m4_ifdef([b4_stype],
[code], [ union semantic_type
[[ 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_union_members[ b4_user_stype
};]])])dnl };],
]) [m4_if(b4_tag_seen_flag, 0,
[[ typedef int semantic_type;]],
[[ typedef ]b4_api_PREFIX[STYPE semantic_type;]])])])
# b4_public_types_declare # b4_public_types_declare
@@ -145,7 +133,7 @@ m4_define([b4_value_type_declare],
# Depending on %define token_lex, may be output in the header or source file. # Depending on %define token_lex, may be output in the header or source file.
m4_define([b4_public_types_declare], m4_define([b4_public_types_declare],
[[#ifndef ]b4_api_PREFIX[STYPE [[#ifndef ]b4_api_PREFIX[STYPE
]b4_value_type_declare[ ]b4_semantic_type_declare[
#else #else
typedef ]b4_api_PREFIX[STYPE semantic_type; typedef ]b4_api_PREFIX[STYPE semantic_type;
#endif]b4_locations_if([ #endif]b4_locations_if([
@@ -532,13 +520,3 @@ m4_define([b4_yylloc_default_define],
while (/*CONSTCOND*/ false) while (/*CONSTCOND*/ false)
# endif # 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]))])])
+25 -166
View File
@@ -150,7 +150,7 @@ m4_popdef([$1])dnl
# b4_parse_param_use([VAL], [LOC]) # 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_define([b4_parse_param_use],
[m4_ifvaln([$1], [ YYUSE ([$1]);])dnl [m4_ifvaln([$1], [ YYUSE ([$1]);])dnl
b4_locations_if([m4_ifvaln([$2], [ YYUSE ([$2]);])])dnl b4_locations_if([m4_ifvaln([$2], [ YYUSE ([$2]);])])dnl
@@ -182,7 +182,7 @@ m4_define([b4_int_type],
# b4_int_type_for(NAME) # b4_int_type_for(NAME)
# --------------------- # ---------------------
# Return the smallest int type able to handle numbers ranging from # 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], m4_define([b4_int_type_for],
[b4_int_type($1_min, $1_max)]) [b4_int_type($1_min, $1_max)])
@@ -199,31 +199,6 @@ m4_define([b4_table_value_equals],
[(!!(($2) == ($3)))])]) [(!!(($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. ## ## Values. ##
## ---------## ## ---------##
@@ -446,7 +421,12 @@ m4_ifset([b4_parse_param], [, b4_parse_param]))[
yymsg = "Deleting"; yymsg = "Deleting";
YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
]b4_symbol_actions([destructor])[ switch (yytype)
{
]b4_symbol_foreach([b4_symbol_destructor])dnl
[ default:
break;
}
}]dnl }]dnl
]) ])
@@ -479,7 +459,12 @@ m4_if(b4_skeleton, ["yacc.c"],
YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
# endif # endif
]])dnl ]])dnl
b4_symbol_actions([printer])[ [ switch (yytype)
{
]b4_symbol_foreach([b4_symbol_printer])dnl
[ default:
break;
}
} }
@@ -507,154 +492,28 @@ b4_locations_if([, yylocationp])[]b4_user_args[);
}]dnl }]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. ## ## Declarations. ##
## -------------- ## ## -------------- ##
# b4_value_type_define # b4_value_type_define
# -------------------- # --------------------
m4_define([b4_value_type_define], m4_define([b4_value_type_define],
[b4_value_type_setup[]dnl [[/* Value type. */
/* Value type. */ #if ! defined ]b4_api_PREFIX[STYPE && ! defined ]b4_api_PREFIX[STYPE_IS_DECLARED
m4_bmatch(b4_percent_define_get_kind([[api.value.type]]), ]m4_ifdef([b4_stype],
[code], [[typedef union ]b4_union_name[ ]b4_api_PREFIX[STYPE;
[[#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[ union ]b4_union_name[
{ {
]b4_user_union_members[ ]b4_user_stype[
}; };
# define ]b4_api_PREFIX[STYPE_IS_TRIVIAL 1 # define ]b4_api_PREFIX[STYPE_IS_TRIVIAL 1]],
[m4_if(b4_tag_seen_flag, 0,
[[typedef int ]b4_api_PREFIX[STYPE;
# define ]b4_api_PREFIX[STYPE_IS_TRIVIAL 1]])])[
# define ]b4_api_PREFIX[STYPE_IS_DECLARED 1 # define ]b4_api_PREFIX[STYPE_IS_DECLARED 1
#endif #endif
]])])]) ]])
# b4_location_type_define # b4_location_type_define
@@ -690,7 +549,7 @@ b4_pure_if([], [[extern ]b4_api_PREFIX[STYPE ]b4_prefix[lval;
# b4_YYDEBUG_define # b4_YYDEBUG_define
# ----------------- # ------------------
m4_define([b4_YYDEBUG_define], m4_define([b4_YYDEBUG_define],
[[/* Debug traces. */ [[/* Debug traces. */
]m4_if(b4_api_prefix, [yy], ]m4_if(b4_api_prefix, [yy],
+18 -1
View File
@@ -246,6 +246,13 @@ b4_percent_code_get[]dnl
# endif # endif
#endif #endif
/* Suppress unused-variable warnings by "using" E. */
#ifdef __GNUC__
# define YYUSE(E) ((void) (E))
#else
# define YYUSE(E) /* empty */
#endif
#ifndef YYFREE #ifndef YYFREE
# define YYFREE free # define YYFREE free
#endif #endif
@@ -274,7 +281,17 @@ b4_percent_code_get[]dnl
# define YYLONGJMP(Env, Val) (longjmp (Env, Val), YYASSERT (0)) # define YYLONGJMP(Env, Val) (longjmp (Env, Val), YYASSERT (0))
#endif #endif
]b4_attribute_define[ /*-----------------.
| 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
#ifndef YYASSERT #ifndef YYASSERT
# define YYASSERT(Condition) ((void) ((Condition) || (abort (), 0))) # define YYASSERT(Condition) ((void) ((Condition) || (abort (), 0)))
+12 -1
View File
@@ -43,6 +43,12 @@
# user must initialize the first positions (in particular the # user must initialize the first positions (in particular the
# filename member). # filename member).
b4_token_ctor_if([b4_variant_if([],
[b4_fatal_at(b4_percent_define_get_loc(api.token.constructor),
[cannot use '%s' without '%s'],
[%define api.token.constructor],
[%define api.value.type variant]))])])
# We require a pure interface. # We require a pure interface.
m4_define([b4_pure_flag], [1]) m4_define([b4_pure_flag], [1])
@@ -187,7 +193,12 @@ m4_pushdef([b4_parse_param], m4_defn([b4_parse_param_orig]))dnl
std::ostream& yyoutput = debug_stream (); std::ostream& yyoutput = debug_stream ();
std::ostream& yyo = yyoutput; std::ostream& yyo = yyoutput;
YYUSE (yyo); YYUSE (yyo);
]b4_symbol_actions([printer])[ switch (yytype)
{
]b4_symbol_foreach([b4_symbol_printer])dnl
[ default:
break;
}
} }
+1 -17
View File
@@ -103,7 +103,7 @@ m4_define([b4_int_type],
# b4_int_type_for(NAME) # b4_int_type_for(NAME)
# --------------------- # ---------------------
# Return the smallest int type able to handle numbers ranging from # 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], m4_define([b4_int_type_for],
[b4_int_type($1_min, $1_max)]) [b4_int_type($1_min, $1_max)])
@@ -169,22 +169,6 @@ 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. ## ## Default values. ##
## ---------------- ## ## ---------------- ##
+18 -14
View File
@@ -17,8 +17,6 @@
m4_include(b4_pkgdatadir/[c++.m4]) 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) # b4_integral_parser_table_declare(TABLE-NAME, CONTENT, COMMENT)
# -------------------------------------------------------------- # --------------------------------------------------------------
@@ -40,14 +38,13 @@ m4_define([b4_integral_parser_table_define],
};dnl };dnl
]) ])
# b4_symbol_value_template(VAL, [TYPE]) # b4_symbol_value_template(VAL, [TYPE])
# ------------------------------------- # -------------------------------------
# Same as b4_symbol_value, but used in a template method. It makes # Same as b4_symbol_value, but used in a template method. It makes
# a difference when using variants. Note that b4_value_type_setup_union # a difference when using variants.
# overrides b4_symbol_value, so we must override it again.
m4_copy([b4_symbol_value], [b4_symbol_value_template]) 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]) # b4_lhs_value([TYPE])
# -------------------- # --------------------
@@ -204,10 +201,6 @@ b4_location_define])])[
void error (const syntax_error& err); void error (const syntax_error& err);
private: 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. /// State numbers.
typedef int state_type; typedef int state_type;
@@ -598,7 +591,13 @@ m4_if(b4_prefix, [yy], [],
YY_SYMBOL_PRINT (yymsg, yysym);]b4_variant_if([], [ YY_SYMBOL_PRINT (yymsg, yysym);]b4_variant_if([], [
// User destructor. // User destructor.
b4_symbol_actions([destructor], [yysym.type_get ()])])[ symbol_number_type yytype = yysym.type_get ();
switch (yytype)
{
]b4_symbol_foreach([b4_symbol_destructor])dnl
[ default:
break;
}])[
} }
#if ]b4_api_PREFIX[DEBUG #if ]b4_api_PREFIX[DEBUG
@@ -613,7 +612,12 @@ m4_if(b4_prefix, [yy], [],
yyo << (yytype < yyntokens_ ? "token" : "nterm") yyo << (yytype < yyntokens_ ? "token" : "nterm")
<< ' ' << yytname_[yytype] << " ("]b4_locations_if([ << ' ' << yytname_[yytype] << " ("]b4_locations_if([
<< yysym.location << ": "])[; << yysym.location << ": "])[;
]b4_symbol_actions([printer])[ switch (yytype)
{
]b4_symbol_foreach([b4_symbol_printer])dnl
[ default:
break;
}
yyo << ')'; yyo << ')';
} }
#endif #endif
@@ -733,7 +737,7 @@ b4_dollar_popdef])[]dnl
yynewstate, since the latter expects the semantical and the yynewstate, since the latter expects the semantical and the
location values to have been already stored, initialize these location values to have been already stored, initialize these
stacks with a primary value. */ stacks with a primary value. */
yystack_.clear (); yystack_ = stack_type (0);
yypush_ (YY_NULL, 0, yyla); yypush_ (YY_NULL, 0, yyla);
// A new symbol was pushed on the stack. // A new symbol was pushed on the stack.
@@ -820,7 +824,7 @@ b4_dollar_popdef])[]dnl
variants. */ variants. */
b4_symbol_variant([[yyr1_@{yyn@}]], [yylhs.value], [build])],[ b4_symbol_variant([[yyr1_@{yyn@}]], [yylhs.value], [build])],[
/* If YYLEN is nonzero, implement the default value of the action: /* 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. Otherwise, the following line sets YYLHS.VALUE to garbage.
This behavior is undocumented and Bison This behavior is undocumented and Bison
+1 -1
View File
@@ -375,7 +375,7 @@ b4_lexer_if([[
]b4_locations_if([b4_location_type[ yyloc = yylloc (yystack, yylen);]])[ ]b4_locations_if([b4_location_type[ yyloc = yylloc (yystack, yylen);]])[
/* If YYLEN is nonzero, implement the default value of the action: /* 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. Otherwise, the following line sets YYVAL to garbage.
This behavior is undocumented and Bison This behavior is undocumented and Bison
+24 -43
View File
@@ -25,7 +25,8 @@ m4_define([b4_position_define],
[[ /// Abstract a position. [[ /// Abstract a position.
class position class position
{ {
public:]m4_ifdef([b4_location_constructors], [[ public:
]m4_ifdef([b4_location_constructors], [[
/// Construct a position. /// Construct a position.
explicit position (]b4_percent_define_get([[filename_type]])[* f = YY_NULL, explicit position (]b4_percent_define_get([[filename_type]])[* f = YY_NULL,
unsigned int l = ]b4_location_initial_line[u, unsigned int l = ]b4_location_initial_line[u,
@@ -52,17 +53,14 @@ m4_define([b4_position_define],
/// (line related) Advance to the COUNT next lines. /// (line related) Advance to the COUNT next lines.
void lines (int count = 1) void lines (int count = 1)
{ {
if (count) column = ]b4_location_initial_column[u;
{ line += count;
column = ]b4_location_initial_column[u;
line = add_ (line, count, ]b4_location_initial_line[);
}
} }
/// (column related) Advance to the COUNT next columns. /// (column related) Advance to the COUNT next columns.
void columns (int count = 1) void columns (int count = 1)
{ {
column = add_ (column, count, ]b4_location_initial_column[); column = std::max (]b4_location_initial_column[u, column + count);
} }
/** \} */ /** \} */
@@ -72,44 +70,36 @@ m4_define([b4_position_define],
unsigned int line; unsigned int line;
/// Current column number. /// Current column number.
unsigned int column; 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. /// Add and assign a position.
inline position& inline position&
operator+= (position& res, int width) operator+= (position& res, const int width)
{ {
res.columns (width); res.columns (width);
return res; return res;
} }
/// Add two position objects. /// Add two position objects.
inline position inline const position
operator+ (position res, int width) operator+ (const position& begin, const int width)
{ {
position res = begin;
return res += width; return res += width;
} }
/// Add and assign a position. /// Add and assign a position.
inline position& inline position&
operator-= (position& res, int width) operator-= (position& res, const int width)
{ {
return res += -width; return res += -width;
} }
/// Add two position objects. /// Add two position objects.
inline position inline const position
operator- (position res, int width) operator- (const position& begin, const int width)
{ {
return res -= width; return begin + -width;
} }
]b4_percent_define_flag_if([[define_location_comparison]], [[ ]b4_percent_define_flag_if([[define_location_comparison]], [[
/// Compare two position objects. /// Compare two position objects.
@@ -196,13 +186,13 @@ m4_define([b4_location_define],
} }
/// Extend the current location to the COUNT next columns. /// Extend the current location to the COUNT next columns.
void columns (int count = 1) void columns (unsigned int count = 1)
{ {
end += count; end += count;
} }
/// Extend the current location to the COUNT next lines. /// Extend the current location to the COUNT next lines.
void lines (int count = 1) void lines (unsigned int count = 1)
{ {
end.lines (count); end.lines (count);
} }
@@ -217,35 +207,26 @@ m4_define([b4_location_define],
}; };
/// Join two location objects to create a location. /// Join two location objects to create a location.
inline location operator+ (location res, const location& end) inline const location operator+ (const location& begin, const location& end)
{ {
location res = begin;
res.end = end.end; res.end = end.end;
return res; return res;
} }
/// Change end position in place. /// Add two location objects.
inline location& operator+= (location& res, int width) inline const location operator+ (const location& begin, unsigned int width)
{ {
location res = begin;
res.columns (width); res.columns (width);
return res; return res;
} }
/// Change end position. /// Add and assign a location.
inline location operator+ (location res, int width) inline location& operator+= (location& res, unsigned int width)
{ {
return res += width; res.columns (width);
} return res;
/// 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]], [[ ]b4_percent_define_flag_if([[define_location_comparison]], [[
/// Compare two location objects. /// Compare two location objects.
-8
View File
@@ -72,12 +72,6 @@ m4_define([b4_stack_define],
seq_.pop_back (); seq_.pop_back ();
} }
void
clear ()
{
seq_.clear ();
}
inline inline
typename S::size_type typename S::size_type
size () const size () const
@@ -100,8 +94,6 @@ m4_define([b4_stack_define],
} }
private: private:
stack (const stack&);
stack& operator= (const stack&);
/// The wrapped container. /// The wrapped container.
S seq_; S seq_;
}; };
+39 -56
View File
@@ -26,7 +26,7 @@
# YYTYPE. # YYTYPE.
m4_define([b4_symbol_variant], m4_define([b4_symbol_variant],
[m4_pushdef([b4_dollar_dollar], [m4_pushdef([b4_dollar_dollar],
[$2.$3< $][3 > (m4_shift3($@))])dnl [$2.$3< $][3 >(m4_shift3($@))])dnl
switch ($1) switch ($1)
{ {
b4_type_foreach([b4_type_action_])[]dnl b4_type_foreach([b4_type_action_])[]dnl
@@ -63,7 +63,7 @@ m4_define([b4_char_sizeof],
[b4_symbol_if([$1], [has_type], [b4_symbol_if([$1], [has_type],
[ [
m4_map([ b4_symbol_tag_comment], [$@])dnl 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. /// Empty construction.
variant ()]b4_parse_assert_if([ variant ()]b4_parse_assert_if([
: yytname_ (YY_NULL)])[ : tname (YY_NULL)])[
{} {}
/// Construct and fill. /// Construct and fill.
template <typename T> template <typename T>
variant (const T& t)]b4_parse_assert_if([ variant (const T& t)]b4_parse_assert_if([
: yytname_ (typeid (T).name ())])[ : tname (typeid (T).name ())])[
{ {
YYASSERT (sizeof (T) <= S); YYASSERT (sizeof (T) <= S);
new (yyas_<T> ()) T (t); new (buffer.raw) T (t);
} }
/// Destruction, allowed only if empty. /// Destruction, allowed only if empty.
~variant () ~variant ()
{]b4_parse_assert_if([ {]b4_parse_assert_if([
YYASSERT (!yytname_); YYASSERT (!tname);
])[} ])[}
/// Instantiate an empty \a T in here. /// Instantiate an empty \a T in here.
@@ -118,10 +118,10 @@ m4_define([b4_variant_define],
T& T&
build () build ()
{]b4_parse_assert_if([ {]b4_parse_assert_if([
YYASSERT (!yytname_); YYASSERT (!tname);
YYASSERT (sizeof (T) <= S); YYASSERT (sizeof (T) <= S);
yytname_ = typeid (T).name ();])[ tname = typeid (T).name ();])[
return *new (yyas_<T> ()) T; return *new (buffer.raw) T;
} }
/// Instantiate a \a T in here from \a t. /// Instantiate a \a T in here from \a t.
@@ -129,10 +129,10 @@ m4_define([b4_variant_define],
T& T&
build (const T& t) build (const T& t)
{]b4_parse_assert_if([ {]b4_parse_assert_if([
YYASSERT (!yytname_); YYASSERT (!tname);
YYASSERT (sizeof (T) <= S); YYASSERT (sizeof (T) <= S);
yytname_ = typeid (T).name ();])[ tname = typeid (T).name ();])[
return *new (yyas_<T> ()) T (t); return *new (buffer.raw) T (t);
} }
/// Accessor to a built \a T. /// Accessor to a built \a T.
@@ -140,9 +140,9 @@ m4_define([b4_variant_define],
T& T&
as () as ()
{]b4_parse_assert_if([ {]b4_parse_assert_if([
YYASSERT (yytname_ == typeid (T).name ()); YYASSERT (tname == typeid (T).name ());
YYASSERT (sizeof (T) <= S);])[ YYASSERT (sizeof (T) <= S);])[
return *yyas_<T> (); return reinterpret_cast<T&> (buffer.raw);
} }
/// Const accessor to a built \a T (for %printer). /// Const accessor to a built \a T (for %printer).
@@ -150,9 +150,9 @@ m4_define([b4_variant_define],
const T& const T&
as () const as () const
{]b4_parse_assert_if([ {]b4_parse_assert_if([
YYASSERT (yytname_ == typeid (T).name ()); YYASSERT (tname == typeid (T).name ());
YYASSERT (sizeof (T) <= S);])[ YYASSERT (sizeof (T) <= S);])[
return *yyas_<T> (); return reinterpret_cast<const T&> (buffer.raw);
} }
/// Swap the content with \a other, of same type. /// Swap the content with \a other, of same type.
@@ -167,9 +167,9 @@ m4_define([b4_variant_define],
void void
swap (self_type& other) swap (self_type& other)
{]b4_parse_assert_if([ {]b4_parse_assert_if([
YYASSERT (yytname_); YYASSERT (tname);
YYASSERT (yytname_ == other.yytname_);])[ YYASSERT (tname == other.tname);])[
std::swap (as<T> (), other.as<T> ()); std::swap (as<T>(), other.as<T>());
} }
/// Move the content of \a other to this. /// Move the content of \a other to this.
@@ -179,10 +179,10 @@ m4_define([b4_variant_define],
void void
move (self_type& other) move (self_type& other)
{]b4_parse_assert_if([ {]b4_parse_assert_if([
YYASSERT (!yytname_);])[ YYASSERT (!tname);])[
build<T> (); build<T>();
swap<T> (other); swap<T>(other);
other.destroy<T> (); other.destroy<T>();
} }
/// Copy the content of \a other to this. /// Copy the content of \a other to this.
@@ -199,7 +199,7 @@ m4_define([b4_variant_define],
destroy () destroy ()
{ {
as<T> ().~T ();]b4_parse_assert_if([ as<T> ().~T ();]b4_parse_assert_if([
yytname_ = YY_NULL;])[ tname = YY_NULL;])[
} }
private: private:
@@ -207,34 +207,17 @@ m4_define([b4_variant_define],
self_type& operator=(const self_type&); self_type& operator=(const self_type&);
variant (const self_type&); variant (const self_type&);
/// Accessor to raw memory as \a T. /// A buffer large enough to store any of the semantic values.
template <typename T> /// Long double is chosen as it has the strongest alignment
T* /// constraints.
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 union
{ {
/// Strongest alignment constraints. long double align_me;
long double yyalign_me; char raw[S];
/// A buffer large enough to store any of the semantic values. } buffer;]b4_parse_assert_if([
char yyraw[S];
} yybuffer_;]b4_parse_assert_if([
/// Whether the content is built: if defined, the name of the stored type. /// Whether the content is built: if defined, the name of the stored type.
const char *yytname_;])[ const char* tname;])[
}; };
]]) ]])
@@ -244,16 +227,16 @@ m4_define([b4_variant_define],
## -------------------------- ## ## -------------------------- ##
# b4_value_type_declare # b4_semantic_type_declare
# --------------------- # ------------------------
# Declare semantic_type. # Declare semantic_type.
m4_define([b4_value_type_declare], m4_define([b4_semantic_type_declare],
[[ /// An auxiliary type to compute the largest semantic type. [ /// An auxiliary type to compute the largest semantic type.
union union_type union union_type
{]b4_type_foreach([b4_char_sizeof])[}; {]b4_type_foreach([b4_char_sizeof])[};
/// Symbol semantic values. /// Symbol semantic values.
typedef variant<sizeof(union_type)> semantic_type;][]dnl typedef variant<sizeof(union_type)> semantic_type;dnl
]) ])
@@ -263,7 +246,7 @@ m4_define([b4_value_type_declare],
# ---------------------------- # ----------------------------
m4_define([b4_symbol_value], m4_define([b4_symbol_value],
[m4_ifval([$2], [m4_ifval([$2],
[$1.as< $2 > ()], [$1.as< $2 >()],
[$1])]) [$1])])
# b4_symbol_value_template(VAL, [TYPE]) # b4_symbol_value_template(VAL, [TYPE])
@@ -271,7 +254,7 @@ m4_define([b4_symbol_value],
# Same as b4_symbol_value, but used in a template method. # Same as b4_symbol_value, but used in a template method.
m4_define([b4_symbol_value_template], m4_define([b4_symbol_value_template],
[m4_ifval([$2], [m4_ifval([$2],
[$1.template as< $2 > ()], [$1.template as< $2 >()],
[$1])]) [$1])])
@@ -328,7 +311,7 @@ b4_join(b4_symbol_if([$1], [has_type],
# b4_basic_symbol_constructor_declare # b4_basic_symbol_constructor_declare
# ----------------------------------- # ----------------------------------
# Generate a constructor declaration for basic_symbol from given type. # Generate a constructor declaration for basic_symbol from given type.
m4_define([b4_basic_symbol_constructor_declare], m4_define([b4_basic_symbol_constructor_declare],
[[ [[
+1 -1
View File
@@ -373,7 +373,7 @@
</xsl:template> </xsl:template>
<xsl:template match="empty"> <xsl:template match="empty">
<xsl:text> %empty</xsl:text> <xsl:text> /* empty */</xsl:text>
</xsl:template> </xsl:template>
<xsl:template match="lookaheads"> <xsl:template match="lookaheads">
+14 -8
View File
@@ -143,6 +143,7 @@ m4_define([b4_rhs_value],
[b4_symbol_value([yyvsp@{b4_subtract([$2], [$1])@}], [$3])]) [b4_symbol_value([yyvsp@{b4_subtract([$2], [$1])@}], [$3])])
## ----------- ## ## ----------- ##
## Locations. ## ## Locations. ##
## ----------- ## ## ----------- ##
@@ -199,7 +200,7 @@ static YYLTYPE yyloc_default][]b4_yyloc_default[;]])])[
#endif #endif
/* The semantic value of the lookahead symbol. */ /* 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. */ /* Location data for the lookahead symbol. */
YYLTYPE yylloc]b4_pure_if([ = yyloc_default], [b4_yyloc_default])[; YYLTYPE yylloc]b4_pure_if([ = yyloc_default], [b4_yyloc_default])[;
@@ -222,9 +223,9 @@ m4_define([b4_declare_parser_state_variables], [b4_pure_if([[
int yyerrstatus; int yyerrstatus;
/* The stacks and their tools: /* The stacks and their tools:
'yyss': related to states. `yyss': related to states.
'yyvs': related to semantic values.]b4_locations_if([[ `yyvs': related to semantic values.]b4_locations_if([[
'yyls': related to locations.]])[ `yyls': related to locations.]])[
Refer to the stacks through separate pointers, to allow yyoverflow Refer to the stacks through separate pointers, to allow yyoverflow
to reallocate them elsewhere. */ to reallocate them elsewhere. */
@@ -430,7 +431,12 @@ typedef short int yytype_int16;
# endif # endif
#endif #endif
]b4_attribute_define[ /* Suppress unused-variable warnings by "using" E. */
#ifdef __GNUC__
# define YYUSE(E) ((void) (E))
#else
# define YYUSE(E) /* empty */
#endif
#if ]b4_lac_if([[1]], [[! defined yyoverflow || YYERROR_VERBOSE]])[ #if ]b4_lac_if([[1]], [[! defined yyoverflow || YYERROR_VERBOSE]])[
@@ -462,7 +468,7 @@ b4_push_if([], [b4_lac_if([], [[
# endif]])])[ # endif]])])[
# ifdef YYSTACK_ALLOC # 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) # define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
# ifndef YYSTACK_ALLOC_MAXIMUM # ifndef YYSTACK_ALLOC_MAXIMUM
/* The OS might guarantee only one guard page at the bottom of the stack, /* The OS might guarantee only one guard page at the bottom of the stack,
@@ -1648,7 +1654,7 @@ yyreduce:
yylen = yyr2[yyn]; yylen = yyr2[yyn];
/* If YYLEN is nonzero, implement the default value of the action: /* If YYLEN is nonzero, implement the default value of the action:
'$$ = $1'. `$$ = $1'.
Otherwise, the following line sets YYVAL to garbage. Otherwise, the following line sets YYVAL to garbage.
This behavior is undocumented and Bison This behavior is undocumented and Bison
@@ -1696,7 +1702,7 @@ yyreduce:
*++yyvsp = yyval;]b4_locations_if([ *++yyvsp = yyval;]b4_locations_if([
*++yylsp = yyloc;])[ *++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 that goes to, based on the state we popped back to and the rule
number reduced by. */ number reduced by. */
+303 -635
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -37,7 +37,7 @@ MOSTLYCLEANFILES += $(top_srcdir)/doc/*.t
CROSS_OPTIONS_PL = $(top_srcdir)/build-aux/cross-options.pl CROSS_OPTIONS_PL = $(top_srcdir)/build-aux/cross-options.pl
CROSS_OPTIONS_TEXI = $(top_srcdir)/doc/cross-options.texi CROSS_OPTIONS_TEXI = $(top_srcdir)/doc/cross-options.texi
$(CROSS_OPTIONS_TEXI): doc/bison.help $(CROSS_OPTIONS_PL) $(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 # that even if we are interrupted, the file is still available for
# diff in the next run. Note that $@ might not exist yet. # diff in the next run. Note that $@ might not exist yet.
$(AM_V_GEN){ test ! -f $@ || cat $@; } >$@~ $(AM_V_GEN){ test ! -f $@ || cat $@; } >$@~
+2 -2
View File
@@ -204,9 +204,9 @@ Format the list of directives for Bison for bench named C<$bench>.
sub directives($@) sub directives($@)
{ {
my ($bench, @directive) = @_; my ($bench, @directive) = @_;
my $res = "/* Directives for bench '$bench'. */\n"; my $res = "/* Directives for bench `$bench'. */\n";
$res .= join ("\n", @directive) . "\n"; $res .= join ("\n", @directive) . "\n";
$res .= "/* End of directives for bench '$bench'. */\n"; $res .= "/* End of directives for bench `$bench'. */\n";
return $res; return $res;
} }
+16 -15
View File
@@ -44,31 +44,32 @@ CLEANFILES += \
# Avoid using BUILT_SOURCES which is too global. # Avoid using BUILT_SOURCES which is too global.
$(examples_calc___calc___OBJECTS): $(calc_sources_generated) $(examples_calc___calc___OBJECTS): $(calc_sources_generated)
calc_sources_extracted = \ calc_sources_extracted = \
examples/calc++/calc++-driver.cc \ examples/calc++/calc++-driver.cc \
examples/calc++/calc++-driver.hh \ examples/calc++/calc++-driver.hh \
examples/calc++/calc++-scanner.ll \ examples/calc++/calc++-scanner.ll \
examples/calc++/calc++.cc examples/calc++/calc++.cc
calc_extracted = \ calc_extracted = \
$(calc_sources_extracted) \ $(calc_sources_extracted) \
examples/calc++/calc++-parser.yy examples/calc++/calc++-parser.yy
extracted += $(calc_extracted) extracted += $(calc_extracted)
calc_sources_generated = \ calc_sources_generated = \
examples/calc++/calc++-parser.cc \ examples/calc++/calc++-parser.cc \
examples/calc++/calc++-parser.hh \ examples/calc++/calc++-parser.hh \
examples/calc++/location.hh \ examples/calc++/location.hh \
examples/calc++/position.hh \ examples/calc++/position.hh \
examples/calc++/stack.hh examples/calc++/stack.hh
calc_sources = \ calc_sources = \
$(calc_sources_extracted) \ $(calc_sources_extracted) \
$(calc_sources_generated) $(calc_sources_generated)
if BISON_CXX_WORKS if BISON_CXX_WORKS
check_PROGRAMS += examples/calc++/calc++ check_PROGRAMS += examples/calc++/calc++
nodist_examples_calc___calc___SOURCES = \ nodist_examples_calc___calc___SOURCES = \
$(calc_sources) $(calc_sources)
examples_calc___calc___CPPFLAGS = -I$(top_builddir)/examples/calc++ examples_calc___calc___CPPFLAGS = -I$(top_builddir)/examples/calc++
examples_calc___calc___CXXFLAGS = $(AM_CXXFLAGS) $(FLEX_SCANNER_CXXFLAGS) examples_calc___calc___CXXFLAGS = \
$(AM_CXXFLAGS) $(WARN_NO_NULL_CONVERSION_CXXFLAGS)
dist_TESTS += examples/calc++/calc++.test dist_TESTS += examples/calc++/calc++.test
endif endif
+1
View File
@@ -17,6 +17,7 @@ dist_noinst_SCRIPTS = examples/extexi examples/test
TEST_LOG_COMPILER = $(top_srcdir)/examples/test TEST_LOG_COMPILER = $(top_srcdir)/examples/test
AM_CXXFLAGS = \ AM_CXXFLAGS = \
$(NO_STRICT_ALIAS_CXXFLAGS) \
$(WARN_CXXFLAGS) $(WARN_CXXFLAGS_TEST) $(WERROR_CXXFLAGS) $(WARN_CXXFLAGS) $(WARN_CXXFLAGS_TEST) $(WERROR_CXXFLAGS)
## ------------ ## ## ------------ ##
+1 -1
Submodule gnulib updated: e28fbd787c...c67e3c0414
+1 -1
View File
@@ -17,7 +17,7 @@
/* Bison depends on libiberty's implementation of bitsets, which /* 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. */ services. */
#ifndef BISON_LIBIBERTY_H_ #ifndef BISON_LIBIBERTY_H_
+1 -1
View File
@@ -36,7 +36,7 @@
Timing variables may be pushed onto the stack; elapsed time is Timing variables may be pushed onto the stack; elapsed time is
attributed to the topmost timing variable on the stack. When attributed to the topmost timing variable on the stack. When
another variable is pushed on, the previous topmost variable is 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. - As a standalone timer, using timevar_start and timevar_stop.
All time elapsed between the two calls is attributed to the All time elapsed between the two calls is attributed to the
+1 -1
View File
@@ -60,7 +60,7 @@ Sbitset__isEmpty (Sbitset self, Sbitset__Index nbits)
} }
void void
Sbitset__fprint (Sbitset self, Sbitset__Index nbits, FILE *file) Sbitset__fprint(Sbitset self, Sbitset__Index nbits, FILE *file)
{ {
Sbitset__Index i; Sbitset__Index i;
Sbitset itr; Sbitset itr;
+6 -6
View File
@@ -44,31 +44,31 @@ void Sbitset__delete (Sbitset self);
bool Sbitset__isEmpty (Sbitset self, Sbitset__Index nbits); 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) \ # define Sbitset__set(SELF, INDEX) \
do { \ do { \
*Sbitset__byteAddress ((SELF), (INDEX)) = \ *Sbitset__byteAddress ((SELF), (INDEX)) = \
*Sbitset__byteAddress ((SELF), (INDEX)) | Sbitset__bit_mask (INDEX); \ *Sbitset__byteAddress ((SELF), (INDEX)) | Sbitset__bit_mask (INDEX); \
} while (0) } while(0)
# define Sbitset__reset(SELF, INDEX) \ # define Sbitset__reset(SELF, INDEX) \
do { \ do { \
*Sbitset__byteAddress ((SELF), (INDEX)) = \ *Sbitset__byteAddress ((SELF), (INDEX)) = \
*Sbitset__byteAddress ((SELF), (INDEX)) & ~Sbitset__bit_mask (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. */ /* NBITS is the size of the bitset. More than NBITS bits might be reset. */
# define Sbitset__zero(SELF, NBITS) \ # define Sbitset__zero(SELF, NBITS) \
do { \ do { \
memset (SELF, 0, Sbitset__nbytes (NBITS)); \ memset (SELF, 0, Sbitset__nbytes (NBITS)); \
} while (0) } while(0)
/* NBITS is the size of the bitset. More than NBITS bits might be set. */ /* NBITS is the size of the bitset. More than NBITS bits might be set. */
# define Sbitset__ones(SELF, NBITS) \ # define Sbitset__ones(SELF, NBITS) \
do { \ do { \
memset (SELF, UCHAR_MAX, Sbitset__nbytes (NBITS)); \ 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. */ /* NBITS is the size of every bitset. More than NBITS bits might be set. */
# define Sbitset__or(SELF, OTHER1, OTHER2, NBITS) \ # 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); \ Sbitset end_self = ptr_self + Sbitset__nbytes (NBITS); \
for (; ptr_self < end_self; ++ptr_self, ++ptr_other1, ++ptr_other2) \ for (; ptr_self < end_self; ++ptr_self, ++ptr_other1, ++ptr_other2) \
*ptr_self = *ptr_other1 | *ptr_other2; \ *ptr_self = *ptr_other1 | *ptr_other2; \
} while (0) } while(0)
# define SBITSET__FOR_EACH(SELF, NBITS, ITER, INDEX) \ # define SBITSET__FOR_EACH(SELF, NBITS, ITER, INDEX) \
for ((ITER) = (SELF); (ITER) < (SELF) + Sbitset__nbytes (NBITS); ++(ITER)) \ for ((ITER) = (SELF); (ITER) < (SELF) + Sbitset__nbytes (NBITS); ++(ITER)) \
+41 -214
View File
@@ -22,7 +22,6 @@
#include <config.h> #include <config.h>
#include "system.h" #include "system.h"
#include <argmatch.h>
#include <stdarg.h> #include <stdarg.h>
#include <progname.h> #include <progname.h>
@@ -31,199 +30,42 @@
#include "getargs.h" #include "getargs.h"
#include "quote.h" #include "quote.h"
warnings warnings_flag =
Wconflicts_sr | Wconflicts_rr | Wdeprecated | Wother;
warnings errors_flag;
err_status complaint_status = status_none; 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; static unsigned *indent_ptr = 0;
/*------------------------.
| --warnings's handling. |
`------------------------*/
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 void
warning_argmatch (char const *arg, size_t no, size_t err) warnings_print_categories (warnings warn_flags)
{ {
int value = XARGMATCH ("--warning", arg + no + err, if (! (warn_flags & silent))
warnings_args, warnings_types);
/* -Wnone == -Wno-everything, and -Wno-none == -Weverything. */
if (!value)
{ {
value = Weverything; char const *warn_names[] =
no = !no; {
} "midrule-values",
"yacc",
"conflicts-sr",
"conflicts-rr",
"deprecated",
"other"
};
if (no) bool any = false;
{ int i;
size_t b; for (i = 0; i < ARRAY_CARDINALITY (warn_names); ++i)
for (b = 0; b < warnings_size; ++b) if (warn_flags & 1 << i)
if (value & 1 << b)
{ {
if (err) bool err = warn_flags & errors_flag;
{ fprintf (stderr, "%s-W", any ? ", " : " [");
/* -Wno-error=foo: if foo enabled as an error, fprintf (stderr, "%s%s", err ? "error=" : "" , warn_names[i]);
make it a warning. */ any = true;
if (warnings_flag[b] == severity_error)
warnings_flag[b] = severity_warning;
}
else
/* -Wno-foo. */
warnings_flag[b] = severity_disabled;
} }
if (any)
fprintf (stderr, "]");
} }
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. /** Report an error message.
@@ -246,7 +88,7 @@ error_message (const location *loc, warnings flags, const char *prefix,
unsigned pos = 0; unsigned pos = 0;
if (loc) if (loc)
pos += location_print (*loc, stderr); pos += location_print (stderr, *loc);
else else
pos += fprintf (stderr, "%s", current_file ? current_file : program_name); pos += fprintf (stderr, "%s", current_file ? current_file : program_name);
pos += fprintf (stderr, ": "); pos += fprintf (stderr, ": ");
@@ -266,8 +108,7 @@ error_message (const location *loc, warnings flags, const char *prefix,
fprintf (stderr, "%s: ", prefix); fprintf (stderr, "%s: ", prefix);
vfprintf (stderr, message, args); vfprintf (stderr, message, args);
if (! (flags & silent)) warnings_print_categories (flags);
warnings_print_categories (flags, stderr);
{ {
size_t l = strlen (message); size_t l = strlen (message);
if (l < 2 || message[l - 2] != ':' || message[l - 1] != ' ') if (l < 2 || message[l - 2] != ':' || message[l - 1] != ' ')
@@ -275,34 +116,29 @@ error_message (const location *loc, warnings flags, const char *prefix,
putc ('\n', stderr); putc ('\n', stderr);
fflush (stderr); fflush (stderr);
if (loc && feature_flag & feature_caret && !(flags & no_caret)) if (loc && feature_flag & feature_caret && !(flags & no_caret))
location_caret (*loc, stderr); location_caret (stderr, *loc);
} }
} }
fflush (stderr); fflush (stderr);
} }
/** Raise a complaint. That can be a fatal error, an error or just a /** Raise a complaint. That can be a fatal error, a complaint or just a
warning. */ warning. */
static inline void
static void
complains (const location *loc, warnings flags, const char *message, complains (const location *loc, warnings flags, const char *message,
va_list args) va_list args)
{ {
severity s = warning_severity (flags); const char* prefix =
flags & fatal ? _("fatal error")
: flags & (errors_flag | complaint) ? _("error")
: _("warning");
if ((flags & complaint) && complaint_status < status_complaint) if ((flags & complaint) && complaint_status < status_complaint)
complaint_status = status_complaint; complaint_status = status_complaint;
else if ((flags & (warnings_flag & errors_flag)) && ! complaint_status)
if (severity_warning <= s) complaint_status = status_warning_as_error;
{ if (flags & (warnings_flag | fatal | complaint))
const char* prefix = error_message (loc, flags, prefix, message, args);
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) if (flags & fatal)
exit (EXIT_FAILURE); exit (EXIT_FAILURE);
} }
@@ -353,6 +189,7 @@ complain_args (location const *loc, warnings w, unsigned *indent,
complain (loc, fatal, "too many arguments for complains"); complain (loc, fatal, "too many arguments for complains");
break; break;
} }
} }
void void
@@ -367,13 +204,3 @@ deprecated_directive (location const *loc, char const *old, char const *upd)
_("deprecated directive: %s, use %s"), _("deprecated directive: %s, use %s"),
quote (old), quote_n (1, upd)); 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"));
}
+16 -68
View File
@@ -28,67 +28,15 @@
| --warnings. | | --warnings. |
`-------------*/ `-------------*/
/** The bits assigned to each warning type. */
typedef enum typedef enum
{ {
warning_midrule_values, /**< Unset or unused midrule values. */ Wnone = 0, /**< Issue no warnings. */
warning_yacc, /**< POSIXME. */ Wmidrule_values = 1 << 0, /**< Unset or unused midrule values. */
warning_conflicts_sr, /**< S/R conflicts. */ Wyacc = 1 << 1, /**< POSIXME. */
warning_conflicts_rr, /**< R/R conflicts. */ Wconflicts_sr = 1 << 2, /**< S/R conflicts. */
warning_empty_rule, /**< Implicitly empty rules. */ Wconflicts_rr = 1 << 3, /**< R/R conflicts. */
warning_deprecated, /**< Obsolete constructs. */ Wdeprecated = 1 << 4, /**< Obsolete constructs. */
warning_precedence, /**< Useless precedence and associativity. */ Wother = 1 << 5, /**< All other warnings. */
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. */ Werror = 1 << 10, /** This bit is no longer used. */
@@ -98,13 +46,17 @@ typedef enum
no_caret = 1 << 14, /**< Do not display caret location. */ no_caret = 1 << 14, /**< Do not display caret location. */
/**< All above warnings. */ /**< All above warnings. */
Weverything = ~complaint & ~fatal & ~silent, Wall = ~complaint & ~fatal & ~silent
Wall = Weverything & ~Wyacc
} warnings; } warnings;
/** Whether the warnings of \a flags are all unset. /** What warnings are issued. */
(Never enabled, never disabled). */ extern warnings warnings_flag;
bool warning_is_unset (warnings flags);
/** What warnings are made errors. */
extern warnings errors_flag;
/** Display a "[-Wyacc]" like message on stderr. */
void warnings_print_categories (warnings warn_flags);
/** Make a complaint, with maybe a location. */ /** Make a complaint, with maybe a location. */
void complain (location const *loc, warnings flags, char const *message, ...) void complain (location const *loc, warnings flags, char const *message, ...)
@@ -124,10 +76,6 @@ void complain_indent (location const *loc, warnings flags, unsigned *indent,
void deprecated_directive (location const *loc, void deprecated_directive (location const *loc,
char const *obsolete, char const *updated); 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 /** 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 should (because due to their nature, it is safe to go on). Thus, there are
three possible execution statuses. */ three possible execution statuses. */
+1 -1
View File
@@ -403,7 +403,7 @@ conflicts_solve (void)
set_conflicts (states[i], errors); set_conflicts (states[i], errors);
/* For uniformity of the code, make sure all the states have a valid /* For uniformity of the code, make sure all the states have a valid
'errs' member. */ `errs' member. */
if (!states[i]->errs) if (!states[i]->errs)
states[i]->errs = errs_new (0, 0); states[i]->errs = errs_new (0, 0);
} }
+13 -13
View File
@@ -34,7 +34,7 @@
#include "getargs.h" #include "getargs.h"
#include "gram.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 tempting, but don't do that: for the time being our handling of the
%directive vs --option leaves precedence to the options by deciding %directive vs --option leaves precedence to the options by deciding
that if a %directive sets a variable which is really set (i.e., not 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; uniqstr current_file = NULL;
/* If --output=dir/foo.c was specified, /* 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/', 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'. 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, 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 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 If neither --output nor --file was specified, DIR_PREFIX is the
empty string (meaning the current directory); otherwise it is empty string (meaning the current directory); otherwise it is
'dir/'. */ `dir/'. */
char *all_but_ext; char *all_but_ext;
static char *all_but_tab_ext; static char *all_but_tab_ext;
@@ -79,7 +79,7 @@ char *dir_prefix;
/* C source file extension (the parser source). */ /* C source file extension (the parser source). */
static char *src_extension = NULL; 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; 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. *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 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. cannot be equal to *BASE.
None are allocated, they are simply pointers to parts of FILE_NAME. 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, '.'); *ext = strrchr (*base, '.');
*tab = NULL; *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. */ before. */
if (*ext) if (*ext)
{ {
@@ -270,7 +270,7 @@ compute_file_name_parts (void)
if (spec_file_prefix) 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 = dir_prefix =
xstrndup (spec_file_prefix, xstrndup (spec_file_prefix,
last_component (spec_file_prefix) - spec_file_prefix); last_component (spec_file_prefix) - spec_file_prefix);
@@ -278,14 +278,14 @@ compute_file_name_parts (void)
} }
else if (yacc_flag) 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 (""); dir_prefix = xstrdup ("");
all_but_tab_ext = xstrdup ("y"); all_but_tab_ext = xstrdup ("y");
} }
else else
{ {
/* Otherwise, ALL_BUT_TAB_EXT is computed from the input /* Otherwise, ALL_BUT_TAB_EXT is computed from the input
grammar: 'foo/bar.yy' => 'bar'. */ grammar: `foo/bar.yy' => `bar'. */
dir_prefix = xstrdup (""); dir_prefix = xstrdup ("");
all_but_tab_ext = all_but_tab_ext =
xstrndup (base, (strlen (base) - (ext ? strlen (ext) : 0))); xstrndup (base, (strlen (base) - (ext ? strlen (ext) : 0)));
+109 -64
View File
@@ -61,6 +61,7 @@ int skeleton_prio = default_prio;
const char *skeleton = NULL; const char *skeleton = NULL;
int language_prio = default_prio; int language_prio = default_prio;
struct bison_language const *language = &valid_languages[0]; struct bison_language const *language = &valid_languages[0];
const char *include = NULL;
/** Decode an option's key. /** Decode an option's key.
* *
@@ -73,6 +74,8 @@ struct bison_language const *language = &valid_languages[0];
* If null, then activate all the flags. * If null, then activate all the flags.
* \param no length of the potential "no-" prefix. * \param no length of the potential "no-" prefix.
* Can be 0 or 3. If 3, negate the action of the subargument. * 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 sets flags and no-KEY clears them.
* If VALUE == 0 then KEY clears all flags from \c all and no-KEY sets all * If VALUE == 0 then KEY clears all flags from \c all and no-KEY sets all
@@ -81,23 +84,36 @@ struct bison_language const *language = &valid_languages[0];
static void static void
flag_argmatch (const char *option, flag_argmatch (const char *option,
const char * const keys[], const int values[], const char * const keys[], const int values[],
int all, int *flags, char *arg, size_t no) int all, int *flags, char *arg, size_t no, size_t err)
{ {
int value = XARGMATCH (option, arg + no, keys, values); int value = 0;
if (!err || arg[no + err++] != '\0')
value = XARGMATCH (option, arg + no + err, keys, values);
/* -rnone == -rno-all, and -rno-none == -rall. */ if (value)
if (!value)
{ {
value = all; if (no)
no = !no; *flags &= ~value;
else
{
if (err)
warnings_flag |= value;
*flags |= value;
}
} }
if (no)
*flags &= ~value;
else else
*flags |= value; {
/* 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;
}
} }
/** Decode an option's set of keys. /** Decode an option's set of keys.
* *
* \param option option being decoded. * \param option option being decoded.
@@ -117,14 +133,16 @@ flags_argmatch (const char *option,
for (args = strtok (args, ","); args; args = strtok (NULL, ",")) for (args = strtok (args, ","); args; args = strtok (NULL, ","))
{ {
size_t no = STRPREFIX_LIT ("no-", args) ? 3 : 0; size_t no = STRPREFIX_LIT ("no-", args) ? 3 : 0;
size_t err = STRPREFIX_LIT ("error", args + no) ? 5 : 0;
flag_argmatch (option, keys, flag_argmatch (option, keys,
values, all, flags, args, no); values, all, err ? &errors_flag : flags,
args, no, err);
} }
else else
*flags |= all; *flags |= all;
} }
/** Decode a set of sub arguments. /** Decode a set of sub arguments.
* *
* \param FlagName the flag familly to update. * \param FlagName the flag familly to update.
@@ -178,6 +196,8 @@ ARGMATCH_VERIFY (report_args, report_types);
static const char * const trace_args[] = 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", "none - no traces",
"scan - grammar scanner traces", "scan - grammar scanner traces",
"parse - grammar parser traces", "parse - grammar parser traces",
@@ -218,6 +238,41 @@ static const int trace_types[] =
ARGMATCH_VERIFY (trace_args, 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. | | --feature's handling. |
`-----------------------*/ `-----------------------*/
@@ -249,7 +304,7 @@ static void
usage (int status) usage (int status)
{ {
if (status != 0) if (status != 0)
fprintf (stderr, _("Try '%s --help' for more information.\n"), fprintf (stderr, _("Try `%s --help' for more information.\n"),
program_name); program_name);
else else
{ {
@@ -291,7 +346,7 @@ Parser:\n\
-L, --language=LANGUAGE specify the output programming language\n\ -L, --language=LANGUAGE specify the output programming language\n\
-S, --skeleton=FILE specify the skeleton to use\n\ -S, --skeleton=FILE specify the skeleton to use\n\
-t, --debug instrument the parser for tracing\n\ -t, --debug instrument the parser for tracing\n\
same as '-Dparse.trace'\n\ same as `-Dparse.trace'\n\
--locations enable location support\n\ --locations enable location support\n\
-D, --define=NAME[=VALUE] similar to '%define NAME \"VALUE\"'\n\ -D, --define=NAME[=VALUE] similar to '%define NAME \"VALUE\"'\n\
-F, --force-define=NAME[=VALUE] override '%define NAME \"VALUE\"'\n\ -F, --force-define=NAME[=VALUE] override '%define NAME \"VALUE\"'\n\
@@ -310,7 +365,7 @@ Output:\n\
-d likewise but cannot specify FILE (for POSIX Yacc)\n\ -d likewise but cannot specify FILE (for POSIX Yacc)\n\
-r, --report=THINGS also produce details on the automaton\n\ -r, --report=THINGS also produce details on the automaton\n\
--report-file=FILE write report to FILE\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\ -b, --file-prefix=PREFIX specify a PREFIX for output files\n\
-o, --output=FILE leave output to FILE\n\ -o, --output=FILE leave output to FILE\n\
-g, --graph[=FILE] also output a graph of the automaton\n\ -g, --graph[=FILE] also output a graph of the automaton\n\
@@ -321,37 +376,35 @@ Output:\n\
fputs (_("\ fputs (_("\
Warning categories include:\n\ Warning categories include:\n\
'midrule-values' unset or unused midrule values\n\ `midrule-values' unset or unused midrule values\n\
'yacc' incompatibilities with POSIX Yacc\n\ `yacc' incompatibilities with POSIX Yacc\n\
'conflicts-sr' S/R conflicts (enabled by default)\n\ `conflicts-sr' S/R conflicts (enabled by default)\n\
'conflicts-rr' R/R conflicts (enabled by default)\n\ `conflicts-rr' R/R conflicts (enabled by default)\n\
'deprecated' obsolete constructs\n\ `deprecated' obsolete constructs\n\
'empty-rule' empty rules without %empty\n\ `other' all other warnings (enabled by default)\n\
'precedence' useless precedence and associativity\n\ `all' all the warnings\n\
'other' all other warnings (enabled by default)\n\ `no-CATEGORY' turn off warnings in CATEGORY\n\
'all' all the warnings except 'yacc'\n\ `none' turn off all the warnings\n\
'no-CATEGORY' turn off warnings in CATEGORY\n\ `error[=CATEGORY]' treat warnings as errors\n\
'none' turn off all the warnings\n\
'error[=CATEGORY]' treat warnings as errors\n\
"), stdout); "), stdout);
putc ('\n', stdout); putc ('\n', stdout);
fputs (_("\ fputs (_("\
THINGS is a list of comma separated words that can include:\n\ THINGS is a list of comma separated words that can include:\n\
'state' describe the states\n\ `state' describe the states\n\
'itemset' complete the core item sets with their closure\n\ `itemset' complete the core item sets with their closure\n\
'lookahead' explicitly associate lookahead tokens to items\n\ `lookahead' explicitly associate lookahead tokens to items\n\
'solved' describe shift/reduce conflicts solving\n\ `solved' describe shift/reduce conflicts solving\n\
'all' include all the above information\n\ `all' include all the above information\n\
'none' disable the report\n\ `none' disable the report\n\
"), stdout); "), stdout);
putc ('\n', stdout); putc ('\n', stdout);
fputs (_("\ fputs (_("\
FEATURE is a list of comma separated words that can include:\n\ FEATURE is a list of comma separated words that can include:\n\
'caret' show errors with carets\n\ `caret' show errors with carets\n\
'all' all of the above\n\ `all' all of the above\n\
'none' disable all of the above\n\ `none' disable all of the above\n\
"), stdout); "), stdout);
putc ('\n', stdout); putc ('\n', stdout);
@@ -464,10 +517,12 @@ static char const short_options[] =
"b:" "b:"
"d" "d"
"f::" "f::"
"e"
"g::" "g::"
"h" "h"
"k" "k"
"l" "l"
"n"
"o:" "o:"
"p:" "p:"
"r:" "r:"
@@ -497,6 +552,7 @@ static struct option const long_options[] =
/* Parser. */ /* Parser. */
{ "name-prefix", required_argument, 0, 'p' }, { "name-prefix", required_argument, 0, 'p' },
{ "include", required_argument, 0, 'I' },
/* Output. */ /* Output. */
{ "file-prefix", required_argument, 0, 'b' }, { "file-prefix", required_argument, 0, 'b' },
@@ -525,6 +581,7 @@ static struct option const long_options[] =
{ "force-define", required_argument, 0, 'F' }, { "force-define", required_argument, 0, 'F' },
{ "locations", no_argument, 0, LOCATIONS_OPTION }, { "locations", no_argument, 0, LOCATIONS_OPTION },
{ "no-lines", no_argument, 0, 'l' }, { "no-lines", no_argument, 0, 'l' },
{ "raw", no_argument, 0, 0 },
{ "skeleton", required_argument, 0, 'S' }, { "skeleton", required_argument, 0, 'S' },
{ "language", required_argument, 0, 'L' }, { "language", required_argument, 0, 'L' },
{ "token-table", no_argument, 0, 'k' }, { "token-table", no_argument, 0, 'k' },
@@ -533,7 +590,7 @@ static struct option const long_options[] =
}; };
/* Under DOS, there is no difference on the case. This can be /* 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 #ifdef MSDOS
# define AS_FILE_NAME(File) (strlwr (File), (File)) # define AS_FILE_NAME(File) (strlwr (File), (File))
#else #else
@@ -569,36 +626,24 @@ getargs (int argc, char *argv[])
/* Certain long options cause getopt_long to return 0. */ /* Certain long options cause getopt_long to return 0. */
break; break;
case 'D': /* -DNAME[=(VALUE|"VALUE"|{VALUE})]. */ case 'D': /* -DNAME[=VALUE]. */
case 'F': /* -FNAME[=(VALUE|"VALUE"|{VALUE})]. */ case 'F': /* -FNAME[=VALUE]. */
{ {
char *name = optarg; char* name = optarg;
char *value = strchr (optarg, '='); char* value = strchr (optarg, '=');
muscle_kind kind = muscle_keyword;
if (value) 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 (), muscle_percent_define_insert (name, command_line_location (),
kind, value ? value : "", value ? value : "",
c == 'D' ? MUSCLE_PERCENT_DEFINE_D c == 'D' ? MUSCLE_PERCENT_DEFINE_D
: MUSCLE_PERCENT_DEFINE_F); : MUSCLE_PERCENT_DEFINE_F);
} }
break; break;
case 'I':
include = AS_FILE_NAME (optarg);
break;
case 'L': case 'L':
language_argmatch (optarg, command_line_prio, language_argmatch (optarg, command_line_prio,
command_line_location ()); command_line_location ());
@@ -622,7 +667,7 @@ getargs (int argc, char *argv[])
break; break;
case 'W': case 'W':
warnings_argmatch (optarg); FLAGS_ARGMATCH (warnings, optarg, Wall);
break; break;
case 'b': case 'b':
@@ -673,8 +718,7 @@ getargs (int argc, char *argv[])
case 't': case 't':
muscle_percent_define_insert ("parse.trace", muscle_percent_define_insert ("parse.trace",
command_line_location (), command_line_location (), "",
muscle_keyword, "",
MUSCLE_PERCENT_DEFINE_D); MUSCLE_PERCENT_DEFINE_D);
break; break;
@@ -692,7 +736,8 @@ getargs (int argc, char *argv[])
break; break;
case 'y': case 'y':
warning_argmatch ("error=yacc", 0, 6); warnings_flag |= Wyacc;
errors_flag |= Wyacc;
yacc_flag = true; yacc_flag = true;
break; break;
-1
View File
@@ -121,7 +121,6 @@ enum feature
/** What additional features to use. */ /** What additional features to use. */
extern int feature_flag; extern int feature_flag;
/** Process the command line arguments. /** Process the command line arguments.
* *
* \param argc size of \a argv * \param argc size of \a argv
+31 -8
View File
@@ -93,14 +93,16 @@ rule_rhs_length (rule const *r)
void void
rule_rhs_print (rule const *r, FILE *out) rule_rhs_print (rule const *r, FILE *out)
{ {
if (0 <= *r->rhs) if (*r->rhs >= 0)
{ {
item_number *rp; item_number *rp;
for (rp = r->rhs; *rp >= 0; rp++) for (rp = r->rhs; *rp >= 0; rp++)
fprintf (out, " %s", symbols[*rp]->tag); fprintf (out, " %s", symbols[*rp]->tag);
} }
else else
fputs (" %empty", out); {
fprintf (out, " /* %s */", _("empty"));
}
} }
static void static void
@@ -123,6 +125,13 @@ 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 void
ritem_print (FILE *out) ritem_print (FILE *out)
{ {
@@ -280,8 +289,8 @@ grammar_dump (FILE *out, const char *title)
rule_number r; rule_number r;
for (r = 0; r < nrules + nuseless_productions; r++) for (r = 0; r < nrules + nuseless_productions; r++)
{ {
fprintf (out, "%-5d %s:", r, rules[r].lhs->tag); fprintf (out, "%-5d ", r);
rule_rhs_print (&rules[r], out); rule_print (&rules[r], out);
fprintf (out, "\n"); fprintf (out, "\n");
} }
} }
@@ -291,10 +300,24 @@ grammar_dump (FILE *out, const char *title)
void void
grammar_rules_useless_report (const char *message) grammar_rules_useless_report (const char *message)
{ {
rule_number r; warnings w = Wother;
for (r = 0; r < nrules ; ++r) if (warnings_flag & w)
if (!rules[r].useful) {
complain (&rules[r].location, Wother, "%s", message); 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");
}
}
}
} }
void void
+6 -6
View File
@@ -35,7 +35,7 @@
The rules receive rule numbers 1 to NRULES in the order they are The rules receive rule numbers 1 to NRULES in the order they are
written. More precisely Bison augments the grammar with the 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 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 presented to the user, we subtract 1, so *displayed* rule numbers
are 0, 1, 2... are 0, 1, 2...
@@ -61,7 +61,7 @@
RULES[R].prec -- the symbol providing the precedence level of R. RULES[R].prec -- the symbol providing the precedence level of R.
RULES[R].precsym -- the symbol attached (via %prec) to give its 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 need to distinguish one from the other when reducing: a symbol used
in a %prec is not useless. in a %prec is not useless.
@@ -205,11 +205,11 @@ extern rule *rules;
/* A function that selects a rule. */ /* A function that selects a rule. */
typedef bool (*rule_filter) (rule const *); 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. */ useful in the grammar. */
bool rule_useful_in_grammar_p (rule const *r); 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. */ useless in the grammar. */
bool rule_useless_in_grammar_p (rule const *r); 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); void grammar_dump (FILE *out, const char *title);
/* Report on STDERR the rules that are not flagged USEFUL, using the /* Report on STDERR the rules that are not flagged USEFUL, using the
MESSAGE (which can be 'rule useless in grammar' when invoked after grammar MESSAGE (which can be `rule useless in grammar' when invoked after grammar
reduction, or 'rule useless in parser due to conflicts' after conflicts reduction, or `rule useless in parser due to conflicts' after conflicts
were taken into account). */ were taken into account). */
void grammar_rules_useless_report (const char *message); void grammar_rules_useless_report (const char *message);
+1 -1
View File
@@ -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 /* We need a lookahead either to distinguish different reductions
(i.e., there are two or more), or to distinguish a reduction from a (i.e., there are two or more), or to distinguish a reduction from a
shift. Otherwise, it is straightforward, and the state is 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 consistent unless it is the accepting state (because there is never
a lookahead token that makes sense there, and so no lookahead token a lookahead token that makes sense there, and so no lookahead token
should be read) if the user has otherwise disabled default should be read) if the user has otherwise disabled default
+5 -3
View File
@@ -96,8 +96,10 @@ 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 unsigned
location_print (location loc, FILE *out) location_print (FILE *out, location loc)
{ {
unsigned res = 0; unsigned res = 0;
int end_col = 0 != loc.end.column ? loc.end.column - 1 : 0; int end_col = 0 != loc.end.column ? loc.end.column - 1 : 0;
@@ -159,7 +161,7 @@ cleanup_caret ()
} }
void void
location_caret (location loc, FILE *out) location_caret (FILE *out, location loc)
{ {
/* FIXME: find a way to support multifile locations, and only open once each /* FIXME: find a way to support multifile locations, and only open once each
file. That would make the procedure future-proof. */ file. That would make the procedure future-proof. */
@@ -219,7 +221,7 @@ void
boundary_set_from_string (boundary *bound, char *loc_str) boundary_set_from_string (boundary *bound, char *loc_str)
{ {
/* Must search in reverse since the file name field may /* Must search in reverse since the file name field may
* contain '.' or ':'. */ * contain `.' or `:'. */
char *delim = strrchr (loc_str, '.'); char *delim = strrchr (loc_str, '.');
aver (delim); aver (delim);
*delim = '\0'; *delim = '\0';
+5 -10
View File
@@ -20,10 +20,6 @@
#ifndef LOCATION_H_ #ifndef LOCATION_H_
# define LOCATION_H_ # define LOCATION_H_
# include <stdbool.h>
# include <stdio.h>
# include <string.h> /* strcmp */
# include "uniqstr.h" # include "uniqstr.h"
/* A boundary between two characters. */ /* A boundary between two characters. */
@@ -102,17 +98,16 @@ extern location const empty_location;
void location_compute (location *loc, void location_compute (location *loc,
boundary *cur, char const *token, size_t size); boundary *cur, char const *token, size_t size);
/* Print location to file. /* Print location to file. Return number of actually printed
Return number of actually printed characters. characters. */
Warning: uses quotearg's slot 3. */ unsigned location_print (FILE *out, location loc);
unsigned location_print (location loc, FILE *out);
/* Free any allocated ressources and close any open file handles that are /* Free any allocated ressources and close any open file handles that are
left-over by the usage of location_caret. */ left-over by the usage of location_caret. */
void cleanup_caret (void); void cleanup_caret (void);
/* Output to OUT the line and caret corresponding to location LOC. */ /* Output to OUT the line and caret corresponding to location LOC. */
void location_caret (location loc, FILE *out); void location_caret (FILE *out, location loc);
/* Return -1, 0, 1, depending whether a is before, equal, or /* Return -1, 0, 1, depending whether a is before, equal, or
after b. */ after b. */
@@ -125,7 +120,7 @@ location_cmp (location a, location b)
return res; 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); void boundary_set_from_string (boundary *bound, char *loc_str);
#endif /* ! defined LOCATION_H_ */ #endif /* ! defined LOCATION_H_ */
+2 -1
View File
@@ -76,7 +76,6 @@ main (int argc, char *argv[])
uniqstrs_new (); uniqstrs_new ();
muscle_init (); muscle_init ();
complain_init ();
getargs (argc, argv); getargs (argc, argv);
@@ -147,6 +146,8 @@ main (int argc, char *argv[])
print_precedence_warnings (); print_precedence_warnings ();
print_assoc_warnings ();
/* Output file names. */ /* Output file names. */
compute_output_file_names (); compute_output_file_names ();
+160 -207
View File
@@ -28,31 +28,6 @@
#include "muscle-tab.h" #include "muscle-tab.h"
#include "quote.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 /* A key-value pair, along with storage that can be reclaimed when
this pair is no longer needed. */ this pair is no longer needed. */
typedef struct typedef struct
@@ -60,21 +35,8 @@ typedef struct
char const *key; char const *key;
char const *value; char const *value;
char *storage; char *storage;
muscle_kind kind;
} muscle_entry; } 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. */ /* An obstack used to create some entries. */
struct obstack muscle_obstack; struct obstack muscle_obstack;
@@ -98,18 +60,10 @@ hash_muscle (const void *x, size_t tablesize)
return hash_string (m->key, tablesize); return hash_string (m->key, tablesize);
} }
/* Create a fresh muscle name KEY, and insert in the hash table. */ /*-----------------------------------------------------------------.
static void * | Create the MUSCLE_TABLE, and initialize it with default values. |
muscle_entry_new (char const *key) | Also set up the MUSCLE_OBSTACK. |
{ `-----------------------------------------------------------------*/
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 static void
muscle_entry_free (void *entry) muscle_entry_free (void *entry)
@@ -133,6 +87,10 @@ muscle_init (void)
} }
/*------------------------------------------------------------.
| Free all the memory consumed by the muscle machinery only. |
`------------------------------------------------------------*/
void void
muscle_free (void) muscle_free (void)
{ {
@@ -140,64 +98,71 @@ muscle_free (void)
obstack_free (&muscle_obstack, NULL); 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 void
muscle_insert (char const *key, char const *value) muscle_insert (char const *key, char const *value)
{ {
muscle_entry *entry = muscle_lookup (key); muscle_entry probe;
if (entry) muscle_entry *entry;
free (entry->storage);
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 else
/* First insertion in the hash. */ free (entry->storage);
entry = muscle_entry_new (key);
entry->value = value; entry->value = value;
entry->storage = NULL; 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 | Append VALUE to the current value of KEY. If KEY did not already |
associated value. Copy VALUE and SEPARATOR. If VALUE does not end | exist, create it. Use MUSCLE_OBSTACK. De-allocate the previously |
with TERMINATOR, append one. */ | associated value. Copy VALUE and SEPARATOR. |
`-------------------------------------------------------------------*/
static void void
muscle_grow (const char *key, const char *val, muscle_grow (const char *key, const char *val, const char *separator)
const char *separator, const char *terminator)
{ {
muscle_entry *entry = muscle_lookup (key); muscle_entry probe;
size_t vals = strlen (val); muscle_entry *entry = NULL;
size_t terms = strlen (terminator);
if (entry) probe.key = key;
entry = hash_lookup (muscle_table, &probe);
if (!entry)
{ {
obstack_sgrow (&muscle_obstack, entry->value); /* First insertion in the hash. */
obstack_sgrow (&muscle_obstack, separator); entry = xmalloc (sizeof *entry);
free (entry->storage); entry->key = key;
if (!hash_insert (muscle_table, entry))
xalloc_die ();
entry->value = entry->storage = xstrdup (val);
} }
else else
entry = muscle_entry_new (key); {
/* Grow the current value. */
obstack_sgrow (&muscle_obstack, val); char *new_val;
obstack_printf (&muscle_obstack, "%s%s%s", entry->value, separator, val);
if (terms <= vals free (entry->storage);
&& STRNEQ (val + vals - terms, terminator)) new_val = obstack_finish0 (&muscle_obstack);
obstack_sgrow (&muscle_obstack, terminator); entry->value = entry->storage = xstrdup (new_val);
obstack_free (&muscle_obstack, new_val);
{ }
char *new_val = obstack_finish0 (&muscle_obstack);
entry->value = entry->storage = xstrdup (new_val);
obstack_free (&muscle_obstack, new_val);
}
} }
/*------------------------------------------------------------------. /*------------------------------------------------------------------.
@@ -214,7 +179,7 @@ muscle_syncline_grow (char const *key, location loc)
quotearg_style (c_quoting_style, loc.start.file)); quotearg_style (c_quoting_style, loc.start.file));
obstack_sgrow (&muscle_obstack, ")["); obstack_sgrow (&muscle_obstack, ")[");
extension = obstack_finish0 (&muscle_obstack); extension = obstack_finish0 (&muscle_obstack);
muscle_grow (key, extension, "", ""); muscle_grow (key, extension, "");
obstack_free (&muscle_obstack, extension); obstack_free (&muscle_obstack, extension);
} }
@@ -228,13 +193,12 @@ void
muscle_code_grow (const char *key, const char *val, location loc) muscle_code_grow (const char *key, const char *val, location loc)
{ {
muscle_syncline_grow (key, loc); muscle_syncline_grow (key, loc);
muscle_grow (key, val, "\n", "\n"); muscle_grow (key, val, "\n");
} }
void void muscle_pair_list_grow (const char *muscle,
muscle_pair_list_grow (const char *muscle, const char *a1, const char *a2)
const char *a1, const char *a2)
{ {
char *pair; char *pair;
obstack_sgrow (&muscle_obstack, "["); obstack_sgrow (&muscle_obstack, "[");
@@ -243,33 +207,54 @@ muscle_pair_list_grow (const char *muscle,
obstack_quote (&muscle_obstack, a2); obstack_quote (&muscle_obstack, a2);
obstack_sgrow (&muscle_obstack, "]"); obstack_sgrow (&muscle_obstack, "]");
pair = obstack_finish0 (&muscle_obstack); pair = obstack_finish0 (&muscle_obstack);
muscle_grow (muscle, pair, ",\n", ""); muscle_grow (muscle, pair, ",\n");
obstack_free (&muscle_obstack, pair); 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 * char const *
muscle_find_const (char const *key) muscle_find_const (char const *key)
{ {
muscle_entry *entry = muscle_lookup (key); muscle_entry probe;
return entry ? entry->value : NULL; muscle_entry *result = NULL;
probe.key = key;
result = hash_lookup (muscle_table, &probe);
if (result)
return result->value;
return 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 * char *
muscle_find (char const *key) muscle_find (char const *key)
{ {
muscle_entry *entry = muscle_lookup (key); muscle_entry probe;
if (entry) muscle_entry *result = NULL;
probe.key = key;
result = hash_lookup (muscle_table, &probe);
if (result)
{ {
aver (entry->value == entry->storage); aver (result->value == result->storage);
return entry->storage; return result->storage;
} }
return NULL; 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. */ digraphs for special characters in the file name. */
static void static void
@@ -280,12 +265,12 @@ muscle_boundary_grow (char const *key, boundary bound)
obstack_escape (&muscle_obstack, bound.file); obstack_escape (&muscle_obstack, bound.file);
obstack_printf (&muscle_obstack, ":%d.%d]]", bound.line, bound.column); obstack_printf (&muscle_obstack, ":%d.%d]]", bound.line, bound.column);
extension = obstack_finish0 (&muscle_obstack); extension = obstack_finish0 (&muscle_obstack);
muscle_grow (key, extension, "", ""); muscle_grow (key, extension, "");
obstack_free (&muscle_obstack, 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 append LOC to MUSCLE. Use digraphs for special characters in each
file name. */ file name. */
@@ -293,7 +278,7 @@ static void
muscle_location_grow (char const *key, location loc) muscle_location_grow (char const *key, location loc)
{ {
muscle_boundary_grow (key, loc.start); muscle_boundary_grow (key, loc.start);
muscle_grow (key, "", ", ", ""); muscle_grow (key, "", ", ");
muscle_boundary_grow (key, loc.end); muscle_boundary_grow (key, loc.end);
} }
@@ -344,9 +329,10 @@ string_decode (char const *key)
/* Reverse of muscle_location_grow. */ /* Reverse of muscle_location_grow. */
static location static location
location_decode (char const *value) location_decode (char const *key)
{ {
location loc; location loc;
char const *value = muscle_find_const (key);
aver (value); aver (value);
aver (*value == '['); aver (*value == '[');
aver (*++value == '['); aver (*++value == '[');
@@ -391,11 +377,11 @@ void
muscle_user_name_list_grow (char const *key, char const *user_name, muscle_user_name_list_grow (char const *key, char const *user_name,
location loc) location loc)
{ {
muscle_grow (key, "[[[[", ",", ""); muscle_grow (key, "[[[[", ",");
muscle_grow (key, user_name, "", ""); muscle_grow (key, user_name, "");
muscle_grow (key, "]], ", "", ""); muscle_grow (key, "]], ", "");
muscle_location_grow (key, loc); muscle_location_grow (key, loc);
muscle_grow (key, "]]", "", ""); muscle_grow (key, "]]", "");
} }
@@ -489,17 +475,16 @@ muscle_percent_variable_update (char const *variable, location variable_loc,
void void
muscle_percent_define_insert (char const *var, location variable_loc, muscle_percent_define_insert (char const *var, location variable_loc,
muscle_kind kind,
char const *value, char const *value,
muscle_percent_define_how how) muscle_percent_define_how how)
{ {
/* Backward compatibility. */ /* Backward compatibility. */
char *variable = muscle_percent_variable_update (var, variable_loc, &value); char *variable = muscle_percent_variable_update (var, variable_loc, &value);
uniqstr name = muscle_name (variable, NULL); char const *name = UNIQSTR_CONCAT ("percent_define(", variable, ")");
uniqstr loc_name = muscle_name (variable, "loc"); char const *loc_name = UNIQSTR_CONCAT ("percent_define_loc(", variable, ")");
uniqstr syncline_name = muscle_name (variable, "syncline"); char const *syncline_name =
uniqstr how_name = muscle_name (variable, "how"); UNIQSTR_CONCAT ("percent_define_syncline(", variable, ")");
uniqstr kind_name = muscle_name (variable, "kind"); char const *how_name = UNIQSTR_CONCAT ("percent_define_how(", variable, ")");
/* Command-line options are processed before the grammar file. */ /* Command-line options are processed before the grammar file. */
if (how == MUSCLE_PERCENT_DEFINE_GRAMMAR_FILE if (how == MUSCLE_PERCENT_DEFINE_GRAMMAR_FILE
@@ -525,7 +510,6 @@ muscle_percent_define_insert (char const *var, location variable_loc,
muscle_user_name_list_grow ("percent_define_user_variables", variable, muscle_user_name_list_grow ("percent_define_user_variables", variable,
variable_loc); variable_loc);
MUSCLE_INSERT_INT (how_name, how); MUSCLE_INSERT_INT (how_name, how);
MUSCLE_INSERT_STRING (kind_name, muscle_kind_string (kind));
end: end:
free (variable); free (variable);
} }
@@ -536,119 +520,85 @@ void
muscle_percent_define_ensure (char const *variable, location loc, muscle_percent_define_ensure (char const *variable, location loc,
bool value) bool value)
{ {
uniqstr name = muscle_name (variable, NULL);
char const *val = value ? "" : "false"; char const *val = value ? "" : "false";
char const *name = UNIQSTR_CONCAT ("percent_define(", variable, ")");
/* Don't complain is VARIABLE is already defined, but be sure to set /* %pure-parser is deprecated in favor of `%define api.pure', so use
its value to VAL. */ `%define api.pure' in a backward-compatible manner here. First,
if (!muscle_find_const (name) don't complain if %pure-parser is specified multiple times. */
|| muscle_percent_define_flag_if (variable) != value) if (!muscle_find_const (name))
muscle_percent_define_insert (variable, loc, muscle_keyword, val, 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,
MUSCLE_PERCENT_DEFINE_GRAMMAR_FILE); 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 * char *
muscle_percent_define_get (char const *variable) muscle_percent_define_get (char const *variable)
{ {
uniqstr name = muscle_name (variable, NULL); char const *name = UNIQSTR_CONCAT ("percent_define(", variable, ")");
char const *usage_name =
UNIQSTR_CONCAT ("percent_define_bison_variables(", variable, ")");
char *value = string_decode (name); char *value = string_decode (name);
if (!value) if (!value)
value = xstrdup (""); value = xstrdup ("");
muscle_percent_define_use (variable);
muscle_insert (usage_name, "");
return value; 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 location
muscle_percent_define_get_loc (char const *variable) muscle_percent_define_get_loc (char const *variable)
{ {
return location_decode (muscle_percent_define_get_raw (variable, "loc")); 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);
} }
char const * char const *
muscle_percent_define_get_syncline (char const *variable) muscle_percent_define_get_syncline (char const *variable)
{ {
return muscle_percent_define_get_raw (variable, "syncline"); 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;
} }
bool bool
muscle_percent_define_ifdef (char const *variable) muscle_percent_define_ifdef (char const *variable)
{ {
if (muscle_find_const (muscle_name (variable, NULL))) 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)
{ {
muscle_percent_define_use (variable); muscle_insert (usage_name, "");
return true; return true;
} }
else
return false; return false;
} }
bool bool
muscle_percent_define_flag_if (char const *variable) muscle_percent_define_flag_if (char const *variable)
{ {
uniqstr invalid_boolean_name = muscle_name (variable, "invalid_boolean"); char const *invalid_boolean_name =
UNIQSTR_CONCAT ("percent_define_invalid_boolean(", variable, ")");
bool result = false; bool result = false;
if (muscle_percent_define_ifdef (variable)) if (muscle_percent_define_ifdef (variable))
{ {
char *value = muscle_percent_define_get (variable); char *value = muscle_percent_define_get (variable);
muscle_percent_define_check_kind (variable, muscle_keyword);
if (value[0] == '\0' || STREQ (value, "true")) if (value[0] == '\0' || STREQ (value, "true"))
result = true; result = true;
else if (STREQ (value, "false")) else if (STREQ (value, "false"))
@@ -673,21 +623,20 @@ muscle_percent_define_flag_if (char const *variable)
void void
muscle_percent_define_default (char const *variable, char const *value) muscle_percent_define_default (char const *variable, char const *value)
{ {
uniqstr name = muscle_name (variable, NULL); 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, ")");
if (!muscle_find_const (name)) if (!muscle_find_const (name))
{ {
location loc;
MUSCLE_INSERT_STRING (name, value); MUSCLE_INSERT_STRING (name, value);
MUSCLE_INSERT_STRING (muscle_name (variable, "kind"), "keyword"); loc.start.file = loc.end.file = "<default value>";
{ loc.start.line = loc.end.line = -1;
uniqstr loc_name = muscle_name (variable, "loc"); loc.start.column = loc.end.column = -1;
location loc; muscle_insert (loc_name, "");
loc.start.file = loc.end.file = "<default value>"; muscle_location_grow (loc_name, loc);
loc.start.line = loc.end.line = -1; muscle_insert (syncline_name, "");
loc.start.column = loc.end.column = -1;
muscle_insert (loc_name, "");
muscle_location_grow (loc_name, loc);
}
muscle_insert (muscle_name (variable, "syncline"), "");
} }
} }
@@ -697,9 +646,8 @@ muscle_percent_define_check_values (char const * const *values)
for (; *values; ++values) for (; *values; ++values)
{ {
char const * const *variablep = values; char const * const *variablep = values;
uniqstr name = muscle_name (*variablep, NULL); char const *name = UNIQSTR_CONCAT ("percent_define(", *variablep, ")");
char *value = string_decode (name); char *value = string_decode (name);
muscle_percent_define_check_kind (*variablep, muscle_keyword);
if (value) if (value)
{ {
for (++values; *values; ++values) for (++values; *values; ++values)
@@ -716,7 +664,7 @@ muscle_percent_define_check_values (char const * const *values)
quote (*variablep), quote_n (1, value)); quote (*variablep), quote_n (1, value));
i += SUB_INDENT; i += SUB_INDENT;
for (values = variablep + 1; *values; ++values) for (values = variablep + 1; *values; ++values)
complain_indent (&loc, complaint | no_caret | silent, &i, complain_indent (&loc, complaint | no_caret, &i,
_("accepted value: %s"), quote (*values)); _("accepted value: %s"), quote (*values));
} }
else else
@@ -763,6 +711,11 @@ muscle_m4_output_processor (void *entry, void *out)
} }
/*----------------------------------------------------------------.
| Output the definition of all the current muscles into a list of |
| m4_defines. |
`----------------------------------------------------------------*/
void void
muscles_m4_output (FILE *out) muscles_m4_output (FILE *out)
{ {
+18 -44
View File
@@ -24,41 +24,10 @@
# include "location.h" # 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); 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); 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); 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); char *muscle_find (char const *key);
/* Free all the memory consumed by the muscle machinery only. */
void muscle_free (void); void muscle_free (void);
@@ -78,14 +47,14 @@ extern struct obstack muscle_obstack;
} while (0) } while (0)
# define MUSCLE_INSERT_INT(Key, Value) \ # define MUSCLE_INSERT_INT(Key, Value) \
MUSCLE_INSERTF (Key, "%d", Value) MUSCLE_INSERTF(Key, "%d", Value)
# define MUSCLE_INSERT_LONG_INT(Key, 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. */ /* Key -> Value, but don't apply escaping to Value. */
# define MUSCLE_INSERT_STRING_RAW(Key, 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. */ /* Key -> Value, applying M4 escaping to Value. */
# define MUSCLE_INSERT_STRING(Key, Value) \ # define MUSCLE_INSERT_STRING(Key, Value) \
@@ -94,14 +63,23 @@ extern struct obstack muscle_obstack;
muscle_insert (Key, obstack_finish0 (&muscle_obstack)); \ muscle_insert (Key, obstack_finish0 (&muscle_obstack)); \
} while (0) } while (0)
/* Key -> Value, applying C escaping to Value (and then M4). */
# define MUSCLE_INSERT_C_STRING(Key, Value) \ # define MUSCLE_INSERT_C_STRING(Key, Value) \
MUSCLE_INSERT_STRING (Key, quotearg_style (c_quoting_style, 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);
/* Append VALUE to the current value of KEY, using muscle_grow. But /* 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); void muscle_code_grow (const char *key, const char *value, location loc);
@@ -114,15 +92,14 @@ void muscle_pair_list_grow (const char *muscle,
/* Grow KEY for the occurrence of the name USER_NAME at LOC appropriately for /* 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 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, void muscle_user_name_list_grow (char const *key, char const *user_name,
location loc); location loc);
/* Indicates whether a variable's value was specified with -D/--define, with /* Indicates whether a variable's value was specified with -D/--define, with
-F/--force-define, or in the grammar file. */ -F/--force-define, or in the grammar file. */
typedef enum { typedef enum {
MUSCLE_PERCENT_DEFINE_D = 0, MUSCLE_PERCENT_DEFINE_D = 0, MUSCLE_PERCENT_DEFINE_F,
MUSCLE_PERCENT_DEFINE_F,
MUSCLE_PERCENT_DEFINE_GRAMMAR_FILE MUSCLE_PERCENT_DEFINE_GRAMMAR_FILE
} muscle_percent_define_how; } muscle_percent_define_how;
@@ -136,7 +113,6 @@ typedef enum {
this as a user occurrence of VARIABLE by invoking this as a user occurrence of VARIABLE by invoking
muscle_user_name_list_grow. */ muscle_user_name_list_grow. */
void muscle_percent_define_insert (char const *variable, location variable_loc, void muscle_percent_define_insert (char const *variable, location variable_loc,
muscle_kind kind,
char const *value, char const *value,
muscle_percent_define_how how); muscle_percent_define_how how);
@@ -210,8 +186,6 @@ void muscle_percent_define_check_values (char const * const *values);
void muscle_percent_code_grow (char const *qualifier, location qualifier_loc, void muscle_percent_code_grow (char const *qualifier, location qualifier_loc,
char const *code, location code_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); void muscles_m4_output (FILE *out);
#endif /* not MUSCLE_TAB_H_ */ #endif /* not MUSCLE_TAB_H_ */
+21 -20
View File
@@ -90,19 +90,20 @@ Name (char const *name, \
\ \
lmin = min; \ lmin = min; \
lmax = max; \ 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); \ obstack_printf (&format_obstack, "%s_min", name); \
MUSCLE_INSERT_LONG_INT (obstack_finish0 (&format_obstack), lmin); \ MUSCLE_INSERT_LONG_INT (obstack_finish0 (&format_obstack), lmin); \
obstack_printf (&format_obstack, "%s_max", name); \ obstack_printf (&format_obstack, "%s_max", name); \
MUSCLE_INSERT_LONG_INT (obstack_finish0 (&format_obstack), lmax); \ MUSCLE_INSERT_LONG_INT (obstack_finish0 (&format_obstack), lmax); \
} }
GENERATE_MUSCLE_INSERT_TABLE (muscle_insert_unsigned_int_table, unsigned int) GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_unsigned_int_table, unsigned int)
GENERATE_MUSCLE_INSERT_TABLE (muscle_insert_int_table, 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_base_table, base_number)
GENERATE_MUSCLE_INSERT_TABLE (muscle_insert_rule_number_table, rule_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_symbol_number_table, symbol_number)
GENERATE_MUSCLE_INSERT_TABLE (muscle_insert_state_number_table, state_number) GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_state_number_table, state_number)
/*----------------------------------------------------------------. /*----------------------------------------------------------------.
| Print to OUT a representation of CP quoted and escaped for M4. | | Print to OUT a representation of CP quoted and escaped for M4. |
@@ -226,7 +227,7 @@ prepare_rules (void)
/* LHS of the rule R. */ /* LHS of the rule R. */
r1[r] = rules[r].lhs->number; r1[r] = rules[r].lhs->number;
/* Length of rule R's RHS. */ /* 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. */ /* Line where rule was defined. */
rline[r] = rules[r].location.start.line; rline[r] = rules[r].location.start.line;
/* Dynamic precedence (GLR). */ /* Dynamic precedence (GLR). */
@@ -416,31 +417,31 @@ prepare_symbol_definitions (void)
/* Whether the symbol has an identifier. */ /* Whether the symbol has an identifier. */
value = symbol_id_get (sym); value = symbol_id_get (sym);
SET_KEY ("has_id"); SET_KEY("has_id");
MUSCLE_INSERT_INT (key, !!value); MUSCLE_INSERT_INT (key, !!value);
/* Its identifier. */ /* Its identifier. */
SET_KEY ("id"); SET_KEY("id");
MUSCLE_INSERT_STRING (key, value ? value : ""); MUSCLE_INSERT_STRING (key, value ? value : "");
/* Its tag. Typically for documentation purpose. */ /* Its tag. Typically for documentation purpose. */
SET_KEY ("tag"); SET_KEY("tag");
MUSCLE_INSERT_STRING (key, sym->tag); MUSCLE_INSERT_STRING (key, sym->tag);
SET_KEY ("user_number"); SET_KEY("user_number");
MUSCLE_INSERT_INT (key, sym->user_token_number); MUSCLE_INSERT_INT (key, sym->user_token_number);
SET_KEY ("is_token"); SET_KEY("is_token");
MUSCLE_INSERT_INT (key, MUSCLE_INSERT_INT (key,
i < ntokens && sym != errtoken && sym != undeftoken); i < ntokens && sym != errtoken && sym != undeftoken);
SET_KEY ("number"); SET_KEY("number");
MUSCLE_INSERT_INT (key, sym->number); MUSCLE_INSERT_INT (key, sym->number);
SET_KEY ("has_type"); SET_KEY("has_type");
MUSCLE_INSERT_INT (key, !!sym->type_name); MUSCLE_INSERT_INT (key, !!sym->type_name);
SET_KEY ("type"); SET_KEY("type");
MUSCLE_INSERT_STRING (key, sym->type_name ? sym->type_name : ""); MUSCLE_INSERT_STRING (key, sym->type_name ? sym->type_name : "");
{ {
@@ -450,18 +451,18 @@ prepare_symbol_definitions (void)
/* "printer", not "%printer". */ /* "printer", not "%printer". */
char const *pname = code_props_type_string (j) + 1; char const *pname = code_props_type_string (j) + 1;
code_props const *p = symbol_code_props_get (sym, j); code_props const *p = symbol_code_props_get (sym, j);
SET_KEY2 ("has", pname); SET_KEY2("has", pname);
MUSCLE_INSERT_INT (key, !!p->code); MUSCLE_INSERT_INT (key, !!p->code);
if (p->code) if (p->code)
{ {
SET_KEY2 (pname, "file"); SET_KEY2(pname, "file");
MUSCLE_INSERT_STRING (key, p->location.start.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); MUSCLE_INSERT_INT (key, p->location.start.line);
SET_KEY (pname); SET_KEY(pname);
MUSCLE_INSERT_STRING_RAW (key, p->code); MUSCLE_INSERT_STRING_RAW (key, p->code);
} }
} }
+691 -692
View File
File diff suppressed because it is too large Load Diff
+133 -89
View File
@@ -1,4 +1,4 @@
/* A Bison parser, made by GNU Bison 2.7.90. */ /* A Bison parser, made by GNU Bison 2.7.1021-bb417-dirty. */
/* Bison interface for Yacc-like parsers in C /* Bison interface for Yacc-like parsers in C
@@ -48,12 +48,10 @@
extern int gram_debug; extern int gram_debug;
#endif #endif
/* "%code requires" blocks. */ /* "%code requires" blocks. */
#line 21 "src/parse-gram.y" /* yacc.c:1926 */ #line 223 "src/parse-gram.y" /* yacc.c:1932 */
#include "symlist.h"
#include "symtab.h"
#line 221 "src/parse-gram.y" /* yacc.c:1926 */
# ifndef PARAM_TYPE
# define PARAM_TYPE
typedef enum typedef enum
{ {
param_none = 0, param_none = 0,
@@ -61,10 +59,10 @@ extern int gram_debug;
param_parse = 1 << 1, param_parse = 1 << 1,
param_both = param_lex | param_parse param_both = param_lex | param_parse
} param_type; } param_type;
#line 645 "src/parse-gram.y" /* yacc.c:1926 */ # endif
#include "muscle-tab.h"
#line 68 "src/parse-gram.h" /* yacc.c:1926 */
#line 66 "src/parse-gram.h" /* yacc.c:1932 */
/* Token type. */ /* Token type. */
#ifndef GRAM_TOKENTYPE #ifndef GRAM_TOKENTYPE
@@ -73,97 +71,143 @@ extern int gram_debug;
{ {
GRAM_EOF = 0, GRAM_EOF = 0,
STRING = 258, STRING = 258,
PERCENT_TOKEN = 259, INT = 259,
PERCENT_NTERM = 260, PERCENT_TOKEN = 260,
PERCENT_TYPE = 261, PERCENT_NTERM = 261,
PERCENT_DESTRUCTOR = 262, PERCENT_TYPE = 262,
PERCENT_PRINTER = 263, PERCENT_DESTRUCTOR = 263,
PERCENT_LEFT = 264, PERCENT_PRINTER = 264,
PERCENT_RIGHT = 265, PERCENT_LEFT = 265,
PERCENT_NONASSOC = 266, PERCENT_RIGHT = 266,
PERCENT_PRECEDENCE = 267, PERCENT_NONASSOC = 267,
PERCENT_PREC = 268, PERCENT_PRECEDENCE = 268,
PERCENT_DPREC = 269, PERCENT_PREC = 269,
PERCENT_MERGE = 270, PERCENT_DPREC = 270,
PERCENT_CODE = 271, PERCENT_MERGE = 271,
PERCENT_DEFAULT_PREC = 272, PERCENT_CODE = 272,
PERCENT_DEFINE = 273, PERCENT_DEFAULT_PREC = 273,
PERCENT_DEFINES = 274, PERCENT_DEFINE = 274,
PERCENT_ERROR_VERBOSE = 275, PERCENT_DEFINES = 275,
PERCENT_EXPECT = 276, PERCENT_ERROR_VERBOSE = 276,
PERCENT_EXPECT_RR = 277, PERCENT_EXPECT = 277,
PERCENT_FLAG = 278, PERCENT_EXPECT_RR = 278,
PERCENT_FILE_PREFIX = 279, PERCENT_FLAG = 279,
PERCENT_GLR_PARSER = 280, PERCENT_FILE_PREFIX = 280,
PERCENT_INITIAL_ACTION = 281, PERCENT_GLR_PARSER = 281,
PERCENT_LANGUAGE = 282, PERCENT_INITIAL_ACTION = 282,
PERCENT_NAME_PREFIX = 283, PERCENT_LANGUAGE = 283,
PERCENT_NO_DEFAULT_PREC = 284, PERCENT_NAME_PREFIX = 284,
PERCENT_NO_LINES = 285, PERCENT_NO_DEFAULT_PREC = 285,
PERCENT_NONDETERMINISTIC_PARSER = 286, PERCENT_NO_LINES = 286,
PERCENT_OUTPUT = 287, PERCENT_NONDETERMINISTIC_PARSER = 287,
PERCENT_REQUIRE = 288, PERCENT_OUTPUT = 288,
PERCENT_SKELETON = 289, PERCENT_REQUIRE = 289,
PERCENT_START = 290, PERCENT_SKELETON = 290,
PERCENT_TOKEN_TABLE = 291, PERCENT_START = 291,
PERCENT_VERBOSE = 292, PERCENT_TOKEN_TABLE = 292,
PERCENT_YACC = 293, PERCENT_VERBOSE = 293,
BRACED_CODE = 294, PERCENT_YACC = 294,
BRACED_PREDICATE = 295, BRACED_CODE = 295,
BRACKETED_ID = 296, BRACED_PREDICATE = 296,
CHAR = 297, BRACKETED_ID = 297,
EPILOGUE = 298, CHAR = 298,
EQUAL = 299, EPILOGUE = 299,
ID = 300, EQUAL = 300,
ID_COLON = 301, ID = 301,
PERCENT_PERCENT = 302, ID_COLON = 302,
PIPE = 303, PERCENT_PERCENT = 303,
PROLOGUE = 304, PIPE = 304,
SEMICOLON = 305, PROLOGUE = 305,
TAG = 306, SEMICOLON = 306,
TAG_ANY = 307, TAG = 307,
TAG_NONE = 308, TAG_ANY = 308,
INT = 309, TAG_NONE = 309,
PERCENT_PARAM = 310, PERCENT_PARAM = 310,
PERCENT_UNION = 311, PERCENT_UNION = 311
PERCENT_EMPTY = 312
}; };
#endif #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. */ /* Value type. */
#if ! defined GRAM_STYPE && ! defined GRAM_STYPE_IS_DECLARED #if ! defined GRAM_STYPE && ! defined GRAM_STYPE_IS_DECLARED
typedef union GRAM_STYPE GRAM_STYPE; typedef union GRAM_STYPE GRAM_STYPE;
union GRAM_STYPE union GRAM_STYPE
{ {
#line 182 "src/parse-gram.y" /* yacc.c:1926 */ #line 109 "src/parse-gram.y" /* yacc.c:1932 */
unsigned char character;
#line 186 "src/parse-gram.y" /* yacc.c:1926 */ assoc assoc;
char *code; char *code;
#line 191 "src/parse-gram.y" /* yacc.c:1926 */ char const *chars;
uniqstr uniqstr; int integer;
#line 199 "src/parse-gram.y" /* yacc.c:1926 */ named_ref *named_ref;
int integer; symbol *symbol;
#line 203 "src/parse-gram.y" /* yacc.c:1926 */ symbol_list *list;
symbol *symbol; uniqstr uniqstr;
#line 208 "src/parse-gram.y" /* yacc.c:1926 */ unsigned char character;
assoc assoc;
#line 211 "src/parse-gram.y" /* yacc.c:1926 */ #line 247 "src/parse-gram.y" /* yacc.c:1932 */
symbol_list *list;
#line 214 "src/parse-gram.y" /* yacc.c:1926 */ param_type param;
named_ref *named_ref;
#line 241 "src/parse-gram.y" /* yacc.c:1926 */ #line 423 "src/parse-gram.y" /* yacc.c:1932 */
param_type param;
#line 409 "src/parse-gram.y" /* yacc.c:1926 */
code_props_type code_type; code_props_type code_type;
#line 647 "src/parse-gram.y" /* yacc.c:1926 */
struct #line 211 "src/parse-gram.h" /* yacc.c:1932 */
{
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_TRIVIAL 1
# define GRAM_STYPE_IS_DECLARED 1 # define GRAM_STYPE_IS_DECLARED 1
+146 -185
View File
@@ -1,4 +1,4 @@
/* Bison Grammar Parser -*- C -*- %{/* Bison Grammar Parser -*- C -*-
Copyright (C) 2002-2013 Free Software Foundation, Inc. Copyright (C) 2002-2013 Free Software Foundation, Inc.
@@ -17,35 +17,45 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */ 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 <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 %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 int current_prec = 0;
static location current_lhs_location; static location current_lhs_location;
static named_ref *current_lhs_named_ref; static named_ref *current_lhs_named_ref;
@@ -56,37 +66,20 @@
/** Set the new current left-hand side symbol, possibly common /** Set the new current left-hand side symbol, possibly common
* to several right-hand side parts of rule. * to several right-hand side parts of rule.
*/ */
static void current_lhs (symbol *sym, location loc, named_ref *ref); static
void
#define YYLLOC_DEFAULT(Current, Rhs, N) \ current_lhs(symbol *sym, location loc, named_ref *ref)
(Current) = lloc_default (Rhs, N) {
static YYLTYPE lloc_default (YYLTYPE const *, int); current_lhs_symbol = sym;
current_lhs_location = loc;
#define YY_LOCATION_PRINT(File, Loc) \ /* In order to simplify memory management, named references for lhs
location_print (Loc, File) are always assigned by deep copy into the current symbol_list
node. This is because a single named-ref in the grammar may
/* Strip initial '{' and final '}' (must be first and last characters). result in several uses when the user factors lhs between several
Return the result. */ rules using "|". Therefore free the parser's original copy. */
static char *strip_braces (char *code); free (current_lhs_named_ref);
current_lhs_named_ref = ref;
/* 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_INT16 int_fast16_t
#define YYTYPE_INT8 int_fast8_t #define YYTYPE_INT8 int_fast8_t
@@ -94,8 +87,8 @@
#define YYTYPE_UINT8 uint_fast8_t #define YYTYPE_UINT8 uint_fast8_t
} }
%define api.prefix {gram_} %define api.prefix "gram_"
%define api.pure full %define api.pure
%define locations %define locations
%define parse.error verbose %define parse.error verbose
%define parse.lac full %define parse.lac full
@@ -112,9 +105,23 @@
boundary_set (&@$.end, current_file, 1, 1); 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. */ /* Define the tokens together with their human representation. */
%token GRAM_EOF 0 "end of file" %token GRAM_EOF 0 "end of file"
%token STRING "string" %token STRING "string"
%token INT "integer"
%token PERCENT_TOKEN "%token" %token PERCENT_TOKEN "%token"
%token PERCENT_NTERM "%nterm" %token PERCENT_NTERM "%nterm"
@@ -179,16 +186,18 @@
%token TAG_ANY "<*>" %token TAG_ANY "<*>"
%token TAG_NONE "<>" %token TAG_NONE "<>"
%union {unsigned char character;}
%type <character> CHAR %type <character> CHAR
%printer { fputs (char_name ($$), yyo); } CHAR %printer { fputs (char_name ($$), yyo); } CHAR
%union {char *code;}; /* braceless is not to be used for rule or symbol actions, as it
%type <code> "{...}" "%?{...}" "%{...%}" EPILOGUE STRING calls code_props_plain_init. */
%printer { fputs (quotearg_style (c_quoting_style, $$), yyo); } STRING %type <chars> STRING "%{...%}" EPILOGUE braceless content.opt
%printer { fprintf (yyo, "{\n%s\n}", $$); } <code> %type <code> "{...}" "%?{...}"
%printer { fputs (quotearg_style (c_quoting_style, $$), yyo); }
STRING
%printer { fprintf (yyo, "{\n%s\n}", $$); }
braceless content.opt "{...}" "%{...%}" EPILOGUE
%union {uniqstr uniqstr;}
%type <uniqstr> BRACKETED_ID ID ID_COLON PERCENT_FLAG TAG tag variable %type <uniqstr> BRACKETED_ID ID ID_COLON PERCENT_FLAG TAG tag variable
%printer { fputs ($$, yyo); } <uniqstr> %printer { fputs ($$, yyo); } <uniqstr>
%printer { fprintf (yyo, "[%s]", $$); } BRACKETED_ID %printer { fprintf (yyo, "[%s]", $$); } BRACKETED_ID
@@ -196,22 +205,15 @@
%printer { fprintf (yyo, "%%%s", $$); } PERCENT_FLAG %printer { fprintf (yyo, "%%%s", $$); } PERCENT_FLAG
%printer { fprintf (yyo, "<%s>", $$); } TAG tag %printer { fprintf (yyo, "<%s>", $$); } TAG tag
%union {int integer;}; %type <integer> INT
%token <integer> INT "integer"
%printer { fprintf (yyo, "%d", $$); } <integer> %printer { fprintf (yyo, "%d", $$); } <integer>
%union {symbol *symbol;}
%type <symbol> id id_colon string_as_id symbol symbol.prec %type <symbol> id id_colon string_as_id symbol symbol.prec
%printer { fprintf (yyo, "%s", $$->tag); } <symbol> %printer { fprintf (yyo, "%s", $$->tag); } <symbol>
%printer { fprintf (yyo, "%s:", $$->tag); } id_colon %printer { fprintf (yyo, "%s:", $$->tag); } id_colon
%union {assoc assoc;};
%type <assoc> precedence_declarator %type <assoc> precedence_declarator
%union {symbol_list *list;}
%type <list> symbols.1 symbols.prec generic_symlist generic_symlist_item %type <list> symbols.1 symbols.prec generic_symlist generic_symlist_item
%union {named_ref *named_ref;}
%type <named_ref> named_ref.opt %type <named_ref> named_ref.opt
/*---------. /*---------.
@@ -219,6 +221,8 @@
`---------*/ `---------*/
%code requires %code requires
{ {
# ifndef PARAM_TYPE
# define PARAM_TYPE
typedef enum typedef enum
{ {
param_none = 0, param_none = 0,
@@ -226,6 +230,7 @@
param_parse = 1 << 1, param_parse = 1 << 1,
param_both = param_lex | param_parse param_both = param_lex | param_parse
} param_type; } param_type;
# endif
}; };
%code %code
{ {
@@ -238,17 +243,20 @@
static void add_param (param_type type, char *decl, location loc); static void add_param (param_type type, char *decl, location loc);
static param_type current_param = param_none; static param_type current_param = param_none;
}; };
%union {param_type param;} %union
{
param_type param;
}
%token <param> PERCENT_PARAM "%param"; %token <param> PERCENT_PARAM "%param";
%printer %printer
{ {
switch ($$) switch ($$)
{ {
#define CASE(In, Out) \ #define CASE(In, Out) \
case param_ ## In: fputs ("%" #Out, yyo); break case param_ ## In: fputs ("%" #Out, stderr); break
CASE (lex, lex-param); CASE(lex, lex-param);
CASE (parse, parse-param); CASE(parse, parse-param);
CASE (both, param); CASE(both, param);
#undef CASE #undef CASE
case param_none: aver (false); break; case param_none: aver (false); break;
} }
@@ -270,7 +278,7 @@ input:
`------------------------------------*/ `------------------------------------*/
prologue_declarations: prologue_declarations:
%empty /* Nothing */
| prologue_declarations prologue_declaration | prologue_declarations prologue_declaration
; ;
@@ -278,17 +286,21 @@ prologue_declaration:
grammar_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", muscle_code_grow (union_seen ? "post_prologue" : "pre_prologue",
translate_code ($1, @1, true), @1); plain_code.code, @1);
code_scanner_last_string_free (); code_scanner_last_string_free ();
} }
| "%<flag>" | "%<flag>"
{ {
muscle_percent_define_ensure ($1, @1, true); muscle_percent_define_ensure ($1, @1, true);
} }
| "%define" variable value | "%define" variable content.opt
{ {
muscle_percent_define_insert ($2, @2, $3.kind, $3.chars, muscle_percent_define_insert ($2, @2, $3,
MUSCLE_PERCENT_DEFINE_GRAMMAR_FILE); MUSCLE_PERCENT_DEFINE_GRAMMAR_FILE);
} }
| "%defines" { defines_flag = true; } | "%defines" { defines_flag = true; }
@@ -299,8 +311,7 @@ prologue_declaration:
} }
| "%error-verbose" | "%error-verbose"
{ {
muscle_percent_define_insert ("parse.error", @1, muscle_keyword, muscle_percent_define_insert ("parse.error", @1, "verbose",
"verbose",
MUSCLE_PERCENT_DEFINE_GRAMMAR_FILE); MUSCLE_PERCENT_DEFINE_GRAMMAR_FILE);
} }
| "%expect" INT { expected_sr_conflicts = $2; } | "%expect" INT { expected_sr_conflicts = $2; }
@@ -313,7 +324,11 @@ prologue_declaration:
} }
| "%initial-action" "{...}" | "%initial-action" "{...}"
{ {
muscle_code_grow ("initial_action", translate_code ($2, @2, false), @2); 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);
code_scanner_last_string_free (); code_scanner_last_string_free ();
} }
| "%language" STRING { language_argmatch ($2, grammar_prio, @1); } | "%language" STRING { language_argmatch ($2, grammar_prio, @1); }
@@ -390,17 +405,16 @@ grammar_declaration:
{ {
default_prec = false; default_prec = false;
} }
| "%code" "{...}" | "%code" braceless
{ {
/* Do not invoke muscle_percent_code_grow here since it invokes /* Do not invoke muscle_percent_code_grow here since it invokes
muscle_user_name_list_grow. */ muscle_user_name_list_grow. */
muscle_code_grow ("percent_code()", muscle_code_grow ("percent_code()", $2, @2);
translate_code_braceless ($2, @2), @2);
code_scanner_last_string_free (); code_scanner_last_string_free ();
} }
| "%code" ID "{...}" | "%code" ID braceless
{ {
muscle_percent_code_grow ($2, @2, translate_code_braceless ($3, @3), @3); muscle_percent_code_grow ($2, @2, $3, @3);
code_scanner_last_string_free (); code_scanner_last_string_free ();
} }
; ;
@@ -420,15 +434,15 @@ code_props_type:
%token PERCENT_UNION "%union"; %token PERCENT_UNION "%union";
union_name: union_name:
%empty {} /* Nothing. */ {}
| ID { muscle_code_grow ("union_name", $1, @1); } | ID { muscle_code_grow ("union_name", $1, @1); }
; ;
grammar_declaration: grammar_declaration:
"%union" union_name "{...}" "%union" union_name braceless
{ {
union_seen = true; union_seen = true;
muscle_code_grow ("union_members", translate_code_braceless ($3, @3), @3); muscle_code_grow ("stype", $3, @3);
code_scanner_last_string_free (); code_scanner_last_string_free ();
} }
; ;
@@ -480,8 +494,8 @@ precedence_declarator:
; ;
tag.opt: tag.opt:
%empty { current_type = NULL; } /* Nothing. */ { current_type = NULL; }
| TAG { current_type = $1; tag_seen = true; } | TAG { current_type = $1; tag_seen = true; }
; ;
/* Just like symbols.1 but accept INT for the sake of POSIX. */ /* Just like symbols.1 but accept INT for the sake of POSIX. */
@@ -493,17 +507,8 @@ symbols.prec:
; ;
symbol.prec: symbol.prec:
symbol symbol { $$ = $1; }
{ | symbol INT { $$ = $1; symbol_user_token_number_set ($1, $2, @2); }
$$ = $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. */ /* One or more symbols to be %typed. */
@@ -604,9 +609,8 @@ rhses.1:
| rhses.1 ";" | rhses.1 ";"
; ;
%token PERCENT_EMPTY "%empty";
rhs: rhs:
%empty /* Nothing. */
{ grammar_current_rule_begin (current_lhs_symbol, current_lhs_location, { grammar_current_rule_begin (current_lhs_symbol, current_lhs_location,
current_lhs_named_ref); } current_lhs_named_ref); }
| rhs symbol named_ref.opt | rhs symbol named_ref.opt
@@ -615,8 +619,6 @@ rhs:
{ grammar_current_rule_action_append ($2, @2, $3, false); } { grammar_current_rule_action_append ($2, @2, $3, false); }
| rhs "%?{...}" | rhs "%?{...}"
{ grammar_current_rule_action_append ($2, @2, NULL, true); } { grammar_current_rule_action_append ($2, @2, NULL, true); }
| rhs "%empty"
{ grammar_current_rule_empty_set (@2); }
| rhs "%prec" symbol | rhs "%prec" symbol
{ grammar_current_rule_prec_set ($3, @3); } { grammar_current_rule_prec_set ($3, @3); }
| rhs "%dprec" INT | rhs "%dprec" INT
@@ -626,47 +628,44 @@ rhs:
; ;
named_ref.opt: named_ref.opt:
%empty { $$ = 0; } /* Nothing. */ { $$ = 0; }
| BRACKETED_ID { $$ = named_ref_new ($1, @1); } |
BRACKETED_ID { $$ = named_ref_new($1, @1); }
; ;
/*---------------------. /*---------------------------.
| variable and value. | | variable and content.opt. |
`---------------------*/ `---------------------------*/
/* The STRING form of variable is deprecated and is not M4-friendly. /* 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: variable:
ID ID
| STRING { $$ = uniqstr_new ($1); } | STRING { $$ = uniqstr_new ($1); }
; ;
/* Some content or empty by default. */ /* Some content or empty by default. */
%code requires {#include "muscle-tab.h"}; content.opt:
%union /* Nothing. */ { $$ = ""; }
{ | ID { $$ = $1; }
struct | STRING
{ ;
char const *chars;
muscle_kind kind;
} value;
};
%type <value> value;
%printer
{
switch ($$.kind)
{
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; } | braceless. |
| STRING { $$.kind = muscle_string; $$.chars = $1; } `------------*/
| "{...}" { $$.kind = muscle_code; $$.chars = strip_braces ($1); }
braceless:
"{...}"
{
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;
}
; ;
@@ -708,10 +707,14 @@ string_as_id:
; ;
epilogue.opt: epilogue.opt:
%empty /* Nothing. */
| "%%" EPILOGUE | "%%" EPILOGUE
{ {
muscle_code_grow ("epilogue", translate_code ($2, @2, true), @2); 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);
code_scanner_last_string_free (); code_scanner_last_string_free ();
} }
; ;
@@ -747,33 +750,6 @@ lloc_default (YYLTYPE const *rhs, int n)
return loc; 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 static void
add_param (param_type type, char *decl, location loc) add_param (param_type type, char *decl, location loc)
@@ -856,18 +832,3 @@ char_name (char c)
return quotearg_style (escape_quoting_style, buf); 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;
}
+7 -13
View File
@@ -45,8 +45,7 @@ struct escape_buf
char *ptr; char *ptr;
size_t size; size_t size;
}; };
enum { num_escape_bufs = 3 }; static struct escape_buf escape_bufs[3];
static struct escape_buf escape_bufs[num_escape_bufs];
/*--------------------------------. /*--------------------------------.
@@ -210,7 +209,7 @@ print_errs (FILE *out, int level, state *s)
/*-------------------------------------------------------------------------. /*-------------------------------------------------------------------------.
| Report a reduction of RULE on LOOKAHEAD_TOKEN (which can be 'default'). | | Report a reduction of RULE on LOOKAHEAD_TOKEN (which can be `default'). |
| If not ENABLED, the rule is masked by a shift or a reduce (S/R and | | If not ENABLED, the rule is masked by a shift or a reduce (S/R and |
| R/R conflicts). | | R/R conflicts). |
`-------------------------------------------------------------------------*/ `-------------------------------------------------------------------------*/
@@ -497,6 +496,7 @@ xml_escape (char const *str)
void void
print_xml (void) print_xml (void)
{ {
state_number i;
int level = 0; int level = 0;
FILE *out = xfopen (spec_xml_file, "w"); FILE *out = xfopen (spec_xml_file, "w");
@@ -522,11 +522,8 @@ print_xml (void)
/* print automaton */ /* print automaton */
fputc ('\n', out); fputc ('\n', out);
xml_puts (out, level + 1, "<automaton>"); xml_puts (out, level + 1, "<automaton>");
{ for (i = 0; i < nstates; i++)
state_number i; print_state (out, level + 2, states[i]);
for (i = 0; i < nstates; i++)
print_state (out, level + 2, states[i]);
}
xml_puts (out, level + 1, "</automaton>"); xml_puts (out, level + 1, "</automaton>");
bitset_free (no_reduce_set); bitset_free (no_reduce_set);
@@ -534,11 +531,8 @@ print_xml (void)
xml_puts (out, 0, "</bison-xml-report>"); xml_puts (out, 0, "</bison-xml-report>");
{ free (escape_bufs[0].ptr);
int i; free (escape_bufs[1].ptr);
for (i = 0; i < num_escape_bufs; ++i)
free (escape_bufs[i].ptr);
}
xfclose (out); xfclose (out);
} }
+2 -2
View File
@@ -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 | | If not ENABLED, the rule is masked by a shift or a reduce (S/R and |
| R/R conflicts). | | R/R conflicts). |
`-------------------------------------------------------------------------*/ `-------------------------------------------------------------------------*/
@@ -514,7 +514,7 @@ print_results (void)
print_grammar (out); print_grammar (out);
/* If the whole state item sets, not only the kernels, are wanted, /* 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) if (report_flag & report_itemsets)
new_closure (nritems); new_closure (nritems);
/* Storage for print_reductions. */ /* Storage for print_reductions. */
+43 -82
View File
@@ -267,9 +267,9 @@ symbol_should_be_used (symbol_list const *s, bool *midrule_warning)
return true; return true;
if ((s->midrule && s->midrule->action_props.is_value_used) if ((s->midrule && s->midrule->action_props.is_value_used)
|| (s->midrule_parent_rule || (s->midrule_parent_rule
&& (symbol_list_n_get (s->midrule_parent_rule, && symbol_list_n_get (s->midrule_parent_rule,
s->midrule_parent_rhs_index) s->midrule_parent_rhs_index)
->action_props.is_value_used))) ->action_props.is_value_used))
{ {
*midrule_warning = true; *midrule_warning = true;
return true; return true;
@@ -321,7 +321,7 @@ grammar_rule_check (const symbol_list *r)
bool midrule_warning = false; bool midrule_warning = false;
if (!l->action_props.is_value_used if (!l->action_props.is_value_used
&& symbol_should_be_used (l, &midrule_warning) && 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))) && (r->action_props.code || (n != 0 && n != 1)))
{ {
warnings warn_flag = midrule_warning ? Wmidrule_values : Wother; warnings warn_flag = midrule_warning ? Wmidrule_values : Wother;
@@ -333,18 +333,6 @@ 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 /* See comments in grammar_current_rule_prec_set for how POSIX
mandates this complaint. It's only for identifiers, so skip mandates this complaint. It's only for identifiers, so skip
it for char literals and strings, which are always tokens. */ it for char literals and strings, which are always tokens. */
@@ -442,26 +430,8 @@ grammar_current_rule_prec_set (symbol *precsym, location loc)
token. */ token. */
symbol_class_set (precsym, token_sym, loc, false); symbol_class_set (precsym, token_sym, loc, false);
if (current_rule->ruleprec) if (current_rule->ruleprec)
duplicate_directive ("%prec", complain (&loc, complaint, _("only one %s allowed per rule"), "%prec");
current_rule->ruleprec->location, loc); current_rule->ruleprec = precsym;
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. */ /* Attach dynamic precedence DPREC to the current rule. */
@@ -476,13 +446,8 @@ grammar_current_rule_dprec_set (int dprec, location loc)
complain (&loc, complaint, _("%s must be followed by positive number"), complain (&loc, complaint, _("%s must be followed by positive number"),
"%dprec"); "%dprec");
else if (current_rule->dprec != 0) else if (current_rule->dprec != 0)
duplicate_directive ("%dprec", complain (&loc, complaint, _("only one %s allowed per rule"), "%dprec");
current_rule->dprec_location, loc); current_rule->dprec = dprec;
else
{
current_rule->dprec = dprec;
current_rule->dprec_location = loc;
}
} }
/* Attach a merge function NAME with argument type TYPE to current /* Attach a merge function NAME with argument type TYPE to current
@@ -495,13 +460,9 @@ grammar_current_rule_merge_set (uniqstr name, location loc)
complain (&loc, Wother, _("%s affects only GLR parsers"), complain (&loc, Wother, _("%s affects only GLR parsers"),
"%merge"); "%merge");
if (current_rule->merger != 0) if (current_rule->merger != 0)
duplicate_directive ("%merge", complain (&loc, complaint, _("only one %s allowed per rule"), "%merge");
current_rule->merger_declaration_location, loc); current_rule->merger = get_merge_function (name);
else current_rule->merger_declaration_location = loc;
{
current_rule->merger = get_merge_function (name);
current_rule->merger_declaration_location = loc;
}
} }
/* Attach SYM to the current rule. If needed, move the previous /* Attach SYM to the current rule. If needed, move the previous
@@ -516,7 +477,7 @@ grammar_current_rule_symbol_append (symbol *sym, location loc,
grammar_midrule_action (); grammar_midrule_action ();
p = grammar_symbol_append (sym, loc); p = grammar_symbol_append (sym, loc);
if (name) if (name)
assign_named_ref (p, name); assign_named_ref(p, name);
if (sym->status == undeclared || sym->status == used) if (sym->status == undeclared || sym->status == used)
sym->status = needed; sym->status = needed;
} }
@@ -546,7 +507,7 @@ packgram (void)
{ {
unsigned int itemno = 0; unsigned int itemno = 0;
rule_number ruleno = 0; rule_number ruleno = 0;
symbol_list *p; symbol_list *p = grammar;
ritem = xnmalloc (nritems + 1, sizeof *ritem); ritem = xnmalloc (nritems + 1, sizeof *ritem);
@@ -555,8 +516,9 @@ packgram (void)
rules = xnmalloc (nrules, sizeof *rules); rules = xnmalloc (nrules, sizeof *rules);
for (p = grammar; p; p = p->next) while (p)
{ {
int rule_length = 0;
symbol *ruleprec = p->ruleprec; symbol *ruleprec = p->ruleprec;
record_merge_function_type (p->merger, p->content.sym->type_name, record_merge_function_type (p->merger, p->content.sym->type_name,
p->merger_declaration_location); p->merger_declaration_location);
@@ -574,14 +536,14 @@ packgram (void)
rules[ruleno].action_location = p->action_props.location; rules[ruleno].action_location = p->action_props.location;
rules[ruleno].is_predicate = p->action_props.is_predicate; 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 symbol name so that it's a user-defined symbol so that the default
%destructor and %printer apply. */ %destructor and %printer apply. */
if (p->midrule_parent_rule if (p->midrule_parent_rule
&& (p->action_props.is_value_used && (p->action_props.is_value_used
|| (symbol_list_n_get (p->midrule_parent_rule, || symbol_list_n_get (p->midrule_parent_rule,
p->midrule_parent_rhs_index) p->midrule_parent_rhs_index)
->action_props.is_value_used))) ->action_props.is_value_used))
p->content.sym->tag += 1; p->content.sym->tag += 1;
/* Don't check the generated rule 0. It has no action, so some rhs /* Don't check the generated rule 0. It has no action, so some rhs
@@ -590,27 +552,24 @@ packgram (void)
if (p != grammar) if (p != grammar)
grammar_rule_check (p); grammar_rule_check (p);
{ for (p = p->next; p && p->content.sym; p = p->next)
size_t rule_length = 0; {
for (p = p->next; p->content.sym; p = p->next) ++rule_length;
{
++rule_length;
/* Don't allow rule_length == INT_MAX, since that might /* Don't allow rule_length == INT_MAX, since that might
cause confusion with strtol if INT_MAX == LONG_MAX. */ cause confusion with strtol if INT_MAX == LONG_MAX. */
if (rule_length == INT_MAX) if (rule_length == INT_MAX)
complain (&rules[ruleno].location, fatal, _("rule is too long")); complain (&rules[ruleno].location, fatal, _("rule is too long"));
/* item_number = symbol_number. /* item_number = symbol_number.
But the former needs to contain more: negative rule numbers. */ But the former needs to contain more: negative rule numbers. */
ritem[itemno++] = ritem[itemno++] =
symbol_number_as_item_number (p->content.sym->number); symbol_number_as_item_number (p->content.sym->number);
/* A rule gets by default the precedence and associativity /* A rule gets by default the precedence and associativity
of its last token. */ of its last token. */
if (p->content.sym->class == token_sym && default_prec) if (p->content.sym->class == token_sym && default_prec)
rules[ruleno].prec = p->content.sym; rules[ruleno].prec = p->content.sym;
} }
}
/* If this rule has a %prec, /* If this rule has a %prec,
the specified symbol's precedence replaces the default. */ the specified symbol's precedence replaces the default. */
@@ -624,6 +583,9 @@ packgram (void)
aver (itemno < ITEM_NUMBER_MAX); aver (itemno < ITEM_NUMBER_MAX);
++ruleno; ++ruleno;
aver (ruleno < RULE_NUMBER_MAX); aver (ruleno < RULE_NUMBER_MAX);
if (p)
p = p->next;
} }
aver (itemno == nritems); aver (itemno == nritems);
@@ -751,7 +713,7 @@ check_and_convert_grammar (void)
/* Insert the initial rule, whose line is that of the first rule /* Insert the initial rule, whose line is that of the first rule
(not that of the start symbol): (not that of the start symbol):
$accept: %start $end. */ accept: %start EOF. */
{ {
symbol_list *p = symbol_list_sym_new (accept, empty_location); symbol_list *p = symbol_list_sym_new (accept, empty_location);
p->location = grammar->location; p->location = grammar->location;
@@ -764,8 +726,7 @@ check_and_convert_grammar (void)
grammar = p; grammar = p;
} }
aver (nsyms <= SYMBOL_NUMBER_MAXIMUM); aver (nsyms <= SYMBOL_NUMBER_MAXIMUM && nsyms == ntokens + nvars);
aver (nsyms == ntokens + nvars);
/* Assign the symbols their symbol numbers. Write #defines for the /* Assign the symbols their symbol numbers. Write #defines for the
token symbols into FDEFINES if requested. */ token symbols into FDEFINES if requested. */
@@ -776,11 +737,11 @@ check_and_convert_grammar (void)
action type checking. action type checking.
Before invoking grammar_rule_check (in packgram below) on any rule, make 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 Otherwise, checking that a midrule's $$ should be set will not always work
properly because the check must forward-reference the midrule's parent properly because the check must forward-reference the midrule's parent
rule. For the same reason, all the 'used' flags must be set before rule. For the same reason, all the `used' flags must be set before
checking whether to remove '$' from any midrule symbol name (also in checking whether to remove `$' from any midrule symbol name (also in
packgram). */ packgram). */
{ {
symbol_list *sym; symbol_list *sym;
-2
View File
@@ -47,8 +47,6 @@ void grammar_current_rule_begin (symbol *lhs, location loc,
named_ref *lhs_named_ref); named_ref *lhs_named_ref);
void grammar_current_rule_end (location loc); void grammar_current_rule_end (location loc);
void grammar_midrule_action (void); 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_prec_set (symbol *precsym, location loc);
void grammar_current_rule_dprec_set (int dprec, location loc); void grammar_current_rule_dprec_set (int dprec, location loc);
void grammar_current_rule_merge_set (uniqstr name, location loc); void grammar_current_rule_merge_set (uniqstr name, location loc);
+1 -1
View File
@@ -49,7 +49,7 @@ static bitset P;
static bitset V; static bitset V;
/* Set of symbols used to define rule precedence (so they are /* 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 bitset V1;
static rule_number nuseful_productions; static rule_number nuseful_productions;
+84 -10
View File
@@ -78,9 +78,8 @@ static bool untyped_var_seen;
/* POSIX says that a tag must be both an id and a C union member, but /* 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 historically almost any character is allowed in a tag. We disallow
NUL and newline, as this simplifies our implementation. We allow NUL and newline, as this simplifies our implementation. */
"->" as a means to dereference a pointer. */ tag [^\0\n>]+
tag ([^\0\n>]|->)+
/* Zero or more instances of backslash-newline. Following GCC, allow /* Zero or more instances of backslash-newline. Following GCC, allow
white space between the backslash and the newline. */ white space between the backslash and the newline. */
@@ -96,6 +95,26 @@ 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 /* This scanner is special: it is invoked only once, henceforth
is expected to return only once. This initialization is is expected to return only once. This initialization is
therefore done once per action to translate. */ therefore done once per action to translate. */
@@ -148,14 +167,32 @@ ref -?[0-9]+|{id}|"["{id}"]"|"$"
<SC_RULE_ACTION,SC_SYMBOL_ACTION> <SC_RULE_ACTION,SC_SYMBOL_ACTION>
{ {
"'" STRING_GROW; BEGIN SC_CHARACTER; "'" {
"\"" STRING_GROW; BEGIN SC_STRING; STRING_GROW;
"/"{splice}"*" STRING_GROW; BEGIN SC_COMMENT; BEGIN SC_CHARACTER;
"/"{splice}"/" STRING_GROW; BEGIN SC_LINE_COMMENT; need_semicolon = true;
}
"\"" {
STRING_GROW;
BEGIN SC_STRING;
need_semicolon = true;
}
"/"{splice}"*" {
STRING_GROW;
BEGIN SC_COMMENT;
}
"/"{splice}"/" {
STRING_GROW;
BEGIN SC_LINE_COMMENT;
}
[$@] { [$@] {
complain (loc, Wother, _("stray '%s'"), yytext); complain (loc, Wother, _("stray '%s'"), yytext);
obstack_escape (&obstack_for_string, yytext); obstack_escape (&obstack_for_string, yytext);
need_semicolon = true;
}
[\[\]] {
obstack_escape (&obstack_for_string, yytext);
need_semicolon = true;
} }
} }
@@ -166,13 +203,51 @@ ref -?[0-9]+|{id}|"["{id}"]"|"$"
handle_action_dollar (self->rule, yytext, *loc); handle_action_dollar (self->rule, yytext, *loc);
if (ref_tail_fields) if (ref_tail_fields)
obstack_sgrow (&obstack_for_string, ref_tail_fields); obstack_sgrow (&obstack_for_string, ref_tail_fields);
need_semicolon = true;
} }
"@"{ref} { "@"{ref} {
ref_tail_fields = NULL; ref_tail_fields = NULL;
handle_action_at (self->rule, yytext, *loc); handle_action_at (self->rule, yytext, *loc);
if (ref_tail_fields) if (ref_tail_fields)
obstack_sgrow (&obstack_for_string, 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> <SC_SYMBOL_ACTION>
@@ -596,8 +671,7 @@ fetch_type_name (char *cp, char const **type_name,
if (*cp == '<') if (*cp == '<')
{ {
*type_name = ++cp; *type_name = ++cp;
/* Series of non-'>' or "->". */ while (*cp != '>')
while (*cp != '>' || cp[-1] == '-')
++cp; ++cp;
/* The '>' symbol will be later replaced by '\0'. Original /* The '>' symbol will be later replaced by '\0'. Original
+23 -16
View File
@@ -112,12 +112,7 @@ static void unexpected_newline (boundary, char const *);
/* A identifier was just read in directives/rules. Special state /* A identifier was just read in directives/rules. Special state
to capture the sequence 'identifier :'. */ to capture the sequence 'identifier :'. */
%x SC_AFTER_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 %x SC_TAG
/* Four types of user code: /* Four types of user code:
@@ -138,6 +133,13 @@ notletter [^.abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_]{-}[%\{]
id {letter}({letter}|[-0-9])* id {letter}({letter}|[-0-9])*
int [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 /* Zero or more instances of backslash-newline. Following GCC, allow
white space between the backslash and the newline. */ white space between the backslash and the newline. */
splice (\\[ \f\t\v]*\n)* splice (\\[ \f\t\v]*\n)*
@@ -215,7 +217,6 @@ eqopt ([[:space:]]*=)?
"%defines" return PERCENT_DEFINES; "%defines" return PERCENT_DEFINES;
"%destructor" return PERCENT_DESTRUCTOR; "%destructor" return PERCENT_DESTRUCTOR;
"%dprec" return PERCENT_DPREC; "%dprec" return PERCENT_DPREC;
"%empty" return PERCENT_EMPTY;
"%error-verbose" return PERCENT_ERROR_VERBOSE; "%error-verbose" return PERCENT_ERROR_VERBOSE;
"%expect" return PERCENT_EXPECT; "%expect" return PERCENT_EXPECT;
"%expect-rr" return PERCENT_EXPECT_RR; "%expect-rr" return PERCENT_EXPECT_RR;
@@ -323,6 +324,13 @@ eqopt ([[:space:]]*=)?
/* A type. */ /* A type. */
"<*>" return TAG_ANY; "<*>" return TAG_ANY;
"<>" return TAG_NONE; "<>" 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; nesting = 0;
token_start = loc->start; token_start = loc->start;
@@ -512,7 +520,7 @@ eqopt ([[:space:]]*=)?
"\"" { "\"" {
STRING_FINISH; STRING_FINISH;
loc->start = token_start; loc->start = token_start;
val->code = last_string; val->chars = last_string;
BEGIN INITIAL; BEGIN INITIAL;
return STRING; return STRING;
} }
@@ -550,11 +558,10 @@ eqopt ([[:space:]]*=)?
<<EOF>> unexpected_eof (token_start, "'"); <<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> <SC_TAG>
{ {
@@ -572,7 +579,7 @@ eqopt ([[:space:]]*=)?
STRING_GROW; STRING_GROW;
} }
([^<>]|->)+ STRING_GROW; [^<>]+ STRING_GROW;
"<"+ STRING_GROW; nesting += yyleng; "<"+ STRING_GROW; nesting += yyleng;
<<EOF>> unexpected_eof (token_start, ">"); <<EOF>> unexpected_eof (token_start, ">");
@@ -751,7 +758,7 @@ eqopt ([[:space:]]*=)?
"%}" { "%}" {
STRING_FINISH; STRING_FINISH;
loc->start = code_start; loc->start = code_start;
val->code = last_string; val->chars = last_string;
BEGIN INITIAL; BEGIN INITIAL;
return PROLOGUE; return PROLOGUE;
} }
@@ -770,7 +777,7 @@ eqopt ([[:space:]]*=)?
<<EOF>> { <<EOF>> {
STRING_FINISH; STRING_FINISH;
loc->start = code_start; loc->start = code_start;
val->code = last_string; val->chars = last_string;
BEGIN INITIAL; BEGIN INITIAL;
return EPILOGUE; return EPILOGUE;
} }
+3 -5
View File
@@ -72,7 +72,7 @@ static void fail_for_invalid_at (char const *at);
"@@" fputc ('@', yyout); "@@" fputc ('@', yyout);
"@{" fputc ('[', yyout); "@{" 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; @\n continue;
"@oline@" fprintf (yyout, "%d", out_lineno + 1); "@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); "@output(" at_init (&argc, argv, &at_ptr, &at_output);
/* This pattern must not match more than the previous @ patterns. */ /* 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 out_lineno++; ECHO;
[^@\n]+ 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, '['); "@{" 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; @\n continue;
@[,)] { @[,)] {
@@ -183,8 +183,6 @@ flag (const char *arg)
/* compare with values issued from b4_error */ /* compare with values issued from b4_error */
if (STREQ (arg, "complain")) if (STREQ (arg, "complain"))
return complaint; return complaint;
else if (STREQ (arg, "deprecated"))
return Wdeprecated;
else if (STREQ (arg, "fatal")) else if (STREQ (arg, "fatal"))
return fatal; return fatal;
else if (STREQ (arg, "note")) else if (STREQ (arg, "note"))
+7 -14
View File
@@ -36,20 +36,18 @@ symbol_list_sym_new (symbol *sym, location loc)
res->content_type = SYMLIST_SYMBOL; res->content_type = SYMLIST_SYMBOL;
res->content.sym = sym; res->content.sym = sym;
res->location = res->sym_loc = loc; res->location = res->sym_loc = loc;
res->named_ref = NULL;
res->midrule = NULL; res->midrule = NULL;
res->midrule_parent_rule = NULL; res->midrule_parent_rule = NULL;
res->midrule_parent_rhs_index = 0; res->midrule_parent_rhs_index = 0;
/* Members used for LHS only. */
res->ruleprec = NULL;
res->percent_empty_loc = empty_location;
code_props_none_init (&res->action_props); code_props_none_init (&res->action_props);
res->ruleprec = NULL;
res->dprec = 0; res->dprec = 0;
res->dprec_location = empty_location;
res->merger = 0; res->merger = 0;
res->merger_declaration_location = empty_location;
res->named_ref = NULL;
res->next = NULL; res->next = NULL;
@@ -87,17 +85,12 @@ symbol_list_type_new (uniqstr type_name, location loc)
void void
symbol_list_syms_print (const symbol_list *l, FILE *f) symbol_list_syms_print (const symbol_list *l, FILE *f)
{ {
char const *sep = "";
for (/* Nothing. */; l && l->content.sym; l = l->next) 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); symbol_print (l->content.sym, f);
fputs (l->action_props.is_value_used ? " used" : " unused", f); fprintf (stderr, l->action_props.is_value_used ? " used" : " unused");
sep = ", "; if (l && l->content.sym)
fprintf (f, ", ");
} }
} }
+5 -15
View File
@@ -50,9 +50,6 @@ typedef struct symbol_list
} content; } content;
location location; location location;
/* Named reference. */
named_ref *named_ref;
/* Proper location of the symbol, not all the rule */ /* Proper location of the symbol, not all the rule */
location sym_loc; location sym_loc;
@@ -67,26 +64,19 @@ typedef struct symbol_list
struct symbol_list *midrule_parent_rule; struct symbol_list *midrule_parent_rule;
int midrule_parent_rhs_index; 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 /* The action is attached to the LHS of a rule, but action properties for
* each RHS are also stored here. */ * each RHS are also stored here. */
code_props action_props; code_props action_props;
/* The location of the first %empty for this rule, or \a /* Precedence/associativity. */
empty_location. */ symbol *ruleprec;
location percent_empty_loc;
int dprec; int dprec;
location dprec_location;
int merger; int merger;
location merger_declaration_location; location merger_declaration_location;
/* Named reference. */
named_ref *named_ref;
/* The list. */ /* The list. */
struct symbol_list *next; struct symbol_list *next;
} symbol_list; } symbol_list;
+39 -77
View File
@@ -153,13 +153,13 @@ symbol_print (symbol const *s, FILE *f)
{ {
if (s) if (s)
{ {
fputs (s->tag, f); fprintf (f, "\"%s\"", s->tag);
SYMBOL_ATTR_PRINT (type_name); SYMBOL_ATTR_PRINT (type_name);
SYMBOL_CODE_PRINT (destructor); SYMBOL_CODE_PRINT (destructor);
SYMBOL_CODE_PRINT (printer); SYMBOL_CODE_PRINT (printer);
} }
else else
fputs ("<NULL>", f); fprintf (f, "<NULL>");
} }
#undef SYMBOL_ATTR_PRINT #undef SYMBOL_ATTR_PRINT
@@ -243,12 +243,9 @@ symbol_type_set (symbol *sym, uniqstr type_name, location loc)
{ {
if (sym->type_name) if (sym->type_name)
symbol_redeclaration (sym, "%type", sym->type_location, loc); symbol_redeclaration (sym, "%type", sym->type_location, loc);
else uniqstr_assert (type_name);
{ sym->type_name = type_name;
uniqstr_assert (type_name); sym->type_location = loc;
sym->type_name = type_name;
sym->type_location = loc;
}
} }
} }
@@ -264,8 +261,7 @@ symbol_code_props_set (symbol *sym, code_props_type kind,
symbol_redeclaration (sym, code_props_type_string (kind), symbol_redeclaration (sym, code_props_type_string (kind),
sym->props[kind].location, sym->props[kind].location,
code->location); code->location);
else sym->props[kind] = *code;
sym->props[kind] = *code;
} }
/*-----------------------------------------------------. /*-----------------------------------------------------.
@@ -281,8 +277,7 @@ semantic_type_code_props_set (semantic_type *type,
semantic_type_redeclaration (type, code_props_type_string (kind), semantic_type_redeclaration (type, code_props_type_string (kind),
type->props[kind].location, type->props[kind].location,
code->location); code->location);
else type->props[kind] = *code;
type->props[kind] = *code;
} }
/*---------------------------------------------------. /*---------------------------------------------------.
@@ -326,15 +321,12 @@ symbol_precedence_set (symbol *sym, int prec, assoc a, location loc)
{ {
if (a != undef_assoc) if (a != undef_assoc)
{ {
if (sym->prec) if (sym->prec != 0)
symbol_redeclaration (sym, assoc_to_string (a), sym->prec_location, symbol_redeclaration (sym, assoc_to_string (a), sym->prec_location,
loc); loc);
else sym->prec = prec;
{ sym->assoc = a;
sym->prec = prec; sym->prec_location = loc;
sym->assoc = a;
sym->prec_location = loc;
}
} }
/* Only terminals have a precedence. */ /* Only terminals have a precedence. */
@@ -368,8 +360,7 @@ symbol_class_set (symbol *sym, symbol_class class, location loc, bool declaring)
{ {
if (sym->status == declared && !warned) if (sym->status == declared && !warned)
complain (&loc, Wother, _("symbol %s redeclared"), sym->tag); complain (&loc, Wother, _("symbol %s redeclared"), sym->tag);
else sym->status = declared;
sym->status = declared;
} }
} }
@@ -450,7 +441,7 @@ semantic_type_check_defined (semantic_type *sem_type)
/* <*> and <> do not have to be "declared". */ /* <*> and <> do not have to be "declared". */
if (sem_type->status == declared if (sem_type->status == declared
|| !*sem_type->tag || !*sem_type->tag
|| STREQ (sem_type->tag, "*")) || STREQ(sem_type->tag, "*"))
{ {
int i; int i;
for (i = 0; i < 2; ++i) for (i = 0; i < 2; ++i)
@@ -624,8 +615,8 @@ symbol_translation (symbol *this)
(this->user_token_number, (this->user_token_number,
symbols[token_translations[this->user_token_number]], symbols[token_translations[this->user_token_number]],
this); this);
else
token_translations[this->user_token_number] = this->number; token_translations[this->user_token_number] = this->number;
} }
return true; return true;
@@ -1066,40 +1057,27 @@ register_precedence (graphid first, graphid snd)
} }
/*---------------------------------------. /*--------------------------------------------------.
| Deep clear a linked / adjacency list). | | Print a warning for unused precedence relations. |
`---------------------------------------*/ `--------------------------------------------------*/
static void void
linkedlist_free (symgraphlink *node) print_precedence_warnings (void)
{
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; int i;
if (!prec_nodes)
init_prec_nodes ();
for (i = 0; i < nsyms; ++i) for (i = 0; i < nsyms; ++i)
{ {
linkedlist_free (prec_nodes[i]->pred); symbol *s = symbols[i];
linkedlist_free (prec_nodes[i]->succ); if (s
free (prec_nodes[i]); && 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);
} }
free (prec_nodes);
} }
/*---------------------------------------. /*---------------------------------------.
@@ -1110,7 +1088,7 @@ static void
init_assoc (void) init_assoc (void)
{ {
graphid i; graphid i;
used_assoc = xcalloc (nsyms, sizeof *used_assoc); used_assoc = xcalloc(nsyms, sizeof(*used_assoc));
for (i = 0; i < nsyms; ++i) for (i = 0; i < nsyms; ++i)
used_assoc[i] = false; used_assoc[i] = false;
} }
@@ -1141,37 +1119,21 @@ register_assoc (graphid i, graphid j)
used_assoc[j] = true; used_assoc[j] = true;
} }
/*--------------------------------------------------. /*------------------------------------------------------.
| Print a warning for unused precedence relations. | | Print a warning for each unused symbol associativity. |
`--------------------------------------------------*/ `------------------------------------------------------*/
void void
print_precedence_warnings (void) print_assoc_warnings (void)
{ {
int i; graphid i;
if (!prec_nodes)
init_prec_nodes ();
if (!used_assoc) if (!used_assoc)
init_assoc (); init_assoc ();
for (i = 0; i < nsyms; ++i) for (i = 0; i < nsyms; ++i)
{ {
symbol *s = symbols[i]; symbol *s = symbols[i];
if (s if (is_assoc_useless (s))
&& s->prec != 0 complain (&s->location, Wother,
&& !prec_nodes[i]->pred _("useless associativity for %s"), s->tag);
&& !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 ();
} }
+7 -6
View File
@@ -128,9 +128,9 @@ struct symbol
/** Undefined user number. */ /** Undefined user number. */
# define USER_NUMBER_UNDEFINED -1 # define USER_NUMBER_UNDEFINED -1
/* 'symbol->user_token_number == USER_NUMBER_HAS_STRING_ALIAS' means /* `symbol->user_token_number == USER_NUMBER_HAS_STRING_ALIAS' means
this symbol has a literal string alias. For instance, '%token foo this symbol has a literal string alias. For instance, `%token foo
"foo"' has '"foo"' numbered regularly, and 'foo' numbered as "foo"' has `"foo"' numbered regularly, and `foo' numbered as
USER_NUMBER_HAS_STRING_ALIAS. */ USER_NUMBER_HAS_STRING_ALIAS. */
# define USER_NUMBER_HAS_STRING_ALIAS -9991 # define USER_NUMBER_HAS_STRING_ALIAS -9991
@@ -266,8 +266,7 @@ struct symgraph
void register_precedence (graphid first, graphid snd); void register_precedence (graphid first, graphid snd);
/** Print a warning for each symbol whose precedence and/or associativity /** Print a warning for each symbol whose precedence is useless. */
* is useless. */
void print_precedence_warnings (void); void print_precedence_warnings (void);
@@ -275,7 +274,9 @@ void print_precedence_warnings (void);
| Symbol associativity | | Symbol associativity |
`----------------------*/ `----------------------*/
void register_assoc (graphid i, graphid j); void register_assoc (int i, int j);
void print_assoc_warnings (void);
/*-----------------. /*-----------------.
| Semantic types. | | Semantic types. |
+1 -1
View File
@@ -99,7 +99,7 @@ typedef size_t uintptr_t;
# endif # endif
# 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. */ are accepted by gcc versions 2.6.4 (effectively 2.7) and later. */
# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7) # if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7)
# define __format__ format # define __format__ format
+7 -7
View File
@@ -35,7 +35,7 @@
#include "tables.h" #include "tables.h"
/* Several tables are indexed both by state and nonterminal numbers. /* 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. or a nonterminal number.
Of course vector_number_t ought to be wide enough to contain 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]: /* For a given state, N = ACTROW[SYMBOL]:
If N = 0, stands for 'run the default action'. If N = 0, stands for `run the default action'.
If N = MIN, stands for 'raise a syntax error'. 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 `shift SYMBOL and go to n'.
If N < 0, stands for 'reduce -N'. */ If N < 0, stands for `reduce -N'. */
typedef int action_number; typedef int action_number;
#define ACTION_NUMBER_MINIMUM INT_MIN #define ACTION_NUMBER_MINIMUM INT_MIN
static action_number *actrow; static action_number *actrow;
/* FROMS and TOS are reordered to be compressed. ORDER[VECTOR] is the /* FROMS and TOS are reordered to be compressed. ORDER[VECTOR] is the
new vector number of VECTOR. We skip 'empty' vectors (i.e., new vector number of VECTOR. We skip `empty' vectors (i.e.,
TALLY[VECTOR] = 0), and call these 'entries'. */ TALLY[VECTOR] = 0), and call these `entries'. */
static vector_number *order; static vector_number *order;
static int nentries; static int nentries;
+1 -1
View File
@@ -105,7 +105,7 @@ uniqstr_print_processor (void *ustr, void *null ATTRIBUTE_UNUSED)
int int
uniqstr_cmp (uniqstr l, uniqstr r) uniqstr_cmp(uniqstr l, uniqstr r)
{ {
return (l == r ? 0 return (l == r ? 0
: !l ? -1 : !l ? -1
+1 -1
View File
@@ -40,7 +40,7 @@ uniqstr uniqstr_vsprintf (char const *format, ...)
/* Compare two uniqstr a la strcmp: negative for <, nul for =, and /* Compare two uniqstr a la strcmp: negative for <, nul for =, and
positive for >. Undefined order, relies on addresses. */ 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. */ /* Die if STR is not a uniqstr. */
void uniqstr_assert (char const *str); void uniqstr_assert (char const *str);
+121 -125
View File
@@ -64,119 +64,6 @@ AT_PARSER_CHECK([./input], 0,
AT_CLEANUP 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. ## ## Initial location. ##
@@ -286,8 +173,8 @@ m4_popdef([AT_TEST])
## Location Print. ## ## Location Print. ##
## ---------------- ## ## ---------------- ##
# AT_TEST(SKELETON-NAME, DIRECTIVES, [MORE-DIRECTIVES]) # AT_TEST(SKELETON-NAME, DIRECTIVES, [MORE-DIRECTIVES], [LOCATION = 1.1])
# ----------------------------------------------------- # -----------------------------------------------------------------------
# Check that the initial location is correct. # Check that the initial location is correct.
m4_pushdef([AT_TEST], m4_pushdef([AT_TEST],
[AT_SETUP([Location print: $1 $2]) [AT_SETUP([Location print: $1 $2])
@@ -305,7 +192,7 @@ AT_DATA_GRAMMAR([[input.y]],
]AT_YYLEX_DECLARE[ ]AT_YYLEX_DECLARE[
} }
%% %%
exp: %empty; exp: /* empty */;
%% %%
]AT_YYERROR_DEFINE[ ]AT_YYERROR_DEFINE[
]AT_YYLEX_DEFINE[ ]AT_YYLEX_DEFINE[
@@ -528,7 +415,7 @@ AT_LALR1_CC_IF([typedef yy::location YYLTYPE;])[
%% %%
/* /*
This grammar is made to exercise error recovery. 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 ')' as synchronizing token. Lines starting with 'x' can never
be recovered from if in error. be recovered from if in error.
*/ */
@@ -605,11 +492,11 @@ static
{ {
static unsigned int counter = 0; static unsigned int counter = 0;
unsigned int c = ]AT_VAL[]m4_ifval([$6], [.ival])[ = counter++; int c = ]AT_VAL[]m4_ifval([$6], [.ival])[ = counter++;
/* As in BASIC, line numbers go from 10 to 10. */ /* As in BASIC, line numbers go from 10 to 10. */
]AT_LOC_FIRST_LINE[ = ]AT_LOC_FIRST_COLUMN[ = 10 * c; ]AT_LOC_FIRST_LINE[ = ]AT_LOC_FIRST_COLUMN[ = 10 * c;
]AT_LOC_LAST_LINE[ = ]AT_LOC_LAST_COLUMN[ = ]AT_LOC_FIRST_LINE[ + 9; ]AT_LOC_LAST_LINE[ = ]AT_LOC_LAST_COLUMN[ = ]AT_LOC_FIRST_LINE[ + 9;
assert (c <= strlen (source)); assert (0 <= c && c <= strlen (source));
if (source[c]) if (source[c])
fprintf (stderr, "sending: '%c'", source[c]); fprintf (stderr, "sending: '%c'", source[c]);
else else
@@ -691,7 +578,7 @@ Successful parse.
# Syntax errors caught by the parser # 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. # can be reduced.
# #
# '(', 'x', 'x', 'x', 'x', 'x', ')', # '(', 'x', 'x', 'x', 'x', 'x', ')',
@@ -848,13 +735,13 @@ AT_CLEANUP
AT_CHECK_PRINTER_AND_DESTRUCTOR([]) 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"])
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])
AT_CHECK_PRINTER_AND_DESTRUCTOR([%glr-parser], [ with union]) AT_CHECK_PRINTER_AND_DESTRUCTOR([%glr-parser], [with union])
@@ -1287,7 +1174,7 @@ AT_SETUP([Default %printer and %destructor are not for $accept])
# - The %printer and %destructor code generated for $accept would always be # - The %printer and %destructor code generated for $accept would always be
# dead code because $accept is currently never shifted onto the stack. # dead code because $accept is currently never shifted onto the stack.
# - $$ for $accept would always be of type YYSTYPE because it's not possible # - $$ 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 # - Thus, the compiler might complain that the user code assumes the wrong
# type for $$ since the code might assume the type associated with a # type for $$ since the code might assume the type associated with a
# specific union field, which is especially reasonable in C++ since that # specific union field, which is especially reasonable in C++ since that
@@ -1607,6 +1494,115 @@ AT_TEST([glr.cc])
m4_popdef([AT_TEST]) 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. ## ## Destroying lookahead assigned by semantic action. ##
## -------------------------------------------------- ## ## -------------------------------------------------- ##
@@ -1641,7 +1637,7 @@ AT_DATA_GRAMMAR([input.y],
// that has set yychar might not always return normally. Instead, // that has set yychar might not always return normally. Instead,
// skeletons must translate before every use of yytoken. // skeletons must translate before every use of yytoken.
start: 'a' accept { USE($1); } ; start: 'a' accept { USE($1); } ;
accept: %empty { accept: /*empty*/ {
assert (yychar == YYEMPTY); assert (yychar == YYEMPTY);
yychar = 'b'; yychar = 'b';
YYACCEPT; YYACCEPT;
+13 -1
View File
@@ -16,7 +16,7 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # 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@" CPPFLAGS="-I$abs_top_builddir/lib @CPPFLAGS@"
# Don't just check if $POSIXLY_CORRECT is set, as Bash, when launched # Don't just check if $POSIXLY_CORRECT is set, as Bash, when launched
@@ -47,6 +47,9 @@ NO_WERROR_CXXFLAGS='@CXXFLAGS@ @WARN_CXXFLAGS@ @WARN_CXXFLAGS_TEST@'
CFLAGS="$NO_WERROR_CFLAGS @WERROR_CFLAGS@" CFLAGS="$NO_WERROR_CFLAGS @WERROR_CFLAGS@"
CXXFLAGS="$NO_WERROR_CXXFLAGS @WERROR_CXXFLAGS@" 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 ':'. # If 'exit 77'; skip all C++ tests; otherwise ':'.
BISON_CXX_WORKS='@BISON_CXX_WORKS@' BISON_CXX_WORKS='@BISON_CXX_WORKS@'
@@ -72,6 +75,15 @@ else
CC_IS_CXX=0 CC_IS_CXX=0
fi 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. ## ## Other. ##
+38 -106
View File
@@ -18,68 +18,6 @@
AT_BANNER([[C++ Features.]]) 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. ## ## C++ Variant-based Symbols. ##
## --------------------------- ## ## --------------------------- ##
@@ -90,7 +28,7 @@ AT_KEYWORDS([variant])
AT_BISON_OPTION_PUSHDEFS([%skeleton "lalr1.cc" %debug $1]) AT_BISON_OPTION_PUSHDEFS([%skeleton "lalr1.cc" %debug $1])
# Store strings and integers in a list of strings. # Store strings and integers in a list of strings.
AT_DATA_GRAMMAR([list.y], AT_DATA_GRAMMAR([list.yy],
[[%skeleton "lalr1.cc" [[%skeleton "lalr1.cc"
%define api.value.type variant %define api.value.type variant
%define parse.assert %define parse.assert
@@ -154,7 +92,8 @@ int main()
} }
]]) ]])
AT_FULL_COMPILE([list]) AT_BISON_CHECK([-o list.cc list.yy])
AT_COMPILE_CXX([list], [$NO_STRICT_ALIAS_CXXFLAGS list.cc])
AT_PARSER_CHECK([./list], 0, [], AT_PARSER_CHECK([./list], 0, [],
[12 [12
123 123
@@ -176,7 +115,7 @@ m4_pushdef([AT_TEST],
AT_BISON_OPTION_PUSHDEFS([%skeleton "lalr1.cc" %debug $1]) AT_BISON_OPTION_PUSHDEFS([%skeleton "lalr1.cc" %debug $1])
# Store strings and integers in a list of strings. # Store strings and integers in a list of strings.
AT_DATA_GRAMMAR([list.y], AT_DATA_GRAMMAR([list.yy],
[[%debug [[%debug
%skeleton "lalr1.cc" %skeleton "lalr1.cc"
%define api.value.type variant %define api.value.type variant
@@ -311,7 +250,8 @@ namespace yy
]AT_MAIN_DEFINE[ ]AT_MAIN_DEFINE[
]]) ]])
AT_FULL_COMPILE([list]) AT_BISON_CHECK([-o list.cc list.yy])
AT_COMPILE_CXX([list], [$NO_STRICT_ALIAS_CXXFLAGS list.cc])
AT_PARSER_CHECK([./list], 0, AT_PARSER_CHECK([./list], 0,
[(0, 1, 2, 4) [(0, 1, 2, 4)
]) ])
@@ -325,8 +265,8 @@ AT_TEST([%define parse.assert])
AT_TEST([%locations %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 %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]])
AT_TEST([[%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_}]]) AT_TEST([[%locations %define parse.assert %define api.token.constructor %define api.token.prefix "TOK_"]])
m4_popdef([AT_TEST]) m4_popdef([AT_TEST])
@@ -423,10 +363,10 @@ AT_CHECK_DOXYGEN([Private])
# is specified, then Bison should accept the input, but compilation will fail, # is specified, then Bison should accept the input, but compilation will fail,
# so don't check compilation. # so don't check compilation.
m4_pushdef([AT_TEST], 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]], AT_DATA_GRAMMAR([[input.y]],
[[%language "C++" [[%language "C++"
%define api.namespace {]$1[} %define api.namespace "]$1["
%union { int i; } %union { int i; }
%define global_tokens_and_yystype %define global_tokens_and_yystype
%locations %locations
@@ -482,8 +422,8 @@ AT_CLEANUP
AT_SETUP([[Syntactically invalid namespace references]]) AT_SETUP([[Syntactically invalid namespace references]])
AT_TEST([[:foo:bar]], [[-]]) AT_TEST([[:foo:bar]], [[-]])
AT_TEST([[foo: :bar]], [[-]]) AT_TEST([[foo: :bar]], [[-]])
# This one is interesting because '[3]' is encoded as '@<:@3@:>@', which # This one is interesting because `[3]' is encoded as `@<:@3@:>@', which
# contains single occurrences of ':'. # contains single occurrences of `:'.
AT_TEST([[foo[3]::bar::baz]], [[-]]) AT_TEST([[foo[3]::bar::baz]], [[-]])
AT_TEST([[foo::bar,baz]], [[-]]) AT_TEST([[foo::bar,baz]], [[-]])
AT_TEST([[foo::bar::(baz /* Pacify Emacs ) */]], [[-]]) AT_TEST([[foo::bar::(baz /* Pacify Emacs ) */]], [[-]])
@@ -675,42 +615,14 @@ $1
/// A class that counts its number of instances. /// A class that counts its number of instances.
struct Object 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; typedef std::list<const Object*> objects;
static objects instances; static objects instances;
char val;
static bool static bool
empty () empty ()
{ {
return instances.empty (); return instances.empty();
} }
static void static void
@@ -733,6 +645,26 @@ $1
std::cerr << " }" << std::endl; 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");
}
}; };
} }
@@ -795,11 +727,11 @@ item:
// Not just 'E', otherwise we reduce when 'E' is the lookahead, and // Not just 'E', otherwise we reduce when 'E' is the lookahead, and
// then the stack is emptied, defeating the point of the test. // then the stack is emptied, defeating the point of the test.
| 'E' 'a' { YYUSE($][1); $][$ = $][2; } | 'E' 'a' { YYUSE($][1); $][$ = $][2; }
| 'R' { $][$ = 0; ]AT_VARIANT_IF([], [delete $][1]; )[YYERROR; } | 'R' { $][$ = YY_NULL; ]AT_VARIANT_IF([], [delete $][1]; )[YYERROR; }
| 'p' { $][$ = $][1; } | 'p' { $][$ = $][1; }
| 's' { $][$ = $][1; throw std::runtime_error ("reduction"); } | 's' { $][$ = $][1; throw std::runtime_error ("reduction"); }
| 'T' { $][$ = 0; ]AT_VARIANT_IF([], [delete $][1]; )[YYABORT; } | 'T' { $][$ = YY_NULL; ]AT_VARIANT_IF([], [delete $][1]; )[YYABORT; }
| error { $][$ = 0; yyerrok; } | error { $][$ = YY_NULL; yyerrok; }
; ;
%% %%
@@ -872,7 +804,7 @@ main (int argc, const char *argv[])
} }
]]) ]])
AT_BISON_CHECK([[-o input.cc --report=all input.yy]]) AT_BISON_CHECK([[-o input.cc --report=all input.yy]])
AT_COMPILE_CXX([[input]]) AT_COMPILE_CXX([input], [[$NO_STRICT_ALIAS_CXXFLAGS input.cc]])
AT_PARSER_CHECK([[./input aaaas]], [[2]], [[]], AT_PARSER_CHECK([[./input aaaas]], [[2]], [[]],
[[exception caught: reduction [[exception caught: reduction
+48 -48
View File
@@ -27,11 +27,11 @@
# _AT_DATA_CALC_Y($1, $2, $3, [BISON-DIRECTIVES]) # _AT_DATA_CALC_Y($1, $2, $3, [BISON-DIRECTIVES])
# ----------------------------------------------- # -----------------------------------------------
# Produce 'calc.y' and, if %defines was specified, 'calc-lex.c' or # Produce `calc.y' and, if %defines was specified, `calc-lex.c' or
# 'calc-lex.cc'. # `calc-lex.cc'.
# #
# Don't call this macro directly, because it contains some occurrences # 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. # 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. # When %defines is not passed, generate a single self-contained file.
@@ -72,12 +72,10 @@ main (int argc, const char **argv)
int count = 0; int count = 0;
int status; int status;
/* This used to be alarm (10), but that isn't enough time for a July /* This used to be alarm (10), but that isn't enough time for
1995 vintage DEC Alphastation 200 4/100 system, according to a July 1995 vintage DEC Alphastation 200 4/100 system,
Nelson H. F. Beebe. 100 seconds was enough for regular users, according to Nelson H. F. Beebe. 100 seconds is enough. */
but the Hydra build farm, which is heavily loaded needs more. */ alarm (100);
alarm (200);
if (argc == 2) if (argc == 2)
input = fopen (argv[1], "r"); input = fopen (argv[1], "r");
@@ -90,7 +88,8 @@ main (int argc, const char **argv)
return 3; return 3;
} }
]AT_SKEL_CC_IF([], [AT_DEBUG_IF([ ]AT_NAME_PREFIX[debug = 1;])])[ ]AT_SKEL_CC_IF([], [m4_bmatch([$4], [%debug],
[ ]AT_NAME_PREFIX[debug = 1;])])[
status = ]AT_NAME_PREFIX[parse (]AT_PARAM_IF([[&result, &count]])[); status = ]AT_NAME_PREFIX[parse (]AT_PARAM_IF([[&result, &count]])[);
if (fclose (input)) if (fclose (input))
perror ("fclose"); perror ("fclose");
@@ -134,7 +133,7 @@ unget_char (]AT_YYLEX_PRE_FORMALS[ int c)
{ {
]AT_USE_LEX_ARGS[; ]AT_USE_LEX_ARGS[;
]AT_LOCATION_IF([ ]AT_LOCATION_IF([
/* Wrong when C == '\n'. */ /* Wrong when C == `\n'. */
AT_LOC = last_yylloc; AT_LOC = last_yylloc;
])[ ])[
ungetc (c, input); ungetc (c, input);
@@ -366,8 +365,8 @@ m4_popdef([AT_CALC_LEX])
# AT_DATA_CALC_Y([BISON-OPTIONS]) # AT_DATA_CALC_Y([BISON-OPTIONS])
# ------------------------------- # -------------------------------
# Produce 'calc.y' and, if %defines was specified, 'calc-lex.c' or # Produce `calc.y' and, if %defines was specified, `calc-lex.c' or
# 'calc-lex.cc'. # `calc-lex.cc'.
m4_define([AT_DATA_CALC_Y], m4_define([AT_DATA_CALC_Y],
[_AT_DATA_CALC_Y($[1], $[2], $[3], [$1]) [_AT_DATA_CALC_Y($[1], $[2], $[3], [$1])
]) ])
@@ -376,9 +375,9 @@ m4_define([AT_DATA_CALC_Y],
# _AT_CHECK_CALC(BISON-OPTIONS, INPUT, [NUM-STDERR-LINES]) # _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. # NUM-STDERR-LINES is the number of expected lines on stderr.
# Currently this is ignored, though, since the output format is fluctuating. # Currently this is ignored, though, since the output format is fluctuating.
@@ -397,7 +396,7 @@ AT_PARSER_CHECK([./calc input], 0, [], [stderr])
# [NUM-STDERR-LINES], # [NUM-STDERR-LINES],
# [VERBOSE-AND-LOCATED-ERROR-MESSAGE]) # [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, # If INPUT starts with a slash, it is used as absolute input file name,
# otherwise as contents. # otherwise as contents.
@@ -405,14 +404,14 @@ AT_PARSER_CHECK([./calc input], 0, [], [stderr])
# NUM-STDERR-LINES is the number of expected lines on stderr. # NUM-STDERR-LINES is the number of expected lines on stderr.
# Currently this is ignored, though, since the output format is fluctuating. # 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. # is correctly output on stderr.
# #
# If BISON-OPTIONS contains '%define parse.error verbose', then make sure the # If BISON-OPTIONS contains `%define parse.error verbose', then make sure the
# IF-YYERROR-VERBOSE message is properly output after 'syntax error, ' # IF-YYERROR-VERBOSE message is properly output after `syntax error, '
# on STDERR. # 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. # is the number of expected lines on stderr.
m4_define([_AT_CHECK_CALC_ERROR], m4_define([_AT_CHECK_CALC_ERROR],
[m4_bmatch([$3], [^/], [m4_bmatch([$3], [^/],
@@ -449,7 +448,7 @@ AT_DATA([[expout]],
AT_YYERROR_SEES_LOC_IF([], AT_YYERROR_SEES_LOC_IF([],
[[sed 's/^[-0-9.]*: //' expout >at-expout [[sed 's/^[-0-9.]*: //' expout >at-expout
mv at-expout 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], [], m4_bmatch([$1], [%define parse.error verbose], [],
[[sed 's/syntax error, .*$/syntax error/' expout >at-expout [[sed 's/syntax error, .*$/syntax error/' expout >at-expout
mv at-expout expout]]) mv at-expout expout]])
@@ -479,7 +478,7 @@ m4_define([AT_CHECK_SPACES],
# AT_CHECK_CALC([BISON-OPTIONS]) # 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. # BISON-OPTIONS, and performs several tests over the parser.
m4_define([AT_CHECK_CALC], m4_define([AT_CHECK_CALC],
[m4_ifval([$2], [m4_fatal([$0: expected a single argument])]) [m4_ifval([$2], [m4_fatal([$0: expected a single argument])])
@@ -539,7 +538,7 @@ _AT_CHECK_CALC_ERROR([$1], [1], [/dev/null], [4],
# - (* * *): nothing to pop, a lot to discard # - (* * *): nothing to pop, a lot to discard
# - (1 + 2 * *): some to pop and 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 # - check the lookahead that triggers an error is not discarded
# when we enter error recovery. Below, the lookahead causing the # when we enter error recovery. Below, the lookahead causing the
@@ -588,7 +587,7 @@ AT_BANNER([[Simple LALR(1) Calculator.]])
# AT_CHECK_CALC_LALR([BISON-OPTIONS]) # 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. # BISON-OPTIONS, and performs several tests over the parser.
m4_define([AT_CHECK_CALC_LALR], m4_define([AT_CHECK_CALC_LALR],
[AT_CHECK_CALC($@)]) [AT_CHECK_CALC($@)])
@@ -607,17 +606,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 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])
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 %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 %name-prefix "calc" %define api.token.prefix "TOK_" %verbose %yacc])
AT_CHECK_CALC_LALR([%debug]) 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 %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.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}])
# ----------------------- # # ----------------------- #
@@ -628,7 +627,7 @@ AT_BANNER([[Simple GLR Calculator.]])
# AT_CHECK_CALC_GLR([BISON-OPTIONS]) # 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. # BISON-OPTIONS and %glr-parser, and performs several tests over the parser.
m4_define([AT_CHECK_CALC_GLR], m4_define([AT_CHECK_CALC_GLR],
[AT_CHECK_CALC([%glr-parser] $@)]) [AT_CHECK_CALC([%glr-parser] $@)])
@@ -639,7 +638,7 @@ AT_CHECK_CALC_GLR()
AT_CHECK_CALC_GLR([%defines]) AT_CHECK_CALC_GLR([%defines])
AT_CHECK_CALC_GLR([%locations]) AT_CHECK_CALC_GLR([%locations])
AT_CHECK_CALC_GLR([%name-prefix "calc"]) 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([%verbose])
AT_CHECK_CALC_GLR([%yacc]) AT_CHECK_CALC_GLR([%yacc])
AT_CHECK_CALC_GLR([%define parse.error verbose]) AT_CHECK_CALC_GLR([%define parse.error verbose])
@@ -651,12 +650,12 @@ AT_CHECK_CALC_GLR([%define parse.error verbose %locations %defines %name-prefix
AT_CHECK_CALC_GLR([%debug]) 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 %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])
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 %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}])
# ----------------------------- # # ----------------------------- #
@@ -670,26 +669,26 @@ AT_CHECK_CALC([%skeleton "lalr1.cc" %defines])
# AT_CHECK_CALC_LALR1_CC([BISON-OPTIONS]) # 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. # the C++ skeleton, and performs several tests over the parser.
m4_define([AT_CHECK_CALC_LALR1_CC], m4_define([AT_CHECK_CALC_LALR1_CC],
[AT_CHECK_CALC([%language "C++"] $@)]) [AT_CHECK_CALC([%language "C++"] $@)])
AT_CHECK_CALC_LALR1_CC([]) AT_CHECK_CALC_LALR1_CC([])
AT_CHECK_CALC_LALR1_CC([%locations]) 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([%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 %define parse.error verbose %debug %name-prefix "calc" %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 %pure-parser %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([%locations %pure-parser %define parse.error verbose %debug %define api.prefix "calc" %define api.token.prefix "TOK_" %verbose %yacc])
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([%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([%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([%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 %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}])
@@ -704,21 +703,22 @@ AT_CHECK_CALC([%skeleton "glr.cc"])
# AT_CHECK_CALC_GLR_CC([BISON-OPTIONS]) # 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. # the GLR C++ skeleton, and performs several tests over the parser.
m4_define([AT_CHECK_CALC_GLR_CC], m4_define([AT_CHECK_CALC_GLR_CC],
[AT_CHECK_CALC([%language "C++" %glr-parser] $@)]) [AT_CHECK_CALC([%language "C++" %glr-parser] $@)])
AT_CHECK_CALC_GLR_CC([]) AT_CHECK_CALC_GLR_CC([])
AT_CHECK_CALC_GLR_CC([%locations]) 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([%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([%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" %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([%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([%pure-parser %define parse.error verbose %debug %name-prefix "calc" %verbose %yacc])
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}]) 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}])
+99 -167
View File
@@ -17,9 +17,42 @@
AT_BANNER([[Conflicts.]]) AT_BANNER([[Conflicts.]])
## ------------------------- ## ## ------------------------------ ##
## Token declaration order. ## ## 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. ##
## ------------------------ ##
# This test checks that token are declared left to right when in a precedence # This test checks that token are declared left to right when in a precedence
# statement. # statement.
@@ -77,7 +110,27 @@ int main (void)
} }
]]) ]])
AT_BISON_CHECK([-o input.c input.y]) 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_COMPILE([input]) AT_COMPILE([input])
AT_PARSER_CHECK([./input]) AT_PARSER_CHECK([./input])
@@ -87,127 +140,6 @@ AT_BISON_OPTION_POPDEFS
AT_CLEANUP 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. ## ## Useless precedence warning. ##
## ---------------------------- ## ## ---------------------------- ##
@@ -215,7 +147,7 @@ AT_CLEANUP
AT_SETUP([Useless precedence warning]) AT_SETUP([Useless precedence warning])
AT_DATA([[input.y]], AT_DATA([[input.y]],
[[%token A B U V W X Y Z [[%token A B
%precedence Z %precedence Z
%left X %left X
%precedence Y %precedence Y
@@ -242,19 +174,19 @@ f: B
; ;
]]) ]])
AT_BISON_CHECK([-Wprecedence -fcaret -o input.c input.y], 0, [], AT_BISON_CHECK([-fcaret -o input.c input.y], 0, [],
[[input.y:7.1-9: warning: useless precedence and associativity for U [-Wprecedence] [[input.y:2.13: warning: useless precedence for Z [-Wother]
%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 %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]
%nonassoc U
^
]]) ]])
AT_CLEANUP AT_CLEANUP
@@ -279,7 +211,7 @@ e: 'e' | /* Nothing. */;
]]) ]])
AT_BISON_CHECK([-o input.c input.y], 0, [], AT_BISON_CHECK([-o input.c input.y], 0, [],
[[input.y:4.9: warning: rule useless in parser due to conflicts [-Wother] [[input.y:4.9: warning: rule useless in parser due to conflicts: e: /* empty */ [-Wother]
]]) ]])
AT_BISON_CHECK([-fcaret -o input.c input.y], 0, [], AT_BISON_CHECK([-fcaret -o input.c input.y], 0, [],
@@ -1007,7 +939,7 @@ cond:
AT_BISON_CHECK([-o input.c input.y], 0, [], AT_BISON_CHECK([-o input.c input.y], 0, [],
[[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr] [[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
input.y:12.3-18: warning: rule useless in parser due to conflicts [-Wother] input.y:12.3-18: warning: rule useless in parser due to conflicts: cond: cond "then" cond [-Wother]
]]) ]])
AT_CLEANUP AT_CLEANUP
@@ -1023,13 +955,13 @@ AT_CLEANUP
# $end reduce using rule 3 (num) # $end reduce using rule 3 (num)
# $end [reduce using rule 4 (id)] # $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)] # $end [reduce using rule 4 (id)]
# $default reduce using rule 3 (num) # $default reduce using rule 3 (num)
# #
# In this precise case (a reduction is masked by the default # 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 3 (num)
# $end [reduce using rule 4 (id)] # $end [reduce using rule 4 (id)]
@@ -1051,7 +983,7 @@ id : '0';
AT_BISON_CHECK([-o input.c --report=all input.y], 0, [], AT_BISON_CHECK([-o input.c --report=all input.y], 0, [],
[[input.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr] [[input.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
input.y:4.6-8: warning: rule useless in parser due to conflicts [-Wother] input.y:4.6-8: warning: rule useless in parser due to conflicts: id: '0' [-Wother]
]]) ]])
# Check the contents of the report. # Check the contents of the report.
@@ -1264,10 +1196,10 @@ e: e '+' e
; ;
]]) ]])
AT_BISON_CHECK([-Wall -o input.c input.y], 0, [], AT_BISON_CHECK([-o input.c input.y], 0, [],
[[input.y: warning: 4 shift/reduce conflicts [-Wconflicts-sr] [[input.y: warning: 4 shift/reduce conflicts [-Wconflicts-sr]
input.y:1.1-5: warning: useless precedence and associativity for '+' [-Wprecedence] input.y:1.7-9: warning: useless associativity for '+' [-Wother]
input.y:2.1-5: warning: useless precedence and associativity for '*' [-Wprecedence] input.y:2.7-9: warning: useless associativity for '*' [-Wother]
]]) ]])
AT_CLEANUP AT_CLEANUP
@@ -1371,13 +1303,13 @@ reported_conflicts:
AT_BISON_CHECK([[--report=all input.y]], 0, [], AT_BISON_CHECK([[--report=all input.y]], 0, [],
[[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr] [[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
input.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr] input.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
input.y:12.5-20: warning: rule useless in parser due to conflicts [-Wother] 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 [-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 [-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 [-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 [-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 [-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 [-Wother] input.y:32.4: warning: rule useless in parser due to conflicts: reported_conflicts: /* empty */ [-Wother]
]]) ]])
AT_CHECK([[cat input.output]], 0, AT_CHECK([[cat input.output]], 0,
@@ -1386,13 +1318,13 @@ AT_CHECK([[cat input.output]], 0,
2 resolved_conflict: 'a' unreachable1 2 resolved_conflict: 'a' unreachable1
4 unreachable1: 'a' unreachable2 4 unreachable1: 'a' unreachable2
5 | %empty 5 | /* empty */
6 unreachable2: %empty 6 unreachable2: /* empty */
7 | %empty 7 | /* empty */
9 reported_conflicts: 'a' 9 reported_conflicts: 'a'
10 | %empty 10 | /* empty */
State 4 conflicts: 1 shift/reduce State 4 conflicts: 1 shift/reduce
@@ -1406,17 +1338,17 @@ Grammar
1 start: resolved_conflict 'a' reported_conflicts 'a' 1 start: resolved_conflict 'a' reported_conflicts 'a'
2 resolved_conflict: 'a' unreachable1 2 resolved_conflict: 'a' unreachable1
3 | %empty 3 | /* empty */
4 unreachable1: 'a' unreachable2 4 unreachable1: 'a' unreachable2
5 | %empty 5 | /* empty */
6 unreachable2: %empty 6 unreachable2: /* empty */
7 | %empty 7 | /* empty */
8 reported_conflicts: 'a' 8 reported_conflicts: 'a'
9 | 'a' 9 | 'a'
10 | %empty 10 | /* empty */
Terminals, with rules where they appear Terminals, with rules where they appear
@@ -1524,10 +1456,10 @@ AT_CHECK([[cat input.y >> input-keep.y]])
AT_BISON_CHECK([[input-keep.y]], 0, [], AT_BISON_CHECK([[input-keep.y]], 0, [],
[[input-keep.y: warning: 2 shift/reduce conflicts [-Wconflicts-sr] [[input-keep.y: warning: 2 shift/reduce conflicts [-Wconflicts-sr]
input-keep.y: warning: 2 reduce/reduce conflicts [-Wconflicts-rr] input-keep.y: warning: 2 reduce/reduce conflicts [-Wconflicts-rr]
input-keep.y:22.4: warning: rule useless in parser due to conflicts [-Wother] 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 [-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 [-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 [-Wother] input-keep.y:33.4: warning: rule useless in parser due to conflicts: reported_conflicts: /* empty */ [-Wother]
]]) ]])
AT_CLEANUP AT_CLEANUP
@@ -1707,7 +1639,7 @@ exp: 'a' | 'a';
AT_BISON_CHECK([[2.y]], [[0]], [], AT_BISON_CHECK([[2.y]], [[0]], [],
[[2.y: warning: %expect-rr applies only to GLR parsers [-Wother] [[2.y: warning: %expect-rr applies only to GLR parsers [-Wother]
2.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr] 2.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
2.y:3.12-14: warning: rule useless in parser due to conflicts [-Wother] 2.y:3.12-14: warning: rule useless in parser due to conflicts: exp: 'a' [-Wother]
]]) ]])
AT_CLEANUP AT_CLEANUP
+143 -156
View File
@@ -403,60 +403,68 @@ dnl parses it as:
dnl dnl
dnl getline $!(4*0); dnl getline $!(4*0);
dnl 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 argument.
dnl dnl
dnl The grammar below using LALR(1) parses it as a syntax error. So does 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 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
dnl GNU AWK 3.1.2, 3.1.3, 3.1.4, and 3.1.5 parse it as: dnl GNU AWK 3.1.2, 3.1.3, 3.1.4, and 3.1.5 parse it as:
dnl dnl
dnl (getline $!4)*0; dnl (getline $!4)*0;
dnl dnl
dnl That is, like the other versions of GNU AWK, they reduce the full getline 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 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 getline rule, `*' actually is a valid lookahead. Solaris /usr/xpg4/bin/awk
dnl and the Open Group awk specification seem to agree: dnl and the Open Group awk specification seem to agree:
dnl dnl
dnl http://www.opengroup.org/pubs/online/7908799/xcu/awk.html dnl http://www.opengroup.org/pubs/online/7908799/xcu/awk.html
dnl dnl
dnl /bin/nawk and /bin/awk on Solaris 10 report it as a syntax error, but they 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, ';']], [[LEX_GETLINE, '$', '!', YNUMBER, '*', YNUMBER, ';']],
dnl BISON-STDERR dnl BISON-STDERR
[[input.y:66.10: warning: empty rule without %empty [-Wempty-rule] [AT_COND_CASE([[canonical LR]],
input.y:169.8: warning: empty rule without %empty [-Wempty-rule] [[input.y: warning: 265 shift/reduce conflicts [-Wconflicts-sr]
input.y:174.12: warning: empty rule without %empty [-Wempty-rule] input.y:19.8-16: warning: useless associativity for FUNC_CALL [-Wother]
input.y:179.13: warning: empty rule without %empty [-Wempty-rule] input.y:21.8-14: warning: useless associativity for YNUMBER [-Wother]
input.y:187.15: warning: empty rule without %empty [-Wempty-rule] input.y:21.16-22: warning: useless associativity for YSTRING [-Wother]
input.y:201.8: warning: empty rule without %empty [-Wempty-rule] input.y:22.14-22: warning: useless associativity for APPEND_OP [-Wother]
input.y:206.21: warning: empty rule without %empty [-Wempty-rule] input.y:23.8-15: warning: useless associativity for ASSIGNOP [-Wother]
input.y:220.20: warning: empty rule without %empty [-Wempty-rule] input.y:23.33-41: warning: useless associativity for CONCAT_OP [-Wother]
input.y:299.13: warning: empty rule without %empty [-Wempty-rule] input.y:27.8-18: warning: useless associativity for LEX_GETLINE [-Wother]
input.y:322.9: warning: empty rule without %empty [-Wempty-rule] input.y:28.8-13: warning: useless associativity for LEX_IN [-Wother]
]AT_COND_CASE([[canonical LR]], input.y:29.23-31: warning: useless associativity for INCREMENT [-Wother]
[[input.y: warning: 265 shift/reduce conflicts [-Wconflicts-sr]]], input.y:29.33-41: warning: useless associativity for DECREMENT [-Wother]
[[input.y: warning: 65 shift/reduce conflicts [-Wconflicts-sr]]])[ input.y:30.8-18: warning: useless associativity for LEX_BUILTIN [-Wother]
input.y:39.1-5: warning: useless associativity for FUNC_CALL, use %precedence [-Wprecedence] input.y:30.20-29: warning: useless associativity for LEX_LENGTH [-Wother]
input.y:44.1-5: warning: useless associativity for YNUMBER, use %precedence [-Wprecedence] input.y:40.11-13: warning: useless associativity for ',' [-Wother]
input.y:44.1-5: warning: useless associativity for YSTRING, use %precedence [-Wprecedence] input.y:47.8-10: warning: useless associativity for '!' [-Wother]
input.y:42.1-9: warning: useless precedence and associativity for APPEND_OP [-Wprecedence] input.y:47.12-16: warning: useless associativity for UNARY [-Wother]
input.y:33.1-6: warning: useless associativity for ASSIGNOP, use %precedence [-Wprecedence] input.y:50.7-9: warning: useless associativity for '$' [-Wother]
input.y:43.1-5: warning: useless associativity for CONCAT_OP, use %precedence [-Wprecedence] input.y:51.7-9: warning: useless associativity for '(' [-Wother]
input.y:37.1-5: warning: useless precedence and associativity for LEX_GETLINE [-Wprecedence] input.y:51.11-13: warning: useless associativity for ')' [-Wother]]],
input.y:38.1-9: warning: useless associativity for LEX_IN, use %precedence [-Wprecedence] [[input.y: warning: 65 shift/reduce conflicts [-Wconflicts-sr]
input.y:49.1-5: warning: useless associativity for INCREMENT, use %precedence [-Wprecedence] input.y:19.8-16: warning: useless associativity for FUNC_CALL [-Wother]
input.y:49.1-5: warning: useless associativity for DECREMENT, use %precedence [-Wprecedence] input.y:21.8-14: warning: useless associativity for YNUMBER [-Wother]
input.y:39.1-5: warning: useless associativity for LEX_BUILTIN, use %precedence [-Wprecedence] input.y:21.16-22: warning: useless associativity for YSTRING [-Wother]
input.y:39.1-5: warning: useless associativity for LEX_LENGTH, use %precedence [-Wprecedence] input.y:22.14-22: warning: useless associativity for APPEND_OP [-Wother]
input.y:40.1-9: warning: useless precedence and associativity for ',' [-Wprecedence] input.y:23.8-15: warning: useless associativity for ASSIGNOP [-Wother]
input.y:47.1-6: warning: useless associativity for '!', use %precedence [-Wprecedence] input.y:23.33-41: warning: useless associativity for CONCAT_OP [-Wother]
input.y:47.1-6: warning: useless associativity for UNARY, use %precedence [-Wprecedence] input.y:27.8-18: warning: useless associativity for LEX_GETLINE [-Wother]
input.y:50.1-5: warning: useless associativity for '$', use %precedence [-Wprecedence] input.y:28.8-13: warning: useless associativity for LEX_IN [-Wother]
input.y:51.1-5: warning: useless associativity for '(', use %precedence [-Wprecedence] input.y:29.23-31: warning: useless associativity for INCREMENT [-Wother]
input.y:51.1-5: warning: useless precedence and associativity for ')' [-Wprecedence] 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]]])[
]], ]],
dnl LAST-STATE dnl LAST-STATE
@@ -1395,39 +1403,23 @@ dnl INPUT
[[]], [[]],
dnl BISON-STDERR dnl BISON-STDERR
[[input.y:128.12: warning: empty rule without %empty [-Wempty-rule] [AT_COND_CASE([[canonical LR]],
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: 1876 shift/reduce conflicts [-Wconflicts-sr]
input.y: warning: 144 reduce/reduce conflicts [-Wconflicts-rr]]], 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: 78 shift/reduce conflicts [-Wconflicts-sr] [[input.y: warning: 78 shift/reduce conflicts [-Wconflicts-sr]
input.y: warning: 10 reduce/reduce conflicts [-Wconflicts-rr]]])[ input.y: warning: 10 reduce/reduce conflicts [-Wconflicts-rr]
input.y:72.1-5: warning: useless associativity for HQUA, use %precedence [-Wprecedence] input.y:32.9-12: warning: useless associativity for HQUA [-Wother]
input.y:53.1-6: warning: useless associativity for HASSIGN, use %precedence [-Wprecedence] input.y:53.8-14: warning: useless associativity for HASSIGN [-Wother]
input.y:54.1-5: warning: useless associativity for HORELSE, use %precedence [-Wprecedence] input.y:54.9-15: warning: useless associativity for HORELSE [-Wother]
input.y:55.1-5: warning: useless associativity for HANDTHEN, use %precedence [-Wprecedence] input.y:55.9-16: warning: useless associativity for HANDTHEN [-Wother]
input.y:61.1-5: warning: useless associativity for HNOT, use %precedence [-Wprecedence] input.y:61.9-12: warning: useless associativity for HNOT [-Wother]
input.y:68.1-5: warning: useless associativity for UNEAR, use %precedence [-Wprecedence] input.y:68.7-11: warning: useless associativity for UNEAR [-Wother]]])[
]], ]],
dnl LAST-STATE dnl LAST-STATE
@@ -1593,7 +1585,7 @@ box "foo" above ljust == box ("foo" above ljust)
%left LEFT RIGHT %left LEFT RIGHT
/* Give attributes that take an optional expression a higher /* 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. */ parses properly. */
%left CHOP SOLID DASHED DOTTED UP DOWN FILL COLORED OUTLINED %left CHOP SOLID DASHED DOTTED UP DOWN FILL COLORED OUTLINED
%left LABEL %left LABEL
@@ -1606,7 +1598,7 @@ parses properly. */
/* these need to be lower than '-' */ /* these need to be lower than '-' */
%left HEIGHT RADIUS WIDTH DIAMETER FROM TO AT THICKNESS %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 */ works */
%left DOT_N DOT_E DOT_W DOT_S DOT_NE DOT_SE DOT_NW DOT_SW DOT_C %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 %left DOT_START DOT_END TOP BOTTOM LEFT_CORNER RIGHT_CORNER
@@ -2009,93 +2001,88 @@ dnl without being followed by "of".)
[[VARIABLE, '=', LABEL, LEFT, DOT_X]], [[VARIABLE, '=', LABEL, LEFT, DOT_X]],
dnl BISON-STDERR dnl BISON-STDERR
[[input.y:202.19: warning: empty rule without %empty [-Wempty-rule] [[input.y:471.11-48: warning: rule useless in parser due to conflicts: path: ORDINAL LAST object_type relative_path [-Wother]
input.y:270.6: warning: empty rule without %empty [-Wempty-rule] input.y:19.8-12: warning: useless associativity for LABEL [-Wother]
input.y:292.12: warning: empty rule without %empty [-Wempty-rule] input.y:20.8-15: warning: useless associativity for VARIABLE [-Wother]
input.y:309.17: warning: empty rule without %empty [-Wempty-rule] input.y:21.8-13: warning: useless associativity for NUMBER [-Wother]
input.y:382.13: warning: empty rule without %empty [-Wempty-rule] input.y:22.8-11: warning: useless associativity for TEXT [-Wother]
input.y:471.11-48: warning: rule useless in parser due to conflicts [-Wother] input.y:25.8-14: warning: useless associativity for ORDINAL [-Wother]
input.y:154.1-5: warning: useless associativity for LABEL, use %precedence [-Wprecedence] input.y:30.8-11: warning: useless associativity for LAST [-Wother]
input.y:156.1-5: warning: useless associativity for VARIABLE, use %precedence [-Wprecedence] input.y:31.8-9: warning: useless associativity for UP [-Wother]
input.y:156.1-5: warning: useless associativity for NUMBER, use %precedence [-Wprecedence] input.y:32.8-11: warning: useless associativity for DOWN [-Wother]
input.y:141.1-5: warning: useless associativity for TEXT, use %precedence [-Wprecedence] input.y:35.8-10: warning: useless associativity for BOX [-Wother]
input.y:157.1-5: warning: useless associativity for ORDINAL, use %precedence [-Wprecedence] input.y:36.8-13: warning: useless associativity for CIRCLE [-Wother]
input.y:156.1-5: warning: useless associativity for LAST, use %precedence [-Wprecedence] input.y:37.8-14: warning: useless associativity for ELLIPSE [-Wother]
input.y:153.1-5: warning: useless associativity for UP, use %precedence [-Wprecedence] input.y:38.8-10: warning: useless associativity for ARC [-Wother]
input.y:153.1-5: warning: useless associativity for DOWN, use %precedence [-Wprecedence] input.y:39.8-11: warning: useless associativity for LINE [-Wother]
input.y:159.1-5: warning: useless associativity for BOX, use %precedence [-Wprecedence] input.y:40.8-12: warning: useless associativity for ARROW [-Wother]
input.y:159.1-5: warning: useless associativity for CIRCLE, use %precedence [-Wprecedence] input.y:42.8-13: warning: useless associativity for SPLINE [-Wother]
input.y:159.1-5: warning: useless associativity for ELLIPSE, use %precedence [-Wprecedence] input.y:43.8-13: warning: useless associativity for HEIGHT [-Wother]
input.y:159.1-5: warning: useless associativity for ARC, use %precedence [-Wprecedence] input.y:44.8-13: warning: useless associativity for RADIUS [-Wother]
input.y:159.1-5: warning: useless associativity for LINE, use %precedence [-Wprecedence] input.y:45.8-12: warning: useless associativity for WIDTH [-Wother]
input.y:159.1-5: warning: useless associativity for ARROW, use %precedence [-Wprecedence] input.y:46.8-15: warning: useless associativity for DIAMETER [-Wother]
input.y:159.1-5: warning: useless associativity for SPLINE, use %precedence [-Wprecedence] input.y:47.8-11: warning: useless associativity for FROM [-Wother]
input.y:162.1-5: warning: useless associativity for HEIGHT, use %precedence [-Wprecedence] input.y:48.8-9: warning: useless associativity for TO [-Wother]
input.y:162.1-5: warning: useless associativity for RADIUS, use %precedence [-Wprecedence] input.y:49.8-9: warning: useless associativity for AT [-Wother]
input.y:162.1-5: warning: useless associativity for WIDTH, use %precedence [-Wprecedence] input.y:53.8-12: warning: useless associativity for SOLID [-Wother]
input.y:162.1-5: warning: useless associativity for DIAMETER, use %precedence [-Wprecedence] input.y:54.8-13: warning: useless associativity for DOTTED [-Wother]
input.y:162.1-5: warning: useless associativity for FROM, use %precedence [-Wprecedence] input.y:55.8-13: warning: useless associativity for DASHED [-Wother]
input.y:162.1-5: warning: useless associativity for TO, use %precedence [-Wprecedence] input.y:56.8-11: warning: useless associativity for CHOP [-Wother]
input.y:162.1-5: warning: useless associativity for AT, use %precedence [-Wprecedence] input.y:59.8-12: warning: useless associativity for LJUST [-Wother]
input.y:153.1-5: warning: useless precedence and associativity for SOLID [-Wprecedence] input.y:60.8-12: warning: useless associativity for RJUST [-Wother]
input.y:153.1-5: warning: useless associativity for DOTTED, use %precedence [-Wprecedence] input.y:61.8-12: warning: useless associativity for ABOVE [-Wother]
input.y:153.1-5: warning: useless associativity for DASHED, use %precedence [-Wprecedence] input.y:62.8-12: warning: useless associativity for BELOW [-Wother]
input.y:153.1-5: warning: useless associativity for CHOP, use %precedence [-Wprecedence] input.y:63.8-9: warning: useless associativity for OF [-Wother]
input.y:147.1-5: warning: useless precedence and associativity for LJUST [-Wprecedence] input.y:66.8-14: warning: useless associativity for BETWEEN [-Wother]
input.y:147.1-5: warning: useless precedence and associativity for RJUST [-Wprecedence] input.y:67.8-10: warning: useless associativity for AND [-Wother]
input.y:147.1-5: warning: useless precedence and associativity for ABOVE [-Wprecedence] input.y:68.8-11: warning: useless associativity for HERE [-Wother]
input.y:147.1-5: warning: useless precedence and associativity for BELOW [-Wprecedence] input.y:69.8-12: warning: useless associativity for DOT_N [-Wother]
input.y:176.1-5: warning: useless associativity for OF, use %precedence [-Wprecedence] input.y:70.8-12: warning: useless associativity for DOT_E [-Wother]
input.y:176.1-5: warning: useless associativity for BETWEEN, use %precedence [-Wprecedence] input.y:71.8-12: warning: useless associativity for DOT_W [-Wother]
input.y:177.1-5: warning: useless associativity for AND, use %precedence [-Wprecedence] input.y:72.8-12: warning: useless associativity for DOT_S [-Wother]
input.y:157.1-5: warning: useless associativity for HERE, use %precedence [-Wprecedence] input.y:73.8-13: warning: useless associativity for DOT_NE [-Wother]
input.y:166.1-5: warning: useless associativity for DOT_N, use %precedence [-Wprecedence] input.y:74.8-13: warning: useless associativity for DOT_SE [-Wother]
input.y:166.1-5: warning: useless associativity for DOT_E, use %precedence [-Wprecedence] input.y:75.8-13: warning: useless associativity for DOT_NW [-Wother]
input.y:166.1-5: warning: useless associativity for DOT_W, use %precedence [-Wprecedence] input.y:76.8-13: warning: useless associativity for DOT_SW [-Wother]
input.y:166.1-5: warning: useless associativity for DOT_S, use %precedence [-Wprecedence] input.y:77.8-12: warning: useless associativity for DOT_C [-Wother]
input.y:166.1-5: warning: useless associativity for DOT_NE, use %precedence [-Wprecedence] input.y:78.8-16: warning: useless associativity for DOT_START [-Wother]
input.y:166.1-5: warning: useless associativity for DOT_SE, use %precedence [-Wprecedence] input.y:79.8-14: warning: useless associativity for DOT_END [-Wother]
input.y:166.1-5: warning: useless associativity for DOT_NW, use %precedence [-Wprecedence] input.y:85.8-10: warning: useless associativity for SIN [-Wother]
input.y:166.1-5: warning: useless associativity for DOT_SW, use %precedence [-Wprecedence] input.y:86.8-10: warning: useless associativity for COS [-Wother]
input.y:166.1-5: warning: useless associativity for DOT_C, use %precedence [-Wprecedence] input.y:87.8-12: warning: useless associativity for ATAN2 [-Wother]
input.y:167.1-5: warning: useless associativity for DOT_START, use %precedence [-Wprecedence] input.y:88.8-10: warning: useless associativity for LOG [-Wother]
input.y:167.1-5: warning: useless associativity for DOT_END, use %precedence [-Wprecedence] input.y:89.8-10: warning: useless associativity for EXP [-Wother]
input.y:156.1-5: warning: useless associativity for SIN, use %precedence [-Wprecedence] input.y:90.8-11: warning: useless associativity for SQRT [-Wother]
input.y:156.1-5: warning: useless associativity for COS, use %precedence [-Wprecedence] input.y:91.8-12: warning: useless associativity for K_MAX [-Wother]
input.y:156.1-5: warning: useless associativity for ATAN2, use %precedence [-Wprecedence] input.y:92.8-12: warning: useless associativity for K_MIN [-Wother]
input.y:156.1-5: warning: useless associativity for LOG, use %precedence [-Wprecedence] input.y:93.8-10: warning: useless associativity for INT [-Wother]
input.y:156.1-5: warning: useless associativity for EXP, use %precedence [-Wprecedence] input.y:94.8-11: warning: useless associativity for RAND [-Wother]
input.y:156.1-5: warning: useless associativity for SQRT, use %precedence [-Wprecedence] input.y:95.8-12: warning: useless associativity for SRAND [-Wother]
input.y:156.1-5: warning: useless associativity for K_MAX, use %precedence [-Wprecedence] input.y:98.8-10: warning: useless associativity for TOP [-Wother]
input.y:156.1-5: warning: useless associativity for K_MIN, use %precedence [-Wprecedence] input.y:99.8-13: warning: useless associativity for BOTTOM [-Wother]
input.y:156.1-5: warning: useless associativity for INT, use %precedence [-Wprecedence] input.y:100.8-12: warning: useless associativity for UPPER [-Wother]
input.y:156.1-5: warning: useless associativity for RAND, use %precedence [-Wprecedence] input.y:101.8-12: warning: useless associativity for LOWER [-Wother]
input.y:156.1-5: warning: useless associativity for SRAND, use %precedence [-Wprecedence] input.y:116.8-18: warning: useless associativity for LEFT_CORNER [-Wother]
input.y:167.1-5: warning: useless associativity for TOP, use %precedence [-Wprecedence] input.y:117.8-19: warning: useless associativity for RIGHT_CORNER [-Wother]
input.y:167.1-5: warning: useless associativity for BOTTOM, use %precedence [-Wprecedence] input.y:118.8-12: warning: useless associativity for NORTH [-Wother]
input.y:168.1-5: warning: useless associativity for UPPER, use %precedence [-Wprecedence] input.y:119.8-12: warning: useless associativity for SOUTH [-Wother]
input.y:168.1-5: warning: useless associativity for LOWER, use %precedence [-Wprecedence] input.y:120.8-11: warning: useless associativity for EAST [-Wother]
input.y:167.1-5: warning: useless associativity for LEFT_CORNER, use %precedence [-Wprecedence] input.y:121.8-11: warning: useless associativity for WEST [-Wother]
input.y:167.1-5: warning: useless associativity for RIGHT_CORNER, use %precedence [-Wprecedence] input.y:122.8-13: warning: useless associativity for CENTER [-Wother]
input.y:168.1-5: warning: useless associativity for NORTH, use %precedence [-Wprecedence] input.y:123.8-10: warning: useless associativity for END [-Wother]
input.y:168.1-5: warning: useless associativity for SOUTH, use %precedence [-Wprecedence] input.y:124.8-12: warning: useless associativity for START [-Wother]
input.y:168.1-5: warning: useless associativity for EAST, use %precedence [-Wprecedence] input.y:127.8-11: warning: useless associativity for PLOT [-Wother]
input.y:168.1-5: warning: useless associativity for WEST, use %precedence [-Wprecedence] input.y:128.8-16: warning: useless associativity for THICKNESS [-Wother]
input.y:168.1-5: warning: useless associativity for CENTER, use %precedence [-Wprecedence] input.y:129.8-11: warning: useless associativity for FILL [-Wother]
input.y:168.1-5: warning: useless associativity for END, use %precedence [-Wprecedence] input.y:130.8-14: warning: useless associativity for COLORED [-Wother]
input.y:168.1-5: warning: useless associativity for START, use %precedence [-Wprecedence] input.y:131.8-15: warning: useless associativity for OUTLINED [-Wother]
input.y:140.1-5: warning: useless associativity for PLOT, use %precedence [-Wprecedence] input.y:134.8-14: warning: useless associativity for SPRINTF [-Wother]
input.y:162.1-5: warning: useless associativity for THICKNESS, use %precedence [-Wprecedence] input.y:137.7-9: warning: useless associativity for '.' [-Wother]
input.y:153.1-5: warning: useless associativity for FILL, use %precedence [-Wprecedence] input.y:156.23-25: warning: useless associativity for '(' [-Wother]
input.y:153.1-5: warning: useless precedence and associativity for COLORED [-Wprecedence] input.y:157.20-22: warning: useless associativity for '`' [-Wother]
input.y:153.1-5: warning: useless precedence and associativity for OUTLINED [-Wprecedence] input.y:159.48-50: warning: useless associativity for '@<:@' [-Wother]
input.y:141.1-5: warning: useless associativity for SPRINTF, use %precedence [-Wprecedence] input.y:170.7-9: warning: useless associativity for ',' [-Wother]
input.y:137.1-5: warning: useless associativity for '.', use %precedence [-Wprecedence] input.y:181.8-10: warning: useless associativity for '!' [-Wother]
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 dnl LAST-STATE
+6 -6
View File
@@ -486,8 +486,8 @@ start:
; ;
%% %%
]AT_YYERROR_DEFINE[
]AT_YYLEX_DEFINE(["a"])[ ]AT_YYLEX_DEFINE(["a"])[
]AT_YYERROR_DEFINE[
]AT_MAIN_DEFINE[ ]AT_MAIN_DEFINE[
]]) ]])
AT_BISON_OPTION_POPDEFS AT_BISON_OPTION_POPDEFS
@@ -1015,17 +1015,17 @@ main (void)
int exit_status = yyparse (); int exit_status = yyparse ();
if (parent_rhs_before_value) 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; exit_status = 1;
} }
if (merged_value) if (merged_value)
{ {
fprintf (stderr, "'merged' destructor not called.\n"); fprintf (stderr, "`merged' destructor not called.\n");
exit_status = 1; exit_status = 1;
} }
if (parent_rhs_after_value) 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; exit_status = 1;
} }
return exit_status; return exit_status;
@@ -1449,7 +1449,7 @@ main (void)
int exit_status = yyparse () != 1; int exit_status = yyparse () != 1;
if (parent_rhs_before_value) 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; exit_status = 1;
} }
return exit_status; return exit_status;
@@ -1679,8 +1679,8 @@ start:
b: 'b'; b: 'b';
d: /* nada. */; d: /* nada. */;
%% %%
]AT_YYERROR_DEFINE[
]AT_YYLEX_DEFINE(["abc"])[ ]AT_YYLEX_DEFINE(["abc"])[
]AT_YYERROR_DEFINE[
]AT_MAIN_DEFINE[ ]AT_MAIN_DEFINE[
]]) ]])
AT_BISON_OPTION_POPDEFS AT_BISON_OPTION_POPDEFS
+2 -2
View File
@@ -117,9 +117,9 @@ AT_SETUP([Several parsers])
# nor yy* identifiers in the header. Check that headers are # nor yy* identifiers in the header. Check that headers are
# self-contained, and can be compiled by a C++ compiler. # self-contained, and can be compiled by a C++ compiler.
m4_pushdef([AT_TEST], 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], AT_DATA_GRAMMAR([$1.y],
[[%define api.prefix {$1_} [[%define api.prefix "$1_"
$2 $2
%error-verbose %error-verbose
%union %union
+133 -224
View File
@@ -20,29 +20,6 @@ AT_BANNER([[Input Processing.]])
# Mostly test that we are robust to mistakes. # 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. ## ## Invalid inputs. ##
## ---------------- ## ## ---------------- ##
@@ -108,17 +85,17 @@ AT_SETUP([Invalid $n and @n])
AT_DATA([input.y], AT_DATA([input.y],
[[%% [[%%
exp: %empty { $$ = $1 ; }; exp: { $$ = $1 ; };
exp: %empty { @$ = @1 ; }; exp: { @$ = @1 ; };
]]) ]])
AT_BISON_CHECK([-fcaret input.y], [1], [], AT_BISON_CHECK([-fcaret input.y], [1], [],
[[input.y:2.20-21: error: integer out of range: '$1' [[input.y:2.13-14: error: integer out of range: '$1'
exp: %empty { $$ = $1 ; }; exp: { $$ = $1 ; };
^^ ^^
input.y:3.20-21: error: integer out of range: '@1' input.y:3.13-14: error: integer out of range: '@1'
exp: %empty { @$ = @1 ; }; exp: { @$ = @1 ; };
^^ ^^
]]) ]])
AT_CLEANUP AT_CLEANUP
@@ -137,7 +114,7 @@ AT_DATA([input.y],
%% %%
exp: foo { $$; } foo { $2; } foo exp: foo { $$; } foo { $2; } foo
| foo | foo
| %empty | /* empty. */
; ;
]]) ]])
@@ -154,9 +131,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] input.y:6.6-8: warning: type clash on default action: <bar> != <> [-Wother]
| foo | foo
^^^ ^^^
input.y:7.6-11: warning: empty rule for typed nonterminal, and no action [-Wother] input.y:7.5: warning: empty rule for typed nonterminal, and no action [-Wother]
| %empty | /* empty. */
^^^^^^ ^
]]) ]])
AT_CLEANUP AT_CLEANUP
@@ -192,7 +169,7 @@ start:
; ;
a: INT | INT { } INT { } INT { }; a: INT | INT { } INT { } INT { };
b: INT | %empty; b: INT | /* empty */;
c: INT | INT { $]1[; } INT { $<integer>2; } INT { $<integer>4; }; c: INT | INT { $]1[; } INT { $<integer>2; } INT { $<integer>4; };
d: INT | INT { } INT { $]1[; } INT { $<integer>2; }; d: INT | INT { } INT { $]1[; } INT { $<integer>2; };
e: INT | INT { } INT { } INT { $]1[; }; e: INT | INT { } INT { } INT { $]1[; };
@@ -220,9 +197,9 @@ input.y:11.18-20: warning: unused value: $][3 [-Wother]
input.y:11.26-28: warning: unused value: $][5 [-Wother] input.y:11.26-28: warning: unused value: $][5 [-Wother]
a: INT | INT { } INT { } INT { }; a: INT | INT { } INT { } INT { };
^^^ ^^^
input.y:12.10-15: warning: empty rule for typed nonterminal, and no action [-Wother] input.y:12.9: warning: empty rule for typed nonterminal, and no action [-Wother]
b: INT | %empty; b: INT | /* empty */;
^^^^^^ ^
]]m4_ifval($2, [[[input.y:13.14-20: warning: unset value: $][$ [-Wmidrule-values] ]]m4_ifval($2, [[[input.y:13.14-20: warning: unset value: $][$ [-Wmidrule-values]
c: INT | INT { $][1; } INT { $<integer>2; } INT { $<integer>4; }; c: INT | INT { $][1; } INT { $<integer>2; } INT { $<integer>4; };
^^^^^^^ ^^^^^^^
@@ -336,67 +313,104 @@ AT_CLEANUP
AT_SETUP([Default %printer and %destructor redeclared]) AT_SETUP([Default %printer and %destructor redeclared])
# AT_TEST([*]) AT_DATA([[input.y]],
# ------------ [[%destructor { destroy ($$); } <*> <*>
m4_pushdef([AT_TEST], %printer { print ($$); } <*> <*>
[AT_DATA([[input.y]],
[[%destructor { destroy ($$); } <$1> <$1>
%printer { print ($$); } <$1> <$1>
%destructor { destroy ($$); } <$1> %destructor { destroy ($$); } <*>
%printer { print ($$); } <$1> %printer { print ($$); } <*>
%destructor { destroy ($$); } <> <>
%printer { print ($$); } <> <>
%destructor { destroy ($$); } <>
%printer { print ($$); } <>
%% %%
start: %empty; start: ;
%destructor { destroy ($$); } <$1>; %destructor { destroy ($$); } <*>;
%printer { print ($$); } <$1>; %printer { print ($$); } <*>;
%destructor { destroy ($$); } <>;
%printer { print ($$); } <>;
]]) ]])
AT_BISON_CHECK([-fcaret input.y], [1], [], AT_BISON_CHECK([-fcaret input.y], [1], [],
[[input.y:1.13-29: error: %destructor redeclaration for <> [[input.y:1.13-29: error: %destructor redeclaration for <*>
%destructor { destroy ($$); } <> <> %destructor { destroy ($$); } <*> <*>
^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^
input.y:1.13-29: previous declaration input.y:1.13-29: previous declaration
%destructor { destroy ($$); } <> <> %destructor { destroy ($$); } <*> <*>
^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^
input.y:2.10-24: error: %printer redeclaration for <> input.y:2.10-24: error: %printer redeclaration for <*>
%printer { print ($$); } <> <> %printer { print ($$); } <*> <*>
^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^
input.y:2.10-24: previous declaration 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 <>
%destructor { destroy ($$); } <> <>
^^^^^^^^^^^^^^^^^
input.y:7.13-29: previous declaration
%destructor { destroy ($$); } <> <>
^^^^^^^^^^^^^^^^^
input.y:8.10-24: error: %printer redeclaration for <>
%printer { print ($$); } <> <> %printer { print ($$); } <> <>
^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^
input.y:4.13-29: error: %destructor redeclaration for <> input.y:8.10-24: previous declaration
%printer { print ($$); } <> <>
^^^^^^^^^^^^^^^
input.y:10.13-29: error: %destructor redeclaration for <>
%destructor { destroy ($$); } <> %destructor { destroy ($$); } <>
^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^
input.y:1.13-29: previous declaration input.y:7.13-29: previous declaration
%destructor { destroy ($$); } <> <> %destructor { destroy ($$); } <> <>
^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^
input.y:5.10-24: error: %printer redeclaration for <> input.y:11.10-24: error: %printer redeclaration for <>
%printer { print ($$); } <> %printer { print ($$); } <>
^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^
input.y:2.10-24: previous declaration input.y:8.10-24: previous declaration
%printer { print ($$); } <> <> %printer { print ($$); } <> <>
^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^
input.y:11.13-29: error: %destructor redeclaration for <> 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 <>
%destructor { destroy ($$); } <>; %destructor { destroy ($$); } <>;
^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^
input.y:1.13-29: previous declaration input.y:10.13-29: previous declaration
%destructor { destroy ($$); } <> <> %destructor { destroy ($$); } <>
^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^
input.y:12.10-24: error: %printer redeclaration for <> input.y:21.10-24: error: %printer redeclaration for <>
%printer { print ($$); } <>; %printer { print ($$); } <>;
^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^
input.y:2.10-24: previous declaration input.y:11.10-24: previous declaration
%printer { print ($$); } <> <> %printer { print ($$); } <>
^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^
]]) ]])
])
AT_TEST([], [], [])
AT_TEST([], [*], [*])
m4_popdef([AT_TEST])
AT_CLEANUP AT_CLEANUP
@@ -416,7 +430,7 @@ AT_DATA([[input.y]],
%% %%
start: %empty; start: ;
%destructor { destroy ($$); } <field2> <field1>; %destructor { destroy ($$); } <field2> <field1>;
%printer { print ($$); } <field2> <field1>; %printer { print ($$); } <field2> <field1>;
@@ -426,17 +440,17 @@ AT_BISON_CHECK([input.y], [1], [],
[[input.y:4.13-29: error: %destructor redeclaration for <field1> [[input.y:4.13-29: error: %destructor redeclaration for <field1>
input.y:1.13-29: previous declaration input.y:1.13-29: previous declaration
input.y:4.13-29: error: %destructor redeclaration for <field1> input.y:4.13-29: error: %destructor redeclaration for <field1>
input.y:1.13-29: previous declaration input.y:4.13-29: previous declaration
input.y:5.10-24: error: %printer redeclaration for <field2> input.y:5.10-24: error: %printer redeclaration for <field2>
input.y:2.10-24: previous declaration input.y:2.10-24: previous declaration
input.y:5.10-24: error: %printer redeclaration for <field2> input.y:5.10-24: error: %printer redeclaration for <field2>
input.y:2.10-24: previous declaration input.y:5.10-24: previous declaration
input.y:11.13-29: error: %destructor redeclaration for <field2> input.y:11.13-29: error: %destructor redeclaration for <field2>
input.y:1.13-29: previous declaration input.y:1.13-29: previous declaration
input.y:11.13-29: error: %destructor redeclaration for <field1> input.y:11.13-29: error: %destructor redeclaration for <field1>
input.y:1.13-29: previous declaration input.y:4.13-29: previous declaration
input.y:12.10-24: error: %printer redeclaration for <field2> input.y:12.10-24: error: %printer redeclaration for <field2>
input.y:2.10-24: previous declaration input.y:5.10-24: previous declaration
input.y:12.10-24: error: %printer redeclaration for <field1> input.y:12.10-24: error: %printer redeclaration for <field1>
input.y:2.10-24: previous declaration input.y:2.10-24: previous declaration
]]) ]])
@@ -812,7 +826,7 @@ exp: '@<:@' '\1' two '$' '@' '{' oline output.or.oline.opt
two: '\x000000000000000000000000000000000000000000000000000000000000000000002'; two: '\x000000000000000000000000000000000000000000000000000000000000000000002';
oline: '@' 'o' 'l' 'i' 'n' 'e' '@' '_' '_' 'o' 'l' 'i' 'n' 'e' '_' '_'; oline: '@' 'o' 'l' 'i' 'n' 'e' '@' '_' '_' 'o' 'l' 'i' 'n' 'e' '_' '_';
output.or.oline.opt: %empty;|oline;;|output;;; output.or.oline.opt: ;|oline;;|output;;;
output: '#' 'o' 'u' 't' 'p' 'u' 't' ' '; output: '#' 'o' 'u' 't' 'p' 'u' 't' ' ';
%% %%
/* Exercise M4 quoting: '@:>@@:>@', @<:@, 2. */ /* Exercise M4 quoting: '@:>@@:>@', @<:@, 2. */
@@ -894,7 +908,7 @@ m4_define([AT_CHECK_REQUIRE],
AT_DATA_GRAMMAR([input.y], AT_DATA_GRAMMAR([input.y],
[[%require "$1"; [[%require "$1";
%% %%
empty_file: %empty; empty_file: /* empty */;
]]) ]])
AT_BISON_CHECK([-o input.c input.y], $2, [], ignore) AT_BISON_CHECK([-o input.c input.y], $2, [], ignore)
AT_CLEANUP AT_CLEANUP
@@ -1052,7 +1066,7 @@ AT_DATA([input.y],
%% %%
start: %empty; start: ;
// Used to report a syntax error because it didn't see any kind of symbol // Used to report a syntax error because it didn't see any kind of symbol
// identifier. // identifier.
@@ -1097,7 +1111,7 @@ AT_SETUP([%start after first rule])
AT_DATA([input.y], AT_DATA([input.y],
[[%% [[%%
false_start: %empty; false_start: ;
start: false_start ; start: false_start ;
%start start; %start start;
]]) ]])
@@ -1118,7 +1132,7 @@ AT_SETUP([%prec takes a token])
AT_DATA([input.y], AT_DATA([input.y],
[[%% [[%%
start: PREC %prec PREC ; start: PREC %prec PREC ;
PREC: %empty; PREC: ;
]]) ]])
AT_BISON_CHECK([input.y], [1], [], AT_BISON_CHECK([input.y], [1], [],
@@ -1160,7 +1174,7 @@ AT_DATA([input-c.y],
%code bad {} %code bad {}
%code format {} %code format {}
%% %%
start: %empty; start: ;
]]) ]])
AT_BISON_CHECK([[input-c.y]], [[1]], [], AT_BISON_CHECK([[input-c.y]], [[1]], [],
[[input-c.y:1.7: error: %code qualifier 'q' is not used [[input-c.y:1.7: error: %code qualifier 'q' is not used
@@ -1174,7 +1188,7 @@ AT_DATA([input-c-glr.y],
%code bad {} %code bad {}
%code bad {} %code bad {}
%% %%
start: %empty; start: ;
]]) ]])
AT_BISON_CHECK([[input-c-glr.y]], [[1]], [], AT_BISON_CHECK([[input-c-glr.y]], [[1]], [],
[[input-c-glr.y:1.7: error: %code qualifier 'q' is not used [[input-c-glr.y:1.7: error: %code qualifier 'q' is not used
@@ -1187,7 +1201,7 @@ AT_DATA([input-c++.y],
%code bad {} %code bad {}
%code q {} %code q {}
%% %%
start: %empty; start: ;
]]) ]])
AT_BISON_CHECK([[input-c++.y]], [[1]], [], AT_BISON_CHECK([[input-c++.y]], [[1]], [],
[[input-c++.y:1.7: error: %code qualifier 'q' is not used [[input-c++.y:1.7: error: %code qualifier 'q' is not used
@@ -1200,7 +1214,7 @@ AT_DATA([input-c++-glr.y],
%code q {} %code q {}
%code q {} %code q {}
%% %%
start: %empty; start: ;
]]) ]])
AT_BISON_CHECK([[input-c++-glr.y]], [[1]], [], AT_BISON_CHECK([[input-c++-glr.y]], [[1]], [],
[[input-c++-glr.y:1.7-9: error: %code qualifier 'bad' is not used [[input-c++-glr.y:1.7-9: error: %code qualifier 'bad' is not used
@@ -1213,7 +1227,7 @@ AT_DATA([special-char-@@.y],
%code q {} %code q {}
%code q {} %code q {}
%% %%
start: %empty; start: ;
]]) ]])
AT_BISON_CHECK([[special-char-@@.y]], [[1]], [], AT_BISON_CHECK([[special-char-@@.y]], [[1]], [],
[[special-char-@@.y:1.7-9: error: %code qualifier 'bad' is not used [[special-char-@@.y:1.7-9: error: %code qualifier 'bad' is not used
@@ -1226,7 +1240,7 @@ AT_DATA([special-char-@:>@.y],
%code q {} %code q {}
%code q {} %code q {}
%% %%
start: %empty; start: ;
]]) ]])
AT_BISON_CHECK([[special-char-@:>@.y]], [[1]], [], AT_BISON_CHECK([[special-char-@:>@.y]], [[1]], [],
[[special-char-@:>@.y:1.7-9: error: %code qualifier 'bad' is not used [[special-char-@:>@.y:1.7-9: error: %code qualifier 'bad' is not used
@@ -1237,45 +1251,6 @@ special-char-@:>@.y:3.7: error: %code qualifier 'q' is not used
AT_CLEANUP 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. ## ## %define errors. ##
## ---------------- ## ## ---------------- ##
@@ -1289,7 +1264,7 @@ AT_DATA([input-redefined.y],
%define special1 "@:>@" %define special1 "@:>@"
%define special2 "@<:@" %define special2 "@<:@"
%% %%
start: %empty; start: ;
]]) ]])
AT_BISON_CHECK([[input-redefined.y]], [[1]], [], AT_BISON_CHECK([[input-redefined.y]], [[1]], [],
@@ -1302,7 +1277,7 @@ input-redefined.y:2.9-11: previous definition
AT_DATA([input-unused.y], AT_DATA([input-unused.y],
[[%define var "value" [[%define var "value"
%% %%
start: %empty; start: ;
]]) ]])
AT_BISON_CHECK([[input-unused.y]], [[1]], [], AT_BISON_CHECK([[input-unused.y]], [[1]], [],
@@ -1330,7 +1305,7 @@ m4@&t@_divert_pop(0)
AT_DATA([[input.y]], AT_DATA([[input.y]],
[[%define var-dfg "gram" [[%define var-dfg "gram"
%% %%
start: %empty; start: ;
]]) ]])
AT_BISON_CHECK([[-Dvar-dd=cmd-d1 -Dvar-dd=cmd-d2 \ AT_BISON_CHECK([[-Dvar-dd=cmd-d1 -Dvar-dd=cmd-d2 \
-Fvar-ff=cmd-f1 -Fvar-ff=cmd-f2 \ -Fvar-ff=cmd-f1 -Fvar-ff=cmd-f2 \
@@ -1347,7 +1322,7 @@ var-fd: cmd-d
AT_DATA([[input-dg.y]], AT_DATA([[input-dg.y]],
[[%define var "gram" [[%define var "gram"
%% %%
start: %empty; start: ;
]]) ]])
AT_BISON_CHECK([[-Dvar=cmd-d input-dg.y]], [[1]], [], AT_BISON_CHECK([[-Dvar=cmd-d input-dg.y]], [[1]], [],
[[input-dg.y:1.9-11: error: %define variable 'var' redefined [[input-dg.y:1.9-11: error: %define variable 'var' redefined
@@ -1357,7 +1332,7 @@ AT_BISON_CHECK([[-Dvar=cmd-d input-dg.y]], [[1]], [],
AT_DATA([[input-dg.y]], AT_DATA([[input-dg.y]],
[[%define var "gram" [[%define var "gram"
%% %%
start: %empty; start: ;
]]) ]])
AT_BISON_CHECK([[-fcaret -Dvar=cmd-d input-dg.y]], [[1]], [], AT_BISON_CHECK([[-fcaret -Dvar=cmd-d input-dg.y]], [[1]], [],
[[input-dg.y:1.9-11: error: %define variable 'var' redefined [[input-dg.y:1.9-11: error: %define variable 'var' redefined
@@ -1368,7 +1343,7 @@ AT_BISON_CHECK([[-fcaret -Dvar=cmd-d input-dg.y]], [[1]], [],
AT_DATA([[input-unused.y]], AT_DATA([[input-unused.y]],
[[%% [[%%
start: %empty; start: ;
]]) ]])
AT_BISON_CHECK([[-Dunused-d -Funused-f input-unused.y]], [[1]], [], AT_BISON_CHECK([[-Dunused-d -Funused-f input-unused.y]], [[1]], [],
[[<command line>:2: error: %define variable 'unused-d' is not used [[<command line>:2: error: %define variable 'unused-d' is not used
@@ -1385,10 +1360,10 @@ AT_SETUP([["%define" Boolean variables]])
AT_DATA([Input.y], AT_DATA([Input.y],
[[%language "Java" [[%language "Java"
%define public maybe %define public "maybe"
%define parser_class_name {Input} %define parser_class_name "Input"
%% %%
start: %empty; start: ;
]]) ]])
AT_BISON_CHECK([[Input.y]], [1], [], AT_BISON_CHECK([[Input.y]], [1], [],
@@ -1397,72 +1372,6 @@ AT_BISON_CHECK([[Input.y]], [1], [],
AT_CLEANUP 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. ## ## %define enum variables. ##
## ------------------------ ## ## ------------------------ ##
@@ -1477,7 +1386,7 @@ AT_SETUP([["%define" enum variables]])
AT_DATA([[input.y]], AT_DATA([[input.y]],
[[%define lr.default-reduction bogus [[%define lr.default-reduction bogus
%% %%
start: %empty; start: ;
]]) ]])
AT_BISON_CHECK([[-fcaret input.y]], [[1]], [[]], AT_BISON_CHECK([[-fcaret input.y]], [[1]], [[]],
[[input.y:1.9-28: error: invalid value for %define variable 'lr.default-reduction': 'bogus' [[input.y:1.9-28: error: invalid value for %define variable 'lr.default-reduction': 'bogus'
@@ -1492,7 +1401,7 @@ input.y:1.9-28: accepted value: 'accepting'
AT_DATA([[input.y]], AT_DATA([[input.y]],
[[%define api.push-pull neither [[%define api.push-pull neither
%% %%
start: %empty; start: ;
]]) ]])
AT_BISON_CHECK([[-fcaret input.y]], [[1]], [[]], AT_BISON_CHECK([[-fcaret input.y]], [[1]], [[]],
[[input.y:1.9-21: error: invalid value for %define variable 'api.push-pull': 'neither' [[input.y:1.9-21: error: invalid value for %define variable 'api.push-pull': 'neither'
@@ -1516,10 +1425,10 @@ AT_DATA([[input.y]],
[[%define api.push_pull both [[%define api.push_pull both
%define lr.keep_unreachable_states maybe %define lr.keep_unreachable_states maybe
%define namespace "foo" %define namespace "foo"
%define api.namespace {foo} %define api.namespace "foo"
%define variant %define variant
%% %%
start: %empty; start: ;
]]) ]])
AT_BISON_CHECK([[-fcaret input.y]], [1], [], AT_BISON_CHECK([[-fcaret input.y]], [1], [],
[[input.y:1.9-21: warning: deprecated directive, use '%define api.push-pull both' [-Wdeprecated] [[input.y:1.9-21: warning: deprecated directive, use '%define api.push-pull both' [-Wdeprecated]
@@ -1532,7 +1441,7 @@ input.y:3.9-17: warning: deprecated directive, use '%define api.namespace foo' [
%define namespace "foo" %define namespace "foo"
^^^^^^^^^ ^^^^^^^^^
input.y:4.9-21: error: %define variable 'api.namespace' redefined 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 input.y:3.9-17: previous definition
%define namespace "foo" %define namespace "foo"
@@ -1552,7 +1461,7 @@ AT_SETUP([[Unused %define api.pure]])
# AT_CHECK_API_PURE(DECLS, VALUE) # 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. # are specified.
m4_define([AT_CHECK_API_PURE], m4_define([AT_CHECK_API_PURE],
[ [
@@ -1560,7 +1469,7 @@ AT_DATA([[input.y]],
[[%define api.pure ]$2[ [[%define api.pure ]$2[
]$1[ ]$1[
%% %%
start: %empty; start: ;
]]) ]])
AT_BISON_CHECK([[input.y]], [[1]], [], AT_BISON_CHECK([[input.y]], [[1]], [],
@@ -1591,9 +1500,9 @@ m4_define([AT_CHECK_NAMESPACE_ERROR],
AT_DATA([[input.y]], AT_DATA([[input.y]],
[[%language "C++" [[%language "C++"
%defines %defines
%define api.namespace {]$1[} %define api.namespace "]$1["
%% %%
start: %empty; start: ;
]]) ]])
AT_BISON_CHECK([[input.y]], [1], [], AT_BISON_CHECK([[input.y]], [1], [],
@@ -1753,7 +1662,7 @@ AT_SETUP([[LAC: Errors for %define]])
AT_DATA([[input.y]], AT_DATA([[input.y]],
[[%% [[%%
start: %empty; start: ;
]]) ]])
# parse.lac.* options are useless if LAC isn't actually activated. # parse.lac.* options are useless if LAC isn't actually activated.
@@ -1776,27 +1685,27 @@ AT_SETUP([[-Werror is not affected by -Wnone and -Wall]])
AT_DATA([[input.y]], AT_DATA([[input.y]],
[[%% [[%%
a: '0' { $$ = $; }; foo-bar: ;
]]) ]])
# -Werror is not enabled by -Wall or equivalent. # -Werror is not enabled by -Wall or equivalent.
AT_BISON_CHECK([[-Wall input.y]], [[0]], [[]], AT_BISON_CHECK([[-Wall input.y]], [[0]], [[]],
[[input.y:2.15: warning: stray '$' [-Wother] [[input.y:2.1-7: warning: POSIX Yacc forbids dashes in symbol names: foo-bar [-Wyacc]
]]) ]])
AT_BISON_CHECK([[-W input.y]], [[0]], [[]], AT_BISON_CHECK([[-W input.y]], [[0]], [[]],
[[input.y:2.15: warning: stray '$' [-Wother] [[input.y:2.1-7: warning: POSIX Yacc forbids dashes in symbol names: foo-bar [-Wyacc]
]]) ]])
AT_BISON_CHECK([[-Wno-none input.y]], [[0]], [[]], AT_BISON_CHECK([[-Wno-none input.y]], [[0]], [[]],
[[input.y:2.15: warning: stray '$' [-Wother] [[input.y:2.1-7: warning: POSIX Yacc forbids dashes in symbol names: foo-bar [-Wyacc]
]]) ]])
# -Werror is not disabled by -Wnone or equivalent. # -Werror is not disabled by -Wnone or equivalent.
AT_BISON_CHECK([[-Werror,none,other input.y]], [[1]], [[]], AT_BISON_CHECK([[-Werror,none,yacc input.y]], [[1]], [[]], [[stderr]])
[[input.y:2.15: error: stray '$' [-Werror=other] 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,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 AT_CLEANUP
@@ -1813,17 +1722,17 @@ m4_pushdef([AT_TEST],
[AT_DATA([[input.y]], [AT_DATA([[input.y]],
[[$1 [[$1
%% %%
exp: %empty; exp: /* empty */;
]]) ]])
AT_BISON_CHECK([[$2 input.y]], [[1]], [[]], AT_BISON_CHECK([[$2 input.y]], [[1]], [[]],
[[$3: error: '%name-prefix' and '%define api.prefix' cannot be used together [[$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([%define api.prefix foo %name-prefix "bar"], [], [input.y:1.9-18])
AT_TEST([], [-Dapi.prefix={foo} -p bar], [<command line>:2]) AT_TEST([], [-Dapi.prefix=foo -p bar], [<command line>:2])
AT_TEST([%name-prefix "bar"], [-Dapi.prefix={foo}], [<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], [-p bar], [input.y:1.9-18])
m4_popdef([AT_TEST]) m4_popdef([AT_TEST])
+33 -33
View File
@@ -25,8 +25,8 @@ AT_BANNER([[Java Calculator.]])
# _AT_DATA_JAVA_CALC_Y($1, $2, $3, [BISON-DIRECTIVES]) # _AT_DATA_JAVA_CALC_Y($1, $2, $3, [BISON-DIRECTIVES])
# ---------------------------------------------------- # ----------------------------------------------------
# Produce 'calc.y'. Don't call this macro directly, because it contains # Produce `calc.y'. Don't call this macro directly, because it contains
# some occurrences of '$1' etc. which will be interpreted by m4. So # 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 # you should call it with $1, $2, and $3 as arguments, which is what
# AT_DATA_JAVA_CALC_Y does. # AT_DATA_JAVA_CALC_Y does.
m4_define([_AT_DATA_JAVA_CALC_Y], m4_define([_AT_DATA_JAVA_CALC_Y],
@@ -37,7 +37,7 @@ AT_DATA([Calc.y],
[[/* Infix notation calculator--calc */ [[/* Infix notation calculator--calc */
%language "Java" %language "Java"
%name-prefix "Calc" %name-prefix "Calc"
%define parser_class_name {Calc} %define parser_class_name "Calc"
%define public %define public
]$4[ ]$4[
@@ -206,7 +206,7 @@ AT_BISON_OPTION_POPDEFS
# AT_DATA_CALC_Y([BISON-OPTIONS]) # AT_DATA_CALC_Y([BISON-OPTIONS])
# ------------------------------- # -------------------------------
# Produce 'calc.y'. # Produce `calc.y'.
m4_define([AT_DATA_JAVA_CALC_Y], m4_define([AT_DATA_JAVA_CALC_Y],
[_AT_DATA_JAVA_CALC_Y($[1], $[2], $[3], [$1]) [_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, # _AT_CHECK_JAVA_CALC_ERROR(BISON-OPTIONS, INPUT,
# [VERBOSE-AND-LOCATED-ERROR-MESSAGE]) # [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, # If INPUT starts with a slash, it is used as absolute input file name,
# otherwise as contents. # otherwise as contents.
@@ -240,7 +240,7 @@ AT_DATA([[expout]],
AT_YYERROR_SEES_LOC_IF([], AT_YYERROR_SEES_LOC_IF([],
[[sed 's/^[-0-9.]*: //' expout >at-expout [[sed 's/^[-0-9.]*: //' expout >at-expout
mv at-expout 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], [], m4_bmatch([$1], [%error-verbose], [],
[[sed 's/syntax error, .*$/syntax error/' expout >at-expout [[sed 's/syntax error, .*$/syntax error/' expout >at-expout
mv at-expout expout]]) mv at-expout expout]])
@@ -250,7 +250,7 @@ AT_CHECK([cat stderr], 0, [expout])
# _AT_CHECK_JAVA_CALC([BISON-DIRECTIVES], [BISON-CODE]) # _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. # BISON-DIRECTIVES, and performs several tests over the parser.
m4_define([_AT_CHECK_JAVA_CALC], m4_define([_AT_CHECK_JAVA_CALC],
[# We use integers to avoid dependencies upon the precision of doubles. [# 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 # - (* * *): nothing to pop, a lot to discard
# - (1 + 2 * *): some to pop and 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 # - check the lookahead that triggers an error is not discarded
# when we enter error recovery. Below, the lookahead causing the # when we enter error recovery. Below, the lookahead causing the
@@ -342,7 +342,7 @@ AT_CLEANUP
# AT_CHECK_JAVA_CALC([BISON-DIRECTIVES]) # 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. # BISON-DIRECTIVES, and performs several tests over the parser.
# Run the test with and without %error-verbose. # Run the test with and without %error-verbose.
m4_define([AT_CHECK_JAVA_CALC], 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_MINIMAL([[%name-prefix "Prefix"]])
AT_CHECK_JAVA_GREP([[class PrefixParser]]) 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_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_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_CHECK_JAVA_GREP([[package user_java_package;]])
AT_CLEANUP 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 # FIXME: Can't do a Java compile because javacomp.sh is configured for 1.3
AT_CHECK_JAVA_MINIMAL([[ 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]]) %define public]])
AT_CHECK_JAVA_GREP([[/\*@Deprecated @SupressWarnings("unchecked") @SupressWarnings({"unchecked", "deprecation"}) @SupressWarnings(value={"unchecked", "deprecation"})\*/ public class YYParser]]) 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_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_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_GREP([[class YYParser implements Cloneable]])
AT_CHECK_JAVA_MINIMAL([[ AT_CHECK_JAVA_MINIMAL([[
%define extends {Thread} %define extends "Thread"
%define implements {Cloneable}]]) %define implements "Cloneable"]])
AT_CHECK_JAVA_GREP([[class YYParser extends Thread implements Cloneable]]) AT_CHECK_JAVA_GREP([[class YYParser extends Thread implements Cloneable]])
AT_CLEANUP AT_CLEANUP
@@ -643,9 +643,9 @@ AT_SETUP([Java throws specifications])
m4_define([AT_JT_lex_throws_define], [m4_case(AT_JT_lex_throws, m4_define([AT_JT_lex_throws_define], [m4_case(AT_JT_lex_throws,
-1, [], -1, [],
0, [[%define lex_throws {}]], 0, [[%define lex_throws ""]],
1, [[%define lex_throws {InterruptedException}]], 1, [[%define lex_throws "InterruptedException"]],
2, [[%define lex_throws {InterruptedException, IllegalAccessException}]])]) 2, [[%define lex_throws "InterruptedException, IllegalAccessException"]])])
m4_define([AT_JT_yylex_throws], [m4_case(AT_JT_lex_throws, m4_define([AT_JT_yylex_throws], [m4_case(AT_JT_lex_throws,
-1, [[ throws java.io.IOException]], -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, m4_define([AT_JT_throws_define], [m4_case(AT_JT_throws,
-1, [], -1, [],
0, [[%define throws {}]], 0, [[%define throws ""]],
1, [[%define throws {ClassNotFoundException}]], 1, [[%define throws "ClassNotFoundException"]],
2, [[%define throws {ClassNotFoundException, InstantiationException}]])]) 2, [[%define throws "ClassNotFoundException, InstantiationException"]])])
m4_define([AT_JT_yyaction_throws], [m4_case(AT_JT_throws, m4_define([AT_JT_yyaction_throws], [m4_case(AT_JT_throws,
-1, [], -1, [],
@@ -727,16 +727,16 @@ AT_CLEANUP
AT_SETUP([Java constructor init and init_throws]) AT_SETUP([Java constructor init and init_throws])
AT_CHECK_JAVA_MINIMAL([[ AT_CHECK_JAVA_MINIMAL([[
%define extends {Thread} %define extends "Thread"
%code init { super("Test Thread"); if (true) throw new InterruptedException(); } %code init { super("Test Thread"); if (true) throw new InterruptedException(); }
%define init_throws {InterruptedException} %define init_throws "InterruptedException"
%lex-param {int lex_param}]]) %lex-param {int lex_param}]])
AT_CHECK([[grep -q 'super("Test Thread"); if (true) throw new InterruptedException();' YYParser.java]]) AT_CHECK([[grep -q 'super("Test Thread"); if (true) throw new InterruptedException();' YYParser.java]])
AT_CHECK_JAVA_MINIMAL_W_LEXER([[ AT_CHECK_JAVA_MINIMAL_W_LEXER([[
%define extends {Thread} %define extends "Thread"
%code init { super("Test Thread"); if (true) throw new InterruptedException(); } %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_CHECK([[grep -q 'super("Test Thread"); if (true) throw new InterruptedException();' YYParser.java]])
AT_CLEANUP AT_CLEANUP
@@ -749,20 +749,20 @@ AT_CLEANUP
AT_SETUP([Java value, position, and location types]) AT_SETUP([Java value, position, and location types])
AT_CHECK_JAVA_MINIMAL([[ AT_CHECK_JAVA_MINIMAL([[
%define api.value.type {java.awt.Color} %define api.value.type "java.awt.Color"
%type<java.awt.Color> start; %type<java.awt.Color> start;
%define api.location.type {MyLoc} %define api.location.type "MyLoc"
%define api.position.type {MyPos} %define api.position.type "MyPos"
%code { class MyPos {} }]], [[$$ = $<java.awt.Color>1;]], [[MyPos]]) %code { class MyPos {} }]], [[$$ = $<java.awt.Color>1;]], [[MyPos]])
AT_CHECK([[grep 'java.awt.Color' YYParser.java]], [0], [ignore]) 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 'Position']], [1], [ignore])
AT_CHECK([[$EGREP -v ' */?\*' YYParser.java | grep 'Location']], [1], [ignore]) AT_CHECK([[$EGREP -v ' */?\*' YYParser.java | grep 'Location']], [1], [ignore])
AT_CHECK_JAVA_MINIMAL_W_LEXER([[ 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; %type<java.awt.Color> start;
%define api.location.type {MyLoc} %define api.location.type "MyLoc"
%define api.position.type {MyPos} %define api.position.type "MyPos"
%code { class MyPos {} }]], [], [[return EOF;]], [], %code { class MyPos {} }]], [], [[return EOF;]], [],
[[$$ = $<java.awt.Color>1;]], [[$$ = $<java.awt.Color>1;]],
[[java.awt.Color]], [[MyPos]], [[MyLoc]]) [[java.awt.Color]], [[MyPos]], [[MyLoc]])
+106 -151
View File
@@ -37,7 +37,7 @@ m4_define([AT_SETUP_STRIP],
[m4_bpatsubsts([$1], [m4_bpatsubsts([$1],
[%\(language\|skeleton\) "?\([^\" ]*\)"?], [%\(language\|skeleton\) "?\([^\" ]*\)"?],
[\2], [\2],
[%define "?\([-A-Za-z0-9_.]+\)"? \({[^\}]+}\|"[^\"]+"\|[-A-Za-z0-9_.]+\)], [%define "?\([-A-Za-z0-9_.]+\)"? \("[^\"]+"\|[-A-Za-z0-9_.]+\)],
[\1=\2], [\1=\2],
[%define "?\([-A-Za-z0-9_.]+\)"?], [%define "?\([-A-Za-z0-9_.]+\)"?],
[\1], [\1],
@@ -134,7 +134,7 @@ m4_define([AT_BISON_OPTION_PUSHDEFS],
# _AT_BISON_OPTION_PUSHDEFS($1, $2, [BISON-OPTIONS]) # _AT_BISON_OPTION_PUSHDEFS($1, $2, [BISON-OPTIONS])
# -------------------------------------------------- # --------------------------------------------------
# This macro works around the impossibility to define macros # 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. # This sucks hard, GNU M4 should really provide M5-like $$1.
m4_define([_AT_BISON_OPTION_PUSHDEFS], m4_define([_AT_BISON_OPTION_PUSHDEFS],
[m4_if([$1$2], $[1]$[2], [], [m4_if([$1$2], $[1]$[2], [],
@@ -178,25 +178,23 @@ m4_bpatsubst([$3], [%parse-param { *\([^{}]*[^{} ]\) *}],
m4_pushdef([AT_PURE_IF], m4_pushdef([AT_PURE_IF],
[m4_bmatch([$3], [%define *api\.pure\|%pure-parser], [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])]) [$2])])
# AT_NAME_PREFIX: also consider api.namespace. # AT_NAME_PREFIX: also consider api.namespace.
m4_pushdef([AT_NAME_PREFIX], m4_pushdef([AT_NAME_PREFIX],
[m4_bmatch([$3], [\(%define api\.\(namespace\|prefix\)\|%name-prefix\) .*], [m4_bmatch([$3], [\(%define api\.\(namespace\|prefix\)\|%name-prefix\) ".*"],
[m4_bregexp([$3], [m4_bregexp([$3], [\(%define api\.\(namespace\|prefix\)\|%name-prefix\) "\([^""]*\)"], [\3])],
[\(%define api\.\(namespace\|prefix\)\|%name-prefix\) [\{\"]\([^\"\}]*\)[\"\}]], [yy])])
[\3])],
[yy])])
m4_pushdef([AT_TOKEN_CTOR_IF], m4_pushdef([AT_TOKEN_CTOR_IF],
[m4_bmatch([$3], [%define api\.token\.constructor], [$1], [$2])]) [m4_bmatch([$3], [%define api\.token\.constructor], [$1], [$2])])
m4_pushdef([AT_TOKEN_PREFIX], m4_pushdef([AT_TOKEN_PREFIX],
[m4_bmatch([$3], [%define api\.token\.prefix {.*}], [m4_bmatch([$3], [%define api\.token\.prefix ".*"],
[m4_bregexp([$3], [%define api\.token\.prefix {\(.*\)}], [\1])])]) [m4_bregexp([$3], [%define api\.token\.prefix "\(.*\)"], [\1])])])
m4_pushdef([AT_VARIANT_IF], 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_pushdef([AT_API_prefix],
[m4_bmatch([$3], [%define api\.prefix {.*}], [m4_bmatch([$3], [%define api\.prefix ".*"],
[m4_bregexp([$3], [%define api\.prefix {\([^\}]*\)}], [\1])], [m4_bregexp([$3], [%define api\.prefix "\([^""]*\)"], [\1])],
[yy])]) [yy])])
m4_pushdef([AT_API_PREFIX], m4_pushdef([AT_API_PREFIX],
[m4_toupper(AT_API_prefix)]) [m4_toupper(AT_API_prefix)])
@@ -207,7 +205,7 @@ m4_pushdef([AT_API_PREFIX],
m4_pushdef([AT_YYERROR_ARG_LOC_IF], m4_pushdef([AT_YYERROR_ARG_LOC_IF],
[AT_LOCATION_IF([AT_PURE_IF([m4_bmatch([$3], [AT_LOCATION_IF([AT_PURE_IF([m4_bmatch([$3],
m4_quote(m4_join([\|], m4_quote(m4_join([\|],
[%define api\.pure full], [%define api\.pure "?full"?],
[%glr-parser], [%glr-parser],
[%parse-param], [%parse-param],
[%skeleton "?glr.c"?])), [%skeleton "?glr.c"?])),
@@ -319,25 +317,6 @@ AT_LOC_POPDEF])dnl
## Generating Grammar Files. ## ## 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 # AT_DATA_SOURCE_PROLOGUE
# ------------------------ # ------------------------
# The prologue that should be included in any source code that is # The prologue that should be included in any source code that is
@@ -427,33 +406,24 @@ static
# AT_YYERROR_DEFINE # AT_YYERROR_DEFINE
# ------------------------- # -------------------------
# Must be called inside a AT_BISON_OPTION_PUSHDEFS/POPDEFS pair. # Must be called inside a AT_BISON_OPTION_PUSHDEFS/POPDEFS pair.
m4_define([AT_YYERROR_FORMALS], [AT_LANG_DISPATCH([$0], $@)]) m4_define([AT_YYERROR_FORMALS],
m4_define([AT_YYERROR_PROTOTYPE],[AT_LANG_DISPATCH([$0], $@)]) [m4_case(AT_LANG,
m4_define([AT_YYERROR_DECLARE_EXTERN], [AT_LANG_DISPATCH([$0], $@)]) [c], [AT_YYERROR_ARG_LOC_IF([AT_YYLTYPE const * const llocp, ])AT_PARSE_PARAMS [const char *msg]])[]dnl
m4_define([AT_YYERROR_DECLARE], [AT_LANG_DISPATCH([$0], $@)]) ])
m4_define([AT_YYERROR_DEFINE], [AT_LANG_DISPATCH([$0], $@)])
# AT_MAIN_DEFINE m4_define([AT_YYERROR_PROTOTYPE],
# -------------- [m4_case(AT_LANG,
m4_define([AT_MAIN_DEFINE], [AT_LANG_DISPATCH([$0], $@)]) [c], [[void ]AT_NAME_PREFIX[error (]AT_YYERROR_FORMALS[)]])[]dnl
])
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. ## [c], [#include <stdio.h>
## --- ##
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([[ ]AT_LOCATION_IF([[
#if defined ]AT_YYLTYPE[_IS_TRIVIAL && ]AT_YYLTYPE[_IS_TRIVIAL #if defined ]AT_YYLTYPE[_IS_TRIVIAL && ]AT_YYLTYPE[_IS_TRIVIAL
static unsigned location_print (FILE *yyo, ]AT_YYLTYPE[ const * const yylocp); static unsigned location_print (FILE *yyo, ]AT_YYLTYPE[ const * const yylocp);
@@ -462,11 +432,12 @@ static unsigned location_print (FILE *yyo, ]AT_YYLTYPE[ const * const yylocp);
# endif # endif
#endif #endif
]])[ ]])[
static AT_YYERROR_DECLARE_EXTERN]) static AT_YYERROR_DECLARE_EXTERN])[]dnl
])
m4_define([AT_YYERROR_DEFINE],
m4_define([AT_YYERROR_DEFINE(c)], [m4_case(AT_LANG,
[[ [c], [[
]AT_LOCATION_IF([[ ]AT_LOCATION_IF([[
# if defined ]AT_YYLTYPE[_IS_TRIVIAL && ]AT_YYLTYPE[_IS_TRIVIAL # if defined ]AT_YYLTYPE[_IS_TRIVIAL && ]AT_YYLTYPE[_IS_TRIVIAL
/* Print *YYLOCP on YYO. */ /* Print *YYLOCP on YYO. */
@@ -507,10 +478,34 @@ AT_YYERROR_SEES_LOC_IF([[
LOCATION_PRINT (stderr, ]AT_LOC[); LOCATION_PRINT (stderr, ]AT_LOC[);
fprintf (stderr, ": ");]])[ fprintf (stderr, ": ");]])[
fprintf (stderr, "%s\n", msg); 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
])
m4_define([AT_MAIN_DEFINE(c)], # AT_MAIN_DEFINE
# --------------
m4_define([AT_MAIN_DEFINE],
[m4_case(AT_LANG,
[c],
[[#include <stdlib.h> /* getenv. */ [[#include <stdlib.h> /* getenv. */
#include <string.h> /* strcmp. */ #include <string.h> /* strcmp. */
int int
@@ -523,27 +518,8 @@ main (int argc, char const* argv[])
(void) argc; (void) argc;
(void) argv;]])[ (void) argv;]])[
return ]AT_NAME_PREFIX[parse (); 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 <cstdlib> // getenv.
#include <cstring> // strcmp. #include <cstring> // strcmp.
int int
@@ -557,30 +533,8 @@ main (int argc, char const* argv[])
(void) argc; (void) argc;
(void) argv;]])[ (void) argv;]])[
return p.parse (); 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 [[class input
{ {
public static void main (String args[]) throws IOException public static void main (String args[]) throws IOException
@@ -588,8 +542,7 @@ m4_define([AT_MAIN_DEFINE(java)],
YYParser p = new YYParser (); YYParser p = new YYParser ();
p.parse (); p.parse ();
} }
}]]) }]])])
## --------------- ## ## --------------- ##
@@ -601,7 +554,7 @@ m4_define([AT_MAIN_DEFINE(java)],
# High-level routine that may call bison several times, under different # High-level routine that may call bison several times, under different
# conditions. # 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 # shell constructs (such as redirection or pipes) that would prevent
# appending additional command-line arguments for bison. OTHER_AT_CHECK_ARGS # appending additional command-line arguments for bison. OTHER_AT_CHECK_ARGS
# are the usual remaining arguments to AT_CHECK: STATUS, STDOUT, etc. # are the usual remaining arguments to AT_CHECK: STATUS, STDOUT, etc.
@@ -773,7 +726,6 @@ AT_CHECK(m4_join([ ],
[m4_bmatch([$1], [[.]], [], [$LIBS])]), [m4_bmatch([$1], [[.]], [], [$LIBS])]),
0, [ignore], [ignore])]) 0, [ignore], [ignore])])
# AT_JAVA_COMPILE(SOURCES) # AT_JAVA_COMPILE(SOURCES)
# ------------------------ # ------------------------
# Compile SOURCES into Java class files. Skip the test if java or javac # Compile SOURCES into Java class files. Skip the test if java or javac
@@ -782,10 +734,9 @@ m4_define([AT_JAVA_COMPILE],
[AT_KEYWORDS(java) [AT_KEYWORDS(java)
AT_SKIP_IF([[test -z "$CONF_JAVAC"]]) AT_SKIP_IF([[test -z "$CONF_JAVAC"]])
AT_SKIP_IF([[test -z "$CONF_JAVA"]]) AT_SKIP_IF([[test -z "$CONF_JAVA"]])
AT_CHECK([[$SHELL ../../../javacomp.sh ]$1], AT_CHECK([[$SHELL $abs_top_builddir/javacomp.sh ]$1],
[[0]], [ignore], [ignore])]) [[0]], [ignore], [ignore])])
# AT_LANG_COMPILE(OUTPUT, [SOURCES = OUTPUT.c] # AT_LANG_COMPILE(OUTPUT, [SOURCES = OUTPUT.c]
# -------------------------------------------- # --------------------------------------------
# Compile SOURCES into OUTPUT. Skip if compiler does not work. # Compile SOURCES into OUTPUT. Skip if compiler does not work.
@@ -793,11 +744,13 @@ AT_CHECK([[$SHELL ../../../javacomp.sh ]$1],
# If OUTPUT does not contain '.', assume that we are linking too, # If OUTPUT does not contain '.', assume that we are linking too,
# otherwise pass "-c"; this is a hack. The default SOURCES is OUTPUT # otherwise pass "-c"; this is a hack. The default SOURCES is OUTPUT
# with trailing .o removed, and ".c"/".cc" appended. # with trailing .o removed, and ".c"/".cc" appended.
m4_define([AT_LANG_COMPILE], [AT_LANG_DISPATCH([$0], $@)]) m4_define([AT_LANG_COMPILE],
m4_define([AT_LANG_COMPILE(c)], [AT_COMPILE([$1], [$2])]) [m4_case(AT_LANG,
m4_define([AT_LANG_COMPILE(c++)], [AT_COMPILE_CXX([$1], [$2])]) [c], [AT_COMPILE([$1], [$2])],
m4_define([AT_LANG_COMPILE(java)], [AT_JAVA_COMPILE([$1.java], [$2])]) [c++], [AT_COMPILE_CXX([$1], [$2])],
[java], [AT_JAVA_COMPILE([$1.java], [$2])],
[m4_fatal([unknown language: ]m4_defn([AT_LANG]))])[]dnl
])
# AT_FULL_COMPILE(OUTPUT, [OTHER1], [OTHER2]) # AT_FULL_COMPILE(OUTPUT, [OTHER1], [OTHER2])
# ------------------------------------------- # -------------------------------------------
@@ -806,31 +759,30 @@ m4_define([AT_LANG_COMPILE(java)], [AT_JAVA_COMPILE([$1.java], [$2])])
# OUTPUT-OTHER.c, OUTPUT-OTHER.cc, or OUTPUT-OTHER.java to OUTPUT or # 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 # OUTPUT.java along with it. Relies on AT_SKEL_CC_IF and
# AT_SKEL_JAVA_IF. # AT_SKEL_JAVA_IF.
m4_define([AT_FULL_COMPILE], [AT_LANG_DISPATCH([$0], $@)]) m4_define([AT_FULL_COMPILE],
m4_define([AT_FULL_COMPILE(c)], [m4_case(AT_LANG,
[AT_BISON_CHECK([-o $1.c $1.y]) [java],
AT_LANG_COMPILE([$1], [AT_BISON_CHECK([-o $1.java $1.y])
m4_join([ ], AT_LANG_COMPILE([$1],
[$1.c], m4_join([ ],
m4_ifval($2, [[$1-$2.c]]), [$1.java],
m4_ifval($3, [[$1-$3.c]])))]) m4_ifval($2, [[$1-$2.java]]),
m4_ifval($3, [[$1-$3.java]])))],
m4_define([AT_FULL_COMPILE(c++)], [c++],
[AT_BISON_CHECK([-o $1.cc $1.y]) [AT_BISON_CHECK([-o $1.cc $1.y])
AT_LANG_COMPILE([$1], AT_LANG_COMPILE([$1],
m4_join([ ], m4_join([ ],
[$1.cc], [$1.cc],
m4_ifval($2, [[$1-$2.cc]]), m4_ifval($2, [[$1-$2.cc]]),
m4_ifval($3, [[$1-$3.cc]])))]) m4_ifval($3, [[$1-$3.cc]])))],
[c],
m4_define([AT_FULL_COMPILE(java)], [AT_BISON_CHECK([-o $1.c $1.y])
[AT_BISON_CHECK([-o $1.java $1.y]) AT_LANG_COMPILE([$1],
AT_LANG_COMPILE([$1], m4_join([ ],
m4_join([ ], [$1.c],
[$1.java], m4_ifval($2, [[$1-$2.c]]),
m4_ifval($2, [[$1-$2.java]]), m4_ifval($3, [[$1-$3.c]])))])
m4_ifval($3, [[$1-$3.java]])))]) ])
@@ -878,7 +830,7 @@ AT_PARSER_CHECK([./c-and-cxx])
# AT_PARSER_CHECK(COMMAND, EXIT-STATUS, EXPOUT, EXPERR, [PRE]) # 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: # Get rid of spurious messages when compiled with --coverage:
# +profiling:/[...]/lib/fprintf.gcda:Merge mismatch for summaries # +profiling:/[...]/lib/fprintf.gcda:Merge mismatch for summaries
@@ -892,7 +844,7 @@ AT_CHECK([sed >&2 -e '/^profiling:.*:Merge mismatch for summaries/d' stderr],
# AT_JAVA_PARSER_CHECK(COMMAND, EXIT-STATUS, EXPOUT, EXPERR, [PRE]) # AT_JAVA_PARSER_CHECK(COMMAND, EXIT-STATUS, EXPOUT, EXPERR, [PRE])
# ----------------------------------------------------------------- # -----------------------------------------------------------------
m4_define([AT_JAVA_PARSER_CHECK], m4_define([AT_JAVA_PARSER_CHECK],
[AT_CHECK([$5[ $SHELL ../../../javaexec.sh ]$1], [$2], [$3], [$4])]) [AT_CHECK([$5[ $SHELL $abs_top_builddir/javaexec.sh ]$1], [$2], [$3], [$4])])
# AT_TEST_TABLES_AND_PARSE(TITLE, COND-VALUE, TEST-SPEC, # AT_TEST_TABLES_AND_PARSE(TITLE, COND-VALUE, TEST-SPEC,
@@ -920,16 +872,16 @@ m4_define([AT_JAVA_PARSER_CHECK],
# that Bison exits with value 0, has no stdout, and has stderr # that Bison exits with value 0, has no stdout, and has stderr
# BISON-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 # 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). # 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 # the definition of state 0 is the same as the entire value of
# TABLES-OR-LAST-STATE. # TABLES-OR-LAST-STATE.
# #
# Expand the M4 in OTHER-CHECKS to perform additional checks of the # Expand the M4 in OTHER-CHECKS to perform additional checks of the
# '.output' file, which is named 'input.output', and/or grammar file, # `.output' file, which is named `input.output', and/or grammar file,
# which is named 'input.y'. # which is named `input.y'.
# #
# Finally, compile the generated parser and then run it using # Finally, compile the generated parser and then run it using
# AT_PARSER_CHECK with PARSER-EXIT-VALUE, PARSER-STDOUT, and # AT_PARSER_CHECK with PARSER-EXIT-VALUE, PARSER-STDOUT, and
@@ -1010,7 +962,7 @@ yylex (void)
m4_if(m4_index(m4_quote($3), [no-xml]), -1, m4_if(m4_index(m4_quote($3), [no-xml]), -1,
[AT_BISON_CHECK], [AT_BISON_CHECK],
[AT_BISON_CHECK_NO_XML])([[-Wall --report=all --defines -o input.c input.y]], [AT_BISON_CHECK_NO_XML])([[--report=all --defines -o input.c input.y]],
[0], [], m4_dquote($7)) [0], [], m4_dquote($7))
m4_if(m4_index(m4_quote($3), [last-state]), -1, m4_if(m4_index(m4_quote($3), [last-state]), -1,
@@ -1070,6 +1022,9 @@ m4_define([AT_SETUP],
AT_ARG_OPTION([compile-c-with-cxx], AT_ARG_OPTION([compile-c-with-cxx],
[compile C parsers with the C++ compiler]) [compile C parsers with the C++ compiler])
AT_ARG_OPTION([release],
[check xml and use push for pull])
AT_COLOR_TESTS AT_COLOR_TESTS
AT_TESTED([bison]) AT_TESTED([bison])
+22 -16
View File
@@ -63,8 +63,7 @@ TESTSUITE_AT = \
tests/sets.at \ tests/sets.at \
tests/skeletons.at \ tests/skeletons.at \
tests/synclines.at \ tests/synclines.at \
tests/torture.at \ tests/torture.at
tests/types.at
TESTSUITE = $(top_srcdir)/tests/testsuite TESTSUITE = $(top_srcdir)/tests/testsuite
@@ -81,8 +80,17 @@ $(TESTSUITE): $(TESTSUITE_AT)
## Run the test suite. ## ## Run the test suite. ##
## -------------------- ## ## -------------------- ##
# Move into tests/ so that testsuite.dir etc. be created there. # Move into tests/ so that testsuite.dir etc. be created there. If a suffix is
RUN_TESTSUITE = $(TESTSUITE) -C tests $(TESTSUITEFLAGS) # 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
check_SCRIPTS = $(BISON) tests/atconfig tests/atlocal check_SCRIPTS = $(BISON) tests/atconfig tests/atlocal
RUN_TESTSUITE_deps = $(TESTSUITE) $(check_SCRIPTS) RUN_TESTSUITE_deps = $(TESTSUITE) $(check_SCRIPTS)
@@ -100,28 +108,26 @@ installcheck-local: $(RUN_TESTSUITE_deps)
# Be real mean with it. # Be real mean with it.
.PHONY: maintainer-check-g++ .PHONY: maintainer-check-g++
maintainer-check-g++: $(RUN_TESTSUITE_deps) maintainer-check-g++: $(RUN_TESTSUITE_deps)
$(RUN_TESTSUITE) --compile-c-with-cxx suf=$@ $(RUN_TESTSUITE) --compile-c-with-cxx
.PHONY: maintainer-check-posix .PHONY: maintainer-check-posix
maintainer-check-posix: $(RUN_TESTSUITE_deps) maintainer-check-posix: $(RUN_TESTSUITE_deps)
$(RUN_TESTSUITE) POSIXLY_CORRECT=1 _POSIX2_VERSION=200112 suf=$@ $(RUN_TESTSUITE) POSIXLY_CORRECT=1 _POSIX2_VERSION=200112
.PHONY: maintainer-check-valgrind .PHONY: maintainer-check-valgrind
maintainer-check-valgrind: $(RUN_TESTSUITE_deps) maintainer-check-valgrind: $(RUN_TESTSUITE_deps)
test -z '$(VALGRIND)' || \ test -z '$(VALGRIND)' || \
$(RUN_TESTSUITE) \ suf=$@ $(RUN_TESTSUITE) \
PREBISON='$(VALGRIND_PREBISON)' PREPARSER='$(VALGRIND) -q' \ PREBISON='$(VALGRIND_PREBISON)' PREPARSER='$(VALGRIND) -q' \
VALGRIND_OPTS='--leak-check=full --show-reachable=yes' VALGRIND_OPTS='--leak-check=full --show-reachable=yes'
.PHONY: maintainer-check .PHONY: maintainer-check
maintainer-check: maintainer-check-posix maintainer-check-valgrind maintainer-check-g++ maintainer-check: maintainer-check-posix maintainer-check-valgrind maintainer-check-g++
.PHONY: maintainer-push-check .PHONY: maintainer-release-check
maintainer-push-check: maintainer-release-check:
$(MAKE) $(AM_MAKEFLAGS) maintainer-check \ $(MAKE) $(AM_MAKEFLAGS) \
TESTSUITEFLAGS='BISON_USE_PUSH_FOR_PULL=1 $(TESTSUITEFLAGS)' maintainer-check-g++ \
maintainer-check-posix \
.PHONY: maintainer-xml-check maintainer-check-valgrind \
maintainer-xml-check: TESTSUITEFLAGS+='--release'
$(MAKE) $(AM_MAKEFLAGS) maintainer-check \
TESTSUITEFLAGS='BISON_TEST_XML=1 $(TESTSUITEFLAGS)'
+2 -7
View File
@@ -62,13 +62,8 @@ AT_CHECK_OUTPUT([foo.y], [], [-dv -o foo.c],
[foo.c foo.h foo.output]) [foo.c foo.h foo.output])
AT_CHECK_OUTPUT([foo.y], [], [-dv -o foo.tab.c], AT_CHECK_OUTPUT([foo.y], [], [-dv -o foo.tab.c],
[foo.output foo.tab.c foo.tab.h]) [foo.output foo.tab.c foo.tab.h])
AT_CHECK_OUTPUT([foo.y], [], [-dv -y],
AT_CHECK_OUTPUT([foo.y], [], [-dv -g --xml -y], [y.output y.tab.c y.tab.h])
[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], AT_CHECK_OUTPUT([foo.y], [], [-dv -b bar],
[bar.output bar.tab.c bar.tab.h]) [bar.output bar.tab.c bar.tab.h])
AT_CHECK_OUTPUT([foo.y], [], [-dv -g -o foo.c], AT_CHECK_OUTPUT([foo.y], [], [-dv -g -o foo.c],
+38 -6
View File
@@ -201,6 +201,28 @@ 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, AT_CHECK([[sed -n '/^Grammar/q;/^$/!p' input.output]], 0,
[[Nonterminals useless in grammar [[Nonterminals useless in grammar
@@ -295,6 +317,16 @@ 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, AT_CHECK([[sed -n '/^Grammar/q;/^$/!p' not-reduced.output]], 0,
[[Nonterminals useless in grammar [[Nonterminals useless in grammar
not_reachable not_reachable
@@ -365,9 +397,9 @@ AT_BISON_CHECK([[input.y]], 0, [],
input.y: warning: 3 rules useless in grammar [-Wother] input.y: warning: 3 rules useless in grammar [-Wother]
input.y:5.15-25: warning: nonterminal useless in grammar: underivable [-Wother] input.y:5.15-25: warning: nonterminal useless in grammar: underivable [-Wother]
input.y:6.14-24: warning: nonterminal useless in grammar: indirection [-Wother] input.y:6.14-24: warning: nonterminal useless in grammar: indirection [-Wother]
input.y:5.15-25: warning: rule useless in grammar [-Wother] input.y:5.15-25: warning: rule useless in grammar: exp: underivable [-Wother]
input.y:6.14-24: warning: rule useless in grammar [-Wother] input.y:6.14-24: warning: rule useless in grammar: underivable: indirection [-Wother]
input.y:7.14-24: warning: rule useless in grammar [-Wother] input.y:7.14-24: warning: rule useless in grammar: indirection: underivable [-Wother]
]]) ]])
AT_CHECK([[sed -n '/^Grammar/q;/^$/!p' input.output]], 0, AT_CHECK([[sed -n '/^Grammar/q;/^$/!p' input.output]], 0,
@@ -933,7 +965,7 @@ S: 'a' A 'a'
A: 'a' 'a' B A: 'a' 'a' B
; ;
B: 'a' B: 'a'
| %empty %prec 'a' | %prec 'a'
; ;
c: 'a' 'a' 'b' c: 'a' 'a' 'b'
| A | A
@@ -1533,8 +1565,8 @@ a: 'a' ;
and multiple reductions. The first reduction has more lookaheads than the and multiple reductions. The first reduction has more lookaheads than the
second, so the first should always be preferred as the default reduction if second, so the first should always be preferred as the default reduction if
enabled. The second reduction has one lookahead. */ enabled. The second reduction has one lookahead. */
b: %empty; b: ;
c: %empty; c: ;
]], ]],
dnl Visit each state mentioned above. dnl Visit each state mentioned above.
[['a', 'a']], [['a', 'a']],
+15 -15
View File
@@ -263,11 +263,11 @@ AT_CHECK([cat input.output], [],
0 $accept: expr $end 0 $accept: expr $end
1 $@1: %empty 1 $@1: /* empty */
2 expr: 'a' $@1 'b' 2 expr: 'a' $@1 'b'
3 $@2: %empty 3 $@2: /* empty */
4 expr: $@2 'c' 4 expr: $@2 'c'
@@ -373,13 +373,13 @@ AT_DATA([input.y],
%token <operator> LE 134 "<=" %token <operator> LE 134 "<="
%left OR "<=" %left OR "<="
%% %%
exp: %empty; exp: ;
%% %%
]]) ]])
AT_BISON_CHECK([-v -Wall -o input.c input.y], 0, [], AT_BISON_CHECK([-v -o input.c input.y], 0, [],
[[input.y:3.1-5: warning: useless precedence and associativity for "||" [-Wprecedence] [[input.y:1.29-32: warning: useless associativity for "||" [-Wother]
input.y:3.1-5: warning: useless precedence and associativity for "<=" [-Wprecedence] input.y:2.29-32: warning: useless associativity for "<=" [-Wother]
]]) ]])
AT_CLEANUP AT_CLEANUP
@@ -573,7 +573,7 @@ AT_CHECK([cat input.output], 0,
2 CONST_DEC_LIST: CONST_DEC 2 CONST_DEC_LIST: CONST_DEC
3 | 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 ';' 5 CONST_DEC: $@1 undef_id_tok '=' const_id_tok ';'
@@ -721,7 +721,7 @@ AT_KEYWORDS([report])
AT_DATA([input.y], AT_DATA([input.y],
[[%% [[%%
statement: struct_stat; statement: struct_stat;
struct_stat: %empty | if else; struct_stat: /* empty. */ | if else;
if: "if" "const" "then" statement; if: "if" "const" "then" statement;
else: "else" statement; else: "else" statement;
%% %%
@@ -869,7 +869,7 @@ type: DATA
| INVALID | INVALID
; ;
body: %empty body: /* empty */
| body member | body member
; ;
@@ -929,7 +929,7 @@ $1
%token B %token B
%% %%
program: %empty program: /* empty */
| program e ';' | program e ';'
| program error ';'; | program error ';';
@@ -1145,15 +1145,15 @@ sr_conflict:
]AT_YYLEX_DEFINE([{ 1, 2, 3, 0 }])[ ]AT_YYLEX_DEFINE([{ 1, 2, 3, 0 }])[
]AT_MAIN_DEFINE[ ]AT_MAIN_DEFINE[
]]) ]])
AT_BISON_OPTION_POPDEFS
AT_BISON_CHECK([[-Wall -o input.c input.y]], [[0]],, AT_BISON_CHECK([[-o input.c input.y]], [[0]],,
[[input.y:24.5-19: warning: rule useless in parser due to conflicts [-Wother] [[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 [-Wother] input.y:28.5-19: warning: rule useless in parser due to conflicts: sr_conflict: TK2 "tok alias" [-Wother]
input.y:18.1-5: warning: useless precedence and associativity for TK1 [-Wprecedence] input.y:18.7-9: warning: useless associativity for TK1 [-Wother]
]]) ]])
AT_COMPILE([[input]]) AT_COMPILE([[input]])
AT_PARSER_CHECK([[./input]]) AT_PARSER_CHECK([[./input]])
AT_BISON_OPTION_POPDEFS
AT_CLEANUP AT_CLEANUP
+5 -5
View File
@@ -86,7 +86,7 @@ AT_CHECK([[cat sets]], [],
0 e $end 0 e $end
e derives e derives
1 'e' 1 'e'
2 %empty 2 /* empty */
NULLABLE NULLABLE
$accept: no $accept: no
e: yes e: yes
@@ -100,10 +100,10 @@ FDERIVES
$accept derives $accept derives
0 e $end 0 e $end
1 'e' 1 'e'
2 %empty 2 /* empty */
e derives e derives
1 'e' 1 'e'
2 %empty 2 /* empty */
]]) ]])
AT_CLEANUP AT_CLEANUP
@@ -113,7 +113,7 @@ AT_CLEANUP
## Broken Closure. ## ## 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 # It resulted in bison dumping core on the following grammar (the
# computation of FIRSTS uses TC). It managed to produce a pretty # computation of FIRSTS uses TC). It managed to produce a pretty
# exotic closure: # exotic closure:
@@ -263,7 +263,7 @@ AT_CLEANUP
# In some weird cases Bison could compute an incorrect final state # In some weird cases Bison could compute an incorrect final state
# number. This happens only if the $end token is used in the user # number. This happens only if the $end token is used in the user
# grammar, which is a very suspicious accidental feature introduced as # 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"'. # "end of file"'.
AT_SETUP([Accept]) AT_SETUP([Accept])
+1 -1
View File
@@ -23,7 +23,7 @@ AT_BANNER([[User Actions.]])
# -------------------------- # --------------------------
# Compile FILE expecting an error, and save in the file stdout the # Compile FILE expecting an error, and save in the file stdout the
# normalized output. Ignore the exit status, since some compilers # 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. # errors.
m4_define([AT_SYNCLINES_COMPILE], m4_define([AT_SYNCLINES_COMPILE],
[AT_CHECK([$CC $CFLAGS $CPPFLAGS -c $1], [ignore], [], [stderr]) [AT_CHECK([$CC $CFLAGS $CPPFLAGS -c $1], [ignore], [], [stderr])
+2 -5
View File
@@ -35,9 +35,6 @@ m4_include([sets.at])
# Testing grammar reduction. # Testing grammar reduction.
m4_include([reduce.at]) m4_include([reduce.at])
# Testing conflicts detection and resolution.
m4_include([conflicts.at])
# Testing that #lines are correct. # Testing that #lines are correct.
m4_include([synclines.at]) m4_include([synclines.at])
@@ -47,8 +44,8 @@ m4_include([headers.at])
# Testing that user actions are properly performed. # Testing that user actions are properly performed.
m4_include([actions.at]) m4_include([actions.at])
# Testing semantic types support. # Testing conflicts detection and resolution.
m4_include([types.at]) m4_include([conflicts.at])
# Fulling testing (compilation and execution of the parser) on calc. # Fulling testing (compilation and execution of the parser) on calc.
m4_include([calc.at]) m4_include([calc.at])
-230
View File
@@ -1,230 +0,0 @@
# 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])