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 ?.? (????-??-??) [?]
|
||||
|
||||
** 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.
|
||||
|
||||
@@ -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
12
TODO
@@ -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
1
cfg.mk
@@ -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,
|
||||
|
||||
17
configure.ac
17
configure.ac
@@ -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
|
||||
|
||||
@@ -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
|
||||
])
|
||||
|
||||
|
||||
@@ -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]])])
|
||||
|
||||
|
||||
|
||||
@@ -55,7 +55,11 @@
|
||||
<xsl:call-template name="escape">
|
||||
<xsl:with-param name="subject" select="$filename"/>
|
||||
</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:text>} </xsl:text>
|
||||
</xsl:template>
|
||||
|
||||
@@ -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
|
||||
|
||||
112
doc/bison.texi
112
doc/bison.texi
@@ -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
|
||||
|
||||
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
|
||||
|
||||
## ----------------------------- ##
|
||||
## 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
2
gnulib
Submodule gnulib updated: dcf27bef48...6061979365
110
src/graphviz.c
110
src/graphviz.c
@@ -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,6 +96,47 @@ 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)
|
||||
{
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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_ */
|
||||
|
||||
@@ -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.
|
||||
|
||||
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_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)
|
||||
{
|
||||
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 ();
|
||||
|
||||
Reference in New Issue
Block a user