mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-08-15 05:35:14 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6675d36e25 | ||
|
|
d0bec3175f | ||
|
|
79e68b6c4d | ||
|
|
5cb74cacd8 | ||
|
|
9c8e6e05b6 | ||
|
|
431774d1f6 | ||
|
|
7d5474e979 | ||
|
|
6b78e50cef | ||
|
|
28769d608e | ||
|
|
a22588bcb9 | ||
|
|
b8c5e5609f | ||
|
|
b81229e1f9 | ||
|
|
815a76f558 | ||
|
|
ea138cd1f1 | ||
|
|
9922f1f877 | ||
|
|
1438b79e80 | ||
|
|
01f3e2969b | ||
|
|
744da03955 | ||
|
|
b28d67b6b0 | ||
|
|
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.93
|
||||||
|
|||||||
@@ -1,13 +1,6 @@
|
|||||||
GNU Bison NEWS
|
GNU Bison NEWS
|
||||||
|
|
||||||
* Noteworthy changes in release 3.6.91 (2020-07-09) [beta]
|
* Noteworthy changes in release 3.7 (2020-07-23) [stable]
|
||||||
|
|
||||||
** Bug fixes
|
|
||||||
|
|
||||||
Portability issues.
|
|
||||||
|
|
||||||
|
|
||||||
* Noteworthy changes in release 3.6.90 (2020-07-04) [beta]
|
|
||||||
|
|
||||||
** Deprecated features
|
** Deprecated features
|
||||||
|
|
||||||
@@ -25,35 +18,114 @@ GNU Bison NEWS
|
|||||||
|
|
||||||
Contributed by Vincent Imbimbo.
|
Contributed by Vincent Imbimbo.
|
||||||
|
|
||||||
When given `--report=counterexamples` or `-Wcounterexamples`, bison will
|
When given `-Wcounterexamples`/`-Wcex`, bison will now output
|
||||||
now output counterexamples for conflicts in the grammar. These are
|
counterexamples for conflicts.
|
||||||
strings in the grammar which can be parsed in two ways due to the
|
|
||||||
conflict. For example:
|
|
||||||
|
|
||||||
Example exp '+' exp • '/' exp
|
**** Unifying Counterexamples
|
||||||
First derivation exp ::=[ exp ::=[ exp '+' exp • ] '/' exp ]
|
|
||||||
Second derivation exp ::=[ exp '+' exp ::=[ exp • '/' exp ] ]
|
|
||||||
|
|
||||||
When Bison is installed with text styling enabled, the example is actually
|
Unifying counterexamples are strings which can be parsed in two ways due
|
||||||
shown twice, with colors highlighting the ambiguity.
|
to the conflict. For example on a grammar that contains the usual
|
||||||
|
"dangling else" ambiguity:
|
||||||
|
|
||||||
This is a shift/reduce conflict caused by none of the operators having
|
$ bison else.y
|
||||||
precedence, so the example can be parsed in the two ways shown. When
|
else.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
|
||||||
bison cannot find an example that can be derived in two ways, it instead
|
else.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
|
||||||
generates two examples that are the same up until the dot:
|
|
||||||
|
|
||||||
First example expr • ID $end
|
$ bison else.y -Wcex
|
||||||
First derivation $accept ::=[ s ::=[ a ::=[ expr • ] ID ] $end ]
|
else.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
|
||||||
Second example expr • ID ',' ID $end
|
else.y: warning: shift/reduce conflict on token "else" [-Wcounterexamples]
|
||||||
Second derivation $accept ::=[ s ::=[ a ::=[ expr ::=[ expr • ID ',' ] ] ID ] $end ]
|
Example: "if" exp "then" "if" exp "then" exp • "else" exp
|
||||||
|
Shift derivation
|
||||||
|
exp
|
||||||
|
↳ "if" exp "then" exp
|
||||||
|
↳ "if" exp "then" exp • "else" exp
|
||||||
|
Example: "if" exp "then" "if" exp "then" exp • "else" exp
|
||||||
|
Reduce derivation
|
||||||
|
exp
|
||||||
|
↳ "if" exp "then" exp "else" exp
|
||||||
|
↳ "if" exp "then" exp •
|
||||||
|
|
||||||
|
When text styling is enabled, colors are used in the examples and the
|
||||||
|
derivations to highlight the structure of both analyses. In this case,
|
||||||
|
|
||||||
|
"if" exp "then" [ "if" exp "then" exp • ] "else" exp
|
||||||
|
|
||||||
|
vs.
|
||||||
|
|
||||||
|
"if" exp "then" [ "if" exp "then" exp • "else" exp ]
|
||||||
|
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
**** Nonunifying Counterexamples
|
||||||
|
|
||||||
|
In the case of the dangling else, Bison found an example that can be
|
||||||
|
parsed in two ways (therefore proving that the grammar is ambiguous).
|
||||||
|
When it cannot find such an example, it instead generates two examples
|
||||||
|
that are the same up until the dot:
|
||||||
|
|
||||||
|
$ bison foo.y
|
||||||
|
foo.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
|
||||||
|
foo.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
|
||||||
|
foo.y:4.4-7: warning: rule useless in parser due to conflicts [-Wother]
|
||||||
|
4 | a: expr
|
||||||
|
| ^~~~
|
||||||
|
|
||||||
|
$ bison -Wcex foo.y
|
||||||
|
foo.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
|
||||||
|
foo.y: warning: shift/reduce conflict on token ID [-Wcounterexamples]
|
||||||
|
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 •
|
||||||
|
foo.y:4.4-7: warning: rule useless in parser due to conflicts [-Wother]
|
||||||
|
4 | a: expr
|
||||||
|
| ^~~~
|
||||||
|
|
||||||
In these cases, the parser usually doesn't have enough lookahead to
|
In these cases, the parser usually doesn't have enough lookahead to
|
||||||
differentiate the two given examples.
|
differentiate the two given examples.
|
||||||
|
|
||||||
The counterexamples are "focused": in two different ways. First, they do
|
**** Reports
|
||||||
not clutter the output with all the derivations from the start symbol,
|
|
||||||
rather they start on the "conflicted nonterminal". They go straight to the
|
Counterexamples are also included in the report when given
|
||||||
point. Second, they don't "expand" nonterminal symbols uselessly.
|
`--report=counterexamples`/`-rcex` (or `--report=all`), with more
|
||||||
|
technical details:
|
||||||
|
|
||||||
|
State 7
|
||||||
|
|
||||||
|
1 exp: "if" exp "then" exp • [$end, "then", "else"]
|
||||||
|
2 | "if" exp "then" exp • "else" exp
|
||||||
|
|
||||||
|
"else" shift, and go to state 8
|
||||||
|
|
||||||
|
"else" [reduce using rule 1 (exp)]
|
||||||
|
$default reduce using rule 1 (exp)
|
||||||
|
|
||||||
|
shift/reduce conflict on token "else":
|
||||||
|
1 exp: "if" exp "then" exp •
|
||||||
|
2 exp: "if" exp "then" exp • "else" exp
|
||||||
|
Example: "if" exp "then" "if" exp "then" exp • "else" exp
|
||||||
|
Shift derivation
|
||||||
|
exp
|
||||||
|
↳ "if" exp "then" exp
|
||||||
|
↳ "if" exp "then" exp • "else" exp
|
||||||
|
Example: "if" exp "then" "if" exp "then" exp • "else" exp
|
||||||
|
Reduce derivation
|
||||||
|
exp
|
||||||
|
↳ "if" exp "then" exp "else" exp
|
||||||
|
↳ "if" exp "then" exp •
|
||||||
|
|
||||||
*** File prefix mapping
|
*** File prefix mapping
|
||||||
|
|
||||||
@@ -67,6 +139,11 @@ GNU Bison NEWS
|
|||||||
|
|
||||||
** Changes
|
** Changes
|
||||||
|
|
||||||
|
*** Diagnostics
|
||||||
|
|
||||||
|
When text styling is enabled and the terminal supports it, the warnings
|
||||||
|
now include hyperlinks to the documentation.
|
||||||
|
|
||||||
*** Relocatable installation
|
*** Relocatable installation
|
||||||
|
|
||||||
When installed to be relocatable (via `configure --enable-relocatable`),
|
When installed to be relocatable (via `configure --enable-relocatable`),
|
||||||
@@ -107,6 +184,18 @@ GNU Bison NEWS
|
|||||||
Now the parser state can be examined when parsing is finished. The parser
|
Now the parser state can be examined when parsing is finished. The parser
|
||||||
state is reset when starting a new parse.
|
state is reset when starting a new parse.
|
||||||
|
|
||||||
|
** 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
|
||||||
|
| ^~~
|
||||||
|
|
||||||
** Bug fixes
|
** Bug fixes
|
||||||
|
|
||||||
*** Include the generated header (yacc.c)
|
*** Include the generated header (yacc.c)
|
||||||
@@ -4372,7 +4461,7 @@ LocalWords: yysymbol yytnamerr yyreport ctx ARGMAX yysyntax stderr LPAREN
|
|||||||
LocalWords: symrec yypcontext TOKENMAX yyexpected YYEMPTY yypstate YYEOF
|
LocalWords: symrec yypcontext TOKENMAX yyexpected YYEMPTY yypstate YYEOF
|
||||||
LocalWords: autocompletion bistromathic submessages Cayuela lexcalc hoc
|
LocalWords: autocompletion bistromathic submessages Cayuela lexcalc hoc
|
||||||
LocalWords: yytoken YYUNDEF YYerror basename Automake's UTF ifdef ffile
|
LocalWords: yytoken YYUNDEF YYerror basename Automake's UTF ifdef ffile
|
||||||
LocalWords: gotos readline Imbimbo Wcounterexamples
|
LocalWords: gotos readline Imbimbo Wcounterexamples Wcex Nonunifying rcex
|
||||||
|
|
||||||
Local Variables:
|
Local Variables:
|
||||||
ispell-dictionary: "american"
|
ispell-dictionary: "american"
|
||||||
|
|||||||
+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`.
|
done with a crude tool: `build-aux/update-test`.
|
||||||
|
|
||||||
Once you ran the test suite, and therefore have many `testsuite.log` files,
|
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
|
$ ./build-aux/update-test $build/tests/testsuite.dir/*/testsuite.log
|
||||||
|
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ Csaba Raduly [email protected]
|
|||||||
Dagobert Michelsen [email protected]
|
Dagobert Michelsen [email protected]
|
||||||
Daniel Frużyński [email protected]
|
Daniel Frużyński [email protected]
|
||||||
Daniel Galloway [email protected]
|
Daniel Galloway [email protected]
|
||||||
|
Daniela Becker [email protected]
|
||||||
Daniel Hagerty [email protected]
|
Daniel Hagerty [email protected]
|
||||||
David Barto [email protected]
|
David Barto [email protected]
|
||||||
David J. MacKenzie [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
|
- How about not evaluating incomplete lines when the text is not finished
|
||||||
(as shells do).
|
(as shells do).
|
||||||
|
|
||||||
- Caret diagnostics
|
|
||||||
|
|
||||||
** Questions
|
** Questions
|
||||||
*** Java
|
*** Java
|
||||||
- Should i18n be part of the Lexer? Currently it's a static method of
|
- Should i18n be part of the Lexer? Currently it's a static method of
|
||||||
|
|||||||
+1
-1
@@ -44,7 +44,7 @@ gnulib_modules='
|
|||||||
realloc-posix
|
realloc-posix
|
||||||
relocatable-prog relocatable-script
|
relocatable-prog relocatable-script
|
||||||
rename
|
rename
|
||||||
spawn-pipe stdbool stpcpy strdup-posix strerror strverscmp
|
spawn-pipe stdbool stpcpy stpncpy strdup-posix strerror strverscmp
|
||||||
timevar
|
timevar
|
||||||
unicodeio unistd unistd-safer unlink unlocked-io
|
unicodeio unistd unistd-safer unlink unlocked-io
|
||||||
update-copyright unsetenv verify
|
update-copyright unsetenv verify
|
||||||
|
|||||||
@@ -49,6 +49,10 @@
|
|||||||
.cex-5 { color: orange; }
|
.cex-5 { color: orange; }
|
||||||
.cex-6 { color: brown; }
|
.cex-6 { color: brown; }
|
||||||
.cex-7 { color: mauve; }
|
.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: derivation rewriting steps. */
|
||||||
.cex-step { font-style: italic; }
|
.cex-step { font-style: italic; }
|
||||||
|
|||||||
+14
-6
@@ -52,7 +52,7 @@
|
|||||||
<xsl:if test="nonterminal[@usefulness='useless-in-grammar']">
|
<xsl:if test="nonterminal[@usefulness='useless-in-grammar']">
|
||||||
<xsl:text>Nonterminals useless in grammar </xsl:text>
|
<xsl:text>Nonterminals useless in grammar </xsl:text>
|
||||||
<xsl:for-each select="nonterminal[@usefulness='useless-in-grammar']">
|
<xsl:for-each select="nonterminal[@usefulness='useless-in-grammar']">
|
||||||
<xsl:text> </xsl:text>
|
<xsl:text> </xsl:text>
|
||||||
<xsl:value-of select="@name"/>
|
<xsl:value-of select="@name"/>
|
||||||
<xsl:text> </xsl:text>
|
<xsl:text> </xsl:text>
|
||||||
</xsl:for-each>
|
</xsl:for-each>
|
||||||
@@ -65,7 +65,7 @@
|
|||||||
<xsl:text>Terminals unused in grammar </xsl:text>
|
<xsl:text>Terminals unused in grammar </xsl:text>
|
||||||
<xsl:for-each select="terminal[@usefulness='unused-in-grammar']">
|
<xsl:for-each select="terminal[@usefulness='unused-in-grammar']">
|
||||||
<xsl:sort select="@symbol-number" data-type="number"/>
|
<xsl:sort select="@symbol-number" data-type="number"/>
|
||||||
<xsl:text> </xsl:text>
|
<xsl:text> </xsl:text>
|
||||||
<xsl:value-of select="@name"/>
|
<xsl:value-of select="@name"/>
|
||||||
<xsl:text> </xsl:text>
|
<xsl:text> </xsl:text>
|
||||||
</xsl:for-each>
|
</xsl:for-each>
|
||||||
@@ -136,6 +136,7 @@
|
|||||||
</xsl:template>
|
</xsl:template>
|
||||||
|
|
||||||
<xsl:template match="terminal">
|
<xsl:template match="terminal">
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
<xsl:value-of select="@name"/>
|
<xsl:value-of select="@name"/>
|
||||||
<xsl:call-template name="line-wrap">
|
<xsl:call-template name="line-wrap">
|
||||||
<xsl:with-param name="first-line-length">
|
<xsl:with-param name="first-line-length">
|
||||||
@@ -148,6 +149,9 @@
|
|||||||
</xsl:with-param>
|
</xsl:with-param>
|
||||||
<xsl:with-param name="line-length" select="66" />
|
<xsl:with-param name="line-length" select="66" />
|
||||||
<xsl:with-param name="text">
|
<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:value-of select="concat(' (', @token-number, ')')"/>
|
||||||
<xsl:for-each select="key('bison:ruleByRhs', @name)">
|
<xsl:for-each select="key('bison:ruleByRhs', @name)">
|
||||||
<xsl:value-of select="concat(' ', @number)"/>
|
<xsl:value-of select="concat(' ', @number)"/>
|
||||||
@@ -157,14 +161,18 @@
|
|||||||
</xsl:template>
|
</xsl:template>
|
||||||
|
|
||||||
<xsl:template match="nonterminal">
|
<xsl:template match="nonterminal">
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
<xsl:value-of select="@name"/>
|
<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:value-of select="concat(' (', @symbol-number, ')')"/>
|
||||||
<xsl:text> </xsl:text>
|
<xsl:text> </xsl:text>
|
||||||
<xsl:variable name="output">
|
<xsl:variable name="output">
|
||||||
<xsl:call-template name="line-wrap">
|
<xsl:call-template name="line-wrap">
|
||||||
<xsl:with-param name="line-length" select="66" />
|
<xsl:with-param name="line-length" select="66" />
|
||||||
<xsl:with-param name="text">
|
<xsl:with-param name="text">
|
||||||
<xsl:text> </xsl:text>
|
<xsl:text> </xsl:text>
|
||||||
<xsl:if test="key('bison:ruleByLhs', @name)">
|
<xsl:if test="key('bison:ruleByLhs', @name)">
|
||||||
<xsl:text>on@left:</xsl:text>
|
<xsl:text>on@left:</xsl:text>
|
||||||
<xsl:for-each select="key('bison:ruleByLhs', @name)">
|
<xsl:for-each select="key('bison:ruleByLhs', @name)">
|
||||||
@@ -173,7 +181,7 @@
|
|||||||
</xsl:if>
|
</xsl:if>
|
||||||
<xsl:if test="key('bison:ruleByRhs', @name)">
|
<xsl:if test="key('bison:ruleByRhs', @name)">
|
||||||
<xsl:if test="key('bison:ruleByLhs', @name)">
|
<xsl:if test="key('bison:ruleByLhs', @name)">
|
||||||
<xsl:text>, </xsl:text>
|
<xsl:text> </xsl:text>
|
||||||
</xsl:if>
|
</xsl:if>
|
||||||
<xsl:text>on@right:</xsl:text>
|
<xsl:text>on@right:</xsl:text>
|
||||||
<xsl:for-each select="key('bison:ruleByRhs', @name)">
|
<xsl:for-each select="key('bison:ruleByRhs', @name)">
|
||||||
@@ -348,11 +356,11 @@
|
|||||||
<!-- RHS -->
|
<!-- RHS -->
|
||||||
<xsl:for-each select="rhs/*">
|
<xsl:for-each select="rhs/*">
|
||||||
<xsl:if test="position() = $dot + 1">
|
<xsl:if test="position() = $dot + 1">
|
||||||
<xsl:text> .</xsl:text>
|
<xsl:text> •</xsl:text>
|
||||||
</xsl:if>
|
</xsl:if>
|
||||||
<xsl:apply-templates select="."/>
|
<xsl:apply-templates select="."/>
|
||||||
<xsl:if test="position() = last() and position() = $dot">
|
<xsl:if test="position() = last() and position() = $dot">
|
||||||
<xsl:text> .</xsl:text>
|
<xsl:text> •</xsl:text>
|
||||||
</xsl:if>
|
</xsl:if>
|
||||||
</xsl:for-each>
|
</xsl:for-each>
|
||||||
<xsl:if test="$lookaheads">
|
<xsl:if test="$lookaheads">
|
||||||
|
|||||||
+72
-48
@@ -227,6 +227,7 @@
|
|||||||
<xsl:text> </xsl:text>
|
<xsl:text> </xsl:text>
|
||||||
<p class="pre">
|
<p class="pre">
|
||||||
<xsl:call-template name="style-rule-set">
|
<xsl:call-template name="style-rule-set">
|
||||||
|
<xsl:with-param name="anchor" select="'true'" />
|
||||||
<xsl:with-param
|
<xsl:with-param
|
||||||
name="rule-set" select="rules/rule[@usefulness!='useless-in-grammar']"
|
name="rule-set" select="rules/rule[@usefulness!='useless-in-grammar']"
|
||||||
/>
|
/>
|
||||||
@@ -238,9 +239,11 @@
|
|||||||
</xsl:template>
|
</xsl:template>
|
||||||
|
|
||||||
<xsl:template name="style-rule-set">
|
<xsl:template name="style-rule-set">
|
||||||
|
<xsl:param name="anchor"/>
|
||||||
<xsl:param name="rule-set"/>
|
<xsl:param name="rule-set"/>
|
||||||
<xsl:for-each select="$rule-set">
|
<xsl:for-each select="$rule-set">
|
||||||
<xsl:apply-templates select=".">
|
<xsl:apply-templates select=".">
|
||||||
|
<xsl:with-param name="anchor" select="$anchor"/>
|
||||||
<xsl:with-param name="pad" select="'3'"/>
|
<xsl:with-param name="pad" select="'3'"/>
|
||||||
<xsl:with-param name="prev-lhs">
|
<xsl:with-param name="prev-lhs">
|
||||||
<xsl:if test="position()>1">
|
<xsl:if test="position()>1">
|
||||||
@@ -306,9 +309,10 @@
|
|||||||
<xsl:text> Terminals, with rules where they appear</xsl:text>
|
<xsl:text> Terminals, with rules where they appear</xsl:text>
|
||||||
</h3>
|
</h3>
|
||||||
<xsl:text> </xsl:text>
|
<xsl:text> </xsl:text>
|
||||||
<p class="pre">
|
<ul>
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
<xsl:apply-templates select="terminal"/>
|
<xsl:apply-templates select="terminal"/>
|
||||||
</p>
|
</ul>
|
||||||
<xsl:text> </xsl:text>
|
<xsl:text> </xsl:text>
|
||||||
</xsl:template>
|
</xsl:template>
|
||||||
|
|
||||||
@@ -318,41 +322,64 @@
|
|||||||
<xsl:text> Nonterminals, with rules where they appear</xsl:text>
|
<xsl:text> Nonterminals, with rules where they appear</xsl:text>
|
||||||
</h3>
|
</h3>
|
||||||
<xsl:text> </xsl:text>
|
<xsl:text> </xsl:text>
|
||||||
<p class="pre">
|
<ul>
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
<xsl:apply-templates
|
<xsl:apply-templates
|
||||||
select="nonterminal[@usefulness!='useless-in-grammar']"
|
select="nonterminal[@usefulness!='useless-in-grammar']"
|
||||||
/>
|
/>
|
||||||
</p>
|
</ul>
|
||||||
</xsl:template>
|
</xsl:template>
|
||||||
|
|
||||||
<xsl:template match="terminal">
|
<xsl:template match="terminal">
|
||||||
<b><xsl:value-of select="@name"/></b>
|
<xsl:text> </xsl:text>
|
||||||
<xsl:value-of select="concat(' (', @token-number, ')')"/>
|
<li>
|
||||||
<xsl:for-each select="key('bison:ruleByRhs', @name)">
|
<b><xsl:value-of select="@name"/></b>
|
||||||
<xsl:apply-templates select="." mode="number-link"/>
|
<xsl:if test="string-length(@type) != 0">
|
||||||
</xsl:for-each>
|
<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:text> </xsl:text>
|
||||||
</xsl:template>
|
</xsl:template>
|
||||||
|
|
||||||
<xsl:template match="nonterminal">
|
<xsl:template match="nonterminal">
|
||||||
<b><xsl:value-of select="@name"/></b>
|
<xsl:text> </xsl:text>
|
||||||
<xsl:value-of select="concat(' (', @symbol-number, ')')"/>
|
<li>
|
||||||
<xsl:text> </xsl:text>
|
<b><xsl:value-of select="@name"/></b>
|
||||||
<xsl:if test="key('bison:ruleByLhs', @name)">
|
<xsl:if test="string-length(@type) != 0">
|
||||||
<xsl:text>on left:</xsl:text>
|
<xsl:value-of select="concat(' <', @type, '>')"/>
|
||||||
<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:if>
|
</xsl:if>
|
||||||
<xsl:text>on right:</xsl:text>
|
<xsl:value-of select="concat(' (', @symbol-number, ')')"/>
|
||||||
<xsl:for-each select="key('bison:ruleByRhs', @name)">
|
<xsl:text> </xsl:text>
|
||||||
<xsl:apply-templates select="." mode="number-link"/>
|
<ul>
|
||||||
</xsl:for-each>
|
<xsl:text> </xsl:text>
|
||||||
</xsl:if>
|
<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:text> </xsl:text>
|
||||||
</xsl:template>
|
</xsl:template>
|
||||||
|
|
||||||
@@ -385,7 +412,7 @@
|
|||||||
<xsl:value-of select="concat('state_', @number)"/>
|
<xsl:value-of select="concat('state_', @number)"/>
|
||||||
</xsl:attribute>
|
</xsl:attribute>
|
||||||
</a>
|
</a>
|
||||||
<xsl:text>state </xsl:text>
|
<xsl:text>State </xsl:text>
|
||||||
<xsl:value-of select="@number"/>
|
<xsl:value-of select="@number"/>
|
||||||
</h3>
|
</h3>
|
||||||
<xsl:text> </xsl:text>
|
<xsl:text> </xsl:text>
|
||||||
@@ -464,7 +491,12 @@
|
|||||||
</xsl:apply-templates>
|
</xsl:apply-templates>
|
||||||
</xsl:template>
|
</xsl:template>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
anchor = 'true': define as an <a> anchor.
|
||||||
|
itemset = 'true': show the items.
|
||||||
|
-->
|
||||||
<xsl:template match="rule">
|
<xsl:template match="rule">
|
||||||
|
<xsl:param name="anchor"/>
|
||||||
<xsl:param name="itemset"/>
|
<xsl:param name="itemset"/>
|
||||||
<xsl:param name="pad"/>
|
<xsl:param name="pad"/>
|
||||||
<xsl:param name="prev-lhs"/>
|
<xsl:param name="prev-lhs"/>
|
||||||
@@ -475,17 +507,21 @@
|
|||||||
<xsl:text> </xsl:text>
|
<xsl:text> </xsl:text>
|
||||||
</xsl:if>
|
</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:text> </xsl:text>
|
||||||
|
|
||||||
<xsl:choose>
|
<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>
|
<a>
|
||||||
<xsl:attribute name="href">
|
<xsl:attribute name="href">
|
||||||
<xsl:value-of select="concat('#rule_', @number)"/>
|
<xsl:value-of select="concat('#rule_', @number)"/>
|
||||||
@@ -495,25 +531,13 @@
|
|||||||
<xsl:with-param name="pad" select="number($pad)"/>
|
<xsl:with-param name="pad" select="number($pad)"/>
|
||||||
</xsl:call-template>
|
</xsl:call-template>
|
||||||
</a>
|
</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:otherwise>
|
||||||
</xsl:choose>
|
</xsl:choose>
|
||||||
<xsl:text> </xsl:text>
|
<xsl:text> </xsl:text>
|
||||||
|
|
||||||
<!-- LHS -->
|
<!-- LHS -->
|
||||||
<xsl:choose>
|
<xsl:choose>
|
||||||
<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"/>
|
|
||||||
</xsl:call-template>
|
|
||||||
</xsl:when>
|
|
||||||
<xsl:when test="$itemset = 'true' and $prev-lhs = lhs[text()]">
|
|
||||||
<xsl:call-template name="lpad">
|
<xsl:call-template name="lpad">
|
||||||
<xsl:with-param name="str" select="'|'"/>
|
<xsl:with-param name="str" select="'|'"/>
|
||||||
<xsl:with-param name="pad" select="number(string-length(lhs[text()])) + 2"/>
|
<xsl:with-param name="pad" select="number(string-length(lhs[text()])) + 2"/>
|
||||||
|
|||||||
+253
-113
@@ -263,7 +263,6 @@ Writing GLR Parsers
|
|||||||
* Merging GLR Parses:: Using GLR parsers to resolve ambiguities.
|
* Merging GLR Parses:: Using GLR parsers to resolve ambiguities.
|
||||||
* GLR Semantic Actions:: Considerations for semantic values and deferred actions.
|
* GLR Semantic Actions:: Considerations for semantic values and deferred actions.
|
||||||
* Semantic Predicates:: Controlling a parse with arbitrary computations.
|
* Semantic Predicates:: Controlling a parse with arbitrary computations.
|
||||||
* Compiler Requirements for GLR:: GLR parsers require a modern C compiler.
|
|
||||||
|
|
||||||
Examples
|
Examples
|
||||||
|
|
||||||
@@ -943,7 +942,6 @@ on the resulting values to produce an arbitrary merged result.
|
|||||||
* Merging GLR Parses:: Using GLR parsers to resolve ambiguities.
|
* Merging GLR Parses:: Using GLR parsers to resolve ambiguities.
|
||||||
* GLR Semantic Actions:: Considerations for semantic values and deferred actions.
|
* GLR Semantic Actions:: Considerations for semantic values and deferred actions.
|
||||||
* Semantic Predicates:: Controlling a parse with arbitrary computations.
|
* Semantic Predicates:: Controlling a parse with arbitrary computations.
|
||||||
* Compiler Requirements for GLR:: GLR parsers require a modern C compiler.
|
|
||||||
@end menu
|
@end menu
|
||||||
|
|
||||||
@node Simple GLR Parsers
|
@node Simple GLR Parsers
|
||||||
@@ -1372,14 +1370,14 @@ widget:
|
|||||||
@noindent
|
@noindent
|
||||||
is one way to allow the same parser to handle two different syntaxes for
|
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
|
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
|
evaluated immediately (even when in nondeterministic mode). If the
|
||||||
expression yields 0 (false), the clause is treated as a syntax error,
|
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
|
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
|
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.
|
to use for denoting the semantic values of right-hand side symbols.
|
||||||
Predicate actions, however, have no defined value, and may not be given
|
Predicate actions, however, have no defined value, and may not be given
|
||||||
labels.
|
labels.
|
||||||
@@ -1393,7 +1391,7 @@ widget:
|
|||||||
@{ if (!new_syntax) YYERROR; @}
|
@{ if (!new_syntax) YYERROR; @}
|
||||||
"widget" id new_args @{ $$ = f($3, $4); @}
|
"widget" id new_args @{ $$ = f($3, $4); @}
|
||||||
| @{ if (new_syntax) YYERROR; @}
|
| @{ if (new_syntax) YYERROR; @}
|
||||||
"widget" id old_args @{ $$ = f($3, $4); @}
|
"widget" id old_args @{ $$ = f($3, $4); @}
|
||||||
;
|
;
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
@@ -1411,36 +1409,6 @@ reports an error.
|
|||||||
Finally, be careful in writing predicates: deferred actions have not been
|
Finally, be careful in writing predicates: deferred actions have not been
|
||||||
evaluated, so that using them in a predicate will have undefined effects.
|
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
|
@node Locations
|
||||||
@section Locations
|
@section Locations
|
||||||
@cindex location
|
@cindex location
|
||||||
@@ -9921,10 +9889,11 @@ initially developed by Chinawat Isradisaikul and Andrew Myers
|
|||||||
As a first example, see the example grammar of @ref{Shift/Reduce}, which
|
As a first example, see the example grammar of @ref{Shift/Reduce}, which
|
||||||
features on shift/reduce conflict:
|
features on shift/reduce conflict:
|
||||||
|
|
||||||
|
@c see doc/if-then-else.y
|
||||||
@example
|
@example
|
||||||
$ @kbd{bison if-then-else.y}
|
$ @kbd{bison if-then-else.y}
|
||||||
if-then-else.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
|
if-then-else.y: @dwarning{warning}: 1 shift/reduce conflict [@dwarning{-Wconflicts-sr}]
|
||||||
if-then-else.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
|
if-then-else.y: @dnotice{note}: rerun with option '-Wcounterexamples' to generate conflict counterexamples
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
@noindent
|
@noindent
|
||||||
@@ -9932,32 +9901,46 @@ Let's rerun @command{bison} with the option
|
|||||||
@option{-Wcex}/@option{-Wcounterexamples}@inlinefmt{info, (the following
|
@option{-Wcex}/@option{-Wcounterexamples}@inlinefmt{info, (the following
|
||||||
output is actually in color)}:
|
output is actually in color)}:
|
||||||
|
|
||||||
@ifhtml
|
@ifnottex
|
||||||
@example
|
@example
|
||||||
Shift/reduce conflict on token "else":
|
if-then-else.y: @dwarning{warning}: 1 shift/reduce conflict [@dwarning{-Wconflicts-sr}]
|
||||||
|
if-then-else.y: @dwarning{warning}: shift/reduce conflict on token "else" [@dwarning{-Wcounterexamples}]
|
||||||
@group
|
@group
|
||||||
Example @yellow{"if" expr "then"} @blue{"if" expr "then" stmt} @red{•} @yellow{"else" stmt}
|
Example: @yellow{"if" expr "then"} "if" expr "then" stmt • "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 ]}
|
Shift derivation
|
||||||
Example @yellow{"if" expr "then"} @blue{"if" expr "then" stmt} @red{•} @blue{"else" stmt}
|
@yellow{if_stmt}
|
||||||
Second derivation @yellow{if_stmt ::=[ "if" expr "then"} @green{stmt ::=[} @blue{if_stmt ::=[ "if" expr "then" stmt} @red{•} @blue{"else" stmt ]} @green{]} @yellow{]}
|
@yellow{↳ "if" expr "then"} @green{stmt}
|
||||||
|
@green{↳} @blue{if_stmt}
|
||||||
|
@blue{↳ "if" expr "then" stmt} @red{•} @blue{"else" stmt}
|
||||||
|
Example: @yellow{"if" expr "then"} @blue{"if" expr "then" stmt} @red{•} @yellow{"else" stmt}
|
||||||
|
Reduce derivation
|
||||||
|
@yellow{if_stmt}
|
||||||
|
@yellow{↳ "if" expr "then"} @green{stmt} @yellow{"else" stmt}
|
||||||
|
@green{↳} @blue{if_stmt}
|
||||||
|
@blue{↳ "if" expr "then" stmt} @red{•}
|
||||||
@end group
|
@end group
|
||||||
@end example
|
@end example
|
||||||
@end ifhtml
|
@end ifnottex
|
||||||
@ifnothtml
|
@iftex
|
||||||
@smallexample
|
@example
|
||||||
Shift/reduce conflict on token "else":
|
if-then-else.y: @dwarning{warning}: 1 shift/reduce conflict [@dwarning{-Wconflicts-sr}]
|
||||||
|
if-then-else.y: @dwarning{warning}: shift/reduce conflict on token "else" [@dwarning{-Wcounterexamples}]
|
||||||
@group
|
@group
|
||||||
Example
|
Example: @yellow{"if" expr "then"} "if" expr "then" stmt • "else" stmt
|
||||||
@yellow{"if" expr "then"} @blue{"if" expr "then" stmt} @red{•} @yellow{"else" stmt}
|
Shift derivation
|
||||||
First derivation
|
@yellow{if_stmt}
|
||||||
@yellow{if_stmt ::=[ "if" expr "then"} @green{stmt ::=[} @blue{if_stmt ::=[ "if" expr "then" stmt} @red{•} @blue{]} @green{]} @yellow{"else" stmt ]}
|
@yellow{@arrow{} "if" expr "then"} @green{stmt}
|
||||||
Example
|
@green{@arrow{}} @blue{if_stmt}
|
||||||
@yellow{"if" expr "then"} @blue{"if" expr "then" stmt} @red{•} @blue{"else" stmt}
|
@blue{@arrow{} "if" expr "then" stmt} @red{•} @blue{"else" stmt}
|
||||||
Second derivation
|
Example: @yellow{"if" expr "then"} @blue{"if" expr "then" stmt} @red{•} @yellow{"else" stmt}
|
||||||
@yellow{if_stmt ::=[ "if" expr "then"} @green{stmt ::=[} @blue{if_stmt ::=[ "if" expr "then" stmt} @red{•} @blue{"else" stmt ]} @green{]} @yellow{]}
|
Reduce derivation
|
||||||
|
@yellow{if_stmt}
|
||||||
|
@yellow{@arrow{} "if" expr "then"} @green{stmt} @yellow{"else" stmt}
|
||||||
|
@green{@arrow{}} @blue{if_stmt}
|
||||||
|
@blue{@arrow{} "if" expr "then" stmt} @red{•}
|
||||||
@end group
|
@end group
|
||||||
@end smallexample
|
@end example
|
||||||
@end ifnothtml
|
@end iftex
|
||||||
|
|
||||||
This shows two different derivations for one single expression. That
|
This shows two different derivations for one single expression. That
|
||||||
demonstrates that the grammar is ambiguous.
|
demonstrates that the grammar is ambiguous.
|
||||||
@@ -9967,6 +9950,7 @@ demonstrates that the grammar is ambiguous.
|
|||||||
As a more delicate example, consider the example grammar of
|
As a more delicate example, consider the example grammar of
|
||||||
@ref{Reduce/Reduce}, which features a reduce/reduce conflict:
|
@ref{Reduce/Reduce}, which features a reduce/reduce conflict:
|
||||||
|
|
||||||
|
@c doc/sequence.y
|
||||||
@example
|
@example
|
||||||
%%
|
%%
|
||||||
sequence:
|
sequence:
|
||||||
@@ -9982,32 +9966,112 @@ maybeword:
|
|||||||
|
|
||||||
Bison generates the following counterexamples:
|
Bison generates the following counterexamples:
|
||||||
|
|
||||||
|
@ifnottex
|
||||||
@example
|
@example
|
||||||
|
@group
|
||||||
$ @kbd{bison -Wcex sequence.y}
|
$ @kbd{bison -Wcex sequence.y}
|
||||||
sequence.y: @dwarning{warning}: 1 shift/reduce conflict [@dwarning{-Wconflicts-sr}]
|
sequence.y: @dwarning{warning}: 1 shift/reduce conflict [@dwarning{-Wconflicts-sr}]
|
||||||
sequence.y: @dwarning{warning}: 2 reduce/reduce conflicts [@dwarning{-Wconflicts-rr}]
|
sequence.y: @dwarning{warning}: 2 reduce/reduce conflicts [@dwarning{-Wconflicts-rr}]
|
||||||
Shift/reduce conflict on token "word":
|
@end group
|
||||||
Example @red{•} @yellow{"word"}
|
@group
|
||||||
First derivation @yellow{sequence ::=[} @green{sequence ::=[} @red{•} @green{]} @yellow{"word" ]}
|
sequence.y: @dwarning{warning}: shift/reduce conflict on token "word" [@dwarning{-Wcounterexamples}]
|
||||||
Example @red{•} @green{"word"}
|
Example: @red{•} @green{"word"}
|
||||||
Second derivation @yellow{sequence ::=[} @green{maybeword ::=[} @red{•} @green{"word" ]} @yellow{]}
|
Shift derivation
|
||||||
|
@yellow{sequence}
|
||||||
Reduce/reduce conflict on tokens $end, "word":
|
@yellow{↳} @green{maybeword}
|
||||||
Example @red{•}
|
@green{↳} @red{•} @green{"word"}
|
||||||
First derivation @yellow{sequence ::=[} @red{•} @yellow{]}
|
Example: @red{•} @yellow{"word"}
|
||||||
Example @red{•}
|
Reduce derivation
|
||||||
Second derivation @yellow{sequence ::=[} @green{maybeword ::=[} @red{•} @green{]} @yellow{]}
|
@yellow{sequence}
|
||||||
|
@yellow{↳} @green{sequence} @yellow{"word"}
|
||||||
Shift/reduce conflict on token "word":
|
@green{↳} @red{•}
|
||||||
Example @red{•} @yellow{"word"}
|
@end group
|
||||||
First derivation @yellow{sequence ::=[} @green{sequence ::=[} @blue{maybeword ::=[} @red{•} @blue{]} @green{]} @yellow{"word" ]}
|
@group
|
||||||
Example @red{•} @green{"word"}
|
sequence.y: @dwarning{warning}: reduce/reduce conflict on tokens $end, "word" [@dwarning{-Wcounterexamples}]
|
||||||
Second derivation @yellow{sequence ::=[} @green{maybeword ::=[} @red{•} @green{"word" ]} @yellow{]}
|
Example: @red{•}
|
||||||
|
First reduce derivation
|
||||||
|
@yellow{sequence}
|
||||||
|
@yellow{↳} @red{•}
|
||||||
|
Example: @red{•}
|
||||||
|
Second reduce derivation
|
||||||
|
@yellow{sequence}
|
||||||
|
@yellow{↳} @green{maybeword}
|
||||||
|
@green{↳} @red{•}
|
||||||
|
@end group
|
||||||
|
@group
|
||||||
|
sequence.y: @dwarning{warning}: shift/reduce conflict on token "word" [@dwarning{-Wcounterexamples}]
|
||||||
|
Example: @red{•} @green{"word"}
|
||||||
|
Shift derivation
|
||||||
|
@yellow{sequence}
|
||||||
|
@yellow{↳} @green{maybeword}
|
||||||
|
@green{↳} @red{•} @green{"word"}
|
||||||
|
Example: @red{•} @yellow{"word"}
|
||||||
|
Reduce derivation
|
||||||
|
@yellow{sequence}
|
||||||
|
@yellow{↳} @green{sequence} @yellow{"word"}
|
||||||
|
@green{↳} @blue{maybeword}
|
||||||
|
@blue{↳} @red{•}
|
||||||
|
@end group
|
||||||
|
@group
|
||||||
sequence.y:8.3-45: @dwarning{warning}: rule useless in parser due to conflicts [@dwarning{-Wother}]
|
sequence.y:8.3-45: @dwarning{warning}: rule useless in parser due to conflicts [@dwarning{-Wother}]
|
||||||
8 | @dwarning{%empty @{ printf ("empty maybeword\n"); @}}
|
8 | @dwarning{%empty @{ printf ("empty maybeword\n"); @}}
|
||||||
| @dwarning{^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}
|
| @dwarning{^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}
|
||||||
|
@end group
|
||||||
@end example
|
@end example
|
||||||
|
@end ifnottex
|
||||||
|
@iftex
|
||||||
|
@example
|
||||||
|
@group
|
||||||
|
$ @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}]
|
||||||
|
@end group
|
||||||
|
@group
|
||||||
|
sequence.y: @dwarning{warning}: shift/reduce conflict on token "word" [@dwarning{-Wcounterexamples}]
|
||||||
|
Example: @red{•} @green{"word"}
|
||||||
|
Shift derivation
|
||||||
|
@yellow{sequence}
|
||||||
|
@yellow{@arrow{}} @green{maybeword}
|
||||||
|
@green{@arrow{}} @red{•} @green{"word"}
|
||||||
|
Example: @red{•} @yellow{"word"}
|
||||||
|
Reduce derivation
|
||||||
|
@yellow{sequence}
|
||||||
|
@yellow{@arrow{}} @green{sequence} @yellow{"word"}
|
||||||
|
@green{@arrow{}} @red{•}
|
||||||
|
@end group
|
||||||
|
@group
|
||||||
|
sequence.y: @dwarning{warning}: reduce/reduce conflict on tokens $end, "word" [@dwarning{-Wcounterexamples}]
|
||||||
|
Example: @red{•}
|
||||||
|
First reduce derivation
|
||||||
|
@yellow{sequence}
|
||||||
|
@yellow{@arrow{}} @red{•}
|
||||||
|
Example: @red{•}
|
||||||
|
Second reduce derivation
|
||||||
|
@yellow{sequence}
|
||||||
|
@yellow{@arrow{}} @green{maybeword}
|
||||||
|
@green{@arrow{}} @red{•}
|
||||||
|
@end group
|
||||||
|
@group
|
||||||
|
sequence.y: @dwarning{warning}: shift/reduce conflict on token "word" [@dwarning{-Wcounterexamples}]
|
||||||
|
Example: @red{•} @green{"word"}
|
||||||
|
Shift derivation
|
||||||
|
@yellow{sequence}
|
||||||
|
@yellow{@arrow{}} @green{maybeword}
|
||||||
|
@green{@arrow{}} @red{•} @green{"word"}
|
||||||
|
Example: @red{•} @yellow{"word"}
|
||||||
|
Reduce derivation
|
||||||
|
@yellow{sequence}
|
||||||
|
@yellow{@arrow{}} @green{sequence} @yellow{"word"}
|
||||||
|
@green{@arrow{}} @blue{maybeword}
|
||||||
|
@blue{@arrow{}} @red{•}
|
||||||
|
@end group
|
||||||
|
@group
|
||||||
|
sequence.y:8.3-45: @dwarning{warning}: rule useless in parser due to conflicts [@dwarning{-Wother}]
|
||||||
|
8 | @dwarning{%empty @{ printf ("empty maybeword\n"); @}}
|
||||||
|
| @dwarning{^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}
|
||||||
|
@end group
|
||||||
|
@end example
|
||||||
|
@end iftex
|
||||||
|
|
||||||
Each of these three conflicts, again, prove that the grammar is ambiguous.
|
Each of these three conflicts, again, prove that the grammar is ambiguous.
|
||||||
For instance, the second conflict (the reduce/reduce one) shows that the
|
For instance, the second conflict (the reduce/reduce one) shows that the
|
||||||
@@ -10021,6 +10085,7 @@ that are the same up until the dot. Most notably, this will happen when
|
|||||||
your grammar requires a stronger parser (more lookahead, LR instead of
|
your grammar requires a stronger parser (more lookahead, LR instead of
|
||||||
LALR). The following example isn't LR(1):
|
LALR). The following example isn't LR(1):
|
||||||
|
|
||||||
|
@c doc/ids.y
|
||||||
@example
|
@example
|
||||||
%token ID
|
%token ID
|
||||||
%%
|
%%
|
||||||
@@ -10031,13 +10096,58 @@ expr: %empty | expr ID ','
|
|||||||
|
|
||||||
@command{bison} reports:
|
@command{bison} reports:
|
||||||
|
|
||||||
@smallexample
|
@ifnottex
|
||||||
Shift/reduce conflict on token ID:
|
@example
|
||||||
First example @blue{expr} @red{•} @green{ID} @yellow{$end}
|
ids.y: @dwarning{warning}: 1 shift/reduce conflict [@dwarning{-Wconflicts-sr}]
|
||||||
First derivation @yellow{$accept ::=[} @green{s ::=[} @blue{a ::=[ expr} @red{•} @blue{]} @green{ID ]} @yellow{$end ]}
|
ids.y: @dwarning{warning}: shift/reduce conflict on token ID [@dwarning{-Wcounterexamples}]
|
||||||
Second example @purple{expr} @red{•} @purple{ID ','} @green{ID} @yellow{$end}
|
@group
|
||||||
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}
|
||||||
@end smallexample
|
Shift derivation
|
||||||
|
@yellow{$accept}
|
||||||
|
@yellow{↳} @green{s} @yellow{$end}
|
||||||
|
@green{↳} @blue{a} @green{ID}
|
||||||
|
@blue{↳} @purple{expr}
|
||||||
|
@purple{↳ expr} @red{•} @purple{ID ','}
|
||||||
|
Second example: @blue{expr} @red{•} @green{ID} @yellow{$end}
|
||||||
|
Reduce derivation
|
||||||
|
@yellow{$accept}
|
||||||
|
@yellow{↳} @green{s} @yellow{$end}
|
||||||
|
@green{↳} @blue{a} @green{ID}
|
||||||
|
@blue{↳ expr} @red{•}
|
||||||
|
@end group
|
||||||
|
@group
|
||||||
|
ids.y:4.4-7: @dwarning{warning}: rule useless in parser due to conflicts [@dwarning{-Wother}]
|
||||||
|
4 | a: expr
|
||||||
|
| ^~~~
|
||||||
|
@end group
|
||||||
|
@end example
|
||||||
|
@end ifnottex
|
||||||
|
@iftex
|
||||||
|
@example
|
||||||
|
ids.y: @dwarning{warning}: 1 shift/reduce conflict [@dwarning{-Wconflicts-sr}]
|
||||||
|
ids.y: @dwarning{warning}: shift/reduce conflict on token ID [@dwarning{-Wcounterexamples}]
|
||||||
|
@group
|
||||||
|
First example: @purple{expr} @red{•} @purple{ID ','} @green{ID} @yellow{$end}
|
||||||
|
Shift derivation
|
||||||
|
@yellow{$accept}
|
||||||
|
@yellow{@arrow{}} @green{s} @yellow{$end}
|
||||||
|
@green{@arrow{}} @blue{a} @green{ID}
|
||||||
|
@blue{@arrow{}} @purple{expr}
|
||||||
|
@purple{@arrow{} expr} @red{•} @purple{ID ','}
|
||||||
|
Second example: @blue{expr} @red{•} @green{ID} @yellow{$end}
|
||||||
|
Reduce derivation
|
||||||
|
@yellow{$accept}
|
||||||
|
@yellow{@arrow{}} @green{s} @yellow{$end}
|
||||||
|
@green{@arrow{}} @blue{a} @green{ID}
|
||||||
|
@blue{@arrow{} expr} @red{•}
|
||||||
|
@end group
|
||||||
|
@group
|
||||||
|
ids.y:4.4-7: @dwarning{warning}: rule useless in parser due to conflicts [@dwarning{-Wother}]
|
||||||
|
4 | a: expr
|
||||||
|
| ^~~~
|
||||||
|
@end group
|
||||||
|
@end example
|
||||||
|
@end iftex
|
||||||
|
|
||||||
This conflict is caused by the parser not having enough information to know
|
This conflict is caused by the parser not having enough information to know
|
||||||
the difference between these two examples. The parser would need an
|
the difference between these two examples. The parser would need an
|
||||||
@@ -10073,6 +10183,7 @@ by default. As a consequence, the verbose output file is called
|
|||||||
|
|
||||||
The following grammar file, @file{calc.y}, will be used in the sequel:
|
The following grammar file, @file{calc.y}, will be used in the sequel:
|
||||||
|
|
||||||
|
@c doc/calc.y
|
||||||
@example
|
@example
|
||||||
@group
|
@group
|
||||||
%union
|
%union
|
||||||
@@ -10116,7 +10227,7 @@ calc.y:19.1-7: @dwarning{warning}: nonterminal useless in grammar: useless [@dwa
|
|||||||
19 | @dwarning{useless: STR;}
|
19 | @dwarning{useless: STR;}
|
||||||
| @dwarning{^~~~~~~}
|
| @dwarning{^~~~~~~}
|
||||||
calc.y: @dwarning{warning}: 7 shift/reduce conflicts [@dwarning{-Wconflicts-sr}]
|
calc.y: @dwarning{warning}: 7 shift/reduce conflicts [@dwarning{-Wconflicts-sr}]
|
||||||
calc.y: @dwarning{warning}: rerun with option '-Wcounterexamples' to generate conflict counterexamples [@dwarning{-Wother}]
|
calc.y: @dnotice{note}: rerun with option '-Wcounterexamples' to generate conflict counterexamples
|
||||||
@end smallexample
|
@end smallexample
|
||||||
|
|
||||||
Going back to the calc example, when given @option{--report=state},
|
Going back to the calc example, when given @option{--report=state},
|
||||||
@@ -10428,15 +10539,44 @@ When given @option{--report=counterexamples}, @command{bison} will generate
|
|||||||
counterexamples within the report, augmented with the corresponding items
|
counterexamples within the report, augmented with the corresponding items
|
||||||
(@pxref{Counterexamples}).
|
(@pxref{Counterexamples}).
|
||||||
|
|
||||||
|
@ifnottex
|
||||||
@example
|
@example
|
||||||
Shift/reduce conflict on token '/':
|
shift/reduce conflict on token '/':
|
||||||
1 exp: exp '+' exp •
|
1 exp: exp '+' exp •
|
||||||
4 exp: exp • '/' exp
|
4 exp: exp • '/' exp
|
||||||
Example @green{exp '+' exp} @red{•} @yellow{'/' exp}
|
@group
|
||||||
First derivation @yellow{exp ::=[} @green{exp ::=[ exp '+' exp} @red{•} @green{]} @yellow{'/' exp ]}
|
Example: exp '+' exp • '/' exp
|
||||||
Example @yellow{exp '+'} @green{exp} @red{•} @green{'/' exp}
|
Shift derivation
|
||||||
Second derivation @yellow{exp ::=[ exp '+'} @green{exp ::=[ exp} @red{•} @green{'/' exp ]} @yellow{]}
|
exp
|
||||||
|
↳ exp '+' exp
|
||||||
|
↳ exp • '/' exp
|
||||||
|
Example: exp '+' exp • '/' exp
|
||||||
|
Reduce derivation
|
||||||
|
exp
|
||||||
|
↳ exp '/' exp
|
||||||
|
↳ exp '+' exp •
|
||||||
|
@end group
|
||||||
@end example
|
@end example
|
||||||
|
@end ifnottex
|
||||||
|
@iftex
|
||||||
|
@example
|
||||||
|
shift/reduce conflict on token '/':
|
||||||
|
1 exp: exp '+' exp •
|
||||||
|
4 exp: exp • '/' exp
|
||||||
|
@group
|
||||||
|
Example: exp '+' exp • '/' exp
|
||||||
|
Shift derivation
|
||||||
|
exp
|
||||||
|
@arrow{} exp '+' exp
|
||||||
|
@arrow{} exp • '/' exp
|
||||||
|
Example: exp '+' exp • '/' exp
|
||||||
|
Reduce derivation
|
||||||
|
exp
|
||||||
|
@arrow{} exp '/' exp
|
||||||
|
@arrow{} exp '+' exp •
|
||||||
|
@end group
|
||||||
|
@end example
|
||||||
|
@end iftex
|
||||||
|
|
||||||
This shows two separate derivations in the grammar for the same @code{exp}:
|
This shows two separate derivations in the grammar for the same @code{exp}:
|
||||||
@samp{e1 + e2 / e3}. The derivations show how your rules would parse the
|
@samp{e1 + e2 / e3}. The derivations show how your rules would parse the
|
||||||
@@ -11047,7 +11187,7 @@ The exit status of @command{bison} is:
|
|||||||
@item 0 (success)
|
@item 0 (success)
|
||||||
when there were no errors. Warnings, which are diagnostics about dubious
|
when there were no errors. Warnings, which are diagnostics about dubious
|
||||||
constructs, do not change the exit status, unless they are turned into
|
constructs, do not change the exit status, unless they are turned into
|
||||||
errors (@pxref{-Werror,,@option{-Werror}}).
|
errors (@pxref{Werror,,@option{-Werror}}).
|
||||||
|
|
||||||
@item 1 (failure)
|
@item 1 (failure)
|
||||||
when there were errors. No file was generated (except the reports generated
|
when there were errors. No file was generated (except the reports generated
|
||||||
@@ -11284,22 +11424,22 @@ Options controlling the diagnostics.
|
|||||||
Output warnings falling in @var{category}. @var{category} can be one
|
Output warnings falling in @var{category}. @var{category} can be one
|
||||||
of:
|
of:
|
||||||
@table @code
|
@table @code
|
||||||
@item conflicts-sr
|
@item @anchor{Wconflicts-sr}conflicts-sr
|
||||||
@itemx conflicts-rr
|
@itemx @anchor{Wconflicts-rr}conflicts-rr
|
||||||
S/R and R/R conflicts. These warnings are enabled by default. However, if
|
S/R and R/R conflicts. These warnings are enabled by default. However, if
|
||||||
the @code{%expect} or @code{%expect-rr} directive is specified, an
|
the @code{%expect} or @code{%expect-rr} directive is specified, an
|
||||||
unexpected number of conflicts is an error, and an expected number of
|
unexpected number of conflicts is an error, and an expected number of
|
||||||
conflicts is not reported, so @option{-W} and @option{--warning} then have
|
conflicts is not reported, so @option{-W} and @option{--warning} then have
|
||||||
no effect on the conflict report.
|
no effect on the conflict report.
|
||||||
|
|
||||||
@item counterexamples
|
@item @anchor{Wcounterexamples}counterexamples
|
||||||
@itemx cex
|
@itemx cex
|
||||||
Provide counterexamples for conflicts. @xref{Counterexamples}.
|
Provide counterexamples for conflicts. @xref{Counterexamples}.
|
||||||
Counterexamples take time to compute. The option @option{-Wcex} should be
|
Counterexamples take time to compute. The option @option{-Wcex} should be
|
||||||
used by the developer when working on the grammar; it hardly makes sense to
|
used by the developer when working on the grammar; it hardly makes sense to
|
||||||
use it in a CI.
|
use it in a CI.
|
||||||
|
|
||||||
@item dangling-alias
|
@item @anchor{Wdangling-alias}dangling-alias
|
||||||
Report string literals that are not bound to a token symbol.
|
Report string literals that are not bound to a token symbol.
|
||||||
|
|
||||||
String literals, which allow for better error messages, are (too) liberally
|
String literals, which allow for better error messages, are (too) liberally
|
||||||
@@ -11345,16 +11485,16 @@ foo: "baz" @{@}
|
|||||||
| @dwarning{^~~~~}
|
| @dwarning{^~~~~}
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
@item deprecated
|
@item @anchor{Wdeprecated}deprecated
|
||||||
Deprecated constructs whose support will be removed in future versions of
|
Deprecated constructs whose support will be removed in future versions of
|
||||||
Bison.
|
Bison.
|
||||||
|
|
||||||
@item empty-rule
|
@item @anchor{Wempty-rule}empty-rule
|
||||||
Empty rules without @code{%empty}. @xref{Empty Rules}. Disabled by
|
Empty rules without @code{%empty}. @xref{Empty Rules}. Disabled by
|
||||||
default, but enabled by uses of @code{%empty}, unless
|
default, but enabled by uses of @code{%empty}, unless
|
||||||
@option{-Wno-empty-rule} was specified.
|
@option{-Wno-empty-rule} was specified.
|
||||||
|
|
||||||
@item midrule-values
|
@item @anchor{Wmidrule-values}midrule-values
|
||||||
Warn about midrule values that are set but not used within any of the actions
|
Warn about midrule values that are set but not used within any of the actions
|
||||||
of the parent rule.
|
of the parent rule.
|
||||||
For example, warn about unused @code{$2} in:
|
For example, warn about unused @code{$2} in:
|
||||||
@@ -11374,7 +11514,7 @@ These warnings are not enabled by default since they sometimes prove to
|
|||||||
be false alarms in existing grammars employing the Yacc constructs
|
be false alarms in existing grammars employing the Yacc constructs
|
||||||
@code{$0} or @code{$-@var{n}} (where @var{n} is some positive integer).
|
@code{$0} or @code{$-@var{n}} (where @var{n} is some positive integer).
|
||||||
|
|
||||||
@item precedence
|
@item @anchor{Wprecedence}precedence
|
||||||
Useless precedence and associativity directives. Disabled by default.
|
Useless precedence and associativity directives. Disabled by default.
|
||||||
|
|
||||||
Consider for instance the following grammar:
|
Consider for instance the following grammar:
|
||||||
@@ -11435,20 +11575,21 @@ One would get the exact same parser with the following directives instead:
|
|||||||
@end group
|
@end group
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
@item yacc
|
@item @anchor{Wyacc}yacc
|
||||||
Incompatibilities with POSIX Yacc.
|
Incompatibilities with POSIX Yacc.
|
||||||
|
|
||||||
@item other
|
@item @anchor{Wother}other
|
||||||
All warnings not categorized above. These warnings are enabled by default.
|
All warnings not categorized above. These warnings are enabled by default.
|
||||||
|
|
||||||
This category is provided merely for the sake of completeness. Future
|
This category is provided merely for the sake of completeness. Future
|
||||||
releases of Bison may move warnings from this category to new, more specific
|
releases of Bison may move warnings from this category to new, more specific
|
||||||
categories.
|
categories.
|
||||||
|
|
||||||
@item all
|
@item @anchor{Wall}all
|
||||||
All the warnings except @code{dangling-alias} and @code{yacc}.
|
All the warnings except @code{counterexamples}, @code{dangling-alias} and
|
||||||
|
@code{yacc}.
|
||||||
|
|
||||||
@item none
|
@item @anchor{Wnone}none
|
||||||
Turn off all the warnings.
|
Turn off all the warnings.
|
||||||
|
|
||||||
@item error
|
@item error
|
||||||
@@ -11459,8 +11600,7 @@ A category can be turned off by prefixing its name with @samp{no-}. For
|
|||||||
instance, @option{-Wno-yacc} will hide the warnings about
|
instance, @option{-Wno-yacc} will hide the warnings about
|
||||||
POSIX Yacc incompatibilities.
|
POSIX Yacc incompatibilities.
|
||||||
|
|
||||||
@item -Werror
|
@item @anchor{Werror}-Werror
|
||||||
@anchor{-Werror}
|
|
||||||
Turn enabled warnings for every @var{category} into errors, unless they are
|
Turn enabled warnings for every @var{category} into errors, unless they are
|
||||||
explicitly disabled by @option{-Wno-error=@var{category}}.
|
explicitly disabled by @option{-Wno-error=@var{category}}.
|
||||||
|
|
||||||
@@ -14824,13 +14964,13 @@ Bison. See the file @file{ABOUT-NLS} for more information.
|
|||||||
I can't build Bison because my C compiler is too old.
|
I can't build Bison because my C compiler is too old.
|
||||||
@end quotation
|
@end quotation
|
||||||
|
|
||||||
Except for GLR parsers (@pxref{Compiler Requirements for GLR}), the C
|
Except for GLR parsers (which require C99), the C code that Bison generates
|
||||||
code that Bison generates requires only C89 or later. However, Bison
|
requires only C89 or later. However, Bison itself requires common C99
|
||||||
itself requires common C99 features such as declarations after
|
features such as declarations after statements. Bison's @code{configure}
|
||||||
statements. Bison's @code{configure} script attempts to enable C99 (or
|
script attempts to enable C99 (or later) support on compilers that default
|
||||||
later) support on compilers that default to pre-C99. If your compiler
|
to pre-C99. If your compiler lacks these C99 features entirely, GCC may
|
||||||
lacks these C99 features entirely, GCC may well be a better choice; or
|
well be a better choice; or you can try upgrading to your compiler's latest
|
||||||
you can try upgrading to your compiler's latest version.
|
version.
|
||||||
|
|
||||||
@node Where can I find help?
|
@node Where can I find help?
|
||||||
@section Where can I find help?
|
@section Where can I find help?
|
||||||
@@ -15887,7 +16027,7 @@ London, Department of Computer Science, TR-00-12 (December 2000).
|
|||||||
@c LocalWords: TokenKind Automake's rtti Wcounterexamples Chinawat PLDI
|
@c LocalWords: TokenKind Automake's rtti Wcounterexamples Chinawat PLDI
|
||||||
@c LocalWords: Isradisaikul tcite pcite rgbGreen colorGreen rgbYellow Wcex
|
@c LocalWords: Isradisaikul tcite pcite rgbGreen colorGreen rgbYellow Wcex
|
||||||
@c LocalWords: colorYellow rgbRed colorRed rgbBlue colorBlue rgbPurple
|
@c LocalWords: colorYellow rgbRed colorRed rgbBlue colorBlue rgbPurple
|
||||||
@c LocalWords: colorPurple ifhtml ifnothtml situ rcex
|
@c LocalWords: colorPurple ifhtml ifnothtml situ rcex MERCHANTABILITY Wnone
|
||||||
|
|
||||||
@c Local Variables:
|
@c Local Variables:
|
||||||
@c ispell-dictionary: "american"
|
@c ispell-dictionary: "american"
|
||||||
|
|||||||
+23
@@ -0,0 +1,23 @@
|
|||||||
|
%union
|
||||||
|
{
|
||||||
|
int ival;
|
||||||
|
const char *sval;
|
||||||
|
}
|
||||||
|
|
||||||
|
%token <ival> NUM
|
||||||
|
%nterm <ival> exp
|
||||||
|
%token <sval> STR
|
||||||
|
%nterm <sval> useless
|
||||||
|
|
||||||
|
%left '+' '-'
|
||||||
|
%left '*'
|
||||||
|
|
||||||
|
%%
|
||||||
|
exp:
|
||||||
|
exp '+' exp
|
||||||
|
| exp '-' exp
|
||||||
|
| exp '*' exp
|
||||||
|
| exp '/' exp
|
||||||
|
| NUM
|
||||||
|
;
|
||||||
|
useless: STR;
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
%%
|
||||||
|
stmt:
|
||||||
|
expr
|
||||||
|
| if_stmt
|
||||||
|
;
|
||||||
|
|
||||||
|
if_stmt:
|
||||||
|
"if" expr "then" stmt
|
||||||
|
| "if" expr "then" stmt "else" stmt
|
||||||
|
;
|
||||||
|
|
||||||
|
expr:
|
||||||
|
"identifier"
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
%%
|
||||||
|
sequence:
|
||||||
|
%empty
|
||||||
|
| maybeword
|
||||||
|
| sequence "word"
|
||||||
|
;
|
||||||
|
maybeword:
|
||||||
|
%empty
|
||||||
|
| "word"
|
||||||
|
;
|
||||||
+10
-1
@@ -53,7 +53,9 @@ push-parser model.
|
|||||||
This example demonstrates best practices when using Bison.
|
This example demonstrates best practices when using Bison.
|
||||||
- Its hand-written scanner tracks locations.
|
- Its hand-written scanner tracks locations.
|
||||||
- Its interface is pure.
|
- 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
|
- Its interface is "incremental", well suited for interaction: it uses the
|
||||||
push-parser API to feed the parser with the incoming tokens.
|
push-parser API to feed the parser with the incoming tokens.
|
||||||
- It features an interactive command line with completion based on the
|
- It features an interactive command line with completion based on the
|
||||||
@@ -62,6 +64,13 @@ This example demonstrates best practices when using Bison.
|
|||||||
messages.
|
messages.
|
||||||
- It uses a custom syntax error with location, lookahead correction and
|
- It uses a custom syntax error with location, lookahead correction and
|
||||||
token internationalization.
|
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 supports debug traces with semantic values.
|
||||||
- It uses named references instead of the traditional $1, $2, etc.
|
- It uses named references instead of the traditional $1, $2, etc.
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,9 @@
|
|||||||
This example demonstrates best practices when using Bison.
|
This example demonstrates best practices when using Bison.
|
||||||
- Its hand-written scanner tracks locations.
|
- Its hand-written scanner tracks locations.
|
||||||
- Its interface is pure.
|
- 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
|
- Its interface is "incremental", well suited for interaction: it uses the
|
||||||
push-parser API to feed the parser with the incoming tokens.
|
push-parser API to feed the parser with the incoming tokens.
|
||||||
- It features an interactive command line with completion based on the
|
- It features an interactive command line with completion based on the
|
||||||
@@ -11,6 +13,13 @@ This example demonstrates best practices when using Bison.
|
|||||||
messages.
|
messages.
|
||||||
- It uses a custom syntax error with location, lookahead correction and
|
- It uses a custom syntax error with location, lookahead correction and
|
||||||
token internationalization.
|
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 supports debug traces with semantic values.
|
||||||
- It uses named references instead of the traditional $1, $2, etc.
|
- It uses named references instead of the traditional $1, $2, etc.
|
||||||
|
|
||||||
|
|||||||
@@ -101,14 +101,28 @@ cat >input <<EOF
|
|||||||
EOF
|
EOF
|
||||||
run 0 '> *
|
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
|
cat >input <<EOF
|
||||||
1 + 2 * * 3
|
1 + 2 * * 3
|
||||||
EOF
|
EOF
|
||||||
run 0 '> 1 + 2 * * 3
|
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
|
cat >input <<EOF
|
||||||
1 / 0
|
1 / 0
|
||||||
@@ -132,8 +146,14 @@ run 0 '> ((1 ++ 2) ** 3)
|
|||||||
1332
|
1332
|
||||||
> ''
|
> ''
|
||||||
err: 1.6: syntax error: expected - or ( or number or function or variable before +
|
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.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 ")".
|
# The rule "( error )" should work even if there are no tokens between "(" and ")".
|
||||||
cat >input <<EOF
|
cat >input <<EOF
|
||||||
@@ -142,7 +162,9 @@ EOF
|
|||||||
run 0 '> ()
|
run 0 '> ()
|
||||||
666
|
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
|
cat >input <<EOF
|
||||||
@@ -189,6 +211,8 @@ err: LAC: checking lookahead function: S5
|
|||||||
err: LAC: checking lookahead variable: S6
|
err: LAC: checking lookahead variable: S6
|
||||||
err: LAC: checking lookahead NEG: Err
|
err: LAC: checking lookahead NEG: Err
|
||||||
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: | ^
|
||||||
err: LAC: initial context discarded due to error recovery
|
err: LAC: initial context discarded due to error recovery
|
||||||
err: Shifting token error (1.2: )
|
err: Shifting token error (1.2: )
|
||||||
err: Entering state 10
|
err: Entering state 10
|
||||||
@@ -286,7 +310,9 @@ run 0 '> (1+
|
|||||||
( - atan cos exp ln number sin sqrt
|
( - atan cos exp ln number sin sqrt
|
||||||
> (1+
|
> (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.
|
# Check the completion of a word.
|
||||||
sed -e 's/\\t/ /g' >input <<EOF
|
sed -e 's/\\t/ /g' >input <<EOF
|
||||||
@@ -294,7 +320,9 @@ sed -e 's/\\t/ /g' >input <<EOF
|
|||||||
EOF
|
EOF
|
||||||
run 0 '> (atan ( ''
|
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.
|
# Check the completion at the very beginning.
|
||||||
sed -e 's/\\t/ /g' >input <<EOF
|
sed -e 's/\\t/ /g' >input <<EOF
|
||||||
@@ -313,8 +341,9 @@ sed -e 's/\\t/ /g' >input <<EOF
|
|||||||
EOF
|
EOF
|
||||||
run -n 0 '> 1++ ''
|
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.3: syntax error: expected - or ( or number or function or variable before +
|
||||||
|
err: 1 | 1++ ''
|
||||||
|
err: | ^
|
||||||
'
|
'
|
||||||
|
|
||||||
# And even when the error was recovered from.
|
# And even when the error was recovered from.
|
||||||
@@ -323,8 +352,10 @@ sed -e 's/\\t/ /g' >input <<EOF
|
|||||||
EOF
|
EOF
|
||||||
run -n 0 '> (1++2) + 3 + ''
|
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.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.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 *putsym (char const *name, int sym_type);
|
||||||
symrec *getsym (char const *name);
|
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.
|
// Emitted in the header file, after the definition of YYSTYPE.
|
||||||
@@ -74,9 +83,13 @@
|
|||||||
# define __attribute__(Spec) /* empty */
|
# define __attribute__(Spec) /* empty */
|
||||||
# endif
|
# endif
|
||||||
# endif
|
# endif
|
||||||
int yylex (const char **line, YYSTYPE *yylval, YYLTYPE *yylloc);
|
|
||||||
void yyerror (YYLTYPE *loc, char const *format, ...)
|
yytoken_kind_t
|
||||||
__attribute__ ((__format__ (__printf__, 2, 3)));
|
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.
|
// Emitted in the implementation file.
|
||||||
@@ -116,6 +129,9 @@
|
|||||||
// Generate the parser description file (calc.output).
|
// Generate the parser description file (calc.output).
|
||||||
%verbose
|
%verbose
|
||||||
|
|
||||||
|
// User information exchanged with the parser and scanner.
|
||||||
|
%param {const user_context *uctx}
|
||||||
|
|
||||||
// Generate YYSTYPE from the types assigned to symbols.
|
// Generate YYSTYPE from the types assigned to symbols.
|
||||||
%define api.value.type union
|
%define api.value.type union
|
||||||
%token
|
%token
|
||||||
@@ -171,7 +187,7 @@ exp:
|
|||||||
{
|
{
|
||||||
if ($r == 0)
|
if ($r == 0)
|
||||||
{
|
{
|
||||||
yyerror (&@$, "error: division by zero");
|
yyerror (&@$, uctx, "error: division by zero");
|
||||||
YYERROR;
|
YYERROR;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -257,8 +273,9 @@ symbol_count (void)
|
|||||||
| Scanner. |
|
| Scanner. |
|
||||||
`----------*/
|
`----------*/
|
||||||
|
|
||||||
int
|
yytoken_kind_t
|
||||||
yylex (const char **line, YYSTYPE *yylval, YYLTYPE *yylloc)
|
yylex (const char **line, YYSTYPE *yylval, YYLTYPE *yylloc,
|
||||||
|
const user_context *uctx)
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
|
|
||||||
@@ -328,7 +345,7 @@ yylex (const char **line, YYSTYPE *yylval, YYLTYPE *yylloc)
|
|||||||
|
|
||||||
// Stray characters.
|
// Stray characters.
|
||||||
default:
|
default:
|
||||||
yyerror (yylloc, "syntax error: invalid character: %c", c);
|
yyerror (yylloc, uctx, "syntax error: invalid character: %c", c);
|
||||||
return TOK_YYerror;
|
return TOK_YYerror;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -366,8 +383,11 @@ error_format_string (int argc)
|
|||||||
|
|
||||||
|
|
||||||
int
|
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 };
|
enum { ARGS_MAX = 6 };
|
||||||
yysymbol_kind_t arg[ARGS_MAX];
|
yysymbol_kind_t arg[ARGS_MAX];
|
||||||
int argsize = yypcontext_expected_tokens (ctx, 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;
|
argsize = ARGS_MAX;
|
||||||
const char *format = error_format_string (1 + argsize + too_many_expected_tokens);
|
const char *format = error_format_string (1 + argsize + too_many_expected_tokens);
|
||||||
|
|
||||||
|
const YYLTYPE *loc = yypcontext_location (ctx);
|
||||||
while (*format)
|
while (*format)
|
||||||
// %@: location.
|
// %@: location.
|
||||||
if (format[0] == '%' && format[1] == '@')
|
if (format[0] == '%' && format[1] == '@')
|
||||||
{
|
{
|
||||||
YY_LOCATION_PRINT (stderr, *yypcontext_location (ctx));
|
YY_LOCATION_PRINT (stderr, *loc);
|
||||||
format += 2;
|
format += 2;
|
||||||
}
|
}
|
||||||
// %u: unexpected token.
|
// %u: unexpected token.
|
||||||
@@ -407,13 +428,25 @@ yyreport_syntax_error (const yypcontext_t *ctx)
|
|||||||
++format;
|
++format;
|
||||||
}
|
}
|
||||||
fputc ('\n', stderr);
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Called by yyparse on error.
|
// 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);
|
YY_LOCATION_PRINT (stderr, *loc);
|
||||||
fputs (": ", stderr);
|
fputs (": ", stderr);
|
||||||
va_list args;
|
va_list args;
|
||||||
@@ -449,11 +482,13 @@ xstrndup (const char *string, size_t n)
|
|||||||
static int
|
static int
|
||||||
process_line (YYLTYPE *lloc, const char *line)
|
process_line (YYLTYPE *lloc, const char *line)
|
||||||
{
|
{
|
||||||
|
user_context uctx = {0, line};
|
||||||
yypstate *ps = yypstate_new ();
|
yypstate *ps = yypstate_new ();
|
||||||
int status = 0;
|
int status = 0;
|
||||||
do {
|
do {
|
||||||
YYSTYPE lval;
|
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);
|
} while (status == YYPUSH_MORE);
|
||||||
yypstate_delete (ps);
|
yypstate_delete (ps);
|
||||||
lloc->last_line++;
|
lloc->last_line++;
|
||||||
@@ -468,18 +503,19 @@ expected_tokens (const char *input,
|
|||||||
int *tokens, int ntokens)
|
int *tokens, int ntokens)
|
||||||
{
|
{
|
||||||
YYDPRINTF ((stderr, "expected_tokens (\"%s\")", input));
|
YYDPRINTF ((stderr, "expected_tokens (\"%s\")", input));
|
||||||
|
user_context uctx = {1, input};
|
||||||
|
|
||||||
// Parse the current state of the line.
|
// Parse the current state of the line.
|
||||||
yypstate *ps = yypstate_new ();
|
yypstate *ps = yypstate_new ();
|
||||||
int status = 0;
|
int status = 0;
|
||||||
|
YYLTYPE lloc = { 1, 1, 1, 1 };
|
||||||
do {
|
do {
|
||||||
YYLTYPE lloc = { 1, 1, 1, 1 };
|
|
||||||
YYSTYPE lval;
|
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.
|
// Don't let the parse know when we reach the end of input.
|
||||||
if (!token)
|
if (token == TOK_YYEOF)
|
||||||
break;
|
break;
|
||||||
status = yypush_parse (ps, token, &lval, &lloc);
|
status = yypush_parse (ps, token, &lval, &lloc, &uctx);
|
||||||
} while (status == YYPUSH_MORE);
|
} while (status == YYPUSH_MORE);
|
||||||
|
|
||||||
int res = 0;
|
int res = 0;
|
||||||
|
|||||||
+1
-1
Submodule gnulib updated: 12c89745e3...ac34618e85
@@ -313,6 +313,7 @@
|
|||||||
/stdlib.h
|
/stdlib.h
|
||||||
/stdlib.in.h
|
/stdlib.in.h
|
||||||
/stpcpy.c
|
/stpcpy.c
|
||||||
|
/stpncpy.c
|
||||||
/strchrnul.c
|
/strchrnul.c
|
||||||
/strchrnul.valgrind
|
/strchrnul.valgrind
|
||||||
/strdup.c
|
/strdup.c
|
||||||
|
|||||||
@@ -175,6 +175,7 @@
|
|||||||
/stdio_h.m4
|
/stdio_h.m4
|
||||||
/stdlib_h.m4
|
/stdlib_h.m4
|
||||||
/stpcpy.m4
|
/stpcpy.m4
|
||||||
|
/stpncpy.m4
|
||||||
/strchrnul.m4
|
/strchrnul.m4
|
||||||
/strdup.m4
|
/strdup.m4
|
||||||
/strerror.m4
|
/strerror.m4
|
||||||
|
|||||||
@@ -169,10 +169,10 @@ AnnotationList__compute_conflicted_tokens (bitset shift_tokens,
|
|||||||
bitset_copy (tokens, shift_tokens);
|
bitset_copy (tokens, shift_tokens);
|
||||||
for (int i = 0; i < reds->num; ++i)
|
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,
|
bitset_or (conflicted_tokens,
|
||||||
conflicted_tokens, conflicted_tokens_rule);
|
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
|
/* Check that rules are sorted on rule number or the next step in
|
||||||
AnnotationList__compute_from_inadequacies will misbehave. */
|
AnnotationList__compute_from_inadequacies will misbehave. */
|
||||||
aver (i == 0 || reds->rules[i-1] < reds->rules[i]);
|
aver (i == 0 || reds->rules[i-1] < reds->rules[i]);
|
||||||
@@ -401,7 +401,7 @@ AnnotationList__compute_from_inadequacies (
|
|||||||
struct obstack *annotations_obstackp,
|
struct obstack *annotations_obstackp,
|
||||||
InadequacyListNodeCount *inadequacy_list_node_count)
|
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)
|
if (s->consistent)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -422,7 +422,7 @@ AnnotationList__compute_from_inadequacies (
|
|||||||
/* Allocate the annotation node. */
|
/* Allocate the annotation node. */
|
||||||
{
|
{
|
||||||
for (int rule_i = 0; rule_i < s->reductions->num; ++rule_i)
|
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))
|
conflicted_token))
|
||||||
++contribution_count;
|
++contribution_count;
|
||||||
if (bitset_test (shift_tokens, conflicted_token))
|
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)
|
for (int rule_i = 0; rule_i < s->reductions->num; ++rule_i)
|
||||||
{
|
{
|
||||||
rule *the_rule = s->reductions->rules[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))
|
conflicted_token))
|
||||||
{
|
{
|
||||||
bitset_set (actions, rule_i);
|
bitset_set (actions, rule_i);
|
||||||
|
|||||||
+35
-3
@@ -35,6 +35,13 @@
|
|||||||
#include "getargs.h"
|
#include "getargs.h"
|
||||||
#include "quote.h"
|
#include "quote.h"
|
||||||
|
|
||||||
|
// The URL of the manual page about diagnostics. Use the per-node
|
||||||
|
// manual, to avoid downloading repeatedly the whole manual over the
|
||||||
|
// Internet.
|
||||||
|
static const char *diagnostics_url
|
||||||
|
= "https://www.gnu.org/software/bison/manual/html_node/Diagnostics.html";
|
||||||
|
|
||||||
|
|
||||||
err_status complaint_status = status_none;
|
err_status complaint_status = status_none;
|
||||||
|
|
||||||
bool warnings_are_errors = false;
|
bool warnings_are_errors = false;
|
||||||
@@ -96,6 +103,20 @@ end_use_class (const char *s, FILE *out)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
begin_hyperlink (FILE *out, const char *ref)
|
||||||
|
{
|
||||||
|
if (out == stderr)
|
||||||
|
styled_ostream_set_hyperlink (errstream, ref, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
end_hyperlink (FILE *out)
|
||||||
|
{
|
||||||
|
if (out == stderr)
|
||||||
|
styled_ostream_set_hyperlink (errstream, NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
flush (FILE *out)
|
flush (FILE *out)
|
||||||
{
|
{
|
||||||
@@ -427,9 +448,20 @@ warnings_print_categories (warnings warn_flags, FILE *out)
|
|||||||
const char* style = severity_style (s);
|
const char* style = severity_style (s);
|
||||||
fputs (" [", out);
|
fputs (" [", out);
|
||||||
begin_use_class (style, out);
|
begin_use_class (style, out);
|
||||||
fprintf (out, "-W%s%s",
|
// E.g., "counterexamples".
|
||||||
s == severity_error ? "error=" : "",
|
const char *warning = argmatch_warning_argument (&w);
|
||||||
argmatch_warning_argument (&w));
|
char ref[200];
|
||||||
|
snprintf (ref, sizeof ref,
|
||||||
|
"%s#W%s", diagnostics_url, warning);
|
||||||
|
begin_hyperlink (out, ref);
|
||||||
|
ostream_printf (errstream,
|
||||||
|
"-W%s%s",
|
||||||
|
s == severity_error ? "error=" : "",
|
||||||
|
warning);
|
||||||
|
end_hyperlink (out);
|
||||||
|
// Because we mix stdio with ostream I/O, we need to flush
|
||||||
|
// here for sake of color == debug.
|
||||||
|
flush (out);
|
||||||
end_use_class (style, out);
|
end_use_class (style, out);
|
||||||
fputc (']', out);
|
fputc (']', out);
|
||||||
/* Display only the first match, the second is "-Wall". */
|
/* Display only the first match, the second is "-Wall". */
|
||||||
|
|||||||
+29
-25
@@ -250,9 +250,9 @@ flush_shift (state *s, int token)
|
|||||||
`--------------------------------------------------------------------*/
|
`--------------------------------------------------------------------*/
|
||||||
|
|
||||||
static void
|
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. */
|
/* Find the rule to reduce by to get precedence of reduction. */
|
||||||
rule *redrule = reds->rules[ruleno];
|
rule *redrule = reds->rules[ruleno];
|
||||||
int redprec = redrule->prec->prec;
|
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)
|
for (symbol_number i = 0; i < ntokens; ++i)
|
||||||
if (bitset_test (lookahead_tokens, i)
|
if (bitset_test (lookaheads, i)
|
||||||
&& bitset_test (lookahead_set, i)
|
&& bitset_test (lookahead_set, i)
|
||||||
&& symbols[i]->content->prec)
|
&& 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);
|
register_precedence (i, redrule->prec->number);
|
||||||
log_resolution (redrule, i, shift_resolution);
|
log_resolution (redrule, i, shift_resolution);
|
||||||
flush_reduce (lookahead_tokens, i);
|
flush_reduce (lookaheads, i);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
/* Matching precedence levels.
|
/* Matching precedence levels.
|
||||||
@@ -316,7 +316,7 @@ resolve_sr_conflict (state *s, int ruleno, symbol **errors, int *nerrs)
|
|||||||
case right_assoc:
|
case right_assoc:
|
||||||
register_assoc (i, redrule->prec->number);
|
register_assoc (i, redrule->prec->number);
|
||||||
log_resolution (redrule, i, right_resolution);
|
log_resolution (redrule, i, right_resolution);
|
||||||
flush_reduce (lookahead_tokens, i);
|
flush_reduce (lookaheads, i);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case left_assoc:
|
case left_assoc:
|
||||||
@@ -329,7 +329,7 @@ resolve_sr_conflict (state *s, int ruleno, symbol **errors, int *nerrs)
|
|||||||
register_assoc (i, redrule->prec->number);
|
register_assoc (i, redrule->prec->number);
|
||||||
log_resolution (redrule, i, nonassoc_resolution);
|
log_resolution (redrule, i, nonassoc_resolution);
|
||||||
flush_shift (s, i);
|
flush_shift (s, i);
|
||||||
flush_reduce (lookahead_tokens, i);
|
flush_reduce (lookaheads, i);
|
||||||
/* Record an explicit error for this token. */
|
/* Record an explicit error for this token. */
|
||||||
errors[(*nerrs)++] = symbols[i];
|
errors[(*nerrs)++] = symbols[i];
|
||||||
break;
|
break;
|
||||||
@@ -369,7 +369,7 @@ set_conflicts (state *s, symbol **errors)
|
|||||||
for (int i = 0; i < reds->num; ++i)
|
for (int i = 0; i < reds->num; ++i)
|
||||||
if (reds->rules[i]->prec
|
if (reds->rules[i]->prec
|
||||||
&& reds->rules[i]->prec->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);
|
resolve_sr_conflict (s, i, errors, &nerrs);
|
||||||
|
|
||||||
if (nerrs)
|
if (nerrs)
|
||||||
@@ -385,13 +385,13 @@ set_conflicts (state *s, symbol **errors)
|
|||||||
/* Loop over all rules which require lookahead in this state. Check
|
/* Loop over all rules which require lookahead in this state. Check
|
||||||
for conflicts not resolved above.
|
for conflicts not resolved above.
|
||||||
|
|
||||||
reds->lookahead_tokens can be NULL if the LR type is LR(0). */
|
reds->lookaheads can be NULL if the LR type is LR(0). */
|
||||||
if (reds->lookahead_tokens)
|
if (reds->lookaheads)
|
||||||
for (int i = 0; i < reds->num; ++i)
|
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;
|
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)
|
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);
|
bitset_and (lookahead_set, lookahead_set, shift_set);
|
||||||
|
|
||||||
@@ -499,7 +499,7 @@ count_state_rr_conflicts (const state *s)
|
|||||||
{
|
{
|
||||||
int count = 0;
|
int count = 0;
|
||||||
for (int j = 0; j < reds->num; ++j)
|
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)
|
if (2 <= count)
|
||||||
res += count-1;
|
res += count-1;
|
||||||
}
|
}
|
||||||
@@ -534,7 +534,7 @@ count_rule_state_sr_conflicts (rule *r, state *s)
|
|||||||
for (int i = 0; i < reds->num; ++i)
|
for (int i = 0; i < reds->num; ++i)
|
||||||
if (reds->rules[i] == r)
|
if (reds->rules[i] == r)
|
||||||
{
|
{
|
||||||
bitset lookaheads = reds->lookahead_tokens[i];
|
bitset lookaheads = reds->lookaheads[i];
|
||||||
int j;
|
int j;
|
||||||
FOR_EACH_SHIFT (trans, j)
|
FOR_EACH_SHIFT (trans, j)
|
||||||
res += bitset_test (lookaheads, TRANSITION_SYMBOL (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)
|
if (reds->rules[j] != r)
|
||||||
{
|
{
|
||||||
bitset_and (lookaheads,
|
bitset_and (lookaheads,
|
||||||
reds->lookahead_tokens[i],
|
reds->lookaheads[i],
|
||||||
reds->lookahead_tokens[j]);
|
reds->lookaheads[j]);
|
||||||
res += bitset_count (lookaheads);
|
res += bitset_count (lookaheads);
|
||||||
}
|
}
|
||||||
bitset_free (lookaheads);
|
bitset_free (lookaheads);
|
||||||
@@ -686,7 +686,8 @@ conflicts_print (void)
|
|||||||
expected_rr_conflicts = -1;
|
expected_rr_conflicts = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool has_unexpected_conflicts = false;
|
// The warning flags used to emit a diagnostic, if we did.
|
||||||
|
warnings unexpected_conflicts_warning = Wnone;
|
||||||
/* The following two blocks scream for factoring, but i18n support
|
/* The following two blocks scream for factoring, but i18n support
|
||||||
would make it ugly. */
|
would make it ugly. */
|
||||||
{
|
{
|
||||||
@@ -703,7 +704,8 @@ conflicts_print (void)
|
|||||||
complain (NULL, complaint,
|
complain (NULL, complaint,
|
||||||
_("shift/reduce conflicts: %d found, %d expected"),
|
_("shift/reduce conflicts: %d found, %d expected"),
|
||||||
total, expected);
|
total, expected);
|
||||||
has_unexpected_conflicts = true;
|
if (total)
|
||||||
|
unexpected_conflicts_warning = complaint;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (total)
|
else if (total)
|
||||||
@@ -713,7 +715,7 @@ conflicts_print (void)
|
|||||||
"%d shift/reduce conflicts",
|
"%d shift/reduce conflicts",
|
||||||
total),
|
total),
|
||||||
total);
|
total);
|
||||||
has_unexpected_conflicts = true;
|
unexpected_conflicts_warning = Wconflicts_sr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -731,7 +733,8 @@ conflicts_print (void)
|
|||||||
complain (NULL, complaint,
|
complain (NULL, complaint,
|
||||||
_("reduce/reduce conflicts: %d found, %d expected"),
|
_("reduce/reduce conflicts: %d found, %d expected"),
|
||||||
total, expected);
|
total, expected);
|
||||||
has_unexpected_conflicts = true;
|
if (total)
|
||||||
|
unexpected_conflicts_warning = complaint;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (total)
|
else if (total)
|
||||||
@@ -741,15 +744,16 @@ conflicts_print (void)
|
|||||||
"%d reduce/reduce conflicts",
|
"%d reduce/reduce conflicts",
|
||||||
total),
|
total),
|
||||||
total);
|
total);
|
||||||
has_unexpected_conflicts = true;
|
unexpected_conflicts_warning = Wconflicts_rr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (warning_is_enabled (Wcounterexamples))
|
if (warning_is_enabled (Wcounterexamples))
|
||||||
report_counterexamples ();
|
report_counterexamples ();
|
||||||
else if (has_unexpected_conflicts)
|
else if (unexpected_conflicts_warning != Wnone)
|
||||||
complain (NULL, Wother,
|
subcomplain (NULL, unexpected_conflicts_warning,
|
||||||
_("rerun with option '-Wcounterexamples' to generate conflict counterexamples"));
|
_("rerun with option '-Wcounterexamples'"
|
||||||
|
" to generate conflict counterexamples"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|||||||
+176
-103
@@ -26,6 +26,7 @@
|
|||||||
#include <gl_linked_list.h>
|
#include <gl_linked_list.h>
|
||||||
#include <gl_rbtreehash_list.h>
|
#include <gl_rbtreehash_list.h>
|
||||||
#include <hash.h>
|
#include <hash.h>
|
||||||
|
#include <mbswidth.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <textstyle.h>
|
#include <textstyle.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
@@ -76,17 +77,29 @@ typedef struct
|
|||||||
{
|
{
|
||||||
derivation *d1;
|
derivation *d1;
|
||||||
derivation *d2;
|
derivation *d2;
|
||||||
|
bool shift_reduce;
|
||||||
bool unifying;
|
bool unifying;
|
||||||
bool timeout;
|
bool timeout;
|
||||||
} counterexample;
|
} counterexample;
|
||||||
|
|
||||||
static counterexample *
|
static counterexample *
|
||||||
new_counterexample (derivation *d1, derivation *d2,
|
new_counterexample (derivation *d1, derivation *d2,
|
||||||
|
bool shift_reduce,
|
||||||
bool u, bool t)
|
bool u, bool t)
|
||||||
{
|
{
|
||||||
counterexample *res = xmalloc (sizeof (counterexample));
|
counterexample *res = xmalloc (sizeof *res);
|
||||||
res->d1 = d1;
|
res->shift_reduce = shift_reduce;
|
||||||
res->d2 = d2;
|
if (shift_reduce)
|
||||||
|
{
|
||||||
|
// Display the shift first.
|
||||||
|
res->d1 = d2;
|
||||||
|
res->d2 = d1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
res->d1 = d1;
|
||||||
|
res->d2 = d2;
|
||||||
|
}
|
||||||
res->unifying = u;
|
res->unifying = u;
|
||||||
res->timeout = t;
|
res->timeout = t;
|
||||||
return res;
|
return res;
|
||||||
@@ -100,14 +113,37 @@ free_counterexample (counterexample *cex)
|
|||||||
free (cex);
|
free (cex);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static int max (int a, int b)
|
||||||
print_counterexample (counterexample *cex, FILE *out, const char *prefix)
|
|
||||||
{
|
{
|
||||||
fprintf (out, " %s%-20s ",
|
return a < b ? b : a;
|
||||||
prefix, cex->unifying ? _("Example") : _("First example"));
|
}
|
||||||
derivation_print_leaves (cex->d1, out, prefix);
|
|
||||||
fprintf (out, " %s%-20s ",
|
static void
|
||||||
prefix, _("First derivation"));
|
print_counterexample (const counterexample *cex, FILE *out, const char *prefix)
|
||||||
|
{
|
||||||
|
const bool flat = getenv ("YYFLAT");
|
||||||
|
const char *example1_label
|
||||||
|
= cex->unifying ? _("Example") : _("First example");
|
||||||
|
const char *example2_label
|
||||||
|
= cex->unifying ? _("Example") : _("Second example");
|
||||||
|
const char *deriv1_label
|
||||||
|
= cex->shift_reduce ? _("Shift derivation") : _("First reduce derivation");
|
||||||
|
const char *deriv2_label
|
||||||
|
= cex->shift_reduce ? _("Reduce derivation") : _("Second reduce derivation");
|
||||||
|
const int width =
|
||||||
|
max (max (mbswidth (example1_label, 0), mbswidth (example2_label, 0)),
|
||||||
|
max (mbswidth (deriv1_label, 0), mbswidth (deriv2_label, 0)));
|
||||||
|
if (flat)
|
||||||
|
fprintf (out, " %s%s%*s ", prefix,
|
||||||
|
example1_label, width - mbswidth (example1_label, 0), "");
|
||||||
|
else
|
||||||
|
fprintf (out, " %s%s: ", prefix, example1_label);
|
||||||
|
derivation_print_leaves (cex->d1, out);
|
||||||
|
if (flat)
|
||||||
|
fprintf (out, " %s%s%*s ", prefix,
|
||||||
|
deriv1_label, width - mbswidth (deriv1_label, 0), "");
|
||||||
|
else
|
||||||
|
fprintf (out, " %s%s", prefix, deriv1_label);
|
||||||
derivation_print (cex->d1, out, prefix);
|
derivation_print (cex->d1, out, prefix);
|
||||||
|
|
||||||
// If we output to the terminal (via stderr) and we have color
|
// If we output to the terminal (via stderr) and we have color
|
||||||
@@ -115,15 +151,22 @@ print_counterexample (counterexample *cex, FILE *out, const char *prefix)
|
|||||||
// to see the differences.
|
// to see the differences.
|
||||||
if (!cex->unifying || is_styled (stderr))
|
if (!cex->unifying || is_styled (stderr))
|
||||||
{
|
{
|
||||||
fprintf (out, " %s%-20s ",
|
if (flat)
|
||||||
prefix, cex->unifying ? _("Example") : _("Second example"));
|
fprintf (out, " %s%s%*s ", prefix,
|
||||||
derivation_print_leaves (cex->d2, out, prefix);
|
example2_label, width - mbswidth (example2_label, 0), "");
|
||||||
|
else
|
||||||
|
fprintf (out, " %s%s: ", prefix, example2_label);
|
||||||
|
derivation_print_leaves (cex->d2, out);
|
||||||
}
|
}
|
||||||
fprintf (out, " %s%-20s ",
|
if (flat)
|
||||||
prefix, _("Second derivation"));
|
fprintf (out, " %s%s%*s ", prefix,
|
||||||
|
deriv2_label, width - mbswidth (deriv2_label, 0), "");
|
||||||
|
else
|
||||||
|
fprintf (out, " %s%s", prefix, deriv2_label);
|
||||||
derivation_print (cex->d2, out, prefix);
|
derivation_print (cex->d2, out, prefix);
|
||||||
|
|
||||||
fputc ('\n', out);
|
if (out != stderr)
|
||||||
|
putc ('\n', out);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -144,7 +187,7 @@ typedef struct si_bfs_node
|
|||||||
static si_bfs_node *
|
static si_bfs_node *
|
||||||
si_bfs_new (state_item_number si, si_bfs_node *parent)
|
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->si = si;
|
||||||
res->parent = parent;
|
res->parent = parent;
|
||||||
res->reference_count = 1;
|
res->reference_count = 1;
|
||||||
@@ -175,6 +218,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
|
* 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
|
* nonterminal after the dot in start. Because of this, we should be able to
|
||||||
@@ -188,15 +233,16 @@ expand_to_conflict (state_item_number start, symbol_number conflict_sym)
|
|||||||
{
|
{
|
||||||
si_bfs_node *init = si_bfs_new (start, NULL);
|
si_bfs_node *init = si_bfs_new (start, NULL);
|
||||||
|
|
||||||
gl_list_t queue = gl_list_create (GL_LINKED_LIST, NULL, NULL,
|
si_bfs_node_list queue
|
||||||
(gl_listelement_dispose_fn) si_bfs_free,
|
= gl_list_create (GL_LINKED_LIST, NULL, NULL,
|
||||||
true, 1, (const void **) &init);
|
(gl_listelement_dispose_fn) si_bfs_free,
|
||||||
|
true, 1, (const void **) &init);
|
||||||
si_bfs_node *node = NULL;
|
si_bfs_node *node = NULL;
|
||||||
// breadth-first search for a path of productions to the conflict symbol
|
// breadth-first search for a path of productions to the conflict symbol
|
||||||
while (gl_list_size (queue) > 0)
|
while (gl_list_size (queue) > 0)
|
||||||
{
|
{
|
||||||
node = (si_bfs_node *) gl_list_get_at (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);
|
symbol_number sym = item_number_as_symbol_number (*silast->item);
|
||||||
if (sym == conflict_sym)
|
if (sym == conflict_sym)
|
||||||
break;
|
break;
|
||||||
@@ -238,7 +284,7 @@ expand_to_conflict (state_item_number start, symbol_number conflict_sym)
|
|||||||
|
|
||||||
for (si_bfs_node *n = node; n != NULL; n = n->parent)
|
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;
|
item_number *pos = si->item;
|
||||||
if (SI_PRODUCTION (si))
|
if (SI_PRODUCTION (si))
|
||||||
{
|
{
|
||||||
@@ -274,7 +320,7 @@ expand_to_conflict (state_item_number start, symbol_number conflict_sym)
|
|||||||
*/
|
*/
|
||||||
static derivation *
|
static derivation *
|
||||||
complete_diverging_example (symbol_number conflict_sym,
|
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
|
// The idea is to transfer each pending symbol on the productions
|
||||||
// associated with the given StateItems to the resulting derivation.
|
// associated with the given StateItems to the resulting derivation.
|
||||||
@@ -395,15 +441,15 @@ complete_diverging_example (symbol_number conflict_sym,
|
|||||||
/* Iterate backwards through the shifts of the path in the reduce
|
/* Iterate backwards through the shifts of the path in the reduce
|
||||||
conflict, and find a path of shifts from the shift conflict that
|
conflict, and find a path of shifts from the shift conflict that
|
||||||
goes through the same states. */
|
goes through the same states. */
|
||||||
static gl_list_t
|
static state_item_list
|
||||||
nonunifying_shift_path (gl_list_t reduce_path, state_item *shift_conflict)
|
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 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 next_node = gl_list_previous_node (reduce_path, tmp);
|
||||||
gl_list_node_t node = gl_list_previous_node (reduce_path, next_node);
|
gl_list_node_t node = gl_list_previous_node (reduce_path, next_node);
|
||||||
gl_list_remove_node (reduce_path, tmp);
|
gl_list_remove_node (reduce_path, tmp);
|
||||||
state_item *si = shift_conflict;
|
state_item *si = shift_conflict;
|
||||||
gl_list_t result =
|
state_item_list result =
|
||||||
gl_list_create_empty (GL_LINKED_LIST, NULL, NULL, NULL, true);
|
gl_list_create_empty (GL_LINKED_LIST, NULL, NULL, NULL, true);
|
||||||
// FIXME: bool paths_merged;
|
// FIXME: bool paths_merged;
|
||||||
for (; node != NULL; next_node = node,
|
for (; node != NULL; next_node = node,
|
||||||
@@ -425,10 +471,10 @@ nonunifying_shift_path (gl_list_t reduce_path, state_item *shift_conflict)
|
|||||||
|
|
||||||
// bfs to find a shift to the right state
|
// bfs to find a shift to the right state
|
||||||
si_bfs_node *init = si_bfs_new (si - state_items, NULL);
|
si_bfs_node *init = si_bfs_new (si - state_items, NULL);
|
||||||
gl_list_t queue =
|
si_bfs_node_list queue
|
||||||
gl_list_create (GL_LINKED_LIST, NULL, NULL,
|
= gl_list_create (GL_LINKED_LIST, NULL, NULL,
|
||||||
(gl_listelement_dispose_fn) si_bfs_free,
|
(gl_listelement_dispose_fn) si_bfs_free,
|
||||||
true, 1, (const void **) &init);
|
true, 1, (const void **) &init);
|
||||||
si_bfs_node *sis = NULL;
|
si_bfs_node *sis = NULL;
|
||||||
state_item *prevsi = NULL;
|
state_item *prevsi = NULL;
|
||||||
while (gl_list_size (queue) > 0)
|
while (gl_list_size (queue) > 0)
|
||||||
@@ -438,7 +484,7 @@ nonunifying_shift_path (gl_list_t reduce_path, state_item *shift_conflict)
|
|||||||
if (sis->si == 0)
|
if (sis->si == 0)
|
||||||
break;
|
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,
|
// if the current state-item is a production item,
|
||||||
// its reverse production items get added to the queue.
|
// its reverse production items get added to the queue.
|
||||||
// Otherwise, look for a reverse transition to the target state.
|
// Otherwise, look for a reverse transition to the target state.
|
||||||
@@ -447,7 +493,7 @@ nonunifying_shift_path (gl_list_t reduce_path, state_item *shift_conflict)
|
|||||||
state_item_number sin;
|
state_item_number sin;
|
||||||
BITSET_FOR_EACH (biter, rsi, sin, 0)
|
BITSET_FOR_EACH (biter, rsi, sin, 0)
|
||||||
{
|
{
|
||||||
prevsi = state_items + sin;
|
prevsi = &state_items[sin];
|
||||||
if (SI_TRANSITION (search_si))
|
if (SI_TRANSITION (search_si))
|
||||||
{
|
{
|
||||||
if (prevsi->state == refsi->state)
|
if (prevsi->state == refsi->state)
|
||||||
@@ -465,9 +511,9 @@ nonunifying_shift_path (gl_list_t reduce_path, state_item *shift_conflict)
|
|||||||
// prepend path to shift we found
|
// prepend path to shift we found
|
||||||
if (sis)
|
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)
|
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;
|
si = prevsi;
|
||||||
@@ -493,17 +539,17 @@ nonunifying_shift_path (gl_list_t reduce_path, state_item *shift_conflict)
|
|||||||
static counterexample *
|
static counterexample *
|
||||||
example_from_path (bool shift_reduce,
|
example_from_path (bool shift_reduce,
|
||||||
state_item_number itm2,
|
state_item_number itm2,
|
||||||
gl_list_t shortest_path, symbol_number next_sym)
|
state_item_list shortest_path, symbol_number next_sym)
|
||||||
{
|
{
|
||||||
derivation *deriv1 =
|
derivation *deriv1 =
|
||||||
complete_diverging_example (next_sym, shortest_path, NULL);
|
complete_diverging_example (next_sym, shortest_path, NULL);
|
||||||
gl_list_t path_2
|
state_item_list path_2
|
||||||
= shift_reduce
|
= shift_reduce
|
||||||
? nonunifying_shift_path (shortest_path, &state_items [itm2])
|
? nonunifying_shift_path (shortest_path, &state_items [itm2])
|
||||||
: shortest_path_from_start (itm2, next_sym);
|
: shortest_path_from_start (itm2, next_sym);
|
||||||
derivation *deriv2 = complete_diverging_example (next_sym, path_2, NULL);
|
derivation *deriv2 = complete_diverging_example (next_sym, path_2, NULL);
|
||||||
gl_list_free (path_2);
|
gl_list_free (path_2);
|
||||||
return new_counterexample (deriv1, deriv2, false, true);
|
return new_counterexample (deriv1, deriv2, shift_reduce, false, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -525,7 +571,7 @@ typedef struct
|
|||||||
static search_state *
|
static search_state *
|
||||||
initial_search_state (state_item *conflict1, state_item *conflict2)
|
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[0] = new_parse_state (conflict1);
|
||||||
res->states[1] = new_parse_state (conflict2);
|
res->states[1] = new_parse_state (conflict2);
|
||||||
parse_state_retain (res->states[0]);
|
parse_state_retain (res->states[0]);
|
||||||
@@ -537,7 +583,7 @@ initial_search_state (state_item *conflict1, state_item *conflict2)
|
|||||||
static search_state *
|
static search_state *
|
||||||
new_search_state (parse_state *ps1, parse_state *ps2, int complexity)
|
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[0] = ps1;
|
||||||
res->states[1] = ps2;
|
res->states[1] = ps2;
|
||||||
parse_state_retain (res->states[0]);
|
parse_state_retain (res->states[0]);
|
||||||
@@ -549,8 +595,8 @@ new_search_state (parse_state *ps1, parse_state *ps2, int complexity)
|
|||||||
static search_state *
|
static search_state *
|
||||||
copy_search_state (search_state *parent)
|
copy_search_state (search_state *parent)
|
||||||
{
|
{
|
||||||
search_state *res = xmalloc (sizeof (search_state));
|
search_state *res = xmalloc (sizeof *res);
|
||||||
memcpy (res, parent, sizeof (search_state));
|
*res = *parent;
|
||||||
parse_state_retain (res->states[0]);
|
parse_state_retain (res->states[0]);
|
||||||
parse_state_retain (res->states[1]);
|
parse_state_retain (res->states[1]);
|
||||||
return res;
|
return res;
|
||||||
@@ -583,6 +629,8 @@ search_state_print (search_state *ss)
|
|||||||
putc ('\n', stderr);
|
putc ('\n', stderr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef gl_list_t search_state_list;
|
||||||
|
|
||||||
static inline bool
|
static inline bool
|
||||||
search_state_list_next (gl_list_iterator_t *it, search_state **ss)
|
search_state_list_next (gl_list_iterator_t *it, search_state **ss)
|
||||||
{
|
{
|
||||||
@@ -614,18 +662,20 @@ ss_set_parse_state (search_state *ss, int idx, parse_state *ps)
|
|||||||
*/
|
*/
|
||||||
static counterexample *
|
static counterexample *
|
||||||
complete_diverging_examples (search_state *ss,
|
complete_diverging_examples (search_state *ss,
|
||||||
symbol_number next_sym)
|
symbol_number next_sym,
|
||||||
|
bool shift_reduce)
|
||||||
{
|
{
|
||||||
derivation *new_derivs[2];
|
derivation *new_derivs[2];
|
||||||
for (int i = 0; i < 2; ++i)
|
for (int i = 0; i < 2; ++i)
|
||||||
{
|
{
|
||||||
gl_list_t sitems;
|
state_item_list sitems;
|
||||||
derivation_list derivs;
|
derivation_list derivs;
|
||||||
parse_state_lists (ss->states[i], &sitems, &derivs);
|
parse_state_lists (ss->states[i], &sitems, &derivs);
|
||||||
new_derivs[i] = complete_diverging_example (next_sym, sitems, derivs);
|
new_derivs[i] = complete_diverging_example (next_sym, sitems, derivs);
|
||||||
gl_list_free (sitems);
|
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 +685,7 @@ complete_diverging_examples (search_state *ss,
|
|||||||
*/
|
*/
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
gl_list_t states;
|
search_state_list states;
|
||||||
int complexity;
|
int complexity;
|
||||||
} search_state_bundle;
|
} search_state_bundle;
|
||||||
|
|
||||||
@@ -664,11 +714,13 @@ ssb_equals (const search_state_bundle *s1, const search_state_bundle *s2)
|
|||||||
return s1->complexity == s2->complexity;
|
return s1->complexity == s2->complexity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef gl_list_t ssb_list;
|
||||||
|
|
||||||
static size_t
|
static size_t
|
||||||
visited_hasher (const search_state *ss, size_t max)
|
visited_hasher (const search_state *ss, size_t maximum)
|
||||||
{
|
{
|
||||||
return (parse_state_hasher (ss->states[0], max)
|
return (parse_state_hasher (ss->states[0], maximum)
|
||||||
+ parse_state_hasher (ss->states[1], max)) % max;
|
+ parse_state_hasher (ss->states[1], maximum)) % maximum;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
@@ -679,7 +731,7 @@ visited_comparator (const search_state *ss1, const search_state *ss2)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Priority queue for search states with minimal complexity. */
|
/* Priority queue for search states with minimal complexity. */
|
||||||
static gl_list_t ssb_queue;
|
static ssb_list ssb_queue;
|
||||||
static Hash_table *visited;
|
static Hash_table *visited;
|
||||||
/* The set of parser states on the shortest lookahead-sensitive path. */
|
/* The set of parser states on the shortest lookahead-sensitive path. */
|
||||||
static bitset scp_set = NULL;
|
static bitset scp_set = NULL;
|
||||||
@@ -702,7 +754,7 @@ ssb_append (search_state *ss)
|
|||||||
parse_state_free_contents_early (ss->states[1]);
|
parse_state_free_contents_early (ss->states[1]);
|
||||||
parse_state_retain (ss->states[0]);
|
parse_state_retain (ss->states[0]);
|
||||||
parse_state_retain (ss->states[1]);
|
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;
|
ssb->complexity = ss->complexity;
|
||||||
gl_list_node_t n = gl_list_search (ssb_queue, ssb);
|
gl_list_node_t n = gl_list_search (ssb_queue, ssb);
|
||||||
if (!n)
|
if (!n)
|
||||||
@@ -756,12 +808,12 @@ reduction_cost (const parse_state *ps)
|
|||||||
return SHIFT_COST * shifts + PRODUCTION_COST * productions;
|
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,
|
reduction_step (search_state *ss, const item_number *conflict_item,
|
||||||
int parser_state, int rule_len)
|
int parser_state, int rule_len)
|
||||||
{
|
{
|
||||||
(void) conflict_item; // FIXME: Unused
|
(void) conflict_item; // FIXME: Unused
|
||||||
gl_list_t result =
|
search_state_list result =
|
||||||
gl_list_create_empty (GL_LINKED_LIST, NULL, NULL, NULL, 1);
|
gl_list_create_empty (GL_LINKED_LIST, NULL, NULL, NULL, 1);
|
||||||
|
|
||||||
parse_state *ps = ss->states[parser_state];
|
parse_state *ps = ss->states[parser_state];
|
||||||
@@ -897,7 +949,7 @@ search_state_prepend (search_state *ss, symbol_number sym, bitset guide)
|
|||||||
* the same prefix up to the dot.
|
* the same prefix up to the dot.
|
||||||
*/
|
*/
|
||||||
static bool
|
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;
|
int i = 0;
|
||||||
for (; !item_number_is_rule_number (itm1[i]); ++i)
|
for (; !item_number_is_rule_number (itm1[i]); ++i)
|
||||||
@@ -988,14 +1040,14 @@ generate_next_states (search_state *ss, state_item *conflict1,
|
|||||||
// prepended further, reduce.
|
// prepended further, reduce.
|
||||||
if (ready1 && ready2)
|
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);
|
gl_list_add_last (reduced1, ss);
|
||||||
search_state *red1 = NULL;
|
search_state *red1 = NULL;
|
||||||
for (gl_list_iterator_t iter = gl_list_iterator (reduced1);
|
for (gl_list_iterator_t iter = gl_list_iterator (reduced1);
|
||||||
search_state_list_next (&iter, &red1);
|
search_state_list_next (&iter, &red1);
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
gl_list_t reduced2 =
|
search_state_list reduced2 =
|
||||||
reduction_step (red1, conflict2->item, 1, len2);
|
reduction_step (red1, conflict2->item, 1, len2);
|
||||||
search_state *red2 = NULL;
|
search_state *red2 = NULL;
|
||||||
for (gl_list_iterator_t iter2 = gl_list_iterator (reduced2);
|
for (gl_list_iterator_t iter2 = gl_list_iterator (reduced2);
|
||||||
@@ -1011,7 +1063,7 @@ generate_next_states (search_state *ss, state_item *conflict1,
|
|||||||
}
|
}
|
||||||
else if (ready1)
|
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;
|
search_state *red1 = NULL;
|
||||||
for (gl_list_iterator_t iter = gl_list_iterator (reduced1);
|
for (gl_list_iterator_t iter = gl_list_iterator (reduced1);
|
||||||
search_state_list_next (&iter, &red1);
|
search_state_list_next (&iter, &red1);
|
||||||
@@ -1021,7 +1073,7 @@ generate_next_states (search_state *ss, state_item *conflict1,
|
|||||||
}
|
}
|
||||||
else if (ready2)
|
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;
|
search_state *red2 = NULL;
|
||||||
for (gl_list_iterator_t iter2 = gl_list_iterator (reduced2);
|
for (gl_list_iterator_t iter2 = gl_list_iterator (reduced2);
|
||||||
search_state_list_next (&iter2, &red2);
|
search_state_list_next (&iter2, &red2);
|
||||||
@@ -1055,10 +1107,10 @@ static counterexample *
|
|||||||
unifying_example (state_item_number itm1,
|
unifying_example (state_item_number itm1,
|
||||||
state_item_number itm2,
|
state_item_number itm2,
|
||||||
bool shift_reduce,
|
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 *conflict1 = &state_items[itm1];
|
||||||
state_item *conflict2 = state_items + itm2;
|
state_item *conflict2 = &state_items[itm2];
|
||||||
search_state *initial = initial_search_state (conflict1, conflict2);
|
search_state *initial = initial_search_state (conflict1, conflict2);
|
||||||
ssb_queue = gl_list_create_empty (GL_RBTREEHASH_LIST,
|
ssb_queue = gl_list_create_empty (GL_RBTREEHASH_LIST,
|
||||||
(gl_listelement_equals_fn) ssb_equals,
|
(gl_listelement_equals_fn) ssb_equals,
|
||||||
@@ -1094,7 +1146,7 @@ unifying_example (state_item_number itm1,
|
|||||||
const state_item *si1src = parse_state_head (ps1);
|
const state_item *si1src = parse_state_head (ps1);
|
||||||
const state_item *si2src = parse_state_head (ps2);
|
const state_item *si2src = parse_state_head (ps2);
|
||||||
if (item_rule (si1src->item)->lhs == item_rule (si2src->item)->lhs
|
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
|
// Stage 4: both paths share a prefix
|
||||||
derivation *d1 = parse_state_derivation (ps1);
|
derivation *d1 = parse_state_derivation (ps1);
|
||||||
@@ -1104,7 +1156,7 @@ unifying_example (state_item_number itm1,
|
|||||||
{
|
{
|
||||||
// Once we have two derivations for the same symbol,
|
// Once we have two derivations for the same symbol,
|
||||||
// we've found a unifying counterexample.
|
// 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 (d1);
|
||||||
derivation_retain (d2);
|
derivation_retain (d2);
|
||||||
goto cex_search_end;
|
goto cex_search_end;
|
||||||
@@ -1142,7 +1194,7 @@ cex_search_end:;
|
|||||||
// If a search state from Stage 3 is available, use it
|
// If a search state from Stage 3 is available, use it
|
||||||
// to construct a more compact nonunifying counterexample.
|
// to construct a more compact nonunifying counterexample.
|
||||||
if (stage3result)
|
if (stage3result)
|
||||||
cex = complete_diverging_examples (stage3result, next_sym);
|
cex = complete_diverging_examples (stage3result, next_sym, shift_reduce);
|
||||||
// Otherwise, construct a nonunifying counterexample that
|
// Otherwise, construct a nonunifying counterexample that
|
||||||
// begins from the start state using the shortest
|
// begins from the start state using the shortest
|
||||||
// lookahead-sensitive path to the reduce item.
|
// lookahead-sensitive path to the reduce item.
|
||||||
@@ -1190,7 +1242,7 @@ counterexample_report (state_item_number itm1, state_item_number itm2,
|
|||||||
{
|
{
|
||||||
// Compute the shortest lookahead-sensitive path and associated sets of
|
// Compute the shortest lookahead-sensitive path and associated sets of
|
||||||
// parser states.
|
// 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;
|
bool reduce_prod_reached = false;
|
||||||
const rule *reduce_rule = item_rule (state_items[itm1].item);
|
const rule *reduce_rule = item_rule (state_items[itm1].item);
|
||||||
|
|
||||||
@@ -1219,14 +1271,24 @@ counterexample_report (state_item_number itm1, state_item_number itm2,
|
|||||||
free_counterexample (cex);
|
free_counterexample (cex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ITM1 denotes a shift, ITM2 a reduce.
|
||||||
static void
|
static void
|
||||||
counterexample_report_shift_reduce (state_item_number itm1, state_item_number itm2,
|
counterexample_report_shift_reduce (state_item_number itm1, state_item_number itm2,
|
||||||
symbol_number next_sym,
|
symbol_number next_sym,
|
||||||
FILE *out, const char *prefix)
|
FILE *out, const char *prefix)
|
||||||
{
|
{
|
||||||
fputs (prefix, out);
|
if (out == stderr)
|
||||||
fprintf (out, _("Shift/reduce conflict on token %s:\n"), symbols[next_sym]->tag);
|
complain (NULL, Wcounterexamples,
|
||||||
if (*prefix)
|
_("shift/reduce conflict on token %s"), symbols[next_sym]->tag);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fputs (prefix, out);
|
||||||
|
fprintf (out, _("shift/reduce conflict on token %s"), symbols[next_sym]->tag);
|
||||||
|
fprintf (out, "%s\n", _(":"));
|
||||||
|
}
|
||||||
|
// In the report, print the items.
|
||||||
|
if (out != stderr || trace_flag & trace_cex)
|
||||||
{
|
{
|
||||||
print_state_item (&state_items[itm1], out, prefix);
|
print_state_item (&state_items[itm1], out, prefix);
|
||||||
print_state_item (&state_items[itm2], out, prefix);
|
print_state_item (&state_items[itm2], out, prefix);
|
||||||
@@ -1240,32 +1302,49 @@ counterexample_report_reduce_reduce (state_item_number itm1, state_item_number i
|
|||||||
FILE *out, const char *prefix)
|
FILE *out, const char *prefix)
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
fputs (prefix, out);
|
struct obstack obstack;
|
||||||
fputs (ngettext ("Reduce/reduce conflict on token",
|
obstack_init (&obstack);
|
||||||
"Reduce/reduce conflict on tokens",
|
|
||||||
bitset_count (conflict_syms)), out);
|
|
||||||
bitset_iterator biter;
|
bitset_iterator biter;
|
||||||
state_item_number sym;
|
state_item_number sym;
|
||||||
const char *sep = " ";
|
const char *sep = "";
|
||||||
BITSET_FOR_EACH (biter, conflict_syms, sym, 0)
|
BITSET_FOR_EACH (biter, conflict_syms, sym, 0)
|
||||||
{
|
{
|
||||||
fprintf (out, "%s%s", sep, symbols[sym]->tag);
|
obstack_printf (&obstack, "%s%s", sep, symbols[sym]->tag);
|
||||||
sep = ", ";
|
sep = ", ";
|
||||||
}
|
}
|
||||||
fputs (_(":\n"), out);
|
char *tokens = obstack_finish0 (&obstack);
|
||||||
|
if (out == stderr)
|
||||||
|
complain (NULL, Wcounterexamples,
|
||||||
|
ngettext ("reduce/reduce conflict on token %s",
|
||||||
|
"reduce/reduce conflict on tokens %s",
|
||||||
|
bitset_count (conflict_syms)),
|
||||||
|
tokens);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fputs (prefix, out);
|
||||||
|
fprintf (out,
|
||||||
|
ngettext ("reduce/reduce conflict on token %s",
|
||||||
|
"reduce/reduce conflict on tokens %s",
|
||||||
|
bitset_count (conflict_syms)),
|
||||||
|
tokens);
|
||||||
|
fprintf (out, "%s\n", _(":"));
|
||||||
|
}
|
||||||
|
obstack_free (&obstack, NULL);
|
||||||
}
|
}
|
||||||
if (*prefix)
|
// In the report, print the items.
|
||||||
|
if (out != stderr || trace_flag & trace_cex)
|
||||||
{
|
{
|
||||||
print_state_item (&state_items[itm1], out, prefix);
|
print_state_item (&state_items[itm1], out, prefix);
|
||||||
print_state_item (&state_items[itm2], out, prefix);
|
print_state_item (&state_items[itm2], out, prefix);
|
||||||
}
|
}
|
||||||
counterexample_report (itm1, itm2, bitset_first (conflict_syms), false, out, prefix);
|
counterexample_report (itm1, itm2, bitset_first (conflict_syms),
|
||||||
|
false, out, prefix);
|
||||||
}
|
}
|
||||||
|
|
||||||
static state_item_number
|
static state_item_number
|
||||||
find_state_item_number (const rule *r, state_number sn)
|
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)
|
if (!SI_DISABLED (i)
|
||||||
&& item_number_as_rule_number (*state_items[i].item) == r->number)
|
&& item_number_as_rule_number (*state_items[i].item) == r->number)
|
||||||
return i;
|
return i;
|
||||||
@@ -1277,41 +1356,35 @@ counterexample_report_state (const state *s, FILE *out, const char *prefix)
|
|||||||
{
|
{
|
||||||
const state_number sn = s->number;
|
const state_number sn = s->number;
|
||||||
const reductions *reds = s->reductions;
|
const reductions *reds = s->reductions;
|
||||||
|
bitset lookaheads = bitset_create (ntokens, BITSET_FIXED);
|
||||||
for (int i = 0; i < reds->num; ++i)
|
for (int i = 0; i < reds->num; ++i)
|
||||||
{
|
{
|
||||||
const rule *r1 = reds->rules[i];
|
const rule *r1 = reds->rules[i];
|
||||||
const state_item_number c1 = find_state_item_number (r1, sn);
|
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)
|
for (state_item_number c2 = state_item_map[sn]; c2 < state_item_map[sn + 1]; ++c2)
|
||||||
if (!SI_DISABLED (j))
|
if (!SI_DISABLED (c2))
|
||||||
{
|
{
|
||||||
state_item *si = state_items + j;
|
item_number conf = *state_items[c2].item;
|
||||||
item_number conf = *si->item;
|
|
||||||
if (item_number_is_symbol_number (conf)
|
if (item_number_is_symbol_number (conf)
|
||||||
&& bitset_test (reds->lookahead_tokens[i], conf))
|
&& bitset_test (reds->lookaheads[i], conf))
|
||||||
counterexample_report_shift_reduce (c1, j, conf, out, prefix);
|
counterexample_report_shift_reduce (c1, c2, conf, out, prefix);
|
||||||
}
|
}
|
||||||
for (int j = i+1; j < reds->num; ++j)
|
for (int j = i+1; j < reds->num; ++j)
|
||||||
{
|
{
|
||||||
bitset conf = bitset_create (ntokens, BITSET_FIXED);
|
const rule *r2 = reds->rules[j];
|
||||||
bitset_intersection (conf,
|
// Conflicts: common lookaheads.
|
||||||
reds->lookahead_tokens[i],
|
bitset_intersection (lookaheads,
|
||||||
reds->lookahead_tokens[j]);
|
reds->lookaheads[i],
|
||||||
if (!bitset_empty_p (conf))
|
reds->lookaheads[j]);
|
||||||
{
|
if (!bitset_empty_p (lookaheads))
|
||||||
const rule *r2 = reds->rules[j];
|
for (state_item_number c2 = state_item_map[sn]; c2 < state_item_map[sn + 1]; ++c2)
|
||||||
for (int k = state_item_map[sn]; k < state_item_map[sn + 1]; ++k)
|
if (!SI_DISABLED (c2)
|
||||||
if (!SI_DISABLED (k))
|
&& item_rule (state_items[c2].item) == r2)
|
||||||
{
|
{
|
||||||
state_item *si = state_items + k;
|
counterexample_report_reduce_reduce (c1, c2, lookaheads, out, prefix);
|
||||||
const rule *r = item_rule (si->item);
|
break;
|
||||||
if (r == r2)
|
}
|
||||||
{
|
|
||||||
counterexample_report_reduce_reduce (c1, k, conf, out, prefix);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
bitset_free (conf);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
bitset_free (lookaheads);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,11 +20,17 @@
|
|||||||
#ifndef COUNTEREXAMPLE_H
|
#ifndef COUNTEREXAMPLE_H
|
||||||
# define COUNTEREXAMPLE_H
|
# define COUNTEREXAMPLE_H
|
||||||
|
|
||||||
# include "state-item.h"
|
# include "state.h"
|
||||||
|
|
||||||
|
// Init/deinit this module.
|
||||||
void counterexample_init (void);
|
void counterexample_init (void);
|
||||||
void counterexample_free (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 */
|
#endif /* COUNTEREXAMPLE_H */
|
||||||
|
|||||||
+272
-41
@@ -20,8 +20,11 @@
|
|||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
|
||||||
#include "derivation.h"
|
#include "derivation.h"
|
||||||
|
#include "glyphs.h"
|
||||||
|
|
||||||
|
#include <c-ctype.h>
|
||||||
#include <gl_linked_list.h>
|
#include <gl_linked_list.h>
|
||||||
|
#include <mbswidth.h>
|
||||||
|
|
||||||
#include "system.h"
|
#include "system.h"
|
||||||
#include "complain.h"
|
#include "complain.h"
|
||||||
@@ -29,11 +32,15 @@
|
|||||||
struct derivation
|
struct derivation
|
||||||
{
|
{
|
||||||
symbol_number sym;
|
symbol_number sym;
|
||||||
gl_list_t children;
|
derivation_list children;
|
||||||
int reference_count;
|
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 *
|
||||||
derivation_dot (void)
|
derivation_dot (void)
|
||||||
@@ -73,6 +80,7 @@ derivation_new (symbol_number sym, derivation_list children)
|
|||||||
deriv->sym = sym;
|
deriv->sym = sym;
|
||||||
deriv->children = children;
|
deriv->children = children;
|
||||||
deriv->reference_count = 0;
|
deriv->reference_count = 0;
|
||||||
|
deriv->color = -1;
|
||||||
return deriv;
|
return deriv;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -126,27 +134,242 @@ derivation_size (const derivation *deriv)
|
|||||||
return size;
|
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
|
static bool
|
||||||
derivation_print_impl (const derivation *deriv, FILE *f,
|
all_spaces (const char *s)
|
||||||
bool leaves_only,
|
{
|
||||||
int *counter, const char *prefix)
|
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, preceded 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)
|
if (deriv->children)
|
||||||
{
|
{
|
||||||
const symbol *sym = symbols[deriv->sym];
|
const symbol *sym = symbols[deriv->sym];
|
||||||
char style[20];
|
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;
|
++*counter;
|
||||||
begin_use_class (style, f);
|
char style[20];
|
||||||
|
snprintf (style, 20, "cex-%d", deriv->color);
|
||||||
|
begin_use_class (style, out);
|
||||||
|
|
||||||
if (!leaves_only)
|
if (!leaves_only)
|
||||||
{
|
{
|
||||||
fputs (prefix, f);
|
fputs (prefix, out);
|
||||||
begin_use_class ("cex-step", f);
|
begin_use_class ("cex-step", out);
|
||||||
fprintf (f, "%s ::=[ ", sym->tag);
|
fprintf (out, "%s %s [ ", sym->tag, arrow);
|
||||||
end_use_class ("cex-step", f);
|
end_use_class ("cex-step", out);
|
||||||
prefix = "";
|
prefix = "";
|
||||||
}
|
}
|
||||||
bool res = false;
|
bool res = false;
|
||||||
@@ -155,7 +378,8 @@ derivation_print_impl (const derivation *deriv, FILE *f,
|
|||||||
derivation_list_next (&it, &child);
|
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 = " ";
|
prefix = " ";
|
||||||
res = true;
|
res = true;
|
||||||
@@ -165,49 +389,56 @@ derivation_print_impl (const derivation *deriv, FILE *f,
|
|||||||
}
|
}
|
||||||
if (!leaves_only)
|
if (!leaves_only)
|
||||||
{
|
{
|
||||||
begin_use_class ("cex-step", f);
|
begin_use_class ("cex-step", out);
|
||||||
if (res)
|
if (res)
|
||||||
fputs (" ]", f);
|
fputs (" ]", out);
|
||||||
else
|
else
|
||||||
fputs ("]", f);
|
fputs ("]", out);
|
||||||
end_use_class ("cex-step", f);
|
end_use_class ("cex-step", out);
|
||||||
}
|
}
|
||||||
end_use_class (style, f);
|
end_use_class (style, out);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
else if (deriv == &d_dot)
|
else if (deriv == &d_dot)
|
||||||
{
|
{
|
||||||
fputs (prefix, f);
|
fputs (prefix, out);
|
||||||
begin_use_class ("cex-dot", f);
|
begin_use_class ("cex-dot", out);
|
||||||
print_dot (f);
|
fputs (dot, out);
|
||||||
end_use_class ("cex-dot", f);
|
end_use_class ("cex-dot", out);
|
||||||
}
|
}
|
||||||
else // leaf.
|
else // leaf.
|
||||||
{
|
{
|
||||||
fputs (prefix, f);
|
fputs (prefix, out);
|
||||||
const symbol *sym = symbols[deriv->sym];
|
const symbol *sym = symbols[deriv->sym];
|
||||||
begin_use_class ("cex-leaf", f);
|
begin_use_class ("cex-leaf", out);
|
||||||
fprintf (f, "%s", sym->tag);
|
fprintf (out, "%s", sym->tag);
|
||||||
end_use_class ("cex-leaf", f);
|
end_use_class ("cex-leaf", out);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
derivation_print_flat (const derivation *deriv, FILE *out, const char *prefix)
|
||||||
|
{
|
||||||
|
int counter = 0;
|
||||||
|
fputs (prefix, out);
|
||||||
|
derivation_print_flat_impl ((derivation *)deriv, out, false, &counter, "");
|
||||||
|
fputc ('\n', out);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
derivation_print_leaves (const derivation *deriv, FILE *out)
|
||||||
|
{
|
||||||
|
int counter = 0;
|
||||||
|
derivation_print_flat_impl ((derivation *)deriv, out, true, &counter, "");
|
||||||
|
fputc ('\n', out);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
derivation_print (const derivation *deriv, FILE *out, const char *prefix)
|
derivation_print (const derivation *deriv, FILE *out, const char *prefix)
|
||||||
{
|
{
|
||||||
int counter = 0;
|
if (getenv ("YYFLAT"))
|
||||||
fputs (prefix, out);
|
derivation_print_flat (deriv, out, prefix);
|
||||||
derivation_print_impl (deriv, out, false, &counter, "");
|
else
|
||||||
fputc ('\n', out);
|
derivation_print_tree (deriv, out, prefix);
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
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, "");
|
|
||||||
fputc ('\n', out);
|
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-1
@@ -60,12 +60,15 @@ static inline derivation *derivation_new_leaf (symbol_number sym)
|
|||||||
{
|
{
|
||||||
return derivation_new (sym, NULL);
|
return derivation_new (sym, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Number of symbols.
|
||||||
size_t derivation_size (const derivation *deriv);
|
size_t derivation_size (const derivation *deriv);
|
||||||
void derivation_print (const derivation *deriv, FILE *out, const char *prefix);
|
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_print_leaves (const derivation *deriv, FILE *out);
|
||||||
void derivation_free (derivation *deriv);
|
void derivation_free (derivation *deriv);
|
||||||
void derivation_retain (derivation *deriv);
|
void derivation_retain (derivation *deriv);
|
||||||
|
|
||||||
|
// A derivation denoting the position of the dot.
|
||||||
derivation *derivation_dot (void);
|
derivation *derivation_dot (void);
|
||||||
|
|
||||||
#endif /* DERIVATION_H */
|
#endif /* DERIVATION_H */
|
||||||
|
|||||||
+1
-1
@@ -221,7 +221,7 @@ static const argmatch_report_arg argmatch_report_args[] =
|
|||||||
{ "none", report_none },
|
{ "none", report_none },
|
||||||
{ "states", report_states },
|
{ "states", report_states },
|
||||||
{ "itemsets", report_states | report_itemsets },
|
{ "itemsets", report_states | report_itemsets },
|
||||||
{ "lookaheads", report_states | report_lookahead_tokens },
|
{ "lookaheads", report_states | report_lookaheads },
|
||||||
{ "solved", report_states | report_solved_conflicts },
|
{ "solved", report_states | report_solved_conflicts },
|
||||||
{ "counterexamples", report_cex },
|
{ "counterexamples", report_cex },
|
||||||
{ "cex", report_cex },
|
{ "cex", report_cex },
|
||||||
|
|||||||
+1
-1
@@ -77,7 +77,7 @@ enum report
|
|||||||
report_none = 0,
|
report_none = 0,
|
||||||
report_states = 1 << 0,
|
report_states = 1 << 0,
|
||||||
report_itemsets = 1 << 1,
|
report_itemsets = 1 << 1,
|
||||||
report_lookahead_tokens = 1 << 2,
|
report_lookaheads = 1 << 2,
|
||||||
report_solved_conflicts = 1 << 3,
|
report_solved_conflicts = 1 << 3,
|
||||||
report_cex = 1 << 4,
|
report_cex = 1 << 4,
|
||||||
report_all = ~0
|
report_all = ~0
|
||||||
|
|||||||
@@ -0,0 +1,93 @@
|
|||||||
|
/* 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>
|
||||||
|
|
||||||
|
|
||||||
|
glyph_buffer_t arrow;
|
||||||
|
int arrow_width;
|
||||||
|
|
||||||
|
glyph_buffer_t down_arrow;
|
||||||
|
int down_arrow_width;
|
||||||
|
|
||||||
|
glyph_buffer_t dot;
|
||||||
|
int dot_width;
|
||||||
|
|
||||||
|
glyph_buffer_t empty;
|
||||||
|
int empty_width;
|
||||||
|
|
||||||
|
const char *derivation_separator = " ";
|
||||||
|
int derivation_separator_width = 1;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
glyph_buffer_t *pbuf;
|
||||||
|
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->pbuf);
|
||||||
|
*stpncpy (*arg->pbuf, 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->pbuf);
|
||||||
|
strcpy (*arg->pbuf, arg->fallback);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
glyph_set (glyph_buffer_t *glyph, int *width,
|
||||||
|
unsigned code, const char *fallback)
|
||||||
|
{
|
||||||
|
callback_arg_t arg = { glyph, fallback };
|
||||||
|
int res = unicode_to_mb (code, on_success, on_failure, &arg);
|
||||||
|
*width = mbswidth (*glyph, 0);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
glyphs_init (void)
|
||||||
|
{
|
||||||
|
glyph_set (&arrow, &arrow_width, 0x2192, "->");
|
||||||
|
glyph_set (&dot, &dot_width, 0x2022, ".");
|
||||||
|
glyph_set (&down_arrow, &down_arrow_width, 0x21b3, "`->");
|
||||||
|
glyph_set (&empty, &empty_width, 0x03b5, "%empty");
|
||||||
|
|
||||||
|
strncat (down_arrow, " ", sizeof down_arrow - strlen (down_arrow) - 1);
|
||||||
|
down_arrow_width += 1;
|
||||||
|
}
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
/* 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);
|
||||||
|
|
||||||
|
/* In gnulib/lib/unicodeio.h unicode_to_mb uses a buffer of 25 bytes.
|
||||||
|
In down_arrow, we append one space. */
|
||||||
|
typedef char glyph_buffer_t[26];
|
||||||
|
|
||||||
|
/* "→", separates the lhs of a rule from its rhs. */
|
||||||
|
extern glyph_buffer_t arrow;
|
||||||
|
extern int arrow_width;
|
||||||
|
|
||||||
|
/* "•", a point in an item (aka, a dotted rule). */
|
||||||
|
extern glyph_buffer_t dot;
|
||||||
|
extern int dot_width;
|
||||||
|
|
||||||
|
/* "↳ ", below an lhs to announce the rhs. */
|
||||||
|
extern glyph_buffer_t down_arrow;
|
||||||
|
extern int down_arrow_width;
|
||||||
|
|
||||||
|
/* "ε", an empty rhs. */
|
||||||
|
extern glyph_buffer_t 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 "complain.h"
|
||||||
#include "getargs.h"
|
#include "getargs.h"
|
||||||
|
#include "glyphs.h"
|
||||||
#include "gram.h"
|
#include "gram.h"
|
||||||
#include "print-xml.h"
|
#include "print-xml.h"
|
||||||
#include "reader.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++)
|
for (item_number *sp = r->rhs; sp < item; sp++)
|
||||||
fprintf (out, " %s", symbols[*sp]->tag);
|
fprintf (out, " %s", symbols[*sp]->tag);
|
||||||
putc (' ', out);
|
fprintf (out, " %s", dot);
|
||||||
print_dot (out);
|
|
||||||
if (0 <= *r->rhs)
|
if (0 <= *r->rhs)
|
||||||
for (item_number *sp = item; 0 <= *sp; ++sp)
|
for (item_number *sp = item; 0 <= *sp; ++sp)
|
||||||
fprintf (out, " %s", symbols[*sp]->tag);
|
fprintf (out, " %s", symbols[*sp]->tag);
|
||||||
|
|||||||
-21
@@ -103,8 +103,6 @@
|
|||||||
|
|
||||||
# include "system.h"
|
# include "system.h"
|
||||||
|
|
||||||
# include <unicodeio.h>
|
|
||||||
|
|
||||||
# include "location.h"
|
# include "location.h"
|
||||||
# include "symtab.h"
|
# include "symtab.h"
|
||||||
|
|
||||||
@@ -217,25 +215,6 @@ typedef struct
|
|||||||
extern rule *rules;
|
extern rule *rules;
|
||||||
extern rule_number nrules;
|
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. */
|
/* Get the rule associated to this item. ITEM points inside RITEM. */
|
||||||
static inline rule const *
|
static inline rule const *
|
||||||
item_rule (item_number const *item)
|
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;
|
bool firste = true;
|
||||||
rule_number ruleno = reds->rules[j]->number;
|
rule_number ruleno = reds->rules[j]->number;
|
||||||
|
|
||||||
if (reds->lookahead_tokens)
|
if (reds->lookaheads)
|
||||||
for (int i = 0; i < ntokens; i++)
|
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))
|
if (bitset_test (no_reduce_set, i))
|
||||||
firstd = print_token (&dout, firstd, symbols[i]->tag);
|
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];
|
rule *this_rule = node->state->reductions->rules[r];
|
||||||
bitset lookahead_set =
|
bitset lookahead_set =
|
||||||
node->state->reductions->lookahead_tokens[r];
|
node->state->reductions->lookaheads[r];
|
||||||
if (item_number_is_rule_number (*this_rule->rhs))
|
if (item_number_is_rule_number (*this_rule->rhs))
|
||||||
ielr_compute_goto_follow_set (follow_kernel_items,
|
ielr_compute_goto_follow_set (follow_kernel_items,
|
||||||
always_follows, node,
|
always_follows, node,
|
||||||
|
|||||||
+24
-27
@@ -256,9 +256,9 @@ lookback_find_state (int lookback_index)
|
|||||||
state *res = NULL;
|
state *res = NULL;
|
||||||
for (int j = 0; j < nstates; ++j)
|
for (int j = 0; j < nstates; ++j)
|
||||||
if (states[j]->reductions
|
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. */
|
/* Went too far. */
|
||||||
break;
|
break;
|
||||||
else
|
else
|
||||||
@@ -280,7 +280,7 @@ lookback_print (FILE *out)
|
|||||||
{
|
{
|
||||||
fprintf (out, " %3d = ", i);
|
fprintf (out, " %3d = ", i);
|
||||||
const state *s = lookback_find_state (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];
|
const rule *r = s->reductions->rules[rnum];
|
||||||
fprintf (out, "(%3d, ", s->number);
|
fprintf (out, "(%3d, ", s->number);
|
||||||
rule_print (r, NULL, out);
|
rule_print (r, NULL, out);
|
||||||
@@ -305,7 +305,7 @@ static void
|
|||||||
add_lookback_edge (state *s, rule const *r, goto_number gotono)
|
add_lookback_edge (state *s, rule const *r, goto_number gotono)
|
||||||
{
|
{
|
||||||
int ri = state_reduction_find (s, r);
|
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]);
|
lookback[idx] = goto_list_new (gotono, lookback[idx]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -421,7 +421,7 @@ compute_follows (void)
|
|||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
compute_lookahead_tokens (void)
|
compute_lookaheads (void)
|
||||||
{
|
{
|
||||||
if (trace_flag & trace_automaton)
|
if (trace_flag & trace_automaton)
|
||||||
lookback_print (stderr);
|
lookback_print (stderr);
|
||||||
@@ -437,13 +437,12 @@ compute_lookahead_tokens (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*----------------------------------------------------.
|
/*------------------------------------------------------.
|
||||||
| Count the number of lookahead tokens required for S |
|
| Count the number of lookahead tokens required for S. |
|
||||||
| (N_LOOKAHEAD_TOKENS member). |
|
`------------------------------------------------------*/
|
||||||
`----------------------------------------------------*/
|
|
||||||
|
|
||||||
static int
|
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 reductions *reds = s->reductions;
|
||||||
const transitions *trans = s->transitions;
|
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
|
void
|
||||||
initialize_LA (void)
|
initialize_LA (void)
|
||||||
@@ -491,25 +490,23 @@ initialize_LA (void)
|
|||||||
/* Compute the total number of reductions requiring a lookahead. */
|
/* Compute the total number of reductions requiring a lookahead. */
|
||||||
nLA = 0;
|
nLA = 0;
|
||||||
for (state_number i = 0; i < nstates; ++i)
|
for (state_number i = 0; i < nstates; ++i)
|
||||||
nLA +=
|
nLA += state_lookaheads_count (states[i],
|
||||||
state_lookahead_tokens_count (states[i],
|
default_reduction_only_for_accept);
|
||||||
default_reduction_only_for_accept);
|
|
||||||
/* Avoid having to special case 0. */
|
/* Avoid having to special case 0. */
|
||||||
if (!nLA)
|
if (!nLA)
|
||||||
nLA = 1;
|
nLA = 1;
|
||||||
|
|
||||||
bitsetv pLA = LA = bitsetv_create (nLA, ntokens, BITSET_FIXED);
|
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. */
|
require lookahead tokens. */
|
||||||
for (state_number i = 0; i < nstates; ++i)
|
for (state_number i = 0; i < nstates; ++i)
|
||||||
{
|
{
|
||||||
int count =
|
int count = state_lookaheads_count (states[i],
|
||||||
state_lookahead_tokens_count (states[i],
|
default_reduction_only_for_accept);
|
||||||
default_reduction_only_for_accept);
|
|
||||||
if (count)
|
if (count)
|
||||||
{
|
{
|
||||||
states[i]->reductions->lookahead_tokens = pLA;
|
states[i]->reductions->lookaheads = pLA;
|
||||||
pLA += count;
|
pLA += count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -521,7 +518,7 @@ initialize_LA (void)
|
|||||||
`---------------------------------------------*/
|
`---------------------------------------------*/
|
||||||
|
|
||||||
static void
|
static void
|
||||||
lookahead_tokens_print (FILE *out)
|
lookaheads_print (FILE *out)
|
||||||
{
|
{
|
||||||
fputs ("Lookaheads:\n", out);
|
fputs ("Lookaheads:\n", out);
|
||||||
for (state_number i = 0; i < nstates; ++i)
|
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)
|
for (int j = 0; j < reds->num; ++j)
|
||||||
{
|
{
|
||||||
fprintf (out, " rule %d:", reds->rules[j]->number);
|
fprintf (out, " rule %d:", reds->rules[j]->number);
|
||||||
if (reds->lookahead_tokens)
|
if (reds->lookaheads)
|
||||||
{
|
{
|
||||||
bitset_iterator iter;
|
bitset_iterator iter;
|
||||||
int k;
|
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);
|
fprintf (out, " %s", symbols[k]->tag);
|
||||||
}
|
}
|
||||||
fputc ('\n', out);
|
fputc ('\n', out);
|
||||||
@@ -564,10 +561,10 @@ lalr (void)
|
|||||||
lookback = xcalloc (nLA, sizeof *lookback);
|
lookback = xcalloc (nLA, sizeof *lookback);
|
||||||
build_relations ();
|
build_relations ();
|
||||||
compute_follows ();
|
compute_follows ();
|
||||||
compute_lookahead_tokens ();
|
compute_lookaheads ();
|
||||||
|
|
||||||
if (trace_flag & trace_sets)
|
if (trace_flag & trace_sets)
|
||||||
lookahead_tokens_print (stderr);
|
lookaheads_print (stderr);
|
||||||
if (trace_flag & trace_automaton)
|
if (trace_flag & trace_automaton)
|
||||||
{
|
{
|
||||||
begin_use_class ("trace0", stderr);
|
begin_use_class ("trace0", stderr);
|
||||||
@@ -614,6 +611,6 @@ void
|
|||||||
lalr_free (void)
|
lalr_free (void)
|
||||||
{
|
{
|
||||||
for (state_number s = 0; s < nstates; ++s)
|
for (state_number s = 0; s < nstates; ++s)
|
||||||
states[s]->reductions->lookahead_tokens = NULL;
|
states[s]->reductions->lookaheads = NULL;
|
||||||
bitsetv_free (LA);
|
bitsetv_free (LA);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,6 +53,8 @@ src_bison_SOURCES = \
|
|||||||
src/flex-scanner.h \
|
src/flex-scanner.h \
|
||||||
src/getargs.c \
|
src/getargs.c \
|
||||||
src/getargs.h \
|
src/getargs.h \
|
||||||
|
src/glyphs.c \
|
||||||
|
src/glyphs.h \
|
||||||
src/gram.c \
|
src/gram.c \
|
||||||
src/gram.h \
|
src/gram.h \
|
||||||
src/graphviz.c \
|
src/graphviz.c \
|
||||||
|
|||||||
+13
-11
@@ -82,8 +82,10 @@ lssi_comparator (lssi *s1, lssi *s2)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef gl_list_t lssi_list;
|
||||||
|
|
||||||
static inline bool
|
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))
|
if (hash_lookup (visited, sn))
|
||||||
{
|
{
|
||||||
@@ -100,7 +102,7 @@ append_lssi (lssi *sn, Hash_table *visited, gl_list_t queue)
|
|||||||
static void
|
static void
|
||||||
lssi_print (lssi *l)
|
lssi_print (lssi *l)
|
||||||
{
|
{
|
||||||
print_state_item (state_items + l->si, stdout);
|
print_state_item (&state_items[l->si], stdout);
|
||||||
if (l->lookahead)
|
if (l->lookahead)
|
||||||
{
|
{
|
||||||
printf ("FOLLOWL = { ");
|
printf ("FOLLOWL = { ");
|
||||||
@@ -121,7 +123,7 @@ static bitset
|
|||||||
eligible_state_items (state_item *target)
|
eligible_state_items (state_item *target)
|
||||||
{
|
{
|
||||||
bitset result = bitset_create (nstate_items, BITSET_FIXED);
|
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,
|
gl_list_create (GL_LINKED_LIST, NULL, NULL, NULL, true, 1,
|
||||||
(const void **) &target);
|
(const void **) &target);
|
||||||
while (gl_list_size (queue) > 0)
|
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
|
* this conflict. If optimized is true, only consider parser states
|
||||||
* that can reach the conflict state.
|
* that can reach the conflict state.
|
||||||
*/
|
*/
|
||||||
gl_list_t
|
state_item_list
|
||||||
shortest_path_from_start (state_item_number target, symbol_number next_sym)
|
shortest_path_from_start (state_item_number target, symbol_number next_sym)
|
||||||
{
|
{
|
||||||
bitset eligible = eligible_state_items (&state_items[target]);
|
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 il = bitset_create (nsyms, BITSET_FIXED);
|
||||||
bitset_set (il, 0);
|
bitset_set (il, 0);
|
||||||
lssi *init = new_lssi (0, NULL, il, true);
|
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);
|
NULL, true);
|
||||||
append_lssi (init, visited, queue);
|
append_lssi (init, visited, queue);
|
||||||
// breadth-first search
|
// breadth-first search
|
||||||
@@ -175,7 +177,7 @@ shortest_path_from_start (state_item_number target, symbol_number next_sym)
|
|||||||
finished = true;
|
finished = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
state_item *si = state_items + last;
|
state_item *si = &state_items[last];
|
||||||
// Transitions don't change follow_L
|
// Transitions don't change follow_L
|
||||||
if (si->trans >= 0)
|
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);
|
fputs ("Cannot find shortest path to conflict state.", stderr);
|
||||||
abort ();
|
abort ();
|
||||||
}
|
}
|
||||||
gl_list_t res =
|
state_item_list res =
|
||||||
gl_list_create_empty (GL_LINKED_LIST, NULL, NULL, NULL, true);
|
gl_list_create_empty (GL_LINKED_LIST, NULL, NULL, NULL, true);
|
||||||
for (lssi *sn = n; sn != NULL; sn = sn->parent)
|
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);
|
hash_free (visited);
|
||||||
gl_list_free (queue);
|
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
|
* Compute a list of state_items that have a production to n with respect
|
||||||
* to its lookahead
|
* to its lookahead
|
||||||
*/
|
*/
|
||||||
gl_list_t
|
state_item_list
|
||||||
lssi_reverse_production (const state_item *si, bitset lookahead)
|
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);
|
gl_list_create_empty (GL_LINKED_LIST, NULL, NULL, NULL, true);
|
||||||
if (SI_TRANSITION (si))
|
if (SI_TRANSITION (si))
|
||||||
return result;
|
return result;
|
||||||
@@ -320,7 +322,7 @@ lssi_reverse_production (const state_item *si, bitset lookahead)
|
|||||||
state_item_number sin;
|
state_item_number sin;
|
||||||
BITSET_FOR_EACH (biter, si->revs, sin, 0)
|
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))
|
if (!production_allowed (prevsi, si))
|
||||||
continue;
|
continue;
|
||||||
bitset prev_lookahead = prevsi->lookahead;
|
bitset prev_lookahead = prevsi->lookahead;
|
||||||
|
|||||||
+3
-3
@@ -32,8 +32,8 @@
|
|||||||
* find shortest lookahead-sensitive path of state-items to target such that
|
* 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.
|
* next_sym is in the follow_L set of target in that position.
|
||||||
*/
|
*/
|
||||||
gl_list_t shortest_path_from_start (state_item_number target,
|
state_item_list shortest_path_from_start (state_item_number target,
|
||||||
symbol_number next_sym);
|
symbol_number next_sym);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine if the given terminal is in the given symbol set or can begin
|
* 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
|
* to this state-item such that the resulting possible lookahead symbols are
|
||||||
* as given.
|
* 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 */
|
#endif /* LSSI_H */
|
||||||
|
|||||||
@@ -38,6 +38,7 @@
|
|||||||
#include "files.h"
|
#include "files.h"
|
||||||
#include "fixits.h"
|
#include "fixits.h"
|
||||||
#include "getargs.h"
|
#include "getargs.h"
|
||||||
|
#include "glyphs.h"
|
||||||
#include "gram.h"
|
#include "gram.h"
|
||||||
#include "ielr.h"
|
#include "ielr.h"
|
||||||
#include "lalr.h"
|
#include "lalr.h"
|
||||||
@@ -85,6 +86,7 @@ main (int argc, char *argv[])
|
|||||||
|
|
||||||
atexit (close_stdout);
|
atexit (close_stdout);
|
||||||
|
|
||||||
|
glyphs_init ();
|
||||||
uniqstrs_new ();
|
uniqstrs_new ();
|
||||||
muscle_init ();
|
muscle_init ();
|
||||||
complain_init ();
|
complain_init ();
|
||||||
|
|||||||
+32
-34
@@ -34,7 +34,7 @@ typedef struct parse_state
|
|||||||
struct si_chunk
|
struct si_chunk
|
||||||
{
|
{
|
||||||
// elements newly added in this chunk
|
// elements newly added in this chunk
|
||||||
gl_list_t contents;
|
state_item_list contents;
|
||||||
// properties of the linked list this chunk represents
|
// properties of the linked list this chunk represents
|
||||||
const state_item *head_elt;
|
const state_item *head_elt;
|
||||||
const state_item *tail_elt;
|
const state_item *tail_elt;
|
||||||
@@ -135,7 +135,7 @@ static parse_state *
|
|||||||
copy_parse_state (bool prepend, parse_state *parent)
|
copy_parse_state (bool prepend, parse_state *parent)
|
||||||
{
|
{
|
||||||
parse_state *res = xmalloc (sizeof *res);
|
parse_state *res = xmalloc (sizeof *res);
|
||||||
memcpy (res, parent, sizeof *res);
|
*res = *parent;
|
||||||
res->state_items.contents
|
res->state_items.contents
|
||||||
= gl_list_create_empty (GL_LINKED_LIST, NULL, NULL, NULL, true);
|
= gl_list_create_empty (GL_LINKED_LIST, NULL, NULL, NULL, true);
|
||||||
res->derivs.contents = derivation_list_new ();
|
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)
|
while (root_ps->parent)
|
||||||
root_ps = 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;
|
int count = 0;
|
||||||
|
|
||||||
state_item *last = NULL;
|
state_item *last = NULL;
|
||||||
@@ -337,19 +337,17 @@ parser_pop (parse_state *ps, int deriv_index,
|
|||||||
for (int i = 0; i < 4; ++i)
|
for (int i = 0; i < 4; ++i)
|
||||||
chunks[i] = gl_list_create_empty (GL_LINKED_LIST, NULL, NULL, NULL, true);
|
chunks[i] = gl_list_create_empty (GL_LINKED_LIST, NULL, NULL, NULL, true);
|
||||||
for (parse_state *pn = ps; pn != NULL; pn = pn->parent)
|
for (parse_state *pn = ps; pn != NULL; pn = pn->parent)
|
||||||
{
|
if (pn->prepend)
|
||||||
if (pn->prepend)
|
{
|
||||||
{
|
gl_list_add_last (chunks[0], pn->state_items.contents);
|
||||||
gl_list_add_last (chunks[0], pn->state_items.contents);
|
gl_list_add_last (chunks[2], pn->derivs.contents);
|
||||||
gl_list_add_last (chunks[2], pn->derivs.contents);
|
}
|
||||||
}
|
else
|
||||||
else
|
{
|
||||||
{
|
gl_list_add_first (chunks[1], pn->state_items.contents);
|
||||||
gl_list_add_first (chunks[1], pn->state_items.contents);
|
gl_list_add_first (chunks[3], pn->derivs.contents);
|
||||||
gl_list_add_first (chunks[3], pn->derivs.contents);
|
}
|
||||||
}
|
derivation_list popped_derivs = derivation_list_new ();
|
||||||
}
|
|
||||||
gl_list_t popped_derivs = derivation_list_new ();
|
|
||||||
gl_list_t ret_chunks[4] = { ret->state_items.contents, NULL,
|
gl_list_t ret_chunks[4] = { ret->state_items.contents, NULL,
|
||||||
ret->derivs.contents, popped_derivs
|
ret->derivs.contents, popped_derivs
|
||||||
};
|
};
|
||||||
@@ -390,7 +388,7 @@ parser_pop (parse_state *ps, int deriv_index,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
parse_state_lists (parse_state *ps, gl_list_t *sitems,
|
parse_state_lists (parse_state *ps, state_item_list *sitems,
|
||||||
derivation_list *derivs)
|
derivation_list *derivs)
|
||||||
{
|
{
|
||||||
parse_state *temp = empty_parse_state ();
|
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;
|
for (state_item_number sin = si->trans; sin != -1;
|
||||||
prev_sin = sin, sin = state_items[sin].trans)
|
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);
|
symbol_number sp = item_number_as_symbol_number (*psi->item);
|
||||||
if (ISTOKEN (sp) || !nullable[sp - ntokens])
|
if (ISTOKEN (sp) || !nullable[sp - ntokens])
|
||||||
break;
|
break;
|
||||||
|
|
||||||
state_item *nsi = state_items + sin;
|
state_item *nsi = &state_items[sin];
|
||||||
current_ps = copy_parse_state (false, current_ps);
|
current_ps = copy_parse_state (false, current_ps);
|
||||||
ps_si_append (current_ps, nsi);
|
ps_si_append (current_ps, nsi);
|
||||||
ps_derivs_append (current_ps, derivation_new (sp, derivation_list_new ()));
|
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)
|
simulate_transition (parse_state *ps)
|
||||||
{
|
{
|
||||||
const state_item *si = ps->state_items.tail_elt;
|
const state_item *si = ps->state_items.tail_elt;
|
||||||
symbol_number sym = item_number_as_symbol_number (*si->item);
|
symbol_number sym = item_number_as_symbol_number (*si->item);
|
||||||
// Transition on the same next symbol, taking nullable
|
// Transition on the same next symbol, taking nullable
|
||||||
// symbols into account.
|
// 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;
|
state_item_number si_next = si->trans;
|
||||||
// check for disabled transition, shouldn't happen
|
// check for disabled transition, shouldn't happen
|
||||||
// as any state_items that lead to these should be
|
// as any state_items that lead to these should be
|
||||||
@@ -446,11 +444,11 @@ simulate_transition (parse_state *ps)
|
|||||||
if (si_next < 0)
|
if (si_next < 0)
|
||||||
return result;
|
return result;
|
||||||
parse_state *next_ps = copy_parse_state (false, ps);
|
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));
|
ps_derivs_append (next_ps, derivation_new_leaf (sym));
|
||||||
parse_state_list_append (result, next_ps);
|
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;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -473,10 +471,10 @@ compatible (symbol_number sym1, symbol_number sym2)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
gl_list_t
|
parse_state_list
|
||||||
simulate_production (parse_state *ps, symbol_number compat_sym)
|
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);
|
const state_item *si = parse_state_tail (ps);
|
||||||
if (si->prods)
|
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
|
// Take production step only if lhs is not nullable and
|
||||||
// if first rhs symbol is compatible with compat_sym
|
// 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;
|
item_number *itm1 = next->item;
|
||||||
if (!compatible (*itm1, compat_sym) || !production_allowed (si, next))
|
if (!compatible (*itm1, compat_sym) || !production_allowed (si, next))
|
||||||
continue;
|
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
|
// 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
|
// item associated with ps's conflict. symbol_set is a lookahead set this
|
||||||
// reduction must be compatible with
|
// reduction must be compatible with
|
||||||
gl_list_t
|
parse_state_list
|
||||||
simulate_reduction (parse_state *ps, int rule_len, bitset symbol_set)
|
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 s_size = ps->state_items.total_size;
|
||||||
int d_size = ps->derivs.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)
|
if (s_size != rule_len + 1)
|
||||||
{
|
{
|
||||||
state_item *tail = (state_item *) new_root->state_items.tail_elt;
|
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);
|
parse_state_list_append (result, new_root);
|
||||||
}
|
}
|
||||||
else
|
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
|
// The head state_item is a production item, so we need to prepend
|
||||||
// with possible source state-items.
|
// with possible source state-items.
|
||||||
const state_item *head = ps->state_items.head_elt;
|
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.
|
// TODO: better understand what causes this case.
|
||||||
if (gl_list_size (prev) == 0)
|
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);
|
copy = copy_parse_state (false, copy);
|
||||||
struct si_chunk *sis = ©->state_items;
|
struct si_chunk *sis = ©->state_items;
|
||||||
const state_item *tail = sis->tail_elt;
|
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);
|
parse_state_list_append (result, copy);
|
||||||
nullable_closure (copy, (state_item *) sis->tail_elt, result);
|
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;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
gl_list_t
|
parse_state_list
|
||||||
parser_prepend (parse_state *ps)
|
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;
|
const state_item *head = ps->state_items.head_elt;
|
||||||
symbol_number prepend_sym =
|
symbol_number prepend_sym =
|
||||||
item_number_as_symbol_number (*(head->item - 1));
|
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)
|
BITSET_FOR_EACH (biter, head->revs, sin, 0)
|
||||||
{
|
{
|
||||||
parse_state *copy = copy_parse_state (true, ps);
|
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))
|
if (SI_TRANSITION (head))
|
||||||
ps_derivs_prepend (copy, derivation_new_leaf (prepend_sym));
|
ps_derivs_prepend (copy, derivation_new_leaf (prepend_sym));
|
||||||
parse_state_list_append (res, copy);
|
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);
|
int parse_state_depth (const parse_state *ps);
|
||||||
|
|
||||||
/* returns the linked lists that the parse state is supposed to represent */
|
/* 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);
|
derivation_list *derivs);
|
||||||
|
|
||||||
/* various functions that return a list of states based off of
|
/* 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");
|
obstack_sgrow (oout, " %empty");
|
||||||
|
|
||||||
/* Experimental feature: display the lookahead tokens. */
|
/* Experimental feature: display the lookahead tokens. */
|
||||||
if (report_flag & report_lookahead_tokens
|
if (report_flag & report_lookaheads
|
||||||
&& item_number_is_rule_number (*sp1))
|
&& item_number_is_rule_number (*sp1))
|
||||||
{
|
{
|
||||||
/* Find the reduction we are handling. */
|
/* Find the reduction we are handling. */
|
||||||
@@ -104,13 +104,13 @@ print_core (struct obstack *oout, state *s)
|
|||||||
int redno = state_reduction_find (s, r);
|
int redno = state_reduction_find (s, r);
|
||||||
|
|
||||||
/* Print them if there are. */
|
/* Print them if there are. */
|
||||||
if (reds->lookahead_tokens && redno != -1)
|
if (reds->lookaheads && redno != -1)
|
||||||
{
|
{
|
||||||
bitset_iterator biter;
|
bitset_iterator biter;
|
||||||
int k;
|
int k;
|
||||||
char const *sep = "";
|
char const *sep = "";
|
||||||
obstack_sgrow (oout, " [");
|
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_sgrow (oout, sep);
|
||||||
obstack_backslash (oout, symbols[k]->tag);
|
obstack_backslash (oout, symbols[k]->tag);
|
||||||
|
|||||||
+29
-22
@@ -86,12 +86,12 @@ print_core (FILE *out, int level, state *s)
|
|||||||
reductions *reds = s->reductions;
|
reductions *reds = s->reductions;
|
||||||
int red = state_reduction_find (s, r);
|
int red = state_reduction_find (s, r);
|
||||||
/* Print item with lookaheads if there are. */
|
/* Print item with lookaheads if there are. */
|
||||||
if (reds->lookahead_tokens && red != -1)
|
if (reds->lookaheads && red != -1)
|
||||||
{
|
{
|
||||||
xml_printf (out, level + 1,
|
xml_printf (out, level + 1,
|
||||||
"<item rule-number=\"%d\" dot=\"%d\">",
|
"<item rule-number=\"%d\" dot=\"%d\">",
|
||||||
r->number, sp1 - sp);
|
r->number, sp1 - sp);
|
||||||
state_rule_lookahead_tokens_print_xml (s, r,
|
state_rule_lookaheads_print_xml (s, r,
|
||||||
out, level + 2);
|
out, level + 2);
|
||||||
xml_puts (out, level + 1, "</item>");
|
xml_puts (out, level + 1, "</item>");
|
||||||
printed = true;
|
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'). |
|
| 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 |
|
| If not ENABLED, the rule is masked by a shift or a reduce (S/R and |
|
||||||
| R/R conflicts). |
|
| R/R conflicts). |
|
||||||
`-------------------------------------------------------------------------*/
|
`-------------------------------------------------------------------*/
|
||||||
|
|
||||||
static void
|
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)
|
rule *r, bool enabled)
|
||||||
{
|
{
|
||||||
if (r->number)
|
if (r->number)
|
||||||
xml_printf (out, level,
|
xml_printf (out, level,
|
||||||
"<reduction symbol=\"%s\" rule=\"%d\" enabled=\"%s\"/>",
|
"<reduction symbol=\"%s\" rule=\"%d\" enabled=\"%s\"/>",
|
||||||
xml_escape (lookahead_token),
|
xml_escape (lookahead),
|
||||||
r->number,
|
r->number,
|
||||||
enabled ? "true" : "false");
|
enabled ? "true" : "false");
|
||||||
else
|
else
|
||||||
xml_printf (out, level,
|
xml_printf (out, level,
|
||||||
"<reduction symbol=\"%s\" rule=\"accept\" enabled=\"%s\"/>",
|
"<reduction symbol=\"%s\" rule=\"accept\" enabled=\"%s\"/>",
|
||||||
xml_escape (lookahead_token),
|
xml_escape (lookahead),
|
||||||
enabled ? "true" : "false");
|
enabled ? "true" : "false");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -258,13 +258,13 @@ print_reductions (FILE *out, int level, state *s)
|
|||||||
if (default_reduction)
|
if (default_reduction)
|
||||||
report = true;
|
report = true;
|
||||||
|
|
||||||
if (reds->lookahead_tokens)
|
if (reds->lookaheads)
|
||||||
for (i = 0; i < ntokens; i++)
|
for (i = 0; i < ntokens; i++)
|
||||||
{
|
{
|
||||||
bool count = bitset_test (no_reduce_set, i);
|
bool count = bitset_test (no_reduce_set, i);
|
||||||
|
|
||||||
for (j = 0; j < reds->num; ++j)
|
for (j = 0; j < reds->num; ++j)
|
||||||
if (bitset_test (reds->lookahead_tokens[j], i))
|
if (bitset_test (reds->lookaheads[j], i))
|
||||||
{
|
{
|
||||||
if (! count)
|
if (! count)
|
||||||
{
|
{
|
||||||
@@ -289,14 +289,14 @@ print_reductions (FILE *out, int level, state *s)
|
|||||||
xml_puts (out, level, "<reductions>");
|
xml_puts (out, level, "<reductions>");
|
||||||
|
|
||||||
/* Report lookahead tokens (or $default) and reductions. */
|
/* Report lookahead tokens (or $default) and reductions. */
|
||||||
if (reds->lookahead_tokens)
|
if (reds->lookaheads)
|
||||||
for (i = 0; i < ntokens; i++)
|
for (i = 0; i < ntokens; i++)
|
||||||
{
|
{
|
||||||
bool defaulted = false;
|
bool defaulted = false;
|
||||||
bool count = bitset_test (no_reduce_set, i);
|
bool count = bitset_test (no_reduce_set, i);
|
||||||
|
|
||||||
for (j = 0; j < reds->num; ++j)
|
for (j = 0; j < reds->num; ++j)
|
||||||
if (bitset_test (reds->lookahead_tokens[j], i))
|
if (bitset_test (reds->lookaheads[j], i))
|
||||||
{
|
{
|
||||||
if (! count)
|
if (! count)
|
||||||
{
|
{
|
||||||
@@ -382,14 +382,17 @@ print_grammar (FILE *out, int level)
|
|||||||
for (int i = 0; i < max_code + 1; i++)
|
for (int i = 0; i < max_code + 1; i++)
|
||||||
if (token_translations[i] != undeftoken->content->number)
|
if (token_translations[i] != undeftoken->content->number)
|
||||||
{
|
{
|
||||||
char const *tag = symbols[token_translations[i]]->tag;
|
symbol const *sym = symbols[token_translations[i]];
|
||||||
int precedence = symbols[token_translations[i]]->content->prec;
|
char const *tag = sym->tag;
|
||||||
assoc associativity = symbols[token_translations[i]]->content->assoc;
|
char const *type = sym->content->type_name;
|
||||||
|
int precedence = sym->content->prec;
|
||||||
|
assoc associativity = sym->content->assoc;
|
||||||
xml_indent (out, level + 2);
|
xml_indent (out, level + 2);
|
||||||
fprintf (out,
|
fprintf (out,
|
||||||
"<terminal symbol-number=\"%d\" token-number=\"%d\""
|
"<terminal symbol-number=\"%d\" token-number=\"%d\""
|
||||||
" name=\"%s\" usefulness=\"%s\"",
|
" name=\"%s\" type=\"%s\" usefulness=\"%s\"",
|
||||||
token_translations[i], i, xml_escape (tag),
|
token_translations[i], i, xml_escape_n (0, tag),
|
||||||
|
type ? xml_escape_n (1, type) : "",
|
||||||
reduce_token_unused_in_grammar (token_translations[i])
|
reduce_token_unused_in_grammar (token_translations[i])
|
||||||
? "unused-in-grammar" : "useful");
|
? "unused-in-grammar" : "useful");
|
||||||
if (precedence)
|
if (precedence)
|
||||||
@@ -404,12 +407,16 @@ print_grammar (FILE *out, int level)
|
|||||||
xml_puts (out, level + 1, "<nonterminals>");
|
xml_puts (out, level + 1, "<nonterminals>");
|
||||||
for (symbol_number i = ntokens; i < nsyms + nuseless_nonterminals; i++)
|
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,
|
xml_printf (out, level + 2,
|
||||||
"<nonterminal symbol-number=\"%d\" name=\"%s\""
|
"<nonterminal symbol-number=\"%d\" name=\"%s\""
|
||||||
|
" type=\"%s\""
|
||||||
" usefulness=\"%s\"/>",
|
" usefulness=\"%s\"/>",
|
||||||
i, xml_escape (tag),
|
i, xml_escape_n (0, tag),
|
||||||
reduce_nonterminal_useless_in_grammar (symbols[i]->content)
|
type ? xml_escape_n (1, type) : "",
|
||||||
|
reduce_nonterminal_useless_in_grammar (sym->content)
|
||||||
? "useless-in-grammar" : "useful");
|
? "useless-in-grammar" : "useful");
|
||||||
}
|
}
|
||||||
xml_puts (out, level + 1, "</nonterminals>");
|
xml_puts (out, level + 1, "</nonterminals>");
|
||||||
|
|||||||
+22
-21
@@ -90,9 +90,9 @@ print_core (FILE *out, const state *s)
|
|||||||
previous_rule = r;
|
previous_rule = r;
|
||||||
|
|
||||||
/* Display the lookahead tokens? */
|
/* Display the lookahead tokens? */
|
||||||
if (report_flag & report_lookahead_tokens
|
if (report_flag & report_lookaheads
|
||||||
&& item_number_is_rule_number (*sp1))
|
&& item_number_is_rule_number (*sp1))
|
||||||
state_rule_lookahead_tokens_print (s, r, out);
|
state_rule_lookaheads_print (s, r, out);
|
||||||
fputc ('\n', 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'). |
|
| 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 |
|
| If not ENABLED, the rule is masked by a shift or a reduce (S/R and |
|
||||||
| R/R conflicts). |
|
| R/R conflicts). |
|
||||||
`-------------------------------------------------------------------------*/
|
`-------------------------------------------------------------------*/
|
||||||
|
|
||||||
static void
|
static void
|
||||||
print_reduction (FILE *out, size_t width,
|
print_reduction (FILE *out, size_t width,
|
||||||
const char *lookahead_token,
|
const char *lookahead,
|
||||||
rule *r, bool enabled)
|
rule *r, bool enabled)
|
||||||
{
|
{
|
||||||
fprintf (out, " %s", lookahead_token);
|
fprintf (out, " %s", lookahead);
|
||||||
for (int j = width - mbswidth (lookahead_token, 0); j > 0; --j)
|
for (int j = width - mbswidth (lookahead, 0); j > 0; --j)
|
||||||
fputc (' ', out);
|
fputc (' ', out);
|
||||||
if (!enabled)
|
if (!enabled)
|
||||||
fputc ('[', out);
|
fputc ('[', out);
|
||||||
@@ -239,13 +239,13 @@ print_reductions (FILE *out, const state *s)
|
|||||||
if (default_reduction)
|
if (default_reduction)
|
||||||
width = mbswidth (_("$default"), 0);
|
width = mbswidth (_("$default"), 0);
|
||||||
|
|
||||||
if (reds->lookahead_tokens)
|
if (reds->lookaheads)
|
||||||
for (int i = 0; i < ntokens; i++)
|
for (int i = 0; i < ntokens; i++)
|
||||||
{
|
{
|
||||||
bool count = bitset_test (no_reduce_set, i);
|
bool count = bitset_test (no_reduce_set, i);
|
||||||
|
|
||||||
for (int j = 0; j < reds->num; ++j)
|
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)
|
if (! count)
|
||||||
{
|
{
|
||||||
@@ -268,7 +268,7 @@ print_reductions (FILE *out, const state *s)
|
|||||||
bool default_reduction_only = true;
|
bool default_reduction_only = true;
|
||||||
|
|
||||||
/* Report lookahead tokens (or $default) and reductions. */
|
/* Report lookahead tokens (or $default) and reductions. */
|
||||||
if (reds->lookahead_tokens)
|
if (reds->lookaheads)
|
||||||
for (int i = 0; i < ntokens; i++)
|
for (int i = 0; i < ntokens; i++)
|
||||||
{
|
{
|
||||||
bool defaulted = false;
|
bool defaulted = false;
|
||||||
@@ -277,7 +277,7 @@ print_reductions (FILE *out, const state *s)
|
|||||||
default_reduction_only = false;
|
default_reduction_only = false;
|
||||||
|
|
||||||
for (int j = 0; j < reds->num; ++j)
|
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)
|
if (! count)
|
||||||
{
|
{
|
||||||
@@ -377,11 +377,11 @@ print_terminal_symbols (FILE *out)
|
|||||||
for (int i = 0; i < max_code + 1; ++i)
|
for (int i = 0; i < max_code + 1; ++i)
|
||||||
if (token_translations[i] != undeftoken->content->number)
|
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);
|
fprintf (out, "%4s%s", "", tag);
|
||||||
if (symbols[token_translations[i]]->content->type_name)
|
if (sym->content->type_name)
|
||||||
fprintf (out, " <%s>",
|
fprintf (out, " <%s>", sym->content->type_name);
|
||||||
symbols[token_translations[i]]->content->type_name);
|
|
||||||
fprintf (out, " (%d)", i);
|
fprintf (out, " (%d)", i);
|
||||||
|
|
||||||
for (rule_number r = 0; r < nrules; r++)
|
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"));
|
fprintf (out, "%s\n\n", _("Nonterminals, with rules where they appear"));
|
||||||
for (symbol_number i = ntokens; i < nsyms; i++)
|
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_left = false;
|
||||||
bool on_right = false;
|
bool on_right = false;
|
||||||
|
|
||||||
@@ -418,9 +419,9 @@ print_nonterminal_symbols (FILE *out)
|
|||||||
|
|
||||||
int column = 4 + mbswidth (tag, 0);
|
int column = 4 + mbswidth (tag, 0);
|
||||||
fprintf (out, "%4s%s", "", tag);
|
fprintf (out, "%4s%s", "", tag);
|
||||||
if (symbols[i]->content->type_name)
|
if (sym->content->type_name)
|
||||||
column += fprintf (out, " <%s>",
|
column += fprintf (out, " <%s>",
|
||||||
symbols[i]->content->type_name);
|
sym->content->type_name);
|
||||||
fprintf (out, " (%d)\n", i);
|
fprintf (out, " (%d)\n", i);
|
||||||
|
|
||||||
if (on_left)
|
if (on_left)
|
||||||
|
|||||||
+32
-34
@@ -144,13 +144,13 @@ init_state_items (void)
|
|||||||
for (int j = 0; j < s->nitems; ++j)
|
for (int j = 0; j < s->nitems; ++j)
|
||||||
{
|
{
|
||||||
state_item_set (sidx, s, s->items[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);
|
const rule *r = item_rule (si->item);
|
||||||
if (rule_search_idx < red->num && red->rules[rule_search_idx] < r)
|
if (rule_search_idx < red->num && red->rules[rule_search_idx] < r)
|
||||||
++rule_search_idx;
|
++rule_search_idx;
|
||||||
if (rule_search_idx < red->num && r == red->rules[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)
|
if (lookahead)
|
||||||
si->lookahead = lookahead[rule_search_idx];
|
si->lookahead = lookahead[rule_search_idx];
|
||||||
}
|
}
|
||||||
@@ -163,7 +163,7 @@ init_state_items (void)
|
|||||||
state_item_set (sidx, s, off);
|
state_item_set (sidx, s, off);
|
||||||
if (item_number_is_rule_number (ritem[off]))
|
if (item_number_is_rule_number (ritem[off]))
|
||||||
{
|
{
|
||||||
bitsetv lookahead = red->lookahead_tokens;
|
bitsetv lookahead = red->lookaheads;
|
||||||
if (lookahead)
|
if (lookahead)
|
||||||
state_items[sidx].lookahead = lookahead[rule_search_idx];
|
state_items[sidx].lookahead = lookahead[rule_search_idx];
|
||||||
++rule_search_idx;
|
++rule_search_idx;
|
||||||
@@ -211,7 +211,7 @@ init_trans (void)
|
|||||||
for (int j = 0; j < t->num; ++j)
|
for (int j = 0; j < t->num; ++j)
|
||||||
if (!TRANSITION_IS_DISABLED (t, j))
|
if (!TRANSITION_IS_DISABLED (t, j))
|
||||||
hash_xinsert (transition_set, t->states[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;
|
item_number *item = state_items[j].item;
|
||||||
if (item_number_is_rule_number (*item))
|
if (item_number_is_rule_number (*item))
|
||||||
@@ -222,16 +222,14 @@ init_trans (void)
|
|||||||
// find the item in the destination state that corresponds
|
// find the item in the destination state that corresponds
|
||||||
// to the transition of item
|
// to the transition of item
|
||||||
for (int k = 0; k < dst->nitems; ++k)
|
for (int k = 0; k < dst->nitems; ++k)
|
||||||
{
|
if (item + 1 == ritem + dst->items[k])
|
||||||
if (item + 1 == ritem + dst->items[k])
|
{
|
||||||
{
|
state_item_number dstSI =
|
||||||
state_item_number dstSI =
|
state_item_index_lookup (dst->number, k);
|
||||||
state_item_index_lookup (dst->number, k);
|
|
||||||
|
|
||||||
state_items[j].trans = dstSI;
|
state_items[j].trans = dstSI;
|
||||||
bitset_set (state_items[dstSI].revs, j);
|
bitset_set (state_items[dstSI].revs, j);
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
hash_free (transition_set);
|
hash_free (transition_set);
|
||||||
@@ -250,10 +248,10 @@ init_prods (void)
|
|||||||
|
|
||||||
// Add the nitems of state to skip to the production portion
|
// Add the nitems of state to skip to the production portion
|
||||||
// of that state's state_items
|
// 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)
|
j < state_item_map[i + 1]; ++j)
|
||||||
{
|
{
|
||||||
state_item *src = state_items + j;
|
state_item *src = &state_items[j];
|
||||||
item_number *item = src->item;
|
item_number *item = src->item;
|
||||||
symbol_number lhs = item_rule (item)->lhs->number;
|
symbol_number lhs = item_rule (item)->lhs->number;
|
||||||
bitset itms = hash_pair_lookup (closure_map, lhs);
|
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,
|
// For each item with a dot followed by a nonterminal,
|
||||||
// try to create a production edge.
|
// 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);
|
item_number item = *(src->item);
|
||||||
// Skip reduce items and items with terminals after the dot
|
// Skip reduce items and items with terminals after the dot
|
||||||
if (item_number_is_rule_number (item) || ISTOKEN (item))
|
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)
|
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)
|
if (item_number_is_symbol_number (*(si->item)) || !si->lookahead)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
bitset lookahead = si->lookahead;
|
bitset lookahead = si->lookahead;
|
||||||
gl_list_t queue =
|
state_item_list queue =
|
||||||
gl_list_create (GL_LINKED_LIST, NULL, NULL, NULL, true, 1,
|
gl_list_create (GL_LINKED_LIST, NULL, NULL, NULL, true, 1,
|
||||||
(const void **) &si);
|
(const void **) &si);
|
||||||
|
|
||||||
@@ -339,7 +337,7 @@ init_firsts (void)
|
|||||||
firsts = bitsetv_create (nnterms, nsyms, BITSET_FIXED);
|
firsts = bitsetv_create (nnterms, nsyms, BITSET_FIXED);
|
||||||
for (rule_number i = 0; i < nrules; ++i)
|
for (rule_number i = 0; i < nrules; ++i)
|
||||||
{
|
{
|
||||||
rule *r = rules + i;
|
rule *r = &rules[i];
|
||||||
item_number *n = r->rhs;
|
item_number *n = r->rhs;
|
||||||
// Iterate through nullable nonterminals to try to find a terminal.
|
// Iterate through nullable nonterminals to try to find a terminal.
|
||||||
while (item_number_is_symbol_number (*n) && ISVAR (*n)
|
while (item_number_is_symbol_number (*n) && ISVAR (*n)
|
||||||
@@ -357,7 +355,7 @@ init_firsts (void)
|
|||||||
change = false;
|
change = false;
|
||||||
for (rule_number i = 0; i < nrules; ++i)
|
for (rule_number i = 0; i < nrules; ++i)
|
||||||
{
|
{
|
||||||
rule *r = rules + i;
|
rule *r = &rules[i];
|
||||||
symbol_number lhs = r->lhs->number;
|
symbol_number lhs = r->lhs->number;
|
||||||
bitset f_lhs = FIRSTS (lhs);
|
bitset f_lhs = FIRSTS (lhs);
|
||||||
for (item_number *n = r->rhs;
|
for (item_number *n = r->rhs;
|
||||||
@@ -392,7 +390,7 @@ disable_state_item (state_item *si)
|
|||||||
static void
|
static void
|
||||||
prune_forward (const state_item *si)
|
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,
|
gl_list_create (GL_LINKED_LIST, NULL, NULL, NULL, true, 1,
|
||||||
(const void **) &si);
|
(const void **) &si);
|
||||||
|
|
||||||
@@ -401,7 +399,7 @@ prune_forward (const state_item *si)
|
|||||||
state_item *dsi = (state_item *) gl_list_get_at (queue, 0);
|
state_item *dsi = (state_item *) gl_list_get_at (queue, 0);
|
||||||
gl_list_remove_at (queue, 0);
|
gl_list_remove_at (queue, 0);
|
||||||
if (dsi->trans >= 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)
|
if (dsi->prods)
|
||||||
{
|
{
|
||||||
@@ -409,7 +407,7 @@ prune_forward (const state_item *si)
|
|||||||
state_item_number sin;
|
state_item_number sin;
|
||||||
BITSET_FOR_EACH (biter, dsi->prods, sin, 0)
|
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);
|
bitset_reset (prod->revs, dsi - state_items);
|
||||||
if (bitset_empty_p (prod->revs))
|
if (bitset_empty_p (prod->revs))
|
||||||
gl_list_add_last (queue, prod);
|
gl_list_add_last (queue, prod);
|
||||||
@@ -427,7 +425,7 @@ prune_forward (const state_item *si)
|
|||||||
static void
|
static void
|
||||||
prune_backward (const state_item *si)
|
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,
|
gl_list_create (GL_LINKED_LIST, NULL, NULL, NULL, true, 1,
|
||||||
(const void **) &si);
|
(const void **) &si);
|
||||||
|
|
||||||
@@ -441,7 +439,7 @@ prune_backward (const state_item *si)
|
|||||||
{
|
{
|
||||||
if (SI_DISABLED (sin))
|
if (SI_DISABLED (sin))
|
||||||
continue;
|
continue;
|
||||||
state_item *rev = state_items + sin;
|
state_item *rev = &state_items[sin];
|
||||||
if (rev->prods)
|
if (rev->prods)
|
||||||
{
|
{
|
||||||
bitset_reset (rev->prods, dsi - state_items);
|
bitset_reset (rev->prods, dsi - state_items);
|
||||||
@@ -466,7 +464,7 @@ prune_disabled_paths (void)
|
|||||||
{
|
{
|
||||||
for (int i = nstate_items - 1; i >= 0; --i)
|
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))
|
if (si->trans == -1 && item_number_is_symbol_number (*si->item))
|
||||||
{
|
{
|
||||||
prune_forward (si);
|
prune_forward (si);
|
||||||
@@ -494,9 +492,9 @@ state_items_report (void)
|
|||||||
for (state_number i = 0; i < nstates; ++i)
|
for (state_number i = 0; i < nstates; ++i)
|
||||||
{
|
{
|
||||||
printf ("State %d:\n", 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);
|
item_print (si->item, NULL, stdout);
|
||||||
if (SI_DISABLED (j))
|
if (SI_DISABLED (j))
|
||||||
{
|
{
|
||||||
@@ -508,7 +506,7 @@ state_items_report (void)
|
|||||||
if (si->trans >= 0)
|
if (si->trans >= 0)
|
||||||
{
|
{
|
||||||
fputs (" -> ", stdout);
|
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 };
|
bitset sets[2] = { si->prods, si->revs };
|
||||||
@@ -523,7 +521,7 @@ state_items_report (void)
|
|||||||
BITSET_FOR_EACH (biter, b, sin, 0)
|
BITSET_FOR_EACH (biter, b, sin, 0)
|
||||||
{
|
{
|
||||||
fputs (txt[seti], stdout);
|
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
|
void
|
||||||
state_items_free (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))
|
if (!SI_DISABLED (i))
|
||||||
{
|
{
|
||||||
state_item *si = state_items + i;
|
state_item *si = &state_items[i];
|
||||||
if (si->prods)
|
if (si->prods)
|
||||||
bitset_free (si->prods);
|
bitset_free (si->prods);
|
||||||
bitset_free (si->revs);
|
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)
|
if (prec1 == prec2 && s1->assoc == left_assoc)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
+12
-8
@@ -28,16 +28,16 @@
|
|||||||
# include "state.h"
|
# include "state.h"
|
||||||
|
|
||||||
/* Initializes a graph connecting (state, production item) pairs to
|
/* 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
|
is used to search for paths that represent counterexamples of some
|
||||||
conflict.
|
conflict.
|
||||||
|
|
||||||
state_items is an array of state state-item pairs ordered by state.
|
state_items is an array of state state-item pairs ordered by state.
|
||||||
state_item_map maps state numbers to the first item which
|
state_item_map maps state numbers to the first item which
|
||||||
corresponds to it in the array. A state's portion in state_items
|
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
|
begins with its items in the same order as it was in the state.
|
||||||
state. This is then followed by productions from the closure of the
|
This is then followed by productions from the closure of the state
|
||||||
state in order by rule.
|
in order by rule.
|
||||||
|
|
||||||
There are two type of edges in this graph transitions and
|
There are two type of edges in this graph transitions and
|
||||||
productions. Transitions are the same as transitions from the
|
productions. Transitions are the same as transitions from the
|
||||||
@@ -53,9 +53,9 @@
|
|||||||
production edges, and all others will have reverse transition
|
production edges, and all others will have reverse transition
|
||||||
edges. */
|
edges. */
|
||||||
|
|
||||||
# define SI_DISABLED(sin) (state_items[sin].trans == -2)
|
# define SI_DISABLED(Sin) (state_items[Sin].trans == -2)
|
||||||
# define SI_PRODUCTION(si) ((si) == state_items || *((si)->item - 1) < 0)
|
# define SI_PRODUCTION(Si) ((Si) == state_items || *((Si)->item - 1) < 0)
|
||||||
# define SI_TRANSITION(si) ((si) != state_items && *((si)->item - 1) >= 0)
|
# define SI_TRANSITION(Si) ((Si) != state_items && *((Si)->item - 1) >= 0)
|
||||||
|
|
||||||
typedef int state_item_number;
|
typedef int state_item_number;
|
||||||
|
|
||||||
@@ -69,6 +69,9 @@ typedef struct
|
|||||||
bitset lookahead;
|
bitset lookahead;
|
||||||
} state_item;
|
} state_item;
|
||||||
|
|
||||||
|
// A path of state-items.
|
||||||
|
typedef gl_list_t state_item_list;
|
||||||
|
|
||||||
extern bitsetv firsts;
|
extern bitsetv firsts;
|
||||||
# define FIRSTS(sym) firsts[(sym) - ntokens]
|
# 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);
|
bool production_allowed (const state_item *si, const state_item *next);
|
||||||
|
|
||||||
|
// Iterating on a state_item_list.
|
||||||
static inline bool
|
static inline bool
|
||||||
state_item_list_next (gl_list_iterator_t *it, state_item **si)
|
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;
|
size_t rules_size = num * sizeof *reds;
|
||||||
reductions *res = xmalloc (offsetof (reductions, rules) + rules_size);
|
reductions *res = xmalloc (offsetof (reductions, rules) + rules_size);
|
||||||
res->num = num;
|
res->num = num;
|
||||||
res->lookahead_tokens = NULL;
|
res->lookaheads = NULL;
|
||||||
memcpy (res->rules, reds, rules_size);
|
memcpy (res->rules, reds, rules_size);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@@ -260,20 +260,20 @@ state_errs_set (state *s, int num, symbol **tokens)
|
|||||||
`--------------------------------------------------*/
|
`--------------------------------------------------*/
|
||||||
|
|
||||||
void
|
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. */
|
/* Find the reduction we are handling. */
|
||||||
reductions *reds = s->reductions;
|
reductions *reds = s->reductions;
|
||||||
int red = state_reduction_find (s, r);
|
int red = state_reduction_find (s, r);
|
||||||
|
|
||||||
/* Print them if there are. */
|
/* Print them if there are. */
|
||||||
if (reds->lookahead_tokens && red != -1)
|
if (reds->lookaheads && red != -1)
|
||||||
{
|
{
|
||||||
bitset_iterator biter;
|
bitset_iterator biter;
|
||||||
int k;
|
int k;
|
||||||
char const *sep = "";
|
char const *sep = "";
|
||||||
fprintf (out, " [");
|
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);
|
fprintf (out, "%s%s", sep, symbols[k]->tag);
|
||||||
sep = ", ";
|
sep = ", ";
|
||||||
@@ -283,7 +283,7 @@ state_rule_lookahead_tokens_print (state const *s, rule const *r, FILE *out)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
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)
|
FILE *out, int level)
|
||||||
{
|
{
|
||||||
/* Find the reduction we are handling. */
|
/* 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);
|
int red = state_reduction_find (s, r);
|
||||||
|
|
||||||
/* Print them if there are. */
|
/* Print them if there are. */
|
||||||
if (reds->lookahead_tokens && red != -1)
|
if (reds->lookaheads && red != -1)
|
||||||
{
|
{
|
||||||
bitset_iterator biter;
|
bitset_iterator biter;
|
||||||
int k;
|
int k;
|
||||||
xml_puts (out, level, "<lookaheads>");
|
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_printf (out, level + 1, "<symbol>%s</symbol>",
|
||||||
xml_escape (symbols[k]->tag));
|
xml_escape (symbols[k]->tag));
|
||||||
|
|||||||
+5
-5
@@ -62,7 +62,7 @@
|
|||||||
|
|
||||||
Each reductions structure describes the possible reductions at the
|
Each reductions structure describes the possible reductions at the
|
||||||
state whose number is in the number field. rules is an array of
|
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
|
Conflict resolution can decide that certain tokens in certain
|
||||||
states should explicitly be errors (for implementing %nonassoc).
|
states should explicitly be errors (for implementing %nonassoc).
|
||||||
@@ -187,7 +187,7 @@ errs *errs_new (int num, symbol **tokens);
|
|||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
int num;
|
int num;
|
||||||
bitset *lookahead_tokens;
|
bitset *lookaheads;
|
||||||
/* Sorted ascendingly on rule number. */
|
/* Sorted ascendingly on rule number. */
|
||||||
rule *rules[1];
|
rule *rules[1];
|
||||||
} reductions;
|
} 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
|
/* Print on OUT all the lookahead tokens such that this STATE wants to
|
||||||
reduce R. */
|
reduce R. */
|
||||||
void state_rule_lookahead_tokens_print (state const *s, rule const *r, FILE *out);
|
void state_rule_lookaheads_print (state const *s, rule const *r, FILE *out);
|
||||||
void state_rule_lookahead_tokens_print_xml (state const *s, rule const *r,
|
void state_rule_lookaheads_print_xml (state const *s, rule const *r,
|
||||||
FILE *out, int level);
|
FILE *out, int level);
|
||||||
|
|
||||||
/* Create/destroy the states hash table. */
|
/* Create/destroy the states hash table. */
|
||||||
void state_hash_new (void);
|
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
|
/* Find all reductions for token J, and record all that do not
|
||||||
match ACTROW[J]. */
|
match ACTROW[J]. */
|
||||||
for (int i = 0; i < reds->num; i += 1)
|
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]
|
&& (actrow[j]
|
||||||
!= rule_number_as_item_number (reds->rules[i]->number)))
|
!= rule_number_as_item_number (reds->rules[i]->number)))
|
||||||
{
|
{
|
||||||
@@ -247,7 +247,7 @@ action_row (state *s)
|
|||||||
|
|
||||||
reductions *reds = s->reductions;
|
reductions *reds = s->reductions;
|
||||||
bool conflicted = false;
|
bool conflicted = false;
|
||||||
if (reds->lookahead_tokens)
|
if (reds->lookaheads)
|
||||||
/* loop over all the rules available here which require
|
/* loop over all the rules available here which require
|
||||||
lookahead (in reverse order to give precedence to the first
|
lookahead (in reverse order to give precedence to the first
|
||||||
rule) */
|
rule) */
|
||||||
@@ -257,7 +257,7 @@ action_row (state *s)
|
|||||||
{
|
{
|
||||||
bitset_iterator biter;
|
bitset_iterator biter;
|
||||||
int j;
|
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
|
/* and record this rule as the rule to use if that
|
||||||
token follows. */
|
token follows. */
|
||||||
@@ -308,7 +308,7 @@ action_row (state *s)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Turn off default reductions where requested by the user. See
|
/* 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. */
|
labeled as consistent. */
|
||||||
{
|
{
|
||||||
char *default_reductions =
|
char *default_reductions =
|
||||||
|
|||||||
+92
-44
@@ -726,7 +726,7 @@ AT_BISON_OPTION_POPDEFS
|
|||||||
AT_BISON_CHECK([[-Dlr.type=canonical-lr -o input.c input.y]],
|
AT_BISON_CHECK([[-Dlr.type=canonical-lr -o input.c input.y]],
|
||||||
[[0]], [[]],
|
[[0]], [[]],
|
||||||
[[input.y: warning: 2 shift/reduce conflicts [-Wconflicts-sr]
|
[[input.y: warning: 2 shift/reduce conflicts [-Wconflicts-sr]
|
||||||
input.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
|
input.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
|
||||||
]])
|
]])
|
||||||
AT_COMPILE([[input]])
|
AT_COMPILE([[input]])
|
||||||
AT_PARSER_CHECK([[input]], [[1]], [[]],
|
AT_PARSER_CHECK([[input]], [[1]], [[]],
|
||||||
@@ -737,7 +737,7 @@ AT_PARSER_CHECK([[input]], [[1]], [[]],
|
|||||||
AT_BISON_CHECK([[-Dlr.type=canonical-lr -Dparse.lac=full \
|
AT_BISON_CHECK([[-Dlr.type=canonical-lr -Dparse.lac=full \
|
||||||
-o input.c input.y]], [[0]], [[]],
|
-o input.c input.y]], [[0]], [[]],
|
||||||
[[input.y: warning: 2 shift/reduce conflicts [-Wconflicts-sr]
|
[[input.y: warning: 2 shift/reduce conflicts [-Wconflicts-sr]
|
||||||
input.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
|
input.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
|
||||||
]])
|
]])
|
||||||
AT_COMPILE([[input]])
|
AT_COMPILE([[input]])
|
||||||
AT_PARSER_CHECK([[input]], [[1]], [[]],
|
AT_PARSER_CHECK([[input]], [[1]], [[]],
|
||||||
@@ -748,7 +748,7 @@ AT_PARSER_CHECK([[input]], [[1]], [[]],
|
|||||||
AT_BISON_CHECK([[-Dlr.type=ielr -Dparse.lac=full -o input.c input.y]],
|
AT_BISON_CHECK([[-Dlr.type=ielr -Dparse.lac=full -o input.c input.y]],
|
||||||
[[0]], [[]],
|
[[0]], [[]],
|
||||||
[[input.y: warning: 2 shift/reduce conflicts [-Wconflicts-sr]
|
[[input.y: warning: 2 shift/reduce conflicts [-Wconflicts-sr]
|
||||||
input.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
|
input.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
|
||||||
]])
|
]])
|
||||||
AT_COMPILE([[input]])
|
AT_COMPILE([[input]])
|
||||||
AT_PARSER_CHECK([[input]], [[1]], [[]],
|
AT_PARSER_CHECK([[input]], [[1]], [[]],
|
||||||
@@ -773,7 +773,7 @@ exp: exp OP exp | NUM;
|
|||||||
|
|
||||||
AT_BISON_CHECK([-o input.c --report=all input.y], 0, [],
|
AT_BISON_CHECK([-o input.c --report=all input.y], 0, [],
|
||||||
[[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
|
[[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
|
||||||
input.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
|
input.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
|
||||||
]])
|
]])
|
||||||
|
|
||||||
# Check the contents of the report.
|
# Check the contents of the report.
|
||||||
@@ -861,12 +861,18 @@ State 5
|
|||||||
OP [reduce using rule 1 (exp)]
|
OP [reduce using rule 1 (exp)]
|
||||||
$default reduce using rule 1 (exp)
|
$default reduce using rule 1 (exp)
|
||||||
|
|
||||||
Shift/reduce conflict on token OP:
|
shift/reduce conflict on token OP:
|
||||||
1 exp: exp OP exp .
|
1 exp: exp OP exp .
|
||||||
1 exp: exp . OP exp
|
1 exp: exp . OP exp
|
||||||
Example exp OP exp . OP exp
|
Example: exp OP exp . OP exp
|
||||||
First derivation exp ::=[ exp ::=[ exp OP exp . ] OP exp ]
|
Shift derivation
|
||||||
Second derivation exp ::=[ exp OP exp ::=[ exp . OP exp ] ]
|
exp
|
||||||
|
`-> exp OP exp
|
||||||
|
`-> exp . OP exp
|
||||||
|
Reduce derivation
|
||||||
|
exp
|
||||||
|
`-> exp OP exp
|
||||||
|
`-> exp OP exp .
|
||||||
|
|
||||||
]])
|
]])
|
||||||
|
|
||||||
@@ -1026,7 +1032,7 @@ cond:
|
|||||||
|
|
||||||
AT_BISON_CHECK([-o input.c input.y], 0, [],
|
AT_BISON_CHECK([-o input.c input.y], 0, [],
|
||||||
[[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
|
[[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
|
||||||
input.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
|
input.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
|
||||||
input.y:12.3-18: warning: rule useless in parser due to conflicts [-Wother]
|
input.y:12.3-18: warning: rule useless in parser due to conflicts [-Wother]
|
||||||
]])
|
]])
|
||||||
|
|
||||||
@@ -1119,7 +1125,7 @@ m4_popdef([AT_TEST])
|
|||||||
# else.
|
# else.
|
||||||
|
|
||||||
AT_SETUP([Defaulted Conflicted Reduction])
|
AT_SETUP([Defaulted Conflicted Reduction])
|
||||||
AT_KEYWORDS([report])
|
AT_KEYWORDS([cex report])
|
||||||
|
|
||||||
AT_DATA([input.y],
|
AT_DATA([input.y],
|
||||||
[[%%
|
[[%%
|
||||||
@@ -1131,7 +1137,7 @@ id : '0';
|
|||||||
|
|
||||||
AT_BISON_CHECK([-o input.c --report=all input.y], 0, [],
|
AT_BISON_CHECK([-o input.c --report=all input.y], 0, [],
|
||||||
[[input.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
|
[[input.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
|
||||||
input.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
|
input.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
|
||||||
input.y:4.6-8: warning: rule useless in parser due to conflicts [-Wother]
|
input.y:4.6-8: warning: rule useless in parser due to conflicts [-Wother]
|
||||||
]])
|
]])
|
||||||
|
|
||||||
@@ -1203,12 +1209,18 @@ State 1
|
|||||||
$end [reduce using rule 4 (id)]
|
$end [reduce using rule 4 (id)]
|
||||||
$default reduce using rule 3 (num)
|
$default reduce using rule 3 (num)
|
||||||
|
|
||||||
Reduce/reduce conflict on token $end:
|
reduce/reduce conflict on token $end:
|
||||||
3 num: '0' .
|
3 num: '0' .
|
||||||
4 id: '0' .
|
4 id: '0' .
|
||||||
Example '0' .
|
Example: '0' .
|
||||||
First derivation exp ::=[ num ::=[ '0' . ] ]
|
First reduce derivation
|
||||||
Second derivation exp ::=[ id ::=[ '0' . ] ]
|
exp
|
||||||
|
`-> num
|
||||||
|
`-> '0' .
|
||||||
|
Second reduce derivation
|
||||||
|
exp
|
||||||
|
`-> id
|
||||||
|
`-> '0' .
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1260,7 +1272,7 @@ exp: exp OP exp | NUM;
|
|||||||
|
|
||||||
AT_BISON_CHECK([-o input.c input.y], 1, [],
|
AT_BISON_CHECK([-o input.c input.y], 1, [],
|
||||||
[[input.y: error: shift/reduce conflicts: 1 found, 0 expected
|
[[input.y: error: shift/reduce conflicts: 1 found, 0 expected
|
||||||
input.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
|
input.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
|
||||||
]])
|
]])
|
||||||
AT_CLEANUP
|
AT_CLEANUP
|
||||||
|
|
||||||
@@ -1297,7 +1309,7 @@ exp: exp OP exp | NUM;
|
|||||||
|
|
||||||
AT_BISON_CHECK([-o input.c input.y], 1, [],
|
AT_BISON_CHECK([-o input.c input.y], 1, [],
|
||||||
[[input.y: error: shift/reduce conflicts: 1 found, 2 expected
|
[[input.y: error: shift/reduce conflicts: 1 found, 2 expected
|
||||||
input.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
|
input.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
|
||||||
]])
|
]])
|
||||||
AT_CLEANUP
|
AT_CLEANUP
|
||||||
|
|
||||||
@@ -1317,7 +1329,7 @@ a: 'a';
|
|||||||
|
|
||||||
AT_BISON_CHECK([-o input.c input.y], 1, [],
|
AT_BISON_CHECK([-o input.c input.y], 1, [],
|
||||||
[[input.y: error: reduce/reduce conflicts: 1 found, 0 expected
|
[[input.y: error: reduce/reduce conflicts: 1 found, 0 expected
|
||||||
input.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
|
input.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
|
||||||
]])
|
]])
|
||||||
AT_CLEANUP
|
AT_CLEANUP
|
||||||
|
|
||||||
@@ -1518,7 +1530,7 @@ e: e '+' e
|
|||||||
|
|
||||||
AT_BISON_CHECK([-Wall -o input.c input.y], 0, [],
|
AT_BISON_CHECK([-Wall -o input.c input.y], 0, [],
|
||||||
[[input.y: warning: 4 shift/reduce conflicts [-Wconflicts-sr]
|
[[input.y: warning: 4 shift/reduce conflicts [-Wconflicts-sr]
|
||||||
input.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
|
input.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
|
||||||
input.y:1.1-5: warning: useless precedence and associativity for '+' [-Wprecedence]
|
input.y:1.1-5: warning: useless precedence and associativity for '+' [-Wprecedence]
|
||||||
input.y:2.1-5: warning: useless precedence and associativity for '*' [-Wprecedence]
|
input.y:2.1-5: warning: useless precedence and associativity for '*' [-Wprecedence]
|
||||||
]])
|
]])
|
||||||
@@ -1579,6 +1591,8 @@ AT_CLEANUP
|
|||||||
|
|
||||||
AT_SETUP([[Unreachable States After Conflict Resolution]])
|
AT_SETUP([[Unreachable States After Conflict Resolution]])
|
||||||
|
|
||||||
|
AT_KEYWORDS([cex report])
|
||||||
|
|
||||||
# If conflict resolution makes states unreachable, remove those states, 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
|
# 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
|
# what happens when a nonterminal becomes useless as a result of state removal
|
||||||
@@ -1624,7 +1638,7 @@ reported_conflicts:
|
|||||||
AT_BISON_CHECK([[--report=all input.y]], 0, [],
|
AT_BISON_CHECK([[--report=all input.y]], 0, [],
|
||||||
[[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
|
[[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
|
||||||
input.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
|
input.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
|
||||||
input.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
|
input.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
|
||||||
input.y:12.5-20: warning: rule useless in parser due to conflicts [-Wother]
|
input.y:12.5-20: warning: rule useless in parser due to conflicts [-Wother]
|
||||||
input.y:20.5-20: warning: rule useless in parser due to conflicts [-Wother]
|
input.y:20.5-20: warning: rule useless in parser due to conflicts [-Wother]
|
||||||
input.y:21.4: warning: rule useless in parser due to conflicts [-Wother]
|
input.y:21.4: warning: rule useless in parser due to conflicts [-Wother]
|
||||||
@@ -1750,21 +1764,33 @@ State 4
|
|||||||
|
|
||||||
reported_conflicts go to state 6
|
reported_conflicts go to state 6
|
||||||
|
|
||||||
Shift/reduce conflict on token 'a':
|
shift/reduce conflict on token 'a':
|
||||||
10 reported_conflicts: . %empty
|
10 reported_conflicts: . %empty
|
||||||
8 reported_conflicts: . 'a'
|
8 reported_conflicts: . 'a'
|
||||||
First example resolved_conflict . 'a'
|
First example: resolved_conflict . 'a' 'a'
|
||||||
First derivation start ::=[ resolved_conflict reported_conflicts ::=[ . ] 'a' ]
|
Shift derivation
|
||||||
Second example resolved_conflict . 'a' 'a'
|
start
|
||||||
Second derivation start ::=[ resolved_conflict reported_conflicts ::=[ . 'a' ] 'a' ]
|
`-> 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':
|
shift/reduce conflict on token 'a':
|
||||||
10 reported_conflicts: . %empty
|
10 reported_conflicts: . %empty
|
||||||
9 reported_conflicts: . 'a'
|
9 reported_conflicts: . 'a'
|
||||||
First example resolved_conflict . 'a'
|
First example: resolved_conflict . 'a' 'a'
|
||||||
First derivation start ::=[ resolved_conflict reported_conflicts ::=[ . ] 'a' ]
|
Shift derivation
|
||||||
Second example resolved_conflict . 'a' 'a'
|
start
|
||||||
Second derivation start ::=[ resolved_conflict reported_conflicts ::=[ . 'a' ] 'a' ]
|
`-> resolved_conflict reported_conflicts 'a'
|
||||||
|
`-> . 'a'
|
||||||
|
Second example: resolved_conflict . 'a'
|
||||||
|
Reduce derivation
|
||||||
|
start
|
||||||
|
`-> resolved_conflict reported_conflicts 'a'
|
||||||
|
`-> .
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1777,12 +1803,16 @@ State 5
|
|||||||
'a' [reduce using rule 9 (reported_conflicts)]
|
'a' [reduce using rule 9 (reported_conflicts)]
|
||||||
$default reduce using rule 8 (reported_conflicts)
|
$default reduce using rule 8 (reported_conflicts)
|
||||||
|
|
||||||
Reduce/reduce conflict on token 'a':
|
reduce/reduce conflict on token 'a':
|
||||||
8 reported_conflicts: 'a' .
|
8 reported_conflicts: 'a' .
|
||||||
9 reported_conflicts: 'a' .
|
9 reported_conflicts: 'a' .
|
||||||
Example 'a' .
|
Example: 'a' .
|
||||||
First derivation reported_conflicts ::=[ 'a' . ]
|
First reduce derivation
|
||||||
Second derivation reported_conflicts ::=[ 'a' . ]
|
reported_conflicts
|
||||||
|
`-> 'a' .
|
||||||
|
Second reduce derivation
|
||||||
|
reported_conflicts
|
||||||
|
`-> 'a' .
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1808,7 +1838,7 @@ AT_CHECK([[cat input.y >> input-keep.y]])
|
|||||||
AT_BISON_CHECK([[input-keep.y]], 0, [],
|
AT_BISON_CHECK([[input-keep.y]], 0, [],
|
||||||
[[input-keep.y: warning: 2 shift/reduce conflicts [-Wconflicts-sr]
|
[[input-keep.y: warning: 2 shift/reduce conflicts [-Wconflicts-sr]
|
||||||
input-keep.y: warning: 2 reduce/reduce conflicts [-Wconflicts-rr]
|
input-keep.y: warning: 2 reduce/reduce conflicts [-Wconflicts-rr]
|
||||||
input-keep.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
|
input-keep.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
|
||||||
input-keep.y:22.4: warning: rule useless in parser due to conflicts [-Wother]
|
input-keep.y:22.4: warning: rule useless in parser due to conflicts [-Wother]
|
||||||
input-keep.y:26.16: warning: rule useless in parser due to conflicts [-Wother]
|
input-keep.y:26.16: warning: rule useless in parser due to conflicts [-Wother]
|
||||||
input-keep.y:32.5-7: warning: rule useless in parser due to conflicts [-Wother]
|
input-keep.y:32.5-7: warning: rule useless in parser due to conflicts [-Wother]
|
||||||
@@ -1904,6 +1934,8 @@ AT_CLEANUP
|
|||||||
|
|
||||||
AT_SETUP([[%nonassoc error actions for multiple reductions in a state]])
|
AT_SETUP([[%nonassoc error actions for multiple reductions in a state]])
|
||||||
|
|
||||||
|
AT_KEYWORDS([cex report])
|
||||||
|
|
||||||
AT_DATA([[input.y]],
|
AT_DATA([[input.y]],
|
||||||
[[%nonassoc 'a' 'b' 'c'
|
[[%nonassoc 'a' 'b' 'c'
|
||||||
%%
|
%%
|
||||||
@@ -1961,12 +1993,18 @@ AT_CHECK([[cat input.output | sed -n '/^State 0$/,/^State 1$/p']], 0,
|
|||||||
Conflict between rule 10 and token 'b' resolved as an error (%nonassoc 'b').
|
Conflict between rule 10 and token 'b' resolved as an error (%nonassoc 'b').
|
||||||
Conflict between rule 11 and token 'c' resolved as an error (%nonassoc 'c').
|
Conflict between rule 11 and token 'c' resolved as an error (%nonassoc 'c').
|
||||||
|
|
||||||
Reduce/reduce conflict on token 'c':
|
reduce/reduce conflict on token 'c':
|
||||||
12 empty_c2: . %empty
|
12 empty_c2: . %empty
|
||||||
13 empty_c3: . %empty
|
13 empty_c3: . %empty
|
||||||
Example . 'c'
|
Example: . 'c'
|
||||||
First derivation start ::=[ empty_c2 ::=[ . ] 'c' ]
|
First reduce derivation
|
||||||
Second derivation start ::=[ empty_c3 ::=[ . ] 'c' ]
|
start
|
||||||
|
`-> empty_c2 'c'
|
||||||
|
`-> .
|
||||||
|
Second reduce derivation
|
||||||
|
start
|
||||||
|
`-> empty_c3 'c'
|
||||||
|
`-> .
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -2000,7 +2038,7 @@ exp: 'a' | 'a';
|
|||||||
AT_BISON_CHECK([[2.y]], [[0]], [],
|
AT_BISON_CHECK([[2.y]], [[0]], [],
|
||||||
[[2.y: warning: %expect-rr applies only to GLR parsers [-Wother]
|
[[2.y: warning: %expect-rr applies only to GLR parsers [-Wother]
|
||||||
2.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
|
2.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
|
||||||
2.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
|
2.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
|
||||||
2.y:3.12-14: warning: rule useless in parser due to conflicts [-Wother]
|
2.y:3.12-14: warning: rule useless in parser due to conflicts [-Wother]
|
||||||
]])
|
]])
|
||||||
|
|
||||||
@@ -2037,15 +2075,14 @@ B: ;
|
|||||||
AT_BISON_CHECK([[sr-rr.y]], [[0]], [[]],
|
AT_BISON_CHECK([[sr-rr.y]], [[0]], [[]],
|
||||||
[[sr-rr.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
|
[[sr-rr.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
|
||||||
sr-rr.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
|
sr-rr.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
|
||||||
sr-rr.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
|
sr-rr.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
|
||||||
]])
|
]])
|
||||||
AT_BISON_CHECK([[-Wno-conflicts-sr sr-rr.y]], [[0]], [[]],
|
AT_BISON_CHECK([[-Wno-conflicts-sr sr-rr.y]], [[0]], [[]],
|
||||||
[[sr-rr.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
|
[[sr-rr.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
|
||||||
sr-rr.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
|
sr-rr.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
|
||||||
]])
|
]])
|
||||||
AT_BISON_CHECK([[-Wno-conflicts-rr sr-rr.y]], [[0]], [[]],
|
AT_BISON_CHECK([[-Wno-conflicts-rr sr-rr.y]], [[0]], [[]],
|
||||||
[[sr-rr.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
|
[[sr-rr.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
|
||||||
sr-rr.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
|
|
||||||
]])
|
]])
|
||||||
|
|
||||||
[
|
[
|
||||||
@@ -2102,19 +2139,30 @@ for gram in sr-rr sr rr; do
|
|||||||
]AT_BISON_CHECK([[-Werror $file]])[
|
]AT_BISON_CHECK([[-Werror $file]])[
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
issue_note=false
|
||||||
if test -z "$sr_exp_i" && test "$sr_count" -ne 0; then
|
if test -z "$sr_exp_i" && test "$sr_count" -ne 0; then
|
||||||
echo "warning: $sr_count shift/reduce conflicts"
|
echo "warning: $sr_count shift/reduce conflicts"
|
||||||
|
issue_note=true
|
||||||
elif test "$sr_exp_i" -ne "$sr_count"; then
|
elif test "$sr_exp_i" -ne "$sr_count"; then
|
||||||
echo "error: shift/reduce conflicts: $sr_count found, $sr_exp_i expected"
|
echo "error: shift/reduce conflicts: $sr_count found, $sr_exp_i expected"
|
||||||
|
if test "$sr_count" -ne 0; then
|
||||||
|
issue_note=true
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
if test -z "$rr_exp_i" && test "$rr_count" -ne 0; then
|
if test -z "$rr_exp_i" && test "$rr_count" -ne 0; then
|
||||||
echo "warning: $rr_count reduce/reduce conflicts"
|
echo "warning: $rr_count reduce/reduce conflicts"
|
||||||
|
issue_note=true
|
||||||
elif test "$rr_exp_i" -ne "$rr_count"; then
|
elif test "$rr_exp_i" -ne "$rr_count"; then
|
||||||
echo "error: reduce/reduce conflicts: $rr_count found, $rr_exp_i expected"
|
echo "error: reduce/reduce conflicts: $rr_count found, $rr_exp_i expected"
|
||||||
|
if test "$rr_count" -ne 0; then
|
||||||
|
issue_note=true
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
if $issue_note; then
|
||||||
|
echo "note: rerun with option '-Wcounterexamples' to generate conflict counterexamples"
|
||||||
fi
|
fi
|
||||||
} | sed -e "s/^/$file: /" > experr
|
} | sed -e "s/^/$file: /" > experr
|
||||||
]AT_BISON_CHECK([[-Wnone $file]], [[1]], [[]], [[experr]])[
|
]AT_BISON_CHECK([[-Wnone $file]], [[1]], [[]], [[experr]])[
|
||||||
echo "$file: error: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Werror=other]" >> experr
|
|
||||||
]AT_BISON_CHECK([[-Werror $file]], [[1]], [[]], [[experr]])[
|
]AT_BISON_CHECK([[-Werror $file]], [[1]], [[]], [[experr]])[
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|||||||
+559
-183
@@ -17,13 +17,23 @@
|
|||||||
|
|
||||||
AT_BANNER([[Counterexamples.]])
|
AT_BANNER([[Counterexamples.]])
|
||||||
|
|
||||||
|
# AT_BISON_CHECK_CEX(TREE, FLAT)
|
||||||
|
# ------------------------------
|
||||||
m4_define([AT_BISON_CHECK_CEX],
|
m4_define([AT_BISON_CHECK_CEX],
|
||||||
[AT_DATA([experr], [$4])
|
[AT_KEYWORDS([cex])
|
||||||
sed -e ['s/time limit exceeded: [0-9][.0-9]*/time limit exceeded: XXX/g'] \
|
|
||||||
experr >expout
|
AT_BISON_CHECK([-Wcounterexamples input.y], [0], [], [stderr])
|
||||||
AT_BISON_CHECK([-Wcounterexamples $1], [$2], [$3], [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]],
|
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_SETUP([Unifying S/R])
|
||||||
AT_KEYWORDS([cex])
|
|
||||||
|
|
||||||
AT_DATA([[input.y]],
|
AT_DATA([[input.y]],
|
||||||
[[%token A B C
|
[[%token A B C
|
||||||
@@ -43,13 +52,25 @@ x: B | B C;
|
|||||||
y: A | A B;
|
y: A | A B;
|
||||||
]])
|
]])
|
||||||
|
|
||||||
AT_BISON_CHECK_CEX([input.y], [], [],
|
AT_BISON_CHECK_CEX(
|
||||||
[[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
|
[[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
|
||||||
Shift/reduce conflict on token B:
|
input.y: warning: shift/reduce conflict on token B [-Wcounterexamples]
|
||||||
Example A . B C
|
Example: A . B C
|
||||||
First derivation s ::=[ a ::=[ A . ] x ::=[ B C ] ]
|
Shift derivation
|
||||||
Second derivation s ::=[ y ::=[ A . B ] c ::=[ C ] ]
|
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]
|
||||||
|
input.y: warning: shift/reduce conflict on token B [-Wcounterexamples]
|
||||||
|
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]
|
input.y:4.4: warning: rule useless in parser due to conflicts [-Wother]
|
||||||
]])
|
]])
|
||||||
|
|
||||||
@@ -60,7 +81,6 @@ AT_CLEANUP
|
|||||||
## ------------------- ##
|
## ------------------- ##
|
||||||
|
|
||||||
AT_SETUP([Deep Unifying S/R])
|
AT_SETUP([Deep Unifying S/R])
|
||||||
AT_KEYWORDS([cex])
|
|
||||||
|
|
||||||
AT_DATA([[input.y]],
|
AT_DATA([[input.y]],
|
||||||
[[%token A B C
|
[[%token A B C
|
||||||
@@ -72,18 +92,46 @@ a: A | A a;
|
|||||||
bc: B bc C | B C;
|
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]
|
[[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
|
||||||
Shift/reduce conflict on token B:
|
input.y: warning: shift/reduce conflict on token B [-Wcounterexamples]
|
||||||
Example A . B C
|
Example: A . B C
|
||||||
First derivation s ::=[ a ::=[ A . ] bc ::=[ B C ] ]
|
Shift derivation
|
||||||
Second derivation s ::=[ ac ::=[ A ac ::=[ b ::=[ . B ] ] C ] ]
|
s
|
||||||
|
`-> ac
|
||||||
Shift/reduce conflict on token B:
|
`-> A ac C
|
||||||
Example A A . B B C C
|
`-> b
|
||||||
First derivation s ::=[ a ::=[ A a ::=[ A . ] ] bc ::=[ B bc ::=[ B C ] C ] ]
|
`-> . B
|
||||||
Second derivation s ::=[ ac ::=[ A ac ::=[ A ac ::=[ b ::=[ . b ::=[ B B ] ] ] C ] C ] ]
|
Reduce derivation
|
||||||
|
s
|
||||||
|
`-> a bc
|
||||||
|
`-> A . `-> B C
|
||||||
|
input.y: warning: shift/reduce conflict on token B [-Wcounterexamples]
|
||||||
|
Example: A A . 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]
|
||||||
|
input.y: warning: shift/reduce conflict on token B [-Wcounterexamples]
|
||||||
|
Example A . B C
|
||||||
|
Shift derivation s -> [ ac -> [ A ac -> [ b -> [ . B ] ] C ] ]
|
||||||
|
Reduce derivation s -> [ a -> [ A . ] bc -> [ B C ] ]
|
||||||
|
input.y: warning: shift/reduce conflict on token B [-Wcounterexamples]
|
||||||
|
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]
|
input.y:6.4: warning: rule useless in parser due to conflicts [-Wother]
|
||||||
]])
|
]])
|
||||||
|
|
||||||
@@ -94,7 +142,6 @@ AT_CLEANUP
|
|||||||
## ------------------------------------ ##
|
## ------------------------------------ ##
|
||||||
|
|
||||||
AT_SETUP([S/R Conflict with Nullable Symbols])
|
AT_SETUP([S/R Conflict with Nullable Symbols])
|
||||||
AT_KEYWORDS([cex])
|
|
||||||
|
|
||||||
AT_DATA([[input.y]],
|
AT_DATA([[input.y]],
|
||||||
[[%token A B X Y
|
[[%token A B X Y
|
||||||
@@ -107,19 +154,47 @@ y: %empty | Y y;
|
|||||||
xby: B | X xby 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]
|
[[input.y: warning: 2 shift/reduce conflicts [-Wconflicts-sr]
|
||||||
Shift/reduce conflict on token B:
|
input.y: warning: shift/reduce conflict on token B [-Wcounterexamples]
|
||||||
Example A . B
|
Example: A . B
|
||||||
First derivation s ::=[ ax ::=[ A x ::=[ . ] ] by ::=[ B y ::=[ ] ] ]
|
Shift derivation
|
||||||
Second derivation s ::=[ A xby ::=[ . B ] ]
|
s
|
||||||
|
`-> A xby
|
||||||
Shift/reduce conflict on token B:
|
`-> . B
|
||||||
First example A X . B y $end
|
Reduce derivation
|
||||||
First derivation $accept ::=[ s ::=[ ax ::=[ A x ::=[ X x ::=[ . ] ] ] by ::=[ B y ] ] $end ]
|
s
|
||||||
Second example A X . B Y $end
|
`-> ax by
|
||||||
Second derivation $accept ::=[ s ::=[ A xby ::=[ X xby ::=[ . B ] Y ] ] $end ]
|
`-> A x `-> B y
|
||||||
|
`-> . `-> %empty
|
||||||
|
input.y: warning: shift/reduce conflict on token B [-Wcounterexamples]
|
||||||
|
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]
|
||||||
|
input.y: warning: shift/reduce conflict on token B [-Wcounterexamples]
|
||||||
|
Example A . B
|
||||||
|
Shift derivation s -> [ A xby -> [ . B ] ]
|
||||||
|
Reduce derivation s -> [ ax -> [ A x -> [ . ] ] by -> [ B y -> [ ] ] ]
|
||||||
|
input.y: warning: shift/reduce conflict on token B [-Wcounterexamples]
|
||||||
|
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]
|
input.y:5.4-9: warning: rule useless in parser due to conflicts [-Wother]
|
||||||
]])
|
]])
|
||||||
|
|
||||||
@@ -130,7 +205,6 @@ AT_CLEANUP
|
|||||||
## ---------------------------- ##
|
## ---------------------------- ##
|
||||||
|
|
||||||
AT_SETUP([Non-unifying Ambiguous S/R])
|
AT_SETUP([Non-unifying Ambiguous S/R])
|
||||||
AT_KEYWORDS([cex])
|
|
||||||
|
|
||||||
AT_DATA([[input.y]],
|
AT_DATA([[input.y]],
|
||||||
[[%token A B C D E
|
[[%token A B C D E
|
||||||
@@ -143,14 +217,31 @@ cd: C D;
|
|||||||
bc: B C;
|
bc: B C;
|
||||||
]])
|
]])
|
||||||
|
|
||||||
AT_BISON_CHECK_CEX([input.y], [], [],
|
AT_BISON_CHECK_CEX(
|
||||||
[[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
|
[[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
|
||||||
Shift/reduce conflict on token C:
|
input.y: warning: shift/reduce conflict on token C [-Wcounterexamples]
|
||||||
First example B . C D $end
|
First example: B . C $end
|
||||||
First derivation $accept ::=[ g ::=[ x ::=[ b ::=[ B . ] cd ::=[ C D ] ] ] $end ]
|
Shift derivation
|
||||||
Second example B . C $end
|
$accept
|
||||||
Second derivation $accept ::=[ g ::=[ x ::=[ bc ::=[ B . C ] ] ] $end ]
|
`-> 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]
|
||||||
|
input.y: warning: shift/reduce conflict on token C [-Wcounterexamples]
|
||||||
|
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]
|
input.y:6.4: warning: rule useless in parser due to conflicts [-Wother]
|
||||||
]])
|
]])
|
||||||
|
|
||||||
@@ -161,7 +252,6 @@ AT_CLEANUP
|
|||||||
## ------------------------------ ##
|
## ------------------------------ ##
|
||||||
|
|
||||||
AT_SETUP([Non-unifying Unambiguous S/R])
|
AT_SETUP([Non-unifying Unambiguous S/R])
|
||||||
AT_KEYWORDS([cex])
|
|
||||||
|
|
||||||
AT_DATA([[input.y]],
|
AT_DATA([[input.y]],
|
||||||
[[%token A B
|
[[%token A B
|
||||||
@@ -172,14 +262,31 @@ x: A;
|
|||||||
y: A A B;
|
y: A A B;
|
||||||
]])
|
]])
|
||||||
|
|
||||||
AT_BISON_CHECK_CEX([input.y], [], [],
|
AT_BISON_CHECK_CEX(
|
||||||
[[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
|
[[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
|
||||||
Shift/reduce conflict on token A:
|
input.y: warning: shift/reduce conflict on token A [-Wcounterexamples]
|
||||||
First example A . A $end
|
First example: A . A B $end
|
||||||
First derivation $accept ::=[ s ::=[ s ::=[ t ::=[ x ::=[ A . ] ] ] t ::=[ x ::=[ A ] ] ] $end ]
|
Shift derivation
|
||||||
Second example A . A B $end
|
$accept
|
||||||
Second derivation $accept ::=[ s ::=[ t ::=[ y ::=[ A . A B ] ] ] $end ]
|
`-> 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]
|
||||||
|
input.y: warning: shift/reduce conflict on token A [-Wcounterexamples]
|
||||||
|
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 ]
|
||||||
]])
|
]])
|
||||||
|
|
||||||
AT_CLEANUP
|
AT_CLEANUP
|
||||||
@@ -189,7 +296,6 @@ AT_CLEANUP
|
|||||||
## ----------------------- ##
|
## ----------------------- ##
|
||||||
|
|
||||||
AT_SETUP([S/R after first token])
|
AT_SETUP([S/R after first token])
|
||||||
AT_KEYWORDS([cex])
|
|
||||||
|
|
||||||
AT_DATA([[input.y]],
|
AT_DATA([[input.y]],
|
||||||
[[%token A B X Y
|
[[%token A B X Y
|
||||||
@@ -205,19 +311,45 @@ xy: X Y;
|
|||||||
y: Y;
|
y: Y;
|
||||||
]])
|
]])
|
||||||
|
|
||||||
AT_BISON_CHECK_CEX([input.y], [], [],
|
AT_BISON_CHECK_CEX(
|
||||||
[[input.y: warning: 2 shift/reduce conflicts [-Wconflicts-sr]
|
[[input.y: warning: 2 shift/reduce conflicts [-Wconflicts-sr]
|
||||||
Shift/reduce conflict on token A:
|
input.y: warning: shift/reduce conflict on token A [-Wcounterexamples]
|
||||||
Example b . A X X Y
|
Example: b . A X X Y
|
||||||
First derivation a ::=[ r ::=[ b . ] t ::=[ A x ::=[ X ] xy ::=[ X Y ] ] ]
|
Shift derivation
|
||||||
Second derivation a ::=[ s ::=[ b . xx ::=[ A X X ] y ::=[ Y ] ] ]
|
a
|
||||||
|
`-> s
|
||||||
Shift/reduce conflict on token X:
|
`-> b . xx y
|
||||||
First example X . X xy
|
`-> A X X `-> Y
|
||||||
First derivation a ::=[ x ::=[ X . ] t ::=[ X xy ] ]
|
Reduce derivation
|
||||||
Second example A X . X
|
a
|
||||||
Second derivation a ::=[ t ::=[ A xx ::=[ X . X ] ] ]
|
`-> r t
|
||||||
|
`-> b . `-> A x xy
|
||||||
|
`-> X `-> X Y
|
||||||
|
input.y: warning: shift/reduce conflict on token X [-Wcounterexamples]
|
||||||
|
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]
|
||||||
|
input.y: warning: shift/reduce conflict on token A [-Wcounterexamples]
|
||||||
|
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 ] ] ]
|
||||||
|
input.y: warning: shift/reduce conflict on token X [-Wcounterexamples]
|
||||||
|
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: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:8.4: warning: rule useless in parser due to conflicts [-Wother]
|
||||||
]])
|
]])
|
||||||
@@ -229,7 +361,6 @@ AT_CLEANUP
|
|||||||
## ----------------------------- ##
|
## ----------------------------- ##
|
||||||
|
|
||||||
AT_SETUP([Unifying R/R counterexample])
|
AT_SETUP([Unifying R/R counterexample])
|
||||||
AT_KEYWORDS([cex])
|
|
||||||
|
|
||||||
AT_DATA([[input.y]],
|
AT_DATA([[input.y]],
|
||||||
[[%token A
|
[[%token A
|
||||||
@@ -238,13 +369,24 @@ a : A b ;
|
|||||||
b : A | b;
|
b : A | b;
|
||||||
]])
|
]])
|
||||||
|
|
||||||
AT_BISON_CHECK_CEX([input.y], [], [],
|
AT_BISON_CHECK_CEX(
|
||||||
[[input.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
|
[[input.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
|
||||||
Reduce/reduce conflict on token $end:
|
input.y: warning: reduce/reduce conflict on token $end [-Wcounterexamples]
|
||||||
Example A b .
|
Example: A b .
|
||||||
First derivation a ::=[ A b . ]
|
First reduce derivation
|
||||||
Second derivation a ::=[ A b ::=[ b . ] ]
|
a
|
||||||
|
`-> A b .
|
||||||
|
Second reduce 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]
|
||||||
|
input.y: warning: reduce/reduce conflict on token $end [-Wcounterexamples]
|
||||||
|
Example A b .
|
||||||
|
First reduce derivation a -> [ A b . ]
|
||||||
|
Second reduce derivation a -> [ A b -> [ b . ] ]
|
||||||
input.y:4.9: warning: rule useless in parser due to conflicts [-Wother]
|
input.y:4.9: warning: rule useless in parser due to conflicts [-Wother]
|
||||||
]])
|
]])
|
||||||
|
|
||||||
@@ -255,7 +397,6 @@ AT_CLEANUP
|
|||||||
## --------------------------------- ##
|
## --------------------------------- ##
|
||||||
|
|
||||||
AT_SETUP([Non-unifying R/R LR(1) conflict])
|
AT_SETUP([Non-unifying R/R LR(1) conflict])
|
||||||
AT_KEYWORDS([cex])
|
|
||||||
|
|
||||||
AT_DATA([[input.y]],
|
AT_DATA([[input.y]],
|
||||||
[[%token A B C D
|
[[%token A B C D
|
||||||
@@ -265,14 +406,29 @@ a: D;
|
|||||||
b: D;
|
b: D;
|
||||||
]])
|
]])
|
||||||
|
|
||||||
AT_BISON_CHECK_CEX([input.y], [], [],
|
AT_BISON_CHECK_CEX(
|
||||||
[[input.y: warning: 2 reduce/reduce conflicts [-Wconflicts-rr]
|
[[input.y: warning: 2 reduce/reduce conflicts [-Wconflicts-rr]
|
||||||
Reduce/reduce conflict on tokens A, C:
|
input.y: warning: reduce/reduce conflict on tokens A, C [-Wcounterexamples]
|
||||||
First example D . A $end
|
First example: D . A $end
|
||||||
First derivation $accept ::=[ s ::=[ a ::=[ D . ] A ] $end ]
|
First reduce derivation
|
||||||
Second example B D . A $end
|
$accept
|
||||||
Second derivation $accept ::=[ s ::=[ B b ::=[ D . ] A ] $end ]
|
`-> s $end
|
||||||
|
`-> a A
|
||||||
|
`-> D .
|
||||||
|
Second example: B D . A $end
|
||||||
|
Second reduce 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]
|
||||||
|
input.y: warning: reduce/reduce conflict on tokens A, C [-Wcounterexamples]
|
||||||
|
First example D . A $end
|
||||||
|
First reduce derivation $accept -> [ s -> [ a -> [ D . ] A ] $end ]
|
||||||
|
Second example B D . A $end
|
||||||
|
Second reduce derivation $accept -> [ s -> [ B b -> [ D . ] A ] $end ]
|
||||||
input.y:5.4: warning: rule useless in parser due to conflicts [-Wother]
|
input.y:5.4: warning: rule useless in parser due to conflicts [-Wother]
|
||||||
]])
|
]])
|
||||||
|
|
||||||
@@ -283,7 +439,6 @@ AT_CLEANUP
|
|||||||
## --------------------------------- ##
|
## --------------------------------- ##
|
||||||
|
|
||||||
AT_SETUP([Non-unifying R/R LR(2) conflict])
|
AT_SETUP([Non-unifying R/R LR(2) conflict])
|
||||||
AT_KEYWORDS([cex])
|
|
||||||
|
|
||||||
AT_DATA([[input.y]],
|
AT_DATA([[input.y]],
|
||||||
[[%token H J K X
|
[[%token H J K X
|
||||||
@@ -293,15 +448,31 @@ a: H i;
|
|||||||
i: X | i J K;
|
i: X | i J K;
|
||||||
]])
|
]])
|
||||||
|
|
||||||
AT_BISON_CHECK_CEX([input.y], [], [],
|
AT_BISON_CHECK_CEX(
|
||||||
[[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
|
[[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
|
||||||
Shift/reduce conflict on token J:
|
input.y: warning: shift/reduce conflict on token J [-Wcounterexamples]
|
||||||
time limit exceeded: XXX
|
time limit exceeded: XXX
|
||||||
First example H i . J $end
|
First example: H i . J K $end
|
||||||
First derivation $accept ::=[ s ::=[ a ::=[ H i . ] J ] $end ]
|
Shift derivation
|
||||||
Second example H i . J K $end
|
$accept
|
||||||
Second derivation $accept ::=[ a ::=[ H i ::=[ i . J K ] ] $end ]
|
`-> 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]
|
||||||
|
input.y: warning: shift/reduce conflict on token J [-Wcounterexamples]
|
||||||
|
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]
|
input.y:4.4-6: warning: rule useless in parser due to conflicts [-Wother]
|
||||||
]])
|
]])
|
||||||
|
|
||||||
@@ -315,7 +486,6 @@ AT_CLEANUP
|
|||||||
# graph search
|
# graph search
|
||||||
|
|
||||||
AT_SETUP([Cex Search Prepend])
|
AT_SETUP([Cex Search Prepend])
|
||||||
AT_KEYWORDS([cex])
|
|
||||||
|
|
||||||
AT_DATA([[input.y]],
|
AT_DATA([[input.y]],
|
||||||
[[%token N A B C D
|
[[%token N A B C D
|
||||||
@@ -326,18 +496,45 @@ a: A;
|
|||||||
b: A B C | A B D;
|
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]
|
[[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
|
||||||
Shift/reduce conflict on token B:
|
input.y: warning: shift/reduce conflict on token B [-Wcounterexamples]
|
||||||
Example N A . B C
|
Example: N A . B C
|
||||||
First derivation s ::=[ n ::=[ N a ::=[ A . ] B ] C ]
|
Shift derivation
|
||||||
Second derivation s ::=[ n ::=[ N b ::=[ A . B C ] ] ]
|
s
|
||||||
|
`-> n
|
||||||
Shift/reduce conflict on token B:
|
`-> N b
|
||||||
Example N N A . B D C
|
`-> A . B C
|
||||||
First derivation s ::=[ n ::=[ N n ::=[ N a ::=[ A . ] B ] D ] C ]
|
Reduce derivation
|
||||||
Second derivation s ::=[ n ::=[ N n ::=[ N b ::=[ A . B D ] ] C ] ]
|
s
|
||||||
|
`-> n C
|
||||||
|
`-> N a B
|
||||||
|
`-> A .
|
||||||
|
input.y: warning: shift/reduce conflict on token B [-Wcounterexamples]
|
||||||
|
Example: N N 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]
|
||||||
|
input.y: warning: shift/reduce conflict on token B [-Wcounterexamples]
|
||||||
|
Example N A . B C
|
||||||
|
Shift derivation s -> [ n -> [ N b -> [ A . B C ] ] ]
|
||||||
|
Reduce derivation s -> [ n -> [ N a -> [ A . ] B ] C ]
|
||||||
|
input.y: warning: shift/reduce conflict on token B [-Wcounterexamples]
|
||||||
|
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]
|
input.y:5.4: warning: rule useless in parser due to conflicts [-Wother]
|
||||||
]])
|
]])
|
||||||
|
|
||||||
@@ -351,7 +548,6 @@ AT_CLEANUP
|
|||||||
# precedence/associativity directives work.
|
# precedence/associativity directives work.
|
||||||
|
|
||||||
AT_SETUP([R/R cex with prec])
|
AT_SETUP([R/R cex with prec])
|
||||||
AT_KEYWORDS([cex])
|
|
||||||
|
|
||||||
AT_DATA([[input.y]],
|
AT_DATA([[input.y]],
|
||||||
[[%left b
|
[[%left b
|
||||||
@@ -363,18 +559,46 @@ B : A b A;
|
|||||||
C : A c A;
|
C : A c A;
|
||||||
]])
|
]])
|
||||||
|
|
||||||
AT_BISON_CHECK_CEX([input.y], [], [],
|
AT_BISON_CHECK_CEX(
|
||||||
[[input.y: warning: 4 reduce/reduce conflicts [-Wconflicts-rr]
|
[[input.y: warning: 4 reduce/reduce conflicts [-Wconflicts-rr]
|
||||||
Reduce/reduce conflict on tokens b, c:
|
input.y: warning: reduce/reduce conflict on tokens b, c [-Wcounterexamples]
|
||||||
Example B . b c
|
Example: B . b c
|
||||||
First derivation S ::=[ B ::=[ A ::=[ B . ] b A ::=[ ] ] C ::=[ A ::=[ ] c A ::=[ ] ] ]
|
First reduce derivation
|
||||||
Second derivation S ::=[ B C ::=[ A ::=[ B ::=[ A ::=[ . ] b A ::=[ ] ] ] c A ::=[ ] ] ]
|
S
|
||||||
|
`-> B C
|
||||||
Reduce/reduce conflict on tokens b, c:
|
`-> A b A `-> A c A
|
||||||
Example C . c b
|
`-> B . `-> %empty `-> %empty `-> %empty
|
||||||
First derivation S ::=[ C ::=[ A ::=[ C . ] c A ::=[ ] ] B ::=[ A ::=[ ] b A ::=[ ] ] ]
|
Second reduce derivation
|
||||||
Second derivation S ::=[ C B ::=[ A ::=[ C ::=[ A ::=[ . ] c A ::=[ ] ] ] b A ::=[ ] ] ]
|
S
|
||||||
|
`-> B C
|
||||||
|
`-> A c A
|
||||||
|
`-> B `-> %empty
|
||||||
|
`-> A b A
|
||||||
|
`-> . `-> %empty
|
||||||
|
input.y: warning: reduce/reduce conflict on tokens b, c [-Wcounterexamples]
|
||||||
|
Example: C . c b
|
||||||
|
First reduce derivation
|
||||||
|
S
|
||||||
|
`-> C B
|
||||||
|
`-> A c A `-> A b A
|
||||||
|
`-> C . `-> %empty `-> %empty `-> %empty
|
||||||
|
Second reduce derivation
|
||||||
|
S
|
||||||
|
`-> C B
|
||||||
|
`-> A b A
|
||||||
|
`-> C `-> %empty
|
||||||
|
`-> A c A
|
||||||
|
`-> . `-> %empty
|
||||||
|
]],
|
||||||
|
[[input.y: warning: 4 reduce/reduce conflicts [-Wconflicts-rr]
|
||||||
|
input.y: warning: reduce/reduce conflict on tokens b, c [-Wcounterexamples]
|
||||||
|
Example B . b c
|
||||||
|
First reduce derivation S -> [ B -> [ A -> [ B . ] b A -> [ ] ] C -> [ A -> [ ] c A -> [ ] ] ]
|
||||||
|
Second reduce derivation S -> [ B C -> [ A -> [ B -> [ A -> [ . ] b A -> [ ] ] ] c A -> [ ] ] ]
|
||||||
|
input.y: warning: reduce/reduce conflict on tokens b, c [-Wcounterexamples]
|
||||||
|
Example C . c b
|
||||||
|
First reduce derivation S -> [ C -> [ A -> [ C . ] c A -> [ ] ] B -> [ A -> [ ] b A -> [ ] ] ]
|
||||||
|
Second reduce derivation S -> [ C B -> [ A -> [ C -> [ A -> [ . ] c A -> [ ] ] ] b A -> [ ] ] ]
|
||||||
]])
|
]])
|
||||||
|
|
||||||
AT_CLEANUP
|
AT_CLEANUP
|
||||||
@@ -384,7 +608,6 @@ AT_CLEANUP
|
|||||||
## ------------------- ##
|
## ------------------- ##
|
||||||
|
|
||||||
AT_SETUP([Null nonterminals])
|
AT_SETUP([Null nonterminals])
|
||||||
AT_KEYWORDS([cex])
|
|
||||||
|
|
||||||
AT_DATA([[input.y]],
|
AT_DATA([[input.y]],
|
||||||
[[%token A
|
[[%token A
|
||||||
@@ -395,58 +618,172 @@ c : ;
|
|||||||
d : a | c A | d;
|
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: 1 shift/reduce conflict [-Wconflicts-sr]
|
||||||
input.y: warning: 6 reduce/reduce conflicts [-Wconflicts-rr]
|
input.y: warning: 6 reduce/reduce conflicts [-Wconflicts-rr]
|
||||||
Reduce/reduce conflict on token A:
|
input.y: warning: reduce/reduce conflict on token A [-Wcounterexamples]
|
||||||
First example . c A A $end
|
First example: . c A A $end
|
||||||
First derivation $accept ::=[ a ::=[ b ::=[ . ] d ::=[ c A A ] ] $end ]
|
First reduce derivation
|
||||||
Second example . c A A $end
|
$accept
|
||||||
Second derivation $accept ::=[ a ::=[ c ::=[ . ] d ::=[ c A A ] ] $end ]
|
`-> a $end
|
||||||
|
`-> b d
|
||||||
Reduce/reduce conflict on token A:
|
`-> . `-> c A A
|
||||||
|
Second example: . c A A $end
|
||||||
|
Second reduce derivation
|
||||||
|
$accept
|
||||||
|
`-> a $end
|
||||||
|
`-> c d
|
||||||
|
`-> . `-> c A A
|
||||||
|
input.y: warning: reduce/reduce conflict on token A [-Wcounterexamples]
|
||||||
time limit exceeded: XXX
|
time limit exceeded: XXX
|
||||||
First example b . c A A $end
|
First example: b . c A A $end
|
||||||
First derivation $accept ::=[ a ::=[ b d ::=[ a ::=[ b ::=[ . ] d ::=[ c A A ] ] ] ] $end ]
|
First reduce derivation
|
||||||
Second example b . A $end
|
$accept
|
||||||
Second derivation $accept ::=[ a ::=[ b d ::=[ c ::=[ . ] A ] ] $end ]
|
`-> a $end
|
||||||
|
`-> b d
|
||||||
Reduce/reduce conflict on token A:
|
`-> a
|
||||||
|
`-> b d
|
||||||
|
`-> . `-> c A A
|
||||||
|
Second example: b . A $end
|
||||||
|
Second reduce derivation
|
||||||
|
$accept
|
||||||
|
`-> a $end
|
||||||
|
`-> b d
|
||||||
|
`-> c A
|
||||||
|
`-> .
|
||||||
|
input.y: warning: reduce/reduce conflict on token A [-Wcounterexamples]
|
||||||
time limit exceeded: XXX
|
time limit exceeded: XXX
|
||||||
First example c . c A A $end
|
First example: c . c A A $end
|
||||||
First derivation $accept ::=[ a ::=[ c d ::=[ a ::=[ b ::=[ . ] d ::=[ c A A ] ] ] ] $end ]
|
First reduce derivation
|
||||||
Second example c . A $end
|
$accept
|
||||||
Second derivation $accept ::=[ a ::=[ c d ::=[ c ::=[ . ] A ] ] $end ]
|
`-> a $end
|
||||||
|
`-> c d
|
||||||
Shift/reduce conflict on token A:
|
`-> a
|
||||||
|
`-> b d
|
||||||
|
`-> . `-> c A A
|
||||||
|
Second example: c . A $end
|
||||||
|
Second reduce derivation
|
||||||
|
$accept
|
||||||
|
`-> a $end
|
||||||
|
`-> c d
|
||||||
|
`-> c A
|
||||||
|
`-> .
|
||||||
|
input.y: warning: shift/reduce conflict on token A [-Wcounterexamples]
|
||||||
time limit exceeded: XXX
|
time limit exceeded: XXX
|
||||||
First example b c . c A A $end
|
First example: b c . A
|
||||||
First derivation $accept ::=[ a ::=[ b d ::=[ a ::=[ c d ::=[ a ::=[ b ::=[ . ] d ::=[ c A A ] ] ] ] ] ] $end ]
|
Shift derivation
|
||||||
Second example b c . A
|
a
|
||||||
Second derivation a ::=[ b d ::=[ c . A ] ]
|
`-> b d
|
||||||
|
`-> c . A
|
||||||
Reduce/reduce conflict on token A:
|
Second example: b c . c A A $end
|
||||||
First example b c . c A A $end
|
Reduce derivation
|
||||||
First derivation $accept ::=[ a ::=[ b d ::=[ a ::=[ c d ::=[ a ::=[ b ::=[ . ] d ::=[ c A A ] ] ] ] ] ] $end ]
|
$accept
|
||||||
Second example b c . A $end
|
`-> a $end
|
||||||
Second derivation $accept ::=[ a ::=[ b d ::=[ a ::=[ c d ::=[ c ::=[ . ] A ] ] ] ] $end ]
|
`-> b d
|
||||||
|
`-> a
|
||||||
Shift/reduce conflict on token A:
|
`-> c d
|
||||||
First example b c . A $end
|
`-> a
|
||||||
First derivation $accept ::=[ a ::=[ b d ::=[ a ::=[ c d ::=[ c ::=[ . ] A ] ] ] ] $end ]
|
`-> b d
|
||||||
Second example b c . A
|
`-> . `-> c A A
|
||||||
Second derivation a ::=[ b d ::=[ c . A ] ]
|
input.y: warning: reduce/reduce conflict on token A [-Wcounterexamples]
|
||||||
|
First example: b c . c A A $end
|
||||||
Reduce/reduce conflict on token $end:
|
First reduce derivation
|
||||||
Example b d .
|
$accept
|
||||||
First derivation a ::=[ b d . ]
|
`-> a $end
|
||||||
Second derivation a ::=[ b d ::=[ d . ] ]
|
`-> b d
|
||||||
|
`-> a
|
||||||
Reduce/reduce conflict on token $end:
|
`-> c d
|
||||||
Example c d .
|
`-> a
|
||||||
First derivation a ::=[ c d . ]
|
`-> b d
|
||||||
Second derivation a ::=[ c d ::=[ d . ] ]
|
`-> . `-> c A A
|
||||||
|
Second example: b c . A $end
|
||||||
|
Second reduce derivation
|
||||||
|
$accept
|
||||||
|
`-> a $end
|
||||||
|
`-> b d
|
||||||
|
`-> a
|
||||||
|
`-> c d
|
||||||
|
`-> c A
|
||||||
|
`-> .
|
||||||
|
input.y: warning: shift/reduce conflict on token A [-Wcounterexamples]
|
||||||
|
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
|
||||||
|
`-> .
|
||||||
|
input.y: warning: reduce/reduce conflict on token $end [-Wcounterexamples]
|
||||||
|
Example: b d .
|
||||||
|
First reduce derivation
|
||||||
|
a
|
||||||
|
`-> b d .
|
||||||
|
Second reduce derivation
|
||||||
|
a
|
||||||
|
`-> b d
|
||||||
|
`-> d .
|
||||||
|
input.y: warning: reduce/reduce conflict on token $end [-Wcounterexamples]
|
||||||
|
Example: c d .
|
||||||
|
First reduce derivation
|
||||||
|
a
|
||||||
|
`-> c d .
|
||||||
|
Second reduce 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]
|
||||||
|
input.y: warning: reduce/reduce conflict on token A [-Wcounterexamples]
|
||||||
|
First example . c A A $end
|
||||||
|
First reduce derivation $accept -> [ a -> [ b -> [ . ] d -> [ c A A ] ] $end ]
|
||||||
|
Second example . c A A $end
|
||||||
|
Second reduce derivation $accept -> [ a -> [ c -> [ . ] d -> [ c A A ] ] $end ]
|
||||||
|
input.y: warning: reduce/reduce conflict on token A [-Wcounterexamples]
|
||||||
|
time limit exceeded: XXX
|
||||||
|
First example b . c A A $end
|
||||||
|
First reduce derivation $accept -> [ a -> [ b d -> [ a -> [ b -> [ . ] d -> [ c A A ] ] ] ] $end ]
|
||||||
|
Second example b . A $end
|
||||||
|
Second reduce derivation $accept -> [ a -> [ b d -> [ c -> [ . ] A ] ] $end ]
|
||||||
|
input.y: warning: reduce/reduce conflict on token A [-Wcounterexamples]
|
||||||
|
time limit exceeded: XXX
|
||||||
|
First example c . c A A $end
|
||||||
|
First reduce derivation $accept -> [ a -> [ c d -> [ a -> [ b -> [ . ] d -> [ c A A ] ] ] ] $end ]
|
||||||
|
Second example c . A $end
|
||||||
|
Second reduce derivation $accept -> [ a -> [ c d -> [ c -> [ . ] A ] ] $end ]
|
||||||
|
input.y: warning: shift/reduce conflict on token A [-Wcounterexamples]
|
||||||
|
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 ]
|
||||||
|
input.y: warning: reduce/reduce conflict on token A [-Wcounterexamples]
|
||||||
|
First example b c . c A A $end
|
||||||
|
First reduce derivation $accept -> [ a -> [ b d -> [ a -> [ c d -> [ a -> [ b -> [ . ] d -> [ c A A ] ] ] ] ] ] $end ]
|
||||||
|
Second example b c . A $end
|
||||||
|
Second reduce derivation $accept -> [ a -> [ b d -> [ a -> [ c d -> [ c -> [ . ] A ] ] ] ] $end ]
|
||||||
|
input.y: warning: shift/reduce conflict on token A [-Wcounterexamples]
|
||||||
|
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 ]
|
||||||
|
input.y: warning: reduce/reduce conflict on token $end [-Wcounterexamples]
|
||||||
|
Example b d .
|
||||||
|
First reduce derivation a -> [ b d . ]
|
||||||
|
Second reduce derivation a -> [ b d -> [ d . ] ]
|
||||||
|
input.y: warning: reduce/reduce conflict on token $end [-Wcounterexamples]
|
||||||
|
Example c d .
|
||||||
|
First reduce derivation a -> [ c d . ]
|
||||||
|
Second reduce derivation a -> [ c d -> [ d . ] ]
|
||||||
input.y:5.4: warning: rule useless in parser due to conflicts [-Wother]
|
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:6.15: warning: rule useless in parser due to conflicts [-Wother]
|
||||||
]])
|
]])
|
||||||
@@ -458,7 +795,6 @@ AT_CLEANUP
|
|||||||
## --------------------------- ##
|
## --------------------------- ##
|
||||||
|
|
||||||
AT_SETUP([Non-unifying Prefix Share])
|
AT_SETUP([Non-unifying Prefix Share])
|
||||||
AT_KEYWORDS([cex])
|
|
||||||
|
|
||||||
# Tests for a counterexample which should start its derivation
|
# Tests for a counterexample which should start its derivation
|
||||||
# at a shared symbol rather than the start symbol.
|
# at a shared symbol rather than the start symbol.
|
||||||
@@ -471,13 +807,26 @@ a: H i J J
|
|||||||
i: %empty | i J;
|
i: %empty | i J;
|
||||||
]])
|
]])
|
||||||
|
|
||||||
AT_BISON_CHECK_CEX([input.y], [], [],
|
AT_BISON_CHECK_CEX(
|
||||||
[[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
|
[[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
|
||||||
Shift/reduce conflict on token J:
|
input.y: warning: shift/reduce conflict on token J [-Wcounterexamples]
|
||||||
Example H i J . J J
|
Example: H i J . J J
|
||||||
First derivation s ::=[ a ::=[ H i ::=[ i J . ] J J ] ]
|
Shift derivation
|
||||||
Second derivation s ::=[ a ::=[ H i J . J ] J ]
|
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]
|
||||||
|
input.y: warning: shift/reduce conflict on token J [-Wcounterexamples]
|
||||||
|
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]
|
input.y:5.13-15: warning: rule useless in parser due to conflicts [-Wother]
|
||||||
]])
|
]])
|
||||||
|
|
||||||
@@ -491,7 +840,6 @@ AT_CLEANUP
|
|||||||
# are derived correctly.
|
# are derived correctly.
|
||||||
|
|
||||||
AT_SETUP([Deep Null Unifying])
|
AT_SETUP([Deep Null Unifying])
|
||||||
AT_KEYWORDS([cex])
|
|
||||||
|
|
||||||
AT_DATA([[input.y]],
|
AT_DATA([[input.y]],
|
||||||
[[%token A D
|
[[%token A D
|
||||||
@@ -503,13 +851,26 @@ c: %empty
|
|||||||
d: D;
|
d: D;
|
||||||
]])
|
]])
|
||||||
|
|
||||||
AT_BISON_CHECK_CEX([input.y], [], [],
|
AT_BISON_CHECK_CEX(
|
||||||
[[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
|
[[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
|
||||||
Shift/reduce conflict on token D:
|
input.y: warning: shift/reduce conflict on token D [-Wcounterexamples]
|
||||||
Example A a . D
|
Example: A a . D
|
||||||
First derivation s ::=[ A a a ::=[ b ::=[ c ::=[ . ] ] ] d ::=[ D ] ]
|
Shift derivation
|
||||||
Second derivation s ::=[ A a d ::=[ . D ] ]
|
s
|
||||||
|
`-> A a d
|
||||||
|
`-> . D
|
||||||
|
Reduce derivation
|
||||||
|
s
|
||||||
|
`-> A a a d
|
||||||
|
`-> b `-> D
|
||||||
|
`-> c
|
||||||
|
`-> .
|
||||||
|
]],
|
||||||
|
[[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
|
||||||
|
input.y: warning: shift/reduce conflict on token D [-Wcounterexamples]
|
||||||
|
Example A a . D
|
||||||
|
Shift derivation s -> [ A a d -> [ . D ] ]
|
||||||
|
Reduce derivation s -> [ A a a -> [ b -> [ c -> [ . ] ] ] d -> [ D ] ]
|
||||||
]])
|
]])
|
||||||
|
|
||||||
AT_CLEANUP
|
AT_CLEANUP
|
||||||
@@ -521,7 +882,6 @@ AT_CLEANUP
|
|||||||
# Tests that expand_to_conflict works with nullable sybols
|
# Tests that expand_to_conflict works with nullable sybols
|
||||||
|
|
||||||
AT_SETUP([Deep Null Non-unifying])
|
AT_SETUP([Deep Null Non-unifying])
|
||||||
AT_KEYWORDS([cex])
|
|
||||||
|
|
||||||
AT_DATA([[input.y]],
|
AT_DATA([[input.y]],
|
||||||
[[%token A D E
|
[[%token A D E
|
||||||
@@ -533,14 +893,30 @@ c: %empty
|
|||||||
d: D;
|
d: D;
|
||||||
]])
|
]])
|
||||||
|
|
||||||
AT_BISON_CHECK_CEX([input.y], [], [],
|
AT_BISON_CHECK_CEX(
|
||||||
[[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
|
[[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
|
||||||
Shift/reduce conflict on token D:
|
input.y: warning: shift/reduce conflict on token D [-Wcounterexamples]
|
||||||
First example A a . D E $end
|
First example: A a . D $end
|
||||||
First derivation $accept ::=[ s ::=[ A a a ::=[ b ::=[ c ::=[ . ] ] ] d ::=[ D ] E ] $end ]
|
Shift derivation
|
||||||
Second example A a . D $end
|
$accept
|
||||||
Second derivation $accept ::=[ s ::=[ A a d ::=[ . D ] ] $end ]
|
`-> 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]
|
||||||
|
input.y: warning: shift/reduce conflict on token D [-Wcounterexamples]
|
||||||
|
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 ]
|
||||||
]])
|
]])
|
||||||
|
|
||||||
AT_CLEANUP
|
AT_CLEANUP
|
||||||
|
|||||||
+105
-26
@@ -28,6 +28,8 @@ m4_pushdef([AT_TEST],
|
|||||||
AT_SETUP([$1])
|
AT_SETUP([$1])
|
||||||
AT_KEYWORDS([diagnostics])
|
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
|
# We need UTF-8 support for correct screen-width computation of UTF-8
|
||||||
# characters. Skip the test if not available.
|
# characters. Skip the test if not available.
|
||||||
locale=`locale -a | $EGREP '^en_US\.(UTF-8|utf8)$' | sed 1q`
|
locale=`locale -a | $EGREP '^en_US\.(UTF-8|utf8)$' | sed 1q`
|
||||||
@@ -49,7 +51,7 @@ if $EGREP ['\^M|\\[0-9][0-9][0-9]'] input.y experr >/dev/null; then
|
|||||||
AT_PERL_REQUIRE([-pi -e 's{\^M}{\r}g;s{\\(\d{3}|.)}{$v = $[]1; $v =~ /\A\d+\z/ ? chr($v) : $v}ge' input.y experr])
|
AT_PERL_REQUIRE([-pi -e 's{\^M}{\r}g;s{\\(\d{3}|.)}{$v = $[]1; $v =~ /\A\d+\z/ ? chr($v) : $v}ge' input.y experr])
|
||||||
fi
|
fi
|
||||||
|
|
||||||
AT_CHECK([LC_ALL="$locale" $5 bison -fcaret --color=debug -Wall,cex input.y], [$3], [], [experr])
|
AT_CHECK(AT_SET_ENV [LC_ALL="$locale" $5 bison -fcaret --color=debug -Wall,cex input.y], [$3], [], [experr])
|
||||||
|
|
||||||
# When no style, same messages, but without style.
|
# When no style, same messages, but without style.
|
||||||
# Except for the second display of the counterexample,
|
# Except for the second display of the counterexample,
|
||||||
@@ -66,7 +68,7 @@ AT_PERL_REQUIRE([-pi -e '
|
|||||||
# Cannot use AT_BISON_CHECK easily as we need to change the
|
# Cannot use AT_BISON_CHECK easily as we need to change the
|
||||||
# environment.
|
# environment.
|
||||||
# FIXME: Enhance AT_BISON_CHECK.
|
# FIXME: Enhance AT_BISON_CHECK.
|
||||||
AT_CHECK([LC_ALL="$locale" $5 bison -fcaret -Wall,cex input.y], [$3], [], [experr])
|
AT_CHECK(AT_SET_ENV [LC_ALL="$locale" $5 bison -fcaret -Wall,cex input.y], [$3], [], [experr])
|
||||||
|
|
||||||
|
|
||||||
AT_BISON_OPTION_POPDEFS
|
AT_BISON_OPTION_POPDEFS
|
||||||
@@ -533,34 +535,111 @@ exp
|
|||||||
]],
|
]],
|
||||||
[1],
|
[1],
|
||||||
[[input.y: <error>error:</error> shift/reduce conflicts: 4 found, 0 expected
|
[[input.y: <error>error:</error> shift/reduce conflicts: 4 found, 0 expected
|
||||||
Shift/reduce conflict on token "+":
|
input.y: <warning>warning:</warning> shift/reduce conflict on token "+" [<warning>-Wcounterexamples</warning>]
|
||||||
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>
|
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>
|
||||||
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>
|
Shift derivation
|
||||||
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>
|
<cex-0><cex-step>exp</cex-step></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>
|
<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>
|
||||||
Shift/reduce conflict on token "else":
|
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>
|
||||||
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
|
||||||
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>
|
<cex-0><cex-step>exp</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>
|
<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>
|
||||||
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>
|
<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>
|
||||||
|
input.y: <warning>warning:</warning> shift/reduce conflict on token "else" [<warning>-Wcounterexamples</warning>]
|
||||||
Shift/reduce conflict on token "+":
|
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>
|
||||||
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>
|
Shift derivation
|
||||||
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>
|
<cex-0><cex-step>exp</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>
|
<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>
|
||||||
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>
|
<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>
|
||||||
Shift/reduce conflict on token "+":
|
Reduce derivation
|
||||||
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>
|
<cex-0><cex-step>exp</cex-step></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>
|
<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>
|
||||||
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>
|
<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>
|
||||||
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>
|
input.y: <warning>warning:</warning> shift/reduce conflict on token "+" [<warning>-Wcounterexamples</warning>]
|
||||||
|
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>
|
||||||
|
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>
|
||||||
|
input.y: <warning>warning:</warning> shift/reduce conflict on token "+" [<warning>-Wcounterexamples</warning>]
|
||||||
|
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>
|
||||||
|
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
|
||||||
|
input.y: <warning>warning:</warning> reduce/reduce conflict on token "X" [<warning>-Wcounterexamples</warning>]
|
||||||
|
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 reduce 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 reduce 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])
|
m4_popdef([AT_TEST])
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -434,7 +434,7 @@ input.y:323.10: warning: empty rule without %empty [-Wempty-rule]
|
|||||||
]AT_COND_CASE([[canonical LR]],
|
]AT_COND_CASE([[canonical LR]],
|
||||||
[[input.y: warning: 265 shift/reduce conflicts [-Wconflicts-sr]]],
|
[[input.y: warning: 265 shift/reduce conflicts [-Wconflicts-sr]]],
|
||||||
[[input.y: warning: 65 shift/reduce conflicts [-Wconflicts-sr]]])[
|
[[input.y: warning: 65 shift/reduce conflicts [-Wconflicts-sr]]])[
|
||||||
input.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
|
input.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
|
||||||
input.y:39.1-5: warning: useless associativity for FUNC_CALL, use %precedence [-Wprecedence]
|
input.y:39.1-5: warning: useless associativity for FUNC_CALL, use %precedence [-Wprecedence]
|
||||||
input.y:44.1-5: warning: useless associativity for YNUMBER, use %precedence [-Wprecedence]
|
input.y:44.1-5: warning: useless associativity for YNUMBER, use %precedence [-Wprecedence]
|
||||||
input.y:44.1-5: warning: useless associativity for YSTRING, use %precedence [-Wprecedence]
|
input.y:44.1-5: warning: useless associativity for YSTRING, use %precedence [-Wprecedence]
|
||||||
@@ -1419,7 +1419,7 @@ input.y:591.18: warning: empty rule without %empty [-Wempty-rule]
|
|||||||
input.y: warning: 144 reduce/reduce conflicts [-Wconflicts-rr]]],
|
input.y: warning: 144 reduce/reduce conflicts [-Wconflicts-rr]]],
|
||||||
[[input.y: warning: 78 shift/reduce conflicts [-Wconflicts-sr]
|
[[input.y: warning: 78 shift/reduce conflicts [-Wconflicts-sr]
|
||||||
input.y: warning: 10 reduce/reduce conflicts [-Wconflicts-rr]]])[
|
input.y: warning: 10 reduce/reduce conflicts [-Wconflicts-rr]]])[
|
||||||
input.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
|
input.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
|
||||||
input.y:72.1-5: warning: useless associativity for HQUA, use %precedence [-Wprecedence]
|
input.y:72.1-5: warning: useless associativity for HQUA, use %precedence [-Wprecedence]
|
||||||
input.y:53.1-6: warning: useless associativity for HASSIGN, use %precedence [-Wprecedence]
|
input.y:53.1-6: warning: useless associativity for HASSIGN, use %precedence [-Wprecedence]
|
||||||
input.y:54.1-5: warning: useless associativity for HORELSE, use %precedence [-Wprecedence]
|
input.y:54.1-5: warning: useless associativity for HORELSE, use %precedence [-Wprecedence]
|
||||||
|
|||||||
+17
-17
@@ -89,7 +89,7 @@ AT_BISON_OPTION_POPDEFS
|
|||||||
|
|
||||||
AT_BISON_CHECK([[-o glr-regr1.c -rall glr-regr1.y]], 0, [],
|
AT_BISON_CHECK([[-o glr-regr1.c -rall glr-regr1.y]], 0, [],
|
||||||
[[glr-regr1.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
|
[[glr-regr1.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
|
||||||
glr-regr1.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
|
glr-regr1.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
|
||||||
]])
|
]])
|
||||||
AT_COMPILE([glr-regr1])
|
AT_COMPILE([glr-regr1])
|
||||||
AT_PARSER_CHECK([[glr-regr1 BPBPB]], 0,
|
AT_PARSER_CHECK([[glr-regr1 BPBPB]], 0,
|
||||||
@@ -214,7 +214,7 @@ AT_BISON_OPTION_POPDEFS
|
|||||||
|
|
||||||
AT_BISON_CHECK([[-o glr-regr2a.c -rall glr-regr2a.y]], 0, [],
|
AT_BISON_CHECK([[-o glr-regr2a.c -rall glr-regr2a.y]], 0, [],
|
||||||
[[glr-regr2a.y: warning: 2 shift/reduce conflicts [-Wconflicts-sr]
|
[[glr-regr2a.y: warning: 2 shift/reduce conflicts [-Wconflicts-sr]
|
||||||
glr-regr2a.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
|
glr-regr2a.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
|
||||||
]])
|
]])
|
||||||
AT_COMPILE([glr-regr2a])
|
AT_COMPILE([glr-regr2a])
|
||||||
|
|
||||||
@@ -350,7 +350,7 @@ AT_BISON_OPTION_POPDEFS
|
|||||||
AT_BISON_CHECK([[-o glr-regr3.c -rall glr-regr3.y]], 0, [],
|
AT_BISON_CHECK([[-o glr-regr3.c -rall glr-regr3.y]], 0, [],
|
||||||
[[glr-regr3.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
|
[[glr-regr3.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
|
||||||
glr-regr3.y: warning: 2 reduce/reduce conflicts [-Wconflicts-rr]
|
glr-regr3.y: warning: 2 reduce/reduce conflicts [-Wconflicts-rr]
|
||||||
glr-regr3.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
|
glr-regr3.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
|
||||||
]])
|
]])
|
||||||
AT_COMPILE([glr-regr3])
|
AT_COMPILE([glr-regr3])
|
||||||
|
|
||||||
@@ -447,7 +447,7 @@ AT_BISON_OPTION_POPDEFS
|
|||||||
|
|
||||||
AT_BISON_CHECK([[-o glr-regr4.c -rall glr-regr4.y]], 0, [],
|
AT_BISON_CHECK([[-o glr-regr4.c -rall glr-regr4.y]], 0, [],
|
||||||
[[glr-regr4.y: warning: 2 reduce/reduce conflicts [-Wconflicts-rr]
|
[[glr-regr4.y: warning: 2 reduce/reduce conflicts [-Wconflicts-rr]
|
||||||
glr-regr4.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
|
glr-regr4.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
|
||||||
]])
|
]])
|
||||||
AT_COMPILE([glr-regr4])
|
AT_COMPILE([glr-regr4])
|
||||||
|
|
||||||
@@ -505,7 +505,7 @@ AT_BISON_OPTION_POPDEFS
|
|||||||
|
|
||||||
AT_BISON_CHECK([[-o glr-regr5.c -rall glr-regr5.y]], 0, [],
|
AT_BISON_CHECK([[-o glr-regr5.c -rall glr-regr5.y]], 0, [],
|
||||||
[[glr-regr5.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
|
[[glr-regr5.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
|
||||||
glr-regr5.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
|
glr-regr5.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
|
||||||
]])
|
]])
|
||||||
AT_COMPILE([glr-regr5])
|
AT_COMPILE([glr-regr5])
|
||||||
|
|
||||||
@@ -555,7 +555,7 @@ AT_BISON_OPTION_POPDEFS
|
|||||||
|
|
||||||
AT_BISON_CHECK([[-o glr-regr6.c -rall glr-regr6.y]], 0, [],
|
AT_BISON_CHECK([[-o glr-regr6.c -rall glr-regr6.y]], 0, [],
|
||||||
[[glr-regr6.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
|
[[glr-regr6.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
|
||||||
glr-regr6.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
|
glr-regr6.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
|
||||||
]])
|
]])
|
||||||
AT_COMPILE([glr-regr6])
|
AT_COMPILE([glr-regr6])
|
||||||
|
|
||||||
@@ -646,7 +646,7 @@ AT_BISON_OPTION_POPDEFS
|
|||||||
|
|
||||||
AT_BISON_CHECK([[-o glr-regr7.c -rall glr-regr7.y]], 0, [],
|
AT_BISON_CHECK([[-o glr-regr7.c -rall glr-regr7.y]], 0, [],
|
||||||
[[glr-regr7.y: warning: 2 reduce/reduce conflicts [-Wconflicts-rr]
|
[[glr-regr7.y: warning: 2 reduce/reduce conflicts [-Wconflicts-rr]
|
||||||
glr-regr7.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
|
glr-regr7.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
|
||||||
]])
|
]])
|
||||||
AT_COMPILE([glr-regr7])
|
AT_COMPILE([glr-regr7])
|
||||||
|
|
||||||
@@ -737,7 +737,7 @@ AT_BISON_OPTION_POPDEFS
|
|||||||
|
|
||||||
AT_BISON_CHECK([[-o glr-regr8.c -rall glr-regr8.y]], 0, [],
|
AT_BISON_CHECK([[-o glr-regr8.c -rall glr-regr8.y]], 0, [],
|
||||||
[[glr-regr8.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
|
[[glr-regr8.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
|
||||||
glr-regr8.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
|
glr-regr8.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
|
||||||
]])
|
]])
|
||||||
AT_COMPILE([glr-regr8])
|
AT_COMPILE([glr-regr8])
|
||||||
|
|
||||||
@@ -819,7 +819,7 @@ AT_BISON_OPTION_POPDEFS
|
|||||||
|
|
||||||
AT_BISON_CHECK([[-o glr-regr9.c -rall glr-regr9.y]], 0, [],
|
AT_BISON_CHECK([[-o glr-regr9.c -rall glr-regr9.y]], 0, [],
|
||||||
[[glr-regr9.y: warning: 2 reduce/reduce conflicts [-Wconflicts-rr]
|
[[glr-regr9.y: warning: 2 reduce/reduce conflicts [-Wconflicts-rr]
|
||||||
glr-regr9.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
|
glr-regr9.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
|
||||||
]])
|
]])
|
||||||
AT_COMPILE([glr-regr9])
|
AT_COMPILE([glr-regr9])
|
||||||
|
|
||||||
@@ -877,7 +877,7 @@ AT_BISON_OPTION_POPDEFS
|
|||||||
|
|
||||||
AT_BISON_CHECK([[-o glr-regr10.c -rall glr-regr10.y]], 0, [],
|
AT_BISON_CHECK([[-o glr-regr10.c -rall glr-regr10.y]], 0, [],
|
||||||
[[glr-regr10.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
|
[[glr-regr10.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
|
||||||
glr-regr10.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
|
glr-regr10.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
|
||||||
]])
|
]])
|
||||||
AT_COMPILE([glr-regr10])
|
AT_COMPILE([glr-regr10])
|
||||||
|
|
||||||
@@ -937,7 +937,7 @@ AT_BISON_OPTION_POPDEFS
|
|||||||
|
|
||||||
AT_BISON_CHECK([[-o glr-regr11.c -rall glr-regr11.y]], 0, [],
|
AT_BISON_CHECK([[-o glr-regr11.c -rall glr-regr11.y]], 0, [],
|
||||||
[[glr-regr11.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
|
[[glr-regr11.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
|
||||||
glr-regr11.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
|
glr-regr11.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
|
||||||
]])
|
]])
|
||||||
AT_COMPILE([glr-regr11])
|
AT_COMPILE([glr-regr11])
|
||||||
|
|
||||||
@@ -1060,7 +1060,7 @@ AT_BISON_OPTION_POPDEFS
|
|||||||
AT_BISON_CHECK([[-o glr-regr12.c -rall glr-regr12.y]], 0, [],
|
AT_BISON_CHECK([[-o glr-regr12.c -rall glr-regr12.y]], 0, [],
|
||||||
[[glr-regr12.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
|
[[glr-regr12.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
|
||||||
glr-regr12.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
|
glr-regr12.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
|
||||||
glr-regr12.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
|
glr-regr12.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
|
||||||
]])
|
]])
|
||||||
AT_COMPILE([glr-regr12])
|
AT_COMPILE([glr-regr12])
|
||||||
|
|
||||||
@@ -1392,7 +1392,7 @@ AT_BISON_OPTION_POPDEFS
|
|||||||
|
|
||||||
AT_BISON_CHECK([[-o glr-regr14.c -rall glr-regr14.y]], 0, [],
|
AT_BISON_CHECK([[-o glr-regr14.c -rall glr-regr14.y]], 0, [],
|
||||||
[[glr-regr14.y: warning: 5 reduce/reduce conflicts [-Wconflicts-rr]
|
[[glr-regr14.y: warning: 5 reduce/reduce conflicts [-Wconflicts-rr]
|
||||||
glr-regr14.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
|
glr-regr14.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
|
||||||
]])
|
]])
|
||||||
AT_COMPILE([glr-regr14])
|
AT_COMPILE([glr-regr14])
|
||||||
|
|
||||||
@@ -1487,7 +1487,7 @@ AT_BISON_OPTION_POPDEFS
|
|||||||
|
|
||||||
AT_BISON_CHECK([[-o glr-regr15.c -rall glr-regr15.y]], 0, [],
|
AT_BISON_CHECK([[-o glr-regr15.c -rall glr-regr15.y]], 0, [],
|
||||||
[[glr-regr15.y: warning: 2 reduce/reduce conflicts [-Wconflicts-rr]
|
[[glr-regr15.y: warning: 2 reduce/reduce conflicts [-Wconflicts-rr]
|
||||||
glr-regr15.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
|
glr-regr15.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
|
||||||
]])
|
]])
|
||||||
AT_COMPILE([glr-regr15])
|
AT_COMPILE([glr-regr15])
|
||||||
|
|
||||||
@@ -1549,7 +1549,7 @@ AT_BISON_OPTION_POPDEFS
|
|||||||
|
|
||||||
AT_BISON_CHECK([[-o glr-regr16.c -rall glr-regr16.y]], 0, [],
|
AT_BISON_CHECK([[-o glr-regr16.c -rall glr-regr16.y]], 0, [],
|
||||||
[[glr-regr16.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
|
[[glr-regr16.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
|
||||||
glr-regr16.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
|
glr-regr16.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
|
||||||
]])
|
]])
|
||||||
AT_COMPILE([glr-regr16])
|
AT_COMPILE([glr-regr16])
|
||||||
|
|
||||||
@@ -1625,7 +1625,7 @@ AT_BISON_OPTION_POPDEFS
|
|||||||
|
|
||||||
AT_BISON_CHECK([[-o glr-regr17.c -rall glr-regr17.y]], 0, [],
|
AT_BISON_CHECK([[-o glr-regr17.c -rall glr-regr17.y]], 0, [],
|
||||||
[[glr-regr17.y: warning: 3 reduce/reduce conflicts [-Wconflicts-rr]
|
[[glr-regr17.y: warning: 3 reduce/reduce conflicts [-Wconflicts-rr]
|
||||||
glr-regr17.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
|
glr-regr17.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
|
||||||
]])
|
]])
|
||||||
AT_COMPILE([glr-regr17])
|
AT_COMPILE([glr-regr17])
|
||||||
|
|
||||||
@@ -1719,7 +1719,7 @@ d: /* nada. */;
|
|||||||
|
|
||||||
AT_BISON_CHECK([[-o input.c input.y]], 0, [],
|
AT_BISON_CHECK([[-o input.c input.y]], 0, [],
|
||||||
[[input.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
|
[[input.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
|
||||||
input.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
|
input.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
|
||||||
]])
|
]])
|
||||||
AT_COMPILE([input])
|
AT_COMPILE([input])
|
||||||
|
|
||||||
|
|||||||
@@ -2887,7 +2887,6 @@ input.y:13.1-14: note: previous definition
|
|||||||
input.y:14.16-29: warning: %define variable 'parse.error' redefined [-Wother]
|
input.y:14.16-29: warning: %define variable 'parse.error' redefined [-Wother]
|
||||||
input.y:13.16-29: note: previous definition
|
input.y:13.16-29: note: previous definition
|
||||||
input.y: error: reduce/reduce conflicts: 0 found, 42 expected
|
input.y: error: reduce/reduce conflicts: 0 found, 42 expected
|
||||||
input.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
|
|
||||||
input.y: warning: fix-its can be applied. Rerun with option '--update'. [-Wother]
|
input.y: warning: fix-its can be applied. Rerun with option '--update'. [-Wother]
|
||||||
]])
|
]])
|
||||||
|
|
||||||
|
|||||||
+8
-3
@@ -1169,11 +1169,16 @@ m4_define([AT_BISON_CHECK_XML],
|
|||||||
[cp xml-tests/test.output expout]
|
[cp xml-tests/test.output expout]
|
||||||
AT_CHECK([[$XSLTPROC \
|
AT_CHECK([[$XSLTPROC \
|
||||||
`]]AT_SET_ENV[[ bison --print-datadir`/xslt/xml2text.xsl \
|
`]]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]
|
[sort xml-tests/test.gv > expout]
|
||||||
AT_CHECK([[$XSLTPROC \
|
AT_CHECK([[$XSLTPROC \
|
||||||
`]]AT_SET_ENV[[ bison --print-datadir`/xslt/xml2dot.xsl \
|
`]]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]
|
[rm -rf xml-tests expout]
|
||||||
AT_RESTORE_SPECIAL_FILES
|
AT_RESTORE_SPECIAL_FILES
|
||||||
[fi]])
|
[fi]])
|
||||||
@@ -1194,7 +1199,7 @@ m4_define([AT_BISON_CHECK_XML],
|
|||||||
# The testsuite verbose output, at least, will be incorrect, but nothing may
|
# The testsuite verbose output, at least, will be incorrect, but nothing may
|
||||||
# fail to make sure you notice.
|
# fail to make sure you notice.
|
||||||
m4_define([AT_SET_ENV_IF],
|
m4_define([AT_SET_ENV_IF],
|
||||||
[[[COLUMNS=1000; export COLUMNS;]] m4_null_if($1, [], [[[VALGRIND_OPTS="$VALGRIND_OPTS --leak-check=summary --show-reachable=no"; export VALGRIND_OPTS; ]]])])
|
[[[COLUMNS=1000; export COLUMNS; NO_TERM_HYPERLINKS=1; export NO_TERM_HYPERLINKS;]] m4_null_if($1, [], [[[VALGRIND_OPTS="$VALGRIND_OPTS --leak-check=summary --show-reachable=no"; export VALGRIND_OPTS; ]]])])
|
||||||
|
|
||||||
|
|
||||||
# AT_SET_ENV
|
# AT_SET_ENV
|
||||||
|
|||||||
@@ -36,6 +36,14 @@ $(top_srcdir)/%D%/package.m4: $(top_srcdir)/configure
|
|||||||
} >$@.tmp
|
} >$@.tmp
|
||||||
$(AM_V_at)mv $@.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. ##
|
## Generate the test suite. ##
|
||||||
## ------------------------- ##
|
## ------------------------- ##
|
||||||
|
|||||||
+1
-1
@@ -1300,7 +1300,7 @@ dnl INPUT
|
|||||||
dnl BISON-STDERR
|
dnl BISON-STDERR
|
||||||
[AT_COND_CASE([[LALR]],
|
[AT_COND_CASE([[LALR]],
|
||||||
[[input.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
|
[[input.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
|
||||||
input.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
|
input.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
|
||||||
]], [])],
|
]], [])],
|
||||||
|
|
||||||
dnl TABLES
|
dnl TABLES
|
||||||
|
|||||||
+746
-79
@@ -764,24 +764,24 @@ AT_CHECK([[sed -e 's/bison-xml-report version="[^"]*"/bison-xml-report version="
|
|||||||
</rule>
|
</rule>
|
||||||
</rules>
|
</rules>
|
||||||
<terminals>
|
<terminals>
|
||||||
<terminal symbol-number="0" token-number="0" name=""end of file"" 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" usefulness="useful"/>
|
<terminal symbol-number="1" token-number="256" name="error" type="" usefulness="useful"/>
|
||||||
<terminal symbol-number="3" token-number="258" name="":="" usefulness="useful"/>
|
<terminal symbol-number="3" token-number="258" name="":="" type="" usefulness="useful"/>
|
||||||
<terminal symbol-number="4" token-number="259" name=""incr"" usefulness="useful"/>
|
<terminal symbol-number="4" token-number="259" name=""incr"" type="" usefulness="useful"/>
|
||||||
<terminal symbol-number="5" token-number="260" name=""identifier"" 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"" usefulness="useful"/>
|
<terminal symbol-number="6" token-number="261" name=""number"" type="int" usefulness="useful"/>
|
||||||
<terminal symbol-number="7" token-number="262" name=""("" usefulness="useful"/>
|
<terminal symbol-number="7" token-number="262" name=""("" type="" usefulness="useful"/>
|
||||||
<terminal symbol-number="8" token-number="263" name="")"" usefulness="useful"/>
|
<terminal symbol-number="8" token-number="263" name="")"" type="" usefulness="useful"/>
|
||||||
</terminals>
|
</terminals>
|
||||||
<nonterminals>
|
<nonterminals>
|
||||||
<nonterminal symbol-number="9" name="$accept" usefulness="useful"/>
|
<nonterminal symbol-number="9" name="$accept" type="" usefulness="useful"/>
|
||||||
<nonterminal symbol-number="10" name="unit" usefulness="useful"/>
|
<nonterminal symbol-number="10" name="unit" type="" usefulness="useful"/>
|
||||||
<nonterminal symbol-number="11" name="assignments" usefulness="useful"/>
|
<nonterminal symbol-number="11" name="assignments" type="" usefulness="useful"/>
|
||||||
<nonterminal symbol-number="12" name="assignment" usefulness="useful"/>
|
<nonterminal symbol-number="12" name="assignment" type="" usefulness="useful"/>
|
||||||
<nonterminal symbol-number="13" name="id" usefulness="useful"/>
|
<nonterminal symbol-number="13" name="id" type="std::string" usefulness="useful"/>
|
||||||
<nonterminal symbol-number="14" name="exp" usefulness="useful"/>
|
<nonterminal symbol-number="14" name="exp" type="int" usefulness="useful"/>
|
||||||
<nonterminal symbol-number="15" name="@1" usefulness="useful"/>
|
<nonterminal symbol-number="15" name="@1" type="int" usefulness="useful"/>
|
||||||
<nonterminal symbol-number="16" name="@2" usefulness="useful"/>
|
<nonterminal symbol-number="16" name="@2" type="int" usefulness="useful"/>
|
||||||
</nonterminals>
|
</nonterminals>
|
||||||
</grammar>
|
</grammar>
|
||||||
|
|
||||||
@@ -1137,6 +1137,373 @@ AT_CHECK([[sed -e 's/bison-xml-report version="[^"]*"/bison-xml-report version="
|
|||||||
</bison-xml-report>
|
</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_BISON_OPTION_POPDEFS
|
||||||
AT_CLEANUP
|
AT_CLEANUP
|
||||||
@@ -1170,41 +1537,70 @@ exp
|
|||||||
AT_CHECK([LC_ALL="$locale" bison -fno-caret -o input.cc -rall -Wcex --graph=input.gv --xml input.y], [], [],
|
AT_CHECK([LC_ALL="$locale" bison -fno-caret -o input.cc -rall -Wcex --graph=input.gv --xml input.y], [], [],
|
||||||
[[input.y: warning: 3 shift/reduce conflicts [-Wconflicts-sr]
|
[[input.y: warning: 3 shift/reduce conflicts [-Wconflicts-sr]
|
||||||
input.y: warning: 3 reduce/reduce conflicts [-Wconflicts-rr]
|
input.y: warning: 3 reduce/reduce conflicts [-Wconflicts-rr]
|
||||||
Shift/reduce conflict on token "⊕":
|
input.y: warning: shift/reduce conflict on token "⊕" [-Wcounterexamples]
|
||||||
Example exp "+" exp • "⊕" exp
|
Example: exp "+" exp • "⊕" exp
|
||||||
First derivation exp ::=[ exp ::=[ exp "+" exp • ] "⊕" exp ]
|
Shift derivation
|
||||||
Second derivation exp ::=[ exp "+" exp ::=[ exp • "⊕" exp ] ]
|
exp
|
||||||
|
↳ exp "+" exp
|
||||||
Reduce/reduce conflict on tokens $end, "+", "⊕":
|
↳ exp • "⊕" exp
|
||||||
Example exp "+" exp •
|
Reduce derivation
|
||||||
First derivation exp ::=[ exp "+" exp • ]
|
exp
|
||||||
Second derivation exp ::=[ exp "+" exp • ]
|
↳ exp "⊕" exp
|
||||||
|
↳ exp "+" exp •
|
||||||
Shift/reduce conflict on token "⊕":
|
input.y: warning: reduce/reduce conflict on tokens $end, "+", "⊕" [-Wcounterexamples]
|
||||||
Example exp "+" exp • "⊕" exp
|
Example: exp "+" exp •
|
||||||
First derivation exp ::=[ exp ::=[ exp "+" exp • ] "⊕" exp ]
|
First reduce derivation
|
||||||
Second derivation exp ::=[ exp "+" exp ::=[ exp • "⊕" exp ] ]
|
exp
|
||||||
|
↳ exp "+" exp •
|
||||||
Shift/reduce conflict on token "⊕":
|
Second reduce derivation
|
||||||
Example exp "⊕" exp • "⊕" exp
|
exp
|
||||||
First derivation exp ::=[ exp ::=[ exp "⊕" exp • ] "⊕" exp ]
|
↳ exp "+" exp •
|
||||||
Second derivation exp ::=[ exp "⊕" exp ::=[ exp • "⊕" exp ] ]
|
input.y: warning: shift/reduce conflict on token "⊕" [-Wcounterexamples]
|
||||||
|
Example: exp "+" exp • "⊕" exp
|
||||||
Shift/reduce conflict on token "+":
|
Shift derivation
|
||||||
Example exp "⊕" exp • "+" exp
|
exp
|
||||||
First derivation exp ::=[ exp ::=[ exp "⊕" exp • ] "+" exp ]
|
↳ exp "+" exp
|
||||||
Second derivation exp ::=[ exp "⊕" exp ::=[ exp • "+" exp ] ]
|
↳ exp • "⊕" exp
|
||||||
|
Reduce derivation
|
||||||
Shift/reduce conflict on token "+":
|
exp
|
||||||
Example exp "⊕" exp • "+" exp
|
↳ exp "⊕" exp
|
||||||
First derivation exp ::=[ exp ::=[ exp "⊕" exp • ] "+" exp ]
|
↳ exp "+" exp •
|
||||||
Second derivation exp ::=[ exp "⊕" exp ::=[ exp • "+" exp ] ]
|
input.y: warning: shift/reduce conflict on token "⊕" [-Wcounterexamples]
|
||||||
|
Example: exp "⊕" exp • "⊕" exp
|
||||||
|
Shift derivation
|
||||||
|
exp
|
||||||
|
↳ exp "⊕" exp
|
||||||
|
↳ exp • "⊕" exp
|
||||||
|
Reduce derivation
|
||||||
|
exp
|
||||||
|
↳ exp "⊕" exp
|
||||||
|
↳ exp "⊕" exp •
|
||||||
|
input.y: warning: shift/reduce conflict on token "+" [-Wcounterexamples]
|
||||||
|
Example: exp "⊕" exp • "+" exp
|
||||||
|
Shift derivation
|
||||||
|
exp
|
||||||
|
↳ exp "⊕" exp
|
||||||
|
↳ exp • "+" exp
|
||||||
|
Reduce derivation
|
||||||
|
exp
|
||||||
|
↳ exp "+" exp
|
||||||
|
↳ exp "⊕" exp •
|
||||||
|
input.y: warning: shift/reduce conflict on token "+" [-Wcounterexamples]
|
||||||
|
Example: 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]
|
input.y:6.3-13: warning: rule useless in parser due to conflicts [-Wother]
|
||||||
]])
|
]])
|
||||||
|
|
||||||
# Check the contents of the report.
|
# 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
|
[[Rules useless in parser due to conflicts
|
||||||
|
|
||||||
3 exp: exp "+" exp
|
3 exp: exp "+" exp
|
||||||
@@ -1343,26 +1739,42 @@ State 7
|
|||||||
|
|
||||||
Conflict between rule 2 and token "+" resolved as reduce (%left "+").
|
Conflict between rule 2 and token "+" resolved as reduce (%left "+").
|
||||||
|
|
||||||
Shift/reduce conflict on token "⊕":
|
shift/reduce conflict on token "⊕":
|
||||||
2 exp: exp "+" exp •
|
2 exp: exp "+" exp •
|
||||||
1 exp: exp • "⊕" exp
|
1 exp: exp • "⊕" exp
|
||||||
Example exp "+" exp • "⊕" exp
|
Example: exp "+" exp • "⊕" exp
|
||||||
First derivation exp ::=[ exp ::=[ exp "+" exp • ] "⊕" exp ]
|
Shift derivation
|
||||||
Second derivation exp ::=[ exp "+" exp ::=[ exp • "⊕" exp ] ]
|
exp
|
||||||
|
↳ exp "+" exp
|
||||||
|
↳ exp • "⊕" exp
|
||||||
|
Reduce derivation
|
||||||
|
exp
|
||||||
|
↳ exp "⊕" exp
|
||||||
|
↳ exp "+" exp •
|
||||||
|
|
||||||
Reduce/reduce conflict on tokens $end, "+", "⊕":
|
reduce/reduce conflict on tokens $end, "+", "⊕":
|
||||||
2 exp: exp "+" exp •
|
2 exp: exp "+" exp •
|
||||||
3 exp: exp "+" exp •
|
3 exp: exp "+" exp •
|
||||||
Example exp "+" exp •
|
Example: exp "+" exp •
|
||||||
First derivation exp ::=[ exp "+" exp • ]
|
First reduce derivation
|
||||||
Second derivation exp ::=[ exp "+" exp • ]
|
exp
|
||||||
|
↳ exp "+" exp •
|
||||||
|
Second reduce derivation
|
||||||
|
exp
|
||||||
|
↳ exp "+" exp •
|
||||||
|
|
||||||
Shift/reduce conflict on token "⊕":
|
shift/reduce conflict on token "⊕":
|
||||||
3 exp: exp "+" exp •
|
3 exp: exp "+" exp •
|
||||||
1 exp: exp • "⊕" exp
|
1 exp: exp • "⊕" exp
|
||||||
Example exp "+" exp • "⊕" exp
|
Example: exp "+" exp • "⊕" exp
|
||||||
First derivation exp ::=[ exp ::=[ exp "+" exp • ] "⊕" exp ]
|
Shift derivation
|
||||||
Second derivation exp ::=[ exp "+" exp ::=[ exp • "⊕" exp ] ]
|
exp
|
||||||
|
↳ exp "+" exp
|
||||||
|
↳ exp • "⊕" exp
|
||||||
|
Reduce derivation
|
||||||
|
exp
|
||||||
|
↳ exp "⊕" exp
|
||||||
|
↳ exp "+" exp •
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1380,26 +1792,44 @@ State 8
|
|||||||
"⊕" [reduce using rule 1 (exp)]
|
"⊕" [reduce using rule 1 (exp)]
|
||||||
$default reduce using rule 1 (exp)
|
$default reduce using rule 1 (exp)
|
||||||
|
|
||||||
Shift/reduce conflict on token "⊕":
|
shift/reduce conflict on token "⊕":
|
||||||
1 exp: exp "⊕" exp •
|
1 exp: exp "⊕" exp •
|
||||||
1 exp: exp • "⊕" exp
|
1 exp: exp • "⊕" exp
|
||||||
Example exp "⊕" exp • "⊕" exp
|
Example: exp "⊕" exp • "⊕" exp
|
||||||
First derivation exp ::=[ exp ::=[ exp "⊕" exp • ] "⊕" exp ]
|
Shift derivation
|
||||||
Second derivation exp ::=[ exp "⊕" exp ::=[ exp • "⊕" exp ] ]
|
exp
|
||||||
|
↳ exp "⊕" exp
|
||||||
|
↳ exp • "⊕" exp
|
||||||
|
Reduce derivation
|
||||||
|
exp
|
||||||
|
↳ exp "⊕" exp
|
||||||
|
↳ exp "⊕" exp •
|
||||||
|
|
||||||
Shift/reduce conflict on token "+":
|
shift/reduce conflict on token "+":
|
||||||
1 exp: exp "⊕" exp •
|
1 exp: exp "⊕" exp •
|
||||||
2 exp: exp • "+" exp
|
2 exp: exp • "+" exp
|
||||||
Example exp "⊕" exp • "+" exp
|
Example: exp "⊕" exp • "+" exp
|
||||||
First derivation exp ::=[ exp ::=[ exp "⊕" exp • ] "+" exp ]
|
Shift derivation
|
||||||
Second derivation exp ::=[ exp "⊕" exp ::=[ exp • "+" exp ] ]
|
exp
|
||||||
|
↳ exp "⊕" exp
|
||||||
|
↳ exp • "+" exp
|
||||||
|
Reduce derivation
|
||||||
|
exp
|
||||||
|
↳ exp "+" exp
|
||||||
|
↳ exp "⊕" exp •
|
||||||
|
|
||||||
Shift/reduce conflict on token "+":
|
shift/reduce conflict on token "+":
|
||||||
1 exp: exp "⊕" exp •
|
1 exp: exp "⊕" exp •
|
||||||
3 exp: exp • "+" exp
|
3 exp: exp • "+" exp
|
||||||
Example exp "⊕" exp • "+" exp
|
Example: exp "⊕" exp • "+" exp
|
||||||
First derivation exp ::=[ exp ::=[ exp "⊕" exp • ] "+" exp ]
|
Shift derivation
|
||||||
Second derivation exp ::=[ exp "⊕" exp ::=[ exp • "+" exp ] ]
|
exp
|
||||||
|
↳ exp "⊕" exp
|
||||||
|
↳ exp • "+" exp
|
||||||
|
Reduce derivation
|
||||||
|
exp
|
||||||
|
↳ exp "+" exp
|
||||||
|
↳ exp "⊕" exp •
|
||||||
|
|
||||||
]])
|
]])
|
||||||
|
|
||||||
@@ -1514,16 +1944,16 @@ AT_CHECK([[sed -e 's/bison-xml-report version="[^"]*"/bison-xml-report version="
|
|||||||
</rule>
|
</rule>
|
||||||
</rules>
|
</rules>
|
||||||
<terminals>
|
<terminals>
|
||||||
<terminal symbol-number="0" token-number="0" name="$end" usefulness="useful"/>
|
<terminal symbol-number="0" token-number="0" name="$end" type="" usefulness="useful"/>
|
||||||
<terminal symbol-number="1" token-number="256" name="error" usefulness="useful"/>
|
<terminal symbol-number="1" token-number="256" name="error" type="" usefulness="useful"/>
|
||||||
<terminal symbol-number="3" token-number="258" name=""+"" usefulness="useful" prec="1" assoc="left"/>
|
<terminal symbol-number="3" token-number="258" name=""+"" type="" usefulness="useful" prec="1" assoc="left"/>
|
||||||
<terminal symbol-number="4" token-number="259" name=""⊕"" usefulness="useful"/>
|
<terminal symbol-number="4" token-number="259" name=""⊕"" type="" usefulness="useful"/>
|
||||||
<terminal symbol-number="5" token-number="260" name=""number"" usefulness="useful"/>
|
<terminal symbol-number="5" token-number="260" name=""number"" type="" usefulness="useful"/>
|
||||||
<terminal symbol-number="6" token-number="261" name=""Ñùṃéℝô"" usefulness="useful"/>
|
<terminal symbol-number="6" token-number="261" name=""Ñùṃéℝô"" type="" usefulness="useful"/>
|
||||||
</terminals>
|
</terminals>
|
||||||
<nonterminals>
|
<nonterminals>
|
||||||
<nonterminal symbol-number="7" name="$accept" usefulness="useful"/>
|
<nonterminal symbol-number="7" name="$accept" type="" usefulness="useful"/>
|
||||||
<nonterminal symbol-number="8" name="exp" usefulness="useful"/>
|
<nonterminal symbol-number="8" name="exp" type="" usefulness="useful"/>
|
||||||
</nonterminals>
|
</nonterminals>
|
||||||
</grammar>
|
</grammar>
|
||||||
|
|
||||||
@@ -1725,6 +2155,243 @@ AT_CHECK([[sed -e 's/bison-xml-report version="[^"]*"/bison-xml-report version="
|
|||||||
</bison-xml-report>
|
</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_BISON_OPTION_POPDEFS
|
||||||
AT_CLEANUP
|
AT_CLEANUP
|
||||||
|
|||||||
+1
-1
@@ -285,7 +285,7 @@ term: 'n'
|
|||||||
|
|
||||||
AT_BISON_CHECK([[-fcaret input.y]], [], [],
|
AT_BISON_CHECK([[-fcaret input.y]], [], [],
|
||||||
[[input.y: warning: 5 reduce/reduce conflicts [-Wconflicts-rr]
|
[[input.y: warning: 5 reduce/reduce conflicts [-Wconflicts-rr]
|
||||||
input.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
|
input.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
|
||||||
input.y:2.14-17: warning: rule useless in parser due to conflicts [-Wother]
|
input.y:2.14-17: warning: rule useless in parser due to conflicts [-Wother]
|
||||||
2 | expr: term | term | term | term | term | term
|
2 | expr: term | term | term | term | term | term
|
||||||
| ^~~~
|
| ^~~~
|
||||||
|
|||||||
+4
-4
@@ -283,11 +283,11 @@ m4_popdef([AT_TEST])
|
|||||||
## Many lookahead tokens. ##
|
## 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
|
# Create FILE-NAME, containing a self checking parser for a grammar
|
||||||
# requiring SIZE lookahead tokens.
|
# requiring SIZE lookahead tokens.
|
||||||
m4_define([AT_DATA_LOOKAHEAD_TOKENS_GRAMMAR],
|
m4_define([AT_DATA_LOOKAHEADS_GRAMMAR],
|
||||||
[AT_BISON_OPTION_PUSHDEFS
|
[AT_BISON_OPTION_PUSHDEFS
|
||||||
AT_DATA([[gengram.pl]],
|
AT_DATA([[gengram.pl]],
|
||||||
[[#! /usr/bin/perl -w
|
[[#! /usr/bin/perl -w
|
||||||
@@ -384,7 +384,7 @@ AT_BISON_OPTION_POPDEFS
|
|||||||
|
|
||||||
AT_SETUP([Many lookahead tokens])
|
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.
|
# 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.
|
# Ask for 200 MiB, which should be plenty even on a 64-bit host.
|
||||||
|
|||||||
Reference in New Issue
Block a user