mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-08-09 10:45:15 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cf890692f1 | ||
|
|
6932023f4d | ||
|
|
fff17fe8fe | ||
|
|
5544615a59 | ||
|
|
346ba14f15 | ||
|
|
4d18195ebc | ||
|
|
dd3e7b3895 | ||
|
|
64a3b6546a | ||
|
|
bad07a7f66 | ||
|
|
88bd814bf1 | ||
|
|
4f9ae5de07 | ||
|
|
78f72a4516 | ||
|
|
c04693d651 | ||
|
|
12191911ba | ||
|
|
d7f27477f4 | ||
|
|
5bad15d7ea | ||
|
|
cd099edf2d | ||
|
|
1e12219775 | ||
|
|
d8c2af56c1 | ||
|
|
cc11bb037c | ||
|
|
121dd98508 | ||
|
|
2eddbd0ac4 | ||
|
|
ee86ea8839 | ||
|
|
a2ad33dca6 | ||
|
|
5b2b7b1ffb | ||
|
|
dc72b3566d | ||
|
|
c47e1174d4 | ||
|
|
093eeb27e9 | ||
|
|
dab23c4a21 | ||
|
|
38a169bec1 | ||
|
|
dc77d6500f | ||
|
|
8262c7dc22 | ||
|
|
44f28d10ee | ||
|
|
44ad466a32 | ||
|
|
a839f4c461 | ||
|
|
9a51c6a128 | ||
|
|
2608b0cf12 | ||
|
|
aa766d1560 | ||
|
|
a7ed13b25f |
+1
-1
@@ -1 +1 @@
|
||||
3.6.90
|
||||
3.6.91
|
||||
|
||||
@@ -1,5 +1,21 @@
|
||||
GNU Bison NEWS
|
||||
|
||||
* Noteworthy changes in release 3.6.92 (2020-07-19) [beta]
|
||||
|
||||
Changes in the display of counterexamples.
|
||||
|
||||
** Documentation
|
||||
|
||||
*** Examples
|
||||
|
||||
The bistromathic demonstrates %param and how to quote sources in the error
|
||||
messages:
|
||||
|
||||
> 123 456
|
||||
1.5-7: syntax error: expected end of file or + or - or * or / or ^ before number
|
||||
1 | 123 456
|
||||
| ^~~
|
||||
|
||||
* Noteworthy changes in release 3.6.91 (2020-07-09) [beta]
|
||||
|
||||
** Bug fixes
|
||||
@@ -30,9 +46,17 @@ GNU Bison NEWS
|
||||
strings in the grammar which can be parsed in two ways due to the
|
||||
conflict. For example:
|
||||
|
||||
Example exp '+' exp • '/' exp
|
||||
First derivation exp ::=[ exp ::=[ exp '+' exp • ] '/' exp ]
|
||||
Second derivation exp ::=[ exp '+' exp ::=[ exp • '/' exp ] ]
|
||||
Shift/reduce conflict on token "/":
|
||||
Example exp "+" exp • "/" exp
|
||||
Shift derivation
|
||||
exp
|
||||
↳ exp "+" exp
|
||||
↳ exp • "/" exp
|
||||
Example exp "+" exp • "/" exp
|
||||
Reduce derivation
|
||||
exp
|
||||
↳ exp "/" exp
|
||||
↳ exp "+" exp •
|
||||
|
||||
When Bison is installed with text styling enabled, the example is actually
|
||||
shown twice, with colors highlighting the ambiguity.
|
||||
@@ -42,15 +66,24 @@ GNU Bison NEWS
|
||||
bison cannot find an example that can be derived in two ways, it instead
|
||||
generates two examples that are the same up until the dot:
|
||||
|
||||
First example expr • ID $end
|
||||
First derivation $accept ::=[ s ::=[ a ::=[ expr • ] ID ] $end ]
|
||||
Second example expr • ID ',' ID $end
|
||||
Second derivation $accept ::=[ s ::=[ a ::=[ expr ::=[ expr • ID ',' ] ] ID ] $end ]
|
||||
First example expr • ID ',' ID $end
|
||||
Shift derivation
|
||||
$accept
|
||||
↳ s $end
|
||||
↳ a ID
|
||||
↳ expr
|
||||
↳ expr • ID ','
|
||||
Second example expr • ID $end
|
||||
Reduce derivation
|
||||
$accept
|
||||
↳ s $end
|
||||
↳ a ID
|
||||
↳ expr •
|
||||
|
||||
In these cases, the parser usually doesn't have enough lookahead to
|
||||
differentiate the two given examples.
|
||||
|
||||
The counterexamples are "focused": in two different ways. First, they do
|
||||
The counterexamples are "focused" in two different ways. First, they do
|
||||
not clutter the output with all the derivations from the start symbol,
|
||||
rather they start on the "conflicted nonterminal". They go straight to the
|
||||
point. Second, they don't "expand" nonterminal symbols uselessly.
|
||||
|
||||
+1
-1
@@ -444,7 +444,7 @@ added the `[-Wother]` part to all the warnings). Part of the update can be
|
||||
done with a crude tool: `build-aux/update-test`.
|
||||
|
||||
Once you ran the test suite, and therefore have many `testsuite.log` files,
|
||||
run, from the source tree:
|
||||
run `make update-tests`. Or, by hand, from the *source* tree:
|
||||
|
||||
$ ./build-aux/update-test $build/tests/testsuite.dir/*/testsuite.log
|
||||
|
||||
|
||||
@@ -45,6 +45,7 @@ Csaba Raduly [email protected]
|
||||
Dagobert Michelsen [email protected]
|
||||
Daniel Frużyński [email protected]
|
||||
Daniel Galloway [email protected]
|
||||
Daniela Becker [email protected]
|
||||
Daniel Hagerty [email protected]
|
||||
David Barto [email protected]
|
||||
David J. MacKenzie [email protected]
|
||||
|
||||
@@ -36,8 +36,6 @@ Unless we play it dumb (little structure).
|
||||
- How about not evaluating incomplete lines when the text is not finished
|
||||
(as shells do).
|
||||
|
||||
- Caret diagnostics
|
||||
|
||||
** Questions
|
||||
*** Java
|
||||
- Should i18n be part of the Lexer? Currently it's a static method of
|
||||
|
||||
@@ -49,6 +49,10 @@
|
||||
.cex-5 { color: orange; }
|
||||
.cex-6 { color: brown; }
|
||||
.cex-7 { color: mauve; }
|
||||
.cex-8 { color: #013220; } /* Dark green. */
|
||||
.cex-9 { color: #e75480; } /* Dark pink. */
|
||||
.cex-10 { color: cyan; }
|
||||
.cex-11 { color: orange; }
|
||||
|
||||
/* Cex: derivation rewriting steps. */
|
||||
.cex-step { font-style: italic; }
|
||||
|
||||
+14
-6
@@ -52,7 +52,7 @@
|
||||
<xsl:if test="nonterminal[@usefulness='useless-in-grammar']">
|
||||
<xsl:text>Nonterminals useless in grammar </xsl:text>
|
||||
<xsl:for-each select="nonterminal[@usefulness='useless-in-grammar']">
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:value-of select="@name"/>
|
||||
<xsl:text> </xsl:text>
|
||||
</xsl:for-each>
|
||||
@@ -65,7 +65,7 @@
|
||||
<xsl:text>Terminals unused in grammar </xsl:text>
|
||||
<xsl:for-each select="terminal[@usefulness='unused-in-grammar']">
|
||||
<xsl:sort select="@symbol-number" data-type="number"/>
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:value-of select="@name"/>
|
||||
<xsl:text> </xsl:text>
|
||||
</xsl:for-each>
|
||||
@@ -136,6 +136,7 @@
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="terminal">
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:value-of select="@name"/>
|
||||
<xsl:call-template name="line-wrap">
|
||||
<xsl:with-param name="first-line-length">
|
||||
@@ -148,6 +149,9 @@
|
||||
</xsl:with-param>
|
||||
<xsl:with-param name="line-length" select="66" />
|
||||
<xsl:with-param name="text">
|
||||
<xsl:if test="string-length(@type) != 0">
|
||||
<xsl:value-of select="concat(' <', @type, '>')"/>
|
||||
</xsl:if>
|
||||
<xsl:value-of select="concat(' (', @token-number, ')')"/>
|
||||
<xsl:for-each select="key('bison:ruleByRhs', @name)">
|
||||
<xsl:value-of select="concat(' ', @number)"/>
|
||||
@@ -157,14 +161,18 @@
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="nonterminal">
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:value-of select="@name"/>
|
||||
<xsl:if test="string-length(@type) != 0">
|
||||
<xsl:value-of select="concat(' <', @type, '>')"/>
|
||||
</xsl:if>
|
||||
<xsl:value-of select="concat(' (', @symbol-number, ')')"/>
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:variable name="output">
|
||||
<xsl:call-template name="line-wrap">
|
||||
<xsl:with-param name="line-length" select="66" />
|
||||
<xsl:with-param name="text">
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:if test="key('bison:ruleByLhs', @name)">
|
||||
<xsl:text>on@left:</xsl:text>
|
||||
<xsl:for-each select="key('bison:ruleByLhs', @name)">
|
||||
@@ -173,7 +181,7 @@
|
||||
</xsl:if>
|
||||
<xsl:if test="key('bison:ruleByRhs', @name)">
|
||||
<xsl:if test="key('bison:ruleByLhs', @name)">
|
||||
<xsl:text>, </xsl:text>
|
||||
<xsl:text> </xsl:text>
|
||||
</xsl:if>
|
||||
<xsl:text>on@right:</xsl:text>
|
||||
<xsl:for-each select="key('bison:ruleByRhs', @name)">
|
||||
@@ -348,11 +356,11 @@
|
||||
<!-- RHS -->
|
||||
<xsl:for-each select="rhs/*">
|
||||
<xsl:if test="position() = $dot + 1">
|
||||
<xsl:text> .</xsl:text>
|
||||
<xsl:text> •</xsl:text>
|
||||
</xsl:if>
|
||||
<xsl:apply-templates select="."/>
|
||||
<xsl:if test="position() = last() and position() = $dot">
|
||||
<xsl:text> .</xsl:text>
|
||||
<xsl:text> •</xsl:text>
|
||||
</xsl:if>
|
||||
</xsl:for-each>
|
||||
<xsl:if test="$lookaheads">
|
||||
|
||||
+72
-48
@@ -227,6 +227,7 @@
|
||||
<xsl:text> </xsl:text>
|
||||
<p class="pre">
|
||||
<xsl:call-template name="style-rule-set">
|
||||
<xsl:with-param name="anchor" select="'true'" />
|
||||
<xsl:with-param
|
||||
name="rule-set" select="rules/rule[@usefulness!='useless-in-grammar']"
|
||||
/>
|
||||
@@ -238,9 +239,11 @@
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template name="style-rule-set">
|
||||
<xsl:param name="anchor"/>
|
||||
<xsl:param name="rule-set"/>
|
||||
<xsl:for-each select="$rule-set">
|
||||
<xsl:apply-templates select=".">
|
||||
<xsl:with-param name="anchor" select="$anchor"/>
|
||||
<xsl:with-param name="pad" select="'3'"/>
|
||||
<xsl:with-param name="prev-lhs">
|
||||
<xsl:if test="position()>1">
|
||||
@@ -306,9 +309,10 @@
|
||||
<xsl:text> Terminals, with rules where they appear</xsl:text>
|
||||
</h3>
|
||||
<xsl:text> </xsl:text>
|
||||
<p class="pre">
|
||||
<ul>
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:apply-templates select="terminal"/>
|
||||
</p>
|
||||
</ul>
|
||||
<xsl:text> </xsl:text>
|
||||
</xsl:template>
|
||||
|
||||
@@ -318,41 +322,64 @@
|
||||
<xsl:text> Nonterminals, with rules where they appear</xsl:text>
|
||||
</h3>
|
||||
<xsl:text> </xsl:text>
|
||||
<p class="pre">
|
||||
<ul>
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:apply-templates
|
||||
select="nonterminal[@usefulness!='useless-in-grammar']"
|
||||
/>
|
||||
</p>
|
||||
</ul>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="terminal">
|
||||
<b><xsl:value-of select="@name"/></b>
|
||||
<xsl:value-of select="concat(' (', @token-number, ')')"/>
|
||||
<xsl:for-each select="key('bison:ruleByRhs', @name)">
|
||||
<xsl:apply-templates select="." mode="number-link"/>
|
||||
</xsl:for-each>
|
||||
<xsl:text> </xsl:text>
|
||||
<li>
|
||||
<b><xsl:value-of select="@name"/></b>
|
||||
<xsl:if test="string-length(@type) != 0">
|
||||
<xsl:value-of select="concat(' <', @type, '>')"/>
|
||||
</xsl:if>
|
||||
<xsl:value-of select="concat(' (', @token-number, ')')"/>
|
||||
<xsl:for-each select="key('bison:ruleByRhs', @name)">
|
||||
<xsl:apply-templates select="." mode="number-link"/>
|
||||
</xsl:for-each>
|
||||
</li>
|
||||
<xsl:text> </xsl:text>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="nonterminal">
|
||||
<b><xsl:value-of select="@name"/></b>
|
||||
<xsl:value-of select="concat(' (', @symbol-number, ')')"/>
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:if test="key('bison:ruleByLhs', @name)">
|
||||
<xsl:text>on left:</xsl:text>
|
||||
<xsl:for-each select="key('bison:ruleByLhs', @name)">
|
||||
<xsl:apply-templates select="." mode="number-link"/>
|
||||
</xsl:for-each>
|
||||
</xsl:if>
|
||||
<xsl:if test="key('bison:ruleByRhs', @name)">
|
||||
<xsl:if test="key('bison:ruleByLhs', @name)">
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:text> </xsl:text>
|
||||
<li>
|
||||
<b><xsl:value-of select="@name"/></b>
|
||||
<xsl:if test="string-length(@type) != 0">
|
||||
<xsl:value-of select="concat(' <', @type, '>')"/>
|
||||
</xsl:if>
|
||||
<xsl:text>on right:</xsl:text>
|
||||
<xsl:for-each select="key('bison:ruleByRhs', @name)">
|
||||
<xsl:apply-templates select="." mode="number-link"/>
|
||||
</xsl:for-each>
|
||||
</xsl:if>
|
||||
<xsl:value-of select="concat(' (', @symbol-number, ')')"/>
|
||||
<xsl:text> </xsl:text>
|
||||
<ul>
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:if test="key('bison:ruleByLhs', @name)">
|
||||
<xsl:text> </xsl:text>
|
||||
<li>
|
||||
<xsl:text>on left:</xsl:text>
|
||||
<xsl:for-each select="key('bison:ruleByLhs', @name)">
|
||||
<xsl:apply-templates select="." mode="number-link"/>
|
||||
</xsl:for-each>
|
||||
</li>
|
||||
<xsl:text> </xsl:text>
|
||||
</xsl:if>
|
||||
<xsl:if test="key('bison:ruleByRhs', @name)">
|
||||
<xsl:text> </xsl:text>
|
||||
<li>
|
||||
<xsl:text>on right:</xsl:text>
|
||||
<xsl:for-each select="key('bison:ruleByRhs', @name)">
|
||||
<xsl:apply-templates select="." mode="number-link"/>
|
||||
</xsl:for-each>
|
||||
</li>
|
||||
<xsl:text> </xsl:text>
|
||||
</xsl:if>
|
||||
<xsl:text> </xsl:text>
|
||||
</ul>
|
||||
<xsl:text> </xsl:text>
|
||||
</li>
|
||||
<xsl:text> </xsl:text>
|
||||
</xsl:template>
|
||||
|
||||
@@ -385,7 +412,7 @@
|
||||
<xsl:value-of select="concat('state_', @number)"/>
|
||||
</xsl:attribute>
|
||||
</a>
|
||||
<xsl:text>state </xsl:text>
|
||||
<xsl:text>State </xsl:text>
|
||||
<xsl:value-of select="@number"/>
|
||||
</h3>
|
||||
<xsl:text> </xsl:text>
|
||||
@@ -464,7 +491,12 @@
|
||||
</xsl:apply-templates>
|
||||
</xsl:template>
|
||||
|
||||
<!--
|
||||
anchor = 'true': define as an <a> anchor.
|
||||
itemset = 'true': show the items.
|
||||
-->
|
||||
<xsl:template match="rule">
|
||||
<xsl:param name="anchor"/>
|
||||
<xsl:param name="itemset"/>
|
||||
<xsl:param name="pad"/>
|
||||
<xsl:param name="prev-lhs"/>
|
||||
@@ -475,17 +507,21 @@
|
||||
<xsl:text> </xsl:text>
|
||||
</xsl:if>
|
||||
|
||||
<xsl:if test="$itemset != 'true'">
|
||||
<a>
|
||||
<xsl:attribute name="name">
|
||||
<xsl:value-of select="concat('rule_', @number)"/>
|
||||
</xsl:attribute>
|
||||
</a>
|
||||
</xsl:if>
|
||||
<xsl:text> </xsl:text>
|
||||
|
||||
<xsl:choose>
|
||||
<xsl:when test="$itemset = 'true'">
|
||||
<xsl:when test="$anchor = 'true'">
|
||||
<a>
|
||||
<xsl:attribute name="name">
|
||||
<xsl:value-of select="concat('rule_', @number)"/>
|
||||
</xsl:attribute>
|
||||
<xsl:call-template name="lpad">
|
||||
<xsl:with-param name="str" select="string(@number)"/>
|
||||
<xsl:with-param name="pad" select="number($pad)"/>
|
||||
</xsl:call-template>
|
||||
</a>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<a>
|
||||
<xsl:attribute name="href">
|
||||
<xsl:value-of select="concat('#rule_', @number)"/>
|
||||
@@ -495,25 +531,13 @@
|
||||
<xsl:with-param name="pad" select="number($pad)"/>
|
||||
</xsl:call-template>
|
||||
</a>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:call-template name="lpad">
|
||||
<xsl:with-param name="str" select="string(@number)"/>
|
||||
<xsl:with-param name="pad" select="number($pad)"/>
|
||||
</xsl:call-template>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
<xsl:text> </xsl:text>
|
||||
|
||||
<!-- LHS -->
|
||||
<xsl:choose>
|
||||
<xsl:when test="$itemset != 'true' and $prev-lhs = lhs[text()]">
|
||||
<xsl:call-template name="lpad">
|
||||
<xsl:with-param name="str" select="'|'"/>
|
||||
<xsl:with-param name="pad" select="number(string-length(lhs[text()])) + 2"/>
|
||||
</xsl:call-template>
|
||||
</xsl:when>
|
||||
<xsl:when test="$itemset = 'true' and $prev-lhs = lhs[text()]">
|
||||
<xsl:when test="$prev-lhs = lhs[text()]">
|
||||
<xsl:call-template name="lpad">
|
||||
<xsl:with-param name="str" select="'|'"/>
|
||||
<xsl:with-param name="pad" select="number(string-length(lhs[text()])) + 2"/>
|
||||
|
||||
+35
-67
@@ -263,7 +263,6 @@ Writing GLR Parsers
|
||||
* Merging GLR Parses:: Using GLR parsers to resolve ambiguities.
|
||||
* GLR Semantic Actions:: Considerations for semantic values and deferred actions.
|
||||
* Semantic Predicates:: Controlling a parse with arbitrary computations.
|
||||
* Compiler Requirements for GLR:: GLR parsers require a modern C compiler.
|
||||
|
||||
Examples
|
||||
|
||||
@@ -943,7 +942,6 @@ on the resulting values to produce an arbitrary merged result.
|
||||
* Merging GLR Parses:: Using GLR parsers to resolve ambiguities.
|
||||
* GLR Semantic Actions:: Considerations for semantic values and deferred actions.
|
||||
* Semantic Predicates:: Controlling a parse with arbitrary computations.
|
||||
* Compiler Requirements for GLR:: GLR parsers require a modern C compiler.
|
||||
@end menu
|
||||
|
||||
@node Simple GLR Parsers
|
||||
@@ -1372,14 +1370,14 @@ widget:
|
||||
@noindent
|
||||
is one way to allow the same parser to handle two different syntaxes for
|
||||
widgets. The clause preceded by @code{%?} is treated like an ordinary
|
||||
action, except that its text is treated as an expression and is always
|
||||
midrule action, except that its text is handled as an expression and is always
|
||||
evaluated immediately (even when in nondeterministic mode). If the
|
||||
expression yields 0 (false), the clause is treated as a syntax error,
|
||||
which, in a nondeterministic parser, causes the stack in which it is reduced
|
||||
to die. In a deterministic parser, it acts like YYERROR.
|
||||
to die. In a deterministic parser, it acts like @code{YYERROR}.
|
||||
|
||||
As the example shows, predicates otherwise look like semantic actions, and
|
||||
therefore you must be take them into account when determining the numbers
|
||||
therefore you must take them into account when determining the numbers
|
||||
to use for denoting the semantic values of right-hand side symbols.
|
||||
Predicate actions, however, have no defined value, and may not be given
|
||||
labels.
|
||||
@@ -1393,7 +1391,7 @@ widget:
|
||||
@{ if (!new_syntax) YYERROR; @}
|
||||
"widget" id new_args @{ $$ = f($3, $4); @}
|
||||
| @{ if (new_syntax) YYERROR; @}
|
||||
"widget" id old_args @{ $$ = f($3, $4); @}
|
||||
"widget" id old_args @{ $$ = f($3, $4); @}
|
||||
;
|
||||
@end example
|
||||
|
||||
@@ -1411,36 +1409,6 @@ reports an error.
|
||||
Finally, be careful in writing predicates: deferred actions have not been
|
||||
evaluated, so that using them in a predicate will have undefined effects.
|
||||
|
||||
@node Compiler Requirements for GLR
|
||||
@subsection Considerations when Compiling GLR Parsers
|
||||
@cindex @code{inline}
|
||||
@cindex GLR parsers and @code{inline}
|
||||
|
||||
The GLR parsers require a compiler for ISO C89 or
|
||||
later. In addition, they use the @code{inline} keyword, which is not
|
||||
C89, but is C99 and is a common extension in pre-C99 compilers. It is
|
||||
up to the user of these parsers to handle
|
||||
portability issues. For instance, if using Autoconf and the Autoconf
|
||||
macro @code{AC_C_INLINE}, a mere
|
||||
|
||||
@example
|
||||
%@{
|
||||
#include <config.h>
|
||||
%@}
|
||||
@end example
|
||||
|
||||
@noindent
|
||||
will suffice. Otherwise, we suggest
|
||||
|
||||
@example
|
||||
%@{
|
||||
#if (__STDC_VERSION__ < 199901 && ! defined __GNUC__ \
|
||||
&& ! defined inline)
|
||||
# define inline
|
||||
#endif
|
||||
%@}
|
||||
@end example
|
||||
|
||||
@node Locations
|
||||
@section Locations
|
||||
@cindex location
|
||||
@@ -9936,10 +9904,10 @@ output is actually in color)}:
|
||||
@example
|
||||
Shift/reduce conflict on token "else":
|
||||
@group
|
||||
Example @yellow{"if" expr "then"} @blue{"if" expr "then" stmt} @red{•} @yellow{"else" stmt}
|
||||
First derivation @yellow{if_stmt ::=[ "if" expr "then"} @green{stmt ::=[} @blue{if_stmt ::=[ "if" expr "then" stmt} @red{•} @blue{]} @green{]} @yellow{"else" stmt ]}
|
||||
Example @yellow{"if" expr "then"} @blue{"if" expr "then" stmt} @red{•} @blue{"else" stmt}
|
||||
Second derivation @yellow{if_stmt ::=[ "if" expr "then"} @green{stmt ::=[} @blue{if_stmt ::=[ "if" expr "then" stmt} @red{•} @blue{"else" stmt ]} @green{]} @yellow{]}
|
||||
Shift derivation @yellow{if_stmt @arrow{} [ "if" expr "then"} @green{stmt @arrow{} [} @blue{if_stmt @arrow{} [ "if" expr "then" stmt} @red{•} @blue{"else" stmt ]} @green{]} @yellow{]}
|
||||
Example @yellow{"if" expr "then"} @blue{"if" expr "then" stmt} @red{•} @yellow{"else" stmt}
|
||||
Reduce derivation @yellow{if_stmt @arrow{} [ "if" expr "then"} @green{stmt @arrow{} [} @blue{if_stmt @arrow{} [ "if" expr "then" stmt} @red{•} @blue{]} @green{]} @yellow{"else" stmt ]}
|
||||
@end group
|
||||
@end example
|
||||
@end ifhtml
|
||||
@@ -9947,14 +9915,14 @@ Shift/reduce conflict on token "else":
|
||||
@smallexample
|
||||
Shift/reduce conflict on token "else":
|
||||
@group
|
||||
Example
|
||||
@yellow{"if" expr "then"} @blue{"if" expr "then" stmt} @red{•} @yellow{"else" stmt}
|
||||
First derivation
|
||||
@yellow{if_stmt ::=[ "if" expr "then"} @green{stmt ::=[} @blue{if_stmt ::=[ "if" expr "then" stmt} @red{•} @blue{]} @green{]} @yellow{"else" stmt ]}
|
||||
Example
|
||||
@yellow{"if" expr "then"} @blue{"if" expr "then" stmt} @red{•} @blue{"else" stmt}
|
||||
Second derivation
|
||||
@yellow{if_stmt ::=[ "if" expr "then"} @green{stmt ::=[} @blue{if_stmt ::=[ "if" expr "then" stmt} @red{•} @blue{"else" stmt ]} @green{]} @yellow{]}
|
||||
Shift derivation
|
||||
@yellow{if_stmt @arrow{} [ "if" expr "then"} @green{stmt @arrow{} [} @blue{if_stmt @arrow{} [ "if" expr "then" stmt} @red{•} @blue{"else" stmt ]} @green{]} @yellow{]}
|
||||
Example
|
||||
@yellow{"if" expr "then"} @blue{"if" expr "then" stmt} @red{•} @yellow{"else" stmt}
|
||||
Reduce derivation
|
||||
@yellow{if_stmt @arrow{} [ "if" expr "then"} @green{stmt @arrow{} [} @blue{if_stmt @arrow{} [ "if" expr "then" stmt} @red{•} @blue{]} @green{]} @yellow{"else" stmt ]}
|
||||
@end group
|
||||
@end smallexample
|
||||
@end ifnothtml
|
||||
@@ -9987,22 +9955,22 @@ $ @kbd{bison -Wcex sequence.y}
|
||||
sequence.y: @dwarning{warning}: 1 shift/reduce conflict [@dwarning{-Wconflicts-sr}]
|
||||
sequence.y: @dwarning{warning}: 2 reduce/reduce conflicts [@dwarning{-Wconflicts-rr}]
|
||||
Shift/reduce conflict on token "word":
|
||||
Example @red{•} @yellow{"word"}
|
||||
First derivation @yellow{sequence ::=[} @green{sequence ::=[} @red{•} @green{]} @yellow{"word" ]}
|
||||
Example @red{•} @green{"word"}
|
||||
Second derivation @yellow{sequence ::=[} @green{maybeword ::=[} @red{•} @green{"word" ]} @yellow{]}
|
||||
Shift derivation @yellow{sequence @arrow{} [} @green{maybeword @arrow{} [} @red{•} @green{"word" ]} @yellow{]}
|
||||
Example @red{•} @yellow{"word"}
|
||||
Reduce derivation @yellow{sequence @arrow{} [} @green{sequence @arrow{} [} @red{•} @green{]} @yellow{"word" ]}
|
||||
|
||||
Reduce/reduce conflict on tokens $end, "word":
|
||||
Example @red{•}
|
||||
First derivation @yellow{sequence ::=[} @red{•} @yellow{]}
|
||||
First derivation @yellow{sequence @arrow{} [} @red{•} @yellow{]}
|
||||
Example @red{•}
|
||||
Second derivation @yellow{sequence ::=[} @green{maybeword ::=[} @red{•} @green{]} @yellow{]}
|
||||
Second derivation @yellow{sequence @arrow{} [} @green{maybeword @arrow{} [} @red{•} @green{]} @yellow{]}
|
||||
|
||||
Shift/reduce conflict on token "word":
|
||||
Example @red{•} @yellow{"word"}
|
||||
First derivation @yellow{sequence ::=[} @green{sequence ::=[} @blue{maybeword ::=[} @red{•} @blue{]} @green{]} @yellow{"word" ]}
|
||||
Example @red{•} @green{"word"}
|
||||
Second derivation @yellow{sequence ::=[} @green{maybeword ::=[} @red{•} @green{"word" ]} @yellow{]}
|
||||
Shift derivation @yellow{sequence @arrow{} [} @green{maybeword @arrow{} [} @red{•} @green{"word" ]} @yellow{]}
|
||||
Example @red{•} @yellow{"word"}
|
||||
Reduce derivation @yellow{sequence @arrow{} [} @green{sequence @arrow{} [} @blue{maybeword @arrow{} [} @red{•} @blue{]} @green{]} @yellow{"word" ]}
|
||||
|
||||
sequence.y:8.3-45: @dwarning{warning}: rule useless in parser due to conflicts [@dwarning{-Wother}]
|
||||
8 | @dwarning{%empty @{ printf ("empty maybeword\n"); @}}
|
||||
@@ -10033,10 +10001,10 @@ expr: %empty | expr ID ','
|
||||
|
||||
@smallexample
|
||||
Shift/reduce conflict on token ID:
|
||||
First example @blue{expr} @red{•} @green{ID} @yellow{$end}
|
||||
First derivation @yellow{$accept ::=[} @green{s ::=[} @blue{a ::=[ expr} @red{•} @blue{]} @green{ID ]} @yellow{$end ]}
|
||||
Second example @purple{expr} @red{•} @purple{ID ','} @green{ID} @yellow{$end}
|
||||
Second derivation @yellow{$accept ::=[} @green{s ::=[} @blue{a ::=[} @purple{expr ::=[ expr} @red{•} @purple{ID ',' ]} @blue{]} @green{ID ]} @yellow{$end ]}
|
||||
First example @purple{expr} @red{•} @purple{ID ','} @green{ID} @yellow{$end}
|
||||
Shift derivation @yellow{$accept @arrow{} [} @green{s @arrow{} [} @blue{a @arrow{} [} @purple{expr @arrow{} [ expr} @red{•} @purple{ID ',' ]} @blue{]} @green{ID ]} @yellow{$end ]}
|
||||
Second example @blue{expr} @red{•} @green{ID} @yellow{$end}
|
||||
Reduce derivation @yellow{$accept @arrow{} [} @green{s @arrow{} [} @blue{a @arrow{} [ expr} @red{•} @blue{]} @green{ID ]} @yellow{$end ]}
|
||||
@end smallexample
|
||||
|
||||
This conflict is caused by the parser not having enough information to know
|
||||
@@ -10432,10 +10400,10 @@ counterexamples within the report, augmented with the corresponding items
|
||||
Shift/reduce conflict on token '/':
|
||||
1 exp: exp '+' exp •
|
||||
4 exp: exp • '/' exp
|
||||
Example @green{exp '+' exp} @red{•} @yellow{'/' exp}
|
||||
First derivation @yellow{exp ::=[} @green{exp ::=[ exp '+' exp} @red{•} @green{]} @yellow{'/' exp ]}
|
||||
Example @yellow{exp '+'} @green{exp} @red{•} @green{'/' exp}
|
||||
Second derivation @yellow{exp ::=[ exp '+'} @green{exp ::=[ exp} @red{•} @green{'/' exp ]} @yellow{]}
|
||||
Shift derivation @yellow{exp @arrow{} [ exp '+'} @green{exp @arrow{} [ exp} @red{•} @green{'/' exp ]} @yellow{]}
|
||||
Example @green{exp '+' exp} @red{•} @yellow{'/' exp}
|
||||
Reduce derivation @yellow{exp @arrow{} [} @green{exp @arrow{} [ exp '+' exp} @red{•} @green{]} @yellow{'/' exp ]}
|
||||
@end example
|
||||
|
||||
This shows two separate derivations in the grammar for the same @code{exp}:
|
||||
@@ -14824,13 +14792,13 @@ Bison. See the file @file{ABOUT-NLS} for more information.
|
||||
I can't build Bison because my C compiler is too old.
|
||||
@end quotation
|
||||
|
||||
Except for GLR parsers (@pxref{Compiler Requirements for GLR}), the C
|
||||
code that Bison generates requires only C89 or later. However, Bison
|
||||
itself requires common C99 features such as declarations after
|
||||
statements. Bison's @code{configure} script attempts to enable C99 (or
|
||||
later) support on compilers that default to pre-C99. If your compiler
|
||||
lacks these C99 features entirely, GCC may well be a better choice; or
|
||||
you can try upgrading to your compiler's latest version.
|
||||
Except for GLR parsers (which require C99), the C code that Bison generates
|
||||
requires only C89 or later. However, Bison itself requires common C99
|
||||
features such as declarations after statements. Bison's @code{configure}
|
||||
script attempts to enable C99 (or later) support on compilers that default
|
||||
to pre-C99. If your compiler lacks these C99 features entirely, GCC may
|
||||
well be a better choice; or you can try upgrading to your compiler's latest
|
||||
version.
|
||||
|
||||
@node Where can I find help?
|
||||
@section Where can I find help?
|
||||
|
||||
+10
-1
@@ -53,7 +53,9 @@ push-parser model.
|
||||
This example demonstrates best practices when using Bison.
|
||||
- Its hand-written scanner tracks locations.
|
||||
- Its interface is pure.
|
||||
- It uses the `error` token to get error recovery.
|
||||
- It uses %params to pass user information to the parser and scanner.
|
||||
- Its scanner uses the `error` token to signal lexical errors and enter
|
||||
error recovery.
|
||||
- Its interface is "incremental", well suited for interaction: it uses the
|
||||
push-parser API to feed the parser with the incoming tokens.
|
||||
- It features an interactive command line with completion based on the
|
||||
@@ -62,6 +64,13 @@ This example demonstrates best practices when using Bison.
|
||||
messages.
|
||||
- It uses a custom syntax error with location, lookahead correction and
|
||||
token internationalization.
|
||||
- Error messages quote the source with squiggles that underline the error:
|
||||
```
|
||||
> 123 456
|
||||
1.5-7: syntax error: expected end of file or + or - or * or / or ^ before number
|
||||
1 | 123 456
|
||||
| ^~~
|
||||
```
|
||||
- It supports debug traces with semantic values.
|
||||
- It uses named references instead of the traditional $1, $2, etc.
|
||||
|
||||
|
||||
@@ -2,7 +2,9 @@
|
||||
This example demonstrates best practices when using Bison.
|
||||
- Its hand-written scanner tracks locations.
|
||||
- Its interface is pure.
|
||||
- It uses the `error` token to get error recovery.
|
||||
- It uses %params to pass user information to the parser and scanner.
|
||||
- Its scanner uses the `error` token to signal lexical errors and enter
|
||||
error recovery.
|
||||
- Its interface is "incremental", well suited for interaction: it uses the
|
||||
push-parser API to feed the parser with the incoming tokens.
|
||||
- It features an interactive command line with completion based on the
|
||||
@@ -11,6 +13,13 @@ This example demonstrates best practices when using Bison.
|
||||
messages.
|
||||
- It uses a custom syntax error with location, lookahead correction and
|
||||
token internationalization.
|
||||
- Error messages quote the source with squiggles that underline the error:
|
||||
```
|
||||
> 123 456
|
||||
1.5-7: syntax error: expected end of file or + or - or * or / or ^ before number
|
||||
1 | 123 456
|
||||
| ^~~
|
||||
```
|
||||
- It supports debug traces with semantic values.
|
||||
- It uses named references instead of the traditional $1, $2, etc.
|
||||
|
||||
|
||||
@@ -101,14 +101,28 @@ cat >input <<EOF
|
||||
EOF
|
||||
run 0 '> *
|
||||
> ''
|
||||
err: 1.1: syntax error: expected end of file or - or ( or exit or number or function etc., before *'
|
||||
err: 1.1: syntax error: expected end of file or - or ( or exit or number or function etc., before *
|
||||
err: 1 | *
|
||||
err: | ^'
|
||||
|
||||
# Underline long errors.
|
||||
cat >input <<EOF
|
||||
123 123456
|
||||
EOF
|
||||
run 0 '> 123 123456
|
||||
> ''
|
||||
err: 1.5-10: syntax error: expected end of file or + or - or * or / or ^ before number
|
||||
err: 1 | 123 123456
|
||||
err: | ^~~~~~'
|
||||
|
||||
cat >input <<EOF
|
||||
1 + 2 * * 3
|
||||
EOF
|
||||
run 0 '> 1 + 2 * * 3
|
||||
> ''
|
||||
err: 1.9: syntax error: expected - or ( or number or function or variable before *'
|
||||
err: 1.9: syntax error: expected - or ( or number or function or variable before *
|
||||
err: 1 | 1 + 2 * * 3
|
||||
err: | ^'
|
||||
|
||||
cat >input <<EOF
|
||||
1 / 0
|
||||
@@ -132,8 +146,14 @@ run 0 '> ((1 ++ 2) ** 3)
|
||||
1332
|
||||
> ''
|
||||
err: 1.6: syntax error: expected - or ( or number or function or variable before +
|
||||
err: 1 | ((1 ++ 2) ** 3)
|
||||
err: | ^
|
||||
err: 2.5: syntax error: expected - or ( or number or function or variable before +
|
||||
err: 2.16: syntax error: expected - or ( or number or function or variable before *'
|
||||
err: 2 | (1 ++ 2) + (3 ** 4)
|
||||
err: | ^
|
||||
err: 2.16: syntax error: expected - or ( or number or function or variable before *
|
||||
err: 2 | (1 ++ 2) + (3 ** 4)
|
||||
err: | ^'
|
||||
|
||||
# The rule "( error )" should work even if there are no tokens between "(" and ")".
|
||||
cat >input <<EOF
|
||||
@@ -142,7 +162,9 @@ EOF
|
||||
run 0 '> ()
|
||||
666
|
||||
> ''
|
||||
err: 1.2: syntax error: expected - or ( or number or function or variable before )'
|
||||
err: 1.2: syntax error: expected - or ( or number or function or variable before )
|
||||
err: 1 | ()
|
||||
err: | ^'
|
||||
|
||||
|
||||
cat >input <<EOF
|
||||
@@ -189,6 +211,8 @@ err: LAC: checking lookahead function: S5
|
||||
err: LAC: checking lookahead variable: S6
|
||||
err: LAC: checking lookahead NEG: Err
|
||||
err: 1.2: syntax error: expected - or ( or number or function or variable before +
|
||||
err: 1 | (+_)
|
||||
err: | ^
|
||||
err: LAC: initial context discarded due to error recovery
|
||||
err: Shifting token error (1.2: )
|
||||
err: Entering state 10
|
||||
@@ -286,7 +310,9 @@ run 0 '> (1+
|
||||
( - atan cos exp ln number sin sqrt
|
||||
> (1+
|
||||
> ''
|
||||
err: 1.4: syntax error: expected - or ( or number or function or variable before end of file'
|
||||
err: 1.4: syntax error: expected - or ( or number or function or variable before end of file
|
||||
err: 1 | (1+
|
||||
err: | ^'
|
||||
|
||||
# Check the completion of a word.
|
||||
sed -e 's/\\t/ /g' >input <<EOF
|
||||
@@ -294,7 +320,9 @@ sed -e 's/\\t/ /g' >input <<EOF
|
||||
EOF
|
||||
run 0 '> (atan ( ''
|
||||
> ''
|
||||
err: 1.9: syntax error: expected - or ( or number or function or variable before end of file'
|
||||
err: 1.9: syntax error: expected - or ( or number or function or variable before end of file
|
||||
err: 1 | (atan ( ''
|
||||
err: | ^'
|
||||
|
||||
# Check the completion at the very beginning.
|
||||
sed -e 's/\\t/ /g' >input <<EOF
|
||||
@@ -313,8 +341,9 @@ sed -e 's/\\t/ /g' >input <<EOF
|
||||
EOF
|
||||
run -n 0 '> 1++ ''
|
||||
> ''
|
||||
err: 1.1: syntax error: expected - or ( or number or function or variable before +
|
||||
err: 1.3: syntax error: expected - or ( or number or function or variable before +
|
||||
err: 1 | 1++ ''
|
||||
err: | ^
|
||||
'
|
||||
|
||||
# And even when the error was recovered from.
|
||||
@@ -323,8 +352,10 @@ sed -e 's/\\t/ /g' >input <<EOF
|
||||
EOF
|
||||
run -n 0 '> (1++2) + 3 + ''
|
||||
> ''
|
||||
err: 1.1: syntax error: expected - or ( or number or function or variable before +
|
||||
err: 1.1: syntax error: expected - or ( or number or function or variable before +
|
||||
err: 1.4: syntax error: expected - or ( or number or function or variable before +
|
||||
err: 1 | (1++2) + 3 + ''
|
||||
err: | ^
|
||||
err: 1.15: syntax error: expected - or ( or number or function or variable before end of file
|
||||
err: 1 | (1++2) + 3 + ''
|
||||
err: | ^
|
||||
'
|
||||
|
||||
@@ -65,6 +65,15 @@
|
||||
|
||||
symrec *putsym (char const *name, int sym_type);
|
||||
symrec *getsym (char const *name);
|
||||
|
||||
// Exchanging information with the parser.
|
||||
typedef struct
|
||||
{
|
||||
// Whether to not emit error messages.
|
||||
int silent;
|
||||
// The current input line.
|
||||
const char *line;
|
||||
} user_context;
|
||||
}
|
||||
|
||||
// Emitted in the header file, after the definition of YYSTYPE.
|
||||
@@ -74,9 +83,13 @@
|
||||
# define __attribute__(Spec) /* empty */
|
||||
# endif
|
||||
# endif
|
||||
int yylex (const char **line, YYSTYPE *yylval, YYLTYPE *yylloc);
|
||||
void yyerror (YYLTYPE *loc, char const *format, ...)
|
||||
__attribute__ ((__format__ (__printf__, 2, 3)));
|
||||
|
||||
yytoken_kind_t
|
||||
yylex (const char **line, YYSTYPE *yylval, YYLTYPE *yylloc,
|
||||
const user_context *uctx);
|
||||
void yyerror (YYLTYPE *loc, const user_context *uctx,
|
||||
char const *format, ...)
|
||||
__attribute__ ((__format__ (__printf__, 3, 4)));
|
||||
}
|
||||
|
||||
// Emitted in the implementation file.
|
||||
@@ -116,6 +129,9 @@
|
||||
// Generate the parser description file (calc.output).
|
||||
%verbose
|
||||
|
||||
// User information exchanged with the parser and scanner.
|
||||
%param {const user_context *uctx}
|
||||
|
||||
// Generate YYSTYPE from the types assigned to symbols.
|
||||
%define api.value.type union
|
||||
%token
|
||||
@@ -171,7 +187,7 @@ exp:
|
||||
{
|
||||
if ($r == 0)
|
||||
{
|
||||
yyerror (&@$, "error: division by zero");
|
||||
yyerror (&@$, uctx, "error: division by zero");
|
||||
YYERROR;
|
||||
}
|
||||
else
|
||||
@@ -257,8 +273,9 @@ symbol_count (void)
|
||||
| Scanner. |
|
||||
`----------*/
|
||||
|
||||
int
|
||||
yylex (const char **line, YYSTYPE *yylval, YYLTYPE *yylloc)
|
||||
yytoken_kind_t
|
||||
yylex (const char **line, YYSTYPE *yylval, YYLTYPE *yylloc,
|
||||
const user_context *uctx)
|
||||
{
|
||||
int c;
|
||||
|
||||
@@ -328,7 +345,7 @@ yylex (const char **line, YYSTYPE *yylval, YYLTYPE *yylloc)
|
||||
|
||||
// Stray characters.
|
||||
default:
|
||||
yyerror (yylloc, "syntax error: invalid character: %c", c);
|
||||
yyerror (yylloc, uctx, "syntax error: invalid character: %c", c);
|
||||
return TOK_YYerror;
|
||||
}
|
||||
}
|
||||
@@ -366,8 +383,11 @@ error_format_string (int argc)
|
||||
|
||||
|
||||
int
|
||||
yyreport_syntax_error (const yypcontext_t *ctx)
|
||||
yyreport_syntax_error (const yypcontext_t *ctx, const user_context *uctx)
|
||||
{
|
||||
if (uctx->silent)
|
||||
return 0;
|
||||
|
||||
enum { ARGS_MAX = 6 };
|
||||
yysymbol_kind_t arg[ARGS_MAX];
|
||||
int argsize = yypcontext_expected_tokens (ctx, arg, ARGS_MAX);
|
||||
@@ -378,11 +398,12 @@ yyreport_syntax_error (const yypcontext_t *ctx)
|
||||
argsize = ARGS_MAX;
|
||||
const char *format = error_format_string (1 + argsize + too_many_expected_tokens);
|
||||
|
||||
const YYLTYPE *loc = yypcontext_location (ctx);
|
||||
while (*format)
|
||||
// %@: location.
|
||||
if (format[0] == '%' && format[1] == '@')
|
||||
{
|
||||
YY_LOCATION_PRINT (stderr, *yypcontext_location (ctx));
|
||||
YY_LOCATION_PRINT (stderr, *loc);
|
||||
format += 2;
|
||||
}
|
||||
// %u: unexpected token.
|
||||
@@ -407,13 +428,25 @@ yyreport_syntax_error (const yypcontext_t *ctx)
|
||||
++format;
|
||||
}
|
||||
fputc ('\n', stderr);
|
||||
|
||||
// Quote the source line.
|
||||
{
|
||||
fprintf (stderr, "%5d | %s\n", loc->first_line, uctx->line);
|
||||
fprintf (stderr, "%5s | %*s", "", loc->first_column, "^");
|
||||
for (int i = loc->last_column - loc->first_column - 1; 0 < i; --i)
|
||||
putc ('~', stderr);
|
||||
putc ('\n', stderr);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// Called by yyparse on error.
|
||||
void yyerror (YYLTYPE *loc, char const *format, ...)
|
||||
void yyerror (YYLTYPE *loc, const user_context *uctx, char const *format, ...)
|
||||
{
|
||||
if (uctx->silent)
|
||||
return;
|
||||
|
||||
YY_LOCATION_PRINT (stderr, *loc);
|
||||
fputs (": ", stderr);
|
||||
va_list args;
|
||||
@@ -449,11 +482,13 @@ xstrndup (const char *string, size_t n)
|
||||
static int
|
||||
process_line (YYLTYPE *lloc, const char *line)
|
||||
{
|
||||
user_context uctx = {0, line};
|
||||
yypstate *ps = yypstate_new ();
|
||||
int status = 0;
|
||||
do {
|
||||
YYSTYPE lval;
|
||||
status = yypush_parse (ps, yylex (&line, &lval, lloc), &lval, lloc);
|
||||
yytoken_kind_t token = yylex (&line, &lval, lloc, &uctx);
|
||||
status = yypush_parse (ps, token, &lval, lloc, &uctx);
|
||||
} while (status == YYPUSH_MORE);
|
||||
yypstate_delete (ps);
|
||||
lloc->last_line++;
|
||||
@@ -468,18 +503,19 @@ expected_tokens (const char *input,
|
||||
int *tokens, int ntokens)
|
||||
{
|
||||
YYDPRINTF ((stderr, "expected_tokens (\"%s\")", input));
|
||||
user_context uctx = {1, input};
|
||||
|
||||
// Parse the current state of the line.
|
||||
yypstate *ps = yypstate_new ();
|
||||
int status = 0;
|
||||
YYLTYPE lloc = { 1, 1, 1, 1 };
|
||||
do {
|
||||
YYLTYPE lloc = { 1, 1, 1, 1 };
|
||||
YYSTYPE lval;
|
||||
int token = yylex (&input, &lval, &lloc);
|
||||
yytoken_kind_t token = yylex (&input, &lval, &lloc, &uctx);
|
||||
// Don't let the parse know when we reach the end of input.
|
||||
if (!token)
|
||||
if (token == TOK_YYEOF)
|
||||
break;
|
||||
status = yypush_parse (ps, token, &lval, &lloc);
|
||||
status = yypush_parse (ps, token, &lval, &lloc, &uctx);
|
||||
} while (status == YYPUSH_MORE);
|
||||
|
||||
int res = 0;
|
||||
|
||||
+1
-1
Submodule gnulib updated: 12c89745e3...cf6d5db127
@@ -313,6 +313,7 @@
|
||||
/stdlib.h
|
||||
/stdlib.in.h
|
||||
/stpcpy.c
|
||||
/stpncpy.c
|
||||
/strchrnul.c
|
||||
/strchrnul.valgrind
|
||||
/strdup.c
|
||||
|
||||
@@ -175,6 +175,7 @@
|
||||
/stdio_h.m4
|
||||
/stdlib_h.m4
|
||||
/stpcpy.m4
|
||||
/stpncpy.m4
|
||||
/strchrnul.m4
|
||||
/strdup.m4
|
||||
/strerror.m4
|
||||
|
||||
@@ -169,10 +169,10 @@ AnnotationList__compute_conflicted_tokens (bitset shift_tokens,
|
||||
bitset_copy (tokens, shift_tokens);
|
||||
for (int i = 0; i < reds->num; ++i)
|
||||
{
|
||||
bitset_and (conflicted_tokens_rule, tokens, reds->lookahead_tokens[i]);
|
||||
bitset_and (conflicted_tokens_rule, tokens, reds->lookaheads[i]);
|
||||
bitset_or (conflicted_tokens,
|
||||
conflicted_tokens, conflicted_tokens_rule);
|
||||
bitset_or (tokens, tokens, reds->lookahead_tokens[i]);
|
||||
bitset_or (tokens, tokens, reds->lookaheads[i]);
|
||||
/* Check that rules are sorted on rule number or the next step in
|
||||
AnnotationList__compute_from_inadequacies will misbehave. */
|
||||
aver (i == 0 || reds->rules[i-1] < reds->rules[i]);
|
||||
@@ -401,7 +401,7 @@ AnnotationList__compute_from_inadequacies (
|
||||
struct obstack *annotations_obstackp,
|
||||
InadequacyListNodeCount *inadequacy_list_node_count)
|
||||
{
|
||||
/* Return an empty list if s->lookahead_tokens = NULL. */
|
||||
/* Return an empty list if s->lookaheads = NULL. */
|
||||
if (s->consistent)
|
||||
return;
|
||||
|
||||
@@ -422,7 +422,7 @@ AnnotationList__compute_from_inadequacies (
|
||||
/* Allocate the annotation node. */
|
||||
{
|
||||
for (int rule_i = 0; rule_i < s->reductions->num; ++rule_i)
|
||||
if (bitset_test (s->reductions->lookahead_tokens[rule_i],
|
||||
if (bitset_test (s->reductions->lookaheads[rule_i],
|
||||
conflicted_token))
|
||||
++contribution_count;
|
||||
if (bitset_test (shift_tokens, conflicted_token))
|
||||
@@ -445,7 +445,7 @@ AnnotationList__compute_from_inadequacies (
|
||||
for (int rule_i = 0; rule_i < s->reductions->num; ++rule_i)
|
||||
{
|
||||
rule *the_rule = s->reductions->rules[rule_i];
|
||||
if (bitset_test (s->reductions->lookahead_tokens[rule_i],
|
||||
if (bitset_test (s->reductions->lookaheads[rule_i],
|
||||
conflicted_token))
|
||||
{
|
||||
bitset_set (actions, rule_i);
|
||||
|
||||
+17
-17
@@ -250,9 +250,9 @@ flush_shift (state *s, int token)
|
||||
`--------------------------------------------------------------------*/
|
||||
|
||||
static void
|
||||
flush_reduce (bitset lookahead_tokens, int token)
|
||||
flush_reduce (bitset lookaheads, int token)
|
||||
{
|
||||
bitset_reset (lookahead_tokens, token);
|
||||
bitset_reset (lookaheads, token);
|
||||
}
|
||||
|
||||
|
||||
@@ -275,10 +275,10 @@ resolve_sr_conflict (state *s, int ruleno, symbol **errors, int *nerrs)
|
||||
/* Find the rule to reduce by to get precedence of reduction. */
|
||||
rule *redrule = reds->rules[ruleno];
|
||||
int redprec = redrule->prec->prec;
|
||||
bitset lookahead_tokens = reds->lookahead_tokens[ruleno];
|
||||
bitset lookaheads = reds->lookaheads[ruleno];
|
||||
|
||||
for (symbol_number i = 0; i < ntokens; ++i)
|
||||
if (bitset_test (lookahead_tokens, i)
|
||||
if (bitset_test (lookaheads, i)
|
||||
&& bitset_test (lookahead_set, i)
|
||||
&& symbols[i]->content->prec)
|
||||
{
|
||||
@@ -295,7 +295,7 @@ resolve_sr_conflict (state *s, int ruleno, symbol **errors, int *nerrs)
|
||||
{
|
||||
register_precedence (i, redrule->prec->number);
|
||||
log_resolution (redrule, i, shift_resolution);
|
||||
flush_reduce (lookahead_tokens, i);
|
||||
flush_reduce (lookaheads, i);
|
||||
}
|
||||
else
|
||||
/* Matching precedence levels.
|
||||
@@ -316,7 +316,7 @@ resolve_sr_conflict (state *s, int ruleno, symbol **errors, int *nerrs)
|
||||
case right_assoc:
|
||||
register_assoc (i, redrule->prec->number);
|
||||
log_resolution (redrule, i, right_resolution);
|
||||
flush_reduce (lookahead_tokens, i);
|
||||
flush_reduce (lookaheads, i);
|
||||
break;
|
||||
|
||||
case left_assoc:
|
||||
@@ -329,7 +329,7 @@ resolve_sr_conflict (state *s, int ruleno, symbol **errors, int *nerrs)
|
||||
register_assoc (i, redrule->prec->number);
|
||||
log_resolution (redrule, i, nonassoc_resolution);
|
||||
flush_shift (s, i);
|
||||
flush_reduce (lookahead_tokens, i);
|
||||
flush_reduce (lookaheads, i);
|
||||
/* Record an explicit error for this token. */
|
||||
errors[(*nerrs)++] = symbols[i];
|
||||
break;
|
||||
@@ -369,7 +369,7 @@ set_conflicts (state *s, symbol **errors)
|
||||
for (int i = 0; i < reds->num; ++i)
|
||||
if (reds->rules[i]->prec
|
||||
&& reds->rules[i]->prec->prec
|
||||
&& !bitset_disjoint_p (reds->lookahead_tokens[i], lookahead_set))
|
||||
&& !bitset_disjoint_p (reds->lookaheads[i], lookahead_set))
|
||||
resolve_sr_conflict (s, i, errors, &nerrs);
|
||||
|
||||
if (nerrs)
|
||||
@@ -385,13 +385,13 @@ set_conflicts (state *s, symbol **errors)
|
||||
/* Loop over all rules which require lookahead in this state. Check
|
||||
for conflicts not resolved above.
|
||||
|
||||
reds->lookahead_tokens can be NULL if the LR type is LR(0). */
|
||||
if (reds->lookahead_tokens)
|
||||
reds->lookaheads can be NULL if the LR type is LR(0). */
|
||||
if (reds->lookaheads)
|
||||
for (int i = 0; i < reds->num; ++i)
|
||||
{
|
||||
if (!bitset_disjoint_p (reds->lookahead_tokens[i], lookahead_set))
|
||||
if (!bitset_disjoint_p (reds->lookaheads[i], lookahead_set))
|
||||
conflicts[s->number] = true;
|
||||
bitset_or (lookahead_set, lookahead_set, reds->lookahead_tokens[i]);
|
||||
bitset_or (lookahead_set, lookahead_set, reds->lookaheads[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -460,7 +460,7 @@ count_state_sr_conflicts (const state *s)
|
||||
}
|
||||
|
||||
for (int i = 0; i < reds->num; ++i)
|
||||
bitset_or (lookahead_set, lookahead_set, reds->lookahead_tokens[i]);
|
||||
bitset_or (lookahead_set, lookahead_set, reds->lookaheads[i]);
|
||||
|
||||
bitset_and (lookahead_set, lookahead_set, shift_set);
|
||||
|
||||
@@ -499,7 +499,7 @@ count_state_rr_conflicts (const state *s)
|
||||
{
|
||||
int count = 0;
|
||||
for (int j = 0; j < reds->num; ++j)
|
||||
count += bitset_test (reds->lookahead_tokens[j], i);
|
||||
count += bitset_test (reds->lookaheads[j], i);
|
||||
if (2 <= count)
|
||||
res += count-1;
|
||||
}
|
||||
@@ -534,7 +534,7 @@ count_rule_state_sr_conflicts (rule *r, state *s)
|
||||
for (int i = 0; i < reds->num; ++i)
|
||||
if (reds->rules[i] == r)
|
||||
{
|
||||
bitset lookaheads = reds->lookahead_tokens[i];
|
||||
bitset lookaheads = reds->lookaheads[i];
|
||||
int j;
|
||||
FOR_EACH_SHIFT (trans, j)
|
||||
res += bitset_test (lookaheads, TRANSITION_SYMBOL (trans, j));
|
||||
@@ -576,8 +576,8 @@ count_rule_state_rr_conflicts (rule *r, state *s)
|
||||
if (reds->rules[j] != r)
|
||||
{
|
||||
bitset_and (lookaheads,
|
||||
reds->lookahead_tokens[i],
|
||||
reds->lookahead_tokens[j]);
|
||||
reds->lookaheads[i],
|
||||
reds->lookaheads[j]);
|
||||
res += bitset_count (lookaheads);
|
||||
}
|
||||
bitset_free (lookaheads);
|
||||
|
||||
+102
-82
@@ -76,17 +76,29 @@ typedef struct
|
||||
{
|
||||
derivation *d1;
|
||||
derivation *d2;
|
||||
bool shift_reduce;
|
||||
bool unifying;
|
||||
bool timeout;
|
||||
} counterexample;
|
||||
|
||||
static counterexample *
|
||||
new_counterexample (derivation *d1, derivation *d2,
|
||||
bool shift_reduce,
|
||||
bool u, bool t)
|
||||
{
|
||||
counterexample *res = xmalloc (sizeof (counterexample));
|
||||
res->d1 = d1;
|
||||
res->d2 = d2;
|
||||
counterexample *res = xmalloc (sizeof *res);
|
||||
res->shift_reduce = shift_reduce;
|
||||
if (shift_reduce)
|
||||
{
|
||||
// Display the shift first.
|
||||
res->d1 = d2;
|
||||
res->d2 = d1;
|
||||
}
|
||||
else
|
||||
{
|
||||
res->d1 = d1;
|
||||
res->d2 = d2;
|
||||
}
|
||||
res->unifying = u;
|
||||
res->timeout = t;
|
||||
return res;
|
||||
@@ -101,13 +113,14 @@ free_counterexample (counterexample *cex)
|
||||
}
|
||||
|
||||
static void
|
||||
print_counterexample (counterexample *cex, FILE *out, const char *prefix)
|
||||
print_counterexample (const counterexample *cex, FILE *out, const char *prefix)
|
||||
{
|
||||
const bool flat = getenv ("YYFLAT");
|
||||
fprintf (out, " %s%-20s ",
|
||||
prefix, cex->unifying ? _("Example") : _("First example"));
|
||||
derivation_print_leaves (cex->d1, out, prefix);
|
||||
fprintf (out, " %s%-20s ",
|
||||
prefix, _("First derivation"));
|
||||
fprintf (out, flat ? " %s%-20s " : " %s%s",
|
||||
prefix, cex->shift_reduce ? _("Shift derivation") : _("First derivation"));
|
||||
derivation_print (cex->d1, out, prefix);
|
||||
|
||||
// If we output to the terminal (via stderr) and we have color
|
||||
@@ -119,8 +132,8 @@ print_counterexample (counterexample *cex, FILE *out, const char *prefix)
|
||||
prefix, cex->unifying ? _("Example") : _("Second example"));
|
||||
derivation_print_leaves (cex->d2, out, prefix);
|
||||
}
|
||||
fprintf (out, " %s%-20s ",
|
||||
prefix, _("Second derivation"));
|
||||
fprintf (out, flat ? " %s%-20s " : " %s%s",
|
||||
prefix, cex->shift_reduce ? _("Reduce derivation") : _("Second derivation"));
|
||||
derivation_print (cex->d2, out, prefix);
|
||||
|
||||
fputc ('\n', out);
|
||||
@@ -144,7 +157,7 @@ typedef struct si_bfs_node
|
||||
static si_bfs_node *
|
||||
si_bfs_new (state_item_number si, si_bfs_node *parent)
|
||||
{
|
||||
si_bfs_node *res = xcalloc (1, sizeof (si_bfs_node));
|
||||
si_bfs_node *res = xcalloc (1, sizeof *res);
|
||||
res->si = si;
|
||||
res->parent = parent;
|
||||
res->reference_count = 1;
|
||||
@@ -175,6 +188,8 @@ si_bfs_free (si_bfs_node *n)
|
||||
}
|
||||
}
|
||||
|
||||
typedef gl_list_t si_bfs_node_list;
|
||||
|
||||
/**
|
||||
* start is a state_item such that conflict_sym is an element of FIRSTS of the
|
||||
* nonterminal after the dot in start. Because of this, we should be able to
|
||||
@@ -188,15 +203,16 @@ expand_to_conflict (state_item_number start, symbol_number conflict_sym)
|
||||
{
|
||||
si_bfs_node *init = si_bfs_new (start, NULL);
|
||||
|
||||
gl_list_t queue = gl_list_create (GL_LINKED_LIST, NULL, NULL,
|
||||
(gl_listelement_dispose_fn) si_bfs_free,
|
||||
true, 1, (const void **) &init);
|
||||
si_bfs_node_list queue
|
||||
= gl_list_create (GL_LINKED_LIST, NULL, NULL,
|
||||
(gl_listelement_dispose_fn) si_bfs_free,
|
||||
true, 1, (const void **) &init);
|
||||
si_bfs_node *node = NULL;
|
||||
// breadth-first search for a path of productions to the conflict symbol
|
||||
while (gl_list_size (queue) > 0)
|
||||
{
|
||||
node = (si_bfs_node *) gl_list_get_at (queue, 0);
|
||||
state_item *silast = state_items + node->si;
|
||||
state_item *silast = &state_items[node->si];
|
||||
symbol_number sym = item_number_as_symbol_number (*silast->item);
|
||||
if (sym == conflict_sym)
|
||||
break;
|
||||
@@ -238,7 +254,7 @@ expand_to_conflict (state_item_number start, symbol_number conflict_sym)
|
||||
|
||||
for (si_bfs_node *n = node; n != NULL; n = n->parent)
|
||||
{
|
||||
state_item *si = state_items + n->si;
|
||||
state_item *si = &state_items[n->si];
|
||||
item_number *pos = si->item;
|
||||
if (SI_PRODUCTION (si))
|
||||
{
|
||||
@@ -274,7 +290,7 @@ expand_to_conflict (state_item_number start, symbol_number conflict_sym)
|
||||
*/
|
||||
static derivation *
|
||||
complete_diverging_example (symbol_number conflict_sym,
|
||||
gl_list_t path, derivation_list derivs)
|
||||
state_item_list path, derivation_list derivs)
|
||||
{
|
||||
// The idea is to transfer each pending symbol on the productions
|
||||
// associated with the given StateItems to the resulting derivation.
|
||||
@@ -395,15 +411,15 @@ complete_diverging_example (symbol_number conflict_sym,
|
||||
/* Iterate backwards through the shifts of the path in the reduce
|
||||
conflict, and find a path of shifts from the shift conflict that
|
||||
goes through the same states. */
|
||||
static gl_list_t
|
||||
nonunifying_shift_path (gl_list_t reduce_path, state_item *shift_conflict)
|
||||
static state_item_list
|
||||
nonunifying_shift_path (state_item_list reduce_path, state_item *shift_conflict)
|
||||
{
|
||||
gl_list_node_t tmp = gl_list_add_last (reduce_path, NULL);
|
||||
gl_list_node_t next_node = gl_list_previous_node (reduce_path, tmp);
|
||||
gl_list_node_t node = gl_list_previous_node (reduce_path, next_node);
|
||||
gl_list_remove_node (reduce_path, tmp);
|
||||
state_item *si = shift_conflict;
|
||||
gl_list_t result =
|
||||
state_item_list result =
|
||||
gl_list_create_empty (GL_LINKED_LIST, NULL, NULL, NULL, true);
|
||||
// FIXME: bool paths_merged;
|
||||
for (; node != NULL; next_node = node,
|
||||
@@ -425,10 +441,10 @@ nonunifying_shift_path (gl_list_t reduce_path, state_item *shift_conflict)
|
||||
|
||||
// bfs to find a shift to the right state
|
||||
si_bfs_node *init = si_bfs_new (si - state_items, NULL);
|
||||
gl_list_t queue =
|
||||
gl_list_create (GL_LINKED_LIST, NULL, NULL,
|
||||
(gl_listelement_dispose_fn) si_bfs_free,
|
||||
true, 1, (const void **) &init);
|
||||
si_bfs_node_list queue
|
||||
= gl_list_create (GL_LINKED_LIST, NULL, NULL,
|
||||
(gl_listelement_dispose_fn) si_bfs_free,
|
||||
true, 1, (const void **) &init);
|
||||
si_bfs_node *sis = NULL;
|
||||
state_item *prevsi = NULL;
|
||||
while (gl_list_size (queue) > 0)
|
||||
@@ -438,7 +454,7 @@ nonunifying_shift_path (gl_list_t reduce_path, state_item *shift_conflict)
|
||||
if (sis->si == 0)
|
||||
break;
|
||||
|
||||
state_item *search_si = state_items + sis->si;
|
||||
state_item *search_si = &state_items[sis->si];
|
||||
// if the current state-item is a production item,
|
||||
// its reverse production items get added to the queue.
|
||||
// Otherwise, look for a reverse transition to the target state.
|
||||
@@ -447,7 +463,7 @@ nonunifying_shift_path (gl_list_t reduce_path, state_item *shift_conflict)
|
||||
state_item_number sin;
|
||||
BITSET_FOR_EACH (biter, rsi, sin, 0)
|
||||
{
|
||||
prevsi = state_items + sin;
|
||||
prevsi = &state_items[sin];
|
||||
if (SI_TRANSITION (search_si))
|
||||
{
|
||||
if (prevsi->state == refsi->state)
|
||||
@@ -465,9 +481,9 @@ nonunifying_shift_path (gl_list_t reduce_path, state_item *shift_conflict)
|
||||
// prepend path to shift we found
|
||||
if (sis)
|
||||
{
|
||||
gl_list_node_t ln = gl_list_add_first (result, state_items + sis->si);
|
||||
gl_list_node_t ln = gl_list_add_first (result, &state_items[sis->si]);
|
||||
for (si_bfs_node *n = sis->parent; n; n = n->parent)
|
||||
ln = gl_list_add_after (result, ln, state_items + n->si);
|
||||
ln = gl_list_add_after (result, ln, &state_items[n->si]);
|
||||
|
||||
}
|
||||
si = prevsi;
|
||||
@@ -493,17 +509,17 @@ nonunifying_shift_path (gl_list_t reduce_path, state_item *shift_conflict)
|
||||
static counterexample *
|
||||
example_from_path (bool shift_reduce,
|
||||
state_item_number itm2,
|
||||
gl_list_t shortest_path, symbol_number next_sym)
|
||||
state_item_list shortest_path, symbol_number next_sym)
|
||||
{
|
||||
derivation *deriv1 =
|
||||
complete_diverging_example (next_sym, shortest_path, NULL);
|
||||
gl_list_t path_2
|
||||
state_item_list path_2
|
||||
= shift_reduce
|
||||
? nonunifying_shift_path (shortest_path, &state_items [itm2])
|
||||
: shortest_path_from_start (itm2, next_sym);
|
||||
derivation *deriv2 = complete_diverging_example (next_sym, path_2, NULL);
|
||||
gl_list_free (path_2);
|
||||
return new_counterexample (deriv1, deriv2, false, true);
|
||||
return new_counterexample (deriv1, deriv2, shift_reduce, false, true);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -525,7 +541,7 @@ typedef struct
|
||||
static search_state *
|
||||
initial_search_state (state_item *conflict1, state_item *conflict2)
|
||||
{
|
||||
search_state *res = xmalloc (sizeof (search_state));
|
||||
search_state *res = xmalloc (sizeof *res);
|
||||
res->states[0] = new_parse_state (conflict1);
|
||||
res->states[1] = new_parse_state (conflict2);
|
||||
parse_state_retain (res->states[0]);
|
||||
@@ -537,7 +553,7 @@ initial_search_state (state_item *conflict1, state_item *conflict2)
|
||||
static search_state *
|
||||
new_search_state (parse_state *ps1, parse_state *ps2, int complexity)
|
||||
{
|
||||
search_state *res = xmalloc (sizeof (search_state));
|
||||
search_state *res = xmalloc (sizeof *res);
|
||||
res->states[0] = ps1;
|
||||
res->states[1] = ps2;
|
||||
parse_state_retain (res->states[0]);
|
||||
@@ -549,8 +565,8 @@ new_search_state (parse_state *ps1, parse_state *ps2, int complexity)
|
||||
static search_state *
|
||||
copy_search_state (search_state *parent)
|
||||
{
|
||||
search_state *res = xmalloc (sizeof (search_state));
|
||||
memcpy (res, parent, sizeof (search_state));
|
||||
search_state *res = xmalloc (sizeof *res);
|
||||
*res = *parent;
|
||||
parse_state_retain (res->states[0]);
|
||||
parse_state_retain (res->states[1]);
|
||||
return res;
|
||||
@@ -583,6 +599,8 @@ search_state_print (search_state *ss)
|
||||
putc ('\n', stderr);
|
||||
}
|
||||
|
||||
typedef gl_list_t search_state_list;
|
||||
|
||||
static inline bool
|
||||
search_state_list_next (gl_list_iterator_t *it, search_state **ss)
|
||||
{
|
||||
@@ -614,18 +632,20 @@ ss_set_parse_state (search_state *ss, int idx, parse_state *ps)
|
||||
*/
|
||||
static counterexample *
|
||||
complete_diverging_examples (search_state *ss,
|
||||
symbol_number next_sym)
|
||||
symbol_number next_sym,
|
||||
bool shift_reduce)
|
||||
{
|
||||
derivation *new_derivs[2];
|
||||
for (int i = 0; i < 2; ++i)
|
||||
{
|
||||
gl_list_t sitems;
|
||||
state_item_list sitems;
|
||||
derivation_list derivs;
|
||||
parse_state_lists (ss->states[i], &sitems, &derivs);
|
||||
new_derivs[i] = complete_diverging_example (next_sym, sitems, derivs);
|
||||
gl_list_free (sitems);
|
||||
}
|
||||
return new_counterexample (new_derivs[0], new_derivs[1], false, true);
|
||||
return new_counterexample (new_derivs[0], new_derivs[1],
|
||||
shift_reduce, false, true);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -635,7 +655,7 @@ complete_diverging_examples (search_state *ss,
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
gl_list_t states;
|
||||
search_state_list states;
|
||||
int complexity;
|
||||
} search_state_bundle;
|
||||
|
||||
@@ -664,6 +684,8 @@ ssb_equals (const search_state_bundle *s1, const search_state_bundle *s2)
|
||||
return s1->complexity == s2->complexity;
|
||||
}
|
||||
|
||||
typedef gl_list_t ssb_list;
|
||||
|
||||
static size_t
|
||||
visited_hasher (const search_state *ss, size_t max)
|
||||
{
|
||||
@@ -679,7 +701,7 @@ visited_comparator (const search_state *ss1, const search_state *ss2)
|
||||
}
|
||||
|
||||
/* Priority queue for search states with minimal complexity. */
|
||||
static gl_list_t ssb_queue;
|
||||
static ssb_list ssb_queue;
|
||||
static Hash_table *visited;
|
||||
/* The set of parser states on the shortest lookahead-sensitive path. */
|
||||
static bitset scp_set = NULL;
|
||||
@@ -702,7 +724,7 @@ ssb_append (search_state *ss)
|
||||
parse_state_free_contents_early (ss->states[1]);
|
||||
parse_state_retain (ss->states[0]);
|
||||
parse_state_retain (ss->states[1]);
|
||||
search_state_bundle *ssb = xmalloc (sizeof (search_state_bundle));
|
||||
search_state_bundle *ssb = xmalloc (sizeof *ssb);
|
||||
ssb->complexity = ss->complexity;
|
||||
gl_list_node_t n = gl_list_search (ssb_queue, ssb);
|
||||
if (!n)
|
||||
@@ -756,12 +778,12 @@ reduction_cost (const parse_state *ps)
|
||||
return SHIFT_COST * shifts + PRODUCTION_COST * productions;
|
||||
}
|
||||
|
||||
static gl_list_t
|
||||
static search_state_list
|
||||
reduction_step (search_state *ss, const item_number *conflict_item,
|
||||
int parser_state, int rule_len)
|
||||
{
|
||||
(void) conflict_item; // FIXME: Unused
|
||||
gl_list_t result =
|
||||
search_state_list result =
|
||||
gl_list_create_empty (GL_LINKED_LIST, NULL, NULL, NULL, 1);
|
||||
|
||||
parse_state *ps = ss->states[parser_state];
|
||||
@@ -897,7 +919,7 @@ search_state_prepend (search_state *ss, symbol_number sym, bitset guide)
|
||||
* the same prefix up to the dot.
|
||||
*/
|
||||
static bool
|
||||
has_common_prefix (const item_number *itm1, const item_number *itm2)
|
||||
have_common_prefix (const item_number *itm1, const item_number *itm2)
|
||||
{
|
||||
int i = 0;
|
||||
for (; !item_number_is_rule_number (itm1[i]); ++i)
|
||||
@@ -988,14 +1010,14 @@ generate_next_states (search_state *ss, state_item *conflict1,
|
||||
// prepended further, reduce.
|
||||
if (ready1 && ready2)
|
||||
{
|
||||
gl_list_t reduced1 = reduction_step (ss, conflict1->item, 0, len1);
|
||||
search_state_list reduced1 = reduction_step (ss, conflict1->item, 0, len1);
|
||||
gl_list_add_last (reduced1, ss);
|
||||
search_state *red1 = NULL;
|
||||
for (gl_list_iterator_t iter = gl_list_iterator (reduced1);
|
||||
search_state_list_next (&iter, &red1);
|
||||
)
|
||||
{
|
||||
gl_list_t reduced2 =
|
||||
search_state_list reduced2 =
|
||||
reduction_step (red1, conflict2->item, 1, len2);
|
||||
search_state *red2 = NULL;
|
||||
for (gl_list_iterator_t iter2 = gl_list_iterator (reduced2);
|
||||
@@ -1011,7 +1033,7 @@ generate_next_states (search_state *ss, state_item *conflict1,
|
||||
}
|
||||
else if (ready1)
|
||||
{
|
||||
gl_list_t reduced1 = reduction_step (ss, conflict1->item, 0, len1);
|
||||
search_state_list reduced1 = reduction_step (ss, conflict1->item, 0, len1);
|
||||
search_state *red1 = NULL;
|
||||
for (gl_list_iterator_t iter = gl_list_iterator (reduced1);
|
||||
search_state_list_next (&iter, &red1);
|
||||
@@ -1021,7 +1043,7 @@ generate_next_states (search_state *ss, state_item *conflict1,
|
||||
}
|
||||
else if (ready2)
|
||||
{
|
||||
gl_list_t reduced2 = reduction_step (ss, conflict2->item, 1, len2);
|
||||
search_state_list reduced2 = reduction_step (ss, conflict2->item, 1, len2);
|
||||
search_state *red2 = NULL;
|
||||
for (gl_list_iterator_t iter2 = gl_list_iterator (reduced2);
|
||||
search_state_list_next (&iter2, &red2);
|
||||
@@ -1055,10 +1077,10 @@ static counterexample *
|
||||
unifying_example (state_item_number itm1,
|
||||
state_item_number itm2,
|
||||
bool shift_reduce,
|
||||
gl_list_t reduce_path, symbol_number next_sym)
|
||||
state_item_list reduce_path, symbol_number next_sym)
|
||||
{
|
||||
state_item *conflict1 = state_items + itm1;
|
||||
state_item *conflict2 = state_items + itm2;
|
||||
state_item *conflict1 = &state_items[itm1];
|
||||
state_item *conflict2 = &state_items[itm2];
|
||||
search_state *initial = initial_search_state (conflict1, conflict2);
|
||||
ssb_queue = gl_list_create_empty (GL_RBTREEHASH_LIST,
|
||||
(gl_listelement_equals_fn) ssb_equals,
|
||||
@@ -1094,7 +1116,7 @@ unifying_example (state_item_number itm1,
|
||||
const state_item *si1src = parse_state_head (ps1);
|
||||
const state_item *si2src = parse_state_head (ps2);
|
||||
if (item_rule (si1src->item)->lhs == item_rule (si2src->item)->lhs
|
||||
&& has_common_prefix (si1src->item, si2src->item))
|
||||
&& have_common_prefix (si1src->item, si2src->item))
|
||||
{
|
||||
// Stage 4: both paths share a prefix
|
||||
derivation *d1 = parse_state_derivation (ps1);
|
||||
@@ -1104,7 +1126,7 @@ unifying_example (state_item_number itm1,
|
||||
{
|
||||
// Once we have two derivations for the same symbol,
|
||||
// we've found a unifying counterexample.
|
||||
cex = new_counterexample (d1, d2, true, false);
|
||||
cex = new_counterexample (d1, d2, shift_reduce, true, false);
|
||||
derivation_retain (d1);
|
||||
derivation_retain (d2);
|
||||
goto cex_search_end;
|
||||
@@ -1142,7 +1164,7 @@ cex_search_end:;
|
||||
// If a search state from Stage 3 is available, use it
|
||||
// to construct a more compact nonunifying counterexample.
|
||||
if (stage3result)
|
||||
cex = complete_diverging_examples (stage3result, next_sym);
|
||||
cex = complete_diverging_examples (stage3result, next_sym, shift_reduce);
|
||||
// Otherwise, construct a nonunifying counterexample that
|
||||
// begins from the start state using the shortest
|
||||
// lookahead-sensitive path to the reduce item.
|
||||
@@ -1190,7 +1212,7 @@ counterexample_report (state_item_number itm1, state_item_number itm2,
|
||||
{
|
||||
// Compute the shortest lookahead-sensitive path and associated sets of
|
||||
// parser states.
|
||||
gl_list_t shortest_path = shortest_path_from_start (itm1, next_sym);
|
||||
state_item_list shortest_path = shortest_path_from_start (itm1, next_sym);
|
||||
bool reduce_prod_reached = false;
|
||||
const rule *reduce_rule = item_rule (state_items[itm1].item);
|
||||
|
||||
@@ -1219,6 +1241,8 @@ counterexample_report (state_item_number itm1, state_item_number itm2,
|
||||
free_counterexample (cex);
|
||||
}
|
||||
|
||||
|
||||
// ITM1 denotes a shift, ITM2 a reduce.
|
||||
static void
|
||||
counterexample_report_shift_reduce (state_item_number itm1, state_item_number itm2,
|
||||
symbol_number next_sym,
|
||||
@@ -1226,7 +1250,8 @@ counterexample_report_shift_reduce (state_item_number itm1, state_item_number it
|
||||
{
|
||||
fputs (prefix, out);
|
||||
fprintf (out, _("Shift/reduce conflict on token %s:\n"), symbols[next_sym]->tag);
|
||||
if (*prefix)
|
||||
// In the report, print the items.
|
||||
if (*prefix || trace_flag & trace_cex)
|
||||
{
|
||||
print_state_item (&state_items[itm1], out, prefix);
|
||||
print_state_item (&state_items[itm2], out, prefix);
|
||||
@@ -1254,7 +1279,8 @@ counterexample_report_reduce_reduce (state_item_number itm1, state_item_number i
|
||||
}
|
||||
fputs (_(":\n"), out);
|
||||
}
|
||||
if (*prefix)
|
||||
// In the report, print the items.
|
||||
if (*prefix || trace_flag & trace_cex)
|
||||
{
|
||||
print_state_item (&state_items[itm1], out, prefix);
|
||||
print_state_item (&state_items[itm2], out, prefix);
|
||||
@@ -1265,7 +1291,7 @@ counterexample_report_reduce_reduce (state_item_number itm1, state_item_number i
|
||||
static state_item_number
|
||||
find_state_item_number (const rule *r, state_number sn)
|
||||
{
|
||||
for (int i = state_item_map[sn]; i < state_item_map[sn + 1]; ++i)
|
||||
for (state_item_number i = state_item_map[sn]; i < state_item_map[sn + 1]; ++i)
|
||||
if (!SI_DISABLED (i)
|
||||
&& item_number_as_rule_number (*state_items[i].item) == r->number)
|
||||
return i;
|
||||
@@ -1277,41 +1303,35 @@ counterexample_report_state (const state *s, FILE *out, const char *prefix)
|
||||
{
|
||||
const state_number sn = s->number;
|
||||
const reductions *reds = s->reductions;
|
||||
bitset lookaheads = bitset_create (ntokens, BITSET_FIXED);
|
||||
for (int i = 0; i < reds->num; ++i)
|
||||
{
|
||||
const rule *r1 = reds->rules[i];
|
||||
const state_item_number c1 = find_state_item_number (r1, sn);
|
||||
for (int j = state_item_map[sn]; j < state_item_map[sn + 1]; ++j)
|
||||
if (!SI_DISABLED (j))
|
||||
for (state_item_number c2 = state_item_map[sn]; c2 < state_item_map[sn + 1]; ++c2)
|
||||
if (!SI_DISABLED (c2))
|
||||
{
|
||||
state_item *si = state_items + j;
|
||||
item_number conf = *si->item;
|
||||
item_number conf = *state_items[c2].item;
|
||||
if (item_number_is_symbol_number (conf)
|
||||
&& bitset_test (reds->lookahead_tokens[i], conf))
|
||||
counterexample_report_shift_reduce (c1, j, conf, out, prefix);
|
||||
&& bitset_test (reds->lookaheads[i], conf))
|
||||
counterexample_report_shift_reduce (c1, c2, conf, out, prefix);
|
||||
}
|
||||
for (int j = i+1; j < reds->num; ++j)
|
||||
{
|
||||
bitset conf = bitset_create (ntokens, BITSET_FIXED);
|
||||
bitset_intersection (conf,
|
||||
reds->lookahead_tokens[i],
|
||||
reds->lookahead_tokens[j]);
|
||||
if (!bitset_empty_p (conf))
|
||||
{
|
||||
const rule *r2 = reds->rules[j];
|
||||
for (int k = state_item_map[sn]; k < state_item_map[sn + 1]; ++k)
|
||||
if (!SI_DISABLED (k))
|
||||
{
|
||||
state_item *si = state_items + k;
|
||||
const rule *r = item_rule (si->item);
|
||||
if (r == r2)
|
||||
{
|
||||
counterexample_report_reduce_reduce (c1, k, conf, out, prefix);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
bitset_free (conf);
|
||||
const rule *r2 = reds->rules[j];
|
||||
// Conflicts: common lookaheads.
|
||||
bitset_intersection (lookaheads,
|
||||
reds->lookaheads[i],
|
||||
reds->lookaheads[j]);
|
||||
if (!bitset_empty_p (lookaheads))
|
||||
for (state_item_number c2 = state_item_map[sn]; c2 < state_item_map[sn + 1]; ++c2)
|
||||
if (!SI_DISABLED (c2)
|
||||
&& item_rule (state_items[c2].item) == r2)
|
||||
{
|
||||
counterexample_report_reduce_reduce (c1, c2, lookaheads, out, prefix);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
bitset_free (lookaheads);
|
||||
}
|
||||
|
||||
@@ -20,11 +20,17 @@
|
||||
#ifndef COUNTEREXAMPLE_H
|
||||
# define COUNTEREXAMPLE_H
|
||||
|
||||
# include "state-item.h"
|
||||
# include "state.h"
|
||||
|
||||
// Init/deinit this module.
|
||||
void counterexample_init (void);
|
||||
void counterexample_free (void);
|
||||
|
||||
void counterexample_report_state (const state *s, FILE *out, const char *prefix);
|
||||
// Print the counterexamples for the conflicts of state S.
|
||||
//
|
||||
// Used both for the warnings on the terminal (OUT = stderr, PREFIX =
|
||||
// ""), and for the reports (OUT != stderr, PREFIX != "").
|
||||
void
|
||||
counterexample_report_state (const state *s, FILE *out, const char *prefix);
|
||||
|
||||
#endif /* COUNTEREXAMPLE_H */
|
||||
|
||||
+265
-32
@@ -20,8 +20,11 @@
|
||||
#include <config.h>
|
||||
|
||||
#include "derivation.h"
|
||||
#include "glyphs.h"
|
||||
|
||||
#include <c-ctype.h>
|
||||
#include <gl_linked_list.h>
|
||||
#include <mbswidth.h>
|
||||
|
||||
#include "system.h"
|
||||
#include "complain.h"
|
||||
@@ -29,11 +32,15 @@
|
||||
struct derivation
|
||||
{
|
||||
symbol_number sym;
|
||||
gl_list_t children;
|
||||
derivation_list children;
|
||||
int reference_count;
|
||||
// Color assigned for styling. Guarantees that the derivation is
|
||||
// always displayed with the same color, independently of the order
|
||||
// in which the derivations are traversed.
|
||||
int color;
|
||||
};
|
||||
|
||||
static derivation d_dot = { -1, NULL, -1 };
|
||||
static derivation d_dot = { -1, NULL, -1, -1 };
|
||||
|
||||
derivation *
|
||||
derivation_dot (void)
|
||||
@@ -73,6 +80,7 @@ derivation_new (symbol_number sym, derivation_list children)
|
||||
deriv->sym = sym;
|
||||
deriv->children = children;
|
||||
deriv->reference_count = 0;
|
||||
deriv->color = -1;
|
||||
return deriv;
|
||||
}
|
||||
|
||||
@@ -126,27 +134,243 @@ derivation_size (const derivation *deriv)
|
||||
return size;
|
||||
}
|
||||
|
||||
/* Print DERIV, colored according to COUNTER.
|
||||
Return false if nothing is printed. */
|
||||
|
||||
static int
|
||||
max (int a, int b)
|
||||
{
|
||||
return a < b ? b : a;
|
||||
}
|
||||
|
||||
// Longest distance from root to leaf.
|
||||
static int
|
||||
derivation_depth (const derivation *deriv)
|
||||
{
|
||||
if (deriv->children)
|
||||
{
|
||||
// Children's depth cannot be 0, even if there are no children
|
||||
// (the case of a derivation with an empty RHS).
|
||||
int res = 1;
|
||||
derivation *child;
|
||||
for (gl_list_iterator_t it = gl_list_iterator (deriv->children);
|
||||
derivation_list_next (&it, &child);
|
||||
)
|
||||
res = max (res, derivation_depth (child));
|
||||
return res + 1;
|
||||
}
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
static bool
|
||||
derivation_print_impl (const derivation *deriv, FILE *f,
|
||||
bool leaves_only,
|
||||
int *counter, const char *prefix)
|
||||
all_spaces (const char *s)
|
||||
{
|
||||
while (c_isspace (*s))
|
||||
s++;
|
||||
return *s == '\0';
|
||||
}
|
||||
|
||||
// Printing the derivation as trees without trailing spaces is
|
||||
// painful: we cannot simply pad one "column" before moving to the
|
||||
// next:
|
||||
//
|
||||
// exp
|
||||
// ↳ x1 e1 foo1 x1
|
||||
// ↳ x2 ↳ ε ↳ foo2 ↳ x2
|
||||
// ↳ x3 ↳ foo3 ↳ x3
|
||||
// ↳ "X" • ↳ x1 foo4 ↳ "X"
|
||||
// ↳ x2 ↳ "quuux"
|
||||
// ↳ x3
|
||||
// ↳ "X"
|
||||
//
|
||||
// It's hard for a column to know that it's "last" to decide whether
|
||||
// to output the right-padding or not. So when we need to pad on the
|
||||
// right to complete a column, we don't output the spaces, we
|
||||
// accumulate the width of padding in *PADDING.
|
||||
//
|
||||
// Each time we actually print something (non space), we flush that
|
||||
// padding. When we _don't_ print something, its width is added to
|
||||
// the current padding.
|
||||
//
|
||||
// This function implements this.
|
||||
//
|
||||
// When COND is true, put S on OUT, preceeded by *PADDING white
|
||||
// spaces. Otherwise add the width to *PADDING. Return the width of
|
||||
// S.
|
||||
static int
|
||||
fputs_if (bool cond, FILE *out, int *padding, const char *s)
|
||||
{
|
||||
int res = mbswidth (s, 0);
|
||||
if (cond && !all_spaces (s))
|
||||
{
|
||||
fprintf (out, "%*s%s", *padding, "", s);
|
||||
*padding = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
*padding += res;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
// The width taken to report this derivation recursively down to its
|
||||
// leaves.
|
||||
static int
|
||||
derivation_width (const derivation *deriv)
|
||||
{
|
||||
if (deriv->children)
|
||||
{
|
||||
const symbol *sym = symbols[deriv->sym];
|
||||
int self_width = mbswidth (sym->tag, 0);
|
||||
|
||||
// Arrow and space.
|
||||
int children_width = down_arrow_width;
|
||||
if (gl_list_size (deriv->children) == 0)
|
||||
// Empty rhs.
|
||||
children_width += empty_width;
|
||||
else
|
||||
{
|
||||
derivation *child;
|
||||
for (gl_list_iterator_t it = gl_list_iterator (deriv->children);
|
||||
derivation_list_next (&it, &child);
|
||||
)
|
||||
children_width
|
||||
+= derivation_separator_width + derivation_width (child);
|
||||
// No separator at the beginning.
|
||||
children_width -= derivation_separator_width;
|
||||
}
|
||||
return max (self_width, children_width);
|
||||
}
|
||||
else if (deriv == &d_dot)
|
||||
{
|
||||
return dot_width;
|
||||
}
|
||||
else // leaf.
|
||||
{
|
||||
const symbol *sym = symbols[deriv->sym];
|
||||
return mbswidth (sym->tag, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Print DERIV for DEPTH.
|
||||
//
|
||||
// The tree is printed from top to bottom with DEPTH ranging from 0 to
|
||||
// the total depth of the tree. DERIV should only printed when we
|
||||
// reach its depth, i.e., then DEPTH is 0.
|
||||
//
|
||||
// When DEPTH is 1 and we're on a subderivation, then we print the RHS
|
||||
// of the derivation (in DEPTH 0 we printed its LHS).
|
||||
//
|
||||
// Return the "logical printed" width. We might have not have reached
|
||||
// that width, in which case the missing spaces are in *PADDING.
|
||||
static int
|
||||
derivation_print_tree_impl (const derivation *deriv, FILE *out,
|
||||
int depth, int *padding)
|
||||
{
|
||||
const int width = derivation_width (deriv);
|
||||
|
||||
int res = 0;
|
||||
if (deriv->children)
|
||||
{
|
||||
const symbol *sym = symbols[deriv->sym];
|
||||
char style[20];
|
||||
snprintf (style, 20, "cex-%d", *counter);
|
||||
snprintf (style, 20, "cex-%d", deriv->color);
|
||||
|
||||
if (depth == 0 || depth == 1)
|
||||
{
|
||||
begin_use_class (style, out);
|
||||
begin_use_class ("cex-step", out);
|
||||
}
|
||||
if (depth == 0)
|
||||
{
|
||||
res += fputs_if (true, out, padding, sym->tag);
|
||||
}
|
||||
else
|
||||
{
|
||||
res += fputs_if (depth == 1, out, padding, down_arrow);
|
||||
if (gl_list_size (deriv->children) == 0)
|
||||
// Empty rhs.
|
||||
res += fputs_if (depth == 1, out, padding, empty);
|
||||
else
|
||||
{
|
||||
bool first = true;
|
||||
derivation *child;
|
||||
for (gl_list_iterator_t it = gl_list_iterator (deriv->children);
|
||||
derivation_list_next (&it, &child);
|
||||
)
|
||||
{
|
||||
if (!first)
|
||||
res += fputs_if (depth == 1, out, padding, derivation_separator);
|
||||
res += derivation_print_tree_impl (child, out, depth - 1, padding);
|
||||
first = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (depth == 0 || depth == 1)
|
||||
{
|
||||
end_use_class ("cex-step", out);
|
||||
end_use_class (style, out);
|
||||
}
|
||||
*padding += width - res;
|
||||
res = width;
|
||||
}
|
||||
else if (deriv == &d_dot)
|
||||
{
|
||||
if (depth == 0)
|
||||
begin_use_class ("cex-dot", out);
|
||||
res += fputs_if (depth == 0, out, padding, dot);
|
||||
if (depth == 0)
|
||||
end_use_class ("cex-dot", out);
|
||||
}
|
||||
else // leaf.
|
||||
{
|
||||
const symbol *sym = symbols[deriv->sym];
|
||||
if (depth == 0)
|
||||
begin_use_class ("cex-leaf", out);
|
||||
res += fputs_if (depth == 0, out, padding, sym->tag);
|
||||
if (depth == 0)
|
||||
end_use_class ("cex-leaf", out);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
static void
|
||||
derivation_print_tree (const derivation *deriv, FILE *out, const char *prefix)
|
||||
{
|
||||
fputc ('\n', out);
|
||||
for (int depth = 0, max_depth = derivation_depth (deriv);
|
||||
depth < max_depth; ++depth)
|
||||
{
|
||||
int padding = 0;
|
||||
fprintf (out, " %s", prefix);
|
||||
derivation_print_tree_impl (deriv, out, depth, &padding);
|
||||
fputc ('\n', out);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Print DERIV, colored according to COUNTER.
|
||||
Return false if nothing is printed. */
|
||||
static bool
|
||||
derivation_print_flat_impl (derivation *deriv, FILE *out,
|
||||
bool leaves_only,
|
||||
int *counter, const char *prefix)
|
||||
{
|
||||
if (deriv->children)
|
||||
{
|
||||
const symbol *sym = symbols[deriv->sym];
|
||||
deriv->color = *counter;
|
||||
++*counter;
|
||||
begin_use_class (style, f);
|
||||
char style[20];
|
||||
snprintf (style, 20, "cex-%d", deriv->color);
|
||||
begin_use_class (style, out);
|
||||
|
||||
if (!leaves_only)
|
||||
{
|
||||
fputs (prefix, f);
|
||||
begin_use_class ("cex-step", f);
|
||||
fprintf (f, "%s ::=[ ", sym->tag);
|
||||
end_use_class ("cex-step", f);
|
||||
fputs (prefix, out);
|
||||
begin_use_class ("cex-step", out);
|
||||
fprintf (out, "%s %s [ ", sym->tag, arrow);
|
||||
end_use_class ("cex-step", out);
|
||||
prefix = "";
|
||||
}
|
||||
bool res = false;
|
||||
@@ -155,7 +379,8 @@ derivation_print_impl (const derivation *deriv, FILE *f,
|
||||
derivation_list_next (&it, &child);
|
||||
)
|
||||
{
|
||||
if (derivation_print_impl (child, f, leaves_only, counter, prefix))
|
||||
if (derivation_print_flat_impl (child, out,
|
||||
leaves_only, counter, prefix))
|
||||
{
|
||||
prefix = " ";
|
||||
res = true;
|
||||
@@ -165,49 +390,57 @@ derivation_print_impl (const derivation *deriv, FILE *f,
|
||||
}
|
||||
if (!leaves_only)
|
||||
{
|
||||
begin_use_class ("cex-step", f);
|
||||
begin_use_class ("cex-step", out);
|
||||
if (res)
|
||||
fputs (" ]", f);
|
||||
fputs (" ]", out);
|
||||
else
|
||||
fputs ("]", f);
|
||||
end_use_class ("cex-step", f);
|
||||
fputs ("]", out);
|
||||
end_use_class ("cex-step", out);
|
||||
}
|
||||
end_use_class (style, f);
|
||||
end_use_class (style, out);
|
||||
return res;
|
||||
}
|
||||
else if (deriv == &d_dot)
|
||||
{
|
||||
fputs (prefix, f);
|
||||
begin_use_class ("cex-dot", f);
|
||||
print_dot (f);
|
||||
end_use_class ("cex-dot", f);
|
||||
fputs (prefix, out);
|
||||
begin_use_class ("cex-dot", out);
|
||||
fputs (dot, out);
|
||||
end_use_class ("cex-dot", out);
|
||||
}
|
||||
else // leaf.
|
||||
{
|
||||
fputs (prefix, f);
|
||||
fputs (prefix, out);
|
||||
const symbol *sym = symbols[deriv->sym];
|
||||
begin_use_class ("cex-leaf", f);
|
||||
fprintf (f, "%s", sym->tag);
|
||||
end_use_class ("cex-leaf", f);
|
||||
begin_use_class ("cex-leaf", out);
|
||||
fprintf (out, "%s", sym->tag);
|
||||
end_use_class ("cex-leaf", out);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
derivation_print (const derivation *deriv, FILE *out, const char *prefix)
|
||||
static void
|
||||
derivation_print_flat (const derivation *deriv, FILE *out, const char *prefix)
|
||||
{
|
||||
int counter = 0;
|
||||
fputs (prefix, out);
|
||||
derivation_print_impl (deriv, out, false, &counter, "");
|
||||
derivation_print_flat_impl ((derivation *)deriv, out, false, &counter, "");
|
||||
fputc ('\n', out);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
derivation_print_leaves (const derivation *deriv, FILE *out, const char *prefix)
|
||||
{
|
||||
int counter = 0;
|
||||
fputs (prefix, out);
|
||||
derivation_print_impl (deriv, out, true, &counter, "");
|
||||
derivation_print_flat_impl ((derivation *)deriv, out, true, &counter, "");
|
||||
fputc ('\n', out);
|
||||
}
|
||||
|
||||
void
|
||||
derivation_print (const derivation *deriv, FILE *out, const char *prefix)
|
||||
{
|
||||
if (getenv ("YYFLAT"))
|
||||
derivation_print_flat (deriv, out, prefix);
|
||||
else
|
||||
derivation_print_tree (deriv, out, prefix);
|
||||
}
|
||||
|
||||
@@ -60,12 +60,15 @@ static inline derivation *derivation_new_leaf (symbol_number sym)
|
||||
{
|
||||
return derivation_new (sym, NULL);
|
||||
}
|
||||
|
||||
// Number of symbols.
|
||||
size_t derivation_size (const derivation *deriv);
|
||||
void derivation_print (const derivation *deriv, FILE *out, const char *prefix);
|
||||
void derivation_print_leaves (const derivation *deriv, FILE *out, const char *prefix);
|
||||
void derivation_free (derivation *deriv);
|
||||
void derivation_retain (derivation *deriv);
|
||||
|
||||
// A derivation denoting the position of the dot.
|
||||
derivation *derivation_dot (void);
|
||||
|
||||
#endif /* DERIVATION_H */
|
||||
|
||||
+1
-1
@@ -221,7 +221,7 @@ static const argmatch_report_arg argmatch_report_args[] =
|
||||
{ "none", report_none },
|
||||
{ "states", report_states },
|
||||
{ "itemsets", report_states | report_itemsets },
|
||||
{ "lookaheads", report_states | report_lookahead_tokens },
|
||||
{ "lookaheads", report_states | report_lookaheads },
|
||||
{ "solved", report_states | report_solved_conflicts },
|
||||
{ "counterexamples", report_cex },
|
||||
{ "cex", report_cex },
|
||||
|
||||
+1
-1
@@ -77,7 +77,7 @@ enum report
|
||||
report_none = 0,
|
||||
report_states = 1 << 0,
|
||||
report_itemsets = 1 << 1,
|
||||
report_lookahead_tokens = 1 << 2,
|
||||
report_lookaheads = 1 << 2,
|
||||
report_solved_conflicts = 1 << 3,
|
||||
report_cex = 1 << 4,
|
||||
report_all = ~0
|
||||
|
||||
+103
@@ -0,0 +1,103 @@
|
||||
/* Graphical symbols.
|
||||
|
||||
Copyright (C) 2020 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of Bison, the GNU Compiler Compiler.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "glyphs.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <attribute.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <mbswidth.h>
|
||||
#include <unicodeio.h>
|
||||
|
||||
// In gnulib/lib/unicodeio.h unicode_to_mb uses a buffer of 25 bytes.
|
||||
typedef char glyph_buffer_t[26];
|
||||
|
||||
|
||||
static glyph_buffer_t arrow_buf;
|
||||
const char *arrow;
|
||||
int arrow_width;
|
||||
|
||||
static glyph_buffer_t down_arrow_buf;
|
||||
const char *down_arrow;
|
||||
int down_arrow_width;
|
||||
|
||||
static glyph_buffer_t dot_buf;
|
||||
const char *dot;
|
||||
int dot_width;
|
||||
|
||||
static glyph_buffer_t empty_buf;
|
||||
const char *empty;
|
||||
int empty_width;
|
||||
|
||||
const char *derivation_separator = " ";
|
||||
int derivation_separator_width = 1;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
const char **glyph;
|
||||
char *buf;
|
||||
const char *fallback;
|
||||
} callback_arg_t;
|
||||
|
||||
|
||||
static long
|
||||
on_success (const char *buf, size_t buflen, void *callback_arg)
|
||||
{
|
||||
callback_arg_t *arg = (callback_arg_t *) callback_arg;
|
||||
assert (buflen + 1 < sizeof arg->buf);
|
||||
*stpncpy (arg->buf, buf, buflen) = '\0';
|
||||
return 1;
|
||||
}
|
||||
|
||||
static long
|
||||
on_failure (unsigned code MAYBE_UNUSED, const char *msg MAYBE_UNUSED,
|
||||
void *callback_arg)
|
||||
{
|
||||
callback_arg_t *arg = (callback_arg_t *) callback_arg;
|
||||
assert (strlen (arg->fallback) + 1 < sizeof arg->buf);
|
||||
strcpy (arg->buf, arg->fallback);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool
|
||||
glyph_set (const char **glyph,
|
||||
char buf[26], int *width,
|
||||
unsigned code, const char *fallback)
|
||||
{
|
||||
callback_arg_t arg = { glyph, buf, fallback };
|
||||
int res = unicode_to_mb (code, on_success, on_failure, &arg);
|
||||
*glyph = buf;
|
||||
*width = mbswidth (*glyph, 0);
|
||||
return res;
|
||||
}
|
||||
|
||||
void
|
||||
glyphs_init (void)
|
||||
{
|
||||
glyph_set (&arrow, arrow_buf, &arrow_width, 0x2192, "->");
|
||||
glyph_set (&dot, dot_buf, &dot_width, 0x2022, ".");
|
||||
glyph_set (&down_arrow, down_arrow_buf, &down_arrow_width, 0x21b3, "`->");
|
||||
glyph_set (&empty, empty_buf, &empty_width, 0x03b5, "%empty");
|
||||
|
||||
strncat (down_arrow_buf, " ", sizeof down_arrow_buf - strlen (down_arrow_buf) - 1);
|
||||
down_arrow_width += 1;
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/* Graphical symbols.
|
||||
|
||||
Copyright (C) 2020 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of Bison, the GNU Compiler Compiler.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef GLYPHS_H
|
||||
# define GLYPHS_H
|
||||
|
||||
/* Initialize the following variables. */
|
||||
void glyphs_init (void);
|
||||
|
||||
/* "→", separates the lhs of a rule from its rhs. */
|
||||
extern const char *arrow;
|
||||
extern int arrow_width;
|
||||
|
||||
/* "•", a point in an item (aka, a dotted rule). */
|
||||
extern const char *dot;
|
||||
extern int dot_width;
|
||||
|
||||
/* "↳ ", below an lhs to announce the rhs. */
|
||||
extern const char *down_arrow;
|
||||
extern int down_arrow_width;
|
||||
|
||||
/* "ε", an empty rhs. */
|
||||
extern const char *empty;
|
||||
extern int empty_width;
|
||||
|
||||
/* " ", separate symbols in the rhs of a derivation. */
|
||||
extern const char *derivation_separator;
|
||||
extern int derivation_separator_width;
|
||||
|
||||
#endif /* GLYPHS_H */
|
||||
+2
-2
@@ -23,6 +23,7 @@
|
||||
|
||||
#include "complain.h"
|
||||
#include "getargs.h"
|
||||
#include "glyphs.h"
|
||||
#include "gram.h"
|
||||
#include "print-xml.h"
|
||||
#include "reader.h"
|
||||
@@ -56,8 +57,7 @@ item_print (item_number *item, rule const *previous_rule, FILE *out)
|
||||
|
||||
for (item_number *sp = r->rhs; sp < item; sp++)
|
||||
fprintf (out, " %s", symbols[*sp]->tag);
|
||||
putc (' ', out);
|
||||
print_dot (out);
|
||||
fprintf (out, " %s", dot);
|
||||
if (0 <= *r->rhs)
|
||||
for (item_number *sp = item; 0 <= *sp; ++sp)
|
||||
fprintf (out, " %s", symbols[*sp]->tag);
|
||||
|
||||
-21
@@ -103,8 +103,6 @@
|
||||
|
||||
# include "system.h"
|
||||
|
||||
# include <unicodeio.h>
|
||||
|
||||
# include "location.h"
|
||||
# include "symtab.h"
|
||||
|
||||
@@ -217,25 +215,6 @@ typedef struct
|
||||
extern rule *rules;
|
||||
extern rule_number nrules;
|
||||
|
||||
/* Fallback in case we can't print "•". */
|
||||
static inline long
|
||||
print_dot_fallback (unsigned int code _GL_UNUSED,
|
||||
const char *msg _GL_UNUSED,
|
||||
void *callback_arg)
|
||||
{
|
||||
FILE *out = (FILE *) callback_arg;
|
||||
putc ('.', out);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Print "•", the symbol used to represent a point in an item (aka, a
|
||||
dotted rule). */
|
||||
static inline void
|
||||
print_dot (FILE *out)
|
||||
{
|
||||
unicode_to_mb (0x2022, fwrite_success_callback, print_dot_fallback, out);
|
||||
}
|
||||
|
||||
/* Get the rule associated to this item. ITEM points inside RITEM. */
|
||||
static inline rule const *
|
||||
item_rule (item_number const *item)
|
||||
|
||||
+2
-2
@@ -184,9 +184,9 @@ output_red (state const *s, reductions const *reds, FILE *fout)
|
||||
bool firste = true;
|
||||
rule_number ruleno = reds->rules[j]->number;
|
||||
|
||||
if (reds->lookahead_tokens)
|
||||
if (reds->lookaheads)
|
||||
for (int i = 0; i < ntokens; i++)
|
||||
if (bitset_test (reds->lookahead_tokens[j], i))
|
||||
if (bitset_test (reds->lookaheads[j], i))
|
||||
{
|
||||
if (bitset_test (no_reduce_set, i))
|
||||
firstd = print_token (&dout, firstd, symbols[i]->tag);
|
||||
|
||||
+1
-1
@@ -1025,7 +1025,7 @@ ielr_split_states (bitsetv follow_kernel_items, bitsetv always_follows,
|
||||
{
|
||||
rule *this_rule = node->state->reductions->rules[r];
|
||||
bitset lookahead_set =
|
||||
node->state->reductions->lookahead_tokens[r];
|
||||
node->state->reductions->lookaheads[r];
|
||||
if (item_number_is_rule_number (*this_rule->rhs))
|
||||
ielr_compute_goto_follow_set (follow_kernel_items,
|
||||
always_follows, node,
|
||||
|
||||
+24
-27
@@ -256,9 +256,9 @@ lookback_find_state (int lookback_index)
|
||||
state *res = NULL;
|
||||
for (int j = 0; j < nstates; ++j)
|
||||
if (states[j]->reductions
|
||||
&& states[j]->reductions->lookahead_tokens)
|
||||
&& states[j]->reductions->lookaheads)
|
||||
{
|
||||
if (states[j]->reductions->lookahead_tokens - LA > lookback_index)
|
||||
if (states[j]->reductions->lookaheads - LA > lookback_index)
|
||||
/* Went too far. */
|
||||
break;
|
||||
else
|
||||
@@ -280,7 +280,7 @@ lookback_print (FILE *out)
|
||||
{
|
||||
fprintf (out, " %3d = ", i);
|
||||
const state *s = lookback_find_state (i);
|
||||
int rnum = i - (s->reductions->lookahead_tokens - LA);
|
||||
int rnum = i - (s->reductions->lookaheads - LA);
|
||||
const rule *r = s->reductions->rules[rnum];
|
||||
fprintf (out, "(%3d, ", s->number);
|
||||
rule_print (r, NULL, out);
|
||||
@@ -305,7 +305,7 @@ static void
|
||||
add_lookback_edge (state *s, rule const *r, goto_number gotono)
|
||||
{
|
||||
int ri = state_reduction_find (s, r);
|
||||
int idx = (s->reductions->lookahead_tokens - LA) + ri;
|
||||
int idx = (s->reductions->lookaheads - LA) + ri;
|
||||
lookback[idx] = goto_list_new (gotono, lookback[idx]);
|
||||
}
|
||||
|
||||
@@ -421,7 +421,7 @@ compute_follows (void)
|
||||
|
||||
|
||||
static void
|
||||
compute_lookahead_tokens (void)
|
||||
compute_lookaheads (void)
|
||||
{
|
||||
if (trace_flag & trace_automaton)
|
||||
lookback_print (stderr);
|
||||
@@ -437,13 +437,12 @@ compute_lookahead_tokens (void)
|
||||
}
|
||||
|
||||
|
||||
/*----------------------------------------------------.
|
||||
| Count the number of lookahead tokens required for S |
|
||||
| (N_LOOKAHEAD_TOKENS member). |
|
||||
`----------------------------------------------------*/
|
||||
/*------------------------------------------------------.
|
||||
| Count the number of lookahead tokens required for S. |
|
||||
`------------------------------------------------------*/
|
||||
|
||||
static int
|
||||
state_lookahead_tokens_count (state *s, bool default_reduction_only_for_accept)
|
||||
state_lookaheads_count (state *s, bool default_reduction_only_for_accept)
|
||||
{
|
||||
const reductions *reds = s->reductions;
|
||||
const transitions *trans = s->transitions;
|
||||
@@ -473,9 +472,9 @@ state_lookahead_tokens_count (state *s, bool default_reduction_only_for_accept)
|
||||
}
|
||||
|
||||
|
||||
/*----------------------------------------------------.
|
||||
| Compute LA, NLA, and the lookahead_tokens members. |
|
||||
`----------------------------------------------------*/
|
||||
/*----------------------------------------------.
|
||||
| Compute LA, NLA, and the lookaheads members. |
|
||||
`----------------------------------------------*/
|
||||
|
||||
void
|
||||
initialize_LA (void)
|
||||
@@ -491,25 +490,23 @@ initialize_LA (void)
|
||||
/* Compute the total number of reductions requiring a lookahead. */
|
||||
nLA = 0;
|
||||
for (state_number i = 0; i < nstates; ++i)
|
||||
nLA +=
|
||||
state_lookahead_tokens_count (states[i],
|
||||
default_reduction_only_for_accept);
|
||||
nLA += state_lookaheads_count (states[i],
|
||||
default_reduction_only_for_accept);
|
||||
/* Avoid having to special case 0. */
|
||||
if (!nLA)
|
||||
nLA = 1;
|
||||
|
||||
bitsetv pLA = LA = bitsetv_create (nLA, ntokens, BITSET_FIXED);
|
||||
|
||||
/* Initialize the members LOOKAHEAD_TOKENS for each state whose reductions
|
||||
/* Initialize the members LOOKAHEADS for each state whose reductions
|
||||
require lookahead tokens. */
|
||||
for (state_number i = 0; i < nstates; ++i)
|
||||
{
|
||||
int count =
|
||||
state_lookahead_tokens_count (states[i],
|
||||
default_reduction_only_for_accept);
|
||||
int count = state_lookaheads_count (states[i],
|
||||
default_reduction_only_for_accept);
|
||||
if (count)
|
||||
{
|
||||
states[i]->reductions->lookahead_tokens = pLA;
|
||||
states[i]->reductions->lookaheads = pLA;
|
||||
pLA += count;
|
||||
}
|
||||
}
|
||||
@@ -521,7 +518,7 @@ initialize_LA (void)
|
||||
`---------------------------------------------*/
|
||||
|
||||
static void
|
||||
lookahead_tokens_print (FILE *out)
|
||||
lookaheads_print (FILE *out)
|
||||
{
|
||||
fputs ("Lookaheads:\n", out);
|
||||
for (state_number i = 0; i < nstates; ++i)
|
||||
@@ -533,11 +530,11 @@ lookahead_tokens_print (FILE *out)
|
||||
for (int j = 0; j < reds->num; ++j)
|
||||
{
|
||||
fprintf (out, " rule %d:", reds->rules[j]->number);
|
||||
if (reds->lookahead_tokens)
|
||||
if (reds->lookaheads)
|
||||
{
|
||||
bitset_iterator iter;
|
||||
int k;
|
||||
BITSET_FOR_EACH (iter, reds->lookahead_tokens[j], k, 0)
|
||||
BITSET_FOR_EACH (iter, reds->lookaheads[j], k, 0)
|
||||
fprintf (out, " %s", symbols[k]->tag);
|
||||
}
|
||||
fputc ('\n', out);
|
||||
@@ -564,10 +561,10 @@ lalr (void)
|
||||
lookback = xcalloc (nLA, sizeof *lookback);
|
||||
build_relations ();
|
||||
compute_follows ();
|
||||
compute_lookahead_tokens ();
|
||||
compute_lookaheads ();
|
||||
|
||||
if (trace_flag & trace_sets)
|
||||
lookahead_tokens_print (stderr);
|
||||
lookaheads_print (stderr);
|
||||
if (trace_flag & trace_automaton)
|
||||
{
|
||||
begin_use_class ("trace0", stderr);
|
||||
@@ -614,6 +611,6 @@ void
|
||||
lalr_free (void)
|
||||
{
|
||||
for (state_number s = 0; s < nstates; ++s)
|
||||
states[s]->reductions->lookahead_tokens = NULL;
|
||||
states[s]->reductions->lookaheads = NULL;
|
||||
bitsetv_free (LA);
|
||||
}
|
||||
|
||||
@@ -53,6 +53,8 @@ src_bison_SOURCES = \
|
||||
src/flex-scanner.h \
|
||||
src/getargs.c \
|
||||
src/getargs.h \
|
||||
src/glyphs.c \
|
||||
src/glyphs.h \
|
||||
src/gram.c \
|
||||
src/gram.h \
|
||||
src/graphviz.c \
|
||||
|
||||
+13
-11
@@ -82,8 +82,10 @@ lssi_comparator (lssi *s1, lssi *s2)
|
||||
return false;
|
||||
}
|
||||
|
||||
typedef gl_list_t lssi_list;
|
||||
|
||||
static inline bool
|
||||
append_lssi (lssi *sn, Hash_table *visited, gl_list_t queue)
|
||||
append_lssi (lssi *sn, Hash_table *visited, lssi_list queue)
|
||||
{
|
||||
if (hash_lookup (visited, sn))
|
||||
{
|
||||
@@ -100,7 +102,7 @@ append_lssi (lssi *sn, Hash_table *visited, gl_list_t queue)
|
||||
static void
|
||||
lssi_print (lssi *l)
|
||||
{
|
||||
print_state_item (state_items + l->si, stdout);
|
||||
print_state_item (&state_items[l->si], stdout);
|
||||
if (l->lookahead)
|
||||
{
|
||||
printf ("FOLLOWL = { ");
|
||||
@@ -121,7 +123,7 @@ static bitset
|
||||
eligible_state_items (state_item *target)
|
||||
{
|
||||
bitset result = bitset_create (nstate_items, BITSET_FIXED);
|
||||
gl_list_t queue =
|
||||
state_item_list queue =
|
||||
gl_list_create (GL_LINKED_LIST, NULL, NULL, NULL, true, 1,
|
||||
(const void **) &target);
|
||||
while (gl_list_size (queue) > 0)
|
||||
@@ -147,7 +149,7 @@ eligible_state_items (state_item *target)
|
||||
* this conflict. If optimized is true, only consider parser states
|
||||
* that can reach the conflict state.
|
||||
*/
|
||||
gl_list_t
|
||||
state_item_list
|
||||
shortest_path_from_start (state_item_number target, symbol_number next_sym)
|
||||
{
|
||||
bitset eligible = eligible_state_items (&state_items[target]);
|
||||
@@ -159,7 +161,7 @@ shortest_path_from_start (state_item_number target, symbol_number next_sym)
|
||||
bitset il = bitset_create (nsyms, BITSET_FIXED);
|
||||
bitset_set (il, 0);
|
||||
lssi *init = new_lssi (0, NULL, il, true);
|
||||
gl_list_t queue = gl_list_create_empty (GL_LINKED_LIST, NULL, NULL,
|
||||
lssi_list queue = gl_list_create_empty (GL_LINKED_LIST, NULL, NULL,
|
||||
NULL, true);
|
||||
append_lssi (init, visited, queue);
|
||||
// breadth-first search
|
||||
@@ -175,7 +177,7 @@ shortest_path_from_start (state_item_number target, symbol_number next_sym)
|
||||
finished = true;
|
||||
break;
|
||||
}
|
||||
state_item *si = state_items + last;
|
||||
state_item *si = &state_items[last];
|
||||
// Transitions don't change follow_L
|
||||
if (si->trans >= 0)
|
||||
{
|
||||
@@ -240,10 +242,10 @@ shortest_path_from_start (state_item_number target, symbol_number next_sym)
|
||||
fputs ("Cannot find shortest path to conflict state.", stderr);
|
||||
abort ();
|
||||
}
|
||||
gl_list_t res =
|
||||
state_item_list res =
|
||||
gl_list_create_empty (GL_LINKED_LIST, NULL, NULL, NULL, true);
|
||||
for (lssi *sn = n; sn != NULL; sn = sn->parent)
|
||||
gl_list_add_first (res, state_items + sn->si);
|
||||
gl_list_add_first (res, &state_items[sn->si]);
|
||||
|
||||
hash_free (visited);
|
||||
gl_list_free (queue);
|
||||
@@ -306,10 +308,10 @@ intersect (bitset ts, bitset syms)
|
||||
* Compute a list of state_items that have a production to n with respect
|
||||
* to its lookahead
|
||||
*/
|
||||
gl_list_t
|
||||
state_item_list
|
||||
lssi_reverse_production (const state_item *si, bitset lookahead)
|
||||
{
|
||||
gl_list_t result =
|
||||
state_item_list result =
|
||||
gl_list_create_empty (GL_LINKED_LIST, NULL, NULL, NULL, true);
|
||||
if (SI_TRANSITION (si))
|
||||
return result;
|
||||
@@ -320,7 +322,7 @@ lssi_reverse_production (const state_item *si, bitset lookahead)
|
||||
state_item_number sin;
|
||||
BITSET_FOR_EACH (biter, si->revs, sin, 0)
|
||||
{
|
||||
state_item *prevsi = state_items + sin;
|
||||
state_item *prevsi = &state_items[sin];
|
||||
if (!production_allowed (prevsi, si))
|
||||
continue;
|
||||
bitset prev_lookahead = prevsi->lookahead;
|
||||
|
||||
+3
-3
@@ -32,8 +32,8 @@
|
||||
* find shortest lookahead-sensitive path of state-items to target such that
|
||||
* next_sym is in the follow_L set of target in that position.
|
||||
*/
|
||||
gl_list_t shortest_path_from_start (state_item_number target,
|
||||
symbol_number next_sym);
|
||||
state_item_list shortest_path_from_start (state_item_number target,
|
||||
symbol_number next_sym);
|
||||
|
||||
/**
|
||||
* Determine if the given terminal is in the given symbol set or can begin
|
||||
@@ -52,6 +52,6 @@ bool intersect (bitset ts, bitset syms);
|
||||
* to this state-item such that the resulting possible lookahead symbols are
|
||||
* as given.
|
||||
*/
|
||||
gl_list_t lssi_reverse_production (const state_item *si, bitset lookahead);
|
||||
state_item_list lssi_reverse_production (const state_item *si, bitset lookahead);
|
||||
|
||||
#endif /* LSSI_H */
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
#include "files.h"
|
||||
#include "fixits.h"
|
||||
#include "getargs.h"
|
||||
#include "glyphs.h"
|
||||
#include "gram.h"
|
||||
#include "ielr.h"
|
||||
#include "lalr.h"
|
||||
@@ -85,6 +86,7 @@ main (int argc, char *argv[])
|
||||
|
||||
atexit (close_stdout);
|
||||
|
||||
glyphs_init ();
|
||||
uniqstrs_new ();
|
||||
muscle_init ();
|
||||
complain_init ();
|
||||
|
||||
+32
-34
@@ -34,7 +34,7 @@ typedef struct parse_state
|
||||
struct si_chunk
|
||||
{
|
||||
// elements newly added in this chunk
|
||||
gl_list_t contents;
|
||||
state_item_list contents;
|
||||
// properties of the linked list this chunk represents
|
||||
const state_item *head_elt;
|
||||
const state_item *tail_elt;
|
||||
@@ -135,7 +135,7 @@ static parse_state *
|
||||
copy_parse_state (bool prepend, parse_state *parent)
|
||||
{
|
||||
parse_state *res = xmalloc (sizeof *res);
|
||||
memcpy (res, parent, sizeof *res);
|
||||
*res = *parent;
|
||||
res->state_items.contents
|
||||
= gl_list_create_empty (GL_LINKED_LIST, NULL, NULL, NULL, true);
|
||||
res->derivs.contents = derivation_list_new ();
|
||||
@@ -252,7 +252,7 @@ parse_state_completed_steps (const parse_state *ps, int *shifts, int *production
|
||||
while (root_ps->parent)
|
||||
root_ps = root_ps->parent;
|
||||
|
||||
gl_list_t sis = root_ps->state_items.contents;
|
||||
state_item_list sis = root_ps->state_items.contents;
|
||||
int count = 0;
|
||||
|
||||
state_item *last = NULL;
|
||||
@@ -337,19 +337,17 @@ parser_pop (parse_state *ps, int deriv_index,
|
||||
for (int i = 0; i < 4; ++i)
|
||||
chunks[i] = gl_list_create_empty (GL_LINKED_LIST, NULL, NULL, NULL, true);
|
||||
for (parse_state *pn = ps; pn != NULL; pn = pn->parent)
|
||||
{
|
||||
if (pn->prepend)
|
||||
{
|
||||
gl_list_add_last (chunks[0], pn->state_items.contents);
|
||||
gl_list_add_last (chunks[2], pn->derivs.contents);
|
||||
}
|
||||
else
|
||||
{
|
||||
gl_list_add_first (chunks[1], pn->state_items.contents);
|
||||
gl_list_add_first (chunks[3], pn->derivs.contents);
|
||||
}
|
||||
}
|
||||
gl_list_t popped_derivs = derivation_list_new ();
|
||||
if (pn->prepend)
|
||||
{
|
||||
gl_list_add_last (chunks[0], pn->state_items.contents);
|
||||
gl_list_add_last (chunks[2], pn->derivs.contents);
|
||||
}
|
||||
else
|
||||
{
|
||||
gl_list_add_first (chunks[1], pn->state_items.contents);
|
||||
gl_list_add_first (chunks[3], pn->derivs.contents);
|
||||
}
|
||||
derivation_list popped_derivs = derivation_list_new ();
|
||||
gl_list_t ret_chunks[4] = { ret->state_items.contents, NULL,
|
||||
ret->derivs.contents, popped_derivs
|
||||
};
|
||||
@@ -390,7 +388,7 @@ parser_pop (parse_state *ps, int deriv_index,
|
||||
}
|
||||
|
||||
void
|
||||
parse_state_lists (parse_state *ps, gl_list_t *sitems,
|
||||
parse_state_lists (parse_state *ps, state_item_list *sitems,
|
||||
derivation_list *derivs)
|
||||
{
|
||||
parse_state *temp = empty_parse_state ();
|
||||
@@ -418,12 +416,12 @@ nullable_closure (parse_state *ps, state_item *si, parse_state_list state_list)
|
||||
for (state_item_number sin = si->trans; sin != -1;
|
||||
prev_sin = sin, sin = state_items[sin].trans)
|
||||
{
|
||||
state_item *psi = state_items + prev_sin;
|
||||
state_item *psi = &state_items[prev_sin];
|
||||
symbol_number sp = item_number_as_symbol_number (*psi->item);
|
||||
if (ISTOKEN (sp) || !nullable[sp - ntokens])
|
||||
break;
|
||||
|
||||
state_item *nsi = state_items + sin;
|
||||
state_item *nsi = &state_items[sin];
|
||||
current_ps = copy_parse_state (false, current_ps);
|
||||
ps_si_append (current_ps, nsi);
|
||||
ps_derivs_append (current_ps, derivation_new (sp, derivation_list_new ()));
|
||||
@@ -431,14 +429,14 @@ nullable_closure (parse_state *ps, state_item *si, parse_state_list state_list)
|
||||
}
|
||||
}
|
||||
|
||||
gl_list_t
|
||||
parse_state_list
|
||||
simulate_transition (parse_state *ps)
|
||||
{
|
||||
const state_item *si = ps->state_items.tail_elt;
|
||||
symbol_number sym = item_number_as_symbol_number (*si->item);
|
||||
// Transition on the same next symbol, taking nullable
|
||||
// symbols into account.
|
||||
gl_list_t result = parse_state_list_new ();
|
||||
parse_state_list result = parse_state_list_new ();
|
||||
state_item_number si_next = si->trans;
|
||||
// check for disabled transition, shouldn't happen
|
||||
// as any state_items that lead to these should be
|
||||
@@ -446,11 +444,11 @@ simulate_transition (parse_state *ps)
|
||||
if (si_next < 0)
|
||||
return result;
|
||||
parse_state *next_ps = copy_parse_state (false, ps);
|
||||
ps_si_append (next_ps, state_items + si_next);
|
||||
ps_si_append (next_ps, &state_items[si_next]);
|
||||
ps_derivs_append (next_ps, derivation_new_leaf (sym));
|
||||
parse_state_list_append (result, next_ps);
|
||||
|
||||
nullable_closure (next_ps, state_items + si_next, result);
|
||||
nullable_closure (next_ps, &state_items[si_next], result);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -473,10 +471,10 @@ compatible (symbol_number sym1, symbol_number sym2)
|
||||
return false;
|
||||
}
|
||||
|
||||
gl_list_t
|
||||
parse_state_list
|
||||
simulate_production (parse_state *ps, symbol_number compat_sym)
|
||||
{
|
||||
gl_list_t result = parse_state_list_new ();
|
||||
parse_state_list result = parse_state_list_new ();
|
||||
const state_item *si = parse_state_tail (ps);
|
||||
if (si->prods)
|
||||
{
|
||||
@@ -486,7 +484,7 @@ simulate_production (parse_state *ps, symbol_number compat_sym)
|
||||
{
|
||||
// Take production step only if lhs is not nullable and
|
||||
// if first rhs symbol is compatible with compat_sym
|
||||
state_item *next = state_items + sin;
|
||||
state_item *next = &state_items[sin];
|
||||
item_number *itm1 = next->item;
|
||||
if (!compatible (*itm1, compat_sym) || !production_allowed (si, next))
|
||||
continue;
|
||||
@@ -504,10 +502,10 @@ simulate_production (parse_state *ps, symbol_number compat_sym)
|
||||
// simulates a reduction on the given parse state, conflict_item is the
|
||||
// item associated with ps's conflict. symbol_set is a lookahead set this
|
||||
// reduction must be compatible with
|
||||
gl_list_t
|
||||
parse_state_list
|
||||
simulate_reduction (parse_state *ps, int rule_len, bitset symbol_set)
|
||||
{
|
||||
gl_list_t result = parse_state_list_new ();
|
||||
parse_state_list result = parse_state_list_new ();
|
||||
|
||||
int s_size = ps->state_items.total_size;
|
||||
int d_size = ps->derivs.total_size;
|
||||
@@ -529,7 +527,7 @@ simulate_reduction (parse_state *ps, int rule_len, bitset symbol_set)
|
||||
if (s_size != rule_len + 1)
|
||||
{
|
||||
state_item *tail = (state_item *) new_root->state_items.tail_elt;
|
||||
ps_si_append (new_root, state_items + tail->trans);
|
||||
ps_si_append (new_root, &state_items[tail->trans]);
|
||||
parse_state_list_append (result, new_root);
|
||||
}
|
||||
else
|
||||
@@ -537,7 +535,7 @@ simulate_reduction (parse_state *ps, int rule_len, bitset symbol_set)
|
||||
// The head state_item is a production item, so we need to prepend
|
||||
// with possible source state-items.
|
||||
const state_item *head = ps->state_items.head_elt;
|
||||
gl_list_t prev = lssi_reverse_production (head, symbol_set);
|
||||
state_item_list prev = lssi_reverse_production (head, symbol_set);
|
||||
// TODO: better understand what causes this case.
|
||||
if (gl_list_size (prev) == 0)
|
||||
{
|
||||
@@ -560,7 +558,7 @@ simulate_reduction (parse_state *ps, int rule_len, bitset symbol_set)
|
||||
copy = copy_parse_state (false, copy);
|
||||
struct si_chunk *sis = ©->state_items;
|
||||
const state_item *tail = sis->tail_elt;
|
||||
ps_si_append (copy, state_items + tail->trans);
|
||||
ps_si_append (copy, &state_items[tail->trans]);
|
||||
parse_state_list_append (result, copy);
|
||||
nullable_closure (copy, (state_item *) sis->tail_elt, result);
|
||||
}
|
||||
@@ -570,10 +568,10 @@ simulate_reduction (parse_state *ps, int rule_len, bitset symbol_set)
|
||||
return result;
|
||||
}
|
||||
|
||||
gl_list_t
|
||||
parse_state_list
|
||||
parser_prepend (parse_state *ps)
|
||||
{
|
||||
gl_list_t res = parse_state_list_new ();
|
||||
parse_state_list res = parse_state_list_new ();
|
||||
const state_item *head = ps->state_items.head_elt;
|
||||
symbol_number prepend_sym =
|
||||
item_number_as_symbol_number (*(head->item - 1));
|
||||
@@ -582,7 +580,7 @@ parser_prepend (parse_state *ps)
|
||||
BITSET_FOR_EACH (biter, head->revs, sin, 0)
|
||||
{
|
||||
parse_state *copy = copy_parse_state (true, ps);
|
||||
ps_si_prepend (copy, state_items + sin);
|
||||
ps_si_prepend (copy, &state_items[sin]);
|
||||
if (SI_TRANSITION (head))
|
||||
ps_derivs_prepend (copy, derivation_new_leaf (prepend_sym));
|
||||
parse_state_list_append (res, copy);
|
||||
|
||||
@@ -113,7 +113,7 @@ int parse_state_length (const parse_state *ps);
|
||||
int parse_state_depth (const parse_state *ps);
|
||||
|
||||
/* returns the linked lists that the parse state is supposed to represent */
|
||||
void parse_state_lists (parse_state *ps, gl_list_t *state_items,
|
||||
void parse_state_lists (parse_state *ps, state_item_list *state_items,
|
||||
derivation_list *derivs);
|
||||
|
||||
/* various functions that return a list of states based off of
|
||||
|
||||
+3
-3
@@ -96,7 +96,7 @@ print_core (struct obstack *oout, state *s)
|
||||
obstack_sgrow (oout, " %empty");
|
||||
|
||||
/* Experimental feature: display the lookahead tokens. */
|
||||
if (report_flag & report_lookahead_tokens
|
||||
if (report_flag & report_lookaheads
|
||||
&& item_number_is_rule_number (*sp1))
|
||||
{
|
||||
/* Find the reduction we are handling. */
|
||||
@@ -104,13 +104,13 @@ print_core (struct obstack *oout, state *s)
|
||||
int redno = state_reduction_find (s, r);
|
||||
|
||||
/* Print them if there are. */
|
||||
if (reds->lookahead_tokens && redno != -1)
|
||||
if (reds->lookaheads && redno != -1)
|
||||
{
|
||||
bitset_iterator biter;
|
||||
int k;
|
||||
char const *sep = "";
|
||||
obstack_sgrow (oout, " [");
|
||||
BITSET_FOR_EACH (biter, reds->lookahead_tokens[redno], k, 0)
|
||||
BITSET_FOR_EACH (biter, reds->lookaheads[redno], k, 0)
|
||||
{
|
||||
obstack_sgrow (oout, sep);
|
||||
obstack_backslash (oout, symbols[k]->tag);
|
||||
|
||||
+29
-22
@@ -86,12 +86,12 @@ print_core (FILE *out, int level, state *s)
|
||||
reductions *reds = s->reductions;
|
||||
int red = state_reduction_find (s, r);
|
||||
/* Print item with lookaheads if there are. */
|
||||
if (reds->lookahead_tokens && red != -1)
|
||||
if (reds->lookaheads && red != -1)
|
||||
{
|
||||
xml_printf (out, level + 1,
|
||||
"<item rule-number=\"%d\" dot=\"%d\">",
|
||||
r->number, sp1 - sp);
|
||||
state_rule_lookahead_tokens_print_xml (s, r,
|
||||
state_rule_lookaheads_print_xml (s, r,
|
||||
out, level + 2);
|
||||
xml_puts (out, level + 1, "</item>");
|
||||
printed = true;
|
||||
@@ -202,26 +202,26 @@ print_errs (FILE *out, int level, state *s)
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------.
|
||||
| Report a reduction of RULE on LOOKAHEAD_TOKEN (which can be 'default'). |
|
||||
| If not ENABLED, the rule is masked by a shift or a reduce (S/R and |
|
||||
| R/R conflicts). |
|
||||
`-------------------------------------------------------------------------*/
|
||||
/*-------------------------------------------------------------------.
|
||||
| Report a reduction of RULE on LOOKAHEAD (which can be 'default'). |
|
||||
| If not ENABLED, the rule is masked by a shift or a reduce (S/R and |
|
||||
| R/R conflicts). |
|
||||
`-------------------------------------------------------------------*/
|
||||
|
||||
static void
|
||||
print_reduction (FILE *out, int level, char const *lookahead_token,
|
||||
print_reduction (FILE *out, int level, char const *lookahead,
|
||||
rule *r, bool enabled)
|
||||
{
|
||||
if (r->number)
|
||||
xml_printf (out, level,
|
||||
"<reduction symbol=\"%s\" rule=\"%d\" enabled=\"%s\"/>",
|
||||
xml_escape (lookahead_token),
|
||||
xml_escape (lookahead),
|
||||
r->number,
|
||||
enabled ? "true" : "false");
|
||||
else
|
||||
xml_printf (out, level,
|
||||
"<reduction symbol=\"%s\" rule=\"accept\" enabled=\"%s\"/>",
|
||||
xml_escape (lookahead_token),
|
||||
xml_escape (lookahead),
|
||||
enabled ? "true" : "false");
|
||||
}
|
||||
|
||||
@@ -258,13 +258,13 @@ print_reductions (FILE *out, int level, state *s)
|
||||
if (default_reduction)
|
||||
report = true;
|
||||
|
||||
if (reds->lookahead_tokens)
|
||||
if (reds->lookaheads)
|
||||
for (i = 0; i < ntokens; i++)
|
||||
{
|
||||
bool count = bitset_test (no_reduce_set, i);
|
||||
|
||||
for (j = 0; j < reds->num; ++j)
|
||||
if (bitset_test (reds->lookahead_tokens[j], i))
|
||||
if (bitset_test (reds->lookaheads[j], i))
|
||||
{
|
||||
if (! count)
|
||||
{
|
||||
@@ -289,14 +289,14 @@ print_reductions (FILE *out, int level, state *s)
|
||||
xml_puts (out, level, "<reductions>");
|
||||
|
||||
/* Report lookahead tokens (or $default) and reductions. */
|
||||
if (reds->lookahead_tokens)
|
||||
if (reds->lookaheads)
|
||||
for (i = 0; i < ntokens; i++)
|
||||
{
|
||||
bool defaulted = false;
|
||||
bool count = bitset_test (no_reduce_set, i);
|
||||
|
||||
for (j = 0; j < reds->num; ++j)
|
||||
if (bitset_test (reds->lookahead_tokens[j], i))
|
||||
if (bitset_test (reds->lookaheads[j], i))
|
||||
{
|
||||
if (! count)
|
||||
{
|
||||
@@ -382,14 +382,17 @@ print_grammar (FILE *out, int level)
|
||||
for (int i = 0; i < max_code + 1; i++)
|
||||
if (token_translations[i] != undeftoken->content->number)
|
||||
{
|
||||
char const *tag = symbols[token_translations[i]]->tag;
|
||||
int precedence = symbols[token_translations[i]]->content->prec;
|
||||
assoc associativity = symbols[token_translations[i]]->content->assoc;
|
||||
symbol const *sym = symbols[token_translations[i]];
|
||||
char const *tag = sym->tag;
|
||||
char const *type = sym->content->type_name;
|
||||
int precedence = sym->content->prec;
|
||||
assoc associativity = sym->content->assoc;
|
||||
xml_indent (out, level + 2);
|
||||
fprintf (out,
|
||||
"<terminal symbol-number=\"%d\" token-number=\"%d\""
|
||||
" name=\"%s\" usefulness=\"%s\"",
|
||||
token_translations[i], i, xml_escape (tag),
|
||||
" name=\"%s\" type=\"%s\" usefulness=\"%s\"",
|
||||
token_translations[i], i, xml_escape_n (0, tag),
|
||||
type ? xml_escape_n (1, type) : "",
|
||||
reduce_token_unused_in_grammar (token_translations[i])
|
||||
? "unused-in-grammar" : "useful");
|
||||
if (precedence)
|
||||
@@ -404,12 +407,16 @@ print_grammar (FILE *out, int level)
|
||||
xml_puts (out, level + 1, "<nonterminals>");
|
||||
for (symbol_number i = ntokens; i < nsyms + nuseless_nonterminals; i++)
|
||||
{
|
||||
char const *tag = symbols[i]->tag;
|
||||
symbol const *sym = symbols[i];
|
||||
char const *tag = sym->tag;
|
||||
char const *type = sym->content->type_name;
|
||||
xml_printf (out, level + 2,
|
||||
"<nonterminal symbol-number=\"%d\" name=\"%s\""
|
||||
" type=\"%s\""
|
||||
" usefulness=\"%s\"/>",
|
||||
i, xml_escape (tag),
|
||||
reduce_nonterminal_useless_in_grammar (symbols[i]->content)
|
||||
i, xml_escape_n (0, tag),
|
||||
type ? xml_escape_n (1, type) : "",
|
||||
reduce_nonterminal_useless_in_grammar (sym->content)
|
||||
? "useless-in-grammar" : "useful");
|
||||
}
|
||||
xml_puts (out, level + 1, "</nonterminals>");
|
||||
|
||||
+22
-21
@@ -90,9 +90,9 @@ print_core (FILE *out, const state *s)
|
||||
previous_rule = r;
|
||||
|
||||
/* Display the lookahead tokens? */
|
||||
if (report_flag & report_lookahead_tokens
|
||||
if (report_flag & report_lookaheads
|
||||
&& item_number_is_rule_number (*sp1))
|
||||
state_rule_lookahead_tokens_print (s, r, out);
|
||||
state_rule_lookaheads_print (s, r, out);
|
||||
fputc ('\n', out);
|
||||
}
|
||||
}
|
||||
@@ -180,19 +180,19 @@ print_errs (FILE *out, const state *s)
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------.
|
||||
| Report a reduction of RULE on LOOKAHEAD_TOKEN (which can be 'default'). |
|
||||
| If not ENABLED, the rule is masked by a shift or a reduce (S/R and |
|
||||
| R/R conflicts). |
|
||||
`-------------------------------------------------------------------------*/
|
||||
/*-------------------------------------------------------------------.
|
||||
| Report a reduction of RULE on LOOKAHEAD (which can be 'default'). |
|
||||
| If not ENABLED, the rule is masked by a shift or a reduce (S/R and |
|
||||
| R/R conflicts). |
|
||||
`-------------------------------------------------------------------*/
|
||||
|
||||
static void
|
||||
print_reduction (FILE *out, size_t width,
|
||||
const char *lookahead_token,
|
||||
const char *lookahead,
|
||||
rule *r, bool enabled)
|
||||
{
|
||||
fprintf (out, " %s", lookahead_token);
|
||||
for (int j = width - mbswidth (lookahead_token, 0); j > 0; --j)
|
||||
fprintf (out, " %s", lookahead);
|
||||
for (int j = width - mbswidth (lookahead, 0); j > 0; --j)
|
||||
fputc (' ', out);
|
||||
if (!enabled)
|
||||
fputc ('[', out);
|
||||
@@ -239,13 +239,13 @@ print_reductions (FILE *out, const state *s)
|
||||
if (default_reduction)
|
||||
width = mbswidth (_("$default"), 0);
|
||||
|
||||
if (reds->lookahead_tokens)
|
||||
if (reds->lookaheads)
|
||||
for (int i = 0; i < ntokens; i++)
|
||||
{
|
||||
bool count = bitset_test (no_reduce_set, i);
|
||||
|
||||
for (int j = 0; j < reds->num; ++j)
|
||||
if (bitset_test (reds->lookahead_tokens[j], i))
|
||||
if (bitset_test (reds->lookaheads[j], i))
|
||||
{
|
||||
if (! count)
|
||||
{
|
||||
@@ -268,7 +268,7 @@ print_reductions (FILE *out, const state *s)
|
||||
bool default_reduction_only = true;
|
||||
|
||||
/* Report lookahead tokens (or $default) and reductions. */
|
||||
if (reds->lookahead_tokens)
|
||||
if (reds->lookaheads)
|
||||
for (int i = 0; i < ntokens; i++)
|
||||
{
|
||||
bool defaulted = false;
|
||||
@@ -277,7 +277,7 @@ print_reductions (FILE *out, const state *s)
|
||||
default_reduction_only = false;
|
||||
|
||||
for (int j = 0; j < reds->num; ++j)
|
||||
if (bitset_test (reds->lookahead_tokens[j], i))
|
||||
if (bitset_test (reds->lookaheads[j], i))
|
||||
{
|
||||
if (! count)
|
||||
{
|
||||
@@ -377,11 +377,11 @@ print_terminal_symbols (FILE *out)
|
||||
for (int i = 0; i < max_code + 1; ++i)
|
||||
if (token_translations[i] != undeftoken->content->number)
|
||||
{
|
||||
const char *tag = symbols[token_translations[i]]->tag;
|
||||
const symbol *sym = symbols[token_translations[i]];
|
||||
const char *tag = sym->tag;
|
||||
fprintf (out, "%4s%s", "", tag);
|
||||
if (symbols[token_translations[i]]->content->type_name)
|
||||
fprintf (out, " <%s>",
|
||||
symbols[token_translations[i]]->content->type_name);
|
||||
if (sym->content->type_name)
|
||||
fprintf (out, " <%s>", sym->content->type_name);
|
||||
fprintf (out, " (%d)", i);
|
||||
|
||||
for (rule_number r = 0; r < nrules; r++)
|
||||
@@ -403,7 +403,8 @@ print_nonterminal_symbols (FILE *out)
|
||||
fprintf (out, "%s\n\n", _("Nonterminals, with rules where they appear"));
|
||||
for (symbol_number i = ntokens; i < nsyms; i++)
|
||||
{
|
||||
const char *tag = symbols[i]->tag;
|
||||
const symbol *sym = symbols[i];
|
||||
const char *tag = sym->tag;
|
||||
bool on_left = false;
|
||||
bool on_right = false;
|
||||
|
||||
@@ -418,9 +419,9 @@ print_nonterminal_symbols (FILE *out)
|
||||
|
||||
int column = 4 + mbswidth (tag, 0);
|
||||
fprintf (out, "%4s%s", "", tag);
|
||||
if (symbols[i]->content->type_name)
|
||||
if (sym->content->type_name)
|
||||
column += fprintf (out, " <%s>",
|
||||
symbols[i]->content->type_name);
|
||||
sym->content->type_name);
|
||||
fprintf (out, " (%d)\n", i);
|
||||
|
||||
if (on_left)
|
||||
|
||||
+32
-34
@@ -144,13 +144,13 @@ init_state_items (void)
|
||||
for (int j = 0; j < s->nitems; ++j)
|
||||
{
|
||||
state_item_set (sidx, s, s->items[j]);
|
||||
state_item *si = state_items + sidx;
|
||||
state_item *si = &state_items[sidx];
|
||||
const rule *r = item_rule (si->item);
|
||||
if (rule_search_idx < red->num && red->rules[rule_search_idx] < r)
|
||||
++rule_search_idx;
|
||||
if (rule_search_idx < red->num && r == red->rules[rule_search_idx])
|
||||
{
|
||||
bitsetv lookahead = red->lookahead_tokens;
|
||||
bitsetv lookahead = red->lookaheads;
|
||||
if (lookahead)
|
||||
si->lookahead = lookahead[rule_search_idx];
|
||||
}
|
||||
@@ -163,7 +163,7 @@ init_state_items (void)
|
||||
state_item_set (sidx, s, off);
|
||||
if (item_number_is_rule_number (ritem[off]))
|
||||
{
|
||||
bitsetv lookahead = red->lookahead_tokens;
|
||||
bitsetv lookahead = red->lookaheads;
|
||||
if (lookahead)
|
||||
state_items[sidx].lookahead = lookahead[rule_search_idx];
|
||||
++rule_search_idx;
|
||||
@@ -211,7 +211,7 @@ init_trans (void)
|
||||
for (int j = 0; j < t->num; ++j)
|
||||
if (!TRANSITION_IS_DISABLED (t, j))
|
||||
hash_xinsert (transition_set, t->states[j]);
|
||||
for (int j = state_item_map[i]; j < state_item_map[i + 1]; ++j)
|
||||
for (state_item_number j = state_item_map[i]; j < state_item_map[i + 1]; ++j)
|
||||
{
|
||||
item_number *item = state_items[j].item;
|
||||
if (item_number_is_rule_number (*item))
|
||||
@@ -222,16 +222,14 @@ init_trans (void)
|
||||
// find the item in the destination state that corresponds
|
||||
// to the transition of item
|
||||
for (int k = 0; k < dst->nitems; ++k)
|
||||
{
|
||||
if (item + 1 == ritem + dst->items[k])
|
||||
{
|
||||
state_item_number dstSI =
|
||||
state_item_index_lookup (dst->number, k);
|
||||
if (item + 1 == ritem + dst->items[k])
|
||||
{
|
||||
state_item_number dstSI =
|
||||
state_item_index_lookup (dst->number, k);
|
||||
|
||||
state_items[j].trans = dstSI;
|
||||
bitset_set (state_items[dstSI].revs, j);
|
||||
break;
|
||||
}
|
||||
state_items[j].trans = dstSI;
|
||||
bitset_set (state_items[dstSI].revs, j);
|
||||
break;
|
||||
}
|
||||
}
|
||||
hash_free (transition_set);
|
||||
@@ -250,10 +248,10 @@ init_prods (void)
|
||||
|
||||
// Add the nitems of state to skip to the production portion
|
||||
// of that state's state_items
|
||||
for (int j = state_item_map[i] + s->nitems;
|
||||
for (state_item_number j = state_item_map[i] + s->nitems;
|
||||
j < state_item_map[i + 1]; ++j)
|
||||
{
|
||||
state_item *src = state_items + j;
|
||||
state_item *src = &state_items[j];
|
||||
item_number *item = src->item;
|
||||
symbol_number lhs = item_rule (item)->lhs->number;
|
||||
bitset itms = hash_pair_lookup (closure_map, lhs);
|
||||
@@ -266,9 +264,9 @@ init_prods (void)
|
||||
}
|
||||
// For each item with a dot followed by a nonterminal,
|
||||
// try to create a production edge.
|
||||
for (int j = state_item_map[i]; j < state_item_map[i + 1]; ++j)
|
||||
for (state_item_number j = state_item_map[i]; j < state_item_map[i + 1]; ++j)
|
||||
{
|
||||
state_item *src = state_items + j;
|
||||
state_item *src = &state_items[j];
|
||||
item_number item = *(src->item);
|
||||
// Skip reduce items and items with terminals after the dot
|
||||
if (item_number_is_rule_number (item) || ISTOKEN (item))
|
||||
@@ -301,12 +299,12 @@ gen_lookaheads (void)
|
||||
{
|
||||
for (state_item_number i = 0; i < nstate_items; ++i)
|
||||
{
|
||||
state_item *si = state_items + i;
|
||||
state_item *si = &state_items[i];
|
||||
if (item_number_is_symbol_number (*(si->item)) || !si->lookahead)
|
||||
continue;
|
||||
|
||||
bitset lookahead = si->lookahead;
|
||||
gl_list_t queue =
|
||||
state_item_list queue =
|
||||
gl_list_create (GL_LINKED_LIST, NULL, NULL, NULL, true, 1,
|
||||
(const void **) &si);
|
||||
|
||||
@@ -339,7 +337,7 @@ init_firsts (void)
|
||||
firsts = bitsetv_create (nnterms, nsyms, BITSET_FIXED);
|
||||
for (rule_number i = 0; i < nrules; ++i)
|
||||
{
|
||||
rule *r = rules + i;
|
||||
rule *r = &rules[i];
|
||||
item_number *n = r->rhs;
|
||||
// Iterate through nullable nonterminals to try to find a terminal.
|
||||
while (item_number_is_symbol_number (*n) && ISVAR (*n)
|
||||
@@ -357,7 +355,7 @@ init_firsts (void)
|
||||
change = false;
|
||||
for (rule_number i = 0; i < nrules; ++i)
|
||||
{
|
||||
rule *r = rules + i;
|
||||
rule *r = &rules[i];
|
||||
symbol_number lhs = r->lhs->number;
|
||||
bitset f_lhs = FIRSTS (lhs);
|
||||
for (item_number *n = r->rhs;
|
||||
@@ -392,7 +390,7 @@ disable_state_item (state_item *si)
|
||||
static void
|
||||
prune_forward (const state_item *si)
|
||||
{
|
||||
gl_list_t queue =
|
||||
state_item_list queue =
|
||||
gl_list_create (GL_LINKED_LIST, NULL, NULL, NULL, true, 1,
|
||||
(const void **) &si);
|
||||
|
||||
@@ -401,7 +399,7 @@ prune_forward (const state_item *si)
|
||||
state_item *dsi = (state_item *) gl_list_get_at (queue, 0);
|
||||
gl_list_remove_at (queue, 0);
|
||||
if (dsi->trans >= 0)
|
||||
gl_list_add_last (queue, state_items + dsi->trans);
|
||||
gl_list_add_last (queue, &state_items[dsi->trans]);
|
||||
|
||||
if (dsi->prods)
|
||||
{
|
||||
@@ -409,7 +407,7 @@ prune_forward (const state_item *si)
|
||||
state_item_number sin;
|
||||
BITSET_FOR_EACH (biter, dsi->prods, sin, 0)
|
||||
{
|
||||
const state_item *prod = state_items + sin;
|
||||
const state_item *prod = &state_items[sin];
|
||||
bitset_reset (prod->revs, dsi - state_items);
|
||||
if (bitset_empty_p (prod->revs))
|
||||
gl_list_add_last (queue, prod);
|
||||
@@ -427,7 +425,7 @@ prune_forward (const state_item *si)
|
||||
static void
|
||||
prune_backward (const state_item *si)
|
||||
{
|
||||
gl_list_t queue =
|
||||
state_item_list queue =
|
||||
gl_list_create (GL_LINKED_LIST, NULL, NULL, NULL, true, 1,
|
||||
(const void **) &si);
|
||||
|
||||
@@ -441,7 +439,7 @@ prune_backward (const state_item *si)
|
||||
{
|
||||
if (SI_DISABLED (sin))
|
||||
continue;
|
||||
state_item *rev = state_items + sin;
|
||||
state_item *rev = &state_items[sin];
|
||||
if (rev->prods)
|
||||
{
|
||||
bitset_reset (rev->prods, dsi - state_items);
|
||||
@@ -466,7 +464,7 @@ prune_disabled_paths (void)
|
||||
{
|
||||
for (int i = nstate_items - 1; i >= 0; --i)
|
||||
{
|
||||
state_item *si = state_items + i;
|
||||
state_item *si = &state_items[i];
|
||||
if (si->trans == -1 && item_number_is_symbol_number (*si->item))
|
||||
{
|
||||
prune_forward (si);
|
||||
@@ -494,9 +492,9 @@ state_items_report (void)
|
||||
for (state_number i = 0; i < nstates; ++i)
|
||||
{
|
||||
printf ("State %d:\n", i);
|
||||
for (int j = state_item_map[i]; j < state_item_map[i + 1]; ++j)
|
||||
for (state_item_number j = state_item_map[i]; j < state_item_map[i + 1]; ++j)
|
||||
{
|
||||
state_item *si = state_items + j;
|
||||
state_item *si = &state_items[j];
|
||||
item_print (si->item, NULL, stdout);
|
||||
if (SI_DISABLED (j))
|
||||
{
|
||||
@@ -508,7 +506,7 @@ state_items_report (void)
|
||||
if (si->trans >= 0)
|
||||
{
|
||||
fputs (" -> ", stdout);
|
||||
print_state_item (state_items + si->trans, stdout, "");
|
||||
print_state_item (&state_items[si->trans], stdout, "");
|
||||
}
|
||||
|
||||
bitset sets[2] = { si->prods, si->revs };
|
||||
@@ -523,7 +521,7 @@ state_items_report (void)
|
||||
BITSET_FOR_EACH (biter, b, sin, 0)
|
||||
{
|
||||
fputs (txt[seti], stdout);
|
||||
print_state_item (state_items + sin, stdout, "");
|
||||
print_state_item (&state_items[sin], stdout, "");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -562,10 +560,10 @@ state_items_init (void)
|
||||
void
|
||||
state_items_free (void)
|
||||
{
|
||||
for (int i = 0; i < nstate_items; ++i)
|
||||
for (state_item_number i = 0; i < nstate_items; ++i)
|
||||
if (!SI_DISABLED (i))
|
||||
{
|
||||
state_item *si = state_items + i;
|
||||
state_item *si = &state_items[i];
|
||||
if (si->prods)
|
||||
bitset_free (si->prods);
|
||||
bitset_free (si->revs);
|
||||
@@ -594,5 +592,5 @@ production_allowed (const state_item *si, const state_item *next)
|
||||
if (prec1 == prec2 && s1->assoc == left_assoc)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
+12
-8
@@ -28,16 +28,16 @@
|
||||
# include "state.h"
|
||||
|
||||
/* Initializes a graph connecting (state, production item) pairs to
|
||||
pairs they can make a transition or production step to. This graph
|
||||
pairs they can make a transition or production step to. This graph
|
||||
is used to search for paths that represent counterexamples of some
|
||||
conflict.
|
||||
|
||||
state_items is an array of state state-item pairs ordered by state.
|
||||
state_item_map maps state numbers to the first item which
|
||||
corresponds to it in the array. A state's portion in state_items
|
||||
begins with its items in the same order as it was in the
|
||||
state. This is then followed by productions from the closure of the
|
||||
state in order by rule.
|
||||
corresponds to it in the array. A state's portion in state_items
|
||||
begins with its items in the same order as it was in the state.
|
||||
This is then followed by productions from the closure of the state
|
||||
in order by rule.
|
||||
|
||||
There are two type of edges in this graph transitions and
|
||||
productions. Transitions are the same as transitions from the
|
||||
@@ -53,9 +53,9 @@
|
||||
production edges, and all others will have reverse transition
|
||||
edges. */
|
||||
|
||||
# define SI_DISABLED(sin) (state_items[sin].trans == -2)
|
||||
# define SI_PRODUCTION(si) ((si) == state_items || *((si)->item - 1) < 0)
|
||||
# define SI_TRANSITION(si) ((si) != state_items && *((si)->item - 1) >= 0)
|
||||
# define SI_DISABLED(Sin) (state_items[Sin].trans == -2)
|
||||
# define SI_PRODUCTION(Si) ((Si) == state_items || *((Si)->item - 1) < 0)
|
||||
# define SI_TRANSITION(Si) ((Si) != state_items && *((Si)->item - 1) >= 0)
|
||||
|
||||
typedef int state_item_number;
|
||||
|
||||
@@ -69,6 +69,9 @@ typedef struct
|
||||
bitset lookahead;
|
||||
} state_item;
|
||||
|
||||
// A path of state-items.
|
||||
typedef gl_list_t state_item_list;
|
||||
|
||||
extern bitsetv firsts;
|
||||
# define FIRSTS(sym) firsts[(sym) - ntokens]
|
||||
|
||||
@@ -92,6 +95,7 @@ void state_items_free (void);
|
||||
|
||||
bool production_allowed (const state_item *si, const state_item *next);
|
||||
|
||||
// Iterating on a state_item_list.
|
||||
static inline bool
|
||||
state_item_list_next (gl_list_iterator_t *it, state_item **si)
|
||||
{
|
||||
|
||||
+7
-7
@@ -101,7 +101,7 @@ reductions_new (int num, rule **reds)
|
||||
size_t rules_size = num * sizeof *reds;
|
||||
reductions *res = xmalloc (offsetof (reductions, rules) + rules_size);
|
||||
res->num = num;
|
||||
res->lookahead_tokens = NULL;
|
||||
res->lookaheads = NULL;
|
||||
memcpy (res->rules, reds, rules_size);
|
||||
return res;
|
||||
}
|
||||
@@ -260,20 +260,20 @@ state_errs_set (state *s, int num, symbol **tokens)
|
||||
`--------------------------------------------------*/
|
||||
|
||||
void
|
||||
state_rule_lookahead_tokens_print (state const *s, rule const *r, FILE *out)
|
||||
state_rule_lookaheads_print (state const *s, rule const *r, FILE *out)
|
||||
{
|
||||
/* Find the reduction we are handling. */
|
||||
reductions *reds = s->reductions;
|
||||
int red = state_reduction_find (s, r);
|
||||
|
||||
/* Print them if there are. */
|
||||
if (reds->lookahead_tokens && red != -1)
|
||||
if (reds->lookaheads && red != -1)
|
||||
{
|
||||
bitset_iterator biter;
|
||||
int k;
|
||||
char const *sep = "";
|
||||
fprintf (out, " [");
|
||||
BITSET_FOR_EACH (biter, reds->lookahead_tokens[red], k, 0)
|
||||
BITSET_FOR_EACH (biter, reds->lookaheads[red], k, 0)
|
||||
{
|
||||
fprintf (out, "%s%s", sep, symbols[k]->tag);
|
||||
sep = ", ";
|
||||
@@ -283,7 +283,7 @@ state_rule_lookahead_tokens_print (state const *s, rule const *r, FILE *out)
|
||||
}
|
||||
|
||||
void
|
||||
state_rule_lookahead_tokens_print_xml (state const *s, rule const *r,
|
||||
state_rule_lookaheads_print_xml (state const *s, rule const *r,
|
||||
FILE *out, int level)
|
||||
{
|
||||
/* Find the reduction we are handling. */
|
||||
@@ -291,12 +291,12 @@ state_rule_lookahead_tokens_print_xml (state const *s, rule const *r,
|
||||
int red = state_reduction_find (s, r);
|
||||
|
||||
/* Print them if there are. */
|
||||
if (reds->lookahead_tokens && red != -1)
|
||||
if (reds->lookaheads && red != -1)
|
||||
{
|
||||
bitset_iterator biter;
|
||||
int k;
|
||||
xml_puts (out, level, "<lookaheads>");
|
||||
BITSET_FOR_EACH (biter, reds->lookahead_tokens[red], k, 0)
|
||||
BITSET_FOR_EACH (biter, reds->lookaheads[red], k, 0)
|
||||
{
|
||||
xml_printf (out, level + 1, "<symbol>%s</symbol>",
|
||||
xml_escape (symbols[k]->tag));
|
||||
|
||||
+5
-5
@@ -62,7 +62,7 @@
|
||||
|
||||
Each reductions structure describes the possible reductions at the
|
||||
state whose number is in the number field. rules is an array of
|
||||
num rules. lookahead_tokens is an array of bitsets, one per rule.
|
||||
num rules. lookaheads is an array of bitsets, one per rule.
|
||||
|
||||
Conflict resolution can decide that certain tokens in certain
|
||||
states should explicitly be errors (for implementing %nonassoc).
|
||||
@@ -187,7 +187,7 @@ errs *errs_new (int num, symbol **tokens);
|
||||
typedef struct
|
||||
{
|
||||
int num;
|
||||
bitset *lookahead_tokens;
|
||||
bitset *lookaheads;
|
||||
/* Sorted ascendingly on rule number. */
|
||||
rule *rules[1];
|
||||
} reductions;
|
||||
@@ -254,9 +254,9 @@ void state_errs_set (state *s, int num, symbol **errors);
|
||||
|
||||
/* Print on OUT all the lookahead tokens such that this STATE wants to
|
||||
reduce R. */
|
||||
void state_rule_lookahead_tokens_print (state const *s, rule const *r, FILE *out);
|
||||
void state_rule_lookahead_tokens_print_xml (state const *s, rule const *r,
|
||||
FILE *out, int level);
|
||||
void state_rule_lookaheads_print (state const *s, rule const *r, FILE *out);
|
||||
void state_rule_lookaheads_print_xml (state const *s, rule const *r,
|
||||
FILE *out, int level);
|
||||
|
||||
/* Create/destroy the states hash table. */
|
||||
void state_hash_new (void);
|
||||
|
||||
+4
-4
@@ -200,7 +200,7 @@ conflict_row (state *s)
|
||||
/* Find all reductions for token J, and record all that do not
|
||||
match ACTROW[J]. */
|
||||
for (int i = 0; i < reds->num; i += 1)
|
||||
if (bitset_test (reds->lookahead_tokens[i], j)
|
||||
if (bitset_test (reds->lookaheads[i], j)
|
||||
&& (actrow[j]
|
||||
!= rule_number_as_item_number (reds->rules[i]->number)))
|
||||
{
|
||||
@@ -247,7 +247,7 @@ action_row (state *s)
|
||||
|
||||
reductions *reds = s->reductions;
|
||||
bool conflicted = false;
|
||||
if (reds->lookahead_tokens)
|
||||
if (reds->lookaheads)
|
||||
/* loop over all the rules available here which require
|
||||
lookahead (in reverse order to give precedence to the first
|
||||
rule) */
|
||||
@@ -257,7 +257,7 @@ action_row (state *s)
|
||||
{
|
||||
bitset_iterator biter;
|
||||
int j;
|
||||
BITSET_FOR_EACH (biter, reds->lookahead_tokens[i], j, 0)
|
||||
BITSET_FOR_EACH (biter, reds->lookaheads[i], j, 0)
|
||||
{
|
||||
/* and record this rule as the rule to use if that
|
||||
token follows. */
|
||||
@@ -308,7 +308,7 @@ action_row (state *s)
|
||||
}
|
||||
|
||||
/* Turn off default reductions where requested by the user. See
|
||||
state_lookahead_tokens_count in lalr.c to understand when states are
|
||||
state_lookaheads_count in lalr.c to understand when states are
|
||||
labeled as consistent. */
|
||||
{
|
||||
char *default_reductions =
|
||||
|
||||
+55
-17
@@ -865,8 +865,14 @@ State 5
|
||||
1 exp: exp OP exp .
|
||||
1 exp: exp . OP exp
|
||||
Example exp OP exp . OP exp
|
||||
First derivation exp ::=[ exp ::=[ exp OP exp . ] OP exp ]
|
||||
Second derivation exp ::=[ exp OP exp ::=[ exp . OP exp ] ]
|
||||
Shift derivation
|
||||
exp
|
||||
`-> exp OP exp
|
||||
`-> exp . OP exp
|
||||
Reduce derivation
|
||||
exp
|
||||
`-> exp OP exp
|
||||
`-> exp OP exp .
|
||||
|
||||
]])
|
||||
|
||||
@@ -1119,7 +1125,7 @@ m4_popdef([AT_TEST])
|
||||
# else.
|
||||
|
||||
AT_SETUP([Defaulted Conflicted Reduction])
|
||||
AT_KEYWORDS([report])
|
||||
AT_KEYWORDS([cex report])
|
||||
|
||||
AT_DATA([input.y],
|
||||
[[%%
|
||||
@@ -1207,8 +1213,14 @@ State 1
|
||||
3 num: '0' .
|
||||
4 id: '0' .
|
||||
Example '0' .
|
||||
First derivation exp ::=[ num ::=[ '0' . ] ]
|
||||
Second derivation exp ::=[ id ::=[ '0' . ] ]
|
||||
First derivation
|
||||
exp
|
||||
`-> num
|
||||
`-> '0' .
|
||||
Second derivation
|
||||
exp
|
||||
`-> id
|
||||
`-> '0' .
|
||||
|
||||
|
||||
|
||||
@@ -1579,6 +1591,8 @@ AT_CLEANUP
|
||||
|
||||
AT_SETUP([[Unreachable States After Conflict Resolution]])
|
||||
|
||||
AT_KEYWORDS([cex report])
|
||||
|
||||
# If conflict resolution makes states unreachable, remove those states, report
|
||||
# rules that are then unused, and don't report conflicts in those states. Test
|
||||
# what happens when a nonterminal becomes useless as a result of state removal
|
||||
@@ -1753,18 +1767,30 @@ State 4
|
||||
Shift/reduce conflict on token 'a':
|
||||
10 reported_conflicts: . %empty
|
||||
8 reported_conflicts: . 'a'
|
||||
First example resolved_conflict . 'a'
|
||||
First derivation start ::=[ resolved_conflict reported_conflicts ::=[ . ] 'a' ]
|
||||
Second example resolved_conflict . 'a' 'a'
|
||||
Second derivation start ::=[ resolved_conflict reported_conflicts ::=[ . 'a' ] 'a' ]
|
||||
First example resolved_conflict . 'a' 'a'
|
||||
Shift derivation
|
||||
start
|
||||
`-> resolved_conflict reported_conflicts 'a'
|
||||
`-> . 'a'
|
||||
Second example resolved_conflict . 'a'
|
||||
Reduce derivation
|
||||
start
|
||||
`-> resolved_conflict reported_conflicts 'a'
|
||||
`-> .
|
||||
|
||||
Shift/reduce conflict on token 'a':
|
||||
10 reported_conflicts: . %empty
|
||||
9 reported_conflicts: . 'a'
|
||||
First example resolved_conflict . 'a'
|
||||
First derivation start ::=[ resolved_conflict reported_conflicts ::=[ . ] 'a' ]
|
||||
Second example resolved_conflict . 'a' 'a'
|
||||
Second derivation start ::=[ resolved_conflict reported_conflicts ::=[ . 'a' ] 'a' ]
|
||||
First example resolved_conflict . 'a' 'a'
|
||||
Shift derivation
|
||||
start
|
||||
`-> resolved_conflict reported_conflicts 'a'
|
||||
`-> . 'a'
|
||||
Second example resolved_conflict . 'a'
|
||||
Reduce derivation
|
||||
start
|
||||
`-> resolved_conflict reported_conflicts 'a'
|
||||
`-> .
|
||||
|
||||
|
||||
|
||||
@@ -1781,8 +1807,12 @@ State 5
|
||||
8 reported_conflicts: 'a' .
|
||||
9 reported_conflicts: 'a' .
|
||||
Example 'a' .
|
||||
First derivation reported_conflicts ::=[ 'a' . ]
|
||||
Second derivation reported_conflicts ::=[ 'a' . ]
|
||||
First derivation
|
||||
reported_conflicts
|
||||
`-> 'a' .
|
||||
Second derivation
|
||||
reported_conflicts
|
||||
`-> 'a' .
|
||||
|
||||
|
||||
|
||||
@@ -1904,6 +1934,8 @@ AT_CLEANUP
|
||||
|
||||
AT_SETUP([[%nonassoc error actions for multiple reductions in a state]])
|
||||
|
||||
AT_KEYWORDS([cex report])
|
||||
|
||||
AT_DATA([[input.y]],
|
||||
[[%nonassoc 'a' 'b' 'c'
|
||||
%%
|
||||
@@ -1965,8 +1997,14 @@ AT_CHECK([[cat input.output | sed -n '/^State 0$/,/^State 1$/p']], 0,
|
||||
12 empty_c2: . %empty
|
||||
13 empty_c3: . %empty
|
||||
Example . 'c'
|
||||
First derivation start ::=[ empty_c2 ::=[ . ] 'c' ]
|
||||
Second derivation start ::=[ empty_c3 ::=[ . ] 'c' ]
|
||||
First derivation
|
||||
start
|
||||
`-> empty_c2 'c'
|
||||
`-> .
|
||||
Second derivation
|
||||
start
|
||||
`-> empty_c3 'c'
|
||||
`-> .
|
||||
|
||||
|
||||
|
||||
|
||||
+535
-105
@@ -17,13 +17,23 @@
|
||||
|
||||
AT_BANNER([[Counterexamples.]])
|
||||
|
||||
# AT_BISON_CHECK_CEX(TREE, FLAT)
|
||||
# ------------------------------
|
||||
m4_define([AT_BISON_CHECK_CEX],
|
||||
[AT_DATA([experr], [$4])
|
||||
sed -e ['s/time limit exceeded: [0-9][.0-9]*/time limit exceeded: XXX/g'] \
|
||||
experr >expout
|
||||
AT_BISON_CHECK([-Wcounterexamples $1], [$2], [$3], [stderr])
|
||||
[AT_KEYWORDS([cex])
|
||||
|
||||
AT_BISON_CHECK([-Wcounterexamples input.y], [0], [], [stderr])
|
||||
# FIXME: Avoid trailing white spaces.
|
||||
AT_CHECK([[sed -e 's/time limit exceeded: [0-9][.0-9]*/time limit exceeded: XXX/g;s/ *$//;' stderr]],
|
||||
[], [$1])
|
||||
|
||||
m4_pushdef([AT_SET_ENV_IF],
|
||||
[[YYFLAT=1; export YYFLAT;]]m4_defn([AT_SET_ENV_IF]))
|
||||
AT_BISON_CHECK([-Wcounterexamples input.y], [0], [], [stderr])
|
||||
AT_CHECK([[sed -e 's/time limit exceeded: [0-9][.0-9]*/time limit exceeded: XXX/g' stderr]],
|
||||
[], [expout])
|
||||
[], [$2])
|
||||
m4_popdef([AT_SET_ENV_IF])
|
||||
|
||||
])
|
||||
|
||||
## --------------------- ##
|
||||
@@ -31,7 +41,6 @@ AT_CHECK([[sed -e 's/time limit exceeded: [0-9][.0-9]*/time limit exceeded: XXX/
|
||||
## --------------------- ##
|
||||
|
||||
AT_SETUP([Unifying S/R])
|
||||
AT_KEYWORDS([cex])
|
||||
|
||||
AT_DATA([[input.y]],
|
||||
[[%token A B C
|
||||
@@ -43,12 +52,26 @@ x: B | B C;
|
||||
y: A | A B;
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK_CEX([input.y], [], [],
|
||||
AT_BISON_CHECK_CEX(
|
||||
[[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
|
||||
Shift/reduce conflict on token B:
|
||||
Example A . B C
|
||||
First derivation s ::=[ a ::=[ A . ] x ::=[ B C ] ]
|
||||
Second derivation s ::=[ y ::=[ A . B ] c ::=[ C ] ]
|
||||
Shift derivation
|
||||
s
|
||||
`-> y c
|
||||
`-> A . B `-> C
|
||||
Reduce derivation
|
||||
s
|
||||
`-> a x
|
||||
`-> A . `-> B C
|
||||
|
||||
input.y:4.4: warning: rule useless in parser due to conflicts [-Wother]
|
||||
]],
|
||||
[[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
|
||||
Shift/reduce conflict on token B:
|
||||
Example A . B C
|
||||
Shift derivation s -> [ y -> [ A . B ] c -> [ C ] ]
|
||||
Reduce derivation s -> [ a -> [ A . ] x -> [ B C ] ]
|
||||
|
||||
input.y:4.4: warning: rule useless in parser due to conflicts [-Wother]
|
||||
]])
|
||||
@@ -60,7 +83,6 @@ AT_CLEANUP
|
||||
## ------------------- ##
|
||||
|
||||
AT_SETUP([Deep Unifying S/R])
|
||||
AT_KEYWORDS([cex])
|
||||
|
||||
AT_DATA([[input.y]],
|
||||
[[%token A B C
|
||||
@@ -72,17 +94,49 @@ a: A | A a;
|
||||
bc: B bc C | B C;
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK_CEX([input.y], [], [],
|
||||
AT_BISON_CHECK_CEX(
|
||||
[[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
|
||||
Shift/reduce conflict on token B:
|
||||
Example A . B C
|
||||
First derivation s ::=[ a ::=[ A . ] bc ::=[ B C ] ]
|
||||
Second derivation s ::=[ ac ::=[ A ac ::=[ b ::=[ . B ] ] C ] ]
|
||||
Shift derivation
|
||||
s
|
||||
`-> ac
|
||||
`-> A ac C
|
||||
`-> b
|
||||
`-> . B
|
||||
Reduce derivation
|
||||
s
|
||||
`-> a bc
|
||||
`-> A . `-> B C
|
||||
|
||||
Shift/reduce conflict on token B:
|
||||
Example A A . B B C C
|
||||
First derivation s ::=[ a ::=[ A a ::=[ A . ] ] bc ::=[ B bc ::=[ B C ] C ] ]
|
||||
Second derivation s ::=[ ac ::=[ A ac ::=[ A ac ::=[ b ::=[ . b ::=[ B B ] ] ] C ] C ] ]
|
||||
Shift derivation
|
||||
s
|
||||
`-> ac
|
||||
`-> A ac C
|
||||
`-> A ac C
|
||||
`-> b
|
||||
`-> . b
|
||||
`-> B B
|
||||
Reduce derivation
|
||||
s
|
||||
`-> a bc
|
||||
`-> A a `-> B bc C
|
||||
`-> A . `-> B C
|
||||
|
||||
input.y:6.4: warning: rule useless in parser due to conflicts [-Wother]
|
||||
]],
|
||||
[[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
|
||||
Shift/reduce conflict on token B:
|
||||
Example A . B C
|
||||
Shift derivation s -> [ ac -> [ A ac -> [ b -> [ . B ] ] C ] ]
|
||||
Reduce derivation s -> [ a -> [ A . ] bc -> [ B C ] ]
|
||||
|
||||
Shift/reduce conflict on token B:
|
||||
Example A A . B B C C
|
||||
Shift derivation s -> [ ac -> [ A ac -> [ A ac -> [ b -> [ . b -> [ B B ] ] ] C ] C ] ]
|
||||
Reduce derivation s -> [ a -> [ A a -> [ A . ] ] bc -> [ B bc -> [ B C ] C ] ]
|
||||
|
||||
input.y:6.4: warning: rule useless in parser due to conflicts [-Wother]
|
||||
]])
|
||||
@@ -94,7 +148,6 @@ AT_CLEANUP
|
||||
## ------------------------------------ ##
|
||||
|
||||
AT_SETUP([S/R Conflict with Nullable Symbols])
|
||||
AT_KEYWORDS([cex])
|
||||
|
||||
AT_DATA([[input.y]],
|
||||
[[%token A B X Y
|
||||
@@ -107,18 +160,50 @@ y: %empty | Y y;
|
||||
xby: B | X xby Y;
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK_CEX([input.y], [], [],
|
||||
AT_BISON_CHECK_CEX(
|
||||
[[input.y: warning: 2 shift/reduce conflicts [-Wconflicts-sr]
|
||||
Shift/reduce conflict on token B:
|
||||
Example A . B
|
||||
First derivation s ::=[ ax ::=[ A x ::=[ . ] ] by ::=[ B y ::=[ ] ] ]
|
||||
Second derivation s ::=[ A xby ::=[ . B ] ]
|
||||
Shift derivation
|
||||
s
|
||||
`-> A xby
|
||||
`-> . B
|
||||
Reduce derivation
|
||||
s
|
||||
`-> ax by
|
||||
`-> A x `-> B y
|
||||
`-> . `-> %empty
|
||||
|
||||
Shift/reduce conflict on token B:
|
||||
First example A X . B y $end
|
||||
First derivation $accept ::=[ s ::=[ ax ::=[ A x ::=[ X x ::=[ . ] ] ] by ::=[ B y ] ] $end ]
|
||||
Second example A X . B Y $end
|
||||
Second derivation $accept ::=[ s ::=[ A xby ::=[ X xby ::=[ . B ] Y ] ] $end ]
|
||||
First example A X . B Y $end
|
||||
Shift derivation
|
||||
$accept
|
||||
`-> s $end
|
||||
`-> A xby
|
||||
`-> X xby Y
|
||||
`-> . B
|
||||
Second example A X . B y $end
|
||||
Reduce derivation
|
||||
$accept
|
||||
`-> s $end
|
||||
`-> ax by
|
||||
`-> A x `-> B y
|
||||
`-> X x
|
||||
`-> .
|
||||
|
||||
input.y:5.4-9: warning: rule useless in parser due to conflicts [-Wother]
|
||||
]],
|
||||
[[input.y: warning: 2 shift/reduce conflicts [-Wconflicts-sr]
|
||||
Shift/reduce conflict on token B:
|
||||
Example A . B
|
||||
Shift derivation s -> [ A xby -> [ . B ] ]
|
||||
Reduce derivation s -> [ ax -> [ A x -> [ . ] ] by -> [ B y -> [ ] ] ]
|
||||
|
||||
Shift/reduce conflict on token B:
|
||||
First example A X . B Y $end
|
||||
Shift derivation $accept -> [ s -> [ A xby -> [ X xby -> [ . B ] Y ] ] $end ]
|
||||
Second example A X . B y $end
|
||||
Reduce derivation $accept -> [ s -> [ ax -> [ A x -> [ X x -> [ . ] ] ] by -> [ B y ] ] $end ]
|
||||
|
||||
input.y:5.4-9: warning: rule useless in parser due to conflicts [-Wother]
|
||||
]])
|
||||
@@ -130,7 +215,6 @@ AT_CLEANUP
|
||||
## ---------------------------- ##
|
||||
|
||||
AT_SETUP([Non-unifying Ambiguous S/R])
|
||||
AT_KEYWORDS([cex])
|
||||
|
||||
AT_DATA([[input.y]],
|
||||
[[%token A B C D E
|
||||
@@ -143,13 +227,32 @@ cd: C D;
|
||||
bc: B C;
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK_CEX([input.y], [], [],
|
||||
AT_BISON_CHECK_CEX(
|
||||
[[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
|
||||
Shift/reduce conflict on token C:
|
||||
First example B . C D $end
|
||||
First derivation $accept ::=[ g ::=[ x ::=[ b ::=[ B . ] cd ::=[ C D ] ] ] $end ]
|
||||
Second example B . C $end
|
||||
Second derivation $accept ::=[ g ::=[ x ::=[ bc ::=[ B . C ] ] ] $end ]
|
||||
First example B . C $end
|
||||
Shift derivation
|
||||
$accept
|
||||
`-> g $end
|
||||
`-> x
|
||||
`-> bc
|
||||
`-> B . C
|
||||
Second example B . C D $end
|
||||
Reduce derivation
|
||||
$accept
|
||||
`-> g $end
|
||||
`-> x
|
||||
`-> b cd
|
||||
`-> B . `-> C D
|
||||
|
||||
input.y:6.4: warning: rule useless in parser due to conflicts [-Wother]
|
||||
]],
|
||||
[[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
|
||||
Shift/reduce conflict on token C:
|
||||
First example B . C $end
|
||||
Shift derivation $accept -> [ g -> [ x -> [ bc -> [ B . C ] ] ] $end ]
|
||||
Second example B . C D $end
|
||||
Reduce derivation $accept -> [ g -> [ x -> [ b -> [ B . ] cd -> [ C D ] ] ] $end ]
|
||||
|
||||
input.y:6.4: warning: rule useless in parser due to conflicts [-Wother]
|
||||
]])
|
||||
@@ -161,7 +264,6 @@ AT_CLEANUP
|
||||
## ------------------------------ ##
|
||||
|
||||
AT_SETUP([Non-unifying Unambiguous S/R])
|
||||
AT_KEYWORDS([cex])
|
||||
|
||||
AT_DATA([[input.y]],
|
||||
[[%token A B
|
||||
@@ -172,13 +274,32 @@ x: A;
|
||||
y: A A B;
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK_CEX([input.y], [], [],
|
||||
AT_BISON_CHECK_CEX(
|
||||
[[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
|
||||
Shift/reduce conflict on token A:
|
||||
First example A . A $end
|
||||
First derivation $accept ::=[ s ::=[ s ::=[ t ::=[ x ::=[ A . ] ] ] t ::=[ x ::=[ A ] ] ] $end ]
|
||||
Second example A . A B $end
|
||||
Second derivation $accept ::=[ s ::=[ t ::=[ y ::=[ A . A B ] ] ] $end ]
|
||||
First example A . A B $end
|
||||
Shift derivation
|
||||
$accept
|
||||
`-> s $end
|
||||
`-> t
|
||||
`-> y
|
||||
`-> A . A B
|
||||
Second example A . A $end
|
||||
Reduce derivation
|
||||
$accept
|
||||
`-> s $end
|
||||
`-> s t
|
||||
`-> t `-> x
|
||||
`-> x `-> A
|
||||
`-> A .
|
||||
|
||||
]],
|
||||
[[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
|
||||
Shift/reduce conflict on token A:
|
||||
First example A . A B $end
|
||||
Shift derivation $accept -> [ s -> [ t -> [ y -> [ A . A B ] ] ] $end ]
|
||||
Second example A . A $end
|
||||
Reduce derivation $accept -> [ s -> [ s -> [ t -> [ x -> [ A . ] ] ] t -> [ x -> [ A ] ] ] $end ]
|
||||
|
||||
]])
|
||||
|
||||
@@ -189,7 +310,6 @@ AT_CLEANUP
|
||||
## ----------------------- ##
|
||||
|
||||
AT_SETUP([S/R after first token])
|
||||
AT_KEYWORDS([cex])
|
||||
|
||||
AT_DATA([[input.y]],
|
||||
[[%token A B X Y
|
||||
@@ -205,18 +325,48 @@ xy: X Y;
|
||||
y: Y;
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK_CEX([input.y], [], [],
|
||||
AT_BISON_CHECK_CEX(
|
||||
[[input.y: warning: 2 shift/reduce conflicts [-Wconflicts-sr]
|
||||
Shift/reduce conflict on token A:
|
||||
Example b . A X X Y
|
||||
First derivation a ::=[ r ::=[ b . ] t ::=[ A x ::=[ X ] xy ::=[ X Y ] ] ]
|
||||
Second derivation a ::=[ s ::=[ b . xx ::=[ A X X ] y ::=[ Y ] ] ]
|
||||
Shift derivation
|
||||
a
|
||||
`-> s
|
||||
`-> b . xx y
|
||||
`-> A X X `-> Y
|
||||
Reduce derivation
|
||||
a
|
||||
`-> r t
|
||||
`-> b . `-> A x xy
|
||||
`-> X `-> X Y
|
||||
|
||||
Shift/reduce conflict on token X:
|
||||
First example X . X xy
|
||||
First derivation a ::=[ x ::=[ X . ] t ::=[ X xy ] ]
|
||||
Second example A X . X
|
||||
Second derivation a ::=[ t ::=[ A xx ::=[ X . X ] ] ]
|
||||
First example A X . X
|
||||
Shift derivation
|
||||
a
|
||||
`-> t
|
||||
`-> A xx
|
||||
`-> X . X
|
||||
Second example X . X xy
|
||||
Reduce derivation
|
||||
a
|
||||
`-> x t
|
||||
`-> X . `-> X xy
|
||||
|
||||
input.y:4.4: warning: rule useless in parser due to conflicts [-Wother]
|
||||
input.y:8.4: warning: rule useless in parser due to conflicts [-Wother]
|
||||
]],
|
||||
[[input.y: warning: 2 shift/reduce conflicts [-Wconflicts-sr]
|
||||
Shift/reduce conflict on token A:
|
||||
Example b . A X X Y
|
||||
Shift derivation a -> [ s -> [ b . xx -> [ A X X ] y -> [ Y ] ] ]
|
||||
Reduce derivation a -> [ r -> [ b . ] t -> [ A x -> [ X ] xy -> [ X Y ] ] ]
|
||||
|
||||
Shift/reduce conflict on token X:
|
||||
First example A X . X
|
||||
Shift derivation a -> [ t -> [ A xx -> [ X . X ] ] ]
|
||||
Second example X . X xy
|
||||
Reduce derivation a -> [ x -> [ X . ] t -> [ X xy ] ]
|
||||
|
||||
input.y:4.4: warning: rule useless in parser due to conflicts [-Wother]
|
||||
input.y:8.4: warning: rule useless in parser due to conflicts [-Wother]
|
||||
@@ -229,7 +379,6 @@ AT_CLEANUP
|
||||
## ----------------------------- ##
|
||||
|
||||
AT_SETUP([Unifying R/R counterexample])
|
||||
AT_KEYWORDS([cex])
|
||||
|
||||
AT_DATA([[input.y]],
|
||||
[[%token A
|
||||
@@ -238,12 +387,25 @@ a : A b ;
|
||||
b : A | b;
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK_CEX([input.y], [], [],
|
||||
AT_BISON_CHECK_CEX(
|
||||
[[input.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
|
||||
Reduce/reduce conflict on token $end:
|
||||
Example A b .
|
||||
First derivation a ::=[ A b . ]
|
||||
Second derivation a ::=[ A b ::=[ b . ] ]
|
||||
First derivation
|
||||
a
|
||||
`-> A b .
|
||||
Second derivation
|
||||
a
|
||||
`-> A b
|
||||
`-> b .
|
||||
|
||||
input.y:4.9: warning: rule useless in parser due to conflicts [-Wother]
|
||||
]],
|
||||
[[input.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
|
||||
Reduce/reduce conflict on token $end:
|
||||
Example A b .
|
||||
First derivation a -> [ A b . ]
|
||||
Second derivation a -> [ A b -> [ b . ] ]
|
||||
|
||||
input.y:4.9: warning: rule useless in parser due to conflicts [-Wother]
|
||||
]])
|
||||
@@ -255,7 +417,6 @@ AT_CLEANUP
|
||||
## --------------------------------- ##
|
||||
|
||||
AT_SETUP([Non-unifying R/R LR(1) conflict])
|
||||
AT_KEYWORDS([cex])
|
||||
|
||||
AT_DATA([[input.y]],
|
||||
[[%token A B C D
|
||||
@@ -265,13 +426,30 @@ a: D;
|
||||
b: D;
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK_CEX([input.y], [], [],
|
||||
AT_BISON_CHECK_CEX(
|
||||
[[input.y: warning: 2 reduce/reduce conflicts [-Wconflicts-rr]
|
||||
Reduce/reduce conflict on tokens A, C:
|
||||
First example D . A $end
|
||||
First derivation $accept ::=[ s ::=[ a ::=[ D . ] A ] $end ]
|
||||
First derivation
|
||||
$accept
|
||||
`-> s $end
|
||||
`-> a A
|
||||
`-> D .
|
||||
Second example B D . A $end
|
||||
Second derivation $accept ::=[ s ::=[ B b ::=[ D . ] A ] $end ]
|
||||
Second derivation
|
||||
$accept
|
||||
`-> s $end
|
||||
`-> B b A
|
||||
`-> D .
|
||||
|
||||
input.y:5.4: warning: rule useless in parser due to conflicts [-Wother]
|
||||
]],
|
||||
[[input.y: warning: 2 reduce/reduce conflicts [-Wconflicts-rr]
|
||||
Reduce/reduce conflict on tokens A, C:
|
||||
First example D . A $end
|
||||
First derivation $accept -> [ s -> [ a -> [ D . ] A ] $end ]
|
||||
Second example B D . A $end
|
||||
Second derivation $accept -> [ s -> [ B b -> [ D . ] A ] $end ]
|
||||
|
||||
input.y:5.4: warning: rule useless in parser due to conflicts [-Wother]
|
||||
]])
|
||||
@@ -283,7 +461,6 @@ AT_CLEANUP
|
||||
## --------------------------------- ##
|
||||
|
||||
AT_SETUP([Non-unifying R/R LR(2) conflict])
|
||||
AT_KEYWORDS([cex])
|
||||
|
||||
AT_DATA([[input.y]],
|
||||
[[%token H J K X
|
||||
@@ -293,14 +470,32 @@ a: H i;
|
||||
i: X | i J K;
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK_CEX([input.y], [], [],
|
||||
AT_BISON_CHECK_CEX(
|
||||
[[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
|
||||
Shift/reduce conflict on token J:
|
||||
time limit exceeded: XXX
|
||||
First example H i . J $end
|
||||
First derivation $accept ::=[ s ::=[ a ::=[ H i . ] J ] $end ]
|
||||
Second example H i . J K $end
|
||||
Second derivation $accept ::=[ a ::=[ H i ::=[ i . J K ] ] $end ]
|
||||
First example H i . J K $end
|
||||
Shift derivation
|
||||
$accept
|
||||
`-> a $end
|
||||
`-> H i
|
||||
`-> i . J K
|
||||
Second example H i . J $end
|
||||
Reduce derivation
|
||||
$accept
|
||||
`-> s $end
|
||||
`-> a J
|
||||
`-> H i .
|
||||
|
||||
input.y:4.4-6: warning: rule useless in parser due to conflicts [-Wother]
|
||||
]],
|
||||
[[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
|
||||
Shift/reduce conflict on token J:
|
||||
time limit exceeded: XXX
|
||||
First example H i . J K $end
|
||||
Shift derivation $accept -> [ a -> [ H i -> [ i . J K ] ] $end ]
|
||||
Second example H i . J $end
|
||||
Reduce derivation $accept -> [ s -> [ a -> [ H i . ] J ] $end ]
|
||||
|
||||
input.y:4.4-6: warning: rule useless in parser due to conflicts [-Wother]
|
||||
]])
|
||||
@@ -315,7 +510,6 @@ AT_CLEANUP
|
||||
# graph search
|
||||
|
||||
AT_SETUP([Cex Search Prepend])
|
||||
AT_KEYWORDS([cex])
|
||||
|
||||
AT_DATA([[input.y]],
|
||||
[[%token N A B C D
|
||||
@@ -326,17 +520,48 @@ a: A;
|
||||
b: A B C | A B D;
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK_CEX([input.y], [], [],
|
||||
AT_BISON_CHECK_CEX(
|
||||
[[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
|
||||
Shift/reduce conflict on token B:
|
||||
Example N A . B C
|
||||
First derivation s ::=[ n ::=[ N a ::=[ A . ] B ] C ]
|
||||
Second derivation s ::=[ n ::=[ N b ::=[ A . B C ] ] ]
|
||||
Shift derivation
|
||||
s
|
||||
`-> n
|
||||
`-> N b
|
||||
`-> A . B C
|
||||
Reduce derivation
|
||||
s
|
||||
`-> n C
|
||||
`-> N a B
|
||||
`-> A .
|
||||
|
||||
Shift/reduce conflict on token B:
|
||||
Example N N A . B D C
|
||||
First derivation s ::=[ n ::=[ N n ::=[ N a ::=[ A . ] B ] D ] C ]
|
||||
Second derivation s ::=[ n ::=[ N n ::=[ N b ::=[ A . B D ] ] C ] ]
|
||||
Shift derivation
|
||||
s
|
||||
`-> n
|
||||
`-> N n C
|
||||
`-> N b
|
||||
`-> A . B D
|
||||
Reduce derivation
|
||||
s
|
||||
`-> n C
|
||||
`-> N n D
|
||||
`-> N a B
|
||||
`-> A .
|
||||
|
||||
input.y:5.4: warning: rule useless in parser due to conflicts [-Wother]
|
||||
]],
|
||||
[[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
|
||||
Shift/reduce conflict on token B:
|
||||
Example N A . B C
|
||||
Shift derivation s -> [ n -> [ N b -> [ A . B C ] ] ]
|
||||
Reduce derivation s -> [ n -> [ N a -> [ A . ] B ] C ]
|
||||
|
||||
Shift/reduce conflict on token B:
|
||||
Example N N A . B D C
|
||||
Shift derivation s -> [ n -> [ N n -> [ N b -> [ A . B D ] ] C ] ]
|
||||
Reduce derivation s -> [ n -> [ N n -> [ N a -> [ A . ] B ] D ] C ]
|
||||
|
||||
input.y:5.4: warning: rule useless in parser due to conflicts [-Wother]
|
||||
]])
|
||||
@@ -351,7 +576,6 @@ AT_CLEANUP
|
||||
# precedence/associativity directives work.
|
||||
|
||||
AT_SETUP([R/R cex with prec])
|
||||
AT_KEYWORDS([cex])
|
||||
|
||||
AT_DATA([[input.y]],
|
||||
[[%left b
|
||||
@@ -363,17 +587,49 @@ B : A b A;
|
||||
C : A c A;
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK_CEX([input.y], [], [],
|
||||
AT_BISON_CHECK_CEX(
|
||||
[[input.y: warning: 4 reduce/reduce conflicts [-Wconflicts-rr]
|
||||
Reduce/reduce conflict on tokens b, c:
|
||||
Example B . b c
|
||||
First derivation S ::=[ B ::=[ A ::=[ B . ] b A ::=[ ] ] C ::=[ A ::=[ ] c A ::=[ ] ] ]
|
||||
Second derivation S ::=[ B C ::=[ A ::=[ B ::=[ A ::=[ . ] b A ::=[ ] ] ] c A ::=[ ] ] ]
|
||||
First derivation
|
||||
S
|
||||
`-> B C
|
||||
`-> A b A `-> A c A
|
||||
`-> B . `-> %empty `-> %empty `-> %empty
|
||||
Second derivation
|
||||
S
|
||||
`-> B C
|
||||
`-> A c A
|
||||
`-> B `-> %empty
|
||||
`-> A b A
|
||||
`-> . `-> %empty
|
||||
|
||||
Reduce/reduce conflict on tokens b, c:
|
||||
Example C . c b
|
||||
First derivation S ::=[ C ::=[ A ::=[ C . ] c A ::=[ ] ] B ::=[ A ::=[ ] b A ::=[ ] ] ]
|
||||
Second derivation S ::=[ C B ::=[ A ::=[ C ::=[ A ::=[ . ] c A ::=[ ] ] ] b A ::=[ ] ] ]
|
||||
First derivation
|
||||
S
|
||||
`-> C B
|
||||
`-> A c A `-> A b A
|
||||
`-> C . `-> %empty `-> %empty `-> %empty
|
||||
Second derivation
|
||||
S
|
||||
`-> C B
|
||||
`-> A b A
|
||||
`-> C `-> %empty
|
||||
`-> A c A
|
||||
`-> . `-> %empty
|
||||
|
||||
]],
|
||||
[[input.y: warning: 4 reduce/reduce conflicts [-Wconflicts-rr]
|
||||
Reduce/reduce conflict on tokens b, c:
|
||||
Example B . b c
|
||||
First derivation S -> [ B -> [ A -> [ B . ] b A -> [ ] ] C -> [ A -> [ ] c A -> [ ] ] ]
|
||||
Second derivation S -> [ B C -> [ A -> [ B -> [ A -> [ . ] b A -> [ ] ] ] c A -> [ ] ] ]
|
||||
|
||||
Reduce/reduce conflict on tokens b, c:
|
||||
Example C . c b
|
||||
First derivation S -> [ C -> [ A -> [ C . ] c A -> [ ] ] B -> [ A -> [ ] b A -> [ ] ] ]
|
||||
Second derivation S -> [ C B -> [ A -> [ C -> [ A -> [ . ] c A -> [ ] ] ] b A -> [ ] ] ]
|
||||
|
||||
]])
|
||||
|
||||
@@ -384,7 +640,6 @@ AT_CLEANUP
|
||||
## ------------------- ##
|
||||
|
||||
AT_SETUP([Null nonterminals])
|
||||
AT_KEYWORDS([cex])
|
||||
|
||||
AT_DATA([[input.y]],
|
||||
[[%token A
|
||||
@@ -395,57 +650,187 @@ c : ;
|
||||
d : a | c A | d;
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK_CEX([input.y], [], [],
|
||||
AT_BISON_CHECK_CEX(
|
||||
[[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
|
||||
input.y: warning: 6 reduce/reduce conflicts [-Wconflicts-rr]
|
||||
Reduce/reduce conflict on token A:
|
||||
First example . c A A $end
|
||||
First derivation $accept ::=[ a ::=[ b ::=[ . ] d ::=[ c A A ] ] $end ]
|
||||
First derivation
|
||||
$accept
|
||||
`-> a $end
|
||||
`-> b d
|
||||
`-> . `-> c A A
|
||||
Second example . c A A $end
|
||||
Second derivation $accept ::=[ a ::=[ c ::=[ . ] d ::=[ c A A ] ] $end ]
|
||||
Second derivation
|
||||
$accept
|
||||
`-> a $end
|
||||
`-> c d
|
||||
`-> . `-> c A A
|
||||
|
||||
Reduce/reduce conflict on token A:
|
||||
time limit exceeded: XXX
|
||||
First example b . c A A $end
|
||||
First derivation $accept ::=[ a ::=[ b d ::=[ a ::=[ b ::=[ . ] d ::=[ c A A ] ] ] ] $end ]
|
||||
First derivation
|
||||
$accept
|
||||
`-> a $end
|
||||
`-> b d
|
||||
`-> a
|
||||
`-> b d
|
||||
`-> . `-> c A A
|
||||
Second example b . A $end
|
||||
Second derivation $accept ::=[ a ::=[ b d ::=[ c ::=[ . ] A ] ] $end ]
|
||||
Second derivation
|
||||
$accept
|
||||
`-> a $end
|
||||
`-> b d
|
||||
`-> c A
|
||||
`-> .
|
||||
|
||||
Reduce/reduce conflict on token A:
|
||||
time limit exceeded: XXX
|
||||
First example c . c A A $end
|
||||
First derivation $accept ::=[ a ::=[ c d ::=[ a ::=[ b ::=[ . ] d ::=[ c A A ] ] ] ] $end ]
|
||||
First derivation
|
||||
$accept
|
||||
`-> a $end
|
||||
`-> c d
|
||||
`-> a
|
||||
`-> b d
|
||||
`-> . `-> c A A
|
||||
Second example c . A $end
|
||||
Second derivation $accept ::=[ a ::=[ c d ::=[ c ::=[ . ] A ] ] $end ]
|
||||
Second derivation
|
||||
$accept
|
||||
`-> a $end
|
||||
`-> c d
|
||||
`-> c A
|
||||
`-> .
|
||||
|
||||
Shift/reduce conflict on token A:
|
||||
time limit exceeded: XXX
|
||||
First example b c . c A A $end
|
||||
First derivation $accept ::=[ a ::=[ b d ::=[ a ::=[ c d ::=[ a ::=[ b ::=[ . ] d ::=[ c A A ] ] ] ] ] ] $end ]
|
||||
Second example b c . A
|
||||
Second derivation a ::=[ b d ::=[ c . A ] ]
|
||||
First example b c . A
|
||||
Shift derivation
|
||||
a
|
||||
`-> b d
|
||||
`-> c . A
|
||||
Second example b c . c A A $end
|
||||
Reduce derivation
|
||||
$accept
|
||||
`-> a $end
|
||||
`-> b d
|
||||
`-> a
|
||||
`-> c d
|
||||
`-> a
|
||||
`-> b d
|
||||
`-> . `-> c A A
|
||||
|
||||
Reduce/reduce conflict on token A:
|
||||
First example b c . c A A $end
|
||||
First derivation $accept ::=[ a ::=[ b d ::=[ a ::=[ c d ::=[ a ::=[ b ::=[ . ] d ::=[ c A A ] ] ] ] ] ] $end ]
|
||||
First derivation
|
||||
$accept
|
||||
`-> a $end
|
||||
`-> b d
|
||||
`-> a
|
||||
`-> c d
|
||||
`-> a
|
||||
`-> b d
|
||||
`-> . `-> c A A
|
||||
Second example b c . A $end
|
||||
Second derivation $accept ::=[ a ::=[ b d ::=[ a ::=[ c d ::=[ c ::=[ . ] A ] ] ] ] $end ]
|
||||
Second derivation
|
||||
$accept
|
||||
`-> a $end
|
||||
`-> b d
|
||||
`-> a
|
||||
`-> c d
|
||||
`-> c A
|
||||
`-> .
|
||||
|
||||
Shift/reduce conflict on token A:
|
||||
First example b c . A $end
|
||||
First derivation $accept ::=[ a ::=[ b d ::=[ a ::=[ c d ::=[ c ::=[ . ] A ] ] ] ] $end ]
|
||||
Second example b c . A
|
||||
Second derivation a ::=[ b d ::=[ c . A ] ]
|
||||
First example b c . A
|
||||
Shift derivation
|
||||
a
|
||||
`-> b d
|
||||
`-> c . A
|
||||
Second example b c . A $end
|
||||
Reduce derivation
|
||||
$accept
|
||||
`-> a $end
|
||||
`-> b d
|
||||
`-> a
|
||||
`-> c d
|
||||
`-> c A
|
||||
`-> .
|
||||
|
||||
Reduce/reduce conflict on token $end:
|
||||
Example b d .
|
||||
First derivation a ::=[ b d . ]
|
||||
Second derivation a ::=[ b d ::=[ d . ] ]
|
||||
First derivation
|
||||
a
|
||||
`-> b d .
|
||||
Second derivation
|
||||
a
|
||||
`-> b d
|
||||
`-> d .
|
||||
|
||||
Reduce/reduce conflict on token $end:
|
||||
Example c d .
|
||||
First derivation a ::=[ c d . ]
|
||||
Second derivation a ::=[ c d ::=[ d . ] ]
|
||||
First derivation
|
||||
a
|
||||
`-> c d .
|
||||
Second derivation
|
||||
a
|
||||
`-> c d
|
||||
`-> d .
|
||||
|
||||
input.y:5.4: warning: rule useless in parser due to conflicts [-Wother]
|
||||
input.y:6.15: warning: rule useless in parser due to conflicts [-Wother]
|
||||
]],
|
||||
[[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
|
||||
input.y: warning: 6 reduce/reduce conflicts [-Wconflicts-rr]
|
||||
Reduce/reduce conflict on token A:
|
||||
First example . c A A $end
|
||||
First derivation $accept -> [ a -> [ b -> [ . ] d -> [ c A A ] ] $end ]
|
||||
Second example . c A A $end
|
||||
Second derivation $accept -> [ a -> [ c -> [ . ] d -> [ c A A ] ] $end ]
|
||||
|
||||
Reduce/reduce conflict on token A:
|
||||
time limit exceeded: XXX
|
||||
First example b . c A A $end
|
||||
First derivation $accept -> [ a -> [ b d -> [ a -> [ b -> [ . ] d -> [ c A A ] ] ] ] $end ]
|
||||
Second example b . A $end
|
||||
Second derivation $accept -> [ a -> [ b d -> [ c -> [ . ] A ] ] $end ]
|
||||
|
||||
Reduce/reduce conflict on token A:
|
||||
time limit exceeded: XXX
|
||||
First example c . c A A $end
|
||||
First derivation $accept -> [ a -> [ c d -> [ a -> [ b -> [ . ] d -> [ c A A ] ] ] ] $end ]
|
||||
Second example c . A $end
|
||||
Second derivation $accept -> [ a -> [ c d -> [ c -> [ . ] A ] ] $end ]
|
||||
|
||||
Shift/reduce conflict on token A:
|
||||
time limit exceeded: XXX
|
||||
First example b c . A
|
||||
Shift derivation a -> [ b d -> [ c . A ] ]
|
||||
Second example b c . c A A $end
|
||||
Reduce derivation $accept -> [ a -> [ b d -> [ a -> [ c d -> [ a -> [ b -> [ . ] d -> [ c A A ] ] ] ] ] ] $end ]
|
||||
|
||||
Reduce/reduce conflict on token A:
|
||||
First example b c . c A A $end
|
||||
First derivation $accept -> [ a -> [ b d -> [ a -> [ c d -> [ a -> [ b -> [ . ] d -> [ c A A ] ] ] ] ] ] $end ]
|
||||
Second example b c . A $end
|
||||
Second derivation $accept -> [ a -> [ b d -> [ a -> [ c d -> [ c -> [ . ] A ] ] ] ] $end ]
|
||||
|
||||
Shift/reduce conflict on token A:
|
||||
First example b c . A
|
||||
Shift derivation a -> [ b d -> [ c . A ] ]
|
||||
Second example b c . A $end
|
||||
Reduce derivation $accept -> [ a -> [ b d -> [ a -> [ c d -> [ c -> [ . ] A ] ] ] ] $end ]
|
||||
|
||||
Reduce/reduce conflict on token $end:
|
||||
Example b d .
|
||||
First derivation a -> [ b d . ]
|
||||
Second derivation a -> [ b d -> [ d . ] ]
|
||||
|
||||
Reduce/reduce conflict on token $end:
|
||||
Example c d .
|
||||
First derivation a -> [ c d . ]
|
||||
Second derivation a -> [ c d -> [ d . ] ]
|
||||
|
||||
input.y:5.4: warning: rule useless in parser due to conflicts [-Wother]
|
||||
input.y:6.15: warning: rule useless in parser due to conflicts [-Wother]
|
||||
@@ -458,7 +843,6 @@ AT_CLEANUP
|
||||
## --------------------------- ##
|
||||
|
||||
AT_SETUP([Non-unifying Prefix Share])
|
||||
AT_KEYWORDS([cex])
|
||||
|
||||
# Tests for a counterexample which should start its derivation
|
||||
# at a shared symbol rather than the start symbol.
|
||||
@@ -471,12 +855,27 @@ a: H i J J
|
||||
i: %empty | i J;
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK_CEX([input.y], [], [],
|
||||
AT_BISON_CHECK_CEX(
|
||||
[[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
|
||||
Shift/reduce conflict on token J:
|
||||
Example H i J . J J
|
||||
First derivation s ::=[ a ::=[ H i ::=[ i J . ] J J ] ]
|
||||
Second derivation s ::=[ a ::=[ H i J . J ] J ]
|
||||
Shift derivation
|
||||
s
|
||||
`-> a J
|
||||
`-> H i J . J
|
||||
Reduce derivation
|
||||
s
|
||||
`-> a
|
||||
`-> H i J J
|
||||
`-> i J .
|
||||
|
||||
input.y:5.13-15: warning: rule useless in parser due to conflicts [-Wother]
|
||||
]],
|
||||
[[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
|
||||
Shift/reduce conflict on token J:
|
||||
Example H i J . J J
|
||||
Shift derivation s -> [ a -> [ H i J . J ] J ]
|
||||
Reduce derivation s -> [ a -> [ H i -> [ i J . ] J J ] ]
|
||||
|
||||
input.y:5.13-15: warning: rule useless in parser due to conflicts [-Wother]
|
||||
]])
|
||||
@@ -491,7 +890,6 @@ AT_CLEANUP
|
||||
# are derived correctly.
|
||||
|
||||
AT_SETUP([Deep Null Unifying])
|
||||
AT_KEYWORDS([cex])
|
||||
|
||||
AT_DATA([[input.y]],
|
||||
[[%token A D
|
||||
@@ -503,12 +901,27 @@ c: %empty
|
||||
d: D;
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK_CEX([input.y], [], [],
|
||||
AT_BISON_CHECK_CEX(
|
||||
[[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
|
||||
Shift/reduce conflict on token D:
|
||||
Example A a . D
|
||||
First derivation s ::=[ A a a ::=[ b ::=[ c ::=[ . ] ] ] d ::=[ D ] ]
|
||||
Second derivation s ::=[ A a d ::=[ . D ] ]
|
||||
Shift derivation
|
||||
s
|
||||
`-> A a d
|
||||
`-> . D
|
||||
Reduce derivation
|
||||
s
|
||||
`-> A a a d
|
||||
`-> b `-> D
|
||||
`-> c
|
||||
`-> .
|
||||
|
||||
]],
|
||||
[[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
|
||||
Shift/reduce conflict on token D:
|
||||
Example A a . D
|
||||
Shift derivation s -> [ A a d -> [ . D ] ]
|
||||
Reduce derivation s -> [ A a a -> [ b -> [ c -> [ . ] ] ] d -> [ D ] ]
|
||||
|
||||
]])
|
||||
|
||||
@@ -521,7 +934,6 @@ AT_CLEANUP
|
||||
# Tests that expand_to_conflict works with nullable sybols
|
||||
|
||||
AT_SETUP([Deep Null Non-unifying])
|
||||
AT_KEYWORDS([cex])
|
||||
|
||||
AT_DATA([[input.y]],
|
||||
[[%token A D E
|
||||
@@ -533,13 +945,31 @@ c: %empty
|
||||
d: D;
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK_CEX([input.y], [], [],
|
||||
AT_BISON_CHECK_CEX(
|
||||
[[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
|
||||
Shift/reduce conflict on token D:
|
||||
First example A a . D E $end
|
||||
First derivation $accept ::=[ s ::=[ A a a ::=[ b ::=[ c ::=[ . ] ] ] d ::=[ D ] E ] $end ]
|
||||
Second example A a . D $end
|
||||
Second derivation $accept ::=[ s ::=[ A a d ::=[ . D ] ] $end ]
|
||||
First example A a . D $end
|
||||
Shift derivation
|
||||
$accept
|
||||
`-> s $end
|
||||
`-> A a d
|
||||
`-> . D
|
||||
Second example A a . D E $end
|
||||
Reduce derivation
|
||||
$accept
|
||||
`-> s $end
|
||||
`-> A a a d E
|
||||
`-> b `-> D
|
||||
`-> c
|
||||
`-> .
|
||||
|
||||
]],
|
||||
[[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
|
||||
Shift/reduce conflict on token D:
|
||||
First example A a . D $end
|
||||
Shift derivation $accept -> [ s -> [ A a d -> [ . D ] ] $end ]
|
||||
Second example A a . D E $end
|
||||
Reduce derivation $accept -> [ s -> [ A a a -> [ b -> [ c -> [ . ] ] ] d -> [ D ] E ] $end ]
|
||||
|
||||
]])
|
||||
|
||||
|
||||
+96
-12
@@ -28,6 +28,8 @@ m4_pushdef([AT_TEST],
|
||||
AT_SETUP([$1])
|
||||
AT_KEYWORDS([diagnostics])
|
||||
|
||||
m4_if(m4_index([$1], [Counterexample]), [-1], [], [AT_KEYWORDS([cex])])
|
||||
|
||||
# We need UTF-8 support for correct screen-width computation of UTF-8
|
||||
# characters. Skip the test if not available.
|
||||
locale=`locale -a | $EGREP '^en_US\.(UTF-8|utf8)$' | sed 1q`
|
||||
@@ -534,33 +536,115 @@ exp
|
||||
[1],
|
||||
[[input.y: <error>error:</error> shift/reduce conflicts: 4 found, 0 expected
|
||||
Shift/reduce conflict on token "+":
|
||||
Example <cex-0><cex-1><cex-leaf>exp</cex-leaf> <cex-leaf>"+"</cex-leaf> <cex-leaf>exp</cex-leaf> <cex-dot>•</cex-dot></cex-1> <cex-leaf>"+"</cex-leaf> <cex-leaf>exp</cex-leaf></cex-0>
|
||||
First derivation <cex-0><cex-step>exp ::=[ </cex-step><cex-1><cex-step>exp ::=[ </cex-step><cex-leaf>exp</cex-leaf> <cex-leaf>"+"</cex-leaf> <cex-leaf>exp</cex-leaf> <cex-dot>•</cex-dot><cex-step> ]</cex-step></cex-1> <cex-leaf>"+"</cex-leaf> <cex-leaf>exp</cex-leaf><cex-step> ]</cex-step></cex-0>
|
||||
Example <cex-0><cex-leaf>exp</cex-leaf> <cex-leaf>"+"</cex-leaf><cex-1> <cex-leaf>exp</cex-leaf> <cex-dot>•</cex-dot> <cex-leaf>"+"</cex-leaf> <cex-leaf>exp</cex-leaf></cex-1></cex-0>
|
||||
Second derivation <cex-0><cex-step>exp ::=[ </cex-step><cex-leaf>exp</cex-leaf> <cex-leaf>"+"</cex-leaf><cex-1> <cex-step>exp ::=[ </cex-step><cex-leaf>exp</cex-leaf> <cex-dot>•</cex-dot> <cex-leaf>"+"</cex-leaf> <cex-leaf>exp</cex-leaf><cex-step> ]</cex-step></cex-1><cex-step> ]</cex-step></cex-0>
|
||||
Shift derivation
|
||||
<cex-0><cex-step>exp</cex-step></cex-0>
|
||||
<cex-0><cex-step>↳ <cex-leaf>exp</cex-leaf><cex-leaf> "+"</cex-leaf><cex-1><cex-step> exp</cex-step></cex-1></cex-step></cex-0>
|
||||
<cex-1><cex-step> ↳ <cex-leaf>exp</cex-leaf><cex-dot> •</cex-dot><cex-leaf> "+"</cex-leaf><cex-leaf> exp</cex-leaf></cex-step></cex-1>
|
||||
Example <cex-0><cex-1><cex-leaf>exp</cex-leaf> <cex-leaf>"+"</cex-leaf> <cex-leaf>exp</cex-leaf> <cex-dot>•</cex-dot></cex-1> <cex-leaf>"+"</cex-leaf> <cex-leaf>exp</cex-leaf></cex-0>
|
||||
Reduce derivation
|
||||
<cex-0><cex-step>exp</cex-step></cex-0>
|
||||
<cex-0><cex-step>↳ <cex-1><cex-step>exp</cex-step></cex-1><cex-leaf> "+"</cex-leaf><cex-leaf> exp</cex-leaf></cex-step></cex-0>
|
||||
<cex-1><cex-step> ↳ <cex-leaf>exp</cex-leaf><cex-leaf> "+"</cex-leaf><cex-leaf> exp</cex-leaf><cex-dot> •</cex-dot></cex-step></cex-1>
|
||||
|
||||
Shift/reduce conflict on token "else":
|
||||
Example <cex-0><cex-leaf>"if"</cex-leaf> <cex-leaf>exp</cex-leaf> <cex-leaf>"then"</cex-leaf><cex-1> <cex-leaf>"if"</cex-leaf> <cex-leaf>exp</cex-leaf> <cex-leaf>"then"</cex-leaf> <cex-leaf>exp</cex-leaf> <cex-dot>•</cex-dot></cex-1> <cex-leaf>"else"</cex-leaf> <cex-leaf>exp</cex-leaf></cex-0>
|
||||
First derivation <cex-0><cex-step>exp ::=[ </cex-step><cex-leaf>"if"</cex-leaf> <cex-leaf>exp</cex-leaf> <cex-leaf>"then"</cex-leaf><cex-1> <cex-step>exp ::=[ </cex-step><cex-leaf>"if"</cex-leaf> <cex-leaf>exp</cex-leaf> <cex-leaf>"then"</cex-leaf> <cex-leaf>exp</cex-leaf> <cex-dot>•</cex-dot><cex-step> ]</cex-step></cex-1> <cex-leaf>"else"</cex-leaf> <cex-leaf>exp</cex-leaf><cex-step> ]</cex-step></cex-0>
|
||||
Example <cex-0><cex-leaf>"if"</cex-leaf> <cex-leaf>exp</cex-leaf> <cex-leaf>"then"</cex-leaf><cex-1> <cex-leaf>"if"</cex-leaf> <cex-leaf>exp</cex-leaf> <cex-leaf>"then"</cex-leaf> <cex-leaf>exp</cex-leaf> <cex-dot>•</cex-dot> <cex-leaf>"else"</cex-leaf> <cex-leaf>exp</cex-leaf></cex-1></cex-0>
|
||||
Second derivation <cex-0><cex-step>exp ::=[ </cex-step><cex-leaf>"if"</cex-leaf> <cex-leaf>exp</cex-leaf> <cex-leaf>"then"</cex-leaf><cex-1> <cex-step>exp ::=[ </cex-step><cex-leaf>"if"</cex-leaf> <cex-leaf>exp</cex-leaf> <cex-leaf>"then"</cex-leaf> <cex-leaf>exp</cex-leaf> <cex-dot>•</cex-dot> <cex-leaf>"else"</cex-leaf> <cex-leaf>exp</cex-leaf><cex-step> ]</cex-step></cex-1><cex-step> ]</cex-step></cex-0>
|
||||
Shift derivation
|
||||
<cex-0><cex-step>exp</cex-step></cex-0>
|
||||
<cex-0><cex-step>↳ <cex-leaf>"if"</cex-leaf><cex-leaf> exp</cex-leaf><cex-leaf> "then"</cex-leaf><cex-1><cex-step> exp</cex-step></cex-1></cex-step></cex-0>
|
||||
<cex-1><cex-step> ↳ <cex-leaf>"if"</cex-leaf><cex-leaf> exp</cex-leaf><cex-leaf> "then"</cex-leaf><cex-leaf> exp</cex-leaf><cex-dot> •</cex-dot><cex-leaf> "else"</cex-leaf><cex-leaf> exp</cex-leaf></cex-step></cex-1>
|
||||
Example <cex-0><cex-leaf>"if"</cex-leaf> <cex-leaf>exp</cex-leaf> <cex-leaf>"then"</cex-leaf><cex-1> <cex-leaf>"if"</cex-leaf> <cex-leaf>exp</cex-leaf> <cex-leaf>"then"</cex-leaf> <cex-leaf>exp</cex-leaf> <cex-dot>•</cex-dot></cex-1> <cex-leaf>"else"</cex-leaf> <cex-leaf>exp</cex-leaf></cex-0>
|
||||
Reduce derivation
|
||||
<cex-0><cex-step>exp</cex-step></cex-0>
|
||||
<cex-0><cex-step>↳ <cex-leaf>"if"</cex-leaf><cex-leaf> exp</cex-leaf><cex-leaf> "then"</cex-leaf><cex-1><cex-step> exp</cex-step></cex-1><cex-leaf> "else"</cex-leaf><cex-leaf> exp</cex-leaf></cex-step></cex-0>
|
||||
<cex-1><cex-step> ↳ <cex-leaf>"if"</cex-leaf><cex-leaf> exp</cex-leaf><cex-leaf> "then"</cex-leaf><cex-leaf> exp</cex-leaf><cex-dot> •</cex-dot></cex-step></cex-1>
|
||||
|
||||
Shift/reduce conflict on token "+":
|
||||
Example <cex-0><cex-1><cex-leaf>"if"</cex-leaf> <cex-leaf>exp</cex-leaf> <cex-leaf>"then"</cex-leaf> <cex-leaf>exp</cex-leaf> <cex-dot>•</cex-dot></cex-1> <cex-leaf>"+"</cex-leaf> <cex-leaf>exp</cex-leaf></cex-0>
|
||||
First derivation <cex-0><cex-step>exp ::=[ </cex-step><cex-1><cex-step>exp ::=[ </cex-step><cex-leaf>"if"</cex-leaf> <cex-leaf>exp</cex-leaf> <cex-leaf>"then"</cex-leaf> <cex-leaf>exp</cex-leaf> <cex-dot>•</cex-dot><cex-step> ]</cex-step></cex-1> <cex-leaf>"+"</cex-leaf> <cex-leaf>exp</cex-leaf><cex-step> ]</cex-step></cex-0>
|
||||
Example <cex-0><cex-leaf>"if"</cex-leaf> <cex-leaf>exp</cex-leaf> <cex-leaf>"then"</cex-leaf><cex-1> <cex-leaf>exp</cex-leaf> <cex-dot>•</cex-dot> <cex-leaf>"+"</cex-leaf> <cex-leaf>exp</cex-leaf></cex-1></cex-0>
|
||||
Second derivation <cex-0><cex-step>exp ::=[ </cex-step><cex-leaf>"if"</cex-leaf> <cex-leaf>exp</cex-leaf> <cex-leaf>"then"</cex-leaf><cex-1> <cex-step>exp ::=[ </cex-step><cex-leaf>exp</cex-leaf> <cex-dot>•</cex-dot> <cex-leaf>"+"</cex-leaf> <cex-leaf>exp</cex-leaf><cex-step> ]</cex-step></cex-1><cex-step> ]</cex-step></cex-0>
|
||||
Shift derivation
|
||||
<cex-0><cex-step>exp</cex-step></cex-0>
|
||||
<cex-0><cex-step>↳ <cex-leaf>"if"</cex-leaf><cex-leaf> exp</cex-leaf><cex-leaf> "then"</cex-leaf><cex-1><cex-step> exp</cex-step></cex-1></cex-step></cex-0>
|
||||
<cex-1><cex-step> ↳ <cex-leaf>exp</cex-leaf><cex-dot> •</cex-dot><cex-leaf> "+"</cex-leaf><cex-leaf> exp</cex-leaf></cex-step></cex-1>
|
||||
Example <cex-0><cex-1><cex-leaf>"if"</cex-leaf> <cex-leaf>exp</cex-leaf> <cex-leaf>"then"</cex-leaf> <cex-leaf>exp</cex-leaf> <cex-dot>•</cex-dot></cex-1> <cex-leaf>"+"</cex-leaf> <cex-leaf>exp</cex-leaf></cex-0>
|
||||
Reduce derivation
|
||||
<cex-0><cex-step>exp</cex-step></cex-0>
|
||||
<cex-0><cex-step>↳ <cex-1><cex-step>exp</cex-step></cex-1><cex-leaf> "+"</cex-leaf><cex-leaf> exp</cex-leaf></cex-step></cex-0>
|
||||
<cex-1><cex-step> ↳ <cex-leaf>"if"</cex-leaf><cex-leaf> exp</cex-leaf><cex-leaf> "then"</cex-leaf><cex-leaf> exp</cex-leaf><cex-dot> •</cex-dot></cex-step></cex-1>
|
||||
|
||||
Shift/reduce conflict on token "+":
|
||||
Example <cex-0><cex-1><cex-leaf>"if"</cex-leaf> <cex-leaf>exp</cex-leaf> <cex-leaf>"then"</cex-leaf> <cex-leaf>exp</cex-leaf> <cex-leaf>"else"</cex-leaf> <cex-leaf>exp</cex-leaf> <cex-dot>•</cex-dot></cex-1> <cex-leaf>"+"</cex-leaf> <cex-leaf>exp</cex-leaf></cex-0>
|
||||
First derivation <cex-0><cex-step>exp ::=[ </cex-step><cex-1><cex-step>exp ::=[ </cex-step><cex-leaf>"if"</cex-leaf> <cex-leaf>exp</cex-leaf> <cex-leaf>"then"</cex-leaf> <cex-leaf>exp</cex-leaf> <cex-leaf>"else"</cex-leaf> <cex-leaf>exp</cex-leaf> <cex-dot>•</cex-dot><cex-step> ]</cex-step></cex-1> <cex-leaf>"+"</cex-leaf> <cex-leaf>exp</cex-leaf><cex-step> ]</cex-step></cex-0>
|
||||
Example <cex-0><cex-leaf>"if"</cex-leaf> <cex-leaf>exp</cex-leaf> <cex-leaf>"then"</cex-leaf> <cex-leaf>exp</cex-leaf> <cex-leaf>"else"</cex-leaf><cex-1> <cex-leaf>exp</cex-leaf> <cex-dot>•</cex-dot> <cex-leaf>"+"</cex-leaf> <cex-leaf>exp</cex-leaf></cex-1></cex-0>
|
||||
Second derivation <cex-0><cex-step>exp ::=[ </cex-step><cex-leaf>"if"</cex-leaf> <cex-leaf>exp</cex-leaf> <cex-leaf>"then"</cex-leaf> <cex-leaf>exp</cex-leaf> <cex-leaf>"else"</cex-leaf><cex-1> <cex-step>exp ::=[ </cex-step><cex-leaf>exp</cex-leaf> <cex-dot>•</cex-dot> <cex-leaf>"+"</cex-leaf> <cex-leaf>exp</cex-leaf><cex-step> ]</cex-step></cex-1><cex-step> ]</cex-step></cex-0>
|
||||
Shift derivation
|
||||
<cex-0><cex-step>exp</cex-step></cex-0>
|
||||
<cex-0><cex-step>↳ <cex-leaf>"if"</cex-leaf><cex-leaf> exp</cex-leaf><cex-leaf> "then"</cex-leaf><cex-leaf> exp</cex-leaf><cex-leaf> "else"</cex-leaf><cex-1><cex-step> exp</cex-step></cex-1></cex-step></cex-0>
|
||||
<cex-1><cex-step> ↳ <cex-leaf>exp</cex-leaf><cex-dot> •</cex-dot><cex-leaf> "+"</cex-leaf><cex-leaf> exp</cex-leaf></cex-step></cex-1>
|
||||
Example <cex-0><cex-1><cex-leaf>"if"</cex-leaf> <cex-leaf>exp</cex-leaf> <cex-leaf>"then"</cex-leaf> <cex-leaf>exp</cex-leaf> <cex-leaf>"else"</cex-leaf> <cex-leaf>exp</cex-leaf> <cex-dot>•</cex-dot></cex-1> <cex-leaf>"+"</cex-leaf> <cex-leaf>exp</cex-leaf></cex-0>
|
||||
Reduce derivation
|
||||
<cex-0><cex-step>exp</cex-step></cex-0>
|
||||
<cex-0><cex-step>↳ <cex-1><cex-step>exp</cex-step></cex-1><cex-leaf> "+"</cex-leaf><cex-leaf> exp</cex-leaf></cex-step></cex-0>
|
||||
<cex-1><cex-step> ↳ <cex-leaf>"if"</cex-leaf><cex-leaf> exp</cex-leaf><cex-leaf> "then"</cex-leaf><cex-leaf> exp</cex-leaf><cex-leaf> "else"</cex-leaf><cex-leaf> exp</cex-leaf><cex-dot> •</cex-dot></cex-step></cex-1>
|
||||
|
||||
]])
|
||||
|
||||
|
||||
AT_TEST([[Deep Counterexamples]],
|
||||
[[%expect 0
|
||||
%%
|
||||
exp: x1 e1 foo1 x1 | y1 e2 bar1 y1
|
||||
foo1: foo2
|
||||
foo2: foo3
|
||||
foo3: x1 foo4
|
||||
foo4: "quuux"
|
||||
|
||||
bar1: bar2
|
||||
bar2: bar3
|
||||
bar3: y1 bar4
|
||||
bar4: "quuux"
|
||||
|
||||
x1: x2
|
||||
x2: x3
|
||||
x3: "X"
|
||||
|
||||
y1: y2
|
||||
y2: y3
|
||||
y3: "X"
|
||||
|
||||
e1:
|
||||
e2:
|
||||
]],
|
||||
[1],
|
||||
[[input.y:30.4: <warning>warning:</warning> empty rule without %empty [<warning>-Wempty-rule</warning>]
|
||||
30 | e1:
|
||||
| <warning>^</warning>
|
||||
| <fixit-insert>%empty</fixit-insert>
|
||||
input.y:31.4: <warning>warning:</warning> empty rule without %empty [<warning>-Wempty-rule</warning>]
|
||||
31 | e2:
|
||||
| <warning>^</warning>
|
||||
| <fixit-insert>%empty</fixit-insert>
|
||||
input.y: <error>error:</error> reduce/reduce conflicts: 1 found, 0 expected
|
||||
Reduce/reduce conflict on token "X":
|
||||
Example <cex-0><cex-1><cex-2><cex-3><cex-leaf>"X"</cex-leaf> <cex-dot>•</cex-dot></cex-3></cex-2></cex-1><cex-4></cex-4><cex-5><cex-6><cex-7><cex-8><cex-9><cex-10> <cex-leaf>"X"</cex-leaf></cex-10></cex-9></cex-8><cex-11> <cex-leaf>"quuux"</cex-leaf></cex-11></cex-7></cex-6></cex-5><cex-12><cex-13><cex-14> <cex-leaf>"X"</cex-leaf></cex-14></cex-13></cex-12></cex-0>
|
||||
First derivation
|
||||
<cex-0><cex-step>exp</cex-step></cex-0>
|
||||
<cex-0><cex-step>↳ <cex-1><cex-step>x1</cex-step></cex-1><cex-4><cex-step> e1</cex-step></cex-4><cex-5><cex-step> foo1</cex-step></cex-5><cex-12><cex-step> x1</cex-step></cex-12></cex-step></cex-0>
|
||||
<cex-1><cex-step> ↳ <cex-2><cex-step>x2</cex-step></cex-2></cex-step></cex-1><cex-4><cex-step> ↳ ε</cex-step></cex-4><cex-5><cex-step> ↳ <cex-6><cex-step>foo2</cex-step></cex-6></cex-step></cex-5><cex-12><cex-step> ↳ <cex-13><cex-step>x2</cex-step></cex-13></cex-step></cex-12>
|
||||
<cex-2><cex-step> ↳ <cex-3><cex-step>x3</cex-step></cex-3></cex-step></cex-2><cex-6><cex-step> ↳ <cex-7><cex-step>foo3</cex-step></cex-7></cex-step></cex-6><cex-13><cex-step> ↳ <cex-14><cex-step>x3</cex-step></cex-14></cex-step></cex-13>
|
||||
<cex-3><cex-step> ↳ <cex-leaf>"X"</cex-leaf><cex-dot> •</cex-dot></cex-step></cex-3><cex-7><cex-step> ↳ <cex-8><cex-step>x1</cex-step></cex-8><cex-11><cex-step> foo4</cex-step></cex-11></cex-step></cex-7><cex-14><cex-step> ↳ <cex-leaf>"X"</cex-leaf></cex-step></cex-14>
|
||||
<cex-8><cex-step> ↳ <cex-9><cex-step>x2</cex-step></cex-9></cex-step></cex-8><cex-11><cex-step> ↳ <cex-leaf>"quuux"</cex-leaf></cex-step></cex-11>
|
||||
<cex-9><cex-step> ↳ <cex-10><cex-step>x3</cex-step></cex-10></cex-step></cex-9>
|
||||
<cex-10><cex-step> ↳ <cex-leaf>"X"</cex-leaf></cex-step></cex-10>
|
||||
Example <cex-0><cex-1><cex-2><cex-3><cex-leaf>"X"</cex-leaf> <cex-dot>•</cex-dot></cex-3></cex-2></cex-1><cex-4></cex-4><cex-5><cex-6><cex-7><cex-8><cex-9><cex-10> <cex-leaf>"X"</cex-leaf></cex-10></cex-9></cex-8><cex-11> <cex-leaf>"quuux"</cex-leaf></cex-11></cex-7></cex-6></cex-5><cex-12><cex-13><cex-14> <cex-leaf>"X"</cex-leaf></cex-14></cex-13></cex-12></cex-0>
|
||||
Second derivation
|
||||
<cex-0><cex-step>exp</cex-step></cex-0>
|
||||
<cex-0><cex-step>↳ <cex-1><cex-step>y1</cex-step></cex-1><cex-4><cex-step> e2</cex-step></cex-4><cex-5><cex-step> bar1</cex-step></cex-5><cex-12><cex-step> y1</cex-step></cex-12></cex-step></cex-0>
|
||||
<cex-1><cex-step> ↳ <cex-2><cex-step>y2</cex-step></cex-2></cex-step></cex-1><cex-4><cex-step> ↳ ε</cex-step></cex-4><cex-5><cex-step> ↳ <cex-6><cex-step>bar2</cex-step></cex-6></cex-step></cex-5><cex-12><cex-step> ↳ <cex-13><cex-step>y2</cex-step></cex-13></cex-step></cex-12>
|
||||
<cex-2><cex-step> ↳ <cex-3><cex-step>y3</cex-step></cex-3></cex-step></cex-2><cex-6><cex-step> ↳ <cex-7><cex-step>bar3</cex-step></cex-7></cex-step></cex-6><cex-13><cex-step> ↳ <cex-14><cex-step>y3</cex-step></cex-14></cex-step></cex-13>
|
||||
<cex-3><cex-step> ↳ <cex-leaf>"X"</cex-leaf><cex-dot> •</cex-dot></cex-step></cex-3><cex-7><cex-step> ↳ <cex-8><cex-step>y1</cex-step></cex-8><cex-11><cex-step> bar4</cex-step></cex-11></cex-step></cex-7><cex-14><cex-step> ↳ <cex-leaf>"X"</cex-leaf></cex-step></cex-14>
|
||||
<cex-8><cex-step> ↳ <cex-9><cex-step>y2</cex-step></cex-9></cex-step></cex-8><cex-11><cex-step> ↳ <cex-leaf>"quuux"</cex-leaf></cex-step></cex-11>
|
||||
<cex-9><cex-step> ↳ <cex-10><cex-step>y3</cex-step></cex-10></cex-step></cex-9>
|
||||
<cex-10><cex-step> ↳ <cex-leaf>"X"</cex-leaf></cex-step></cex-10>
|
||||
|
||||
input.y: <warning>warning:</warning> fix-its can be applied. Rerun with option '--update'. [<warning>-Wother</warning>]
|
||||
]])
|
||||
|
||||
m4_popdef([AT_TEST])
|
||||
|
||||
|
||||
+7
-2
@@ -1169,11 +1169,16 @@ m4_define([AT_BISON_CHECK_XML],
|
||||
[cp xml-tests/test.output expout]
|
||||
AT_CHECK([[$XSLTPROC \
|
||||
`]]AT_SET_ENV[[ bison --print-datadir`/xslt/xml2text.xsl \
|
||||
xml-tests/test.xml]], [[0]], [expout])
|
||||
xml-tests/test.xml]], [[0]], [stdout])
|
||||
# xml2text and xml2dot always use '•', while --report uses '•' or '.'
|
||||
# depending on the locale, and the test suite is run with the plain
|
||||
# C locale.
|
||||
AT_CHECK([[sed -e 's/•/./g' stdout]], [], [expout])
|
||||
[sort xml-tests/test.gv > expout]
|
||||
AT_CHECK([[$XSLTPROC \
|
||||
`]]AT_SET_ENV[[ bison --print-datadir`/xslt/xml2dot.xsl \
|
||||
xml-tests/test.xml | sort]], [[0]], [expout])
|
||||
xml-tests/test.xml | sort | sed -e 's/•/./g']],
|
||||
[[0]], [stdout])
|
||||
[rm -rf xml-tests expout]
|
||||
AT_RESTORE_SPECIAL_FILES
|
||||
[fi]])
|
||||
|
||||
@@ -36,6 +36,14 @@ $(top_srcdir)/%D%/package.m4: $(top_srcdir)/configure
|
||||
} >$@.tmp
|
||||
$(AM_V_at)mv $@.tmp $@
|
||||
|
||||
|
||||
# Update the test cases. Consider the latest test results to be the
|
||||
# correct expectations, and change the test cases to match them.
|
||||
.PHONY: update-tests
|
||||
update-tests:
|
||||
$(AM_V_GEN)cd $(top_srcdir) \
|
||||
&& build-aux/update-test $(abs_builddir)/%D%/testsuite.dir/*/testsuite.log
|
||||
|
||||
## ------------------------- ##
|
||||
## Generate the test suite. ##
|
||||
## ------------------------- ##
|
||||
|
||||
+722
-49
@@ -764,24 +764,24 @@ AT_CHECK([[sed -e 's/bison-xml-report version="[^"]*"/bison-xml-report version="
|
||||
</rule>
|
||||
</rules>
|
||||
<terminals>
|
||||
<terminal symbol-number="0" token-number="0" name=""end of file"" usefulness="useful"/>
|
||||
<terminal symbol-number="1" token-number="256" name="error" usefulness="useful"/>
|
||||
<terminal symbol-number="3" token-number="258" name="":="" usefulness="useful"/>
|
||||
<terminal symbol-number="4" token-number="259" name=""incr"" usefulness="useful"/>
|
||||
<terminal symbol-number="5" token-number="260" name=""identifier"" usefulness="useful"/>
|
||||
<terminal symbol-number="6" token-number="261" name=""number"" usefulness="useful"/>
|
||||
<terminal symbol-number="7" token-number="262" name=""("" usefulness="useful"/>
|
||||
<terminal symbol-number="8" token-number="263" name="")"" usefulness="useful"/>
|
||||
<terminal symbol-number="0" token-number="0" name=""end of file"" type="" usefulness="useful"/>
|
||||
<terminal symbol-number="1" token-number="256" name="error" type="" usefulness="useful"/>
|
||||
<terminal symbol-number="3" token-number="258" name="":="" type="" usefulness="useful"/>
|
||||
<terminal symbol-number="4" token-number="259" name=""incr"" type="" usefulness="useful"/>
|
||||
<terminal symbol-number="5" token-number="260" name=""identifier"" type="std::string" usefulness="useful"/>
|
||||
<terminal symbol-number="6" token-number="261" name=""number"" type="int" usefulness="useful"/>
|
||||
<terminal symbol-number="7" token-number="262" name=""("" type="" usefulness="useful"/>
|
||||
<terminal symbol-number="8" token-number="263" name="")"" type="" usefulness="useful"/>
|
||||
</terminals>
|
||||
<nonterminals>
|
||||
<nonterminal symbol-number="9" name="$accept" usefulness="useful"/>
|
||||
<nonterminal symbol-number="10" name="unit" usefulness="useful"/>
|
||||
<nonterminal symbol-number="11" name="assignments" usefulness="useful"/>
|
||||
<nonterminal symbol-number="12" name="assignment" usefulness="useful"/>
|
||||
<nonterminal symbol-number="13" name="id" usefulness="useful"/>
|
||||
<nonterminal symbol-number="14" name="exp" usefulness="useful"/>
|
||||
<nonterminal symbol-number="15" name="@1" usefulness="useful"/>
|
||||
<nonterminal symbol-number="16" name="@2" usefulness="useful"/>
|
||||
<nonterminal symbol-number="9" name="$accept" type="" usefulness="useful"/>
|
||||
<nonterminal symbol-number="10" name="unit" type="" usefulness="useful"/>
|
||||
<nonterminal symbol-number="11" name="assignments" type="" usefulness="useful"/>
|
||||
<nonterminal symbol-number="12" name="assignment" type="" usefulness="useful"/>
|
||||
<nonterminal symbol-number="13" name="id" type="std::string" usefulness="useful"/>
|
||||
<nonterminal symbol-number="14" name="exp" type="int" usefulness="useful"/>
|
||||
<nonterminal symbol-number="15" name="@1" type="int" usefulness="useful"/>
|
||||
<nonterminal symbol-number="16" name="@2" type="int" usefulness="useful"/>
|
||||
</nonterminals>
|
||||
</grammar>
|
||||
|
||||
@@ -1137,6 +1137,373 @@ AT_CHECK([[sed -e 's/bison-xml-report version="[^"]*"/bison-xml-report version="
|
||||
</bison-xml-report>
|
||||
]])
|
||||
|
||||
# Check HTML output.
|
||||
if test x"$XSLTPROC" != x""; then
|
||||
AT_CHECK([[$XSLTPROC \
|
||||
`]]AT_SET_ENV[[ bison --print-datadir`/xslt/xml2xhtml.xsl \
|
||||
input.xml | \
|
||||
sed -e 's/GNU Bison [0-9][-.0-9a-z]*/GNU Bison VERSION/' \
|
||||
>input.html]])
|
||||
|
||||
AT_CHECK([cat input.html], [],
|
||||
[[<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:bison="http://www.gnu.org/software/bison/">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
|
||||
<title>input.yy - GNU Bison XML Automaton Report</title>
|
||||
<style type="text/css">
|
||||
body {
|
||||
font-family: "Nimbus Sans L", Arial, sans-serif;
|
||||
font-size: 9pt;
|
||||
}
|
||||
a:link {
|
||||
color: #1f00ff;
|
||||
text-decoration: none;
|
||||
}
|
||||
a:visited {
|
||||
color: #1f00ff;
|
||||
text-decoration: none;
|
||||
}
|
||||
a:hover {
|
||||
color: red;
|
||||
}
|
||||
#menu a {
|
||||
text-decoration: underline;
|
||||
}
|
||||
.i {
|
||||
font-style: italic;
|
||||
}
|
||||
.pre {
|
||||
font-family: monospace;
|
||||
white-space: pre;
|
||||
}
|
||||
ol.decimal {
|
||||
list-style-type: decimal;
|
||||
}
|
||||
ol.lower-alpha {
|
||||
list-style-type: lower-alpha;
|
||||
}
|
||||
.dot {
|
||||
color: #cc0000;
|
||||
}
|
||||
#footer {
|
||||
margin-top: 3.5em;
|
||||
font-size: 7pt;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body><h1>GNU Bison XML Automaton Report</h1><p>
|
||||
input grammar: <span class="i">input.yy</span></p>
|
||||
|
||||
<h3>Table of Contents</h3><ul id="menu"><li><a href="#reductions">Reductions</a><ul class="lower-alpha"><li><a href="#nonterminals_useless_in_grammar">Nonterminals useless in grammar</a></li><li><a href="#terminals_unused_in_grammar">Terminals unused in grammar</a></li><li><a href="#rules_useless_in_grammar">Rules useless in grammar</a></li></ul></li><li><a href="#conflicts">Conflicts</a></li><li><a href="#grammar">Grammar</a><ul class="lower-alpha"><li><a href="#grammar">Itemset</a></li><li><a href="#terminals">Terminal symbols</a></li><li><a href="#nonterminals">Nonterminal symbols</a></li></ul></li><li><a href="#automaton">Automaton</a></li></ul><h2><a name="reductions" id="reductions"></a> Reductions</h2><h3><a name="nonterminals_useless_in_grammar" id="nonterminals_useless_in_grammar"></a> Nonterminals useless in grammar</h3>
|
||||
|
||||
<h3><a name="terminals_unused_in_grammar" id="terminals_unused_in_grammar"></a> Terminals unused in grammar</h3>
|
||||
|
||||
<h3><a name="rules_useless_in_grammar" id="rules_useless_in_grammar"></a> Rules useless in grammar</h3>
|
||||
<h2><a name="conflicts" id="conflicts"></a> Conflicts</h2>
|
||||
|
||||
<h2><a name="grammar" id="grammar"></a> Grammar</h2>
|
||||
<p class="pre">
|
||||
<a name="rule_0" id="rule_0"> 0</a> <span class="i">$accept</span> → <span class="i">unit</span> <b>"end of file"</b>
|
||||
|
||||
<a name="rule_1" id="rule_1"> 1</a> <span class="i">unit</span> → <span class="i">assignments</span> <span class="i">exp</span>
|
||||
|
||||
<a name="rule_2" id="rule_2"> 2</a> <span class="i">assignments</span> → %empty
|
||||
<a name="rule_3" id="rule_3"> 3</a> | <span class="i">assignments</span> <span class="i">assignment</span>
|
||||
|
||||
<a name="rule_4" id="rule_4"> 4</a> <span class="i">assignment</span> → <span class="i">id</span> <b>":="</b> <span class="i">exp</span>
|
||||
|
||||
<a name="rule_5" id="rule_5"> 5</a> <span class="i">id</span> → <b>"identifier"</b>
|
||||
|
||||
<a name="rule_6" id="rule_6"> 6</a> <span class="i">@1</span> → %empty
|
||||
|
||||
<a name="rule_7" id="rule_7"> 7</a> <span class="i">@2</span> → %empty
|
||||
|
||||
<a name="rule_8" id="rule_8"> 8</a> <span class="i">exp</span> → <b>"incr"</b> <span class="i">exp</span> <span class="i">@1</span> <span class="i">@2</span> <span class="i">exp</span>
|
||||
<a name="rule_9" id="rule_9"> 9</a> | <b>"("</b> <span class="i">exp</span> <b>")"</b>
|
||||
<a name="rule_10" id="rule_10"> 10</a> | <b>"identifier"</b>
|
||||
<a name="rule_11" id="rule_11"> 11</a> | <b>"number"</b>
|
||||
</p>
|
||||
|
||||
<h3><a name="terminals" id="terminals"></a> Terminals, with rules where they appear</h3>
|
||||
|
||||
<ul>
|
||||
<li><b>"end of file"</b> (0) <a href="#rule_0">0</a></li>
|
||||
<li><b>error</b> (256)</li>
|
||||
<li><b>":="</b> (258) <a href="#rule_4">4</a></li>
|
||||
<li><b>"incr"</b> (259) <a href="#rule_8">8</a></li>
|
||||
<li><b>"identifier"</b> <std::string> (260) <a href="#rule_5">5</a> <a href="#rule_10">10</a></li>
|
||||
<li><b>"number"</b> <int> (261) <a href="#rule_11">11</a></li>
|
||||
<li><b>"("</b> (262) <a href="#rule_9">9</a></li>
|
||||
<li><b>")"</b> (263) <a href="#rule_9">9</a></li>
|
||||
</ul>
|
||||
|
||||
<h3><a name="nonterminals" id="nonterminals"></a> Nonterminals, with rules where they appear</h3>
|
||||
|
||||
<ul>
|
||||
<li><b>$accept</b> (9)
|
||||
<ul>
|
||||
<li>on left: <a href="#rule_0">0</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><b>unit</b> (10)
|
||||
<ul>
|
||||
<li>on left: <a href="#rule_1">1</a></li>
|
||||
<li>on right: <a href="#rule_0">0</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><b>assignments</b> (11)
|
||||
<ul>
|
||||
<li>on left: <a href="#rule_2">2</a> <a href="#rule_3">3</a></li>
|
||||
<li>on right: <a href="#rule_1">1</a> <a href="#rule_3">3</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><b>assignment</b> (12)
|
||||
<ul>
|
||||
<li>on left: <a href="#rule_4">4</a></li>
|
||||
<li>on right: <a href="#rule_3">3</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><b>id</b> <std::string> (13)
|
||||
<ul>
|
||||
<li>on left: <a href="#rule_5">5</a></li>
|
||||
<li>on right: <a href="#rule_4">4</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><b>exp</b> <int> (14)
|
||||
<ul>
|
||||
<li>on left: <a href="#rule_8">8</a> <a href="#rule_9">9</a> <a href="#rule_10">10</a> <a href="#rule_11">11</a></li>
|
||||
<li>on right: <a href="#rule_1">1</a> <a href="#rule_4">4</a> <a href="#rule_8">8</a> <a href="#rule_9">9</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><b>@1</b> <int> (15)
|
||||
<ul>
|
||||
<li>on left: <a href="#rule_6">6</a></li>
|
||||
<li>on right: <a href="#rule_8">8</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><b>@2</b> <int> (16)
|
||||
<ul>
|
||||
<li>on left: <a href="#rule_7">7</a></li>
|
||||
<li>on right: <a href="#rule_8">8</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul><h2><a name="automaton" id="automaton"></a> Automaton</h2>
|
||||
|
||||
<h3><a name="state_0" id="state_0"></a>State 0</h3>
|
||||
|
||||
<p class="pre"> <a href="#rule_0"> 0</a> <span class="i">$accept</span> → <span class="dot">•</span> <span class="i">unit</span> <b>"end of file"</b>
|
||||
<a href="#rule_1"> 1</a> <span class="i">unit</span> → <span class="dot">•</span> <span class="i">assignments</span> <span class="i">exp</span>
|
||||
<a href="#rule_2"> 2</a> <span class="i">assignments</span> → <span class="dot">•</span> %empty
|
||||
<a href="#rule_3"> 3</a> | <span class="dot">•</span> <span class="i">assignments</span> <span class="i">assignment</span>
|
||||
|
||||
$default <a href="#rule_2">reduce using rule 2</a> (assignments)
|
||||
|
||||
unit <a href="#state_1">go to state 1</a>
|
||||
assignments <a href="#state_2">go to state 2</a>
|
||||
</p>
|
||||
|
||||
<h3><a name="state_1" id="state_1"></a>State 1</h3>
|
||||
|
||||
<p class="pre"> <a href="#rule_0"> 0</a> <span class="i">$accept</span> → <span class="i">unit</span> <span class="dot">•</span> <b>"end of file"</b>
|
||||
|
||||
"end of file" <a href="#state_3">shift, and go to state 3</a>
|
||||
</p>
|
||||
|
||||
<h3><a name="state_2" id="state_2"></a>State 2</h3>
|
||||
|
||||
<p class="pre"> <a href="#rule_1"> 1</a> <span class="i">unit</span> → <span class="i">assignments</span> <span class="dot">•</span> <span class="i">exp</span>
|
||||
<a href="#rule_3"> 3</a> <span class="i">assignments</span> → <span class="i">assignments</span> <span class="dot">•</span> <span class="i">assignment</span>
|
||||
<a href="#rule_4"> 4</a> <span class="i">assignment</span> → <span class="dot">•</span> <span class="i">id</span> <b>":="</b> <span class="i">exp</span>
|
||||
<a href="#rule_5"> 5</a> <span class="i">id</span> → <span class="dot">•</span> <b>"identifier"</b>
|
||||
<a href="#rule_8"> 8</a> <span class="i">exp</span> → <span class="dot">•</span> <b>"incr"</b> <span class="i">exp</span> <span class="i">@1</span> <span class="i">@2</span> <span class="i">exp</span>
|
||||
<a href="#rule_9"> 9</a> | <span class="dot">•</span> <b>"("</b> <span class="i">exp</span> <b>")"</b>
|
||||
<a href="#rule_10"> 10</a> | <span class="dot">•</span> <b>"identifier"</b>
|
||||
<a href="#rule_11"> 11</a> | <span class="dot">•</span> <b>"number"</b>
|
||||
|
||||
"incr" <a href="#state_4">shift, and go to state 4</a>
|
||||
"identifier" <a href="#state_5">shift, and go to state 5</a>
|
||||
"number" <a href="#state_6">shift, and go to state 6</a>
|
||||
"(" <a href="#state_7">shift, and go to state 7</a>
|
||||
|
||||
assignment <a href="#state_8">go to state 8</a>
|
||||
id <a href="#state_9">go to state 9</a>
|
||||
exp <a href="#state_10">go to state 10</a>
|
||||
</p>
|
||||
|
||||
<h3><a name="state_3" id="state_3"></a>State 3</h3>
|
||||
|
||||
<p class="pre"> <a href="#rule_0"> 0</a> <span class="i">$accept</span> → <span class="i">unit</span> <b>"end of file"</b> <span class="dot">•</span>
|
||||
|
||||
$default accept
|
||||
</p>
|
||||
|
||||
<h3><a name="state_4" id="state_4"></a>State 4</h3>
|
||||
|
||||
<p class="pre"> <a href="#rule_8"> 8</a> <span class="i">exp</span> → <span class="dot">•</span> <b>"incr"</b> <span class="i">exp</span> <span class="i">@1</span> <span class="i">@2</span> <span class="i">exp</span>
|
||||
<a href="#rule_8"> 8</a> | <b>"incr"</b> <span class="dot">•</span> <span class="i">exp</span> <span class="i">@1</span> <span class="i">@2</span> <span class="i">exp</span>
|
||||
<a href="#rule_9"> 9</a> | <span class="dot">•</span> <b>"("</b> <span class="i">exp</span> <b>")"</b>
|
||||
<a href="#rule_10"> 10</a> | <span class="dot">•</span> <b>"identifier"</b>
|
||||
<a href="#rule_11"> 11</a> | <span class="dot">•</span> <b>"number"</b>
|
||||
|
||||
"incr" <a href="#state_4">shift, and go to state 4</a>
|
||||
"identifier" <a href="#state_11">shift, and go to state 11</a>
|
||||
"number" <a href="#state_6">shift, and go to state 6</a>
|
||||
"(" <a href="#state_7">shift, and go to state 7</a>
|
||||
|
||||
exp <a href="#state_12">go to state 12</a>
|
||||
</p>
|
||||
|
||||
<h3><a name="state_5" id="state_5"></a>State 5</h3>
|
||||
|
||||
<p class="pre"> <a href="#rule_5"> 5</a> <span class="i">id</span> → <b>"identifier"</b> <span class="dot">•</span> [":="]
|
||||
<a href="#rule_10"> 10</a> <span class="i">exp</span> → <b>"identifier"</b> <span class="dot">•</span> ["end of file"]
|
||||
|
||||
"end of file" <a href="#rule_10">reduce using rule 10</a> (exp)
|
||||
$default <a href="#rule_5">reduce using rule 5</a> (id)
|
||||
</p>
|
||||
|
||||
<h3><a name="state_6" id="state_6"></a>State 6</h3>
|
||||
|
||||
<p class="pre"> <a href="#rule_11"> 11</a> <span class="i">exp</span> → <b>"number"</b> <span class="dot">•</span>
|
||||
|
||||
$default <a href="#rule_11">reduce using rule 11</a> (exp)
|
||||
</p>
|
||||
|
||||
<h3><a name="state_7" id="state_7"></a>State 7</h3>
|
||||
|
||||
<p class="pre"> <a href="#rule_8"> 8</a> <span class="i">exp</span> → <span class="dot">•</span> <b>"incr"</b> <span class="i">exp</span> <span class="i">@1</span> <span class="i">@2</span> <span class="i">exp</span>
|
||||
<a href="#rule_9"> 9</a> | <span class="dot">•</span> <b>"("</b> <span class="i">exp</span> <b>")"</b>
|
||||
<a href="#rule_9"> 9</a> | <b>"("</b> <span class="dot">•</span> <span class="i">exp</span> <b>")"</b>
|
||||
<a href="#rule_10"> 10</a> | <span class="dot">•</span> <b>"identifier"</b>
|
||||
<a href="#rule_11"> 11</a> | <span class="dot">•</span> <b>"number"</b>
|
||||
|
||||
"incr" <a href="#state_4">shift, and go to state 4</a>
|
||||
"identifier" <a href="#state_11">shift, and go to state 11</a>
|
||||
"number" <a href="#state_6">shift, and go to state 6</a>
|
||||
"(" <a href="#state_7">shift, and go to state 7</a>
|
||||
|
||||
exp <a href="#state_13">go to state 13</a>
|
||||
</p>
|
||||
|
||||
<h3><a name="state_8" id="state_8"></a>State 8</h3>
|
||||
|
||||
<p class="pre"> <a href="#rule_3"> 3</a> <span class="i">assignments</span> → <span class="i">assignments</span> <span class="i">assignment</span> <span class="dot">•</span>
|
||||
|
||||
$default <a href="#rule_3">reduce using rule 3</a> (assignments)
|
||||
</p>
|
||||
|
||||
<h3><a name="state_9" id="state_9"></a>State 9</h3>
|
||||
|
||||
<p class="pre"> <a href="#rule_4"> 4</a> <span class="i">assignment</span> → <span class="i">id</span> <span class="dot">•</span> <b>":="</b> <span class="i">exp</span>
|
||||
|
||||
":=" <a href="#state_14">shift, and go to state 14</a>
|
||||
</p>
|
||||
|
||||
<h3><a name="state_10" id="state_10"></a>State 10</h3>
|
||||
|
||||
<p class="pre"> <a href="#rule_1"> 1</a> <span class="i">unit</span> → <span class="i">assignments</span> <span class="i">exp</span> <span class="dot">•</span>
|
||||
|
||||
$default <a href="#rule_1">reduce using rule 1</a> (unit)
|
||||
</p>
|
||||
|
||||
<h3><a name="state_11" id="state_11"></a>State 11</h3>
|
||||
|
||||
<p class="pre"> <a href="#rule_10"> 10</a> <span class="i">exp</span> → <b>"identifier"</b> <span class="dot">•</span>
|
||||
|
||||
$default <a href="#rule_10">reduce using rule 10</a> (exp)
|
||||
</p>
|
||||
|
||||
<h3><a name="state_12" id="state_12"></a>State 12</h3>
|
||||
|
||||
<p class="pre"> <a href="#rule_6"> 6</a> <span class="i">@1</span> → <span class="dot">•</span> %empty
|
||||
<a href="#rule_8"> 8</a> <span class="i">exp</span> → <b>"incr"</b> <span class="i">exp</span> <span class="dot">•</span> <span class="i">@1</span> <span class="i">@2</span> <span class="i">exp</span>
|
||||
|
||||
$default <a href="#rule_6">reduce using rule 6</a> (@1)
|
||||
|
||||
@1 <a href="#state_15">go to state 15</a>
|
||||
</p>
|
||||
|
||||
<h3><a name="state_13" id="state_13"></a>State 13</h3>
|
||||
|
||||
<p class="pre"> <a href="#rule_9"> 9</a> <span class="i">exp</span> → <b>"("</b> <span class="i">exp</span> <span class="dot">•</span> <b>")"</b>
|
||||
|
||||
")" <a href="#state_16">shift, and go to state 16</a>
|
||||
</p>
|
||||
|
||||
<h3><a name="state_14" id="state_14"></a>State 14</h3>
|
||||
|
||||
<p class="pre"> <a href="#rule_4"> 4</a> <span class="i">assignment</span> → <span class="i">id</span> <b>":="</b> <span class="dot">•</span> <span class="i">exp</span>
|
||||
<a href="#rule_8"> 8</a> <span class="i">exp</span> → <span class="dot">•</span> <b>"incr"</b> <span class="i">exp</span> <span class="i">@1</span> <span class="i">@2</span> <span class="i">exp</span>
|
||||
<a href="#rule_9"> 9</a> | <span class="dot">•</span> <b>"("</b> <span class="i">exp</span> <b>")"</b>
|
||||
<a href="#rule_10"> 10</a> | <span class="dot">•</span> <b>"identifier"</b>
|
||||
<a href="#rule_11"> 11</a> | <span class="dot">•</span> <b>"number"</b>
|
||||
|
||||
"incr" <a href="#state_4">shift, and go to state 4</a>
|
||||
"identifier" <a href="#state_11">shift, and go to state 11</a>
|
||||
"number" <a href="#state_6">shift, and go to state 6</a>
|
||||
"(" <a href="#state_7">shift, and go to state 7</a>
|
||||
|
||||
exp <a href="#state_17">go to state 17</a>
|
||||
</p>
|
||||
|
||||
<h3><a name="state_15" id="state_15"></a>State 15</h3>
|
||||
|
||||
<p class="pre"> <a href="#rule_7"> 7</a> <span class="i">@2</span> → <span class="dot">•</span> %empty
|
||||
<a href="#rule_8"> 8</a> <span class="i">exp</span> → <b>"incr"</b> <span class="i">exp</span> <span class="i">@1</span> <span class="dot">•</span> <span class="i">@2</span> <span class="i">exp</span>
|
||||
|
||||
$default <a href="#rule_7">reduce using rule 7</a> (@2)
|
||||
|
||||
@2 <a href="#state_18">go to state 18</a>
|
||||
</p>
|
||||
|
||||
<h3><a name="state_16" id="state_16"></a>State 16</h3>
|
||||
|
||||
<p class="pre"> <a href="#rule_9"> 9</a> <span class="i">exp</span> → <b>"("</b> <span class="i">exp</span> <b>")"</b> <span class="dot">•</span>
|
||||
|
||||
$default <a href="#rule_9">reduce using rule 9</a> (exp)
|
||||
</p>
|
||||
|
||||
<h3><a name="state_17" id="state_17"></a>State 17</h3>
|
||||
|
||||
<p class="pre"> <a href="#rule_4"> 4</a> <span class="i">assignment</span> → <span class="i">id</span> <b>":="</b> <span class="i">exp</span> <span class="dot">•</span>
|
||||
|
||||
$default <a href="#rule_4">reduce using rule 4</a> (assignment)
|
||||
</p>
|
||||
|
||||
<h3><a name="state_18" id="state_18"></a>State 18</h3>
|
||||
|
||||
<p class="pre"> <a href="#rule_8"> 8</a> <span class="i">exp</span> → <span class="dot">•</span> <b>"incr"</b> <span class="i">exp</span> <span class="i">@1</span> <span class="i">@2</span> <span class="i">exp</span>
|
||||
<a href="#rule_8"> 8</a> | <b>"incr"</b> <span class="i">exp</span> <span class="i">@1</span> <span class="i">@2</span> <span class="dot">•</span> <span class="i">exp</span>
|
||||
<a href="#rule_9"> 9</a> | <span class="dot">•</span> <b>"("</b> <span class="i">exp</span> <b>")"</b>
|
||||
<a href="#rule_10"> 10</a> | <span class="dot">•</span> <b>"identifier"</b>
|
||||
<a href="#rule_11"> 11</a> | <span class="dot">•</span> <b>"number"</b>
|
||||
|
||||
"incr" <a href="#state_4">shift, and go to state 4</a>
|
||||
"identifier" <a href="#state_11">shift, and go to state 11</a>
|
||||
"number" <a href="#state_6">shift, and go to state 6</a>
|
||||
"(" <a href="#state_7">shift, and go to state 7</a>
|
||||
|
||||
exp <a href="#state_19">go to state 19</a>
|
||||
</p>
|
||||
|
||||
<h3><a name="state_19" id="state_19"></a>State 19</h3>
|
||||
|
||||
<p class="pre"> <a href="#rule_8"> 8</a> <span class="i">exp</span> → <b>"incr"</b> <span class="i">exp</span> <span class="i">@1</span> <span class="i">@2</span> <span class="i">exp</span> <span class="dot">•</span>
|
||||
|
||||
$default <a href="#rule_8">reduce using rule 8</a> (exp)
|
||||
</p>
|
||||
|
||||
<div id="footer"><hr />This document was generated using
|
||||
<a href="http://www.gnu.org/software/bison/" title="GNU Bison">
|
||||
GNU Bison VERSION</a>
|
||||
XML Automaton Report.<br />
|
||||
Verbatim copying and distribution of this entire page is
|
||||
permitted in any medium, provided this notice is preserved.</div></body>
|
||||
</html>
|
||||
]])
|
||||
fi
|
||||
|
||||
AT_BISON_OPTION_POPDEFS
|
||||
AT_CLEANUP
|
||||
@@ -1172,39 +1539,74 @@ AT_CHECK([LC_ALL="$locale" bison -fno-caret -o input.cc -rall -Wcex --graph=inpu
|
||||
input.y: warning: 3 reduce/reduce conflicts [-Wconflicts-rr]
|
||||
Shift/reduce conflict on token "⊕":
|
||||
Example exp "+" exp • "⊕" exp
|
||||
First derivation exp ::=[ exp ::=[ exp "+" exp • ] "⊕" exp ]
|
||||
Second derivation exp ::=[ exp "+" exp ::=[ exp • "⊕" exp ] ]
|
||||
Shift derivation
|
||||
exp
|
||||
↳ exp "+" exp
|
||||
↳ exp • "⊕" exp
|
||||
Reduce derivation
|
||||
exp
|
||||
↳ exp "⊕" exp
|
||||
↳ exp "+" exp •
|
||||
|
||||
Reduce/reduce conflict on tokens $end, "+", "⊕":
|
||||
Example exp "+" exp •
|
||||
First derivation exp ::=[ exp "+" exp • ]
|
||||
Second derivation exp ::=[ exp "+" exp • ]
|
||||
First derivation
|
||||
exp
|
||||
↳ exp "+" exp •
|
||||
Second derivation
|
||||
exp
|
||||
↳ exp "+" exp •
|
||||
|
||||
Shift/reduce conflict on token "⊕":
|
||||
Example exp "+" exp • "⊕" exp
|
||||
First derivation exp ::=[ exp ::=[ exp "+" exp • ] "⊕" exp ]
|
||||
Second derivation exp ::=[ exp "+" exp ::=[ exp • "⊕" exp ] ]
|
||||
Shift derivation
|
||||
exp
|
||||
↳ exp "+" exp
|
||||
↳ exp • "⊕" exp
|
||||
Reduce derivation
|
||||
exp
|
||||
↳ exp "⊕" exp
|
||||
↳ exp "+" exp •
|
||||
|
||||
Shift/reduce conflict on token "⊕":
|
||||
Example exp "⊕" exp • "⊕" exp
|
||||
First derivation exp ::=[ exp ::=[ exp "⊕" exp • ] "⊕" exp ]
|
||||
Second derivation exp ::=[ exp "⊕" exp ::=[ exp • "⊕" exp ] ]
|
||||
Shift derivation
|
||||
exp
|
||||
↳ exp "⊕" exp
|
||||
↳ exp • "⊕" exp
|
||||
Reduce derivation
|
||||
exp
|
||||
↳ exp "⊕" exp
|
||||
↳ exp "⊕" exp •
|
||||
|
||||
Shift/reduce conflict on token "+":
|
||||
Example exp "⊕" exp • "+" exp
|
||||
First derivation exp ::=[ exp ::=[ exp "⊕" exp • ] "+" exp ]
|
||||
Second derivation exp ::=[ exp "⊕" exp ::=[ exp • "+" exp ] ]
|
||||
Shift derivation
|
||||
exp
|
||||
↳ exp "⊕" exp
|
||||
↳ exp • "+" exp
|
||||
Reduce derivation
|
||||
exp
|
||||
↳ exp "+" exp
|
||||
↳ exp "⊕" exp •
|
||||
|
||||
Shift/reduce conflict on token "+":
|
||||
Example exp "⊕" exp • "+" exp
|
||||
First derivation exp ::=[ exp ::=[ exp "⊕" exp • ] "+" exp ]
|
||||
Second derivation exp ::=[ exp "⊕" exp ::=[ exp • "+" exp ] ]
|
||||
Shift derivation
|
||||
exp
|
||||
↳ exp "⊕" exp
|
||||
↳ exp • "+" exp
|
||||
Reduce derivation
|
||||
exp
|
||||
↳ exp "+" exp
|
||||
↳ exp "⊕" exp •
|
||||
|
||||
input.y:6.3-13: warning: rule useless in parser due to conflicts [-Wother]
|
||||
]])
|
||||
|
||||
# Check the contents of the report.
|
||||
AT_CHECK([cat input.output], [],
|
||||
# FIXME: Avoid trailing white spaces.
|
||||
AT_CHECK([sed -e 's/ *$//' input.output], [],
|
||||
[[Rules useless in parser due to conflicts
|
||||
|
||||
3 exp: exp "+" exp
|
||||
@@ -1347,22 +1749,38 @@ State 7
|
||||
2 exp: exp "+" exp •
|
||||
1 exp: exp • "⊕" exp
|
||||
Example exp "+" exp • "⊕" exp
|
||||
First derivation exp ::=[ exp ::=[ exp "+" exp • ] "⊕" exp ]
|
||||
Second derivation exp ::=[ exp "+" exp ::=[ exp • "⊕" exp ] ]
|
||||
Shift derivation
|
||||
exp
|
||||
↳ exp "+" exp
|
||||
↳ exp • "⊕" exp
|
||||
Reduce derivation
|
||||
exp
|
||||
↳ exp "⊕" exp
|
||||
↳ exp "+" exp •
|
||||
|
||||
Reduce/reduce conflict on tokens $end, "+", "⊕":
|
||||
2 exp: exp "+" exp •
|
||||
3 exp: exp "+" exp •
|
||||
Example exp "+" exp •
|
||||
First derivation exp ::=[ exp "+" exp • ]
|
||||
Second derivation exp ::=[ exp "+" exp • ]
|
||||
First derivation
|
||||
exp
|
||||
↳ exp "+" exp •
|
||||
Second derivation
|
||||
exp
|
||||
↳ exp "+" exp •
|
||||
|
||||
Shift/reduce conflict on token "⊕":
|
||||
3 exp: exp "+" exp •
|
||||
1 exp: exp • "⊕" exp
|
||||
Example exp "+" exp • "⊕" exp
|
||||
First derivation exp ::=[ exp ::=[ exp "+" exp • ] "⊕" exp ]
|
||||
Second derivation exp ::=[ exp "+" exp ::=[ exp • "⊕" exp ] ]
|
||||
Shift derivation
|
||||
exp
|
||||
↳ exp "+" exp
|
||||
↳ exp • "⊕" exp
|
||||
Reduce derivation
|
||||
exp
|
||||
↳ exp "⊕" exp
|
||||
↳ exp "+" exp •
|
||||
|
||||
|
||||
|
||||
@@ -1384,22 +1802,40 @@ State 8
|
||||
1 exp: exp "⊕" exp •
|
||||
1 exp: exp • "⊕" exp
|
||||
Example exp "⊕" exp • "⊕" exp
|
||||
First derivation exp ::=[ exp ::=[ exp "⊕" exp • ] "⊕" exp ]
|
||||
Second derivation exp ::=[ exp "⊕" exp ::=[ exp • "⊕" exp ] ]
|
||||
Shift derivation
|
||||
exp
|
||||
↳ exp "⊕" exp
|
||||
↳ exp • "⊕" exp
|
||||
Reduce derivation
|
||||
exp
|
||||
↳ exp "⊕" exp
|
||||
↳ exp "⊕" exp •
|
||||
|
||||
Shift/reduce conflict on token "+":
|
||||
1 exp: exp "⊕" exp •
|
||||
2 exp: exp • "+" exp
|
||||
Example exp "⊕" exp • "+" exp
|
||||
First derivation exp ::=[ exp ::=[ exp "⊕" exp • ] "+" exp ]
|
||||
Second derivation exp ::=[ exp "⊕" exp ::=[ exp • "+" exp ] ]
|
||||
Shift derivation
|
||||
exp
|
||||
↳ exp "⊕" exp
|
||||
↳ exp • "+" exp
|
||||
Reduce derivation
|
||||
exp
|
||||
↳ exp "+" exp
|
||||
↳ exp "⊕" exp •
|
||||
|
||||
Shift/reduce conflict on token "+":
|
||||
1 exp: exp "⊕" exp •
|
||||
3 exp: exp • "+" exp
|
||||
Example exp "⊕" exp • "+" exp
|
||||
First derivation exp ::=[ exp ::=[ exp "⊕" exp • ] "+" exp ]
|
||||
Second derivation exp ::=[ exp "⊕" exp ::=[ exp • "+" exp ] ]
|
||||
Shift derivation
|
||||
exp
|
||||
↳ exp "⊕" exp
|
||||
↳ exp • "+" exp
|
||||
Reduce derivation
|
||||
exp
|
||||
↳ exp "+" exp
|
||||
↳ exp "⊕" exp •
|
||||
|
||||
]])
|
||||
|
||||
@@ -1514,16 +1950,16 @@ AT_CHECK([[sed -e 's/bison-xml-report version="[^"]*"/bison-xml-report version="
|
||||
</rule>
|
||||
</rules>
|
||||
<terminals>
|
||||
<terminal symbol-number="0" token-number="0" name="$end" usefulness="useful"/>
|
||||
<terminal symbol-number="1" token-number="256" name="error" usefulness="useful"/>
|
||||
<terminal symbol-number="3" token-number="258" name=""+"" usefulness="useful" prec="1" assoc="left"/>
|
||||
<terminal symbol-number="4" token-number="259" name=""⊕"" usefulness="useful"/>
|
||||
<terminal symbol-number="5" token-number="260" name=""number"" usefulness="useful"/>
|
||||
<terminal symbol-number="6" token-number="261" name=""Ñùṃéℝô"" usefulness="useful"/>
|
||||
<terminal symbol-number="0" token-number="0" name="$end" type="" usefulness="useful"/>
|
||||
<terminal symbol-number="1" token-number="256" name="error" type="" usefulness="useful"/>
|
||||
<terminal symbol-number="3" token-number="258" name=""+"" type="" usefulness="useful" prec="1" assoc="left"/>
|
||||
<terminal symbol-number="4" token-number="259" name=""⊕"" type="" usefulness="useful"/>
|
||||
<terminal symbol-number="5" token-number="260" name=""number"" type="" usefulness="useful"/>
|
||||
<terminal symbol-number="6" token-number="261" name=""Ñùṃéℝô"" type="" usefulness="useful"/>
|
||||
</terminals>
|
||||
<nonterminals>
|
||||
<nonterminal symbol-number="7" name="$accept" usefulness="useful"/>
|
||||
<nonterminal symbol-number="8" name="exp" usefulness="useful"/>
|
||||
<nonterminal symbol-number="7" name="$accept" type="" usefulness="useful"/>
|
||||
<nonterminal symbol-number="8" name="exp" type="" usefulness="useful"/>
|
||||
</nonterminals>
|
||||
</grammar>
|
||||
|
||||
@@ -1725,6 +2161,243 @@ AT_CHECK([[sed -e 's/bison-xml-report version="[^"]*"/bison-xml-report version="
|
||||
</bison-xml-report>
|
||||
]])
|
||||
|
||||
# Check HTML output.
|
||||
if test x"$XSLTPROC" != x""; then
|
||||
AT_CHECK([[$XSLTPROC \
|
||||
`]]AT_SET_ENV[[ bison --print-datadir`/xslt/xml2xhtml.xsl \
|
||||
input.xml | \
|
||||
sed -e 's/GNU Bison [0-9][-.0-9a-z]*/GNU Bison VERSION/' \
|
||||
>input.html]])
|
||||
|
||||
AT_CHECK([cat input.html], [],
|
||||
[[<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:bison="http://www.gnu.org/software/bison/">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
|
||||
<title>input.y - GNU Bison XML Automaton Report</title>
|
||||
<style type="text/css">
|
||||
body {
|
||||
font-family: "Nimbus Sans L", Arial, sans-serif;
|
||||
font-size: 9pt;
|
||||
}
|
||||
a:link {
|
||||
color: #1f00ff;
|
||||
text-decoration: none;
|
||||
}
|
||||
a:visited {
|
||||
color: #1f00ff;
|
||||
text-decoration: none;
|
||||
}
|
||||
a:hover {
|
||||
color: red;
|
||||
}
|
||||
#menu a {
|
||||
text-decoration: underline;
|
||||
}
|
||||
.i {
|
||||
font-style: italic;
|
||||
}
|
||||
.pre {
|
||||
font-family: monospace;
|
||||
white-space: pre;
|
||||
}
|
||||
ol.decimal {
|
||||
list-style-type: decimal;
|
||||
}
|
||||
ol.lower-alpha {
|
||||
list-style-type: lower-alpha;
|
||||
}
|
||||
.dot {
|
||||
color: #cc0000;
|
||||
}
|
||||
#footer {
|
||||
margin-top: 3.5em;
|
||||
font-size: 7pt;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body><h1>GNU Bison XML Automaton Report</h1><p>
|
||||
input grammar: <span class="i">input.y</span></p>
|
||||
|
||||
<h3>Table of Contents</h3><ul id="menu"><li><a href="#reductions">Reductions</a><ul class="lower-alpha"><li><a href="#nonterminals_useless_in_grammar">Nonterminals useless in grammar</a></li><li><a href="#terminals_unused_in_grammar">Terminals unused in grammar</a></li><li><a href="#rules_useless_in_grammar">Rules useless in grammar</a></li><li><a href="#rules_useless_in_parser">Rules useless in parser due to conflicts</a></li></ul></li><li><a href="#conflicts">Conflicts</a></li><li><a href="#grammar">Grammar</a><ul class="lower-alpha"><li><a href="#grammar">Itemset</a></li><li><a href="#terminals">Terminal symbols</a></li><li><a href="#nonterminals">Nonterminal symbols</a></li></ul></li><li><a href="#automaton">Automaton</a></li></ul><h2><a name="reductions" id="reductions"></a> Reductions</h2><h3><a name="nonterminals_useless_in_grammar" id="nonterminals_useless_in_grammar"></a> Nonterminals useless in grammar</h3>
|
||||
|
||||
<h3><a name="terminals_unused_in_grammar" id="terminals_unused_in_grammar"></a> Terminals unused in grammar</h3>
|
||||
|
||||
<h3><a name="rules_useless_in_grammar" id="rules_useless_in_grammar"></a> Rules useless in grammar</h3>
|
||||
<h2><a name="rules_useless_in_parser" id="rules_useless_in_parser"></a> Rules useless in parser due to conflicts</h2>
|
||||
<p class="pre">
|
||||
<a href="#rule_3"> 3</a> <span class="i">exp</span> → <span class="i">exp</span> <b>"+"</b> <span class="i">exp</span>
|
||||
</p>
|
||||
|
||||
<h2><a name="conflicts" id="conflicts"></a> Conflicts</h2>
|
||||
|
||||
<p class="pre"><a href="#state_7">State 7</a> conflicts: 1 shift/reduce, 3 reduce/reduce
|
||||
<a href="#state_8">State 8</a> conflicts: 2 shift/reduce
|
||||
|
||||
|
||||
</p><h2><a name="grammar" id="grammar"></a> Grammar</h2>
|
||||
<p class="pre">
|
||||
<a name="rule_0" id="rule_0"> 0</a> <span class="i">$accept</span> → <span class="i">exp</span> <b>$end</b>
|
||||
|
||||
<a name="rule_1" id="rule_1"> 1</a> <span class="i">exp</span> → <span class="i">exp</span> <b>"⊕"</b> <span class="i">exp</span>
|
||||
<a name="rule_2" id="rule_2"> 2</a> | <span class="i">exp</span> <b>"+"</b> <span class="i">exp</span>
|
||||
<a name="rule_3" id="rule_3"> 3</a> | <span class="i">exp</span> <b>"+"</b> <span class="i">exp</span>
|
||||
<a name="rule_4" id="rule_4"> 4</a> | <b>"number"</b>
|
||||
<a name="rule_5" id="rule_5"> 5</a> | <b>"Ñùṃéℝô"</b>
|
||||
</p>
|
||||
|
||||
<h3><a name="terminals" id="terminals"></a> Terminals, with rules where they appear</h3>
|
||||
|
||||
<ul>
|
||||
<li><b>$end</b> (0) <a href="#rule_0">0</a></li>
|
||||
<li><b>error</b> (256)</li>
|
||||
<li><b>"+"</b> (258) <a href="#rule_2">2</a> <a href="#rule_3">3</a></li>
|
||||
<li><b>"⊕"</b> (259) <a href="#rule_1">1</a></li>
|
||||
<li><b>"number"</b> (260) <a href="#rule_4">4</a></li>
|
||||
<li><b>"Ñùṃéℝô"</b> (261) <a href="#rule_5">5</a></li>
|
||||
</ul>
|
||||
|
||||
<h3><a name="nonterminals" id="nonterminals"></a> Nonterminals, with rules where they appear</h3>
|
||||
|
||||
<ul>
|
||||
<li><b>$accept</b> (7)
|
||||
<ul>
|
||||
<li>on left: <a href="#rule_0">0</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><b>exp</b> (8)
|
||||
<ul>
|
||||
<li>on left: <a href="#rule_1">1</a> <a href="#rule_2">2</a> <a href="#rule_3">3</a> <a href="#rule_4">4</a> <a href="#rule_5">5</a></li>
|
||||
<li>on right: <a href="#rule_0">0</a> <a href="#rule_1">1</a> <a href="#rule_2">2</a> <a href="#rule_3">3</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul><h2><a name="automaton" id="automaton"></a> Automaton</h2>
|
||||
|
||||
<h3><a name="state_0" id="state_0"></a>State 0</h3>
|
||||
|
||||
<p class="pre"> <a href="#rule_0"> 0</a> <span class="i">$accept</span> → <span class="dot">•</span> <span class="i">exp</span> <b>$end</b>
|
||||
<a href="#rule_1"> 1</a> <span class="i">exp</span> → <span class="dot">•</span> <span class="i">exp</span> <b>"⊕"</b> <span class="i">exp</span>
|
||||
<a href="#rule_2"> 2</a> | <span class="dot">•</span> <span class="i">exp</span> <b>"+"</b> <span class="i">exp</span>
|
||||
<a href="#rule_3"> 3</a> | <span class="dot">•</span> <span class="i">exp</span> <b>"+"</b> <span class="i">exp</span>
|
||||
<a href="#rule_4"> 4</a> | <span class="dot">•</span> <b>"number"</b>
|
||||
<a href="#rule_5"> 5</a> | <span class="dot">•</span> <b>"Ñùṃéℝô"</b>
|
||||
|
||||
"number" <a href="#state_1">shift, and go to state 1</a>
|
||||
"Ñùṃéℝô" <a href="#state_2">shift, and go to state 2</a>
|
||||
|
||||
exp <a href="#state_3">go to state 3</a>
|
||||
</p>
|
||||
|
||||
<h3><a name="state_1" id="state_1"></a>State 1</h3>
|
||||
|
||||
<p class="pre"> <a href="#rule_4"> 4</a> <span class="i">exp</span> → <b>"number"</b> <span class="dot">•</span>
|
||||
|
||||
$default <a href="#rule_4">reduce using rule 4</a> (exp)
|
||||
</p>
|
||||
|
||||
<h3><a name="state_2" id="state_2"></a>State 2</h3>
|
||||
|
||||
<p class="pre"> <a href="#rule_5"> 5</a> <span class="i">exp</span> → <b>"Ñùṃéℝô"</b> <span class="dot">•</span>
|
||||
|
||||
$default <a href="#rule_5">reduce using rule 5</a> (exp)
|
||||
</p>
|
||||
|
||||
<h3><a name="state_3" id="state_3"></a>State 3</h3>
|
||||
|
||||
<p class="pre"> <a href="#rule_0"> 0</a> <span class="i">$accept</span> → <span class="i">exp</span> <span class="dot">•</span> <b>$end</b>
|
||||
<a href="#rule_1"> 1</a> <span class="i">exp</span> → <span class="i">exp</span> <span class="dot">•</span> <b>"⊕"</b> <span class="i">exp</span>
|
||||
<a href="#rule_2"> 2</a> | <span class="i">exp</span> <span class="dot">•</span> <b>"+"</b> <span class="i">exp</span>
|
||||
<a href="#rule_3"> 3</a> | <span class="i">exp</span> <span class="dot">•</span> <b>"+"</b> <span class="i">exp</span>
|
||||
|
||||
$end <a href="#state_4">shift, and go to state 4</a>
|
||||
"+" <a href="#state_5">shift, and go to state 5</a>
|
||||
"⊕" <a href="#state_6">shift, and go to state 6</a>
|
||||
</p>
|
||||
|
||||
<h3><a name="state_4" id="state_4"></a>State 4</h3>
|
||||
|
||||
<p class="pre"> <a href="#rule_0"> 0</a> <span class="i">$accept</span> → <span class="i">exp</span> <b>$end</b> <span class="dot">•</span>
|
||||
|
||||
$default accept
|
||||
</p>
|
||||
|
||||
<h3><a name="state_5" id="state_5"></a>State 5</h3>
|
||||
|
||||
<p class="pre"> <a href="#rule_1"> 1</a> <span class="i">exp</span> → <span class="dot">•</span> <span class="i">exp</span> <b>"⊕"</b> <span class="i">exp</span>
|
||||
<a href="#rule_2"> 2</a> | <span class="dot">•</span> <span class="i">exp</span> <b>"+"</b> <span class="i">exp</span>
|
||||
<a href="#rule_2"> 2</a> | <span class="i">exp</span> <b>"+"</b> <span class="dot">•</span> <span class="i">exp</span>
|
||||
<a href="#rule_3"> 3</a> | <span class="dot">•</span> <span class="i">exp</span> <b>"+"</b> <span class="i">exp</span>
|
||||
<a href="#rule_3"> 3</a> | <span class="i">exp</span> <b>"+"</b> <span class="dot">•</span> <span class="i">exp</span>
|
||||
<a href="#rule_4"> 4</a> | <span class="dot">•</span> <b>"number"</b>
|
||||
<a href="#rule_5"> 5</a> | <span class="dot">•</span> <b>"Ñùṃéℝô"</b>
|
||||
|
||||
"number" <a href="#state_1">shift, and go to state 1</a>
|
||||
"Ñùṃéℝô" <a href="#state_2">shift, and go to state 2</a>
|
||||
|
||||
exp <a href="#state_7">go to state 7</a>
|
||||
</p>
|
||||
|
||||
<h3><a name="state_6" id="state_6"></a>State 6</h3>
|
||||
|
||||
<p class="pre"> <a href="#rule_1"> 1</a> <span class="i">exp</span> → <span class="dot">•</span> <span class="i">exp</span> <b>"⊕"</b> <span class="i">exp</span>
|
||||
<a href="#rule_1"> 1</a> | <span class="i">exp</span> <b>"⊕"</b> <span class="dot">•</span> <span class="i">exp</span>
|
||||
<a href="#rule_2"> 2</a> | <span class="dot">•</span> <span class="i">exp</span> <b>"+"</b> <span class="i">exp</span>
|
||||
<a href="#rule_3"> 3</a> | <span class="dot">•</span> <span class="i">exp</span> <b>"+"</b> <span class="i">exp</span>
|
||||
<a href="#rule_4"> 4</a> | <span class="dot">•</span> <b>"number"</b>
|
||||
<a href="#rule_5"> 5</a> | <span class="dot">•</span> <b>"Ñùṃéℝô"</b>
|
||||
|
||||
"number" <a href="#state_1">shift, and go to state 1</a>
|
||||
"Ñùṃéℝô" <a href="#state_2">shift, and go to state 2</a>
|
||||
|
||||
exp <a href="#state_8">go to state 8</a>
|
||||
</p>
|
||||
|
||||
<h3><a name="state_7" id="state_7"></a>State 7</h3>
|
||||
|
||||
<p class="pre"> <a href="#rule_1"> 1</a> <span class="i">exp</span> → <span class="i">exp</span> <span class="dot">•</span> <b>"⊕"</b> <span class="i">exp</span>
|
||||
<a href="#rule_2"> 2</a> | <span class="i">exp</span> <span class="dot">•</span> <b>"+"</b> <span class="i">exp</span>
|
||||
<a href="#rule_2"> 2</a> | <span class="i">exp</span> <b>"+"</b> <span class="i">exp</span> <span class="dot">•</span> [$end, "+", "⊕"]
|
||||
<a href="#rule_3"> 3</a> | <span class="i">exp</span> <span class="dot">•</span> <b>"+"</b> <span class="i">exp</span>
|
||||
<a href="#rule_3"> 3</a> | <span class="i">exp</span> <b>"+"</b> <span class="i">exp</span> <span class="dot">•</span> [$end, "+", "⊕"]
|
||||
|
||||
"⊕" <a href="#state_6">shift, and go to state 6</a>
|
||||
|
||||
$end <a href="#rule_2">reduce using rule 2</a> (exp)
|
||||
$end [<a href="#rule_3">reduce using rule 3</a> (exp)]
|
||||
"+" <a href="#rule_2">reduce using rule 2</a> (exp)
|
||||
"+" [<a href="#rule_3">reduce using rule 3</a> (exp)]
|
||||
"⊕" [<a href="#rule_2">reduce using rule 2</a> (exp)]
|
||||
"⊕" [<a href="#rule_3">reduce using rule 3</a> (exp)]
|
||||
$default <a href="#rule_2">reduce using rule 2</a> (exp)
|
||||
|
||||
Conflict between <a href="#rule_2">rule 2</a> and token "+" resolved as reduce (%left "+").
|
||||
</p>
|
||||
|
||||
<h3><a name="state_8" id="state_8"></a>State 8</h3>
|
||||
|
||||
<p class="pre"> <a href="#rule_1"> 1</a> <span class="i">exp</span> → <span class="i">exp</span> <span class="dot">•</span> <b>"⊕"</b> <span class="i">exp</span>
|
||||
<a href="#rule_1"> 1</a> | <span class="i">exp</span> <b>"⊕"</b> <span class="i">exp</span> <span class="dot">•</span> [$end, "+", "⊕"]
|
||||
<a href="#rule_2"> 2</a> | <span class="i">exp</span> <span class="dot">•</span> <b>"+"</b> <span class="i">exp</span>
|
||||
<a href="#rule_3"> 3</a> | <span class="i">exp</span> <span class="dot">•</span> <b>"+"</b> <span class="i">exp</span>
|
||||
|
||||
"+" <a href="#state_5">shift, and go to state 5</a>
|
||||
"⊕" <a href="#state_6">shift, and go to state 6</a>
|
||||
|
||||
"+" [<a href="#rule_1">reduce using rule 1</a> (exp)]
|
||||
"⊕" [<a href="#rule_1">reduce using rule 1</a> (exp)]
|
||||
$default <a href="#rule_1">reduce using rule 1</a> (exp)
|
||||
</p>
|
||||
|
||||
<div id="footer"><hr />This document was generated using
|
||||
<a href="http://www.gnu.org/software/bison/" title="GNU Bison">
|
||||
GNU Bison VERSION</a>
|
||||
XML Automaton Report.<br />
|
||||
Verbatim copying and distribution of this entire page is
|
||||
permitted in any medium, provided this notice is preserved.</div></body>
|
||||
</html>
|
||||
]])
|
||||
fi
|
||||
|
||||
AT_BISON_OPTION_POPDEFS
|
||||
AT_CLEANUP
|
||||
|
||||
+4
-4
@@ -283,11 +283,11 @@ m4_popdef([AT_TEST])
|
||||
## Many lookahead tokens. ##
|
||||
## ------------------------ ##
|
||||
|
||||
# AT_DATA_LOOKAHEAD_TOKENS_GRAMMAR(FILE-NAME, SIZE)
|
||||
# --------------------------------------------------
|
||||
# AT_DATA_LOOKAHEADS_GRAMMAR(FILE-NAME, SIZE)
|
||||
# -------------------------------------------
|
||||
# Create FILE-NAME, containing a self checking parser for a grammar
|
||||
# requiring SIZE lookahead tokens.
|
||||
m4_define([AT_DATA_LOOKAHEAD_TOKENS_GRAMMAR],
|
||||
m4_define([AT_DATA_LOOKAHEADS_GRAMMAR],
|
||||
[AT_BISON_OPTION_PUSHDEFS
|
||||
AT_DATA([[gengram.pl]],
|
||||
[[#! /usr/bin/perl -w
|
||||
@@ -384,7 +384,7 @@ AT_BISON_OPTION_POPDEFS
|
||||
|
||||
AT_SETUP([Many lookahead tokens])
|
||||
|
||||
AT_DATA_LOOKAHEAD_TOKENS_GRAMMAR([input.y], [1000])
|
||||
AT_DATA_LOOKAHEADS_GRAMMAR([input.y], [1000])
|
||||
|
||||
# GNU m4 requires about 70 MiB for this test on a 32-bit host.
|
||||
# Ask for 200 MiB, which should be plenty even on a 64-bit host.
|
||||
|
||||
Reference in New Issue
Block a user