mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-08-08 18:25:13 +00:00
Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fcf845a716 | ||
|
|
3158164614 |
+1
-1
@@ -1 +1 @@
|
||||
3.0
|
||||
2.7
|
||||
|
||||
+4
-4
@@ -32,8 +32,8 @@ EXTRA_DIST = .prev-version .version \
|
||||
## version of Bison nearby...
|
||||
BISON = $(top_builddir)/tests/bison
|
||||
BISON_IN = $(top_srcdir)/tests/bison.in
|
||||
YACC = $(BISON) -o y.tab.c
|
||||
AM_YFLAGS = -d -v -Werror -Wall -Wno-yacc --report=all
|
||||
YACC = $(BISON) -y
|
||||
AM_YFLAGS = -d -v --warnings=all,error --report=all
|
||||
|
||||
# Initialization before completion by local.mk's.
|
||||
AM_CFLAGS = $(WARN_CFLAGS)
|
||||
@@ -78,11 +78,11 @@ dist-hook: gen-ChangeLog
|
||||
|
||||
.PHONY: update-b4-copyright update-package-copyright-year
|
||||
update-b4-copyright:
|
||||
$(AM_V_GEN)find $(srcdir)/data -type f \
|
||||
find $(srcdir)/data -type f \
|
||||
| xargs $(srcdir)/build-aux/$@
|
||||
@echo 'warning: src/parse-gram.[hc] may need to be regenerated.'
|
||||
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
|
||||
.PHONY: gen-ChangeLog
|
||||
|
||||
@@ -2,37 +2,16 @@ GNU Bison NEWS
|
||||
|
||||
* Noteworthy changes in release ?.? (????-??-??) [?]
|
||||
|
||||
** New syntax: partial-order precedence relationships
|
||||
|
||||
Formerly, the precedence order of tokens was linear, depending only on the
|
||||
order in which they were declared. With the new syntax, all the tokens are
|
||||
not necessarily comparable. It is possible to declare a group of tokens with
|
||||
no links outside of the group, and to later on add only those needed.
|
||||
The uncomparability of tokens would allow for more feedback on new conflicts
|
||||
silently resolved via precedence.
|
||||
|
||||
An example of the new syntax applied to arithmetic and boolean operators,
|
||||
with '^' serving as both numerical power and boolean XOR:
|
||||
|
||||
%gprec arith {
|
||||
%left '+' '-'
|
||||
%left '*' '/'
|
||||
}
|
||||
%gprec bool {
|
||||
%left OR
|
||||
%left AND
|
||||
}
|
||||
%gprec { %right '^' }
|
||||
|
||||
%precr '^' > arith
|
||||
%precr OR AND > '^'
|
||||
|
||||
Here, AND is not comparable with '+', but '^' > '+' and AND > '^'
|
||||
|
||||
* Noteworthy changes in release 3.0 (2013-07-25) [stable]
|
||||
|
||||
** WARNING: Future backward-incompatibilities!
|
||||
|
||||
Bison will stop adding a semicolon at the end of the actions (as announced
|
||||
in the release 2.5):
|
||||
|
||||
foo.y:2.22: warning: a ';' might be needed at the end of action code
|
||||
exp: "num" { $$ = $1 }
|
||||
^
|
||||
foo.y:2.22: future versions of Bison will not add the ';'
|
||||
|
||||
Like other GNU packages, Bison will start using some of the C99 features
|
||||
for its own code, especially the definition of variables after statements.
|
||||
The generated C parsers still aim at C90.
|
||||
@@ -49,32 +28,9 @@ GNU Bison NEWS
|
||||
Support for YYLEX_PARAM and YYPARSE_PARAM is removed (deprecated in Bison
|
||||
1.875): use %lex-param, %parse-param, or %param.
|
||||
|
||||
Missing semicolons at the end of actions are no longer added (as announced
|
||||
in the release 2.5).
|
||||
|
||||
*** Use of YACC='bison -y'
|
||||
|
||||
TL;DR: With Autoconf <= 2.69, pass -Wno-yacc to (AM_)YFLAGS if you use
|
||||
Bison extensions.
|
||||
|
||||
Traditional Yacc generates 'y.tab.c' whatever the name of the input file.
|
||||
Therefore Makefiles written for Yacc expect 'y.tab.c' (and possibly
|
||||
'y.tab.h' and 'y.outout') to be generated from 'foo.y'.
|
||||
|
||||
To this end, for ages, AC_PROG_YACC, Autoconf's macro to look for an
|
||||
implementation of Yacc, was using Bison as 'bison -y'. While it does
|
||||
ensure compatible output file names, it also enables warnings for
|
||||
incompatibilities with POSIX Yacc. In other words, 'bison -y' triggers
|
||||
warnings for Bison extensions.
|
||||
|
||||
Autoconf 2.70+ fixes this incompatibility by using YACC='bison -o y.tab.c'
|
||||
(which also generates 'y.tab.h' and 'y.output' when needed).
|
||||
Alternatively, disable Yacc warnings by passing '-Wno-yacc' to your Yacc
|
||||
flags (YFLAGS, or AM_YFLAGS with Automake).
|
||||
|
||||
** Bug fixes
|
||||
|
||||
*** The epilogue is no longer affected by internal #defines (glr.c)
|
||||
*** The epilogue is no longer affected by internal #defines
|
||||
|
||||
The glr.c skeleton uses defines such as #define yylval (yystackp->yyval) in
|
||||
generated code. These weren't properly undefined before the inclusion of
|
||||
@@ -83,7 +39,7 @@ GNU Bison NEWS
|
||||
|
||||
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.
|
||||
|
||||
*** stdio.h is no longer needed when locations are enabled (yacc.c)
|
||||
@@ -91,8 +47,6 @@ GNU Bison NEWS
|
||||
Changes in Bison 2.7 introduced a dependency on FILE and fprintf when
|
||||
locations are enabled. This is fixed.
|
||||
|
||||
*** Warnings about useless %pure-parser/%define api.pure are restored
|
||||
|
||||
** Diagnostics reported by Bison
|
||||
|
||||
Most of these features were contributed by Théophile Ranquet and Victor
|
||||
@@ -104,29 +58,6 @@ GNU Bison NEWS
|
||||
activated by default. The old format can still be used by invoking Bison
|
||||
with -fno-caret (or -fnone).
|
||||
|
||||
Some error messages that reproduced excerpts of the grammar are now using
|
||||
the caret information only. For instance on:
|
||||
|
||||
%%
|
||||
exp: 'a' | 'a';
|
||||
|
||||
Bison 2.7 reports:
|
||||
|
||||
in.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
|
||||
in.y:2.12-14: warning: rule useless in parser due to conflicts: exp: 'a' [-Wother]
|
||||
|
||||
Now bison reports:
|
||||
|
||||
in.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
|
||||
in.y:2.12-14: warning: rule useless in parser due to conflicts [-Wother]
|
||||
exp: 'a' | 'a';
|
||||
^^^
|
||||
|
||||
and "bison -fno-caret" reports:
|
||||
|
||||
in.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
|
||||
in.y:2.12-14: warning: rule useless in parser due to conflicts [-Wother]
|
||||
|
||||
*** Enhancements of the -Werror option
|
||||
|
||||
The -Werror=CATEGORY option is now recognized, and will treat specified
|
||||
@@ -267,10 +198,12 @@ GNU Bison NEWS
|
||||
bar.y: error: shift/reduce conflicts: 1 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
|
||||
with '-Wyacc'.
|
||||
Bison now warns about symbols with a declared precedence but no declared
|
||||
associativity (i.e. declared with %precedence), and whose precedence is
|
||||
never used. In that case, the symbol can be safely declared with %token
|
||||
instead, without modifying the parsing tables.
|
||||
|
||||
** Additional yylex/yyparse arguments
|
||||
|
||||
@@ -287,271 +220,13 @@ GNU Bison NEWS
|
||||
|
||||
%param {arg1_type *arg1} {arg2_type *arg2}
|
||||
|
||||
** Types of values for %define variables
|
||||
|
||||
Bison used to make no difference between '%define foo bar' and '%define
|
||||
foo "bar"'. The former is now called a 'keyword value', and the latter a
|
||||
'string value'. A third kind was added: 'code values', such as '%define
|
||||
foo {bar}'.
|
||||
|
||||
Keyword variables are used for fixed value sets, e.g.,
|
||||
|
||||
%define lr.type lalr
|
||||
|
||||
Code variables are used for value in the target language, e.g.,
|
||||
|
||||
%define api.value.type {struct semantic_type}
|
||||
|
||||
String variables are used remaining cases, e.g. file names.
|
||||
|
||||
** Variable api.token.prefix
|
||||
|
||||
The variable api.token.prefix changes the way tokens are identified in
|
||||
the generated files. This is especially useful to avoid collisions
|
||||
with identifiers in the target language. For instance
|
||||
|
||||
%token FILE for ERROR
|
||||
%define api.token.prefix {TOK_}
|
||||
%%
|
||||
start: FILE for ERROR;
|
||||
|
||||
will generate the definition of the symbols TOK_FILE, TOK_for, and
|
||||
TOK_ERROR in the generated sources. In particular, the scanner must
|
||||
use these prefixed token names, although the grammar itself still
|
||||
uses the short names (as in the sample rule given above).
|
||||
|
||||
** Variable api.value.type
|
||||
|
||||
This new %define variable supersedes the #define macro YYSTYPE. The use
|
||||
of YYSTYPE is discouraged. In particular, #defining YYSTYPE *and* either
|
||||
using %union or %defining api.value.type results in undefined behavior.
|
||||
|
||||
Either define api.value.type, or use "%union":
|
||||
|
||||
%union
|
||||
{
|
||||
int ival;
|
||||
char *sval;
|
||||
}
|
||||
%token <ival> INT "integer"
|
||||
%token <sval> STRING "string"
|
||||
%printer { fprintf (yyo, "%d", $$); } <ival>
|
||||
%destructor { free ($$); } <sval>
|
||||
|
||||
/* In yylex(). */
|
||||
yylval.ival = 42; return INT;
|
||||
yylval.sval = "42"; return STRING;
|
||||
|
||||
The %define variable api.value.type supports both keyword and code values.
|
||||
|
||||
The keyword value 'union' means that the user provides genuine types, not
|
||||
union member names such as "ival" and "sval" above (WARNING: will fail if
|
||||
-y/--yacc/%yacc is enabled).
|
||||
|
||||
%define api.value.type union
|
||||
%token <int> INT "integer"
|
||||
%token <char *> STRING "string"
|
||||
%printer { fprintf (yyo, "%d", $$); } <int>
|
||||
%destructor { free ($$); } <char *>
|
||||
|
||||
/* In yylex(). */
|
||||
yylval.INT = 42; return INT;
|
||||
yylval.STRING = "42"; return STRING;
|
||||
|
||||
The keyword value variant is somewhat equivalent, but for C++ special
|
||||
provision is made to allow classes to be used (more about this below).
|
||||
|
||||
%define api.value.type variant
|
||||
%token <int> INT "integer"
|
||||
%token <std::string> STRING "string"
|
||||
|
||||
Code values (in braces) denote user defined types. This is where YYSTYPE
|
||||
used to be used.
|
||||
|
||||
%code requires
|
||||
{
|
||||
struct my_value
|
||||
{
|
||||
enum
|
||||
{
|
||||
is_int, is_string
|
||||
} kind;
|
||||
union
|
||||
{
|
||||
int ival;
|
||||
char *sval;
|
||||
} u;
|
||||
};
|
||||
}
|
||||
%define api.value.type {struct my_value}
|
||||
%token <u.ival> INT "integer"
|
||||
%token <u.sval> STRING "string"
|
||||
%printer { fprintf (yyo, "%d", $$); } <u.ival>
|
||||
%destructor { free ($$); } <u.sval>
|
||||
|
||||
/* In yylex(). */
|
||||
yylval.u.ival = 42; return INT;
|
||||
yylval.u.sval = "42"; return STRING;
|
||||
|
||||
** Variable parse.error
|
||||
|
||||
This variable controls the verbosity of error messages. The use of the
|
||||
%error-verbose directive is deprecated in favor of "%define parse.error
|
||||
verbose".
|
||||
|
||||
** Renamed %define variables
|
||||
|
||||
The following variables have been renamed for consistency. Backward
|
||||
compatibility is ensured, but upgrading is recommended.
|
||||
|
||||
lr.default-reductions -> lr.default-reduction
|
||||
lr.keep-unreachable-states -> lr.keep-unreachable-state
|
||||
namespace -> api.namespace
|
||||
stype -> api.value.type
|
||||
|
||||
** Semantic predicates
|
||||
|
||||
Contributed by Paul Hilfinger.
|
||||
|
||||
The new, experimental, semantic-predicate feature allows actions of the
|
||||
form "%?{ BOOLEAN-EXPRESSION }", which cause syntax errors (as for
|
||||
YYERROR) if the expression evaluates to 0, and are evaluated immediately
|
||||
in GLR parsers, rather than being deferred. The result is that they allow
|
||||
the programmer to prune possible parses based on the values of run-time
|
||||
expressions.
|
||||
|
||||
** The directive %expect-rr is now an error in non GLR mode
|
||||
|
||||
It used to be an error only if used in non GLR mode, _and_ if there are
|
||||
reduce/reduce conflicts.
|
||||
|
||||
** Tokens are numbered in their order of appearance
|
||||
|
||||
Contributed by Valentin Tolmer.
|
||||
|
||||
With '%token A B', A had a number less than the one of B. However,
|
||||
precedence declarations used to generate a reversed order. This is now
|
||||
fixed, and introducing tokens with any of %token, %left, %right,
|
||||
%precedence, or %nonassoc yields the same result.
|
||||
|
||||
When mixing declarations of tokens with a litteral character (e.g., 'a')
|
||||
or with an identifier (e.g., B) in a precedence declaration, Bison
|
||||
numbered the litteral characters first. For example
|
||||
|
||||
%right A B 'c' 'd'
|
||||
|
||||
would lead to the tokens declared in this order: 'c' 'd' A B. Again, the
|
||||
input order is now preserved.
|
||||
|
||||
These changes were made so that one can remove useless precedence and
|
||||
associativity declarations (i.e., map %nonassoc, %left or %right to
|
||||
%precedence, or to %token) and get exactly the same output.
|
||||
|
||||
** Useless precedence and associativity
|
||||
|
||||
Contributed by Valentin Tolmer.
|
||||
|
||||
When developing and maintaining a grammar, useless associativity and
|
||||
precedence directives are common. They can be a nuisance: new ambiguities
|
||||
arising are sometimes masked because their conflicts are resolved due to
|
||||
the extra precedence or associativity information. Furthermore, it can
|
||||
hinder the comprehension of a new grammar: one will wonder about the role
|
||||
of a precedence, where in fact it is useless. The following changes aim
|
||||
at detecting and reporting these extra directives.
|
||||
|
||||
*** Precedence warning category
|
||||
|
||||
A new category of warning, -Wprecedence, was introduced. It flags the
|
||||
useless precedence and associativity directives.
|
||||
|
||||
*** Useless associativity
|
||||
|
||||
Bison now warns about symbols with a declared associativity that is never
|
||||
used to resolve conflicts. In that case, using %precedence is sufficient;
|
||||
the parsing tables will remain unchanged. Solving these warnings may raise
|
||||
useless precedence warnings, as the symbols no longer have associativity.
|
||||
For example:
|
||||
|
||||
%left '+'
|
||||
%left '*'
|
||||
%%
|
||||
exp:
|
||||
"number"
|
||||
| exp '+' "number"
|
||||
| exp '*' exp
|
||||
;
|
||||
|
||||
will produce a
|
||||
|
||||
warning: useless associativity for '+', use %precedence [-Wprecedence]
|
||||
%left '+'
|
||||
^^^
|
||||
|
||||
*** Useless precedence
|
||||
|
||||
Bison now warns about symbols with a declared precedence and no declared
|
||||
associativity (i.e., declared with %precedence), and whose precedence is
|
||||
never used. In that case, the symbol can be safely declared with %token
|
||||
instead, without modifying the parsing tables. For example:
|
||||
|
||||
%precedence '='
|
||||
%%
|
||||
exp: "var" '=' "number";
|
||||
|
||||
will produce a
|
||||
|
||||
warning: useless precedence for '=' [-Wprecedence]
|
||||
%precedence '='
|
||||
^^^
|
||||
|
||||
*** Useless precedence and associativity
|
||||
|
||||
In case of both useless precedence and associativity, the issue is flagged
|
||||
as follows:
|
||||
|
||||
%nonassoc '='
|
||||
%%
|
||||
exp: "var" '=' "number";
|
||||
|
||||
The warning is:
|
||||
|
||||
warning: useless precedence and associativity for '=' [-Wprecedence]
|
||||
%nonassoc '='
|
||||
^^^
|
||||
|
||||
** Empty rules
|
||||
|
||||
With help from Joel E. Denny and Gabriel Rassoul.
|
||||
|
||||
Empty rules (i.e., with an empty right-hand side) can now be explicitly
|
||||
marked by the new %empty directive. Using %empty on a non-empty rule is
|
||||
an error. The new -Wempty-rule warning reports empty rules without
|
||||
%empty. On the following grammar:
|
||||
|
||||
%%
|
||||
s: a b c;
|
||||
a: ;
|
||||
b: %empty;
|
||||
c: 'a' %empty;
|
||||
|
||||
bison reports:
|
||||
|
||||
3.4-5: warning: empty rule without %empty [-Wempty-rule]
|
||||
a: {}
|
||||
^^
|
||||
5.8-13: error: %empty on non-empty rule
|
||||
c: 'a' %empty {};
|
||||
^^^^^^
|
||||
|
||||
** Java skeleton improvements
|
||||
|
||||
Contributed by Paolo Bonzini.
|
||||
|
||||
The constants for token names were moved to the Lexer interface. Also, it
|
||||
is possible to add code to the parser's constructors using "%code init"
|
||||
and "%define init_throws".
|
||||
Contributed by Paolo Bonzini.
|
||||
|
||||
The Java skeleton now supports push parsing.
|
||||
Contributed by Dennis Heimbigner.
|
||||
|
||||
** C++ skeletons improvements
|
||||
|
||||
@@ -574,66 +249,59 @@ GNU Bison NEWS
|
||||
used by the scanner, or rejecting invalid combinations from a
|
||||
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
|
||||
from Théophile Ranquet.
|
||||
The following variables have been renamed for consistency. Backward
|
||||
compatibility is ensured, but upgrading is recommended.
|
||||
|
||||
In this mode, complex C++ objects can be used as semantic values. For
|
||||
instance:
|
||||
lr.default-reductions -> lr.default-reduction
|
||||
lr.keep-unreachable-states -> lr.keep-unreachable-state
|
||||
namespace -> api.namespace
|
||||
stype -> api.value.type
|
||||
|
||||
%token <::std::string> TEXT;
|
||||
%token <int> NUMBER;
|
||||
%token SEMICOLON ";"
|
||||
%type <::std::string> item;
|
||||
%type <::std::list<std::string>> list;
|
||||
** 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_"
|
||||
%%
|
||||
result:
|
||||
list { std::cout << $1 << std::endl; }
|
||||
;
|
||||
start: FILE for ERROR;
|
||||
|
||||
list:
|
||||
%empty { /* Generates an empty string list. */ }
|
||||
| list item ";" { std::swap ($$, $1); $$.push_back ($2); }
|
||||
;
|
||||
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).
|
||||
|
||||
item:
|
||||
TEXT { std::swap ($$, $1); }
|
||||
| NUMBER { $$ = string_cast ($1); }
|
||||
;
|
||||
** Variable parse.error
|
||||
|
||||
*** %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
|
||||
tokens. This guarantees that the token type (e.g., NUMBER) is consistent
|
||||
with the semantic value (e.g., int):
|
||||
** Semantic predicates
|
||||
|
||||
parser::symbol_type yylex ()
|
||||
{
|
||||
parser::location_type loc = ...;
|
||||
...
|
||||
return parser::make_TEXT ("Hello, world!", loc);
|
||||
...
|
||||
return parser::make_NUMBER (42, loc);
|
||||
...
|
||||
return parser::make_SEMICOLON (loc);
|
||||
...
|
||||
}
|
||||
Contributed by Paul Hilfinger.
|
||||
|
||||
*** 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
|
||||
increments can no longer underflow the resulting value.
|
||||
** The directive %expect-rr is now an error in non GLR mode
|
||||
|
||||
* 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)
|
||||
|
||||
With locations enabled, __attribute__ was used unprotected.
|
||||
|
||||
*** Fix some compiler warnings (lalr1.cc)
|
||||
When declaring %token A B, the numbering for A is inferior to B. Up to now,
|
||||
when declaring associativity at the same time, with %left (or %right,
|
||||
%precedence, %nonassoc), B was inferior to A.
|
||||
|
||||
* Noteworthy changes in release 2.7 (2012-12-12) [stable]
|
||||
|
||||
@@ -685,8 +353,8 @@ GNU Bison NEWS
|
||||
exp: exp '+' exp { $exp = $1 + $3; };
|
||||
^^^
|
||||
|
||||
The default behavior for now is still not to display these unless
|
||||
explicitly asked with -fcaret (or -fall). However, in a later release, it
|
||||
The default behaviour for now is still not to display these unless
|
||||
explictly asked with -fcaret (or -fall). However, in a later release, it
|
||||
will be made the default behavior (but may still be deactivated with
|
||||
-fno-caret).
|
||||
|
||||
@@ -773,7 +441,7 @@ GNU Bison NEWS
|
||||
|
||||
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
|
||||
is no longer necessary to initialize it in the %initial-action.
|
||||
@@ -2689,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: extern YYTOKENTYPE TOKENTYPE yytokentype tokentype STYPE lval pdf
|
||||
LocalWords: lang yyoutput dvi html ps POSIX lvalp llocp Wother nterm arg init
|
||||
LocalWords: TOK calc yyo fval Wconflicts parsers yystackp yyval yynerrs
|
||||
LocalWords: Théophile Ranquet Santet fno fnone stype associativity Tolmer
|
||||
LocalWords: Wprecedence Rassoul Wempty Paolo Bonzini parser's Michiel loc
|
||||
LocalWords: redeclaration sval fcaret reentrant XSLT xsl Wmaybe yyvsp Tedi
|
||||
LocalWords: pragmas noreturn untyped Rozenman unexpanded Wojciech Polak
|
||||
LocalWords: Alexandre MERCHANTABILITY yytype
|
||||
LocalWords: TOK calc yyo fval Wconflicts
|
||||
|
||||
Local Variables:
|
||||
mode: outline
|
||||
|
||||
@@ -30,7 +30,7 @@ not answer them, please send mail to <[email protected]>.
|
||||
|
||||
* Bug reports
|
||||
Please send bug reports to <[email protected]>. Please include the
|
||||
version number from 'bison --version', and a complete, self-contained
|
||||
version number from `bison --version', and a complete, self-contained
|
||||
test case in each bug report.
|
||||
|
||||
* Copyright statements
|
||||
|
||||
+1
-1
@@ -9,7 +9,7 @@ Bison supports the @N construction, which gives you access to
|
||||
the starting and ending line number and character number associated
|
||||
with any of the symbols in the current rule.
|
||||
|
||||
Also, Bison supports the command '%expect N' which says not to mention
|
||||
Also, Bison supports the command `%expect N' which says not to mention
|
||||
the conflicts if there are N shift/reduce conflicts and no reduce/reduce
|
||||
conflicts.
|
||||
|
||||
|
||||
@@ -25,12 +25,10 @@ Bruce Lilly [email protected]
|
||||
Bruno Haible [email protected]
|
||||
Charles-Henri de Boysson [email protected]
|
||||
Christian Burger [email protected]
|
||||
Colin Daley [email protected]
|
||||
Cris Bailiff [email protected]
|
||||
Cris van Pelt [email protected]
|
||||
Csaba Raduly [email protected]
|
||||
Dagobert Michelsen [email protected]
|
||||
Daniel Frużyński [email protected]
|
||||
Daniel Hagerty [email protected]
|
||||
David J. MacKenzie [email protected]
|
||||
David Kastrup [email protected]
|
||||
@@ -39,7 +37,6 @@ Derek M. Jones [email protected]
|
||||
Di-an Jan [email protected]
|
||||
Dick Streefland [email protected]
|
||||
Didier Godefroy [email protected]
|
||||
Efi Fogel [email protected]
|
||||
Enrico Scholz [email protected]
|
||||
Eric Blake [email protected]
|
||||
Evgeny Stambulchik [email protected]
|
||||
@@ -47,7 +44,6 @@ Fabrice Bauzac [email protected]
|
||||
Florian Krohm [email protected]
|
||||
Frank Heckenbach [email protected]
|
||||
Frans Englich [email protected]
|
||||
Gabriel Rassoul [email protected]
|
||||
Georg Sauthoff [email protected]
|
||||
George Neuner [email protected]
|
||||
Gilles Espinasse [email protected]
|
||||
@@ -101,7 +97,6 @@ Peter Eisentraut [email protected]
|
||||
Peter Fales [email protected]
|
||||
Peter Hamorsky [email protected]
|
||||
Peter Simons [email protected]
|
||||
Petr Machata [email protected]
|
||||
Piotr Gackiewicz [email protected]
|
||||
Quentin Hocquet [email protected]
|
||||
Quoc Peyrot [email protected]
|
||||
@@ -111,7 +106,6 @@ Ralf Wildenhues [email protected]
|
||||
Richard Stallman [email protected]
|
||||
Rob Vermaas [email protected]
|
||||
Robert Anisko [email protected]
|
||||
Rob Conde [email protected]
|
||||
Roland Levillain [email protected]
|
||||
Satya Kiran Popuri [email protected]
|
||||
Sebastian Setzer [email protected]
|
||||
@@ -132,7 +126,6 @@ Tommy Nordgren [email protected]
|
||||
Troy A. Johnson [email protected]
|
||||
Tys Lefering [email protected]
|
||||
Valentin Tolmer [email protected]
|
||||
Victor Khomenko [email protected]
|
||||
Vin Shelton [email protected]
|
||||
W.C.A. Wijngaards [email protected]
|
||||
Wayne Green [email protected]
|
||||
|
||||
@@ -1,27 +1,16 @@
|
||||
* Short term
|
||||
** Graphviz display code thoughts
|
||||
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
|
||||
this is no longer true, maybe we could consider these files for fusion.
|
||||
graphviz. I believe this is because Bison used to also produce VCG graphs,
|
||||
but since this is no longer true, maybe we could consider these files for
|
||||
fusion.
|
||||
|
||||
An other consideration worth noting is that print_graph.c (correct me if I
|
||||
am wrong) should contain generic functions, whereas graphviz.c and other
|
||||
potential files should contain just the specific code for that output
|
||||
format. It will probably prove difficult to tell if the implementation is
|
||||
actually generic whilst only having support for a single format, but it
|
||||
would be nice to keep stuff a bit tidier: right now, the construction of the
|
||||
bitset used to show reductions is in the graphviz-specific code, and on the
|
||||
opposite side we have some use of \l, which is graphviz-specific, in what
|
||||
should be generic code.
|
||||
Little effort factoring seems to have been given to factoring in these files,
|
||||
and their print-xml and print counterpart. We would very much like to re-use
|
||||
the pretty format of states from .output in the .dot
|
||||
|
||||
Little effort seems to have been given to factoring these files and their
|
||||
rint{,-xml} counterpart. We would very much like to re-use the pretty format
|
||||
of states from .output for the graphs, etc.
|
||||
|
||||
Also, the underscore in print_graph.[ch] isn't very fitting considering the
|
||||
dashes in the other filenames.
|
||||
|
||||
Since graphviz dies on medium-to-big grammars, maybe consider an other tool?
|
||||
Also, the underscore in print_graph.[ch] isn't very fitting considering
|
||||
the dashes in the other filenames.
|
||||
|
||||
** push-parser
|
||||
Check it too when checking the different kinds of parsers. And be
|
||||
@@ -176,13 +165,13 @@ part of $default. Should we make the two reductions explicit, or just
|
||||
keep $default? See the following point.
|
||||
|
||||
** Disabled Reductions
|
||||
See 'tests/conflicts.at (Defaulted Conflicted Reduction)', and decide
|
||||
See `tests/conflicts.at (Defaulted Conflicted Reduction)', and decide
|
||||
what we want to do.
|
||||
|
||||
** Documentation
|
||||
Extend with error productions. The hard part will probably be finding
|
||||
the right rule so that a single state does not exhibit too many yet
|
||||
undocumented ''features''. Maybe an empty action ought to be
|
||||
undocumented ``features''. Maybe an empty action ought to be
|
||||
presented too. Shall we try to make a single grammar with all these
|
||||
features, or should we have several very small grammars?
|
||||
|
||||
@@ -243,9 +232,9 @@ into
|
||||
exp: exp '+' exp | exp '&' exp;
|
||||
|
||||
when there are no actions. This can significantly speed up some
|
||||
grammars. I can't find the papers. In particular the book 'LR
|
||||
grammars. I can't find the papers. In particular the book `LR
|
||||
parsing: Theory and Practice' is impossible to find, but according to
|
||||
'Parsing Techniques: a Practical Guide', it includes information about
|
||||
`Parsing Techniques: a Practical Guide', it includes information about
|
||||
this issue. Does anybody have it?
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#! /bin/sh
|
||||
# Print a version string.
|
||||
scriptversion=2013-07-03.20; # UTC
|
||||
scriptversion=2012-12-28.10; # UTC
|
||||
|
||||
# Bootstrap this package from checked-out sources.
|
||||
|
||||
@@ -140,21 +140,20 @@ po_download_command_format2=\
|
||||
"wget --mirror -nd -q -np -A.po -P '%s' \
|
||||
http://translationproject.org/latest/%s/"
|
||||
|
||||
# Prefer a non-empty tarname (4th argument of AC_INIT if given), else
|
||||
# fall back to the package name (1st argument with munging)
|
||||
extract_package_name='
|
||||
/^AC_INIT(\[*/{
|
||||
s///
|
||||
/^[^,]*,[^,]*,[^,]*,[ []*\([^][ ,)]\)/{
|
||||
s//\1/
|
||||
s/[],)].*//
|
||||
/^AC_INIT(/{
|
||||
/.*,.*,.*, */{
|
||||
s///
|
||||
s/[][]//g
|
||||
s/)$//
|
||||
p
|
||||
q
|
||||
}
|
||||
s/[],)].*//
|
||||
s/AC_INIT(\[*//
|
||||
s/]*,.*//
|
||||
s/^GNU //
|
||||
y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/
|
||||
s/[^abcdefghijklmnopqrstuvwxyz0123456789_]/-/g
|
||||
s/[^A-Za-z0-9_]/-/g
|
||||
p
|
||||
}
|
||||
'
|
||||
@@ -256,12 +255,12 @@ esac
|
||||
# Extra files from gnulib, which override files from other sources.
|
||||
test -z "${gnulib_extra_files}" && \
|
||||
gnulib_extra_files="
|
||||
build-aux/install-sh
|
||||
build-aux/mdate-sh
|
||||
build-aux/texinfo.tex
|
||||
build-aux/depcomp
|
||||
build-aux/config.guess
|
||||
build-aux/config.sub
|
||||
$build_aux/install-sh
|
||||
$build_aux/mdate-sh
|
||||
$build_aux/texinfo.tex
|
||||
$build_aux/depcomp
|
||||
$build_aux/config.guess
|
||||
$build_aux/config.sub
|
||||
doc/INSTALL
|
||||
"
|
||||
|
||||
@@ -307,34 +306,34 @@ if test -n "$checkout_only_file" && test ! -r "$checkout_only_file"; then
|
||||
die "Bootstrapping from a non-checked-out distribution is risky."
|
||||
fi
|
||||
|
||||
# Strip blank and comment lines to leave significant entries.
|
||||
gitignore_entries() {
|
||||
sed '/^#/d; /^$/d' "$@"
|
||||
# Ensure that lines starting with ! sort last, per gitignore conventions
|
||||
# for whitelisting exceptions after a more generic blacklist pattern.
|
||||
sort_patterns() {
|
||||
sort -u "$@" | sed '/^!/ {
|
||||
H
|
||||
d
|
||||
}
|
||||
$ {
|
||||
P
|
||||
x
|
||||
s/^\n//
|
||||
}' | sed '/^$/d'
|
||||
}
|
||||
|
||||
# If $STR is not already on a line by itself in $FILE, insert it at the start.
|
||||
# Entries are inserted at the start of the ignore list to ensure existing
|
||||
# entries starting with ! are not overridden. Such entries support
|
||||
# whitelisting exceptions after a more generic blacklist pattern.
|
||||
insert_if_absent() {
|
||||
# If $STR is not already on a line by itself in $FILE, insert it,
|
||||
# sorting the new contents of the file and replacing $FILE with the result.
|
||||
insert_sorted_if_absent() {
|
||||
file=$1
|
||||
str=$2
|
||||
test -f $file || touch $file
|
||||
test -r $file || die "Error: failed to read ignore file: $file"
|
||||
duplicate_entries=$(gitignore_entries $file | sort | uniq -d)
|
||||
if [ "$duplicate_entries" ] ; then
|
||||
die "Error: Duplicate entries in $file: " $duplicate_entries
|
||||
fi
|
||||
linesold=$(gitignore_entries $file | wc -l)
|
||||
linesnew=$(echo "$str" | gitignore_entries - $file | sort -u | wc -l)
|
||||
if [ $linesold != $linesnew ] ; then
|
||||
{ echo "$str" | cat - $file > $file.bak && mv $file.bak $file; } \
|
||||
|| die "insert_if_absent $file $str: failed"
|
||||
fi
|
||||
echo "$str" | sort_patterns - $file | cmp -s - $file > /dev/null \
|
||||
|| { echo "$str" | sort_patterns - $file > $file.bak \
|
||||
&& mv $file.bak $file; } \
|
||||
|| die "insert_sorted_if_absent $file $str: failed"
|
||||
}
|
||||
|
||||
# Adjust $PATTERN for $VC_IGNORE_FILE and insert it with
|
||||
# insert_if_absent.
|
||||
# insert_sorted_if_absent.
|
||||
insert_vc_ignore() {
|
||||
vc_ignore_file="$1"
|
||||
pattern="$2"
|
||||
@@ -345,7 +344,7 @@ insert_vc_ignore() {
|
||||
# .gitignore entry.
|
||||
pattern=$(echo "$pattern" | sed s,^,/,);;
|
||||
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.
|
||||
@@ -551,7 +550,7 @@ fi
|
||||
echo "$0: Bootstrapping from checked-out $package sources..."
|
||||
|
||||
# See if we can use gnulib's git-merge-changelog merge driver.
|
||||
if $use_git && test -d .git && (git --version) >/dev/null 2>/dev/null ; then
|
||||
if test -d .git && (git --version) >/dev/null 2>/dev/null ; then
|
||||
if git config merge.merge-changelog.driver >/dev/null ; then
|
||||
:
|
||||
elif (git-merge-changelog --version) >/dev/null 2>/dev/null ; then
|
||||
@@ -574,17 +573,13 @@ git_modules_config () {
|
||||
test -f .gitmodules && git config --file .gitmodules "$@"
|
||||
}
|
||||
|
||||
if $use_git; then
|
||||
gnulib_path=$(git_modules_config submodule.gnulib.path)
|
||||
test -z "$gnulib_path" && gnulib_path=gnulib
|
||||
fi
|
||||
gnulib_path=$(git_modules_config submodule.gnulib.path)
|
||||
test -z "$gnulib_path" && gnulib_path=gnulib
|
||||
|
||||
# Get gnulib files. Populate $GNULIB_SRCDIR, possibly updating a
|
||||
# submodule, for use in the rest of the script.
|
||||
# Get gnulib files.
|
||||
|
||||
case ${GNULIB_SRCDIR--} in
|
||||
-)
|
||||
# Note that $use_git is necessarily true in this case.
|
||||
if git_modules_config submodule.gnulib.url >/dev/null; then
|
||||
echo "$0: getting gnulib files..."
|
||||
git submodule init || exit $?
|
||||
@@ -605,8 +600,8 @@ case ${GNULIB_SRCDIR--} in
|
||||
GNULIB_SRCDIR=$gnulib_path
|
||||
;;
|
||||
*)
|
||||
# Use GNULIB_SRCDIR directly or as a reference.
|
||||
if $use_git && test -d "$GNULIB_SRCDIR"/.git && \
|
||||
# Use GNULIB_SRCDIR as a reference.
|
||||
if test -d "$GNULIB_SRCDIR"/.git && \
|
||||
git_modules_config submodule.gnulib.url >/dev/null; then
|
||||
echo "$0: getting gnulib files..."
|
||||
if git submodule -h|grep -- --reference > /dev/null; then
|
||||
@@ -632,19 +627,12 @@ case ${GNULIB_SRCDIR--} in
|
||||
;;
|
||||
esac
|
||||
|
||||
# $GNULIB_SRCDIR now points to the version of gnulib to use, and
|
||||
# we no longer need to use git or $gnulib_path below here.
|
||||
|
||||
if $bootstrap_sync; then
|
||||
cmp -s "$0" "$GNULIB_SRCDIR/build-aux/bootstrap" || {
|
||||
echo "$0: updating bootstrap and restarting..."
|
||||
case $(sh -c 'echo "$1"' -- a) in
|
||||
a) ignored=--;;
|
||||
*) ignored=ignored;;
|
||||
esac
|
||||
exec sh -c \
|
||||
'cp "$1" "$2" && shift && exec "${CONFIG_SHELL-/bin/sh}" "$@"' \
|
||||
$ignored "$GNULIB_SRCDIR/build-aux/bootstrap" \
|
||||
-- "$GNULIB_SRCDIR/build-aux/bootstrap" \
|
||||
"$0" "$@" --no-bootstrap-sync
|
||||
}
|
||||
fi
|
||||
|
||||
@@ -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
@@ -1,3 +1,5 @@
|
||||
## Makefile for Bison testsuite.
|
||||
|
||||
# Copyright (C) 2000-2013 Free Software Foundation, Inc.
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
@@ -16,7 +18,6 @@
|
||||
EXTRA_DIST += \
|
||||
build-aux/cross-options.pl \
|
||||
build-aux/darwin11.4.0.valgrind \
|
||||
build-aux/linux-gnu.valgrind \
|
||||
build-aux/move-if-change \
|
||||
build-aux/prev-version.txt \
|
||||
build-aux/update-b4-copyright
|
||||
|
||||
@@ -135,7 +135,7 @@ _sed_rm_comments_q = $(subst ','\'',$(_sed_remove_comments))
|
||||
|
||||
_space_before_paren_exempt =? \\n\\$$
|
||||
_space_before_paren_exempt = \
|
||||
(^ *\#|(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.
|
||||
sc_space_before_open_paren:
|
||||
@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_tab_based_indentation=\.(am|mk)$$|^djgpp/|^\.git \
|
||||
require_config_h_first=^(lib/yyerror|data/(glr|yacc))\.c$$ \
|
||||
space_before_open_paren=^(data/|djgpp/) \
|
||||
unmarked_diagnostics=^(djgpp/|doc/bison.texi$$|tests/c\+\+\.at$$) \
|
||||
)
|
||||
|
||||
+8
-16
@@ -18,7 +18,7 @@
|
||||
# In order for some versions of Sun Studio to compile our C++ test cases
|
||||
# correctly, we need Autoconf 2.64 or better to handle the restrict
|
||||
# keyword in at least string.h from gnulib. We need Autoconf 2.68 or
|
||||
# better to avoid a typo in the 'configure --help' entry for the YACC
|
||||
# better to avoid a typo in the `configure --help' entry for the YACC
|
||||
# environment variable.
|
||||
AC_PREREQ([2.68])
|
||||
m4_pattern_forbid([^gl_[A-Z]])
|
||||
@@ -91,7 +91,7 @@ if test "$enable_gcc_warnings" = yes; then
|
||||
# -fno-color-diagnostics: Clang's use of colors in the error
|
||||
# messages is confusing the tests looking at the compiler's output
|
||||
# (e.g., synclines.at).
|
||||
warn_tests='-Wundef -pedantic -Wsign-compare -fno-color-diagnostics'
|
||||
warn_tests='-Wundef -pedantic -fno-color-diagnostics'
|
||||
|
||||
AC_LANG_PUSH([C])
|
||||
# Clang supports many of GCC's -W options, but only issues warnings
|
||||
@@ -143,11 +143,9 @@ if test "$enable_gcc_warnings" = yes; then
|
||||
gl_WARN_ADD([$i], [WARN_CXXFLAGS_TEST])
|
||||
done
|
||||
# Clang++ 3.2+ reject C code generated by Flex.
|
||||
gl_WARN_ADD([-Wno-null-conversion], [FLEX_SCANNER_CXXFLAGS])
|
||||
# So does G++ 4.8...
|
||||
gl_WARN_ADD([-Wno-sign-compare], [FLEX_SCANNER_CXXFLAGS])
|
||||
# ... possiby in std=c++11 mode.
|
||||
gl_WARN_ADD([-Wno-zero-as-null-pointer-constant], [FLEX_SCANNER_CXXFLAGS])
|
||||
gl_WARN_ADD([-Wno-null-conversion], [WARN_NO_NULL_CONVERSION_CXXFLAGS])
|
||||
# Variants break strict aliasing analysis.
|
||||
gl_WARN_ADD([-fno-strict-aliasing], [NO_STRICT_ALIAS_CXXFLAGS])
|
||||
CXXFLAGS=$save_CXXFLAGS
|
||||
AC_LANG_POP([C++])
|
||||
fi
|
||||
@@ -222,7 +220,7 @@ AC_SUBST([aclocaldir])
|
||||
AC_CONFIG_FILES([etc/bench.pl], [chmod +x etc/bench.pl])
|
||||
|
||||
# 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/bison], [chmod +x tests/bison])
|
||||
AC_CHECK_PROGS([VALGRIND], [valgrind])
|
||||
@@ -230,16 +228,10 @@ case $VALGRIND:$host_os in
|
||||
'':*) ;;
|
||||
*:darwin*)
|
||||
# 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=;;
|
||||
*:*)
|
||||
suppfile=build-aux/$host_os.valgrind
|
||||
if test -f "$srcdir/$suppfile"; then
|
||||
VALGRIND="$VALGRIND --gen-suppressions=all"
|
||||
VALGRIND="$VALGRIND --suppressions=\$(abs_top_srcdir)/$suppfile"
|
||||
fi
|
||||
AC_SUBST([VALGRIND_PREBISON], ["$VALGRIND -q"])
|
||||
;;
|
||||
AC_SUBST([VALGRIND_PREBISON], ["$VALGRIND -q"]);;
|
||||
esac
|
||||
|
||||
AM_MISSING_PROG([AUTOM4TE], [autom4te])
|
||||
|
||||
+1
-1
@@ -27,7 +27,7 @@ Currently, the supported skeletons are:
|
||||
These skeletons are the only ones supported by the Bison team.
|
||||
Because the interface between skeletons and the bison program is not
|
||||
finished, *we are not bound to it*. In particular, Bison is not
|
||||
mature enough for us to consider that "foreign skeletons" are
|
||||
mature enough for us to consider that ``foreign skeletons'' are
|
||||
supported.
|
||||
|
||||
* m4sugar
|
||||
|
||||
+28
-141
@@ -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. ##
|
||||
## ---------------- ##
|
||||
@@ -327,7 +313,7 @@ m4_define([b4_define_flag_if],
|
||||
# _b4_define_flag_if($1, $2, FLAG)
|
||||
# --------------------------------
|
||||
# Work around the impossibility to define macros inside macros,
|
||||
# because issuing '[$1]' is not possible in M4. GNU M4 should provide
|
||||
# because issuing `[$1]' is not possible in M4. GNU M4 should provide
|
||||
# $$1 a la M5/TeX.
|
||||
m4_define([_b4_define_flag_if],
|
||||
[m4_if([$1$2], $[1]$[2], [],
|
||||
@@ -361,7 +347,6 @@ b4_define_flag_if([yacc]) # Whether POSIX Yacc is emulated.
|
||||
# Whether the symbol has an id.
|
||||
# - id: string
|
||||
# If has_id, the id. Guaranteed to be usable as a C identifier.
|
||||
# Prefixed by api.token.prefix if defined.
|
||||
# - tag: string.
|
||||
# A representat of the symbol. Can be 'foo', 'foo.id', '"foo"' etc.
|
||||
# - user_number: integer
|
||||
@@ -372,13 +357,9 @@ b4_define_flag_if([yacc]) # Whether POSIX Yacc is emulated.
|
||||
# The internalized number (used after yytranslate).
|
||||
# - has_type: 0, 1
|
||||
# Whether has a semantic value.
|
||||
# - type_tag: string
|
||||
# When api.value.type=union, the generated name for the union member.
|
||||
# yytype_INT etc. for symbols that has_id, otherwise yytype_1 etc.
|
||||
# - type
|
||||
# If it has a semantic value, its type tag, or, if variant are used,
|
||||
# its type.
|
||||
# In the case of api.value.type=union, type is the real type (e.g. int).
|
||||
# - has_printer: 0, 1
|
||||
# - printer: string
|
||||
# - printer_file: string
|
||||
@@ -461,24 +442,6 @@ m4_define([b4_symbol_destructor], [b4_symbol_action([$1], [destructor])])
|
||||
m4_define([b4_symbol_printer], [b4_symbol_action([$1], [printer])])
|
||||
|
||||
|
||||
# b4_symbol_actions(KIND, [TYPE = yytype])
|
||||
# ----------------------------------------
|
||||
# Emit the symbol actions for KIND ("printer" or "destructor").
|
||||
# Dispatch on TYPE.
|
||||
m4_define([b4_symbol_actions],
|
||||
[m4_pushdef([b4_actions_], m4_expand([b4_symbol_foreach([b4_symbol_$1])]))dnl
|
||||
m4_ifval(m4_defn([b4_actions_]),
|
||||
[switch (m4_default([$2], [yytype]))
|
||||
{
|
||||
m4_defn([b4_actions_])
|
||||
default:
|
||||
break;
|
||||
}dnl
|
||||
],
|
||||
[YYUSE (m4_default([$2], [yytype]));])dnl
|
||||
m4_popdef([b4_actions_])dnl
|
||||
])
|
||||
|
||||
# b4_symbol_case_(SYMBOL-NUM)
|
||||
# ---------------------------
|
||||
# Issue a "case NUM" for SYMBOL-NUM.
|
||||
@@ -614,14 +577,14 @@ m4_define([b4_define_user_code],
|
||||
# b4_user_initial_action
|
||||
# b4_user_post_prologue
|
||||
# b4_user_pre_prologue
|
||||
# b4_user_union_members
|
||||
# b4_user_stype
|
||||
# ----------------------
|
||||
# Macros that issue user code, ending with synclines.
|
||||
b4_define_user_code([actions])
|
||||
b4_define_user_code([initial_action])
|
||||
b4_define_user_code([post_prologue])
|
||||
b4_define_user_code([pre_prologue])
|
||||
b4_define_user_code([union_members])
|
||||
b4_define_user_code([stype])
|
||||
|
||||
|
||||
# b4_check_user_names(WHAT, USER-LIST, BISON-NAMESPACE)
|
||||
@@ -702,9 +665,9 @@ m4_define([b4_percent_define_use],
|
||||
# b4_percent_define_get([[foo]])
|
||||
m4_define([b4_percent_define_get],
|
||||
[b4_percent_define_use([$1])dnl
|
||||
b4_percent_define_ifdef_([$1],
|
||||
[m4_indir([b4_percent_define(]$1[)])],
|
||||
[$2])])
|
||||
m4_ifdef([b4_percent_define(]$1[)],
|
||||
[m4_indir([b4_percent_define(]$1[)])],
|
||||
[$2])])
|
||||
|
||||
# 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
|
||||
b4_loc[]dnl
|
||||
m4_popdef([b4_loc])],
|
||||
[b4_fatal([[$0: undefined %%define variable '%s']], [$1])])])
|
||||
|
||||
# b4_percent_define_get_kind(VARIABLE)
|
||||
# ------------------------------------
|
||||
# Get the kind (code, keyword, string) of VARIABLE, i.e., how its
|
||||
# value was defined (braces, not delimiters, quotes).
|
||||
#
|
||||
# If the %define variable VARIABLE is undefined, complain fatally
|
||||
# since that's a Bison or skeleton error. Don't record this as a
|
||||
# Bison usage of VARIABLE as there's no reason to suspect that the
|
||||
# user-supplied value has yet influenced the output.
|
||||
m4_define([b4_percent_define_get_kind],
|
||||
[m4_ifdef([b4_percent_define_kind(]$1[)],
|
||||
[m4_indir([b4_percent_define_kind(]$1[)])],
|
||||
[b4_fatal([[$0: undefined %%define variable '%s']], [$1])])])
|
||||
[b4_fatal([[b4_percent_define_get_loc: undefined %%define variable '%s']], [$1])])])
|
||||
|
||||
# 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_ifdef([b4_percent_define_syncline(]$1[)],
|
||||
[m4_indir([b4_percent_define_syncline(]$1[)])],
|
||||
[b4_fatal([[$0: undefined %%define variable '%s']], [$1])])])
|
||||
|
||||
# b4_percent_define_ifdef_(VARIABLE, IF-TRUE, [IF-FALSE])
|
||||
# ------------------------------------------------------
|
||||
# If the %define variable VARIABLE is defined, expand IF-TRUE, else expand
|
||||
# IF-FALSE. Don't record usage of VARIABLE.
|
||||
#
|
||||
# For example:
|
||||
#
|
||||
# b4_percent_define_ifdef_([[foo]], [[it's defined]], [[it's undefined]])
|
||||
m4_define([b4_percent_define_ifdef_],
|
||||
[m4_ifdef([b4_percent_define(]$1[)],
|
||||
[$2],
|
||||
[$3])])
|
||||
[b4_fatal([[b4_percent_define_get_syncline: undefined %%define variable '%s']], [$1])])])
|
||||
|
||||
# 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]])
|
||||
m4_define([b4_percent_define_ifdef],
|
||||
[b4_percent_define_ifdef_([$1],
|
||||
[b4_percent_define_use([$1])$2],
|
||||
[$3])])
|
||||
[m4_ifdef([b4_percent_define(]$1[)],
|
||||
[b4_percent_define_use([$1])$2],
|
||||
[$3])])
|
||||
|
||||
|
||||
## --------- ##
|
||||
@@ -811,11 +747,11 @@ m4_define([b4_percent_define_flag_if],
|
||||
[[invalid value for %%define Boolean variable '%s']],
|
||||
[$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,
|
||||
# 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
|
||||
@@ -825,10 +761,8 @@ m4_define([b4_percent_define_flag_if],
|
||||
#
|
||||
# b4_percent_define_default([[foo]], [[default value]])
|
||||
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_kind(]$1[)],
|
||||
[m4_default([$3], [keyword])])dnl
|
||||
m4_define([b4_percent_define_loc(]$1[)],
|
||||
[[[[<skeleton default value>:-1.-1]],
|
||||
[[<skeleton default value>:-1.-1]]]])dnl
|
||||
@@ -838,8 +772,8 @@ m4_define([b4_percent_define_default],
|
||||
# b4_percent_define_if_define(NAME, [VARIABLE = NAME])
|
||||
# ----------------------------------------------------
|
||||
# Define b4_NAME_if that executes its $1 or $2 depending whether
|
||||
# VARIABLE was %defined. The characters '.' and `-' in VARIABLE are mapped
|
||||
# to '_'.
|
||||
# VARIABLE was %defined. The characters `.' and `-' in VARIABLE are mapped
|
||||
# to `_'.
|
||||
m4_define([b4_percent_define_if_define_],
|
||||
[m4_define(m4_bpatsubst([b4_$1_if], [[-.]], [_]),
|
||||
[b4_percent_define_flag_if(m4_default([$2], [$1]),
|
||||
@@ -849,21 +783,6 @@ m4_define([b4_percent_define_if_define],
|
||||
b4_percent_define_if_define_([$1], [$2], $[1], $[2])])
|
||||
|
||||
|
||||
# b4_percent_define_check_kind(VARIABLE, KIND, [DIAGNOSTIC = complain])
|
||||
# ---------------------------------------------------------------------
|
||||
m4_define([b4_percent_define_check_kind],
|
||||
[b4_percent_define_ifdef_([$1],
|
||||
[m4_if(b4_percent_define_get_kind([$1]), [$2], [],
|
||||
[b4_error([m4_default([$3], [complain])],
|
||||
b4_percent_define_get_loc([$1]),
|
||||
[m4_case([$2],
|
||||
[code], [[%%define variable '%s' requires '{...}' values]],
|
||||
[keyword], [[%%define variable '%s' requires keyword values]],
|
||||
[string], [[%%define variable '%s' requires '"..."' values]])],
|
||||
[$1])])])dnl
|
||||
])
|
||||
|
||||
|
||||
# b4_percent_define_check_values(VALUES)
|
||||
# --------------------------------------
|
||||
# Mimic muscle_percent_define_check_values in ../src/muscle-tab.h exactly
|
||||
@@ -885,9 +804,8 @@ m4_define([b4_percent_define_check_values],
|
||||
[_b4_percent_define_check_values(b4_sublist)])])
|
||||
|
||||
m4_define([_b4_percent_define_check_values],
|
||||
[b4_percent_define_ifdef_([$1],
|
||||
[b4_percent_define_check_kind(]$1[, [keyword], [deprecated])dnl
|
||||
m4_pushdef([b4_good_value], [0])dnl
|
||||
[m4_ifdef([b4_percent_define(]$1[)],
|
||||
[m4_pushdef([b4_good_value], [0])dnl
|
||||
m4_if($#, 1, [],
|
||||
[m4_foreach([b4_value], m4_dquote(m4_shift($@)),
|
||||
[m4_if(m4_indir([b4_percent_define(]$1[)]), b4_value,
|
||||
@@ -902,7 +820,7 @@ m4_define([_b4_percent_define_check_values],
|
||||
[[accepted value: '%s']],
|
||||
m4_dquote(b4_value))])])dnl
|
||||
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])
|
||||
# --------------------------------
|
||||
@@ -943,6 +861,10 @@ m4_define([b4_percent_code_ifdef],
|
||||
## Common variables. ##
|
||||
## ------------------ ##
|
||||
|
||||
# Default values for %define.
|
||||
# ---------------------------
|
||||
# If the api.token.prefix, it is empty.
|
||||
m4_percent_define_default([[api.token.prefix]], [[]])
|
||||
|
||||
# b4_parse_assert_if([IF-ASSERTIONS-ARE-USED], [IF-NOT])
|
||||
# b4_parse_trace_if([IF-DEBUG-TRACES-ARE-ENABLED], [IF-NOT])
|
||||
@@ -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_percent_define_if_define([variant])
|
||||
m4_define([b4_variant_flag], [[0]])
|
||||
b4_percent_define_ifdef([[api.value.type]],
|
||||
[m4_case(b4_percent_define_get_kind([[api.value.type]]), [keyword],
|
||||
[m4_case(b4_percent_define_get([[api.value.type]]), [variant],
|
||||
[m4_define([b4_variant_flag], [[1]])])])])
|
||||
m4_case(b4_percent_define_get([[api.value.type]]),
|
||||
[variant], [m4_define([b4_variant_flag], [[1]])],
|
||||
[m4_define([b4_variant_flag], [[0]])])
|
||||
b4_define_flag_if([variant])
|
||||
|
||||
|
||||
@@ -1021,43 +941,10 @@ m4_define_default([b4_parse_param], [])
|
||||
m4_define_default([b4_location_initial_column], [1])
|
||||
m4_define_default([b4_location_initial_line], [1])
|
||||
|
||||
|
||||
## --------------- ##
|
||||
## 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])
|
||||
# Sanity checks.
|
||||
b4_percent_define_ifdef([api.prefix],
|
||||
[m4_ifdef([b4_prefix],
|
||||
[b4_complain_at(b4_percent_define_get_loc([api.prefix]),
|
||||
[['%s' and '%s' cannot be used together]],
|
||||
[%name-prefix],
|
||||
[%define api.prefix])])])
|
||||
|
||||
# api.token.prefix={...}
|
||||
# Make it a warning for those who used betas of Bison 3.0.
|
||||
b4_percent_define_check_kind([api.token.prefix], [code], [deprecated])
|
||||
|
||||
# api.value.type >< %union.
|
||||
b4_percent_define_ifdef([api.value.type],
|
||||
[m4_ifdef([b4_union_members],
|
||||
[b4_complain_at(b4_percent_define_get_loc([api.value.type]),
|
||||
[['%s' and '%s' cannot be used together]],
|
||||
[%union],
|
||||
[%define api.value.type])])])
|
||||
|
||||
# api.value.type=union >< %yacc.
|
||||
b4_percent_define_ifdef([api.value.type],
|
||||
[m4_if(b4_percent_define_get([api.value.type]), [union],
|
||||
[b4_yacc_if(dnl
|
||||
[b4_complain_at(b4_percent_define_get_loc([api.value.type]),
|
||||
[['%s' and '%s' cannot be used together]],
|
||||
[%yacc],
|
||||
[%define api.value.type "union"])])])])
|
||||
|
||||
+13
-35
@@ -25,12 +25,6 @@ m4_include(b4_pkgdatadir/[c.m4])
|
||||
m4_define([b4_comment],
|
||||
[b4_comment_([$1], [$2// ], [$2// ])])
|
||||
|
||||
## -------- ##
|
||||
## Checks. ##
|
||||
## -------- ##
|
||||
|
||||
b4_percent_define_check_kind([api.namespace], [code], [deprecated])
|
||||
b4_percent_define_check_kind([parser_class_name], [code], [deprecated])
|
||||
|
||||
## ---------------- ##
|
||||
## Default values. ##
|
||||
@@ -44,7 +38,6 @@ b4_percent_define_default([[parser_class_name]], [[parser]])
|
||||
# b4_percent_define_default([[api.location.type]], [[location]])
|
||||
|
||||
b4_percent_define_default([[filename_type]], [[std::string]])
|
||||
# Make it a warning for those who used betas of Bison 3.0.
|
||||
b4_percent_define_default([[api.namespace]], m4_defn([b4_prefix]))
|
||||
|
||||
b4_percent_define_default([[global_tokens_and_yystype]], [[false]])
|
||||
@@ -61,8 +54,8 @@ b4_percent_define_default([[define_location_comparison]],
|
||||
m4_define([b4_namespace_ref], [b4_percent_define_get([[api.namespace]])])
|
||||
|
||||
|
||||
# Don't permit an empty b4_namespace_ref. Any '::parser::foo' appended to it
|
||||
# would compile as an absolute reference with 'parser' in the global namespace.
|
||||
# Don't permit an empty b4_namespace_ref. Any `::parser::foo' appended to it
|
||||
# would compile as an absolute reference with `parser' in the global namespace.
|
||||
# b4_namespace_open would open an anonymous namespace and thus establish
|
||||
# internal linkage. This would compile. However, it's cryptic, and internal
|
||||
# linkage for the parser would be specified in all translation units that
|
||||
@@ -119,24 +112,19 @@ m4_define([b4_token_enums],
|
||||
## Semantic Values. ##
|
||||
## ----------------- ##
|
||||
|
||||
|
||||
|
||||
# b4_value_type_declare
|
||||
# ---------------------
|
||||
# b4_semantic_type_declare
|
||||
# ------------------------
|
||||
# Declare semantic_type.
|
||||
m4_define([b4_value_type_declare],
|
||||
[b4_value_type_setup[]dnl
|
||||
m4_define([b4_semantic_type_declare],
|
||||
[ /// Symbol semantic values.
|
||||
]m4_bmatch(b4_percent_define_get_kind([[api.value.type]]),
|
||||
[code],
|
||||
[[ typedef ]b4_percent_define_get([[api.value.type]])[ semantic_type;]],
|
||||
[m4_bmatch(b4_percent_define_get([[api.value.type]]),
|
||||
[union\|union-directive],
|
||||
[[ union semantic_type
|
||||
m4_ifdef([b4_stype],
|
||||
[ union semantic_type
|
||||
{
|
||||
]b4_user_union_members[
|
||||
};]])])dnl
|
||||
])
|
||||
b4_user_stype
|
||||
};],
|
||||
[m4_if(b4_tag_seen_flag, 0,
|
||||
[[ typedef int semantic_type;]],
|
||||
[[ typedef ]b4_api_PREFIX[STYPE semantic_type;]])])])
|
||||
|
||||
|
||||
# b4_public_types_declare
|
||||
@@ -145,7 +133,7 @@ m4_define([b4_value_type_declare],
|
||||
# Depending on %define token_lex, may be output in the header or source file.
|
||||
m4_define([b4_public_types_declare],
|
||||
[[#ifndef ]b4_api_PREFIX[STYPE
|
||||
]b4_value_type_declare[
|
||||
]b4_semantic_type_declare[
|
||||
#else
|
||||
typedef ]b4_api_PREFIX[STYPE semantic_type;
|
||||
#endif]b4_locations_if([
|
||||
@@ -532,13 +520,3 @@ m4_define([b4_yylloc_default_define],
|
||||
while (/*CONSTCOND*/ false)
|
||||
# endif
|
||||
]])
|
||||
|
||||
## -------- ##
|
||||
## Checks. ##
|
||||
## -------- ##
|
||||
|
||||
b4_token_ctor_if([b4_variant_if([],
|
||||
[b4_fatal_at(b4_percent_define_get_loc(api.token.constructor),
|
||||
[cannot use '%s' without '%s'],
|
||||
[%define api.token.constructor],
|
||||
[%define api.value.type variant]))])])
|
||||
|
||||
@@ -150,7 +150,7 @@ m4_popdef([$1])dnl
|
||||
|
||||
# b4_parse_param_use([VAL], [LOC])
|
||||
# --------------------------------
|
||||
# 'YYUSE' VAL, LOC if locations are enabled, and all the parse-params.
|
||||
# `YYUSE' VAL, LOC if locations are enabled, and all the parse-params.
|
||||
m4_define([b4_parse_param_use],
|
||||
[m4_ifvaln([$1], [ YYUSE ([$1]);])dnl
|
||||
b4_locations_if([m4_ifvaln([$2], [ YYUSE ([$2]);])])dnl
|
||||
@@ -182,7 +182,7 @@ m4_define([b4_int_type],
|
||||
# b4_int_type_for(NAME)
|
||||
# ---------------------
|
||||
# Return the smallest int type able to handle numbers ranging from
|
||||
# 'NAME_min' to 'NAME_max' (included).
|
||||
# `NAME_min' to `NAME_max' (included).
|
||||
m4_define([b4_int_type_for],
|
||||
[b4_int_type($1_min, $1_max)])
|
||||
|
||||
@@ -199,50 +199,6 @@ m4_define([b4_table_value_equals],
|
||||
[(!!(($2) == ($3)))])])
|
||||
|
||||
|
||||
## ----------------- ##
|
||||
## Compiler issues. ##
|
||||
## ----------------- ##
|
||||
|
||||
# b4_attribute_define
|
||||
# -------------------
|
||||
# Provide portability for __attribute__.
|
||||
m4_define([b4_attribute_define],
|
||||
[#ifndef __attribute__
|
||||
/* This feature is available in gcc versions 2.5 and later. */
|
||||
# if (! defined __GNUC__ || __GNUC__ < 2 \
|
||||
|| (__GNUC__ == 2 && __GNUC_MINOR__ < 5))
|
||||
# define __attribute__(Spec) /* empty */
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Suppress unused-variable warnings by "using" E. */
|
||||
#if ! defined lint || defined __GNUC__
|
||||
# define YYUSE(E) ((void) (E))
|
||||
#else
|
||||
# define YYUSE(E) /* empty */
|
||||
#endif
|
||||
|
||||
#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. ##
|
||||
## ---------##
|
||||
@@ -465,9 +421,12 @@ m4_ifset([b4_parse_param], [, b4_parse_param]))[
|
||||
yymsg = "Deleting";
|
||||
YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
|
||||
|
||||
YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
|
||||
]b4_symbol_actions([destructor])[
|
||||
YY_IGNORE_MAYBE_UNINITIALIZED_END
|
||||
switch (yytype)
|
||||
{
|
||||
]b4_symbol_foreach([b4_symbol_destructor])dnl
|
||||
[ default:
|
||||
break;
|
||||
}
|
||||
}]dnl
|
||||
])
|
||||
|
||||
@@ -477,9 +436,9 @@ m4_ifset([b4_parse_param], [, b4_parse_param]))[
|
||||
# Define the "yy_symbol_print" function.
|
||||
m4_define_default([b4_yy_symbol_print_define],
|
||||
[[
|
||||
/*----------------------------------------.
|
||||
| Print this symbol's value on YYOUTPUT. |
|
||||
`----------------------------------------*/
|
||||
/*--------------------------------.
|
||||
| Print this symbol on YYOUTPUT. |
|
||||
`--------------------------------*/
|
||||
|
||||
]b4_function_define([yy_symbol_value_print],
|
||||
[static void],
|
||||
@@ -500,7 +459,12 @@ m4_if(b4_skeleton, ["yacc.c"],
|
||||
YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
|
||||
# endif
|
||||
]])dnl
|
||||
b4_symbol_actions([printer])[
|
||||
[ switch (yytype)
|
||||
{
|
||||
]b4_symbol_foreach([b4_symbol_printer])dnl
|
||||
[ default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -528,154 +492,28 @@ b4_locations_if([, yylocationp])[]b4_user_args[);
|
||||
}]dnl
|
||||
])
|
||||
|
||||
|
||||
## ---------------- ##
|
||||
## api.value.type. ##
|
||||
## ---------------- ##
|
||||
|
||||
|
||||
# ---------------------- #
|
||||
# api.value.type=union. #
|
||||
# ---------------------- #
|
||||
|
||||
# b4_symbol_type_register(SYMBOL-NUM)
|
||||
# -----------------------------------
|
||||
# Symbol SYMBOL-NUM has a type (for variant) instead of a type-tag.
|
||||
# Extend the definition of %union's body with a field of that type,
|
||||
# and extend the symbol's "type" field to point to the field name,
|
||||
# instead of the type name.
|
||||
m4_define([b4_symbol_type_register],
|
||||
[m4_define([b4_symbol($1, type_tag)],
|
||||
[b4_symbol_if([$1], [has_id],
|
||||
[b4_symbol([$1], [id])],
|
||||
[yytype_[]b4_symbol([$1], [number])])])dnl
|
||||
m4_append([b4_user_union_members],
|
||||
m4_expand([
|
||||
b4_symbol_tag_comment([$1])dnl
|
||||
b4_symbol([$1], [type]) b4_symbol([$1], [type_tag]);]))
|
||||
])
|
||||
|
||||
|
||||
# b4_type_define_tag(SYMBOL1-NUM, ...)
|
||||
# ------------------------------------
|
||||
# For the batch of symbols SYMBOL1-NUM... (which all have the same
|
||||
# type), enhance the %union definition for each of them, and set
|
||||
# there "type" field to the field tag name, instead of the type name.
|
||||
m4_define([b4_type_define_tag],
|
||||
[b4_symbol_if([$1], [has_type],
|
||||
[m4_map([b4_symbol_type_register], [$@])])
|
||||
])
|
||||
|
||||
|
||||
# b4_symbol_value_union(VAL, [TYPE])
|
||||
# ----------------------------------
|
||||
# Same of b4_symbol_value, but when api.value.type=union.
|
||||
m4_define([b4_symbol_value_union],
|
||||
[m4_ifval([$2],
|
||||
[(*($2*)(&$1))],
|
||||
[$1])])
|
||||
])
|
||||
|
||||
|
||||
# b4_value_type_setup_union
|
||||
# -------------------------
|
||||
# Setup support for api.value.type=union. Symbols are defined with a
|
||||
# type instead of a union member name: build the corresponding union,
|
||||
# and give the symbols their tag.
|
||||
m4_define([b4_value_type_setup_union],
|
||||
[m4_define([b4_union_members])
|
||||
b4_type_foreach([b4_type_define_tag])
|
||||
m4_copy_force([b4_symbol_value_union], [b4_symbol_value])
|
||||
])
|
||||
|
||||
|
||||
# ---------------- #
|
||||
# api.value.type. #
|
||||
# ---------------- #
|
||||
|
||||
|
||||
# b4_value_type_setup_variant
|
||||
# ---------------------------
|
||||
# Setup support for api.value.type=variant. By default, fail, specialized
|
||||
# by other skeletons.
|
||||
m4_define([b4_value_type_setup_variant],
|
||||
[b4_complain_at(b4_percent_define_get_loc([[api.value.type]]),
|
||||
[['%s' does not support '%s']],
|
||||
[b4_skeleton],
|
||||
[%define api.value.type variant])])
|
||||
|
||||
|
||||
# _b4_value_type_setup_keyword
|
||||
# ----------------------------
|
||||
# api.value.type is defined with a keyword/string syntax. Check if
|
||||
# that is properly defined, and prepare its use.
|
||||
m4_define([_b4_value_type_setup_keyword],
|
||||
[b4_percent_define_check_values([[[[api.value.type]],
|
||||
[[none]],
|
||||
[[union]],
|
||||
[[union-directive]],
|
||||
[[variant]],
|
||||
[[yystype]]]])dnl
|
||||
m4_case(b4_percent_define_get([[api.value.type]]),
|
||||
[union], [b4_value_type_setup_union],
|
||||
[variant], [b4_value_type_setup_variant])])
|
||||
|
||||
|
||||
# b4_value_type_setup
|
||||
# -------------------
|
||||
# Check if api.value.type is properly defined, and possibly prepare
|
||||
# its use.
|
||||
b4_define_silent([b4_value_type_setup],
|
||||
[# Define default value.
|
||||
b4_percent_define_ifdef([[api.value.type]], [],
|
||||
[# %union => api.value.type=union-directive
|
||||
m4_ifdef([b4_union_members],
|
||||
[m4_define([b4_percent_define_kind(api.value.type)], [keyword])
|
||||
m4_define([b4_percent_define(api.value.type)], [union-directive])],
|
||||
[# no tag seen => api.value.type={int}
|
||||
m4_if(b4_tag_seen_flag, 0,
|
||||
[m4_define([b4_percent_define_kind(api.value.type)], [code])
|
||||
m4_define([b4_percent_define(api.value.type)], [int])],
|
||||
[# otherwise api.value.type=yystype
|
||||
m4_define([b4_percent_define_kind(api.value.type)], [keyword])
|
||||
m4_define([b4_percent_define(api.value.type)], [yystype])])])])
|
||||
|
||||
# Set up.
|
||||
m4_bmatch(b4_percent_define_get_kind([[api.value.type]]),
|
||||
[keyword\|string], [_b4_value_type_setup_keyword])
|
||||
])
|
||||
|
||||
|
||||
## -------------- ##
|
||||
## Declarations. ##
|
||||
## -------------- ##
|
||||
|
||||
|
||||
# b4_value_type_define
|
||||
# --------------------
|
||||
m4_define([b4_value_type_define],
|
||||
[b4_value_type_setup[]dnl
|
||||
/* Value type. */
|
||||
m4_bmatch(b4_percent_define_get_kind([[api.value.type]]),
|
||||
[code],
|
||||
[[#if ! defined ]b4_api_PREFIX[STYPE && ! defined ]b4_api_PREFIX[STYPE_IS_DECLARED
|
||||
typedef ]b4_percent_define_get([[api.value.type]])[ ]b4_api_PREFIX[STYPE;
|
||||
# define ]b4_api_PREFIX[STYPE_IS_TRIVIAL 1
|
||||
# define ]b4_api_PREFIX[STYPE_IS_DECLARED 1
|
||||
#endif
|
||||
]],
|
||||
[m4_bmatch(b4_percent_define_get([[api.value.type]]),
|
||||
[union\|union-directive],
|
||||
[[#if ! defined ]b4_api_PREFIX[STYPE && ! defined ]b4_api_PREFIX[STYPE_IS_DECLARED
|
||||
typedef union ]b4_union_name[ ]b4_api_PREFIX[STYPE;
|
||||
[[/* Value type. */
|
||||
#if ! defined ]b4_api_PREFIX[STYPE && ! defined ]b4_api_PREFIX[STYPE_IS_DECLARED
|
||||
]m4_ifdef([b4_stype],
|
||||
[[typedef union ]b4_union_name[ ]b4_api_PREFIX[STYPE;
|
||||
union ]b4_union_name[
|
||||
{
|
||||
]b4_user_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
|
||||
#endif
|
||||
]])])])
|
||||
]])
|
||||
|
||||
|
||||
# b4_location_type_define
|
||||
@@ -711,7 +549,7 @@ b4_pure_if([], [[extern ]b4_api_PREFIX[STYPE ]b4_prefix[lval;
|
||||
|
||||
|
||||
# b4_YYDEBUG_define
|
||||
# -----------------
|
||||
# ------------------
|
||||
m4_define([b4_YYDEBUG_define],
|
||||
[[/* Debug traces. */
|
||||
]m4_if(b4_api_prefix, [yy],
|
||||
|
||||
+18
-1
@@ -246,6 +246,13 @@ b4_percent_code_get[]dnl
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Suppress unused-variable warnings by "using" E. */
|
||||
#ifdef __GNUC__
|
||||
# define YYUSE(E) ((void) (E))
|
||||
#else
|
||||
# define YYUSE(E) /* empty */
|
||||
#endif
|
||||
|
||||
#ifndef YYFREE
|
||||
# define YYFREE free
|
||||
#endif
|
||||
@@ -274,7 +281,17 @@ b4_percent_code_get[]dnl
|
||||
# define YYLONGJMP(Env, Val) (longjmp (Env, Val), YYASSERT (0))
|
||||
#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
|
||||
# define YYASSERT(Condition) ((void) ((Condition) || (abort (), 0)))
|
||||
|
||||
+12
-1
@@ -43,6 +43,12 @@
|
||||
# user must initialize the first positions (in particular the
|
||||
# filename member).
|
||||
|
||||
b4_token_ctor_if([b4_variant_if([],
|
||||
[b4_fatal_at(b4_percent_define_get_loc(api.token.constructor),
|
||||
[cannot use '%s' without '%s'],
|
||||
[%define api.token.constructor],
|
||||
[%define api.value.type variant]))])])
|
||||
|
||||
# We require a pure interface.
|
||||
m4_define([b4_pure_flag], [1])
|
||||
|
||||
@@ -187,7 +193,12 @@ m4_pushdef([b4_parse_param], m4_defn([b4_parse_param_orig]))dnl
|
||||
std::ostream& yyoutput = debug_stream ();
|
||||
std::ostream& yyo = yyoutput;
|
||||
YYUSE (yyo);
|
||||
]b4_symbol_actions([printer])[
|
||||
switch (yytype)
|
||||
{
|
||||
]b4_symbol_foreach([b4_symbol_printer])dnl
|
||||
[ default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
+1
-17
@@ -103,7 +103,7 @@ m4_define([b4_int_type],
|
||||
# b4_int_type_for(NAME)
|
||||
# ---------------------
|
||||
# Return the smallest int type able to handle numbers ranging from
|
||||
# 'NAME_min' to 'NAME_max' (included).
|
||||
# `NAME_min' to `NAME_max' (included).
|
||||
m4_define([b4_int_type_for],
|
||||
[b4_int_type($1_min, $1_max)])
|
||||
|
||||
@@ -169,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. ##
|
||||
## ---------------- ##
|
||||
|
||||
+18
-14
@@ -17,8 +17,6 @@
|
||||
|
||||
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)
|
||||
# --------------------------------------------------------------
|
||||
@@ -40,14 +38,13 @@ m4_define([b4_integral_parser_table_define],
|
||||
};dnl
|
||||
])
|
||||
|
||||
|
||||
# b4_symbol_value_template(VAL, [TYPE])
|
||||
# -------------------------------------
|
||||
# Same as b4_symbol_value, but used in a template method. It makes
|
||||
# a difference when using variants. Note that b4_value_type_setup_union
|
||||
# overrides b4_symbol_value, so we must override it again.
|
||||
# a difference when using variants.
|
||||
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])
|
||||
# --------------------
|
||||
@@ -204,10 +201,6 @@ b4_location_define])])[
|
||||
void error (const syntax_error& err);
|
||||
|
||||
private:
|
||||
/// This class is not copyable.
|
||||
]b4_parser_class_name[ (const ]b4_parser_class_name[&);
|
||||
]b4_parser_class_name[& operator= (const ]b4_parser_class_name[&);
|
||||
|
||||
/// State numbers.
|
||||
typedef int state_type;
|
||||
|
||||
@@ -598,7 +591,13 @@ m4_if(b4_prefix, [yy], [],
|
||||
YY_SYMBOL_PRINT (yymsg, yysym);]b4_variant_if([], [
|
||||
|
||||
// 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
|
||||
@@ -613,7 +612,12 @@ m4_if(b4_prefix, [yy], [],
|
||||
yyo << (yytype < yyntokens_ ? "token" : "nterm")
|
||||
<< ' ' << yytname_[yytype] << " ("]b4_locations_if([
|
||||
<< yysym.location << ": "])[;
|
||||
]b4_symbol_actions([printer])[
|
||||
switch (yytype)
|
||||
{
|
||||
]b4_symbol_foreach([b4_symbol_printer])dnl
|
||||
[ default:
|
||||
break;
|
||||
}
|
||||
yyo << ')';
|
||||
}
|
||||
#endif
|
||||
@@ -733,7 +737,7 @@ b4_dollar_popdef])[]dnl
|
||||
yynewstate, since the latter expects the semantical and the
|
||||
location values to have been already stored, initialize these
|
||||
stacks with a primary value. */
|
||||
yystack_.clear ();
|
||||
yystack_ = stack_type (0);
|
||||
yypush_ (YY_NULL, 0, yyla);
|
||||
|
||||
// A new symbol was pushed on the stack.
|
||||
@@ -820,7 +824,7 @@ b4_dollar_popdef])[]dnl
|
||||
variants. */
|
||||
b4_symbol_variant([[yyr1_@{yyn@}]], [yylhs.value], [build])],[
|
||||
/* If YYLEN is nonzero, implement the default value of the action:
|
||||
'$$ = $1'. Otherwise, use the top of the stack.
|
||||
`$$ = $1'. Otherwise, use the top of the stack.
|
||||
|
||||
Otherwise, the following line sets YYLHS.VALUE to garbage.
|
||||
This behavior is undocumented and Bison
|
||||
|
||||
+71
-260
@@ -20,8 +20,7 @@ m4_include(b4_pkgdatadir/[java.m4])
|
||||
b4_defines_if([b4_fatal([%s: %%defines does not make sense in Java],
|
||||
[b4_skeleton])])
|
||||
|
||||
# We do not depend on %debug in Java, but pacify warnings about
|
||||
# non-used flags.
|
||||
# We don't depend on %debug in Java, but pacify warnings about non-used flags.
|
||||
b4_parse_trace_if([0], [0])
|
||||
|
||||
m4_define([b4_symbol_no_destructor_assert],
|
||||
@@ -31,57 +30,6 @@ m4_define([b4_symbol_no_destructor_assert],
|
||||
[b4_symbol_action_location([$1], [destructor])])])])
|
||||
b4_symbol_foreach([b4_symbol_no_destructor_assert])
|
||||
|
||||
# Setup some macros for api.push-pull.
|
||||
b4_percent_define_default([[api.push-pull]], [[pull]])
|
||||
b4_percent_define_check_values([[[[api.push-pull]],
|
||||
[[pull]], [[push]], [[both]]]])
|
||||
|
||||
# Define m4 conditional macros that encode the value
|
||||
# of the api.push-pull flag.
|
||||
b4_define_flag_if([pull]) m4_define([b4_pull_flag], [[1]])
|
||||
b4_define_flag_if([push]) m4_define([b4_push_flag], [[1]])
|
||||
m4_case(b4_percent_define_get([[api.push-pull]]),
|
||||
[pull], [m4_define([b4_push_flag], [[0]])],
|
||||
[push], [m4_define([b4_pull_flag], [[0]])])
|
||||
|
||||
# Define a macro to be true when api.push-pull has the value "both".
|
||||
m4_define([b4_both_if],[b4_push_if([b4_pull_if([$1],[$2])],[$2])])
|
||||
|
||||
# Handle BISON_USE_PUSH_FOR_PULL for the test suite. So that push parsing
|
||||
# tests function as written, do not let BISON_USE_PUSH_FOR_PULL modify the
|
||||
# behavior of Bison at all when push parsing is already requested.
|
||||
b4_define_flag_if([use_push_for_pull])
|
||||
b4_use_push_for_pull_if([
|
||||
b4_push_if([m4_define([b4_use_push_for_pull_flag], [[0]])],
|
||||
[m4_define([b4_push_flag], [[1]])])])
|
||||
|
||||
# Define a macro to encapsulate the parse state variables.
|
||||
# This allows them to be defined either in parse() when doing
|
||||
# pull parsing, or as class instance variable when doing push parsing.
|
||||
m4_define([b4_define_state],[[
|
||||
/* Lookahead and lookahead in internal form. */
|
||||
int yychar = yyempty_;
|
||||
int yytoken = 0;
|
||||
|
||||
/* State. */
|
||||
int yyn = 0;
|
||||
int yylen = 0;
|
||||
int yystate = 0;
|
||||
YYStack yystack = new YYStack ();
|
||||
int label = YYNEWSTATE;
|
||||
|
||||
/* Error handling. */
|
||||
int yynerrs_ = 0;
|
||||
]b4_locations_if([/* The location where the error started. */
|
||||
b4_location_type yyerrloc = null;
|
||||
|
||||
/* Location. */
|
||||
b4_location_type yylloc = new b4_location_type (null, null);])[
|
||||
|
||||
/* Semantic value of the lookahead. */
|
||||
]b4_yystype[ yylval = null;
|
||||
]])
|
||||
|
||||
b4_output_begin([b4_parser_file_name])
|
||||
b4_copyright([Skeleton implementation for Bison LALR(1) parsers in Java],
|
||||
[2007-2013])
|
||||
@@ -107,9 +55,7 @@ b4_percent_define_get3([implements], [ implements ])[
|
||||
{
|
||||
]b4_identification[
|
||||
]b4_error_verbose_if([[
|
||||
/**
|
||||
* True if verbose error messages are enabled.
|
||||
*/
|
||||
/** True if verbose error messages are enabled. */
|
||||
private boolean yyErrorVerbose = true;
|
||||
|
||||
/**
|
||||
@@ -130,24 +76,18 @@ b4_locations_if([[
|
||||
* A class defining a pair of positions. Positions, defined by the
|
||||
* <code>]b4_position_type[</code> class, denote a point in the input.
|
||||
* Locations represent a part of the input through the beginning
|
||||
* and ending positions.
|
||||
*/
|
||||
* and ending positions. */
|
||||
public class ]b4_location_type[ {
|
||||
/**
|
||||
* The first, inclusive, position in the range.
|
||||
*/
|
||||
/** The first, inclusive, position in the range. */
|
||||
public ]b4_position_type[ begin;
|
||||
|
||||
/**
|
||||
* The first position beyond the range.
|
||||
*/
|
||||
/** The first position beyond the range. */
|
||||
public ]b4_position_type[ end;
|
||||
|
||||
/**
|
||||
* Create a <code>]b4_location_type[</code> denoting an empty range located at
|
||||
* a given point.
|
||||
* @@param loc The position at which the range is anchored.
|
||||
*/
|
||||
* @@param loc The position at which the range is anchored. */
|
||||
public ]b4_location_type[ (]b4_position_type[ loc) {
|
||||
this.begin = this.end = loc;
|
||||
}
|
||||
@@ -155,8 +95,7 @@ b4_locations_if([[
|
||||
/**
|
||||
* Create a <code>]b4_location_type[</code> from the endpoints of the range.
|
||||
* @@param begin The first position included in the range.
|
||||
* @@param end The first position beyond the range.
|
||||
*/
|
||||
* @@param end The first position beyond the range. */
|
||||
public ]b4_location_type[ (]b4_position_type[ begin, ]b4_position_type[ end) {
|
||||
this.begin = begin;
|
||||
this.end = end;
|
||||
@@ -165,8 +104,7 @@ b4_locations_if([[
|
||||
/**
|
||||
* Print a representation of the location. For this to be correct,
|
||||
* <code>]b4_position_type[</code> should override the <code>equals</code>
|
||||
* method.
|
||||
*/
|
||||
* method. */
|
||||
public String toString () {
|
||||
if (begin.equals (end))
|
||||
return begin.toString ();
|
||||
@@ -198,28 +136,24 @@ b4_locations_if([[
|
||||
|
||||
]b4_locations_if([[/**
|
||||
* Method to retrieve the beginning position of the last scanned token.
|
||||
* @@return the position at which the last scanned token starts.
|
||||
*/
|
||||
* @@return the position at which the last scanned token starts. */
|
||||
]b4_position_type[ getStartPos ();
|
||||
|
||||
/**
|
||||
* Method to retrieve the ending position of the last scanned token.
|
||||
* @@return the first position beyond the last scanned token.
|
||||
*/
|
||||
* @@return the first position beyond the last scanned token. */
|
||||
]b4_position_type[ getEndPos ();]])[
|
||||
|
||||
/**
|
||||
* Method to retrieve the semantic value of the last scanned token.
|
||||
* @@return the semantic value of the last scanned token.
|
||||
*/
|
||||
* @@return the semantic value of the last scanned token. */
|
||||
]b4_yystype[ getLVal ();
|
||||
|
||||
/**
|
||||
* Entry point for the scanner. Returns the token identifier corresponding
|
||||
* to the next token and prepares to return the semantic value
|
||||
* ]b4_locations_if([and beginning/ending positions ])[of the token.
|
||||
* @@return the token identifier corresponding to the next token.
|
||||
*/
|
||||
* @@return the token identifier corresponding to the next token. */
|
||||
int yylex () ]b4_maybe_throws([b4_lex_throws])[;
|
||||
|
||||
/**
|
||||
@@ -228,8 +162,7 @@ b4_locations_if([[
|
||||
*
|
||||
* ]b4_locations_if([[@@param loc The location of the element to which the
|
||||
* error message is related]])[
|
||||
* @@param msg The string for the error message.
|
||||
*/
|
||||
* @@param msg The string for the error message. */
|
||||
void yyerror (]b4_locations_if([b4_location_type[ loc, ]])[String msg);]
|
||||
}
|
||||
|
||||
@@ -237,9 +170,7 @@ b4_locations_if([[
|
||||
]b4_percent_code_get([[lexer]])[
|
||||
}
|
||||
|
||||
]])[/**
|
||||
* The object doing lexical analysis for us.
|
||||
*/
|
||||
]])[/** The object doing lexical analysis for us. */
|
||||
private Lexer yylexer;
|
||||
]
|
||||
b4_parse_param_vars
|
||||
@@ -405,49 +336,34 @@ b4_lexer_if([[
|
||||
|
||||
/**
|
||||
* Returned by a Bison action in order to stop the parsing process and
|
||||
* return success (<tt>true</tt>).
|
||||
*/
|
||||
* return success (<tt>true</tt>). */
|
||||
public static final int YYACCEPT = 0;
|
||||
|
||||
/**
|
||||
* Returned by a Bison action in order to stop the parsing process and
|
||||
* return failure (<tt>false</tt>).
|
||||
*/
|
||||
* return failure (<tt>false</tt>). */
|
||||
public static final int YYABORT = 1;
|
||||
|
||||
]b4_push_if([
|
||||
/**
|
||||
* Returned by a Bison action in order to request a new token.
|
||||
*/
|
||||
public static final int YYPUSH_MORE = 4;])[
|
||||
|
||||
/**
|
||||
* Returned by a Bison action in order to start error recovery without
|
||||
* printing an error message.
|
||||
*/
|
||||
* printing an error message. */
|
||||
public static final int YYERROR = 2;
|
||||
|
||||
/**
|
||||
* Internal return codes that are not supported for user semantic
|
||||
* actions.
|
||||
*/
|
||||
// Internal return codes that are not supported for user semantic
|
||||
// actions.
|
||||
private static final int YYERRLAB = 3;
|
||||
private static final int YYNEWSTATE = 4;
|
||||
private static final int YYDEFAULT = 5;
|
||||
private static final int YYREDUCE = 6;
|
||||
private static final int YYERRLAB1 = 7;
|
||||
private static final int YYRETURN = 8;
|
||||
]b4_push_if([[ private static final int YYGETTOKEN = 9; /* Signify that a new token is expected when doing push-parsing. */]])[
|
||||
|
||||
private int yyerrstatus_ = 0;
|
||||
|
||||
]b4_push_if([dnl
|
||||
b4_define_state])[
|
||||
/**
|
||||
* Return whether error recovery is being done. In this state, the parser
|
||||
* reads token until it reaches a known state, and then restarts normal
|
||||
* operation.
|
||||
*/
|
||||
* operation. */
|
||||
public final boolean recovering ()
|
||||
{
|
||||
return yyerrstatus_ == 0;
|
||||
@@ -459,7 +375,7 @@ b4_define_state])[
|
||||
]b4_locations_if([b4_location_type[ yyloc = yylloc (yystack, yylen);]])[
|
||||
|
||||
/* If YYLEN is nonzero, implement the default value of the action:
|
||||
'$$ = $1'. Otherwise, use the top of the stack.
|
||||
`$$ = $1'. Otherwise, use the top of the stack.
|
||||
|
||||
Otherwise, the following line sets YYVAL to garbage.
|
||||
This behavior is undocumented and Bison
|
||||
@@ -547,7 +463,6 @@ b4_define_state])[
|
||||
+ (yyvaluep == null ? "(null)" : yyvaluep.toString ()) + ")");
|
||||
}
|
||||
|
||||
]b4_push_if([],[[
|
||||
/**
|
||||
* Parse input from the scanner that was specified at object construction
|
||||
* time. Return whether the end of the input was reached successfully.
|
||||
@@ -555,53 +470,46 @@ b4_define_state])[
|
||||
* @@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])])[]])[
|
||||
]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])])])[
|
||||
public boolean parse () ]b4_maybe_throws([b4_list2([b4_lex_throws], [b4_throws])])[
|
||||
{
|
||||
]b4_locations_if([/* @@$. */
|
||||
b4_location_type yyloc;])[
|
||||
]b4_push_if([],[[
|
||||
]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 ();
|
||||
|
||||
/* 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");
|
||||
yyerrstatus_ = 0;
|
||||
|
||||
/* Initialize the stack. */
|
||||
yystack.push (yystate, yylval ]b4_locations_if([, yylloc])[);
|
||||
]m4_ifdef([b4_initial_action], [
|
||||
b4_dollar_pushdef([yylval], [], [yylloc])dnl
|
||||
/* User initialization code. */
|
||||
b4_user_initial_action
|
||||
b4_dollar_popdef[]dnl
|
||||
])[
|
||||
]])[
|
||||
]b4_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;
|
||||
b4_dollar_popdef])[]dnl
|
||||
|
||||
boolean push_token_consumed = true;
|
||||
]])[
|
||||
[ /* Initialize the stack. */
|
||||
yystack.push (yystate, yylval]b4_locations_if([, yylloc])[);
|
||||
|
||||
int label = YYNEWSTATE;
|
||||
for (;;)
|
||||
switch (label)
|
||||
{
|
||||
@@ -614,8 +522,7 @@ b4_dollar_popdef[]dnl
|
||||
|
||||
/* Accept? */
|
||||
if (yystate == yyfinal_)
|
||||
]b4_push_if([{label = YYACCEPT; break;}],
|
||||
[return true;])[
|
||||
return true;
|
||||
|
||||
/* Take a decision. First try without lookahead. */
|
||||
yyn = yypact_[yystate];
|
||||
@@ -624,27 +531,16 @@ b4_dollar_popdef[]dnl
|
||||
label = YYDEFAULT;
|
||||
break;
|
||||
}
|
||||
]b4_push_if([ /* Fall Through */
|
||||
|
||||
case YYGETTOKEN:])[
|
||||
/* Read a lookahead token. */
|
||||
if (yychar == yyempty_)
|
||||
{
|
||||
]b4_push_if([[
|
||||
if (!push_token_consumed)
|
||||
return YYPUSH_MORE;
|
||||
yycdebug ("Reading a token: ");
|
||||
yychar = yylextoken;
|
||||
yylval = yylexval;]b4_locations_if([
|
||||
yylloc = yylexloc;])[
|
||||
push_token_consumed = false;]])[
|
||||
]b4_push_if([],[[
|
||||
yycdebug ("Reading a token: ");
|
||||
yychar = yylexer.yylex ();
|
||||
yylval = yylexer.getLVal ();]b4_locations_if([
|
||||
yylloc = new b4_location_type (yylexer.getStartPos (),
|
||||
yylexer.getEndPos ());])[
|
||||
]])[
|
||||
yychar = yylexer.yylex ();]
|
||||
b4_locations_if([[
|
||||
yylloc = new ]b4_location_type[(yylexer.getStartPos (),
|
||||
yylexer.getEndPos ());]])
|
||||
yylval = yylexer.getLVal ();[
|
||||
}
|
||||
|
||||
/* Convert token to internal form. */
|
||||
@@ -741,10 +637,10 @@ b4_dollar_popdef[]dnl
|
||||
{
|
||||
/* Return failure if at end of input. */
|
||||
if (yychar == Lexer.EOF)
|
||||
]b4_push_if([{label = YYABORT; break;}],[return false;])[
|
||||
return false;
|
||||
}
|
||||
else
|
||||
yychar = yyempty_;
|
||||
yychar = yyempty_;
|
||||
}
|
||||
|
||||
/* Else will try to reuse lookahead token after shifting the error
|
||||
@@ -752,9 +648,9 @@ b4_dollar_popdef[]dnl
|
||||
label = YYERRLAB1;
|
||||
break;
|
||||
|
||||
/*-------------------------------------------------.
|
||||
/*---------------------------------------------------.
|
||||
| errorlab -- error raised explicitly by YYERROR. |
|
||||
`-------------------------------------------------*/
|
||||
`---------------------------------------------------*/
|
||||
case YYERROR:
|
||||
|
||||
]b4_locations_if([yyerrloc = yystack.locationAt (yylen - 1);])[
|
||||
@@ -786,10 +682,9 @@ b4_dollar_popdef[]dnl
|
||||
}
|
||||
}
|
||||
|
||||
/* Pop the current state because it cannot handle the
|
||||
* error token. */
|
||||
/* Pop the current state because it cannot handle the error token. */
|
||||
if (yystack.height == 0)
|
||||
]b4_push_if([{label = YYABORT; break;}],[return false;])[
|
||||
return false;
|
||||
|
||||
]b4_locations_if([yyerrloc = yystack.locationAt (0);])[
|
||||
yystack.pop ();
|
||||
@@ -798,11 +693,7 @@ b4_dollar_popdef[]dnl
|
||||
yystack.print (yyDebugStream);
|
||||
}
|
||||
|
||||
if (label == YYABORT)
|
||||
/* Leave the switch. */
|
||||
break;
|
||||
|
||||
]b4_locations_if([
|
||||
]b4_locations_if([
|
||||
/* Muck with the stack to setup for yylloc. */
|
||||
yystack.push (0, null, yylloc);
|
||||
yystack.push (0, null, yyerrloc);
|
||||
@@ -820,91 +711,13 @@ b4_dollar_popdef[]dnl
|
||||
|
||||
/* Accept. */
|
||||
case YYACCEPT:
|
||||
]b4_push_if([this.push_parse_initialized = false; return YYACCEPT;],
|
||||
[return true;])[
|
||||
return true;
|
||||
|
||||
/* Abort. */
|
||||
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.
|
||||
private String yysyntax_error (int yystate, int tok)
|
||||
@@ -939,8 +752,8 @@ b4_both_if([[
|
||||
*/
|
||||
if (tok != yyempty_)
|
||||
{
|
||||
/* FIXME: This method of building the message is not compatible
|
||||
with internationalization. */
|
||||
// FIXME: This method of building the message is not compatible
|
||||
// with internationalization.
|
||||
StringBuffer res =
|
||||
new StringBuffer ("syntax error, unexpected ");
|
||||
res.append (yytnamerr_ (yytname_[tok]));
|
||||
@@ -989,9 +802,8 @@ b4_both_if([[
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the given <code>yytable_</code>
|
||||
* value indicates a syntax error.
|
||||
* @@param yyvalue the value to check
|
||||
* Whether the given <code>yytable_</code> value indicates a syntax error.
|
||||
* @@param yyvalue the value to check
|
||||
*/
|
||||
private static boolean yy_table_value_is_error_ (int yyvalue)
|
||||
{
|
||||
@@ -1013,7 +825,6 @@ b4_both_if([[
|
||||
]b4_integral_parser_table_define([rline], [b4_rline],
|
||||
[[YYRLINE[YYN] -- Source line where rule number YYN was defined.]])[
|
||||
|
||||
|
||||
// Report on the debug stream that the rule yyrule is going to be reduced.
|
||||
private void yy_reduce_print (int yyrule, YYStack yystack)
|
||||
{
|
||||
|
||||
+24
-43
@@ -25,7 +25,8 @@ m4_define([b4_position_define],
|
||||
[[ /// Abstract a position.
|
||||
class position
|
||||
{
|
||||
public:]m4_ifdef([b4_location_constructors], [[
|
||||
public:
|
||||
]m4_ifdef([b4_location_constructors], [[
|
||||
/// Construct a position.
|
||||
explicit position (]b4_percent_define_get([[filename_type]])[* f = YY_NULL,
|
||||
unsigned int l = ]b4_location_initial_line[u,
|
||||
@@ -52,17 +53,14 @@ m4_define([b4_position_define],
|
||||
/// (line related) Advance to the COUNT next lines.
|
||||
void lines (int count = 1)
|
||||
{
|
||||
if (count)
|
||||
{
|
||||
column = ]b4_location_initial_column[u;
|
||||
line = add_ (line, count, ]b4_location_initial_line[);
|
||||
}
|
||||
column = ]b4_location_initial_column[u;
|
||||
line += count;
|
||||
}
|
||||
|
||||
/// (column related) Advance to the COUNT next columns.
|
||||
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;
|
||||
/// Current column number.
|
||||
unsigned int column;
|
||||
|
||||
private:
|
||||
/// Compute max(min, lhs+rhs) (provided min <= lhs).
|
||||
static unsigned int add_ (unsigned int lhs, int rhs, unsigned int min)
|
||||
{
|
||||
return (0 < rhs || -static_cast<unsigned int>(rhs) < lhs
|
||||
? rhs + lhs
|
||||
: min);
|
||||
}
|
||||
};
|
||||
|
||||
/// Add and assign a position.
|
||||
inline position&
|
||||
operator+= (position& res, int width)
|
||||
operator+= (position& res, const int width)
|
||||
{
|
||||
res.columns (width);
|
||||
return res;
|
||||
}
|
||||
|
||||
/// Add two position objects.
|
||||
inline position
|
||||
operator+ (position res, int width)
|
||||
inline const position
|
||||
operator+ (const position& begin, const int width)
|
||||
{
|
||||
position res = begin;
|
||||
return res += width;
|
||||
}
|
||||
|
||||
/// Add and assign a position.
|
||||
inline position&
|
||||
operator-= (position& res, int width)
|
||||
operator-= (position& res, const int width)
|
||||
{
|
||||
return res += -width;
|
||||
}
|
||||
|
||||
/// Add two position objects.
|
||||
inline position
|
||||
operator- (position res, int width)
|
||||
inline const position
|
||||
operator- (const position& begin, const int width)
|
||||
{
|
||||
return res -= width;
|
||||
return begin + -width;
|
||||
}
|
||||
]b4_percent_define_flag_if([[define_location_comparison]], [[
|
||||
/// Compare two position objects.
|
||||
@@ -196,13 +186,13 @@ m4_define([b4_location_define],
|
||||
}
|
||||
|
||||
/// Extend the current location to the COUNT next columns.
|
||||
void columns (int count = 1)
|
||||
void columns (unsigned int count = 1)
|
||||
{
|
||||
end += count;
|
||||
}
|
||||
|
||||
/// Extend the current location to the COUNT next lines.
|
||||
void lines (int count = 1)
|
||||
void lines (unsigned int count = 1)
|
||||
{
|
||||
end.lines (count);
|
||||
}
|
||||
@@ -217,35 +207,26 @@ m4_define([b4_location_define],
|
||||
};
|
||||
|
||||
/// 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;
|
||||
return res;
|
||||
}
|
||||
|
||||
/// Change end position in place.
|
||||
inline location& operator+= (location& res, int width)
|
||||
/// Add two location objects.
|
||||
inline const location operator+ (const location& begin, unsigned int width)
|
||||
{
|
||||
location res = begin;
|
||||
res.columns (width);
|
||||
return res;
|
||||
}
|
||||
|
||||
/// Change end position.
|
||||
inline location operator+ (location res, int width)
|
||||
/// Add and assign a location.
|
||||
inline location& operator+= (location& res, unsigned int width)
|
||||
{
|
||||
return res += width;
|
||||
}
|
||||
|
||||
/// Change end position in place.
|
||||
inline location& operator-= (location& res, int width)
|
||||
{
|
||||
return res += -width;
|
||||
}
|
||||
|
||||
/// Change end position.
|
||||
inline location operator- (const location& begin, int width)
|
||||
{
|
||||
return begin + -width;
|
||||
res.columns (width);
|
||||
return res;
|
||||
}
|
||||
]b4_percent_define_flag_if([[define_location_comparison]], [[
|
||||
/// Compare two location objects.
|
||||
|
||||
@@ -72,12 +72,6 @@ m4_define([b4_stack_define],
|
||||
seq_.pop_back ();
|
||||
}
|
||||
|
||||
void
|
||||
clear ()
|
||||
{
|
||||
seq_.clear ();
|
||||
}
|
||||
|
||||
inline
|
||||
typename S::size_type
|
||||
size () const
|
||||
@@ -100,8 +94,6 @@ m4_define([b4_stack_define],
|
||||
}
|
||||
|
||||
private:
|
||||
stack (const stack&);
|
||||
stack& operator= (const stack&);
|
||||
/// The wrapped container.
|
||||
S seq_;
|
||||
};
|
||||
|
||||
+39
-56
@@ -26,7 +26,7 @@
|
||||
# YYTYPE.
|
||||
m4_define([b4_symbol_variant],
|
||||
[m4_pushdef([b4_dollar_dollar],
|
||||
[$2.$3< $][3 > (m4_shift3($@))])dnl
|
||||
[$2.$3< $][3 >(m4_shift3($@))])dnl
|
||||
switch ($1)
|
||||
{
|
||||
b4_type_foreach([b4_type_action_])[]dnl
|
||||
@@ -63,7 +63,7 @@ m4_define([b4_char_sizeof],
|
||||
[b4_symbol_if([$1], [has_type],
|
||||
[
|
||||
m4_map([ b4_symbol_tag_comment], [$@])dnl
|
||||
char _b4_char_sizeof_dummy@{sizeof(b4_symbol([$1], [type]))@};
|
||||
char _b4_char_sizeof_dummy@{sizeof([b4_symbol([$1], [type])])@};
|
||||
])])
|
||||
|
||||
|
||||
@@ -95,22 +95,22 @@ m4_define([b4_variant_define],
|
||||
|
||||
/// Empty construction.
|
||||
variant ()]b4_parse_assert_if([
|
||||
: yytname_ (YY_NULL)])[
|
||||
: tname (YY_NULL)])[
|
||||
{}
|
||||
|
||||
/// Construct and fill.
|
||||
template <typename T>
|
||||
variant (const T& t)]b4_parse_assert_if([
|
||||
: yytname_ (typeid (T).name ())])[
|
||||
: tname (typeid (T).name ())])[
|
||||
{
|
||||
YYASSERT (sizeof (T) <= S);
|
||||
new (yyas_<T> ()) T (t);
|
||||
new (buffer.raw) T (t);
|
||||
}
|
||||
|
||||
/// Destruction, allowed only if empty.
|
||||
~variant ()
|
||||
{]b4_parse_assert_if([
|
||||
YYASSERT (!yytname_);
|
||||
YYASSERT (!tname);
|
||||
])[}
|
||||
|
||||
/// Instantiate an empty \a T in here.
|
||||
@@ -118,10 +118,10 @@ m4_define([b4_variant_define],
|
||||
T&
|
||||
build ()
|
||||
{]b4_parse_assert_if([
|
||||
YYASSERT (!yytname_);
|
||||
YYASSERT (!tname);
|
||||
YYASSERT (sizeof (T) <= S);
|
||||
yytname_ = typeid (T).name ();])[
|
||||
return *new (yyas_<T> ()) T;
|
||||
tname = typeid (T).name ();])[
|
||||
return *new (buffer.raw) T;
|
||||
}
|
||||
|
||||
/// Instantiate a \a T in here from \a t.
|
||||
@@ -129,10 +129,10 @@ m4_define([b4_variant_define],
|
||||
T&
|
||||
build (const T& t)
|
||||
{]b4_parse_assert_if([
|
||||
YYASSERT (!yytname_);
|
||||
YYASSERT (!tname);
|
||||
YYASSERT (sizeof (T) <= S);
|
||||
yytname_ = typeid (T).name ();])[
|
||||
return *new (yyas_<T> ()) T (t);
|
||||
tname = typeid (T).name ();])[
|
||||
return *new (buffer.raw) T (t);
|
||||
}
|
||||
|
||||
/// Accessor to a built \a T.
|
||||
@@ -140,9 +140,9 @@ m4_define([b4_variant_define],
|
||||
T&
|
||||
as ()
|
||||
{]b4_parse_assert_if([
|
||||
YYASSERT (yytname_ == typeid (T).name ());
|
||||
YYASSERT (tname == typeid (T).name ());
|
||||
YYASSERT (sizeof (T) <= S);])[
|
||||
return *yyas_<T> ();
|
||||
return reinterpret_cast<T&> (buffer.raw);
|
||||
}
|
||||
|
||||
/// Const accessor to a built \a T (for %printer).
|
||||
@@ -150,9 +150,9 @@ m4_define([b4_variant_define],
|
||||
const T&
|
||||
as () const
|
||||
{]b4_parse_assert_if([
|
||||
YYASSERT (yytname_ == typeid (T).name ());
|
||||
YYASSERT (tname == typeid (T).name ());
|
||||
YYASSERT (sizeof (T) <= S);])[
|
||||
return *yyas_<T> ();
|
||||
return reinterpret_cast<const T&> (buffer.raw);
|
||||
}
|
||||
|
||||
/// Swap the content with \a other, of same type.
|
||||
@@ -167,9 +167,9 @@ m4_define([b4_variant_define],
|
||||
void
|
||||
swap (self_type& other)
|
||||
{]b4_parse_assert_if([
|
||||
YYASSERT (yytname_);
|
||||
YYASSERT (yytname_ == other.yytname_);])[
|
||||
std::swap (as<T> (), other.as<T> ());
|
||||
YYASSERT (tname);
|
||||
YYASSERT (tname == other.tname);])[
|
||||
std::swap (as<T>(), other.as<T>());
|
||||
}
|
||||
|
||||
/// Move the content of \a other to this.
|
||||
@@ -179,10 +179,10 @@ m4_define([b4_variant_define],
|
||||
void
|
||||
move (self_type& other)
|
||||
{]b4_parse_assert_if([
|
||||
YYASSERT (!yytname_);])[
|
||||
build<T> ();
|
||||
swap<T> (other);
|
||||
other.destroy<T> ();
|
||||
YYASSERT (!tname);])[
|
||||
build<T>();
|
||||
swap<T>(other);
|
||||
other.destroy<T>();
|
||||
}
|
||||
|
||||
/// Copy the content of \a other to this.
|
||||
@@ -199,7 +199,7 @@ m4_define([b4_variant_define],
|
||||
destroy ()
|
||||
{
|
||||
as<T> ().~T ();]b4_parse_assert_if([
|
||||
yytname_ = YY_NULL;])[
|
||||
tname = YY_NULL;])[
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -207,34 +207,17 @@ m4_define([b4_variant_define],
|
||||
self_type& operator=(const self_type&);
|
||||
variant (const self_type&);
|
||||
|
||||
/// Accessor to raw memory as \a T.
|
||||
template <typename T>
|
||||
T*
|
||||
yyas_ ()
|
||||
{
|
||||
void *yyp = yybuffer_.yyraw;
|
||||
return static_cast<T*> (yyp);
|
||||
}
|
||||
|
||||
/// Const accessor to raw memory as \a T.
|
||||
template <typename T>
|
||||
const T*
|
||||
yyas_ () const
|
||||
{
|
||||
const void *yyp = yybuffer_.yyraw;
|
||||
return static_cast<const T*> (yyp);
|
||||
}
|
||||
|
||||
/// A buffer large enough to store any of the semantic values.
|
||||
/// Long double is chosen as it has the strongest alignment
|
||||
/// constraints.
|
||||
union
|
||||
{
|
||||
/// Strongest alignment constraints.
|
||||
long double yyalign_me;
|
||||
/// A buffer large enough to store any of the semantic values.
|
||||
char yyraw[S];
|
||||
} yybuffer_;]b4_parse_assert_if([
|
||||
long double align_me;
|
||||
char raw[S];
|
||||
} buffer;]b4_parse_assert_if([
|
||||
|
||||
/// Whether the content is built: if defined, the name of the stored type.
|
||||
const char *yytname_;])[
|
||||
const char* tname;])[
|
||||
};
|
||||
]])
|
||||
|
||||
@@ -244,16 +227,16 @@ m4_define([b4_variant_define],
|
||||
## -------------------------- ##
|
||||
|
||||
|
||||
# b4_value_type_declare
|
||||
# ---------------------
|
||||
# b4_semantic_type_declare
|
||||
# ------------------------
|
||||
# Declare semantic_type.
|
||||
m4_define([b4_value_type_declare],
|
||||
[[ /// An auxiliary type to compute the largest semantic type.
|
||||
m4_define([b4_semantic_type_declare],
|
||||
[ /// An auxiliary type to compute the largest semantic type.
|
||||
union union_type
|
||||
{]b4_type_foreach([b4_char_sizeof])[};
|
||||
|
||||
/// Symbol semantic values.
|
||||
typedef variant<sizeof(union_type)> semantic_type;][]dnl
|
||||
typedef variant<sizeof(union_type)> semantic_type;dnl
|
||||
])
|
||||
|
||||
|
||||
@@ -263,7 +246,7 @@ m4_define([b4_value_type_declare],
|
||||
# ----------------------------
|
||||
m4_define([b4_symbol_value],
|
||||
[m4_ifval([$2],
|
||||
[$1.as< $2 > ()],
|
||||
[$1.as< $2 >()],
|
||||
[$1])])
|
||||
|
||||
# b4_symbol_value_template(VAL, [TYPE])
|
||||
@@ -271,7 +254,7 @@ m4_define([b4_symbol_value],
|
||||
# Same as b4_symbol_value, but used in a template method.
|
||||
m4_define([b4_symbol_value_template],
|
||||
[m4_ifval([$2],
|
||||
[$1.template as< $2 > ()],
|
||||
[$1.template as< $2 >()],
|
||||
[$1])])
|
||||
|
||||
|
||||
@@ -328,7 +311,7 @@ b4_join(b4_symbol_if([$1], [has_type],
|
||||
|
||||
|
||||
# b4_basic_symbol_constructor_declare
|
||||
# -----------------------------------
|
||||
# ----------------------------------
|
||||
# Generate a constructor declaration for basic_symbol from given type.
|
||||
m4_define([b4_basic_symbol_constructor_declare],
|
||||
[[
|
||||
|
||||
@@ -373,7 +373,7 @@
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="empty">
|
||||
<xsl:text> %empty</xsl:text>
|
||||
<xsl:text> /* empty */</xsl:text>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="lookaheads">
|
||||
|
||||
+39
-16
@@ -143,6 +143,7 @@ m4_define([b4_rhs_value],
|
||||
[b4_symbol_value([yyvsp@{b4_subtract([$2], [$1])@}], [$3])])
|
||||
|
||||
|
||||
|
||||
## ----------- ##
|
||||
## Locations. ##
|
||||
## ----------- ##
|
||||
@@ -175,19 +176,36 @@ m4_define([b4_declare_scanner_communication_variables], [[
|
||||
int yychar;
|
||||
|
||||
]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
|
||||
or non-GCC compilers. */
|
||||
YY_INITIAL_VALUE (static YYSTYPE yyval_default;)
|
||||
YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);]b4_locations_if([[
|
||||
static YYSTYPE yyval_default;
|
||||
# define YY_INITIAL_VALUE(Value) = Value
|
||||
#endif]b4_locations_if([[
|
||||
static YYLTYPE yyloc_default][]b4_yyloc_default[;]])])[
|
||||
#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
|
||||
# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
|
||||
# define YY_IGNORE_MAYBE_UNINITIALIZED_END
|
||||
#endif
|
||||
#ifndef YY_INITIAL_VALUE
|
||||
# define YY_INITIAL_VALUE(Value) /* Nothing. */
|
||||
#endif
|
||||
|
||||
/* The semantic value of the lookahead symbol. */
|
||||
YYSTYPE yylval YY_INITIAL_VALUE(yyval_default);]b4_locations_if([[
|
||||
|
||||
/* Location data for the lookahead symbol. */
|
||||
static YYLTYPE yyloc_default]b4_yyloc_default[;
|
||||
YYLTYPE yylloc = yyloc_default;]])],
|
||||
[[/* The semantic value of the lookahead symbol. */
|
||||
YYSTYPE yylval;]b4_locations_if([[
|
||||
/* Location data for the lookahead symbol. */
|
||||
YYLTYPE yylloc]b4_yyloc_default[;]])[
|
||||
YYLTYPE yylloc]b4_pure_if([ = yyloc_default], [b4_yyloc_default])[;
|
||||
]])b4_pure_if([], [[
|
||||
|
||||
/* Number of syntax errors so far. */
|
||||
int yynerrs;]])])
|
||||
|
||||
@@ -205,9 +223,9 @@ m4_define([b4_declare_parser_state_variables], [b4_pure_if([[
|
||||
int yyerrstatus;
|
||||
|
||||
/* The stacks and their tools:
|
||||
'yyss': related to states.
|
||||
'yyvs': related to semantic values.]b4_locations_if([[
|
||||
'yyls': related to locations.]])[
|
||||
`yyss': related to states.
|
||||
`yyvs': related to semantic values.]b4_locations_if([[
|
||||
`yyls': related to locations.]])[
|
||||
|
||||
Refer to the stacks through separate pointers, to allow yyoverflow
|
||||
to reallocate them elsewhere. */
|
||||
@@ -413,7 +431,12 @@ typedef short int yytype_int16;
|
||||
# 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]])[
|
||||
|
||||
@@ -445,7 +468,7 @@ b4_push_if([], [b4_lac_if([], [[
|
||||
# endif]])])[
|
||||
|
||||
# ifdef YYSTACK_ALLOC
|
||||
/* Pacify GCC's 'empty if-body' warning. */
|
||||
/* Pacify GCC's `empty if-body' warning. */
|
||||
# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
|
||||
# ifndef YYSTACK_ALLOC_MAXIMUM
|
||||
/* The OS might guarantee only one guard page at the bottom of the stack,
|
||||
@@ -1631,7 +1654,7 @@ yyreduce:
|
||||
yylen = yyr2[yyn];
|
||||
|
||||
/* If YYLEN is nonzero, implement the default value of the action:
|
||||
'$$ = $1'.
|
||||
`$$ = $1'.
|
||||
|
||||
Otherwise, the following line sets YYVAL to garbage.
|
||||
This behavior is undocumented and Bison
|
||||
@@ -1679,7 +1702,7 @@ yyreduce:
|
||||
*++yyvsp = yyval;]b4_locations_if([
|
||||
*++yylsp = yyloc;])[
|
||||
|
||||
/* Now 'shift' the result of the reduction. Determine what state
|
||||
/* Now `shift' the result of the reduction. Determine what state
|
||||
that goes to, based on the state we popped back to and the rule
|
||||
number reduced by. */
|
||||
|
||||
|
||||
+304
-704
File diff suppressed because it is too large
Load Diff
@@ -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
-15
@@ -23,10 +23,9 @@ doc_bison_TEXINFOS = \
|
||||
# Cannot express dependencies directly on file names because of Automake.
|
||||
# Obfuscate with a variable.
|
||||
doc_bison = doc/bison
|
||||
$(doc_bison).dvi: $(FIGS_GV:.gv=.eps)
|
||||
$(doc_bison).info: $(FIGS_GV:.gv=.txt)
|
||||
$(doc_bison).pdf: $(FIGS_GV:.gv=.pdf)
|
||||
$(doc_bison).html: $(FIGS_GV:.gv=.png)
|
||||
$(doc_bison).dvi: $(FIGS_DOT:.dot=.eps)
|
||||
$(doc_bison).pdf: $(FIGS_DOT:.dot=.pdf)
|
||||
$(doc_bison).html: $(FIGS_DOT:.dot=.png)
|
||||
|
||||
TEXI2DVI = texi2dvi --build-dir=doc/bison.t2d -I doc
|
||||
CLEANDIRS = doc/bison.t2d
|
||||
@@ -38,7 +37,7 @@ MOSTLYCLEANFILES += $(top_srcdir)/doc/*.t
|
||||
CROSS_OPTIONS_PL = $(top_srcdir)/build-aux/cross-options.pl
|
||||
CROSS_OPTIONS_TEXI = $(top_srcdir)/doc/cross-options.texi
|
||||
$(CROSS_OPTIONS_TEXI): doc/bison.help $(CROSS_OPTIONS_PL)
|
||||
# Create $@~ which is the previous contents. Don't use 'mv' here so
|
||||
# Create $@~ which is the previous contents. Don't use `mv' here so
|
||||
# that even if we are interrupted, the file is still available for
|
||||
# diff in the next run. Note that $@ might not exist yet.
|
||||
$(AM_V_GEN){ test ! -f $@ || cat $@; } >$@~
|
||||
@@ -125,25 +124,25 @@ nodist_man_MANS = doc/yacc.1
|
||||
## ----------------------------- ##
|
||||
|
||||
CLEANDIRS += doc/figs
|
||||
FIGS_GV = \
|
||||
doc/figs/example.gv \
|
||||
doc/figs/example-reduce.gv doc/figs/example-shift.gv
|
||||
EXTRA_DIST += \
|
||||
$(FIGS_GV) $(FIGS_GV:.gv=.txt) \
|
||||
$(FIGS_GV:.gv=.eps) $(FIGS_GV:.gv=.pdf) $(FIGS_GV:.gv=.png)
|
||||
SUFFIXES += .gv .eps .pdf .png
|
||||
FIGS_DOT = \
|
||||
doc/figs/example.dot \
|
||||
doc/figs/example-reduce.dot doc/figs/example-shift.dot
|
||||
EXTRA_DIST += \
|
||||
$(FIGS_DOT) \
|
||||
$(FIGS_DOT:.dot=.eps) $(FIGS_DOT:.dot=.pdf) $(FIGS_DOT:.dot=.png)
|
||||
SUFFIXES += .dot .eps .pdf .png
|
||||
|
||||
.gv.eps:
|
||||
.dot.eps:
|
||||
$(AM_V_GEN) $(MKDIR_P) `echo "./$@" | sed -e 's,/[^/]*$$,,'`
|
||||
$(AM_V_at) $(DOT) -Gmargin=0 -Teps $< >$@.tmp
|
||||
$(AM_V_at) mv $@.tmp $@
|
||||
|
||||
.gv.pdf:
|
||||
.dot.pdf:
|
||||
$(AM_V_GEN) $(MKDIR_P) `echo "./$@" | sed -e 's,/[^/]*$$,,'`
|
||||
$(AM_V_at) $(DOT) -Gmargin=0 -Tpdf $< >$@.tmp
|
||||
$(AM_V_at) mv $@.tmp $@
|
||||
|
||||
.gv.png:
|
||||
.dot.png:
|
||||
$(AM_V_GEN) $(MKDIR_P) `echo "./$@" | sed -e 's,/[^/]*$$,,'`
|
||||
$(AM_V_at) $(DOT) -Gmargin=0 -Tpng $< >$@.tmp
|
||||
$(AM_V_at) mv $@.tmp $@
|
||||
|
||||
+2
-2
@@ -204,9 +204,9 @@ Format the list of directives for Bison for bench named C<$bench>.
|
||||
sub directives($@)
|
||||
{
|
||||
my ($bench, @directive) = @_;
|
||||
my $res = "/* Directives for bench '$bench'. */\n";
|
||||
my $res = "/* Directives for bench `$bench'. */\n";
|
||||
$res .= join ("\n", @directive) . "\n";
|
||||
$res .= "/* End of directives for bench '$bench'. */\n";
|
||||
$res .= "/* End of directives for bench `$bench'. */\n";
|
||||
return $res;
|
||||
}
|
||||
|
||||
|
||||
+16
-17
@@ -44,33 +44,32 @@ CLEANFILES += \
|
||||
# Avoid using BUILT_SOURCES which is too global.
|
||||
$(examples_calc___calc___OBJECTS): $(calc_sources_generated)
|
||||
|
||||
calc_sources_extracted = \
|
||||
examples/calc++/calc++-driver.cc \
|
||||
examples/calc++/calc++-driver.hh \
|
||||
examples/calc++/calc++-scanner.ll \
|
||||
calc_sources_extracted = \
|
||||
examples/calc++/calc++-driver.cc \
|
||||
examples/calc++/calc++-driver.hh \
|
||||
examples/calc++/calc++-scanner.ll \
|
||||
examples/calc++/calc++.cc
|
||||
calc_extracted = \
|
||||
$(calc_sources_extracted) \
|
||||
calc_extracted = \
|
||||
$(calc_sources_extracted) \
|
||||
examples/calc++/calc++-parser.yy
|
||||
extracted += $(calc_extracted)
|
||||
calc_sources_generated = \
|
||||
examples/calc++/calc++-parser.cc \
|
||||
examples/calc++/calc++-parser.hh \
|
||||
examples/calc++/location.hh \
|
||||
examples/calc++/position.hh \
|
||||
calc_sources_generated = \
|
||||
examples/calc++/calc++-parser.cc \
|
||||
examples/calc++/calc++-parser.hh \
|
||||
examples/calc++/location.hh \
|
||||
examples/calc++/position.hh \
|
||||
examples/calc++/stack.hh
|
||||
calc_sources = \
|
||||
$(calc_sources_extracted) \
|
||||
calc_sources = \
|
||||
$(calc_sources_extracted) \
|
||||
$(calc_sources_generated)
|
||||
|
||||
if BISON_CXX_WORKS
|
||||
check_PROGRAMS += examples/calc++/calc++
|
||||
nodist_examples_calc___calc___SOURCES = \
|
||||
nodist_examples_calc___calc___SOURCES = \
|
||||
$(calc_sources)
|
||||
|
||||
examples_calc___calc___CPPFLAGS = -I$(top_builddir)/examples/calc++
|
||||
examples_calc___calc___CXXFLAGS = $(AM_CXXFLAGS) $(FLEX_SCANNER_CXXFLAGS)
|
||||
examples_calc___calc___CXXFLAGS = \
|
||||
$(AM_CXXFLAGS) $(WARN_NO_NULL_CONVERSION_CXXFLAGS)
|
||||
dist_TESTS += examples/calc++/calc++.test
|
||||
else
|
||||
EXTRA_DIST += examples/calc++/calc++.test
|
||||
endif
|
||||
|
||||
@@ -17,6 +17,7 @@ dist_noinst_SCRIPTS = examples/extexi examples/test
|
||||
TEST_LOG_COMPILER = $(top_srcdir)/examples/test
|
||||
|
||||
AM_CXXFLAGS = \
|
||||
$(NO_STRICT_ALIAS_CXXFLAGS) \
|
||||
$(WARN_CXXFLAGS) $(WARN_CXXFLAGS_TEST) $(WERROR_CXXFLAGS)
|
||||
|
||||
## ------------ ##
|
||||
|
||||
+1
-1
Submodule gnulib updated: 03e96cc338...c67e3c0414
+1
-1
@@ -17,7 +17,7 @@
|
||||
|
||||
|
||||
/* Bison depends on libiberty's implementation of bitsets, which
|
||||
requires a 'libiberty.h' file. This file provides the minimum
|
||||
requires a `libiberty.h' file. This file provides the minimum
|
||||
services. */
|
||||
|
||||
#ifndef BISON_LIBIBERTY_H_
|
||||
|
||||
+1
-1
@@ -36,7 +36,7 @@
|
||||
Timing variables may be pushed onto the stack; elapsed time is
|
||||
attributed to the topmost timing variable on the stack. When
|
||||
another variable is pushed on, the previous topmost variable is
|
||||
'paused' until the pushed variable is popped back off.
|
||||
`paused' until the pushed variable is popped back off.
|
||||
|
||||
- As a standalone timer, using timevar_start and timevar_stop.
|
||||
All time elapsed between the two calls is attributed to the
|
||||
|
||||
@@ -242,7 +242,7 @@ AnnotationList__computePredecessorAnnotations (AnnotationList *self, state *s,
|
||||
{
|
||||
symbol_number contribution_token =
|
||||
InadequacyList__getContributionToken (self->inadequacyNode, ci)
|
||||
->content->number;
|
||||
->number;
|
||||
if (AnnotationList__isContributionAlways (self, ci))
|
||||
{
|
||||
annotation_node->contributions[ci] = NULL;
|
||||
@@ -549,7 +549,7 @@ AnnotationList__compute_from_inadequacies (
|
||||
does discard annotations in the simplest case of a S/R
|
||||
conflict with no token precedence. */
|
||||
aver (!bitset_test (shift_tokens, conflicted_token)
|
||||
|| symbols[conflicted_token]->content->prec);
|
||||
|| symbols[conflicted_token]->prec);
|
||||
++annotation_counts[s->number];
|
||||
if (contribution_count > *max_contributionsp)
|
||||
*max_contributionsp = contribution_count;
|
||||
@@ -595,7 +595,7 @@ AnnotationList__debug (AnnotationList const *self, size_t nitems, int spaces)
|
||||
{
|
||||
symbol_number token =
|
||||
InadequacyList__getContributionToken (a->inadequacyNode, ci)
|
||||
->content->number;
|
||||
->number;
|
||||
{
|
||||
int j;
|
||||
for (j = 0; j < spaces+2; ++j)
|
||||
@@ -644,7 +644,7 @@ AnnotationList__computeLookaheadFilter (AnnotationList const *self,
|
||||
Sbitset biter;
|
||||
symbol_number token =
|
||||
InadequacyList__getContributionToken (self->inadequacyNode, ci)
|
||||
->content->number;
|
||||
->number;
|
||||
SBITSET__FOR_EACH (self->contributions[ci], nitems, biter, item)
|
||||
bitset_set (lookahead_filter[item], token);
|
||||
}
|
||||
@@ -679,8 +679,7 @@ AnnotationList__stateMakesContribution (AnnotationList const *self,
|
||||
return false;
|
||||
{
|
||||
symbol_number token =
|
||||
InadequacyList__getContributionToken (self->inadequacyNode, ci)
|
||||
->content->number;
|
||||
InadequacyList__getContributionToken (self->inadequacyNode, ci)->number;
|
||||
Sbitset__Index item;
|
||||
Sbitset biter;
|
||||
SBITSET__FOR_EACH (self->contributions[ci], nitems, biter, item)
|
||||
@@ -710,7 +709,7 @@ AnnotationList__computeDominantContribution (AnnotationList const *self,
|
||||
ContributionIndex ci;
|
||||
int actioni;
|
||||
ContributionIndex ci_rr_dominator = ContributionIndex__none;
|
||||
int shift_precedence = token->content->prec;
|
||||
int shift_precedence = token->prec;
|
||||
|
||||
/* If the token has no precedence set, shift is always chosen. */
|
||||
if (!shift_precedence)
|
||||
@@ -740,7 +739,7 @@ AnnotationList__computeDominantContribution (AnnotationList const *self,
|
||||
if (reduce_precedence
|
||||
&& (reduce_precedence < shift_precedence
|
||||
|| (reduce_precedence == shift_precedence
|
||||
&& token->content->prec_node->assoc == right_assoc)))
|
||||
&& token->assoc == right_assoc)))
|
||||
continue;
|
||||
if (!AnnotationList__stateMakesContribution (self, nitems, ci,
|
||||
lookaheads))
|
||||
@@ -748,7 +747,7 @@ AnnotationList__computeDominantContribution (AnnotationList const *self,
|
||||
/* This uneliminated reduction contributes, so see if it can cause
|
||||
an error action. */
|
||||
if (reduce_precedence == shift_precedence
|
||||
&& token->content->prec_node->assoc == non_assoc)
|
||||
&& token->assoc == non_assoc)
|
||||
{
|
||||
/* It's not possible to find split-stable domination over
|
||||
shift after a potential %nonassoc. */
|
||||
|
||||
+1
-1
@@ -60,7 +60,7 @@ Sbitset__isEmpty (Sbitset self, Sbitset__Index nbits)
|
||||
}
|
||||
|
||||
void
|
||||
Sbitset__fprint (Sbitset self, Sbitset__Index nbits, FILE *file)
|
||||
Sbitset__fprint(Sbitset self, Sbitset__Index nbits, FILE *file)
|
||||
{
|
||||
Sbitset__Index i;
|
||||
Sbitset itr;
|
||||
|
||||
+6
-6
@@ -44,31 +44,31 @@ void Sbitset__delete (Sbitset self);
|
||||
|
||||
bool Sbitset__isEmpty (Sbitset self, Sbitset__Index nbits);
|
||||
|
||||
void Sbitset__fprint (Sbitset self, Sbitset__Index nbits, FILE *file);
|
||||
void Sbitset__fprint(Sbitset self, Sbitset__Index nbits, FILE *file);
|
||||
|
||||
# define Sbitset__set(SELF, INDEX) \
|
||||
do { \
|
||||
*Sbitset__byteAddress ((SELF), (INDEX)) = \
|
||||
*Sbitset__byteAddress ((SELF), (INDEX)) | Sbitset__bit_mask (INDEX); \
|
||||
} while (0)
|
||||
} while(0)
|
||||
|
||||
# define Sbitset__reset(SELF, INDEX) \
|
||||
do { \
|
||||
*Sbitset__byteAddress ((SELF), (INDEX)) = \
|
||||
*Sbitset__byteAddress ((SELF), (INDEX)) & ~Sbitset__bit_mask (INDEX); \
|
||||
} while (0)
|
||||
} while(0)
|
||||
|
||||
/* NBITS is the size of the bitset. More than NBITS bits might be reset. */
|
||||
# define Sbitset__zero(SELF, NBITS) \
|
||||
do { \
|
||||
memset (SELF, 0, Sbitset__nbytes (NBITS)); \
|
||||
} while (0)
|
||||
} while(0)
|
||||
|
||||
/* NBITS is the size of the bitset. More than NBITS bits might be set. */
|
||||
# define Sbitset__ones(SELF, NBITS) \
|
||||
do { \
|
||||
memset (SELF, UCHAR_MAX, Sbitset__nbytes (NBITS)); \
|
||||
} while (0)
|
||||
} while(0)
|
||||
|
||||
/* NBITS is the size of every bitset. More than NBITS bits might be set. */
|
||||
# define Sbitset__or(SELF, OTHER1, OTHER2, NBITS) \
|
||||
@@ -79,7 +79,7 @@ void Sbitset__fprint (Sbitset self, Sbitset__Index nbits, FILE *file);
|
||||
Sbitset end_self = ptr_self + Sbitset__nbytes (NBITS); \
|
||||
for (; ptr_self < end_self; ++ptr_self, ++ptr_other1, ++ptr_other2) \
|
||||
*ptr_self = *ptr_other1 | *ptr_other2; \
|
||||
} while (0)
|
||||
} while(0)
|
||||
|
||||
# define SBITSET__FOR_EACH(SELF, NBITS, ITER, INDEX) \
|
||||
for ((ITER) = (SELF); (ITER) < (SELF) + Sbitset__nbytes (NBITS); ++(ITER)) \
|
||||
|
||||
+41
-214
@@ -22,7 +22,6 @@
|
||||
#include <config.h>
|
||||
#include "system.h"
|
||||
|
||||
#include <argmatch.h>
|
||||
#include <stdarg.h>
|
||||
#include <progname.h>
|
||||
|
||||
@@ -31,199 +30,42 @@
|
||||
#include "getargs.h"
|
||||
#include "quote.h"
|
||||
|
||||
warnings warnings_flag =
|
||||
Wconflicts_sr | Wconflicts_rr | Wdeprecated | Wother;
|
||||
|
||||
warnings errors_flag;
|
||||
|
||||
err_status complaint_status = status_none;
|
||||
|
||||
bool warnings_are_errors = false;
|
||||
|
||||
/** Diagnostics severity. */
|
||||
typedef enum
|
||||
{
|
||||
severity_disabled = 0,
|
||||
severity_unset = 1,
|
||||
severity_warning = 2,
|
||||
severity_error = 3,
|
||||
severity_fatal = 4
|
||||
} severity;
|
||||
|
||||
|
||||
/** For each warning type, its severity. */
|
||||
static severity warnings_flag[warnings_size];
|
||||
|
||||
static unsigned *indent_ptr = 0;
|
||||
|
||||
/*------------------------.
|
||||
| --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
|
||||
warning_argmatch (char const *arg, size_t no, size_t err)
|
||||
warnings_print_categories (warnings warn_flags)
|
||||
{
|
||||
int value = XARGMATCH ("--warning", arg + no + err,
|
||||
warnings_args, warnings_types);
|
||||
|
||||
/* -Wnone == -Wno-everything, and -Wno-none == -Weverything. */
|
||||
if (!value)
|
||||
if (! (warn_flags & silent))
|
||||
{
|
||||
value = Weverything;
|
||||
no = !no;
|
||||
}
|
||||
char const *warn_names[] =
|
||||
{
|
||||
"midrule-values",
|
||||
"yacc",
|
||||
"conflicts-sr",
|
||||
"conflicts-rr",
|
||||
"deprecated",
|
||||
"other"
|
||||
};
|
||||
|
||||
if (no)
|
||||
{
|
||||
size_t b;
|
||||
for (b = 0; b < warnings_size; ++b)
|
||||
if (value & 1 << b)
|
||||
bool any = false;
|
||||
int i;
|
||||
for (i = 0; i < ARRAY_CARDINALITY (warn_names); ++i)
|
||||
if (warn_flags & 1 << i)
|
||||
{
|
||||
if (err)
|
||||
{
|
||||
/* -Wno-error=foo: if foo enabled as an error,
|
||||
make it a warning. */
|
||||
if (warnings_flag[b] == severity_error)
|
||||
warnings_flag[b] = severity_warning;
|
||||
}
|
||||
else
|
||||
/* -Wno-foo. */
|
||||
warnings_flag[b] = severity_disabled;
|
||||
bool err = warn_flags & errors_flag;
|
||||
fprintf (stderr, "%s-W", any ? ", " : " [");
|
||||
fprintf (stderr, "%s%s", err ? "error=" : "" , warn_names[i]);
|
||||
any = true;
|
||||
}
|
||||
if (any)
|
||||
fprintf (stderr, "]");
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t b;
|
||||
for (b = 0; b < warnings_size; ++b)
|
||||
if (value & 1 << b)
|
||||
/* -Wfoo and -Werror=foo. */
|
||||
warnings_flag[b] = err ? severity_error : severity_warning;
|
||||
}
|
||||
}
|
||||
|
||||
/** Decode a comma-separated list of arguments from -W.
|
||||
*
|
||||
* \param args comma separated list of effective subarguments to decode.
|
||||
* If 0, then activate all the flags.
|
||||
*/
|
||||
|
||||
void
|
||||
warnings_argmatch (char *args)
|
||||
{
|
||||
if (args)
|
||||
for (args = strtok (args, ","); args; args = strtok (NULL, ","))
|
||||
if (STREQ (args, "error"))
|
||||
warnings_are_errors = true;
|
||||
else if (STREQ (args, "no-error"))
|
||||
{
|
||||
warnings_are_errors = false;
|
||||
warning_argmatch ("no-error=everything", 3, 6);
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t no = STRPREFIX_LIT ("no-", args) ? 3 : 0;
|
||||
size_t err = STRPREFIX_LIT ("error=", args + no) ? 6 : 0;
|
||||
|
||||
warning_argmatch (args, no, err);
|
||||
}
|
||||
else
|
||||
warning_argmatch ("all", 0, 0);
|
||||
}
|
||||
|
||||
|
||||
/*-----------.
|
||||
| complain. |
|
||||
`-----------*/
|
||||
|
||||
void
|
||||
complain_init (void)
|
||||
{
|
||||
warnings warnings_default =
|
||||
Wconflicts_sr | Wconflicts_rr | Wdeprecated | Wother;
|
||||
|
||||
size_t b;
|
||||
for (b = 0; b < warnings_size; ++b)
|
||||
warnings_flag[b] = (1 << b & warnings_default
|
||||
? severity_warning
|
||||
: severity_unset);
|
||||
}
|
||||
|
||||
static severity
|
||||
warning_severity (warnings flags)
|
||||
{
|
||||
if (flags & fatal)
|
||||
return severity_fatal;
|
||||
else if (flags & complaint)
|
||||
return severity_error;
|
||||
else
|
||||
{
|
||||
severity res = severity_disabled;
|
||||
size_t b;
|
||||
for (b = 0; b < warnings_size; ++b)
|
||||
if (flags & 1 << b)
|
||||
res = res < warnings_flag[b] ? warnings_flag[b] : res;
|
||||
if (res == severity_warning && warnings_are_errors)
|
||||
res = severity_error;
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
warning_is_unset (warnings flags)
|
||||
{
|
||||
size_t b;
|
||||
for (b = 0; b < warnings_size; ++b)
|
||||
if (flags & 1 << b && warnings_flag[b] != severity_unset)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Display a "[-Wyacc]" like message on \a f. */
|
||||
|
||||
static void
|
||||
warnings_print_categories (warnings warn_flags, FILE *f)
|
||||
{
|
||||
/* Display only the first match, the second is "-Wall". */
|
||||
size_t i;
|
||||
for (i = 0; warnings_args[i]; ++i)
|
||||
if (warn_flags & warnings_types[i])
|
||||
{
|
||||
severity s = warning_severity (warnings_types[i]);
|
||||
fprintf (f, " [-W%s%s]",
|
||||
s == severity_error ? "error=" : "",
|
||||
warnings_args[i]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/** Report an error message.
|
||||
@@ -246,7 +88,7 @@ error_message (const location *loc, warnings flags, const char *prefix,
|
||||
unsigned pos = 0;
|
||||
|
||||
if (loc)
|
||||
pos += location_print (*loc, stderr);
|
||||
pos += location_print (stderr, *loc);
|
||||
else
|
||||
pos += fprintf (stderr, "%s", current_file ? current_file : program_name);
|
||||
pos += fprintf (stderr, ": ");
|
||||
@@ -266,8 +108,7 @@ error_message (const location *loc, warnings flags, const char *prefix,
|
||||
fprintf (stderr, "%s: ", prefix);
|
||||
|
||||
vfprintf (stderr, message, args);
|
||||
if (! (flags & silent))
|
||||
warnings_print_categories (flags, stderr);
|
||||
warnings_print_categories (flags);
|
||||
{
|
||||
size_t l = strlen (message);
|
||||
if (l < 2 || message[l - 2] != ':' || message[l - 1] != ' ')
|
||||
@@ -275,34 +116,29 @@ error_message (const location *loc, warnings flags, const char *prefix,
|
||||
putc ('\n', stderr);
|
||||
fflush (stderr);
|
||||
if (loc && feature_flag & feature_caret && !(flags & no_caret))
|
||||
location_caret (*loc, stderr);
|
||||
location_caret (stderr, *loc);
|
||||
}
|
||||
}
|
||||
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. */
|
||||
|
||||
static void
|
||||
static inline void
|
||||
complains (const location *loc, warnings flags, const char *message,
|
||||
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)
|
||||
complaint_status = status_complaint;
|
||||
|
||||
if (severity_warning <= s)
|
||||
{
|
||||
const char* prefix =
|
||||
s == severity_fatal ? _("fatal error")
|
||||
: s == severity_error ? _("error")
|
||||
: _("warning");
|
||||
if (severity_error <= s && ! complaint_status)
|
||||
complaint_status = status_warning_as_error;
|
||||
error_message (loc, flags, prefix, message, args);
|
||||
}
|
||||
|
||||
else if ((flags & (warnings_flag & errors_flag)) && ! complaint_status)
|
||||
complaint_status = status_warning_as_error;
|
||||
if (flags & (warnings_flag | fatal | complaint))
|
||||
error_message (loc, flags, prefix, message, args);
|
||||
if (flags & fatal)
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
@@ -353,6 +189,7 @@ complain_args (location const *loc, warnings w, unsigned *indent,
|
||||
complain (loc, fatal, "too many arguments for complains");
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
@@ -367,13 +204,3 @@ deprecated_directive (location const *loc, char const *old, char const *upd)
|
||||
_("deprecated directive: %s, use %s"),
|
||||
quote (old), quote_n (1, upd));
|
||||
}
|
||||
|
||||
void
|
||||
duplicate_directive (char const *directive,
|
||||
location first, location second)
|
||||
{
|
||||
unsigned i = 0;
|
||||
complain (&second, complaint, _("only one %s allowed per rule"), directive);
|
||||
i += SUB_INDENT;
|
||||
complain_indent (&first, complaint, &i, _("previous declaration"));
|
||||
}
|
||||
|
||||
+16
-68
@@ -28,67 +28,15 @@
|
||||
| --warnings. |
|
||||
`-------------*/
|
||||
|
||||
/** The bits assigned to each warning type. */
|
||||
typedef enum
|
||||
{
|
||||
warning_midrule_values, /**< Unset or unused midrule values. */
|
||||
warning_yacc, /**< POSIXME. */
|
||||
warning_conflicts_sr, /**< S/R conflicts. */
|
||||
warning_conflicts_rr, /**< R/R conflicts. */
|
||||
warning_empty_rule, /**< Implicitly empty rules. */
|
||||
warning_deprecated, /**< Obsolete constructs. */
|
||||
warning_precedence, /**< Useless precedence and associativity. */
|
||||
warning_other, /**< All other warnings. */
|
||||
|
||||
warnings_size /**< The number of warnings. Must be last. */
|
||||
} warning_bit;
|
||||
|
||||
/** Whether -Werror was set. */
|
||||
extern bool warnings_are_errors;
|
||||
|
||||
/** Decode a single argument from -W.
|
||||
*
|
||||
* \param arg the subarguments to decode.
|
||||
* If null, then activate all the flags.
|
||||
* \param no length of the potential "no-" prefix.
|
||||
* Can be 0 or 3. If 3, negate the action of the subargument.
|
||||
* \param err length of a potential "error=".
|
||||
* Can be 0 or 6. If 6, treat the subargument as a CATEGORY.
|
||||
*
|
||||
* If VALUE != 0 then KEY sets flags and no-KEY clears them.
|
||||
* If VALUE == 0 then KEY clears all flags from \c all and no-KEY sets all
|
||||
* flags from \c all. Thus no-none = all and no-all = none.
|
||||
*/
|
||||
void warning_argmatch (char const *arg, size_t no, size_t err);
|
||||
|
||||
/** Decode a comma-separated list of arguments from -W.
|
||||
*
|
||||
* \param args comma separated list of effective subarguments to decode.
|
||||
* If 0, then activate all the flags.
|
||||
*/
|
||||
void warnings_argmatch (char *args);
|
||||
|
||||
|
||||
/*-----------.
|
||||
| complain. |
|
||||
`-----------*/
|
||||
|
||||
/** Initialize this module. */
|
||||
void complain_init (void);
|
||||
|
||||
typedef enum
|
||||
{
|
||||
/**< Issue no warnings. */
|
||||
Wnone = 0,
|
||||
|
||||
Wmidrule_values = 1 << warning_midrule_values,
|
||||
Wyacc = 1 << warning_yacc,
|
||||
Wconflicts_sr = 1 << warning_conflicts_sr,
|
||||
Wconflicts_rr = 1 << warning_conflicts_rr,
|
||||
Wdeprecated = 1 << warning_deprecated,
|
||||
Wempty_rule = 1 << warning_empty_rule,
|
||||
Wprecedence = 1 << warning_precedence,
|
||||
Wother = 1 << warning_other,
|
||||
Wnone = 0, /**< Issue no warnings. */
|
||||
Wmidrule_values = 1 << 0, /**< Unset or unused midrule values. */
|
||||
Wyacc = 1 << 1, /**< POSIXME. */
|
||||
Wconflicts_sr = 1 << 2, /**< S/R conflicts. */
|
||||
Wconflicts_rr = 1 << 3, /**< R/R conflicts. */
|
||||
Wdeprecated = 1 << 4, /**< Obsolete constructs. */
|
||||
Wother = 1 << 5, /**< All other warnings. */
|
||||
|
||||
Werror = 1 << 10, /** This bit is no longer used. */
|
||||
|
||||
@@ -98,13 +46,17 @@ typedef enum
|
||||
no_caret = 1 << 14, /**< Do not display caret location. */
|
||||
|
||||
/**< All above warnings. */
|
||||
Weverything = ~complaint & ~fatal & ~silent,
|
||||
Wall = Weverything & ~Wyacc
|
||||
Wall = ~complaint & ~fatal & ~silent
|
||||
} warnings;
|
||||
|
||||
/** Whether the warnings of \a flags are all unset.
|
||||
(Never enabled, never disabled). */
|
||||
bool warning_is_unset (warnings flags);
|
||||
/** What warnings are issued. */
|
||||
extern warnings warnings_flag;
|
||||
|
||||
/** What warnings are made errors. */
|
||||
extern warnings errors_flag;
|
||||
|
||||
/** Display a "[-Wyacc]" like message on stderr. */
|
||||
void warnings_print_categories (warnings warn_flags);
|
||||
|
||||
/** Make a complaint, with maybe a location. */
|
||||
void complain (location const *loc, warnings flags, char const *message, ...)
|
||||
@@ -124,10 +76,6 @@ void complain_indent (location const *loc, warnings flags, unsigned *indent,
|
||||
void deprecated_directive (location const *loc,
|
||||
char const *obsolete, char const *updated);
|
||||
|
||||
/** Report a repeated directive for a rule. */
|
||||
void duplicate_directive (char const *directive,
|
||||
location first, location second);
|
||||
|
||||
/** Warnings treated as errors shouldn't stop the execution as regular errors
|
||||
should (because due to their nature, it is safe to go on). Thus, there are
|
||||
three possible execution statuses. */
|
||||
|
||||
+61
-82
@@ -53,8 +53,7 @@ enum conflict_resolution
|
||||
reduce_resolution,
|
||||
left_resolution,
|
||||
right_resolution,
|
||||
nonassoc_resolution,
|
||||
uncomparable_resolution
|
||||
nonassoc_resolution
|
||||
};
|
||||
|
||||
|
||||
@@ -91,7 +90,6 @@ log_resolution (rule *r, symbol_number token,
|
||||
break;
|
||||
|
||||
case nonassoc_resolution:
|
||||
case uncomparable_resolution:
|
||||
obstack_printf (&solved_conflicts_obstack,
|
||||
_(" Conflict between rule %d and token %s"
|
||||
" resolved as an error"),
|
||||
@@ -106,7 +104,7 @@ log_resolution (rule *r, symbol_number token,
|
||||
case shift_resolution:
|
||||
obstack_printf (&solved_conflicts_obstack,
|
||||
" (%s < %s)",
|
||||
r->prec->symbol->tag,
|
||||
r->prec->tag,
|
||||
symbols[token]->tag);
|
||||
break;
|
||||
|
||||
@@ -114,7 +112,7 @@ log_resolution (rule *r, symbol_number token,
|
||||
obstack_printf (&solved_conflicts_obstack,
|
||||
" (%s < %s)",
|
||||
symbols[token]->tag,
|
||||
r->prec->symbol->tag);
|
||||
r->prec->tag);
|
||||
break;
|
||||
|
||||
case left_resolution:
|
||||
@@ -134,12 +132,6 @@ log_resolution (rule *r, symbol_number token,
|
||||
" (%%nonassoc %s)",
|
||||
symbols[token]->tag);
|
||||
break;
|
||||
case uncomparable_resolution:
|
||||
obstack_printf (&solved_conflicts_obstack,
|
||||
" (%s uncomparable with %s)",
|
||||
r->prec->symbol->tag,
|
||||
symbols[token]->tag);
|
||||
break;
|
||||
}
|
||||
|
||||
obstack_sgrow (&solved_conflicts_obstack, ".\n");
|
||||
@@ -169,7 +161,6 @@ log_resolution (rule *r, symbol_number token,
|
||||
xml_escape (symbols[token]->tag));
|
||||
break;
|
||||
|
||||
case uncomparable_resolution:
|
||||
case nonassoc_resolution:
|
||||
obstack_printf (&solved_conflicts_xml_obstack,
|
||||
" <resolution rule=\"%d\" symbol=\"%s\""
|
||||
@@ -185,7 +176,7 @@ log_resolution (rule *r, symbol_number token,
|
||||
case shift_resolution:
|
||||
obstack_printf (&solved_conflicts_xml_obstack,
|
||||
"%s < %s",
|
||||
xml_escape_n (0, r->prec->symbol->tag),
|
||||
xml_escape_n (0, r->prec->tag),
|
||||
xml_escape_n (1, symbols[token]->tag));
|
||||
break;
|
||||
|
||||
@@ -193,7 +184,7 @@ log_resolution (rule *r, symbol_number token,
|
||||
obstack_printf (&solved_conflicts_xml_obstack,
|
||||
"%s < %s",
|
||||
xml_escape_n (0, symbols[token]->tag),
|
||||
xml_escape_n (1, r->prec->symbol->tag));
|
||||
xml_escape_n (1, r->prec->tag));
|
||||
break;
|
||||
|
||||
case left_resolution:
|
||||
@@ -212,13 +203,7 @@ log_resolution (rule *r, symbol_number token,
|
||||
obstack_printf (&solved_conflicts_xml_obstack,
|
||||
"%%nonassoc %s",
|
||||
xml_escape (symbols[token]->tag));
|
||||
break;
|
||||
case uncomparable_resolution:
|
||||
obstack_printf (&solved_conflicts_xml_obstack,
|
||||
"%s uncomparable with %s",
|
||||
xml_escape_n (0, symbols[token]->tag),
|
||||
xml_escape_n (1, r->prec->symbol->tag));
|
||||
break;
|
||||
break;
|
||||
}
|
||||
|
||||
obstack_sgrow (&solved_conflicts_xml_obstack, "</resolution>\n");
|
||||
@@ -258,6 +243,7 @@ flush_reduce (bitset lookahead_tokens, int token)
|
||||
bitset_reset (lookahead_tokens, token);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------.
|
||||
| Attempt to resolve shift-reduce conflict for one rule by means of |
|
||||
| precedence declarations. It has already been checked that the |
|
||||
@@ -277,73 +263,66 @@ resolve_sr_conflict (state *s, int ruleno, symbol **errors, int *nerrs)
|
||||
reductions *reds = s->reductions;
|
||||
/* Find the rule to reduce by to get precedence of reduction. */
|
||||
rule *redrule = reds->rules[ruleno];
|
||||
prec_node *redprecsym = redrule->prec->prec_node;
|
||||
int redprec = redrule->prec->prec;
|
||||
bitset lookahead_tokens = reds->lookahead_tokens[ruleno];
|
||||
|
||||
for (i = 0; i < ntokens; i++)
|
||||
if (bitset_test (lookahead_tokens, i)
|
||||
&& bitset_test (lookahead_set, i))
|
||||
&& bitset_test (lookahead_set, i)
|
||||
&& symbols[i]->prec)
|
||||
{
|
||||
if (redprecsym && symbols[i]->content->prec_node)
|
||||
/* Shift-reduce conflict occurs for token number i
|
||||
and it has a precedence.
|
||||
The precedence of shifting is that of token i. */
|
||||
if (symbols[i]->prec < redprec)
|
||||
{
|
||||
/* Shift-reduce conflict occurs for token number i
|
||||
and it has a precedence.
|
||||
The precedence of shifting is that of token i. */
|
||||
if (is_prec_superior (redprecsym, symbols[i]->content->prec_node))
|
||||
{
|
||||
register_precedence (redrule->prec->number, i);
|
||||
log_resolution (redrule, i, reduce_resolution);
|
||||
flush_shift (s, i);
|
||||
}
|
||||
else if (is_prec_superior (symbols[i]->content->prec_node,
|
||||
redprecsym))
|
||||
{
|
||||
register_precedence (i, redrule->prec->number);
|
||||
log_resolution (redrule, i, shift_resolution);
|
||||
flush_reduce (lookahead_tokens, i);
|
||||
}
|
||||
else if (is_prec_equal (redprecsym, symbols[i]->content->prec_node))
|
||||
/* Matching precedence levels.
|
||||
For non-defined associativity, keep both: unexpected
|
||||
associativity conflict.
|
||||
For left associativity, keep only the reduction.
|
||||
For right associativity, keep only the shift.
|
||||
For nonassociativity, keep neither. */
|
||||
|
||||
switch (symbols[i]->content->prec_node->assoc)
|
||||
{
|
||||
case undef_assoc:
|
||||
break;
|
||||
|
||||
case precedence_assoc:
|
||||
break;
|
||||
|
||||
case right_assoc:
|
||||
register_assoc (i, redrule->prec->number);
|
||||
log_resolution (redrule, i, right_resolution);
|
||||
flush_reduce (lookahead_tokens, i);
|
||||
break;
|
||||
|
||||
case left_assoc:
|
||||
register_assoc (i, redrule->prec->number);
|
||||
log_resolution (redrule, i, left_resolution);
|
||||
flush_shift (s, i);
|
||||
break;
|
||||
|
||||
case non_assoc:
|
||||
register_assoc (i, redrule->prec->number);
|
||||
log_resolution (redrule, i, nonassoc_resolution);
|
||||
flush_shift (s, i);
|
||||
flush_reduce (lookahead_tokens, i);
|
||||
/* Record an explicit error for this token. */
|
||||
errors[(*nerrs)++] = symbols[i];
|
||||
break;
|
||||
}
|
||||
else
|
||||
log_resolution (redrule, i, uncomparable_resolution);
|
||||
register_precedence (redrule->prec->number, i);
|
||||
log_resolution (redrule, i, reduce_resolution);
|
||||
flush_shift (s, i);
|
||||
}
|
||||
else if (symbols[i]->prec > redprec)
|
||||
{
|
||||
register_precedence (i, redrule->prec->number);
|
||||
log_resolution (redrule, i, shift_resolution);
|
||||
flush_reduce (lookahead_tokens, i);
|
||||
}
|
||||
else
|
||||
log_resolution (redrule, i, uncomparable_resolution);
|
||||
/* Matching precedence levels.
|
||||
For non-defined associativity, keep both: unexpected
|
||||
associativity conflict.
|
||||
For left associativity, keep only the reduction.
|
||||
For right associativity, keep only the shift.
|
||||
For nonassociativity, keep neither. */
|
||||
|
||||
switch (symbols[i]->assoc)
|
||||
{
|
||||
case undef_assoc:
|
||||
abort ();
|
||||
|
||||
case precedence_assoc:
|
||||
break;
|
||||
|
||||
case right_assoc:
|
||||
register_assoc (i, redrule->prec->number);
|
||||
log_resolution (redrule, i, right_resolution);
|
||||
flush_reduce (lookahead_tokens, i);
|
||||
break;
|
||||
|
||||
case left_assoc:
|
||||
register_assoc (i, redrule->prec->number);
|
||||
log_resolution (redrule, i, left_resolution);
|
||||
flush_shift (s, i);
|
||||
break;
|
||||
|
||||
case non_assoc:
|
||||
register_assoc (i, redrule->prec->number);
|
||||
log_resolution (redrule, i, nonassoc_resolution);
|
||||
flush_shift (s, i);
|
||||
flush_reduce (lookahead_tokens, i);
|
||||
/* Record an explicit error for this token. */
|
||||
errors[(*nerrs)++] = symbols[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -375,7 +354,7 @@ set_conflicts (state *s, symbol **errors)
|
||||
check for shift-reduce conflict, and try to resolve using
|
||||
precedence. */
|
||||
for (i = 0; i < reds->num; ++i)
|
||||
if (reds->rules[i]->prec /* && reds->rules[i]->prec->prec */
|
||||
if (reds->rules[i]->prec && reds->rules[i]->prec->prec
|
||||
&& !bitset_disjoint_p (reds->lookahead_tokens[i], lookahead_set))
|
||||
resolve_sr_conflict (s, i, errors, &nerrs);
|
||||
|
||||
@@ -424,7 +403,7 @@ conflicts_solve (void)
|
||||
set_conflicts (states[i], errors);
|
||||
|
||||
/* For uniformity of the code, make sure all the states have a valid
|
||||
'errs' member. */
|
||||
`errs' member. */
|
||||
if (!states[i]->errs)
|
||||
states[i]->errs = errs_new (0, 0);
|
||||
}
|
||||
|
||||
+13
-13
@@ -34,7 +34,7 @@
|
||||
#include "getargs.h"
|
||||
#include "gram.h"
|
||||
|
||||
/* Initializing some values below (such SPEC_NAME_PREFIX to 'yy') is
|
||||
/* Initializing some values below (such SPEC_NAME_PREFIX to `yy') is
|
||||
tempting, but don't do that: for the time being our handling of the
|
||||
%directive vs --option leaves precedence to the options by deciding
|
||||
that if a %directive sets a variable which is really set (i.e., not
|
||||
@@ -58,20 +58,20 @@ uniqstr grammar_file = NULL;
|
||||
uniqstr current_file = NULL;
|
||||
|
||||
/* If --output=dir/foo.c was specified,
|
||||
DIR_PREFIX is 'dir/' and ALL_BUT_EXT and ALL_BUT_TAB_EXT are 'dir/foo'.
|
||||
DIR_PREFIX is `dir/' and ALL_BUT_EXT and ALL_BUT_TAB_EXT are `dir/foo'.
|
||||
|
||||
If --output=dir/foo.tab.c was specified, DIR_PREFIX is 'dir/',
|
||||
ALL_BUT_EXT is 'dir/foo.tab', and ALL_BUT_TAB_EXT is 'dir/foo'.
|
||||
If --output=dir/foo.tab.c was specified, DIR_PREFIX is `dir/',
|
||||
ALL_BUT_EXT is `dir/foo.tab', and ALL_BUT_TAB_EXT is `dir/foo'.
|
||||
|
||||
If --output was not specified but --file-prefix=dir/foo was specified,
|
||||
ALL_BUT_EXT = 'foo.tab' and ALL_BUT_TAB_EXT = 'foo'.
|
||||
ALL_BUT_EXT = `foo.tab' and ALL_BUT_TAB_EXT = `foo'.
|
||||
|
||||
If neither --output nor --file was specified but the input grammar
|
||||
is name dir/foo.y, ALL_BUT_EXT and ALL_BUT_TAB_EXT are 'foo'.
|
||||
is name dir/foo.y, ALL_BUT_EXT and ALL_BUT_TAB_EXT are `foo'.
|
||||
|
||||
If neither --output nor --file was specified, DIR_PREFIX is the
|
||||
empty string (meaning the current directory); otherwise it is
|
||||
'dir/'. */
|
||||
`dir/'. */
|
||||
|
||||
char *all_but_ext;
|
||||
static char *all_but_tab_ext;
|
||||
@@ -79,7 +79,7 @@ char *dir_prefix;
|
||||
|
||||
/* C source file extension (the parser source). */
|
||||
static char *src_extension = NULL;
|
||||
/* Header file extension (if option '`-d'' is specified). */
|
||||
/* Header file extension (if option ``-d'' is specified). */
|
||||
static char *header_extension = NULL;
|
||||
|
||||
/*-----------------------------------------------------------------.
|
||||
@@ -191,7 +191,7 @@ compute_exts_from_src (const char *ext)
|
||||
*EXT points to the last period in the basename, or NULL if none.
|
||||
|
||||
If there is no *EXT, *TAB is NULL. Otherwise, *TAB points to
|
||||
'.tab' or '_tab' if present right before *EXT, or is NULL. *TAB
|
||||
`.tab' or `_tab' if present right before *EXT, or is NULL. *TAB
|
||||
cannot be equal to *BASE.
|
||||
|
||||
None are allocated, they are simply pointers to parts of FILE_NAME.
|
||||
@@ -222,7 +222,7 @@ file_name_split (const char *file_name,
|
||||
*ext = strrchr (*base, '.');
|
||||
*tab = NULL;
|
||||
|
||||
/* If there is an extension, check if there is a '.tab' part right
|
||||
/* If there is an extension, check if there is a `.tab' part right
|
||||
before. */
|
||||
if (*ext)
|
||||
{
|
||||
@@ -270,7 +270,7 @@ compute_file_name_parts (void)
|
||||
|
||||
if (spec_file_prefix)
|
||||
{
|
||||
/* If --file-prefix=foo was specified, ALL_BUT_TAB_EXT = 'foo'. */
|
||||
/* If --file-prefix=foo was specified, ALL_BUT_TAB_EXT = `foo'. */
|
||||
dir_prefix =
|
||||
xstrndup (spec_file_prefix,
|
||||
last_component (spec_file_prefix) - spec_file_prefix);
|
||||
@@ -278,14 +278,14 @@ compute_file_name_parts (void)
|
||||
}
|
||||
else if (yacc_flag)
|
||||
{
|
||||
/* If --yacc, then the output is 'y.tab.c'. */
|
||||
/* If --yacc, then the output is `y.tab.c'. */
|
||||
dir_prefix = xstrdup ("");
|
||||
all_but_tab_ext = xstrdup ("y");
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Otherwise, ALL_BUT_TAB_EXT is computed from the input
|
||||
grammar: 'foo/bar.yy' => 'bar'. */
|
||||
grammar: `foo/bar.yy' => `bar'. */
|
||||
dir_prefix = xstrdup ("");
|
||||
all_but_tab_ext =
|
||||
xstrndup (base, (strlen (base) - (ext ? strlen (ext) : 0)));
|
||||
|
||||
+109
-64
@@ -61,6 +61,7 @@ int skeleton_prio = default_prio;
|
||||
const char *skeleton = NULL;
|
||||
int language_prio = default_prio;
|
||||
struct bison_language const *language = &valid_languages[0];
|
||||
const char *include = NULL;
|
||||
|
||||
/** Decode an option's key.
|
||||
*
|
||||
@@ -73,6 +74,8 @@ struct bison_language const *language = &valid_languages[0];
|
||||
* 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
|
||||
@@ -81,23 +84,36 @@ struct bison_language const *language = &valid_languages[0];
|
||||
static void
|
||||
flag_argmatch (const char *option,
|
||||
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;
|
||||
no = !no;
|
||||
if (no)
|
||||
*flags &= ~value;
|
||||
else
|
||||
{
|
||||
if (err)
|
||||
warnings_flag |= value;
|
||||
*flags |= value;
|
||||
}
|
||||
}
|
||||
|
||||
if (no)
|
||||
*flags &= ~value;
|
||||
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.
|
||||
*
|
||||
* \param option option being decoded.
|
||||
@@ -117,14 +133,16 @@ flags_argmatch (const char *option,
|
||||
for (args = strtok (args, ","); args; args = strtok (NULL, ","))
|
||||
{
|
||||
size_t no = STRPREFIX_LIT ("no-", args) ? 3 : 0;
|
||||
size_t err = STRPREFIX_LIT ("error", args + no) ? 5 : 0;
|
||||
|
||||
flag_argmatch (option, keys,
|
||||
values, all, flags, args, no);
|
||||
values, all, err ? &errors_flag : flags,
|
||||
args, no, err);
|
||||
}
|
||||
else
|
||||
*flags |= all;
|
||||
}
|
||||
|
||||
|
||||
/** Decode a set of sub arguments.
|
||||
*
|
||||
* \param FlagName the flag familly to update.
|
||||
@@ -178,6 +196,8 @@ ARGMATCH_VERIFY (report_args, report_types);
|
||||
|
||||
static const char * const trace_args[] =
|
||||
{
|
||||
/* In a series of synonyms, present the most meaningful first, so
|
||||
that argmatch_valid be more readable. */
|
||||
"none - no traces",
|
||||
"scan - grammar scanner traces",
|
||||
"parse - grammar parser traces",
|
||||
@@ -218,6 +238,41 @@ static const int trace_types[] =
|
||||
ARGMATCH_VERIFY (trace_args, trace_types);
|
||||
|
||||
|
||||
/*------------------------.
|
||||
| --warnings's handling. |
|
||||
`------------------------*/
|
||||
|
||||
static const char * const warnings_args[] =
|
||||
{
|
||||
/* In a series of synonyms, present the most meaningful first, so
|
||||
that argmatch_valid be more readable. */
|
||||
"none - no warnings",
|
||||
"midrule-values - unset or unused midrule values",
|
||||
"yacc - incompatibilities with POSIX Yacc",
|
||||
"conflicts-sr - S/R conflicts",
|
||||
"conflicts-rr - R/R conflicts",
|
||||
"deprecated - obsolete constructs",
|
||||
"other - all other warnings",
|
||||
"all - all of the above",
|
||||
"error - warnings are errors",
|
||||
0
|
||||
};
|
||||
|
||||
static const int warnings_types[] =
|
||||
{
|
||||
Wnone,
|
||||
Wmidrule_values,
|
||||
Wyacc,
|
||||
Wconflicts_sr,
|
||||
Wconflicts_rr,
|
||||
Wdeprecated,
|
||||
Wother,
|
||||
Wall,
|
||||
Werror
|
||||
};
|
||||
|
||||
ARGMATCH_VERIFY (warnings_args, warnings_types);
|
||||
|
||||
/*-----------------------.
|
||||
| --feature's handling. |
|
||||
`-----------------------*/
|
||||
@@ -249,7 +304,7 @@ static void
|
||||
usage (int status)
|
||||
{
|
||||
if (status != 0)
|
||||
fprintf (stderr, _("Try '%s --help' for more information.\n"),
|
||||
fprintf (stderr, _("Try `%s --help' for more information.\n"),
|
||||
program_name);
|
||||
else
|
||||
{
|
||||
@@ -291,7 +346,7 @@ Parser:\n\
|
||||
-L, --language=LANGUAGE specify the output programming language\n\
|
||||
-S, --skeleton=FILE specify the skeleton to use\n\
|
||||
-t, --debug instrument the parser for tracing\n\
|
||||
same as '-Dparse.trace'\n\
|
||||
same as `-Dparse.trace'\n\
|
||||
--locations enable location support\n\
|
||||
-D, --define=NAME[=VALUE] similar to '%define NAME \"VALUE\"'\n\
|
||||
-F, --force-define=NAME[=VALUE] override '%define NAME \"VALUE\"'\n\
|
||||
@@ -310,7 +365,7 @@ Output:\n\
|
||||
-d likewise but cannot specify FILE (for POSIX Yacc)\n\
|
||||
-r, --report=THINGS also produce details on the automaton\n\
|
||||
--report-file=FILE write report to FILE\n\
|
||||
-v, --verbose same as '--report=state'\n\
|
||||
-v, --verbose same as `--report=state'\n\
|
||||
-b, --file-prefix=PREFIX specify a PREFIX for output files\n\
|
||||
-o, --output=FILE leave output to FILE\n\
|
||||
-g, --graph[=FILE] also output a graph of the automaton\n\
|
||||
@@ -321,37 +376,35 @@ Output:\n\
|
||||
|
||||
fputs (_("\
|
||||
Warning categories include:\n\
|
||||
'midrule-values' unset or unused midrule values\n\
|
||||
'yacc' incompatibilities with POSIX Yacc\n\
|
||||
'conflicts-sr' S/R conflicts (enabled by default)\n\
|
||||
'conflicts-rr' R/R conflicts (enabled by default)\n\
|
||||
'deprecated' obsolete constructs\n\
|
||||
'empty-rule' empty rules without %empty\n\
|
||||
'precedence' useless precedence and associativity\n\
|
||||
'other' all other warnings (enabled by default)\n\
|
||||
'all' all the warnings except 'yacc'\n\
|
||||
'no-CATEGORY' turn off warnings in CATEGORY\n\
|
||||
'none' turn off all the warnings\n\
|
||||
'error[=CATEGORY]' treat warnings as errors\n\
|
||||
`midrule-values' unset or unused midrule values\n\
|
||||
`yacc' incompatibilities with POSIX Yacc\n\
|
||||
`conflicts-sr' S/R conflicts (enabled by default)\n\
|
||||
`conflicts-rr' R/R conflicts (enabled by default)\n\
|
||||
`deprecated' obsolete constructs\n\
|
||||
`other' all other warnings (enabled by default)\n\
|
||||
`all' all the warnings\n\
|
||||
`no-CATEGORY' turn off warnings in CATEGORY\n\
|
||||
`none' turn off all the warnings\n\
|
||||
`error[=CATEGORY]' treat warnings as errors\n\
|
||||
"), stdout);
|
||||
putc ('\n', stdout);
|
||||
|
||||
fputs (_("\
|
||||
THINGS is a list of comma separated words that can include:\n\
|
||||
'state' describe the states\n\
|
||||
'itemset' complete the core item sets with their closure\n\
|
||||
'lookahead' explicitly associate lookahead tokens to items\n\
|
||||
'solved' describe shift/reduce conflicts solving\n\
|
||||
'all' include all the above information\n\
|
||||
'none' disable the report\n\
|
||||
`state' describe the states\n\
|
||||
`itemset' complete the core item sets with their closure\n\
|
||||
`lookahead' explicitly associate lookahead tokens to items\n\
|
||||
`solved' describe shift/reduce conflicts solving\n\
|
||||
`all' include all the above information\n\
|
||||
`none' disable the report\n\
|
||||
"), stdout);
|
||||
putc ('\n', stdout);
|
||||
|
||||
fputs (_("\
|
||||
FEATURE is a list of comma separated words that can include:\n\
|
||||
'caret' show errors with carets\n\
|
||||
'all' all of the above\n\
|
||||
'none' disable all of the above\n\
|
||||
`caret' show errors with carets\n\
|
||||
`all' all of the above\n\
|
||||
`none' disable all of the above\n\
|
||||
"), stdout);
|
||||
|
||||
putc ('\n', stdout);
|
||||
@@ -464,10 +517,12 @@ static char const short_options[] =
|
||||
"b:"
|
||||
"d"
|
||||
"f::"
|
||||
"e"
|
||||
"g::"
|
||||
"h"
|
||||
"k"
|
||||
"l"
|
||||
"n"
|
||||
"o:"
|
||||
"p:"
|
||||
"r:"
|
||||
@@ -497,6 +552,7 @@ static struct option const long_options[] =
|
||||
|
||||
/* Parser. */
|
||||
{ "name-prefix", required_argument, 0, 'p' },
|
||||
{ "include", required_argument, 0, 'I' },
|
||||
|
||||
/* Output. */
|
||||
{ "file-prefix", required_argument, 0, 'b' },
|
||||
@@ -525,6 +581,7 @@ static struct option const long_options[] =
|
||||
{ "force-define", required_argument, 0, 'F' },
|
||||
{ "locations", no_argument, 0, LOCATIONS_OPTION },
|
||||
{ "no-lines", no_argument, 0, 'l' },
|
||||
{ "raw", no_argument, 0, 0 },
|
||||
{ "skeleton", required_argument, 0, 'S' },
|
||||
{ "language", required_argument, 0, 'L' },
|
||||
{ "token-table", no_argument, 0, 'k' },
|
||||
@@ -533,7 +590,7 @@ static struct option const long_options[] =
|
||||
};
|
||||
|
||||
/* Under DOS, there is no difference on the case. This can be
|
||||
troublesome when looking for '.tab' etc. */
|
||||
troublesome when looking for `.tab' etc. */
|
||||
#ifdef MSDOS
|
||||
# define AS_FILE_NAME(File) (strlwr (File), (File))
|
||||
#else
|
||||
@@ -569,36 +626,24 @@ getargs (int argc, char *argv[])
|
||||
/* Certain long options cause getopt_long to return 0. */
|
||||
break;
|
||||
|
||||
case 'D': /* -DNAME[=(VALUE|"VALUE"|{VALUE})]. */
|
||||
case 'F': /* -FNAME[=(VALUE|"VALUE"|{VALUE})]. */
|
||||
case 'D': /* -DNAME[=VALUE]. */
|
||||
case 'F': /* -FNAME[=VALUE]. */
|
||||
{
|
||||
char *name = optarg;
|
||||
char *value = strchr (optarg, '=');
|
||||
muscle_kind kind = muscle_keyword;
|
||||
char* name = optarg;
|
||||
char* value = strchr (optarg, '=');
|
||||
if (value)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
*value++ = 0;
|
||||
muscle_percent_define_insert (name, command_line_location (),
|
||||
kind, value ? value : "",
|
||||
value ? value : "",
|
||||
c == 'D' ? MUSCLE_PERCENT_DEFINE_D
|
||||
: MUSCLE_PERCENT_DEFINE_F);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'I':
|
||||
include = AS_FILE_NAME (optarg);
|
||||
break;
|
||||
|
||||
case 'L':
|
||||
language_argmatch (optarg, command_line_prio,
|
||||
command_line_location ());
|
||||
@@ -622,7 +667,7 @@ getargs (int argc, char *argv[])
|
||||
break;
|
||||
|
||||
case 'W':
|
||||
warnings_argmatch (optarg);
|
||||
FLAGS_ARGMATCH (warnings, optarg, Wall);
|
||||
break;
|
||||
|
||||
case 'b':
|
||||
@@ -673,8 +718,7 @@ getargs (int argc, char *argv[])
|
||||
|
||||
case 't':
|
||||
muscle_percent_define_insert ("parse.trace",
|
||||
command_line_location (),
|
||||
muscle_keyword, "",
|
||||
command_line_location (), "",
|
||||
MUSCLE_PERCENT_DEFINE_D);
|
||||
break;
|
||||
|
||||
@@ -692,7 +736,8 @@ getargs (int argc, char *argv[])
|
||||
break;
|
||||
|
||||
case 'y':
|
||||
warning_argmatch ("error=yacc", 0, 6);
|
||||
warnings_flag |= Wyacc;
|
||||
errors_flag |= Wyacc;
|
||||
yacc_flag = true;
|
||||
break;
|
||||
|
||||
|
||||
@@ -121,7 +121,6 @@ enum feature
|
||||
/** What additional features to use. */
|
||||
extern int feature_flag;
|
||||
|
||||
|
||||
/** Process the command line arguments.
|
||||
*
|
||||
* \param argc size of \a argv
|
||||
|
||||
+39
-18
@@ -44,8 +44,6 @@ int nvars = 0;
|
||||
|
||||
symbol_number *token_translations = NULL;
|
||||
|
||||
enum braces_state prec_braces = 0;
|
||||
|
||||
int max_user_token_number = 256;
|
||||
|
||||
bool
|
||||
@@ -67,19 +65,19 @@ rule_useless_in_parser_p (rule const *r)
|
||||
}
|
||||
|
||||
void
|
||||
rule_lhs_print (rule const *r, sym_content const *previous_lhs, FILE *out)
|
||||
rule_lhs_print (rule const *r, symbol const *previous_lhs, FILE *out)
|
||||
{
|
||||
fprintf (out, " %3d ", r->number);
|
||||
if (previous_lhs != r->lhs)
|
||||
fprintf (out, "%s:", r->lhs->symbol->tag);
|
||||
fprintf (out, "%s:", r->lhs->tag);
|
||||
else
|
||||
fprintf (out, "%*s|", (int) strlen (previous_lhs->symbol->tag), "");
|
||||
fprintf (out, "%*s|", (int) strlen (previous_lhs->tag), "");
|
||||
}
|
||||
|
||||
void
|
||||
rule_lhs_print_xml (rule const *r, FILE *out, int level)
|
||||
{
|
||||
xml_printf (out, level, "<lhs>%s</lhs>", r->lhs->symbol->tag);
|
||||
xml_printf (out, level, "<lhs>%s</lhs>", r->lhs->tag);
|
||||
}
|
||||
|
||||
size_t
|
||||
@@ -95,14 +93,16 @@ rule_rhs_length (rule const *r)
|
||||
void
|
||||
rule_rhs_print (rule const *r, FILE *out)
|
||||
{
|
||||
if (0 <= *r->rhs)
|
||||
if (*r->rhs >= 0)
|
||||
{
|
||||
item_number *rp;
|
||||
for (rp = r->rhs; *rp >= 0; rp++)
|
||||
fprintf (out, " %s", symbols[*rp]->tag);
|
||||
}
|
||||
else
|
||||
fputs (" %empty", out);
|
||||
{
|
||||
fprintf (out, " /* %s */", _("empty"));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -125,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
|
||||
ritem_print (FILE *out)
|
||||
{
|
||||
@@ -160,7 +167,7 @@ grammar_rules_partial_print (FILE *out, const char *title,
|
||||
{
|
||||
rule_number r;
|
||||
bool first = true;
|
||||
sym_content *previous_lhs = NULL;
|
||||
symbol *previous_lhs = NULL;
|
||||
|
||||
/* rule # : LHS -> RHS */
|
||||
for (r = 0; r < nrules + nuseless_productions; r++)
|
||||
@@ -211,7 +218,7 @@ grammar_rules_print_xml (FILE *out, int level)
|
||||
rules[r].number, usefulness);
|
||||
if (rules[r].precsym)
|
||||
fprintf (out, " percent_prec=\"%s\"",
|
||||
xml_escape (rules[r].precsym->symbol->tag));
|
||||
xml_escape (rules[r].precsym->tag));
|
||||
fputs (">\n", out);
|
||||
}
|
||||
rule_lhs_print_xml (&rules[r], out, level + 3);
|
||||
@@ -241,7 +248,7 @@ grammar_dump (FILE *out, const char *title)
|
||||
for (i = ntokens; i < nsyms; i++)
|
||||
fprintf (out, "%5d %5d %5d %s\n",
|
||||
i,
|
||||
symbols[i]->content->prec, symbols[i]->content->prec_node->assoc,
|
||||
symbols[i]->prec, symbols[i]->assoc,
|
||||
symbols[i]->tag);
|
||||
fprintf (out, "\n\n");
|
||||
}
|
||||
@@ -264,7 +271,7 @@ grammar_dump (FILE *out, const char *title)
|
||||
fprintf (out, "%3d (%2d, %2d, %2d, %2u-%2u) %2d ->",
|
||||
i,
|
||||
rule_i->prec ? rule_i->prec->prec : 0,
|
||||
rule_i->prec ? rule_i->prec->prec_node->assoc : 0,
|
||||
rule_i->prec ? rule_i->prec->assoc : 0,
|
||||
rule_i->useful,
|
||||
rhs_itemno,
|
||||
rhs_itemno + rhs_count - 1,
|
||||
@@ -282,8 +289,8 @@ grammar_dump (FILE *out, const char *title)
|
||||
rule_number r;
|
||||
for (r = 0; r < nrules + nuseless_productions; r++)
|
||||
{
|
||||
fprintf (out, "%-5d %s:", r, rules[r].lhs->symbol->tag);
|
||||
rule_rhs_print (&rules[r], out);
|
||||
fprintf (out, "%-5d ", r);
|
||||
rule_print (&rules[r], out);
|
||||
fprintf (out, "\n");
|
||||
}
|
||||
}
|
||||
@@ -293,10 +300,24 @@ grammar_dump (FILE *out, const char *title)
|
||||
void
|
||||
grammar_rules_useless_report (const char *message)
|
||||
{
|
||||
rule_number r;
|
||||
for (r = 0; r < nrules ; ++r)
|
||||
if (!rules[r].useful)
|
||||
complain (&rules[r].location, Wother, "%s", message);
|
||||
warnings w = Wother;
|
||||
if (warnings_flag & w)
|
||||
{
|
||||
rule_number r;
|
||||
for (r = 0; r < nrules ; ++r)
|
||||
if (!rules[r].useful)
|
||||
{
|
||||
if (feature_flag & feature_caret)
|
||||
complain (&rules[r].location, w, "%s", message);
|
||||
else
|
||||
{
|
||||
complain (&rules[r].location, w | silent, "%s: ", message);
|
||||
rule_print (&rules[r], stderr);
|
||||
warnings_print_categories (w);
|
||||
fprintf (stderr, "\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
+10
-22
@@ -35,7 +35,7 @@
|
||||
|
||||
The rules receive rule numbers 1 to NRULES in the order they are
|
||||
written. More precisely Bison augments the grammar with the
|
||||
initial rule, '$accept: START-SYMBOL $end', which is numbered 1,
|
||||
initial rule, `$accept: START-SYMBOL $end', which is numbered 1,
|
||||
all the user rules are 2, 3 etc. Each time a rule number is
|
||||
presented to the user, we subtract 1, so *displayed* rule numbers
|
||||
are 0, 1, 2...
|
||||
@@ -61,7 +61,7 @@
|
||||
RULES[R].prec -- the symbol providing the precedence level of R.
|
||||
|
||||
RULES[R].precsym -- the symbol attached (via %prec) to give its
|
||||
precedence to R. Of course, if set, it is equal to 'prec', but we
|
||||
precedence to R. Of course, if set, it is equal to `prec', but we
|
||||
need to distinguish one from the other when reducing: a symbol used
|
||||
in a %prec is not useless.
|
||||
|
||||
@@ -117,17 +117,6 @@ typedef int item_number;
|
||||
extern item_number *ritem;
|
||||
extern unsigned int nritems;
|
||||
|
||||
enum braces_state
|
||||
{
|
||||
default_braces_state,
|
||||
gprec_seen,
|
||||
group_name_seen,
|
||||
braces_seen
|
||||
};
|
||||
|
||||
/* Marker for the lexer and parser, to correctly interpret braces. */
|
||||
extern enum braces_state prec_braces;
|
||||
|
||||
/* There is weird relationship between OT1H item_number and OTOH
|
||||
symbol_number and rule_number: we store the latter in
|
||||
item_number. symbol_number values are stored as-is, while
|
||||
@@ -191,17 +180,17 @@ typedef struct
|
||||
except if some rules are useless. */
|
||||
rule_number number;
|
||||
|
||||
sym_content *lhs;
|
||||
symbol *lhs;
|
||||
item_number *rhs;
|
||||
|
||||
/* This symbol provides both the associativity, and the precedence. */
|
||||
sym_content *prec;
|
||||
symbol *prec;
|
||||
|
||||
int dprec;
|
||||
int merger;
|
||||
|
||||
/* This symbol was attached to the rule via %prec. */
|
||||
sym_content *precsym;
|
||||
symbol *precsym;
|
||||
|
||||
location location;
|
||||
bool useful;
|
||||
@@ -216,11 +205,11 @@ extern rule *rules;
|
||||
/* A function that selects a rule. */
|
||||
typedef bool (*rule_filter) (rule const *);
|
||||
|
||||
/* Return true IFF the rule has a 'number' smaller than NRULES. That is, it is
|
||||
/* Return true IFF the rule has a `number' smaller than NRULES. That is, it is
|
||||
useful in the grammar. */
|
||||
bool rule_useful_in_grammar_p (rule const *r);
|
||||
|
||||
/* Return true IFF the rule has a 'number' higher than NRULES. That is, it is
|
||||
/* Return true IFF the rule has a `number' higher than NRULES. That is, it is
|
||||
useless in the grammar. */
|
||||
bool rule_useless_in_grammar_p (rule const *r);
|
||||
|
||||
@@ -231,8 +220,7 @@ bool rule_useless_in_parser_p (rule const *r);
|
||||
/* Print this rule's number and lhs on OUT. If a PREVIOUS_LHS was
|
||||
already displayed (by a previous call for another rule), avoid
|
||||
useless repetitions. */
|
||||
void rule_lhs_print (rule const *r, sym_content const *previous_lhs,
|
||||
FILE *out);
|
||||
void rule_lhs_print (rule const *r, symbol const *previous_lhs, FILE *out);
|
||||
void rule_lhs_print_xml (rule const *r, FILE *out, int level);
|
||||
|
||||
/* Return the length of the RHS. */
|
||||
@@ -274,8 +262,8 @@ void grammar_rules_print_xml (FILE *out, int level);
|
||||
void grammar_dump (FILE *out, const char *title);
|
||||
|
||||
/* Report on STDERR the rules that are not flagged USEFUL, using the
|
||||
MESSAGE (which can be 'rule useless in grammar' when invoked after grammar
|
||||
reduction, or 'rule useless in parser due to conflicts' after conflicts
|
||||
MESSAGE (which can be `rule useless in grammar' when invoked after grammar
|
||||
reduction, or `rule useless in parser due to conflicts' after conflicts
|
||||
were taken into account). */
|
||||
void grammar_rules_useless_report (const char *message);
|
||||
|
||||
|
||||
+1
-1
@@ -93,7 +93,7 @@ no_reduce_bitset_init (state const *s, bitset *no_reduce_set)
|
||||
bitset_set (*no_reduce_set, TRANSITION_SYMBOL (s->transitions, n));
|
||||
for (n = 0; n < s->errs->num; ++n)
|
||||
if (s->errs->symbols[n])
|
||||
bitset_set (*no_reduce_set, s->errs->symbols[n]->content->number);
|
||||
bitset_set (*no_reduce_set, s->errs->symbols[n]->number);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
+2
-2
@@ -424,7 +424,7 @@ ielr_item_has_lookahead (state *s, symbol_number lhs, size_t item,
|
||||
if (item_number_is_rule_number (ritem[s->items[item] - 2]))
|
||||
{
|
||||
state **predecessor;
|
||||
aver (lhs != accept->content->number);
|
||||
aver (lhs != accept->number);
|
||||
for (predecessor = predecessors[s->number];
|
||||
*predecessor;
|
||||
++predecessor)
|
||||
@@ -580,7 +580,7 @@ typedef struct state_list {
|
||||
static void
|
||||
ielr_compute_goto_follow_set (bitsetv follow_kernel_items,
|
||||
bitsetv always_follows, state_list *s,
|
||||
sym_content *n, bitset follow_set)
|
||||
symbol *n, bitset follow_set)
|
||||
{
|
||||
goto_number n_goto = map_goto (s->lr0Isocore->state->number, n->number);
|
||||
bitset_copy (follow_set, always_follows[n_goto]);
|
||||
|
||||
+1
-1
@@ -342,7 +342,7 @@ state_lookahead_tokens_count (state *s, bool default_reduction_only_for_accept)
|
||||
/* We need a lookahead either to distinguish different reductions
|
||||
(i.e., there are two or more), or to distinguish a reduction from a
|
||||
shift. Otherwise, it is straightforward, and the state is
|
||||
'consistent'. However, do not treat a state with any reductions as
|
||||
`consistent'. However, do not treat a state with any reductions as
|
||||
consistent unless it is the accepting state (because there is never
|
||||
a lookahead token that makes sense there, and so no lookahead token
|
||||
should be read) if the user has otherwise disabled default
|
||||
|
||||
+5
-3
@@ -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
|
||||
location_print (location loc, FILE *out)
|
||||
location_print (FILE *out, location loc)
|
||||
{
|
||||
unsigned res = 0;
|
||||
int end_col = 0 != loc.end.column ? loc.end.column - 1 : 0;
|
||||
@@ -159,7 +161,7 @@ cleanup_caret ()
|
||||
}
|
||||
|
||||
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
|
||||
file. That would make the procedure future-proof. */
|
||||
@@ -219,7 +221,7 @@ void
|
||||
boundary_set_from_string (boundary *bound, char *loc_str)
|
||||
{
|
||||
/* Must search in reverse since the file name field may
|
||||
* contain '.' or ':'. */
|
||||
* contain `.' or `:'. */
|
||||
char *delim = strrchr (loc_str, '.');
|
||||
aver (delim);
|
||||
*delim = '\0';
|
||||
|
||||
+5
-10
@@ -20,10 +20,6 @@
|
||||
#ifndef LOCATION_H_
|
||||
# define LOCATION_H_
|
||||
|
||||
# include <stdbool.h>
|
||||
# include <stdio.h>
|
||||
# include <string.h> /* strcmp */
|
||||
|
||||
# include "uniqstr.h"
|
||||
|
||||
/* A boundary between two characters. */
|
||||
@@ -102,17 +98,16 @@ extern location const empty_location;
|
||||
void location_compute (location *loc,
|
||||
boundary *cur, char const *token, size_t size);
|
||||
|
||||
/* Print location to file.
|
||||
Return number of actually printed characters.
|
||||
Warning: uses quotearg's slot 3. */
|
||||
unsigned location_print (location loc, FILE *out);
|
||||
/* Print location to file. Return number of actually printed
|
||||
characters. */
|
||||
unsigned location_print (FILE *out, location loc);
|
||||
|
||||
/* Free any allocated ressources and close any open file handles that are
|
||||
left-over by the usage of location_caret. */
|
||||
void cleanup_caret (void);
|
||||
|
||||
/* Output to OUT the line and caret corresponding to location LOC. */
|
||||
void location_caret (location loc, FILE *out);
|
||||
void location_caret (FILE *out, location loc);
|
||||
|
||||
/* Return -1, 0, 1, depending whether a is before, equal, or
|
||||
after b. */
|
||||
@@ -125,7 +120,7 @@ location_cmp (location a, location b)
|
||||
return res;
|
||||
}
|
||||
|
||||
/* LOC_STR must be formatted as 'file:line.column', it will be modified. */
|
||||
/* LOC_STR must be formatted as `file:line.column', it will be modified. */
|
||||
void boundary_set_from_string (boundary *bound, char *loc_str);
|
||||
|
||||
#endif /* ! defined LOCATION_H_ */
|
||||
|
||||
+2
-1
@@ -76,7 +76,6 @@ main (int argc, char *argv[])
|
||||
|
||||
uniqstrs_new ();
|
||||
muscle_init ();
|
||||
complain_init ();
|
||||
|
||||
getargs (argc, argv);
|
||||
|
||||
@@ -147,6 +146,8 @@ main (int argc, char *argv[])
|
||||
|
||||
print_precedence_warnings ();
|
||||
|
||||
print_assoc_warnings ();
|
||||
|
||||
/* Output file names. */
|
||||
compute_output_file_names ();
|
||||
|
||||
|
||||
+160
-208
@@ -28,31 +28,6 @@
|
||||
#include "muscle-tab.h"
|
||||
#include "quote.h"
|
||||
|
||||
muscle_kind
|
||||
muscle_kind_new (char const *k)
|
||||
{
|
||||
if (STREQ (k, "code"))
|
||||
return muscle_code;
|
||||
else if (STREQ (k, "keyword"))
|
||||
return muscle_keyword;
|
||||
else if (STREQ (k, "string"))
|
||||
return muscle_string;
|
||||
aver (0);
|
||||
}
|
||||
|
||||
char const *
|
||||
muscle_kind_string (muscle_kind k)
|
||||
{
|
||||
switch (k)
|
||||
{
|
||||
case muscle_code: return "code";
|
||||
case muscle_keyword: return "keyword";
|
||||
case muscle_string: return "string";
|
||||
}
|
||||
aver (0);
|
||||
}
|
||||
|
||||
|
||||
/* A key-value pair, along with storage that can be reclaimed when
|
||||
this pair is no longer needed. */
|
||||
typedef struct
|
||||
@@ -60,21 +35,8 @@ typedef struct
|
||||
char const *key;
|
||||
char const *value;
|
||||
char *storage;
|
||||
muscle_kind kind;
|
||||
} muscle_entry;
|
||||
|
||||
|
||||
/* The name of muscle for the %define variable VAR (corresponding to
|
||||
FIELD, if defined). */
|
||||
static uniqstr
|
||||
muscle_name (char const *var, char const *field)
|
||||
{
|
||||
if (field)
|
||||
return UNIQSTR_CONCAT ("percent_define_", field, "(", var, ")");
|
||||
else
|
||||
return UNIQSTR_CONCAT ("percent_define(", var, ")");
|
||||
}
|
||||
|
||||
/* An obstack used to create some entries. */
|
||||
struct obstack muscle_obstack;
|
||||
|
||||
@@ -98,18 +60,10 @@ hash_muscle (const void *x, size_t tablesize)
|
||||
return hash_string (m->key, tablesize);
|
||||
}
|
||||
|
||||
/* Create a fresh muscle name KEY, and insert in the hash table. */
|
||||
static void *
|
||||
muscle_entry_new (char const *key)
|
||||
{
|
||||
muscle_entry *res = xmalloc (sizeof *res);
|
||||
res->key = key;
|
||||
res->value = NULL;
|
||||
res->storage = NULL;
|
||||
if (!hash_insert (muscle_table, res))
|
||||
xalloc_die ();
|
||||
return res;
|
||||
}
|
||||
/*-----------------------------------------------------------------.
|
||||
| Create the MUSCLE_TABLE, and initialize it with default values. |
|
||||
| Also set up the MUSCLE_OBSTACK. |
|
||||
`-----------------------------------------------------------------*/
|
||||
|
||||
static void
|
||||
muscle_entry_free (void *entry)
|
||||
@@ -133,6 +87,10 @@ muscle_init (void)
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------.
|
||||
| Free all the memory consumed by the muscle machinery only. |
|
||||
`------------------------------------------------------------*/
|
||||
|
||||
void
|
||||
muscle_free (void)
|
||||
{
|
||||
@@ -140,64 +98,71 @@ muscle_free (void)
|
||||
obstack_free (&muscle_obstack, NULL);
|
||||
}
|
||||
|
||||
/* Look for the muscle named KEY. Return NULL if does not exist. */
|
||||
static
|
||||
muscle_entry *
|
||||
muscle_lookup (char const *key)
|
||||
{
|
||||
muscle_entry probe;
|
||||
probe.key = key;
|
||||
return hash_lookup (muscle_table, &probe);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------.
|
||||
| Insert (KEY, VALUE). If KEY already existed, overwrite the |
|
||||
| previous value. |
|
||||
`------------------------------------------------------------*/
|
||||
|
||||
void
|
||||
muscle_insert (char const *key, char const *value)
|
||||
{
|
||||
muscle_entry *entry = muscle_lookup (key);
|
||||
if (entry)
|
||||
free (entry->storage);
|
||||
muscle_entry probe;
|
||||
muscle_entry *entry;
|
||||
|
||||
probe.key = key;
|
||||
entry = hash_lookup (muscle_table, &probe);
|
||||
|
||||
if (!entry)
|
||||
{
|
||||
/* First insertion in the hash. */
|
||||
entry = xmalloc (sizeof *entry);
|
||||
entry->key = key;
|
||||
if (!hash_insert (muscle_table, entry))
|
||||
xalloc_die ();
|
||||
}
|
||||
else
|
||||
/* First insertion in the hash. */
|
||||
entry = muscle_entry_new (key);
|
||||
free (entry->storage);
|
||||
entry->value = value;
|
||||
entry->storage = NULL;
|
||||
}
|
||||
|
||||
|
||||
/* Append VALUE to the current value of KEY. If KEY did not already
|
||||
exist, create it. Use MUSCLE_OBSTACK. De-allocate the previously
|
||||
associated value. Copy VALUE and SEPARATOR. If VALUE does not end
|
||||
with TERMINATOR, append one. */
|
||||
/*-------------------------------------------------------------------.
|
||||
| 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. |
|
||||
`-------------------------------------------------------------------*/
|
||||
|
||||
static void
|
||||
muscle_grow (const char *key, const char *val,
|
||||
const char *separator, const char *terminator)
|
||||
void
|
||||
muscle_grow (const char *key, const char *val, const char *separator)
|
||||
{
|
||||
muscle_entry *entry = muscle_lookup (key);
|
||||
size_t vals = strlen (val);
|
||||
size_t terms = strlen (terminator);
|
||||
muscle_entry probe;
|
||||
muscle_entry *entry = NULL;
|
||||
|
||||
if (entry)
|
||||
probe.key = key;
|
||||
entry = hash_lookup (muscle_table, &probe);
|
||||
|
||||
if (!entry)
|
||||
{
|
||||
obstack_sgrow (&muscle_obstack, entry->value);
|
||||
obstack_sgrow (&muscle_obstack, separator);
|
||||
free (entry->storage);
|
||||
/* First insertion in the hash. */
|
||||
entry = xmalloc (sizeof *entry);
|
||||
entry->key = key;
|
||||
if (!hash_insert (muscle_table, entry))
|
||||
xalloc_die ();
|
||||
entry->value = entry->storage = xstrdup (val);
|
||||
}
|
||||
else
|
||||
entry = muscle_entry_new (key);
|
||||
|
||||
obstack_sgrow (&muscle_obstack, val);
|
||||
|
||||
if (terms <= vals
|
||||
&& STRNEQ (val + vals - terms, terminator))
|
||||
obstack_sgrow (&muscle_obstack, terminator);
|
||||
|
||||
{
|
||||
char *new_val = obstack_finish0 (&muscle_obstack);
|
||||
entry->value = entry->storage = xstrdup (new_val);
|
||||
obstack_free (&muscle_obstack, new_val);
|
||||
}
|
||||
{
|
||||
/* Grow the current value. */
|
||||
char *new_val;
|
||||
obstack_printf (&muscle_obstack, "%s%s%s", entry->value, separator, val);
|
||||
free (entry->storage);
|
||||
new_val = obstack_finish0 (&muscle_obstack);
|
||||
entry->value = entry->storage = xstrdup (new_val);
|
||||
obstack_free (&muscle_obstack, new_val);
|
||||
}
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------.
|
||||
@@ -214,7 +179,7 @@ muscle_syncline_grow (char const *key, location loc)
|
||||
quotearg_style (c_quoting_style, loc.start.file));
|
||||
obstack_sgrow (&muscle_obstack, ")[");
|
||||
extension = obstack_finish0 (&muscle_obstack);
|
||||
muscle_grow (key, extension, "", "");
|
||||
muscle_grow (key, extension, "");
|
||||
obstack_free (&muscle_obstack, extension);
|
||||
}
|
||||
|
||||
@@ -228,13 +193,12 @@ void
|
||||
muscle_code_grow (const char *key, const char *val, location loc)
|
||||
{
|
||||
muscle_syncline_grow (key, loc);
|
||||
muscle_grow (key, val, "\n", "\n");
|
||||
muscle_grow (key, val, "\n");
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
muscle_pair_list_grow (const char *muscle,
|
||||
const char *a1, const char *a2)
|
||||
void muscle_pair_list_grow (const char *muscle,
|
||||
const char *a1, const char *a2)
|
||||
{
|
||||
char *pair;
|
||||
obstack_sgrow (&muscle_obstack, "[");
|
||||
@@ -243,33 +207,54 @@ muscle_pair_list_grow (const char *muscle,
|
||||
obstack_quote (&muscle_obstack, a2);
|
||||
obstack_sgrow (&muscle_obstack, "]");
|
||||
pair = obstack_finish0 (&muscle_obstack);
|
||||
muscle_grow (muscle, pair, ",\n", "");
|
||||
muscle_grow (muscle, pair, ",\n");
|
||||
obstack_free (&muscle_obstack, pair);
|
||||
}
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------.
|
||||
| Find the value of muscle KEY. Unlike MUSCLE_FIND, this is always reliable |
|
||||
| to determine whether KEY has a value. |
|
||||
`----------------------------------------------------------------------------*/
|
||||
|
||||
char const *
|
||||
muscle_find_const (char const *key)
|
||||
{
|
||||
muscle_entry *entry = muscle_lookup (key);
|
||||
return entry ? entry->value : NULL;
|
||||
muscle_entry probe;
|
||||
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 *
|
||||
muscle_find (char const *key)
|
||||
{
|
||||
muscle_entry *entry = muscle_lookup (key);
|
||||
if (entry)
|
||||
muscle_entry probe;
|
||||
muscle_entry *result = NULL;
|
||||
|
||||
probe.key = key;
|
||||
result = hash_lookup (muscle_table, &probe);
|
||||
if (result)
|
||||
{
|
||||
aver (entry->value == entry->storage);
|
||||
return entry->storage;
|
||||
aver (result->value == result->storage);
|
||||
return result->storage;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/* In the format 'file_name:line.column', append BOUND to MUSCLE. Use
|
||||
/* In the format `file_name:line.column', append BOUND to MUSCLE. Use
|
||||
digraphs for special characters in the file name. */
|
||||
|
||||
static void
|
||||
@@ -280,12 +265,12 @@ muscle_boundary_grow (char const *key, boundary bound)
|
||||
obstack_escape (&muscle_obstack, bound.file);
|
||||
obstack_printf (&muscle_obstack, ":%d.%d]]", bound.line, bound.column);
|
||||
extension = obstack_finish0 (&muscle_obstack);
|
||||
muscle_grow (key, extension, "", "");
|
||||
muscle_grow (key, extension, "");
|
||||
obstack_free (&muscle_obstack, extension);
|
||||
}
|
||||
|
||||
|
||||
/* In the format '[[file_name:line.column]], [[file_name:line.column]]',
|
||||
/* In the format `[[file_name:line.column]], [[file_name:line.column]]',
|
||||
append LOC to MUSCLE. Use digraphs for special characters in each
|
||||
file name. */
|
||||
|
||||
@@ -293,7 +278,7 @@ static void
|
||||
muscle_location_grow (char const *key, location loc)
|
||||
{
|
||||
muscle_boundary_grow (key, loc.start);
|
||||
muscle_grow (key, "", ", ", "");
|
||||
muscle_grow (key, "", ", ");
|
||||
muscle_boundary_grow (key, loc.end);
|
||||
}
|
||||
|
||||
@@ -344,9 +329,10 @@ string_decode (char const *key)
|
||||
|
||||
/* Reverse of muscle_location_grow. */
|
||||
static location
|
||||
location_decode (char const *value)
|
||||
location_decode (char const *key)
|
||||
{
|
||||
location loc;
|
||||
char const *value = muscle_find_const (key);
|
||||
aver (value);
|
||||
aver (*value == '[');
|
||||
aver (*++value == '[');
|
||||
@@ -391,11 +377,11 @@ void
|
||||
muscle_user_name_list_grow (char const *key, char const *user_name,
|
||||
location loc)
|
||||
{
|
||||
muscle_grow (key, "[[[[", ",", "");
|
||||
muscle_grow (key, user_name, "", "");
|
||||
muscle_grow (key, "]], ", "", "");
|
||||
muscle_grow (key, "[[[[", ",");
|
||||
muscle_grow (key, user_name, "");
|
||||
muscle_grow (key, "]], ", "");
|
||||
muscle_location_grow (key, loc);
|
||||
muscle_grow (key, "]]", "", "");
|
||||
muscle_grow (key, "]]", "");
|
||||
}
|
||||
|
||||
|
||||
@@ -489,17 +475,16 @@ muscle_percent_variable_update (char const *variable, location variable_loc,
|
||||
|
||||
void
|
||||
muscle_percent_define_insert (char const *var, location variable_loc,
|
||||
muscle_kind kind,
|
||||
char const *value,
|
||||
muscle_percent_define_how how)
|
||||
{
|
||||
/* Backward compatibility. */
|
||||
char *variable = muscle_percent_variable_update (var, variable_loc, &value);
|
||||
uniqstr name = muscle_name (variable, NULL);
|
||||
uniqstr loc_name = muscle_name (variable, "loc");
|
||||
uniqstr syncline_name = muscle_name (variable, "syncline");
|
||||
uniqstr how_name = muscle_name (variable, "how");
|
||||
uniqstr kind_name = muscle_name (variable, "kind");
|
||||
char const *name = UNIQSTR_CONCAT ("percent_define(", variable, ")");
|
||||
char const *loc_name = UNIQSTR_CONCAT ("percent_define_loc(", variable, ")");
|
||||
char const *syncline_name =
|
||||
UNIQSTR_CONCAT ("percent_define_syncline(", variable, ")");
|
||||
char const *how_name = UNIQSTR_CONCAT ("percent_define_how(", variable, ")");
|
||||
|
||||
/* Command-line options are processed before the grammar file. */
|
||||
if (how == MUSCLE_PERCENT_DEFINE_GRAMMAR_FILE
|
||||
@@ -525,7 +510,6 @@ muscle_percent_define_insert (char const *var, location variable_loc,
|
||||
muscle_user_name_list_grow ("percent_define_user_variables", variable,
|
||||
variable_loc);
|
||||
MUSCLE_INSERT_INT (how_name, how);
|
||||
MUSCLE_INSERT_STRING (kind_name, muscle_kind_string (kind));
|
||||
end:
|
||||
free (variable);
|
||||
}
|
||||
@@ -536,120 +520,85 @@ void
|
||||
muscle_percent_define_ensure (char const *variable, location loc,
|
||||
bool value)
|
||||
{
|
||||
uniqstr name = muscle_name (variable, NULL);
|
||||
char const *val = value ? "" : "false";
|
||||
char const *name = UNIQSTR_CONCAT ("percent_define(", variable, ")");
|
||||
|
||||
/* Don't complain is VARIABLE is already defined, but be sure to set
|
||||
its value to VAL. */
|
||||
if (!muscle_find_const (name)
|
||||
|| muscle_percent_define_flag_if (variable) != value)
|
||||
muscle_percent_define_insert (variable, loc, muscle_keyword, val,
|
||||
/* %pure-parser is deprecated in favor of `%define api.pure', so use
|
||||
`%define api.pure' in a backward-compatible manner here. First,
|
||||
don't complain if %pure-parser is specified multiple times. */
|
||||
if (!muscle_find_const (name))
|
||||
muscle_percent_define_insert (variable, loc, val,
|
||||
MUSCLE_PERCENT_DEFINE_GRAMMAR_FILE);
|
||||
/* In all cases, use api.pure now so that the backend doesn't complain if
|
||||
the skeleton ignores api.pure, but do warn now if there's a previous
|
||||
conflicting definition from an actual %define. */
|
||||
if (muscle_percent_define_flag_if (variable) != value)
|
||||
muscle_percent_define_insert (variable, loc, val,
|
||||
MUSCLE_PERCENT_DEFINE_GRAMMAR_FILE);
|
||||
}
|
||||
|
||||
/* Mark %define VARIABLE as used. */
|
||||
static void
|
||||
muscle_percent_define_use (char const *variable)
|
||||
{
|
||||
muscle_insert (muscle_name (variable, "bison_variables"), "");
|
||||
}
|
||||
|
||||
/* The value of %define variable VARIABLE (corresponding to FIELD, if
|
||||
defined). Do not register as used, but diagnose unset variables. */
|
||||
|
||||
static
|
||||
char const *
|
||||
muscle_percent_define_get_raw (char const *variable, char const *field)
|
||||
{
|
||||
uniqstr name = muscle_name (variable, field);
|
||||
char const *res = muscle_find_const (name);
|
||||
if (!res)
|
||||
complain (NULL, fatal, _("%s: undefined %%define variable %s"),
|
||||
"muscle_percent_define_get_raw", quote (variable));
|
||||
return res;
|
||||
}
|
||||
|
||||
char *
|
||||
muscle_percent_define_get (char const *variable)
|
||||
{
|
||||
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);
|
||||
if (!value)
|
||||
value = xstrdup ("");
|
||||
muscle_percent_define_use (variable);
|
||||
|
||||
muscle_insert (usage_name, "");
|
||||
return value;
|
||||
}
|
||||
|
||||
/* The kind of VARIABLE. An error if undefined. */
|
||||
static muscle_kind
|
||||
muscle_percent_define_get_kind (char const *variable)
|
||||
{
|
||||
return muscle_kind_new (muscle_percent_define_get_raw (variable, "kind"));
|
||||
}
|
||||
|
||||
/* Check the kind of VARIABLE. An error if undefined. */
|
||||
static void
|
||||
muscle_percent_define_check_kind (char const *variable, muscle_kind kind)
|
||||
{
|
||||
if (muscle_percent_define_get_kind (variable) != kind)
|
||||
{
|
||||
location loc = muscle_percent_define_get_loc (variable);
|
||||
switch (kind)
|
||||
{
|
||||
case muscle_code:
|
||||
complain (&loc, Wdeprecated,
|
||||
"%%define variable '%s' requires '{...}' values",
|
||||
variable);
|
||||
break;
|
||||
case muscle_keyword:
|
||||
complain (&loc, Wdeprecated,
|
||||
"%%define variable '%s' requires keyword values",
|
||||
variable);
|
||||
break;
|
||||
case muscle_string:
|
||||
complain (&loc, Wdeprecated,
|
||||
"%%define variable '%s' requires '\"...\"' values",
|
||||
variable);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
location
|
||||
muscle_percent_define_get_loc (char const *variable)
|
||||
{
|
||||
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 *
|
||||
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
|
||||
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;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
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;
|
||||
|
||||
if (muscle_percent_define_ifdef (variable))
|
||||
{
|
||||
char *value = muscle_percent_define_get (variable);
|
||||
muscle_percent_define_check_kind (variable, muscle_keyword);
|
||||
if (value[0] == '\0' || STREQ (value, "true"))
|
||||
result = true;
|
||||
else if (STREQ (value, "false"))
|
||||
@@ -674,21 +623,20 @@ muscle_percent_define_flag_if (char const *variable)
|
||||
void
|
||||
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))
|
||||
{
|
||||
location loc;
|
||||
MUSCLE_INSERT_STRING (name, value);
|
||||
MUSCLE_INSERT_STRING (muscle_name (variable, "kind"), "keyword");
|
||||
{
|
||||
uniqstr loc_name = muscle_name (variable, "loc");
|
||||
location loc;
|
||||
loc.start.file = loc.end.file = "<default value>";
|
||||
loc.start.line = loc.end.line = -1;
|
||||
loc.start.column = loc.end.column = -1;
|
||||
muscle_insert (loc_name, "");
|
||||
muscle_location_grow (loc_name, loc);
|
||||
}
|
||||
muscle_insert (muscle_name (variable, "syncline"), "");
|
||||
loc.start.file = loc.end.file = "<default value>";
|
||||
loc.start.line = loc.end.line = -1;
|
||||
loc.start.column = loc.end.column = -1;
|
||||
muscle_insert (loc_name, "");
|
||||
muscle_location_grow (loc_name, loc);
|
||||
muscle_insert (syncline_name, "");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -698,9 +646,8 @@ muscle_percent_define_check_values (char const * const *values)
|
||||
for (; *values; ++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);
|
||||
muscle_percent_define_check_kind (*variablep, muscle_keyword);
|
||||
if (value)
|
||||
{
|
||||
for (++values; *values; ++values)
|
||||
@@ -717,7 +664,7 @@ muscle_percent_define_check_values (char const * const *values)
|
||||
quote (*variablep), quote_n (1, value));
|
||||
i += SUB_INDENT;
|
||||
for (values = variablep + 1; *values; ++values)
|
||||
complain_indent (&loc, complaint | no_caret | silent, &i,
|
||||
complain_indent (&loc, complaint | no_caret, &i,
|
||||
_("accepted value: %s"), quote (*values));
|
||||
}
|
||||
else
|
||||
@@ -764,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
|
||||
muscles_m4_output (FILE *out)
|
||||
{
|
||||
|
||||
+18
-44
@@ -24,41 +24,10 @@
|
||||
|
||||
# include "location.h"
|
||||
|
||||
/* The kind of value associated to this muscle, depending on the
|
||||
syntax of the value: keyword (no delimiter, e.g., true), string
|
||||
(double quotes, e.g., "foo.h"), or code (braces, e.g., {int}). */
|
||||
typedef enum
|
||||
{
|
||||
muscle_code,
|
||||
muscle_keyword,
|
||||
muscle_string
|
||||
} muscle_kind;
|
||||
|
||||
/* Conversion from string. */
|
||||
muscle_kind muscle_kind_new (char const *k);
|
||||
|
||||
/* Conversion to string. */
|
||||
char const *muscle_kind_string (muscle_kind k);
|
||||
|
||||
|
||||
/* Create the MUSCLE_TABLE, and initialize it with default values.
|
||||
Also set up the MUSCLE_OBSTACK. */
|
||||
void muscle_init (void);
|
||||
|
||||
/* Insert (KEY, VALUE). If KEY already existed, overwrite the
|
||||
previous value. Otherwise create as a muscle_string type. */
|
||||
void muscle_insert (char const *key, char const *value);
|
||||
|
||||
/* Find the value of muscle KEY. Unlike MUSCLE_FIND, this is always
|
||||
reliable to determine whether KEY has a value. */
|
||||
char const *muscle_find_const (char const *key);
|
||||
|
||||
/* Find the value of muscle KEY. Abort if muscle_insert was invoked
|
||||
more recently than muscle_grow for KEY since muscle_find can't
|
||||
return a char const *. */
|
||||
char *muscle_find (char const *key);
|
||||
|
||||
/* Free all the memory consumed by the muscle machinery only. */
|
||||
void muscle_free (void);
|
||||
|
||||
|
||||
@@ -78,14 +47,14 @@ extern struct obstack muscle_obstack;
|
||||
} while (0)
|
||||
|
||||
# define MUSCLE_INSERT_INT(Key, Value) \
|
||||
MUSCLE_INSERTF (Key, "%d", Value)
|
||||
MUSCLE_INSERTF(Key, "%d", Value)
|
||||
|
||||
# define MUSCLE_INSERT_LONG_INT(Key, Value) \
|
||||
MUSCLE_INSERTF (Key, "%ld", Value)
|
||||
MUSCLE_INSERTF(Key, "%ld", Value)
|
||||
|
||||
/* Key -> Value, but don't apply escaping to Value. */
|
||||
# define MUSCLE_INSERT_STRING_RAW(Key, Value) \
|
||||
MUSCLE_INSERTF (Key, "%s", Value)
|
||||
MUSCLE_INSERTF(Key, "%s", Value)
|
||||
|
||||
/* Key -> Value, applying M4 escaping to Value. */
|
||||
# define MUSCLE_INSERT_STRING(Key, Value) \
|
||||
@@ -94,14 +63,23 @@ extern struct obstack muscle_obstack;
|
||||
muscle_insert (Key, obstack_finish0 (&muscle_obstack)); \
|
||||
} while (0)
|
||||
|
||||
/* Key -> Value, applying C escaping to Value (and then M4). */
|
||||
# define MUSCLE_INSERT_C_STRING(Key, Value) \
|
||||
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
|
||||
in addition, issue a synchronization line for the location LOC.
|
||||
Be sure to append on a new line. */
|
||||
in addition, issue a synchronization line for the 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
|
||||
use with b4_check_user_names in ../data/bison.m4. USER_NAME is not escaped
|
||||
with digraphs, so it must not contain '[' or ']'. */
|
||||
with digraphs, so it must not contain `[' or `]'. */
|
||||
void muscle_user_name_list_grow (char const *key, char const *user_name,
|
||||
location loc);
|
||||
|
||||
/* Indicates whether a variable's value was specified with -D/--define, with
|
||||
-F/--force-define, or in the grammar file. */
|
||||
typedef enum {
|
||||
MUSCLE_PERCENT_DEFINE_D = 0,
|
||||
MUSCLE_PERCENT_DEFINE_F,
|
||||
MUSCLE_PERCENT_DEFINE_D = 0, MUSCLE_PERCENT_DEFINE_F,
|
||||
MUSCLE_PERCENT_DEFINE_GRAMMAR_FILE
|
||||
} muscle_percent_define_how;
|
||||
|
||||
@@ -136,7 +113,6 @@ typedef enum {
|
||||
this as a user occurrence of VARIABLE by invoking
|
||||
muscle_user_name_list_grow. */
|
||||
void muscle_percent_define_insert (char const *variable, location variable_loc,
|
||||
muscle_kind kind,
|
||||
char const *value,
|
||||
muscle_percent_define_how how);
|
||||
|
||||
@@ -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,
|
||||
char const *code, location code_loc);
|
||||
|
||||
/* Output the definition of all the current muscles into a list of
|
||||
m4_defines. */
|
||||
void muscles_m4_output (FILE *out);
|
||||
|
||||
#endif /* not MUSCLE_TAB_H_ */
|
||||
|
||||
+31
-32
@@ -90,19 +90,20 @@ Name (char const *name, \
|
||||
\
|
||||
lmin = min; \
|
||||
lmax = max; \
|
||||
/* Build 'NAME_min' and 'NAME_max' in the obstack. */ \
|
||||
/* Build `NAME_min' and `NAME_max' in the obstack. */ \
|
||||
obstack_printf (&format_obstack, "%s_min", name); \
|
||||
MUSCLE_INSERT_LONG_INT (obstack_finish0 (&format_obstack), lmin); \
|
||||
obstack_printf (&format_obstack, "%s_max", name); \
|
||||
MUSCLE_INSERT_LONG_INT (obstack_finish0 (&format_obstack), lmax); \
|
||||
}
|
||||
|
||||
GENERATE_MUSCLE_INSERT_TABLE (muscle_insert_unsigned_int_table, unsigned int)
|
||||
GENERATE_MUSCLE_INSERT_TABLE (muscle_insert_int_table, int)
|
||||
GENERATE_MUSCLE_INSERT_TABLE (muscle_insert_base_table, base_number)
|
||||
GENERATE_MUSCLE_INSERT_TABLE (muscle_insert_rule_number_table, rule_number)
|
||||
GENERATE_MUSCLE_INSERT_TABLE (muscle_insert_symbol_number_table, symbol_number)
|
||||
GENERATE_MUSCLE_INSERT_TABLE (muscle_insert_state_number_table, state_number)
|
||||
GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_unsigned_int_table, unsigned int)
|
||||
GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_int_table, int)
|
||||
GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_base_table, base_number)
|
||||
GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_rule_number_table, rule_number)
|
||||
GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_symbol_number_table, symbol_number)
|
||||
GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_state_number_table, state_number)
|
||||
|
||||
|
||||
/*----------------------------------------------------------------.
|
||||
| Print to OUT a representation of CP quoted and escaped for M4. |
|
||||
@@ -149,7 +150,7 @@ prepare_symbols (void)
|
||||
MUSCLE_INSERT_INT ("tokens_number", ntokens);
|
||||
MUSCLE_INSERT_INT ("nterms_number", nvars);
|
||||
MUSCLE_INSERT_INT ("symbols_number", nsyms);
|
||||
MUSCLE_INSERT_INT ("undef_token_number", undeftoken->content->number);
|
||||
MUSCLE_INSERT_INT ("undef_token_number", undeftoken->number);
|
||||
MUSCLE_INSERT_INT ("user_token_number_max", max_user_token_number);
|
||||
|
||||
muscle_insert_symbol_number_table ("translate",
|
||||
@@ -197,7 +198,7 @@ prepare_symbols (void)
|
||||
int i;
|
||||
int *values = xnmalloc (ntokens, sizeof *values);
|
||||
for (i = 0; i < ntokens; ++i)
|
||||
values[i] = symbols[i]->content->user_token_number;
|
||||
values[i] = symbols[i]->user_token_number;
|
||||
muscle_insert_int_table ("toknum", values,
|
||||
values[0], 1, ntokens);
|
||||
free (values);
|
||||
@@ -226,7 +227,7 @@ prepare_rules (void)
|
||||
/* LHS of the rule R. */
|
||||
r1[r] = rules[r].lhs->number;
|
||||
/* Length of rule R's RHS. */
|
||||
r2[r] = rule_rhs_length (&rules[r]);
|
||||
r2[r] = rule_rhs_length(&rules[r]);
|
||||
/* Line where rule was defined. */
|
||||
rline[r] = rules[r].location.start.line;
|
||||
/* Dynamic precedence (GLR). */
|
||||
@@ -283,9 +284,9 @@ prepare_states (void)
|
||||
static int
|
||||
symbol_type_name_cmp (const symbol **lhs, const symbol **rhs)
|
||||
{
|
||||
int res = uniqstr_cmp ((*lhs)->content->type_name, (*rhs)->content->type_name);
|
||||
int res = uniqstr_cmp ((*lhs)->type_name, (*rhs)->type_name);
|
||||
if (!res)
|
||||
res = (*lhs)->content->number - (*rhs)->content->number;
|
||||
res = (*lhs)->number - (*rhs)->number;
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -320,9 +321,8 @@ type_names_output (FILE *out)
|
||||
/* The index of the first symbol of the current type-name. */
|
||||
int i0 = i;
|
||||
fputs (i ? ",\n[" : "[", out);
|
||||
for (; i < nsyms
|
||||
&& syms[i]->content->type_name == syms[i0]->content->type_name; ++i)
|
||||
fprintf (out, "%s%d", i != i0 ? ", " : "", syms[i]->content->number);
|
||||
for (; i < nsyms && syms[i]->type_name == syms[i0]->type_name; ++i)
|
||||
fprintf (out, "%s%d", i != i0 ? ", " : "", syms[i]->number);
|
||||
fputs ("]", out);
|
||||
}
|
||||
fputs ("])\n\n", out);
|
||||
@@ -417,33 +417,32 @@ prepare_symbol_definitions (void)
|
||||
|
||||
/* Whether the symbol has an identifier. */
|
||||
value = symbol_id_get (sym);
|
||||
SET_KEY ("has_id");
|
||||
SET_KEY("has_id");
|
||||
MUSCLE_INSERT_INT (key, !!value);
|
||||
|
||||
/* Its identifier. */
|
||||
SET_KEY ("id");
|
||||
SET_KEY("id");
|
||||
MUSCLE_INSERT_STRING (key, value ? value : "");
|
||||
|
||||
/* Its tag. Typically for documentation purpose. */
|
||||
SET_KEY ("tag");
|
||||
SET_KEY("tag");
|
||||
MUSCLE_INSERT_STRING (key, sym->tag);
|
||||
|
||||
SET_KEY ("user_number");
|
||||
MUSCLE_INSERT_INT (key, sym->content->user_token_number);
|
||||
SET_KEY("user_number");
|
||||
MUSCLE_INSERT_INT (key, sym->user_token_number);
|
||||
|
||||
SET_KEY ("is_token");
|
||||
SET_KEY("is_token");
|
||||
MUSCLE_INSERT_INT (key,
|
||||
i < ntokens && sym != errtoken && sym != undeftoken);
|
||||
|
||||
SET_KEY ("number");
|
||||
MUSCLE_INSERT_INT (key, sym->content->number);
|
||||
SET_KEY("number");
|
||||
MUSCLE_INSERT_INT (key, sym->number);
|
||||
|
||||
SET_KEY ("has_type");
|
||||
MUSCLE_INSERT_INT (key, !!sym->content->type_name);
|
||||
SET_KEY("has_type");
|
||||
MUSCLE_INSERT_INT (key, !!sym->type_name);
|
||||
|
||||
SET_KEY ("type");
|
||||
MUSCLE_INSERT_STRING (key, sym->content->type_name
|
||||
? sym->content->type_name : "");
|
||||
SET_KEY("type");
|
||||
MUSCLE_INSERT_STRING (key, sym->type_name ? sym->type_name : "");
|
||||
|
||||
{
|
||||
int j;
|
||||
@@ -452,18 +451,18 @@ prepare_symbol_definitions (void)
|
||||
/* "printer", not "%printer". */
|
||||
char const *pname = code_props_type_string (j) + 1;
|
||||
code_props const *p = symbol_code_props_get (sym, j);
|
||||
SET_KEY2 ("has", pname);
|
||||
SET_KEY2("has", pname);
|
||||
MUSCLE_INSERT_INT (key, !!p->code);
|
||||
|
||||
if (p->code)
|
||||
{
|
||||
SET_KEY2 (pname, "file");
|
||||
SET_KEY2(pname, "file");
|
||||
MUSCLE_INSERT_STRING (key, p->location.start.file);
|
||||
|
||||
SET_KEY2 (pname, "line");
|
||||
SET_KEY2(pname, "line");
|
||||
MUSCLE_INSERT_INT (key, p->location.start.line);
|
||||
|
||||
SET_KEY (pname);
|
||||
SET_KEY(pname);
|
||||
MUSCLE_INSERT_STRING_RAW (key, p->code);
|
||||
}
|
||||
}
|
||||
|
||||
+865
-1002
File diff suppressed because it is too large
Load Diff
+134
-97
@@ -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
|
||||
|
||||
@@ -48,12 +48,10 @@
|
||||
extern int gram_debug;
|
||||
#endif
|
||||
/* "%code requires" blocks. */
|
||||
#line 21 "src/parse-gram.y" /* yacc.c:1909 */
|
||||
|
||||
#include "symlist.h"
|
||||
#include "symtab.h"
|
||||
#line 233 "src/parse-gram.y" /* yacc.c:1909 */
|
||||
#line 223 "src/parse-gram.y" /* yacc.c:1932 */
|
||||
|
||||
# ifndef PARAM_TYPE
|
||||
# define PARAM_TYPE
|
||||
typedef enum
|
||||
{
|
||||
param_none = 0,
|
||||
@@ -61,10 +59,10 @@ extern int gram_debug;
|
||||
param_parse = 1 << 1,
|
||||
param_both = param_lex | param_parse
|
||||
} param_type;
|
||||
#line 723 "src/parse-gram.y" /* yacc.c:1909 */
|
||||
#include "muscle-tab.h"
|
||||
# endif
|
||||
|
||||
#line 68 "src/parse-gram.h" /* yacc.c:1909 */
|
||||
|
||||
#line 66 "src/parse-gram.h" /* yacc.c:1932 */
|
||||
|
||||
/* Token type. */
|
||||
#ifndef GRAM_TOKENTYPE
|
||||
@@ -73,104 +71,143 @@ extern int gram_debug;
|
||||
{
|
||||
GRAM_EOF = 0,
|
||||
STRING = 258,
|
||||
PERCENT_TOKEN = 259,
|
||||
PERCENT_NTERM = 260,
|
||||
PERCENT_TYPE = 261,
|
||||
PERCENT_DESTRUCTOR = 262,
|
||||
PERCENT_PRINTER = 263,
|
||||
PERCENT_LEFT = 264,
|
||||
PERCENT_RIGHT = 265,
|
||||
PERCENT_NONASSOC = 266,
|
||||
PERCENT_PRECEDENCE = 267,
|
||||
PERCENT_PREC = 268,
|
||||
PERCENT_DPREC = 269,
|
||||
PERCENT_GPREC = 270,
|
||||
PERCENT_PRECR = 271,
|
||||
PERCENT_MERGE = 272,
|
||||
PERCENT_CODE = 273,
|
||||
PERCENT_DEFAULT_PREC = 274,
|
||||
PERCENT_DEFINE = 275,
|
||||
PERCENT_DEFINES = 276,
|
||||
PERCENT_ERROR_VERBOSE = 277,
|
||||
PERCENT_EXPECT = 278,
|
||||
PERCENT_EXPECT_RR = 279,
|
||||
PERCENT_FLAG = 280,
|
||||
PERCENT_FILE_PREFIX = 281,
|
||||
PERCENT_GLR_PARSER = 282,
|
||||
PERCENT_INITIAL_ACTION = 283,
|
||||
PERCENT_LANGUAGE = 284,
|
||||
PERCENT_NAME_PREFIX = 285,
|
||||
PERCENT_NO_DEFAULT_PREC = 286,
|
||||
PERCENT_NO_LINES = 287,
|
||||
PERCENT_NONDETERMINISTIC_PARSER = 288,
|
||||
PERCENT_OUTPUT = 289,
|
||||
PERCENT_REQUIRE = 290,
|
||||
PERCENT_SKELETON = 291,
|
||||
PERCENT_START = 292,
|
||||
PERCENT_TOKEN_TABLE = 293,
|
||||
PERCENT_VERBOSE = 294,
|
||||
PERCENT_YACC = 295,
|
||||
BRACED_CODE = 296,
|
||||
BRACED_PREDICATE = 297,
|
||||
BRACKETED_ID = 298,
|
||||
CHAR = 299,
|
||||
EPILOGUE = 300,
|
||||
EQUAL = 301,
|
||||
ID = 302,
|
||||
ID_COLON = 303,
|
||||
PERCENT_PERCENT = 304,
|
||||
PIPE = 305,
|
||||
PROLOGUE = 306,
|
||||
SEMICOLON = 307,
|
||||
GT = 308,
|
||||
TAG = 309,
|
||||
TAG_ANY = 310,
|
||||
TAG_NONE = 311,
|
||||
LBRACE = 312,
|
||||
RBRACE = 313,
|
||||
INT = 314,
|
||||
PERCENT_PARAM = 315,
|
||||
PERCENT_UNION = 316,
|
||||
PERCENT_EMPTY = 317
|
||||
INT = 259,
|
||||
PERCENT_TOKEN = 260,
|
||||
PERCENT_NTERM = 261,
|
||||
PERCENT_TYPE = 262,
|
||||
PERCENT_DESTRUCTOR = 263,
|
||||
PERCENT_PRINTER = 264,
|
||||
PERCENT_LEFT = 265,
|
||||
PERCENT_RIGHT = 266,
|
||||
PERCENT_NONASSOC = 267,
|
||||
PERCENT_PRECEDENCE = 268,
|
||||
PERCENT_PREC = 269,
|
||||
PERCENT_DPREC = 270,
|
||||
PERCENT_MERGE = 271,
|
||||
PERCENT_CODE = 272,
|
||||
PERCENT_DEFAULT_PREC = 273,
|
||||
PERCENT_DEFINE = 274,
|
||||
PERCENT_DEFINES = 275,
|
||||
PERCENT_ERROR_VERBOSE = 276,
|
||||
PERCENT_EXPECT = 277,
|
||||
PERCENT_EXPECT_RR = 278,
|
||||
PERCENT_FLAG = 279,
|
||||
PERCENT_FILE_PREFIX = 280,
|
||||
PERCENT_GLR_PARSER = 281,
|
||||
PERCENT_INITIAL_ACTION = 282,
|
||||
PERCENT_LANGUAGE = 283,
|
||||
PERCENT_NAME_PREFIX = 284,
|
||||
PERCENT_NO_DEFAULT_PREC = 285,
|
||||
PERCENT_NO_LINES = 286,
|
||||
PERCENT_NONDETERMINISTIC_PARSER = 287,
|
||||
PERCENT_OUTPUT = 288,
|
||||
PERCENT_REQUIRE = 289,
|
||||
PERCENT_SKELETON = 290,
|
||||
PERCENT_START = 291,
|
||||
PERCENT_TOKEN_TABLE = 292,
|
||||
PERCENT_VERBOSE = 293,
|
||||
PERCENT_YACC = 294,
|
||||
BRACED_CODE = 295,
|
||||
BRACED_PREDICATE = 296,
|
||||
BRACKETED_ID = 297,
|
||||
CHAR = 298,
|
||||
EPILOGUE = 299,
|
||||
EQUAL = 300,
|
||||
ID = 301,
|
||||
ID_COLON = 302,
|
||||
PERCENT_PERCENT = 303,
|
||||
PIPE = 304,
|
||||
PROLOGUE = 305,
|
||||
SEMICOLON = 306,
|
||||
TAG = 307,
|
||||
TAG_ANY = 308,
|
||||
TAG_NONE = 309,
|
||||
PERCENT_PARAM = 310,
|
||||
PERCENT_UNION = 311
|
||||
};
|
||||
#endif
|
||||
/* Tokens. */
|
||||
#define GRAM_EOF 0
|
||||
#define STRING 258
|
||||
#define INT 259
|
||||
#define PERCENT_TOKEN 260
|
||||
#define PERCENT_NTERM 261
|
||||
#define PERCENT_TYPE 262
|
||||
#define PERCENT_DESTRUCTOR 263
|
||||
#define PERCENT_PRINTER 264
|
||||
#define PERCENT_LEFT 265
|
||||
#define PERCENT_RIGHT 266
|
||||
#define PERCENT_NONASSOC 267
|
||||
#define PERCENT_PRECEDENCE 268
|
||||
#define PERCENT_PREC 269
|
||||
#define PERCENT_DPREC 270
|
||||
#define PERCENT_MERGE 271
|
||||
#define PERCENT_CODE 272
|
||||
#define PERCENT_DEFAULT_PREC 273
|
||||
#define PERCENT_DEFINE 274
|
||||
#define PERCENT_DEFINES 275
|
||||
#define PERCENT_ERROR_VERBOSE 276
|
||||
#define PERCENT_EXPECT 277
|
||||
#define PERCENT_EXPECT_RR 278
|
||||
#define PERCENT_FLAG 279
|
||||
#define PERCENT_FILE_PREFIX 280
|
||||
#define PERCENT_GLR_PARSER 281
|
||||
#define PERCENT_INITIAL_ACTION 282
|
||||
#define PERCENT_LANGUAGE 283
|
||||
#define PERCENT_NAME_PREFIX 284
|
||||
#define PERCENT_NO_DEFAULT_PREC 285
|
||||
#define PERCENT_NO_LINES 286
|
||||
#define PERCENT_NONDETERMINISTIC_PARSER 287
|
||||
#define PERCENT_OUTPUT 288
|
||||
#define PERCENT_REQUIRE 289
|
||||
#define PERCENT_SKELETON 290
|
||||
#define PERCENT_START 291
|
||||
#define PERCENT_TOKEN_TABLE 292
|
||||
#define PERCENT_VERBOSE 293
|
||||
#define PERCENT_YACC 294
|
||||
#define BRACED_CODE 295
|
||||
#define BRACED_PREDICATE 296
|
||||
#define BRACKETED_ID 297
|
||||
#define CHAR 298
|
||||
#define EPILOGUE 299
|
||||
#define EQUAL 300
|
||||
#define ID 301
|
||||
#define ID_COLON 302
|
||||
#define PERCENT_PERCENT 303
|
||||
#define PIPE 304
|
||||
#define PROLOGUE 305
|
||||
#define SEMICOLON 306
|
||||
#define TAG 307
|
||||
#define TAG_ANY 308
|
||||
#define TAG_NONE 309
|
||||
#define PERCENT_PARAM 310
|
||||
#define PERCENT_UNION 311
|
||||
|
||||
/* Value type. */
|
||||
#if ! defined GRAM_STYPE && ! defined GRAM_STYPE_IS_DECLARED
|
||||
typedef union GRAM_STYPE GRAM_STYPE;
|
||||
union GRAM_STYPE
|
||||
{
|
||||
#line 187 "src/parse-gram.y" /* yacc.c:1909 */
|
||||
unsigned char character;
|
||||
#line 191 "src/parse-gram.y" /* yacc.c:1909 */
|
||||
char *code;
|
||||
#line 196 "src/parse-gram.y" /* yacc.c:1909 */
|
||||
uniqstr uniqstr;
|
||||
#line 204 "src/parse-gram.y" /* yacc.c:1909 */
|
||||
int integer;
|
||||
#line 208 "src/parse-gram.y" /* yacc.c:1909 */
|
||||
symbol *symbol;
|
||||
#line 213 "src/parse-gram.y" /* yacc.c:1909 */
|
||||
assoc assoc;
|
||||
#line 216 "src/parse-gram.y" /* yacc.c:1909 */
|
||||
symbol_list *list;
|
||||
#line 219 "src/parse-gram.y" /* yacc.c:1909 */
|
||||
named_ref *named_ref;
|
||||
#line 224 "src/parse-gram.y" /* yacc.c:1909 */
|
||||
prec_rel_comparator prec_rel_comparator;
|
||||
#line 253 "src/parse-gram.y" /* yacc.c:1909 */
|
||||
param_type param;
|
||||
#line 423 "src/parse-gram.y" /* yacc.c:1909 */
|
||||
#line 109 "src/parse-gram.y" /* yacc.c:1932 */
|
||||
|
||||
assoc assoc;
|
||||
char *code;
|
||||
char const *chars;
|
||||
int integer;
|
||||
named_ref *named_ref;
|
||||
symbol *symbol;
|
||||
symbol_list *list;
|
||||
uniqstr uniqstr;
|
||||
unsigned char character;
|
||||
|
||||
#line 247 "src/parse-gram.y" /* yacc.c:1932 */
|
||||
|
||||
param_type param;
|
||||
|
||||
#line 423 "src/parse-gram.y" /* yacc.c:1932 */
|
||||
code_props_type code_type;
|
||||
#line 725 "src/parse-gram.y" /* yacc.c:1909 */
|
||||
|
||||
struct
|
||||
{
|
||||
char const *chars;
|
||||
muscle_kind kind;
|
||||
} value;
|
||||
|
||||
#line 174 "src/parse-gram.h" /* yacc.c:1909 */
|
||||
#line 211 "src/parse-gram.h" /* yacc.c:1932 */
|
||||
};
|
||||
# define GRAM_STYPE_IS_TRIVIAL 1
|
||||
# define GRAM_STYPE_IS_DECLARED 1
|
||||
|
||||
+146
-263
@@ -1,4 +1,4 @@
|
||||
/* Bison Grammar Parser -*- C -*-
|
||||
%{/* Bison Grammar Parser -*- C -*-
|
||||
|
||||
Copyright (C) 2002-2013 Free Software Foundation, Inc.
|
||||
|
||||
@@ -17,35 +17,45 @@
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
%code requires
|
||||
{
|
||||
#include "symlist.h"
|
||||
#include "symtab.h"
|
||||
}
|
||||
|
||||
%code top
|
||||
{
|
||||
/* On column 0 to please syntax-check. */
|
||||
#include <config.h>
|
||||
}
|
||||
#include "system.h"
|
||||
|
||||
#include "c-ctype.h"
|
||||
#include "complain.h"
|
||||
#include "conflicts.h"
|
||||
#include "files.h"
|
||||
#include "getargs.h"
|
||||
#include "gram.h"
|
||||
#include "muscle-tab.h"
|
||||
#include "named-ref.h"
|
||||
#include "quotearg.h"
|
||||
#include "reader.h"
|
||||
#include "symlist.h"
|
||||
#include "symtab.h"
|
||||
#include "scan-gram.h"
|
||||
#include "scan-code.h"
|
||||
#include "xmemdup0.h"
|
||||
|
||||
#define YYLLOC_DEFAULT(Current, Rhs, N) (Current) = lloc_default (Rhs, N)
|
||||
static YYLTYPE lloc_default (YYLTYPE const *, int);
|
||||
|
||||
#define YY_LOCATION_PRINT(File, Loc) \
|
||||
location_print (File, Loc)
|
||||
|
||||
static void version_check (location const *loc, char const *version);
|
||||
|
||||
/* Request detailed syntax error messages, and pass them to GRAM_ERROR.
|
||||
FIXME: depends on the undocumented availability of YYLLOC. */
|
||||
#undef yyerror
|
||||
#define yyerror(Msg) \
|
||||
gram_error (&yylloc, Msg)
|
||||
static void gram_error (location const *, char const *);
|
||||
|
||||
static char const *char_name (char);
|
||||
%}
|
||||
|
||||
%code
|
||||
{
|
||||
#include "system.h"
|
||||
|
||||
#include "c-ctype.h"
|
||||
#include "complain.h"
|
||||
#include "conflicts.h"
|
||||
#include "files.h"
|
||||
#include "getargs.h"
|
||||
#include "gram.h"
|
||||
#include "named-ref.h"
|
||||
#include "quotearg.h"
|
||||
#include "reader.h"
|
||||
#include "scan-gram.h"
|
||||
#include "scan-code.h"
|
||||
#include "xmemdup0.h"
|
||||
|
||||
static int current_prec = 0;
|
||||
static location current_lhs_location;
|
||||
static named_ref *current_lhs_named_ref;
|
||||
@@ -56,37 +66,20 @@
|
||||
/** Set the new current left-hand side symbol, possibly common
|
||||
* to several right-hand side parts of rule.
|
||||
*/
|
||||
static void current_lhs (symbol *sym, location loc, named_ref *ref);
|
||||
|
||||
#define YYLLOC_DEFAULT(Current, Rhs, N) \
|
||||
(Current) = lloc_default (Rhs, N)
|
||||
static YYLTYPE lloc_default (YYLTYPE const *, int);
|
||||
|
||||
#define YY_LOCATION_PRINT(File, Loc) \
|
||||
location_print (Loc, File)
|
||||
|
||||
/* Strip initial '{' and final '}' (must be first and last characters).
|
||||
Return the result. */
|
||||
static char *strip_braces (char *code);
|
||||
|
||||
/* Convert CODE by calling code_props_plain_init if PLAIN, otherwise
|
||||
code_props_symbol_action_init. Call
|
||||
gram_scanner_last_string_free to release the latest string from
|
||||
the scanner (should be CODE). */
|
||||
static char const *translate_code (char *code, location loc, bool plain);
|
||||
|
||||
/* Convert CODE by calling code_props_plain_init after having
|
||||
stripped the first and last characters (expected to be '{', and
|
||||
'}'). Call gram_scanner_last_string_free to release the latest
|
||||
string from the scanner (should be CODE). */
|
||||
static char const *translate_code_braceless (char *code, location loc);
|
||||
|
||||
static void version_check (location const *loc, char const *version);
|
||||
|
||||
static void gram_error (location const *, char const *);
|
||||
|
||||
/* A string that describes a char (e.g., 'a' -> "'a'"). */
|
||||
static char const *char_name (char);
|
||||
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;
|
||||
}
|
||||
|
||||
#define YYTYPE_INT16 int_fast16_t
|
||||
#define YYTYPE_INT8 int_fast8_t
|
||||
@@ -94,8 +87,8 @@
|
||||
#define YYTYPE_UINT8 uint_fast8_t
|
||||
}
|
||||
|
||||
%define api.prefix {gram_}
|
||||
%define api.pure full
|
||||
%define api.prefix "gram_"
|
||||
%define api.pure
|
||||
%define locations
|
||||
%define parse.error verbose
|
||||
%define parse.lac full
|
||||
@@ -112,9 +105,23 @@
|
||||
boundary_set (&@$.end, current_file, 1, 1);
|
||||
}
|
||||
|
||||
%union
|
||||
{
|
||||
assoc assoc;
|
||||
char *code;
|
||||
char const *chars;
|
||||
int integer;
|
||||
named_ref *named_ref;
|
||||
symbol *symbol;
|
||||
symbol_list *list;
|
||||
uniqstr uniqstr;
|
||||
unsigned char character;
|
||||
};
|
||||
|
||||
/* Define the tokens together with their human representation. */
|
||||
%token GRAM_EOF 0 "end of file"
|
||||
%token STRING "string"
|
||||
%token INT "integer"
|
||||
|
||||
%token PERCENT_TOKEN "%token"
|
||||
%token PERCENT_NTERM "%nterm"
|
||||
@@ -130,8 +137,6 @@
|
||||
|
||||
%token PERCENT_PREC "%prec"
|
||||
%token PERCENT_DPREC "%dprec"
|
||||
%token PERCENT_GPREC "%gprec"
|
||||
%token PERCENT_PRECR "%precr"
|
||||
%token PERCENT_MERGE "%merge"
|
||||
|
||||
/*----------------------.
|
||||
@@ -177,23 +182,22 @@
|
||||
%token PIPE "|"
|
||||
%token PROLOGUE "%{...%}"
|
||||
%token SEMICOLON ";"
|
||||
%token GT ">"
|
||||
%token TAG "<tag>"
|
||||
%token TAG_ANY "<*>"
|
||||
%token TAG_NONE "<>"
|
||||
%token LBRACE "{"
|
||||
%token RBRACE "}"
|
||||
|
||||
%union {unsigned char character;}
|
||||
%type <character> CHAR
|
||||
%printer { fputs (char_name ($$), yyo); } CHAR
|
||||
|
||||
%union {char *code;};
|
||||
%type <code> "{...}" "%?{...}" "%{...%}" EPILOGUE STRING
|
||||
%printer { fputs (quotearg_style (c_quoting_style, $$), yyo); } STRING
|
||||
%printer { fprintf (yyo, "{\n%s\n}", $$); } <code>
|
||||
/* braceless is not to be used for rule or symbol actions, as it
|
||||
calls code_props_plain_init. */
|
||||
%type <chars> STRING "%{...%}" EPILOGUE braceless content.opt
|
||||
%type <code> "{...}" "%?{...}"
|
||||
%printer { fputs (quotearg_style (c_quoting_style, $$), yyo); }
|
||||
STRING
|
||||
%printer { fprintf (yyo, "{\n%s\n}", $$); }
|
||||
braceless content.opt "{...}" "%{...%}" EPILOGUE
|
||||
|
||||
%union {uniqstr uniqstr;}
|
||||
%type <uniqstr> BRACKETED_ID ID ID_COLON PERCENT_FLAG TAG tag variable
|
||||
%printer { fputs ($$, yyo); } <uniqstr>
|
||||
%printer { fprintf (yyo, "[%s]", $$); } BRACKETED_ID
|
||||
@@ -201,36 +205,24 @@
|
||||
%printer { fprintf (yyo, "%%%s", $$); } PERCENT_FLAG
|
||||
%printer { fprintf (yyo, "<%s>", $$); } TAG tag
|
||||
|
||||
%union {int integer;};
|
||||
%token <integer> INT "integer"
|
||||
%type <integer> INT
|
||||
%printer { fprintf (yyo, "%d", $$); } <integer>
|
||||
|
||||
%union {symbol *symbol;}
|
||||
%type <symbol> id id_colon string_as_id symbol symbol.prec
|
||||
%printer { fprintf (yyo, "%s", $$->tag); } <symbol>
|
||||
%printer { fprintf (yyo, "%s:", $$->tag); } id_colon
|
||||
|
||||
%union {assoc assoc;};
|
||||
%type <assoc> precedence_declarator
|
||||
|
||||
%union {symbol_list *list;}
|
||||
%type <list> symbols.1 symbols.prec generic_symlist generic_symlist_item
|
||||
|
||||
%union {named_ref *named_ref;}
|
||||
%type <named_ref> named_ref.opt
|
||||
|
||||
%type <uniqstr> prec_group_name.opt string_or_id
|
||||
|
||||
%union {prec_rel_comparator prec_rel_comparator;}
|
||||
%type <prec_rel_comparator> prec_rel_comparator
|
||||
|
||||
%type <list> precedence_relation_symbols precedence_symbol
|
||||
|
||||
/*---------.
|
||||
| %param. |
|
||||
`---------*/
|
||||
%code requires
|
||||
{
|
||||
# ifndef PARAM_TYPE
|
||||
# define PARAM_TYPE
|
||||
typedef enum
|
||||
{
|
||||
param_none = 0,
|
||||
@@ -238,6 +230,7 @@
|
||||
param_parse = 1 << 1,
|
||||
param_both = param_lex | param_parse
|
||||
} param_type;
|
||||
# endif
|
||||
};
|
||||
%code
|
||||
{
|
||||
@@ -250,17 +243,20 @@
|
||||
static void add_param (param_type type, char *decl, location loc);
|
||||
static param_type current_param = param_none;
|
||||
};
|
||||
%union {param_type param;}
|
||||
%union
|
||||
{
|
||||
param_type param;
|
||||
}
|
||||
%token <param> PERCENT_PARAM "%param";
|
||||
%printer
|
||||
{
|
||||
switch ($$)
|
||||
{
|
||||
#define CASE(In, Out) \
|
||||
case param_ ## In: fputs ("%" #Out, yyo); break
|
||||
CASE (lex, lex-param);
|
||||
CASE (parse, parse-param);
|
||||
CASE (both, param);
|
||||
case param_ ## In: fputs ("%" #Out, stderr); break
|
||||
CASE(lex, lex-param);
|
||||
CASE(parse, parse-param);
|
||||
CASE(both, param);
|
||||
#undef CASE
|
||||
case param_none: aver (false); break;
|
||||
}
|
||||
@@ -282,7 +278,7 @@ input:
|
||||
`------------------------------------*/
|
||||
|
||||
prologue_declarations:
|
||||
%empty
|
||||
/* Nothing */
|
||||
| prologue_declarations prologue_declaration
|
||||
;
|
||||
|
||||
@@ -290,17 +286,21 @@ prologue_declaration:
|
||||
grammar_declaration
|
||||
| "%{...%}"
|
||||
{
|
||||
code_props plain_code;
|
||||
code_props_plain_init (&plain_code, $1, @1);
|
||||
code_props_translate_code (&plain_code);
|
||||
gram_scanner_last_string_free ();
|
||||
muscle_code_grow (union_seen ? "post_prologue" : "pre_prologue",
|
||||
translate_code ($1, @1, true), @1);
|
||||
plain_code.code, @1);
|
||||
code_scanner_last_string_free ();
|
||||
}
|
||||
| "%<flag>"
|
||||
{
|
||||
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);
|
||||
}
|
||||
| "%defines" { defines_flag = true; }
|
||||
@@ -311,8 +311,7 @@ prologue_declaration:
|
||||
}
|
||||
| "%error-verbose"
|
||||
{
|
||||
muscle_percent_define_insert ("parse.error", @1, muscle_keyword,
|
||||
"verbose",
|
||||
muscle_percent_define_insert ("parse.error", @1, "verbose",
|
||||
MUSCLE_PERCENT_DEFINE_GRAMMAR_FILE);
|
||||
}
|
||||
| "%expect" INT { expected_sr_conflicts = $2; }
|
||||
@@ -325,7 +324,11 @@ prologue_declaration:
|
||||
}
|
||||
| "%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 ();
|
||||
}
|
||||
| "%language" STRING { language_argmatch ($2, grammar_prio, @1); }
|
||||
@@ -377,8 +380,6 @@ params:
|
||||
|
||||
grammar_declaration:
|
||||
precedence_declaration
|
||||
| precedence_group_declaration
|
||||
| precedence_relation_declaration
|
||||
| symbol_declaration
|
||||
| "%start" symbol
|
||||
{
|
||||
@@ -404,17 +405,16 @@ grammar_declaration:
|
||||
{
|
||||
default_prec = false;
|
||||
}
|
||||
| "%code" "{...}"
|
||||
| "%code" braceless
|
||||
{
|
||||
/* Do not invoke muscle_percent_code_grow here since it invokes
|
||||
muscle_user_name_list_grow. */
|
||||
muscle_code_grow ("percent_code()",
|
||||
translate_code_braceless ($2, @2), @2);
|
||||
muscle_code_grow ("percent_code()", $2, @2);
|
||||
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 ();
|
||||
}
|
||||
;
|
||||
@@ -434,15 +434,15 @@ code_props_type:
|
||||
%token PERCENT_UNION "%union";
|
||||
|
||||
union_name:
|
||||
%empty {}
|
||||
| ID { muscle_code_grow ("union_name", $1, @1); }
|
||||
/* Nothing. */ {}
|
||||
| ID { muscle_code_grow ("union_name", $1, @1); }
|
||||
;
|
||||
|
||||
grammar_declaration:
|
||||
"%union" union_name "{...}"
|
||||
"%union" union_name braceless
|
||||
{
|
||||
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 ();
|
||||
}
|
||||
;
|
||||
@@ -471,30 +471,6 @@ symbol_declaration:
|
||||
}
|
||||
;
|
||||
|
||||
/* A group of symbols for precedence declaration */
|
||||
precedence_group_declaration:
|
||||
"%gprec" prec_group_name.opt
|
||||
{
|
||||
set_current_group ($2, &@2);
|
||||
}
|
||||
"{" precedence_declarations "}"
|
||||
{
|
||||
set_current_group (DEFAULT_GROUP_NAME, NULL);
|
||||
}
|
||||
;
|
||||
|
||||
/* Name for the precedence group. If none is present a new unique one is
|
||||
generated. */
|
||||
prec_group_name.opt:
|
||||
%empty { $$ = new_anonymous_group_name (); }
|
||||
| variable /* Just a string, maybe there's a better way? */
|
||||
;
|
||||
|
||||
precedence_declarations:
|
||||
precedence_declaration
|
||||
| precedence_declarations precedence_declaration
|
||||
;
|
||||
|
||||
precedence_declaration:
|
||||
precedence_declarator tag.opt symbols.prec
|
||||
{
|
||||
@@ -518,48 +494,8 @@ precedence_declarator:
|
||||
;
|
||||
|
||||
tag.opt:
|
||||
%empty { current_type = NULL; }
|
||||
| TAG { current_type = $1; tag_seen = true; }
|
||||
;
|
||||
|
||||
/* Declaration of a precedence relation between two (lists of) tokens */
|
||||
precedence_relation_declaration:
|
||||
"%precr" precedence_relation_symbols
|
||||
{ prec_braces = default_braces_state; }
|
||||
prec_rel_comparator
|
||||
precedence_relation_symbols
|
||||
{ declare_precedence_relation ($2, $5, $4, @4); }
|
||||
;
|
||||
|
||||
precedence_relation_symbols:
|
||||
precedence_symbol { $$ = $1; }
|
||||
| precedence_relation_symbols precedence_symbol
|
||||
{ $$ = symbol_list_append ($1, $2); }
|
||||
;
|
||||
|
||||
precedence_symbol:
|
||||
string_or_id
|
||||
{
|
||||
if (is_prec_group ($1))
|
||||
$$ = expand_symbol_group (symgroup_from_uniqstr($1, &@1), @1);
|
||||
else
|
||||
$$ = symbol_list_sym_new (symbol_from_uniqstr ($1, @1), @1);
|
||||
}
|
||||
| CHAR
|
||||
{
|
||||
$$ = symbol_list_sym_new (symbol_from_uniqstr (uniqstr_new (char_name ($1)), @1), @1);
|
||||
}
|
||||
;
|
||||
|
||||
string_or_id:
|
||||
STRING { $$ = uniqstr_new (quotearg_style (c_quoting_style, $1)); }
|
||||
| ID { $$ = $1; }
|
||||
;
|
||||
|
||||
prec_rel_comparator:
|
||||
">" { $$ = prec_superior; }
|
||||
| "=" { $$ = prec_equal; }
|
||||
| ">" ">" { $$ = prec_superior_strict; }
|
||||
/* Nothing. */ { current_type = NULL; }
|
||||
| TAG { current_type = $1; tag_seen = true; }
|
||||
;
|
||||
|
||||
/* Just like symbols.1 but accept INT for the sake of POSIX. */
|
||||
@@ -571,17 +507,8 @@ symbols.prec:
|
||||
;
|
||||
|
||||
symbol.prec:
|
||||
symbol
|
||||
{
|
||||
$$ = $1;
|
||||
symbol_class_set ($1, token_sym, @1, false);
|
||||
}
|
||||
| symbol INT
|
||||
{
|
||||
$$ = $1;
|
||||
symbol_user_token_number_set ($1, $2, @2);
|
||||
symbol_class_set ($1, token_sym, @1, false);
|
||||
}
|
||||
symbol { $$ = $1; }
|
||||
| symbol INT { $$ = $1; symbol_user_token_number_set ($1, $2, @2); }
|
||||
;
|
||||
|
||||
/* One or more symbols to be %typed. */
|
||||
@@ -682,9 +609,8 @@ rhses.1:
|
||||
| rhses.1 ";"
|
||||
;
|
||||
|
||||
%token PERCENT_EMPTY "%empty";
|
||||
rhs:
|
||||
%empty
|
||||
/* Nothing. */
|
||||
{ grammar_current_rule_begin (current_lhs_symbol, current_lhs_location,
|
||||
current_lhs_named_ref); }
|
||||
| rhs symbol named_ref.opt
|
||||
@@ -693,8 +619,6 @@ rhs:
|
||||
{ grammar_current_rule_action_append ($2, @2, $3, false); }
|
||||
| rhs "%?{...}"
|
||||
{ grammar_current_rule_action_append ($2, @2, NULL, true); }
|
||||
| rhs "%empty"
|
||||
{ grammar_current_rule_empty_set (@2); }
|
||||
| rhs "%prec" symbol
|
||||
{ grammar_current_rule_prec_set ($3, @3); }
|
||||
| rhs "%dprec" INT
|
||||
@@ -704,47 +628,44 @@ rhs:
|
||||
;
|
||||
|
||||
named_ref.opt:
|
||||
%empty { $$ = 0; }
|
||||
| BRACKETED_ID { $$ = named_ref_new ($1, @1); }
|
||||
/* Nothing. */ { $$ = 0; }
|
||||
|
|
||||
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.
|
||||
For example, M4 fails for '%define "[" "value"'. */
|
||||
For example, M4 fails for `%define "[" "value"'. */
|
||||
variable:
|
||||
ID
|
||||
| STRING { $$ = uniqstr_new ($1); }
|
||||
;
|
||||
|
||||
/* Some content or empty by default. */
|
||||
%code requires {#include "muscle-tab.h"};
|
||||
%union
|
||||
{
|
||||
struct
|
||||
{
|
||||
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>;
|
||||
content.opt:
|
||||
/* Nothing. */ { $$ = ""; }
|
||||
| ID { $$ = $1; }
|
||||
| STRING
|
||||
;
|
||||
|
||||
value:
|
||||
%empty { $$.kind = muscle_keyword; $$.chars = ""; }
|
||||
| ID { $$.kind = muscle_keyword; $$.chars = $1; }
|
||||
| STRING { $$.kind = muscle_string; $$.chars = $1; }
|
||||
| "{...}" { $$.kind = muscle_code; $$.chars = strip_braces ($1); }
|
||||
|
||||
/*------------.
|
||||
| braceless. |
|
||||
`------------*/
|
||||
|
||||
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;
|
||||
}
|
||||
;
|
||||
|
||||
|
||||
@@ -786,10 +707,14 @@ string_as_id:
|
||||
;
|
||||
|
||||
epilogue.opt:
|
||||
%empty
|
||||
/* Nothing. */
|
||||
| "%%" 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 ();
|
||||
}
|
||||
;
|
||||
@@ -825,33 +750,6 @@ lloc_default (YYLTYPE const *rhs, int n)
|
||||
return loc;
|
||||
}
|
||||
|
||||
static
|
||||
char *strip_braces (char *code)
|
||||
{
|
||||
code[strlen (code) - 1] = 0;
|
||||
return code + 1;
|
||||
}
|
||||
|
||||
static
|
||||
char const *
|
||||
translate_code (char *code, location loc, bool plain)
|
||||
{
|
||||
code_props plain_code;
|
||||
if (plain)
|
||||
code_props_plain_init (&plain_code, code, loc);
|
||||
else
|
||||
code_props_symbol_action_init (&plain_code, code, loc);
|
||||
code_props_translate_code (&plain_code);
|
||||
gram_scanner_last_string_free ();
|
||||
return plain_code.code;
|
||||
}
|
||||
|
||||
static
|
||||
char const *
|
||||
translate_code_braceless (char *code, location loc)
|
||||
{
|
||||
return translate_code (strip_braces (code), loc, true);
|
||||
}
|
||||
|
||||
static void
|
||||
add_param (param_type type, char *decl, location loc)
|
||||
@@ -934,18 +832,3 @@ char_name (char c)
|
||||
return quotearg_style (escape_quoting_style, buf);
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
current_lhs (symbol *sym, location loc, named_ref *ref)
|
||||
{
|
||||
current_lhs_symbol = sym;
|
||||
current_lhs_location = loc;
|
||||
/* In order to simplify memory management, named references for lhs
|
||||
are always assigned by deep copy into the current symbol_list
|
||||
node. This is because a single named-ref in the grammar may
|
||||
result in several uses when the user factors lhs between several
|
||||
rules using "|". Therefore free the parser's original copy. */
|
||||
free (current_lhs_named_ref);
|
||||
current_lhs_named_ref = ref;
|
||||
}
|
||||
|
||||
+11
-18
@@ -45,8 +45,7 @@ struct escape_buf
|
||||
char *ptr;
|
||||
size_t size;
|
||||
};
|
||||
enum { num_escape_bufs = 3 };
|
||||
static struct escape_buf escape_bufs[num_escape_bufs];
|
||||
static struct escape_buf escape_bufs[3];
|
||||
|
||||
|
||||
/*--------------------------------.
|
||||
@@ -210,7 +209,7 @@ print_errs (FILE *out, int level, state *s)
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------.
|
||||
| Report a reduction of RULE on LOOKAHEAD_TOKEN (which can be 'default'). |
|
||||
| Report a reduction of RULE on LOOKAHEAD_TOKEN (which can be `default'). |
|
||||
| If not ENABLED, the rule is masked by a shift or a reduce (S/R and |
|
||||
| R/R conflicts). |
|
||||
`-------------------------------------------------------------------------*/
|
||||
@@ -260,7 +259,7 @@ print_reductions (FILE *out, int level, state *s)
|
||||
bitset_set (no_reduce_set, TRANSITION_SYMBOL (trans, i));
|
||||
for (i = 0; i < s->errs->num; ++i)
|
||||
if (s->errs->symbols[i])
|
||||
bitset_set (no_reduce_set, s->errs->symbols[i]->content->number);
|
||||
bitset_set (no_reduce_set, s->errs->symbols[i]->number);
|
||||
|
||||
if (default_reduction)
|
||||
report = true;
|
||||
@@ -388,12 +387,11 @@ print_grammar (FILE *out, int level)
|
||||
/* Terminals */
|
||||
xml_puts (out, level + 1, "<terminals>");
|
||||
for (i = 0; i < max_user_token_number + 1; i++)
|
||||
if (token_translations[i] != undeftoken->content->number)
|
||||
if (token_translations[i] != undeftoken->number)
|
||||
{
|
||||
char const *tag = symbols[token_translations[i]]->tag;
|
||||
int precedence = symbols[token_translations[i]]->content->prec;
|
||||
assoc associativity = symbols[token_translations[i]]->content->prec_node
|
||||
->assoc;
|
||||
int precedence = symbols[token_translations[i]]->prec;
|
||||
assoc associativity = symbols[token_translations[i]]->assoc;
|
||||
xml_indent (out, level + 2);
|
||||
fprintf (out,
|
||||
"<terminal symbol-number=\"%d\" token-number=\"%d\""
|
||||
@@ -498,6 +496,7 @@ xml_escape (char const *str)
|
||||
void
|
||||
print_xml (void)
|
||||
{
|
||||
state_number i;
|
||||
int level = 0;
|
||||
|
||||
FILE *out = xfopen (spec_xml_file, "w");
|
||||
@@ -523,11 +522,8 @@ print_xml (void)
|
||||
/* print automaton */
|
||||
fputc ('\n', out);
|
||||
xml_puts (out, level + 1, "<automaton>");
|
||||
{
|
||||
state_number i;
|
||||
for (i = 0; i < nstates; 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>");
|
||||
|
||||
bitset_free (no_reduce_set);
|
||||
@@ -535,11 +531,8 @@ print_xml (void)
|
||||
|
||||
xml_puts (out, 0, "</bison-xml-report>");
|
||||
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < num_escape_bufs; ++i)
|
||||
free (escape_bufs[i].ptr);
|
||||
}
|
||||
free (escape_bufs[0].ptr);
|
||||
free (escape_bufs[1].ptr);
|
||||
|
||||
xfclose (out);
|
||||
}
|
||||
|
||||
+6
-7
@@ -72,7 +72,7 @@ print_core (FILE *out, state *s)
|
||||
size_t i;
|
||||
item_number *sitems = s->items;
|
||||
size_t snritems = s->nitems;
|
||||
sym_content *previous_lhs = NULL;
|
||||
symbol *previous_lhs = NULL;
|
||||
|
||||
/* Output all the items of a state, not only its kernel. */
|
||||
if (report_flag & report_itemsets)
|
||||
@@ -206,7 +206,7 @@ print_errs (FILE *out, state *s)
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------.
|
||||
| Report a reduction of RULE on LOOKAHEAD_TOKEN (which can be 'default'). |
|
||||
| Report a reduction of RULE on LOOKAHEAD_TOKEN (which can be `default'). |
|
||||
| If not ENABLED, the rule is masked by a shift or a reduce (S/R and |
|
||||
| R/R conflicts). |
|
||||
`-------------------------------------------------------------------------*/
|
||||
@@ -223,8 +223,7 @@ print_reduction (FILE *out, size_t width,
|
||||
if (!enabled)
|
||||
fputc ('[', out);
|
||||
if (r->number)
|
||||
fprintf (out, _("reduce using rule %d (%s)"), r->number,
|
||||
r->lhs->symbol->tag);
|
||||
fprintf (out, _("reduce using rule %d (%s)"), r->number, r->lhs->tag);
|
||||
else
|
||||
fprintf (out, _("accept"));
|
||||
if (!enabled)
|
||||
@@ -258,7 +257,7 @@ print_reductions (FILE *out, state *s)
|
||||
bitset_set (no_reduce_set, TRANSITION_SYMBOL (trans, i));
|
||||
for (i = 0; i < s->errs->num; ++i)
|
||||
if (s->errs->symbols[i])
|
||||
bitset_set (no_reduce_set, s->errs->symbols[i]->content->number);
|
||||
bitset_set (no_reduce_set, s->errs->symbols[i]->number);
|
||||
|
||||
/* Compute the width of the lookahead token column. */
|
||||
if (default_reduction)
|
||||
@@ -409,7 +408,7 @@ print_grammar (FILE *out)
|
||||
/* TERMINAL (type #) : rule #s terminal is on RHS */
|
||||
fprintf (out, "%s\n\n", _("Terminals, with rules where they appear"));
|
||||
for (i = 0; i < max_user_token_number + 1; i++)
|
||||
if (token_translations[i] != undeftoken->content->number)
|
||||
if (token_translations[i] != undeftoken->number)
|
||||
{
|
||||
const char *tag = symbols[token_translations[i]]->tag;
|
||||
rule_number r;
|
||||
@@ -515,7 +514,7 @@ print_results (void)
|
||||
print_grammar (out);
|
||||
|
||||
/* If the whole state item sets, not only the kernels, are wanted,
|
||||
'closure' will be run, which needs memory allocation/deallocation. */
|
||||
`closure' will be run, which needs memory allocation/deallocation. */
|
||||
if (report_flag & report_itemsets)
|
||||
new_closure (nritems);
|
||||
/* Storage for print_reductions. */
|
||||
|
||||
+4
-5
@@ -46,7 +46,7 @@ static void
|
||||
print_core (struct obstack *oout, state *s)
|
||||
{
|
||||
item_number const *sitems = s->items;
|
||||
sym_content *previous_lhs = NULL;
|
||||
symbol *previous_lhs = NULL;
|
||||
size_t i;
|
||||
size_t snritems = s->nitems;
|
||||
|
||||
@@ -72,12 +72,11 @@ print_core (struct obstack *oout, state *s)
|
||||
r = &rules[item_number_as_rule_number (*sp)];
|
||||
|
||||
obstack_printf (oout, "%3d ", r->number);
|
||||
if (previous_lhs && UNIQSTR_EQ (previous_lhs->symbol->tag,
|
||||
r->lhs->symbol->tag))
|
||||
if (previous_lhs && UNIQSTR_EQ (previous_lhs->tag, r->lhs->tag))
|
||||
obstack_printf (oout, "%*s| ",
|
||||
(int) strlen (previous_lhs->symbol->tag), "");
|
||||
(int) strlen (previous_lhs->tag), "");
|
||||
else
|
||||
obstack_printf (oout, "%s: ", escape (r->lhs->symbol->tag));
|
||||
obstack_printf (oout, "%s: ", escape (r->lhs->tag));
|
||||
previous_lhs = r->lhs;
|
||||
|
||||
for (sp = r->rhs; sp < sp1; sp++)
|
||||
|
||||
+66
-106
@@ -240,13 +240,13 @@ grammar_current_rule_begin (symbol *lhs, location loc,
|
||||
current_rule = grammar_end;
|
||||
|
||||
/* Mark the rule's lhs as a nonterminal if not already so. */
|
||||
if (lhs->content->class == unknown_sym)
|
||||
if (lhs->class == unknown_sym)
|
||||
{
|
||||
lhs->content->class = nterm_sym;
|
||||
lhs->content->number = nvars;
|
||||
lhs->class = nterm_sym;
|
||||
lhs->number = nvars;
|
||||
++nvars;
|
||||
}
|
||||
else if (lhs->content->class == token_sym)
|
||||
else if (lhs->class == token_sym)
|
||||
complain (&loc, complaint, _("rule given for %s, which is a token"),
|
||||
lhs->tag);
|
||||
}
|
||||
@@ -267,9 +267,9 @@ symbol_should_be_used (symbol_list const *s, bool *midrule_warning)
|
||||
return true;
|
||||
if ((s->midrule && s->midrule->action_props.is_value_used)
|
||||
|| (s->midrule_parent_rule
|
||||
&& (symbol_list_n_get (s->midrule_parent_rule,
|
||||
s->midrule_parent_rhs_index)
|
||||
->action_props.is_value_used)))
|
||||
&& symbol_list_n_get (s->midrule_parent_rule,
|
||||
s->midrule_parent_rhs_index)
|
||||
->action_props.is_value_used))
|
||||
{
|
||||
*midrule_warning = true;
|
||||
return true;
|
||||
@@ -292,15 +292,15 @@ grammar_rule_check (const symbol_list *r)
|
||||
|
||||
Don't worry about the default action if $$ is untyped, since $$'s
|
||||
value can't be used. */
|
||||
if (!r->action_props.code && r->content.sym->content->type_name)
|
||||
if (!r->action_props.code && r->content.sym->type_name)
|
||||
{
|
||||
symbol *first_rhs = r->next->content.sym;
|
||||
/* If $$ is being set in default way, report if any type mismatch. */
|
||||
if (first_rhs)
|
||||
{
|
||||
char const *lhs_type = r->content.sym->content->type_name;
|
||||
char const *lhs_type = r->content.sym->type_name;
|
||||
const char *rhs_type =
|
||||
first_rhs->content->type_name ? first_rhs->content->type_name : "";
|
||||
first_rhs->type_name ? first_rhs->type_name : "";
|
||||
if (!UNIQSTR_EQ (lhs_type, rhs_type))
|
||||
complain (&r->location, Wother,
|
||||
_("type clash on default action: <%s> != <%s>"),
|
||||
@@ -321,7 +321,7 @@ grammar_rule_check (const symbol_list *r)
|
||||
bool midrule_warning = false;
|
||||
if (!l->action_props.is_value_used
|
||||
&& symbol_should_be_used (l, &midrule_warning)
|
||||
/* The default action, $$ = $1, 'uses' both. */
|
||||
/* The default action, $$ = $1, `uses' both. */
|
||||
&& (r->action_props.code || (n != 0 && n != 1)))
|
||||
{
|
||||
warnings warn_flag = midrule_warning ? Wmidrule_values : Wother;
|
||||
@@ -333,25 +333,12 @@ grammar_rule_check (const symbol_list *r)
|
||||
}
|
||||
}
|
||||
|
||||
/* Check that %empty => empty rule. */
|
||||
if (r->percent_empty_loc.start.file
|
||||
&& r->next && r->next->content.sym)
|
||||
complain (&r->percent_empty_loc, complaint,
|
||||
_("%%empty on non-empty rule"));
|
||||
|
||||
/* Check that empty rule => %empty. */
|
||||
if (!(r->next && r->next->content.sym)
|
||||
&& !r->midrule_parent_rule
|
||||
&& !r->percent_empty_loc.start.file)
|
||||
complain (&r->location, Wempty_rule, _("empty rule without %%empty"));
|
||||
|
||||
/* See comments in grammar_current_rule_prec_set for how POSIX
|
||||
mandates this complaint. It's only for identifiers, so skip
|
||||
it for char literals and strings, which are always tokens. */
|
||||
if (r->ruleprec
|
||||
&& r->ruleprec->tag[0] != '\'' && r->ruleprec->tag[0] != '"'
|
||||
&& r->ruleprec->content->status != declared
|
||||
&& !r->ruleprec->content->prec)
|
||||
&& r->ruleprec->status != declared && !r->ruleprec->prec)
|
||||
complain (&r->location, Wother,
|
||||
_("token for %%prec is not defined: %s"), r->ruleprec->tag);
|
||||
}
|
||||
@@ -443,26 +430,8 @@ grammar_current_rule_prec_set (symbol *precsym, location loc)
|
||||
token. */
|
||||
symbol_class_set (precsym, token_sym, loc, false);
|
||||
if (current_rule->ruleprec)
|
||||
duplicate_directive ("%prec",
|
||||
current_rule->ruleprec->location, loc);
|
||||
else
|
||||
current_rule->ruleprec = precsym;
|
||||
}
|
||||
|
||||
/* Set %empty for the current rule. */
|
||||
|
||||
void
|
||||
grammar_current_rule_empty_set (location loc)
|
||||
{
|
||||
/* If %empty is used and -Wno-empty-rule is not, then enable
|
||||
-Wempty-rule. */
|
||||
if (warning_is_unset (Wempty_rule))
|
||||
warning_argmatch ("empty-rule", 0, 0);
|
||||
if (current_rule->percent_empty_loc.start.file)
|
||||
duplicate_directive ("%empty",
|
||||
current_rule->percent_empty_loc, loc);
|
||||
else
|
||||
current_rule->percent_empty_loc = loc;
|
||||
complain (&loc, complaint, _("only one %s allowed per rule"), "%prec");
|
||||
current_rule->ruleprec = precsym;
|
||||
}
|
||||
|
||||
/* Attach dynamic precedence DPREC to the current rule. */
|
||||
@@ -477,13 +446,8 @@ grammar_current_rule_dprec_set (int dprec, location loc)
|
||||
complain (&loc, complaint, _("%s must be followed by positive number"),
|
||||
"%dprec");
|
||||
else if (current_rule->dprec != 0)
|
||||
duplicate_directive ("%dprec",
|
||||
current_rule->dprec_location, loc);
|
||||
else
|
||||
{
|
||||
current_rule->dprec = dprec;
|
||||
current_rule->dprec_location = loc;
|
||||
}
|
||||
complain (&loc, complaint, _("only one %s allowed per rule"), "%dprec");
|
||||
current_rule->dprec = dprec;
|
||||
}
|
||||
|
||||
/* Attach a merge function NAME with argument type TYPE to current
|
||||
@@ -496,13 +460,9 @@ grammar_current_rule_merge_set (uniqstr name, location loc)
|
||||
complain (&loc, Wother, _("%s affects only GLR parsers"),
|
||||
"%merge");
|
||||
if (current_rule->merger != 0)
|
||||
duplicate_directive ("%merge",
|
||||
current_rule->merger_declaration_location, loc);
|
||||
else
|
||||
{
|
||||
current_rule->merger = get_merge_function (name);
|
||||
current_rule->merger_declaration_location = loc;
|
||||
}
|
||||
complain (&loc, complaint, _("only one %s allowed per rule"), "%merge");
|
||||
current_rule->merger = get_merge_function (name);
|
||||
current_rule->merger_declaration_location = loc;
|
||||
}
|
||||
|
||||
/* Attach SYM to the current rule. If needed, move the previous
|
||||
@@ -517,9 +477,9 @@ grammar_current_rule_symbol_append (symbol *sym, location loc,
|
||||
grammar_midrule_action ();
|
||||
p = grammar_symbol_append (sym, loc);
|
||||
if (name)
|
||||
assign_named_ref (p, name);
|
||||
if (sym->content->status == undeclared || sym->content->status == used)
|
||||
sym->content->status = needed;
|
||||
assign_named_ref(p, name);
|
||||
if (sym->status == undeclared || sym->status == used)
|
||||
sym->status = needed;
|
||||
}
|
||||
|
||||
/* Attach an ACTION to the current rule. */
|
||||
@@ -547,7 +507,7 @@ packgram (void)
|
||||
{
|
||||
unsigned int itemno = 0;
|
||||
rule_number ruleno = 0;
|
||||
symbol_list *p;
|
||||
symbol_list *p = grammar;
|
||||
|
||||
ritem = xnmalloc (nritems + 1, sizeof *ritem);
|
||||
|
||||
@@ -556,14 +516,15 @@ packgram (void)
|
||||
|
||||
rules = xnmalloc (nrules, sizeof *rules);
|
||||
|
||||
for (p = grammar; p; p = p->next)
|
||||
while (p)
|
||||
{
|
||||
int rule_length = 0;
|
||||
symbol *ruleprec = p->ruleprec;
|
||||
record_merge_function_type (p->merger, p->content.sym->content->type_name,
|
||||
record_merge_function_type (p->merger, p->content.sym->type_name,
|
||||
p->merger_declaration_location);
|
||||
rules[ruleno].user_number = ruleno;
|
||||
rules[ruleno].number = ruleno;
|
||||
rules[ruleno].lhs = p->content.sym->content;
|
||||
rules[ruleno].lhs = p->content.sym;
|
||||
rules[ruleno].rhs = ritem + itemno;
|
||||
rules[ruleno].prec = NULL;
|
||||
rules[ruleno].dprec = p->dprec;
|
||||
@@ -575,14 +536,14 @@ packgram (void)
|
||||
rules[ruleno].action_location = p->action_props.location;
|
||||
rules[ruleno].is_predicate = p->action_props.is_predicate;
|
||||
|
||||
/* If the midrule's $$ is set or its $n is used, remove the '$' from the
|
||||
/* If the midrule's $$ is set or its $n is used, remove the `$' from the
|
||||
symbol name so that it's a user-defined symbol so that the default
|
||||
%destructor and %printer apply. */
|
||||
if (p->midrule_parent_rule
|
||||
&& (p->action_props.is_value_used
|
||||
|| (symbol_list_n_get (p->midrule_parent_rule,
|
||||
p->midrule_parent_rhs_index)
|
||||
->action_props.is_value_used)))
|
||||
|| symbol_list_n_get (p->midrule_parent_rule,
|
||||
p->midrule_parent_rhs_index)
|
||||
->action_props.is_value_used))
|
||||
p->content.sym->tag += 1;
|
||||
|
||||
/* Don't check the generated rule 0. It has no action, so some rhs
|
||||
@@ -591,40 +552,40 @@ packgram (void)
|
||||
if (p != grammar)
|
||||
grammar_rule_check (p);
|
||||
|
||||
{
|
||||
size_t rule_length = 0;
|
||||
for (p = p->next; p->content.sym; p = p->next)
|
||||
{
|
||||
++rule_length;
|
||||
for (p = p->next; p && p->content.sym; p = p->next)
|
||||
{
|
||||
++rule_length;
|
||||
|
||||
/* Don't allow rule_length == INT_MAX, since that might
|
||||
cause confusion with strtol if INT_MAX == LONG_MAX. */
|
||||
if (rule_length == INT_MAX)
|
||||
complain (&rules[ruleno].location, fatal, _("rule is too long"));
|
||||
/* Don't allow rule_length == INT_MAX, since that might
|
||||
cause confusion with strtol if INT_MAX == LONG_MAX. */
|
||||
if (rule_length == INT_MAX)
|
||||
complain (&rules[ruleno].location, fatal, _("rule is too long"));
|
||||
|
||||
/* item_number = symbol_number.
|
||||
But the former needs to contain more: negative rule numbers. */
|
||||
ritem[itemno++] =
|
||||
symbol_number_as_item_number (p->content.sym->content->number);
|
||||
/* A rule gets by default the precedence and associativity
|
||||
of its last token. */
|
||||
if (p->content.sym->content->class == token_sym && default_prec)
|
||||
rules[ruleno].prec = p->content.sym->content;
|
||||
}
|
||||
}
|
||||
/* item_number = symbol_number.
|
||||
But the former needs to contain more: negative rule numbers. */
|
||||
ritem[itemno++] =
|
||||
symbol_number_as_item_number (p->content.sym->number);
|
||||
/* A rule gets by default the precedence and associativity
|
||||
of its last token. */
|
||||
if (p->content.sym->class == token_sym && default_prec)
|
||||
rules[ruleno].prec = p->content.sym;
|
||||
}
|
||||
|
||||
/* If this rule has a %prec,
|
||||
the specified symbol's precedence replaces the default. */
|
||||
if (ruleprec)
|
||||
{
|
||||
rules[ruleno].precsym = ruleprec->content;
|
||||
rules[ruleno].prec = ruleprec->content;
|
||||
rules[ruleno].precsym = ruleprec;
|
||||
rules[ruleno].prec = ruleprec;
|
||||
}
|
||||
/* An item ends by the rule number (negated). */
|
||||
ritem[itemno++] = rule_number_as_item_number (ruleno);
|
||||
aver (itemno < ITEM_NUMBER_MAX);
|
||||
++ruleno;
|
||||
aver (ruleno < RULE_NUMBER_MAX);
|
||||
|
||||
if (p)
|
||||
p = p->next;
|
||||
}
|
||||
|
||||
aver (itemno == nritems);
|
||||
@@ -648,19 +609,19 @@ reader (void)
|
||||
|
||||
/* Construct the accept symbol. */
|
||||
accept = symbol_get ("$accept", empty_location);
|
||||
accept->content->class = nterm_sym;
|
||||
accept->content->number = nvars++;
|
||||
accept->class = nterm_sym;
|
||||
accept->number = nvars++;
|
||||
|
||||
/* Construct the error token */
|
||||
errtoken = symbol_get ("error", empty_location);
|
||||
errtoken->content->class = token_sym;
|
||||
errtoken->content->number = ntokens++;
|
||||
errtoken->class = token_sym;
|
||||
errtoken->number = ntokens++;
|
||||
|
||||
/* Construct a token that represents all undefined literal tokens.
|
||||
It is always token number 2. */
|
||||
undeftoken = symbol_get ("$undefined", empty_location);
|
||||
undeftoken->content->class = token_sym;
|
||||
undeftoken->content->number = ntokens++;
|
||||
undeftoken->class = token_sym;
|
||||
undeftoken->number = ntokens++;
|
||||
|
||||
gram_in = xfopen (grammar_file, "r");
|
||||
|
||||
@@ -722,10 +683,10 @@ check_and_convert_grammar (void)
|
||||
if (!endtoken)
|
||||
{
|
||||
endtoken = symbol_get ("$end", empty_location);
|
||||
endtoken->content->class = token_sym;
|
||||
endtoken->content->number = 0;
|
||||
endtoken->class = token_sym;
|
||||
endtoken->number = 0;
|
||||
/* Value specified by POSIX. */
|
||||
endtoken->content->user_token_number = 0;
|
||||
endtoken->user_token_number = 0;
|
||||
}
|
||||
|
||||
/* Report any undefined symbols and consider them nonterminals. */
|
||||
@@ -752,7 +713,7 @@ check_and_convert_grammar (void)
|
||||
/* Insert the initial rule, whose line is that of the first rule
|
||||
(not that of the start symbol):
|
||||
|
||||
$accept: %start $end. */
|
||||
accept: %start EOF. */
|
||||
{
|
||||
symbol_list *p = symbol_list_sym_new (accept, empty_location);
|
||||
p->location = grammar->location;
|
||||
@@ -765,8 +726,7 @@ check_and_convert_grammar (void)
|
||||
grammar = p;
|
||||
}
|
||||
|
||||
aver (nsyms <= SYMBOL_NUMBER_MAXIMUM);
|
||||
aver (nsyms == ntokens + nvars);
|
||||
aver (nsyms <= SYMBOL_NUMBER_MAXIMUM && nsyms == ntokens + nvars);
|
||||
|
||||
/* Assign the symbols their symbol numbers. Write #defines for the
|
||||
token symbols into FDEFINES if requested. */
|
||||
@@ -777,11 +737,11 @@ check_and_convert_grammar (void)
|
||||
action type checking.
|
||||
|
||||
Before invoking grammar_rule_check (in packgram below) on any rule, make
|
||||
sure all actions have already been scanned in order to set 'used' flags.
|
||||
sure all actions have already been scanned in order to set `used' flags.
|
||||
Otherwise, checking that a midrule's $$ should be set will not always work
|
||||
properly because the check must forward-reference the midrule's parent
|
||||
rule. For the same reason, all the 'used' flags must be set before
|
||||
checking whether to remove '$' from any midrule symbol name (also in
|
||||
rule. For the same reason, all the `used' flags must be set before
|
||||
checking whether to remove `$' from any midrule symbol name (also in
|
||||
packgram). */
|
||||
{
|
||||
symbol_list *sym;
|
||||
|
||||
@@ -47,8 +47,6 @@ void grammar_current_rule_begin (symbol *lhs, location loc,
|
||||
named_ref *lhs_named_ref);
|
||||
void grammar_current_rule_end (location loc);
|
||||
void grammar_midrule_action (void);
|
||||
/* Apply %empty to the current rule. */
|
||||
void grammar_current_rule_empty_set (location loc);
|
||||
void grammar_current_rule_prec_set (symbol *precsym, location loc);
|
||||
void grammar_current_rule_dprec_set (int dprec, location loc);
|
||||
void grammar_current_rule_merge_set (uniqstr name, location loc);
|
||||
|
||||
+10
-10
@@ -49,7 +49,7 @@ static bitset P;
|
||||
static bitset V;
|
||||
|
||||
/* Set of symbols used to define rule precedence (so they are
|
||||
'useless', but no warning should be issued). */
|
||||
`useless', but no warning should be issued). */
|
||||
static bitset V1;
|
||||
|
||||
static rule_number nuseful_productions;
|
||||
@@ -163,9 +163,9 @@ inaccessable_symbols (void)
|
||||
Pp = bitset_create (nrules, BITSET_FIXED);
|
||||
|
||||
/* If the start symbol isn't useful, then nothing will be useful. */
|
||||
if (bitset_test (N, accept->content->number - ntokens))
|
||||
if (bitset_test (N, accept->number - ntokens))
|
||||
{
|
||||
bitset_set (V, accept->content->number);
|
||||
bitset_set (V, accept->number);
|
||||
|
||||
while (1)
|
||||
{
|
||||
@@ -196,9 +196,9 @@ inaccessable_symbols (void)
|
||||
V = Vp;
|
||||
|
||||
/* Tokens 0, 1, and 2 are internal to Bison. Consider them useful. */
|
||||
bitset_set (V, endtoken->content->number); /* end-of-input token */
|
||||
bitset_set (V, errtoken->content->number); /* error token */
|
||||
bitset_set (V, undeftoken->content->number); /* some undefined token */
|
||||
bitset_set (V, endtoken->number); /* end-of-input token */
|
||||
bitset_set (V, errtoken->number); /* error token */
|
||||
bitset_set (V, undeftoken->number); /* some undefined token */
|
||||
|
||||
bitset_free (P);
|
||||
P = Pp;
|
||||
@@ -298,7 +298,7 @@ nonterminals_reduce (void)
|
||||
if (!bitset_test (V, i))
|
||||
{
|
||||
nontermmap[i - ntokens] = n++;
|
||||
if (symbols[i]->content->status != used)
|
||||
if (symbols[i]->status != used)
|
||||
complain (&symbols[i]->location, Wother,
|
||||
_("nonterminal useless in grammar: %s"),
|
||||
symbols[i]->tag);
|
||||
@@ -310,7 +310,7 @@ nonterminals_reduce (void)
|
||||
symbol **symbols_sorted = xnmalloc (nvars, sizeof *symbols_sorted);
|
||||
|
||||
for (i = ntokens; i < nsyms; i++)
|
||||
symbols[i]->content->number = nontermmap[i - ntokens];
|
||||
symbols[i]->number = nontermmap[i - ntokens];
|
||||
for (i = ntokens; i < nsyms; i++)
|
||||
symbols_sorted[nontermmap[i - ntokens] - ntokens] = symbols[i];
|
||||
for (i = ntokens; i < nsyms; i++)
|
||||
@@ -328,7 +328,7 @@ nonterminals_reduce (void)
|
||||
*rhsp = symbol_number_as_item_number (nontermmap[*rhsp
|
||||
- ntokens]);
|
||||
}
|
||||
accept->content->number = nontermmap[accept->content->number - ntokens];
|
||||
accept->number = nontermmap[accept->number - ntokens];
|
||||
}
|
||||
|
||||
nsyms -= nuseless_nonterminals;
|
||||
@@ -415,7 +415,7 @@ reduce_grammar (void)
|
||||
|
||||
reduce_print ();
|
||||
|
||||
if (!bitset_test (N, accept->content->number - ntokens))
|
||||
if (!bitset_test (N, accept->number - ntokens))
|
||||
complain (&startsymbol_location, fatal,
|
||||
_("start symbol %s does not derive any sentence"),
|
||||
startsymbol->tag);
|
||||
|
||||
+84
-10
@@ -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
|
||||
historically almost any character is allowed in a tag. We disallow
|
||||
NUL and newline, as this simplifies our implementation. We allow
|
||||
"->" as a means to dereference a pointer. */
|
||||
tag ([^\0\n>]|->)+
|
||||
NUL and newline, as this simplifies our implementation. */
|
||||
tag [^\0\n>]+
|
||||
|
||||
/* Zero or more instances of backslash-newline. Following GCC, allow
|
||||
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
|
||||
is expected to return only once. This initialization is
|
||||
therefore done once per action to translate. */
|
||||
@@ -148,14 +167,32 @@ ref -?[0-9]+|{id}|"["{id}"]"|"$"
|
||||
|
||||
<SC_RULE_ACTION,SC_SYMBOL_ACTION>
|
||||
{
|
||||
"'" STRING_GROW; BEGIN SC_CHARACTER;
|
||||
"\"" STRING_GROW; BEGIN SC_STRING;
|
||||
"/"{splice}"*" STRING_GROW; BEGIN SC_COMMENT;
|
||||
"/"{splice}"/" STRING_GROW; BEGIN SC_LINE_COMMENT;
|
||||
|
||||
"'" {
|
||||
STRING_GROW;
|
||||
BEGIN SC_CHARACTER;
|
||||
need_semicolon = true;
|
||||
}
|
||||
"\"" {
|
||||
STRING_GROW;
|
||||
BEGIN SC_STRING;
|
||||
need_semicolon = true;
|
||||
}
|
||||
"/"{splice}"*" {
|
||||
STRING_GROW;
|
||||
BEGIN SC_COMMENT;
|
||||
}
|
||||
"/"{splice}"/" {
|
||||
STRING_GROW;
|
||||
BEGIN SC_LINE_COMMENT;
|
||||
}
|
||||
[$@] {
|
||||
complain (loc, Wother, _("stray '%s'"), 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);
|
||||
if (ref_tail_fields)
|
||||
obstack_sgrow (&obstack_for_string, ref_tail_fields);
|
||||
need_semicolon = true;
|
||||
}
|
||||
"@"{ref} {
|
||||
ref_tail_fields = NULL;
|
||||
handle_action_at (self->rule, yytext, *loc);
|
||||
if (ref_tail_fields)
|
||||
obstack_sgrow (&obstack_for_string, ref_tail_fields);
|
||||
need_semicolon = true;
|
||||
}
|
||||
|
||||
";" STRING_GROW; need_semicolon = false;
|
||||
"{" STRING_GROW; ++braces_level; need_semicolon = false;
|
||||
"}" {
|
||||
bool outer_brace = --braces_level == 0;
|
||||
|
||||
/* As an undocumented Bison extension, append ';' before the last
|
||||
brace in braced code, so that the user code can omit trailing
|
||||
';'. But do not append ';' if emulating Yacc, since Yacc does
|
||||
not append one. This is deprecated since release 2.4.1. */
|
||||
if (outer_brace && !yacc_flag && language_prio == default_prio
|
||||
&& skeleton_prio == default_prio && need_semicolon && ! in_cpp)
|
||||
{
|
||||
unsigned int indent = 0;
|
||||
complain_indent (loc, Wdeprecated, &indent,
|
||||
_("a ';' might be needed at the end of action code"));
|
||||
indent += SUB_INDENT;
|
||||
complain_indent (loc, Wdeprecated | silent | no_caret, &indent,
|
||||
_("future versions of Bison will not add the ';'"));
|
||||
obstack_1grow (&obstack_for_string, ';');
|
||||
}
|
||||
|
||||
STRING_GROW;
|
||||
need_semicolon = false;
|
||||
}
|
||||
|
||||
/* Preprocessing directives should only be recognized at the beginning
|
||||
of lines, allowing whitespace including comments, but in C/C++,
|
||||
'#' can only be the start of preprocessor directives or within
|
||||
'#define' directives anyway, so don't bother with begin of line. */
|
||||
"#" STRING_GROW; in_cpp = true;
|
||||
|
||||
{splice} STRING_GROW;
|
||||
[\n\r] STRING_GROW; if (in_cpp) in_cpp = need_semicolon = false;
|
||||
[ \t\f] STRING_GROW;
|
||||
. STRING_GROW; need_semicolon = true;
|
||||
}
|
||||
|
||||
<SC_SYMBOL_ACTION>
|
||||
@@ -596,8 +671,7 @@ fetch_type_name (char *cp, char const **type_name,
|
||||
if (*cp == '<')
|
||||
{
|
||||
*type_name = ++cp;
|
||||
/* Series of non-'>' or "->". */
|
||||
while (*cp != '>' || cp[-1] == '-')
|
||||
while (*cp != '>')
|
||||
++cp;
|
||||
|
||||
/* The '>' symbol will be later replaced by '\0'. Original
|
||||
|
||||
+23
-33
@@ -112,12 +112,7 @@ static void unexpected_newline (boundary, char const *);
|
||||
/* A identifier was just read in directives/rules. Special state
|
||||
to capture the sequence 'identifier :'. */
|
||||
%x SC_AFTER_IDENTIFIER
|
||||
|
||||
/* 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. */
|
||||
/* A complex tag, with nested angles brackets. */
|
||||
%x SC_TAG
|
||||
|
||||
/* Four types of user code:
|
||||
@@ -138,6 +133,13 @@ notletter [^.abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_]{-}[%\{]
|
||||
id {letter}({letter}|[-0-9])*
|
||||
int [0-9]+
|
||||
|
||||
/* POSIX says that a tag must be both an id and a C union member, but
|
||||
historically almost any character is allowed in a tag. We disallow
|
||||
NUL, as this simplifies our implementation. We disallow angle
|
||||
bracket to match them in nested pairs: several languages use them
|
||||
for generics/template types. */
|
||||
tag [^\0<>]+
|
||||
|
||||
/* Zero or more instances of backslash-newline. Following GCC, allow
|
||||
white space between the backslash and the newline. */
|
||||
splice (\\[ \f\t\v]*\n)*
|
||||
@@ -215,7 +217,6 @@ eqopt ([[:space:]]*=)?
|
||||
"%defines" return PERCENT_DEFINES;
|
||||
"%destructor" return PERCENT_DESTRUCTOR;
|
||||
"%dprec" return PERCENT_DPREC;
|
||||
"%empty" return PERCENT_EMPTY;
|
||||
"%error-verbose" return PERCENT_ERROR_VERBOSE;
|
||||
"%expect" return PERCENT_EXPECT;
|
||||
"%expect-rr" return PERCENT_EXPECT_RR;
|
||||
@@ -223,10 +224,6 @@ eqopt ([[:space:]]*=)?
|
||||
"%fixed-output-files" return PERCENT_YACC;
|
||||
"%initial-action" return PERCENT_INITIAL_ACTION;
|
||||
"%glr-parser" return PERCENT_GLR_PARSER;
|
||||
"%gprec" {
|
||||
prec_braces = gprec_seen;
|
||||
return PERCENT_GPREC;
|
||||
}
|
||||
"%language" return PERCENT_LANGUAGE;
|
||||
"%left" return PERCENT_LEFT;
|
||||
"%lex-param" RETURN_PERCENT_PARAM(lex);
|
||||
@@ -243,7 +240,6 @@ eqopt ([[:space:]]*=)?
|
||||
"%parse-param" RETURN_PERCENT_PARAM(parse);
|
||||
"%prec" return PERCENT_PREC;
|
||||
"%precedence" return PERCENT_PRECEDENCE;
|
||||
"%precr" return PERCENT_PRECR;
|
||||
"%printer" return PERCENT_PRINTER;
|
||||
"%pure-parser" RETURN_PERCENT_FLAG("api.pure");
|
||||
"%require" return PERCENT_REQUIRE;
|
||||
@@ -278,17 +274,10 @@ eqopt ([[:space:]]*=)?
|
||||
"=" return EQUAL;
|
||||
"|" return PIPE;
|
||||
";" return SEMICOLON;
|
||||
"}" return RBRACE;
|
||||
">" return GT;
|
||||
|
||||
{id} {
|
||||
val->uniqstr = uniqstr_new (yytext);
|
||||
id_loc = *loc;
|
||||
if (prec_braces == gprec_seen)
|
||||
{
|
||||
prec_braces = group_name_seen;
|
||||
return ID;
|
||||
}
|
||||
bracketed_id_str = NULL;
|
||||
BEGIN SC_AFTER_IDENTIFIER;
|
||||
}
|
||||
@@ -319,11 +308,6 @@ eqopt ([[:space:]]*=)?
|
||||
|
||||
/* Code in between braces. */
|
||||
"{" {
|
||||
if (prec_braces == gprec_seen || prec_braces == group_name_seen)
|
||||
{
|
||||
prec_braces = braces_seen;
|
||||
return LBRACE;
|
||||
}
|
||||
STRING_GROW;
|
||||
nesting = 0;
|
||||
code_start = loc->start;
|
||||
@@ -340,6 +324,13 @@ eqopt ([[:space:]]*=)?
|
||||
/* A type. */
|
||||
"<*>" return TAG_ANY;
|
||||
"<>" return TAG_NONE;
|
||||
"<"{tag}">" {
|
||||
obstack_grow (&obstack_for_string, yytext + 1, yyleng - 2);
|
||||
STRING_FINISH;
|
||||
val->uniqstr = uniqstr_new (last_string);
|
||||
STRING_FREE;
|
||||
return TAG;
|
||||
}
|
||||
"<" {
|
||||
nesting = 0;
|
||||
token_start = loc->start;
|
||||
@@ -529,7 +520,7 @@ eqopt ([[:space:]]*=)?
|
||||
"\"" {
|
||||
STRING_FINISH;
|
||||
loc->start = token_start;
|
||||
val->code = last_string;
|
||||
val->chars = last_string;
|
||||
BEGIN INITIAL;
|
||||
return STRING;
|
||||
}
|
||||
@@ -567,11 +558,10 @@ eqopt ([[:space:]]*=)?
|
||||
<<EOF>> unexpected_eof (token_start, "'");
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*--------------------------------------------------------------.
|
||||
| Scanning a tag. The initial angle bracket is already eaten. |
|
||||
`--------------------------------------------------------------*/
|
||||
/*-----------------------------------------------------------.
|
||||
| Scanning a Bison nested tag. The initial angle bracket is |
|
||||
| already eaten. |
|
||||
`-----------------------------------------------------------*/
|
||||
|
||||
<SC_TAG>
|
||||
{
|
||||
@@ -589,7 +579,7 @@ eqopt ([[:space:]]*=)?
|
||||
STRING_GROW;
|
||||
}
|
||||
|
||||
([^<>]|->)+ STRING_GROW;
|
||||
[^<>]+ STRING_GROW;
|
||||
"<"+ STRING_GROW; nesting += yyleng;
|
||||
|
||||
<<EOF>> unexpected_eof (token_start, ">");
|
||||
@@ -768,7 +758,7 @@ eqopt ([[:space:]]*=)?
|
||||
"%}" {
|
||||
STRING_FINISH;
|
||||
loc->start = code_start;
|
||||
val->code = last_string;
|
||||
val->chars = last_string;
|
||||
BEGIN INITIAL;
|
||||
return PROLOGUE;
|
||||
}
|
||||
@@ -787,7 +777,7 @@ eqopt ([[:space:]]*=)?
|
||||
<<EOF>> {
|
||||
STRING_FINISH;
|
||||
loc->start = code_start;
|
||||
val->code = last_string;
|
||||
val->chars = last_string;
|
||||
BEGIN INITIAL;
|
||||
return EPILOGUE;
|
||||
}
|
||||
|
||||
+3
-5
@@ -72,7 +72,7 @@ static void fail_for_invalid_at (char const *at);
|
||||
"@@" fputc ('@', yyout);
|
||||
"@{" fputc ('[', yyout);
|
||||
"@}" fputc (']', yyout);
|
||||
"@'" continue; /* Used by b4_cat in ../data/bison.m4. */
|
||||
"@`" continue; /* Used by b4_cat in ../data/bison.m4. */
|
||||
@\n continue;
|
||||
|
||||
"@oline@" fprintf (yyout, "%d", out_lineno + 1);
|
||||
@@ -83,7 +83,7 @@ static void fail_for_invalid_at (char const *at);
|
||||
"@output(" at_init (&argc, argv, &at_ptr, &at_output);
|
||||
|
||||
/* This pattern must not match more than the previous @ patterns. */
|
||||
@[^@{}\'(\n]* fail_for_invalid_at (yytext);
|
||||
@[^@{}`(\n]* fail_for_invalid_at (yytext);
|
||||
\n out_lineno++; ECHO;
|
||||
[^@\n]+ ECHO;
|
||||
|
||||
@@ -103,7 +103,7 @@ static void fail_for_invalid_at (char const *at);
|
||||
"@@" obstack_1grow (&obstack_for_string, '@');
|
||||
"@{" obstack_1grow (&obstack_for_string, '[');
|
||||
"@}" obstack_1grow (&obstack_for_string, ']');
|
||||
"@'" continue; /* For starting an argument that begins with whitespace. */
|
||||
"@`" continue; /* For starting an argument that begins with whitespace. */
|
||||
@\n continue;
|
||||
|
||||
@[,)] {
|
||||
@@ -183,8 +183,6 @@ flag (const char *arg)
|
||||
/* compare with values issued from b4_error */
|
||||
if (STREQ (arg, "complain"))
|
||||
return complaint;
|
||||
else if (STREQ (arg, "deprecated"))
|
||||
return Wdeprecated;
|
||||
else if (STREQ (arg, "fatal"))
|
||||
return fatal;
|
||||
else if (STREQ (arg, "note"))
|
||||
|
||||
+1
-1
@@ -135,7 +135,7 @@ typedef struct
|
||||
/* Is the TRANSITIONS->states[Num] labelled by the error token? */
|
||||
|
||||
# define TRANSITION_IS_ERROR(Transitions, Num) \
|
||||
(TRANSITION_SYMBOL (Transitions, Num) == errtoken->content->number)
|
||||
(TRANSITION_SYMBOL (Transitions, Num) == errtoken->number)
|
||||
|
||||
/* When resolving a SR conflicts, if the reduction wins, the shift is
|
||||
disabled. */
|
||||
|
||||
+10
-17
@@ -36,20 +36,18 @@ symbol_list_sym_new (symbol *sym, location loc)
|
||||
res->content_type = SYMLIST_SYMBOL;
|
||||
res->content.sym = sym;
|
||||
res->location = res->sym_loc = loc;
|
||||
res->named_ref = NULL;
|
||||
|
||||
res->midrule = NULL;
|
||||
res->midrule_parent_rule = NULL;
|
||||
res->midrule_parent_rhs_index = 0;
|
||||
|
||||
/* Members used for LHS only. */
|
||||
res->ruleprec = NULL;
|
||||
res->percent_empty_loc = empty_location;
|
||||
code_props_none_init (&res->action_props);
|
||||
|
||||
res->ruleprec = NULL;
|
||||
res->dprec = 0;
|
||||
res->dprec_location = empty_location;
|
||||
res->merger = 0;
|
||||
res->merger_declaration_location = empty_location;
|
||||
|
||||
res->named_ref = NULL;
|
||||
|
||||
res->next = NULL;
|
||||
|
||||
@@ -87,17 +85,12 @@ symbol_list_type_new (uniqstr type_name, location loc)
|
||||
void
|
||||
symbol_list_syms_print (const symbol_list *l, FILE *f)
|
||||
{
|
||||
char const *sep = "";
|
||||
for (/* Nothing. */; l && l->content.sym; l = l->next)
|
||||
{
|
||||
fputs (sep, f);
|
||||
fputs (l->content_type == SYMLIST_SYMBOL ? "symbol: "
|
||||
: l->content_type == SYMLIST_TYPE ? "type: "
|
||||
: "invalid content_type: ",
|
||||
f);
|
||||
symbol_print (l->content.sym, f);
|
||||
fputs (l->action_props.is_value_used ? " used" : " unused", f);
|
||||
sep = ", ";
|
||||
fprintf (stderr, l->action_props.is_value_used ? " used" : " unused");
|
||||
if (l && l->content.sym)
|
||||
fprintf (f, ", ");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -205,7 +198,7 @@ symbol_list_n_type_name_get (symbol_list *l, location loc, int n)
|
||||
return NULL;
|
||||
}
|
||||
aver (l->content_type == SYMLIST_SYMBOL);
|
||||
return l->content.sym->content->type_name;
|
||||
return l->content.sym->type_name;
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -223,8 +216,8 @@ symbol_list_code_props_set (symbol_list *node, code_props_type kind,
|
||||
{
|
||||
case SYMLIST_SYMBOL:
|
||||
symbol_code_props_set (node->content.sym, kind, cprops);
|
||||
if (node->content.sym->content->status == undeclared)
|
||||
node->content.sym->content->status = used;
|
||||
if (node->content.sym->status == undeclared)
|
||||
node->content.sym->status = used;
|
||||
break;
|
||||
case SYMLIST_TYPE:
|
||||
semantic_type_code_props_set
|
||||
|
||||
+5
-15
@@ -50,9 +50,6 @@ typedef struct symbol_list
|
||||
} content;
|
||||
location location;
|
||||
|
||||
/* Named reference. */
|
||||
named_ref *named_ref;
|
||||
|
||||
/* Proper location of the symbol, not all the rule */
|
||||
location sym_loc;
|
||||
|
||||
@@ -67,26 +64,19 @@ typedef struct symbol_list
|
||||
struct symbol_list *midrule_parent_rule;
|
||||
int midrule_parent_rhs_index;
|
||||
|
||||
/* ---------------------------------------------- */
|
||||
/* Apply to the rule (attached to the LHS only). */
|
||||
/* ---------------------------------------------- */
|
||||
|
||||
/* Precedence/associativity. */
|
||||
symbol *ruleprec;
|
||||
|
||||
/* The action is attached to the LHS of a rule, but action properties for
|
||||
* each RHS are also stored here. */
|
||||
code_props action_props;
|
||||
|
||||
/* The location of the first %empty for this rule, or \a
|
||||
empty_location. */
|
||||
location percent_empty_loc;
|
||||
|
||||
/* Precedence/associativity. */
|
||||
symbol *ruleprec;
|
||||
int dprec;
|
||||
location dprec_location;
|
||||
int merger;
|
||||
location merger_declaration_location;
|
||||
|
||||
/* Named reference. */
|
||||
named_ref *named_ref;
|
||||
|
||||
/* The list. */
|
||||
struct symbol_list *next;
|
||||
} symbol_list;
|
||||
|
||||
+182
-670
File diff suppressed because it is too large
Load Diff
+14
-119
@@ -31,8 +31,6 @@
|
||||
# include "scan-code.h"
|
||||
# include "uniqstr.h"
|
||||
|
||||
typedef struct symbol_list symbol_list;
|
||||
|
||||
/*----------.
|
||||
| Symbols. |
|
||||
`----------*/
|
||||
@@ -52,7 +50,6 @@ typedef int symbol_number;
|
||||
|
||||
|
||||
typedef struct symbol symbol;
|
||||
typedef struct sym_content sym_content;
|
||||
|
||||
/* Declaration status of a symbol.
|
||||
|
||||
@@ -64,8 +61,6 @@ typedef struct sym_content sym_content;
|
||||
When status are checked at the end, "declared" symbols are fine,
|
||||
"used" symbols trigger warnings, otherwise it's an error. */
|
||||
|
||||
typedef struct prec_node prec_node;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
/** Used in the input file for an unknown reason (error). */
|
||||
@@ -87,6 +82,8 @@ enum code_props_type
|
||||
|
||||
enum { CODE_PROPS_SIZE = 2 };
|
||||
|
||||
/* When extending this structure, be sure to complete
|
||||
symbol_check_alias_consistency. */
|
||||
struct symbol
|
||||
{
|
||||
/** The key, name of the symbol. */
|
||||
@@ -94,20 +91,6 @@ struct symbol
|
||||
/** The location of its first occurrence. */
|
||||
location location;
|
||||
|
||||
/* Points to the other in the symbol-string pair for an alias. */
|
||||
symbol *alias;
|
||||
|
||||
/** Whether this symbol is the alias of another or not. */
|
||||
bool is_alias;
|
||||
|
||||
/** All the info about the pointed symbol is there. */
|
||||
sym_content *content;
|
||||
};
|
||||
|
||||
struct sym_content
|
||||
{
|
||||
symbol *symbol;
|
||||
|
||||
/** Its \c \%type.
|
||||
|
||||
Beware that this is the type_name as was entered by the user,
|
||||
@@ -129,29 +112,25 @@ struct sym_content
|
||||
code_props props[CODE_PROPS_SIZE];
|
||||
|
||||
symbol_number number;
|
||||
|
||||
/* Not used anymore, to remove. */
|
||||
location prec_location;
|
||||
int prec;
|
||||
|
||||
assoc assoc;
|
||||
int user_token_number;
|
||||
|
||||
/* Points to the other in the symbol-string pair for an alias.
|
||||
Special value USER_NUMBER_HAS_STRING_ALIAS in the symbol half of the
|
||||
symbol-string pair for an alias. */
|
||||
symbol *alias;
|
||||
symbol_class class;
|
||||
status status;
|
||||
|
||||
/* The next element in the symbol precedence group. */
|
||||
sym_content *group_next;
|
||||
|
||||
/* The graph node containing all the precedence information for this
|
||||
symbol. */
|
||||
prec_node *prec_node;
|
||||
};
|
||||
|
||||
/** Undefined user number. */
|
||||
# define USER_NUMBER_UNDEFINED -1
|
||||
|
||||
/* 'symbol->user_token_number == USER_NUMBER_HAS_STRING_ALIAS' means
|
||||
this symbol has a literal string alias. For instance, '%token foo
|
||||
"foo"' has '"foo"' numbered regularly, and 'foo' numbered as
|
||||
/* `symbol->user_token_number == USER_NUMBER_HAS_STRING_ALIAS' means
|
||||
this symbol has a literal string alias. For instance, `%token foo
|
||||
"foo"' has `"foo"' numbered regularly, and `foo' numbered as
|
||||
USER_NUMBER_HAS_STRING_ALIAS. */
|
||||
# define USER_NUMBER_HAS_STRING_ALIAS -9991
|
||||
|
||||
@@ -287,8 +266,7 @@ struct symgraph
|
||||
|
||||
void register_precedence (graphid first, graphid snd);
|
||||
|
||||
/** Print a warning for each symbol whose precedence and/or associativity
|
||||
* is useless. */
|
||||
/** Print a warning for each symbol whose precedence is useless. */
|
||||
|
||||
void print_precedence_warnings (void);
|
||||
|
||||
@@ -296,92 +274,9 @@ void print_precedence_warnings (void);
|
||||
| Symbol associativity |
|
||||
`----------------------*/
|
||||
|
||||
void register_assoc (graphid i, graphid j);
|
||||
|
||||
|
||||
/*------------------.
|
||||
| Groups of symbols |
|
||||
`------------------*/
|
||||
|
||||
#define DEFAULT_GROUP_NAME uniqstr_new ("__default__")
|
||||
|
||||
typedef struct symgroup symgroup;
|
||||
|
||||
struct symgroup
|
||||
{
|
||||
/** The name of the group. */
|
||||
uniqstr tag;
|
||||
|
||||
/** The list of symbols in the group. */
|
||||
sym_content * symbol_list;
|
||||
|
||||
location location;
|
||||
} ;
|
||||
|
||||
/** Get a dummy name for an anonymous group. */
|
||||
uniqstr new_anonymous_group_name (void);
|
||||
|
||||
/** Set the current group in the token precedence declaration to a new group
|
||||
* with this name */
|
||||
void set_current_group (const uniqstr name, location *loc);
|
||||
|
||||
/** Get or create the group by that name. The location information is used for
|
||||
* creation when available. */
|
||||
symgroup *
|
||||
symgroup_from_uniqstr (const uniqstr key, location *loc);
|
||||
|
||||
/** Check if there is a symbol precedence group by that name. */
|
||||
bool
|
||||
is_prec_group (const uniqstr key);
|
||||
|
||||
|
||||
/*----------------------------------.
|
||||
| Graph of precedence relationships |
|
||||
`----------------------------------*/
|
||||
|
||||
typedef struct prec_link prec_link;
|
||||
|
||||
struct prec_link
|
||||
{
|
||||
prec_node *target;
|
||||
bool transitive;
|
||||
prec_link *next;
|
||||
};
|
||||
|
||||
struct prec_node
|
||||
{
|
||||
symbol *symbol;
|
||||
/** Associativity for the symbol. */
|
||||
assoc assoc;
|
||||
location prec_location;
|
||||
prec_link *sons;
|
||||
prec_link *equals;
|
||||
};
|
||||
|
||||
typedef enum prec_rel_comparator prec_rel_comparator;
|
||||
|
||||
enum prec_rel_comparator
|
||||
{
|
||||
prec_equal,
|
||||
prec_superior,
|
||||
prec_superior_strict,
|
||||
};
|
||||
|
||||
/** Declare a precedence relationship between the symbols of the two lists,
|
||||
* as defined by the operator. */
|
||||
void
|
||||
declare_precedence_relation (symbol_list *l1, symbol_list *l2,
|
||||
prec_rel_comparator c, location loc);
|
||||
/** Return the list of symbols contained in the group. */
|
||||
symbol_list *
|
||||
expand_symbol_group (symgroup * group, location loc);
|
||||
|
||||
/** Check if s1 and s2 have the same precedence level. */
|
||||
bool is_prec_equal (prec_node * s1, prec_node * s2);
|
||||
|
||||
/** Check if from > to . */
|
||||
bool is_prec_superior (prec_node * from, prec_node * to);
|
||||
void register_assoc (int i, int j);
|
||||
|
||||
void print_assoc_warnings (void);
|
||||
|
||||
/*-----------------.
|
||||
| Semantic types. |
|
||||
|
||||
+1
-1
@@ -99,7 +99,7 @@ typedef size_t uintptr_t;
|
||||
# endif
|
||||
# endif
|
||||
|
||||
/* The __-protected variants of 'format' and 'printf' attributes
|
||||
/* The __-protected variants of `format' and `printf' attributes
|
||||
are accepted by gcc versions 2.6.4 (effectively 2.7) and later. */
|
||||
# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7)
|
||||
# define __format__ format
|
||||
|
||||
+9
-9
@@ -35,7 +35,7 @@
|
||||
#include "tables.h"
|
||||
|
||||
/* Several tables are indexed both by state and nonterminal numbers.
|
||||
We call such an index a 'vector'; i.e., a vector is either a state
|
||||
We call such an index a `vector'; i.e., a vector is either a state
|
||||
or a nonterminal number.
|
||||
|
||||
Of course vector_number_t ought to be wide enough to contain
|
||||
@@ -90,18 +90,18 @@ static base_number *width;
|
||||
|
||||
/* For a given state, N = ACTROW[SYMBOL]:
|
||||
|
||||
If N = 0, stands for 'run the default action'.
|
||||
If N = MIN, stands for 'raise a syntax error'.
|
||||
If N > 0, stands for 'shift SYMBOL and go to n'.
|
||||
If N < 0, stands for 'reduce -N'. */
|
||||
If N = 0, stands for `run the default action'.
|
||||
If N = MIN, stands for `raise a syntax error'.
|
||||
If N > 0, stands for `shift SYMBOL and go to n'.
|
||||
If N < 0, stands for `reduce -N'. */
|
||||
typedef int action_number;
|
||||
#define ACTION_NUMBER_MINIMUM INT_MIN
|
||||
|
||||
static action_number *actrow;
|
||||
|
||||
/* FROMS and TOS are reordered to be compressed. ORDER[VECTOR] is the
|
||||
new vector number of VECTOR. We skip 'empty' vectors (i.e.,
|
||||
TALLY[VECTOR] = 0), and call these 'entries'. */
|
||||
new vector number of VECTOR. We skip `empty' vectors (i.e.,
|
||||
TALLY[VECTOR] = 0), and call these `entries'. */
|
||||
static vector_number *order;
|
||||
static int nentries;
|
||||
|
||||
@@ -290,7 +290,7 @@ action_row (state *s)
|
||||
|
||||
/* Do not use any default reduction if there is a shift for
|
||||
error */
|
||||
if (sym == errtoken->content->number)
|
||||
if (sym == errtoken->number)
|
||||
nodefault = true;
|
||||
}
|
||||
|
||||
@@ -300,7 +300,7 @@ action_row (state *s)
|
||||
for (i = 0; i < errp->num; i++)
|
||||
{
|
||||
symbol *sym = errp->symbols[i];
|
||||
actrow[sym->content->number] = ACTION_NUMBER_MINIMUM;
|
||||
actrow[sym->number] = ACTION_NUMBER_MINIMUM;
|
||||
}
|
||||
|
||||
/* Turn off default reductions where requested by the user. See
|
||||
|
||||
+1
-1
@@ -105,7 +105,7 @@ uniqstr_print_processor (void *ustr, void *null ATTRIBUTE_UNUSED)
|
||||
|
||||
|
||||
int
|
||||
uniqstr_cmp (uniqstr l, uniqstr r)
|
||||
uniqstr_cmp(uniqstr l, uniqstr r)
|
||||
{
|
||||
return (l == r ? 0
|
||||
: !l ? -1
|
||||
|
||||
+1
-1
@@ -40,7 +40,7 @@ uniqstr uniqstr_vsprintf (char const *format, ...)
|
||||
|
||||
/* Compare two uniqstr a la strcmp: negative for <, nul for =, and
|
||||
positive for >. Undefined order, relies on addresses. */
|
||||
int uniqstr_cmp (uniqstr u1, uniqstr u2);
|
||||
int uniqstr_cmp(uniqstr u1, uniqstr u2);
|
||||
|
||||
/* Die if STR is not a uniqstr. */
|
||||
void uniqstr_assert (char const *str);
|
||||
|
||||
+1
-1
Submodule submodules/autoconf updated: 9e087dd343...26cb0918d3
+121
-125
@@ -64,119 +64,6 @@ AT_PARSER_CHECK([./input], 0,
|
||||
|
||||
AT_CLEANUP
|
||||
|
||||
## ----------------------- ##
|
||||
## Implicitly empty rule. ##
|
||||
## ----------------------- ##
|
||||
|
||||
AT_SETUP([Implicitly empty rule])
|
||||
|
||||
AT_DATA_GRAMMAR([[1.y]],
|
||||
[[%%
|
||||
exp: a b;
|
||||
a: /* empty. */ {};
|
||||
// A mid-rule action does not count as an empty rule.
|
||||
b: {} {};
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK([-fcaret -Wempty-rule 1.y], [0], [],
|
||||
[[1.y:11.17-18: warning: empty rule without %empty [-Wempty-rule]
|
||||
a: /* empty. */ {};
|
||||
^^
|
||||
]])
|
||||
|
||||
AT_DATA_GRAMMAR([[2.y]],
|
||||
[[%%
|
||||
exp: a b c;
|
||||
a: /* empty. */ {};
|
||||
b: %empty {};
|
||||
c: /* empty. */ {};
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK([-fcaret 2.y], [0], [],
|
||||
[[2.y:11.17-18: warning: empty rule without %empty [-Wempty-rule]
|
||||
a: /* empty. */ {};
|
||||
^^
|
||||
2.y:13.17-18: warning: empty rule without %empty [-Wempty-rule]
|
||||
c: /* empty. */ {};
|
||||
^^
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK([-fcaret -Wno-empty-rule 2.y], [0])
|
||||
|
||||
AT_CLEANUP
|
||||
|
||||
## ------------------------ ##
|
||||
## Invalid uses of %empty. ##
|
||||
## ------------------------ ##
|
||||
|
||||
AT_SETUP([Invalid uses of %empty])
|
||||
|
||||
AT_DATA_GRAMMAR([[one.y]],
|
||||
[[%%
|
||||
exp:
|
||||
%empty {} %empty
|
||||
;
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK([-fcaret one.y], [1], [],
|
||||
[[one.y:11.13-18: error: only one %empty allowed per rule
|
||||
%empty {} %empty
|
||||
^^^^^^
|
||||
one.y:11.3-8: previous declaration
|
||||
%empty {} %empty
|
||||
^^^^^^
|
||||
]])
|
||||
|
||||
AT_DATA_GRAMMAR([[two.y]],
|
||||
[[%%
|
||||
exp:
|
||||
'a' %empty {}
|
||||
| %empty 'a' {}
|
||||
| %empty {} {}
|
||||
;
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK([-fcaret two.y], [1], [],
|
||||
[[two.y:11.7-12: error: %empty on non-empty rule
|
||||
'a' %empty {}
|
||||
^^^^^^
|
||||
two.y:12.3-8: error: %empty on non-empty rule
|
||||
| %empty 'a' {}
|
||||
^^^^^^
|
||||
two.y:13.3-8: error: %empty on non-empty rule
|
||||
| %empty {} {}
|
||||
^^^^^^
|
||||
]])
|
||||
|
||||
AT_CLEANUP
|
||||
|
||||
## ---------------------- ##
|
||||
## Valid uses of %empty. ##
|
||||
## ---------------------- ##
|
||||
|
||||
AT_SETUP([Valid uses of %empty])
|
||||
|
||||
AT_BISON_OPTION_PUSHDEFS
|
||||
AT_DATA_GRAMMAR([[input.y]],
|
||||
[[
|
||||
%debug
|
||||
%code
|
||||
{
|
||||
]AT_YYERROR_DECLARE[
|
||||
]AT_YYLEX_DECLARE[
|
||||
}
|
||||
%%
|
||||
exp: %empty {}
|
||||
%%
|
||||
]AT_YYERROR_DEFINE[
|
||||
]AT_YYLEX_DEFINE[
|
||||
]AT_MAIN_DEFINE[
|
||||
]])
|
||||
|
||||
AT_FULL_COMPILE([input])
|
||||
AT_PARSER_CHECK([./input])
|
||||
AT_BISON_OPTION_POPDEFS
|
||||
AT_CLEANUP
|
||||
|
||||
## ------------------ ##
|
||||
## Initial location. ##
|
||||
@@ -286,8 +173,8 @@ m4_popdef([AT_TEST])
|
||||
## 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.
|
||||
m4_pushdef([AT_TEST],
|
||||
[AT_SETUP([Location print: $1 $2])
|
||||
@@ -305,7 +192,7 @@ AT_DATA_GRAMMAR([[input.y]],
|
||||
]AT_YYLEX_DECLARE[
|
||||
}
|
||||
%%
|
||||
exp: %empty;
|
||||
exp: /* empty */;
|
||||
%%
|
||||
]AT_YYERROR_DEFINE[
|
||||
]AT_YYLEX_DEFINE[
|
||||
@@ -528,7 +415,7 @@ AT_LALR1_CC_IF([typedef yy::location YYLTYPE;])[
|
||||
%%
|
||||
/*
|
||||
This grammar is made to exercise error recovery.
|
||||
"Lines" starting with '(' support error recovery, with
|
||||
"Lines" starting with `(' support error recovery, with
|
||||
')' as synchronizing token. Lines starting with 'x' can never
|
||||
be recovered from if in error.
|
||||
*/
|
||||
@@ -605,11 +492,11 @@ static
|
||||
{
|
||||
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. */
|
||||
]AT_LOC_FIRST_LINE[ = ]AT_LOC_FIRST_COLUMN[ = 10 * c;
|
||||
]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])
|
||||
fprintf (stderr, "sending: '%c'", source[c]);
|
||||
else
|
||||
@@ -691,7 +578,7 @@ Successful parse.
|
||||
|
||||
# Syntax errors caught by the parser
|
||||
# ----------------------------------
|
||||
# Exercise the discarding of stack top and input until 'error'
|
||||
# Exercise the discarding of stack top and input until `error'
|
||||
# can be reduced.
|
||||
#
|
||||
# '(', 'x', 'x', 'x', 'x', 'x', ')',
|
||||
@@ -848,13 +735,13 @@ AT_CLEANUP
|
||||
|
||||
|
||||
AT_CHECK_PRINTER_AND_DESTRUCTOR([])
|
||||
AT_CHECK_PRINTER_AND_DESTRUCTOR([], [ with union])
|
||||
AT_CHECK_PRINTER_AND_DESTRUCTOR([], [with union])
|
||||
|
||||
AT_CHECK_PRINTER_AND_DESTRUCTOR([%defines %skeleton "lalr1.cc"])
|
||||
AT_CHECK_PRINTER_AND_DESTRUCTOR([%defines %skeleton "lalr1.cc"], [ with union])
|
||||
AT_CHECK_PRINTER_AND_DESTRUCTOR([%defines %skeleton "lalr1.cc"], [with union])
|
||||
|
||||
AT_CHECK_PRINTER_AND_DESTRUCTOR([%glr-parser])
|
||||
AT_CHECK_PRINTER_AND_DESTRUCTOR([%glr-parser], [ with union])
|
||||
AT_CHECK_PRINTER_AND_DESTRUCTOR([%glr-parser], [with union])
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
# dead code because $accept is currently never shifted onto the stack.
|
||||
# - $$ for $accept would always be of type YYSTYPE because it's not possible
|
||||
# to declare '%type <field> $accept'. (Also true for $undefined.)
|
||||
# to declare `%type <field> $accept'. (Also true for $undefined.)
|
||||
# - Thus, the compiler might complain that the user code assumes the wrong
|
||||
# type for $$ since the code might assume the type associated with a
|
||||
# specific union field, which is especially reasonable in C++ since that
|
||||
@@ -1607,6 +1494,115 @@ AT_TEST([glr.cc])
|
||||
|
||||
m4_popdef([AT_TEST])
|
||||
|
||||
## ----------------------------------------------- ##
|
||||
## Fix user actions without a trailing semicolon. ##
|
||||
## ----------------------------------------------- ##
|
||||
|
||||
AT_SETUP([[Fix user actions without a trailing semicolon]])
|
||||
|
||||
# This feature is undocumented, but we accidentally broke it in 2.3a,
|
||||
# and there was a complaint at:
|
||||
# <http://lists.gnu.org/archive/html/bug-bison/2008-11/msg00001.html>.
|
||||
AT_BISON_OPTION_PUSHDEFS
|
||||
AT_DATA([input.y],
|
||||
[[%%
|
||||
start: test2 test1 test0 testc;
|
||||
|
||||
test2
|
||||
: 'a' { semi; /* TEST:N:2 */ }
|
||||
| 'b' { if (0) {no_semi} /* TEST:N:2 */ }
|
||||
| 'c' { if (0) {semi;} /* TEST:N:2 */ }
|
||||
| 'd' { semi; no_semi /* TEST:Y:2 */ }
|
||||
| 'e' { semi(); no_semi() /* TEST:Y:2 */ }
|
||||
| 'f' { semi[]; no_semi[] /* TEST:Y:2 */ }
|
||||
| 'g' { semi++; no_semi++ /* TEST:Y:2 */ }
|
||||
| 'h' { {no_semi} no_semi /* TEST:Y:2 */ }
|
||||
| 'i' { {semi;} no_semi /* TEST:Y:2 */ }
|
||||
;
|
||||
test1
|
||||
: 'a' { semi; // TEST:N:1 ;
|
||||
} | 'b' { if (0) {no_semi} // TEST:N:1 ;
|
||||
} | 'c' { if (0) {semi;} // TEST:N:1 ;
|
||||
} | 'd' { semi; no_semi // TEST:Y:1 ;
|
||||
} | 'e' { semi(); no_semi() // TEST:Y:1 ;
|
||||
} | 'f' { semi[]; no_semi[] // TEST:Y:1 ;
|
||||
} | 'g' { semi++; no_semi++ // TEST:Y:1 ;
|
||||
} | 'h' { {no_semi} no_semi // TEST:Y:1 ;
|
||||
} | 'i' { {semi;} no_semi // TEST:Y:1 ;
|
||||
} ;
|
||||
test0
|
||||
: 'a' { semi; // TEST:N:1 {}
|
||||
} | 'b' { if (0) {no_semi} // TEST:N:1 {}
|
||||
} | 'c' { if (0) {semi;} // TEST:N:1 {}
|
||||
} | 'd' { semi; no_semi // TEST:Y:1 {}
|
||||
} | 'e' { semi(); no_semi() // TEST:Y:1 {}
|
||||
} | 'f' { semi[]; no_semi[] // TEST:Y:1 {}
|
||||
} | 'g' { semi++; no_semi++ // TEST:Y:1 {}
|
||||
} | 'h' { {no_semi} no_semi // TEST:Y:1 {}
|
||||
} | 'i' { {semi;} no_semi // TEST:Y:1 {}
|
||||
} ;
|
||||
|
||||
testc
|
||||
: 'a' {
|
||||
#define TEST_MACRO_N \
|
||||
[]"broken\" $ @ $$ @$ [];\
|
||||
string;"}
|
||||
| 'b' {
|
||||
no_semi
|
||||
#define TEST_MACRO_N \
|
||||
[]"broken\" $ @ $$ @$ [];\
|
||||
string;"}
|
||||
]])
|
||||
AT_BISON_OPTION_POPDEFS
|
||||
|
||||
AT_BISON_CHECK([[-o input.c input.y]], [0], [],
|
||||
[[input.y:8.48: warning: a ';' might be needed at the end of action code [-Wdeprecated]
|
||||
input.y:8.48: future versions of Bison will not add the ';'
|
||||
input.y:9.48: warning: a ';' might be needed at the end of action code [-Wdeprecated]
|
||||
input.y:9.48: future versions of Bison will not add the ';'
|
||||
input.y:10.48: warning: a ';' might be needed at the end of action code [-Wdeprecated]
|
||||
input.y:10.48: future versions of Bison will not add the ';'
|
||||
input.y:11.48: warning: a ';' might be needed at the end of action code [-Wdeprecated]
|
||||
input.y:11.48: future versions of Bison will not add the ';'
|
||||
input.y:12.48: warning: a ';' might be needed at the end of action code [-Wdeprecated]
|
||||
input.y:12.48: future versions of Bison will not add the ';'
|
||||
input.y:13.48: warning: a ';' might be needed at the end of action code [-Wdeprecated]
|
||||
input.y:13.48: future versions of Bison will not add the ';'
|
||||
input.y:20.1: warning: a ';' might be needed at the end of action code [-Wdeprecated]
|
||||
input.y:20.1: future versions of Bison will not add the ';'
|
||||
input.y:21.1: warning: a ';' might be needed at the end of action code [-Wdeprecated]
|
||||
input.y:21.1: future versions of Bison will not add the ';'
|
||||
input.y:22.1: warning: a ';' might be needed at the end of action code [-Wdeprecated]
|
||||
input.y:22.1: future versions of Bison will not add the ';'
|
||||
input.y:23.1: warning: a ';' might be needed at the end of action code [-Wdeprecated]
|
||||
input.y:23.1: future versions of Bison will not add the ';'
|
||||
input.y:24.1: warning: a ';' might be needed at the end of action code [-Wdeprecated]
|
||||
input.y:24.1: future versions of Bison will not add the ';'
|
||||
input.y:25.1: warning: a ';' might be needed at the end of action code [-Wdeprecated]
|
||||
input.y:25.1: future versions of Bison will not add the ';'
|
||||
input.y:31.1: warning: a ';' might be needed at the end of action code [-Wdeprecated]
|
||||
input.y:31.1: future versions of Bison will not add the ';'
|
||||
input.y:32.1: warning: a ';' might be needed at the end of action code [-Wdeprecated]
|
||||
input.y:32.1: future versions of Bison will not add the ';'
|
||||
input.y:33.1: warning: a ';' might be needed at the end of action code [-Wdeprecated]
|
||||
input.y:33.1: future versions of Bison will not add the ';'
|
||||
input.y:34.1: warning: a ';' might be needed at the end of action code [-Wdeprecated]
|
||||
input.y:34.1: future versions of Bison will not add the ';'
|
||||
input.y:35.1: warning: a ';' might be needed at the end of action code [-Wdeprecated]
|
||||
input.y:35.1: future versions of Bison will not add the ';'
|
||||
input.y:36.1: warning: a ';' might be needed at the end of action code [-Wdeprecated]
|
||||
input.y:36.1: future versions of Bison will not add the ';'
|
||||
]])
|
||||
|
||||
AT_MATCHES_CHECK([input.c], [[/\* TEST:N:2 \*/ \}$]], [[3]])
|
||||
AT_MATCHES_CHECK([input.c], [[/\* TEST:Y:2 \*/ ;\}$]], [[6]])
|
||||
AT_MATCHES_CHECK([input.c], [[// TEST:N:1 [;{}]*\n\}$]], [[6]])
|
||||
AT_MATCHES_CHECK([input.c], [[// TEST:Y:1 [;{}]*\n;\}$]], [[12]])
|
||||
AT_MATCHES_CHECK([input.c], [[#define TEST_MACRO_N \\\n\[\]"broken\\" \$ \@ \$\$ \@\$ \[\];\\\nstring;"\}]], [[2]])
|
||||
|
||||
AT_CLEANUP
|
||||
|
||||
|
||||
## -------------------------------------------------- ##
|
||||
## Destroying lookahead assigned by semantic action. ##
|
||||
## -------------------------------------------------- ##
|
||||
@@ -1641,7 +1637,7 @@ AT_DATA_GRAMMAR([input.y],
|
||||
// that has set yychar might not always return normally. Instead,
|
||||
// skeletons must translate before every use of yytoken.
|
||||
start: 'a' accept { USE($1); } ;
|
||||
accept: %empty {
|
||||
accept: /*empty*/ {
|
||||
assert (yychar == YYEMPTY);
|
||||
yychar = 'b';
|
||||
YYACCEPT;
|
||||
|
||||
+13
-32
@@ -16,7 +16,7 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# We need 'config.h'.
|
||||
# We need `config.h'.
|
||||
CPPFLAGS="-I$abs_top_builddir/lib @CPPFLAGS@"
|
||||
|
||||
# Don't just check if $POSIXLY_CORRECT is set, as Bash, when launched
|
||||
@@ -47,40 +47,12 @@ NO_WERROR_CXXFLAGS='@CXXFLAGS@ @WARN_CXXFLAGS@ @WARN_CXXFLAGS_TEST@'
|
||||
CFLAGS="$NO_WERROR_CFLAGS @WERROR_CFLAGS@"
|
||||
CXXFLAGS="$NO_WERROR_CXXFLAGS @WERROR_CXXFLAGS@"
|
||||
|
||||
# C++ variants break strict aliasing analysis.
|
||||
NO_STRICT_ALIAS_CXXFLAGS='@NO_STRICT_ALIAS_CXXFLAGS@'
|
||||
|
||||
# If 'exit 77'; skip all C++ tests; otherwise ':'.
|
||||
BISON_CXX_WORKS='@BISON_CXX_WORKS@'
|
||||
|
||||
# Be sure that the C++ compiler is not broken because of gnulib. This
|
||||
# cannot be checked in configure (gnulib is not parameterized yet),
|
||||
# and checking this in every C++ test in AC_COMPILE_CXX is too costly.
|
||||
#
|
||||
# http://lists.gnu.org/archive/html/bug-bison/2013-06/msg00001.html
|
||||
#
|
||||
# FIXME: Check (say 2014) whether this is still needed.
|
||||
if $BISON_CXX_WORKS; then
|
||||
# See AT_DATA_SOURCE_PROLOGUE.
|
||||
cat >conftest.cc <<EOF
|
||||
#include <config.h>
|
||||
/* We don't need perfect functions for these tests. */
|
||||
#undef malloc
|
||||
#undef memcmp
|
||||
#undef realloc
|
||||
#include <iostream>
|
||||
|
||||
int main ()
|
||||
{
|
||||
std::cout << "Works" << std::endl;
|
||||
}
|
||||
EOF
|
||||
ls
|
||||
$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 -f conftest*
|
||||
fi
|
||||
|
||||
# Whether the compiler supports POSIXLY_CORRECT defined.
|
||||
: ${C_COMPILER_POSIXLY_CORRECT='@C_COMPILER_POSIXLY_CORRECT@'}
|
||||
: ${CXX_COMPILER_POSIXLY_CORRECT='@CXX_COMPILER_POSIXLY_CORRECT@'}
|
||||
@@ -103,6 +75,15 @@ else
|
||||
CC_IS_CXX=0
|
||||
fi
|
||||
|
||||
# In a similar way, handle --release
|
||||
if "$at_arg_release"; then
|
||||
BISON_USE_PUSH_FOR_PULL=1
|
||||
BISON_TEST_XML=1
|
||||
else
|
||||
BISON_USE_PUSH_FOR_PULL=0
|
||||
BISON_TEST_XML=0
|
||||
fi
|
||||
|
||||
|
||||
## ------- ##
|
||||
## Other. ##
|
||||
|
||||
+42
-110
@@ -18,68 +18,6 @@
|
||||
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. ##
|
||||
## --------------------------- ##
|
||||
@@ -90,7 +28,7 @@ AT_KEYWORDS([variant])
|
||||
|
||||
AT_BISON_OPTION_PUSHDEFS([%skeleton "lalr1.cc" %debug $1])
|
||||
# Store strings and integers in a list of strings.
|
||||
AT_DATA_GRAMMAR([list.y],
|
||||
AT_DATA_GRAMMAR([list.yy],
|
||||
[[%skeleton "lalr1.cc"
|
||||
%define api.value.type variant
|
||||
%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, [],
|
||||
[12
|
||||
123
|
||||
@@ -176,7 +115,7 @@ m4_pushdef([AT_TEST],
|
||||
|
||||
AT_BISON_OPTION_PUSHDEFS([%skeleton "lalr1.cc" %debug $1])
|
||||
# Store strings and integers in a list of strings.
|
||||
AT_DATA_GRAMMAR([list.y],
|
||||
AT_DATA_GRAMMAR([list.yy],
|
||||
[[%debug
|
||||
%skeleton "lalr1.cc"
|
||||
%define api.value.type variant
|
||||
@@ -311,7 +250,8 @@ namespace yy
|
||||
]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,
|
||||
[(0, 1, 2, 4)
|
||||
])
|
||||
@@ -325,8 +265,8 @@ AT_TEST([%define parse.assert])
|
||||
AT_TEST([%locations %define parse.assert])
|
||||
AT_TEST([[%define parse.assert %code {\n#define TWO_STAGE_BUILD\n}]])
|
||||
AT_TEST([[%define parse.assert %define api.token.constructor]])
|
||||
AT_TEST([[%define parse.assert %define api.token.constructor %define api.token.prefix {TOK_}]])
|
||||
AT_TEST([[%locations %define parse.assert %define api.token.constructor %define api.token.prefix {TOK_}]])
|
||||
AT_TEST([[%define parse.assert %define api.token.constructor %define api.token.prefix "TOK_"]])
|
||||
AT_TEST([[%locations %define parse.assert %define api.token.constructor %define api.token.prefix "TOK_"]])
|
||||
|
||||
m4_popdef([AT_TEST])
|
||||
|
||||
@@ -423,10 +363,10 @@ AT_CHECK_DOXYGEN([Private])
|
||||
# is specified, then Bison should accept the input, but compilation will fail,
|
||||
# so don't check compilation.
|
||||
m4_pushdef([AT_TEST],
|
||||
[AT_BISON_OPTION_PUSHDEFS([%language "C++" %define api.namespace {$1}])
|
||||
[AT_BISON_OPTION_PUSHDEFS([%language "C++" %define api.namespace "$1"])
|
||||
AT_DATA_GRAMMAR([[input.y]],
|
||||
[[%language "C++"
|
||||
%define api.namespace {]$1[}
|
||||
%define api.namespace "]$1["
|
||||
%union { int i; }
|
||||
%define global_tokens_and_yystype
|
||||
%locations
|
||||
@@ -482,8 +422,8 @@ AT_CLEANUP
|
||||
AT_SETUP([[Syntactically invalid namespace references]])
|
||||
AT_TEST([[:foo:bar]], [[-]])
|
||||
AT_TEST([[foo: :bar]], [[-]])
|
||||
# This one is interesting because '[3]' is encoded as '@<:@3@:>@', which
|
||||
# contains single occurrences of ':'.
|
||||
# This one is interesting because `[3]' is encoded as `@<:@3@:>@', which
|
||||
# contains single occurrences of `:'.
|
||||
AT_TEST([[foo[3]::bar::baz]], [[-]])
|
||||
AT_TEST([[foo::bar,baz]], [[-]])
|
||||
AT_TEST([[foo::bar::(baz /* Pacify Emacs ) */]], [[-]])
|
||||
@@ -675,42 +615,14 @@ $1
|
||||
/// A class that counts its number of instances.
|
||||
struct Object
|
||||
{
|
||||
char val;
|
||||
|
||||
Object (char v)
|
||||
: val (v)
|
||||
{
|
||||
Object::instances.push_back(this);
|
||||
log (this, "Object::Object");
|
||||
}
|
||||
|
||||
Object ()
|
||||
: val ('?')
|
||||
{
|
||||
Object::instances.push_back(this);
|
||||
log (this, "Object::Object");
|
||||
}
|
||||
|
||||
Object& operator= (char v)
|
||||
{
|
||||
val = v;
|
||||
return *this;
|
||||
}
|
||||
|
||||
~Object ()
|
||||
{
|
||||
Object::instances.remove (this);
|
||||
log (this, "Object::~Object");
|
||||
}
|
||||
|
||||
// Static part.
|
||||
typedef std::list<const Object*> objects;
|
||||
static objects instances;
|
||||
char val;
|
||||
|
||||
static bool
|
||||
empty ()
|
||||
{
|
||||
return instances.empty ();
|
||||
return instances.empty();
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -733,6 +645,26 @@ $1
|
||||
std::cerr << " }" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
Object (char v)
|
||||
: val (v)
|
||||
{
|
||||
instances.push_back(this);
|
||||
log (this, "Object::Object");
|
||||
}
|
||||
|
||||
Object ()
|
||||
: val ('?')
|
||||
{
|
||||
instances.push_back(this);
|
||||
log (this, "Object::Object");
|
||||
}
|
||||
|
||||
~Object ()
|
||||
{
|
||||
instances.remove(this);
|
||||
log (this, "Object::~Object");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -790,16 +722,16 @@ list:
|
||||
;
|
||||
|
||||
item:
|
||||
'a' { $$][ = $][1; }
|
||||
| 'e' { YYUSE ($][$); YYUSE($][1); error ("syntax error"); }
|
||||
'a' { $$][ = $][1; }
|
||||
| 'e' { YYUSE ($][$); YYUSE($][1); error ("syntax error"); }
|
||||
// Not just 'E', otherwise we reduce when 'E' is the lookahead, and
|
||||
// then the stack is emptied, defeating the point of the test.
|
||||
| 'E' 'a' { YYUSE($][1); $][$ = $][2; }
|
||||
| 'R' { ]AT_VARIANT_IF([], [$][$ = YY_NULL; delete $][1]; )[YYERROR; }
|
||||
| 'p' { $][$ = $][1; }
|
||||
| 's' { $][$ = $][1; throw std::runtime_error ("reduction"); }
|
||||
| 'T' { ]AT_VARIANT_IF([], [$][$ = YY_NULL; delete $][1]; )[YYABORT; }
|
||||
| error { ]AT_VARIANT_IF([], [$][$ = YY_NULL; ])[yyerrok; }
|
||||
| 'R' { $][$ = YY_NULL; ]AT_VARIANT_IF([], [delete $][1]; )[YYERROR; }
|
||||
| 'p' { $][$ = $][1; }
|
||||
| 's' { $][$ = $][1; throw std::runtime_error ("reduction"); }
|
||||
| 'T' { $][$ = YY_NULL; ]AT_VARIANT_IF([], [delete $][1]; )[YYABORT; }
|
||||
| error { $][$ = YY_NULL; yyerrok; }
|
||||
;
|
||||
%%
|
||||
|
||||
@@ -872,7 +804,7 @@ main (int argc, const char *argv[])
|
||||
}
|
||||
]])
|
||||
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]], [[]],
|
||||
[[exception caught: reduction
|
||||
|
||||
+48
-48
@@ -27,11 +27,11 @@
|
||||
|
||||
# _AT_DATA_CALC_Y($1, $2, $3, [BISON-DIRECTIVES])
|
||||
# -----------------------------------------------
|
||||
# Produce 'calc.y' and, if %defines was specified, 'calc-lex.c' or
|
||||
# 'calc-lex.cc'.
|
||||
# Produce `calc.y' and, if %defines was specified, `calc-lex.c' or
|
||||
# `calc-lex.cc'.
|
||||
#
|
||||
# Don't call this macro directly, because it contains some occurrences
|
||||
# of '$1' etc. which will be interpreted by m4. So you should call it
|
||||
# of `$1' etc. which will be interpreted by m4. So you should call it
|
||||
# with $1, $2, and $3 as arguments, which is what AT_DATA_CALC_Y does.
|
||||
#
|
||||
# When %defines is not passed, generate a single self-contained file.
|
||||
@@ -72,12 +72,10 @@ main (int argc, const char **argv)
|
||||
int count = 0;
|
||||
int status;
|
||||
|
||||
/* This used to be alarm (10), but that isn't enough time for a July
|
||||
1995 vintage DEC Alphastation 200 4/100 system, according to
|
||||
Nelson H. F. Beebe. 100 seconds was enough for regular users,
|
||||
but the Hydra build farm, which is heavily loaded needs more. */
|
||||
|
||||
alarm (200);
|
||||
/* This used to be alarm (10), but that isn't enough time for
|
||||
a July 1995 vintage DEC Alphastation 200 4/100 system,
|
||||
according to Nelson H. F. Beebe. 100 seconds is enough. */
|
||||
alarm (100);
|
||||
|
||||
if (argc == 2)
|
||||
input = fopen (argv[1], "r");
|
||||
@@ -90,7 +88,8 @@ main (int argc, const char **argv)
|
||||
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]])[);
|
||||
if (fclose (input))
|
||||
perror ("fclose");
|
||||
@@ -134,7 +133,7 @@ unget_char (]AT_YYLEX_PRE_FORMALS[ int c)
|
||||
{
|
||||
]AT_USE_LEX_ARGS[;
|
||||
]AT_LOCATION_IF([
|
||||
/* Wrong when C == '\n'. */
|
||||
/* Wrong when C == `\n'. */
|
||||
AT_LOC = last_yylloc;
|
||||
])[
|
||||
ungetc (c, input);
|
||||
@@ -366,8 +365,8 @@ m4_popdef([AT_CALC_LEX])
|
||||
|
||||
# AT_DATA_CALC_Y([BISON-OPTIONS])
|
||||
# -------------------------------
|
||||
# Produce 'calc.y' and, if %defines was specified, 'calc-lex.c' or
|
||||
# 'calc-lex.cc'.
|
||||
# Produce `calc.y' and, if %defines was specified, `calc-lex.c' or
|
||||
# `calc-lex.cc'.
|
||||
m4_define([AT_DATA_CALC_Y],
|
||||
[_AT_DATA_CALC_Y($[1], $[2], $[3], [$1])
|
||||
])
|
||||
@@ -376,9 +375,9 @@ m4_define([AT_DATA_CALC_Y],
|
||||
|
||||
# _AT_CHECK_CALC(BISON-OPTIONS, INPUT, [NUM-STDERR-LINES])
|
||||
# --------------------------------------------------------
|
||||
# Run 'calc' on INPUT and expect no STDOUT nor STDERR.
|
||||
# Run `calc' on INPUT and expect no STDOUT nor STDERR.
|
||||
#
|
||||
# If BISON-OPTIONS contains '%debug' but not '%glr-parser', then
|
||||
# If BISON-OPTIONS contains `%debug' but not `%glr-parser', then
|
||||
#
|
||||
# NUM-STDERR-LINES is the number of expected lines on stderr.
|
||||
# Currently this is ignored, though, since the output format is fluctuating.
|
||||
@@ -397,7 +396,7 @@ AT_PARSER_CHECK([./calc input], 0, [], [stderr])
|
||||
# [NUM-STDERR-LINES],
|
||||
# [VERBOSE-AND-LOCATED-ERROR-MESSAGE])
|
||||
# ---------------------------------------------------------
|
||||
# Run 'calc' on INPUT, and expect a 'syntax error' message.
|
||||
# Run `calc' on INPUT, and expect a `syntax error' message.
|
||||
#
|
||||
# If INPUT starts with a slash, it is used as absolute input file name,
|
||||
# otherwise as contents.
|
||||
@@ -405,14 +404,14 @@ AT_PARSER_CHECK([./calc input], 0, [], [stderr])
|
||||
# NUM-STDERR-LINES is the number of expected lines on stderr.
|
||||
# Currently this is ignored, though, since the output format is fluctuating.
|
||||
#
|
||||
# If BISON-OPTIONS contains '%location', then make sure the ERROR-LOCATION
|
||||
# If BISON-OPTIONS contains `%location', then make sure the ERROR-LOCATION
|
||||
# is correctly output on stderr.
|
||||
#
|
||||
# If BISON-OPTIONS contains '%define parse.error verbose', then make sure the
|
||||
# IF-YYERROR-VERBOSE message is properly output after 'syntax error, '
|
||||
# If BISON-OPTIONS contains `%define parse.error verbose', then make sure the
|
||||
# IF-YYERROR-VERBOSE message is properly output after `syntax error, '
|
||||
# on STDERR.
|
||||
#
|
||||
# If BISON-OPTIONS contains '%debug' but not '%glr', then NUM-STDERR-LINES
|
||||
# If BISON-OPTIONS contains `%debug' but not `%glr', then NUM-STDERR-LINES
|
||||
# is the number of expected lines on stderr.
|
||||
m4_define([_AT_CHECK_CALC_ERROR],
|
||||
[m4_bmatch([$3], [^/],
|
||||
@@ -449,7 +448,7 @@ AT_DATA([[expout]],
|
||||
AT_YYERROR_SEES_LOC_IF([],
|
||||
[[sed 's/^[-0-9.]*: //' expout >at-expout
|
||||
mv at-expout expout]])
|
||||
# 4. If error-verbose is not used, strip the', unexpected....' part.
|
||||
# 4. If error-verbose is not used, strip the`, unexpected....' part.
|
||||
m4_bmatch([$1], [%define parse.error verbose], [],
|
||||
[[sed 's/syntax error, .*$/syntax error/' expout >at-expout
|
||||
mv at-expout expout]])
|
||||
@@ -479,7 +478,7 @@ m4_define([AT_CHECK_SPACES],
|
||||
|
||||
# AT_CHECK_CALC([BISON-OPTIONS])
|
||||
# ------------------------------
|
||||
# Start a testing chunk which compiles 'calc' grammar with
|
||||
# Start a testing chunk which compiles `calc' grammar with
|
||||
# BISON-OPTIONS, and performs several tests over the parser.
|
||||
m4_define([AT_CHECK_CALC],
|
||||
[m4_ifval([$2], [m4_fatal([$0: expected a single argument])])
|
||||
@@ -539,7 +538,7 @@ _AT_CHECK_CALC_ERROR([$1], [1], [/dev/null], [4],
|
||||
# - (* * *): nothing to pop, a lot to discard
|
||||
# - (1 + 2 * *): some to pop and discard
|
||||
#
|
||||
# - test the action associated to 'error'
|
||||
# - test the action associated to `error'
|
||||
#
|
||||
# - check the lookahead that triggers an error is not discarded
|
||||
# when we enter error recovery. Below, the lookahead causing the
|
||||
@@ -588,7 +587,7 @@ AT_BANNER([[Simple LALR(1) Calculator.]])
|
||||
|
||||
# AT_CHECK_CALC_LALR([BISON-OPTIONS])
|
||||
# -----------------------------------
|
||||
# Start a testing chunk which compiles 'calc' grammar with
|
||||
# Start a testing chunk which compiles `calc' grammar with
|
||||
# BISON-OPTIONS, and performs several tests over the parser.
|
||||
m4_define([AT_CHECK_CALC_LALR],
|
||||
[AT_CHECK_CALC($@)])
|
||||
@@ -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 parse.error verbose %locations])
|
||||
|
||||
AT_CHECK_CALC_LALR([%define parse.error verbose %locations %defines %define api.prefix {calc} %verbose %yacc])
|
||||
AT_CHECK_CALC_LALR([%define parse.error verbose %locations %defines %name-prefix "calc" %define api.token.prefix {TOK_} %verbose %yacc])
|
||||
AT_CHECK_CALC_LALR([%define parse.error verbose %locations %defines %define api.prefix "calc" %verbose %yacc])
|
||||
AT_CHECK_CALC_LALR([%define parse.error verbose %locations %defines %name-prefix "calc" %define api.token.prefix "TOK_" %verbose %yacc])
|
||||
|
||||
AT_CHECK_CALC_LALR([%debug])
|
||||
AT_CHECK_CALC_LALR([%define parse.error verbose %debug %locations %defines %name-prefix "calc" %verbose %yacc])
|
||||
AT_CHECK_CALC_LALR([%define parse.error verbose %debug %locations %defines %define api.prefix {calc} %verbose %yacc])
|
||||
AT_CHECK_CALC_LALR([%define parse.error verbose %debug %locations %defines %define api.prefix "calc" %verbose %yacc])
|
||||
|
||||
AT_CHECK_CALC_LALR([%define api.pure full %define parse.error verbose %debug %locations %defines %name-prefix "calc" %verbose %yacc])
|
||||
AT_CHECK_CALC_LALR([%define api.push-pull both %define api.pure full %define parse.error verbose %debug %locations %defines %define api.prefix {calc} %verbose %yacc])
|
||||
AT_CHECK_CALC_LALR([%define api.push-pull both %define api.pure full %define parse.error verbose %debug %locations %defines %define api.prefix "calc" %verbose %yacc])
|
||||
|
||||
AT_CHECK_CALC_LALR([%define api.pure %define parse.error verbose %debug %locations %defines %define api.prefix {calc} %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}])
|
||||
AT_CHECK_CALC_LALR([%define api.pure %define parse.error verbose %debug %locations %defines %define api.prefix "calc" %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}])
|
||||
|
||||
|
||||
# ----------------------- #
|
||||
@@ -628,7 +627,7 @@ AT_BANNER([[Simple GLR Calculator.]])
|
||||
|
||||
# AT_CHECK_CALC_GLR([BISON-OPTIONS])
|
||||
# ----------------------------------
|
||||
# Start a testing chunk which compiles 'calc' grammar with
|
||||
# Start a testing chunk which compiles `calc' grammar with
|
||||
# BISON-OPTIONS and %glr-parser, and performs several tests over the parser.
|
||||
m4_define([AT_CHECK_CALC_GLR],
|
||||
[AT_CHECK_CALC([%glr-parser] $@)])
|
||||
@@ -639,7 +638,7 @@ AT_CHECK_CALC_GLR()
|
||||
AT_CHECK_CALC_GLR([%defines])
|
||||
AT_CHECK_CALC_GLR([%locations])
|
||||
AT_CHECK_CALC_GLR([%name-prefix "calc"])
|
||||
AT_CHECK_CALC_GLR([%define api.prefix {calc}])
|
||||
AT_CHECK_CALC_GLR([%define api.prefix "calc"])
|
||||
AT_CHECK_CALC_GLR([%verbose])
|
||||
AT_CHECK_CALC_GLR([%yacc])
|
||||
AT_CHECK_CALC_GLR([%define parse.error verbose])
|
||||
@@ -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([%define parse.error verbose %debug %locations %defines %name-prefix "calc" %verbose %yacc])
|
||||
AT_CHECK_CALC_GLR([%define parse.error verbose %debug %locations %defines %define api.prefix {calc} %define api.token.prefix {TOK_} %verbose %yacc])
|
||||
AT_CHECK_CALC_GLR([%define parse.error verbose %debug %locations %defines %define api.prefix "calc" %define api.token.prefix "TOK_" %verbose %yacc])
|
||||
|
||||
AT_CHECK_CALC_GLR([%define api.pure %define parse.error verbose %debug %locations %defines %name-prefix "calc" %verbose %yacc])
|
||||
|
||||
AT_CHECK_CALC_GLR([%define api.pure %define parse.error verbose %debug %locations %defines %name-prefix "calc" %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}])
|
||||
AT_CHECK_CALC_GLR([%define api.pure %define parse.error verbose %debug %locations %defines %define api.prefix {calc} %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}])
|
||||
AT_CHECK_CALC_GLR([%define api.pure %define parse.error verbose %debug %locations %defines %define api.prefix "calc" %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}])
|
||||
|
||||
|
||||
# ----------------------------- #
|
||||
@@ -670,26 +669,26 @@ AT_CHECK_CALC([%skeleton "lalr1.cc" %defines])
|
||||
|
||||
# AT_CHECK_CALC_LALR1_CC([BISON-OPTIONS])
|
||||
# ---------------------------------------
|
||||
# Start a testing chunk which compiles 'calc' grammar with
|
||||
# Start a testing chunk which compiles `calc' grammar with
|
||||
# the C++ skeleton, and performs several tests over the parser.
|
||||
m4_define([AT_CHECK_CALC_LALR1_CC],
|
||||
[AT_CHECK_CALC([%language "C++"] $@)])
|
||||
|
||||
AT_CHECK_CALC_LALR1_CC([])
|
||||
AT_CHECK_CALC_LALR1_CC([%locations])
|
||||
AT_CHECK_CALC_LALR1_CC([%locations %define api.location.type {Span}])
|
||||
AT_CHECK_CALC_LALR1_CC([%locations %define api.location.type Span])
|
||||
AT_CHECK_CALC_LALR1_CC([%defines %locations %define parse.error verbose %name-prefix "calc" %verbose %yacc])
|
||||
|
||||
AT_CHECK_CALC_LALR1_CC([%locations %define parse.error verbose %define api.prefix {calc} %verbose %yacc])
|
||||
AT_CHECK_CALC_LALR1_CC([%locations %define parse.error verbose %define api.prefix "calc" %verbose %yacc])
|
||||
AT_CHECK_CALC_LALR1_CC([%locations %define parse.error verbose %debug %name-prefix "calc" %verbose %yacc])
|
||||
|
||||
AT_CHECK_CALC_LALR1_CC([%locations %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" %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([%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([%pure-parser %define parse.error verbose %debug %define api.prefix "calc" %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}])
|
||||
AT_CHECK_CALC_LALR1_CC([%defines %locations %pure-parser %define parse.error verbose %debug %define api.prefix "calc" %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}])
|
||||
|
||||
|
||||
|
||||
@@ -704,21 +703,22 @@ AT_CHECK_CALC([%skeleton "glr.cc"])
|
||||
|
||||
# AT_CHECK_CALC_GLR_CC([BISON-OPTIONS])
|
||||
# -------------------------------------
|
||||
# Start a testing chunk which compiles 'calc' grammar with
|
||||
# Start a testing chunk which compiles `calc' grammar with
|
||||
# the GLR C++ skeleton, and performs several tests over the parser.
|
||||
m4_define([AT_CHECK_CALC_GLR_CC],
|
||||
[AT_CHECK_CALC([%language "C++" %glr-parser] $@)])
|
||||
|
||||
AT_CHECK_CALC_GLR_CC([])
|
||||
AT_CHECK_CALC_GLR_CC([%locations])
|
||||
AT_CHECK_CALC_GLR_CC([%locations %define api.location.type {Span}])
|
||||
AT_CHECK_CALC_GLR_CC([%locations %define api.location.type Span])
|
||||
AT_CHECK_CALC_GLR_CC([%defines %define parse.error verbose %name-prefix "calc" %verbose %yacc])
|
||||
AT_CHECK_CALC_GLR_CC([%define parse.error verbose %define api.prefix {calc} %verbose %yacc])
|
||||
AT_CHECK_CALC_GLR_CC([%define parse.error verbose %define api.prefix "calc" %verbose %yacc])
|
||||
|
||||
AT_CHECK_CALC_GLR_CC([%debug])
|
||||
|
||||
AT_CHECK_CALC_GLR_CC([%define parse.error verbose %debug %name-prefix "calc" %verbose %yacc])
|
||||
AT_CHECK_CALC_GLR_CC([%define parse.error verbose %debug %name-prefix "calc" %define api.token.prefix {TOK_} %verbose %yacc])
|
||||
|
||||
AT_CHECK_CALC_GLR_CC([%locations %defines %define parse.error verbose %debug %name-prefix "calc" %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}])
|
||||
AT_CHECK_CALC_GLR_CC([%locations %defines %define parse.error verbose %debug %define api.prefix {calc} %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}])
|
||||
AT_CHECK_CALC_GLR_CC([%pure-parser %define parse.error verbose %debug %name-prefix "calc" %verbose %yacc])
|
||||
AT_CHECK_CALC_GLR_CC([%pure-parser %define parse.error verbose %debug %name-prefix "calc" %define api.token.prefix "TOK_" %verbose %yacc])
|
||||
|
||||
AT_CHECK_CALC_GLR_CC([%locations %defines %pure-parser %define parse.error verbose %debug %name-prefix "calc" %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}])
|
||||
AT_CHECK_CALC_GLR_CC([%locations %defines %pure-parser %define parse.error verbose %debug %define api.prefix "calc" %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}])
|
||||
|
||||
+86
-300
@@ -17,155 +17,42 @@
|
||||
|
||||
AT_BANNER([[Conflicts.]])
|
||||
|
||||
## ----------------- ##
|
||||
## Precedence groups ##
|
||||
## ----------------- ##
|
||||
|
||||
# Sample use case of precedence groups and relations, working.
|
||||
|
||||
AT_SETUP([Precedence groups])
|
||||
|
||||
AT_DATA_GRAMMAR([[input.y]],
|
||||
[[%token CARET "^"
|
||||
%token NUM BOOL '^' OR AND
|
||||
|
||||
%left '+' '-'
|
||||
%gprec {
|
||||
%right CARET
|
||||
}
|
||||
%gprec boolean {
|
||||
%left OR
|
||||
%left AND
|
||||
}
|
||||
%left '*' '/'
|
||||
|
||||
%precr boolean >> "^"
|
||||
%precr CARET > '*' '/' '-' '+'
|
||||
|
||||
%%
|
||||
|
||||
stmt:
|
||||
exp
|
||||
| bool_exp
|
||||
|
||||
exp:
|
||||
NUM
|
||||
| exp '+' exp
|
||||
| exp '-' exp
|
||||
| exp '*' exp
|
||||
| exp '/' exp
|
||||
| exp "^" exp
|
||||
|
||||
bool_exp:
|
||||
BOOL
|
||||
| bool_exp AND bool_exp
|
||||
| bool_exp OR bool_exp
|
||||
| bool_exp CARET bool_exp
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK([[--report=all -o input.c input.y]], 0, [])
|
||||
|
||||
AT_CLEANUP
|
||||
|
||||
## -------------------------------- ##
|
||||
## Conflicting precedence relations ##
|
||||
## -------------------------------- ##
|
||||
|
||||
AT_SETUP([Conflicting precedence relations])
|
||||
|
||||
AT_DATA_GRAMMAR([[input.y]],
|
||||
[[%token TOKEN
|
||||
%precedence A
|
||||
%precedence B
|
||||
%precedence C
|
||||
%precedence D E
|
||||
|
||||
%gprec group {
|
||||
%precedence F
|
||||
%precedence G
|
||||
}
|
||||
|
||||
%precr B = C
|
||||
%precr A > B
|
||||
%precr C > B
|
||||
%precr F > G
|
||||
%precr F > A
|
||||
%%
|
||||
exp:
|
||||
TOKEN
|
||||
| exp A exp
|
||||
| exp B exp
|
||||
| exp C exp
|
||||
| exp D exp
|
||||
| exp E exp
|
||||
| exp F exp
|
||||
| exp G exp
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK([[-Wall -o input.c input.y]], 0, [],
|
||||
[[input.y:20.10: warning: contradicting declaration: B = C is in conflict with the previous declaration: B > C [-Wprecedence]
|
||||
input.y:21.10: warning: contradicting declaration: A > B is in conflict with the previous declaration: A < B [-Wprecedence]
|
||||
input.y:22.10: warning: contradicting declaration: C > B is in conflict with the previous declaration: C = B [-Wprecedence]
|
||||
input.y:23.10: warning: contradicting declaration: F > G is in conflict with the previous declaration: F < G [-Wprecedence]
|
||||
input.y: warning: 27 shift/reduce conflicts [-Wconflicts-sr]
|
||||
]])
|
||||
|
||||
AT_CLEANUP
|
||||
|
||||
## ------------------------------ ##
|
||||
## Duplicate precedence relations ##
|
||||
## Useless associativity warning. ##
|
||||
## ------------------------------ ##
|
||||
|
||||
AT_SETUP([Duplicate precedence relations])
|
||||
AT_SETUP([Useless associativity warning])
|
||||
|
||||
AT_DATA_GRAMMAR([[input.y]],
|
||||
[[%token TOKEN
|
||||
%precedence A
|
||||
%precedence B
|
||||
%precedence C
|
||||
%precedence D E
|
||||
AT_DATA([[input.y]],
|
||||
[[%token T
|
||||
%left A B
|
||||
%right C
|
||||
%nonassoc D
|
||||
%precedence E
|
||||
|
||||
%gprec group {
|
||||
%precedence F
|
||||
%precedence G
|
||||
}
|
||||
|
||||
%precr D = E
|
||||
%precr B > A
|
||||
%precr C > B
|
||||
%precr G > F
|
||||
%precr F > A
|
||||
%precr C > group
|
||||
%precr C > F
|
||||
%%
|
||||
exp:
|
||||
TOKEN
|
||||
| exp A exp
|
||||
| exp B exp
|
||||
| exp C exp
|
||||
| exp D exp
|
||||
| exp E exp
|
||||
| exp F exp
|
||||
| exp G exp
|
||||
e: T A T
|
||||
| T B T
|
||||
| T C T
|
||||
| T D T
|
||||
| T E T
|
||||
;
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK([[-Wall -o input.c input.y]], 0, [],
|
||||
[[input.y:20.10: warning: duplicate declaration of the precedence relationship D = E [-Wprecedence]
|
||||
input.y:20.10: warning: duplicate declaration of the precedence relationship E = D [-Wprecedence]
|
||||
input.y:21.10: warning: duplicate declaration of the precedence relationship B > A [-Wprecedence]
|
||||
input.y:22.10: warning: duplicate declaration of the precedence relationship C > B [-Wprecedence]
|
||||
input.y:23.10: warning: duplicate declaration of the precedence relationship G > F [-Wprecedence]
|
||||
input.y:26.10: warning: duplicate declaration of the precedence relationship C > F [-Wprecedence]
|
||||
input.y: warning: 23 shift/reduce conflicts [-Wconflicts-sr]
|
||||
AT_BISON_CHECK([input.y], 0, [],
|
||||
[[input.y:5.13: warning: useless precedence for E [-Wother]
|
||||
input.y:2.7: warning: useless associativity for A [-Wother]
|
||||
input.y:2.9: warning: useless associativity for B [-Wother]
|
||||
input.y:3.8: warning: useless associativity for C [-Wother]
|
||||
input.y:4.11: warning: useless associativity for D [-Wother]
|
||||
]])
|
||||
|
||||
AT_CLEANUP
|
||||
|
||||
|
||||
|
||||
## ------------------------- ##
|
||||
## Token declaration order. ##
|
||||
## ------------------------- ##
|
||||
## ------------------------ ##
|
||||
## Token declaration order. ##
|
||||
## ------------------------ ##
|
||||
|
||||
# This test checks that token are declared left to right when in a precedence
|
||||
# statement.
|
||||
@@ -223,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_PARSER_CHECK([./input])
|
||||
@@ -233,127 +140,6 @@ AT_BISON_OPTION_POPDEFS
|
||||
AT_CLEANUP
|
||||
|
||||
|
||||
## --------------------------------------------------- ##
|
||||
## Token declaration order: literals vs. identifiers. ##
|
||||
## --------------------------------------------------- ##
|
||||
|
||||
# This test checks that when several tokens are declared by the same keyword,
|
||||
# some of them defined as a character ('a'), others as simple textual reference
|
||||
# (A), they are declared correctly left to right.
|
||||
# Previously, the following test would declare the states in the order 'o' 'p'
|
||||
# M N, instead of M N 'o' 'p'.
|
||||
|
||||
AT_SETUP([Token declaration order: literals vs. identifiers])
|
||||
|
||||
AT_DATA_GRAMMAR([[input.y]],
|
||||
[[%token 'a' 'b' C D
|
||||
%token E F 'g' 'h'
|
||||
%right 'i' 'j' K L
|
||||
%right M N 'o' 'p'
|
||||
%%
|
||||
exp: 'a'
|
||||
| 'b'
|
||||
| C
|
||||
| D
|
||||
| E
|
||||
| F
|
||||
| 'g'
|
||||
| 'h'
|
||||
| 'i'
|
||||
| 'j'
|
||||
| K
|
||||
| L
|
||||
| M
|
||||
| N
|
||||
| 'o'
|
||||
| 'p'
|
||||
;
|
||||
%%
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK([[--report=all -o input.c input.y]], 0, [], [ignore])
|
||||
AT_CHECK([[cat input.output | sed -n '/^State 0$/,/^State 1$/p']], 0,
|
||||
[[State 0
|
||||
|
||||
0 $accept: . exp $end
|
||||
1 exp: . 'a'
|
||||
2 | . 'b'
|
||||
3 | . C
|
||||
4 | . D
|
||||
5 | . E
|
||||
6 | . F
|
||||
7 | . 'g'
|
||||
8 | . 'h'
|
||||
9 | . 'i'
|
||||
10 | . 'j'
|
||||
11 | . K
|
||||
12 | . L
|
||||
13 | . M
|
||||
14 | . N
|
||||
15 | . 'o'
|
||||
16 | . 'p'
|
||||
|
||||
'a' shift, and go to state 1
|
||||
'b' shift, and go to state 2
|
||||
C shift, and go to state 3
|
||||
D shift, and go to state 4
|
||||
E shift, and go to state 5
|
||||
F shift, and go to state 6
|
||||
'g' shift, and go to state 7
|
||||
'h' shift, and go to state 8
|
||||
'i' shift, and go to state 9
|
||||
'j' shift, and go to state 10
|
||||
K shift, and go to state 11
|
||||
L shift, and go to state 12
|
||||
M shift, and go to state 13
|
||||
N shift, and go to state 14
|
||||
'o' shift, and go to state 15
|
||||
'p' shift, and go to state 16
|
||||
|
||||
exp go to state 17
|
||||
|
||||
|
||||
State 1
|
||||
]])
|
||||
|
||||
AT_CLEANUP
|
||||
|
||||
|
||||
## ------------------------------- ##
|
||||
## Useless associativity warning. ##
|
||||
## ------------------------------- ##
|
||||
|
||||
AT_SETUP([Useless associativity warning])
|
||||
|
||||
AT_DATA([[input.y]],
|
||||
[[%token EQ "=" PL "+" ST "*" LP "("
|
||||
%nonassoc "="
|
||||
%left "+"
|
||||
%left "*"
|
||||
%precedence "("
|
||||
%%
|
||||
stmt:
|
||||
exp
|
||||
| "var" "=" exp
|
||||
;
|
||||
|
||||
exp:
|
||||
exp "+" exp
|
||||
| exp "*" "num"
|
||||
| "(" exp ")"
|
||||
| "num"
|
||||
;
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK([-Wprecedence input.y], 0, [],
|
||||
[[input.y:2.1-9: warning: useless precedence and associativity for "=" [-Wprecedence]
|
||||
input.y:4.1-5: warning: useless associativity for "*", use %precedence [-Wprecedence]
|
||||
input.y:5.1-11: warning: useless precedence for "(" [-Wprecedence]
|
||||
]])
|
||||
|
||||
AT_CLEANUP
|
||||
|
||||
|
||||
## ---------------------------- ##
|
||||
## Useless precedence warning. ##
|
||||
## ---------------------------- ##
|
||||
@@ -361,7 +147,7 @@ AT_CLEANUP
|
||||
AT_SETUP([Useless precedence warning])
|
||||
|
||||
AT_DATA([[input.y]],
|
||||
[[%token A B U V W X Y Z
|
||||
[[%token A B
|
||||
%precedence Z
|
||||
%left X
|
||||
%precedence Y
|
||||
@@ -388,19 +174,19 @@ f: B
|
||||
;
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK([-Wprecedence -fcaret -o input.c input.y], 0, [],
|
||||
[[input.y:7.1-9: warning: useless precedence and associativity for U [-Wprecedence]
|
||||
%nonassoc U
|
||||
^^^^^^^^^
|
||||
input.y:6.1-6: warning: useless precedence and associativity for V [-Wprecedence]
|
||||
%right V
|
||||
^^^^^^
|
||||
input.y:5.1-5: warning: useless precedence and associativity for W [-Wprecedence]
|
||||
%left W
|
||||
^^^^^
|
||||
input.y:2.1-11: warning: useless precedence for Z [-Wprecedence]
|
||||
AT_BISON_CHECK([-fcaret -o input.c input.y], 0, [],
|
||||
[[input.y:2.13: warning: useless precedence for Z [-Wother]
|
||||
%precedence Z
|
||||
^^^^^^^^^^^
|
||||
^
|
||||
input.y:5.7: warning: useless associativity for W [-Wother]
|
||||
%left W
|
||||
^
|
||||
input.y:6.8: warning: useless associativity for V [-Wother]
|
||||
%right V
|
||||
^
|
||||
input.y:7.11: warning: useless associativity for U [-Wother]
|
||||
%nonassoc U
|
||||
^
|
||||
]])
|
||||
|
||||
AT_CLEANUP
|
||||
@@ -425,7 +211,7 @@ e: 'e' | /* Nothing. */;
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK([-o input.c input.y], 0, [],
|
||||
[[input.y:4.9: warning: rule useless in parser due to conflicts [-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, [],
|
||||
@@ -1153,7 +939,7 @@ cond:
|
||||
|
||||
AT_BISON_CHECK([-o input.c input.y], 0, [],
|
||||
[[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
|
||||
input.y:12.3-18: warning: rule useless in parser due to conflicts [-Wother]
|
||||
input.y:12.3-18: warning: rule useless in parser due to conflicts: cond: cond "then" cond [-Wother]
|
||||
]])
|
||||
|
||||
AT_CLEANUP
|
||||
@@ -1169,13 +955,13 @@ AT_CLEANUP
|
||||
# $end reduce using rule 3 (num)
|
||||
# $end [reduce using rule 4 (id)]
|
||||
#
|
||||
# But when 'reduce 3' is the default action, we'd produce:
|
||||
# But when `reduce 3' is the default action, we'd produce:
|
||||
#
|
||||
# $end [reduce using rule 4 (id)]
|
||||
# $default reduce using rule 3 (num)
|
||||
#
|
||||
# In this precise case (a reduction is masked by the default
|
||||
# reduction), we make the 'reduce 3' explicit:
|
||||
# reduction), we make the `reduce 3' explicit:
|
||||
#
|
||||
# $end reduce using rule 3 (num)
|
||||
# $end [reduce using rule 4 (id)]
|
||||
@@ -1197,7 +983,7 @@ id : '0';
|
||||
|
||||
AT_BISON_CHECK([-o input.c --report=all input.y], 0, [],
|
||||
[[input.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
|
||||
input.y:4.6-8: warning: rule useless in parser due to conflicts [-Wother]
|
||||
input.y:4.6-8: warning: rule useless in parser due to conflicts: id: '0' [-Wother]
|
||||
]])
|
||||
|
||||
# Check the contents of the report.
|
||||
@@ -1410,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:1.1-5: warning: useless precedence and associativity for '+' [-Wprecedence]
|
||||
input.y:2.1-5: warning: useless precedence and associativity for '*' [-Wprecedence]
|
||||
input.y:1.7-9: warning: useless associativity for '+' [-Wother]
|
||||
input.y:2.7-9: warning: useless associativity for '*' [-Wother]
|
||||
]])
|
||||
AT_CLEANUP
|
||||
|
||||
@@ -1517,13 +1303,13 @@ reported_conflicts:
|
||||
AT_BISON_CHECK([[--report=all input.y]], 0, [],
|
||||
[[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
|
||||
input.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
|
||||
input.y:12.5-20: warning: rule useless in parser due to conflicts [-Wother]
|
||||
input.y:20.5-20: warning: rule useless in parser due to conflicts [-Wother]
|
||||
input.y:21.4: warning: rule useless in parser due to conflicts [-Wother]
|
||||
input.y:25.13: warning: rule useless in parser due to conflicts [-Wother]
|
||||
input.y:25.16: warning: rule useless in parser due to conflicts [-Wother]
|
||||
input.y:31.5-7: warning: rule useless in parser due to conflicts [-Wother]
|
||||
input.y:32.4: warning: rule useless in parser due to conflicts [-Wother]
|
||||
input.y:12.5-20: warning: rule useless in parser due to conflicts: resolved_conflict: 'a' unreachable1 [-Wother]
|
||||
input.y:20.5-20: warning: rule useless in parser due to conflicts: unreachable1: 'a' unreachable2 [-Wother]
|
||||
input.y:21.4: warning: rule useless in parser due to conflicts: unreachable1: /* empty */ [-Wother]
|
||||
input.y:25.13: warning: rule useless in parser due to conflicts: unreachable2: /* empty */ [-Wother]
|
||||
input.y:25.16: warning: rule useless in parser due to conflicts: unreachable2: /* empty */ [-Wother]
|
||||
input.y:31.5-7: warning: rule useless in parser due to conflicts: reported_conflicts: 'a' [-Wother]
|
||||
input.y:32.4: warning: rule useless in parser due to conflicts: reported_conflicts: /* empty */ [-Wother]
|
||||
]])
|
||||
|
||||
AT_CHECK([[cat input.output]], 0,
|
||||
@@ -1532,13 +1318,13 @@ AT_CHECK([[cat input.output]], 0,
|
||||
2 resolved_conflict: 'a' unreachable1
|
||||
|
||||
4 unreachable1: 'a' unreachable2
|
||||
5 | %empty
|
||||
5 | /* empty */
|
||||
|
||||
6 unreachable2: %empty
|
||||
7 | %empty
|
||||
6 unreachable2: /* empty */
|
||||
7 | /* empty */
|
||||
|
||||
9 reported_conflicts: 'a'
|
||||
10 | %empty
|
||||
10 | /* empty */
|
||||
|
||||
|
||||
State 4 conflicts: 1 shift/reduce
|
||||
@@ -1552,17 +1338,17 @@ Grammar
|
||||
1 start: resolved_conflict 'a' reported_conflicts 'a'
|
||||
|
||||
2 resolved_conflict: 'a' unreachable1
|
||||
3 | %empty
|
||||
3 | /* empty */
|
||||
|
||||
4 unreachable1: 'a' unreachable2
|
||||
5 | %empty
|
||||
5 | /* empty */
|
||||
|
||||
6 unreachable2: %empty
|
||||
7 | %empty
|
||||
6 unreachable2: /* empty */
|
||||
7 | /* empty */
|
||||
|
||||
8 reported_conflicts: 'a'
|
||||
9 | 'a'
|
||||
10 | %empty
|
||||
10 | /* empty */
|
||||
|
||||
|
||||
Terminals, with rules where they appear
|
||||
@@ -1670,10 +1456,10 @@ AT_CHECK([[cat input.y >> input-keep.y]])
|
||||
AT_BISON_CHECK([[input-keep.y]], 0, [],
|
||||
[[input-keep.y: warning: 2 shift/reduce conflicts [-Wconflicts-sr]
|
||||
input-keep.y: warning: 2 reduce/reduce conflicts [-Wconflicts-rr]
|
||||
input-keep.y:22.4: warning: rule useless in parser due to conflicts [-Wother]
|
||||
input-keep.y:26.16: warning: rule useless in parser due to conflicts [-Wother]
|
||||
input-keep.y:32.5-7: warning: rule useless in parser due to conflicts [-Wother]
|
||||
input-keep.y:33.4: warning: rule useless in parser due to conflicts [-Wother]
|
||||
input-keep.y:22.4: warning: rule useless in parser due to conflicts: unreachable1: /* empty */ [-Wother]
|
||||
input-keep.y:26.16: warning: rule useless in parser due to conflicts: unreachable2: /* empty */ [-Wother]
|
||||
input-keep.y:32.5-7: warning: rule useless in parser due to conflicts: reported_conflicts: 'a' [-Wother]
|
||||
input-keep.y:33.4: warning: rule useless in parser due to conflicts: reported_conflicts: /* empty */ [-Wother]
|
||||
]])
|
||||
|
||||
AT_CLEANUP
|
||||
@@ -1853,7 +1639,7 @@ exp: 'a' | 'a';
|
||||
AT_BISON_CHECK([[2.y]], [[0]], [],
|
||||
[[2.y: warning: %expect-rr applies only to GLR parsers [-Wother]
|
||||
2.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
|
||||
2.y:3.12-14: warning: rule useless in parser due to conflicts [-Wother]
|
||||
2.y:3.12-14: warning: rule useless in parser due to conflicts: exp: 'a' [-Wother]
|
||||
]])
|
||||
|
||||
AT_CLEANUP
|
||||
|
||||
+147
-160
@@ -403,60 +403,68 @@ dnl parses it as:
|
||||
dnl
|
||||
dnl getline $!(4*0);
|
||||
dnl
|
||||
dnl That is, they shift '*' immediately and make it part of the getline
|
||||
dnl That is, they shift `*' immediately and make it part of the getline
|
||||
dnl argument.
|
||||
dnl
|
||||
dnl The grammar below using LALR(1) parses it as a syntax error. So does
|
||||
dnl GNU AWK 3.0.6, 3.1.0, and 3.1.1. They reduce the full getline expression
|
||||
dnl before shifting '*' even though '*' is not a valid lookahead.
|
||||
dnl before shifting `*' even though `*' is not a valid lookahead.
|
||||
dnl
|
||||
dnl GNU AWK 3.1.2, 3.1.3, 3.1.4, and 3.1.5 parse it as:
|
||||
dnl
|
||||
dnl (getline $!4)*0;
|
||||
dnl
|
||||
dnl That is, like the other versions of GNU AWK, they reduce the full getline
|
||||
dnl expression before shifting '*'. However, because of a different LHS on the
|
||||
dnl getline rule, '*' actually is a valid lookahead. Solaris /usr/xpg4/bin/awk
|
||||
dnl expression before shifting `*'. However, because of a different LHS on the
|
||||
dnl getline rule, `*' actually is a valid lookahead. Solaris /usr/xpg4/bin/awk
|
||||
dnl and the Open Group awk specification seem to agree:
|
||||
dnl
|
||||
dnl http://www.opengroup.org/pubs/online/7908799/xcu/awk.html
|
||||
dnl
|
||||
dnl /bin/nawk and /bin/awk on Solaris 10 report it as a syntax error, but they
|
||||
dnl don't like even 'print $!4;'.
|
||||
dnl don't like even `print $!4;'.
|
||||
[[LEX_GETLINE, '$', '!', YNUMBER, '*', YNUMBER, ';']],
|
||||
|
||||
dnl BISON-STDERR
|
||||
[[input.y:66.10: warning: empty rule without %empty [-Wempty-rule]
|
||||
input.y:169.8: warning: empty rule without %empty [-Wempty-rule]
|
||||
input.y:174.12: warning: empty rule without %empty [-Wempty-rule]
|
||||
input.y:179.13: warning: empty rule without %empty [-Wempty-rule]
|
||||
input.y:187.15: warning: empty rule without %empty [-Wempty-rule]
|
||||
input.y:201.8: warning: empty rule without %empty [-Wempty-rule]
|
||||
input.y:206.21: warning: empty rule without %empty [-Wempty-rule]
|
||||
input.y:220.20: warning: empty rule without %empty [-Wempty-rule]
|
||||
input.y:299.13: warning: empty rule without %empty [-Wempty-rule]
|
||||
input.y:322.9: warning: empty rule without %empty [-Wempty-rule]
|
||||
]AT_COND_CASE([[canonical LR]],
|
||||
[[input.y: warning: 265 shift/reduce conflicts [-Wconflicts-sr]]],
|
||||
[[input.y: warning: 65 shift/reduce conflicts [-Wconflicts-sr]]])[
|
||||
input.y:39.1-5: warning: useless associativity for FUNC_CALL, use %precedence [-Wprecedence]
|
||||
input.y:44.1-5: warning: useless associativity for YNUMBER, use %precedence [-Wprecedence]
|
||||
input.y:44.1-5: warning: useless associativity for YSTRING, use %precedence [-Wprecedence]
|
||||
input.y:42.1-9: warning: useless precedence and associativity for APPEND_OP [-Wprecedence]
|
||||
input.y:33.1-6: warning: useless associativity for ASSIGNOP, use %precedence [-Wprecedence]
|
||||
input.y:43.1-5: warning: useless associativity for CONCAT_OP, use %precedence [-Wprecedence]
|
||||
input.y:37.1-5: warning: useless precedence and associativity for LEX_GETLINE [-Wprecedence]
|
||||
input.y:38.1-9: warning: useless associativity for LEX_IN, use %precedence [-Wprecedence]
|
||||
input.y:49.1-5: warning: useless associativity for INCREMENT, use %precedence [-Wprecedence]
|
||||
input.y:49.1-5: warning: useless associativity for DECREMENT, use %precedence [-Wprecedence]
|
||||
input.y:39.1-5: warning: useless associativity for LEX_BUILTIN, use %precedence [-Wprecedence]
|
||||
input.y:39.1-5: warning: useless associativity for LEX_LENGTH, use %precedence [-Wprecedence]
|
||||
input.y:40.1-9: warning: useless precedence and associativity for ',' [-Wprecedence]
|
||||
input.y:47.1-6: warning: useless associativity for '!', use %precedence [-Wprecedence]
|
||||
input.y:47.1-6: warning: useless associativity for UNARY, use %precedence [-Wprecedence]
|
||||
input.y:50.1-5: warning: useless associativity for '$', use %precedence [-Wprecedence]
|
||||
input.y:51.1-5: warning: useless associativity for '(', use %precedence [-Wprecedence]
|
||||
input.y:51.1-5: warning: useless precedence and associativity for ')' [-Wprecedence]
|
||||
[AT_COND_CASE([[canonical LR]],
|
||||
[[input.y: warning: 265 shift/reduce conflicts [-Wconflicts-sr]
|
||||
input.y:19.8-16: warning: useless associativity for FUNC_CALL [-Wother]
|
||||
input.y:21.8-14: warning: useless associativity for YNUMBER [-Wother]
|
||||
input.y:21.16-22: warning: useless associativity for YSTRING [-Wother]
|
||||
input.y:22.14-22: warning: useless associativity for APPEND_OP [-Wother]
|
||||
input.y:23.8-15: warning: useless associativity for ASSIGNOP [-Wother]
|
||||
input.y:23.33-41: warning: useless associativity for CONCAT_OP [-Wother]
|
||||
input.y:27.8-18: warning: useless associativity for LEX_GETLINE [-Wother]
|
||||
input.y:28.8-13: warning: useless associativity for LEX_IN [-Wother]
|
||||
input.y:29.23-31: warning: useless associativity for INCREMENT [-Wother]
|
||||
input.y:29.33-41: warning: useless associativity for DECREMENT [-Wother]
|
||||
input.y:30.8-18: warning: useless associativity for LEX_BUILTIN [-Wother]
|
||||
input.y:30.20-29: warning: useless associativity for LEX_LENGTH [-Wother]
|
||||
input.y:40.11-13: warning: useless associativity for ',' [-Wother]
|
||||
input.y:47.8-10: warning: useless associativity for '!' [-Wother]
|
||||
input.y:47.12-16: warning: useless associativity for UNARY [-Wother]
|
||||
input.y:50.7-9: warning: useless associativity for '$' [-Wother]
|
||||
input.y:51.7-9: warning: useless associativity for '(' [-Wother]
|
||||
input.y:51.11-13: warning: useless associativity for ')' [-Wother]]],
|
||||
[[input.y: warning: 65 shift/reduce conflicts [-Wconflicts-sr]
|
||||
input.y:19.8-16: warning: useless associativity for FUNC_CALL [-Wother]
|
||||
input.y:21.8-14: warning: useless associativity for YNUMBER [-Wother]
|
||||
input.y:21.16-22: warning: useless associativity for YSTRING [-Wother]
|
||||
input.y:22.14-22: warning: useless associativity for APPEND_OP [-Wother]
|
||||
input.y:23.8-15: warning: useless associativity for ASSIGNOP [-Wother]
|
||||
input.y:23.33-41: warning: useless associativity for CONCAT_OP [-Wother]
|
||||
input.y:27.8-18: warning: useless associativity for LEX_GETLINE [-Wother]
|
||||
input.y:28.8-13: warning: useless associativity for LEX_IN [-Wother]
|
||||
input.y:29.23-31: warning: useless associativity for INCREMENT [-Wother]
|
||||
input.y:29.33-41: warning: useless associativity for DECREMENT [-Wother]
|
||||
input.y:30.8-18: warning: useless associativity for LEX_BUILTIN [-Wother]
|
||||
input.y:30.20-29: warning: useless associativity for LEX_LENGTH [-Wother]
|
||||
input.y:40.11-13: warning: useless associativity for ',' [-Wother]
|
||||
input.y:47.8-10: warning: useless associativity for '!' [-Wother]
|
||||
input.y:47.12-16: warning: useless associativity for UNARY [-Wother]
|
||||
input.y:50.7-9: warning: useless associativity for '$' [-Wother]
|
||||
input.y:51.7-9: warning: useless associativity for '(' [-Wother]
|
||||
input.y:51.11-13: warning: useless associativity for ')' [-Wother]]])[
|
||||
]],
|
||||
|
||||
dnl LAST-STATE
|
||||
@@ -484,7 +492,7 @@ dnl - 61 -> 328: reduce -> shift on '*', '/', and '%'
|
||||
|
||||
NAME [reduce using rule 152 (opt_variable)]
|
||||
'$' [reduce using rule 152 (opt_variable)]
|
||||
@@ -5385,7 +5385,7 @@
|
||||
@@ -5379,7 +5379,7 @@
|
||||
156 | . '$' non_post_simp_exp
|
||||
|
||||
NAME shift, and go to state 9
|
||||
@@ -493,7 +501,7 @@ dnl - 61 -> 328: reduce -> shift on '*', '/', and '%'
|
||||
|
||||
NAME [reduce using rule 152 (opt_variable)]
|
||||
'$' [reduce using rule 152 (opt_variable)]
|
||||
@@ -5405,7 +5405,7 @@
|
||||
@@ -5399,7 +5399,7 @@
|
||||
156 | . '$' non_post_simp_exp
|
||||
|
||||
NAME shift, and go to state 9
|
||||
@@ -502,7 +510,7 @@ dnl - 61 -> 328: reduce -> shift on '*', '/', and '%'
|
||||
|
||||
NAME [reduce using rule 152 (opt_variable)]
|
||||
'$' [reduce using rule 152 (opt_variable)]
|
||||
@@ -6220,7 +6220,7 @@
|
||||
@@ -6214,7 +6214,7 @@
|
||||
156 | . '$' non_post_simp_exp
|
||||
|
||||
NAME shift, and go to state 9
|
||||
@@ -511,7 +519,7 @@ dnl - 61 -> 328: reduce -> shift on '*', '/', and '%'
|
||||
|
||||
NAME [reduce using rule 152 (opt_variable)]
|
||||
'$' [reduce using rule 152 (opt_variable)]
|
||||
@@ -11117,3 +11117,274 @@
|
||||
@@ -11099,3 +11099,274 @@
|
||||
45 statement: LEX_FOR '(' opt_exp semi opt_nls exp semi opt_nls opt_exp r_paren opt_nls statement .
|
||||
|
||||
$default reduce using rule 45 (statement)
|
||||
@@ -1395,39 +1403,23 @@ dnl INPUT
|
||||
[[]],
|
||||
|
||||
dnl BISON-STDERR
|
||||
[[input.y:128.12: warning: empty rule without %empty [-Wempty-rule]
|
||||
input.y:137.10: warning: empty rule without %empty [-Wempty-rule]
|
||||
input.y:142.8: warning: empty rule without %empty [-Wempty-rule]
|
||||
input.y:161.15: warning: empty rule without %empty [-Wempty-rule]
|
||||
input.y:179.17: warning: empty rule without %empty [-Wempty-rule]
|
||||
input.y:205.16: warning: empty rule without %empty [-Wempty-rule]
|
||||
input.y:213.9: warning: empty rule without %empty [-Wempty-rule]
|
||||
input.y:225.6: warning: empty rule without %empty [-Wempty-rule]
|
||||
input.y:292.18: warning: empty rule without %empty [-Wempty-rule]
|
||||
input.y:294.19: warning: empty rule without %empty [-Wempty-rule]
|
||||
input.y:367.16: warning: empty rule without %empty [-Wempty-rule]
|
||||
input.y:373.11: warning: empty rule without %empty [-Wempty-rule]
|
||||
input.y:387.15: warning: empty rule without %empty [-Wempty-rule]
|
||||
input.y:401.18: warning: empty rule without %empty [-Wempty-rule]
|
||||
input.y:413.15: warning: empty rule without %empty [-Wempty-rule]
|
||||
input.y:443.15: warning: empty rule without %empty [-Wempty-rule]
|
||||
input.y:471.15: warning: empty rule without %empty [-Wempty-rule]
|
||||
input.y:474.15: warning: empty rule without %empty [-Wempty-rule]
|
||||
input.y:489.15: warning: empty rule without %empty [-Wempty-rule]
|
||||
input.y:506.14: warning: empty rule without %empty [-Wempty-rule]
|
||||
input.y:587.9: warning: empty rule without %empty [-Wempty-rule]
|
||||
input.y:591.14: warning: empty rule without %empty [-Wempty-rule]
|
||||
]AT_COND_CASE([[canonical LR]],
|
||||
[AT_COND_CASE([[canonical LR]],
|
||||
[[input.y: warning: 1876 shift/reduce conflicts [-Wconflicts-sr]
|
||||
input.y: warning: 144 reduce/reduce conflicts [-Wconflicts-rr]]],
|
||||
input.y: 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: 10 reduce/reduce conflicts [-Wconflicts-rr]]])[
|
||||
input.y:72.1-5: warning: useless associativity for HQUA, use %precedence [-Wprecedence]
|
||||
input.y:53.1-6: warning: useless associativity for HASSIGN, use %precedence [-Wprecedence]
|
||||
input.y:54.1-5: warning: useless associativity for HORELSE, use %precedence [-Wprecedence]
|
||||
input.y:55.1-5: warning: useless associativity for HANDTHEN, use %precedence [-Wprecedence]
|
||||
input.y:61.1-5: warning: useless associativity for HNOT, use %precedence [-Wprecedence]
|
||||
input.y:68.1-5: warning: useless associativity for UNEAR, use %precedence [-Wprecedence]
|
||||
input.y: warning: 10 reduce/reduce conflicts [-Wconflicts-rr]
|
||||
input.y:32.9-12: warning: useless associativity for HQUA [-Wother]
|
||||
input.y:53.8-14: warning: useless associativity for HASSIGN [-Wother]
|
||||
input.y:54.9-15: warning: useless associativity for HORELSE [-Wother]
|
||||
input.y:55.9-16: warning: useless associativity for HANDTHEN [-Wother]
|
||||
input.y:61.9-12: warning: useless associativity for HNOT [-Wother]
|
||||
input.y:68.7-11: warning: useless associativity for UNEAR [-Wother]]])[
|
||||
]],
|
||||
|
||||
dnl LAST-STATE
|
||||
@@ -1593,7 +1585,7 @@ box "foo" above ljust == box ("foo" above ljust)
|
||||
|
||||
%left LEFT RIGHT
|
||||
/* Give attributes that take an optional expression a higher
|
||||
precedence than left and right, so that eg 'line chop left'
|
||||
precedence than left and right, so that eg `line chop left'
|
||||
parses properly. */
|
||||
%left CHOP SOLID DASHED DOTTED UP DOWN FILL COLORED OUTLINED
|
||||
%left LABEL
|
||||
@@ -1606,7 +1598,7 @@ parses properly. */
|
||||
/* these need to be lower than '-' */
|
||||
%left HEIGHT RADIUS WIDTH DIAMETER FROM TO AT THICKNESS
|
||||
|
||||
/* these must have higher precedence than CHOP so that 'label %prec CHOP'
|
||||
/* these must have higher precedence than CHOP so that `label %prec CHOP'
|
||||
works */
|
||||
%left DOT_N DOT_E DOT_W DOT_S DOT_NE DOT_SE DOT_NW DOT_SW DOT_C
|
||||
%left DOT_START DOT_END TOP BOTTOM LEFT_CORNER RIGHT_CORNER
|
||||
@@ -2009,93 +2001,88 @@ dnl without being followed by "of".)
|
||||
[[VARIABLE, '=', LABEL, LEFT, DOT_X]],
|
||||
|
||||
dnl BISON-STDERR
|
||||
[[input.y:202.19: warning: empty rule without %empty [-Wempty-rule]
|
||||
input.y:270.6: warning: empty rule without %empty [-Wempty-rule]
|
||||
input.y:292.12: warning: empty rule without %empty [-Wempty-rule]
|
||||
input.y:309.17: warning: empty rule without %empty [-Wempty-rule]
|
||||
input.y:382.13: warning: empty rule without %empty [-Wempty-rule]
|
||||
input.y:471.11-48: warning: rule useless in parser due to conflicts [-Wother]
|
||||
input.y:154.1-5: warning: useless associativity for LABEL, use %precedence [-Wprecedence]
|
||||
input.y:156.1-5: warning: useless associativity for VARIABLE, use %precedence [-Wprecedence]
|
||||
input.y:156.1-5: warning: useless associativity for NUMBER, use %precedence [-Wprecedence]
|
||||
input.y:141.1-5: warning: useless associativity for TEXT, use %precedence [-Wprecedence]
|
||||
input.y:157.1-5: warning: useless associativity for ORDINAL, use %precedence [-Wprecedence]
|
||||
input.y:156.1-5: warning: useless associativity for LAST, use %precedence [-Wprecedence]
|
||||
input.y:153.1-5: warning: useless associativity for UP, use %precedence [-Wprecedence]
|
||||
input.y:153.1-5: warning: useless associativity for DOWN, use %precedence [-Wprecedence]
|
||||
input.y:159.1-5: warning: useless associativity for BOX, use %precedence [-Wprecedence]
|
||||
input.y:159.1-5: warning: useless associativity for CIRCLE, use %precedence [-Wprecedence]
|
||||
input.y:159.1-5: warning: useless associativity for ELLIPSE, use %precedence [-Wprecedence]
|
||||
input.y:159.1-5: warning: useless associativity for ARC, use %precedence [-Wprecedence]
|
||||
input.y:159.1-5: warning: useless associativity for LINE, use %precedence [-Wprecedence]
|
||||
input.y:159.1-5: warning: useless associativity for ARROW, use %precedence [-Wprecedence]
|
||||
input.y:159.1-5: warning: useless associativity for SPLINE, use %precedence [-Wprecedence]
|
||||
input.y:162.1-5: warning: useless associativity for HEIGHT, use %precedence [-Wprecedence]
|
||||
input.y:162.1-5: warning: useless associativity for RADIUS, use %precedence [-Wprecedence]
|
||||
input.y:162.1-5: warning: useless associativity for WIDTH, use %precedence [-Wprecedence]
|
||||
input.y:162.1-5: warning: useless associativity for DIAMETER, use %precedence [-Wprecedence]
|
||||
input.y:162.1-5: warning: useless associativity for FROM, use %precedence [-Wprecedence]
|
||||
input.y:162.1-5: warning: useless associativity for TO, use %precedence [-Wprecedence]
|
||||
input.y:162.1-5: warning: useless associativity for AT, use %precedence [-Wprecedence]
|
||||
input.y:153.1-5: warning: useless precedence and associativity for SOLID [-Wprecedence]
|
||||
input.y:153.1-5: warning: useless associativity for DOTTED, use %precedence [-Wprecedence]
|
||||
input.y:153.1-5: warning: useless associativity for DASHED, use %precedence [-Wprecedence]
|
||||
input.y:153.1-5: warning: useless associativity for CHOP, use %precedence [-Wprecedence]
|
||||
input.y:147.1-5: warning: useless precedence and associativity for LJUST [-Wprecedence]
|
||||
input.y:147.1-5: warning: useless precedence and associativity for RJUST [-Wprecedence]
|
||||
input.y:147.1-5: warning: useless precedence and associativity for ABOVE [-Wprecedence]
|
||||
input.y:147.1-5: warning: useless precedence and associativity for BELOW [-Wprecedence]
|
||||
input.y:176.1-5: warning: useless associativity for OF, use %precedence [-Wprecedence]
|
||||
input.y:176.1-5: warning: useless associativity for BETWEEN, use %precedence [-Wprecedence]
|
||||
input.y:177.1-5: warning: useless associativity for AND, use %precedence [-Wprecedence]
|
||||
input.y:157.1-5: warning: useless associativity for HERE, use %precedence [-Wprecedence]
|
||||
input.y:166.1-5: warning: useless associativity for DOT_N, use %precedence [-Wprecedence]
|
||||
input.y:166.1-5: warning: useless associativity for DOT_E, use %precedence [-Wprecedence]
|
||||
input.y:166.1-5: warning: useless associativity for DOT_W, use %precedence [-Wprecedence]
|
||||
input.y:166.1-5: warning: useless associativity for DOT_S, use %precedence [-Wprecedence]
|
||||
input.y:166.1-5: warning: useless associativity for DOT_NE, use %precedence [-Wprecedence]
|
||||
input.y:166.1-5: warning: useless associativity for DOT_SE, use %precedence [-Wprecedence]
|
||||
input.y:166.1-5: warning: useless associativity for DOT_NW, use %precedence [-Wprecedence]
|
||||
input.y:166.1-5: warning: useless associativity for DOT_SW, use %precedence [-Wprecedence]
|
||||
input.y:166.1-5: warning: useless associativity for DOT_C, use %precedence [-Wprecedence]
|
||||
input.y:167.1-5: warning: useless associativity for DOT_START, use %precedence [-Wprecedence]
|
||||
input.y:167.1-5: warning: useless associativity for DOT_END, use %precedence [-Wprecedence]
|
||||
input.y:156.1-5: warning: useless associativity for SIN, use %precedence [-Wprecedence]
|
||||
input.y:156.1-5: warning: useless associativity for COS, use %precedence [-Wprecedence]
|
||||
input.y:156.1-5: warning: useless associativity for ATAN2, use %precedence [-Wprecedence]
|
||||
input.y:156.1-5: warning: useless associativity for LOG, use %precedence [-Wprecedence]
|
||||
input.y:156.1-5: warning: useless associativity for EXP, use %precedence [-Wprecedence]
|
||||
input.y:156.1-5: warning: useless associativity for SQRT, use %precedence [-Wprecedence]
|
||||
input.y:156.1-5: warning: useless associativity for K_MAX, use %precedence [-Wprecedence]
|
||||
input.y:156.1-5: warning: useless associativity for K_MIN, use %precedence [-Wprecedence]
|
||||
input.y:156.1-5: warning: useless associativity for INT, use %precedence [-Wprecedence]
|
||||
input.y:156.1-5: warning: useless associativity for RAND, use %precedence [-Wprecedence]
|
||||
input.y:156.1-5: warning: useless associativity for SRAND, use %precedence [-Wprecedence]
|
||||
input.y:167.1-5: warning: useless associativity for TOP, use %precedence [-Wprecedence]
|
||||
input.y:167.1-5: warning: useless associativity for BOTTOM, use %precedence [-Wprecedence]
|
||||
input.y:168.1-5: warning: useless associativity for UPPER, use %precedence [-Wprecedence]
|
||||
input.y:168.1-5: warning: useless associativity for LOWER, use %precedence [-Wprecedence]
|
||||
input.y:167.1-5: warning: useless associativity for LEFT_CORNER, use %precedence [-Wprecedence]
|
||||
input.y:167.1-5: warning: useless associativity for RIGHT_CORNER, use %precedence [-Wprecedence]
|
||||
input.y:168.1-5: warning: useless associativity for NORTH, use %precedence [-Wprecedence]
|
||||
input.y:168.1-5: warning: useless associativity for SOUTH, use %precedence [-Wprecedence]
|
||||
input.y:168.1-5: warning: useless associativity for EAST, use %precedence [-Wprecedence]
|
||||
input.y:168.1-5: warning: useless associativity for WEST, use %precedence [-Wprecedence]
|
||||
input.y:168.1-5: warning: useless associativity for CENTER, use %precedence [-Wprecedence]
|
||||
input.y:168.1-5: warning: useless associativity for END, use %precedence [-Wprecedence]
|
||||
input.y:168.1-5: warning: useless associativity for START, use %precedence [-Wprecedence]
|
||||
input.y:140.1-5: warning: useless associativity for PLOT, use %precedence [-Wprecedence]
|
||||
input.y:162.1-5: warning: useless associativity for THICKNESS, use %precedence [-Wprecedence]
|
||||
input.y:153.1-5: warning: useless associativity for FILL, use %precedence [-Wprecedence]
|
||||
input.y:153.1-5: warning: useless precedence and associativity for COLORED [-Wprecedence]
|
||||
input.y:153.1-5: warning: useless precedence and associativity for OUTLINED [-Wprecedence]
|
||||
input.y:141.1-5: warning: useless associativity for SPRINTF, use %precedence [-Wprecedence]
|
||||
input.y:137.1-5: warning: useless associativity for '.', use %precedence [-Wprecedence]
|
||||
input.y:156.1-5: warning: useless associativity for '(', use %precedence [-Wprecedence]
|
||||
input.y:157.1-5: warning: useless associativity for '`', use %precedence [-Wprecedence]
|
||||
input.y:159.1-5: warning: useless associativity for '@<:@', use %precedence [-Wprecedence]
|
||||
input.y:170.1-5: warning: useless associativity for ',', use %precedence [-Wprecedence]
|
||||
input.y:181.1-6: warning: useless associativity for '!', use %precedence [-Wprecedence]
|
||||
[[input.y:471.11-48: warning: rule useless in parser due to conflicts: path: ORDINAL LAST object_type relative_path [-Wother]
|
||||
input.y:19.8-12: warning: useless associativity for LABEL [-Wother]
|
||||
input.y:20.8-15: warning: useless associativity for VARIABLE [-Wother]
|
||||
input.y:21.8-13: warning: useless associativity for NUMBER [-Wother]
|
||||
input.y:22.8-11: warning: useless associativity for TEXT [-Wother]
|
||||
input.y:25.8-14: warning: useless associativity for ORDINAL [-Wother]
|
||||
input.y:30.8-11: warning: useless associativity for LAST [-Wother]
|
||||
input.y:31.8-9: warning: useless associativity for UP [-Wother]
|
||||
input.y:32.8-11: warning: useless associativity for DOWN [-Wother]
|
||||
input.y:35.8-10: warning: useless associativity for BOX [-Wother]
|
||||
input.y:36.8-13: warning: useless associativity for CIRCLE [-Wother]
|
||||
input.y:37.8-14: warning: useless associativity for ELLIPSE [-Wother]
|
||||
input.y:38.8-10: warning: useless associativity for ARC [-Wother]
|
||||
input.y:39.8-11: warning: useless associativity for LINE [-Wother]
|
||||
input.y:40.8-12: warning: useless associativity for ARROW [-Wother]
|
||||
input.y:42.8-13: warning: useless associativity for SPLINE [-Wother]
|
||||
input.y:43.8-13: warning: useless associativity for HEIGHT [-Wother]
|
||||
input.y:44.8-13: warning: useless associativity for RADIUS [-Wother]
|
||||
input.y:45.8-12: warning: useless associativity for WIDTH [-Wother]
|
||||
input.y:46.8-15: warning: useless associativity for DIAMETER [-Wother]
|
||||
input.y:47.8-11: warning: useless associativity for FROM [-Wother]
|
||||
input.y:48.8-9: warning: useless associativity for TO [-Wother]
|
||||
input.y:49.8-9: warning: useless associativity for AT [-Wother]
|
||||
input.y:53.8-12: warning: useless associativity for SOLID [-Wother]
|
||||
input.y:54.8-13: warning: useless associativity for DOTTED [-Wother]
|
||||
input.y:55.8-13: warning: useless associativity for DASHED [-Wother]
|
||||
input.y:56.8-11: warning: useless associativity for CHOP [-Wother]
|
||||
input.y:59.8-12: warning: useless associativity for LJUST [-Wother]
|
||||
input.y:60.8-12: warning: useless associativity for RJUST [-Wother]
|
||||
input.y:61.8-12: warning: useless associativity for ABOVE [-Wother]
|
||||
input.y:62.8-12: warning: useless associativity for BELOW [-Wother]
|
||||
input.y:63.8-9: warning: useless associativity for OF [-Wother]
|
||||
input.y:66.8-14: warning: useless associativity for BETWEEN [-Wother]
|
||||
input.y:67.8-10: warning: useless associativity for AND [-Wother]
|
||||
input.y:68.8-11: warning: useless associativity for HERE [-Wother]
|
||||
input.y:69.8-12: warning: useless associativity for DOT_N [-Wother]
|
||||
input.y:70.8-12: warning: useless associativity for DOT_E [-Wother]
|
||||
input.y:71.8-12: warning: useless associativity for DOT_W [-Wother]
|
||||
input.y:72.8-12: warning: useless associativity for DOT_S [-Wother]
|
||||
input.y:73.8-13: warning: useless associativity for DOT_NE [-Wother]
|
||||
input.y:74.8-13: warning: useless associativity for DOT_SE [-Wother]
|
||||
input.y:75.8-13: warning: useless associativity for DOT_NW [-Wother]
|
||||
input.y:76.8-13: warning: useless associativity for DOT_SW [-Wother]
|
||||
input.y:77.8-12: warning: useless associativity for DOT_C [-Wother]
|
||||
input.y:78.8-16: warning: useless associativity for DOT_START [-Wother]
|
||||
input.y:79.8-14: warning: useless associativity for DOT_END [-Wother]
|
||||
input.y:85.8-10: warning: useless associativity for SIN [-Wother]
|
||||
input.y:86.8-10: warning: useless associativity for COS [-Wother]
|
||||
input.y:87.8-12: warning: useless associativity for ATAN2 [-Wother]
|
||||
input.y:88.8-10: warning: useless associativity for LOG [-Wother]
|
||||
input.y:89.8-10: warning: useless associativity for EXP [-Wother]
|
||||
input.y:90.8-11: warning: useless associativity for SQRT [-Wother]
|
||||
input.y:91.8-12: warning: useless associativity for K_MAX [-Wother]
|
||||
input.y:92.8-12: warning: useless associativity for K_MIN [-Wother]
|
||||
input.y:93.8-10: warning: useless associativity for INT [-Wother]
|
||||
input.y:94.8-11: warning: useless associativity for RAND [-Wother]
|
||||
input.y:95.8-12: warning: useless associativity for SRAND [-Wother]
|
||||
input.y:98.8-10: warning: useless associativity for TOP [-Wother]
|
||||
input.y:99.8-13: warning: useless associativity for BOTTOM [-Wother]
|
||||
input.y:100.8-12: warning: useless associativity for UPPER [-Wother]
|
||||
input.y:101.8-12: warning: useless associativity for LOWER [-Wother]
|
||||
input.y:116.8-18: warning: useless associativity for LEFT_CORNER [-Wother]
|
||||
input.y:117.8-19: warning: useless associativity for RIGHT_CORNER [-Wother]
|
||||
input.y:118.8-12: warning: useless associativity for NORTH [-Wother]
|
||||
input.y:119.8-12: warning: useless associativity for SOUTH [-Wother]
|
||||
input.y:120.8-11: warning: useless associativity for EAST [-Wother]
|
||||
input.y:121.8-11: warning: useless associativity for WEST [-Wother]
|
||||
input.y:122.8-13: warning: useless associativity for CENTER [-Wother]
|
||||
input.y:123.8-10: warning: useless associativity for END [-Wother]
|
||||
input.y:124.8-12: warning: useless associativity for START [-Wother]
|
||||
input.y:127.8-11: warning: useless associativity for PLOT [-Wother]
|
||||
input.y:128.8-16: warning: useless associativity for THICKNESS [-Wother]
|
||||
input.y:129.8-11: warning: useless associativity for FILL [-Wother]
|
||||
input.y:130.8-14: warning: useless associativity for COLORED [-Wother]
|
||||
input.y:131.8-15: warning: useless associativity for OUTLINED [-Wother]
|
||||
input.y:134.8-14: warning: useless associativity for SPRINTF [-Wother]
|
||||
input.y:137.7-9: warning: useless associativity for '.' [-Wother]
|
||||
input.y:156.23-25: warning: useless associativity for '(' [-Wother]
|
||||
input.y:157.20-22: warning: useless associativity for '`' [-Wother]
|
||||
input.y:159.48-50: warning: useless associativity for '@<:@' [-Wother]
|
||||
input.y:170.7-9: warning: useless associativity for ',' [-Wother]
|
||||
input.y:181.8-10: warning: useless associativity for '!' [-Wother]
|
||||
]],
|
||||
|
||||
dnl LAST-STATE
|
||||
|
||||
@@ -486,8 +486,8 @@ start:
|
||||
;
|
||||
|
||||
%%
|
||||
]AT_YYERROR_DEFINE[
|
||||
]AT_YYLEX_DEFINE(["a"])[
|
||||
]AT_YYERROR_DEFINE[
|
||||
]AT_MAIN_DEFINE[
|
||||
]])
|
||||
AT_BISON_OPTION_POPDEFS
|
||||
@@ -1015,17 +1015,17 @@ main (void)
|
||||
int exit_status = yyparse ();
|
||||
if (parent_rhs_before_value)
|
||||
{
|
||||
fprintf (stderr, "'parent_rhs_before' destructor not called.\n");
|
||||
fprintf (stderr, "`parent_rhs_before' destructor not called.\n");
|
||||
exit_status = 1;
|
||||
}
|
||||
if (merged_value)
|
||||
{
|
||||
fprintf (stderr, "'merged' destructor not called.\n");
|
||||
fprintf (stderr, "`merged' destructor not called.\n");
|
||||
exit_status = 1;
|
||||
}
|
||||
if (parent_rhs_after_value)
|
||||
{
|
||||
fprintf (stderr, "'PARENT_RHS_AFTER' destructor not called.\n");
|
||||
fprintf (stderr, "`PARENT_RHS_AFTER' destructor not called.\n");
|
||||
exit_status = 1;
|
||||
}
|
||||
return exit_status;
|
||||
@@ -1449,7 +1449,7 @@ main (void)
|
||||
int exit_status = yyparse () != 1;
|
||||
if (parent_rhs_before_value)
|
||||
{
|
||||
fprintf (stderr, "'parent_rhs_before' destructor not called.\n");
|
||||
fprintf (stderr, "`parent_rhs_before' destructor not called.\n");
|
||||
exit_status = 1;
|
||||
}
|
||||
return exit_status;
|
||||
@@ -1679,8 +1679,8 @@ start:
|
||||
b: 'b';
|
||||
d: /* nada. */;
|
||||
%%
|
||||
]AT_YYERROR_DEFINE[
|
||||
]AT_YYLEX_DEFINE(["abc"])[
|
||||
]AT_YYERROR_DEFINE[
|
||||
]AT_MAIN_DEFINE[
|
||||
]])
|
||||
AT_BISON_OPTION_POPDEFS
|
||||
|
||||
+2
-2
@@ -117,9 +117,9 @@ AT_SETUP([Several parsers])
|
||||
# nor yy* identifiers in the header. Check that headers are
|
||||
# self-contained, and can be compiled by a C++ compiler.
|
||||
m4_pushdef([AT_TEST],
|
||||
[AT_BISON_OPTION_PUSHDEFS([%define api.prefix {$1_} $2])
|
||||
[AT_BISON_OPTION_PUSHDEFS([%define api.prefix "$1_" $2])
|
||||
AT_DATA_GRAMMAR([$1.y],
|
||||
[[%define api.prefix {$1_}
|
||||
[[%define api.prefix "$1_"
|
||||
$2
|
||||
%error-verbose
|
||||
%union
|
||||
|
||||
+144
-234
@@ -20,29 +20,6 @@ AT_BANNER([[Input Processing.]])
|
||||
# Mostly test that we are robust to mistakes.
|
||||
|
||||
|
||||
## ----------------- ##
|
||||
## Invalid options. ##
|
||||
## ----------------- ##
|
||||
|
||||
AT_SETUP([Invalid options])
|
||||
|
||||
AT_DATA([input.y],
|
||||
[[%%
|
||||
exp: '0'
|
||||
]])
|
||||
|
||||
# We used to accept these, as -f, --report and others were sharing
|
||||
# their code with -W.
|
||||
AT_BISON_CHECK([-ferror=caret input.y], [1], [], [ignore])
|
||||
AT_BISON_CHECK([--report=error=itemsets input.y], [1], [], [ignore])
|
||||
|
||||
# We used to accept any character after "-Werror", instead of ensuring
|
||||
# this is "=".
|
||||
AT_BISON_CHECK([-Werror?all input.y], [1], [], [ignore])
|
||||
|
||||
AT_CLEANUP
|
||||
|
||||
|
||||
## ---------------- ##
|
||||
## Invalid inputs. ##
|
||||
## ---------------- ##
|
||||
@@ -64,13 +41,14 @@ AT_CHECK([[$PERL -pi -e 's/\\(\d{3})/chr(oct($1))/ge' input.y || exit 77]])
|
||||
AT_BISON_CHECK([input.y], [1], [],
|
||||
[[input.y:1.1-2: error: invalid characters: '\0\001\002\377?'
|
||||
input.y:3.1: error: invalid character: '?'
|
||||
input.y:4.14: error: syntax error, unexpected }
|
||||
input.y:4.14: error: invalid character: '}'
|
||||
input.y:5.1: error: invalid character: '%'
|
||||
input.y:5.2: error: invalid character: '&'
|
||||
input.y:6.1-17: error: invalid directive: '%a-does-not-exist'
|
||||
input.y:7.1: error: invalid character: '%'
|
||||
input.y:7.2: error: invalid character: '-'
|
||||
input.y:8.1-9.0: error: missing '%}' at end of file
|
||||
input.y:8.1-9.0: error: syntax error, unexpected %{...%}
|
||||
]])
|
||||
|
||||
AT_CLEANUP
|
||||
@@ -107,17 +85,17 @@ AT_SETUP([Invalid $n and @n])
|
||||
|
||||
AT_DATA([input.y],
|
||||
[[%%
|
||||
exp: %empty { $$ = $1 ; };
|
||||
exp: %empty { @$ = @1 ; };
|
||||
exp: { $$ = $1 ; };
|
||||
exp: { @$ = @1 ; };
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK([-fcaret input.y], [1], [],
|
||||
[[input.y:2.20-21: error: integer out of range: '$1'
|
||||
exp: %empty { $$ = $1 ; };
|
||||
^^
|
||||
input.y:3.20-21: error: integer out of range: '@1'
|
||||
exp: %empty { @$ = @1 ; };
|
||||
^^
|
||||
[[input.y:2.13-14: error: integer out of range: '$1'
|
||||
exp: { $$ = $1 ; };
|
||||
^^
|
||||
input.y:3.13-14: error: integer out of range: '@1'
|
||||
exp: { @$ = @1 ; };
|
||||
^^
|
||||
]])
|
||||
|
||||
AT_CLEANUP
|
||||
@@ -136,7 +114,7 @@ AT_DATA([input.y],
|
||||
%%
|
||||
exp: foo { $$; } foo { $2; } foo
|
||||
| foo
|
||||
| %empty
|
||||
| /* empty. */
|
||||
;
|
||||
]])
|
||||
|
||||
@@ -153,9 +131,9 @@ input.y:5.6-32: warning: type clash on default action: <bar> != <> [-Wother]
|
||||
input.y:6.6-8: warning: type clash on default action: <bar> != <> [-Wother]
|
||||
| foo
|
||||
^^^
|
||||
input.y:7.6-11: warning: empty rule for typed nonterminal, and no action [-Wother]
|
||||
| %empty
|
||||
^^^^^^
|
||||
input.y:7.5: warning: empty rule for typed nonterminal, and no action [-Wother]
|
||||
| /* empty. */
|
||||
^
|
||||
]])
|
||||
|
||||
AT_CLEANUP
|
||||
@@ -191,7 +169,7 @@ start:
|
||||
;
|
||||
|
||||
a: INT | INT { } INT { } INT { };
|
||||
b: INT | %empty;
|
||||
b: INT | /* empty */;
|
||||
c: INT | INT { $]1[; } INT { $<integer>2; } INT { $<integer>4; };
|
||||
d: INT | INT { } INT { $]1[; } INT { $<integer>2; };
|
||||
e: INT | INT { } INT { } INT { $]1[; };
|
||||
@@ -219,9 +197,9 @@ input.y:11.18-20: warning: unused value: $][3 [-Wother]
|
||||
input.y:11.26-28: warning: unused value: $][5 [-Wother]
|
||||
a: INT | INT { } INT { } INT { };
|
||||
^^^
|
||||
input.y:12.10-15: warning: empty rule for typed nonterminal, and no action [-Wother]
|
||||
b: INT | %empty;
|
||||
^^^^^^
|
||||
input.y:12.9: warning: empty rule for typed nonterminal, and no action [-Wother]
|
||||
b: INT | /* empty */;
|
||||
^
|
||||
]]m4_ifval($2, [[[input.y:13.14-20: warning: unset value: $][$ [-Wmidrule-values]
|
||||
c: INT | INT { $][1; } INT { $<integer>2; } INT { $<integer>4; };
|
||||
^^^^^^^
|
||||
@@ -335,67 +313,104 @@ AT_CLEANUP
|
||||
|
||||
AT_SETUP([Default %printer and %destructor redeclared])
|
||||
|
||||
# AT_TEST([*])
|
||||
# ------------
|
||||
m4_pushdef([AT_TEST],
|
||||
[AT_DATA([[input.y]],
|
||||
[[%destructor { destroy ($$); } <$1> <$1>
|
||||
%printer { print ($$); } <$1> <$1>
|
||||
AT_DATA([[input.y]],
|
||||
[[%destructor { destroy ($$); } <*> <*>
|
||||
%printer { print ($$); } <*> <*>
|
||||
|
||||
%destructor { destroy ($$); } <$1>
|
||||
%printer { print ($$); } <$1>
|
||||
%destructor { destroy ($$); } <*>
|
||||
%printer { print ($$); } <*>
|
||||
|
||||
%destructor { destroy ($$); } <> <>
|
||||
%printer { print ($$); } <> <>
|
||||
|
||||
%destructor { destroy ($$); } <>
|
||||
%printer { print ($$); } <>
|
||||
|
||||
%%
|
||||
|
||||
start: %empty;
|
||||
start: ;
|
||||
|
||||
%destructor { destroy ($$); } <$1>;
|
||||
%printer { print ($$); } <$1>;
|
||||
%destructor { destroy ($$); } <*>;
|
||||
%printer { print ($$); } <*>;
|
||||
|
||||
%destructor { destroy ($$); } <>;
|
||||
%printer { print ($$); } <>;
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK([-fcaret input.y], [1], [],
|
||||
[[input.y:1.13-29: error: %destructor redeclaration for <>
|
||||
%destructor { destroy ($$); } <> <>
|
||||
[[input.y:1.13-29: error: %destructor redeclaration for <*>
|
||||
%destructor { destroy ($$); } <*> <*>
|
||||
^^^^^^^^^^^^^^^^^
|
||||
input.y:1.13-29: previous declaration
|
||||
%destructor { destroy ($$); } <> <>
|
||||
%destructor { destroy ($$); } <*> <*>
|
||||
^^^^^^^^^^^^^^^^^
|
||||
input.y:2.10-24: error: %printer redeclaration for <>
|
||||
%printer { print ($$); } <> <>
|
||||
input.y:2.10-24: error: %printer redeclaration for <*>
|
||||
%printer { print ($$); } <*> <*>
|
||||
^^^^^^^^^^^^^^^
|
||||
input.y:2.10-24: previous declaration
|
||||
%printer { print ($$); } <*> <*>
|
||||
^^^^^^^^^^^^^^^
|
||||
input.y:4.13-29: error: %destructor redeclaration for <*>
|
||||
%destructor { destroy ($$); } <*>
|
||||
^^^^^^^^^^^^^^^^^
|
||||
input.y:1.13-29: previous declaration
|
||||
%destructor { destroy ($$); } <*> <*>
|
||||
^^^^^^^^^^^^^^^^^
|
||||
input.y:5.10-24: error: %printer redeclaration for <*>
|
||||
%printer { print ($$); } <*>
|
||||
^^^^^^^^^^^^^^^
|
||||
input.y:2.10-24: previous declaration
|
||||
%printer { print ($$); } <*> <*>
|
||||
^^^^^^^^^^^^^^^
|
||||
input.y:7.13-29: error: %destructor redeclaration for <>
|
||||
%destructor { destroy ($$); } <> <>
|
||||
^^^^^^^^^^^^^^^^^
|
||||
input.y:7.13-29: previous declaration
|
||||
%destructor { destroy ($$); } <> <>
|
||||
^^^^^^^^^^^^^^^^^
|
||||
input.y:8.10-24: error: %printer redeclaration for <>
|
||||
%printer { print ($$); } <> <>
|
||||
^^^^^^^^^^^^^^^
|
||||
input.y:4.13-29: error: %destructor redeclaration for <>
|
||||
input.y:8.10-24: previous declaration
|
||||
%printer { print ($$); } <> <>
|
||||
^^^^^^^^^^^^^^^
|
||||
input.y:10.13-29: error: %destructor redeclaration for <>
|
||||
%destructor { destroy ($$); } <>
|
||||
^^^^^^^^^^^^^^^^^
|
||||
input.y:1.13-29: previous declaration
|
||||
input.y:7.13-29: previous declaration
|
||||
%destructor { destroy ($$); } <> <>
|
||||
^^^^^^^^^^^^^^^^^
|
||||
input.y:5.10-24: error: %printer redeclaration for <>
|
||||
input.y:11.10-24: error: %printer redeclaration for <>
|
||||
%printer { print ($$); } <>
|
||||
^^^^^^^^^^^^^^^
|
||||
input.y:2.10-24: previous declaration
|
||||
input.y:8.10-24: previous declaration
|
||||
%printer { print ($$); } <> <>
|
||||
^^^^^^^^^^^^^^^
|
||||
input.y:11.13-29: error: %destructor redeclaration for <>
|
||||
input.y:17.13-29: error: %destructor redeclaration for <*>
|
||||
%destructor { destroy ($$); } <*>;
|
||||
^^^^^^^^^^^^^^^^^
|
||||
input.y:4.13-29: previous declaration
|
||||
%destructor { destroy ($$); } <*>
|
||||
^^^^^^^^^^^^^^^^^
|
||||
input.y:18.10-24: error: %printer redeclaration for <*>
|
||||
%printer { print ($$); } <*>;
|
||||
^^^^^^^^^^^^^^^
|
||||
input.y:5.10-24: previous declaration
|
||||
%printer { print ($$); } <*>
|
||||
^^^^^^^^^^^^^^^
|
||||
input.y:20.13-29: error: %destructor redeclaration for <>
|
||||
%destructor { destroy ($$); } <>;
|
||||
^^^^^^^^^^^^^^^^^
|
||||
input.y:1.13-29: previous declaration
|
||||
%destructor { destroy ($$); } <> <>
|
||||
input.y:10.13-29: previous declaration
|
||||
%destructor { destroy ($$); } <>
|
||||
^^^^^^^^^^^^^^^^^
|
||||
input.y:12.10-24: error: %printer redeclaration for <>
|
||||
input.y:21.10-24: error: %printer redeclaration for <>
|
||||
%printer { print ($$); } <>;
|
||||
^^^^^^^^^^^^^^^
|
||||
input.y:2.10-24: previous declaration
|
||||
%printer { print ($$); } <> <>
|
||||
input.y:11.10-24: previous declaration
|
||||
%printer { print ($$); } <>
|
||||
^^^^^^^^^^^^^^^
|
||||
]])
|
||||
])
|
||||
|
||||
AT_TEST([], [], [])
|
||||
AT_TEST([], [*], [*])
|
||||
m4_popdef([AT_TEST])
|
||||
|
||||
AT_CLEANUP
|
||||
|
||||
@@ -415,7 +430,7 @@ AT_DATA([[input.y]],
|
||||
|
||||
%%
|
||||
|
||||
start: %empty;
|
||||
start: ;
|
||||
|
||||
%destructor { destroy ($$); } <field2> <field1>;
|
||||
%printer { print ($$); } <field2> <field1>;
|
||||
@@ -425,17 +440,17 @@ AT_BISON_CHECK([input.y], [1], [],
|
||||
[[input.y:4.13-29: error: %destructor redeclaration for <field1>
|
||||
input.y:1.13-29: previous declaration
|
||||
input.y:4.13-29: error: %destructor redeclaration for <field1>
|
||||
input.y:1.13-29: previous declaration
|
||||
input.y:4.13-29: previous declaration
|
||||
input.y:5.10-24: error: %printer redeclaration for <field2>
|
||||
input.y:2.10-24: previous declaration
|
||||
input.y:5.10-24: error: %printer redeclaration for <field2>
|
||||
input.y:2.10-24: previous declaration
|
||||
input.y:5.10-24: previous declaration
|
||||
input.y:11.13-29: error: %destructor redeclaration for <field2>
|
||||
input.y:1.13-29: previous declaration
|
||||
input.y:11.13-29: error: %destructor redeclaration for <field1>
|
||||
input.y:1.13-29: previous declaration
|
||||
input.y:4.13-29: previous declaration
|
||||
input.y:12.10-24: error: %printer redeclaration for <field2>
|
||||
input.y:2.10-24: previous declaration
|
||||
input.y:5.10-24: previous declaration
|
||||
input.y:12.10-24: error: %printer redeclaration for <field1>
|
||||
input.y:2.10-24: previous declaration
|
||||
]])
|
||||
@@ -671,25 +686,25 @@ exp: foo;
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK([-fcaret input.y], [1], [],
|
||||
[[input.y:8.7-11: error: %type redeclaration for "foo"
|
||||
[[input.y:8.7-11: error: %type redeclaration for foo
|
||||
%type <baz> "foo"
|
||||
^^^^^
|
||||
input.y:3.7-11: previous declaration
|
||||
%type <bar> foo
|
||||
^^^^^
|
||||
input.y:9.10-14: error: %printer redeclaration for "foo"
|
||||
%printer {baz} "foo"
|
||||
^^^^^
|
||||
input.y:4.10-14: previous declaration
|
||||
%printer {bar} foo
|
||||
^^^^^
|
||||
input.y:10.13-17: error: %destructor redeclaration for "foo"
|
||||
input.y:10.13-17: error: %destructor redeclaration for foo
|
||||
%destructor {baz} "foo"
|
||||
^^^^^
|
||||
input.y:5.13-17: previous declaration
|
||||
%destructor {bar} foo
|
||||
^^^^^
|
||||
input.y:11.1-5: error: %left redeclaration for "foo"
|
||||
input.y:9.10-14: error: %printer redeclaration for foo
|
||||
%printer {baz} "foo"
|
||||
^^^^^
|
||||
input.y:4.10-14: previous declaration
|
||||
%printer {bar} foo
|
||||
^^^^^
|
||||
input.y:11.1-5: error: %left redeclaration for foo
|
||||
%left "foo"
|
||||
^^^^^
|
||||
input.y:6.1-5: previous declaration
|
||||
@@ -811,7 +826,7 @@ exp: '@<:@' '\1' two '$' '@' '{' oline output.or.oline.opt
|
||||
|
||||
two: '\x000000000000000000000000000000000000000000000000000000000000000000002';
|
||||
oline: '@' 'o' 'l' 'i' 'n' 'e' '@' '_' '_' 'o' 'l' 'i' 'n' 'e' '_' '_';
|
||||
output.or.oline.opt: %empty;|oline;;|output;;;
|
||||
output.or.oline.opt: ;|oline;;|output;;;
|
||||
output: '#' 'o' 'u' 't' 'p' 'u' 't' ' ';
|
||||
%%
|
||||
/* Exercise M4 quoting: '@:>@@:>@', @<:@, 2. */
|
||||
@@ -893,7 +908,7 @@ m4_define([AT_CHECK_REQUIRE],
|
||||
AT_DATA_GRAMMAR([input.y],
|
||||
[[%require "$1";
|
||||
%%
|
||||
empty_file: %empty;
|
||||
empty_file: /* empty */;
|
||||
]])
|
||||
AT_BISON_CHECK([-o input.c input.y], $2, [], ignore)
|
||||
AT_CLEANUP
|
||||
@@ -1051,7 +1066,7 @@ AT_DATA([input.y],
|
||||
|
||||
%%
|
||||
|
||||
start: %empty;
|
||||
start: ;
|
||||
|
||||
// Used to report a syntax error because it didn't see any kind of symbol
|
||||
// identifier.
|
||||
@@ -1096,7 +1111,7 @@ AT_SETUP([%start after first rule])
|
||||
|
||||
AT_DATA([input.y],
|
||||
[[%%
|
||||
false_start: %empty;
|
||||
false_start: ;
|
||||
start: false_start ;
|
||||
%start start;
|
||||
]])
|
||||
@@ -1117,7 +1132,7 @@ AT_SETUP([%prec takes a token])
|
||||
AT_DATA([input.y],
|
||||
[[%%
|
||||
start: PREC %prec PREC ;
|
||||
PREC: %empty;
|
||||
PREC: ;
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK([input.y], [1], [],
|
||||
@@ -1159,7 +1174,7 @@ AT_DATA([input-c.y],
|
||||
%code bad {}
|
||||
%code format {}
|
||||
%%
|
||||
start: %empty;
|
||||
start: ;
|
||||
]])
|
||||
AT_BISON_CHECK([[input-c.y]], [[1]], [],
|
||||
[[input-c.y:1.7: error: %code qualifier 'q' is not used
|
||||
@@ -1173,7 +1188,7 @@ AT_DATA([input-c-glr.y],
|
||||
%code bad {}
|
||||
%code bad {}
|
||||
%%
|
||||
start: %empty;
|
||||
start: ;
|
||||
]])
|
||||
AT_BISON_CHECK([[input-c-glr.y]], [[1]], [],
|
||||
[[input-c-glr.y:1.7: error: %code qualifier 'q' is not used
|
||||
@@ -1186,7 +1201,7 @@ AT_DATA([input-c++.y],
|
||||
%code bad {}
|
||||
%code q {}
|
||||
%%
|
||||
start: %empty;
|
||||
start: ;
|
||||
]])
|
||||
AT_BISON_CHECK([[input-c++.y]], [[1]], [],
|
||||
[[input-c++.y:1.7: error: %code qualifier 'q' is not used
|
||||
@@ -1199,7 +1214,7 @@ AT_DATA([input-c++-glr.y],
|
||||
%code q {}
|
||||
%code q {}
|
||||
%%
|
||||
start: %empty;
|
||||
start: ;
|
||||
]])
|
||||
AT_BISON_CHECK([[input-c++-glr.y]], [[1]], [],
|
||||
[[input-c++-glr.y:1.7-9: error: %code qualifier 'bad' is not used
|
||||
@@ -1212,7 +1227,7 @@ AT_DATA([special-char-@@.y],
|
||||
%code q {}
|
||||
%code q {}
|
||||
%%
|
||||
start: %empty;
|
||||
start: ;
|
||||
]])
|
||||
AT_BISON_CHECK([[special-char-@@.y]], [[1]], [],
|
||||
[[special-char-@@.y:1.7-9: error: %code qualifier 'bad' is not used
|
||||
@@ -1225,7 +1240,7 @@ AT_DATA([special-char-@:>@.y],
|
||||
%code q {}
|
||||
%code q {}
|
||||
%%
|
||||
start: %empty;
|
||||
start: ;
|
||||
]])
|
||||
AT_BISON_CHECK([[special-char-@:>@.y]], [[1]], [],
|
||||
[[special-char-@:>@.y:1.7-9: error: %code qualifier 'bad' is not used
|
||||
@@ -1236,45 +1251,6 @@ special-char-@:>@.y:3.7: error: %code qualifier 'q' is not used
|
||||
AT_CLEANUP
|
||||
|
||||
|
||||
## ---------------- ##
|
||||
## Multiple %code. ##
|
||||
## ---------------- ##
|
||||
|
||||
AT_SETUP([Multiple %code])
|
||||
|
||||
# Make sure that repeated arguments to %code are separated by
|
||||
# end-of-lines. At some point, a missing eol would leave synclines
|
||||
# appended to the previous value. Here, we use CPP directive to
|
||||
# introduce dependency on the absence/presence of the eol.
|
||||
AT_BISON_OPTION_PUSHDEFS
|
||||
|
||||
AT_DATA([input.y],
|
||||
[[%code {#include <assert.h>}
|
||||
%code {#define A B}
|
||||
%code {#define B C}
|
||||
%code {#define C D}
|
||||
%code {#define D 42}
|
||||
%code {
|
||||
]AT_YYERROR_DECLARE[
|
||||
]AT_YYLEX_DECLARE[
|
||||
}
|
||||
%%
|
||||
start: %empty;
|
||||
%%
|
||||
]AT_YYERROR_DEFINE[
|
||||
]AT_YYLEX_DEFINE[
|
||||
int main (void)
|
||||
{
|
||||
assert (A == 42);
|
||||
return 0;
|
||||
}
|
||||
]])
|
||||
AT_FULL_COMPILE([input])
|
||||
AT_PARSER_CHECK([./input])
|
||||
|
||||
AT_BISON_OPTION_POPDEFS
|
||||
AT_CLEANUP()
|
||||
|
||||
## ---------------- ##
|
||||
## %define errors. ##
|
||||
## ---------------- ##
|
||||
@@ -1288,7 +1264,7 @@ AT_DATA([input-redefined.y],
|
||||
%define special1 "@:>@"
|
||||
%define special2 "@<:@"
|
||||
%%
|
||||
start: %empty;
|
||||
start: ;
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK([[input-redefined.y]], [[1]], [],
|
||||
@@ -1301,7 +1277,7 @@ input-redefined.y:2.9-11: previous definition
|
||||
AT_DATA([input-unused.y],
|
||||
[[%define var "value"
|
||||
%%
|
||||
start: %empty;
|
||||
start: ;
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK([[input-unused.y]], [[1]], [],
|
||||
@@ -1329,7 +1305,7 @@ m4@&t@_divert_pop(0)
|
||||
AT_DATA([[input.y]],
|
||||
[[%define var-dfg "gram"
|
||||
%%
|
||||
start: %empty;
|
||||
start: ;
|
||||
]])
|
||||
AT_BISON_CHECK([[-Dvar-dd=cmd-d1 -Dvar-dd=cmd-d2 \
|
||||
-Fvar-ff=cmd-f1 -Fvar-ff=cmd-f2 \
|
||||
@@ -1346,7 +1322,7 @@ var-fd: cmd-d
|
||||
AT_DATA([[input-dg.y]],
|
||||
[[%define var "gram"
|
||||
%%
|
||||
start: %empty;
|
||||
start: ;
|
||||
]])
|
||||
AT_BISON_CHECK([[-Dvar=cmd-d input-dg.y]], [[1]], [],
|
||||
[[input-dg.y:1.9-11: error: %define variable 'var' redefined
|
||||
@@ -1356,7 +1332,7 @@ AT_BISON_CHECK([[-Dvar=cmd-d input-dg.y]], [[1]], [],
|
||||
AT_DATA([[input-dg.y]],
|
||||
[[%define var "gram"
|
||||
%%
|
||||
start: %empty;
|
||||
start: ;
|
||||
]])
|
||||
AT_BISON_CHECK([[-fcaret -Dvar=cmd-d input-dg.y]], [[1]], [],
|
||||
[[input-dg.y:1.9-11: error: %define variable 'var' redefined
|
||||
@@ -1367,7 +1343,7 @@ AT_BISON_CHECK([[-fcaret -Dvar=cmd-d input-dg.y]], [[1]], [],
|
||||
|
||||
AT_DATA([[input-unused.y]],
|
||||
[[%%
|
||||
start: %empty;
|
||||
start: ;
|
||||
]])
|
||||
AT_BISON_CHECK([[-Dunused-d -Funused-f input-unused.y]], [[1]], [],
|
||||
[[<command line>:2: error: %define variable 'unused-d' is not used
|
||||
@@ -1384,10 +1360,10 @@ AT_SETUP([["%define" Boolean variables]])
|
||||
|
||||
AT_DATA([Input.y],
|
||||
[[%language "Java"
|
||||
%define public maybe
|
||||
%define parser_class_name {Input}
|
||||
%define public "maybe"
|
||||
%define parser_class_name "Input"
|
||||
%%
|
||||
start: %empty;
|
||||
start: ;
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK([[Input.y]], [1], [],
|
||||
@@ -1396,72 +1372,6 @@ AT_BISON_CHECK([[Input.y]], [1], [],
|
||||
|
||||
AT_CLEANUP
|
||||
|
||||
## ------------------------ ##
|
||||
## %define code variables. ##
|
||||
## ------------------------ ##
|
||||
|
||||
AT_SETUP([["%define" code variables]])
|
||||
|
||||
m4_pushdef([AT_TEST],
|
||||
[AT_DATA([input.yy],
|
||||
[[%skeleton "lalr1.cc" %locations
|
||||
%define api.location.type ]$1[quux]$2[
|
||||
%define api.namespace ]$1[quux]$2[
|
||||
%define api.prefix ]$1[quux]$2[
|
||||
%define api.token.prefix ]$1[quux]$2[
|
||||
%token TOK // Otherwise api.token.prefix is unused.
|
||||
%%
|
||||
start: TOK;
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK([[input.yy]], [0], [],
|
||||
[[input.yy:2.9-25: warning: %define variable 'api.location.type' requires '{...}' values [-Wdeprecated]
|
||||
input.yy:4.9-18: warning: %define variable 'api.prefix' requires '{...}' values [-Wdeprecated]
|
||||
input.yy:5.9-24: warning: %define variable 'api.token.prefix' requires '{...}' values [-Wdeprecated]
|
||||
input.yy:3.9-21: warning: %define variable 'api.namespace' requires '{...}' values [-Wdeprecated]
|
||||
]])
|
||||
])
|
||||
|
||||
AT_TEST([], [])
|
||||
AT_TEST(["], ["])
|
||||
m4_popdef([AT_TEST])
|
||||
|
||||
AT_CLEANUP
|
||||
|
||||
|
||||
## --------------------------- ##
|
||||
## %define keyword variables. ##
|
||||
## --------------------------- ##
|
||||
|
||||
AT_SETUP([["%define" keyword variables]])
|
||||
|
||||
m4_pushdef([AT_TEST],
|
||||
[AT_DATA([input.y],
|
||||
[[%define api.pure ]$1[true]$2[
|
||||
%define api.push-pull ]$1[both]$2[
|
||||
%define lr.default-reduction ]$1[most]$2[
|
||||
%define lr.keep-unreachable-state ]$1[true]$2[
|
||||
%define lr.type ]$1[lalr]$2[
|
||||
%%
|
||||
exp: %empty
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK([[input.y]], [0], [],
|
||||
[[input.y:5.9-15: warning: %define variable 'lr.type' requires keyword values [-Wdeprecated]
|
||||
input.y:3.9-28: warning: %define variable 'lr.default-reduction' requires keyword values [-Wdeprecated]
|
||||
input.y:4.9-33: warning: %define variable 'lr.keep-unreachable-state' requires keyword values [-Wdeprecated]
|
||||
input.y:2.9-21: warning: %define variable 'api.push-pull' requires keyword values [-Wdeprecated]
|
||||
input.y:1.9-16: warning: %define variable 'api.pure' requires keyword values [-Wdeprecated]
|
||||
]])
|
||||
])
|
||||
|
||||
AT_TEST(["], ["])
|
||||
AT_TEST([{], [}])
|
||||
m4_popdef([AT_TEST])
|
||||
|
||||
AT_CLEANUP
|
||||
|
||||
|
||||
## ------------------------ ##
|
||||
## %define enum variables. ##
|
||||
## ------------------------ ##
|
||||
@@ -1476,7 +1386,7 @@ AT_SETUP([["%define" enum variables]])
|
||||
AT_DATA([[input.y]],
|
||||
[[%define lr.default-reduction bogus
|
||||
%%
|
||||
start: %empty;
|
||||
start: ;
|
||||
]])
|
||||
AT_BISON_CHECK([[-fcaret input.y]], [[1]], [[]],
|
||||
[[input.y:1.9-28: error: invalid value for %define variable 'lr.default-reduction': 'bogus'
|
||||
@@ -1491,7 +1401,7 @@ input.y:1.9-28: accepted value: 'accepting'
|
||||
AT_DATA([[input.y]],
|
||||
[[%define api.push-pull neither
|
||||
%%
|
||||
start: %empty;
|
||||
start: ;
|
||||
]])
|
||||
AT_BISON_CHECK([[-fcaret input.y]], [[1]], [[]],
|
||||
[[input.y:1.9-21: error: invalid value for %define variable 'api.push-pull': 'neither'
|
||||
@@ -1515,10 +1425,10 @@ AT_DATA([[input.y]],
|
||||
[[%define api.push_pull both
|
||||
%define lr.keep_unreachable_states maybe
|
||||
%define namespace "foo"
|
||||
%define api.namespace {foo}
|
||||
%define api.namespace "foo"
|
||||
%define variant
|
||||
%%
|
||||
start: %empty;
|
||||
start: ;
|
||||
]])
|
||||
AT_BISON_CHECK([[-fcaret input.y]], [1], [],
|
||||
[[input.y:1.9-21: warning: deprecated directive, use '%define api.push-pull both' [-Wdeprecated]
|
||||
@@ -1531,7 +1441,7 @@ input.y:3.9-17: warning: deprecated directive, use '%define api.namespace foo' [
|
||||
%define namespace "foo"
|
||||
^^^^^^^^^
|
||||
input.y:4.9-21: error: %define variable 'api.namespace' redefined
|
||||
%define api.namespace {foo}
|
||||
%define api.namespace "foo"
|
||||
^^^^^^^^^^^^^
|
||||
input.y:3.9-17: previous definition
|
||||
%define namespace "foo"
|
||||
@@ -1551,7 +1461,7 @@ AT_SETUP([[Unused %define api.pure]])
|
||||
|
||||
# AT_CHECK_API_PURE(DECLS, VALUE)
|
||||
# -------------------------------
|
||||
# Make sure Bison reports that '%define api.pure VALUE' is unused when DECLS
|
||||
# Make sure Bison reports that `%define api.pure VALUE' is unused when DECLS
|
||||
# are specified.
|
||||
m4_define([AT_CHECK_API_PURE],
|
||||
[
|
||||
@@ -1559,7 +1469,7 @@ AT_DATA([[input.y]],
|
||||
[[%define api.pure ]$2[
|
||||
]$1[
|
||||
%%
|
||||
start: %empty;
|
||||
start: ;
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK([[input.y]], [[1]], [],
|
||||
@@ -1590,9 +1500,9 @@ m4_define([AT_CHECK_NAMESPACE_ERROR],
|
||||
AT_DATA([[input.y]],
|
||||
[[%language "C++"
|
||||
%defines
|
||||
%define api.namespace {]$1[}
|
||||
%define api.namespace "]$1["
|
||||
%%
|
||||
start: %empty;
|
||||
start: ;
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK([[input.y]], [1], [],
|
||||
@@ -1752,7 +1662,7 @@ AT_SETUP([[LAC: Errors for %define]])
|
||||
|
||||
AT_DATA([[input.y]],
|
||||
[[%%
|
||||
start: %empty;
|
||||
start: ;
|
||||
]])
|
||||
|
||||
# parse.lac.* options are useless if LAC isn't actually activated.
|
||||
@@ -1775,27 +1685,27 @@ AT_SETUP([[-Werror is not affected by -Wnone and -Wall]])
|
||||
|
||||
AT_DATA([[input.y]],
|
||||
[[%%
|
||||
a: '0' { $$ = $; };
|
||||
foo-bar: ;
|
||||
]])
|
||||
|
||||
# -Werror is not enabled by -Wall or equivalent.
|
||||
AT_BISON_CHECK([[-Wall input.y]], [[0]], [[]],
|
||||
[[input.y:2.15: warning: stray '$' [-Wother]
|
||||
[[input.y:2.1-7: warning: POSIX Yacc forbids dashes in symbol names: foo-bar [-Wyacc]
|
||||
]])
|
||||
AT_BISON_CHECK([[-W input.y]], [[0]], [[]],
|
||||
[[input.y:2.15: warning: stray '$' [-Wother]
|
||||
[[input.y:2.1-7: warning: POSIX Yacc forbids dashes in symbol names: foo-bar [-Wyacc]
|
||||
]])
|
||||
AT_BISON_CHECK([[-Wno-none input.y]], [[0]], [[]],
|
||||
[[input.y:2.15: warning: stray '$' [-Wother]
|
||||
[[input.y:2.1-7: warning: POSIX Yacc forbids dashes in symbol names: foo-bar [-Wyacc]
|
||||
]])
|
||||
|
||||
# -Werror is not disabled by -Wnone or equivalent.
|
||||
AT_BISON_CHECK([[-Werror,none,other input.y]], [[1]], [[]],
|
||||
[[input.y:2.15: error: stray '$' [-Werror=other]
|
||||
]])
|
||||
AT_BISON_CHECK([[-Werror,no-all,other input.y]], [[1]], [[]],
|
||||
[[input.y:2.15: error: stray '$' [-Werror=other]
|
||||
AT_BISON_CHECK([[-Werror,none,yacc input.y]], [[1]], [[]], [[stderr]])
|
||||
AT_CHECK([[sed 's/^.*bison:/bison:/' stderr]], [[0]],
|
||||
[[input.y:2.1-7: error: POSIX Yacc forbids dashes in symbol names: foo-bar [-Werror=yacc]
|
||||
]])
|
||||
[mv stderr experr]
|
||||
AT_BISON_CHECK([[-Werror,no-all,yacc input.y]], [[1]], [[]], [[experr]])
|
||||
|
||||
AT_CLEANUP
|
||||
|
||||
@@ -1812,17 +1722,17 @@ m4_pushdef([AT_TEST],
|
||||
[AT_DATA([[input.y]],
|
||||
[[$1
|
||||
%%
|
||||
exp: %empty;
|
||||
exp: /* empty */;
|
||||
]])
|
||||
AT_BISON_CHECK([[$2 input.y]], [[1]], [[]],
|
||||
[[$3: error: '%name-prefix' and '%define api.prefix' cannot be used together
|
||||
]])
|
||||
])
|
||||
|
||||
AT_TEST([%define api.prefix {foo} %name-prefix "bar"], [], [input.y:1.9-18])
|
||||
AT_TEST([], [-Dapi.prefix={foo} -p bar], [<command line>:2])
|
||||
AT_TEST([%name-prefix "bar"], [-Dapi.prefix={foo}], [<command line>:2])
|
||||
AT_TEST([%define api.prefix {foo}], [-p bar], [input.y:1.9-18])
|
||||
AT_TEST([%define api.prefix foo %name-prefix "bar"], [], [input.y:1.9-18])
|
||||
AT_TEST([], [-Dapi.prefix=foo -p bar], [<command line>:2])
|
||||
AT_TEST([%name-prefix "bar"], [-Dapi.prefix=foo], [<command line>:2])
|
||||
AT_TEST([%define api.prefix foo], [-p bar], [input.y:1.9-18])
|
||||
|
||||
m4_popdef([AT_TEST])
|
||||
|
||||
|
||||
+36
-35
@@ -25,8 +25,8 @@ AT_BANNER([[Java Calculator.]])
|
||||
|
||||
# _AT_DATA_JAVA_CALC_Y($1, $2, $3, [BISON-DIRECTIVES])
|
||||
# ----------------------------------------------------
|
||||
# Produce 'calc.y'. Don't call this macro directly, because it contains
|
||||
# some occurrences of '$1' etc. which will be interpreted by m4. So
|
||||
# Produce `calc.y'. Don't call this macro directly, because it contains
|
||||
# some occurrences of `$1' etc. which will be interpreted by m4. So
|
||||
# you should call it with $1, $2, and $3 as arguments, which is what
|
||||
# AT_DATA_JAVA_CALC_Y does.
|
||||
m4_define([_AT_DATA_JAVA_CALC_Y],
|
||||
@@ -37,7 +37,7 @@ AT_DATA([Calc.y],
|
||||
[[/* Infix notation calculator--calc */
|
||||
%language "Java"
|
||||
%name-prefix "Calc"
|
||||
%define parser_class_name {Calc}
|
||||
%define parser_class_name "Calc"
|
||||
%define public
|
||||
|
||||
]$4[
|
||||
@@ -206,7 +206,7 @@ AT_BISON_OPTION_POPDEFS
|
||||
|
||||
# AT_DATA_CALC_Y([BISON-OPTIONS])
|
||||
# -------------------------------
|
||||
# Produce 'calc.y'.
|
||||
# Produce `calc.y'.
|
||||
m4_define([AT_DATA_JAVA_CALC_Y],
|
||||
[_AT_DATA_JAVA_CALC_Y($[1], $[2], $[3], [$1])
|
||||
])
|
||||
@@ -215,7 +215,7 @@ m4_define([AT_DATA_JAVA_CALC_Y],
|
||||
# _AT_CHECK_JAVA_CALC_ERROR(BISON-OPTIONS, INPUT,
|
||||
# [VERBOSE-AND-LOCATED-ERROR-MESSAGE])
|
||||
# --------------------------------------------------------------
|
||||
# Run 'calc' on INPUT, and expect a 'syntax error' message.
|
||||
# Run `calc' on INPUT, and expect a `syntax error' message.
|
||||
#
|
||||
# If INPUT starts with a slash, it is used as absolute input file name,
|
||||
# otherwise as contents.
|
||||
@@ -240,7 +240,7 @@ AT_DATA([[expout]],
|
||||
AT_YYERROR_SEES_LOC_IF([],
|
||||
[[sed 's/^[-0-9.]*: //' expout >at-expout
|
||||
mv at-expout expout]])
|
||||
# 3. If error-verbose is not used, strip the', unexpected....' part.
|
||||
# 3. If error-verbose is not used, strip the`, unexpected....' part.
|
||||
m4_bmatch([$1], [%error-verbose], [],
|
||||
[[sed 's/syntax error, .*$/syntax error/' expout >at-expout
|
||||
mv at-expout expout]])
|
||||
@@ -250,7 +250,7 @@ AT_CHECK([cat stderr], 0, [expout])
|
||||
|
||||
# _AT_CHECK_JAVA_CALC([BISON-DIRECTIVES], [BISON-CODE])
|
||||
# -----------------------------------------------------
|
||||
# Start a testing chunk which compiles 'calc' grammar with
|
||||
# Start a testing chunk which compiles `calc' grammar with
|
||||
# BISON-DIRECTIVES, and performs several tests over the parser.
|
||||
m4_define([_AT_CHECK_JAVA_CALC],
|
||||
[# We use integers to avoid dependencies upon the precision of doubles.
|
||||
@@ -310,7 +310,7 @@ _AT_CHECK_JAVA_CALC_ERROR([$1], [/dev/null],
|
||||
# - (* * *): nothing to pop, a lot to discard
|
||||
# - (1 + 2 * *): some to pop and discard
|
||||
#
|
||||
# - test the action associated to 'error'
|
||||
# - test the action associated to `error'
|
||||
#
|
||||
# - check the lookahead that triggers an error is not discarded
|
||||
# when we enter error recovery. Below, the lookahead causing the
|
||||
@@ -342,7 +342,7 @@ AT_CLEANUP
|
||||
|
||||
# AT_CHECK_JAVA_CALC([BISON-DIRECTIVES])
|
||||
# --------------------------------------
|
||||
# Start a testing chunk which compiles 'calc' grammar with
|
||||
# Start a testing chunk which compiles `calc' grammar with
|
||||
# BISON-DIRECTIVES, and performs several tests over the parser.
|
||||
# Run the test with and without %error-verbose.
|
||||
m4_define([AT_CHECK_JAVA_CALC],
|
||||
@@ -444,8 +444,9 @@ m4_define([AT_CHECK_JAVA_MINIMAL_W_LEXER],
|
||||
# Check that YYParser.java contains exactly COUNT lines matching ^LINE$
|
||||
# with grep.
|
||||
m4_define([AT_CHECK_JAVA_GREP],
|
||||
[AT_CHECK([grep -c '^$1$' YYParser.java], [ignore], [m4_default([$2], [1])
|
||||
])])
|
||||
[AT_CHECK([grep -c '^$1$' YYParser.java], [], [m4_default([$2], [1])
|
||||
])
|
||||
])
|
||||
|
||||
|
||||
# ------------------------------------- #
|
||||
@@ -460,13 +461,13 @@ AT_CHECK_JAVA_GREP([[class YYParser]])
|
||||
AT_CHECK_JAVA_MINIMAL([[%name-prefix "Prefix"]])
|
||||
AT_CHECK_JAVA_GREP([[class PrefixParser]])
|
||||
|
||||
AT_CHECK_JAVA_MINIMAL([[%define api.token.prefix {TOK_}]])
|
||||
AT_CHECK_JAVA_MINIMAL([[%define api.token.prefix "TOK_"]])
|
||||
AT_CHECK_JAVA_GREP([[.*TOK_END.*]])
|
||||
|
||||
AT_CHECK_JAVA_MINIMAL([[%define parser_class_name {ParserClassName}]])
|
||||
AT_CHECK_JAVA_MINIMAL([[%define parser_class_name "ParserClassName"]])
|
||||
AT_CHECK_JAVA_GREP([[class ParserClassName]])
|
||||
|
||||
AT_CHECK_JAVA_MINIMAL([[%define package {user_java_package}]])
|
||||
AT_CHECK_JAVA_MINIMAL([[%define package "user_java_package"]])
|
||||
AT_CHECK_JAVA_GREP([[package user_java_package;]])
|
||||
|
||||
AT_CLEANUP
|
||||
@@ -529,7 +530,7 @@ AT_CHECK_JAVA_GREP([[public final strictfp class YYParser]])
|
||||
|
||||
# FIXME: Can't do a Java compile because javacomp.sh is configured for 1.3
|
||||
AT_CHECK_JAVA_MINIMAL([[
|
||||
%define annotations {/*@Deprecated @SupressWarnings("unchecked") @SupressWarnings({"unchecked", "deprecation"}) @SupressWarnings(value={"unchecked", "deprecation"})*/}
|
||||
%define annotations "/*@Deprecated @SupressWarnings(\"unchecked\") @SupressWarnings({\"unchecked\", \"deprecation\"}) @SupressWarnings(value={\"unchecked\", \"deprecation\"})*/"
|
||||
%define public]])
|
||||
AT_CHECK_JAVA_GREP([[/\*@Deprecated @SupressWarnings("unchecked") @SupressWarnings({"unchecked", "deprecation"}) @SupressWarnings(value={"unchecked", "deprecation"})\*/ public class YYParser]])
|
||||
|
||||
@@ -542,15 +543,15 @@ AT_CLEANUP
|
||||
|
||||
AT_SETUP([Java parser class extends and implements])
|
||||
|
||||
AT_CHECK_JAVA_MINIMAL([[%define extends {Thread}]])
|
||||
AT_CHECK_JAVA_MINIMAL([[%define extends "Thread"]])
|
||||
AT_CHECK_JAVA_GREP([[class YYParser extends Thread]])
|
||||
|
||||
AT_CHECK_JAVA_MINIMAL([[%define implements {Cloneable}]])
|
||||
AT_CHECK_JAVA_MINIMAL([[%define implements "Cloneable"]])
|
||||
AT_CHECK_JAVA_GREP([[class YYParser implements Cloneable]])
|
||||
|
||||
AT_CHECK_JAVA_MINIMAL([[
|
||||
%define extends {Thread}
|
||||
%define implements {Cloneable}]])
|
||||
%define extends "Thread"
|
||||
%define implements "Cloneable"]])
|
||||
AT_CHECK_JAVA_GREP([[class YYParser extends Thread implements Cloneable]])
|
||||
|
||||
AT_CLEANUP
|
||||
@@ -642,9 +643,9 @@ AT_SETUP([Java throws specifications])
|
||||
|
||||
m4_define([AT_JT_lex_throws_define], [m4_case(AT_JT_lex_throws,
|
||||
-1, [],
|
||||
0, [[%define lex_throws {}]],
|
||||
1, [[%define lex_throws {InterruptedException}]],
|
||||
2, [[%define lex_throws {InterruptedException, IllegalAccessException}]])])
|
||||
0, [[%define lex_throws ""]],
|
||||
1, [[%define lex_throws "InterruptedException"]],
|
||||
2, [[%define lex_throws "InterruptedException, IllegalAccessException"]])])
|
||||
|
||||
m4_define([AT_JT_yylex_throws], [m4_case(AT_JT_lex_throws,
|
||||
-1, [[ throws java.io.IOException]],
|
||||
@@ -661,9 +662,9 @@ m4_define([AT_JT_yylex_action], [m4_case(AT_JT_lex_throws,
|
||||
|
||||
m4_define([AT_JT_throws_define], [m4_case(AT_JT_throws,
|
||||
-1, [],
|
||||
0, [[%define throws {}]],
|
||||
1, [[%define throws {ClassNotFoundException}]],
|
||||
2, [[%define throws {ClassNotFoundException, InstantiationException}]])])
|
||||
0, [[%define throws ""]],
|
||||
1, [[%define throws "ClassNotFoundException"]],
|
||||
2, [[%define throws "ClassNotFoundException, InstantiationException"]])])
|
||||
|
||||
m4_define([AT_JT_yyaction_throws], [m4_case(AT_JT_throws,
|
||||
-1, [],
|
||||
@@ -726,16 +727,16 @@ AT_CLEANUP
|
||||
AT_SETUP([Java constructor init and init_throws])
|
||||
|
||||
AT_CHECK_JAVA_MINIMAL([[
|
||||
%define extends {Thread}
|
||||
%define extends "Thread"
|
||||
%code init { super("Test Thread"); if (true) throw new InterruptedException(); }
|
||||
%define init_throws {InterruptedException}
|
||||
%define init_throws "InterruptedException"
|
||||
%lex-param {int lex_param}]])
|
||||
AT_CHECK([[grep -q 'super("Test Thread"); if (true) throw new InterruptedException();' YYParser.java]])
|
||||
|
||||
AT_CHECK_JAVA_MINIMAL_W_LEXER([[
|
||||
%define extends {Thread}
|
||||
%define extends "Thread"
|
||||
%code init { super("Test Thread"); if (true) throw new InterruptedException(); }
|
||||
%define init_throws {InterruptedException}]], [], [[return EOF;]])
|
||||
%define init_throws "InterruptedException"]], [], [[return EOF;]])
|
||||
AT_CHECK([[grep -q 'super("Test Thread"); if (true) throw new InterruptedException();' YYParser.java]])
|
||||
|
||||
AT_CLEANUP
|
||||
@@ -748,20 +749,20 @@ AT_CLEANUP
|
||||
AT_SETUP([Java value, position, and location types])
|
||||
|
||||
AT_CHECK_JAVA_MINIMAL([[
|
||||
%define api.value.type {java.awt.Color}
|
||||
%define api.value.type "java.awt.Color"
|
||||
%type<java.awt.Color> start;
|
||||
%define api.location.type {MyLoc}
|
||||
%define api.position.type {MyPos}
|
||||
%define api.location.type "MyLoc"
|
||||
%define api.position.type "MyPos"
|
||||
%code { class MyPos {} }]], [[$$ = $<java.awt.Color>1;]], [[MyPos]])
|
||||
AT_CHECK([[grep 'java.awt.Color' YYParser.java]], [0], [ignore])
|
||||
AT_CHECK([[$EGREP -v ' */?\*' YYParser.java | grep 'Position']], [1], [ignore])
|
||||
AT_CHECK([[$EGREP -v ' */?\*' YYParser.java | grep 'Location']], [1], [ignore])
|
||||
|
||||
AT_CHECK_JAVA_MINIMAL_W_LEXER([[
|
||||
%define api.value.type {java.awt.Color}
|
||||
%define api.value.type "java.awt.Color"
|
||||
%type<java.awt.Color> start;
|
||||
%define api.location.type {MyLoc}
|
||||
%define api.position.type {MyPos}
|
||||
%define api.location.type "MyLoc"
|
||||
%define api.position.type "MyPos"
|
||||
%code { class MyPos {} }]], [], [[return EOF;]], [],
|
||||
[[$$ = $<java.awt.Color>1;]],
|
||||
[[java.awt.Color]], [[MyPos]], [[MyLoc]])
|
||||
|
||||
@@ -1,864 +0,0 @@
|
||||
# Checking Java Push Parsing. -*- Autotest -*-
|
||||
|
||||
# Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# The Java push parser tests are intended primarily
|
||||
# to verify that the sequence of states that the parser
|
||||
# traverses is the same as a pull parser would traverse.
|
||||
|
||||
##################################################
|
||||
# Provide a way to generate data with and without push parsing
|
||||
# so it is possible to capture the output for comparison
|
||||
# (except the "trivial" tests).
|
||||
# Use "both" rather than "push" so we can also set it to "pull" to
|
||||
# get the "experr" data.
|
||||
|
||||
m4_define([PUSHPULLFLAG],[-Dapi.push-pull=both])
|
||||
|
||||
# AT_CHECK_JAVA_GREP(FILE, [LINE], [COUNT=1])
|
||||
# -------------------------------------------
|
||||
# Check that FILE contains exactly COUNT lines matching ^LINE$
|
||||
# with grep. Unquoted so that COUNT can be a shell expression.
|
||||
m4_define([AT_CHECK_JAVA_GREP],
|
||||
[AT_CHECK_UNQUOTED([grep -c '^$2$' $1], [ignore], [m4_default([$3], [1])
|
||||
])])
|
||||
|
||||
##################################################
|
||||
|
||||
AT_BANNER([[Java Push Parsing Tests]])
|
||||
|
||||
# Define a single copy of the trivial parser grammar.
|
||||
# This is missing main(), so two versions
|
||||
# are instantiated with different main() procedures.
|
||||
m4_define([AT_TRIVIAL_GRAMMAR],[
|
||||
%define parser_class_name {YYParser}
|
||||
%error-verbose
|
||||
|
||||
%code imports {
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
}
|
||||
|
||||
%%
|
||||
|
||||
start: 'a' 'b' 'c' ;
|
||||
|
||||
%%
|
||||
])
|
||||
|
||||
# Define comon code across to be includede in
|
||||
# class Main for the trivial parser tests.
|
||||
m4_define([AT_TRIVIAL_COMMON],[
|
||||
static class YYerror implements YYParser.Lexer
|
||||
{
|
||||
public Object getLVal() {return null;}
|
||||
public int yylex () throws java.io.IOException { return 0; }
|
||||
public void yyerror (String msg) { System.err.println(msg); }
|
||||
}
|
||||
|
||||
static YYParser parser = null;
|
||||
static YYerror yyerror = null;
|
||||
static int teststate = -1;
|
||||
|
||||
static void setup()
|
||||
throws IOException
|
||||
{
|
||||
yyerror = new YYerror();
|
||||
parser = new YYParser(yyerror);
|
||||
parser.setDebugLevel(1);
|
||||
teststate = -1;
|
||||
}
|
||||
|
||||
static String[[]] teststatename
|
||||
= new String[[]]{"YYACCEPT","YYABORT","YYERROR","UNKNOWN","YYPUSH_MORE"};
|
||||
|
||||
static void check(int teststate, int expected, String msg)
|
||||
{
|
||||
System.err.println("teststate="+teststatename[[teststate]]
|
||||
+"; expected="+teststatename[[expected]]);
|
||||
if (teststate == expected)
|
||||
return;
|
||||
System.err.println("unexpected state: "+msg);
|
||||
System.exit(1);
|
||||
}
|
||||
])
|
||||
|
||||
m4_define([AT_TRIVIAL_PARSER],[
|
||||
AT_TRIVIAL_GRAMMAR
|
||||
|
||||
public class Main
|
||||
{
|
||||
|
||||
AT_TRIVIAL_COMMON
|
||||
|
||||
static public void main (String[[]] argv)
|
||||
throws IOException
|
||||
{
|
||||
setup();
|
||||
|
||||
teststate = parser.push_parse('a', null);
|
||||
check(teststate,YYParser.YYPUSH_MORE,"push_parse('a', null)");
|
||||
|
||||
setup();
|
||||
|
||||
teststate = parser.push_parse('a', null);
|
||||
check(teststate,YYParser.YYPUSH_MORE,"push_parse('a', null)");
|
||||
teststate = parser.push_parse('b', null);
|
||||
check(teststate,YYParser.YYPUSH_MORE,"push_parse('b', null)");
|
||||
teststate = parser.push_parse('c', null);
|
||||
check(teststate,YYParser.YYPUSH_MORE,"push_parse('c', null)");
|
||||
teststate = parser.push_parse('\0', null);
|
||||
check(teststate,YYParser.YYACCEPT,"push_parse('\\0', null)");
|
||||
|
||||
/* Reuse the parser instance and cause a failure */
|
||||
teststate = parser.push_parse('b', null);
|
||||
check(teststate,YYParser.YYABORT,"push_parse('b', null)");
|
||||
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
}
|
||||
])
|
||||
|
||||
m4_define([AT_TRIVIAL_PARSER_INITIAL_ACTION],[
|
||||
AT_TRIVIAL_GRAMMAR
|
||||
|
||||
public class Main
|
||||
{
|
||||
|
||||
AT_TRIVIAL_COMMON
|
||||
|
||||
static public void main (String[[]] argv)
|
||||
throws IOException
|
||||
{
|
||||
setup();
|
||||
|
||||
teststate = parser.push_parse('a', null);
|
||||
check(teststate,YYParser.YYPUSH_MORE,"push_parse('a', null)");
|
||||
teststate = parser.push_parse('b', null);
|
||||
check(teststate,YYParser.YYPUSH_MORE,"push_parse('b', null)");
|
||||
teststate = parser.push_parse('c', null);
|
||||
check(teststate,YYParser.YYPUSH_MORE,"push_parse('c', null)");
|
||||
teststate = parser.push_parse('\0', null);
|
||||
check(teststate,YYParser.YYACCEPT,"push_parse('\\0', null)");
|
||||
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
}
|
||||
])
|
||||
|
||||
## ----------------------------------------------------- ##
|
||||
## Trivial Push Parser with api.push-pull verification. ##
|
||||
## ----------------------------------------------------- ##
|
||||
|
||||
AT_SETUP([Trivial Push Parser with api.push-pull verification])
|
||||
AT_BISON_OPTION_PUSHDEFS
|
||||
|
||||
AT_DATA([[input.y]],
|
||||
[[%language "Java"
|
||||
]AT_TRIVIAL_PARSER[
|
||||
]])
|
||||
|
||||
# Verify that the proper procedure(s) are generated for each case.
|
||||
AT_BISON_CHECK([[-Dapi.push-pull=pull -o Main.java input.y]])
|
||||
AT_CHECK_JAVA_GREP([[Main.java]],
|
||||
[[.*public boolean parse ().*]],
|
||||
[1])
|
||||
# If BISON_USE_PUSH_FOR_PULL is set, then we have one occurrence of
|
||||
# this function, otherwise it should not be there.
|
||||
AT_CHECK_JAVA_GREP([[Main.java]],
|
||||
[[.*public int push_parse (int yylextoken, Object yylexval).*]],
|
||||
[${BISON_USE_PUSH_FOR_PULL-0}])
|
||||
|
||||
AT_BISON_CHECK([[-Dapi.push-pull=both -o Main.java input.y]])
|
||||
AT_CHECK_JAVA_GREP([[Main.java]],
|
||||
[[.*public boolean parse ().*]],
|
||||
[1])
|
||||
AT_CHECK_JAVA_GREP([[Main.java]],
|
||||
[[.*public int push_parse (int yylextoken, Object yylexval).*]],
|
||||
[1])
|
||||
|
||||
AT_BISON_CHECK([[-Dapi.push-pull=push -o Main.java input.y]])
|
||||
AT_CHECK_JAVA_GREP([[Main.java]],
|
||||
[[.*public boolean parse ().*]],
|
||||
[0])
|
||||
AT_CHECK_JAVA_GREP([[Main.java]],
|
||||
[[.*public int push_parse (int yylextoken, Object yylexval).*]],
|
||||
[1])
|
||||
|
||||
AT_JAVA_COMPILE([[Main.java]])
|
||||
AT_JAVA_PARSER_CHECK([Main], 0, [], [stderr-nolog])
|
||||
AT_BISON_OPTION_POPDEFS
|
||||
AT_CLEANUP
|
||||
|
||||
|
||||
## ------------------------------------------ ##
|
||||
## Trivial Push Parser with %initial-action. ##
|
||||
## ------------------------------------------ ##
|
||||
|
||||
AT_SETUP([Trivial Push Parser with %initial-action])
|
||||
AT_BISON_OPTION_PUSHDEFS
|
||||
AT_DATA([[input.y]],[[%language "Java"
|
||||
%initial-action {
|
||||
System.err.println("Initial action invoked");
|
||||
}
|
||||
]AT_TRIVIAL_PARSER_INITIAL_ACTION[
|
||||
]])
|
||||
AT_BISON_OPTION_POPDEFS
|
||||
AT_BISON_CHECK([[-Dapi.push-pull=push -o Main.java input.y]])
|
||||
AT_CHECK_JAVA_GREP([[Main.java]],
|
||||
[[System.err.println("Initial action invoked");]])
|
||||
AT_JAVA_COMPILE([[Main.java]])
|
||||
AT_JAVA_PARSER_CHECK([Main], 0, [], [stderr-nolog])
|
||||
# Verify that initial action is called exactly once.
|
||||
AT_CHECK_JAVA_GREP(
|
||||
[[stderr]],
|
||||
[[Initial action invoked]],
|
||||
[1])
|
||||
AT_CLEANUP
|
||||
|
||||
# Define a single copy of the Calculator grammar.
|
||||
m4_define([AT_CALC_BODY],[
|
||||
%code imports {
|
||||
import java.io.*;
|
||||
}
|
||||
|
||||
%code {
|
||||
static StringReader
|
||||
getinput(String filename) throws IOException
|
||||
{
|
||||
StringBuilder buf = new StringBuilder();
|
||||
FileReader file = new FileReader(filename);
|
||||
int c;
|
||||
while ((c=file.read()) > 0)
|
||||
buf.append((char)c);
|
||||
file.close();
|
||||
return new StringReader(buf.toString());
|
||||
}
|
||||
}
|
||||
|
||||
/* Bison Declarations */
|
||||
%token <Integer> NUM "number"
|
||||
%type <Integer> exp
|
||||
|
||||
%nonassoc '=' /* comparison */
|
||||
%left '-' '+'
|
||||
%left '*' '/'
|
||||
%left NEG /* negation--unary minus */
|
||||
%right '^' /* exponentiation */
|
||||
|
||||
/* Grammar follows */
|
||||
%%
|
||||
input:
|
||||
line
|
||||
| input line
|
||||
;
|
||||
|
||||
line:
|
||||
'\n'
|
||||
| exp '\n'
|
||||
{System.out.println("total = "+$[]1);}
|
||||
| error '\n'
|
||||
;
|
||||
|
||||
exp:
|
||||
NUM { $[]$ = $[]1;}
|
||||
| exp '=' exp
|
||||
{
|
||||
if ($[]1.intValue() != $[]3.intValue())
|
||||
yyerror (]AT_LOCATION_IF([[@$,]])[ "calc: error: " + $[]1 + " != " + $[]3);
|
||||
}
|
||||
| exp '+' exp
|
||||
{ $[]$ = new Integer ($[]1.intValue () + $[]3.intValue ()); }
|
||||
| exp '-' exp
|
||||
{ $[]$ = new Integer ($[]1.intValue () - $[]3.intValue ()); }
|
||||
| exp '*' exp
|
||||
{ $[]$ = new Integer ($[]1.intValue () * $[]3.intValue ()); }
|
||||
| exp '/' exp
|
||||
{ $[]$ = new Integer ($[]1.intValue () / $[]3.intValue ()); }
|
||||
| '-' exp %prec NEG
|
||||
{ $[]$ = new Integer (-$[]2.intValue ()); }
|
||||
| exp '^' exp
|
||||
{ $[]$ = new Integer ((int)Math.pow ($[]1.intValue (),
|
||||
$[]3.intValue ())); }
|
||||
| '(' exp ')' { $[]$ = $[]2;}
|
||||
| '(' error ')' { $[]$ = new Integer (1111);}
|
||||
| '!' { $[]$ = new Integer (0); return YYERROR;}
|
||||
| '-' error { $[]$ = new Integer (0); return YYERROR;}
|
||||
;
|
||||
])
|
||||
|
||||
# Test that the states transitioned by the push parser are the
|
||||
# same as for the pull parser. This test is assumed to work
|
||||
# if it produces the same partial trace of stack states as is
|
||||
# produced when using pull parsing. The output is verbose,
|
||||
# but seems essential for verifying push parsing.
|
||||
|
||||
AT_SETUP([Calc parser with api.push-pull both])
|
||||
AT_BISON_OPTION_PUSHDEFS
|
||||
|
||||
# Define the calculator input.
|
||||
# Warning: if you changes the input file
|
||||
# then the locations test file position numbers
|
||||
# may be incorrect and you will have
|
||||
# to modify that file as well.
|
||||
|
||||
AT_DATA([input],[[1 + 2 * 3 = 7
|
||||
1 + 2 * -3 = -5
|
||||
|
||||
-1^2 = -1
|
||||
(-1)^2 = 1
|
||||
|
||||
---1 = -1
|
||||
|
||||
1 - 2 - 3 = -4
|
||||
1 - (2 - 3) = 2
|
||||
|
||||
2^2^3 = 256
|
||||
(2^2)^3 = 64
|
||||
]])
|
||||
|
||||
# Compose pieces to build the actual .y file.
|
||||
AT_DATA([Calc.y],[[/* Infix notation calculator--calc */
|
||||
%language "Java"
|
||||
%name-prefix "Calc"
|
||||
%define parser_class_name {Calc}
|
||||
|
||||
%code {
|
||||
static class UserLexer implements Calc.Lexer
|
||||
{
|
||||
StreamTokenizer st;
|
||||
StringReader rdr;
|
||||
|
||||
public UserLexer(StringReader reader)
|
||||
{
|
||||
rdr = reader;
|
||||
st = new StreamTokenizer(rdr);
|
||||
st.resetSyntax();
|
||||
st.eolIsSignificant(true);
|
||||
st.whitespaceChars(9, 9);
|
||||
st.whitespaceChars(32, 32);
|
||||
st.wordChars(48, 57);
|
||||
}
|
||||
|
||||
Integer yylval;
|
||||
|
||||
public Object getLVal() { return yylval; }
|
||||
|
||||
public void yyerror(String msg) { System.err.println(msg); }
|
||||
|
||||
public int yylex () throws IOException
|
||||
{
|
||||
switch (st.nextToken()) {
|
||||
case StreamTokenizer.TT_EOF: return EOF;
|
||||
case StreamTokenizer.TT_EOL: return (int) '\n';
|
||||
case StreamTokenizer.TT_WORD:
|
||||
yylval = new Integer (st.sval);
|
||||
return NUM;
|
||||
default: return st.ttype;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
%code {
|
||||
public static void main (String[] argv)
|
||||
throws IOException
|
||||
{
|
||||
StringReader reader = getinput(argv[0]);
|
||||
UserLexer lexer = new UserLexer(reader);
|
||||
Calc calc = new Calc(lexer);
|
||||
calc.setDebugLevel(1);
|
||||
calc.parse();
|
||||
}//main
|
||||
|
||||
}
|
||||
|
||||
]AT_CALC_BODY[
|
||||
|
||||
]])
|
||||
|
||||
# This data was captured from running a pull parser.
|
||||
AT_DATA([[expout]],[[Stack now 0
|
||||
Stack now 0 2
|
||||
Stack now 0 9
|
||||
Stack now 0 9 19
|
||||
Stack now 0 9 19 2
|
||||
Stack now 0 9 19 28
|
||||
Stack now 0 9 19 28 20
|
||||
Stack now 0 9 19 28 20 2
|
||||
Stack now 0 9 19 28 20 29
|
||||
Stack now 0 9 19 28
|
||||
Stack now 0 9
|
||||
Stack now 0 9 17
|
||||
Stack now 0 9 17 2
|
||||
Stack now 0 9 17 26
|
||||
Stack now 0 9
|
||||
Stack now 0 9 23
|
||||
Stack now 0 8
|
||||
Stack now 0 7
|
||||
Stack now 0 7 2
|
||||
Stack now 0 7 9
|
||||
Stack now 0 7 9 19
|
||||
Stack now 0 7 9 19 2
|
||||
Stack now 0 7 9 19 28
|
||||
Stack now 0 7 9 19 28 20
|
||||
Stack now 0 7 9 19 28 20 3
|
||||
Stack now 0 7 9 19 28 20 3 2
|
||||
Stack now 0 7 9 19 28 20 3 12
|
||||
Stack now 0 7 9 19 28 20 29
|
||||
Stack now 0 7 9 19 28
|
||||
Stack now 0 7 9
|
||||
Stack now 0 7 9 17
|
||||
Stack now 0 7 9 17 3
|
||||
Stack now 0 7 9 17 3 2
|
||||
Stack now 0 7 9 17 3 12
|
||||
Stack now 0 7 9 17 26
|
||||
Stack now 0 7 9
|
||||
Stack now 0 7 9 23
|
||||
Stack now 0 7 16
|
||||
Stack now 0 7
|
||||
Stack now 0 7 4
|
||||
Stack now 0 7 16
|
||||
Stack now 0 7
|
||||
Stack now 0 7 3
|
||||
Stack now 0 7 3 2
|
||||
Stack now 0 7 3 12
|
||||
Stack now 0 7 3 12 22
|
||||
Stack now 0 7 3 12 22 2
|
||||
Stack now 0 7 3 12 22 31
|
||||
Stack now 0 7 3 12
|
||||
Stack now 0 7 9
|
||||
Stack now 0 7 9 17
|
||||
Stack now 0 7 9 17 3
|
||||
Stack now 0 7 9 17 3 2
|
||||
Stack now 0 7 9 17 3 12
|
||||
Stack now 0 7 9 17 26
|
||||
Stack now 0 7 9
|
||||
Stack now 0 7 9 23
|
||||
Stack now 0 7 16
|
||||
Stack now 0 7
|
||||
Stack now 0 7 5
|
||||
Stack now 0 7 5 3
|
||||
Stack now 0 7 5 3 2
|
||||
Stack now 0 7 5 3 12
|
||||
Stack now 0 7 5 14
|
||||
Stack now 0 7 5 14 25
|
||||
Stack now 0 7 9
|
||||
Stack now 0 7 9 22
|
||||
Stack now 0 7 9 22 2
|
||||
Stack now 0 7 9 22 31
|
||||
Stack now 0 7 9
|
||||
Stack now 0 7 9 17
|
||||
Stack now 0 7 9 17 2
|
||||
Stack now 0 7 9 17 26
|
||||
Stack now 0 7 9
|
||||
Stack now 0 7 9 23
|
||||
Stack now 0 7 16
|
||||
Stack now 0 7
|
||||
Stack now 0 7 4
|
||||
Stack now 0 7 16
|
||||
Stack now 0 7
|
||||
Stack now 0 7 3
|
||||
Stack now 0 7 3 3
|
||||
Stack now 0 7 3 3 3
|
||||
Stack now 0 7 3 3 3 2
|
||||
Stack now 0 7 3 3 3 12
|
||||
Stack now 0 7 3 3 12
|
||||
Stack now 0 7 3 12
|
||||
Stack now 0 7 9
|
||||
Stack now 0 7 9 17
|
||||
Stack now 0 7 9 17 3
|
||||
Stack now 0 7 9 17 3 2
|
||||
Stack now 0 7 9 17 3 12
|
||||
Stack now 0 7 9 17 26
|
||||
Stack now 0 7 9
|
||||
Stack now 0 7 9 23
|
||||
Stack now 0 7 16
|
||||
Stack now 0 7
|
||||
Stack now 0 7 4
|
||||
Stack now 0 7 16
|
||||
Stack now 0 7
|
||||
Stack now 0 7 2
|
||||
Stack now 0 7 9
|
||||
Stack now 0 7 9 18
|
||||
Stack now 0 7 9 18 2
|
||||
Stack now 0 7 9 18 27
|
||||
Stack now 0 7 9
|
||||
Stack now 0 7 9 18
|
||||
Stack now 0 7 9 18 2
|
||||
Stack now 0 7 9 18 27
|
||||
Stack now 0 7 9
|
||||
Stack now 0 7 9 17
|
||||
Stack now 0 7 9 17 3
|
||||
Stack now 0 7 9 17 3 2
|
||||
Stack now 0 7 9 17 3 12
|
||||
Stack now 0 7 9 17 26
|
||||
Stack now 0 7 9
|
||||
Stack now 0 7 9 23
|
||||
Stack now 0 7 16
|
||||
Stack now 0 7
|
||||
Stack now 0 7 2
|
||||
Stack now 0 7 9
|
||||
Stack now 0 7 9 18
|
||||
Stack now 0 7 9 18 5
|
||||
Stack now 0 7 9 18 5 2
|
||||
Stack now 0 7 9 18 5 14
|
||||
Stack now 0 7 9 18 5 14 18
|
||||
Stack now 0 7 9 18 5 14 18 2
|
||||
Stack now 0 7 9 18 5 14 18 27
|
||||
Stack now 0 7 9 18 5 14
|
||||
Stack now 0 7 9 18 5 14 25
|
||||
Stack now 0 7 9 18 27
|
||||
Stack now 0 7 9
|
||||
Stack now 0 7 9 17
|
||||
Stack now 0 7 9 17 2
|
||||
Stack now 0 7 9 17 26
|
||||
Stack now 0 7 9
|
||||
Stack now 0 7 9 23
|
||||
Stack now 0 7 16
|
||||
Stack now 0 7
|
||||
Stack now 0 7 4
|
||||
Stack now 0 7 16
|
||||
Stack now 0 7
|
||||
Stack now 0 7 2
|
||||
Stack now 0 7 9
|
||||
Stack now 0 7 9 22
|
||||
Stack now 0 7 9 22 2
|
||||
Stack now 0 7 9 22 31
|
||||
Stack now 0 7 9 22 31 22
|
||||
Stack now 0 7 9 22 31 22 2
|
||||
Stack now 0 7 9 22 31 22 31
|
||||
Stack now 0 7 9 22 31
|
||||
Stack now 0 7 9
|
||||
Stack now 0 7 9 17
|
||||
Stack now 0 7 9 17 2
|
||||
Stack now 0 7 9 17 26
|
||||
Stack now 0 7 9
|
||||
Stack now 0 7 9 23
|
||||
Stack now 0 7 16
|
||||
Stack now 0 7
|
||||
Stack now 0 7 5
|
||||
Stack now 0 7 5 2
|
||||
Stack now 0 7 5 14
|
||||
Stack now 0 7 5 14 22
|
||||
Stack now 0 7 5 14 22 2
|
||||
Stack now 0 7 5 14 22 31
|
||||
Stack now 0 7 5 14
|
||||
Stack now 0 7 5 14 25
|
||||
Stack now 0 7 9
|
||||
Stack now 0 7 9 22
|
||||
Stack now 0 7 9 22 2
|
||||
Stack now 0 7 9 22 31
|
||||
Stack now 0 7 9
|
||||
Stack now 0 7 9 17
|
||||
Stack now 0 7 9 17 2
|
||||
Stack now 0 7 9 17 26
|
||||
Stack now 0 7 9
|
||||
Stack now 0 7 9 23
|
||||
Stack now 0 7 16
|
||||
Stack now 0 7
|
||||
Stack now 0 7 15
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK([PUSHPULLFLAG [-o Calc.java Calc.y]])
|
||||
AT_JAVA_COMPILE([[Calc.java]])
|
||||
#Verify that this is a push parser.
|
||||
AT_CHECK_JAVA_GREP([[Calc.java]],
|
||||
[[.*public void push_parse_initialize().*]])
|
||||
# Capture stderr output for comparison purposes.
|
||||
AT_JAVA_PARSER_CHECK([Calc input], 0, [ignore-nolog], [stderr-nolog])
|
||||
# Extract the "Stack Now" lines from the error output,
|
||||
# send them to stdout (via the sed command) and compare to expout.
|
||||
# NOTE: because the target is "expout", this macro automatically
|
||||
# compares the output of the sed command with the contents of
|
||||
# the file "expout" (defined above).
|
||||
AT_CHECK([[sed -e '/^Stack now.*$/p' -e d ./stderr]],
|
||||
[ignore], [expout], [ignore-nolog])
|
||||
AT_BISON_OPTION_POPDEFS
|
||||
AT_CLEANUP
|
||||
|
||||
# This test looks for location reporting by looking
|
||||
# at the lexer output with locations enabled.
|
||||
# It defines a lexer that reports location info.
|
||||
AT_SETUP([Calc parser with %locations %code lexer and api.push-pull both])
|
||||
AT_BISON_OPTION_PUSHDEFS
|
||||
|
||||
AT_DATA([Calc.y],[[/* Infix notation calculator--calc. */
|
||||
%language "Java"
|
||||
%name-prefix "Calc"
|
||||
%define parser_class_name {Calc}
|
||||
%lex-param { Reader rdr }
|
||||
%locations
|
||||
|
||||
%code imports {
|
||||
import java.io.*;
|
||||
}
|
||||
|
||||
%code lexer {
|
||||
StreamTokenizer st;
|
||||
Integer yylval;
|
||||
|
||||
public YYLexer(Reader rdr)
|
||||
{
|
||||
st = new StreamTokenizer(rdr);
|
||||
st.resetSyntax();
|
||||
st.eolIsSignificant(true);
|
||||
st.whitespaceChars(9, 9);
|
||||
st.whitespaceChars(32, 32);
|
||||
st.wordChars(48, 57);
|
||||
}
|
||||
|
||||
Position yypos = new Position (1, 0);
|
||||
|
||||
public Position getStartPos() { return yypos; }
|
||||
|
||||
public Position getEndPos() { return yypos; }
|
||||
|
||||
public Object getLVal() { return yylval; }
|
||||
|
||||
public void yyerror(Location loc, String msg)
|
||||
{
|
||||
System.err.println(loc+":"+msg);
|
||||
}
|
||||
|
||||
public int yylex () throws IOException
|
||||
{
|
||||
yypos = new Position (yypos.lineno (),yypos.token () + 1);
|
||||
switch (st.nextToken()) {
|
||||
case StreamTokenizer.TT_EOF:
|
||||
return EOF;
|
||||
case StreamTokenizer.TT_EOL:
|
||||
yypos = new Position (yypos.lineno () + 1, 0);
|
||||
return (int) '\n';
|
||||
case StreamTokenizer.TT_WORD:
|
||||
yylval = new Integer (st.sval);
|
||||
return NUM;
|
||||
default:
|
||||
return st.ttype;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
%code {
|
||||
class Position {
|
||||
public int line;
|
||||
public int token;
|
||||
|
||||
public Position () { line = 0; token = 0; }
|
||||
|
||||
public Position (int l, int t) { line = l; token = t; }
|
||||
|
||||
public boolean equals (Position l)
|
||||
{
|
||||
return l.line == line && l.token == token;
|
||||
}
|
||||
|
||||
public String toString ()
|
||||
{
|
||||
return Integer.toString(line) + "." + Integer.toString(token);
|
||||
}
|
||||
|
||||
public int lineno () { return line; }
|
||||
|
||||
public int token () { return token; }
|
||||
}//Class Position
|
||||
}
|
||||
|
||||
%code {
|
||||
public static void main (String[] argv)
|
||||
throws IOException
|
||||
{
|
||||
StringReader reader = getinput(argv[0]);
|
||||
Calc calc = new Calc(reader);
|
||||
calc.setDebugLevel(1);
|
||||
calc.parse();
|
||||
}
|
||||
}
|
||||
|
||||
]AT_CALC_BODY[
|
||||
|
||||
]])
|
||||
|
||||
# Define the expected calculator output.
|
||||
# This should match the output from a pull parser.
|
||||
AT_DATA([output],[[total = 7
|
||||
total = -5
|
||||
total = -1
|
||||
total = 1
|
||||
total = -1
|
||||
total = -4
|
||||
total = 2
|
||||
total = 256
|
||||
total = 64
|
||||
]])
|
||||
|
||||
AT_DATA([locations],[[Next token is token "number" (1.1: 1)
|
||||
Next token is token '+' (1.2: 1)
|
||||
Next token is token "number" (1.3: 2)
|
||||
Next token is token '*' (1.4: 2)
|
||||
Next token is token "number" (1.5: 3)
|
||||
Next token is token '=' (1.6: 3)
|
||||
Next token is token '=' (1.6: 3)
|
||||
Next token is token '=' (1.6: 3)
|
||||
Next token is token "number" (1.7: 7)
|
||||
Next token is token '\n' (2.0: 7)
|
||||
Next token is token '\n' (2.0: 7)
|
||||
Next token is token "number" (2.1: 1)
|
||||
Next token is token '+' (2.2: 1)
|
||||
Next token is token "number" (2.3: 2)
|
||||
Next token is token '*' (2.4: 2)
|
||||
Next token is token '-' (2.5: 2)
|
||||
Next token is token "number" (2.6: 3)
|
||||
Next token is token '=' (2.7: 3)
|
||||
Next token is token '=' (2.7: 3)
|
||||
Next token is token '=' (2.7: 3)
|
||||
Next token is token '=' (2.7: 3)
|
||||
Next token is token '-' (2.8: 3)
|
||||
Next token is token "number" (2.9: 5)
|
||||
Next token is token '\n' (3.0: 5)
|
||||
Next token is token '\n' (3.0: 5)
|
||||
Next token is token '\n' (3.0: 5)
|
||||
Next token is token '\n' (4.0: 5)
|
||||
Next token is token '-' (4.1: 5)
|
||||
Next token is token "number" (4.2: 1)
|
||||
Next token is token '^' (4.3: 1)
|
||||
Next token is token "number" (4.4: 2)
|
||||
Next token is token '=' (4.5: 2)
|
||||
Next token is token '=' (4.5: 2)
|
||||
Next token is token '=' (4.5: 2)
|
||||
Next token is token '-' (4.6: 2)
|
||||
Next token is token "number" (4.7: 1)
|
||||
Next token is token '\n' (5.0: 1)
|
||||
Next token is token '\n' (5.0: 1)
|
||||
Next token is token '\n' (5.0: 1)
|
||||
Next token is token '(' (5.1: 1)
|
||||
Next token is token '-' (5.2: 1)
|
||||
Next token is token "number" (5.3: 1)
|
||||
Next token is token ')' (5.4: 1)
|
||||
Next token is token ')' (5.4: 1)
|
||||
Next token is token '^' (5.5: 1)
|
||||
Next token is token "number" (5.6: 2)
|
||||
Next token is token '=' (5.7: 2)
|
||||
Next token is token '=' (5.7: 2)
|
||||
Next token is token "number" (5.8: 1)
|
||||
Next token is token '\n' (6.0: 1)
|
||||
Next token is token '\n' (6.0: 1)
|
||||
Next token is token '\n' (7.0: 1)
|
||||
Next token is token '-' (7.1: 1)
|
||||
Next token is token '-' (7.2: 1)
|
||||
Next token is token '-' (7.3: 1)
|
||||
Next token is token "number" (7.4: 1)
|
||||
Next token is token '=' (7.5: 1)
|
||||
Next token is token '=' (7.5: 1)
|
||||
Next token is token '=' (7.5: 1)
|
||||
Next token is token '=' (7.5: 1)
|
||||
Next token is token '-' (7.6: 1)
|
||||
Next token is token "number" (7.7: 1)
|
||||
Next token is token '\n' (8.0: 1)
|
||||
Next token is token '\n' (8.0: 1)
|
||||
Next token is token '\n' (8.0: 1)
|
||||
Next token is token '\n' (9.0: 1)
|
||||
Next token is token "number" (9.1: 1)
|
||||
Next token is token '-' (9.2: 1)
|
||||
Next token is token "number" (9.3: 2)
|
||||
Next token is token '-' (9.4: 2)
|
||||
Next token is token '-' (9.4: 2)
|
||||
Next token is token "number" (9.5: 3)
|
||||
Next token is token '=' (9.6: 3)
|
||||
Next token is token '=' (9.6: 3)
|
||||
Next token is token '-' (9.7: 3)
|
||||
Next token is token "number" (9.8: 4)
|
||||
Next token is token '\n' (10.0: 4)
|
||||
Next token is token '\n' (10.0: 4)
|
||||
Next token is token '\n' (10.0: 4)
|
||||
Next token is token "number" (10.1: 1)
|
||||
Next token is token '-' (10.2: 1)
|
||||
Next token is token '(' (10.3: 1)
|
||||
Next token is token "number" (10.4: 2)
|
||||
Next token is token '-' (10.5: 2)
|
||||
Next token is token "number" (10.6: 3)
|
||||
Next token is token ')' (10.7: 3)
|
||||
Next token is token ')' (10.7: 3)
|
||||
Next token is token '=' (10.8: 3)
|
||||
Next token is token '=' (10.8: 3)
|
||||
Next token is token "number" (10.9: 2)
|
||||
Next token is token '\n' (11.0: 2)
|
||||
Next token is token '\n' (11.0: 2)
|
||||
Next token is token '\n' (12.0: 2)
|
||||
Next token is token "number" (12.1: 2)
|
||||
Next token is token '^' (12.2: 2)
|
||||
Next token is token "number" (12.3: 2)
|
||||
Next token is token '^' (12.4: 2)
|
||||
Next token is token "number" (12.5: 3)
|
||||
Next token is token '=' (12.6: 3)
|
||||
Next token is token '=' (12.6: 3)
|
||||
Next token is token '=' (12.6: 3)
|
||||
Next token is token "number" (12.7: 256)
|
||||
Next token is token '\n' (13.0: 256)
|
||||
Next token is token '\n' (13.0: 256)
|
||||
Next token is token '(' (13.1: 256)
|
||||
Next token is token "number" (13.2: 2)
|
||||
Next token is token '^' (13.3: 2)
|
||||
Next token is token "number" (13.4: 2)
|
||||
Next token is token ')' (13.5: 2)
|
||||
Next token is token ')' (13.5: 2)
|
||||
Next token is token '^' (13.6: 2)
|
||||
Next token is token "number" (13.7: 3)
|
||||
Next token is token '=' (13.8: 3)
|
||||
Next token is token '=' (13.8: 3)
|
||||
Next token is token "number" (13.9: 64)
|
||||
Next token is token '\n' (14.0: 64)
|
||||
Next token is token '\n' (14.0: 64)
|
||||
]])
|
||||
|
||||
# Define the calculator input.
|
||||
# Warning: if you changes the input file
|
||||
# then the locations test file position numbers
|
||||
# may be incorrect and you will have
|
||||
# to modify that file as well.
|
||||
|
||||
AT_DATA([input],[[1 + 2 * 3 = 7
|
||||
1 + 2 * -3 = -5
|
||||
|
||||
-1^2 = -1
|
||||
(-1)^2 = 1
|
||||
|
||||
---1 = -1
|
||||
|
||||
1 - 2 - 3 = -4
|
||||
1 - (2 - 3) = 2
|
||||
|
||||
2^2^3 = 256
|
||||
(2^2)^3 = 64
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK([PUSHPULLFLAG [-o Calc.java Calc.y]])
|
||||
AT_JAVA_COMPILE([[Calc.java]])
|
||||
# Verify that this is a push parser
|
||||
AT_CHECK_JAVA_GREP([[Calc.java]],
|
||||
[[.*public void push_parse_initialize().*]])
|
||||
# Capture the stdout and stderr output for comparison purposes.
|
||||
AT_JAVA_PARSER_CHECK([Calc input], 0, [stdout-nolog], [stderr-nolog])
|
||||
# 1. Check that the token locations are correct
|
||||
AT_CHECK([[cp -f ./locations ./expout]],[ignore],[ignore-nolog],[ignore-nolog])
|
||||
AT_CHECK([[sed -e '/^Next token.*$/p' -e d ./stderr]],[ignore],[expout],[ignore-nolog])
|
||||
# 2. Check that the calculator output matches that of a pull parser
|
||||
AT_CHECK([[rm -f ./expout; cp -f ./output ./expout]],[ignore],[ignore-nolog],[ignore-nolog])
|
||||
AT_CHECK([[cat ./stdout]],[ignore],[expout],[ignore-nolog])
|
||||
AT_CLEANUP
|
||||
+109
-155
@@ -37,7 +37,7 @@ m4_define([AT_SETUP_STRIP],
|
||||
[m4_bpatsubsts([$1],
|
||||
[%\(language\|skeleton\) "?\([^\" ]*\)"?],
|
||||
[\2],
|
||||
[%define "?\([-A-Za-z0-9_.]+\)"? \({[^\}]+}\|"[^\"]+"\|[-A-Za-z0-9_.]+\)],
|
||||
[%define "?\([-A-Za-z0-9_.]+\)"? \("[^\"]+"\|[-A-Za-z0-9_.]+\)],
|
||||
[\1=\2],
|
||||
[%define "?\([-A-Za-z0-9_.]+\)"?],
|
||||
[\1],
|
||||
@@ -134,7 +134,7 @@ m4_define([AT_BISON_OPTION_PUSHDEFS],
|
||||
# _AT_BISON_OPTION_PUSHDEFS($1, $2, [BISON-OPTIONS])
|
||||
# --------------------------------------------------
|
||||
# This macro works around the impossibility to define macros
|
||||
# inside macros, because issuing '[$1]' is not possible in M4 :(.
|
||||
# inside macros, because issuing `[$1]' is not possible in M4 :(.
|
||||
# This sucks hard, GNU M4 should really provide M5-like $$1.
|
||||
m4_define([_AT_BISON_OPTION_PUSHDEFS],
|
||||
[m4_if([$1$2], $[1]$[2], [],
|
||||
@@ -178,25 +178,23 @@ m4_bpatsubst([$3], [%parse-param { *\([^{}]*[^{} ]\) *}],
|
||||
|
||||
m4_pushdef([AT_PURE_IF],
|
||||
[m4_bmatch([$3], [%define *api\.pure\|%pure-parser],
|
||||
[m4_bmatch([$3], [%define *api\.pure *false], [$2], [$1])],
|
||||
[m4_bmatch([$3], [%define *api\.pure *"?false"?], [$2], [$1])],
|
||||
[$2])])
|
||||
# AT_NAME_PREFIX: also consider api.namespace.
|
||||
m4_pushdef([AT_NAME_PREFIX],
|
||||
[m4_bmatch([$3], [\(%define api\.\(namespace\|prefix\)\|%name-prefix\) .*],
|
||||
[m4_bregexp([$3],
|
||||
[\(%define api\.\(namespace\|prefix\)\|%name-prefix\) [\{\"]\([^\"\}]*\)[\"\}]],
|
||||
[\3])],
|
||||
[yy])])
|
||||
[m4_bmatch([$3], [\(%define api\.\(namespace\|prefix\)\|%name-prefix\) ".*"],
|
||||
[m4_bregexp([$3], [\(%define api\.\(namespace\|prefix\)\|%name-prefix\) "\([^""]*\)"], [\3])],
|
||||
[yy])])
|
||||
m4_pushdef([AT_TOKEN_CTOR_IF],
|
||||
[m4_bmatch([$3], [%define api\.token\.constructor], [$1], [$2])])
|
||||
m4_pushdef([AT_TOKEN_PREFIX],
|
||||
[m4_bmatch([$3], [%define api\.token\.prefix {.*}],
|
||||
[m4_bregexp([$3], [%define api\.token\.prefix {\(.*\)}], [\1])])])
|
||||
[m4_bmatch([$3], [%define api\.token\.prefix ".*"],
|
||||
[m4_bregexp([$3], [%define api\.token\.prefix "\(.*\)"], [\1])])])
|
||||
m4_pushdef([AT_VARIANT_IF],
|
||||
[m4_bmatch([$3], [%define api\.value\.type variant], [$1], [$2])])
|
||||
[m4_bmatch([$3], [%define api\.value\.type "?variant"?], [$1], [$2])])
|
||||
m4_pushdef([AT_API_prefix],
|
||||
[m4_bmatch([$3], [%define api\.prefix {.*}],
|
||||
[m4_bregexp([$3], [%define api\.prefix {\([^\}]*\)}], [\1])],
|
||||
[m4_bmatch([$3], [%define api\.prefix ".*"],
|
||||
[m4_bregexp([$3], [%define api\.prefix "\([^""]*\)"], [\1])],
|
||||
[yy])])
|
||||
m4_pushdef([AT_API_PREFIX],
|
||||
[m4_toupper(AT_API_prefix)])
|
||||
@@ -207,7 +205,7 @@ m4_pushdef([AT_API_PREFIX],
|
||||
m4_pushdef([AT_YYERROR_ARG_LOC_IF],
|
||||
[AT_LOCATION_IF([AT_PURE_IF([m4_bmatch([$3],
|
||||
m4_quote(m4_join([\|],
|
||||
[%define api\.pure full],
|
||||
[%define api\.pure "?full"?],
|
||||
[%glr-parser],
|
||||
[%parse-param],
|
||||
[%skeleton "?glr.c"?])),
|
||||
@@ -319,29 +317,10 @@ AT_LOC_POPDEF])dnl
|
||||
## Generating Grammar Files. ##
|
||||
## -------------------------- ##
|
||||
|
||||
# _AT_LANG_DISPATCH(LANG, MACRO, ARGS)
|
||||
# ------------------------------------
|
||||
# Call the specialization of MACRO for LANG with ARGS. Complain if
|
||||
# unavailable.
|
||||
m4_define([_AT_LANG_DISPATCH],
|
||||
[m4_ifdef([$2($1)],
|
||||
[m4_indir([$2($1)], m4_shift2($@))],
|
||||
[m4_fatal([$2: unknown language: $1])])])
|
||||
|
||||
|
||||
# AT_LANG_DISPATCH(MACRO, ARGS)
|
||||
# -----------------------------
|
||||
# Call the specialization of MACRO for AT_LANG with ARGS. Complain if
|
||||
# unavailable.
|
||||
m4_define([AT_LANG_DISPATCH],
|
||||
[_AT_LANG_DISPATCH(AT_LANG, $@)])
|
||||
|
||||
|
||||
|
||||
# AT_DATA_SOURCE_PROLOGUE
|
||||
# -----------------------
|
||||
# ------------------------
|
||||
# The prologue that should be included in any source code that is
|
||||
# meant to be compiled. Keep atlocal.in sync (BISON_CXX_WORKS).
|
||||
# meant to be compiled.
|
||||
m4_define([AT_DATA_SOURCE_PROLOGUE],
|
||||
[[#include <config.h>
|
||||
/* We don't need perfect functions for these tests. */
|
||||
@@ -427,33 +406,24 @@ static
|
||||
# AT_YYERROR_DEFINE
|
||||
# -------------------------
|
||||
# Must be called inside a AT_BISON_OPTION_PUSHDEFS/POPDEFS pair.
|
||||
m4_define([AT_YYERROR_FORMALS], [AT_LANG_DISPATCH([$0], $@)])
|
||||
m4_define([AT_YYERROR_PROTOTYPE],[AT_LANG_DISPATCH([$0], $@)])
|
||||
m4_define([AT_YYERROR_DECLARE_EXTERN], [AT_LANG_DISPATCH([$0], $@)])
|
||||
m4_define([AT_YYERROR_DECLARE], [AT_LANG_DISPATCH([$0], $@)])
|
||||
m4_define([AT_YYERROR_DEFINE], [AT_LANG_DISPATCH([$0], $@)])
|
||||
m4_define([AT_YYERROR_FORMALS],
|
||||
[m4_case(AT_LANG,
|
||||
[c], [AT_YYERROR_ARG_LOC_IF([AT_YYLTYPE const * const llocp, ])AT_PARSE_PARAMS [const char *msg]])[]dnl
|
||||
])
|
||||
|
||||
# AT_MAIN_DEFINE
|
||||
# --------------
|
||||
m4_define([AT_MAIN_DEFINE], [AT_LANG_DISPATCH([$0], $@)])
|
||||
m4_define([AT_YYERROR_PROTOTYPE],
|
||||
[m4_case(AT_LANG,
|
||||
[c], [[void ]AT_NAME_PREFIX[error (]AT_YYERROR_FORMALS[)]])[]dnl
|
||||
])
|
||||
|
||||
m4_define([AT_YYERROR_DECLARE_EXTERN],
|
||||
[m4_case(AT_LANG,
|
||||
[c], [AT_YYERROR_PROTOTYPE;])[]dnl
|
||||
])
|
||||
|
||||
|
||||
## --- ##
|
||||
## C. ##
|
||||
## --- ##
|
||||
|
||||
m4_define([AT_YYERROR_FORMALS(c)],
|
||||
[AT_YYERROR_ARG_LOC_IF([AT_YYLTYPE const * const llocp, ])AT_PARSE_PARAMS[const char *msg]])
|
||||
|
||||
m4_define([AT_YYERROR_PROTOTYPE(c)],
|
||||
[[void ]AT_NAME_PREFIX[error (]AT_YYERROR_FORMALS[)]])
|
||||
|
||||
m4_define([AT_YYERROR_DECLARE_EXTERN(c)],
|
||||
[AT_YYERROR_PROTOTYPE;])
|
||||
|
||||
m4_define([AT_YYERROR_DECLARE(c)],
|
||||
[#include <stdio.h>
|
||||
m4_define([AT_YYERROR_DECLARE],
|
||||
[m4_case(AT_LANG,
|
||||
[c], [#include <stdio.h>
|
||||
]AT_LOCATION_IF([[
|
||||
#if defined ]AT_YYLTYPE[_IS_TRIVIAL && ]AT_YYLTYPE[_IS_TRIVIAL
|
||||
static unsigned location_print (FILE *yyo, ]AT_YYLTYPE[ const * const yylocp);
|
||||
@@ -462,11 +432,12 @@ static unsigned location_print (FILE *yyo, ]AT_YYLTYPE[ const * const yylocp);
|
||||
# endif
|
||||
#endif
|
||||
]])[
|
||||
static AT_YYERROR_DECLARE_EXTERN])
|
||||
static AT_YYERROR_DECLARE_EXTERN])[]dnl
|
||||
])
|
||||
|
||||
|
||||
m4_define([AT_YYERROR_DEFINE(c)],
|
||||
[[
|
||||
m4_define([AT_YYERROR_DEFINE],
|
||||
[m4_case(AT_LANG,
|
||||
[c], [[
|
||||
]AT_LOCATION_IF([[
|
||||
# if defined ]AT_YYLTYPE[_IS_TRIVIAL && ]AT_YYLTYPE[_IS_TRIVIAL
|
||||
/* Print *YYLOCP on YYO. */
|
||||
@@ -507,10 +478,34 @@ AT_YYERROR_SEES_LOC_IF([[
|
||||
LOCATION_PRINT (stderr, ]AT_LOC[);
|
||||
fprintf (stderr, ": ");]])[
|
||||
fprintf (stderr, "%s\n", msg);
|
||||
}]])
|
||||
}]],
|
||||
[c++], [[/* A C++ error reporting function. */
|
||||
void
|
||||
]AT_NAME_PREFIX[::parser::error (]AT_LOCATION_IF([[const location_type& l, ]])[const std::string& m)
|
||||
{
|
||||
std::cerr << ]AT_LOCATION_IF([l << ": " << ])[m << std::endl;
|
||||
}]],
|
||||
[java], [AT_LOCATION_IF([[public void yyerror (Calc.Location l, String s)
|
||||
{
|
||||
if (l == null)
|
||||
System.err.println (s);
|
||||
else
|
||||
System.err.println (l + ": " + s);
|
||||
}
|
||||
]], [[
|
||||
public void yyerror (String s)
|
||||
{
|
||||
System.err.println (s);
|
||||
}]])],
|
||||
[m4_fatal([$0: invalid language: ]AT_LANG)])dnl
|
||||
])
|
||||
|
||||
|
||||
m4_define([AT_MAIN_DEFINE(c)],
|
||||
# AT_MAIN_DEFINE
|
||||
# --------------
|
||||
m4_define([AT_MAIN_DEFINE],
|
||||
[m4_case(AT_LANG,
|
||||
[c],
|
||||
[[#include <stdlib.h> /* getenv. */
|
||||
#include <string.h> /* strcmp. */
|
||||
int
|
||||
@@ -523,27 +518,8 @@ main (int argc, char const* argv[])
|
||||
(void) argc;
|
||||
(void) argv;]])[
|
||||
return ]AT_NAME_PREFIX[parse ();
|
||||
}]])
|
||||
|
||||
|
||||
## ----- ##
|
||||
## C++. ##
|
||||
## ----- ##
|
||||
|
||||
# No need to declare, it's part of the class interface.
|
||||
m4_define([AT_YYERROR_DECLARE(c++)], [])
|
||||
m4_define([AT_YYERROR_DECLARE_EXTERN(c++)], [])
|
||||
|
||||
m4_define([AT_YYERROR_DEFINE(c++)],
|
||||
[[/* A C++ error reporting function. */
|
||||
void
|
||||
]AT_NAME_PREFIX[::parser::error (]AT_LOCATION_IF([[const location_type& l, ]])[const std::string& m)
|
||||
{
|
||||
std::cerr << ]AT_LOCATION_IF([l << ": " << ])[m << std::endl;
|
||||
}]])
|
||||
|
||||
|
||||
m4_define([AT_MAIN_DEFINE(c++)],
|
||||
}]],
|
||||
[c++],
|
||||
[[#include <cstdlib> // getenv.
|
||||
#include <cstring> // strcmp.
|
||||
int
|
||||
@@ -557,30 +533,8 @@ main (int argc, char const* argv[])
|
||||
(void) argc;
|
||||
(void) argv;]])[
|
||||
return p.parse ();
|
||||
}]])
|
||||
|
||||
|
||||
|
||||
## ------ ##
|
||||
## Java. ##
|
||||
## ------ ##
|
||||
|
||||
m4_define([AT_YYERROR_DEFINE(java)],
|
||||
[AT_LOCATION_IF([[public void yyerror (Calc.Location l, String s)
|
||||
{
|
||||
if (l == null)
|
||||
System.err.println (s);
|
||||
else
|
||||
System.err.println (l + ": " + s);
|
||||
}
|
||||
]], [[
|
||||
public void yyerror (String s)
|
||||
{
|
||||
System.err.println (s);
|
||||
}
|
||||
]])])
|
||||
|
||||
m4_define([AT_MAIN_DEFINE(java)],
|
||||
}]],
|
||||
[java],
|
||||
[[class input
|
||||
{
|
||||
public static void main (String args[]) throws IOException
|
||||
@@ -588,8 +542,7 @@ m4_define([AT_MAIN_DEFINE(java)],
|
||||
YYParser p = new YYParser ();
|
||||
p.parse ();
|
||||
}
|
||||
}]])
|
||||
|
||||
}]])])
|
||||
|
||||
|
||||
## --------------- ##
|
||||
@@ -601,7 +554,7 @@ m4_define([AT_MAIN_DEFINE(java)],
|
||||
# High-level routine that may call bison several times, under different
|
||||
# conditions.
|
||||
#
|
||||
# Check Bison by invoking 'bison BISON_ARGS'. BISON_ARGS should not contain
|
||||
# Check Bison by invoking `bison BISON_ARGS'. BISON_ARGS should not contain
|
||||
# shell constructs (such as redirection or pipes) that would prevent
|
||||
# appending additional command-line arguments for bison. OTHER_AT_CHECK_ARGS
|
||||
# are the usual remaining arguments to AT_CHECK: STATUS, STDOUT, etc.
|
||||
@@ -754,7 +707,6 @@ AT_CHECK(m4_join([ ],
|
||||
[m4_bmatch([$1], [[.]], [], [$LIBS])]),
|
||||
0, [ignore], [ignore])])
|
||||
|
||||
|
||||
# AT_COMPILE_CXX(OUTPUT, [SOURCES = OUTPUT.cc])
|
||||
# ---------------------------------------------
|
||||
# Compile SOURCES into OUTPUT. If the C++ compiler does not work,
|
||||
@@ -762,7 +714,7 @@ AT_CHECK(m4_join([ ],
|
||||
#
|
||||
# If OUTPUT does not contain '.', assume that we are linking too,
|
||||
# otherwise pass "-c"; this is a hack. The default SOURCES is OUTPUT
|
||||
# with trailing ".o" removed, and ".cc" appended.
|
||||
# with trailing .o removed, and ".cc" appended.
|
||||
m4_define([AT_COMPILE_CXX],
|
||||
[AT_KEYWORDS(c++)
|
||||
AT_CHECK([$BISON_CXX_WORKS], 0, ignore, ignore)
|
||||
@@ -774,7 +726,6 @@ AT_CHECK(m4_join([ ],
|
||||
[m4_bmatch([$1], [[.]], [], [$LIBS])]),
|
||||
0, [ignore], [ignore])])
|
||||
|
||||
|
||||
# AT_JAVA_COMPILE(SOURCES)
|
||||
# ------------------------
|
||||
# Compile SOURCES into Java class files. Skip the test if java or javac
|
||||
@@ -783,10 +734,9 @@ m4_define([AT_JAVA_COMPILE],
|
||||
[AT_KEYWORDS(java)
|
||||
AT_SKIP_IF([[test -z "$CONF_JAVAC"]])
|
||||
AT_SKIP_IF([[test -z "$CONF_JAVA"]])
|
||||
AT_CHECK([[$SHELL ../../../javacomp.sh ]$1],
|
||||
AT_CHECK([[$SHELL $abs_top_builddir/javacomp.sh ]$1],
|
||||
[[0]], [ignore], [ignore])])
|
||||
|
||||
|
||||
# AT_LANG_COMPILE(OUTPUT, [SOURCES = OUTPUT.c]
|
||||
# --------------------------------------------
|
||||
# Compile SOURCES into OUTPUT. Skip if compiler does not work.
|
||||
@@ -794,11 +744,13 @@ AT_CHECK([[$SHELL ../../../javacomp.sh ]$1],
|
||||
# If OUTPUT does not contain '.', assume that we are linking too,
|
||||
# otherwise pass "-c"; this is a hack. The default SOURCES is OUTPUT
|
||||
# with trailing .o removed, and ".c"/".cc" appended.
|
||||
m4_define([AT_LANG_COMPILE], [AT_LANG_DISPATCH([$0], $@)])
|
||||
m4_define([AT_LANG_COMPILE(c)], [AT_COMPILE([$1], [$2])])
|
||||
m4_define([AT_LANG_COMPILE(c++)], [AT_COMPILE_CXX([$1], [$2])])
|
||||
m4_define([AT_LANG_COMPILE(java)], [AT_JAVA_COMPILE([$1.java], [$2])])
|
||||
|
||||
m4_define([AT_LANG_COMPILE],
|
||||
[m4_case(AT_LANG,
|
||||
[c], [AT_COMPILE([$1], [$2])],
|
||||
[c++], [AT_COMPILE_CXX([$1], [$2])],
|
||||
[java], [AT_JAVA_COMPILE([$1.java], [$2])],
|
||||
[m4_fatal([unknown language: ]m4_defn([AT_LANG]))])[]dnl
|
||||
])
|
||||
|
||||
# AT_FULL_COMPILE(OUTPUT, [OTHER1], [OTHER2])
|
||||
# -------------------------------------------
|
||||
@@ -807,31 +759,30 @@ m4_define([AT_LANG_COMPILE(java)], [AT_JAVA_COMPILE([$1.java], [$2])])
|
||||
# OUTPUT-OTHER.c, OUTPUT-OTHER.cc, or OUTPUT-OTHER.java to OUTPUT or
|
||||
# OUTPUT.java along with it. Relies on AT_SKEL_CC_IF and
|
||||
# AT_SKEL_JAVA_IF.
|
||||
m4_define([AT_FULL_COMPILE], [AT_LANG_DISPATCH([$0], $@)])
|
||||
m4_define([AT_FULL_COMPILE(c)],
|
||||
[AT_BISON_CHECK([-o $1.c $1.y])
|
||||
AT_LANG_COMPILE([$1],
|
||||
m4_join([ ],
|
||||
[$1.c],
|
||||
m4_ifval($2, [[$1-$2.c]]),
|
||||
m4_ifval($3, [[$1-$3.c]])))])
|
||||
|
||||
m4_define([AT_FULL_COMPILE(c++)],
|
||||
[AT_BISON_CHECK([-o $1.cc $1.y])
|
||||
AT_LANG_COMPILE([$1],
|
||||
m4_join([ ],
|
||||
[$1.cc],
|
||||
m4_ifval($2, [[$1-$2.cc]]),
|
||||
m4_ifval($3, [[$1-$3.cc]])))])
|
||||
|
||||
m4_define([AT_FULL_COMPILE(java)],
|
||||
[AT_BISON_CHECK([-o $1.java $1.y])
|
||||
AT_LANG_COMPILE([$1],
|
||||
m4_join([ ],
|
||||
[$1.java],
|
||||
m4_ifval($2, [[$1-$2.java]]),
|
||||
m4_ifval($3, [[$1-$3.java]])))])
|
||||
|
||||
m4_define([AT_FULL_COMPILE],
|
||||
[m4_case(AT_LANG,
|
||||
[java],
|
||||
[AT_BISON_CHECK([-o $1.java $1.y])
|
||||
AT_LANG_COMPILE([$1],
|
||||
m4_join([ ],
|
||||
[$1.java],
|
||||
m4_ifval($2, [[$1-$2.java]]),
|
||||
m4_ifval($3, [[$1-$3.java]])))],
|
||||
[c++],
|
||||
[AT_BISON_CHECK([-o $1.cc $1.y])
|
||||
AT_LANG_COMPILE([$1],
|
||||
m4_join([ ],
|
||||
[$1.cc],
|
||||
m4_ifval($2, [[$1-$2.cc]]),
|
||||
m4_ifval($3, [[$1-$3.cc]])))],
|
||||
[c],
|
||||
[AT_BISON_CHECK([-o $1.c $1.y])
|
||||
AT_LANG_COMPILE([$1],
|
||||
m4_join([ ],
|
||||
[$1.c],
|
||||
m4_ifval($2, [[$1-$2.c]]),
|
||||
m4_ifval($3, [[$1-$3.c]])))])
|
||||
])
|
||||
|
||||
|
||||
|
||||
@@ -879,7 +830,7 @@ AT_PARSER_CHECK([./c-and-cxx])
|
||||
|
||||
# AT_PARSER_CHECK(COMMAND, EXIT-STATUS, EXPOUT, EXPERR, [PRE])
|
||||
# ------------------------------------------------------------
|
||||
# So that we can run './testsuite PREPARSER='valgrind -q' for instance.
|
||||
# So that we can run `./testsuite PREPARSER='valgrind -q' for instance.
|
||||
#
|
||||
# Get rid of spurious messages when compiled with --coverage:
|
||||
# +profiling:/[...]/lib/fprintf.gcda:Merge mismatch for summaries
|
||||
@@ -893,7 +844,7 @@ AT_CHECK([sed >&2 -e '/^profiling:.*:Merge mismatch for summaries/d' stderr],
|
||||
# AT_JAVA_PARSER_CHECK(COMMAND, EXIT-STATUS, EXPOUT, EXPERR, [PRE])
|
||||
# -----------------------------------------------------------------
|
||||
m4_define([AT_JAVA_PARSER_CHECK],
|
||||
[AT_CHECK([$5[ $SHELL ../../../javaexec.sh ]$1], [$2], [$3], [$4])])
|
||||
[AT_CHECK([$5[ $SHELL $abs_top_builddir/javaexec.sh ]$1], [$2], [$3], [$4])])
|
||||
|
||||
|
||||
# AT_TEST_TABLES_AND_PARSE(TITLE, COND-VALUE, TEST-SPEC,
|
||||
@@ -921,16 +872,16 @@ m4_define([AT_JAVA_PARSER_CHECK],
|
||||
# that Bison exits with value 0, has no stdout, and has stderr
|
||||
# BISON-STDERR.
|
||||
#
|
||||
# If TEST-SPEC contains the attribute 'last-state', check that the value
|
||||
# If TEST-SPEC contains the attribute `last-state', check that the value
|
||||
# of TABLES-OR-LAST-STATE is the index of the last state generated for
|
||||
# the grammar; in other words, check the number of states (minus one).
|
||||
# Otherwise, check that everything in the '.output' file starting with
|
||||
# Otherwise, check that everything in the `.output' file starting with
|
||||
# the definition of state 0 is the same as the entire value of
|
||||
# TABLES-OR-LAST-STATE.
|
||||
#
|
||||
# Expand the M4 in OTHER-CHECKS to perform additional checks of the
|
||||
# '.output' file, which is named 'input.output', and/or grammar file,
|
||||
# which is named 'input.y'.
|
||||
# `.output' file, which is named `input.output', and/or grammar file,
|
||||
# which is named `input.y'.
|
||||
#
|
||||
# Finally, compile the generated parser and then run it using
|
||||
# AT_PARSER_CHECK with PARSER-EXIT-VALUE, PARSER-STDOUT, and
|
||||
@@ -1011,7 +962,7 @@ yylex (void)
|
||||
|
||||
m4_if(m4_index(m4_quote($3), [no-xml]), -1,
|
||||
[AT_BISON_CHECK],
|
||||
[AT_BISON_CHECK_NO_XML])([[-Wall --report=all --defines -o input.c input.y]],
|
||||
[AT_BISON_CHECK_NO_XML])([[--report=all --defines -o input.c input.y]],
|
||||
[0], [], m4_dquote($7))
|
||||
|
||||
m4_if(m4_index(m4_quote($3), [last-state]), -1,
|
||||
@@ -1071,6 +1022,9 @@ m4_define([AT_SETUP],
|
||||
AT_ARG_OPTION([compile-c-with-cxx],
|
||||
[compile C parsers with the C++ compiler])
|
||||
|
||||
AT_ARG_OPTION([release],
|
||||
[check xml and use push for pull])
|
||||
|
||||
AT_COLOR_TESTS
|
||||
|
||||
AT_TESTED([bison])
|
||||
|
||||
+22
-17
@@ -53,7 +53,6 @@ TESTSUITE_AT = \
|
||||
tests/headers.at \
|
||||
tests/input.at \
|
||||
tests/java.at \
|
||||
tests/javapush.at \
|
||||
tests/local.at \
|
||||
tests/named-refs.at \
|
||||
tests/output.at \
|
||||
@@ -64,8 +63,7 @@ TESTSUITE_AT = \
|
||||
tests/sets.at \
|
||||
tests/skeletons.at \
|
||||
tests/synclines.at \
|
||||
tests/torture.at \
|
||||
tests/types.at
|
||||
tests/torture.at
|
||||
|
||||
TESTSUITE = $(top_srcdir)/tests/testsuite
|
||||
|
||||
@@ -82,8 +80,17 @@ $(TESTSUITE): $(TESTSUITE_AT)
|
||||
## Run the test suite. ##
|
||||
## -------------------- ##
|
||||
|
||||
# Move into tests/ so that testsuite.dir etc. be created there.
|
||||
RUN_TESTSUITE = $(TESTSUITE) -C tests $(TESTSUITEFLAGS)
|
||||
# Move into tests/ so that testsuite.dir etc. be created there. If a suffix is
|
||||
# specified, create it in a corresponding subdirectory of tests/.
|
||||
RUN_TESTSUITE = dir=tests/$$suf \
|
||||
&& { test -d $$dir || mkdir $$dir; } \
|
||||
&& { test -f $$dir/atconfig \
|
||||
&& diff -q $$dir/atconfig tests/atconfig \
|
||||
|| cp tests/atconfig $$dir; } \
|
||||
&& { test -f $$dir/atlocal \
|
||||
&& diff -q $$dir/atlocal tests/atlocal \
|
||||
|| cp tests/atlocal $$dir; } \
|
||||
&& $(TESTSUITE) -C $$dir $$TESTSUITEFLAGS
|
||||
check_SCRIPTS = $(BISON) tests/atconfig tests/atlocal
|
||||
RUN_TESTSUITE_deps = $(TESTSUITE) $(check_SCRIPTS)
|
||||
|
||||
@@ -101,28 +108,26 @@ installcheck-local: $(RUN_TESTSUITE_deps)
|
||||
# Be real mean with it.
|
||||
.PHONY: maintainer-check-g++
|
||||
maintainer-check-g++: $(RUN_TESTSUITE_deps)
|
||||
$(RUN_TESTSUITE) --compile-c-with-cxx
|
||||
suf=$@ $(RUN_TESTSUITE) --compile-c-with-cxx
|
||||
|
||||
.PHONY: maintainer-check-posix
|
||||
maintainer-check-posix: $(RUN_TESTSUITE_deps)
|
||||
$(RUN_TESTSUITE) POSIXLY_CORRECT=1 _POSIX2_VERSION=200112
|
||||
suf=$@ $(RUN_TESTSUITE) POSIXLY_CORRECT=1 _POSIX2_VERSION=200112
|
||||
|
||||
.PHONY: maintainer-check-valgrind
|
||||
maintainer-check-valgrind: $(RUN_TESTSUITE_deps)
|
||||
test -z '$(VALGRIND)' || \
|
||||
$(RUN_TESTSUITE) \
|
||||
suf=$@ $(RUN_TESTSUITE) \
|
||||
PREBISON='$(VALGRIND_PREBISON)' PREPARSER='$(VALGRIND) -q' \
|
||||
VALGRIND_OPTS='--leak-check=full --show-reachable=yes'
|
||||
|
||||
.PHONY: maintainer-check
|
||||
maintainer-check: maintainer-check-posix maintainer-check-valgrind maintainer-check-g++
|
||||
|
||||
.PHONY: maintainer-push-check
|
||||
maintainer-push-check:
|
||||
$(MAKE) $(AM_MAKEFLAGS) maintainer-check \
|
||||
TESTSUITEFLAGS='BISON_USE_PUSH_FOR_PULL=1 $(TESTSUITEFLAGS)'
|
||||
|
||||
.PHONY: maintainer-xml-check
|
||||
maintainer-xml-check:
|
||||
$(MAKE) $(AM_MAKEFLAGS) maintainer-check \
|
||||
TESTSUITEFLAGS='BISON_TEST_XML=1 $(TESTSUITEFLAGS)'
|
||||
.PHONY: maintainer-release-check
|
||||
maintainer-release-check:
|
||||
$(MAKE) $(AM_MAKEFLAGS) \
|
||||
maintainer-check-g++ \
|
||||
maintainer-check-posix \
|
||||
maintainer-check-valgrind \
|
||||
TESTSUITEFLAGS+='--release'
|
||||
|
||||
+6
-12
@@ -37,11 +37,10 @@ foo: {};
|
||||
|
||||
]AT_BISON_CHECK([$3 $1 $5], 0)[
|
||||
# Ignore the files non-generated files
|
||||
]AT_CHECK([[find . -type f |
|
||||
$PERL -ne '
|
||||
s,\./,,; chomp;
|
||||
push @file, $_ unless m{^($1|testsuite.log)$};
|
||||
END { print join (" ", sort @file), "\n" }']],
|
||||
]AT_CHECK([find . -type f -and -not -path './$1' -and -not -path './testsuite.log' |
|
||||
sed 's,\./,,' |
|
||||
sort |
|
||||
xargs echo],
|
||||
[], [$4
|
||||
])[
|
||||
]$6[
|
||||
@@ -63,13 +62,8 @@ AT_CHECK_OUTPUT([foo.y], [], [-dv -o foo.c],
|
||||
[foo.c foo.h foo.output])
|
||||
AT_CHECK_OUTPUT([foo.y], [], [-dv -o foo.tab.c],
|
||||
[foo.output foo.tab.c foo.tab.h])
|
||||
|
||||
AT_CHECK_OUTPUT([foo.y], [], [-dv -g --xml -y],
|
||||
[y.dot y.output y.tab.c y.tab.h y.xml])
|
||||
# With '-o y.tab.c', we expect 'y.output' etc. (for compatility with Yacc).
|
||||
AT_CHECK_OUTPUT([foo.y], [], [-dv -g --xml -o y.tab.c],
|
||||
[y.dot y.output y.tab.c y.tab.h y.xml])
|
||||
|
||||
AT_CHECK_OUTPUT([foo.y], [], [-dv -y],
|
||||
[y.output y.tab.c y.tab.h])
|
||||
AT_CHECK_OUTPUT([foo.y], [], [-dv -b bar],
|
||||
[bar.output bar.tab.c bar.tab.h])
|
||||
AT_CHECK_OUTPUT([foo.y], [], [-dv -g -o foo.c],
|
||||
|
||||
+38
-6
@@ -201,6 +201,28 @@ input.y:14.11-13: warning: rule useless in grammar [-Wother]
|
||||
^^^
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK([[input.y]], 0, [],
|
||||
[[input.y: warning: 9 nonterminals useless in grammar [-Wother]
|
||||
input.y: warning: 9 rules useless in grammar [-Wother]
|
||||
input.y:6.1-8: warning: nonterminal useless in grammar: useless1 [-Wother]
|
||||
input.y:7.1-8: warning: nonterminal useless in grammar: useless2 [-Wother]
|
||||
input.y:8.1-8: warning: nonterminal useless in grammar: useless3 [-Wother]
|
||||
input.y:9.1-8: warning: nonterminal useless in grammar: useless4 [-Wother]
|
||||
input.y:10.1-8: warning: nonterminal useless in grammar: useless5 [-Wother]
|
||||
input.y:11.1-8: warning: nonterminal useless in grammar: useless6 [-Wother]
|
||||
input.y:12.1-8: warning: nonterminal useless in grammar: useless7 [-Wother]
|
||||
input.y:13.1-8: warning: nonterminal useless in grammar: useless8 [-Wother]
|
||||
input.y:14.1-8: warning: nonterminal useless in grammar: useless9 [-Wother]
|
||||
input.y:6.11-13: warning: rule useless in grammar: useless1: '1' [-Wother]
|
||||
input.y:7.11-13: warning: rule useless in grammar: useless2: '2' [-Wother]
|
||||
input.y:8.11-13: warning: rule useless in grammar: useless3: '3' [-Wother]
|
||||
input.y:9.11-13: warning: rule useless in grammar: useless4: '4' [-Wother]
|
||||
input.y:10.11-13: warning: rule useless in grammar: useless5: '5' [-Wother]
|
||||
input.y:11.11-13: warning: rule useless in grammar: useless6: '6' [-Wother]
|
||||
input.y:12.11-13: warning: rule useless in grammar: useless7: '7' [-Wother]
|
||||
input.y:13.11-13: warning: rule useless in grammar: useless8: '8' [-Wother]
|
||||
input.y:14.11-13: warning: rule useless in grammar: useless9: '9' [-Wother]
|
||||
]])
|
||||
|
||||
AT_CHECK([[sed -n '/^Grammar/q;/^$/!p' input.output]], 0,
|
||||
[[Nonterminals useless in grammar
|
||||
@@ -295,6 +317,16 @@ not-reduced.y:17.17-18.63: warning: rule useless in grammar [-Wother]
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK([[not-reduced.y]], 0, [],
|
||||
[[not-reduced.y: warning: 2 nonterminals useless in grammar [-Wother]
|
||||
not-reduced.y: warning: 3 rules useless in grammar [-Wother]
|
||||
not-reduced.y:14.1-13: warning: nonterminal useless in grammar: not_reachable [-Wother]
|
||||
not-reduced.y:11.6-19: warning: nonterminal useless in grammar: non_productive [-Wother]
|
||||
not-reduced.y:11.6-57: warning: rule useless in grammar: exp: non_productive [-Wother]
|
||||
not-reduced.y:14.16-56: warning: rule useless in grammar: not_reachable: useful [-Wother]
|
||||
not-reduced.y:17.17-18.63: warning: rule useless in grammar: non_productive: non_productive useless_token [-Wother]
|
||||
]])
|
||||
|
||||
AT_CHECK([[sed -n '/^Grammar/q;/^$/!p' not-reduced.output]], 0,
|
||||
[[Nonterminals useless in grammar
|
||||
not_reachable
|
||||
@@ -365,9 +397,9 @@ AT_BISON_CHECK([[input.y]], 0, [],
|
||||
input.y: warning: 3 rules useless in grammar [-Wother]
|
||||
input.y:5.15-25: warning: nonterminal useless in grammar: underivable [-Wother]
|
||||
input.y:6.14-24: warning: nonterminal useless in grammar: indirection [-Wother]
|
||||
input.y:5.15-25: warning: rule useless in grammar [-Wother]
|
||||
input.y:6.14-24: warning: rule useless in grammar [-Wother]
|
||||
input.y:7.14-24: warning: rule useless in grammar [-Wother]
|
||||
input.y:5.15-25: warning: rule useless in grammar: exp: underivable [-Wother]
|
||||
input.y:6.14-24: warning: rule useless in grammar: underivable: indirection [-Wother]
|
||||
input.y:7.14-24: warning: rule useless in grammar: indirection: underivable [-Wother]
|
||||
]])
|
||||
|
||||
AT_CHECK([[sed -n '/^Grammar/q;/^$/!p' input.output]], 0,
|
||||
@@ -933,7 +965,7 @@ S: 'a' A 'a'
|
||||
A: 'a' 'a' B
|
||||
;
|
||||
B: 'a'
|
||||
| %empty %prec 'a'
|
||||
| %prec 'a'
|
||||
;
|
||||
c: 'a' 'a' 'b'
|
||||
| A
|
||||
@@ -1533,8 +1565,8 @@ a: 'a' ;
|
||||
and multiple reductions. The first reduction has more lookaheads than the
|
||||
second, so the first should always be preferred as the default reduction if
|
||||
enabled. The second reduction has one lookahead. */
|
||||
b: %empty;
|
||||
c: %empty;
|
||||
b: ;
|
||||
c: ;
|
||||
]],
|
||||
dnl Visit each state mentioned above.
|
||||
[['a', 'a']],
|
||||
|
||||
+17
-16
@@ -263,11 +263,11 @@ AT_CHECK([cat input.output], [],
|
||||
|
||||
0 $accept: expr $end
|
||||
|
||||
1 $@1: %empty
|
||||
1 $@1: /* empty */
|
||||
|
||||
2 expr: 'a' $@1 'b'
|
||||
|
||||
3 $@2: %empty
|
||||
3 $@2: /* empty */
|
||||
|
||||
4 expr: $@2 'c'
|
||||
|
||||
@@ -373,13 +373,13 @@ AT_DATA([input.y],
|
||||
%token <operator> LE 134 "<="
|
||||
%left OR "<="
|
||||
%%
|
||||
exp: %empty;
|
||||
exp: ;
|
||||
%%
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK([-v -Wall -o input.c input.y], 0, [],
|
||||
[[input.y:3.1-5: warning: useless precedence and associativity for "||" [-Wprecedence]
|
||||
input.y:3.1-5: warning: useless precedence and associativity for "<=" [-Wprecedence]
|
||||
AT_BISON_CHECK([-v -o input.c input.y], 0, [],
|
||||
[[input.y:1.29-32: warning: useless associativity for "||" [-Wother]
|
||||
input.y:2.29-32: warning: useless associativity for "<=" [-Wother]
|
||||
]])
|
||||
|
||||
AT_CLEANUP
|
||||
@@ -405,13 +405,14 @@ default: 'a' }
|
||||
|
||||
AT_BISON_CHECK([input.y], [1], [],
|
||||
[[input.y:2.1: error: invalid character: '?'
|
||||
input.y:3.14: error: syntax error, unexpected }
|
||||
input.y:3.14: error: invalid character: '}'
|
||||
input.y:4.1: error: invalid character: '%'
|
||||
input.y:4.2: error: invalid character: '&'
|
||||
input.y:5.1-17: error: invalid directive: '%a-does-not-exist'
|
||||
input.y:6.1: error: invalid character: '%'
|
||||
input.y:6.2: error: invalid character: '-'
|
||||
input.y:7.1-8.0: error: missing '%}' at end of file
|
||||
input.y:7.1-8.0: error: syntax error, unexpected %{...%}
|
||||
]])
|
||||
|
||||
AT_CLEANUP
|
||||
@@ -572,7 +573,7 @@ AT_CHECK([cat input.output], 0,
|
||||
2 CONST_DEC_LIST: CONST_DEC
|
||||
3 | CONST_DEC_LIST CONST_DEC
|
||||
|
||||
4 $@1: %empty
|
||||
4 $@1: /* empty */
|
||||
|
||||
5 CONST_DEC: $@1 undef_id_tok '=' const_id_tok ';'
|
||||
|
||||
@@ -720,7 +721,7 @@ AT_KEYWORDS([report])
|
||||
AT_DATA([input.y],
|
||||
[[%%
|
||||
statement: struct_stat;
|
||||
struct_stat: %empty | if else;
|
||||
struct_stat: /* empty. */ | if else;
|
||||
if: "if" "const" "then" statement;
|
||||
else: "else" statement;
|
||||
%%
|
||||
@@ -868,7 +869,7 @@ type: DATA
|
||||
| INVALID
|
||||
;
|
||||
|
||||
body: %empty
|
||||
body: /* empty */
|
||||
| body member
|
||||
;
|
||||
|
||||
@@ -928,7 +929,7 @@ $1
|
||||
%token B
|
||||
|
||||
%%
|
||||
program: %empty
|
||||
program: /* empty */
|
||||
| program e ';'
|
||||
| program error ';';
|
||||
|
||||
@@ -1144,15 +1145,15 @@ sr_conflict:
|
||||
]AT_YYLEX_DEFINE([{ 1, 2, 3, 0 }])[
|
||||
]AT_MAIN_DEFINE[
|
||||
]])
|
||||
AT_BISON_OPTION_POPDEFS
|
||||
|
||||
AT_BISON_CHECK([[-Wall -o input.c input.y]], [[0]],,
|
||||
[[input.y:24.5-19: warning: rule useless in parser due to conflicts [-Wother]
|
||||
input.y:28.5-19: warning: rule useless in parser due to conflicts [-Wother]
|
||||
input.y:18.1-5: warning: useless precedence and associativity for TK1 [-Wprecedence]
|
||||
AT_BISON_CHECK([[-o input.c input.y]], [[0]],,
|
||||
[[input.y:24.5-19: warning: rule useless in parser due to conflicts: start: start [-Wother]
|
||||
input.y:28.5-19: warning: rule useless in parser due to conflicts: sr_conflict: TK2 "tok alias" [-Wother]
|
||||
input.y:18.7-9: warning: useless associativity for TK1 [-Wother]
|
||||
]])
|
||||
AT_COMPILE([[input]])
|
||||
AT_PARSER_CHECK([[./input]])
|
||||
AT_BISON_OPTION_POPDEFS
|
||||
|
||||
AT_CLEANUP
|
||||
|
||||
|
||||
+5
-5
@@ -86,7 +86,7 @@ AT_CHECK([[cat sets]], [],
|
||||
0 e $end
|
||||
e derives
|
||||
1 'e'
|
||||
2 %empty
|
||||
2 /* empty */
|
||||
NULLABLE
|
||||
$accept: no
|
||||
e: yes
|
||||
@@ -100,10 +100,10 @@ FDERIVES
|
||||
$accept derives
|
||||
0 e $end
|
||||
1 'e'
|
||||
2 %empty
|
||||
2 /* empty */
|
||||
e derives
|
||||
1 'e'
|
||||
2 %empty
|
||||
2 /* empty */
|
||||
]])
|
||||
|
||||
AT_CLEANUP
|
||||
@@ -113,7 +113,7 @@ AT_CLEANUP
|
||||
## Broken Closure. ##
|
||||
## ---------------- ##
|
||||
|
||||
# TC was once broken during a massive 'simplification' of the code.
|
||||
# TC was once broken during a massive `simplification' of the code.
|
||||
# It resulted in bison dumping core on the following grammar (the
|
||||
# computation of FIRSTS uses TC). It managed to produce a pretty
|
||||
# exotic closure:
|
||||
@@ -263,7 +263,7 @@ AT_CLEANUP
|
||||
# In some weird cases Bison could compute an incorrect final state
|
||||
# number. This happens only if the $end token is used in the user
|
||||
# grammar, which is a very suspicious accidental feature introduced as
|
||||
# a side effect of allowing the user to name $end using '%token END 0
|
||||
# a side effect of allowing the user to name $end using `%token END 0
|
||||
# "end of file"'.
|
||||
|
||||
AT_SETUP([Accept])
|
||||
|
||||
+1
-1
@@ -23,7 +23,7 @@ AT_BANNER([[User Actions.]])
|
||||
# --------------------------
|
||||
# Compile FILE expecting an error, and save in the file stdout the
|
||||
# normalized output. Ignore the exit status, since some compilers
|
||||
# (e.g. c89 on IRIX 6.5) trigger warnings on '#error', instead of
|
||||
# (e.g. c89 on IRIX 6.5) trigger warnings on `#error', instead of
|
||||
# errors.
|
||||
m4_define([AT_SYNCLINES_COMPILE],
|
||||
[AT_CHECK([$CC $CFLAGS $CPPFLAGS -c $1], [ignore], [], [stderr])
|
||||
|
||||
+5
-9
@@ -35,9 +35,6 @@ m4_include([sets.at])
|
||||
# Testing grammar reduction.
|
||||
m4_include([reduce.at])
|
||||
|
||||
# Testing conflicts detection and resolution.
|
||||
m4_include([conflicts.at])
|
||||
|
||||
# Testing that #lines are correct.
|
||||
m4_include([synclines.at])
|
||||
|
||||
@@ -47,8 +44,8 @@ m4_include([headers.at])
|
||||
# Testing that user actions are properly performed.
|
||||
m4_include([actions.at])
|
||||
|
||||
# Testing semantic types support.
|
||||
m4_include([types.at])
|
||||
# Testing conflicts detection and resolution.
|
||||
m4_include([conflicts.at])
|
||||
|
||||
# Fulling testing (compilation and execution of the parser) on calc.
|
||||
m4_include([calc.at])
|
||||
@@ -63,18 +60,17 @@ m4_include([existing.at])
|
||||
# Some old bugs.
|
||||
m4_include([regression.at])
|
||||
|
||||
# Push parsing specific tests.
|
||||
m4_include([push.at])
|
||||
|
||||
# Some C++ specific tests.
|
||||
m4_include([c++.at])
|
||||
|
||||
# And some Java specific tests.
|
||||
m4_include([java.at])
|
||||
m4_include([javapush.at])
|
||||
|
||||
# GLR tests:
|
||||
# C++ types, simplified
|
||||
m4_include([cxx-type.at])
|
||||
# Regression tests
|
||||
m4_include([glr-regression.at])
|
||||
|
||||
# Push parsing specific tests.
|
||||
m4_include([push.at])
|
||||
|
||||
-230
@@ -1,230 +0,0 @@
|
||||
# Value type. -*- Autotest -*-
|
||||
|
||||
# Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
AT_BANNER([[Value type tests.]])
|
||||
|
||||
|
||||
## ----------------------------------- ##
|
||||
## %union vs. %define api.value.type. ##
|
||||
## ----------------------------------- ##
|
||||
|
||||
AT_SETUP([[%union vs. %define api.value.type]])
|
||||
|
||||
AT_DATA([[input.y]],
|
||||
[[%union { int ival; }
|
||||
%define api.value.type union-directive
|
||||
%%
|
||||
exp: %empty;
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK([[input.y]], [[1]], [[]],
|
||||
[[input.y:2.9-22: error: '%union' and '%define api.value.type' cannot be used together
|
||||
]])
|
||||
|
||||
AT_CLEANUP
|
||||
|
||||
## ---------------------------------------- ##
|
||||
## %yacc vs. %define api.value.type union. ##
|
||||
## ---------------------------------------- ##
|
||||
|
||||
AT_SETUP([[%yacc vs. %define api.value.type union]])
|
||||
|
||||
AT_DATA([[input.y]],
|
||||
[[%yacc
|
||||
%define api.value.type union
|
||||
%%
|
||||
exp: %empty;
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK([[input.y]], [[1]], [[]],
|
||||
[[input.y:2.9-22: error: '%yacc' and '%define api.value.type "union"' cannot be used together
|
||||
]])
|
||||
|
||||
AT_CLEANUP
|
||||
|
||||
|
||||
## ---------------- ##
|
||||
## api.value.type. ##
|
||||
## ---------------- ##
|
||||
|
||||
# AT_TEST($1: BISON-DIRECTIVES,
|
||||
# $2: MORE-BISON-DIRECTIVES,
|
||||
# $3: PARSER-ACTION,
|
||||
# $4: INPUT, $5: SCANNER-ACTION,
|
||||
# $6: RESULT)
|
||||
# --------------------------------------
|
||||
# Compile the grammar and check the expected result.
|
||||
# BISON-DIRECTIVES are passed to AT_SETUP, contrary to MORE-BISON-DIRECTIVES.
|
||||
m4_pushdef([AT_TEST],
|
||||
[
|
||||
AT_SETUP([$1])
|
||||
AT_KEYWORDS([api.value.type])
|
||||
AT_BISON_OPTION_PUSHDEFS([%debug $1 $2])
|
||||
AT_DATA_GRAMMAR([test.y],
|
||||
[[%debug
|
||||
|
||||
%code
|
||||
{
|
||||
# include <stdio.h>
|
||||
# include <stdlib.h>
|
||||
]AT_YYERROR_DECLARE[
|
||||
]AT_YYLEX_DECLARE[
|
||||
}
|
||||
|
||||
]$1[
|
||||
]$2[
|
||||
|
||||
%%
|
||||
|
||||
start: $3;
|
||||
|
||||
%%
|
||||
]AT_YYERROR_DEFINE[
|
||||
]AT_YYLEX_DEFINE([$4], [$5])[
|
||||
]AT_MAIN_DEFINE[
|
||||
]])
|
||||
|
||||
AT_FULL_COMPILE([[test]])
|
||||
AT_PARSER_CHECK([./test], 0, [$6
|
||||
], [stderr])
|
||||
AT_BISON_OPTION_POPDEFS
|
||||
AT_CLEANUP
|
||||
])
|
||||
|
||||
m4_foreach([b4_skel], [[yacc.c], [glr.c], [lalr1.cc], [glr.cc]],
|
||||
[# A built-in type.
|
||||
AT_TEST([%skeleton "]b4_skel["
|
||||
%define api.value.type {double}],
|
||||
[],
|
||||
['1' '2' { printf ("%2.1f\n", $1 + $2); }],
|
||||
["12"],
|
||||
[AT_VAL = (res - '0') / 10.0],
|
||||
[0.3])
|
||||
|
||||
# A typedef which looks like a Bison keyword, but it's using braces.
|
||||
AT_TEST([%skeleton "]b4_skel["
|
||||
%define api.value.type {variant}],
|
||||
[%code requires { typedef double variant; }],
|
||||
['1' '2' { printf ("%2.1f\n", $1 + $2); }],
|
||||
["12"],
|
||||
[AT_VAL = (res - '0') / 10.0],
|
||||
[0.3])
|
||||
|
||||
# A user defined struct.
|
||||
AT_TEST([%skeleton "]b4_skel["
|
||||
%define api.value.type {struct foo}],
|
||||
[%code requires { struct foo { float fval; int ival; }; }],
|
||||
['1' '2'
|
||||
{ printf ("%d %2.1f\n", $1.ival + $2.ival, $1.fval + $2.fval); }],
|
||||
["12"],
|
||||
[AT_VAL.ival = (res - '0') * 10;
|
||||
AT_VAL.fval = (res - '0') / 10.f],
|
||||
[30 0.3])
|
||||
|
||||
# A user defined struct that uses pointers.
|
||||
AT_TEST([%skeleton "]b4_skel["
|
||||
%define api.value.type {struct bar}],
|
||||
[%code requires
|
||||
{
|
||||
struct u
|
||||
{
|
||||
int ival;
|
||||
};
|
||||
struct bar
|
||||
{
|
||||
struct u *up;
|
||||
};
|
||||
}
|
||||
%token <up->ival> '1' '2'
|
||||
%printer { ]AT_SKEL_CC_IF([[yyoutput << $$]],
|
||||
[[fprintf (yyo, "%d", $$)]])[; } <up->ival>
|
||||
],
|
||||
['1' '2'
|
||||
{
|
||||
printf ("%d %d\n", $1, $<up->ival>2);
|
||||
free ($<up>1);
|
||||
free ($<up>2);
|
||||
}],
|
||||
["12"],
|
||||
[AT_VAL.up = (struct u *) malloc (sizeof *AT_VAL.up);
|
||||
assert (AT_VAL.up);
|
||||
AT_VAL.up->ival = res - '0';],
|
||||
[1 2])
|
||||
|
||||
# A user defined union.
|
||||
AT_TEST([%skeleton "]b4_skel["
|
||||
%define api.value.type {union foo}],
|
||||
[%code requires { union foo { float fval; int ival; }; }],
|
||||
['1' '2' { printf ("%d %2.1f\n", $1.ival, $2.fval); }],
|
||||
["12"],
|
||||
[if (res == '1')
|
||||
AT_VAL.ival = 10;
|
||||
else
|
||||
AT_VAL.fval = .2f],
|
||||
[10 0.2])
|
||||
|
||||
# A %union.
|
||||
AT_TEST([%skeleton "]b4_skel["
|
||||
%union { float fval; int ival; };],
|
||||
[%token <ival> '1';
|
||||
%token <fval> '2';],
|
||||
['1' '2' { printf ("%d %2.1f\n", $1, $2); }],
|
||||
["12"],
|
||||
[if (res == '1')
|
||||
AT_VAL.ival = 10;
|
||||
else
|
||||
AT_VAL.fval = 0.2f],
|
||||
[10 0.2])
|
||||
|
||||
# A Bison-defined union.
|
||||
# The tokens names are not available directly in C++, we use their
|
||||
# user number to keep it simple between C and C++.
|
||||
AT_TEST([%skeleton "]b4_skel["
|
||||
%define api.value.type union],
|
||||
[%token <int> ONE 101;
|
||||
%token <float> TWO 102 THREE 103;
|
||||
%printer { ]AT_SKEL_CC_IF([[yyoutput << $$]],
|
||||
[[fprintf (yyo, "%d", $$)]])[; } <int>
|
||||
%printer { ]AT_SKEL_CC_IF([[yyoutput << $$]],
|
||||
[[fprintf (yyo, "%f", $$)]])[; } <float>
|
||||
],
|
||||
[ONE TWO THREE { printf ("%d %2.1f %2.1f\n", $1, $2, $3); }],
|
||||
[{ 101, 102, 103, EOF }],
|
||||
[if (res == 101)
|
||||
AT_VAL.ONE = 10;
|
||||
else if (res == 102)
|
||||
AT_VAL.TWO = .2f;
|
||||
else if (res == 103)
|
||||
AT_VAL.THREE = 3.3f],
|
||||
[10 0.2 3.3])
|
||||
|
||||
# A Bison-defined variant, for lalr1.cc only.
|
||||
m4_if(b4_skel, [lalr1.cc], [
|
||||
AT_TEST([%skeleton "]b4_skel["
|
||||
%define api.value.type variant],
|
||||
[%token <int> '1';
|
||||
%token <std::string> '2';],
|
||||
['1' '2' { std::cout << $1 << ", " << $2 << std::endl; }],
|
||||
["12"],
|
||||
[if (res == '1')
|
||||
AT_VAL.build(10);
|
||||
else
|
||||
AT_VAL.build<std::string>("two");],
|
||||
[10, two])])
|
||||
])
|
||||
|
||||
m4_popdef([AT_TEST])
|
||||
Reference in New Issue
Block a user