mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-09 12:23:04 +00:00
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:
@@ -1 +1 @@
|
|||||||
2.6.2
|
2.6.4
|
||||||
|
|||||||
101
NEWS
101
NEWS
@@ -242,20 +242,6 @@ GNU Bison NEWS
|
|||||||
|
|
||||||
* Noteworthy changes in release ?.? (????-??-??) [?]
|
* 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
|
** Changes in the format of error messages
|
||||||
|
|
||||||
This used to be the format of many error reports:
|
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:5.10-25: result type clash on merge function 'merge': <t3> != <t2>
|
||||||
foo.y:4.13-27: previous declaration
|
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)
|
** Exception safety (lalr1.cc)
|
||||||
|
|
||||||
The parse function now catches exceptions, uses the %destructors to
|
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
|
This feature is somewhat experimental. User feedback would be
|
||||||
appreciated.
|
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)
|
** 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
|
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
|
position_type are deprecated in favor of api.location.type and
|
||||||
api.position.type.
|
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]
|
* Noteworthy changes in release 2.6.2 (2012-08-03) [stable]
|
||||||
|
|
||||||
** Bug fixes
|
** Bug fixes
|
||||||
@@ -380,7 +395,7 @@ GNU Bison NEWS
|
|||||||
|
|
||||||
* Noteworthy changes in release 2.6 (2012-07-19) [stable]
|
* 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
|
The next major release of Bison will drop support for the following
|
||||||
deprecated features. Please report disagreements to bug-bison@gnu.org.
|
deprecated features. Please report disagreements to bug-bison@gnu.org.
|
||||||
|
|||||||
@@ -50,16 +50,17 @@ These requirements do not apply when building from a distribution tarball.
|
|||||||
|
|
||||||
** Requirements
|
** Requirements
|
||||||
|
|
||||||
We've opted to keep only the highest-level sources in the repository.
|
We've opted to keep only the highest-level sources in the repository. This
|
||||||
This eases our maintenance burden, (fewer merges etc.), but imposes more
|
eases our maintenance burden, (fewer merges etc.), but imposes more
|
||||||
requirements on anyone wishing to build from the just-checked-out sources.
|
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
|
For example, you have to use the latest stable versions of the maintainer
|
||||||
tools we depend upon, including:
|
tools we depend upon, including:
|
||||||
|
|
||||||
- Automake <http://www.gnu.org/software/automake/>
|
|
||||||
- Autoconf <http://www.gnu.org/software/autoconf/>
|
- Autoconf <http://www.gnu.org/software/autoconf/>
|
||||||
|
- Automake <http://www.gnu.org/software/automake/>
|
||||||
- Flex <http://www.gnu.org/software/flex/>
|
- Flex <http://www.gnu.org/software/flex/>
|
||||||
- Gettext <http://www.gnu.org/software/gettext/>
|
- Gettext <http://www.gnu.org/software/gettext/>
|
||||||
|
- Graphviz <http://www.graphviz.org>
|
||||||
- Gzip <http://www.gnu.org/software/gzip/>
|
- Gzip <http://www.gnu.org/software/gzip/>
|
||||||
- Perl <http://www.cpan.org/>
|
- Perl <http://www.cpan.org/>
|
||||||
- Rsync <http://samba.anu.edu.au/rsync/>
|
- 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
|
Valgrind <http://valgrind.org/> is also highly recommended, if it supports
|
||||||
your architecture.
|
your architecture.
|
||||||
|
|
||||||
Bison is written using Bison grammars, so there are bootstrapping
|
Bison is written using Bison grammars, so there are bootstrapping issues.
|
||||||
issues. The bootstrap script attempts to discover when the C code
|
The bootstrap script attempts to discover when the C code generated from the
|
||||||
generated from the grammars is out of date, and to bootstrap with an
|
grammars is out of date, and to bootstrap with an out-of-date version of the
|
||||||
out-of-date version of the C code, but the process is not foolproof.
|
C code, but the process is not foolproof. Also, you may run into similar
|
||||||
Also, you may run into similar problems yourself if you modify Bison.
|
problems yourself if you modify Bison.
|
||||||
|
|
||||||
Only building the initial full source tree will be a bit painful.
|
Only building the initial full source tree will be a bit painful. Later,
|
||||||
Later, after synchronizing from the repository a plain 'make' should
|
after synchronizing from the repository a plain 'make' should be sufficient.
|
||||||
be sufficient. Note, however, that when gnulib is updated, running
|
Note, however, that when gnulib is updated, running './bootstrap' again
|
||||||
'./bootstrap' again might be needed.
|
might be needed.
|
||||||
|
|
||||||
** First checkout
|
** First checkout
|
||||||
|
|
||||||
|
|||||||
12
TODO
12
TODO
@@ -1,4 +1,16 @@
|
|||||||
* Short term
|
* 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
|
** push-parser
|
||||||
Check it too when checking the different kinds of parsers. And be
|
Check it too when checking the different kinds of parsers. And be
|
||||||
|
|||||||
1
cfg.mk
1
cfg.mk
@@ -24,6 +24,7 @@ regen: _version
|
|||||||
|
|
||||||
# Used in maint.mk's web-manual rule
|
# Used in maint.mk's web-manual rule
|
||||||
manual_title = The Yacc-compatible Parser Generator
|
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
|
# 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,
|
# don't want to wait on a recompile because of an update to $(VERSION). Thus,
|
||||||
|
|||||||
17
configure.ac
17
configure.ac
@@ -75,6 +75,18 @@ if test "$enable_gcc_warnings" = yes; then
|
|||||||
warn_cxx='-Wnoexcept'
|
warn_cxx='-Wnoexcept'
|
||||||
|
|
||||||
AC_LANG_PUSH([C])
|
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;
|
for i in $warn_common $warn_c;
|
||||||
do
|
do
|
||||||
gl_WARN_ADD([$i], [WARN_CFLAGS])
|
gl_WARN_ADD([$i], [WARN_CFLAGS])
|
||||||
@@ -83,9 +95,12 @@ if test "$enable_gcc_warnings" = yes; then
|
|||||||
# Warnings for the test suite only.
|
# Warnings for the test suite only.
|
||||||
gl_WARN_ADD([-Wundef], [WARN_CFLAGS_TEST])
|
gl_WARN_ADD([-Wundef], [WARN_CFLAGS_TEST])
|
||||||
gl_WARN_ADD([-pedantic], [WARN_CFLAGS_TEST])
|
gl_WARN_ADD([-pedantic], [WARN_CFLAGS_TEST])
|
||||||
|
CFLAGS=$save_CFLAGS
|
||||||
AC_LANG_POP([C])
|
AC_LANG_POP([C])
|
||||||
|
|
||||||
AC_LANG_PUSH([C++])
|
AC_LANG_PUSH([C++])
|
||||||
|
save_CXXFLAGS=$CXXFLAGS
|
||||||
|
gl_WARN_ADD([-Werror=unknown-warning-option], [CXXFLAGS])
|
||||||
for i in $warn_common $warn_cxx;
|
for i in $warn_common $warn_cxx;
|
||||||
do
|
do
|
||||||
gl_WARN_ADD([$i], [WARN_CXXFLAGS])
|
gl_WARN_ADD([$i], [WARN_CXXFLAGS])
|
||||||
@@ -96,6 +111,7 @@ if test "$enable_gcc_warnings" = yes; then
|
|||||||
# Warnings for the test suite only.
|
# Warnings for the test suite only.
|
||||||
gl_WARN_ADD([-Wundef], [WARN_CXXFLAGS_TEST])
|
gl_WARN_ADD([-Wundef], [WARN_CXXFLAGS_TEST])
|
||||||
gl_WARN_ADD([-pedantic], [WARN_CXXFLAGS_TEST])
|
gl_WARN_ADD([-pedantic], [WARN_CXXFLAGS_TEST])
|
||||||
|
CXXFLAGS=$save_CXXFLAGS
|
||||||
AC_LANG_POP([C++])
|
AC_LANG_POP([C++])
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -118,6 +134,7 @@ AC_SUBST([YACC_SCRIPT])
|
|||||||
AC_SUBST([YACC_LIBRARY])
|
AC_SUBST([YACC_LIBRARY])
|
||||||
|
|
||||||
# Checks for programs.
|
# Checks for programs.
|
||||||
|
AM_MISSING_PROG([DOT], [dot])
|
||||||
AC_PROG_LEX
|
AC_PROG_LEX
|
||||||
$LEX_IS_FLEX || AC_MSG_ERROR([Flex is required])
|
$LEX_IS_FLEX || AC_MSG_ERROR([Flex is required])
|
||||||
AC_PROG_YACC
|
AC_PROG_YACC
|
||||||
|
|||||||
@@ -557,7 +557,7 @@ m4_define([b4_YYDEBUG_define],
|
|||||||
# endif
|
# endif
|
||||||
# else /* ! defined YYDEBUG */
|
# else /* ! defined YYDEBUG */
|
||||||
# define ]b4_api_PREFIX[DEBUG ]b4_parse_trace_if([1], [0])[
|
# 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
|
#endif /* ! defined ]b4_api_PREFIX[DEBUG */]])[]dnl
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|||||||
@@ -200,7 +200,7 @@ m4_define([b4_init_throws], [b4_percent_define_get([[init_throws]])])
|
|||||||
b4_percent_define_default([[api.location.type]], [Location])
|
b4_percent_define_default([[api.location.type]], [Location])
|
||||||
m4_define([b4_location_type], [b4_percent_define_get([[api.location.type]])])
|
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]])])
|
m4_define([b4_position_type], [b4_percent_define_get([[api.position.type]])])
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -55,7 +55,11 @@
|
|||||||
<xsl:call-template name="escape">
|
<xsl:call-template name="escape">
|
||||||
<xsl:with-param name="subject" select="$filename"/>
|
<xsl:with-param name="subject" select="$filename"/>
|
||||||
</xsl:call-template>
|
</xsl:call-template>
|
||||||
<xsl:text>" { </xsl:text>
|
<xsl:text> {
|
||||||
|
node [fontname = courier, shape = box, colorscheme = paired6]
|
||||||
|
edge [fontname = courier]
|
||||||
|
|
||||||
|
</xsl:text>
|
||||||
<xsl:apply-templates select="state"/>
|
<xsl:apply-templates select="state"/>
|
||||||
<xsl:text>} </xsl:text>
|
<xsl:text>} </xsl:text>
|
||||||
</xsl:template>
|
</xsl:template>
|
||||||
@@ -124,20 +128,20 @@
|
|||||||
<xsl:with-param name="dst" select="@state"/>
|
<xsl:with-param name="dst" select="@state"/>
|
||||||
<xsl:with-param name="style">
|
<xsl:with-param name="style">
|
||||||
<xsl:choose>
|
<xsl:choose>
|
||||||
<xsl:when test="@symbol = 'error'">
|
<xsl:when test="@symbol = 'error'">
|
||||||
<xsl:text>dotted</xsl:text>
|
<xsl:text>dotted</xsl:text>
|
||||||
</xsl:when>
|
</xsl:when>
|
||||||
<xsl:when test="@type = 'shift'">
|
<xsl:when test="@type = 'shift'">
|
||||||
<xsl:text>solid</xsl:text>
|
<xsl:text>solid</xsl:text>
|
||||||
</xsl:when>
|
</xsl:when>
|
||||||
<xsl:otherwise>
|
<xsl:otherwise>
|
||||||
<xsl:text>dashed</xsl:text>
|
<xsl:text>dashed</xsl:text>
|
||||||
</xsl:otherwise>
|
</xsl:otherwise>
|
||||||
</xsl:choose>
|
</xsl:choose>
|
||||||
</xsl:with-param>
|
</xsl:with-param>
|
||||||
<xsl:with-param name="label">
|
<xsl:with-param name="label">
|
||||||
<xsl:if test="not(@symbol = 'error')">
|
<xsl:if test="not(@symbol = 'error')">
|
||||||
<xsl:value-of select="@symbol"/>
|
<xsl:value-of select="@symbol"/>
|
||||||
</xsl:if>
|
</xsl:if>
|
||||||
</xsl:with-param>
|
</xsl:with-param>
|
||||||
</xsl:call-template>
|
</xsl:call-template>
|
||||||
|
|||||||
@@ -685,18 +685,14 @@ while (0)
|
|||||||
# else
|
# else
|
||||||
# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
|
# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
|
||||||
# endif
|
# endif
|
||||||
#endif]], [[
|
#endif]],
|
||||||
|
[[/* This macro is provided for backward compatibility. */
|
||||||
|
|
||||||
/* This macro is provided for backward compatibility. */
|
|
||||||
|
|
||||||
#ifndef YY_LOCATION_PRINT
|
#ifndef YY_LOCATION_PRINT
|
||||||
# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
|
# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
|
||||||
#endif]])[
|
#endif]])[
|
||||||
|
|
||||||
|
|
||||||
/* YYLEX -- calling `yylex' with the right arguments. */
|
/* YYLEX -- calling `yylex' with the right arguments. */
|
||||||
|
|
||||||
#ifdef YYLEX_PARAM
|
#ifdef YYLEX_PARAM
|
||||||
# define YYLEX yylex (]b4_pure_if([&yylval[]b4_locations_if([, &yylloc]), ])[YYLEX_PARAM)
|
# define YYLEX yylex (]b4_pure_if([&yylval[]b4_locations_if([, &yylloc]), ])[YYLEX_PARAM)
|
||||||
#else
|
#else
|
||||||
|
|||||||
112
doc/bison.texi
112
doc/bison.texi
@@ -298,6 +298,7 @@ Handling Context Dependencies
|
|||||||
Debugging Your Parser
|
Debugging Your Parser
|
||||||
|
|
||||||
* Understanding:: Understanding the structure of 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:: Tracing the execution of your parser.
|
||||||
|
|
||||||
Tracing Your Parser
|
Tracing Your Parser
|
||||||
@@ -8422,6 +8423,7 @@ automaton, and how to enable and understand the parser run-time traces.
|
|||||||
|
|
||||||
@menu
|
@menu
|
||||||
* Understanding:: Understanding the structure of 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:: Tracing the execution of your parser.
|
||||||
@end menu
|
@end menu
|
||||||
|
|
||||||
@@ -8838,6 +8840,114 @@ precedence of @samp{/} with respect to @samp{+}, @samp{-}, and
|
|||||||
@samp{*}, but also because the
|
@samp{*}, but also because the
|
||||||
associativity of @samp{/} is not specified.
|
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
|
@node Tracing
|
||||||
@section Tracing Your Parser
|
@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: subdirectory Solaris nonassociativity perror schemas Malloy ints
|
||||||
@c LocalWords: Scannerless ispell american ChangeLog smallexample CSTYPE CLTYPE
|
@c LocalWords: Scannerless ispell american ChangeLog smallexample CSTYPE CLTYPE
|
||||||
@c LocalWords: clval CDEBUG cdebug deftypeopx yyterminate LocationType
|
@c LocalWords: clval CDEBUG cdebug deftypeopx yyterminate LocationType
|
||||||
|
@c LocalWords: errorVerbose
|
||||||
|
|
||||||
@c Local Variables:
|
@c Local Variables:
|
||||||
@c ispell-dictionary: "american"
|
@c ispell-dictionary: "american"
|
||||||
@c fill-column: 76
|
@c fill-column: 76
|
||||||
@c End:
|
@c End:
|
||||||
@c LocalWords: errorVerbose
|
|
||||||
|
|||||||
11
doc/figs/example-reduce.dot
Normal file
11
doc/figs/example-reduce.dot
Normal 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"]
|
||||||
|
}
|
||||||
13
doc/figs/example-reduce.txt
Normal file
13
doc/figs/example-reduce.txt
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
.------------------.
|
||||||
|
| State 1 |
|
||||||
|
| 3 a: "0" . [";"] |
|
||||||
|
| 4 b: "0" . ["."] |
|
||||||
|
`------------------'
|
||||||
|
/ \
|
||||||
|
/ \ ["."]
|
||||||
|
/ \
|
||||||
|
v v
|
||||||
|
/ \ / \
|
||||||
|
/ R \ / R \
|
||||||
|
(green) \ 3 / \ 4 / (green)
|
||||||
|
\ / \ /
|
||||||
9
doc/figs/example-shift.dot
Normal file
9
doc/figs/example-shift.dot
Normal 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"]
|
||||||
|
}
|
||||||
12
doc/figs/example-shift.txt
Normal file
12
doc/figs/example-shift.txt
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
.----------------.
|
||||||
|
| State 3 |
|
||||||
|
| 1 exp: a . ";" |
|
||||||
|
`----------------'
|
||||||
|
|
|
||||||
|
| ";"
|
||||||
|
|
|
||||||
|
v
|
||||||
|
.----------------.
|
||||||
|
| State 6 |
|
||||||
|
| 1 exp: a ";" . |
|
||||||
|
`----------------'
|
||||||
30
doc/local.mk
30
doc/local.mk
@@ -112,6 +112,36 @@ $(top_srcdir)/doc/bison.1: doc/bison.help doc/bison.x $(top_srcdir)/configure
|
|||||||
|
|
||||||
nodist_man_MANS = doc/yacc.1
|
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. ##
|
## Doxygenation. ##
|
||||||
## -------------- ##
|
## -------------- ##
|
||||||
|
|||||||
2
gnulib
2
gnulib
Submodule gnulib updated: dcf27bef48...6061979365
108
src/graphviz.c
108
src/graphviz.c
@@ -53,7 +53,10 @@ start_graph (FILE *fout)
|
|||||||
"digraph %s\n"
|
"digraph %s\n"
|
||||||
"{\n",
|
"{\n",
|
||||||
quote (grammar_file));
|
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
|
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);
|
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
|
static bool
|
||||||
print_token (struct obstack *out, bool first, char const *tok)
|
print_token (struct obstack *out, bool first, char const *tok)
|
||||||
{
|
{
|
||||||
char const *q = escape (tok);
|
char const *q = escape (tok);
|
||||||
|
|
||||||
if (! first)
|
if (! first)
|
||||||
obstack_sgrow (out, ",");
|
obstack_sgrow (out, ", ");
|
||||||
obstack_sgrow (out, q);
|
obstack_sgrow (out, q);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -110,58 +154,56 @@ output_red (state const *s, reductions const *reds, FILE *fout)
|
|||||||
bitset no_reduce_set;
|
bitset no_reduce_set;
|
||||||
int j;
|
int j;
|
||||||
int source = s->number;
|
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);
|
no_reduce_bitset_init (s, &no_reduce_set);
|
||||||
obstack_init (&oout);
|
obstack_init (&dout);
|
||||||
|
obstack_init (&eout);
|
||||||
|
|
||||||
for (j = 0; j < reds->num; ++j)
|
for (j = 0; j < reds->num; ++j)
|
||||||
{
|
{
|
||||||
bool disabled = false;
|
bool defaulted = false;
|
||||||
bool first = true;
|
bool firstd = true;
|
||||||
int ruleno = reds->rules[j]->user_number;
|
bool firste = true;
|
||||||
|
rule_number ruleno = reds->rules[j]->user_number;
|
||||||
rule *default_reduction = NULL;
|
rule *default_reduction = NULL;
|
||||||
|
|
||||||
if (yydefact[s->number] != 0)
|
if (yydefact[s->number] != 0)
|
||||||
default_reduction = &rules[yydefact[s->number] - 1];
|
default_reduction = &rules[yydefact[s->number] - 1];
|
||||||
|
|
||||||
/* First, print the edges that represent each possible reduction for
|
/* Build the lookahead tokens lists, one for enabled transitions and one
|
||||||
the given state. */
|
for disabled transistions. */
|
||||||
obstack_printf (&oout, " %1$d -> \"%1$dR%2$d\" [label=\"",
|
|
||||||
source, ruleno);
|
|
||||||
if (default_reduction && default_reduction == reds->rules[j])
|
if (default_reduction && default_reduction == reds->rules[j])
|
||||||
first = print_token (&oout, true, "$default");
|
defaulted = true;
|
||||||
else
|
if (reds->lookahead_tokens)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < ntokens; i++)
|
for (i = 0; i < ntokens; i++)
|
||||||
if (bitset_test (reds->lookahead_tokens[j], i))
|
if (bitset_test (reds->lookahead_tokens[j], i))
|
||||||
{
|
{
|
||||||
first = print_token (&oout, first, symbols[i]->tag);
|
|
||||||
if (bitset_test (no_reduce_set, i))
|
if (bitset_test (no_reduce_set, i))
|
||||||
disabled = true;
|
firstd = print_token (&dout, firstd, symbols[i]->tag);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (! defaulted)
|
||||||
|
firste = print_token (&eout, firste, symbols[i]->tag);
|
||||||
|
bitset_set (no_reduce_set, i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
obstack_sgrow (&oout, "\" style=solid]\n");
|
|
||||||
|
|
||||||
/* Then, print the reduction's representation. Done later since
|
/* Do the actual output. */
|
||||||
we need to know whether this reduction is disabled. */
|
conclude_red (&eout, source, ruleno, true, firste && !defaulted, fout);
|
||||||
obstack_printf (&oout,
|
conclude_red (&dout, source, ruleno, false, firstd, fout);
|
||||||
" \"%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);
|
|
||||||
else
|
|
||||||
fprintf (fout, obstack_finish0 (&oout));
|
|
||||||
}
|
}
|
||||||
obstack_free (&oout, 0);
|
obstack_free (&eout, 0);
|
||||||
|
obstack_free (&dout, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ typedef struct
|
|||||||
|
|
||||||
} location;
|
} location;
|
||||||
|
|
||||||
#define YYLTYPE location
|
#define GRAM_LTYPE location
|
||||||
|
|
||||||
#define EMPTY_LOCATION_INIT {{NULL, 0, 0}, {NULL, 0, 0}}
|
#define EMPTY_LOCATION_INIT {{NULL, 0, 0}, {NULL, 0, 0}}
|
||||||
extern location const empty_location;
|
extern location const empty_location;
|
||||||
|
|||||||
@@ -87,15 +87,15 @@ static char const *char_name (char);
|
|||||||
#define YYTYPE_UINT8 uint_fast8_t
|
#define YYTYPE_UINT8 uint_fast8_t
|
||||||
}
|
}
|
||||||
|
|
||||||
%verbose
|
%define api.prefix "gram_"
|
||||||
%defines
|
|
||||||
%define locations
|
|
||||||
%define api.pure
|
%define api.pure
|
||||||
|
%define locations
|
||||||
%define parse.error verbose
|
%define parse.error verbose
|
||||||
%define parse.lac full
|
%define parse.lac full
|
||||||
%define parse.trace
|
%define parse.trace
|
||||||
%name-prefix "gram_"
|
%defines
|
||||||
%expect 0
|
%expect 0
|
||||||
|
%verbose
|
||||||
|
|
||||||
%initial-action
|
%initial-action
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -40,11 +40,32 @@
|
|||||||
| Construct the node labels. |
|
| 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
|
static void
|
||||||
print_core (struct obstack *oout, state *s)
|
print_core (struct obstack *oout, state *s)
|
||||||
{
|
{
|
||||||
size_t i;
|
|
||||||
item_number *sitems = s->items;
|
item_number *sitems = s->items;
|
||||||
|
rule *previous_rule = NULL;
|
||||||
|
size_t i;
|
||||||
size_t snritems = s->nitems;
|
size_t snritems = s->nitems;
|
||||||
|
|
||||||
/* Output all the items of a state, not only its kernel. */
|
/* Output all the items of a state, not only its kernel. */
|
||||||
@@ -55,7 +76,8 @@ print_core (struct obstack *oout, state *s)
|
|||||||
snritems = nitemset;
|
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++)
|
for (i = 0; i < snritems; i++)
|
||||||
{
|
{
|
||||||
item_number *sp;
|
item_number *sp;
|
||||||
@@ -69,12 +91,14 @@ print_core (struct obstack *oout, state *s)
|
|||||||
|
|
||||||
r = item_number_as_rule_number (*sp);
|
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++)
|
for (sp = rules[r].rhs; sp < sp1; sp++)
|
||||||
obstack_printf (oout, "%s ", escape (symbols[*sp]->tag));
|
obstack_printf (oout, "%s ", escape (symbols[*sp]->tag));
|
||||||
|
|
||||||
obstack_1grow (oout, '.');
|
obstack_sgrow (oout, " .");
|
||||||
|
|
||||||
for (/* Nothing */; *sp >= 0; ++sp)
|
for (/* Nothing */; *sp >= 0; ++sp)
|
||||||
obstack_printf (oout, " %s", escape (symbols[*sp]->tag));
|
obstack_printf (oout, " %s", escape (symbols[*sp]->tag));
|
||||||
@@ -93,7 +117,7 @@ print_core (struct obstack *oout, state *s)
|
|||||||
bitset_iterator biter;
|
bitset_iterator biter;
|
||||||
int k;
|
int k;
|
||||||
char const *sep = "";
|
char const *sep = "";
|
||||||
obstack_1grow (oout, '[');
|
obstack_sgrow (oout, " [");
|
||||||
BITSET_FOR_EACH (biter, reds->lookahead_tokens[redno], k, 0)
|
BITSET_FOR_EACH (biter, reds->lookahead_tokens[redno], k, 0)
|
||||||
{
|
{
|
||||||
obstack_sgrow (oout, sep);
|
obstack_sgrow (oout, sep);
|
||||||
@@ -116,9 +140,8 @@ print_core (struct obstack *oout, state *s)
|
|||||||
static void
|
static void
|
||||||
print_actions (state const *s, FILE *fgraph)
|
print_actions (state const *s, FILE *fgraph)
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
|
|
||||||
transitions const *trans = s->transitions;
|
transitions const *trans = s->transitions;
|
||||||
|
int i;
|
||||||
|
|
||||||
/* Display reductions. */
|
/* Display reductions. */
|
||||||
output_red (s, s->reductions, fgraph);
|
output_red (s, s->reductions, fgraph);
|
||||||
|
|||||||
@@ -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_dprec_set (int dprec, location loc);
|
||||||
void grammar_current_rule_merge_set (uniqstr name, location loc);
|
void grammar_current_rule_merge_set (uniqstr name, location loc);
|
||||||
void grammar_current_rule_symbol_append (symbol *sym, 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,
|
void grammar_current_rule_action_append (const char *action, location loc,
|
||||||
named_ref *named_ref, bool);
|
named_ref *nref, bool);
|
||||||
void reader (void);
|
void reader (void);
|
||||||
void free_merger_functions (void);
|
void free_merger_functions (void);
|
||||||
|
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ void gram_scanner_last_string_free (void);
|
|||||||
extern FILE *gram_out;
|
extern FILE *gram_out;
|
||||||
extern int gram_lineno;
|
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;
|
GRAM_LEX_DECL;
|
||||||
|
|
||||||
#endif /* !SCAN_GRAM_H_ */
|
#endif /* !SCAN_GRAM_H_ */
|
||||||
|
|||||||
@@ -465,10 +465,14 @@ m4_define([AT_BISON_CHECK_WARNINGS],
|
|||||||
[m4_null_if([$2], [AT_BISON_CHECK_WARNINGS_($@)])])])
|
[m4_null_if([$2], [AT_BISON_CHECK_WARNINGS_($@)])])])
|
||||||
|
|
||||||
m4_define([AT_BISON_CHECK_WARNINGS_],
|
m4_define([AT_BISON_CHECK_WARNINGS_],
|
||||||
[[# Defining POSIXLY_CORRECT causes bison to complain if options
|
[[# Defining POSIXLY_CORRECT causes bison to complain if options are
|
||||||
# are added after the grammar file name, so skip these checks
|
# added after the grammar file name, so skip these checks in that
|
||||||
# in that case.
|
# case.
|
||||||
if test -z "${POSIXLY_CORRECT+set}"; then
|
#
|
||||||
|
# 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[
|
]AT_SAVE_SPECIAL_FILES[
|
||||||
|
|
||||||
# To avoid expanding it repeatedly, store specified stdout.
|
# To avoid expanding it repeatedly, store specified stdout.
|
||||||
|
|||||||
365
tests/output.at
365
tests/output.at
@@ -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_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])
|
||||||
|
|||||||
@@ -431,7 +431,7 @@ int
|
|||||||
main (int argc, const char **argv)
|
main (int argc, const char **argv)
|
||||||
{
|
{
|
||||||
YYSTYPE yylval_init = get_args (argc, argv);
|
YYSTYPE yylval_init = get_args (argc, argv);
|
||||||
int status;
|
int status = 0;
|
||||||
int count;
|
int count;
|
||||||
]m4_bmatch([$2], [api.push-pull both],
|
]m4_bmatch([$2], [api.push-pull both],
|
||||||
[[ yypstate *ps = yypstate_new ();
|
[[ yypstate *ps = yypstate_new ();
|
||||||
|
|||||||
Reference in New Issue
Block a user