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
113 changed files with 3766 additions and 6960 deletions
+1 -10
View File
@@ -1,16 +1,7 @@
*.eps
*.log
*.o
*.pdf
*.png
*.stamp
*.trs
*~
.deps
.dirstamp
/*.cache /*.cache
/*.flc /*.flc
/*.prj /*.prj
/*~
/.tarball-version /.tarball-version
/.version /.version
/ABOUT-NLS /ABOUT-NLS
+1 -1
View File
@@ -1 +1 @@
3.0.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
+61 -424
View File
@@ -1,64 +1,17 @@
GNU Bison NEWS GNU Bison NEWS
* Noteworthy changes in release 3.0.2 (2013-12-05) [stable] * Noteworthy changes in release ?.? (????-??-??) [?]
** Bug fixes
*** Generated source files when errors are reported
When warnings are issued and -Werror is set, bison would still generate
the source files (*.c, *.h...). As a consequence, some runs of "make"
could fail the first time, but not the second (as the files were generated
anyway).
This is fixed: bison no longer generates this source files, but, of
course, still produces the various reports (*.output, *.xml, etc.).
*** %empty is used in reports
Empty right-hand sides are denoted by '%empty' in all the reports (text,
dot, XML and formats derived from it).
*** YYERROR and variants
When C++ variant support is enabled, an error triggered via YYERROR, but
not caught via error recovery, resulted in a double deletion.
* Noteworthy changes in release 3.0.1 (2013-11-12) [stable]
** Bug fixes
*** Errors in caret diagnostics
On some platforms, some errors could result in endless diagnostics.
*** Fixes of the -Werror option
Options such as "-Werror -Wno-error=foo" were still turning "foo"
diagnostics into errors instead of warnings. This is fixed.
Actually, for consistency with GCC, "-Wno-error=foo -Werror" now also
leaves "foo" diagnostics as warnings. Similarly, with "-Werror=foo
-Wno-error", "foo" diagnostics are now errors.
*** GLR Predicates
As demonstrated in the documentation, one can now leave spaces between
"%?" and its "{".
*** Installation
The yacc.1 man page is no longer installed if --disable-yacc was
specified.
*** Fixes in the test suite
Bugs and portability issues.
* Noteworthy changes in release 3.0 (2013-07-25) [stable]
** WARNING: Future backward-incompatibilities! ** 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.
@@ -75,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
@@ -109,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)
@@ -117,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
@@ -130,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
@@ -293,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
@@ -313,271 +220,13 @@ 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.
The constants for token names were moved to the Lexer interface. Also, it The constants for token names were moved to the Lexer interface. Also, it
is possible to add code to the parser's constructors using "%code init" is possible to add code to the parser's constructors using "%code init"
and "%define init_throws". and "%define init_throws".
Contributed by Paolo Bonzini.
The Java skeleton now supports push parsing.
Contributed by Dennis Heimbigner.
** C++ skeletons improvements ** C++ skeletons improvements
@@ -600,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]
@@ -711,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).
@@ -799,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.
@@ -2715,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
-9
View File
@@ -62,22 +62,13 @@ tools we depend upon, including:
- Gettext <http://www.gnu.org/software/gettext/> - Gettext <http://www.gnu.org/software/gettext/>
- Graphviz <http://www.graphviz.org> - Graphviz <http://www.graphviz.org>
- Gzip <http://www.gnu.org/software/gzip/> - Gzip <http://www.gnu.org/software/gzip/>
- Help2man <http://www.gnu.org/software/help2man/>
- Perl <http://www.cpan.org/> - Perl <http://www.cpan.org/>
- Rsync <http://samba.anu.edu.au/rsync/> - Rsync <http://samba.anu.edu.au/rsync/>
- Tar <http://www.gnu.org/software/tar/> - Tar <http://www.gnu.org/software/tar/>
- Texinfo <http://www.gnu.org/software/texinfo/>
Valgrind <http://valgrind.org/> is also highly recommended, if it supports Valgrind <http://valgrind.org/> is also highly recommended, if it supports
your architecture. your architecture.
If you're using a GNU/Linux distribution, the easiest way to install the
above packages depends on your system. The following shell command should
work for Debian-based systems such as Ubuntu:
sudo apt-get install \
autoconf automake autopoint flex graphviz help2man texinfo valgrind
Bison is written using Bison grammars, so there are bootstrapping issues. Bison is written using Bison grammars, so there are bootstrapping issues.
The bootstrap script attempts to discover when the C code generated from the The bootstrap script attempts to discover when the C code generated from the
grammars is out of date, and to bootstrap with an out-of-date version of the grammars is out of date, and to bootstrap with an out-of-date version of the
+1 -1
View File
@@ -9,7 +9,7 @@ Bison supports the @N construction, which gives you access to
the starting and ending line number and character number associated 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.
-12
View File
@@ -25,13 +25,10 @@ Bruce Lilly [email protected]
Bruno Haible [email protected] Bruno Haible [email protected]
Charles-Henri de Boysson [email protected] Charles-Henri de Boysson [email protected]
Christian Burger [email protected] Christian Burger [email protected]
Colin Daley [email protected]
Cris Bailiff [email protected] 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 Galloway [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]
@@ -40,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]
@@ -48,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]
@@ -66,7 +61,6 @@ Johan van Selst [email protected]
Jonathan Fabrizio [email protected] Jonathan Fabrizio [email protected]
Jonathan Nieder [email protected] Jonathan Nieder [email protected]
Juan Manuel Guerrero [email protected] Juan Manuel Guerrero [email protected]
Ken Moffat [email protected]
Kees Zeelenberg [email protected] Kees Zeelenberg [email protected]
Keith Browne [email protected] Keith Browne [email protected]
Laurent Mascherpa [email protected] Laurent Mascherpa [email protected]
@@ -80,7 +74,6 @@ Martin Mokrejs [email protected]
Martin Nylin [email protected] Martin Nylin [email protected]
Matt Kraai [email protected] Matt Kraai [email protected]
Matt Rosing [email protected] Matt Rosing [email protected]
Michael Felt [email protected]
Michael Hayes [email protected] Michael Hayes [email protected]
Michael Raskin [email protected] Michael Raskin [email protected]
Michiel De Wilde [email protected] Michiel De Wilde [email protected]
@@ -96,7 +89,6 @@ Odd Arild Olsen [email protected]
Oleg Smolsky [email protected] Oleg Smolsky [email protected]
Oleksii Taran [email protected] Oleksii Taran [email protected]
Paolo Bonzini [email protected] Paolo Bonzini [email protected]
Paolo Simone Gasparello [email protected]
Pascal Bart [email protected] Pascal Bart [email protected]
Paul Eggert [email protected] Paul Eggert [email protected]
Paul Hilfinger [email protected] Paul Hilfinger [email protected]
@@ -105,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]
@@ -113,10 +104,8 @@ R Blake [email protected]
Raja R Harinath [email protected] Raja R Harinath [email protected]
Ralf Wildenhues [email protected] Ralf Wildenhues [email protected]
Richard Stallman [email protected] Richard Stallman [email protected]
Rici Lake [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]
@@ -137,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?
+66 -80
View File
@@ -1,6 +1,6 @@
#! /bin/sh #! /bin/sh
# Print a version string. # Print a version string.
scriptversion=2013-08-15.22; # 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
} }
' '
@@ -209,16 +208,12 @@ bootstrap_sync=false
# Use git to update gnulib sources # Use git to update gnulib sources
use_git=true use_git=true
check_exists() {
($1 --version </dev/null) >/dev/null 2>&1
test $? -lt 126
}
# find_tool ENVVAR NAMES... # find_tool ENVVAR NAMES...
# ------------------------- # -------------------------
# Search for a required program. Use the value of ENVVAR, if set, # Search for a required program. Use the value of ENVVAR, if set,
# otherwise find the first of the NAMES that can be run. # otherwise find the first of the NAMES that can be run (i.e.,
# If found, set ENVVAR to the program name, die otherwise. # supports --version). If found, set ENVVAR to the program name,
# die otherwise.
# #
# FIXME: code duplication, see also gnu-web-doc-update. # FIXME: code duplication, see also gnu-web-doc-update.
find_tool () find_tool ()
@@ -228,21 +223,27 @@ find_tool ()
find_tool_names=$@ find_tool_names=$@
eval "find_tool_res=\$$find_tool_envvar" eval "find_tool_res=\$$find_tool_envvar"
if test x"$find_tool_res" = x; then if test x"$find_tool_res" = x; then
for i; do for i
if check_exists $i; then do
find_tool_res=$i if ($i --version </dev/null) >/dev/null 2>&1; then
break find_tool_res=$i
break
fi fi
done done
else
find_tool_error_prefix="\$$find_tool_envvar: "
fi fi
if test x"$find_tool_res" = x; then test x"$find_tool_res" != x \
warn_ "one of these is required: $find_tool_names;" || die "one of these is required: $find_tool_names"
die "alternatively set $find_tool_envvar to a compatible tool" ($find_tool_res --version </dev/null) >/dev/null 2>&1 \
fi || die "${find_tool_error_prefix}cannot run $find_tool_res --version"
eval "$find_tool_envvar=\$find_tool_res" eval "$find_tool_envvar=\$find_tool_res"
eval "export $find_tool_envvar" eval "export $find_tool_envvar"
} }
# Find sha1sum, named gsha1sum on MacPorts, and shasum on Mac OS X 10.6.
find_tool SHA1SUM sha1sum gsha1sum shasum
# Override the default configuration, if necessary. # Override the default configuration, if necessary.
# Make sure that bootstrap.conf is sourced from the current directory # Make sure that bootstrap.conf is sourced from the current directory
# if we were invoked as "sh bootstrap". # if we were invoked as "sh bootstrap".
@@ -254,12 +255,12 @@ esac
# Extra files from gnulib, which override files from other sources. # Extra files from gnulib, which override files from other sources.
test -z "${gnulib_extra_files}" && \ test -z "${gnulib_extra_files}" && \
gnulib_extra_files=" gnulib_extra_files="
build-aux/install-sh $build_aux/install-sh
build-aux/mdate-sh $build_aux/mdate-sh
build-aux/texinfo.tex $build_aux/texinfo.tex
build-aux/depcomp $build_aux/depcomp
build-aux/config.guess $build_aux/config.guess
build-aux/config.sub $build_aux/config.sub
doc/INSTALL doc/INSTALL
" "
@@ -305,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"; cat $file; } | gitignore_entries | sort -u | wc -l)
if [ $linesold != $linesnew ] ; then
{ echo "$str" | cat - $file > $file.bak && mv $file.bak $file; } \
|| die "insert_if_absent $file $str: failed"
fi
} }
# Adjust $PATTERN for $VC_IGNORE_FILE and insert it with # 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"
@@ -343,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.
@@ -467,7 +468,8 @@ check_versions() {
if [ "$req_ver" = "-" ]; then if [ "$req_ver" = "-" ]; then
# Merely require app to exist; not all prereq apps are well-behaved # Merely require app to exist; not all prereq apps are well-behaved
# so we have to rely on $? rather than get_version. # so we have to rely on $? rather than get_version.
if ! check_exists $app; then $app --version >/dev/null 2>&1
if [ 126 -le $? ]; then
warn_ "Error: '$app' not found" warn_ "Error: '$app' not found"
ret=1 ret=1
fi fi
@@ -500,12 +502,6 @@ print_versions() {
# can't depend on column -t # can't depend on column -t
} }
# Find sha1sum, named gsha1sum on MacPorts, shasum on Mac OS X 10.6.
# Also find the compatible sha1 utility on the BSDs
if test x"$SKIP_PO" = x; then
find_tool SHA1SUM sha1sum gsha1sum shasum sha1
fi
use_libtool=0 use_libtool=0
# We'd like to use grep -E, to see if any of LT_INIT, # We'd like to use grep -E, to see if any of LT_INIT,
# AC_PROG_LIBTOOL, AM_PROG_LIBTOOL is used in configure.ac, # AC_PROG_LIBTOOL, AM_PROG_LIBTOOL is used in configure.ac,
@@ -554,10 +550,10 @@ fi
echo "$0: Bootstrapping from checked-out $package sources..." echo "$0: Bootstrapping from checked-out $package sources..."
# See if we can use gnulib's git-merge-changelog merge driver. # See if we can use gnulib's git-merge-changelog merge driver.
if $use_git && test -d .git && check_exists git; then if test -d .git && (git --version) >/dev/null 2>/dev/null ; then
if git config merge.merge-changelog.driver >/dev/null ; then if git config merge.merge-changelog.driver >/dev/null ; then
: :
elif check_exists git-merge-changelog; then elif (git-merge-changelog --version) >/dev/null 2>/dev/null ; then
echo "$0: initializing git-merge-changelog driver" echo "$0: initializing git-merge-changelog driver"
git config merge.merge-changelog.name 'GNU-style ChangeLog merge driver' git config merge.merge-changelog.name 'GNU-style ChangeLog merge driver'
git config merge.merge-changelog.driver 'git-merge-changelog %O %A %B' git config merge.merge-changelog.driver 'git-merge-changelog %O %A %B'
@@ -577,17 +573,13 @@ git_modules_config () {
test -f .gitmodules && git config --file .gitmodules "$@" test -f .gitmodules && git config --file .gitmodules "$@"
} }
if $use_git; then gnulib_path=$(git_modules_config submodule.gnulib.path)
gnulib_path=$(git_modules_config submodule.gnulib.path) test -z "$gnulib_path" && gnulib_path=gnulib
test -z "$gnulib_path" && gnulib_path=gnulib
fi
# Get gnulib files. Populate $GNULIB_SRCDIR, possibly updating a # Get gnulib files.
# submodule, for use in the rest of the script.
case ${GNULIB_SRCDIR--} in case ${GNULIB_SRCDIR--} in
-) -)
# Note that $use_git is necessarily true in this case.
if git_modules_config submodule.gnulib.url >/dev/null; then if git_modules_config submodule.gnulib.url >/dev/null; then
echo "$0: getting gnulib files..." echo "$0: getting gnulib files..."
git submodule init || exit $? git submodule init || exit $?
@@ -608,8 +600,8 @@ case ${GNULIB_SRCDIR--} in
GNULIB_SRCDIR=$gnulib_path GNULIB_SRCDIR=$gnulib_path
;; ;;
*) *)
# Use GNULIB_SRCDIR directly or as a reference. # Use GNULIB_SRCDIR as a reference.
if $use_git && test -d "$GNULIB_SRCDIR"/.git && \ if test -d "$GNULIB_SRCDIR"/.git && \
git_modules_config submodule.gnulib.url >/dev/null; then git_modules_config submodule.gnulib.url >/dev/null; then
echo "$0: getting gnulib files..." echo "$0: getting gnulib files..."
if git submodule -h|grep -- --reference > /dev/null; then if git submodule -h|grep -- --reference > /dev/null; then
@@ -635,19 +627,12 @@ case ${GNULIB_SRCDIR--} in
;; ;;
esac esac
# $GNULIB_SRCDIR now points to the version of gnulib to use, and
# we no longer need to use git or $gnulib_path below here.
if $bootstrap_sync; then 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
@@ -695,10 +680,11 @@ update_po_files() {
cksum_file="$ref_po_dir/$po.s1" cksum_file="$ref_po_dir/$po.s1"
if ! test -f "$cksum_file" || if ! test -f "$cksum_file" ||
! test -f "$po_dir/$po.po" || ! test -f "$po_dir/$po.po" ||
! $SHA1SUM -c "$cksum_file" < "$new_po" > /dev/null 2>&1; then ! $SHA1SUM -c --status "$cksum_file" \
< "$new_po" > /dev/null; then
echo "$me: updated $po_dir/$po.po..." echo "$me: updated $po_dir/$po.po..."
cp "$new_po" "$po_dir/$po.po" \ cp "$new_po" "$po_dir/$po.po" \
&& $SHA1SUM < "$new_po" > "$cksum_file" || return && $SHA1SUM < "$new_po" > "$cksum_file"
fi fi
done done
} }
+1 -2
View File
@@ -34,8 +34,7 @@ gnulib_modules='
readme-release readme-release
realloc-posix realloc-posix
spawn-pipe stdbool stpcpy strdup-posix strerror strtoul strverscmp spawn-pipe stdbool stpcpy strdup-posix strerror strtoul strverscmp
unistd unistd-safer unlink unlocked-io unistd unistd-safer unlocked-io update-copyright unsetenv verify
update-copyright unsetenv verify
warnings warnings
xalloc xalloc
xalloc-die xalloc-die
-16
View File
@@ -1,16 +0,0 @@
# Linux seattle 2.6.32-5-amd64 #1 SMP Thu Mar 22 17:26:33 UTC 2012
# x86_64 GNU/Linux
{
index
Memcheck:Cond
fun:index
fun:expand_dynamic_string_token
fun:_dl_map_object
fun:map_doit
fun:_dl_catch_error
fun:do_preload
fun:dl_main
fun:_dl_sysdep_start
fun:_dl_start
obj:/lib/ld-2.11.3.so
}
+2 -1
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
@@ -16,7 +18,6 @@
EXTRA_DIST += \ EXTRA_DIST += \
build-aux/cross-options.pl \ build-aux/cross-options.pl \
build-aux/darwin11.4.0.valgrind \ build-aux/darwin11.4.0.valgrind \
build-aux/linux-gnu.valgrind \
build-aux/move-if-change \ build-aux/move-if-change \
build-aux/prev-version.txt \ build-aux/prev-version.txt \
build-aux/update-b4-copyright build-aux/update-b4-copyright
+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$$) \
) )
+26 -26
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]])
@@ -33,7 +33,11 @@ AC_DEFINE_UNQUOTED([PACKAGE_COPYRIGHT_YEAR], [$PACKAGE_COPYRIGHT_YEAR],
AC_CONFIG_AUX_DIR([build-aux]) AC_CONFIG_AUX_DIR([build-aux])
AC_CONFIG_MACRO_DIR([m4]) AC_CONFIG_MACRO_DIR([m4])
# We use Automake 1.14's %D% and %C%. # Automake 1.10.3 and 1.11.1 fix a security flaw discussed here:
#
# http://thread.gmane.org/gmane.comp.sysutils.autotools.announce/131
#
# To avoid 1.11, we make 1.11.1 the minimum version.
# #
# We want gnits strictness only when rolling a stable release. For # We want gnits strictness only when rolling a stable release. For
# release candidates, we use version strings like 2.4.3_rc1, but gnits # release candidates, we use version strings like 2.4.3_rc1, but gnits
@@ -41,7 +45,7 @@ AC_CONFIG_MACRO_DIR([m4])
# releases, we want to be able run make dist without being required to # releases, we want to be able run make dist without being required to
# add a bogus NEWS entry. In that case, the version string # add a bogus NEWS entry. In that case, the version string
# automatically contains a dash, which we also let disable gnits. # automatically contains a dash, which we also let disable gnits.
AM_INIT_AUTOMAKE([1.14 dist-xz nostdinc AM_INIT_AUTOMAKE([1.11.1 dist-xz nostdinc
color-tests parallel-tests color-tests parallel-tests
silent-rules] silent-rules]
m4_bmatch(m4_defn([AC_PACKAGE_VERSION]), [[-_]], m4_bmatch(m4_defn([AC_PACKAGE_VERSION]), [[-_]],
@@ -78,7 +82,7 @@ AC_ARG_ENABLE([gcc-warnings],
esac], esac],
[enable_gcc_warnings=no]) [enable_gcc_warnings=no])
if test "$enable_gcc_warnings" = yes; then if test "$enable_gcc_warnings" = yes; then
warn_common='-Wall-Wextra -Wno-sign-compare -Wcast-align -Wdocumentation warn_common='-Wall -Wextra -Wno-sign-compare -Wcast-align
-Wformat -Wpointer-arith -Wwrite-strings' -Wformat -Wpointer-arith -Wwrite-strings'
warn_c='-Wbad-function-cast -Wshadow -Wstrict-prototypes' warn_c='-Wbad-function-cast -Wshadow -Wstrict-prototypes'
warn_cxx='-Wnoexcept' warn_cxx='-Wnoexcept'
@@ -87,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
@@ -139,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
@@ -157,17 +159,21 @@ AC_ARG_ENABLE([yacc],
[AC_HELP_STRING([--disable-yacc], [AC_HELP_STRING([--disable-yacc],
[do not build a yacc command or an -ly library])], [do not build a yacc command or an -ly library])],
, [enable_yacc=yes]) , [enable_yacc=yes])
AM_CONDITIONAL([ENABLE_YACC], [test "$enable_yacc" = yes]) case $enable_yacc in
yes)
YACC_SCRIPT=src/yacc
YACC_LIBRARY=lib/liby.a;;
*)
YACC_SCRIPT=
YACC_LIBRARY=;;
esac
AC_SUBST([YACC_SCRIPT])
AC_SUBST([YACC_LIBRARY])
# Checks for programs. # Checks for programs.
AM_MISSING_PROG([DOT], [dot]) AM_MISSING_PROG([DOT], [dot])
AC_PROG_LEX AC_PROG_LEX
$LEX_IS_FLEX || test "X$LEX" = X: || { $LEX_IS_FLEX || AC_MSG_ERROR([Flex is required])
AC_MSG_WARN([bypassing lex because flex is required])
LEX=:
}
AM_CONDITIONAL([FLEX_CXX_WORKS],
[$LEX_IS_FLEX && test $bison_cv_cxx_works = yes])
AC_PROG_YACC AC_PROG_YACC
AC_PROG_RANLIB AC_PROG_RANLIB
AC_PROG_GNU_M4 AC_PROG_GNU_M4
@@ -214,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])
@@ -222,16 +228,10 @@ case $VALGRIND:$host_os in
'':*) ;; '':*) ;;
*:darwin*) *:darwin*)
# See README-hacking. # See README-hacking.
# VALGRIND+='-q --suppressions=$(abs_top_srcdir)/build-aux/darwin11.4.0.valgrind' # VALGRIND+=' --suppressions=$(abs_top_srcdir)/build-aux/darwin11.4.0.valgrind'
VALGRIND=;; VALGRIND=;;
*:*) *:*)
suppfile=build-aux/$host_os.valgrind AC_SUBST([VALGRIND_PREBISON], ["$VALGRIND -q"]);;
if test -f "$srcdir/$suppfile"; then
VALGRIND="$VALGRIND --gen-suppressions=all"
VALGRIND="$VALGRIND --suppressions=\$(abs_top_srcdir)/$suppfile"
fi
AC_SUBST([VALGRIND_PREBISON], ["$VALGRIND -q"])
;;
esac esac
AM_MISSING_PROG([AUTOM4TE], [autom4te]) AM_MISSING_PROG([AUTOM4TE], [autom4te])
+1 -1
View File
@@ -27,7 +27,7 @@ Currently, the supported skeletons are:
These skeletons are the only ones supported by the Bison team. 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]))])])
+34 -215
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,69 +199,6 @@ m4_define([b4_table_value_equals],
[(!!(($2) == ($3)))])]) [(!!(($2) == ($3)))])])
## ----------------- ##
## Compiler issues. ##
## ----------------- ##
# b4_attribute_define
# -------------------
# Provide portable compiler "attributes".
m4_define([b4_attribute_define],
[#ifndef YY_ATTRIBUTE
# if (defined __GNUC__ \
&& (2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__))) \
|| defined __SUNPRO_C && 0x5110 <= __SUNPRO_C
# define YY_ATTRIBUTE(Spec) __attribute__(Spec)
# else
# define YY_ATTRIBUTE(Spec) /* empty */
# endif
#endif
#ifndef YY_ATTRIBUTE_PURE
# define YY_ATTRIBUTE_PURE YY_ATTRIBUTE ((__pure__))
#endif
#ifndef YY_ATTRIBUTE_UNUSED
# define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__))
#endif
#if !defined _Noreturn \
&& (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112)
# if defined _MSC_VER && 1200 <= _MSC_VER
# define _Noreturn __declspec (noreturn)
# else
# define _Noreturn YY_ATTRIBUTE ((__noreturn__))
# endif
#endif
/* Suppress unused-variable warnings by "using" E. */
#if ! defined lint || defined __GNUC__
# define YYUSE(E) ((void) (E))
#else
# define YYUSE(E) /* empty */
#endif
#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__
/* Suppress an incorrect diagnostic about yylval being uninitialized. */
# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
_Pragma ("GCC diagnostic push") \
_Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\
_Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"")
# define YY_IGNORE_MAYBE_UNINITIALIZED_END \
_Pragma ("GCC diagnostic pop")
#else
# define YY_INITIAL_VALUE(Value) Value
#endif
#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
# define YY_IGNORE_MAYBE_UNINITIALIZED_END
#endif
#ifndef YY_INITIAL_VALUE
# define YY_INITIAL_VALUE(Value) /* Nothing. */
#endif
])
## ---------## ## ---------##
## Values. ## ## Values. ##
## ---------## ## ---------##
@@ -269,14 +206,14 @@ m4_define([b4_attribute_define],
# b4_null_define # b4_null_define
# -------------- # --------------
# Portability issues: define a YY_NULLPTR appropriate for the current # Portability issues: define a YY_NULL appropriate for the current
# language (C, C++98, or C++11). # language (C, C++98, or C++11).
m4_define([b4_null_define], m4_define([b4_null_define],
[# ifndef YY_NULLPTR [# ifndef YY_NULL
# if defined __cplusplus && 201103L <= __cplusplus # if defined __cplusplus && 201103L <= __cplusplus
# define YY_NULLPTR nullptr # define YY_NULL nullptr
# else # else
# define YY_NULLPTR 0 # define YY_NULL 0
# endif # endif
# endif[]dnl # endif[]dnl
]) ])
@@ -285,7 +222,7 @@ m4_define([b4_null_define],
# b4_null # b4_null
# ------- # -------
# Return a null pointer constant. # Return a null pointer constant.
m4_define([b4_null], [YY_NULLPTR]) m4_define([b4_null], [YY_NULL])
# b4_integral_parser_table_define(TABLE-NAME, CONTENT, COMMENT) # b4_integral_parser_table_define(TABLE-NAME, CONTENT, COMMENT)
# ------------------------------------------------------------- # -------------------------------------------------------------
@@ -484,9 +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);
YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN switch (yytype)
]b4_symbol_actions([destructor])[ {
YY_IGNORE_MAYBE_UNINITIALIZED_END ]b4_symbol_foreach([b4_symbol_destructor])dnl
[ default:
break;
}
}]dnl }]dnl
]) ])
@@ -496,9 +436,9 @@ m4_ifset([b4_parse_param], [, b4_parse_param]))[
# Define the "yy_symbol_print" function. # Define the "yy_symbol_print" function.
m4_define_default([b4_yy_symbol_print_define], m4_define_default([b4_yy_symbol_print_define],
[[ [[
/*----------------------------------------. /*--------------------------------.
| Print this symbol's value on YYOUTPUT. | | Print this symbol on YYOUTPUT. |
`----------------------------------------*/ `--------------------------------*/
]b4_function_define([yy_symbol_value_print], ]b4_function_define([yy_symbol_value_print],
[static void], [static void],
@@ -519,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;
}
} }
@@ -547,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
@@ -730,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],
@@ -802,7 +621,7 @@ m4_define([b4_yy_location_print_define],
/* Print *YYLOCP on YYO. Private, do not rely on its existence. */ /* Print *YYLOCP on YYO. Private, do not rely on its existence. */
YY_ATTRIBUTE_UNUSED __attribute__((__unused__))
]b4_function_define([yy_location_print_], ]b4_function_define([yy_location_print_],
[static unsigned], [static unsigned],
[[FILE *yyo], [yyo]], [[FILE *yyo], [yyo]],
+97 -82
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)))
@@ -445,9 +462,9 @@ int yydebug;
struct yyGLRStack; struct yyGLRStack;
static void yypstack (struct yyGLRStack* yystackp, size_t yyk) static void yypstack (struct yyGLRStack* yystackp, size_t yyk)
YY_ATTRIBUTE_UNUSED; __attribute__ ((__unused__));
static void yypdumpstack (struct yyGLRStack* yystackp) static void yypdumpstack (struct yyGLRStack* yystackp)
YY_ATTRIBUTE_UNUSED; __attribute__ ((__unused__));
#else /* !]b4_api_PREFIX[DEBUG */ #else /* !]b4_api_PREFIX[DEBUG */
@@ -669,15 +686,19 @@ struct yyGLRStack {
static void yyexpandGLRStack (yyGLRStack* yystackp); static void yyexpandGLRStack (yyGLRStack* yystackp);
#endif #endif
static _Noreturn void static void yyFail (yyGLRStack* yystackp]b4_pure_formals[, const char* yymsg)
__attribute__ ((__noreturn__));
static void
yyFail (yyGLRStack* yystackp]b4_pure_formals[, const char* yymsg) yyFail (yyGLRStack* yystackp]b4_pure_formals[, const char* yymsg)
{ {
if (yymsg != YY_NULLPTR) if (yymsg != YY_NULL)
yyerror (]b4_yyerror_args[yymsg); yyerror (]b4_yyerror_args[yymsg);
YYLONGJMP (yystackp->yyexception_buffer, 1); YYLONGJMP (yystackp->yyexception_buffer, 1);
} }
static _Noreturn void static void yyMemoryExhausted (yyGLRStack* yystackp)
__attribute__ ((__noreturn__));
static void
yyMemoryExhausted (yyGLRStack* yystackp) yyMemoryExhausted (yyGLRStack* yystackp)
{ {
YYLONGJMP (yystackp->yyexception_buffer, 2); YYLONGJMP (yystackp->yyexception_buffer, 2);
@@ -698,7 +719,7 @@ yytokenName (yySymbol yytoken)
/** Fill in YYVSP[YYLOW1 .. YYLOW0-1] from the chain of states starting /** Fill in YYVSP[YYLOW1 .. YYLOW0-1] from the chain of states starting
* at YYVSP[YYLOW0].yystate.yypred. Leaves YYVSP[YYLOW1].yystate.yypred * at YYVSP[YYLOW0].yystate.yypred. Leaves YYVSP[YYLOW1].yystate.yypred
* containing the pointer to the next state in the chain. */ * containing the pointer to the next state in the chain. */
static void yyfillin (yyGLRStackItem *, int, int) YY_ATTRIBUTE_UNUSED; static void yyfillin (yyGLRStackItem *, int, int) __attribute__ ((__unused__));
static void static void
yyfillin (yyGLRStackItem *yyvsp, int yylow0, int yylow1) yyfillin (yyGLRStackItem *yyvsp, int yylow0, int yylow1)
{ {
@@ -715,7 +736,7 @@ yyfillin (yyGLRStackItem *yyvsp, int yylow0, int yylow1)
else else
/* The effect of using yysval or yyloc (in an immediate rule) is /* The effect of using yysval or yyloc (in an immediate rule) is
* undefined. */ * undefined. */
yyvsp[i].yystate.yysemantics.yyfirstVal = YY_NULLPTR;]b4_locations_if([[ yyvsp[i].yystate.yysemantics.yyfirstVal = YY_NULL;]b4_locations_if([[
yyvsp[i].yystate.yyloc = s->yyloc;]])[ yyvsp[i].yystate.yyloc = s->yyloc;]])[
s = yyvsp[i].yystate.yypred = s->yypred; s = yyvsp[i].yystate.yypred = s->yypred;
} }
@@ -725,7 +746,7 @@ yyfillin (yyGLRStackItem *yyvsp, int yylow0, int yylow1)
* YYVSP[YYLOW1 .. *YYLOW-1] as in yyfillin and set *YYLOW = YYLOW1. * YYVSP[YYLOW1 .. *YYLOW-1] as in yyfillin and set *YYLOW = YYLOW1.
* For convenience, always return YYLOW1. */ * For convenience, always return YYLOW1. */
static inline int yyfill (yyGLRStackItem *, int *, int, yybool) static inline int yyfill (yyGLRStackItem *, int *, int, yybool)
YY_ATTRIBUTE_UNUSED; __attribute__ ((__unused__));
static inline int static inline int
yyfill (yyGLRStackItem *yyvsp, int *yylow, int yylow1, yybool yynormal) yyfill (yyGLRStackItem *yyvsp, int *yylow, int yylow1, yybool yynormal)
{ {
@@ -747,7 +768,8 @@ yyuserAction (yyRuleNum yyn, size_t yyrhslen, yyGLRStackItem* yyvsp,
yyGLRStack* yystackp, yyGLRStack* yystackp,
YYSTYPE* yyvalp]b4_locuser_formals[) YYSTYPE* yyvalp]b4_locuser_formals[)
{ {
yybool yynormal YY_ATTRIBUTE_UNUSED = (yystackp->yysplitPoint == YY_NULLPTR); yybool yynormal __attribute__ ((__unused__)) =
(yystackp->yysplitPoint == YY_NULL);
int yylow; int yylow;
]b4_parse_param_use([yyvalp], [yylocp])dnl ]b4_parse_param_use([yyvalp], [yylocp])dnl
[ YYUSE (yyrhslen); [ YYUSE (yyrhslen);
@@ -831,10 +853,12 @@ yydestroyGLRState (char const *yymsg, yyGLRState *yys]b4_user_formals[)
if (yydebug) if (yydebug)
{ {
if (yys->yysemantics.yyfirstVal) if (yys->yysemantics.yyfirstVal)
YYFPRINTF (stderr, "%s unresolved", yymsg); YYFPRINTF (stderr, "%s unresolved ", yymsg);
else else
YYFPRINTF (stderr, "%s incomplete", yymsg); YYFPRINTF (stderr, "%s incomplete ", yymsg);
YY_SYMBOL_PRINT ("", yystos[yys->yylrState], YY_NULLPTR, &yys->yyloc); yy_symbol_print (stderr, yystos[yys->yylrState],
YY_NULL]b4_locuser_args([&yys->yyloc])[);
YYFPRINTF (stderr, "\n");
} }
#endif #endif
@@ -910,18 +934,14 @@ yygetLRActions (yyStateNum yystate, int yytoken,
} }
} }
/** Compute post-reduction state.
* \param yystate the current state
* \param yysym the nonterminal to push on the stack
*/
static inline yyStateNum static inline yyStateNum
yyLRgotoState (yyStateNum yystate, yySymbol yysym) yyLRgotoState (yyStateNum yystate, yySymbol yylhs)
{ {
int yyr = yypgoto[yysym - YYNTOKENS] + yystate; int yyr = yypgoto[yylhs - YYNTOKENS] + yystate;
if (0 <= yyr && yyr <= YYLAST && yycheck[yyr] == yystate) if (0 <= yyr && yyr <= YYLAST && yycheck[yyr] == yystate)
return yytable[yyr]; return yytable[yyr];
else else
return yydefgoto[yysym - YYNTOKENS]; return yydefgoto[yylhs - YYNTOKENS];
} }
static inline yybool static inline yybool
@@ -963,7 +983,6 @@ yyaddDeferredAction (yyGLRStack* yystackp, size_t yyk, yyGLRState* yystate,
{ {
yySemanticOption* yynewOption = yySemanticOption* yynewOption =
&yynewGLRStackItem (yystackp, yyfalse)->yyoption; &yynewGLRStackItem (yystackp, yyfalse)->yyoption;
YYASSERT (!yynewOption->yyisState);
yynewOption->yystate = yyrhs; yynewOption->yystate = yyrhs;
yynewOption->yyrule = yyrule; yynewOption->yyrule = yyrule;
if (yystackp->yytops.yylookaheadNeeds[yyk]) if (yystackp->yytops.yylookaheadNeeds[yyk])
@@ -991,7 +1010,7 @@ yyinitStateSet (yyGLRStateSet* yyset)
yyset->yystates = (yyGLRState**) YYMALLOC (16 * sizeof yyset->yystates[0]); yyset->yystates = (yyGLRState**) YYMALLOC (16 * sizeof yyset->yystates[0]);
if (! yyset->yystates) if (! yyset->yystates)
return yyfalse; return yyfalse;
yyset->yystates[0] = YY_NULLPTR; yyset->yystates[0] = YY_NULL;
yyset->yylookaheadNeeds = yyset->yylookaheadNeeds =
(yybool*) YYMALLOC (16 * sizeof yyset->yylookaheadNeeds[0]); (yybool*) YYMALLOC (16 * sizeof yyset->yylookaheadNeeds[0]);
if (! yyset->yylookaheadNeeds) if (! yyset->yylookaheadNeeds)
@@ -1021,8 +1040,8 @@ yyinitGLRStack (yyGLRStack* yystackp, size_t yysize)
if (!yystackp->yyitems) if (!yystackp->yyitems)
return yyfalse; return yyfalse;
yystackp->yynextFree = yystackp->yyitems; yystackp->yynextFree = yystackp->yyitems;
yystackp->yysplitPoint = YY_NULLPTR; yystackp->yysplitPoint = YY_NULL;
yystackp->yylastDeleted = YY_NULLPTR; yystackp->yylastDeleted = YY_NULL;
return yyinitStateSet (&yystackp->yytops); return yyinitStateSet (&yystackp->yytops);
} }
@@ -1061,10 +1080,10 @@ yyexpandGLRStack (yyGLRStack* yystackp)
{ {
yyGLRState* yys0 = &yyp0->yystate; yyGLRState* yys0 = &yyp0->yystate;
yyGLRState* yys1 = &yyp1->yystate; yyGLRState* yys1 = &yyp1->yystate;
if (yys0->yypred != YY_NULLPTR) if (yys0->yypred != YY_NULL)
yys1->yypred = yys1->yypred =
YYRELOC (yyp0, yyp1, yys0->yypred, yystate); YYRELOC (yyp0, yyp1, yys0->yypred, yystate);
if (! yys0->yyresolved && yys0->yysemantics.yyfirstVal != YY_NULLPTR) if (! yys0->yyresolved && yys0->yysemantics.yyfirstVal != YY_NULL)
yys1->yysemantics.yyfirstVal = yys1->yysemantics.yyfirstVal =
YYRELOC (yyp0, yyp1, yys0->yysemantics.yyfirstVal, yyoption); YYRELOC (yyp0, yyp1, yys0->yysemantics.yyfirstVal, yyoption);
} }
@@ -1072,18 +1091,18 @@ yyexpandGLRStack (yyGLRStack* yystackp)
{ {
yySemanticOption* yyv0 = &yyp0->yyoption; yySemanticOption* yyv0 = &yyp0->yyoption;
yySemanticOption* yyv1 = &yyp1->yyoption; yySemanticOption* yyv1 = &yyp1->yyoption;
if (yyv0->yystate != YY_NULLPTR) if (yyv0->yystate != YY_NULL)
yyv1->yystate = YYRELOC (yyp0, yyp1, yyv0->yystate, yystate); yyv1->yystate = YYRELOC (yyp0, yyp1, yyv0->yystate, yystate);
if (yyv0->yynext != YY_NULLPTR) if (yyv0->yynext != YY_NULL)
yyv1->yynext = YYRELOC (yyp0, yyp1, yyv0->yynext, yyoption); yyv1->yynext = YYRELOC (yyp0, yyp1, yyv0->yynext, yyoption);
} }
} }
if (yystackp->yysplitPoint != YY_NULLPTR) if (yystackp->yysplitPoint != YY_NULL)
yystackp->yysplitPoint = YYRELOC (yystackp->yyitems, yynewItems, yystackp->yysplitPoint = YYRELOC (yystackp->yyitems, yynewItems,
yystackp->yysplitPoint, yystate); yystackp->yysplitPoint, yystate);
for (yyn = 0; yyn < yystackp->yytops.yysize; yyn += 1) for (yyn = 0; yyn < yystackp->yytops.yysize; yyn += 1)
if (yystackp->yytops.yystates[yyn] != YY_NULLPTR) if (yystackp->yytops.yystates[yyn] != YY_NULL)
yystackp->yytops.yystates[yyn] = yystackp->yytops.yystates[yyn] =
YYRELOC (yystackp->yyitems, yynewItems, YYRELOC (yystackp->yyitems, yynewItems,
yystackp->yytops.yystates[yyn], yystate); yystackp->yytops.yystates[yyn], yystate);
@@ -1107,7 +1126,7 @@ yyfreeGLRStack (yyGLRStack* yystackp)
static inline void static inline void
yyupdateSplit (yyGLRStack* yystackp, yyGLRState* yys) yyupdateSplit (yyGLRStack* yystackp, yyGLRState* yys)
{ {
if (yystackp->yysplitPoint != YY_NULLPTR && yystackp->yysplitPoint > yys) if (yystackp->yysplitPoint != YY_NULL && yystackp->yysplitPoint > yys)
yystackp->yysplitPoint = yys; yystackp->yysplitPoint = yys;
} }
@@ -1115,9 +1134,9 @@ yyupdateSplit (yyGLRStack* yystackp, yyGLRState* yys)
static inline void static inline void
yymarkStackDeleted (yyGLRStack* yystackp, size_t yyk) yymarkStackDeleted (yyGLRStack* yystackp, size_t yyk)
{ {
if (yystackp->yytops.yystates[yyk] != YY_NULLPTR) if (yystackp->yytops.yystates[yyk] != YY_NULL)
yystackp->yylastDeleted = yystackp->yytops.yystates[yyk]; yystackp->yylastDeleted = yystackp->yytops.yystates[yyk];
yystackp->yytops.yystates[yyk] = YY_NULLPTR; yystackp->yytops.yystates[yyk] = YY_NULL;
} }
/** Undelete the last stack in *YYSTACKP that was marked as deleted. Can /** Undelete the last stack in *YYSTACKP that was marked as deleted. Can
@@ -1126,12 +1145,12 @@ yymarkStackDeleted (yyGLRStack* yystackp, size_t yyk)
static void static void
yyundeleteLastStack (yyGLRStack* yystackp) yyundeleteLastStack (yyGLRStack* yystackp)
{ {
if (yystackp->yylastDeleted == YY_NULLPTR || yystackp->yytops.yysize != 0) if (yystackp->yylastDeleted == YY_NULL || yystackp->yytops.yysize != 0)
return; return;
yystackp->yytops.yystates[0] = yystackp->yylastDeleted; yystackp->yytops.yystates[0] = yystackp->yylastDeleted;
yystackp->yytops.yysize = 1; yystackp->yytops.yysize = 1;
YYDPRINTF ((stderr, "Restoring last deleted stack as stack #0.\n")); YYDPRINTF ((stderr, "Restoring last deleted stack as stack #0.\n"));
yystackp->yylastDeleted = YY_NULLPTR; yystackp->yylastDeleted = YY_NULL;
} }
static inline void static inline void
@@ -1141,7 +1160,7 @@ yyremoveDeletes (yyGLRStack* yystackp)
yyi = yyj = 0; yyi = yyj = 0;
while (yyj < yystackp->yytops.yysize) while (yyj < yystackp->yytops.yysize)
{ {
if (yystackp->yytops.yystates[yyi] == YY_NULLPTR) if (yystackp->yytops.yystates[yyi] == YY_NULL)
{ {
if (yyi == yyj) if (yyi == yyj)
{ {
@@ -1199,13 +1218,12 @@ yyglrShiftDefer (yyGLRStack* yystackp, size_t yyk, yyStateNum yylrState,
size_t yyposn, yyGLRState* yyrhs, yyRuleNum yyrule) size_t yyposn, yyGLRState* yyrhs, yyRuleNum yyrule)
{ {
yyGLRState* yynewState = &yynewGLRStackItem (yystackp, yytrue)->yystate; yyGLRState* yynewState = &yynewGLRStackItem (yystackp, yytrue)->yystate;
YYASSERT (yynewState->yyisState);
yynewState->yylrState = yylrState; yynewState->yylrState = yylrState;
yynewState->yyposn = yyposn; yynewState->yyposn = yyposn;
yynewState->yyresolved = yyfalse; yynewState->yyresolved = yyfalse;
yynewState->yypred = yystackp->yytops.yystates[yyk]; yynewState->yypred = yystackp->yytops.yystates[yyk];
yynewState->yysemantics.yyfirstVal = YY_NULLPTR; yynewState->yysemantics.yyfirstVal = YY_NULL;
yystackp->yytops.yystates[yyk] = yynewState; yystackp->yytops.yystates[yyk] = yynewState;
/* Invokes YY_RESERVE_GLRSTACK. */ /* Invokes YY_RESERVE_GLRSTACK. */
@@ -1265,7 +1283,7 @@ yydoAction (yyGLRStack* yystackp, size_t yyk, yyRuleNum yyrule,
{ {
int yynrhs = yyrhsLength (yyrule); int yynrhs = yyrhsLength (yyrule);
if (yystackp->yysplitPoint == YY_NULLPTR) if (yystackp->yysplitPoint == YY_NULL)
{ {
/* Standard special case: single stack. */ /* Standard special case: single stack. */
yyGLRStackItem* yyrhs = (yyGLRStackItem*) yystackp->yytops.yystates[yyk]; yyGLRStackItem* yyrhs = (yyGLRStackItem*) yystackp->yytops.yystates[yyk];
@@ -1317,13 +1335,14 @@ yyglrReduce (yyGLRStack* yystackp, size_t yyk, yyRuleNum yyrule,
{ {
size_t yyposn = yystackp->yytops.yystates[yyk]->yyposn; size_t yyposn = yystackp->yytops.yystates[yyk]->yyposn;
if (yyforceEval || yystackp->yysplitPoint == YY_NULLPTR) if (yyforceEval || yystackp->yysplitPoint == YY_NULL)
{ {
YYSTYPE yysval;]b4_locations_if([[ YYRESULTTAG yyflag;
YYLTYPE yyloc;]])[ YYSTYPE yysval;]b4_locations_if([
YYLTYPE yyloc;])[
YYRESULTTAG yyflag = yydoAction (yystackp, yyk, yyrule, &yysval]b4_locuser_args([&yyloc])[); yyflag = yydoAction (yystackp, yyk, yyrule, &yysval]b4_locuser_args([&yyloc])[);
if (yyflag == yyerr && yystackp->yysplitPoint != YY_NULLPTR) if (yyflag == yyerr && yystackp->yysplitPoint != YY_NULL)
{ {
YYDPRINTF ((stderr, "Parse on stack %lu rejected by rule #%d.\n", YYDPRINTF ((stderr, "Parse on stack %lu rejected by rule #%d.\n",
(unsigned long int) yyk, yyrule - 1)); (unsigned long int) yyk, yyrule - 1));
@@ -1356,7 +1375,7 @@ yyglrReduce (yyGLRStack* yystackp, size_t yyk, yyRuleNum yyrule,
"Now in state %d.\n", "Now in state %d.\n",
(unsigned long int) yyk, yyrule - 1, yynewLRState)); (unsigned long int) yyk, yyrule - 1, yynewLRState));
for (yyi = 0; yyi < yystackp->yytops.yysize; yyi += 1) for (yyi = 0; yyi < yystackp->yytops.yysize; yyi += 1)
if (yyi != yyk && yystackp->yytops.yystates[yyi] != YY_NULLPTR) if (yyi != yyk && yystackp->yytops.yystates[yyi] != YY_NULL)
{ {
yyGLRState *yysplit = yystackp->yysplitPoint; yyGLRState *yysplit = yystackp->yysplitPoint;
yyGLRState *yyp = yystackp->yytops.yystates[yyi]; yyGLRState *yyp = yystackp->yytops.yystates[yyi];
@@ -1383,7 +1402,7 @@ yyglrReduce (yyGLRStack* yystackp, size_t yyk, yyRuleNum yyrule,
static size_t static size_t
yysplitStack (yyGLRStack* yystackp, size_t yyk) yysplitStack (yyGLRStack* yystackp, size_t yyk)
{ {
if (yystackp->yysplitPoint == YY_NULLPTR) if (yystackp->yysplitPoint == YY_NULL)
{ {
YYASSERT (yyk == 0); YYASSERT (yyk == 0);
yystackp->yysplitPoint = yystackp->yytops.yystates[yyk]; yystackp->yysplitPoint = yystackp->yytops.yystates[yyk];
@@ -1393,7 +1412,7 @@ yysplitStack (yyGLRStack* yystackp, size_t yyk)
yyGLRState** yynewStates; yyGLRState** yynewStates;
yybool* yynewLookaheadNeeds; yybool* yynewLookaheadNeeds;
yynewStates = YY_NULLPTR; yynewStates = YY_NULL;
if (yystackp->yytops.yycapacity if (yystackp->yytops.yycapacity
> (YYSIZEMAX / (2 * sizeof yynewStates[0]))) > (YYSIZEMAX / (2 * sizeof yynewStates[0])))
@@ -1404,7 +1423,7 @@ yysplitStack (yyGLRStack* yystackp, size_t yyk)
(yyGLRState**) YYREALLOC (yystackp->yytops.yystates, (yyGLRState**) YYREALLOC (yystackp->yytops.yystates,
(yystackp->yytops.yycapacity (yystackp->yytops.yycapacity
* sizeof yynewStates[0])); * sizeof yynewStates[0]));
if (yynewStates == YY_NULLPTR) if (yynewStates == YY_NULL)
yyMemoryExhausted (yystackp); yyMemoryExhausted (yystackp);
yystackp->yytops.yystates = yynewStates; yystackp->yytops.yystates = yynewStates;
@@ -1412,7 +1431,7 @@ yysplitStack (yyGLRStack* yystackp, size_t yyk)
(yybool*) YYREALLOC (yystackp->yytops.yylookaheadNeeds, (yybool*) YYREALLOC (yystackp->yytops.yylookaheadNeeds,
(yystackp->yytops.yycapacity (yystackp->yytops.yycapacity
* sizeof yynewLookaheadNeeds[0])); * sizeof yynewLookaheadNeeds[0]));
if (yynewLookaheadNeeds == YY_NULLPTR) if (yynewLookaheadNeeds == YY_NULL)
yyMemoryExhausted (yystackp); yyMemoryExhausted (yystackp);
yystackp->yytops.yylookaheadNeeds = yynewLookaheadNeeds; yystackp->yytops.yylookaheadNeeds = yynewLookaheadNeeds;
} }
@@ -1476,9 +1495,9 @@ yymergeOptionSets (yySemanticOption* yyy0, yySemanticOption* yyy1)
yySemanticOption* yyz1 = yys1->yysemantics.yyfirstVal; yySemanticOption* yyz1 = yys1->yysemantics.yyfirstVal;
while (yytrue) while (yytrue)
{ {
if (yyz1 == *yyz0p || yyz1 == YY_NULLPTR) if (yyz1 == *yyz0p || yyz1 == YY_NULL)
break; break;
else if (*yyz0p == YY_NULLPTR) else if (*yyz0p == YY_NULL)
{ {
*yyz0p = yyz1; *yyz0p = yyz1;
break; break;
@@ -1599,7 +1618,7 @@ yyreportTree (yySemanticOption* yyx, int yyindent)
for (yyi = yynrhs, yys = yyx->yystate; 0 < yyi; yyi -= 1, yys = yys->yypred) for (yyi = yynrhs, yys = yyx->yystate; 0 < yyi; yyi -= 1, yys = yys->yypred)
yystates[yyi] = yys; yystates[yyi] = yys;
if (yys == YY_NULLPTR) if (yys == YY_NULL)
{ {
yyleftmost_state.yyposn = 0; yyleftmost_state.yyposn = 0;
yystates[0] = &yyleftmost_state; yystates[0] = &yyleftmost_state;
@@ -1670,7 +1689,7 @@ yyresolveLocations (yyGLRState* yys1, int yyn1,
yyGLRStackItem yyrhsloc[1 + YYMAXRHS]; yyGLRStackItem yyrhsloc[1 + YYMAXRHS];
int yynrhs; int yynrhs;
yySemanticOption *yyoption = yys1->yysemantics.yyfirstVal; yySemanticOption *yyoption = yys1->yysemantics.yyfirstVal;
YYASSERT (yyoption != YY_NULLPTR); YYASSERT (yyoption != YY_NULL);
yynrhs = yyrhsLength (yyoption->yyrule); yynrhs = yyrhsLength (yyoption->yyrule);
if (yynrhs > 0) if (yynrhs > 0)
{ {
@@ -1729,7 +1748,7 @@ yyresolveValue (yyGLRState* yys, yyGLRStack* yystackp]b4_user_formals[)
YYRESULTTAG yyflag;]b4_locations_if([ YYRESULTTAG yyflag;]b4_locations_if([
YYLTYPE *yylocp = &yys->yyloc;])[ YYLTYPE *yylocp = &yys->yyloc;])[
for (yypp = &yyoptionList->yynext; *yypp != YY_NULLPTR; ) for (yypp = &yyoptionList->yynext; *yypp != YY_NULL; )
{ {
yySemanticOption* yyp = *yypp; yySemanticOption* yyp = *yypp;
@@ -1771,7 +1790,7 @@ yyresolveValue (yyGLRState* yys, yyGLRStack* yystackp]b4_user_formals[)
int yyprec = yydprec[yybest->yyrule]; int yyprec = yydprec[yybest->yyrule];
yyflag = yyresolveAction (yybest, yystackp, &yysval]b4_locuser_args[); yyflag = yyresolveAction (yybest, yystackp, &yysval]b4_locuser_args[);
if (yyflag == yyok) if (yyflag == yyok)
for (yyp = yybest->yynext; yyp != YY_NULLPTR; yyp = yyp->yynext) for (yyp = yybest->yynext; yyp != YY_NULL; yyp = yyp->yynext)
{ {
if (yyprec == yydprec[yyp->yyrule]) if (yyprec == yydprec[yyp->yyrule])
{ {
@@ -1798,14 +1817,14 @@ yyresolveValue (yyGLRState* yys, yyGLRStack* yystackp]b4_user_formals[)
yys->yysemantics.yysval = yysval; yys->yysemantics.yysval = yysval;
} }
else else
yys->yysemantics.yyfirstVal = YY_NULLPTR; yys->yysemantics.yyfirstVal = YY_NULL;
return yyflag; return yyflag;
} }
static YYRESULTTAG static YYRESULTTAG
yyresolveStack (yyGLRStack* yystackp]b4_user_formals[) yyresolveStack (yyGLRStack* yystackp]b4_user_formals[)
{ {
if (yystackp->yysplitPoint != YY_NULLPTR) if (yystackp->yysplitPoint != YY_NULL)
{ {
yyGLRState* yys; yyGLRState* yys;
int yyn; int yyn;
@@ -1825,10 +1844,10 @@ yycompressStack (yyGLRStack* yystackp)
{ {
yyGLRState* yyp, *yyq, *yyr; yyGLRState* yyp, *yyq, *yyr;
if (yystackp->yytops.yysize != 1 || yystackp->yysplitPoint == YY_NULLPTR) if (yystackp->yytops.yysize != 1 || yystackp->yysplitPoint == YY_NULL)
return; return;
for (yyp = yystackp->yytops.yystates[0], yyq = yyp->yypred, yyr = YY_NULLPTR; for (yyp = yystackp->yytops.yystates[0], yyq = yyp->yypred, yyr = YY_NULL;
yyp != yystackp->yysplitPoint; yyp != yystackp->yysplitPoint;
yyr = yyp, yyp = yyq, yyq = yyp->yypred) yyr = yyp, yyp = yyq, yyq = yyp->yypred)
yyp->yypred = yyr; yyp->yypred = yyr;
@@ -1836,10 +1855,10 @@ yycompressStack (yyGLRStack* yystackp)
yystackp->yyspaceLeft += yystackp->yynextFree - yystackp->yyitems; yystackp->yyspaceLeft += yystackp->yynextFree - yystackp->yyitems;
yystackp->yynextFree = ((yyGLRStackItem*) yystackp->yysplitPoint) + 1; yystackp->yynextFree = ((yyGLRStackItem*) yystackp->yysplitPoint) + 1;
yystackp->yyspaceLeft -= yystackp->yynextFree - yystackp->yyitems; yystackp->yyspaceLeft -= yystackp->yynextFree - yystackp->yyitems;
yystackp->yysplitPoint = YY_NULLPTR; yystackp->yysplitPoint = YY_NULL;
yystackp->yylastDeleted = YY_NULLPTR; yystackp->yylastDeleted = YY_NULL;
while (yyr != YY_NULLPTR) while (yyr != YY_NULL)
{ {
yystackp->yynextFree->yystate = *yyr; yystackp->yynextFree->yystate = *yyr;
yyr = yyr->yypred; yyr = yyr->yypred;
@@ -1854,7 +1873,7 @@ static YYRESULTTAG
yyprocessOneStack (yyGLRStack* yystackp, size_t yyk, yyprocessOneStack (yyGLRStack* yystackp, size_t yyk,
size_t yyposn]b4_pure_formals[) size_t yyposn]b4_pure_formals[)
{ {
while (yystackp->yytops.yystates[yyk] != YY_NULLPTR) while (yystackp->yytops.yystates[yyk] != YY_NULL)
{ {
yyStateNum yystate = yystackp->yytops.yystates[yyk]->yylrState; yyStateNum yystate = yystackp->yytops.yystates[yyk]->yylrState;
YYDPRINTF ((stderr, "Stack %lu Entering state %d\n", YYDPRINTF ((stderr, "Stack %lu Entering state %d\n",
@@ -1976,13 +1995,13 @@ yyreportSyntaxError (yyGLRStack* yystackp]b4_user_formals[)
#else #else
{ {
yySymbol yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar); yySymbol yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar);
size_t yysize0 = yytnamerr (YY_NULLPTR, yytokenName (yytoken)); size_t yysize0 = yytnamerr (YY_NULL, yytokenName (yytoken));
size_t yysize = yysize0; size_t yysize = yysize0;
yybool yysize_overflow = yyfalse; yybool yysize_overflow = yyfalse;
char* yymsg = YY_NULLPTR; char* yymsg = YY_NULL;
enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
/* Internationalized format string. */ /* Internationalized format string. */
const char *yyformat = YY_NULLPTR; const char *yyformat = YY_NULL;
/* Arguments of yyformat. */ /* Arguments of yyformat. */
char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
/* Number of reported tokens (one for the "unexpected", one per /* Number of reported tokens (one for the "unexpected", one per
@@ -2038,7 +2057,7 @@ yyreportSyntaxError (yyGLRStack* yystackp]b4_user_formals[)
} }
yyarg[yycount++] = yytokenName (yyx); yyarg[yycount++] = yytokenName (yyx);
{ {
size_t yysz = yysize + yytnamerr (YY_NULLPTR, yytokenName (yyx)); size_t yysz = yysize + yytnamerr (YY_NULL, yytokenName (yyx));
yysize_overflow |= yysz < yysize; yysize_overflow |= yysz < yysize;
yysize = yysz; yysize = yysz;
} }
@@ -2116,7 +2135,7 @@ yyrecoverSyntaxError (yyGLRStack* yystackp]b4_user_formals[)
{ {
yySymbol yytoken; yySymbol yytoken;
if (yychar == YYEOF) if (yychar == YYEOF)
yyFail (yystackp][]b4_lpure_args[, YY_NULLPTR); yyFail (yystackp][]b4_lpure_args[, YY_NULL);
if (yychar != YYEMPTY) if (yychar != YYEMPTY)
{]b4_locations_if([[ {]b4_locations_if([[
/* We throw away the lookahead, but the error range /* We throw away the lookahead, but the error range
@@ -2157,10 +2176,10 @@ yyrecoverSyntaxError (yyGLRStack* yystackp]b4_user_formals[)
/* Reduce to one stack. */ /* Reduce to one stack. */
for (yyk = 0; yyk < yystackp->yytops.yysize; yyk += 1) for (yyk = 0; yyk < yystackp->yytops.yysize; yyk += 1)
if (yystackp->yytops.yystates[yyk] != YY_NULLPTR) if (yystackp->yytops.yystates[yyk] != YY_NULL)
break; break;
if (yyk >= yystackp->yytops.yysize) if (yyk >= yystackp->yytops.yysize)
yyFail (yystackp][]b4_lpure_args[, YY_NULLPTR); yyFail (yystackp][]b4_lpure_args[, YY_NULL);
for (yyk += 1; yyk < yystackp->yytops.yysize; yyk += 1) for (yyk += 1; yyk < yystackp->yytops.yysize; yyk += 1)
yymarkStackDeleted (yystackp, yyk); yymarkStackDeleted (yystackp, yyk);
yyremoveDeletes (yystackp); yyremoveDeletes (yystackp);
@@ -2168,7 +2187,7 @@ yyrecoverSyntaxError (yyGLRStack* yystackp]b4_user_formals[)
/* Now pop stack until we find a state that shifts the error token. */ /* Now pop stack until we find a state that shifts the error token. */
yystackp->yyerrState = 3; yystackp->yyerrState = 3;
while (yystackp->yytops.yystates[0] != YY_NULLPTR) while (yystackp->yytops.yystates[0] != YY_NULL)
{ {
yyGLRState *yys = yystackp->yytops.yystates[0]; yyGLRState *yys = yystackp->yytops.yystates[0];
yyj = yypact[yys->yylrState]; yyj = yypact[yys->yylrState];
@@ -2192,14 +2211,14 @@ yyrecoverSyntaxError (yyGLRStack* yystackp]b4_user_formals[)
} }
}]b4_locations_if([[ }]b4_locations_if([[
yystackp->yyerror_range[1].yystate.yyloc = yys->yyloc;]])[ yystackp->yyerror_range[1].yystate.yyloc = yys->yyloc;]])[
if (yys->yypred != YY_NULLPTR) if (yys->yypred != YY_NULL)
yydestroyGLRState ("Error: popping", yys]b4_user_args[); yydestroyGLRState ("Error: popping", yys]b4_user_args[);
yystackp->yytops.yystates[0] = yys->yypred; yystackp->yytops.yystates[0] = yys->yypred;
yystackp->yynextFree -= 1; yystackp->yynextFree -= 1;
yystackp->yyspaceLeft += 1; yystackp->yyspaceLeft += 1;
} }
if (yystackp->yytops.yystates[0] == YY_NULLPTR) if (yystackp->yytops.yystates[0] == YY_NULL)
yyFail (yystackp][]b4_lpure_args[, YY_NULLPTR); yyFail (yystackp][]b4_lpure_args[, YY_NULL);
} }
#define YYCHK1(YYE) \ #define YYCHK1(YYE) \
@@ -2442,7 +2461,7 @@ b4_dollar_popdef])[]dnl
{ {
yyGLRState *yys = yystates[yyk]; yyGLRState *yys = yystates[yyk];
]b4_locations_if([[ yystack.yyerror_range[1].yystate.yyloc = yys->yyloc;]] ]b4_locations_if([[ yystack.yyerror_range[1].yystate.yyloc = yys->yyloc;]]
)[ if (yys->yypred != YY_NULLPTR) )[ if (yys->yypred != YY_NULL)
yydestroyGLRState ("Cleanup: popping", yys]b4_user_args[); yydestroyGLRState ("Cleanup: popping", yys]b4_user_args[);
yystates[yyk] = yys->yypred; yystates[yyk] = yys->yypred;
yystack.yynextFree -= 1; yystack.yynextFree -= 1;
@@ -2474,7 +2493,7 @@ yy_yypstack (yyGLRState* yys)
static void static void
yypstates (yyGLRState* yyst) yypstates (yyGLRState* yyst)
{ {
if (yyst == YY_NULLPTR) if (yyst == YY_NULL)
YYFPRINTF (stderr, "<null>"); YYFPRINTF (stderr, "<null>");
else else
yy_yypstack (yyst); yy_yypstack (yyst);
@@ -2488,7 +2507,7 @@ yypstack (yyGLRStack* yystackp, size_t yyk)
} }
#define YYINDEX(YYX) \ #define YYINDEX(YYX) \
((YYX) == YY_NULLPTR ? -1 : (yyGLRStackItem*) (YYX) - yystackp->yyitems) ((YYX) == YY_NULL ? -1 : (yyGLRStackItem*) (YYX) - yystackp->yyitems)
static void static void
@@ -2502,8 +2521,6 @@ yypdumpstack (yyGLRStack* yystackp)
(unsigned long int) (yyp - yystackp->yyitems)); (unsigned long int) (yyp - yystackp->yyitems));
if (*(yybool *) yyp) if (*(yybool *) yyp)
{ {
YYASSERT (yyp->yystate.yyisState);
YYASSERT (yyp->yyoption.yyisState);
YYFPRINTF (stderr, "Res: %d, LR State: %d, posn: %lu, pred: %ld", YYFPRINTF (stderr, "Res: %d, LR State: %d, posn: %lu, pred: %ld",
yyp->yystate.yyresolved, yyp->yystate.yylrState, yyp->yystate.yyresolved, yyp->yystate.yylrState,
(unsigned long int) yyp->yystate.yyposn, (unsigned long int) yyp->yystate.yyposn,
@@ -2515,8 +2532,6 @@ yypdumpstack (yyGLRStack* yystackp)
} }
else else
{ {
YYASSERT (!yyp->yystate.yyisState);
YYASSERT (!yyp->yyoption.yyisState);
YYFPRINTF (stderr, "Option. rule: %d, state: %ld, next: %ld", YYFPRINTF (stderr, "Option. rule: %d, state: %ld, next: %ld",
yyp->yyoption.yyrule - 1, yyp->yyoption.yyrule - 1,
(long int) YYINDEX (yyp->yyoption.yystate), (long int) YYINDEX (yyp->yyoption.yystate),
+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. ##
## ---------------- ## ## ---------------- ##
+80 -75
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])
# -------------------- # --------------------
@@ -157,7 +154,6 @@ m4_define([b4_shared_declarations],
]b4_bison_locations_if([[# include "location.hh"]])])[ ]b4_bison_locations_if([[# include "location.hh"]])])[
]b4_variant_if([b4_variant_includes])[ ]b4_variant_if([b4_variant_includes])[
]b4_attribute_define[
]b4_YYDEBUG_define[ ]b4_YYDEBUG_define[
]b4_namespace_open[ ]b4_namespace_open[
@@ -184,14 +180,14 @@ b4_location_define])])[
#if ]b4_api_PREFIX[DEBUG #if ]b4_api_PREFIX[DEBUG
/// The current debugging stream. /// The current debugging stream.
std::ostream& debug_stream () const YY_ATTRIBUTE_PURE; std::ostream& debug_stream () const;
/// Set the current debugging stream. /// Set the current debugging stream.
void set_debug_stream (std::ostream &); void set_debug_stream (std::ostream &);
/// Type for debugging levels. /// Type for debugging levels.
typedef int debug_level_type; typedef int debug_level_type;
/// The current debugging level. /// The current debugging level.
debug_level_type debug_level () const YY_ATTRIBUTE_PURE; debug_level_type debug_level () const;
/// Set the current debugging level. /// Set the current debugging level.
void set_debug_level (debug_level_type l); void set_debug_level (debug_level_type l);
#endif #endif
@@ -205,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;
@@ -220,8 +212,8 @@ b4_location_define])])[
/// Compute post-reduction state. /// Compute post-reduction state.
/// \param yystate the current state /// \param yystate the current state
/// \param yysym the nonterminal to push on the stack /// \param yylhs the nonterminal to push on the stack
state_type yy_lr_goto_state_ (state_type yystate, int yysym); state_type yy_lr_goto_state_ (state_type yystate, int yylhs);
/// Whether the given \c yypact_ value indicates a defaulted state. /// Whether the given \c yypact_ value indicates a defaulted state.
/// \param yyvalue the value to check /// \param yyvalue the value to check
@@ -268,7 +260,7 @@ b4_location_define])])[
/// \brief Reclaim the memory associated to a symbol. /// \brief Reclaim the memory associated to a symbol.
/// \param yymsg Why this token is reclaimed. /// \param yymsg Why this token is reclaimed.
/// If null, print nothing. /// If null, print nothing.
/// \param yysym The symbol. /// \param s The symbol.
template <typename Base> template <typename Base>
void yy_destroy_ (const char* yymsg, basic_symbol<Base>& yysym) const; void yy_destroy_ (const char* yymsg, basic_symbol<Base>& yysym) const;
@@ -342,13 +334,13 @@ b4_location_define])])[
enum enum
{ {
yyeof_ = 0, yyeof_ = 0,
yylast_ = ]b4_last[, ///< Last index in yytable_. yylast_ = ]b4_last[, //< Last index in yytable_.
yynnts_ = ]b4_nterms_number[, ///< Number of nonterminal symbols. yynnts_ = ]b4_nterms_number[, //< Number of nonterminal symbols.
yyempty_ = -2, yyempty_ = -2,
yyfinal_ = ]b4_final_state_number[, ///< Termination state number. yyfinal_ = ]b4_final_state_number[, //< Termination state number.
yyterror_ = 1, yyterror_ = 1,
yyerrcode_ = 256, yyerrcode_ = 256,
yyntokens_ = ]b4_tokens_number[ ///< Number of tokens. yyntokens_ = ]b4_tokens_number[ //< Number of tokens.
}; };
]b4_parse_param_vars[ ]b4_parse_param_vars[
@@ -599,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
@@ -614,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
@@ -671,13 +674,13 @@ m4_if(b4_prefix, [yy], [],
#endif // ]b4_api_PREFIX[DEBUG #endif // ]b4_api_PREFIX[DEBUG
inline ]b4_parser_class_name[::state_type inline ]b4_parser_class_name[::state_type
]b4_parser_class_name[::yy_lr_goto_state_ (state_type yystate, int yysym) ]b4_parser_class_name[::yy_lr_goto_state_ (state_type yystate, int yylhs)
{ {
int yyr = yypgoto_[yysym - yyntokens_] + yystate; int yyr = yypgoto_[yylhs - yyntokens_] + yystate;
if (0 <= yyr && yyr <= yylast_ && yycheck_[yyr] == yystate) if (0 <= yyr && yyr <= yylast_ && yycheck_[yyr] == yystate)
return yytable_[yyr]; return yytable_[yyr];
else else
return yydefgoto_[yysym - yyntokens_]; return yydefgoto_[yylhs - yyntokens_];
} }
inline bool inline bool
@@ -700,7 +703,6 @@ m4_if(b4_prefix, [yy], [],
// State. // State.
int yyn; int yyn;
/// Length of the RHS of the rule being reduced.
int yylen = 0; int yylen = 0;
// Error handling. // Error handling.
@@ -713,6 +715,9 @@ m4_if(b4_prefix, [yy], [],
/// The locations where the error started and ended. /// The locations where the error started and ended.
stack_symbol_type yyerror_range[3];]])[ stack_symbol_type yyerror_range[3];]])[
/// $$ and @@$.
stack_symbol_type yylhs;
/// The return value of parse (). /// The return value of parse ().
int yyresult; int yyresult;
@@ -732,8 +737,8 @@ 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_NULLPTR, 0, yyla); yypush_ (YY_NULL, 0, yyla);
// A new symbol was pushed on the stack. // A new symbol was pushed on the stack.
yynewstate: yynewstate:
@@ -813,55 +818,52 @@ b4_dollar_popdef])[]dnl
`-----------------------------*/ `-----------------------------*/
yyreduce: yyreduce:
yylen = yyr2_[yyn]; yylen = yyr2_[yyn];
{ yylhs.state = yy_lr_goto_state_(yystack_[yylen].state, yyr1_[yyn]);]b4_variant_if([
stack_symbol_type yylhs; /* Variants are always initialized to an empty instance of the
yylhs.state = yy_lr_goto_state_(yystack_[yylen].state, yyr1_[yyn]);]b4_variant_if([ correct type. The default $$=$1 action is NOT applied when using
/* Variants are always initialized to an empty instance of the variants. */
correct type. The default '$$ = $1' action is NOT applied b4_symbol_variant([[yyr1_@{yyn@}]], [yylhs.value], [build])],[
when using variants. */ /* If YYLEN is nonzero, implement the default value of the action:
b4_symbol_variant([[yyr1_@{yyn@}]], [yylhs.value], [build])], [ `$$ = $1'. Otherwise, use the top of the stack.
/* If YYLEN is nonzero, implement the default value of the
action: '$$ = $1'. Otherwise, use the top of the stack.
Otherwise, the following line sets YYLHS.VALUE to garbage. Otherwise, the following line sets YYLHS.VALUE to garbage.
This behavior is undocumented and Bison users should not rely This behavior is undocumented and Bison
upon it. */ users should not rely upon it. */
if (yylen) if (yylen)
yylhs.value = yystack_@{yylen - 1@}.value; yylhs.value = yystack_@{yylen - 1@}.value;
else else
yylhs.value = yystack_@{0@}.value;])[ yylhs.value = yystack_@{0@}.value;])[
]b4_locations_if([dnl ]b4_locations_if([dnl
[ [
// Compute the default @@$. // Compute the default @@$.
{
slice<stack_symbol_type, stack_type> slice (yystack_, yylen);
YYLLOC_DEFAULT (yylhs.location, slice, yylen);
}]])[
// Perform the reduction.
YY_REDUCE_PRINT (yyn);
try
{ {
slice<stack_symbol_type, stack_type> slice (yystack_, yylen); switch (yyn)
YYLLOC_DEFAULT (yylhs.location, slice, yylen); {
}]])[
// Perform the reduction.
YY_REDUCE_PRINT (yyn);
try
{
switch (yyn)
{
]b4_user_actions[ ]b4_user_actions[
default: default:
break; break;
} }
} }
catch (const syntax_error& yyexc) catch (const syntax_error& yyexc)
{ {
error (yyexc); error (yyexc);
YYERROR; YYERROR;
} }
YY_SYMBOL_PRINT ("-> $$ =", yylhs); YY_SYMBOL_PRINT ("-> $$ =", yylhs);
yypop_ (yylen); yypop_ (yylen);
yylen = 0; yylen = 0;
YY_STACK_PRINT (); YY_STACK_PRINT ();
// Shift the result of the reduction. // Shift the result of the reduction.
yypush_ (YY_NULLPTR, yylhs); yypush_ (YY_NULL, yylhs);
}
goto yynewstate; goto yynewstate;
/*--------------------------------------. /*--------------------------------------.
@@ -908,7 +910,10 @@ b4_dollar_popdef])[]dnl
code. */ code. */
if (false) if (false)
goto yyerrorlab;]b4_locations_if([[ goto yyerrorlab;]b4_locations_if([[
yyerror_range[1].location = yystack_[yylen - 1].location;]])[ yyerror_range[1].location = yystack_[yylen - 1].location;]])b4_variant_if([[
/* $$ was initialized before running the user action. */
YY_SYMBOL_PRINT ("Error: discarding", yylhs);
yylhs.~stack_symbol_type();]])[
/* Do not reclaim the symbols of the rule whose action triggered /* Do not reclaim the symbols of the rule whose action triggered
this YYERROR. */ this YYERROR. */
yypop_ (yylen); yypop_ (yylen);
@@ -987,11 +992,11 @@ b4_dollar_popdef])[]dnl
// Do not try to display the values of the reclaimed symbols, // Do not try to display the values of the reclaimed symbols,
// as their printer might throw an exception. // as their printer might throw an exception.
if (!yyempty) if (!yyempty)
yy_destroy_ (YY_NULLPTR, yyla); yy_destroy_ (YY_NULL, yyla);
while (1 < yystack_.size ()) while (1 < yystack_.size ())
{ {
yy_destroy_ (YY_NULLPTR, yystack_[0]); yy_destroy_ (YY_NULL, yystack_[0]);
yypop_ (); yypop_ ();
} }
throw; throw;
@@ -1073,7 +1078,7 @@ b4_error_verbose_if([state_type yystate, symbol_number_type yytoken],
} }
} }
char const* yyformat = YY_NULLPTR; char const* yyformat = YY_NULL;
switch (yycount) switch (yycount)
{ {
#define YYCASE_(N, S) \ #define YYCASE_(N, S) \
+79 -274
View File
@@ -20,8 +20,7 @@ m4_include(b4_pkgdatadir/[java.m4])
b4_defines_if([b4_fatal([%s: %%defines does not make sense in Java], b4_defines_if([b4_fatal([%s: %%defines does not make sense in Java],
[b4_skeleton])]) [b4_skeleton])])
# We do not depend on %debug in Java, but pacify warnings about # We don't depend on %debug in Java, but pacify warnings about non-used flags.
# non-used flags.
b4_parse_trace_if([0], [0]) b4_parse_trace_if([0], [0])
m4_define([b4_symbol_no_destructor_assert], m4_define([b4_symbol_no_destructor_assert],
@@ -31,57 +30,6 @@ m4_define([b4_symbol_no_destructor_assert],
[b4_symbol_action_location([$1], [destructor])])])]) [b4_symbol_action_location([$1], [destructor])])])])
b4_symbol_foreach([b4_symbol_no_destructor_assert]) b4_symbol_foreach([b4_symbol_no_destructor_assert])
# Setup some macros for api.push-pull.
b4_percent_define_default([[api.push-pull]], [[pull]])
b4_percent_define_check_values([[[[api.push-pull]],
[[pull]], [[push]], [[both]]]])
# Define m4 conditional macros that encode the value
# of the api.push-pull flag.
b4_define_flag_if([pull]) m4_define([b4_pull_flag], [[1]])
b4_define_flag_if([push]) m4_define([b4_push_flag], [[1]])
m4_case(b4_percent_define_get([[api.push-pull]]),
[pull], [m4_define([b4_push_flag], [[0]])],
[push], [m4_define([b4_pull_flag], [[0]])])
# Define a macro to be true when api.push-pull has the value "both".
m4_define([b4_both_if],[b4_push_if([b4_pull_if([$1],[$2])],[$2])])
# Handle BISON_USE_PUSH_FOR_PULL for the test suite. So that push parsing
# tests function as written, do not let BISON_USE_PUSH_FOR_PULL modify the
# behavior of Bison at all when push parsing is already requested.
b4_define_flag_if([use_push_for_pull])
b4_use_push_for_pull_if([
b4_push_if([m4_define([b4_use_push_for_pull_flag], [[0]])],
[m4_define([b4_push_flag], [[1]])])])
# Define a macro to encapsulate the parse state variables.
# This allows them to be defined either in parse() when doing
# pull parsing, or as class instance variable when doing push parsing.
m4_define([b4_define_state],[[
/* Lookahead and lookahead in internal form. */
int yychar = yyempty_;
int yytoken = 0;
/* State. */
int yyn = 0;
int yylen = 0;
int yystate = 0;
YYStack yystack = new YYStack ();
int label = YYNEWSTATE;
/* Error handling. */
int yynerrs_ = 0;
]b4_locations_if([/* The location where the error started. */
b4_location_type yyerrloc = null;
/* Location. */
b4_location_type yylloc = new b4_location_type (null, null);])[
/* Semantic value of the lookahead. */
]b4_yystype[ yylval = null;
]])
b4_output_begin([b4_parser_file_name]) b4_output_begin([b4_parser_file_name])
b4_copyright([Skeleton implementation for Bison LALR(1) parsers in Java], b4_copyright([Skeleton implementation for Bison LALR(1) parsers in Java],
[2007-2013]) [2007-2013])
@@ -107,9 +55,7 @@ b4_percent_define_get3([implements], [ implements ])[
{ {
]b4_identification[ ]b4_identification[
]b4_error_verbose_if([[ ]b4_error_verbose_if([[
/** /** True if verbose error messages are enabled. */
* True if verbose error messages are enabled.
*/
private boolean yyErrorVerbose = true; private boolean yyErrorVerbose = true;
/** /**
@@ -130,24 +76,18 @@ b4_locations_if([[
* A class defining a pair of positions. Positions, defined by the * A class defining a pair of positions. Positions, defined by the
* <code>]b4_position_type[</code> class, denote a point in the input. * <code>]b4_position_type[</code> class, denote a point in the input.
* Locations represent a part of the input through the beginning * Locations represent a part of the input through the beginning
* and ending positions. * and ending positions. */
*/
public class ]b4_location_type[ { public class ]b4_location_type[ {
/** /** The first, inclusive, position in the range. */
* The first, inclusive, position in the range.
*/
public ]b4_position_type[ begin; public ]b4_position_type[ begin;
/** /** The first position beyond the range. */
* The first position beyond the range.
*/
public ]b4_position_type[ end; public ]b4_position_type[ end;
/** /**
* Create a <code>]b4_location_type[</code> denoting an empty range located at * Create a <code>]b4_location_type[</code> denoting an empty range located at
* a given point. * a given point.
* @@param loc The position at which the range is anchored. * @@param loc The position at which the range is anchored. */
*/
public ]b4_location_type[ (]b4_position_type[ loc) { public ]b4_location_type[ (]b4_position_type[ loc) {
this.begin = this.end = loc; this.begin = this.end = loc;
} }
@@ -155,8 +95,7 @@ b4_locations_if([[
/** /**
* Create a <code>]b4_location_type[</code> from the endpoints of the range. * Create a <code>]b4_location_type[</code> from the endpoints of the range.
* @@param begin The first position included in the range. * @@param begin The first position included in the range.
* @@param end The first position beyond the range. * @@param end The first position beyond the range. */
*/
public ]b4_location_type[ (]b4_position_type[ begin, ]b4_position_type[ end) { public ]b4_location_type[ (]b4_position_type[ begin, ]b4_position_type[ end) {
this.begin = begin; this.begin = begin;
this.end = end; this.end = end;
@@ -165,8 +104,7 @@ b4_locations_if([[
/** /**
* Print a representation of the location. For this to be correct, * Print a representation of the location. For this to be correct,
* <code>]b4_position_type[</code> should override the <code>equals</code> * <code>]b4_position_type[</code> should override the <code>equals</code>
* method. * method. */
*/
public String toString () { public String toString () {
if (begin.equals (end)) if (begin.equals (end))
return begin.toString (); return begin.toString ();
@@ -198,28 +136,24 @@ b4_locations_if([[
]b4_locations_if([[/** ]b4_locations_if([[/**
* Method to retrieve the beginning position of the last scanned token. * Method to retrieve the beginning position of the last scanned token.
* @@return the position at which the last scanned token starts. * @@return the position at which the last scanned token starts. */
*/
]b4_position_type[ getStartPos (); ]b4_position_type[ getStartPos ();
/** /**
* Method to retrieve the ending position of the last scanned token. * Method to retrieve the ending position of the last scanned token.
* @@return the first position beyond the last scanned token. * @@return the first position beyond the last scanned token. */
*/
]b4_position_type[ getEndPos ();]])[ ]b4_position_type[ getEndPos ();]])[
/** /**
* Method to retrieve the semantic value of the last scanned token. * Method to retrieve the semantic value of the last scanned token.
* @@return the semantic value of the last scanned token. * @@return the semantic value of the last scanned token. */
*/
]b4_yystype[ getLVal (); ]b4_yystype[ getLVal ();
/** /**
* Entry point for the scanner. Returns the token identifier corresponding * Entry point for the scanner. Returns the token identifier corresponding
* to the next token and prepares to return the semantic value * to the next token and prepares to return the semantic value
* ]b4_locations_if([and beginning/ending positions ])[of the token. * ]b4_locations_if([and beginning/ending positions ])[of the token.
* @@return the token identifier corresponding to the next token. * @@return the token identifier corresponding to the next token. */
*/
int yylex () ]b4_maybe_throws([b4_lex_throws])[; int yylex () ]b4_maybe_throws([b4_lex_throws])[;
/** /**
@@ -228,8 +162,7 @@ b4_locations_if([[
* *
* ]b4_locations_if([[@@param loc The location of the element to which the * ]b4_locations_if([[@@param loc The location of the element to which the
* error message is related]])[ * error message is related]])[
* @@param msg The string for the error message. * @@param msg The string for the error message. */
*/
void yyerror (]b4_locations_if([b4_location_type[ loc, ]])[String msg);] void yyerror (]b4_locations_if([b4_location_type[ loc, ]])[String msg);]
} }
@@ -237,9 +170,7 @@ b4_locations_if([[
]b4_percent_code_get([[lexer]])[ ]b4_percent_code_get([[lexer]])[
} }
]])[/** ]])[/** The object doing lexical analysis for us. */
* The object doing lexical analysis for us.
*/
private Lexer yylexer; private Lexer yylexer;
] ]
b4_parse_param_vars b4_parse_param_vars
@@ -405,74 +336,46 @@ b4_lexer_if([[
/** /**
* Returned by a Bison action in order to stop the parsing process and * Returned by a Bison action in order to stop the parsing process and
* return success (<tt>true</tt>). * return success (<tt>true</tt>). */
*/
public static final int YYACCEPT = 0; public static final int YYACCEPT = 0;
/** /**
* Returned by a Bison action in order to stop the parsing process and * Returned by a Bison action in order to stop the parsing process and
* return failure (<tt>false</tt>). * return failure (<tt>false</tt>). */
*/
public static final int YYABORT = 1; public static final int YYABORT = 1;
]b4_push_if([
/**
* Returned by a Bison action in order to request a new token.
*/
public static final int YYPUSH_MORE = 4;])[
/** /**
* Returned by a Bison action in order to start error recovery without * Returned by a Bison action in order to start error recovery without
* printing an error message. * printing an error message. */
*/
public static final int YYERROR = 2; public static final int YYERROR = 2;
/** // Internal return codes that are not supported for user semantic
* Internal return codes that are not supported for user semantic // actions.
* actions.
*/
private static final int YYERRLAB = 3; private static final int YYERRLAB = 3;
private static final int YYNEWSTATE = 4; private static final int YYNEWSTATE = 4;
private static final int YYDEFAULT = 5; private static final int YYDEFAULT = 5;
private static final int YYREDUCE = 6; private static final int YYREDUCE = 6;
private static final int YYERRLAB1 = 7; private static final int YYERRLAB1 = 7;
private static final int YYRETURN = 8; private static final int YYRETURN = 8;
]b4_push_if([[ private static final int YYGETTOKEN = 9; /* Signify that a new token is expected when doing push-parsing. */]])[
private int yyerrstatus_ = 0; private int yyerrstatus_ = 0;
]b4_push_if([dnl
b4_define_state])[
/** /**
* Return whether error recovery is being done. In this state, the parser * Return whether error recovery is being done. In this state, the parser
* reads token until it reaches a known state, and then restarts normal * reads token until it reaches a known state, and then restarts normal
* operation. * operation. */
*/
public final boolean recovering () public final boolean recovering ()
{ {
return yyerrstatus_ == 0; return yyerrstatus_ == 0;
} }
/** Compute post-reduction state.
* @@param yystate the current state
* @@param yysym the nonterminal to push on the stack
*/
private int yy_lr_goto_state_ (int yystate, int yysym)
{
int yyr = yypgoto_[yysym - yyntokens_] + yystate;
if (0 <= yyr && yyr <= yylast_ && yycheck_[yyr] == yystate)
return yytable_[yyr];
else
return yydefgoto_[yysym - yyntokens_];
}
private int yyaction (int yyn, YYStack yystack, int yylen) ]b4_maybe_throws([b4_throws])[ private int yyaction (int yyn, YYStack yystack, int yylen) ]b4_maybe_throws([b4_throws])[
{ {
]b4_yystype[ yyval; ]b4_yystype[ yyval;
]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
@@ -496,7 +399,14 @@ b4_define_state])[
yylen = 0; yylen = 0;
/* Shift the result of the reduction. */ /* Shift the result of the reduction. */
int yystate = yy_lr_goto_state_ (yystack.stateAt (0), yyr1_[yyn]); yyn = yyr1_[yyn];
int yystate = yypgoto_[yyn - yyntokens_] + yystack.stateAt (0);
if (0 <= yystate && yystate <= yylast_
&& yycheck_[yystate] == yystack.stateAt (0))
yystate = yytable_[yystate];
else
yystate = yydefgoto_[yyn - yyntokens_];
yystack.push (yystate, yyval]b4_locations_if([, yyloc])[); yystack.push (yystate, yyval]b4_locations_if([, yyloc])[);
return YYNEWSTATE; return YYNEWSTATE;
} }
@@ -553,7 +463,6 @@ b4_define_state])[
+ (yyvaluep == null ? "(null)" : yyvaluep.toString ()) + ")"); + (yyvaluep == null ? "(null)" : yyvaluep.toString ()) + ")");
} }
]b4_push_if([],[[
/** /**
* Parse input from the scanner that was specified at object construction * Parse input from the scanner that was specified at object construction
* time. Return whether the end of the input was reached successfully. * time. Return whether the end of the input was reached successfully.
@@ -561,53 +470,46 @@ b4_define_state])[
* @@return <tt>true</tt> if the parsing succeeds. Note that this does not * @@return <tt>true</tt> if the parsing succeeds. Note that this does not
* imply that there were no syntax errors. * imply that there were no syntax errors.
*/ */
public boolean parse () ]b4_maybe_throws([b4_list2([b4_lex_throws], [b4_throws])])[]])[ public boolean parse () ]b4_maybe_throws([b4_list2([b4_lex_throws], [b4_throws])])[
]b4_push_if([
/**
* Push Parse input from external lexer
*
* @@param yylextoken current token
* @@param yylexval current lval
]b4_locations_if([ * @@param yylexloc current position])[
*
* @@return <tt>YYACCEPT, YYABORT, YYPUSH_MORE</tt>
*/
public int push_parse (int yylextoken, b4_yystype yylexval[]b4_locations_if([, b4_location_type yylexloc]))
b4_maybe_throws([b4_list2([b4_lex_throws], [b4_throws])])])[
{ {
]b4_locations_if([/* @@$. */ /// Lookahead and lookahead in internal form.
b4_location_type yyloc;])[ int yychar = yyempty_;
]b4_push_if([],[[ int yytoken = 0;
]b4_define_state[
/* State. */
int yyn = 0;
int yylen = 0;
int yystate = 0;
YYStack yystack = new YYStack ();
/* Error handling. */
int yynerrs_ = 0;
]b4_locations_if([/// The location where the error started.
]b4_location_type[ yyerrloc = null;
/// ]b4_location_type[ of the lookahead.
]b4_location_type[ yylloc = new ]b4_location_type[ (null, null);
/// @@$.
]b4_location_type[ yyloc;])
/// Semantic value of the lookahead.
b4_yystype[ yylval = null;
yycdebug ("Starting parse\n"); yycdebug ("Starting parse\n");
yyerrstatus_ = 0; yyerrstatus_ = 0;
/* Initialize the stack. */
yystack.push (yystate, yylval ]b4_locations_if([, yylloc])[);
]m4_ifdef([b4_initial_action], [ ]m4_ifdef([b4_initial_action], [
b4_dollar_pushdef([yylval], [], [yylloc])dnl b4_dollar_pushdef([yylval], [], [yylloc])dnl
/* User initialization code. */ /* User initialization code. */
b4_user_initial_action b4_user_initial_action
b4_dollar_popdef[]dnl b4_dollar_popdef])[]dnl
])[
]])[
]b4_push_if([[
if (!this.push_parse_initialized)
{
push_parse_initialize ();
]m4_ifdef([b4_initial_action], [
b4_dollar_pushdef([yylval], [], [yylloc])dnl
/* User initialization code. */
b4_user_initial_action
b4_dollar_popdef[]dnl
])[
yycdebug ("Starting parse\n");
yyerrstatus_ = 0;
} else
label = YYGETTOKEN;
boolean push_token_consumed = true; [ /* Initialize the stack. */
]])[ yystack.push (yystate, yylval]b4_locations_if([, yylloc])[);
int label = YYNEWSTATE;
for (;;) for (;;)
switch (label) switch (label)
{ {
@@ -620,8 +522,7 @@ b4_dollar_popdef[]dnl
/* Accept? */ /* Accept? */
if (yystate == yyfinal_) if (yystate == yyfinal_)
]b4_push_if([{label = YYACCEPT; break;}], return true;
[return true;])[
/* Take a decision. First try without lookahead. */ /* Take a decision. First try without lookahead. */
yyn = yypact_[yystate]; yyn = yypact_[yystate];
@@ -630,27 +531,16 @@ b4_dollar_popdef[]dnl
label = YYDEFAULT; label = YYDEFAULT;
break; break;
} }
]b4_push_if([ /* Fall Through */
case YYGETTOKEN:])[
/* Read a lookahead token. */ /* Read a lookahead token. */
if (yychar == yyempty_) if (yychar == yyempty_)
{ {
]b4_push_if([[
if (!push_token_consumed)
return YYPUSH_MORE;
yycdebug ("Reading a token: "); yycdebug ("Reading a token: ");
yychar = yylextoken; yychar = yylexer.yylex ();]
yylval = yylexval;]b4_locations_if([ b4_locations_if([[
yylloc = yylexloc;])[ yylloc = new ]b4_location_type[(yylexer.getStartPos (),
push_token_consumed = false;]])[ yylexer.getEndPos ());]])
]b4_push_if([],[[ yylval = yylexer.getLVal ();[
yycdebug ("Reading a token: ");
yychar = yylexer.yylex ();
yylval = yylexer.getLVal ();]b4_locations_if([
yylloc = new b4_location_type (yylexer.getStartPos (),
yylexer.getEndPos ());])[
]])[
} }
/* Convert token to internal form. */ /* Convert token to internal form. */
@@ -747,10 +637,10 @@ b4_dollar_popdef[]dnl
{ {
/* Return failure if at end of input. */ /* Return failure if at end of input. */
if (yychar == Lexer.EOF) if (yychar == Lexer.EOF)
]b4_push_if([{label = YYABORT; break;}],[return false;])[ return false;
} }
else else
yychar = yyempty_; yychar = yyempty_;
} }
/* Else will try to reuse lookahead token after shifting the error /* Else will try to reuse lookahead token after shifting the error
@@ -758,9 +648,9 @@ b4_dollar_popdef[]dnl
label = YYERRLAB1; label = YYERRLAB1;
break; break;
/*-------------------------------------------------. /*---------------------------------------------------.
| errorlab -- error raised explicitly by YYERROR. | | errorlab -- error raised explicitly by YYERROR. |
`-------------------------------------------------*/ `---------------------------------------------------*/
case YYERROR: case YYERROR:
]b4_locations_if([yyerrloc = yystack.locationAt (yylen - 1);])[ ]b4_locations_if([yyerrloc = yystack.locationAt (yylen - 1);])[
@@ -792,10 +682,9 @@ b4_dollar_popdef[]dnl
} }
} }
/* Pop the current state because it cannot handle the /* Pop the current state because it cannot handle the error token. */
* error token. */
if (yystack.height == 0) if (yystack.height == 0)
]b4_push_if([{label = YYABORT; break;}],[return false;])[ return false;
]b4_locations_if([yyerrloc = yystack.locationAt (0);])[ ]b4_locations_if([yyerrloc = yystack.locationAt (0);])[
yystack.pop (); yystack.pop ();
@@ -804,11 +693,7 @@ b4_dollar_popdef[]dnl
yystack.print (yyDebugStream); yystack.print (yyDebugStream);
} }
if (label == YYABORT) ]b4_locations_if([
/* Leave the switch. */
break;
]b4_locations_if([
/* Muck with the stack to setup for yylloc. */ /* Muck with the stack to setup for yylloc. */
yystack.push (0, null, yylloc); yystack.push (0, null, yylloc);
yystack.push (0, null, yyerrloc); yystack.push (0, null, yyerrloc);
@@ -826,91 +711,13 @@ b4_dollar_popdef[]dnl
/* Accept. */ /* Accept. */
case YYACCEPT: case YYACCEPT:
]b4_push_if([this.push_parse_initialized = false; return YYACCEPT;], return true;
[return true;])[
/* Abort. */ /* Abort. */
case YYABORT: case YYABORT:
]b4_push_if([this.push_parse_initialized = false; return YYABORT;], return false;
[return false;])[
} }
}
]b4_push_if([[
boolean push_parse_initialized = false;
/**
* (Re-)Initialize the state of the push parser.
*/
public void push_parse_initialize()
{
/* Lookahead and lookahead in internal form. */
this.yychar = yyempty_;
this.yytoken = 0;
/* State. */
this.yyn = 0;
this.yylen = 0;
this.yystate = 0;
this.yystack = new YYStack ();
this.label = YYNEWSTATE;
/* Error handling. */
this.yynerrs_ = 0;
]b4_locations_if([/* The location where the error started. */
this.yyerrloc = null;
this.yylloc = new b4_location_type (null, null);])[
/* Semantic value of the lookahead. */
this.yylval = null;
yystack.push (this.yystate, this.yylval]b4_locations_if([, this.yylloc])[);
this.push_parse_initialized = true;
} }
]b4_locations_if([
/**
* Push parse given input from an external lexer.
*
* @@param yylextoken current token
* @@param yylexval current lval
* @@param yyylexpos current position
*
* @@return <tt>YYACCEPT, YYABORT, YYPUSH_MORE</tt>
*/
public int push_parse (int yylextoken, b4_yystype yylexval, b4_position_type yylexpos)
b4_maybe_throws([b4_list2([b4_lex_throws], [b4_throws])])
{
return push_parse (yylextoken, yylexval, new b4_location_type (yylexpos));
}
])[]])
b4_both_if([[
/**
* Parse input from the scanner that was specified at object construction
* time. Return whether the end of the input was reached successfully.
* This version of parse () is defined only when api.push-push=both.
*
* @@return <tt>true</tt> if the parsing succeeds. Note that this does not
* imply that there were no syntax errors.
*/
public boolean parse () ]b4_maybe_throws([b4_list2([b4_lex_throws], [b4_throws])])[
{
if (yylexer == null)
throw new NullPointerException("Null Lexer");
int status;
do {
int token = yylexer.yylex();
]b4_yystype[ lval = yylexer.getLVal();
]b4_locations_if([dnl
b4_location_type yyloc = new b4_location_type (yylexer.getStartPos (),
yylexer.getEndPos ());])[
]b4_locations_if([status = push_parse(token,lval,yyloc);],[
status = push_parse(token,lval);])[
} while (status == YYPUSH_MORE);
return (status == YYACCEPT);
}
]])[
// Generate an error message. // Generate an error message.
private String yysyntax_error (int yystate, int tok) private String yysyntax_error (int yystate, int tok)
@@ -945,8 +752,8 @@ b4_both_if([[
*/ */
if (tok != yyempty_) if (tok != yyempty_)
{ {
/* FIXME: This method of building the message is not compatible // FIXME: This method of building the message is not compatible
with internationalization. */ // with internationalization.
StringBuffer res = StringBuffer res =
new StringBuffer ("syntax error, unexpected "); new StringBuffer ("syntax error, unexpected ");
res.append (yytnamerr_ (yytname_[tok])); res.append (yytnamerr_ (yytname_[tok]));
@@ -995,9 +802,8 @@ b4_both_if([[
} }
/** /**
* Whether the given <code>yytable_</code> * Whether the given <code>yytable_</code> value indicates a syntax error.
* value indicates a syntax error. * @@param yyvalue the value to check
* @@param yyvalue the value to check
*/ */
private static boolean yy_table_value_is_error_ (int yyvalue) private static boolean yy_table_value_is_error_ (int yyvalue)
{ {
@@ -1019,7 +825,6 @@ b4_both_if([[
]b4_integral_parser_table_define([rline], [b4_rline], ]b4_integral_parser_table_define([rline], [b4_rline],
[[YYRLINE[YYN] -- Source line where rule number YYN was defined.]])[ [[YYRLINE[YYN] -- Source line where rule number YYN was defined.]])[
// Report on the debug stream that the rule yyrule is going to be reduced. // Report on the debug stream that the rule yyrule is going to be reduced.
private void yy_reduce_print (int yyrule, YYStack yystack) private void yy_reduce_print (int yyrule, YYStack yystack)
{ {
+27 -46
View File
@@ -25,9 +25,10 @@ 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_NULLPTR, 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,
unsigned int c = ]b4_location_initial_column[u) unsigned int c = ]b4_location_initial_column[u)
: filename (f) : filename (f)
@@ -38,7 +39,7 @@ m4_define([b4_position_define],
]])[ ]])[
/// Initialization. /// Initialization.
void initialize (]b4_percent_define_get([[filename_type]])[* fn = YY_NULLPTR, void initialize (]b4_percent_define_get([[filename_type]])[* fn = YY_NULL,
unsigned int l = ]b4_location_initial_line[u, unsigned int l = ]b4_location_initial_line[u,
unsigned int c = ]b4_location_initial_column[u) unsigned int c = ]b4_location_initial_column[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.
@@ -178,7 +168,7 @@ m4_define([b4_location_define],
])[ ])[
/// Initialization. /// Initialization.
void initialize (]b4_percent_define_get([[filename_type]])[* f = YY_NULLPTR, void initialize (]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,
unsigned int c = ]b4_location_initial_column[u) unsigned int c = ]b4_location_initial_column[u)
{ {
@@ -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_;
}; };
+41 -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_NULLPTR)])[ : 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.
@@ -178,10 +178,11 @@ m4_define([b4_variant_define],
template <typename T> template <typename T>
void void
move (self_type& other) move (self_type& other)
{ {]b4_parse_assert_if([
build<T> (); YYASSERT (!tname);])[
swap<T> (other); build<T>();
other.destroy<T> (); swap<T>(other);
other.destroy<T>();
} }
/// Copy the content of \a other to this. /// Copy the content of \a other to this.
@@ -198,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_NULLPTR;])[ tname = YY_NULL;])[
} }
private: private:
@@ -206,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;])[
}; };
]]) ]])
@@ -243,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
]) ])
@@ -262,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])
@@ -270,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])])
@@ -320,13 +304,14 @@ b4_join(b4_symbol_if([$1], [has_type],
return symbol_type (b4_join([token::b4_symbol([$1], [id])], return symbol_type (b4_join([token::b4_symbol([$1], [id])],
b4_symbol_if([$1], [has_type], [v]), b4_symbol_if([$1], [has_type], [v]),
b4_locations_if([l]))); b4_locations_if([l])));
} }
])])]) ])])])
# 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 -5
View File
@@ -201,8 +201,6 @@
<xsl:if test="$point = 0"> <xsl:if test="$point = 0">
<xsl:text> .</xsl:text> <xsl:text> .</xsl:text>
</xsl:if> </xsl:if>
<!-- RHS -->
<xsl:for-each select="rhs/symbol|rhs/empty"> <xsl:for-each select="rhs/symbol|rhs/empty">
<xsl:apply-templates select="."/> <xsl:apply-templates select="."/>
<xsl:if test="$point = position()"> <xsl:if test="$point = position()">
@@ -216,9 +214,7 @@
<xsl:value-of select="."/> <xsl:value-of select="."/>
</xsl:template> </xsl:template>
<xsl:template match="empty"> <xsl:template match="empty"/>
<xsl:text> %empty</xsl:text>
</xsl:template>
<xsl:template match="lookaheads"> <xsl:template match="lookaheads">
<xsl:text> [</xsl:text> <xsl:text> [</xsl:text>
+7 -2
View File
@@ -350,7 +350,12 @@
<xsl:if test="position() = $point + 1"> <xsl:if test="position() = $point + 1">
<xsl:text> .</xsl:text> <xsl:text> .</xsl:text>
</xsl:if> </xsl:if>
<xsl:apply-templates select="."/> <xsl:if test="$itemset = 'true' and name(.) != 'empty'">
<xsl:apply-templates select="."/>
</xsl:if>
<xsl:if test="$itemset != 'true'">
<xsl:apply-templates select="."/>
</xsl:if>
<xsl:if test="position() = last() and position() = $point"> <xsl:if test="position() = last() and position() = $point">
<xsl:text> .</xsl:text> <xsl:text> .</xsl:text>
</xsl:if> </xsl:if>
@@ -368,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">
+7 -2
View File
@@ -532,7 +532,12 @@
<xsl:text> </xsl:text> <xsl:text> </xsl:text>
<span class="point">.</span> <span class="point">.</span>
</xsl:if> </xsl:if>
<xsl:apply-templates select="."/> <xsl:if test="$itemset = 'true' and name(.) != 'empty'">
<xsl:apply-templates select="."/>
</xsl:if>
<xsl:if test="$itemset != 'true'">
<xsl:apply-templates select="."/>
</xsl:if>
<xsl:if test="position() = last() and position() = $point"> <xsl:if test="position() = last() and position() = $point">
<xsl:text> </xsl:text> <xsl:text> </xsl:text>
<span class="point">.</span> <span class="point">.</span>
@@ -558,7 +563,7 @@
</xsl:template> </xsl:template>
<xsl:template match="empty"> <xsl:template match="empty">
<xsl:text> %empty</xsl:text> <xsl:text> &#949;</xsl:text>
</xsl:template> </xsl:template>
<xsl:template match="lookaheads"> <xsl:template match="lookaheads">
+45 -22
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. ##
## ----------- ## ## ----------- ##
@@ -175,19 +176,36 @@ m4_define([b4_declare_scanner_communication_variables], [[
int yychar; int yychar;
]b4_pure_if([[ ]b4_pure_if([[
/* The semantic value of the lookahead symbol. */ #if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__
/* Suppress an incorrect diagnostic about yylval being uninitialized. */
# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
_Pragma ("GCC diagnostic push") \
_Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\
_Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"")
# define YY_IGNORE_MAYBE_UNINITIALIZED_END \
_Pragma ("GCC diagnostic pop")
#else
/* Default value used for initialization, for pacifying older GCCs /* Default value used for initialization, for pacifying older GCCs
or non-GCC compilers. */ or non-GCC compilers. */
YY_INITIAL_VALUE (static YYSTYPE yyval_default;) static YYSTYPE yyval_default;
YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);]b4_locations_if([[ # define YY_INITIAL_VALUE(Value) = Value
#endif]b4_locations_if([[
static YYLTYPE yyloc_default][]b4_yyloc_default[;]])])[
#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
# define YY_IGNORE_MAYBE_UNINITIALIZED_END
#endif
#ifndef YY_INITIAL_VALUE
# define YY_INITIAL_VALUE(Value) /* Nothing. */
#endif
/* The semantic value of the lookahead symbol. */
YYSTYPE yylval YY_INITIAL_VALUE(yyval_default);]b4_locations_if([[
/* Location data for the lookahead symbol. */ /* Location data for the lookahead symbol. */
static YYLTYPE yyloc_default]b4_yyloc_default[; YYLTYPE yylloc]b4_pure_if([ = yyloc_default], [b4_yyloc_default])[;
YYLTYPE yylloc = yyloc_default;]])], ]])b4_pure_if([], [[
[[/* The semantic value of the lookahead symbol. */
YYSTYPE yylval;]b4_locations_if([[
/* Location data for the lookahead symbol. */
YYLTYPE yylloc]b4_yyloc_default[;]])[
/* Number of syntax errors so far. */ /* Number of syntax errors so far. */
int yynerrs;]])]) int yynerrs;]])])
@@ -205,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. */
@@ -413,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]])[
@@ -445,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,
@@ -1108,11 +1131,11 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
]b4_lac_if([[yytype_int16 *yyesa, yytype_int16 **yyes, ]b4_lac_if([[yytype_int16 *yyesa, yytype_int16 **yyes,
YYSIZE_T *yyes_capacity, ]])[yytype_int16 *yyssp, int yytoken) YYSIZE_T *yyes_capacity, ]])[yytype_int16 *yyssp, int yytoken)
{ {
YYSIZE_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]); YYSIZE_T yysize0 = yytnamerr (YY_NULL, yytname[yytoken]);
YYSIZE_T yysize = yysize0; YYSIZE_T yysize = yysize0;
enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
/* Internationalized format string. */ /* Internationalized format string. */
const char *yyformat = YY_NULLPTR; const char *yyformat = YY_NULL;
/* Arguments of yyformat. */ /* Arguments of yyformat. */
char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
/* Number of reported tokens (one for the "unexpected", one per /* Number of reported tokens (one for the "unexpected", one per
@@ -1187,7 +1210,7 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
} }
yyarg[yycount++] = yytname[yyx]; yyarg[yycount++] = yytname[yyx];
{ {
YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]); YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULL, yytname[yyx]);
if (! (yysize <= yysize1 if (! (yysize <= yysize1
&& yysize1 <= YYSTACK_ALLOC_MAXIMUM)) && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
return 2; return 2;
@@ -1271,7 +1294,7 @@ static char yypstate_allocated = 0;]])b4_pull_if([
b4_function_define([[yyparse]], [[int]], b4_parse_param)[ b4_function_define([[yyparse]], [[int]], b4_parse_param)[
{ {
return yypull_parse (YY_NULLPTR]m4_ifset([b4_parse_param], return yypull_parse (YY_NULL]m4_ifset([b4_parse_param],
[[, ]b4_args(b4_parse_param)])[); [[, ]b4_args(b4_parse_param)])[);
} }
@@ -1313,10 +1336,10 @@ b4_function_define([[yyparse]], [[int]], b4_parse_param)[
{ {
yypstate *yyps;]b4_pure_if([], [[ yypstate *yyps;]b4_pure_if([], [[
if (yypstate_allocated) if (yypstate_allocated)
return YY_NULLPTR;]])[ return YY_NULL;]])[
yyps = (yypstate *) malloc (sizeof *yyps); yyps = (yypstate *) malloc (sizeof *yyps);
if (!yyps) if (!yyps)
return YY_NULLPTR; return YY_NULL;
yyps->yynew = 1;]b4_pure_if([], [[ yyps->yynew = 1;]b4_pure_if([], [[
yypstate_allocated = 1;]])[ yypstate_allocated = 1;]])[
return yyps; return yyps;
@@ -1631,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
@@ -1679,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. */
+312 -718
View File
File diff suppressed because it is too large Load Diff
-2
View File
@@ -1,2 +0,0 @@
This file is a stub, not used by the documentation. If you feel like
contributing ASCII art for example.gv, please step forward!
+14 -17
View File
@@ -23,10 +23,9 @@ doc_bison_TEXINFOS = \
# Cannot express dependencies directly on file names because of Automake. # Cannot express dependencies directly on file names because of Automake.
# Obfuscate with a variable. # Obfuscate with a variable.
doc_bison = doc/bison doc_bison = doc/bison
$(doc_bison).dvi: $(FIGS_GV:.gv=.eps) $(doc_bison).dvi: $(FIGS_DOT:.dot=.eps)
$(doc_bison).info: $(FIGS_GV:.gv=.txt) $(doc_bison).pdf: $(FIGS_DOT:.dot=.pdf)
$(doc_bison).pdf: $(FIGS_GV:.gv=.pdf) $(doc_bison).html: $(FIGS_DOT:.dot=.png)
$(doc_bison).html: $(FIGS_GV:.gv=.png)
TEXI2DVI = texi2dvi --build-dir=doc/bison.t2d -I doc TEXI2DVI = texi2dvi --build-dir=doc/bison.t2d -I doc
CLEANDIRS = doc/bison.t2d CLEANDIRS = doc/bison.t2d
@@ -38,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 $@; } >$@~
@@ -118,34 +117,32 @@ $(top_srcdir)/doc/bison.1: doc/bison.help doc/bison.x $(top_srcdir)/configure
fi fi
$(AM_V_at)rm -f $@*.t $(AM_V_at)rm -f $@*.t
if ENABLE_YACC
nodist_man_MANS = doc/yacc.1 nodist_man_MANS = doc/yacc.1
endif
## ----------------------------- ## ## ----------------------------- ##
## Graphviz examples generation. ## ## Graphviz examples generation. ##
## ----------------------------- ## ## ----------------------------- ##
CLEANDIRS += doc/figs CLEANDIRS += doc/figs
FIGS_GV = \ FIGS_DOT = \
doc/figs/example.gv \ doc/figs/example.dot \
doc/figs/example-reduce.gv doc/figs/example-shift.gv doc/figs/example-reduce.dot doc/figs/example-shift.dot
EXTRA_DIST += \ EXTRA_DIST += \
$(FIGS_GV) $(FIGS_GV:.gv=.txt) \ $(FIGS_DOT) \
$(FIGS_GV:.gv=.eps) $(FIGS_GV:.gv=.pdf) $(FIGS_GV:.gv=.png) $(FIGS_DOT:.dot=.eps) $(FIGS_DOT:.dot=.pdf) $(FIGS_DOT:.dot=.png)
SUFFIXES += .gv .eps .pdf .png SUFFIXES += .dot .eps .pdf .png
.gv.eps: .dot.eps:
$(AM_V_GEN) $(MKDIR_P) `echo "./$@" | sed -e 's,/[^/]*$$,,'` $(AM_V_GEN) $(MKDIR_P) `echo "./$@" | sed -e 's,/[^/]*$$,,'`
$(AM_V_at) $(DOT) -Gmargin=0 -Teps $< >$@.tmp $(AM_V_at) $(DOT) -Gmargin=0 -Teps $< >$@.tmp
$(AM_V_at) mv $@.tmp $@ $(AM_V_at) mv $@.tmp $@
.gv.pdf: .dot.pdf:
$(AM_V_GEN) $(MKDIR_P) `echo "./$@" | sed -e 's,/[^/]*$$,,'` $(AM_V_GEN) $(MKDIR_P) `echo "./$@" | sed -e 's,/[^/]*$$,,'`
$(AM_V_at) $(DOT) -Gmargin=0 -Tpdf $< >$@.tmp $(AM_V_at) $(DOT) -Gmargin=0 -Tpdf $< >$@.tmp
$(AM_V_at) mv $@.tmp $@ $(AM_V_at) mv $@.tmp $@
.gv.png: .dot.png:
$(AM_V_GEN) $(MKDIR_P) `echo "./$@" | sed -e 's,/[^/]*$$,,'` $(AM_V_GEN) $(MKDIR_P) `echo "./$@" | sed -e 's,/[^/]*$$,,'`
$(AM_V_at) $(DOT) -Gmargin=0 -Tpng $< >$@.tmp $(AM_V_at) $(DOT) -Gmargin=0 -Tpng $< >$@.tmp
$(AM_V_at) mv $@.tmp $@ $(AM_V_at) mv $@.tmp $@
+2 -2
View File
@@ -204,9 +204,9 @@ Format the list of directives for Bison for bench named C<$bench>.
sub directives($@) 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;
} }
+31 -32
View File
@@ -19,7 +19,7 @@
# Don't depend on $(BISON) otherwise we would rebuild these files # Don't depend on $(BISON) otherwise we would rebuild these files
# in srcdir, including during distcheck, which is forbidden. # in srcdir, including during distcheck, which is forbidden.
%D%/calc++-parser.stamp: $(BISON_IN) examples/calc++/calc++-parser.stamp: $(BISON_IN)
SUFFIXES += .yy .stamp SUFFIXES += .yy .stamp
.yy.stamp: .yy.stamp:
$(AM_V_YACC)rm -f $@ $(AM_V_YACC)rm -f $@
@@ -27,14 +27,14 @@ SUFFIXES += .yy .stamp
$(AM_V_at)$(YACCCOMPILE) -o $*.cc $< $(AM_V_at)$(YACCCOMPILE) -o $*.cc $<
$(AM_V_at)mv -f $@.tmp $@ $(AM_V_at)mv -f $@.tmp $@
$(calc_sources_generated): %D%/calc++-parser.stamp $(calc_sources_generated): examples/calc++/calc++-parser.stamp
@test -f $@ || rm -f %D%/calc++-parser.stamp @test -f $@ || rm -f examples/calc++/calc++-parser.stamp
@test -f $@ || $(MAKE) $(AM_MAKEFLAGS) %D%/calc++-parser.stamp @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) examples/calc++/calc++-parser.stamp
CLEANFILES += \ CLEANFILES += \
$(calc_sources_generated) \ $(calc_sources_generated) \
%D%/calc++-parser.output \ examples/calc++/calc++-parser.output \
%D%/calc++-parser.stamp \ examples/calc++/calc++-parser.stamp \
%D%/calc++-scanner.cc examples/calc++/calc++-scanner.cc
## -------------------- ## ## -------------------- ##
@@ -42,35 +42,34 @@ CLEANFILES += \
## -------------------- ## ## -------------------- ##
# Avoid using BUILT_SOURCES which is too global. # Avoid using BUILT_SOURCES which is too global.
$(%C%_calc___OBJECTS): $(calc_sources_generated) $(examples_calc___calc___OBJECTS): $(calc_sources_generated)
calc_sources_extracted = \ calc_sources_extracted = \
%D%/calc++-driver.cc \ examples/calc++/calc++-driver.cc \
%D%/calc++-driver.hh \ examples/calc++/calc++-driver.hh \
%D%/calc++-scanner.ll \ examples/calc++/calc++-scanner.ll \
%D%/calc++.cc examples/calc++/calc++.cc
calc_extracted = \ calc_extracted = \
$(calc_sources_extracted) \ $(calc_sources_extracted) \
%D%/calc++-parser.yy examples/calc++/calc++-parser.yy
extracted += $(calc_extracted) extracted += $(calc_extracted)
calc_sources_generated = \ calc_sources_generated = \
%D%/calc++-parser.cc \ examples/calc++/calc++-parser.cc \
%D%/calc++-parser.hh \ examples/calc++/calc++-parser.hh \
%D%/location.hh \ examples/calc++/location.hh \
%D%/position.hh \ examples/calc++/position.hh \
%D%/stack.hh examples/calc++/stack.hh
calc_sources = \ calc_sources = \
$(calc_sources_extracted) \ $(calc_sources_extracted) \
$(calc_sources_generated) $(calc_sources_generated)
if FLEX_CXX_WORKS if BISON_CXX_WORKS
check_PROGRAMS += %D%/calc++ check_PROGRAMS += examples/calc++/calc++
nodist_%C%_calc___SOURCES = \ nodist_examples_calc___calc___SOURCES = \
$(calc_sources) $(calc_sources)
%C%_calc___CPPFLAGS = -I$(top_builddir)/%D% examples_calc___calc___CPPFLAGS = -I$(top_builddir)/examples/calc++
%C%_calc___CXXFLAGS = $(AM_CXXFLAGS) $(FLEX_SCANNER_CXXFLAGS) examples_calc___calc___CXXFLAGS = \
dist_TESTS += %D%/calc++.test $(AM_CXXFLAGS) $(WARN_NO_NULL_CONVERSION_CXXFLAGS)
else dist_TESTS += examples/calc++/calc++.test
EXTRA_DIST += %D%/calc++.test
endif endif
+13 -12
View File
@@ -13,10 +13,11 @@
# 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/>.
dist_noinst_SCRIPTS = %D%/extexi %D%/test dist_noinst_SCRIPTS = examples/extexi examples/test
TEST_LOG_COMPILER = $(top_srcdir)/%D%/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)
## ------------ ## ## ------------ ##
@@ -24,20 +25,20 @@ AM_CXXFLAGS = \
## ------------ ## ## ------------ ##
doc = $(top_srcdir)/doc/bison.texi doc = $(top_srcdir)/doc/bison.texi
extexi = $(top_srcdir)/%D%/extexi extexi = $(top_srcdir)/examples/extexi
extract = VERSION="$(VERSION)" $(PERL) $(extexi) $(doc) -- extract = VERSION="$(VERSION)" $(PERL) -f $(extexi) $(doc) --
extracted = extracted =
CLEANFILES += $(extracted) %D%/extracted.stamp CLEANFILES += $(extracted) examples/extracted.stamp
%D%/extracted.stamp: $(doc) $(extexi) examples/extracted.stamp: $(doc) $(extexi)
$(AM_V_GEN)rm -f $@ $@.tmp $(AM_V_GEN)rm -f $@ $@.tmp
$(AM_V_at)touch $@.tmp $(AM_V_at)touch $@.tmp
$(AM_V_at)$(extract) $(extracted) $(AM_V_at)$(extract) $(extracted)
$(AM_V_at)mv $@.tmp $@ $(AM_V_at)mv $@.tmp $@
$(extracted): %D%/extracted.stamp $(extracted): examples/extracted.stamp
@test -f $@ || rm -f %D%/extracted.stamp @test -f $@ || rm -f examples/extracted.stamp
@test -f $@ || $(MAKE) $(AM_MAKEFLAGS) %D%/extracted.stamp @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) examples/extracted.stamp
include %D%/calc++/local.mk include examples/calc++/local.mk
include %D%/mfcalc/local.mk include examples/mfcalc/local.mk
include %D%/rpcalc/local.mk include examples/rpcalc/local.mk
+12 -8
View File
@@ -18,15 +18,19 @@
## -------------------- ## ## -------------------- ##
BUILT_SOURCES += $(mfcalc_sources) BUILT_SOURCES += $(mfcalc_sources)
CLEANFILES += %D%/mfcalc.[ch] %D%/mfcalc.output CLEANFILES += examples/mfcalc/mfcalc.[ch] examples/mfcalc/mfcalc.output
mfcalc_extracted = %D%/calc.h %D%/mfcalc.y mfcalc_extracted = \
mfcalc_sources = $(mfcalc_extracted) examples/mfcalc/calc.h \
examples/mfcalc/mfcalc.y
mfcalc_sources = \
$(mfcalc_extracted)
extracted += $(mfcalc_extracted) extracted += $(mfcalc_extracted)
check_PROGRAMS += %D%/mfcalc check_PROGRAMS += examples/mfcalc/mfcalc
%C%_mfcalc_LDADD = -lm examples_mfcalc_mfcalc_LDADD = -lm
nodist_%C%_mfcalc_SOURCES = $(mfcalc_sources) nodist_examples_mfcalc_mfcalc_SOURCES = \
$(mfcalc_sources)
%C%_mfcalc_CPPFLAGS = -I$(top_builddir)/%D% examples_mfcalc_mfcalc_CPPFLAGS = -I$(top_builddir)/examples/mfcalc
dist_TESTS += %D%/mfcalc.test dist_TESTS += examples/mfcalc/mfcalc.test
-1
View File
@@ -1,5 +1,4 @@
/calc.h /calc.h
/rpcalc
/rpcalc.c /rpcalc.c
/rpcalc.h /rpcalc.h
/rpcalc.output /rpcalc.output
+11 -8
View File
@@ -18,15 +18,18 @@
## -------------------- ## ## -------------------- ##
BUILT_SOURCES += $(rpcalc_sources) BUILT_SOURCES += $(rpcalc_sources)
CLEANFILES += %D%/rpcalc.[ch] %D%/rpcalc.output CLEANFILES += examples/rpcalc/rpcalc.[ch] examples/rpcalc/rpcalc.output
rpcalc_extracted = %D%/rpcalc.y rpcalc_extracted = \
rpcalc_sources = $(rpcalc_extracted) examples/rpcalc/rpcalc.y
rpcalc_sources = \
$(rpcalc_extracted)
extracted += $(rpcalc_extracted) extracted += $(rpcalc_extracted)
check_PROGRAMS += %D%/rpcalc check_PROGRAMS += examples/rpcalc/rpcalc
%C%_rpcalc_LDADD = -lm examples_rpcalc_rpcalc_LDADD = -lm
nodist_%C%_rpcalc_SOURCES = $(rpcalc_sources) nodist_examples_rpcalc_rpcalc_SOURCES = \
$(rpcalc_sources)
%C%_rpcalc_CPPFLAGS = -I$(top_builddir)/%D% examples_rpcalc_rpcalc_CPPFLAGS = -I$(top_builddir)/examples/rpcalc
dist_TESTS += %D%/rpcalc.test dist_TESTS += examples/rpcalc/rpcalc.test
+5 -11
View File
@@ -16,7 +16,7 @@
*/ */
%debug %debug
%language "c++" %skeleton "lalr1.cc"
%defines %defines
%define api.token.constructor %define api.token.constructor
%define api.value.type variant %define api.value.type variant
@@ -48,17 +48,11 @@ typedef std::list<std::string> strings_type;
namespace std namespace std
{ {
std::ostream& std::ostream&
operator<< (std::ostream& o, const strings_type& ss) operator<< (std::ostream& o, const strings_type& s)
{ {
o << "(" << &ss << ") {"; std::copy (s.begin (), s.end (),
const char *sep = ""; std::ostream_iterator<strings_type::value_type> (o, "\n"));
for (strings_type::const_iterator i = ss.begin(), end = ss.end(); return o;
i != end; ++i)
{
o << sep << *i;
sep = ", ";
}
return o << "}";
} }
} }
+1 -1
Submodule gnulib updated: 74540d44dc...c67e3c0414
-2
View File
@@ -272,5 +272,3 @@
/sig-handler.c /sig-handler.c
/unistd.c /unistd.c
/wctype-h.c /wctype-h.c
/lstat.c
/unlink.c
+1 -1
View File
@@ -17,7 +17,7 @@
/* Bison depends on libiberty's implementation of bitsets, which /* 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 -3
View File
@@ -51,8 +51,6 @@ lib_libbison_a_SOURCES += \
lib/get-errno.c lib/get-errno.c
# The Yacc compatibility library. # The Yacc compatibility library.
if ENABLE_YACC lib_LIBRARIES = $(YACC_LIBRARY)
lib_LIBRARIES = lib/liby.a
EXTRA_LIBRARIES = lib/liby.a EXTRA_LIBRARIES = lib/liby.a
lib_liby_a_SOURCES = lib/main.c lib/yyerror.c lib_liby_a_SOURCES = lib/main.c lib/yyerror.c
endif
+1 -1
View File
@@ -36,7 +36,7 @@
Timing variables may be pushed onto the stack; elapsed time is 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
-3
View File
@@ -180,6 +180,3 @@
/obstack-printf.m4 /obstack-printf.m4
/extern-inline.m4 /extern-inline.m4
/non-recursive-gnulib-prefix-hack.m4 /non-recursive-gnulib-prefix-hack.m4
/absolute-header.m4
/lstat.m4
/unlink.m4
+3 -7
View File
@@ -541,13 +541,9 @@ AnnotationList__compute_from_inadequacies (
{ {
InadequacyList__prependTo (conflict_node, InadequacyList__prependTo (conflict_node,
&inadequacy_lists[s->number]); &inadequacy_lists[s->number]);
{ aver (AnnotationList__insertInto (
bool b = annotation_node, &annotation_lists[s->number],
AnnotationList__insertInto (annotation_node, s->nitems));
&annotation_lists[s->number],
s->nitems);
aver (b);
}
/* This aver makes sure the /* This aver makes sure the
AnnotationList__computeDominantContribution check above AnnotationList__computeDominantContribution check above
does discard annotations in the simplest case of a S/R does discard annotations in the simplest case of a S/R
+1 -1
View File
@@ -60,7 +60,7 @@ Sbitset__isEmpty (Sbitset self, Sbitset__Index nbits)
} }
void 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)) \
+40 -237
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,225 +30,44 @@
#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;
/** Whether -Werror/-Wno-error was applied to a warning. */
typedef enum
{
errority_unset = 0, /** No explict status. */
errority_disabled = 1, /** Explictly disabled with -Wno-error=foo. */
errority_enabled = 2 /** Explictly enabled with -Werror=foo. */
} errority;
/** For each warning type, its errority. */
static errority errority_flag[warnings_size];
/** Diagnostics severity. */
typedef enum
{
severity_disabled = 0, /**< Explicitly disabled via -Wno-foo. */
severity_unset = 1, /**< Unspecified status. */
severity_warning = 2, /**< A warning. */
severity_error = 3, /**< An error (continue, but die soon). */
severity_fatal = 4 /**< Fatal error (die now). */
} severity;
/** For each warning type, its severity. */
static severity warnings_flag[warnings_size];
static unsigned *indent_ptr = 0; 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;
}
size_t b;
for (b = 0; b < warnings_size; ++b)
if (value & 1 << b)
{
if (err && no)
/* -Wno-error=foo. */
errority_flag[b] = errority_disabled;
else if (err && !no)
{
/* -Werror=foo: enables -Wfoo. */
errority_flag[b] = errority_enabled;
warnings_flag[b] = severity_warning;
}
else if (no)
/* -Wno-foo. */
warnings_flag[b] = severity_disabled;
else
/* -Wfoo. */
warnings_flag[b] = severity_warning;
}
}
/** Decode a comma-separated list of arguments from -W.
*
* \param args comma separated list of effective subarguments to decode.
* If 0, then activate all the flags.
*/
void
warnings_argmatch (char *args)
{
if (args)
for (args = strtok (args, ","); args; args = strtok (NULL, ","))
if (STREQ (args, "error"))
warnings_are_errors = true;
else if (STREQ (args, "no-error"))
warnings_are_errors = false;
else
{ {
/* The length of the possible 'no-' prefix: 3, or 0. */ "midrule-values",
size_t no = STRPREFIX_LIT ("no-", args) ? 3 : 0; "yacc",
/* The length of the possible 'error=' (possibly after "conflicts-sr",
'no-') prefix: 6, or 0. */ "conflicts-rr",
size_t err = STRPREFIX_LIT ("error=", args + no) ? 6 : 0; "deprecated",
"other"
};
warning_argmatch (args, no, err); bool any = false;
} int i;
else for (i = 0; i < ARRAY_CARDINALITY (warn_names); ++i)
warning_argmatch ("all", 0, 0); if (warn_flags & 1 << i)
}
/*-----------.
| complain. |
`-----------*/
void
complain_init (void)
{
warnings warnings_default =
Wconflicts_sr | Wconflicts_rr | Wdeprecated | Wother;
size_t b;
for (b = 0; b < warnings_size; ++b)
{
warnings_flag[b] = (1 << b & warnings_default
? severity_warning
: severity_unset);
errority_flag[b] = errority_unset;
}
}
/* A diagnostic with FLAGS is about to be issued. With what severity?
(severity_fatal, severity_error, severity_disabled, or
severity_warning.) */
static severity
warning_severity (warnings flags)
{
if (flags & fatal)
/* Diagnostics about fatal errors. */
return severity_fatal;
else if (flags & complaint)
/* Diagnostics about errors. */
return severity_error;
else
{
/* Diagnostics about warnings. */
severity res = severity_disabled;
size_t b;
for (b = 0; b < warnings_size; ++b)
if (flags & 1 << b)
{ {
res = res < warnings_flag[b] ? warnings_flag[b] : res; bool err = warn_flags & errors_flag;
/* If the diagnostic is enabled, and -Werror is enabled, fprintf (stderr, "%s-W", any ? ", " : " [");
and -Wno-error=foo was not explicitly requested, this fprintf (stderr, "%s%s", err ? "error=" : "" , warn_names[i]);
is an error. */ any = true;
if (res == severity_warning
&& (errority_flag[b] == errority_enabled
|| (warnings_are_errors
&& errority_flag[b] != errority_disabled)))
res = severity_error;
} }
return res; if (any)
fprintf (stderr, "]");
} }
} }
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.
* *
* \param loc the location, defaulting to the current file, * \param loc the location, defaulting to the current file,
@@ -270,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, ": ");
@@ -290,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] != ' ')
@@ -299,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);
} }
@@ -377,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
@@ -391,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"));
}
+22 -74
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,18 +76,14 @@ 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. */ /** Warnings treated as errors shouldn't stop the execution as regular errors
void duplicate_directive (char const *directive, should (because due to their nature, it is safe to go on). Thus, there are
location first, location second); three possible execution statuses. */
/** Warnings treated as errors shouldn't stop the execution as regular
errors should (because due to their nature, it is safe to go
on). Thus, there are three possible execution statuses. */
typedef enum typedef enum
{ {
status_none, /**< No diagnostic issued so far. */ status_none,
status_warning_as_error, /**< A warning was issued (but no error). */ status_warning_as_error,
status_complaint /**< An error was issued. */ status_complaint
} err_status; } err_status;
/** Whether an error was reported. */ /** Whether an error was reported. */
+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);
} }
+28 -48
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
@@ -51,36 +51,27 @@ char *spec_defines_file = NULL; /* for --defines. */
char *parser_file_name; char *parser_file_name;
/* All computed output file names. */ /* All computed output file names. */
typedef struct generated_file static char **file_names = NULL;
{ static int file_names_count = 0;
/** File name. */
char *name;
/** Whether is a generated source file (e.g., *.c, *.java...), as
opposed to the report file (e.g., *.output). When late errors
are detected, generated source files are removed. */
bool is_source;
} generated_file;
static generated_file *generated_files = NULL;
static int generated_files_size = 0;
uniqstr grammar_file = NULL; uniqstr 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;
@@ -88,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;
/*-----------------------------------------------------------------. /*-----------------------------------------------------------------.
@@ -200,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.
@@ -231,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)
{ {
@@ -279,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);
@@ -287,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)));
@@ -341,21 +332,21 @@ compute_output_file_names (void)
{ {
if (! spec_graph_file) if (! spec_graph_file)
spec_graph_file = concat2 (all_but_tab_ext, ".dot"); spec_graph_file = concat2 (all_but_tab_ext, ".dot");
output_file_name_check (&spec_graph_file, false); output_file_name_check (&spec_graph_file);
} }
if (xml_flag) if (xml_flag)
{ {
if (! spec_xml_file) if (! spec_xml_file)
spec_xml_file = concat2 (all_but_tab_ext, ".xml"); spec_xml_file = concat2 (all_but_tab_ext, ".xml");
output_file_name_check (&spec_xml_file, false); output_file_name_check (&spec_xml_file);
} }
if (report_flag) if (report_flag)
{ {
if (!spec_verbose_file) if (!spec_verbose_file)
spec_verbose_file = concat2 (all_but_tab_ext, OUTPUT_EXT); spec_verbose_file = concat2 (all_but_tab_ext, OUTPUT_EXT);
output_file_name_check (&spec_verbose_file, false); output_file_name_check (&spec_verbose_file);
} }
free (all_but_tab_ext); free (all_but_tab_ext);
@@ -364,7 +355,7 @@ compute_output_file_names (void)
} }
void void
output_file_name_check (char **file_name, bool source) output_file_name_check (char **file_name)
{ {
bool conflict = false; bool conflict = false;
if (STREQ (*file_name, grammar_file)) if (STREQ (*file_name, grammar_file))
@@ -376,11 +367,11 @@ output_file_name_check (char **file_name, bool source)
else else
{ {
int i; int i;
for (i = 0; i < generated_files_size; i++) for (i = 0; i < file_names_count; i++)
if (STREQ (generated_files[i].name, *file_name)) if (STREQ (file_names[i], *file_name))
{ {
complain (NULL, Wother, _("conflicting outputs to file %s"), complain (NULL, Wother, _("conflicting outputs to file %s"),
quote (generated_files[i].name)); quote (*file_name));
conflict = true; conflict = true;
} }
} }
@@ -391,23 +382,12 @@ output_file_name_check (char **file_name, bool source)
} }
else else
{ {
generated_files = xnrealloc (generated_files, ++generated_files_size, file_names = xnrealloc (file_names, ++file_names_count,
sizeof *generated_files); sizeof *file_names);
generated_files[generated_files_size-1].name = xstrdup (*file_name); file_names[file_names_count-1] = xstrdup (*file_name);
generated_files[generated_files_size-1].is_source = source;
} }
} }
void
unlink_generated_sources (void)
{
int i;
for (i = 0; i < generated_files_size; i++)
if (generated_files[i].is_source)
/* Ignore errors. The file might not even exist. */
unlink (generated_files[i].name);
}
void void
output_file_names_free (void) output_file_names_free (void)
{ {
@@ -420,8 +400,8 @@ output_file_names_free (void)
free (dir_prefix); free (dir_prefix);
{ {
int i; int i;
for (i = 0; i < generated_files_size; i++) for (i = 0; i < file_names_count; i++)
free (generated_files[i].name); free (file_names[i]);
} }
free (generated_files); free (file_names);
} }
+1 -9
View File
@@ -63,15 +63,7 @@ extern char *all_but_ext;
void compute_output_file_names (void); void compute_output_file_names (void);
void output_file_names_free (void); void output_file_names_free (void);
void output_file_name_check (char **file_name);
/** Record that we generate file \a file_name.
* \param source whether this is a source file (*c, *.java...)
* as opposed to a report (*.output, *.dot...).
*/
void output_file_name_check (char **file_name, bool source);
/** Remove all the generated source files. */
void unlink_generated_sources (void);
FILE *xfopen (const char *name, char const *mode); FILE *xfopen (const char *name, char const *mode);
void xfclose (FILE *ptr); void xfclose (FILE *ptr);
+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);
+24 -20
View File
@@ -67,13 +67,17 @@ static goto_number **includes;
static goto_list **lookback; static goto_list **lookback;
void void
set_goto_map (void) set_goto_map (void)
{ {
state_number s; state_number s;
goto_number *temp_map = xnmalloc (nvars + 1, sizeof *temp_map); goto_number *temp_map;
goto_map = xcalloc (nvars + 1, sizeof *goto_map); goto_map = xcalloc (nvars + 1, sizeof *goto_map);
temp_map = xnmalloc (nvars + 1, sizeof *temp_map);
ngotos = 0; ngotos = 0;
for (s = 0; s < nstates; ++s) for (s = 0; s < nstates; ++s)
{ {
@@ -128,13 +132,16 @@ set_goto_map (void)
goto_number goto_number
map_goto (state_number s0, symbol_number sym) map_goto (state_number s0, symbol_number sym)
{ {
goto_number low = goto_map[sym - ntokens]; goto_number high;
goto_number high = goto_map[sym - ntokens + 1] - 1; goto_number low;
goto_number middle;
state_number s;
low = goto_map[sym - ntokens];
high = goto_map[sym - ntokens + 1] - 1;
for (;;) for (;;)
{ {
goto_number middle;
state_number s;
aver (low <= high); aver (low <= high);
middle = (low + high) / 2; middle = (low + high) / 2;
s = from_state[middle]; s = from_state[middle];
@@ -335,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
@@ -405,6 +412,7 @@ static void
lookahead_tokens_print (FILE *out) lookahead_tokens_print (FILE *out)
{ {
state_number i; state_number i;
int j, k;
fprintf (out, "Lookahead tokens: BEGIN\n"); fprintf (out, "Lookahead tokens: BEGIN\n");
for (i = 0; i < nstates; ++i) for (i = 0; i < nstates; ++i)
{ {
@@ -413,25 +421,21 @@ lookahead_tokens_print (FILE *out)
int n_lookahead_tokens = 0; int n_lookahead_tokens = 0;
if (reds->lookahead_tokens) if (reds->lookahead_tokens)
{ for (k = 0; k < reds->num; ++k)
int j; if (reds->lookahead_tokens[k])
for (j = 0; j < reds->num; ++j) ++n_lookahead_tokens;
if (reds->lookahead_tokens[j])
++n_lookahead_tokens;
}
fprintf (out, "State %d: %d lookahead tokens\n", fprintf (out, "State %d: %d lookahead tokens\n",
i, n_lookahead_tokens); i, n_lookahead_tokens);
if (reds->lookahead_tokens) if (reds->lookahead_tokens)
{ for (j = 0; j < reds->num; ++j)
int j, k; BITSET_FOR_EACH (iter, reds->lookahead_tokens[j], k, 0)
for (j = 0; j < reds->num; ++j) {
BITSET_FOR_EACH (iter, reds->lookahead_tokens[j], k, 0) fprintf (out, " on %d (%s) -> rule %d\n",
fprintf (out, " on %d (%s) -> rule %d\n", k, symbols[k]->tag,
k, symbols[k]->tag, reds->rules[j]->number);
reds->rules[j]->number); };
}
} }
fprintf (out, "Lookahead tokens: END\n"); fprintf (out, "Lookahead tokens: END\n");
} }
+1 -3
View File
@@ -111,9 +111,7 @@ BUILT_SOURCES += \
## yacc. ## ## yacc. ##
## ------ ## ## ------ ##
if ENABLE_YACC bin_SCRIPTS = $(YACC_SCRIPT)
bin_SCRIPTS = src/yacc
endif
EXTRA_SCRIPTS = src/yacc EXTRA_SCRIPTS = src/yacc
MOSTLYCLEANFILES += src/yacc MOSTLYCLEANFILES += src/yacc
+6 -4
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. */
@@ -188,7 +190,7 @@ location_caret (location loc, FILE *out)
/* Read the actual line. Don't update the offset, so that we keep a pointer /* Read the actual line. Don't update the offset, so that we keep a pointer
to the start of the line. */ to the start of the line. */
{ {
int c = getc (caret_info.source); char c = getc (caret_info.source);
if (c != EOF) if (c != EOF)
{ {
/* Quote the file, indent by a single column. */ /* Quote the file, indent by a single column. */
@@ -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 ();
+167 -216
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,15 +278,14 @@ 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);
} }
#define COMMON_DECODE(Value) \ #define COMMON_DECODE(Value) \
case '$': \ case '$': \
++(Value); aver (*(Value) == '['); \ aver (*++(Value) == ']'); \
++(Value); aver (*(Value) == ']'); \ aver (*++(Value) == '['); \
++(Value); aver (*(Value) == '['); \
obstack_sgrow (&muscle_obstack, "$"); \ obstack_sgrow (&muscle_obstack, "$"); \
break; \ break; \
case '@': \ case '@': \
@@ -345,12 +329,13 @@ 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 == '[');
++value; aver (*value == '['); aver (*++value == '[');
while (*++value) while (*++value)
switch (*value) switch (*value)
{ {
@@ -361,16 +346,16 @@ location_decode (char const *value)
case ']': case ']':
{ {
char *boundary_str; char *boundary_str;
++value; aver (*value == ']'); aver (*++value == ']');
boundary_str = obstack_finish0 (&muscle_obstack); boundary_str = obstack_finish0 (&muscle_obstack);
switch (*++value) switch (*++value)
{ {
case ',': case ',':
boundary_set_from_string (&loc.start, boundary_str); boundary_set_from_string (&loc.start, boundary_str);
obstack_free (&muscle_obstack, boundary_str); obstack_free (&muscle_obstack, boundary_str);
++value; aver (*value == ' '); aver (*++value == ' ');
++value; aver (*value == '['); aver (*++value == '[');
++value; aver (*value == '['); aver (*++value == '[');
break; break;
case '\0': case '\0':
boundary_set_from_string (&loc.end, boundary_str); boundary_set_from_string (&loc.end, boundary_str);
@@ -392,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, "]]", "");
} }
@@ -490,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
@@ -526,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);
} }
@@ -537,120 +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. */
static
char const *
muscle_percent_define_get_raw (char const *variable, char const *field)
{
uniqstr name = muscle_name (variable, field);
char const *res = muscle_find_const (name);
if (!res)
complain (NULL, fatal, _("%s: undefined %%define variable %s"),
"muscle_percent_define_get_raw", quote (variable));
return res;
} }
char * 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"))
@@ -675,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"), "");
} }
} }
@@ -699,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)
@@ -718,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
@@ -765,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 -25
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);
} }
} }
@@ -704,11 +705,6 @@ output (void)
/* Process the selected skeleton file. */ /* Process the selected skeleton file. */
output_skeleton (); output_skeleton ();
/* If late errors were generated, destroy the generated source
files. */
if (complaint_status)
unlink_generated_sources ();
obstack_free (&format_obstack, NULL); obstack_free (&format_obstack, NULL);
} }
+724 -726
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 3.0. */ /* 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:1909 */ #line 223 "src/parse-gram.y" /* yacc.c:1932 */
#include "symlist.h"
#include "symtab.h"
#line 221 "src/parse-gram.y" /* yacc.c:1909 */
# 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:1909 */ # endif
#include "muscle-tab.h"
#line 68 "src/parse-gram.h" /* yacc.c:1909 */
#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:1909 */ #line 109 "src/parse-gram.y" /* yacc.c:1932 */
unsigned char character;
#line 186 "src/parse-gram.y" /* yacc.c:1909 */ assoc assoc;
char *code; char *code;
#line 191 "src/parse-gram.y" /* yacc.c:1909 */ char const *chars;
uniqstr uniqstr; int integer;
#line 199 "src/parse-gram.y" /* yacc.c:1909 */ named_ref *named_ref;
int integer; symbol *symbol;
#line 203 "src/parse-gram.y" /* yacc.c:1909 */ symbol_list *list;
symbol *symbol; uniqstr uniqstr;
#line 208 "src/parse-gram.y" /* yacc.c:1909 */ unsigned char character;
assoc assoc;
#line 211 "src/parse-gram.y" /* yacc.c:1909 */ #line 247 "src/parse-gram.y" /* yacc.c:1932 */
symbol_list *list;
#line 214 "src/parse-gram.y" /* yacc.c:1909 */ param_type param;
named_ref *named_ref;
#line 241 "src/parse-gram.y" /* yacc.c:1909 */ #line 423 "src/parse-gram.y" /* yacc.c:1932 */
param_type param;
#line 409 "src/parse-gram.y" /* yacc.c:1909 */
code_props_type code_type; code_props_type code_type;
#line 647 "src/parse-gram.y" /* yacc.c:1909 */
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:1909 */
}; };
# 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;
}
+40 -46
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];
/*--------------------------------. /*--------------------------------.
@@ -65,39 +64,40 @@ print_core (FILE *out, int level, state *s)
sitems = itemset; sitems = itemset;
snritems = nitemset; snritems = nitemset;
if (!snritems) if (!snritems) {
{ xml_puts (out, level, "<itemset/>");
xml_puts (out, level, "<itemset/>"); return;
return; }
}
xml_puts (out, level, "<itemset>"); xml_puts (out, level, "<itemset>");
for (i = 0; i < snritems; i++) for (i = 0; i < snritems; i++)
{ {
bool printed = false; bool printed = false;
item_number *sp1 = ritem + sitems[i]; item_number *sp;
item_number *sp = sp1; item_number *sp1;
rule *r; rule_number r;
while (0 <= *sp) sp1 = sp = ritem + sitems[i];
while (*sp >= 0)
sp++; sp++;
r = &rules[item_number_as_rule_number (*sp)]; r = item_number_as_rule_number (*sp);
sp = r->rhs; sp = rules[r].rhs;
/* Display the lookahead tokens? */ /* Display the lookahead tokens? */
if (item_number_is_rule_number (*sp1)) if (item_number_is_rule_number (*sp1))
{ {
reductions *reds = s->reductions; reductions *reds = s->reductions;
int red = state_reduction_find (s, r); int red = state_reduction_find (s, &rules[r]);
/* Print item with lookaheads if there are. */ /* Print item with lookaheads if there are. */
if (reds->lookahead_tokens && red != -1) if (reds->lookahead_tokens && red != -1)
{ {
xml_printf (out, level + 1, xml_printf (out, level + 1,
"<item rule-number=\"%d\" point=\"%d\">", "<item rule-number=\"%d\" point=\"%d\">",
r->number, sp1 - sp); rules[r].number, sp1 - sp);
state_rule_lookahead_tokens_print_xml (s, r, state_rule_lookahead_tokens_print_xml (s, &rules[r],
out, level + 2); out, level + 2);
xml_puts (out, level + 1, "</item>"); xml_puts (out, level + 1, "</item>");
printed = true; printed = true;
@@ -105,10 +105,12 @@ print_core (FILE *out, int level, state *s)
} }
if (!printed) if (!printed)
xml_printf (out, level + 1, {
"<item rule-number=\"%d\" point=\"%d\"/>", xml_printf (out, level + 1,
r->number, "<item rule-number=\"%d\" point=\"%d\"/>",
sp1 - sp); rules[r].number,
sp1 - sp);
}
} }
xml_puts (out, level, "</itemset>"); xml_puts (out, level, "</itemset>");
} }
@@ -133,11 +135,10 @@ print_transitions (state *s, FILE *out, int level)
} }
/* Nothing to report. */ /* Nothing to report. */
if (!n) if (!n) {
{ xml_puts (out, level, "<transitions/>");
xml_puts (out, level, "<transitions/>"); return;
return; }
}
/* Report lookahead tokens and shifts. */ /* Report lookahead tokens and shifts. */
xml_puts (out, level, "<transitions>"); xml_puts (out, level, "<transitions>");
@@ -188,11 +189,10 @@ print_errs (FILE *out, int level, state *s)
count = true; count = true;
/* Nothing to report. */ /* Nothing to report. */
if (!count) if (!count) {
{ xml_puts (out, level, "<errors/>");
xml_puts (out, level, "<errors/>"); return;
return; }
}
/* Report lookahead tokens and errors. */ /* Report lookahead tokens and errors. */
xml_puts (out, level, "<errors>"); xml_puts (out, level, "<errors>");
@@ -209,7 +209,7 @@ print_errs (FILE *out, int level, state *s)
/*-------------------------------------------------------------------------. /*-------------------------------------------------------------------------.
| Report a reduction of RULE on LOOKAHEAD_TOKEN (which can be 'default'). | | Report a reduction of RULE on LOOKAHEAD_TOKEN (which can be `default'). |
| If not ENABLED, the rule is masked by a shift or a reduce (S/R and | | If not ENABLED, the rule is masked by a shift or a reduce (S/R and |
| R/R conflicts). | | R/R conflicts). |
`-------------------------------------------------------------------------*/ `-------------------------------------------------------------------------*/
@@ -286,11 +286,10 @@ print_reductions (FILE *out, int level, state *s)
} }
/* Nothing to report. */ /* Nothing to report. */
if (!report) if (!report) {
{ xml_puts (out, level, "<reductions/>");
xml_puts (out, level, "<reductions/>"); return;
return; }
}
xml_puts (out, level, "<reductions>"); xml_puts (out, level, "<reductions>");
@@ -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);
} }
+4 -7
View File
@@ -106,11 +106,8 @@ print_core (FILE *out, state *s)
for (sp = rules[r].rhs; sp < sp1; sp++) for (sp = rules[r].rhs; sp < sp1; sp++)
fprintf (out, " %s", symbols[*sp]->tag); fprintf (out, " %s", symbols[*sp]->tag);
fputs (" .", out); fputs (" .", out);
if (0 <= *rules[r].rhs) for (/* Nothing */; *sp >= 0; ++sp)
for (/* Nothing */; 0 <= *sp; ++sp) fprintf (out, " %s", symbols[*sp]->tag);
fprintf (out, " %s", symbols[*sp]->tag);
else
fprintf (out, " %%empty");
/* Display the lookahead tokens? */ /* Display the lookahead tokens? */
if (report_flag & report_lookahead_tokens if (report_flag & report_lookahead_tokens
@@ -209,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). |
`-------------------------------------------------------------------------*/ `-------------------------------------------------------------------------*/
@@ -517,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. */
+2 -5
View File
@@ -84,11 +84,8 @@ print_core (struct obstack *oout, state *s)
obstack_1grow (oout, '.'); obstack_1grow (oout, '.');
if (0 <= *r->rhs) for (/* Nothing */; *sp >= 0; ++sp)
for (/* Nothing */; *sp >= 0; ++sp) obstack_printf (oout, " %s", escape (symbols[*sp]->tag));
obstack_printf (oout, " %s", escape (symbols[*sp]->tag));
else
obstack_printf (oout, " %%empty");
/* Experimental feature: display the lookahead tokens. */ /* Experimental feature: display the lookahead tokens. */
if (report_flag & report_lookahead_tokens if (report_flag & report_lookahead_tokens
+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;
+89 -23
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>
@@ -342,19 +417,8 @@ show_sub_message (warnings warning,
{ {
static struct obstack msg_buf; static struct obstack msg_buf;
const char *tail = explicit_bracketing ? "" : cp + strlen (var->id); const char *tail = explicit_bracketing ? "" : cp + strlen (var->id);
const char *id; const char *id = var->hidden_by ? var->hidden_by->id : var->id;
location id_loc; location id_loc = var->hidden_by ? var->hidden_by->loc : var->loc;
if (var->hidden_by)
{
id = var->hidden_by->id;
id_loc = var->hidden_by->loc;
}
else
{
id = var->id;
id_loc = var->loc;
}
/* Create the explanation message. */ /* Create the explanation message. */
obstack_init (&msg_buf); obstack_init (&msg_buf);
@@ -584,6 +648,9 @@ parse_ref (char *cp, symbol_list *rule, int rule_length,
return INVALID_REF; return INVALID_REF;
} }
} }
/* Not reachable. */
return INVALID_REF;
} }
/* Keeps track of the maximum number of semantic values to the left of /* Keeps track of the maximum number of semantic values to the left of
@@ -604,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
+24 -17
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;
@@ -266,7 +267,7 @@ eqopt ([[:space:]]*=)?
"%pure"[-_]"parser" DEPRECATED("%pure-parser"); "%pure"[-_]"parser" DEPRECATED("%pure-parser");
"%token"[-_]"table" DEPRECATED("%token-table"); "%token"[-_]"table" DEPRECATED("%token-table");
"%"{id} { "%"{id}|"%"{notletter}([[:graph:]])+ {
complain (loc, complaint, _("invalid directive: %s"), quote (yytext)); complain (loc, complaint, _("invalid directive: %s"), quote (yytext));
} }
@@ -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;
} }
+5 -8
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"))
@@ -244,9 +242,8 @@ at_output (int argc, char *argv[], char **out_namep, int *out_linenop)
xfclose (yyout); xfclose (yyout);
} }
*out_namep = xstrdup (argv[1]); *out_namep = xstrdup (argv[1]);
output_file_name_check (out_namep, true); output_file_name_check (out_namep);
/* If there were errors, do not generate the output. */ yyout = xfopen (*out_namep, "w");
yyout = xfopen (complaint_status ? "/dev/null" : *out_namep, "w");
*out_linenop = 1; *out_linenop = 1;
} }
+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;
+2 -3
View File
@@ -77,8 +77,7 @@ uniqstr_vsprintf (char const *format, ...)
void void
uniqstr_assert (char const *str) uniqstr_assert (char const *str)
{ {
uniqstr s = hash_lookup (uniqstrs_table, str); if (!hash_lookup (uniqstrs_table, str))
if (!s || s != str)
{ {
error (0, 0, error (0, 0,
"not a uniqstr: %s", quotearg (str)); "not a uniqstr: %s", quotearg (str));
@@ -106,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
+2 -4
View File
@@ -20,8 +20,6 @@
#ifndef UNIQSTR_H_ #ifndef UNIQSTR_H_
# define UNIQSTR_H_ # define UNIQSTR_H_
# include <stdio.h>
/*-----------------------------------------. /*-----------------------------------------.
| Pointers to unique copies of C strings. | | Pointers to unique copies of C strings. |
`-----------------------------------------*/ `-----------------------------------------*/
@@ -35,14 +33,14 @@ uniqstr uniqstr_new (char const *str);
strings, use UNIQSTR_CONCAT, which is a convenient wrapper around strings, use UNIQSTR_CONCAT, which is a convenient wrapper around
this function. */ this function. */
uniqstr uniqstr_vsprintf (char const *format, ...) uniqstr uniqstr_vsprintf (char const *format, ...)
_GL_ATTRIBUTE_FORMAT_PRINTF (1, 2); __attribute__ ((__format__ (__printf__, 1, 2)));
/* Two uniqstr values have the same value iff they are the same. */ /* Two uniqstr values have the same value iff they are the same. */
# define UNIQSTR_EQ(Ustr1, Ustr2) (!!((Ustr1) == (Ustr2))) # define UNIQSTR_EQ(Ustr1, Ustr2) (!!((Ustr1) == (Ustr2)))
/* 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);
+122 -126
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.
*/ */
@@ -596,7 +483,7 @@ thing:
; ;
%% %%
/* Alias to ARGV[1]. */ /* Alias to ARGV[1]. */
const char *source = YY_NULLPTR; const char *source = YY_NULL;
]AT_YYERROR_DEFINE[ ]AT_YYERROR_DEFINE[
@@ -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 -31
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,39 +47,12 @@ 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@'
# Be sure that the C++ compiler is not broken because of gnulib. This
# cannot be checked in configure (gnulib is not parameterized yet),
# and checking this in every C++ test in AC_COMPILE_CXX is too costly.
#
# http://lists.gnu.org/archive/html/bug-bison/2013-06/msg00001.html
#
# FIXME: Check (say 2014) whether this is still needed.
if $BISON_CXX_WORKS; then
# See AT_DATA_SOURCE_PROLOGUE.
cat >conftest.cc <<EOF
#include <config.h>
/* We don't need perfect functions for these tests. */
#undef malloc
#undef memcmp
#undef realloc
#include <iostream>
int main ()
{
std::cout << "Works" << std::endl;
}
EOF
$CXX $CXXFLAGS $CPPFLAGS $LDFLAGS $LIBS -o conftest conftest.cc
case $? in
0);;
*) BISON_CXX_WORKS="as_fn_error 77 cannot-compile-simple-program";;
esac
rm -fr conftest*
fi
# Whether the compiler supports POSIXLY_CORRECT defined. # Whether the compiler supports POSIXLY_CORRECT defined.
: ${C_COMPILER_POSIXLY_CORRECT='@C_COMPILER_POSIXLY_CORRECT@'} : ${C_COMPILER_POSIXLY_CORRECT='@C_COMPILER_POSIXLY_CORRECT@'}
: ${CXX_COMPILER_POSIXLY_CORRECT='@CXX_COMPILER_POSIXLY_CORRECT@'} : ${CXX_COMPILER_POSIXLY_CORRECT='@CXX_COMPILER_POSIXLY_CORRECT@'}
@@ -102,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. ##
+69 -152
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
@@ -174,10 +113,11 @@ AT_CLEANUP
m4_pushdef([AT_TEST], m4_pushdef([AT_TEST],
[AT_SETUP([Variants $1]) [AT_SETUP([Variants $1])
AT_BISON_OPTION_PUSHDEFS([%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"
%define api.value.type variant %define api.value.type variant
]m4_bpatsubst([$1], [\\n], [ ]m4_bpatsubst([$1], [\\n], [
])[ ])[
@@ -243,7 +183,7 @@ typedef std::list<std::string> strings_type;
// digraph for the left square bracket. // digraph for the left square bracket.
%type <::std::list<std::string>> list result; %type <::std::list<std::string>> list result;
%printer { yyo << $$; } %printer { yyo << $][$; }
<int> <::std::string> <::std::list<std::string>>; <int> <::std::string> <::std::list<std::string>>;
%% %%
@@ -253,13 +193,13 @@ result:
list: list:
/* nothing */ { /* Generates an empty string list */ } /* nothing */ { /* Generates an empty string list */ }
| list item { std::swap ($$,$][1); $$.push_back ($][2); } | list item { std::swap ($][$,$][1); $$.push_back ($][2); }
| list error { std::swap ($$,$][1); } | list error { std::swap ($][$,$][1); }
; ;
item: item:
TEXT { std::swap ($$,$][1); } TEXT { std::swap ($][$,$][1); }
| NUMBER { if ($][1 == 3) YYERROR; else $$ = string_cast ($][1); } | NUMBER { if ($][1 == 3) YYERROR; else $][$ = string_cast ($][1); }
; ;
%% %%
]AT_TOKEN_CTOR_IF([], ]AT_TOKEN_CTOR_IF([],
@@ -310,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)
]) ])
@@ -319,13 +260,13 @@ AT_BISON_OPTION_POPDEFS
AT_CLEANUP AT_CLEANUP
]) ])
AT_TEST([[%skeleton "lalr1.cc" ]]) AT_TEST([])
AT_TEST([[%skeleton "lalr1.cc" %define parse.assert]]) AT_TEST([%define parse.assert])
AT_TEST([[%skeleton "lalr1.cc" %locations %define parse.assert]]) AT_TEST([%locations %define parse.assert])
AT_TEST([[%skeleton "lalr1.cc" %define parse.assert %code {\n#define TWO_STAGE_BUILD\n}]]) AT_TEST([[%define parse.assert %code {\n#define TWO_STAGE_BUILD\n}]])
AT_TEST([[%skeleton "lalr1.cc" %define parse.assert %define api.token.constructor]]) AT_TEST([[%define parse.assert %define api.token.constructor]])
AT_TEST([[%skeleton "lalr1.cc" %define parse.assert %define api.token.constructor %define api.token.prefix {TOK_}]]) AT_TEST([[%define parse.assert %define api.token.constructor %define api.token.prefix "TOK_"]])
AT_TEST([[%skeleton "lalr1.cc" %locations %define parse.assert %define api.token.constructor %define api.token.prefix {TOK_}]]) AT_TEST([[%locations %define parse.assert %define api.token.constructor %define api.token.prefix "TOK_"]])
m4_popdef([AT_TEST]) m4_popdef([AT_TEST])
@@ -422,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
@@ -481,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 ) */]], [[-]])
@@ -649,14 +590,11 @@ AT_CLEANUP
## Exception safety. ## ## Exception safety. ##
## ------------------ ## ## ------------------ ##
# AT_TEST([BISON-DIRECTIVES = ''], [WITH-RECOVERY = "with"]) # AT_TEST([BISON-DIRECTIVES])
# ---------------------------------------------------------- # ---------------------------
# Check that no object is leaked when exceptions are thrown. # Check that no object is leaked when exceptions are thrown.
# WITH-RECOVERY = "with" or "without".
m4_pushdef([AT_TEST], m4_pushdef([AT_TEST],
[AT_SETUP([[Exception safety $2 error recovery $1]]) [AT_SETUP([[Exception safety $1]])
AT_SKIP_IF_EXCEPTION_SUPPORT_IS_POOR
AT_BISON_OPTION_PUSHDEFS([%skeleton "lalr1.cc" $1]) AT_BISON_OPTION_PUSHDEFS([%skeleton "lalr1.cc" $1])
@@ -670,59 +608,21 @@ $1
#include <cassert> #include <cassert>
#include <cstdlib> // size_t and getenv. #include <cstdlib> // size_t and getenv.
#include <iostream> #include <iostream>
#include <set> #include <list>
bool debug = false; bool debug = false;
/// A class that tracks its instances. /// A class that counts its number of instances.
struct Object struct Object
{ {
char val; typedef std::list<const Object*> objects;
Object ()
: val ('?')
{
log (this, "Object::Object");
Object::instances.insert (this);
}
Object (const Object& that)
: val (that.val)
{
log (this, "Object::Object");
Object::instances.insert (this);
}
Object (char v)
: val (v)
{
log (this, "Object::Object");
Object::instances.insert (this);
}
~Object ()
{
log (this, "Object::~Object");
objects::const_iterator i = instances.find (this);
// Make sure this object is alive.
assert (i != instances.end ());
Object::instances.erase (i);
}
Object& operator= (char v)
{
val = v;
return *this;
}
// Static part.
typedef std::set<const Object*> objects;
static objects instances; static objects instances;
char val;
static bool static bool
empty () empty ()
{ {
return instances.empty (); return instances.empty();
} }
static void static void
@@ -745,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");
}
}; };
} }
@@ -796,23 +716,22 @@ $1
start: list {]AT_VARIANT_IF([], [ delete $][1]; )[}; start: list {]AT_VARIANT_IF([], [ delete $][1]; )[};
list: list:
item { $$ = $][1; } item { $][$ = $][1; }
// Right recursion to load the stack. // Right recursion to load the stack.
| item list { $$ = $][1; ]AT_VARIANT_IF([], [delete $][2]; )[} | item list { $][$ = $][1; ]AT_VARIANT_IF([], [delete $][2]; )[}
; ;
item: item:
'a' { $$ = $][1; } 'a' { $$][ = $][1; }
| 'e' { YYUSE ($$); YYUSE($][1); error ("syntax error"); } | 'e' { YYUSE ($][$); YYUSE($][1); error ("syntax error"); }
// 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' { ]AT_VARIANT_IF([], [$$ = YY_NULLPTR; 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' { ]AT_VARIANT_IF([], [$$ = YY_NULLPTR; delete $][1]; )[YYABORT; } | 'T' { $][$ = YY_NULL; ]AT_VARIANT_IF([], [delete $][1]; )[YYABORT; }
]m4_if([$2], [with], | error { $][$ = YY_NULL; yyerrok; }
[[| error { $$ = ]AT_VARIANT_IF([], [new ])[Object ('R'); yyerrok; }]])[
; ;
%% %%
@@ -832,8 +751,7 @@ yylex (yy::parser::semantic_type *lvalp)
case 'l': case 'l':
throw std::runtime_error ("yylex"); throw std::runtime_error ("yylex");
default: default:
lvalp->]AT_VARIANT_IF([build (Object (res))], lvalp]AT_VARIANT_IF([->build (res)], [->obj = new Object (res)])[;
[obj = new Object (res)])[;
// Fall through. // Fall through.
case 0: case 0:
return res; return res;
@@ -880,13 +798,13 @@ main (int argc, const char *argv[])
{ {
std::cerr << "unknown exception caught" << std::endl; std::cerr << "unknown exception caught" << std::endl;
} }
Object::log (YY_NULLPTR, "end"); Object::log (YY_NULL, "end");
assert (Object::empty()); assert (Object::empty());
return res; return res;
} }
]]) ]])
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
@@ -915,17 +833,16 @@ AT_PARSER_CHECK([[./input aaaaE]], [[2]], [[]],
AT_PARSER_CHECK([[./input aaaaT]], [[1]]) AT_PARSER_CHECK([[./input aaaaT]], [[1]])
AT_PARSER_CHECK([[./input aaaaR]], [m4_if([$2], [with], [0], [1])]) # There is error-recovery, so exit success.
AT_PARSER_CHECK([[./input aaaaR]], [[0]])
AT_BISON_OPTION_POPDEFS AT_BISON_OPTION_POPDEFS
AT_CLEANUP AT_CLEANUP
]) ])
AT_TEST([], [with]) AT_TEST
AT_TEST([], [without]) AT_TEST([%define api.value.type variant])
AT_TEST([%define api.value.type variant], [with])
AT_TEST([%define api.value.type variant], [without])
m4_popdef([AT_TEST]) m4_popdef([AT_TEST])
+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}])
+111 -179
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
@@ -1447,7 +1379,7 @@ State 0
0 $accept: . start $end 0 $accept: . start $end
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 ['a'] 3 | . ['a']
$default reduce using rule 3 (resolved_conflict) $default reduce using rule 3 (resolved_conflict)
@@ -1483,7 +1415,7 @@ State 4
1 start: resolved_conflict 'a' . reported_conflicts 'a' 1 start: resolved_conflict 'a' . reported_conflicts 'a'
8 reported_conflicts: . 'a' 8 reported_conflicts: . 'a'
9 | . 'a' 9 | . 'a'
10 | . %empty ['a'] 10 | . ['a']
'a' shift, and go to state 5 'a' shift, and go to state 5
@@ -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
@@ -1576,11 +1508,11 @@ AT_CHECK([[cat input.output | sed -n '/^State 0$/,/^State 1$/p']], 0,
6 | . empty_c1 'c' 6 | . empty_c1 'c'
7 | . empty_c2 'c' 7 | . empty_c2 'c'
8 | . empty_c3 'c' 8 | . empty_c3 'c'
9 empty_a: . %empty ['a'] 9 empty_a: . ['a']
10 empty_b: . %empty [] 10 empty_b: . []
11 empty_c1: . %empty [] 11 empty_c1: . []
12 empty_c2: . %empty [] 12 empty_c2: . []
13 empty_c3: . %empty ['c'] 13 empty_c3: . ['c']
'b' shift, and go to state 1 'b' shift, and go to state 1
@@ -1652,11 +1584,11 @@ AT_CHECK([[cat input.output | sed -n '/^State 0$/,/^State 1$/p']], 0,
6 | . empty_c1 'c' 6 | . empty_c1 'c'
7 | . empty_c2 'c' 7 | . empty_c2 'c'
8 | . empty_c3 'c' 8 | . empty_c3 'c'
9 empty_a: . %empty [] 9 empty_a: . []
10 empty_b: . %empty [] 10 empty_b: . []
11 empty_c1: . %empty [] 11 empty_c1: . []
12 empty_c2: . %empty ['c'] 12 empty_c2: . ['c']
13 empty_c3: . %empty ['c'] 13 empty_c3: . ['c']
'a' error (nonassociative) 'a' error (nonassociative)
'b' error (nonassociative) 'b' error (nonassociative)
@@ -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
+7 -7
View File
@@ -94,19 +94,19 @@ prog :
stmt : expr ';' $2 { $$ = ]$[1; } stmt : expr ';' $2 { $$ = ]$[1; }
| decl $3 | decl $3
| error ';' { $$ = new_nterm ("<error>", YY_NULLPTR, YY_NULLPTR, YY_NULLPTR); } | error ';' { $$ = new_nterm ("<error>", YY_NULL, YY_NULL, YY_NULL); }
| '@' { YYACCEPT; } | '@' { YYACCEPT; }
; ;
expr : ID expr : ID
| TYPENAME '(' expr ')' | TYPENAME '(' expr ')'
{ $$ = new_nterm ("<cast>(%s,%s)", ]$[3, ]$[1, YY_NULLPTR); } { $$ = new_nterm ("<cast>(%s,%s)", ]$[3, ]$[1, YY_NULL); }
| expr '+' expr { $$ = new_nterm ("+(%s,%s)", ]$[1, ]$[3, YY_NULLPTR); } | expr '+' expr { $$ = new_nterm ("+(%s,%s)", ]$[1, ]$[3, YY_NULL); }
| expr '=' expr { $$ = new_nterm ("=(%s,%s)", ]$[1, ]$[3, YY_NULLPTR); } | expr '=' expr { $$ = new_nterm ("=(%s,%s)", ]$[1, ]$[3, YY_NULL); }
; ;
decl : TYPENAME declarator ';' decl : TYPENAME declarator ';'
{ $$ = new_nterm ("<declare>(%s,%s)", ]$[1, ]$[2, YY_NULLPTR); } { $$ = new_nterm ("<declare>(%s,%s)", ]$[1, ]$[2, YY_NULL); }
| TYPENAME declarator '=' expr ';' | TYPENAME declarator '=' expr ';'
{ $$ = new_nterm ("<init-declare>(%s,%s,%s)", ]$[1, { $$ = new_nterm ("<init-declare>(%s,%s,%s)", ]$[1,
]$[2, ]$[4); } ]$[2, ]$[4); }
@@ -195,7 +195,7 @@ main (int argc, char **argv)
{ {
colNum += 1; colNum += 1;
tok = c; tok = c;
yylval = YY_NULLPTR; yylval = YY_NULL;
}]AT_LOCATION_IF([[ }]AT_LOCATION_IF([[
yylloc.last_column = colNum-1;]])[ yylloc.last_column = colNum-1;]])[
return tok; return tok;
@@ -287,7 +287,7 @@ m4_bmatch([$2], [stmtMerge],
[[static YYSTYPE [[static YYSTYPE
stmtMerge (YYSTYPE x0, YYSTYPE x1) stmtMerge (YYSTYPE x0, YYSTYPE x1)
{ {
return new_nterm ("<OR>(%s,%s)", x0, x1, YY_NULLPTR); return new_nterm ("<OR>(%s,%s)", x0, x1, YY_NULL);
} }
]]) ]])
) )
+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
+8 -38
View File
@@ -67,7 +67,7 @@ static YYSTYPE exprMerge (YYSTYPE x0, YYSTYPE x1)
return 0; return 0;
} }
const char *input = YY_NULLPTR; const char *input = YY_NULL;
int int
main (int argc, const char* argv[]) main (int argc, const char* argv[])
@@ -304,7 +304,7 @@ MergeRule (int x0, int x1)
} }
]AT_YYERROR_DEFINE[ ]AT_YYERROR_DEFINE[
FILE *input = YY_NULLPTR; FILE *input = YY_NULL;
int P[] = { P1, P2 }; int P[] = { P1, P2 };
int O[] = { O1, O2 }; int O[] = { O1, O2 };
@@ -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
@@ -1749,33 +1749,3 @@ Cleanup: popping token 'a' ()
]) ])
AT_CLEANUP AT_CLEANUP
## ----------------------------------------------------------------- ##
## Predicates. ##
## ##
## http://lists.gnu.org/archive/html/bug-bison/2013-10/msg00004.html ##
## ----------------------------------------------------------------- ##
AT_SETUP([Predicates])
# FIXME: We need genuine test cases with uses of %?.
AT_DATA_GRAMMAR([input.y],
[[%glr-parser
%expect-rr 1
%%
// Exercise "%?{...}" and "%? {...}".
widget:
%? {new_syntax} "widget" id new_args { $$ = f($3, $4); }
| %?{!new_syntax} "widget" id old_args { $$ = f($3, $4); }
;
id:;
new_args:;
old_args:;
%%
]])
AT_BISON_CHECK([[input.y]])
AT_CLEANUP
+4 -8
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
@@ -223,13 +223,9 @@ AT_CHECK([[$PERL -n -0777 -e '
s{/\*.*?\*/}{}gs; s{/\*.*?\*/}{}gs;
s{//.*}{}g; s{//.*}{}g;
s{\b(YYChar s{\b(YYChar
|YYPUSH_MORE(?:_DEFINED)? |YYPUSH_MORE(_DEFINED)?
|YYUSE
|YY_ATTRIBUTE(?:_PURE|_UNUSED)?
|YY_IGNORE_MAYBE_UNINITIALIZED_(?:BEGIN|END)
|YY_INITIAL_VALUE
|YY_\w+_INCLUDED |YY_\w+_INCLUDED
|YY_NULLPTR |YY_NULL
|(defined|if)\ YYDEBUG |(defined|if)\ YYDEBUG
)\b}{}gx; )\b}{}gx;
while (/^(.*YY.*)$/gm) while (/^(.*YY.*)$/gm)

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