Merge remote-tracking branch 'origin/maint'

* origin/maint: (46 commits)
  doc: minor style change
  maint: use gendocs's new -I option
  regen
  yacc.c: do not define location support when not using locations
  maint: be compilable with GCC 4.0
  tests: address a warning from GCC 4.4
  tests: don't use options that Clang does not support
  tests: restore the tests on -Werror
  regen
  parse-gram: update the Bison interface
  fix comment
  maint: post-release administrivia
  version 2.6.4
  regen
  2.6.4: botched 2.6.3
  maint: post-release administrivia
  version 2.6.3
  gnulib: update
  tests: check %no-lines
  NEWS: warnings with clang
  ...

Conflicts:
	NEWS
	TODO
	data/c.m4
	data/java.m4
	doc/Makefile.am
	src/getargs.c
	src/getargs.h
	src/output.c
	src/parse-gram.c
	src/parse-gram.h
	src/parse-gram.y
	src/reader.h
This commit is contained in:
Akim Demaille
2012-10-26 16:50:26 +02:00
26 changed files with 795 additions and 130 deletions

View File

@@ -1 +1 @@
2.6.2
2.6.4

101
NEWS
View File

@@ -242,20 +242,6 @@ GNU Bison NEWS
* Noteworthy changes in release ?.? (????-??-??) [?]
** Bug fixes
Bugs and portability issues in the test suite have been fixed.
Some errors in translations have been addressed, and --help now directs
users to the appropriate place to report them.
Stray Info files shipped by accident are removed.
Incorrect definitions of YY_, issued by yacc.c when no parser header is
generated, are removed.
All the generated headers are self-contained.
** Changes in the format of error messages
This used to be the format of many error reports:
@@ -268,17 +254,6 @@ GNU Bison NEWS
foo.y:5.10-25: result type clash on merge function 'merge': <t3> != <t2>
foo.y:4.13-27: previous declaration
** Header guards (yacc.c, glr.c, glr.cc)
In order to avoid collisions, the header guards are now
YY_<PREFIX>_<FILE>_INCLUDED, instead of merely <PREFIX>_<FILE>.
For instance the header generated from
%define api.prefix "calc"
%defines "lib/parse.h"
will use YY_CALC_LIB_PARSE_H_INCLUDED as guard.
** Exception safety (lalr1.cc)
The parse function now catches exceptions, uses the %destructors to
@@ -288,23 +263,6 @@ GNU Bison NEWS
This feature is somewhat experimental. User feedback would be
appreciated.
** Fix compiler warnings in the generated parser (yacc.c, glr.c)
The compilation of pure parsers (%define api.pure) can trigger GCC
warnings such as:
input.c: In function 'yyparse':
input.c:1503:12: warning: 'yylval' may be used uninitialized in this
function [-Wmaybe-uninitialized]
*++yyvsp = yylval;
^
This is now fixed; pragmas to avoid these warnings are no longer needed.
Warnings from clang ("equality comparison with extraneous parentheses" and
"function declared 'noreturn' should not return") have also been
addressed.
** New %define variable: api.location.type (glr.cc, lalr1.cc, lalr1.java)
The %define variable api.location.type defines the name of the type to use
@@ -324,6 +282,63 @@ GNU Bison NEWS
position_type are deprecated in favor of api.location.type and
api.position.type.
** Graphviz improvements
The graphical presentation of the states is more readable: their shape is
now rectangular, the state number is clearly displayed, and the items are
numbered and left-justified.
The reductions are now explicitly represented as transitions to other
diamond shaped nodes.
* Noteworthy changes in release 2.6.4 (2012-10-23) [stable]
Bison 2.6.3's --version was incorrect. This release fixes this issue.
* Noteworthy changes in release 2.6.3 (2012-10-22) [stable]
** Bug fixes
Bugs and portability issues in the test suite have been fixed.
Some errors in translations have been addressed, and --help now directs
users to the appropriate place to report them.
Stray Info files shipped by accident are removed.
Incorrect definitions of YY_, issued by yacc.c when no parser header is
generated, are removed.
All the generated headers are self-contained.
** Header guards (yacc.c, glr.c, glr.cc)
In order to avoid collisions, the header guards are now
YY_<PREFIX>_<FILE>_INCLUDED, instead of merely <PREFIX>_<FILE>.
For instance the header generated from
%define api.prefix "calc"
%defines "lib/parse.h"
will use YY_CALC_LIB_PARSE_H_INCLUDED as guard.
** Fix compiler warnings in the generated parser (yacc.c, glr.c)
The compilation of pure parsers (%define api.pure) can trigger GCC
warnings such as:
input.c: In function 'yyparse':
input.c:1503:12: warning: 'yylval' may be used uninitialized in this
function [-Wmaybe-uninitialized]
*++yyvsp = yylval;
^
This is now fixed; pragmas to avoid these warnings are no longer needed.
Warnings from clang ("equality comparison with extraneous parentheses" and
"function declared 'noreturn' should not return") have also been
addressed.
* Noteworthy changes in release 2.6.2 (2012-08-03) [stable]
** Bug fixes
@@ -380,7 +395,7 @@ GNU Bison NEWS
* Noteworthy changes in release 2.6 (2012-07-19) [stable]
** Future changes:
** Future changes
The next major release of Bison will drop support for the following
deprecated features. Please report disagreements to bug-bison@gnu.org.

View File

@@ -50,16 +50,17 @@ These requirements do not apply when building from a distribution tarball.
** Requirements
We've opted to keep only the highest-level sources in the repository.
This eases our maintenance burden, (fewer merges etc.), but imposes more
We've opted to keep only the highest-level sources in the repository. This
eases our maintenance burden, (fewer merges etc.), but imposes more
requirements on anyone wishing to build from the just-checked-out sources.
For example, you have to use the latest stable versions of the maintainer
tools we depend upon, including:
- Automake <http://www.gnu.org/software/automake/>
- Autoconf <http://www.gnu.org/software/autoconf/>
- Automake <http://www.gnu.org/software/automake/>
- Flex <http://www.gnu.org/software/flex/>
- Gettext <http://www.gnu.org/software/gettext/>
- Graphviz <http://www.graphviz.org>
- Gzip <http://www.gnu.org/software/gzip/>
- Perl <http://www.cpan.org/>
- Rsync <http://samba.anu.edu.au/rsync/>
@@ -68,16 +69,16 @@ tools we depend upon, including:
Valgrind <http://valgrind.org/> is also highly recommended, if it supports
your architecture.
Bison is written using Bison grammars, so there are bootstrapping
issues. The bootstrap script attempts to discover when the C code
generated from the grammars is out of date, and to bootstrap with an
out-of-date version of the C code, but the process is not foolproof.
Also, you may run into similar problems yourself if you modify Bison.
Bison is written using Bison grammars, so there are bootstrapping issues.
The bootstrap script attempts to discover when the C code generated from the
grammars is out of date, and to bootstrap with an out-of-date version of the
C code, but the process is not foolproof. Also, you may run into similar
problems yourself if you modify Bison.
Only building the initial full source tree will be a bit painful.
Later, after synchronizing from the repository a plain 'make' should
be sufficient. Note, however, that when gnulib is updated, running
'./bootstrap' again might be needed.
Only building the initial full source tree will be a bit painful. Later,
after synchronizing from the repository a plain 'make' should be sufficient.
Note, however, that when gnulib is updated, running './bootstrap' again
might be needed.
** First checkout

12
TODO
View File

@@ -1,4 +1,16 @@
* Short term
** Graphviz display code thoughts
The code for the --graph option is over two files: print_graph, and
graphviz. I believe this is because Bison used to also produce VCG graphs,
but since this is no longer true, maybe we could consider these files for
fusion.
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
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

1
cfg.mk
View File

@@ -24,6 +24,7 @@ regen: _version
# Used in maint.mk's web-manual rule
manual_title = The Yacc-compatible Parser Generator
gendocs_options_ = -I $(abs_top_srcdir)/doc -I $(abs_top_builddir)/doc
# It's useful to run maintainer-*check* targets during development, but we
# don't want to wait on a recompile because of an update to $(VERSION). Thus,

View File

@@ -75,6 +75,18 @@ if test "$enable_gcc_warnings" = yes; then
warn_cxx='-Wnoexcept'
AC_LANG_PUSH([C])
# Clang supports many of GCC's -W options, but only issues warnings
# on the ones it does not recognize. In that case, gl_WARN_ADD
# thinks the option is supported, and unknown options are then added
# to CFLAGS. But then, when -Werror is added in the test suite for
# instance, the warning about the unknown option turns into an
# error.
#
# This should be addressed by gnulib's gl_WARN_ADD, but in the
# meanwhile, turn warnings about unknown options into errors in
# CFLAGS, and restore CFLAGS after the tests.
save_CFLAGS=$CFLAGS
gl_WARN_ADD([-Werror=unknown-warning-option], [CFLAGS])
for i in $warn_common $warn_c;
do
gl_WARN_ADD([$i], [WARN_CFLAGS])
@@ -83,9 +95,12 @@ if test "$enable_gcc_warnings" = yes; then
# Warnings for the test suite only.
gl_WARN_ADD([-Wundef], [WARN_CFLAGS_TEST])
gl_WARN_ADD([-pedantic], [WARN_CFLAGS_TEST])
CFLAGS=$save_CFLAGS
AC_LANG_POP([C])
AC_LANG_PUSH([C++])
save_CXXFLAGS=$CXXFLAGS
gl_WARN_ADD([-Werror=unknown-warning-option], [CXXFLAGS])
for i in $warn_common $warn_cxx;
do
gl_WARN_ADD([$i], [WARN_CXXFLAGS])
@@ -96,6 +111,7 @@ if test "$enable_gcc_warnings" = yes; then
# Warnings for the test suite only.
gl_WARN_ADD([-Wundef], [WARN_CXXFLAGS_TEST])
gl_WARN_ADD([-pedantic], [WARN_CXXFLAGS_TEST])
CXXFLAGS=$save_CXXFLAGS
AC_LANG_POP([C++])
fi
@@ -118,6 +134,7 @@ AC_SUBST([YACC_SCRIPT])
AC_SUBST([YACC_LIBRARY])
# Checks for programs.
AM_MISSING_PROG([DOT], [dot])
AC_PROG_LEX
$LEX_IS_FLEX || AC_MSG_ERROR([Flex is required])
AC_PROG_YACC

View File

@@ -557,7 +557,7 @@ m4_define([b4_YYDEBUG_define],
# endif
# else /* ! defined YYDEBUG */
# define ]b4_api_PREFIX[DEBUG ]b4_parse_trace_if([1], [0])[
# endif /* ! defined ]b4_api_PREFIX[DEBUG */
# endif /* ! defined YYDEBUG */
#endif /* ! defined ]b4_api_PREFIX[DEBUG */]])[]dnl
])

View File

@@ -200,7 +200,7 @@ m4_define([b4_init_throws], [b4_percent_define_get([[init_throws]])])
b4_percent_define_default([[api.location.type]], [Location])
m4_define([b4_location_type], [b4_percent_define_get([[api.location.type]])])
b4_percent_define_default([[api.position.type]], [Position])])
b4_percent_define_default([[api.position.type]], [Position])
m4_define([b4_position_type], [b4_percent_define_get([[api.position.type]])])

View File

@@ -55,7 +55,11 @@
<xsl:call-template name="escape">
<xsl:with-param name="subject" select="$filename"/>
</xsl:call-template>
<xsl:text>"&#10;{&#10;</xsl:text>
<xsl:text>&#10;{
node [fontname = courier, shape = box, colorscheme = paired6]
edge [fontname = courier]
</xsl:text>
<xsl:apply-templates select="state"/>
<xsl:text>}&#10;</xsl:text>
</xsl:template>

View File

@@ -685,18 +685,14 @@ while (0)
# else
# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
# endif
#endif]], [[
/* This macro is provided for backward compatibility. */
#endif]],
[[/* This macro is provided for backward compatibility. */
#ifndef YY_LOCATION_PRINT
# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
#endif]])[
/* YYLEX -- calling `yylex' with the right arguments. */
#ifdef YYLEX_PARAM
# define YYLEX yylex (]b4_pure_if([&yylval[]b4_locations_if([, &yylloc]), ])[YYLEX_PARAM)
#else

View File

@@ -298,6 +298,7 @@ Handling Context Dependencies
Debugging Your Parser
* Understanding:: Understanding the structure of your parser.
* Graphviz:: Getting a visual representation of the parser.
* Tracing:: Tracing the execution of your parser.
Tracing Your Parser
@@ -8422,6 +8423,7 @@ automaton, and how to enable and understand the parser run-time traces.
@menu
* Understanding:: Understanding the structure of your parser.
* Graphviz:: Getting a visual representation of the parser.
* Tracing:: Tracing the execution of your parser.
@end menu
@@ -8838,6 +8840,114 @@ precedence of @samp{/} with respect to @samp{+}, @samp{-}, and
@samp{*}, but also because the
associativity of @samp{/} is not specified.
@c ================================================= Graphical Representation
@node Graphviz
@section Visualizing Your Parser
@cindex dot
As another means to gain better understanding of the shift/reduce
automaton corresponding to the Bison parser, a DOT file can be generated. Note
that debugging a real grammar with this is tedious at best, and impractical
most of the times, because the generated files are huge (the generation of
a PDF or PNG file from it will take very long, and more often than not it will
fail due to memory exhaustion). This option was rather designed for beginners,
to help them understand LR parsers.
This file is generated when the @option{--graph} option is specified (see
@pxref{Invocation, , Invoking Bison}). Its name is made by removing
@samp{.tab.c} or @samp{.c} from the parser implementation file name, and
adding @samp{.dot} instead. If the grammar file is @file{foo.y}, the
Graphviz output file is called @file{foo.dot}.
The following grammar file, @file{rr.y}, will be used in the sequel:
@example
%%
@group
exp: a ";" | b ".";
a: "0";
b: "0";
@end group
@end example
The graphical output is very similar to the textual one, and as such it is
easier understood by making direct comparisons between them. See
@ref{Debugging, , Debugging Your Parser} for a detailled analysis of the
textual report.
@subheading Graphical Representation of States
The items (pointed rules) for each state are grouped together in graph nodes.
Their numbering is the same as in the verbose file. See the following points,
about transitions, for examples
When invoked with @option{--report=lookaheads}, the lookahead tokens, when
needed, are shown next to the relevant rule between square brackets as a
comma separated list. This is the case in the figure for the representation of
reductions, below.
@sp 1
The transitions are represented as directed edges between the current and
the target states.
@subheading Graphical Representation of Shifts
Shifts are shown as solid arrows, labelled with the lookahead token for that
shift. The following describes a reduction in the @file{rr.output} file:
@example
@group
state 3
1 exp: a . ";"
";" shift, and go to state 6
@end group
@end example
A Graphviz rendering of this portion of the graph could be:
@center @image{figs/example-shift, 100pt}
@subheading Graphical Representation of Reductions
Reductions are shown as solid arrows, leading to a diamond-shaped node
bearing the number of the reduction rule. The arrow is labelled with the
appropriate comma separated lookahead tokens. If the reduction is the default
action for the given state, there is no such label.
This is how reductions are represented in the verbose file @file{rr.output}:
@example
state 1
3 a: "0" . [";"]
4 b: "0" . ["."]
"." reduce using rule 4 (b)
$default reduce using rule 3 (a)
@end example
A Graphviz rendering of this portion of the graph could be:
@center @image{figs/example-reduce, 120pt}
When unresolved conflicts are present, because in deterministic parsing
a single decision can be made, Bison can arbitrarily choose to disable a
reduction, see @ref{Shift/Reduce, , Shift/Reduce Conflicts}. Discarded actions
are distinguished by a red filling color on these nodes, just like how they are
reported between square brackets in the verbose file.
The reduction corresponding to the rule number 0 is the acceptation state. It
is shown as a blue diamond, labelled "Acc".
@subheading Graphical representation of go tos
The @samp{go to} jump transitions are represented as dotted lines bearing
the name of the rule being jumped to.
@c ================================================= Tracing
@node Tracing
@section Tracing Your Parser
@@ -12580,9 +12690,9 @@ London, Department of Computer Science, TR-00-12 (December 2000).
@c LocalWords: subdirectory Solaris nonassociativity perror schemas Malloy ints
@c LocalWords: Scannerless ispell american ChangeLog smallexample CSTYPE CLTYPE
@c LocalWords: clval CDEBUG cdebug deftypeopx yyterminate LocationType
@c LocalWords: errorVerbose
@c Local Variables:
@c ispell-dictionary: "american"
@c fill-column: 76
@c End:
@c LocalWords: errorVerbose

View File

@@ -0,0 +1,11 @@
digraph "reduce.y"
{
node [fontname=courier shape=box]
edge [fontname=courier]
1 [label="State 1\n 3 a: \"0\" . [\".\"]\l 4 b: \"0\" . [\";\"]\l"]
1 -> "1R3" [label="" style=solid]
"1R3" [style=filled shape=diamond fillcolor=yellowgreen label="R3"]
1 -> "1R4" [label="[\";\"]" style=solid]
"1R4" [style=filled shape=diamond fillcolor=yellowgreen label="R4"]
}

View File

@@ -0,0 +1,13 @@
.------------------.
| State 1 |
| 3 a: "0" . [";"] |
| 4 b: "0" . ["."] |
`------------------'
/ \
/ \ ["."]
/ \
v v
/ \ / \
/ R \ / R \
(green) \ 3 / \ 4 / (green)
\ / \ /

View File

@@ -0,0 +1,9 @@
digraph "shift.y"
{
node [fontname=courier shape=box]
edge [fontname=courier]
3 [label="State 3\n 1 exp: a . \".\"\l"]
3 -> 6 [style=solid label="\".\""]
6 [label="State 6\n 1 exp: a \".\" .\l"]
}

View File

@@ -0,0 +1,12 @@
.----------------.
| State 3 |
| 1 exp: a . ";" |
`----------------'
|
| ";"
|
v
.----------------.
| State 6 |
| 1 exp: a ";" . |
`----------------'

View File

@@ -112,6 +112,36 @@ $(top_srcdir)/doc/bison.1: doc/bison.help doc/bison.x $(top_srcdir)/configure
nodist_man_MANS = doc/yacc.1
## ----------------------------- ##
## Graphviz examples generation. ##
## ----------------------------- ##
CLEANDIRS += doc/figs
FIGS_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
bison.dvi: $(FIGS_DOT:.dot=.eps)
bison.html: $(FIGS_DOT:.dot=.png)
bison.pdf: $(FIGS_DOT:.dot=.pdf)
.dot.eps:
$(AM_V_GEN) $(MKDIR_P) `echo "./$@" | sed -e 's,/[^/]*$$,,'`
$(AM_V_at) $(DOT) -Gmargin=0 -Teps $< >$@.tmp
$(AM_V_at) mv $@.tmp $@
.dot.pdf:
$(AM_V_GEN) $(MKDIR_P) `echo "./$@" | sed -e 's,/[^/]*$$,,'`
$(AM_V_at) $(DOT) -Gmargin=0 -Tpdf $< >$@.tmp
$(AM_V_at) mv $@.tmp $@
.dot.png:
$(AM_V_GEN) $(MKDIR_P) `echo "./$@" | sed -e 's,/[^/]*$$,,'`
$(AM_V_at) $(DOT) -Gmargin=0 -Tpng $< >$@.tmp
$(AM_V_at) mv $@.tmp $@
## -------------- ##
## Doxygenation. ##
## -------------- ##

2
gnulib

Submodule gnulib updated: dcf27bef48...6061979365

View File

@@ -53,7 +53,10 @@ start_graph (FILE *fout)
"digraph %s\n"
"{\n",
quote (grammar_file));
fprintf (fout, "node [shape=box]\n");
fprintf (fout,
" node [fontname = courier, shape = box, colorscheme = paired6]\n"
" edge [fontname = courier]\n"
"\n");
}
void
@@ -93,13 +96,54 @@ no_reduce_bitset_init (state const *s, bitset *no_reduce_set)
bitset_set (*no_reduce_set, s->errs->symbols[n]->number);
}
static void
conclude_red (struct obstack *out, int source, rule_number ruleno,
bool enabled, bool first, FILE *fout)
{
/* If no lookahead tokens were valid transitions, this reduction is
actually hidden, so cancel everything. */
if (first)
return (void) obstack_finish0 (out);
else
{
char const *ed = enabled ? "e" : "d";
char const *color = enabled ? ruleno ? "3" : "1" : "5";
/* First, build the edge's head. The name of reduction nodes is "nRm",
with n the source state and m the rule number. This is because we
don't want all the reductions bearing a same rule number to point to
the same state, since that is not the desired format. */
fprintf (fout, " %1$d -> \"%1$dR%2$d%3$s\" [",
source, ruleno, ed);
if (! obstack_empty_p (out))
/* (The lookahead tokens have been added to the beginning of the
obstack, in the caller function.) */
fprintf (fout, "label = \"[%s]\" ", obstack_finish0 (out));
/* Then, the edge's tail. */
fprintf (fout, "style = solid]\n");
/* Build the associated diamond representation of the target rule. */
fprintf (fout, " \"%dR%d%s\" [style = filled, "
"shape = diamond, fillcolor = %s, ",
source, ruleno, ed, color);
if (ruleno)
fprintf (fout, "label = \"R%d\"]\n", ruleno);
else
fprintf (fout, "label = \"Acc\"]\n");
}
}
static bool
print_token (struct obstack *out, bool first, char const *tok)
{
char const *q = escape (tok);
if (! first)
obstack_sgrow (out, ",");
obstack_sgrow (out, ", ");
obstack_sgrow (out, q);
return false;
}
@@ -110,58 +154,56 @@ output_red (state const *s, reductions const *reds, FILE *fout)
bitset no_reduce_set;
int j;
int source = s->number;
struct obstack oout;
/* Two obstacks are needed: one for the enabled reductions, and one
for the disabled reductions, because in the end we want two
separate edges, even though in most cases only one will actually
be printed. */
struct obstack dout;
struct obstack eout;
no_reduce_bitset_init (s, &no_reduce_set);
obstack_init (&oout);
obstack_init (&dout);
obstack_init (&eout);
for (j = 0; j < reds->num; ++j)
{
bool disabled = false;
bool first = true;
int ruleno = reds->rules[j]->user_number;
bool defaulted = false;
bool firstd = true;
bool firste = true;
rule_number ruleno = reds->rules[j]->user_number;
rule *default_reduction = NULL;
if (yydefact[s->number] != 0)
default_reduction = &rules[yydefact[s->number] - 1];
/* First, print the edges that represent each possible reduction for
the given state. */
obstack_printf (&oout, " %1$d -> \"%1$dR%2$d\" [label=\"",
source, ruleno);
/* Build the lookahead tokens lists, one for enabled transitions and one
for disabled transistions. */
if (default_reduction && default_reduction == reds->rules[j])
first = print_token (&oout, true, "$default");
else
defaulted = true;
if (reds->lookahead_tokens)
{
int i;
for (i = 0; i < ntokens; i++)
if (bitset_test (reds->lookahead_tokens[j], i))
{
first = print_token (&oout, first, symbols[i]->tag);
if (bitset_test (no_reduce_set, i))
disabled = true;
}
}
obstack_sgrow (&oout, "\" style=solid]\n");
/* Then, print the reduction's representation. Done later since
we need to know whether this reduction is disabled. */
obstack_printf (&oout,
" \"%dR%d\" "
"[style=filled shape=diamond fillcolor=%s "
"label=\"R%d\"]\n",
source, ruleno,
disabled ? "firebrick1" : "yellowgreen",
ruleno);
/* If no lookahead tokens were valid transitions, this reduction is
actually disabled, so don't print it. */
if (first)
(void) obstack_finish0 (&oout);
firstd = print_token (&dout, firstd, symbols[i]->tag);
else
fprintf (fout, obstack_finish0 (&oout));
{
if (! defaulted)
firste = print_token (&eout, firste, symbols[i]->tag);
bitset_set (no_reduce_set, i);
}
obstack_free (&oout, 0);
}
}
/* Do the actual output. */
conclude_red (&eout, source, ruleno, true, firste && !defaulted, fout);
conclude_red (&dout, source, ruleno, false, firstd, fout);
}
obstack_free (&eout, 0);
obstack_free (&dout, 0);
}
void

View File

@@ -88,7 +88,7 @@ typedef struct
} location;
#define YYLTYPE location
#define GRAM_LTYPE location
#define EMPTY_LOCATION_INIT {{NULL, 0, 0}, {NULL, 0, 0}}
extern location const empty_location;

View File

@@ -87,15 +87,15 @@ static char const *char_name (char);
#define YYTYPE_UINT8 uint_fast8_t
}
%verbose
%defines
%define locations
%define api.prefix "gram_"
%define api.pure
%define locations
%define parse.error verbose
%define parse.lac full
%define parse.trace
%name-prefix "gram_"
%defines
%expect 0
%verbose
%initial-action
{

View File

@@ -40,11 +40,32 @@
| Construct the node labels. |
`----------------------------*/
/* Print the lhs of a rule in such a manner that there is no vertical
repetition, like in *.output files. */
static void
print_lhs (struct obstack *oout, rule *previous_rule, rule *r)
{
if (previous_rule && STREQ (previous_rule->lhs->tag, r->lhs->tag))
{
int i;
for (i = 0; i < strlen (r->lhs->tag); ++i)
obstack_1grow (oout, ' ');
obstack_1grow (oout, '|');
}
else
{
obstack_sgrow (oout, escape (r->lhs->tag));
obstack_1grow (oout, ':');
}
}
static void
print_core (struct obstack *oout, state *s)
{
size_t i;
item_number *sitems = s->items;
rule *previous_rule = NULL;
size_t i;
size_t snritems = s->nitems;
/* Output all the items of a state, not only its kernel. */
@@ -55,7 +76,8 @@ print_core (struct obstack *oout, state *s)
snritems = nitemset;
}
obstack_printf (oout, "state %d\\n", s->number);
obstack_printf (oout, _("State %d"), s->number);
obstack_sgrow (oout, "\\n");
for (i = 0; i < snritems; i++)
{
item_number *sp;
@@ -69,12 +91,14 @@ print_core (struct obstack *oout, state *s)
r = item_number_as_rule_number (*sp);
obstack_printf (oout, "%d: %s -> ", r, escape (rules[r].lhs->tag));
obstack_printf (oout, "%3d ", r);
print_lhs (oout, previous_rule, &rules[r]);
previous_rule = &rules[r];
for (sp = rules[r].rhs; sp < sp1; sp++)
obstack_printf (oout, "%s ", escape (symbols[*sp]->tag));
obstack_1grow (oout, '.');
obstack_sgrow (oout, " .");
for (/* Nothing */; *sp >= 0; ++sp)
obstack_printf (oout, " %s", escape (symbols[*sp]->tag));
@@ -93,7 +117,7 @@ print_core (struct obstack *oout, state *s)
bitset_iterator biter;
int k;
char const *sep = "";
obstack_1grow (oout, '[');
obstack_sgrow (oout, " [");
BITSET_FOR_EACH (biter, reds->lookahead_tokens[redno], k, 0)
{
obstack_sgrow (oout, sep);
@@ -116,9 +140,8 @@ print_core (struct obstack *oout, state *s)
static void
print_actions (state const *s, FILE *fgraph)
{
int i;
transitions const *trans = s->transitions;
int i;
/* Display reductions. */
output_red (s, s->reductions, fgraph);

View File

@@ -51,9 +51,9 @@ 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);
void grammar_current_rule_symbol_append (symbol *sym, location loc,
named_ref *named_ref);
named_ref *nref);
void grammar_current_rule_action_append (const char *action, location loc,
named_ref *named_ref, bool);
named_ref *nref, bool);
void reader (void);
void free_merger_functions (void);

View File

@@ -32,7 +32,7 @@ void gram_scanner_last_string_free (void);
extern FILE *gram_out;
extern int gram_lineno;
# define GRAM_LEX_DECL int gram_lex (YYSTYPE *val, location *loc)
# define GRAM_LEX_DECL int gram_lex (GRAM_STYPE *val, location *loc)
GRAM_LEX_DECL;
#endif /* !SCAN_GRAM_H_ */

View File

@@ -465,10 +465,14 @@ m4_define([AT_BISON_CHECK_WARNINGS],
[m4_null_if([$2], [AT_BISON_CHECK_WARNINGS_($@)])])])
m4_define([AT_BISON_CHECK_WARNINGS_],
[[# Defining POSIXLY_CORRECT causes bison to complain if options
# are added after the grammar file name, so skip these checks
# in that case.
if test -z "${POSIXLY_CORRECT+set}"; then
[[# Defining POSIXLY_CORRECT causes bison to complain if options are
# added after the grammar file name, so skip these checks in that
# case.
#
# Don't just check if $POSIXLY_CORRECT is set, as Bash, when launched
# as /bin/sh, sets the shell variable POSIXLY_CORRECT to y, but not
# the environment variable.
if env | grep '^POSIXLY_CORRECT=' >/dev/null; then :; else
]AT_SAVE_SPECIAL_FILES[
# To avoid expanding it repeatedly, store specified stdout.

View File

@@ -251,3 +251,368 @@ AT_CHECK_OUTPUT_FILE_NAME([[@{]])
AT_CHECK_OUTPUT_FILE_NAME([[@}]])
AT_CHECK_OUTPUT_FILE_NAME([[@<:@]])
AT_CHECK_OUTPUT_FILE_NAME([[@:>@]])
# AT_TEST(SETUP-NAME, GRAMMAR, DOT-BODY)
# --------------------------------------
# Check that the DOT graph for GRAMMAR is DOT-BODY.
m4_pushdef([AT_TEST],
[AT_SETUP([$1])
AT_KEYWORDS([[graph]])
AT_DATA([[input.y]], [$2])
AT_BISON_CHECK([[-rall --graph input.y]], [0], [[]], [[ignore]])
AT_CHECK([[grep -v // input.dot]], [0],
[[
digraph "input.y"
{
node [fontname = courier, shape = box, colorscheme = paired6]
edge [fontname = courier]
]$3[}
]])
AT_CLEANUP
])
## ------------------------ ##
## Graph with no conflicts. ##
## ------------------------ ##
AT_TEST([Graph with no conflicts],
[[%%
exp: a '?' b;
a: ;
b: 'b';
]],
[[
0 [label="State 0\n 0 $accept: . exp $end\l 1 exp: . a '?' b\l 2 a: .\l"]
0 -> "0R2e" [style = solid]
"0R2e" [style = filled, shape = diamond, fillcolor = 3, label = "R2"]
0 -> 1 [style=dashed label="exp"]
0 -> 2 [style=dashed label="a"]
1 [label="State 1\n 0 $accept: exp . $end\l"]
1 -> 3 [style=solid label="$end"]
2 [label="State 2\n 1 exp: a . '?' b\l"]
2 -> 4 [style=solid label="'?'"]
3 [label="State 3\n 0 $accept: exp $end .\l"]
3 -> "3R0e" [style = solid]
"3R0e" [style = filled, shape = diamond, fillcolor = 1, label = "Acc"]
4 [label="State 4\n 1 exp: a '?' . b\l 3 b: . 'b'\l"]
4 -> 5 [style=solid label="'b'"]
4 -> 6 [style=dashed label="b"]
5 [label="State 5\n 3 b: 'b' .\l"]
5 -> "5R3e" [style = solid]
"5R3e" [style = filled, shape = diamond, fillcolor = 3, label = "R3"]
6 [label="State 6\n 1 exp: a '?' b .\l"]
6 -> "6R1e" [style = solid]
"6R1e" [style = filled, shape = diamond, fillcolor = 3, label = "R1"]
]])
## ------------------------ ##
## Graph with unsolved S/R. ##
## ------------------------ ##
AT_TEST([Graph with unsolved S/R],
[[%%
start:
'a'
| empty_a 'a'
| 'b'
| empty_b 'b'
| 'c'
| empty_c 'c'
;
empty_a: %prec 'a';
empty_b: %prec 'b';
empty_c: %prec 'c';
]],
[[
0 [label="State 0\n 0 $accept: . start $end\l 1 start: . 'a'\l 2 | . empty_a 'a'\l 3 | . 'b'\l 4 | . empty_b 'b'\l 5 | . 'c'\l 6 | . empty_c 'c'\l 7 empty_a: . ['a']\l 8 empty_b: . ['b']\l 9 empty_c: . ['c']\l"]
0 -> "0R7d" [label = "['a']" style = solid]
"0R7d" [style = filled, shape = diamond, fillcolor = 5, label = "R7"]
0 -> "0R8d" [label = "['b']" style = solid]
"0R8d" [style = filled, shape = diamond, fillcolor = 5, label = "R8"]
0 -> "0R9d" [label = "['c']" style = solid]
"0R9d" [style = filled, shape = diamond, fillcolor = 5, label = "R9"]
0 -> 1 [style=solid label="'a'"]
0 -> 2 [style=solid label="'b'"]
0 -> 3 [style=solid label="'c'"]
0 -> 4 [style=dashed label="start"]
0 -> 5 [style=dashed label="empty_a"]
0 -> 6 [style=dashed label="empty_b"]
0 -> 7 [style=dashed label="empty_c"]
1 [label="State 1\n 1 start: 'a' .\l"]
1 -> "1R1e" [style = solid]
"1R1e" [style = filled, shape = diamond, fillcolor = 3, label = "R1"]
2 [label="State 2\n 3 start: 'b' .\l"]
2 -> "2R3e" [style = solid]
"2R3e" [style = filled, shape = diamond, fillcolor = 3, label = "R3"]
3 [label="State 3\n 5 start: 'c' .\l"]
3 -> "3R5e" [style = solid]
"3R5e" [style = filled, shape = diamond, fillcolor = 3, label = "R5"]
4 [label="State 4\n 0 $accept: start . $end\l"]
4 -> 8 [style=solid label="$end"]
5 [label="State 5\n 2 start: empty_a . 'a'\l"]
5 -> 9 [style=solid label="'a'"]
6 [label="State 6\n 4 start: empty_b . 'b'\l"]
6 -> 10 [style=solid label="'b'"]
7 [label="State 7\n 6 start: empty_c . 'c'\l"]
7 -> 11 [style=solid label="'c'"]
8 [label="State 8\n 0 $accept: start $end .\l"]
8 -> "8R0e" [style = solid]
"8R0e" [style = filled, shape = diamond, fillcolor = 1, label = "Acc"]
9 [label="State 9\n 2 start: empty_a 'a' .\l"]
9 -> "9R2e" [style = solid]
"9R2e" [style = filled, shape = diamond, fillcolor = 3, label = "R2"]
10 [label="State 10\n 4 start: empty_b 'b' .\l"]
10 -> "10R4e" [style = solid]
"10R4e" [style = filled, shape = diamond, fillcolor = 3, label = "R4"]
11 [label="State 11\n 6 start: empty_c 'c' .\l"]
11 -> "11R6e" [style = solid]
"11R6e" [style = filled, shape = diamond, fillcolor = 3, label = "R6"]
]])
## ---------------------- ##
## Graph with solved S/R. ##
## ---------------------- ##
AT_TEST([Graph with solved S/R],
[[%left 'a'
%right 'b'
%right 'c'
%%
start:
'a'
| empty_a 'a'
| 'b'
| empty_b 'b'
| 'c'
| empty_c 'c'
;
empty_a: %prec 'a';
empty_b: %prec 'b';
empty_c: %prec 'c';
]],
[[
0 [label="State 0\n 0 $accept: . start $end\l 1 start: . 'a'\l 2 | . empty_a 'a'\l 3 | . 'b'\l 4 | . empty_b 'b'\l 5 | . 'c'\l 6 | . empty_c 'c'\l 7 empty_a: . ['a']\l 8 empty_b: . []\l 9 empty_c: . []\l"]
0 -> "0R7e" [style = solid]
"0R7e" [style = filled, shape = diamond, fillcolor = 3, label = "R7"]
0 -> 1 [style=solid label="'b'"]
0 -> 2 [style=solid label="'c'"]
0 -> 3 [style=dashed label="start"]
0 -> 4 [style=dashed label="empty_a"]
0 -> 5 [style=dashed label="empty_b"]
0 -> 6 [style=dashed label="empty_c"]
1 [label="State 1\n 3 start: 'b' .\l"]
1 -> "1R3e" [style = solid]
"1R3e" [style = filled, shape = diamond, fillcolor = 3, label = "R3"]
2 [label="State 2\n 5 start: 'c' .\l"]
2 -> "2R5e" [style = solid]
"2R5e" [style = filled, shape = diamond, fillcolor = 3, label = "R5"]
3 [label="State 3\n 0 $accept: start . $end\l"]
3 -> 7 [style=solid label="$end"]
4 [label="State 4\n 2 start: empty_a . 'a'\l"]
4 -> 8 [style=solid label="'a'"]
5 [label="State 5\n 4 start: empty_b . 'b'\l"]
5 -> 9 [style=solid label="'b'"]
6 [label="State 6\n 6 start: empty_c . 'c'\l"]
6 -> 10 [style=solid label="'c'"]
7 [label="State 7\n 0 $accept: start $end .\l"]
7 -> "7R0e" [style = solid]
"7R0e" [style = filled, shape = diamond, fillcolor = 1, label = "Acc"]
8 [label="State 8\n 2 start: empty_a 'a' .\l"]
8 -> "8R2e" [style = solid]
"8R2e" [style = filled, shape = diamond, fillcolor = 3, label = "R2"]
9 [label="State 9\n 4 start: empty_b 'b' .\l"]
9 -> "9R4e" [style = solid]
"9R4e" [style = filled, shape = diamond, fillcolor = 3, label = "R4"]
10 [label="State 10\n 6 start: empty_c 'c' .\l"]
10 -> "10R6e" [style = solid]
"10R6e" [style = filled, shape = diamond, fillcolor = 3, label = "R6"]
]])
## ---------------- ##
## Graph with R/R. ##
## ---------------- ##
AT_TEST([Graph with R/R],
[[%%
exp: a | b;
a: ;
b: ;
]],
[[
0 [label="State 0\n 0 $accept: . exp $end\l 1 exp: . a\l 2 | . b\l 3 a: . [$end]\l 4 b: . [$end]\l"]
0 -> "0R3e" [style = solid]
"0R3e" [style = filled, shape = diamond, fillcolor = 3, label = "R3"]
0 -> "0R4d" [label = "[$end]" style = solid]
"0R4d" [style = filled, shape = diamond, fillcolor = 5, label = "R4"]
0 -> 1 [style=dashed label="exp"]
0 -> 2 [style=dashed label="a"]
0 -> 3 [style=dashed label="b"]
1 [label="State 1\n 0 $accept: exp . $end\l"]
1 -> 4 [style=solid label="$end"]
2 [label="State 2\n 1 exp: a .\l"]
2 -> "2R1e" [style = solid]
"2R1e" [style = filled, shape = diamond, fillcolor = 3, label = "R1"]
3 [label="State 3\n 2 exp: b .\l"]
3 -> "3R2e" [style = solid]
"3R2e" [style = filled, shape = diamond, fillcolor = 3, label = "R2"]
4 [label="State 4\n 0 $accept: exp $end .\l"]
4 -> "4R0e" [style = solid]
"4R0e" [style = filled, shape = diamond, fillcolor = 1, label = "Acc"]
]])
## ---------------------------------------- ##
## Graph with reductions with multiple LAT. ##
## ---------------------------------------- ##
AT_TEST([Graph with reductions with multiple LAT],
[[%%
exp: a ';' | a ';' | a '.' | b '?' | b '!' | c '?' | c ';';
a: ;
b: ;
c: ;
]],
[[
0 [label="State 0\n 0 $accept: . exp $end\l 1 exp: . a ';'\l 2 | . a ';'\l 3 | . a '.'\l 4 | . b '?'\l 5 | . b '!'\l 6 | . c '?'\l 7 | . c ';'\l 8 a: . [';', '.']\l 9 b: . ['?', '!']\l 10 c: . [';', '?']\l"]
0 -> "0R8e" [style = solid]
"0R8e" [style = filled, shape = diamond, fillcolor = 3, label = "R8"]
0 -> "0R9e" [label = "['?', '!']" style = solid]
"0R9e" [style = filled, shape = diamond, fillcolor = 3, label = "R9"]
0 -> "0R10d" [label = "[';', '?']" style = solid]
"0R10d" [style = filled, shape = diamond, fillcolor = 5, label = "R10"]
0 -> 1 [style=dashed label="exp"]
0 -> 2 [style=dashed label="a"]
0 -> 3 [style=dashed label="b"]
0 -> 4 [style=dashed label="c"]
1 [label="State 1\n 0 $accept: exp . $end\l"]
1 -> 5 [style=solid label="$end"]
2 [label="State 2\n 1 exp: a . ';'\l 2 | a . ';'\l 3 | a . '.'\l"]
2 -> 6 [style=solid label="';'"]
2 -> 7 [style=solid label="'.'"]
3 [label="State 3\n 4 exp: b . '?'\l 5 | b . '!'\l"]
3 -> 8 [style=solid label="'?'"]
3 -> 9 [style=solid label="'!'"]
4 [label="State 4\n 6 exp: c . '?'\l 7 | c . ';'\l"]
4 -> 10 [style=solid label="';'"]
4 -> 11 [style=solid label="'?'"]
5 [label="State 5\n 0 $accept: exp $end .\l"]
5 -> "5R0e" [style = solid]
"5R0e" [style = filled, shape = diamond, fillcolor = 1, label = "Acc"]
6 [label="State 6\n 1 exp: a ';' . [$end]\l 2 | a ';' . [$end]\l"]
6 -> "6R1e" [style = solid]
"6R1e" [style = filled, shape = diamond, fillcolor = 3, label = "R1"]
6 -> "6R2d" [label = "[$end]" style = solid]
"6R2d" [style = filled, shape = diamond, fillcolor = 5, label = "R2"]
7 [label="State 7\n 3 exp: a '.' .\l"]
7 -> "7R3e" [style = solid]
"7R3e" [style = filled, shape = diamond, fillcolor = 3, label = "R3"]
8 [label="State 8\n 4 exp: b '?' .\l"]
8 -> "8R4e" [style = solid]
"8R4e" [style = filled, shape = diamond, fillcolor = 3, label = "R4"]
9 [label="State 9\n 5 exp: b '!' .\l"]
9 -> "9R5e" [style = solid]
"9R5e" [style = filled, shape = diamond, fillcolor = 3, label = "R5"]
10 [label="State 10\n 7 exp: c ';' .\l"]
10 -> "10R7e" [style = solid]
"10R7e" [style = filled, shape = diamond, fillcolor = 3, label = "R7"]
11 [label="State 11\n 6 exp: c '?' .\l"]
11 -> "11R6e" [style = solid]
"11R6e" [style = filled, shape = diamond, fillcolor = 3, label = "R6"]
]])
## ------------------------------------------------------ ##
## Graph with a reduction rule both enabled and disabled. ##
## ------------------------------------------------------ ##
AT_TEST([Graph with a reduction rule both enabled and disabled],
[[%%
exp: ifexp | opexp | imm;
ifexp: "if" exp "then" exp elseexp;
elseexp: "else" exp | ;
opexp: exp '+' exp;
imm: '0';
]],
[[
0 [label="State 0\n 0 $accept: . exp $end\l 1 exp: . ifexp\l 2 | . opexp\l 3 | . imm\l 4 ifexp: . \"if\" exp \"then\" exp elseexp\l 7 opexp: . exp '+' exp\l 8 imm: . '0'\l"]
0 -> 1 [style=solid label="\"if\""]
0 -> 2 [style=solid label="'0'"]
0 -> 3 [style=dashed label="exp"]
0 -> 4 [style=dashed label="ifexp"]
0 -> 5 [style=dashed label="opexp"]
0 -> 6 [style=dashed label="imm"]
1 [label="State 1\n 1 exp: . ifexp\l 2 | . opexp\l 3 | . imm\l 4 ifexp: . \"if\" exp \"then\" exp elseexp\l 4 | \"if\" . exp \"then\" exp elseexp\l 7 opexp: . exp '+' exp\l 8 imm: . '0'\l"]
1 -> 1 [style=solid label="\"if\""]
1 -> 2 [style=solid label="'0'"]
1 -> 7 [style=dashed label="exp"]
1 -> 4 [style=dashed label="ifexp"]
1 -> 5 [style=dashed label="opexp"]
1 -> 6 [style=dashed label="imm"]
2 [label="State 2\n 8 imm: '0' .\l"]
2 -> "2R8e" [style = solid]
"2R8e" [style = filled, shape = diamond, fillcolor = 3, label = "R8"]
3 [label="State 3\n 0 $accept: exp . $end\l 7 opexp: exp . '+' exp\l"]
3 -> 8 [style=solid label="$end"]
3 -> 9 [style=solid label="'+'"]
4 [label="State 4\n 1 exp: ifexp .\l"]
4 -> "4R1e" [style = solid]
"4R1e" [style = filled, shape = diamond, fillcolor = 3, label = "R1"]
5 [label="State 5\n 2 exp: opexp .\l"]
5 -> "5R2e" [style = solid]
"5R2e" [style = filled, shape = diamond, fillcolor = 3, label = "R2"]
6 [label="State 6\n 3 exp: imm .\l"]
6 -> "6R3e" [style = solid]
"6R3e" [style = filled, shape = diamond, fillcolor = 3, label = "R3"]
7 [label="State 7\n 4 ifexp: \"if\" exp . \"then\" exp elseexp\l 7 opexp: exp . '+' exp\l"]
7 -> 10 [style=solid label="\"then\""]
7 -> 9 [style=solid label="'+'"]
8 [label="State 8\n 0 $accept: exp $end .\l"]
8 -> "8R0e" [style = solid]
"8R0e" [style = filled, shape = diamond, fillcolor = 1, label = "Acc"]
9 [label="State 9\n 1 exp: . ifexp\l 2 | . opexp\l 3 | . imm\l 4 ifexp: . \"if\" exp \"then\" exp elseexp\l 7 opexp: . exp '+' exp\l 7 | exp '+' . exp\l 8 imm: . '0'\l"]
9 -> 1 [style=solid label="\"if\""]
9 -> 2 [style=solid label="'0'"]
9 -> 11 [style=dashed label="exp"]
9 -> 4 [style=dashed label="ifexp"]
9 -> 5 [style=dashed label="opexp"]
9 -> 6 [style=dashed label="imm"]
10 [label="State 10\n 1 exp: . ifexp\l 2 | . opexp\l 3 | . imm\l 4 ifexp: . \"if\" exp \"then\" exp elseexp\l 4 | \"if\" exp \"then\" . exp elseexp\l 7 opexp: . exp '+' exp\l 8 imm: . '0'\l"]
10 -> 1 [style=solid label="\"if\""]
10 -> 2 [style=solid label="'0'"]
10 -> 12 [style=dashed label="exp"]
10 -> 4 [style=dashed label="ifexp"]
10 -> 5 [style=dashed label="opexp"]
10 -> 6 [style=dashed label="imm"]
11 [label="State 11\n 7 opexp: exp . '+' exp\l 7 | exp '+' exp . [$end, \"then\", \"else\", '+']\l"]
11 -> "11R7e" [style = solid]
"11R7e" [style = filled, shape = diamond, fillcolor = 3, label = "R7"]
11 -> "11R7d" [label = "['+']" style = solid]
"11R7d" [style = filled, shape = diamond, fillcolor = 5, label = "R7"]
11 -> 9 [style=solid label="'+'"]
12 [label="State 12\n 4 ifexp: \"if\" exp \"then\" exp . elseexp\l 5 elseexp: . \"else\" exp\l 6 | . [$end, \"then\", \"else\", '+']\l 7 opexp: exp . '+' exp\l"]
12 -> "12R6e" [style = solid]
"12R6e" [style = filled, shape = diamond, fillcolor = 3, label = "R6"]
12 -> "12R6d" [label = "[\"else\", '+']" style = solid]
"12R6d" [style = filled, shape = diamond, fillcolor = 5, label = "R6"]
12 -> 13 [style=solid label="\"else\""]
12 -> 9 [style=solid label="'+'"]
12 -> 14 [style=dashed label="elseexp"]
13 [label="State 13\n 1 exp: . ifexp\l 2 | . opexp\l 3 | . imm\l 4 ifexp: . \"if\" exp \"then\" exp elseexp\l 5 elseexp: \"else\" . exp\l 7 opexp: . exp '+' exp\l 8 imm: . '0'\l"]
13 -> 1 [style=solid label="\"if\""]
13 -> 2 [style=solid label="'0'"]
13 -> 15 [style=dashed label="exp"]
13 -> 4 [style=dashed label="ifexp"]
13 -> 5 [style=dashed label="opexp"]
13 -> 6 [style=dashed label="imm"]
14 [label="State 14\n 4 ifexp: \"if\" exp \"then\" exp elseexp .\l"]
14 -> "14R4e" [style = solid]
"14R4e" [style = filled, shape = diamond, fillcolor = 3, label = "R4"]
15 [label="State 15\n 5 elseexp: \"else\" exp . [$end, \"then\", \"else\", '+']\l 7 opexp: exp . '+' exp\l"]
15 -> "15R5e" [style = solid]
"15R5e" [style = filled, shape = diamond, fillcolor = 3, label = "R5"]
15 -> "15R5d" [label = "['+']" style = solid]
"15R5d" [style = filled, shape = diamond, fillcolor = 5, label = "R5"]
15 -> 9 [style=solid label="'+'"]
]])
m4_popdef([AT_TEST])

View File

@@ -431,7 +431,7 @@ int
main (int argc, const char **argv)
{
YYSTYPE yylval_init = get_args (argc, argv);
int status;
int status = 0;
int count;
]m4_bmatch([$2], [api.push-pull both],
[[ yypstate *ps = yypstate_new ();