mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-08-08 18:25:13 +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 | ||
|
|
2d90916067 | ||
|
|
91e5a23ff2 | ||
|
|
d4ae66c371 | ||
|
|
70fb574717 | ||
|
|
0820f16ca8 | ||
|
|
49f1e5f428 | ||
|
|
238692ad77 | ||
|
|
5f95583da7 | ||
|
|
964fb2aa6f | ||
|
|
7c0d36b760 |
+1
-1
@@ -1 +1 @@
|
||||
3.6.4
|
||||
3.6.93
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
GNU Bison NEWS
|
||||
|
||||
* Noteworthy changes in release 3.6.90 (2020-07-04) [beta]
|
||||
* Noteworthy changes in release 3.7 (2020-07-23) [stable]
|
||||
|
||||
** Deprecated features
|
||||
|
||||
@@ -18,28 +18,115 @@ GNU Bison NEWS
|
||||
|
||||
Contributed by Vincent Imbimbo.
|
||||
|
||||
When given `--report=counterexamples` or `-Wcounterexamples`, bison will
|
||||
now output counterexamples for conflicts in the grammar. These are
|
||||
strings in the grammar which can be parsed in two ways due to the
|
||||
conflict. For example:
|
||||
When given `-Wcounterexamples`/`-Wcex`, bison will now output
|
||||
counterexamples for conflicts.
|
||||
|
||||
Example exp '+' exp • '/' exp
|
||||
First derivation exp ::=[ exp ::=[ exp '+' exp • ] '/' exp ]
|
||||
Second derivation exp ::=[ exp '+' exp ::=[ exp • '/' exp ] ]
|
||||
**** Unifying Counterexamples
|
||||
|
||||
This is a shift/reduce conflict caused by none of the operators having
|
||||
precedence, so the example can be parsed in the two ways shown. When
|
||||
bison cannot find an example that can be derived in two ways, it instead
|
||||
generates two examples that are the same up until the dot:
|
||||
Unifying counterexamples are strings which can be parsed in two ways due
|
||||
to the conflict. For example on a grammar that contains the usual
|
||||
"dangling else" ambiguity:
|
||||
|
||||
First example expr • ID $end
|
||||
First derivation $accept ::=[ s ::=[ a ::=[ expr • ] ID ] $end ]
|
||||
Second example expr • ID ',' ID $end
|
||||
Second derivation $accept ::=[ s ::=[ a ::=[ expr ::=[ expr • ID ',' ] ] ID ] $end ]
|
||||
$ bison else.y
|
||||
else.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
|
||||
else.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
|
||||
|
||||
$ bison else.y -Wcex
|
||||
else.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
|
||||
else.y: warning: shift/reduce conflict on token "else" [-Wcounterexamples]
|
||||
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
|
||||
differentiate the two given examples.
|
||||
|
||||
**** Reports
|
||||
|
||||
Counterexamples are also included in the report when given
|
||||
`--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
|
||||
|
||||
Contributed by Joshua Watt.
|
||||
@@ -52,6 +139,11 @@ GNU Bison NEWS
|
||||
|
||||
** Changes
|
||||
|
||||
*** Diagnostics
|
||||
|
||||
When text styling is enabled and the terminal supports it, the warnings
|
||||
now include hyperlinks to the documentation.
|
||||
|
||||
*** Relocatable installation
|
||||
|
||||
When installed to be relocatable (via `configure --enable-relocatable`),
|
||||
@@ -92,6 +184,18 @@ GNU Bison NEWS
|
||||
Now the parser state can be examined when parsing is finished. The parser
|
||||
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
|
||||
|
||||
*** Include the generated header (yacc.c)
|
||||
@@ -4357,7 +4461,7 @@ LocalWords: yysymbol yytnamerr yyreport ctx ARGMAX yysyntax stderr LPAREN
|
||||
LocalWords: symrec yypcontext TOKENMAX yyexpected YYEMPTY yypstate YYEOF
|
||||
LocalWords: autocompletion bistromathic submessages Cayuela lexcalc hoc
|
||||
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:
|
||||
ispell-dictionary: "american"
|
||||
|
||||
+3
-1
@@ -211,6 +211,8 @@ assert/abort), and all the --trace output which is meant for the maintainers
|
||||
only.
|
||||
|
||||
## Vocabulary
|
||||
- "lookahead", not "look-ahead".
|
||||
- "midrule", not "mid-rule".
|
||||
- "nonterminal", not "variable" or "non-terminal" or "non terminal".
|
||||
Abbreviated as "nterm".
|
||||
- "shift/reduce" and "reduce/reduce", not "shift-reduce" or "shift reduce",
|
||||
@@ -442,7 +444,7 @@ added the `[-Wother]` part to all the warnings). Part of the update can be
|
||||
done with a crude tool: `build-aux/update-test`.
|
||||
|
||||
Once you ran the test suite, and therefore have many `testsuite.log` files,
|
||||
run, from the source tree:
|
||||
run `make update-tests`. Or, by hand, from the *source* tree:
|
||||
|
||||
$ ./build-aux/update-test $build/tests/testsuite.dir/*/testsuite.log
|
||||
|
||||
|
||||
@@ -45,6 +45,7 @@ Csaba Raduly [email protected]
|
||||
Dagobert Michelsen [email protected]
|
||||
Daniel Frużyński [email protected]
|
||||
Daniel Galloway [email protected]
|
||||
Daniela Becker [email protected]
|
||||
Daniel Hagerty [email protected]
|
||||
David Barto [email protected]
|
||||
David J. MacKenzie [email protected]
|
||||
|
||||
@@ -36,8 +36,6 @@ Unless we play it dumb (little structure).
|
||||
- How about not evaluating incomplete lines when the text is not finished
|
||||
(as shells do).
|
||||
|
||||
- Caret diagnostics
|
||||
|
||||
** Questions
|
||||
*** Java
|
||||
- Should i18n be part of the Lexer? Currently it's a static method of
|
||||
|
||||
+1
-1
@@ -44,7 +44,7 @@ gnulib_modules='
|
||||
realloc-posix
|
||||
relocatable-prog relocatable-script
|
||||
rename
|
||||
spawn-pipe stdbool stpcpy strdup-posix strerror strverscmp
|
||||
spawn-pipe stdbool stpcpy stpncpy strdup-posix strerror strverscmp
|
||||
timevar
|
||||
unicodeio unistd unistd-safer unlink unlocked-io
|
||||
update-copyright unsetenv verify
|
||||
|
||||
+3
-3
@@ -86,7 +86,7 @@ The macro `b4_symbol(NUM, FIELD)` gives access to the following FIELDS:
|
||||
- `has_id`: 0 or 1
|
||||
Whether the symbol has an `id`.
|
||||
|
||||
- `id`: string
|
||||
- `id`: string (e.g., `exp`, `NUM`, or `TOK_NUM` with api.token.prefix)
|
||||
If `has_id`, the name of the token kind (prefixed by api.token.prefix if
|
||||
defined), otherwise empty. Guaranteed to be usable as a C identifier.
|
||||
This is used to define the token kind (i.e., the enum used by the return
|
||||
@@ -105,9 +105,9 @@ The macro `b4_symbol(NUM, FIELD)` gives access to the following FIELDS:
|
||||
- `is_token`: 0 or 1
|
||||
Whether this is a terminal symbol.
|
||||
|
||||
- `kind_base`: string
|
||||
- `kind_base`: string (e.g., `YYSYMBOL_exp`, `YYSYMBOL_NUM`)
|
||||
The base of the symbol kind, i.e., the enumerator of this symbol (token or
|
||||
nonterminal) which is mapping to its `number`.
|
||||
nonterminal) which is mapped to its `number`.
|
||||
|
||||
- `kind`: string
|
||||
Same as `kind_base`, but possibly with a prefix in some languages. E.g.,
|
||||
|
||||
@@ -49,6 +49,10 @@
|
||||
.cex-5 { color: orange; }
|
||||
.cex-6 { color: brown; }
|
||||
.cex-7 { color: mauve; }
|
||||
.cex-8 { color: #013220; } /* Dark green. */
|
||||
.cex-9 { color: #e75480; } /* Dark pink. */
|
||||
.cex-10 { color: cyan; }
|
||||
.cex-11 { color: orange; }
|
||||
|
||||
/* Cex: derivation rewriting steps. */
|
||||
.cex-step { font-style: italic; }
|
||||
|
||||
@@ -594,11 +594,12 @@ m4_define([b4_yytranslate_define],
|
||||
{
|
||||
]b4_translate[
|
||||
};
|
||||
const int code_max_ = ]b4_code_max[;
|
||||
// Last valid token kind.
|
||||
const int code_max = ]b4_code_max[;
|
||||
|
||||
if (t <= 0)
|
||||
return symbol_kind::]b4_symbol_prefix[YYEOF;
|
||||
else if (t <= code_max_)
|
||||
else if (t <= code_max)
|
||||
return YY_CAST (symbol_kind_type, translate_table[t]);
|
||||
else
|
||||
return symbol_kind::]b4_symbol_prefix[YYUNDEF;]])[
|
||||
|
||||
@@ -333,7 +333,7 @@ static YYLTYPE yyloc_default][]b4_yyloc_default;])[
|
||||
accessed by $0, $-1, etc., in any rule. */
|
||||
#define YYMAXLEFT ]b4_max_left_semantic_context[
|
||||
|
||||
/* YYMAXUTOK -- Last valid token number (for yychar). */
|
||||
/* YYMAXUTOK -- Last valid token kind. */
|
||||
#define YYMAXUTOK ]b4_code_max[
|
||||
|
||||
/* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM
|
||||
|
||||
@@ -428,8 +428,9 @@ b4_locations_if([, ref ]b4_location_type[ yylocationp])[)
|
||||
*/
|
||||
public bool parse ()
|
||||
{
|
||||
/// Lookahead and lookahead in internal form.
|
||||
// Lookahead token kind.
|
||||
int yychar = TokenKind.YYEMPTY;
|
||||
// Lookahead symbol kind.
|
||||
SymbolKind yytoken = ]b4_symbol(-2, kind)[;
|
||||
|
||||
/* State. */
|
||||
@@ -841,11 +842,12 @@ m4_popdef([b4_at_dollar])])dnl
|
||||
]b4_translate[
|
||||
@};
|
||||
|
||||
immutable int code_max_ = ]b4_code_max[;
|
||||
// Last valid token kind.
|
||||
immutable int code_max = ]b4_code_max[;
|
||||
|
||||
if (t <= 0)
|
||||
return ]b4_symbol(0, kind)[;
|
||||
else if (t <= code_max_)
|
||||
else if (t <= code_max)
|
||||
{
|
||||
import std.conv : to;
|
||||
return to!SymbolKind (translate_table[t]);
|
||||
|
||||
@@ -53,8 +53,9 @@ b4_use_push_for_pull_if([
|
||||
# allows them to be defined either in parse() when doing pull parsing,
|
||||
# or as class instance variable when doing push parsing.
|
||||
m4_define([b4_define_state],[[
|
||||
/* Lookahead and lookahead in internal form. */
|
||||
/* Lookahead token kind. */
|
||||
int yychar = YYEMPTY_;
|
||||
/* Lookahead symbol kind. */
|
||||
SymbolKind yytoken = null;
|
||||
|
||||
/* State. */
|
||||
@@ -1078,17 +1079,18 @@ b4_dollar_popdef[]dnl
|
||||
|
||||
/* YYTRANSLATE_(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM
|
||||
as returned by yylex, with out-of-bounds checking. */
|
||||
private static final SymbolKind yytranslate_ (int t)
|
||||
private static final SymbolKind yytranslate_(int t)
|
||||
]b4_api_token_raw_if(dnl
|
||||
[[ {
|
||||
return SymbolKind.get(t);
|
||||
}
|
||||
]],
|
||||
[[ {
|
||||
int code_max_ = ]b4_code_max[;
|
||||
// Last valid token kind.
|
||||
int code_max = ]b4_code_max[;
|
||||
if (t <= 0)
|
||||
return ]b4_symbol(0, kind)[;
|
||||
else if (t <= code_max_)
|
||||
else if (t <= code_max)
|
||||
return SymbolKind.get(yytranslate_table_[t]);
|
||||
else
|
||||
return ]b4_symbol(2, kind)[;
|
||||
|
||||
@@ -48,6 +48,10 @@ m4_define([b4_pure_if],
|
||||
## api.push-pull. ##
|
||||
## --------------- ##
|
||||
|
||||
# b4_pull_if, b4_push_if
|
||||
# ----------------------
|
||||
# Whether the pull/push APIs are needed. Both can be enabled.
|
||||
|
||||
b4_percent_define_default([[api.push-pull]], [[pull]])
|
||||
b4_percent_define_check_values([[[[api.push-pull]],
|
||||
[[pull]], [[push]], [[both]]]])
|
||||
@@ -155,7 +159,7 @@ m4_define([b4_rhs_location],
|
||||
# Declare the variables that are global, or local to YYPARSE if
|
||||
# pure-parser.
|
||||
m4_define([b4_declare_scanner_communication_variables], [[
|
||||
/* The lookahead symbol. */
|
||||
/* Lookahead token kind. */
|
||||
int yychar;
|
||||
|
||||
]b4_pure_if([[
|
||||
@@ -571,6 +575,7 @@ union yyalloc
|
||||
/* YYNSTATES -- Number of states. */
|
||||
#define YYNSTATES ]b4_states_number[
|
||||
|
||||
/* YYMAXUTOK -- Last valid token kind. */
|
||||
#define YYMAXUTOK ]b4_code_max[
|
||||
|
||||
|
||||
@@ -1544,7 +1549,7 @@ yyparse (]m4_ifset([b4_parse_param], [b4_formals(b4_parse_param)], [void])[)]])[
|
||||
int yyn;
|
||||
/* The return value of yyparse. */
|
||||
int yyresult;
|
||||
/* Lookahead token as an internal (translated) token number. */
|
||||
/* Lookahead symbol kind. */
|
||||
yysymbol_kind_t yytoken = ]b4_symbol(-2, kind)[;
|
||||
/* The variables used to return semantic value and location from the
|
||||
action routines. */
|
||||
|
||||
+14
-6
@@ -52,7 +52,7 @@
|
||||
<xsl:if test="nonterminal[@usefulness='useless-in-grammar']">
|
||||
<xsl:text>Nonterminals useless in grammar </xsl:text>
|
||||
<xsl:for-each select="nonterminal[@usefulness='useless-in-grammar']">
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:value-of select="@name"/>
|
||||
<xsl:text> </xsl:text>
|
||||
</xsl:for-each>
|
||||
@@ -65,7 +65,7 @@
|
||||
<xsl:text>Terminals unused in grammar </xsl:text>
|
||||
<xsl:for-each select="terminal[@usefulness='unused-in-grammar']">
|
||||
<xsl:sort select="@symbol-number" data-type="number"/>
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:value-of select="@name"/>
|
||||
<xsl:text> </xsl:text>
|
||||
</xsl:for-each>
|
||||
@@ -136,6 +136,7 @@
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="terminal">
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:value-of select="@name"/>
|
||||
<xsl:call-template name="line-wrap">
|
||||
<xsl:with-param name="first-line-length">
|
||||
@@ -148,6 +149,9 @@
|
||||
</xsl:with-param>
|
||||
<xsl:with-param name="line-length" select="66" />
|
||||
<xsl:with-param name="text">
|
||||
<xsl:if test="string-length(@type) != 0">
|
||||
<xsl:value-of select="concat(' <', @type, '>')"/>
|
||||
</xsl:if>
|
||||
<xsl:value-of select="concat(' (', @token-number, ')')"/>
|
||||
<xsl:for-each select="key('bison:ruleByRhs', @name)">
|
||||
<xsl:value-of select="concat(' ', @number)"/>
|
||||
@@ -157,14 +161,18 @@
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="nonterminal">
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:value-of select="@name"/>
|
||||
<xsl:if test="string-length(@type) != 0">
|
||||
<xsl:value-of select="concat(' <', @type, '>')"/>
|
||||
</xsl:if>
|
||||
<xsl:value-of select="concat(' (', @symbol-number, ')')"/>
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:variable name="output">
|
||||
<xsl:call-template name="line-wrap">
|
||||
<xsl:with-param name="line-length" select="66" />
|
||||
<xsl:with-param name="text">
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:if test="key('bison:ruleByLhs', @name)">
|
||||
<xsl:text>on@left:</xsl:text>
|
||||
<xsl:for-each select="key('bison:ruleByLhs', @name)">
|
||||
@@ -173,7 +181,7 @@
|
||||
</xsl:if>
|
||||
<xsl:if test="key('bison:ruleByRhs', @name)">
|
||||
<xsl:if test="key('bison:ruleByLhs', @name)">
|
||||
<xsl:text>, </xsl:text>
|
||||
<xsl:text> </xsl:text>
|
||||
</xsl:if>
|
||||
<xsl:text>on@right:</xsl:text>
|
||||
<xsl:for-each select="key('bison:ruleByRhs', @name)">
|
||||
@@ -348,11 +356,11 @@
|
||||
<!-- RHS -->
|
||||
<xsl:for-each select="rhs/*">
|
||||
<xsl:if test="position() = $dot + 1">
|
||||
<xsl:text> .</xsl:text>
|
||||
<xsl:text> •</xsl:text>
|
||||
</xsl:if>
|
||||
<xsl:apply-templates select="."/>
|
||||
<xsl:if test="position() = last() and position() = $dot">
|
||||
<xsl:text> .</xsl:text>
|
||||
<xsl:text> •</xsl:text>
|
||||
</xsl:if>
|
||||
</xsl:for-each>
|
||||
<xsl:if test="$lookaheads">
|
||||
|
||||
+72
-48
@@ -227,6 +227,7 @@
|
||||
<xsl:text> </xsl:text>
|
||||
<p class="pre">
|
||||
<xsl:call-template name="style-rule-set">
|
||||
<xsl:with-param name="anchor" select="'true'" />
|
||||
<xsl:with-param
|
||||
name="rule-set" select="rules/rule[@usefulness!='useless-in-grammar']"
|
||||
/>
|
||||
@@ -238,9 +239,11 @@
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template name="style-rule-set">
|
||||
<xsl:param name="anchor"/>
|
||||
<xsl:param name="rule-set"/>
|
||||
<xsl:for-each select="$rule-set">
|
||||
<xsl:apply-templates select=".">
|
||||
<xsl:with-param name="anchor" select="$anchor"/>
|
||||
<xsl:with-param name="pad" select="'3'"/>
|
||||
<xsl:with-param name="prev-lhs">
|
||||
<xsl:if test="position()>1">
|
||||
@@ -306,9 +309,10 @@
|
||||
<xsl:text> Terminals, with rules where they appear</xsl:text>
|
||||
</h3>
|
||||
<xsl:text> </xsl:text>
|
||||
<p class="pre">
|
||||
<ul>
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:apply-templates select="terminal"/>
|
||||
</p>
|
||||
</ul>
|
||||
<xsl:text> </xsl:text>
|
||||
</xsl:template>
|
||||
|
||||
@@ -318,41 +322,64 @@
|
||||
<xsl:text> Nonterminals, with rules where they appear</xsl:text>
|
||||
</h3>
|
||||
<xsl:text> </xsl:text>
|
||||
<p class="pre">
|
||||
<ul>
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:apply-templates
|
||||
select="nonterminal[@usefulness!='useless-in-grammar']"
|
||||
/>
|
||||
</p>
|
||||
</ul>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="terminal">
|
||||
<b><xsl:value-of select="@name"/></b>
|
||||
<xsl:value-of select="concat(' (', @token-number, ')')"/>
|
||||
<xsl:for-each select="key('bison:ruleByRhs', @name)">
|
||||
<xsl:apply-templates select="." mode="number-link"/>
|
||||
</xsl:for-each>
|
||||
<xsl:text> </xsl:text>
|
||||
<li>
|
||||
<b><xsl:value-of select="@name"/></b>
|
||||
<xsl:if test="string-length(@type) != 0">
|
||||
<xsl:value-of select="concat(' <', @type, '>')"/>
|
||||
</xsl:if>
|
||||
<xsl:value-of select="concat(' (', @token-number, ')')"/>
|
||||
<xsl:for-each select="key('bison:ruleByRhs', @name)">
|
||||
<xsl:apply-templates select="." mode="number-link"/>
|
||||
</xsl:for-each>
|
||||
</li>
|
||||
<xsl:text> </xsl:text>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="nonterminal">
|
||||
<b><xsl:value-of select="@name"/></b>
|
||||
<xsl:value-of select="concat(' (', @symbol-number, ')')"/>
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:if test="key('bison:ruleByLhs', @name)">
|
||||
<xsl:text>on left:</xsl:text>
|
||||
<xsl:for-each select="key('bison:ruleByLhs', @name)">
|
||||
<xsl:apply-templates select="." mode="number-link"/>
|
||||
</xsl:for-each>
|
||||
</xsl:if>
|
||||
<xsl:if test="key('bison:ruleByRhs', @name)">
|
||||
<xsl:if test="key('bison:ruleByLhs', @name)">
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:text> </xsl:text>
|
||||
<li>
|
||||
<b><xsl:value-of select="@name"/></b>
|
||||
<xsl:if test="string-length(@type) != 0">
|
||||
<xsl:value-of select="concat(' <', @type, '>')"/>
|
||||
</xsl:if>
|
||||
<xsl:text>on right:</xsl:text>
|
||||
<xsl:for-each select="key('bison:ruleByRhs', @name)">
|
||||
<xsl:apply-templates select="." mode="number-link"/>
|
||||
</xsl:for-each>
|
||||
</xsl:if>
|
||||
<xsl:value-of select="concat(' (', @symbol-number, ')')"/>
|
||||
<xsl:text> </xsl:text>
|
||||
<ul>
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:if test="key('bison:ruleByLhs', @name)">
|
||||
<xsl:text> </xsl:text>
|
||||
<li>
|
||||
<xsl:text>on left:</xsl:text>
|
||||
<xsl:for-each select="key('bison:ruleByLhs', @name)">
|
||||
<xsl:apply-templates select="." mode="number-link"/>
|
||||
</xsl:for-each>
|
||||
</li>
|
||||
<xsl:text> </xsl:text>
|
||||
</xsl:if>
|
||||
<xsl:if test="key('bison:ruleByRhs', @name)">
|
||||
<xsl:text> </xsl:text>
|
||||
<li>
|
||||
<xsl:text>on right:</xsl:text>
|
||||
<xsl:for-each select="key('bison:ruleByRhs', @name)">
|
||||
<xsl:apply-templates select="." mode="number-link"/>
|
||||
</xsl:for-each>
|
||||
</li>
|
||||
<xsl:text> </xsl:text>
|
||||
</xsl:if>
|
||||
<xsl:text> </xsl:text>
|
||||
</ul>
|
||||
<xsl:text> </xsl:text>
|
||||
</li>
|
||||
<xsl:text> </xsl:text>
|
||||
</xsl:template>
|
||||
|
||||
@@ -385,7 +412,7 @@
|
||||
<xsl:value-of select="concat('state_', @number)"/>
|
||||
</xsl:attribute>
|
||||
</a>
|
||||
<xsl:text>state </xsl:text>
|
||||
<xsl:text>State </xsl:text>
|
||||
<xsl:value-of select="@number"/>
|
||||
</h3>
|
||||
<xsl:text> </xsl:text>
|
||||
@@ -464,7 +491,12 @@
|
||||
</xsl:apply-templates>
|
||||
</xsl:template>
|
||||
|
||||
<!--
|
||||
anchor = 'true': define as an <a> anchor.
|
||||
itemset = 'true': show the items.
|
||||
-->
|
||||
<xsl:template match="rule">
|
||||
<xsl:param name="anchor"/>
|
||||
<xsl:param name="itemset"/>
|
||||
<xsl:param name="pad"/>
|
||||
<xsl:param name="prev-lhs"/>
|
||||
@@ -475,17 +507,21 @@
|
||||
<xsl:text> </xsl:text>
|
||||
</xsl:if>
|
||||
|
||||
<xsl:if test="$itemset != 'true'">
|
||||
<a>
|
||||
<xsl:attribute name="name">
|
||||
<xsl:value-of select="concat('rule_', @number)"/>
|
||||
</xsl:attribute>
|
||||
</a>
|
||||
</xsl:if>
|
||||
<xsl:text> </xsl:text>
|
||||
|
||||
<xsl:choose>
|
||||
<xsl:when test="$itemset = 'true'">
|
||||
<xsl:when test="$anchor = 'true'">
|
||||
<a>
|
||||
<xsl:attribute name="name">
|
||||
<xsl:value-of select="concat('rule_', @number)"/>
|
||||
</xsl:attribute>
|
||||
<xsl:call-template name="lpad">
|
||||
<xsl:with-param name="str" select="string(@number)"/>
|
||||
<xsl:with-param name="pad" select="number($pad)"/>
|
||||
</xsl:call-template>
|
||||
</a>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<a>
|
||||
<xsl:attribute name="href">
|
||||
<xsl:value-of select="concat('#rule_', @number)"/>
|
||||
@@ -495,25 +531,13 @@
|
||||
<xsl:with-param name="pad" select="number($pad)"/>
|
||||
</xsl:call-template>
|
||||
</a>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:call-template name="lpad">
|
||||
<xsl:with-param name="str" select="string(@number)"/>
|
||||
<xsl:with-param name="pad" select="number($pad)"/>
|
||||
</xsl:call-template>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
<xsl:text> </xsl:text>
|
||||
|
||||
<!-- LHS -->
|
||||
<xsl:choose>
|
||||
<xsl:when test="$itemset != 'true' and $prev-lhs = lhs[text()]">
|
||||
<xsl:call-template name="lpad">
|
||||
<xsl:with-param name="str" select="'|'"/>
|
||||
<xsl:with-param name="pad" select="number(string-length(lhs[text()])) + 2"/>
|
||||
</xsl:call-template>
|
||||
</xsl:when>
|
||||
<xsl:when test="$itemset = 'true' and $prev-lhs = lhs[text()]">
|
||||
<xsl:when test="$prev-lhs = lhs[text()]">
|
||||
<xsl:call-template name="lpad">
|
||||
<xsl:with-param name="str" select="'|'"/>
|
||||
<xsl:with-param name="pad" select="number(string-length(lhs[text()])) + 2"/>
|
||||
|
||||
+474
-115
@@ -263,7 +263,6 @@ Writing GLR Parsers
|
||||
* Merging GLR Parses:: Using GLR parsers to resolve ambiguities.
|
||||
* GLR Semantic Actions:: Considerations for semantic values and deferred actions.
|
||||
* Semantic Predicates:: Controlling a parse with arbitrary computations.
|
||||
* Compiler Requirements for GLR:: GLR parsers require a modern C compiler.
|
||||
|
||||
Examples
|
||||
|
||||
@@ -943,7 +942,6 @@ on the resulting values to produce an arbitrary merged result.
|
||||
* Merging GLR Parses:: Using GLR parsers to resolve ambiguities.
|
||||
* GLR Semantic Actions:: Considerations for semantic values and deferred actions.
|
||||
* Semantic Predicates:: Controlling a parse with arbitrary computations.
|
||||
* Compiler Requirements for GLR:: GLR parsers require a modern C compiler.
|
||||
@end menu
|
||||
|
||||
@node Simple GLR Parsers
|
||||
@@ -1372,14 +1370,14 @@ widget:
|
||||
@noindent
|
||||
is one way to allow the same parser to handle two different syntaxes for
|
||||
widgets. The clause preceded by @code{%?} is treated like an ordinary
|
||||
action, except that its text is treated as an expression and is always
|
||||
midrule action, except that its text is handled as an expression and is always
|
||||
evaluated immediately (even when in nondeterministic mode). If the
|
||||
expression yields 0 (false), the clause is treated as a syntax error,
|
||||
which, in a nondeterministic parser, causes the stack in which it is reduced
|
||||
to die. In a deterministic parser, it acts like YYERROR.
|
||||
to die. In a deterministic parser, it acts like @code{YYERROR}.
|
||||
|
||||
As the example shows, predicates otherwise look like semantic actions, and
|
||||
therefore you must be take them into account when determining the numbers
|
||||
therefore you must take them into account when determining the numbers
|
||||
to use for denoting the semantic values of right-hand side symbols.
|
||||
Predicate actions, however, have no defined value, and may not be given
|
||||
labels.
|
||||
@@ -1393,7 +1391,7 @@ widget:
|
||||
@{ if (!new_syntax) YYERROR; @}
|
||||
"widget" id new_args @{ $$ = f($3, $4); @}
|
||||
| @{ if (new_syntax) YYERROR; @}
|
||||
"widget" id old_args @{ $$ = f($3, $4); @}
|
||||
"widget" id old_args @{ $$ = f($3, $4); @}
|
||||
;
|
||||
@end example
|
||||
|
||||
@@ -1411,36 +1409,6 @@ reports an error.
|
||||
Finally, be careful in writing predicates: deferred actions have not been
|
||||
evaluated, so that using them in a predicate will have undefined effects.
|
||||
|
||||
@node Compiler Requirements for GLR
|
||||
@subsection Considerations when Compiling GLR Parsers
|
||||
@cindex @code{inline}
|
||||
@cindex GLR parsers and @code{inline}
|
||||
|
||||
The GLR parsers require a compiler for ISO C89 or
|
||||
later. In addition, they use the @code{inline} keyword, which is not
|
||||
C89, but is C99 and is a common extension in pre-C99 compilers. It is
|
||||
up to the user of these parsers to handle
|
||||
portability issues. For instance, if using Autoconf and the Autoconf
|
||||
macro @code{AC_C_INLINE}, a mere
|
||||
|
||||
@example
|
||||
%@{
|
||||
#include <config.h>
|
||||
%@}
|
||||
@end example
|
||||
|
||||
@noindent
|
||||
will suffice. Otherwise, we suggest
|
||||
|
||||
@example
|
||||
%@{
|
||||
#if (__STDC_VERSION__ < 199901 && ! defined __GNUC__ \
|
||||
&& ! defined inline)
|
||||
# define inline
|
||||
#endif
|
||||
%@}
|
||||
@end example
|
||||
|
||||
@node Locations
|
||||
@section Locations
|
||||
@cindex location
|
||||
@@ -1677,6 +1645,31 @@ Here are the C and Bison declarations for the Reverse Polish Notation
|
||||
calculator. As in C, comments are placed between @samp{/*@dots{}*/} or
|
||||
after @samp{//}.
|
||||
|
||||
@ignore
|
||||
@comment file: rpcalc.y
|
||||
@example
|
||||
/* Parser for rpcalc. -*- C -*-
|
||||
|
||||
Copyright (C) 1988-1993, 1995, 1998-2015, 2018-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/>. */
|
||||
@end example
|
||||
@end ignore
|
||||
|
||||
@comment file: rpcalc.y
|
||||
@example
|
||||
/* Reverse Polish Notation calculator. */
|
||||
@@ -2538,6 +2531,31 @@ Note that multiple assignment and nested function calls are permitted.
|
||||
|
||||
Here are the C and Bison declarations for the multi-function calculator.
|
||||
|
||||
@ignore
|
||||
@comment file: mfcalc.y
|
||||
@example
|
||||
/* Parser for mfcalc. -*- C -*-
|
||||
|
||||
Copyright (C) 1988-1993, 1995, 1998-2015, 2018-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/>. */
|
||||
@end example
|
||||
@end ignore
|
||||
|
||||
@comment file: mfcalc.y: 1
|
||||
@example
|
||||
@group
|
||||
@@ -2642,6 +2660,31 @@ The symbol table itself consists of a linked list of records. Its
|
||||
definition, which is kept in the header @file{calc.h}, is as follows. It
|
||||
provides for either functions or variables to be placed in the table.
|
||||
|
||||
@ignore
|
||||
@comment file: calc.h
|
||||
@example
|
||||
/* Functions for mfcalc. -*- C -*-
|
||||
|
||||
Copyright (C) 1988-1993, 1995, 1998-2015, 2018-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/>. */
|
||||
@end example
|
||||
@end ignore
|
||||
|
||||
@comment file: calc.h
|
||||
@example
|
||||
@group
|
||||
@@ -9846,10 +9889,11 @@ initially developed by Chinawat Isradisaikul and Andrew Myers
|
||||
As a first example, see the example grammar of @ref{Shift/Reduce}, which
|
||||
features on shift/reduce conflict:
|
||||
|
||||
@c see doc/if-then-else.y
|
||||
@example
|
||||
$ @kbd{bison if-then-else.y}
|
||||
if-then-else.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
|
||||
if-then-else.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
|
||||
if-then-else.y: @dwarning{warning}: 1 shift/reduce conflict [@dwarning{-Wconflicts-sr}]
|
||||
if-then-else.y: @dnotice{note}: rerun with option '-Wcounterexamples' to generate conflict counterexamples
|
||||
@end example
|
||||
|
||||
@noindent
|
||||
@@ -9857,32 +9901,46 @@ Let's rerun @command{bison} with the option
|
||||
@option{-Wcex}/@option{-Wcounterexamples}@inlinefmt{info, (the following
|
||||
output is actually in color)}:
|
||||
|
||||
@ifhtml
|
||||
@ifnottex
|
||||
@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
|
||||
Example @yellow{"if" expr "then"} @blue{"if" expr "then" stmt} @red{•} @yellow{"else" stmt}
|
||||
First derivation @yellow{if_stmt ::=[ "if" expr "then"} @green{stmt ::=[} @blue{if_stmt ::=[ "if" expr "then" stmt} @red{•} @blue{]} @green{]} @yellow{"else" stmt ]}
|
||||
Example @yellow{"if" expr "then"} @blue{"if" expr "then" stmt} @red{•} @blue{"else" stmt}
|
||||
Second derivation @yellow{if_stmt ::=[ "if" expr "then"} @green{stmt ::=[} @blue{if_stmt ::=[ "if" expr "then" stmt} @red{•} @blue{"else" stmt ]} @green{]} @yellow{]}
|
||||
Example: @yellow{"if" expr "then"} "if" expr "then" stmt • "else" stmt
|
||||
Shift derivation
|
||||
@yellow{if_stmt}
|
||||
@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 example
|
||||
@end ifhtml
|
||||
@ifnothtml
|
||||
@smallexample
|
||||
Shift/reduce conflict on token "else":
|
||||
@end ifnottex
|
||||
@iftex
|
||||
@example
|
||||
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
|
||||
Example
|
||||
@yellow{"if" expr "then"} @blue{"if" expr "then" stmt} @red{•} @yellow{"else" stmt}
|
||||
First derivation
|
||||
@yellow{if_stmt ::=[ "if" expr "then"} @green{stmt ::=[} @blue{if_stmt ::=[ "if" expr "then" stmt} @red{•} @blue{]} @green{]} @yellow{"else" stmt ]}
|
||||
Example
|
||||
@yellow{"if" expr "then"} @blue{"if" expr "then" stmt} @red{•} @blue{"else" stmt}
|
||||
Second derivation
|
||||
@yellow{if_stmt ::=[ "if" expr "then"} @green{stmt ::=[} @blue{if_stmt ::=[ "if" expr "then" stmt} @red{•} @blue{"else" stmt ]} @green{]} @yellow{]}
|
||||
Example: @yellow{"if" expr "then"} "if" expr "then" stmt • "else" stmt
|
||||
Shift derivation
|
||||
@yellow{if_stmt}
|
||||
@yellow{@arrow{} "if" expr "then"} @green{stmt}
|
||||
@green{@arrow{}} @blue{if_stmt}
|
||||
@blue{@arrow{} "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{@arrow{} "if" expr "then"} @green{stmt} @yellow{"else" stmt}
|
||||
@green{@arrow{}} @blue{if_stmt}
|
||||
@blue{@arrow{} "if" expr "then" stmt} @red{•}
|
||||
@end group
|
||||
@end smallexample
|
||||
@end ifnothtml
|
||||
@end example
|
||||
@end iftex
|
||||
|
||||
This shows two different derivations for one single expression. That
|
||||
demonstrates that the grammar is ambiguous.
|
||||
@@ -9892,6 +9950,7 @@ demonstrates that the grammar is ambiguous.
|
||||
As a more delicate example, consider the example grammar of
|
||||
@ref{Reduce/Reduce}, which features a reduce/reduce conflict:
|
||||
|
||||
@c doc/sequence.y
|
||||
@example
|
||||
%%
|
||||
sequence:
|
||||
@@ -9907,32 +9966,112 @@ maybeword:
|
||||
|
||||
Bison generates the following counterexamples:
|
||||
|
||||
@ifnottex
|
||||
@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}]
|
||||
Shift/reduce conflict on token "word":
|
||||
Example @red{•} @yellow{"word"}
|
||||
First derivation @yellow{sequence ::=[} @green{sequence ::=[} @red{•} @green{]} @yellow{"word" ]}
|
||||
Example @red{•} @green{"word"}
|
||||
Second derivation @yellow{sequence ::=[} @green{maybeword ::=[} @red{•} @green{"word" ]} @yellow{]}
|
||||
|
||||
Reduce/reduce conflict on tokens $end, "word":
|
||||
Example @red{•}
|
||||
First derivation @yellow{sequence ::=[} @red{•} @yellow{]}
|
||||
Example @red{•}
|
||||
Second derivation @yellow{sequence ::=[} @green{maybeword ::=[} @red{•} @green{]} @yellow{]}
|
||||
|
||||
Shift/reduce conflict on token "word":
|
||||
Example @red{•} @yellow{"word"}
|
||||
First derivation @yellow{sequence ::=[} @green{sequence ::=[} @blue{maybeword ::=[} @red{•} @blue{]} @green{]} @yellow{"word" ]}
|
||||
Example @red{•} @green{"word"}
|
||||
Second derivation @yellow{sequence ::=[} @green{maybeword ::=[} @red{•} @green{"word" ]} @yellow{]}
|
||||
|
||||
@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{↳} @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{↳} @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}]
|
||||
8 | @dwarning{%empty @{ printf ("empty maybeword\n"); @}}
|
||||
| @dwarning{^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}
|
||||
@end group
|
||||
@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.
|
||||
For instance, the second conflict (the reduce/reduce one) shows that the
|
||||
@@ -9946,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
|
||||
LALR). The following example isn't LR(1):
|
||||
|
||||
@c doc/ids.y
|
||||
@example
|
||||
%token ID
|
||||
%%
|
||||
@@ -9956,13 +10096,58 @@ expr: %empty | expr ID ','
|
||||
|
||||
@command{bison} reports:
|
||||
|
||||
@smallexample
|
||||
Shift/reduce conflict on token ID:
|
||||
First example @blue{expr} @red{•} @green{ID} @yellow{$end}
|
||||
First derivation @yellow{$accept ::=[} @green{s ::=[} @blue{a ::=[ expr} @red{•} @blue{]} @green{ID ]} @yellow{$end ]}
|
||||
Second example @purple{expr} @red{•} @purple{ID ','} @green{ID} @yellow{$end}
|
||||
Second derivation @yellow{$accept ::=[} @green{s ::=[} @blue{a ::=[} @purple{expr ::=[ expr} @red{•} @purple{ID ',' ]} @blue{]} @green{ID ]} @yellow{$end ]}
|
||||
@end smallexample
|
||||
@ifnottex
|
||||
@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{↳} @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
|
||||
the difference between these two examples. The parser would need an
|
||||
@@ -9998,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:
|
||||
|
||||
@c doc/calc.y
|
||||
@example
|
||||
@group
|
||||
%union
|
||||
@@ -10041,7 +10227,7 @@ calc.y:19.1-7: @dwarning{warning}: nonterminal useless in grammar: useless [@dwa
|
||||
19 | @dwarning{useless: STR;}
|
||||
| @dwarning{^~~~~~~}
|
||||
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
|
||||
|
||||
Going back to the calc example, when given @option{--report=state},
|
||||
@@ -10353,15 +10539,44 @@ When given @option{--report=counterexamples}, @command{bison} will generate
|
||||
counterexamples within the report, augmented with the corresponding items
|
||||
(@pxref{Counterexamples}).
|
||||
|
||||
@ifnottex
|
||||
@example
|
||||
Shift/reduce conflict on token '/':
|
||||
shift/reduce conflict on token '/':
|
||||
1 exp: exp '+' exp •
|
||||
4 exp: exp • '/' exp
|
||||
Example @green{exp '+' exp} @red{•} @yellow{'/' exp}
|
||||
First derivation @yellow{exp ::=[} @green{exp ::=[ exp '+' exp} @red{•} @green{]} @yellow{'/' exp ]}
|
||||
Example @yellow{exp '+'} @green{exp} @red{•} @green{'/' exp}
|
||||
Second derivation @yellow{exp ::=[ exp '+'} @green{exp ::=[ exp} @red{•} @green{'/' exp ]} @yellow{]}
|
||||
@group
|
||||
Example: exp '+' exp • '/' exp
|
||||
Shift derivation
|
||||
exp
|
||||
↳ exp '+' exp
|
||||
↳ exp • '/' exp
|
||||
Example: exp '+' exp • '/' exp
|
||||
Reduce derivation
|
||||
exp
|
||||
↳ exp '/' exp
|
||||
↳ exp '+' exp •
|
||||
@end group
|
||||
@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}:
|
||||
@samp{e1 + e2 / e3}. The derivations show how your rules would parse the
|
||||
@@ -10972,7 +11187,7 @@ The exit status of @command{bison} is:
|
||||
@item 0 (success)
|
||||
when there were no errors. Warnings, which are diagnostics about dubious
|
||||
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)
|
||||
when there were errors. No file was generated (except the reports generated
|
||||
@@ -11209,22 +11424,22 @@ Options controlling the diagnostics.
|
||||
Output warnings falling in @var{category}. @var{category} can be one
|
||||
of:
|
||||
@table @code
|
||||
@item conflicts-sr
|
||||
@itemx conflicts-rr
|
||||
@item @anchor{Wconflicts-sr}conflicts-sr
|
||||
@itemx @anchor{Wconflicts-rr}conflicts-rr
|
||||
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
|
||||
unexpected number of conflicts is an error, and an expected number of
|
||||
conflicts is not reported, so @option{-W} and @option{--warning} then have
|
||||
no effect on the conflict report.
|
||||
|
||||
@item counterexamples
|
||||
@item @anchor{Wcounterexamples}counterexamples
|
||||
@itemx cex
|
||||
Provide counterexamples for conflicts. @xref{Counterexamples}.
|
||||
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
|
||||
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.
|
||||
|
||||
String literals, which allow for better error messages, are (too) liberally
|
||||
@@ -11270,16 +11485,16 @@ foo: "baz" @{@}
|
||||
| @dwarning{^~~~~}
|
||||
@end example
|
||||
|
||||
@item deprecated
|
||||
@item @anchor{Wdeprecated}deprecated
|
||||
Deprecated constructs whose support will be removed in future versions of
|
||||
Bison.
|
||||
|
||||
@item empty-rule
|
||||
@item @anchor{Wempty-rule}empty-rule
|
||||
Empty rules without @code{%empty}. @xref{Empty Rules}. Disabled by
|
||||
default, but enabled by uses of @code{%empty}, unless
|
||||
@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
|
||||
of the parent rule.
|
||||
For example, warn about unused @code{$2} in:
|
||||
@@ -11299,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
|
||||
@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.
|
||||
|
||||
Consider for instance the following grammar:
|
||||
@@ -11360,20 +11575,21 @@ One would get the exact same parser with the following directives instead:
|
||||
@end group
|
||||
@end example
|
||||
|
||||
@item yacc
|
||||
@item @anchor{Wyacc}yacc
|
||||
Incompatibilities with POSIX Yacc.
|
||||
|
||||
@item other
|
||||
@item @anchor{Wother}other
|
||||
All warnings not categorized above. These warnings are enabled by default.
|
||||
|
||||
This category is provided merely for the sake of completeness. Future
|
||||
releases of Bison may move warnings from this category to new, more specific
|
||||
categories.
|
||||
|
||||
@item all
|
||||
All the warnings except @code{dangling-alias} and @code{yacc}.
|
||||
@item @anchor{Wall}all
|
||||
All the warnings except @code{counterexamples}, @code{dangling-alias} and
|
||||
@code{yacc}.
|
||||
|
||||
@item none
|
||||
@item @anchor{Wnone}none
|
||||
Turn off all the warnings.
|
||||
|
||||
@item error
|
||||
@@ -11384,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
|
||||
POSIX Yacc incompatibilities.
|
||||
|
||||
@item -Werror
|
||||
@anchor{-Werror}
|
||||
@item @anchor{Werror}-Werror
|
||||
Turn enabled warnings for every @var{category} into errors, unless they are
|
||||
explicitly disabled by @option{-Wno-error=@var{category}}.
|
||||
|
||||
@@ -11745,6 +11960,30 @@ A Bison file has three parts. In the first part, the prologue, we start by
|
||||
making sure we run a version of Bison which is recent enough, and that we
|
||||
generate C++.
|
||||
|
||||
@ignore
|
||||
@comment file: c++/simple.yy: 1
|
||||
@example
|
||||
/* Simple variant-based parser. -*- C++ -*-
|
||||
|
||||
Copyright (C) 2018-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/>. */
|
||||
@end example
|
||||
@end ignore
|
||||
|
||||
@comment file: c++/simple.yy: 1
|
||||
@example
|
||||
%require "3.2"
|
||||
@@ -12817,6 +13056,30 @@ The declaration of this driver class, in @file{driver.hh}, is as follows.
|
||||
The first part includes the CPP guard and imports the required standard
|
||||
library components, and the declaration of the parser class.
|
||||
|
||||
@ignore
|
||||
@comment file: calc++/driver.hh
|
||||
@example
|
||||
/* Driver for calc++. -*- C++ -*-
|
||||
|
||||
Copyright (C) 2005--2015, 2018--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/>. */
|
||||
@end example
|
||||
@end ignore
|
||||
|
||||
@comment file: calc++/driver.hh
|
||||
@example
|
||||
#ifndef DRIVER_HH
|
||||
@@ -12889,6 +13152,30 @@ member functions to open and close the scanning phase.
|
||||
|
||||
The implementation of the driver (@file{driver.cc}) is straightforward.
|
||||
|
||||
@ignore
|
||||
@comment file: calc++/driver.cc
|
||||
@example
|
||||
/* Driver for calc++. -*- C++ -*-
|
||||
|
||||
Copyright (C) 2005--2015, 2018--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/>. */
|
||||
@end example
|
||||
@end ignore
|
||||
|
||||
@comment file: calc++/driver.cc
|
||||
@example
|
||||
#include "driver.hh"
|
||||
@@ -12932,6 +13219,30 @@ parser skeleton, the creation of the parser header file. Because the C++
|
||||
skeleton changed several times, it is safer to require the version you
|
||||
designed the grammar for.
|
||||
|
||||
@ignore
|
||||
@comment file: calc++/parser.yy
|
||||
@example
|
||||
/* Parser for calc++. -*- C++ -*-
|
||||
|
||||
Copyright (C) 2005--2015, 2018--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/>. */
|
||||
@end example
|
||||
@end ignore
|
||||
|
||||
@comment file: calc++/parser.yy
|
||||
@example
|
||||
%skeleton "lalr1.cc" // -*- C++ -*-
|
||||
@@ -13120,6 +13431,30 @@ yy::parser::error (const location_type& l, const std::string& m)
|
||||
In addition to standard headers, the Flex scanner includes the driver's,
|
||||
then the parser's to get the set of defined tokens.
|
||||
|
||||
@ignore
|
||||
@comment file: calc++/scanner.ll
|
||||
@example
|
||||
/* Scanner for calc++. -*- C++ -*-
|
||||
|
||||
Copyright (C) 2005--2015, 2018--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/>. */
|
||||
@end example
|
||||
@end ignore
|
||||
|
||||
@comment file: calc++/scanner.ll
|
||||
@example
|
||||
%@{ /* -*- C++ -*- */
|
||||
@@ -13293,7 +13628,7 @@ The rules are simple. The driver is used to report errors.
|
||||
You should keep your rules simple, both in the parser and in the scanner.
|
||||
Throwing from the auxiliary functions is then very handy to report errors.
|
||||
|
||||
@comment file: scanner.ll
|
||||
@comment file: calc++/scanner.ll
|
||||
@example
|
||||
@group
|
||||
yy::parser::symbol_type
|
||||
@@ -13343,7 +13678,31 @@ driver::scan_end ()
|
||||
|
||||
The top level file, @file{calc++.cc}, poses no problem.
|
||||
|
||||
@comment file: calc++.cc
|
||||
@ignore
|
||||
@comment file: calc++/calc++.cc
|
||||
@example
|
||||
/* Main for calc++. -*- C++ -*-
|
||||
|
||||
Copyright (C) 2005--2015, 2018--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/>. */
|
||||
@end example
|
||||
@end ignore
|
||||
|
||||
@comment file: calc++/calc++.cc
|
||||
@example
|
||||
#include <iostream>
|
||||
#include "driver.hh"
|
||||
@@ -14605,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.
|
||||
@end quotation
|
||||
|
||||
Except for GLR parsers (@pxref{Compiler Requirements for GLR}), the C
|
||||
code that Bison generates requires only C89 or later. However, Bison
|
||||
itself requires common C99 features such as declarations after
|
||||
statements. Bison's @code{configure} script attempts to enable C99 (or
|
||||
later) support on compilers that default to pre-C99. If your compiler
|
||||
lacks these C99 features entirely, GCC may well be a better choice; or
|
||||
you can try upgrading to your compiler's latest version.
|
||||
Except for GLR parsers (which require C99), the C code that Bison generates
|
||||
requires only C89 or later. However, Bison itself requires common C99
|
||||
features such as declarations after statements. Bison's @code{configure}
|
||||
script attempts to enable C99 (or later) support on compilers that default
|
||||
to pre-C99. If your compiler lacks these C99 features entirely, GCC may
|
||||
well be a better choice; or you can try upgrading to your compiler's latest
|
||||
version.
|
||||
|
||||
@node Where can I find help?
|
||||
@section Where can I find help?
|
||||
@@ -15668,7 +16027,7 @@ London, Department of Computer Science, TR-00-12 (December 2000).
|
||||
@c LocalWords: TokenKind Automake's rtti Wcounterexamples Chinawat PLDI
|
||||
@c LocalWords: Isradisaikul tcite pcite rgbGreen colorGreen rgbYellow Wcex
|
||||
@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 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.
|
||||
- Its hand-written scanner tracks locations.
|
||||
- Its interface is pure.
|
||||
- It uses the `error` token to get error recovery.
|
||||
- It uses %params to pass user information to the parser and scanner.
|
||||
- Its scanner uses the `error` token to signal lexical errors and enter
|
||||
error recovery.
|
||||
- Its interface is "incremental", well suited for interaction: it uses the
|
||||
push-parser API to feed the parser with the incoming tokens.
|
||||
- It features an interactive command line with completion based on the
|
||||
@@ -62,6 +64,13 @@ This example demonstrates best practices when using Bison.
|
||||
messages.
|
||||
- It uses a custom syntax error with location, lookahead correction and
|
||||
token internationalization.
|
||||
- Error messages quote the source with squiggles that underline the error:
|
||||
```
|
||||
> 123 456
|
||||
1.5-7: syntax error: expected end of file or + or - or * or / or ^ before number
|
||||
1 | 123 456
|
||||
| ^~~
|
||||
```
|
||||
- It supports debug traces with semantic values.
|
||||
- It uses named references instead of the traditional $1, $2, etc.
|
||||
|
||||
|
||||
@@ -2,7 +2,9 @@
|
||||
This example demonstrates best practices when using Bison.
|
||||
- Its hand-written scanner tracks locations.
|
||||
- Its interface is pure.
|
||||
- It uses the `error` token to get error recovery.
|
||||
- It uses %params to pass user information to the parser and scanner.
|
||||
- Its scanner uses the `error` token to signal lexical errors and enter
|
||||
error recovery.
|
||||
- Its interface is "incremental", well suited for interaction: it uses the
|
||||
push-parser API to feed the parser with the incoming tokens.
|
||||
- It features an interactive command line with completion based on the
|
||||
@@ -11,6 +13,13 @@ This example demonstrates best practices when using Bison.
|
||||
messages.
|
||||
- It uses a custom syntax error with location, lookahead correction and
|
||||
token internationalization.
|
||||
- Error messages quote the source with squiggles that underline the error:
|
||||
```
|
||||
> 123 456
|
||||
1.5-7: syntax error: expected end of file or + or - or * or / or ^ before number
|
||||
1 | 123 456
|
||||
| ^~~
|
||||
```
|
||||
- It supports debug traces with semantic values.
|
||||
- It uses named references instead of the traditional $1, $2, etc.
|
||||
|
||||
|
||||
@@ -101,14 +101,28 @@ cat >input <<EOF
|
||||
EOF
|
||||
run 0 '> *
|
||||
> ''
|
||||
err: 1.1: syntax error: expected end of file or - or ( or exit or number or function etc., before *'
|
||||
err: 1.1: syntax error: expected end of file or - or ( or exit or number or function etc., before *
|
||||
err: 1 | *
|
||||
err: | ^'
|
||||
|
||||
# Underline long errors.
|
||||
cat >input <<EOF
|
||||
123 123456
|
||||
EOF
|
||||
run 0 '> 123 123456
|
||||
> ''
|
||||
err: 1.5-10: syntax error: expected end of file or + or - or * or / or ^ before number
|
||||
err: 1 | 123 123456
|
||||
err: | ^~~~~~'
|
||||
|
||||
cat >input <<EOF
|
||||
1 + 2 * * 3
|
||||
EOF
|
||||
run 0 '> 1 + 2 * * 3
|
||||
> ''
|
||||
err: 1.9: syntax error: expected - or ( or number or function or variable before *'
|
||||
err: 1.9: syntax error: expected - or ( or number or function or variable before *
|
||||
err: 1 | 1 + 2 * * 3
|
||||
err: | ^'
|
||||
|
||||
cat >input <<EOF
|
||||
1 / 0
|
||||
@@ -132,8 +146,14 @@ run 0 '> ((1 ++ 2) ** 3)
|
||||
1332
|
||||
> ''
|
||||
err: 1.6: syntax error: expected - or ( or number or function or variable before +
|
||||
err: 1 | ((1 ++ 2) ** 3)
|
||||
err: | ^
|
||||
err: 2.5: syntax error: expected - or ( or number or function or variable before +
|
||||
err: 2.16: syntax error: expected - or ( or number or function or variable before *'
|
||||
err: 2 | (1 ++ 2) + (3 ** 4)
|
||||
err: | ^
|
||||
err: 2.16: syntax error: expected - or ( or number or function or variable before *
|
||||
err: 2 | (1 ++ 2) + (3 ** 4)
|
||||
err: | ^'
|
||||
|
||||
# The rule "( error )" should work even if there are no tokens between "(" and ")".
|
||||
cat >input <<EOF
|
||||
@@ -142,7 +162,9 @@ EOF
|
||||
run 0 '> ()
|
||||
666
|
||||
> ''
|
||||
err: 1.2: syntax error: expected - or ( or number or function or variable before )'
|
||||
err: 1.2: syntax error: expected - or ( or number or function or variable before )
|
||||
err: 1 | ()
|
||||
err: | ^'
|
||||
|
||||
|
||||
cat >input <<EOF
|
||||
@@ -189,6 +211,8 @@ err: LAC: checking lookahead function: S5
|
||||
err: LAC: checking lookahead variable: S6
|
||||
err: LAC: checking lookahead NEG: Err
|
||||
err: 1.2: syntax error: expected - or ( or number or function or variable before +
|
||||
err: 1 | (+_)
|
||||
err: | ^
|
||||
err: LAC: initial context discarded due to error recovery
|
||||
err: Shifting token error (1.2: )
|
||||
err: Entering state 10
|
||||
@@ -286,7 +310,9 @@ run 0 '> (1+
|
||||
( - atan cos exp ln number sin sqrt
|
||||
> (1+
|
||||
> ''
|
||||
err: 1.4: syntax error: expected - or ( or number or function or variable before end of file'
|
||||
err: 1.4: syntax error: expected - or ( or number or function or variable before end of file
|
||||
err: 1 | (1+
|
||||
err: | ^'
|
||||
|
||||
# Check the completion of a word.
|
||||
sed -e 's/\\t/ /g' >input <<EOF
|
||||
@@ -294,7 +320,9 @@ sed -e 's/\\t/ /g' >input <<EOF
|
||||
EOF
|
||||
run 0 '> (atan ( ''
|
||||
> ''
|
||||
err: 1.9: syntax error: expected - or ( or number or function or variable before end of file'
|
||||
err: 1.9: syntax error: expected - or ( or number or function or variable before end of file
|
||||
err: 1 | (atan ( ''
|
||||
err: | ^'
|
||||
|
||||
# Check the completion at the very beginning.
|
||||
sed -e 's/\\t/ /g' >input <<EOF
|
||||
@@ -313,8 +341,9 @@ sed -e 's/\\t/ /g' >input <<EOF
|
||||
EOF
|
||||
run -n 0 '> 1++ ''
|
||||
> ''
|
||||
err: 1.1: syntax error: expected - or ( or number or function or variable before +
|
||||
err: 1.3: syntax error: expected - or ( or number or function or variable before +
|
||||
err: 1 | 1++ ''
|
||||
err: | ^
|
||||
'
|
||||
|
||||
# And even when the error was recovered from.
|
||||
@@ -323,8 +352,10 @@ sed -e 's/\\t/ /g' >input <<EOF
|
||||
EOF
|
||||
run -n 0 '> (1++2) + 3 + ''
|
||||
> ''
|
||||
err: 1.1: syntax error: expected - or ( or number or function or variable before +
|
||||
err: 1.1: syntax error: expected - or ( or number or function or variable before +
|
||||
err: 1.4: syntax error: expected - or ( or number or function or variable before +
|
||||
err: 1 | (1++2) + 3 + ''
|
||||
err: | ^
|
||||
err: 1.15: syntax error: expected - or ( or number or function or variable before end of file
|
||||
err: 1 | (1++2) + 3 + ''
|
||||
err: | ^
|
||||
'
|
||||
|
||||
@@ -1,5 +1,25 @@
|
||||
%require "3.6"
|
||||
/* Parser and scanner for bistromathic. -*- C -*-
|
||||
|
||||
Copyright (C) 2019-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/>. */
|
||||
|
||||
%require "3.7"
|
||||
|
||||
// Emitted on top of the implementation file.
|
||||
%code top {
|
||||
#include <ctype.h> // isdigit
|
||||
#include <locale.h> // LC_ALL
|
||||
@@ -24,6 +44,7 @@
|
||||
#endif
|
||||
}
|
||||
|
||||
// Emitted in the header file, before the definition of YYSTYPE.
|
||||
%code requires {
|
||||
// Function type.
|
||||
typedef double (func_t) (double);
|
||||
@@ -44,19 +65,34 @@
|
||||
|
||||
symrec *putsym (char const *name, int sym_type);
|
||||
symrec *getsym (char const *name);
|
||||
|
||||
// Exchanging information with the parser.
|
||||
typedef struct
|
||||
{
|
||||
// Whether to not emit error messages.
|
||||
int silent;
|
||||
// The current input line.
|
||||
const char *line;
|
||||
} user_context;
|
||||
}
|
||||
|
||||
// Emitted in the header file, after the definition of YYSTYPE.
|
||||
%code provides {
|
||||
# ifndef __attribute__
|
||||
# ifndef __GNUC__
|
||||
# define __attribute__(Spec) /* empty */
|
||||
# endif
|
||||
# endif
|
||||
int yylex (const char **line, YYSTYPE *yylval, YYLTYPE *yylloc);
|
||||
void yyerror (YYLTYPE *loc, char const *format, ...)
|
||||
__attribute__ ((__format__ (__printf__, 2, 3)));
|
||||
|
||||
yytoken_kind_t
|
||||
yylex (const char **line, YYSTYPE *yylval, YYLTYPE *yylloc,
|
||||
const user_context *uctx);
|
||||
void yyerror (YYLTYPE *loc, const user_context *uctx,
|
||||
char const *format, ...)
|
||||
__attribute__ ((__format__ (__printf__, 3, 4)));
|
||||
}
|
||||
|
||||
// Emitted in the implementation file.
|
||||
%code {
|
||||
#if defined ENABLE_NLS && ENABLE_NLS
|
||||
# define _(Msgid) gettext (Msgid)
|
||||
@@ -68,6 +104,9 @@
|
||||
int done = 0;
|
||||
}
|
||||
|
||||
// Include the header in the implementation rather than duplicating it.
|
||||
%define api.header.include {"parse.h"}
|
||||
|
||||
// Don't share global variables between the scanner and the parser.
|
||||
%define api.pure full
|
||||
|
||||
@@ -90,6 +129,9 @@
|
||||
// Generate the parser description file (calc.output).
|
||||
%verbose
|
||||
|
||||
// User information exchanged with the parser and scanner.
|
||||
%param {const user_context *uctx}
|
||||
|
||||
// Generate YYSTYPE from the types assigned to symbols.
|
||||
%define api.value.type union
|
||||
%token
|
||||
@@ -145,7 +187,7 @@ exp:
|
||||
{
|
||||
if ($r == 0)
|
||||
{
|
||||
yyerror (&@$, "error: division by zero");
|
||||
yyerror (&@$, uctx, "error: division by zero");
|
||||
YYERROR;
|
||||
}
|
||||
else
|
||||
@@ -231,8 +273,9 @@ symbol_count (void)
|
||||
| Scanner. |
|
||||
`----------*/
|
||||
|
||||
int
|
||||
yylex (const char **line, YYSTYPE *yylval, YYLTYPE *yylloc)
|
||||
yytoken_kind_t
|
||||
yylex (const char **line, YYSTYPE *yylval, YYLTYPE *yylloc,
|
||||
const user_context *uctx)
|
||||
{
|
||||
int c;
|
||||
|
||||
@@ -302,7 +345,7 @@ yylex (const char **line, YYSTYPE *yylval, YYLTYPE *yylloc)
|
||||
|
||||
// Stray characters.
|
||||
default:
|
||||
yyerror (yylloc, "syntax error: invalid character: %c", c);
|
||||
yyerror (yylloc, uctx, "syntax error: invalid character: %c", c);
|
||||
return TOK_YYerror;
|
||||
}
|
||||
}
|
||||
@@ -340,8 +383,11 @@ error_format_string (int argc)
|
||||
|
||||
|
||||
int
|
||||
yyreport_syntax_error (const yypcontext_t *ctx)
|
||||
yyreport_syntax_error (const yypcontext_t *ctx, const user_context *uctx)
|
||||
{
|
||||
if (uctx->silent)
|
||||
return 0;
|
||||
|
||||
enum { ARGS_MAX = 6 };
|
||||
yysymbol_kind_t arg[ARGS_MAX];
|
||||
int argsize = yypcontext_expected_tokens (ctx, arg, ARGS_MAX);
|
||||
@@ -352,11 +398,12 @@ yyreport_syntax_error (const yypcontext_t *ctx)
|
||||
argsize = ARGS_MAX;
|
||||
const char *format = error_format_string (1 + argsize + too_many_expected_tokens);
|
||||
|
||||
const YYLTYPE *loc = yypcontext_location (ctx);
|
||||
while (*format)
|
||||
// %@: location.
|
||||
if (format[0] == '%' && format[1] == '@')
|
||||
{
|
||||
YY_LOCATION_PRINT (stderr, *yypcontext_location (ctx));
|
||||
YY_LOCATION_PRINT (stderr, *loc);
|
||||
format += 2;
|
||||
}
|
||||
// %u: unexpected token.
|
||||
@@ -381,13 +428,25 @@ yyreport_syntax_error (const yypcontext_t *ctx)
|
||||
++format;
|
||||
}
|
||||
fputc ('\n', stderr);
|
||||
|
||||
// Quote the source line.
|
||||
{
|
||||
fprintf (stderr, "%5d | %s\n", loc->first_line, uctx->line);
|
||||
fprintf (stderr, "%5s | %*s", "", loc->first_column, "^");
|
||||
for (int i = loc->last_column - loc->first_column - 1; 0 < i; --i)
|
||||
putc ('~', stderr);
|
||||
putc ('\n', stderr);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// Called by yyparse on error.
|
||||
void yyerror (YYLTYPE *loc, char const *format, ...)
|
||||
void yyerror (YYLTYPE *loc, const user_context *uctx, char const *format, ...)
|
||||
{
|
||||
if (uctx->silent)
|
||||
return;
|
||||
|
||||
YY_LOCATION_PRINT (stderr, *loc);
|
||||
fputs (": ", stderr);
|
||||
va_list args;
|
||||
@@ -423,11 +482,13 @@ xstrndup (const char *string, size_t n)
|
||||
static int
|
||||
process_line (YYLTYPE *lloc, const char *line)
|
||||
{
|
||||
user_context uctx = {0, line};
|
||||
yypstate *ps = yypstate_new ();
|
||||
int status = 0;
|
||||
do {
|
||||
YYSTYPE lval;
|
||||
status = yypush_parse (ps, yylex (&line, &lval, lloc), &lval, lloc);
|
||||
yytoken_kind_t token = yylex (&line, &lval, lloc, &uctx);
|
||||
status = yypush_parse (ps, token, &lval, lloc, &uctx);
|
||||
} while (status == YYPUSH_MORE);
|
||||
yypstate_delete (ps);
|
||||
lloc->last_line++;
|
||||
@@ -442,18 +503,19 @@ expected_tokens (const char *input,
|
||||
int *tokens, int ntokens)
|
||||
{
|
||||
YYDPRINTF ((stderr, "expected_tokens (\"%s\")", input));
|
||||
user_context uctx = {1, input};
|
||||
|
||||
// Parse the current state of the line.
|
||||
yypstate *ps = yypstate_new ();
|
||||
int status = 0;
|
||||
YYLTYPE lloc = { 1, 1, 1, 1 };
|
||||
do {
|
||||
YYLTYPE lloc = { 1, 1, 1, 1 };
|
||||
YYSTYPE lval;
|
||||
int token = yylex (&input, &lval, &lloc);
|
||||
yytoken_kind_t token = yylex (&input, &lval, &lloc, &uctx);
|
||||
// Don't let the parse know when we reach the end of input.
|
||||
if (!token)
|
||||
if (token == TOK_YYEOF)
|
||||
break;
|
||||
status = yypush_parse (ps, token, &lval, &lloc);
|
||||
status = yypush_parse (ps, token, &lval, &lloc, &uctx);
|
||||
} while (status == YYPUSH_MORE);
|
||||
|
||||
int res = 0;
|
||||
|
||||
@@ -1,3 +1,22 @@
|
||||
/* Parser for lexcalc. -*- C -*-
|
||||
|
||||
Copyright (C) 2018-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/>. */
|
||||
|
||||
// Prologue (directives).
|
||||
%expect 0
|
||||
|
||||
@@ -19,6 +38,9 @@
|
||||
#include <stdlib.h> // getenv.
|
||||
}
|
||||
|
||||
// Include the header in the implementation rather than duplicating it.
|
||||
%define api.header.include {"parse.h"}
|
||||
|
||||
// Don't share global variables between the scanner and the parser.
|
||||
%define api.pure full
|
||||
|
||||
|
||||
@@ -1,4 +1,23 @@
|
||||
/* Prologue (directives). -*- C -*- */
|
||||
/* Scanner for lexcalc. -*- C -*-
|
||||
|
||||
Copyright (C) 2018-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/>. */
|
||||
|
||||
/* Prologue (directives). */
|
||||
|
||||
/* Disable Flex features we don't need, to avoid warnings. */
|
||||
%option nodefault noinput nounput noyywrap
|
||||
|
||||
@@ -1,3 +1,22 @@
|
||||
/* Parser and scanner for pushcalc. -*- C -*-
|
||||
|
||||
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/>. */
|
||||
|
||||
%code top {
|
||||
#include <ctype.h> /* isdigit. */
|
||||
#include <stdio.h> /* printf. */
|
||||
|
||||
@@ -1,3 +1,22 @@
|
||||
/* Parser for reccalc. -*- C -*-
|
||||
|
||||
Copyright (C) 2019-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/>. */
|
||||
|
||||
// Prologue (directives).
|
||||
%expect 0
|
||||
|
||||
@@ -46,14 +65,29 @@
|
||||
result parse (void);
|
||||
}
|
||||
|
||||
// Include the header in the implementation rather than duplicating it.
|
||||
%define api.header.include {"parse.h"}
|
||||
|
||||
// Don't share global variables between the scanner and the parser.
|
||||
%define api.pure full
|
||||
|
||||
// To avoid name clashes (e.g., with C's EOF) prefix token definitions
|
||||
// with TOK_ (e.g., TOK_EOF).
|
||||
%define api.token.prefix {TOK_}
|
||||
|
||||
// Generate YYSTYPE from the types assigned to symbols.
|
||||
%define api.value.type union
|
||||
%define parse.error verbose
|
||||
|
||||
// Error messages with "unexpected XXX, expected XXX...".
|
||||
%define parse.error detailed
|
||||
|
||||
// Enable run-time traces (yydebug).
|
||||
%define parse.trace
|
||||
|
||||
// Generate the parser description file (parse.output).
|
||||
%verbose
|
||||
|
||||
// Scanner and error count are exchanged between main, yyparse and yylex.
|
||||
// Scanner and error count are exchanged between main, yyparse and yylex.
|
||||
%param {yyscan_t scanner}{result *res}
|
||||
|
||||
%token
|
||||
|
||||
@@ -1,3 +1,22 @@
|
||||
/* Scanner for reccalc. -*- C -*-
|
||||
|
||||
Copyright (C) 2019-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/>. */
|
||||
|
||||
/* Prologue (directives). -*- C -*- */
|
||||
|
||||
/* Disable Flex features we don't need, to avoid warnings. */
|
||||
|
||||
@@ -1,3 +1,22 @@
|
||||
/* Parser and scanner for calc in D. -*- D -*-
|
||||
|
||||
Copyright (C) 2018-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/>. */
|
||||
|
||||
%language "D"
|
||||
|
||||
%define api.parser.class {Calc}
|
||||
|
||||
@@ -1,3 +1,22 @@
|
||||
/* Parser and scanner for calc in Java. -*- Java -*-
|
||||
|
||||
Copyright (C) 2018-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/>. */
|
||||
|
||||
%language "Java"
|
||||
|
||||
%define api.parser.class {Calc}
|
||||
|
||||
@@ -1,3 +1,22 @@
|
||||
/* Simple parser and scanner in Java. -*- Java -*-
|
||||
|
||||
Copyright (C) 2018-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/>. */
|
||||
|
||||
%language "Java"
|
||||
|
||||
%define api.parser.class {Calc}
|
||||
|
||||
+1
-1
Submodule gnulib updated: 845d69187a...ac34618e85
@@ -20,6 +20,7 @@
|
||||
/assure.h
|
||||
/attribute.h
|
||||
/basename-lgpl.c
|
||||
/basename-lgpl.h
|
||||
/basename.c
|
||||
/binary-io.c
|
||||
/binary-io.h
|
||||
@@ -312,6 +313,7 @@
|
||||
/stdlib.h
|
||||
/stdlib.in.h
|
||||
/stpcpy.c
|
||||
/stpncpy.c
|
||||
/strchrnul.c
|
||||
/strchrnul.valgrind
|
||||
/strdup.c
|
||||
|
||||
+1
-1
@@ -13,7 +13,6 @@
|
||||
/codeset.m4
|
||||
/config-h.m4
|
||||
/configmake.m4
|
||||
/dirname.m4
|
||||
/double-slash-root.m4
|
||||
/dup2.m4
|
||||
/eealloc.m4
|
||||
@@ -176,6 +175,7 @@
|
||||
/stdio_h.m4
|
||||
/stdlib_h.m4
|
||||
/stpcpy.m4
|
||||
/stpncpy.m4
|
||||
/strchrnul.m4
|
||||
/strdup.m4
|
||||
/strerror.m4
|
||||
|
||||
@@ -169,10 +169,10 @@ AnnotationList__compute_conflicted_tokens (bitset shift_tokens,
|
||||
bitset_copy (tokens, shift_tokens);
|
||||
for (int i = 0; i < reds->num; ++i)
|
||||
{
|
||||
bitset_and (conflicted_tokens_rule, tokens, reds->lookahead_tokens[i]);
|
||||
bitset_and (conflicted_tokens_rule, tokens, reds->lookaheads[i]);
|
||||
bitset_or (conflicted_tokens,
|
||||
conflicted_tokens, conflicted_tokens_rule);
|
||||
bitset_or (tokens, tokens, reds->lookahead_tokens[i]);
|
||||
bitset_or (tokens, tokens, reds->lookaheads[i]);
|
||||
/* Check that rules are sorted on rule number or the next step in
|
||||
AnnotationList__compute_from_inadequacies will misbehave. */
|
||||
aver (i == 0 || reds->rules[i-1] < reds->rules[i]);
|
||||
@@ -401,7 +401,7 @@ AnnotationList__compute_from_inadequacies (
|
||||
struct obstack *annotations_obstackp,
|
||||
InadequacyListNodeCount *inadequacy_list_node_count)
|
||||
{
|
||||
/* Return an empty list if s->lookahead_tokens = NULL. */
|
||||
/* Return an empty list if s->lookaheads = NULL. */
|
||||
if (s->consistent)
|
||||
return;
|
||||
|
||||
@@ -422,7 +422,7 @@ AnnotationList__compute_from_inadequacies (
|
||||
/* Allocate the annotation node. */
|
||||
{
|
||||
for (int rule_i = 0; rule_i < s->reductions->num; ++rule_i)
|
||||
if (bitset_test (s->reductions->lookahead_tokens[rule_i],
|
||||
if (bitset_test (s->reductions->lookaheads[rule_i],
|
||||
conflicted_token))
|
||||
++contribution_count;
|
||||
if (bitset_test (shift_tokens, conflicted_token))
|
||||
@@ -445,7 +445,7 @@ AnnotationList__compute_from_inadequacies (
|
||||
for (int rule_i = 0; rule_i < s->reductions->num; ++rule_i)
|
||||
{
|
||||
rule *the_rule = s->reductions->rules[rule_i];
|
||||
if (bitset_test (s->reductions->lookahead_tokens[rule_i],
|
||||
if (bitset_test (s->reductions->lookaheads[rule_i],
|
||||
conflicted_token))
|
||||
{
|
||||
bitset_set (actions, rule_i);
|
||||
|
||||
+35
-3
@@ -35,6 +35,13 @@
|
||||
#include "getargs.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;
|
||||
|
||||
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
|
||||
flush (FILE *out)
|
||||
{
|
||||
@@ -427,9 +448,20 @@ warnings_print_categories (warnings warn_flags, FILE *out)
|
||||
const char* style = severity_style (s);
|
||||
fputs (" [", out);
|
||||
begin_use_class (style, out);
|
||||
fprintf (out, "-W%s%s",
|
||||
s == severity_error ? "error=" : "",
|
||||
argmatch_warning_argument (&w));
|
||||
// E.g., "counterexamples".
|
||||
const char *warning = 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);
|
||||
fputc (']', out);
|
||||
/* Display only the first match, the second is "-Wall". */
|
||||
|
||||
+29
-25
@@ -250,9 +250,9 @@ flush_shift (state *s, int token)
|
||||
`--------------------------------------------------------------------*/
|
||||
|
||||
static void
|
||||
flush_reduce (bitset lookahead_tokens, int token)
|
||||
flush_reduce (bitset lookaheads, int token)
|
||||
{
|
||||
bitset_reset (lookahead_tokens, token);
|
||||
bitset_reset (lookaheads, token);
|
||||
}
|
||||
|
||||
|
||||
@@ -275,10 +275,10 @@ resolve_sr_conflict (state *s, int ruleno, symbol **errors, int *nerrs)
|
||||
/* Find the rule to reduce by to get precedence of reduction. */
|
||||
rule *redrule = reds->rules[ruleno];
|
||||
int redprec = redrule->prec->prec;
|
||||
bitset lookahead_tokens = reds->lookahead_tokens[ruleno];
|
||||
bitset lookaheads = reds->lookaheads[ruleno];
|
||||
|
||||
for (symbol_number i = 0; i < ntokens; ++i)
|
||||
if (bitset_test (lookahead_tokens, i)
|
||||
if (bitset_test (lookaheads, i)
|
||||
&& bitset_test (lookahead_set, i)
|
||||
&& symbols[i]->content->prec)
|
||||
{
|
||||
@@ -295,7 +295,7 @@ resolve_sr_conflict (state *s, int ruleno, symbol **errors, int *nerrs)
|
||||
{
|
||||
register_precedence (i, redrule->prec->number);
|
||||
log_resolution (redrule, i, shift_resolution);
|
||||
flush_reduce (lookahead_tokens, i);
|
||||
flush_reduce (lookaheads, i);
|
||||
}
|
||||
else
|
||||
/* Matching precedence levels.
|
||||
@@ -316,7 +316,7 @@ resolve_sr_conflict (state *s, int ruleno, symbol **errors, int *nerrs)
|
||||
case right_assoc:
|
||||
register_assoc (i, redrule->prec->number);
|
||||
log_resolution (redrule, i, right_resolution);
|
||||
flush_reduce (lookahead_tokens, i);
|
||||
flush_reduce (lookaheads, i);
|
||||
break;
|
||||
|
||||
case left_assoc:
|
||||
@@ -329,7 +329,7 @@ resolve_sr_conflict (state *s, int ruleno, symbol **errors, int *nerrs)
|
||||
register_assoc (i, redrule->prec->number);
|
||||
log_resolution (redrule, i, nonassoc_resolution);
|
||||
flush_shift (s, i);
|
||||
flush_reduce (lookahead_tokens, i);
|
||||
flush_reduce (lookaheads, i);
|
||||
/* Record an explicit error for this token. */
|
||||
errors[(*nerrs)++] = symbols[i];
|
||||
break;
|
||||
@@ -369,7 +369,7 @@ set_conflicts (state *s, symbol **errors)
|
||||
for (int i = 0; i < reds->num; ++i)
|
||||
if (reds->rules[i]->prec
|
||||
&& reds->rules[i]->prec->prec
|
||||
&& !bitset_disjoint_p (reds->lookahead_tokens[i], lookahead_set))
|
||||
&& !bitset_disjoint_p (reds->lookaheads[i], lookahead_set))
|
||||
resolve_sr_conflict (s, i, errors, &nerrs);
|
||||
|
||||
if (nerrs)
|
||||
@@ -385,13 +385,13 @@ set_conflicts (state *s, symbol **errors)
|
||||
/* Loop over all rules which require lookahead in this state. Check
|
||||
for conflicts not resolved above.
|
||||
|
||||
reds->lookahead_tokens can be NULL if the LR type is LR(0). */
|
||||
if (reds->lookahead_tokens)
|
||||
reds->lookaheads can be NULL if the LR type is LR(0). */
|
||||
if (reds->lookaheads)
|
||||
for (int i = 0; i < reds->num; ++i)
|
||||
{
|
||||
if (!bitset_disjoint_p (reds->lookahead_tokens[i], lookahead_set))
|
||||
if (!bitset_disjoint_p (reds->lookaheads[i], lookahead_set))
|
||||
conflicts[s->number] = true;
|
||||
bitset_or (lookahead_set, lookahead_set, reds->lookahead_tokens[i]);
|
||||
bitset_or (lookahead_set, lookahead_set, reds->lookaheads[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -460,7 +460,7 @@ count_state_sr_conflicts (const state *s)
|
||||
}
|
||||
|
||||
for (int i = 0; i < reds->num; ++i)
|
||||
bitset_or (lookahead_set, lookahead_set, reds->lookahead_tokens[i]);
|
||||
bitset_or (lookahead_set, lookahead_set, reds->lookaheads[i]);
|
||||
|
||||
bitset_and (lookahead_set, lookahead_set, shift_set);
|
||||
|
||||
@@ -499,7 +499,7 @@ count_state_rr_conflicts (const state *s)
|
||||
{
|
||||
int count = 0;
|
||||
for (int j = 0; j < reds->num; ++j)
|
||||
count += bitset_test (reds->lookahead_tokens[j], i);
|
||||
count += bitset_test (reds->lookaheads[j], i);
|
||||
if (2 <= count)
|
||||
res += count-1;
|
||||
}
|
||||
@@ -534,7 +534,7 @@ count_rule_state_sr_conflicts (rule *r, state *s)
|
||||
for (int i = 0; i < reds->num; ++i)
|
||||
if (reds->rules[i] == r)
|
||||
{
|
||||
bitset lookaheads = reds->lookahead_tokens[i];
|
||||
bitset lookaheads = reds->lookaheads[i];
|
||||
int j;
|
||||
FOR_EACH_SHIFT (trans, j)
|
||||
res += bitset_test (lookaheads, TRANSITION_SYMBOL (trans, j));
|
||||
@@ -576,8 +576,8 @@ count_rule_state_rr_conflicts (rule *r, state *s)
|
||||
if (reds->rules[j] != r)
|
||||
{
|
||||
bitset_and (lookaheads,
|
||||
reds->lookahead_tokens[i],
|
||||
reds->lookahead_tokens[j]);
|
||||
reds->lookaheads[i],
|
||||
reds->lookaheads[j]);
|
||||
res += bitset_count (lookaheads);
|
||||
}
|
||||
bitset_free (lookaheads);
|
||||
@@ -686,7 +686,8 @@ conflicts_print (void)
|
||||
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
|
||||
would make it ugly. */
|
||||
{
|
||||
@@ -703,7 +704,8 @@ conflicts_print (void)
|
||||
complain (NULL, complaint,
|
||||
_("shift/reduce conflicts: %d found, %d expected"),
|
||||
total, expected);
|
||||
has_unexpected_conflicts = true;
|
||||
if (total)
|
||||
unexpected_conflicts_warning = complaint;
|
||||
}
|
||||
}
|
||||
else if (total)
|
||||
@@ -713,7 +715,7 @@ conflicts_print (void)
|
||||
"%d shift/reduce conflicts",
|
||||
total),
|
||||
total);
|
||||
has_unexpected_conflicts = true;
|
||||
unexpected_conflicts_warning = Wconflicts_sr;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -731,7 +733,8 @@ conflicts_print (void)
|
||||
complain (NULL, complaint,
|
||||
_("reduce/reduce conflicts: %d found, %d expected"),
|
||||
total, expected);
|
||||
has_unexpected_conflicts = true;
|
||||
if (total)
|
||||
unexpected_conflicts_warning = complaint;
|
||||
}
|
||||
}
|
||||
else if (total)
|
||||
@@ -741,15 +744,16 @@ conflicts_print (void)
|
||||
"%d reduce/reduce conflicts",
|
||||
total),
|
||||
total);
|
||||
has_unexpected_conflicts = true;
|
||||
unexpected_conflicts_warning = Wconflicts_rr;
|
||||
}
|
||||
}
|
||||
|
||||
if (warning_is_enabled (Wcounterexamples))
|
||||
report_counterexamples ();
|
||||
else if (has_unexpected_conflicts)
|
||||
complain (NULL, Wother,
|
||||
_("rerun with option '-Wcounterexamples' to generate conflict counterexamples"));
|
||||
else if (unexpected_conflicts_warning != Wnone)
|
||||
subcomplain (NULL, unexpected_conflicts_warning,
|
||||
_("rerun with option '-Wcounterexamples'"
|
||||
" to generate conflict counterexamples"));
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
+176
-103
@@ -26,6 +26,7 @@
|
||||
#include <gl_linked_list.h>
|
||||
#include <gl_rbtreehash_list.h>
|
||||
#include <hash.h>
|
||||
#include <mbswidth.h>
|
||||
#include <stdlib.h>
|
||||
#include <textstyle.h>
|
||||
#include <time.h>
|
||||
@@ -76,17 +77,29 @@ typedef struct
|
||||
{
|
||||
derivation *d1;
|
||||
derivation *d2;
|
||||
bool shift_reduce;
|
||||
bool unifying;
|
||||
bool timeout;
|
||||
} counterexample;
|
||||
|
||||
static counterexample *
|
||||
new_counterexample (derivation *d1, derivation *d2,
|
||||
bool shift_reduce,
|
||||
bool u, bool t)
|
||||
{
|
||||
counterexample *res = xmalloc (sizeof (counterexample));
|
||||
res->d1 = d1;
|
||||
res->d2 = d2;
|
||||
counterexample *res = xmalloc (sizeof *res);
|
||||
res->shift_reduce = shift_reduce;
|
||||
if (shift_reduce)
|
||||
{
|
||||
// Display the shift first.
|
||||
res->d1 = d2;
|
||||
res->d2 = d1;
|
||||
}
|
||||
else
|
||||
{
|
||||
res->d1 = d1;
|
||||
res->d2 = d2;
|
||||
}
|
||||
res->unifying = u;
|
||||
res->timeout = t;
|
||||
return res;
|
||||
@@ -100,14 +113,37 @@ free_counterexample (counterexample *cex)
|
||||
free (cex);
|
||||
}
|
||||
|
||||
static void
|
||||
print_counterexample (counterexample *cex, FILE *out, const char *prefix)
|
||||
static int max (int a, int b)
|
||||
{
|
||||
fprintf (out, " %s%-20s ",
|
||||
prefix, cex->unifying ? _("Example") : _("First example"));
|
||||
derivation_print_leaves (cex->d1, out, prefix);
|
||||
fprintf (out, " %s%-20s ",
|
||||
prefix, _("First derivation"));
|
||||
return a < b ? b : a;
|
||||
}
|
||||
|
||||
static void
|
||||
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);
|
||||
|
||||
// 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.
|
||||
if (!cex->unifying || is_styled (stderr))
|
||||
{
|
||||
fprintf (out, " %s%-20s ",
|
||||
prefix, cex->unifying ? _("Example") : _("Second example"));
|
||||
derivation_print_leaves (cex->d2, out, prefix);
|
||||
if (flat)
|
||||
fprintf (out, " %s%s%*s ", 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 ",
|
||||
prefix, _("Second derivation"));
|
||||
if (flat)
|
||||
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);
|
||||
|
||||
fputc ('\n', out);
|
||||
if (out != stderr)
|
||||
putc ('\n', out);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -144,7 +187,7 @@ typedef struct si_bfs_node
|
||||
static si_bfs_node *
|
||||
si_bfs_new (state_item_number si, si_bfs_node *parent)
|
||||
{
|
||||
si_bfs_node *res = xcalloc (1, sizeof (si_bfs_node));
|
||||
si_bfs_node *res = xcalloc (1, sizeof *res);
|
||||
res->si = si;
|
||||
res->parent = parent;
|
||||
res->reference_count = 1;
|
||||
@@ -175,6 +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
|
||||
* 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);
|
||||
|
||||
gl_list_t queue = gl_list_create (GL_LINKED_LIST, NULL, NULL,
|
||||
(gl_listelement_dispose_fn) si_bfs_free,
|
||||
true, 1, (const void **) &init);
|
||||
si_bfs_node_list queue
|
||||
= gl_list_create (GL_LINKED_LIST, NULL, NULL,
|
||||
(gl_listelement_dispose_fn) si_bfs_free,
|
||||
true, 1, (const void **) &init);
|
||||
si_bfs_node *node = NULL;
|
||||
// breadth-first search for a path of productions to the conflict symbol
|
||||
while (gl_list_size (queue) > 0)
|
||||
{
|
||||
node = (si_bfs_node *) gl_list_get_at (queue, 0);
|
||||
state_item *silast = state_items + node->si;
|
||||
state_item *silast = &state_items[node->si];
|
||||
symbol_number sym = item_number_as_symbol_number (*silast->item);
|
||||
if (sym == conflict_sym)
|
||||
break;
|
||||
@@ -238,7 +284,7 @@ expand_to_conflict (state_item_number start, symbol_number conflict_sym)
|
||||
|
||||
for (si_bfs_node *n = node; n != NULL; n = n->parent)
|
||||
{
|
||||
state_item *si = state_items + n->si;
|
||||
state_item *si = &state_items[n->si];
|
||||
item_number *pos = si->item;
|
||||
if (SI_PRODUCTION (si))
|
||||
{
|
||||
@@ -274,7 +320,7 @@ expand_to_conflict (state_item_number start, symbol_number conflict_sym)
|
||||
*/
|
||||
static derivation *
|
||||
complete_diverging_example (symbol_number conflict_sym,
|
||||
gl_list_t path, derivation_list derivs)
|
||||
state_item_list path, derivation_list derivs)
|
||||
{
|
||||
// The idea is to transfer each pending symbol on the productions
|
||||
// associated with the given StateItems to the resulting derivation.
|
||||
@@ -395,15 +441,15 @@ complete_diverging_example (symbol_number conflict_sym,
|
||||
/* Iterate backwards through the shifts of the path in the reduce
|
||||
conflict, and find a path of shifts from the shift conflict that
|
||||
goes through the same states. */
|
||||
static gl_list_t
|
||||
nonunifying_shift_path (gl_list_t reduce_path, state_item *shift_conflict)
|
||||
static state_item_list
|
||||
nonunifying_shift_path (state_item_list reduce_path, state_item *shift_conflict)
|
||||
{
|
||||
gl_list_node_t tmp = gl_list_add_last (reduce_path, NULL);
|
||||
gl_list_node_t next_node = gl_list_previous_node (reduce_path, tmp);
|
||||
gl_list_node_t node = gl_list_previous_node (reduce_path, next_node);
|
||||
gl_list_remove_node (reduce_path, tmp);
|
||||
state_item *si = shift_conflict;
|
||||
gl_list_t result =
|
||||
state_item_list result =
|
||||
gl_list_create_empty (GL_LINKED_LIST, NULL, NULL, NULL, true);
|
||||
// FIXME: bool paths_merged;
|
||||
for (; node != NULL; next_node = node,
|
||||
@@ -425,10 +471,10 @@ nonunifying_shift_path (gl_list_t reduce_path, state_item *shift_conflict)
|
||||
|
||||
// bfs to find a shift to the right state
|
||||
si_bfs_node *init = si_bfs_new (si - state_items, NULL);
|
||||
gl_list_t queue =
|
||||
gl_list_create (GL_LINKED_LIST, NULL, NULL,
|
||||
(gl_listelement_dispose_fn) si_bfs_free,
|
||||
true, 1, (const void **) &init);
|
||||
si_bfs_node_list queue
|
||||
= gl_list_create (GL_LINKED_LIST, NULL, NULL,
|
||||
(gl_listelement_dispose_fn) si_bfs_free,
|
||||
true, 1, (const void **) &init);
|
||||
si_bfs_node *sis = NULL;
|
||||
state_item *prevsi = NULL;
|
||||
while (gl_list_size (queue) > 0)
|
||||
@@ -438,7 +484,7 @@ nonunifying_shift_path (gl_list_t reduce_path, state_item *shift_conflict)
|
||||
if (sis->si == 0)
|
||||
break;
|
||||
|
||||
state_item *search_si = state_items + sis->si;
|
||||
state_item *search_si = &state_items[sis->si];
|
||||
// if the current state-item is a production item,
|
||||
// its reverse production items get added to the queue.
|
||||
// Otherwise, look for a reverse transition to the target state.
|
||||
@@ -447,7 +493,7 @@ nonunifying_shift_path (gl_list_t reduce_path, state_item *shift_conflict)
|
||||
state_item_number sin;
|
||||
BITSET_FOR_EACH (biter, rsi, sin, 0)
|
||||
{
|
||||
prevsi = state_items + sin;
|
||||
prevsi = &state_items[sin];
|
||||
if (SI_TRANSITION (search_si))
|
||||
{
|
||||
if (prevsi->state == refsi->state)
|
||||
@@ -465,9 +511,9 @@ nonunifying_shift_path (gl_list_t reduce_path, state_item *shift_conflict)
|
||||
// prepend path to shift we found
|
||||
if (sis)
|
||||
{
|
||||
gl_list_node_t ln = gl_list_add_first (result, state_items + sis->si);
|
||||
gl_list_node_t ln = gl_list_add_first (result, &state_items[sis->si]);
|
||||
for (si_bfs_node *n = sis->parent; n; n = n->parent)
|
||||
ln = gl_list_add_after (result, ln, state_items + n->si);
|
||||
ln = gl_list_add_after (result, ln, &state_items[n->si]);
|
||||
|
||||
}
|
||||
si = prevsi;
|
||||
@@ -493,17 +539,17 @@ nonunifying_shift_path (gl_list_t reduce_path, state_item *shift_conflict)
|
||||
static counterexample *
|
||||
example_from_path (bool shift_reduce,
|
||||
state_item_number itm2,
|
||||
gl_list_t shortest_path, symbol_number next_sym)
|
||||
state_item_list shortest_path, symbol_number next_sym)
|
||||
{
|
||||
derivation *deriv1 =
|
||||
complete_diverging_example (next_sym, shortest_path, NULL);
|
||||
gl_list_t path_2
|
||||
state_item_list path_2
|
||||
= shift_reduce
|
||||
? nonunifying_shift_path (shortest_path, &state_items [itm2])
|
||||
: shortest_path_from_start (itm2, next_sym);
|
||||
derivation *deriv2 = complete_diverging_example (next_sym, path_2, NULL);
|
||||
gl_list_free (path_2);
|
||||
return new_counterexample (deriv1, deriv2, false, true);
|
||||
return new_counterexample (deriv1, deriv2, shift_reduce, false, true);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -525,7 +571,7 @@ typedef struct
|
||||
static search_state *
|
||||
initial_search_state (state_item *conflict1, state_item *conflict2)
|
||||
{
|
||||
search_state *res = xmalloc (sizeof (search_state));
|
||||
search_state *res = xmalloc (sizeof *res);
|
||||
res->states[0] = new_parse_state (conflict1);
|
||||
res->states[1] = new_parse_state (conflict2);
|
||||
parse_state_retain (res->states[0]);
|
||||
@@ -537,7 +583,7 @@ initial_search_state (state_item *conflict1, state_item *conflict2)
|
||||
static search_state *
|
||||
new_search_state (parse_state *ps1, parse_state *ps2, int complexity)
|
||||
{
|
||||
search_state *res = xmalloc (sizeof (search_state));
|
||||
search_state *res = xmalloc (sizeof *res);
|
||||
res->states[0] = ps1;
|
||||
res->states[1] = ps2;
|
||||
parse_state_retain (res->states[0]);
|
||||
@@ -549,8 +595,8 @@ new_search_state (parse_state *ps1, parse_state *ps2, int complexity)
|
||||
static search_state *
|
||||
copy_search_state (search_state *parent)
|
||||
{
|
||||
search_state *res = xmalloc (sizeof (search_state));
|
||||
memcpy (res, parent, sizeof (search_state));
|
||||
search_state *res = xmalloc (sizeof *res);
|
||||
*res = *parent;
|
||||
parse_state_retain (res->states[0]);
|
||||
parse_state_retain (res->states[1]);
|
||||
return res;
|
||||
@@ -583,6 +629,8 @@ search_state_print (search_state *ss)
|
||||
putc ('\n', stderr);
|
||||
}
|
||||
|
||||
typedef gl_list_t search_state_list;
|
||||
|
||||
static inline bool
|
||||
search_state_list_next (gl_list_iterator_t *it, search_state **ss)
|
||||
{
|
||||
@@ -614,18 +662,20 @@ ss_set_parse_state (search_state *ss, int idx, parse_state *ps)
|
||||
*/
|
||||
static counterexample *
|
||||
complete_diverging_examples (search_state *ss,
|
||||
symbol_number next_sym)
|
||||
symbol_number next_sym,
|
||||
bool shift_reduce)
|
||||
{
|
||||
derivation *new_derivs[2];
|
||||
for (int i = 0; i < 2; ++i)
|
||||
{
|
||||
gl_list_t sitems;
|
||||
state_item_list sitems;
|
||||
derivation_list derivs;
|
||||
parse_state_lists (ss->states[i], &sitems, &derivs);
|
||||
new_derivs[i] = complete_diverging_example (next_sym, sitems, derivs);
|
||||
gl_list_free (sitems);
|
||||
}
|
||||
return new_counterexample (new_derivs[0], new_derivs[1], false, true);
|
||||
return new_counterexample (new_derivs[0], new_derivs[1],
|
||||
shift_reduce, false, true);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -635,7 +685,7 @@ complete_diverging_examples (search_state *ss,
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
gl_list_t states;
|
||||
search_state_list states;
|
||||
int complexity;
|
||||
} search_state_bundle;
|
||||
|
||||
@@ -664,11 +714,13 @@ ssb_equals (const search_state_bundle *s1, const search_state_bundle *s2)
|
||||
return s1->complexity == s2->complexity;
|
||||
}
|
||||
|
||||
typedef gl_list_t ssb_list;
|
||||
|
||||
static size_t
|
||||
visited_hasher (const search_state *ss, size_t max)
|
||||
visited_hasher (const search_state *ss, size_t maximum)
|
||||
{
|
||||
return (parse_state_hasher (ss->states[0], max)
|
||||
+ parse_state_hasher (ss->states[1], max)) % max;
|
||||
return (parse_state_hasher (ss->states[0], maximum)
|
||||
+ parse_state_hasher (ss->states[1], maximum)) % maximum;
|
||||
}
|
||||
|
||||
static bool
|
||||
@@ -679,7 +731,7 @@ visited_comparator (const search_state *ss1, const search_state *ss2)
|
||||
}
|
||||
|
||||
/* Priority queue for search states with minimal complexity. */
|
||||
static gl_list_t ssb_queue;
|
||||
static ssb_list ssb_queue;
|
||||
static Hash_table *visited;
|
||||
/* The set of parser states on the shortest lookahead-sensitive path. */
|
||||
static bitset scp_set = NULL;
|
||||
@@ -702,7 +754,7 @@ ssb_append (search_state *ss)
|
||||
parse_state_free_contents_early (ss->states[1]);
|
||||
parse_state_retain (ss->states[0]);
|
||||
parse_state_retain (ss->states[1]);
|
||||
search_state_bundle *ssb = xmalloc (sizeof (search_state_bundle));
|
||||
search_state_bundle *ssb = xmalloc (sizeof *ssb);
|
||||
ssb->complexity = ss->complexity;
|
||||
gl_list_node_t n = gl_list_search (ssb_queue, ssb);
|
||||
if (!n)
|
||||
@@ -756,12 +808,12 @@ reduction_cost (const parse_state *ps)
|
||||
return SHIFT_COST * shifts + PRODUCTION_COST * productions;
|
||||
}
|
||||
|
||||
static gl_list_t
|
||||
static search_state_list
|
||||
reduction_step (search_state *ss, const item_number *conflict_item,
|
||||
int parser_state, int rule_len)
|
||||
{
|
||||
(void) conflict_item; // FIXME: Unused
|
||||
gl_list_t result =
|
||||
search_state_list result =
|
||||
gl_list_create_empty (GL_LINKED_LIST, NULL, NULL, NULL, 1);
|
||||
|
||||
parse_state *ps = ss->states[parser_state];
|
||||
@@ -897,7 +949,7 @@ search_state_prepend (search_state *ss, symbol_number sym, bitset guide)
|
||||
* the same prefix up to the dot.
|
||||
*/
|
||||
static bool
|
||||
has_common_prefix (const item_number *itm1, const item_number *itm2)
|
||||
have_common_prefix (const item_number *itm1, const item_number *itm2)
|
||||
{
|
||||
int i = 0;
|
||||
for (; !item_number_is_rule_number (itm1[i]); ++i)
|
||||
@@ -988,14 +1040,14 @@ generate_next_states (search_state *ss, state_item *conflict1,
|
||||
// prepended further, reduce.
|
||||
if (ready1 && ready2)
|
||||
{
|
||||
gl_list_t reduced1 = reduction_step (ss, conflict1->item, 0, len1);
|
||||
search_state_list reduced1 = reduction_step (ss, conflict1->item, 0, len1);
|
||||
gl_list_add_last (reduced1, ss);
|
||||
search_state *red1 = NULL;
|
||||
for (gl_list_iterator_t iter = gl_list_iterator (reduced1);
|
||||
search_state_list_next (&iter, &red1);
|
||||
)
|
||||
{
|
||||
gl_list_t reduced2 =
|
||||
search_state_list reduced2 =
|
||||
reduction_step (red1, conflict2->item, 1, len2);
|
||||
search_state *red2 = NULL;
|
||||
for (gl_list_iterator_t iter2 = gl_list_iterator (reduced2);
|
||||
@@ -1011,7 +1063,7 @@ generate_next_states (search_state *ss, state_item *conflict1,
|
||||
}
|
||||
else if (ready1)
|
||||
{
|
||||
gl_list_t reduced1 = reduction_step (ss, conflict1->item, 0, len1);
|
||||
search_state_list reduced1 = reduction_step (ss, conflict1->item, 0, len1);
|
||||
search_state *red1 = NULL;
|
||||
for (gl_list_iterator_t iter = gl_list_iterator (reduced1);
|
||||
search_state_list_next (&iter, &red1);
|
||||
@@ -1021,7 +1073,7 @@ generate_next_states (search_state *ss, state_item *conflict1,
|
||||
}
|
||||
else if (ready2)
|
||||
{
|
||||
gl_list_t reduced2 = reduction_step (ss, conflict2->item, 1, len2);
|
||||
search_state_list reduced2 = reduction_step (ss, conflict2->item, 1, len2);
|
||||
search_state *red2 = NULL;
|
||||
for (gl_list_iterator_t iter2 = gl_list_iterator (reduced2);
|
||||
search_state_list_next (&iter2, &red2);
|
||||
@@ -1055,10 +1107,10 @@ static counterexample *
|
||||
unifying_example (state_item_number itm1,
|
||||
state_item_number itm2,
|
||||
bool shift_reduce,
|
||||
gl_list_t reduce_path, symbol_number next_sym)
|
||||
state_item_list reduce_path, symbol_number next_sym)
|
||||
{
|
||||
state_item *conflict1 = state_items + itm1;
|
||||
state_item *conflict2 = state_items + itm2;
|
||||
state_item *conflict1 = &state_items[itm1];
|
||||
state_item *conflict2 = &state_items[itm2];
|
||||
search_state *initial = initial_search_state (conflict1, conflict2);
|
||||
ssb_queue = gl_list_create_empty (GL_RBTREEHASH_LIST,
|
||||
(gl_listelement_equals_fn) ssb_equals,
|
||||
@@ -1094,7 +1146,7 @@ unifying_example (state_item_number itm1,
|
||||
const state_item *si1src = parse_state_head (ps1);
|
||||
const state_item *si2src = parse_state_head (ps2);
|
||||
if (item_rule (si1src->item)->lhs == item_rule (si2src->item)->lhs
|
||||
&& has_common_prefix (si1src->item, si2src->item))
|
||||
&& have_common_prefix (si1src->item, si2src->item))
|
||||
{
|
||||
// Stage 4: both paths share a prefix
|
||||
derivation *d1 = parse_state_derivation (ps1);
|
||||
@@ -1104,7 +1156,7 @@ unifying_example (state_item_number itm1,
|
||||
{
|
||||
// Once we have two derivations for the same symbol,
|
||||
// we've found a unifying counterexample.
|
||||
cex = new_counterexample (d1, d2, true, false);
|
||||
cex = new_counterexample (d1, d2, shift_reduce, true, false);
|
||||
derivation_retain (d1);
|
||||
derivation_retain (d2);
|
||||
goto cex_search_end;
|
||||
@@ -1142,7 +1194,7 @@ cex_search_end:;
|
||||
// If a search state from Stage 3 is available, use it
|
||||
// to construct a more compact nonunifying counterexample.
|
||||
if (stage3result)
|
||||
cex = complete_diverging_examples (stage3result, next_sym);
|
||||
cex = complete_diverging_examples (stage3result, next_sym, shift_reduce);
|
||||
// Otherwise, construct a nonunifying counterexample that
|
||||
// begins from the start state using the shortest
|
||||
// lookahead-sensitive path to the reduce item.
|
||||
@@ -1190,7 +1242,7 @@ counterexample_report (state_item_number itm1, state_item_number itm2,
|
||||
{
|
||||
// Compute the shortest lookahead-sensitive path and associated sets of
|
||||
// parser states.
|
||||
gl_list_t shortest_path = shortest_path_from_start (itm1, next_sym);
|
||||
state_item_list shortest_path = shortest_path_from_start (itm1, next_sym);
|
||||
bool reduce_prod_reached = false;
|
||||
const rule *reduce_rule = item_rule (state_items[itm1].item);
|
||||
|
||||
@@ -1219,14 +1271,24 @@ counterexample_report (state_item_number itm1, state_item_number itm2,
|
||||
free_counterexample (cex);
|
||||
}
|
||||
|
||||
|
||||
// ITM1 denotes a shift, ITM2 a reduce.
|
||||
static void
|
||||
counterexample_report_shift_reduce (state_item_number itm1, state_item_number itm2,
|
||||
symbol_number next_sym,
|
||||
FILE *out, const char *prefix)
|
||||
{
|
||||
fputs (prefix, out);
|
||||
fprintf (out, _("Shift/reduce conflict on token %s:\n"), symbols[next_sym]->tag);
|
||||
if (*prefix)
|
||||
if (out == stderr)
|
||||
complain (NULL, Wcounterexamples,
|
||||
_("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[itm2], out, prefix);
|
||||
@@ -1240,32 +1302,49 @@ counterexample_report_reduce_reduce (state_item_number itm1, state_item_number i
|
||||
FILE *out, const char *prefix)
|
||||
{
|
||||
{
|
||||
fputs (prefix, out);
|
||||
fputs (ngettext ("Reduce/reduce conflict on token",
|
||||
"Reduce/reduce conflict on tokens",
|
||||
bitset_count (conflict_syms)), out);
|
||||
struct obstack obstack;
|
||||
obstack_init (&obstack);
|
||||
bitset_iterator biter;
|
||||
state_item_number sym;
|
||||
const char *sep = " ";
|
||||
const char *sep = "";
|
||||
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 = ", ";
|
||||
}
|
||||
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[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
|
||||
find_state_item_number (const rule *r, state_number sn)
|
||||
{
|
||||
for (int i = state_item_map[sn]; i < state_item_map[sn + 1]; ++i)
|
||||
for (state_item_number i = state_item_map[sn]; i < state_item_map[sn + 1]; ++i)
|
||||
if (!SI_DISABLED (i)
|
||||
&& item_number_as_rule_number (*state_items[i].item) == r->number)
|
||||
return i;
|
||||
@@ -1277,41 +1356,35 @@ counterexample_report_state (const state *s, FILE *out, const char *prefix)
|
||||
{
|
||||
const state_number sn = s->number;
|
||||
const reductions *reds = s->reductions;
|
||||
bitset lookaheads = bitset_create (ntokens, BITSET_FIXED);
|
||||
for (int i = 0; i < reds->num; ++i)
|
||||
{
|
||||
const rule *r1 = reds->rules[i];
|
||||
const state_item_number c1 = find_state_item_number (r1, sn);
|
||||
for (int j = state_item_map[sn]; j < state_item_map[sn + 1]; ++j)
|
||||
if (!SI_DISABLED (j))
|
||||
for (state_item_number c2 = state_item_map[sn]; c2 < state_item_map[sn + 1]; ++c2)
|
||||
if (!SI_DISABLED (c2))
|
||||
{
|
||||
state_item *si = state_items + j;
|
||||
item_number conf = *si->item;
|
||||
item_number conf = *state_items[c2].item;
|
||||
if (item_number_is_symbol_number (conf)
|
||||
&& bitset_test (reds->lookahead_tokens[i], conf))
|
||||
counterexample_report_shift_reduce (c1, j, conf, out, prefix);
|
||||
&& bitset_test (reds->lookaheads[i], conf))
|
||||
counterexample_report_shift_reduce (c1, c2, conf, out, prefix);
|
||||
}
|
||||
for (int j = i+1; j < reds->num; ++j)
|
||||
{
|
||||
bitset conf = bitset_create (ntokens, BITSET_FIXED);
|
||||
bitset_intersection (conf,
|
||||
reds->lookahead_tokens[i],
|
||||
reds->lookahead_tokens[j]);
|
||||
if (!bitset_empty_p (conf))
|
||||
{
|
||||
const rule *r2 = reds->rules[j];
|
||||
for (int k = state_item_map[sn]; k < state_item_map[sn + 1]; ++k)
|
||||
if (!SI_DISABLED (k))
|
||||
{
|
||||
state_item *si = state_items + k;
|
||||
const rule *r = item_rule (si->item);
|
||||
if (r == r2)
|
||||
{
|
||||
counterexample_report_reduce_reduce (c1, k, conf, out, prefix);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
bitset_free (conf);
|
||||
const rule *r2 = reds->rules[j];
|
||||
// Conflicts: common lookaheads.
|
||||
bitset_intersection (lookaheads,
|
||||
reds->lookaheads[i],
|
||||
reds->lookaheads[j]);
|
||||
if (!bitset_empty_p (lookaheads))
|
||||
for (state_item_number c2 = state_item_map[sn]; c2 < state_item_map[sn + 1]; ++c2)
|
||||
if (!SI_DISABLED (c2)
|
||||
&& item_rule (state_items[c2].item) == r2)
|
||||
{
|
||||
counterexample_report_reduce_reduce (c1, c2, lookaheads, out, prefix);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
bitset_free (lookaheads);
|
||||
}
|
||||
|
||||
@@ -20,11 +20,17 @@
|
||||
#ifndef COUNTEREXAMPLE_H
|
||||
# define COUNTEREXAMPLE_H
|
||||
|
||||
# include "state-item.h"
|
||||
# include "state.h"
|
||||
|
||||
// Init/deinit this module.
|
||||
void counterexample_init (void);
|
||||
void counterexample_free (void);
|
||||
|
||||
void counterexample_report_state (const state *s, FILE *out, const char *prefix);
|
||||
// Print the counterexamples for the conflicts of state S.
|
||||
//
|
||||
// Used both for the warnings on the terminal (OUT = stderr, PREFIX =
|
||||
// ""), and for the reports (OUT != stderr, PREFIX != "").
|
||||
void
|
||||
counterexample_report_state (const state *s, FILE *out, const char *prefix);
|
||||
|
||||
#endif /* COUNTEREXAMPLE_H */
|
||||
|
||||
+272
-41
@@ -20,8 +20,11 @@
|
||||
#include <config.h>
|
||||
|
||||
#include "derivation.h"
|
||||
#include "glyphs.h"
|
||||
|
||||
#include <c-ctype.h>
|
||||
#include <gl_linked_list.h>
|
||||
#include <mbswidth.h>
|
||||
|
||||
#include "system.h"
|
||||
#include "complain.h"
|
||||
@@ -29,11 +32,15 @@
|
||||
struct derivation
|
||||
{
|
||||
symbol_number sym;
|
||||
gl_list_t children;
|
||||
derivation_list children;
|
||||
int reference_count;
|
||||
// Color assigned for styling. Guarantees that the derivation is
|
||||
// always displayed with the same color, independently of the order
|
||||
// in which the derivations are traversed.
|
||||
int color;
|
||||
};
|
||||
|
||||
static derivation d_dot = { -1, NULL, -1 };
|
||||
static derivation d_dot = { -1, NULL, -1, -1 };
|
||||
|
||||
derivation *
|
||||
derivation_dot (void)
|
||||
@@ -73,6 +80,7 @@ derivation_new (symbol_number sym, derivation_list children)
|
||||
deriv->sym = sym;
|
||||
deriv->children = children;
|
||||
deriv->reference_count = 0;
|
||||
deriv->color = -1;
|
||||
return deriv;
|
||||
}
|
||||
|
||||
@@ -126,27 +134,242 @@ derivation_size (const derivation *deriv)
|
||||
return size;
|
||||
}
|
||||
|
||||
/* Print DERIV, colored according to COUNTER.
|
||||
Return false if nothing is printed. */
|
||||
|
||||
static int
|
||||
max (int a, int b)
|
||||
{
|
||||
return a < b ? b : a;
|
||||
}
|
||||
|
||||
// Longest distance from root to leaf.
|
||||
static int
|
||||
derivation_depth (const derivation *deriv)
|
||||
{
|
||||
if (deriv->children)
|
||||
{
|
||||
// Children's depth cannot be 0, even if there are no children
|
||||
// (the case of a derivation with an empty RHS).
|
||||
int res = 1;
|
||||
derivation *child;
|
||||
for (gl_list_iterator_t it = gl_list_iterator (deriv->children);
|
||||
derivation_list_next (&it, &child);
|
||||
)
|
||||
res = max (res, derivation_depth (child));
|
||||
return res + 1;
|
||||
}
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
static bool
|
||||
derivation_print_impl (const derivation *deriv, FILE *f,
|
||||
bool leaves_only,
|
||||
int *counter, const char *prefix)
|
||||
all_spaces (const char *s)
|
||||
{
|
||||
while (c_isspace (*s))
|
||||
s++;
|
||||
return *s == '\0';
|
||||
}
|
||||
|
||||
// Printing the derivation as trees without trailing spaces is
|
||||
// painful: we cannot simply pad one "column" before moving to the
|
||||
// next:
|
||||
//
|
||||
// exp
|
||||
// ↳ x1 e1 foo1 x1
|
||||
// ↳ x2 ↳ ε ↳ foo2 ↳ x2
|
||||
// ↳ x3 ↳ foo3 ↳ x3
|
||||
// ↳ "X" • ↳ x1 foo4 ↳ "X"
|
||||
// ↳ x2 ↳ "quuux"
|
||||
// ↳ x3
|
||||
// ↳ "X"
|
||||
//
|
||||
// It's hard for a column to know that it's "last" to decide whether
|
||||
// to output the right-padding or not. So when we need to pad on the
|
||||
// right to complete a column, we don't output the spaces, we
|
||||
// accumulate the width of padding in *PADDING.
|
||||
//
|
||||
// Each time we actually print something (non space), we flush that
|
||||
// padding. When we _don't_ print something, its width is added to
|
||||
// the current padding.
|
||||
//
|
||||
// This function implements this.
|
||||
//
|
||||
// When COND is true, put S on OUT, 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)
|
||||
{
|
||||
const symbol *sym = symbols[deriv->sym];
|
||||
char style[20];
|
||||
snprintf (style, 20, "cex-%d", *counter);
|
||||
snprintf (style, 20, "cex-%d", deriv->color);
|
||||
|
||||
if (depth == 0 || depth == 1)
|
||||
{
|
||||
begin_use_class (style, out);
|
||||
begin_use_class ("cex-step", out);
|
||||
}
|
||||
if (depth == 0)
|
||||
{
|
||||
res += fputs_if (true, out, padding, sym->tag);
|
||||
}
|
||||
else
|
||||
{
|
||||
res += fputs_if (depth == 1, out, padding, down_arrow);
|
||||
if (gl_list_size (deriv->children) == 0)
|
||||
// Empty rhs.
|
||||
res += fputs_if (depth == 1, out, padding, empty);
|
||||
else
|
||||
{
|
||||
bool first = true;
|
||||
derivation *child;
|
||||
for (gl_list_iterator_t it = gl_list_iterator (deriv->children);
|
||||
derivation_list_next (&it, &child);
|
||||
)
|
||||
{
|
||||
if (!first)
|
||||
res += fputs_if (depth == 1, out, padding, derivation_separator);
|
||||
res += derivation_print_tree_impl (child, out, depth - 1, padding);
|
||||
first = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (depth == 0 || depth == 1)
|
||||
{
|
||||
end_use_class ("cex-step", out);
|
||||
end_use_class (style, out);
|
||||
}
|
||||
*padding += width - res;
|
||||
res = width;
|
||||
}
|
||||
else if (deriv == &d_dot)
|
||||
{
|
||||
if (depth == 0)
|
||||
begin_use_class ("cex-dot", out);
|
||||
res += fputs_if (depth == 0, out, padding, dot);
|
||||
if (depth == 0)
|
||||
end_use_class ("cex-dot", out);
|
||||
}
|
||||
else // leaf.
|
||||
{
|
||||
const symbol *sym = symbols[deriv->sym];
|
||||
if (depth == 0)
|
||||
begin_use_class ("cex-leaf", out);
|
||||
res += fputs_if (depth == 0, out, padding, sym->tag);
|
||||
if (depth == 0)
|
||||
end_use_class ("cex-leaf", out);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
static void
|
||||
derivation_print_tree (const derivation *deriv, FILE *out, const char *prefix)
|
||||
{
|
||||
fputc ('\n', out);
|
||||
for (int depth = 0, max_depth = derivation_depth (deriv);
|
||||
depth < max_depth; ++depth)
|
||||
{
|
||||
int padding = 0;
|
||||
fprintf (out, " %s", prefix);
|
||||
derivation_print_tree_impl (deriv, out, depth, &padding);
|
||||
fputc ('\n', out);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Print DERIV, colored according to COUNTER.
|
||||
Return false if nothing is printed. */
|
||||
static bool
|
||||
derivation_print_flat_impl (derivation *deriv, FILE *out,
|
||||
bool leaves_only,
|
||||
int *counter, const char *prefix)
|
||||
{
|
||||
if (deriv->children)
|
||||
{
|
||||
const symbol *sym = symbols[deriv->sym];
|
||||
deriv->color = *counter;
|
||||
++*counter;
|
||||
begin_use_class (style, f);
|
||||
char style[20];
|
||||
snprintf (style, 20, "cex-%d", deriv->color);
|
||||
begin_use_class (style, out);
|
||||
|
||||
if (!leaves_only)
|
||||
{
|
||||
fputs (prefix, f);
|
||||
begin_use_class ("cex-step", f);
|
||||
fprintf (f, "%s ::=[ ", sym->tag);
|
||||
end_use_class ("cex-step", f);
|
||||
fputs (prefix, out);
|
||||
begin_use_class ("cex-step", out);
|
||||
fprintf (out, "%s %s [ ", sym->tag, arrow);
|
||||
end_use_class ("cex-step", out);
|
||||
prefix = "";
|
||||
}
|
||||
bool res = false;
|
||||
@@ -155,7 +378,8 @@ derivation_print_impl (const derivation *deriv, FILE *f,
|
||||
derivation_list_next (&it, &child);
|
||||
)
|
||||
{
|
||||
if (derivation_print_impl (child, f, leaves_only, counter, prefix))
|
||||
if (derivation_print_flat_impl (child, out,
|
||||
leaves_only, counter, prefix))
|
||||
{
|
||||
prefix = " ";
|
||||
res = true;
|
||||
@@ -165,49 +389,56 @@ derivation_print_impl (const derivation *deriv, FILE *f,
|
||||
}
|
||||
if (!leaves_only)
|
||||
{
|
||||
begin_use_class ("cex-step", f);
|
||||
begin_use_class ("cex-step", out);
|
||||
if (res)
|
||||
fputs (" ]", f);
|
||||
fputs (" ]", out);
|
||||
else
|
||||
fputs ("]", f);
|
||||
end_use_class ("cex-step", f);
|
||||
fputs ("]", out);
|
||||
end_use_class ("cex-step", out);
|
||||
}
|
||||
end_use_class (style, f);
|
||||
end_use_class (style, out);
|
||||
return res;
|
||||
}
|
||||
else if (deriv == &d_dot)
|
||||
{
|
||||
fputs (prefix, f);
|
||||
begin_use_class ("cex-dot", f);
|
||||
print_dot (f);
|
||||
end_use_class ("cex-dot", f);
|
||||
fputs (prefix, out);
|
||||
begin_use_class ("cex-dot", out);
|
||||
fputs (dot, out);
|
||||
end_use_class ("cex-dot", out);
|
||||
}
|
||||
else // leaf.
|
||||
{
|
||||
fputs (prefix, f);
|
||||
fputs (prefix, out);
|
||||
const symbol *sym = symbols[deriv->sym];
|
||||
begin_use_class ("cex-leaf", f);
|
||||
fprintf (f, "%s", sym->tag);
|
||||
end_use_class ("cex-leaf", f);
|
||||
begin_use_class ("cex-leaf", out);
|
||||
fprintf (out, "%s", sym->tag);
|
||||
end_use_class ("cex-leaf", out);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
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
|
||||
derivation_print (const derivation *deriv, FILE *out, const char *prefix)
|
||||
{
|
||||
int counter = 0;
|
||||
fputs (prefix, out);
|
||||
derivation_print_impl (deriv, out, false, &counter, "");
|
||||
fputc ('\n', out);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
derivation_print_leaves (const derivation *deriv, FILE *out, const char *prefix)
|
||||
{
|
||||
int counter = 0;
|
||||
fputs (prefix, out);
|
||||
derivation_print_impl (deriv, out, true, &counter, "");
|
||||
fputc ('\n', out);
|
||||
if (getenv ("YYFLAT"))
|
||||
derivation_print_flat (deriv, out, prefix);
|
||||
else
|
||||
derivation_print_tree (deriv, out, prefix);
|
||||
}
|
||||
|
||||
+4
-1
@@ -60,12 +60,15 @@ static inline derivation *derivation_new_leaf (symbol_number sym)
|
||||
{
|
||||
return derivation_new (sym, NULL);
|
||||
}
|
||||
|
||||
// Number of symbols.
|
||||
size_t derivation_size (const derivation *deriv);
|
||||
void derivation_print (const derivation *deriv, FILE *out, const char *prefix);
|
||||
void derivation_print_leaves (const derivation *deriv, FILE *out, const char *prefix);
|
||||
void derivation_print_leaves (const derivation *deriv, FILE *out);
|
||||
void derivation_free (derivation *deriv);
|
||||
void derivation_retain (derivation *deriv);
|
||||
|
||||
// A derivation denoting the position of the dot.
|
||||
derivation *derivation_dot (void);
|
||||
|
||||
#endif /* DERIVATION_H */
|
||||
|
||||
+1
-1
@@ -221,7 +221,7 @@ static const argmatch_report_arg argmatch_report_args[] =
|
||||
{ "none", report_none },
|
||||
{ "states", report_states },
|
||||
{ "itemsets", report_states | report_itemsets },
|
||||
{ "lookaheads", report_states | report_lookahead_tokens },
|
||||
{ "lookaheads", report_states | report_lookaheads },
|
||||
{ "solved", report_states | report_solved_conflicts },
|
||||
{ "counterexamples", report_cex },
|
||||
{ "cex", report_cex },
|
||||
|
||||
+1
-1
@@ -77,7 +77,7 @@ enum report
|
||||
report_none = 0,
|
||||
report_states = 1 << 0,
|
||||
report_itemsets = 1 << 1,
|
||||
report_lookahead_tokens = 1 << 2,
|
||||
report_lookaheads = 1 << 2,
|
||||
report_solved_conflicts = 1 << 3,
|
||||
report_cex = 1 << 4,
|
||||
report_all = ~0
|
||||
|
||||
@@ -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 "getargs.h"
|
||||
#include "glyphs.h"
|
||||
#include "gram.h"
|
||||
#include "print-xml.h"
|
||||
#include "reader.h"
|
||||
@@ -56,8 +57,7 @@ item_print (item_number *item, rule const *previous_rule, FILE *out)
|
||||
|
||||
for (item_number *sp = r->rhs; sp < item; sp++)
|
||||
fprintf (out, " %s", symbols[*sp]->tag);
|
||||
putc (' ', out);
|
||||
print_dot (out);
|
||||
fprintf (out, " %s", dot);
|
||||
if (0 <= *r->rhs)
|
||||
for (item_number *sp = item; 0 <= *sp; ++sp)
|
||||
fprintf (out, " %s", symbols[*sp]->tag);
|
||||
|
||||
-21
@@ -103,8 +103,6 @@
|
||||
|
||||
# include "system.h"
|
||||
|
||||
# include <unicodeio.h>
|
||||
|
||||
# include "location.h"
|
||||
# include "symtab.h"
|
||||
|
||||
@@ -217,25 +215,6 @@ typedef struct
|
||||
extern rule *rules;
|
||||
extern rule_number nrules;
|
||||
|
||||
/* Fallback in case we can't print "•". */
|
||||
static inline long
|
||||
print_dot_fallback (unsigned int code _GL_UNUSED,
|
||||
const char *msg _GL_UNUSED,
|
||||
void *callback_arg)
|
||||
{
|
||||
FILE *out = (FILE *) callback_arg;
|
||||
putc ('.', out);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Print "•", the symbol used to represent a point in an item (aka, a
|
||||
dotted rule). */
|
||||
static inline void
|
||||
print_dot (FILE *out)
|
||||
{
|
||||
unicode_to_mb (0x2022, fwrite_success_callback, print_dot_fallback, out);
|
||||
}
|
||||
|
||||
/* Get the rule associated to this item. ITEM points inside RITEM. */
|
||||
static inline rule const *
|
||||
item_rule (item_number const *item)
|
||||
|
||||
+2
-2
@@ -184,9 +184,9 @@ output_red (state const *s, reductions const *reds, FILE *fout)
|
||||
bool firste = true;
|
||||
rule_number ruleno = reds->rules[j]->number;
|
||||
|
||||
if (reds->lookahead_tokens)
|
||||
if (reds->lookaheads)
|
||||
for (int i = 0; i < ntokens; i++)
|
||||
if (bitset_test (reds->lookahead_tokens[j], i))
|
||||
if (bitset_test (reds->lookaheads[j], i))
|
||||
{
|
||||
if (bitset_test (no_reduce_set, i))
|
||||
firstd = print_token (&dout, firstd, symbols[i]->tag);
|
||||
|
||||
+1
-1
@@ -1025,7 +1025,7 @@ ielr_split_states (bitsetv follow_kernel_items, bitsetv always_follows,
|
||||
{
|
||||
rule *this_rule = node->state->reductions->rules[r];
|
||||
bitset lookahead_set =
|
||||
node->state->reductions->lookahead_tokens[r];
|
||||
node->state->reductions->lookaheads[r];
|
||||
if (item_number_is_rule_number (*this_rule->rhs))
|
||||
ielr_compute_goto_follow_set (follow_kernel_items,
|
||||
always_follows, node,
|
||||
|
||||
+24
-27
@@ -256,9 +256,9 @@ lookback_find_state (int lookback_index)
|
||||
state *res = NULL;
|
||||
for (int j = 0; j < nstates; ++j)
|
||||
if (states[j]->reductions
|
||||
&& states[j]->reductions->lookahead_tokens)
|
||||
&& states[j]->reductions->lookaheads)
|
||||
{
|
||||
if (states[j]->reductions->lookahead_tokens - LA > lookback_index)
|
||||
if (states[j]->reductions->lookaheads - LA > lookback_index)
|
||||
/* Went too far. */
|
||||
break;
|
||||
else
|
||||
@@ -280,7 +280,7 @@ lookback_print (FILE *out)
|
||||
{
|
||||
fprintf (out, " %3d = ", i);
|
||||
const state *s = lookback_find_state (i);
|
||||
int rnum = i - (s->reductions->lookahead_tokens - LA);
|
||||
int rnum = i - (s->reductions->lookaheads - LA);
|
||||
const rule *r = s->reductions->rules[rnum];
|
||||
fprintf (out, "(%3d, ", s->number);
|
||||
rule_print (r, NULL, out);
|
||||
@@ -305,7 +305,7 @@ static void
|
||||
add_lookback_edge (state *s, rule const *r, goto_number gotono)
|
||||
{
|
||||
int ri = state_reduction_find (s, r);
|
||||
int idx = (s->reductions->lookahead_tokens - LA) + ri;
|
||||
int idx = (s->reductions->lookaheads - LA) + ri;
|
||||
lookback[idx] = goto_list_new (gotono, lookback[idx]);
|
||||
}
|
||||
|
||||
@@ -421,7 +421,7 @@ compute_follows (void)
|
||||
|
||||
|
||||
static void
|
||||
compute_lookahead_tokens (void)
|
||||
compute_lookaheads (void)
|
||||
{
|
||||
if (trace_flag & trace_automaton)
|
||||
lookback_print (stderr);
|
||||
@@ -437,13 +437,12 @@ compute_lookahead_tokens (void)
|
||||
}
|
||||
|
||||
|
||||
/*----------------------------------------------------.
|
||||
| Count the number of lookahead tokens required for S |
|
||||
| (N_LOOKAHEAD_TOKENS member). |
|
||||
`----------------------------------------------------*/
|
||||
/*------------------------------------------------------.
|
||||
| Count the number of lookahead tokens required for S. |
|
||||
`------------------------------------------------------*/
|
||||
|
||||
static int
|
||||
state_lookahead_tokens_count (state *s, bool default_reduction_only_for_accept)
|
||||
state_lookaheads_count (state *s, bool default_reduction_only_for_accept)
|
||||
{
|
||||
const reductions *reds = s->reductions;
|
||||
const transitions *trans = s->transitions;
|
||||
@@ -473,9 +472,9 @@ state_lookahead_tokens_count (state *s, bool default_reduction_only_for_accept)
|
||||
}
|
||||
|
||||
|
||||
/*----------------------------------------------------.
|
||||
| Compute LA, NLA, and the lookahead_tokens members. |
|
||||
`----------------------------------------------------*/
|
||||
/*----------------------------------------------.
|
||||
| Compute LA, NLA, and the lookaheads members. |
|
||||
`----------------------------------------------*/
|
||||
|
||||
void
|
||||
initialize_LA (void)
|
||||
@@ -491,25 +490,23 @@ initialize_LA (void)
|
||||
/* Compute the total number of reductions requiring a lookahead. */
|
||||
nLA = 0;
|
||||
for (state_number i = 0; i < nstates; ++i)
|
||||
nLA +=
|
||||
state_lookahead_tokens_count (states[i],
|
||||
default_reduction_only_for_accept);
|
||||
nLA += state_lookaheads_count (states[i],
|
||||
default_reduction_only_for_accept);
|
||||
/* Avoid having to special case 0. */
|
||||
if (!nLA)
|
||||
nLA = 1;
|
||||
|
||||
bitsetv pLA = LA = bitsetv_create (nLA, ntokens, BITSET_FIXED);
|
||||
|
||||
/* Initialize the members LOOKAHEAD_TOKENS for each state whose reductions
|
||||
/* Initialize the members LOOKAHEADS for each state whose reductions
|
||||
require lookahead tokens. */
|
||||
for (state_number i = 0; i < nstates; ++i)
|
||||
{
|
||||
int count =
|
||||
state_lookahead_tokens_count (states[i],
|
||||
default_reduction_only_for_accept);
|
||||
int count = state_lookaheads_count (states[i],
|
||||
default_reduction_only_for_accept);
|
||||
if (count)
|
||||
{
|
||||
states[i]->reductions->lookahead_tokens = pLA;
|
||||
states[i]->reductions->lookaheads = pLA;
|
||||
pLA += count;
|
||||
}
|
||||
}
|
||||
@@ -521,7 +518,7 @@ initialize_LA (void)
|
||||
`---------------------------------------------*/
|
||||
|
||||
static void
|
||||
lookahead_tokens_print (FILE *out)
|
||||
lookaheads_print (FILE *out)
|
||||
{
|
||||
fputs ("Lookaheads:\n", out);
|
||||
for (state_number i = 0; i < nstates; ++i)
|
||||
@@ -533,11 +530,11 @@ lookahead_tokens_print (FILE *out)
|
||||
for (int j = 0; j < reds->num; ++j)
|
||||
{
|
||||
fprintf (out, " rule %d:", reds->rules[j]->number);
|
||||
if (reds->lookahead_tokens)
|
||||
if (reds->lookaheads)
|
||||
{
|
||||
bitset_iterator iter;
|
||||
int k;
|
||||
BITSET_FOR_EACH (iter, reds->lookahead_tokens[j], k, 0)
|
||||
BITSET_FOR_EACH (iter, reds->lookaheads[j], k, 0)
|
||||
fprintf (out, " %s", symbols[k]->tag);
|
||||
}
|
||||
fputc ('\n', out);
|
||||
@@ -564,10 +561,10 @@ lalr (void)
|
||||
lookback = xcalloc (nLA, sizeof *lookback);
|
||||
build_relations ();
|
||||
compute_follows ();
|
||||
compute_lookahead_tokens ();
|
||||
compute_lookaheads ();
|
||||
|
||||
if (trace_flag & trace_sets)
|
||||
lookahead_tokens_print (stderr);
|
||||
lookaheads_print (stderr);
|
||||
if (trace_flag & trace_automaton)
|
||||
{
|
||||
begin_use_class ("trace0", stderr);
|
||||
@@ -614,6 +611,6 @@ void
|
||||
lalr_free (void)
|
||||
{
|
||||
for (state_number s = 0; s < nstates; ++s)
|
||||
states[s]->reductions->lookahead_tokens = NULL;
|
||||
states[s]->reductions->lookaheads = NULL;
|
||||
bitsetv_free (LA);
|
||||
}
|
||||
|
||||
@@ -53,6 +53,8 @@ src_bison_SOURCES = \
|
||||
src/flex-scanner.h \
|
||||
src/getargs.c \
|
||||
src/getargs.h \
|
||||
src/glyphs.c \
|
||||
src/glyphs.h \
|
||||
src/gram.c \
|
||||
src/gram.h \
|
||||
src/graphviz.c \
|
||||
|
||||
+13
-11
@@ -82,8 +82,10 @@ lssi_comparator (lssi *s1, lssi *s2)
|
||||
return false;
|
||||
}
|
||||
|
||||
typedef gl_list_t lssi_list;
|
||||
|
||||
static inline bool
|
||||
append_lssi (lssi *sn, Hash_table *visited, gl_list_t queue)
|
||||
append_lssi (lssi *sn, Hash_table *visited, lssi_list queue)
|
||||
{
|
||||
if (hash_lookup (visited, sn))
|
||||
{
|
||||
@@ -100,7 +102,7 @@ append_lssi (lssi *sn, Hash_table *visited, gl_list_t queue)
|
||||
static void
|
||||
lssi_print (lssi *l)
|
||||
{
|
||||
print_state_item (state_items + l->si, stdout);
|
||||
print_state_item (&state_items[l->si], stdout);
|
||||
if (l->lookahead)
|
||||
{
|
||||
printf ("FOLLOWL = { ");
|
||||
@@ -121,7 +123,7 @@ static bitset
|
||||
eligible_state_items (state_item *target)
|
||||
{
|
||||
bitset result = bitset_create (nstate_items, BITSET_FIXED);
|
||||
gl_list_t queue =
|
||||
state_item_list queue =
|
||||
gl_list_create (GL_LINKED_LIST, NULL, NULL, NULL, true, 1,
|
||||
(const void **) &target);
|
||||
while (gl_list_size (queue) > 0)
|
||||
@@ -147,7 +149,7 @@ eligible_state_items (state_item *target)
|
||||
* this conflict. If optimized is true, only consider parser states
|
||||
* that can reach the conflict state.
|
||||
*/
|
||||
gl_list_t
|
||||
state_item_list
|
||||
shortest_path_from_start (state_item_number target, symbol_number next_sym)
|
||||
{
|
||||
bitset eligible = eligible_state_items (&state_items[target]);
|
||||
@@ -159,7 +161,7 @@ shortest_path_from_start (state_item_number target, symbol_number next_sym)
|
||||
bitset il = bitset_create (nsyms, BITSET_FIXED);
|
||||
bitset_set (il, 0);
|
||||
lssi *init = new_lssi (0, NULL, il, true);
|
||||
gl_list_t queue = gl_list_create_empty (GL_LINKED_LIST, NULL, NULL,
|
||||
lssi_list queue = gl_list_create_empty (GL_LINKED_LIST, NULL, NULL,
|
||||
NULL, true);
|
||||
append_lssi (init, visited, queue);
|
||||
// breadth-first search
|
||||
@@ -175,7 +177,7 @@ shortest_path_from_start (state_item_number target, symbol_number next_sym)
|
||||
finished = true;
|
||||
break;
|
||||
}
|
||||
state_item *si = state_items + last;
|
||||
state_item *si = &state_items[last];
|
||||
// Transitions don't change follow_L
|
||||
if (si->trans >= 0)
|
||||
{
|
||||
@@ -240,10 +242,10 @@ shortest_path_from_start (state_item_number target, symbol_number next_sym)
|
||||
fputs ("Cannot find shortest path to conflict state.", stderr);
|
||||
abort ();
|
||||
}
|
||||
gl_list_t res =
|
||||
state_item_list res =
|
||||
gl_list_create_empty (GL_LINKED_LIST, NULL, NULL, NULL, true);
|
||||
for (lssi *sn = n; sn != NULL; sn = sn->parent)
|
||||
gl_list_add_first (res, state_items + sn->si);
|
||||
gl_list_add_first (res, &state_items[sn->si]);
|
||||
|
||||
hash_free (visited);
|
||||
gl_list_free (queue);
|
||||
@@ -306,10 +308,10 @@ intersect (bitset ts, bitset syms)
|
||||
* Compute a list of state_items that have a production to n with respect
|
||||
* to its lookahead
|
||||
*/
|
||||
gl_list_t
|
||||
state_item_list
|
||||
lssi_reverse_production (const state_item *si, bitset lookahead)
|
||||
{
|
||||
gl_list_t result =
|
||||
state_item_list result =
|
||||
gl_list_create_empty (GL_LINKED_LIST, NULL, NULL, NULL, true);
|
||||
if (SI_TRANSITION (si))
|
||||
return result;
|
||||
@@ -320,7 +322,7 @@ lssi_reverse_production (const state_item *si, bitset lookahead)
|
||||
state_item_number sin;
|
||||
BITSET_FOR_EACH (biter, si->revs, sin, 0)
|
||||
{
|
||||
state_item *prevsi = state_items + sin;
|
||||
state_item *prevsi = &state_items[sin];
|
||||
if (!production_allowed (prevsi, si))
|
||||
continue;
|
||||
bitset prev_lookahead = prevsi->lookahead;
|
||||
|
||||
+3
-3
@@ -32,8 +32,8 @@
|
||||
* find shortest lookahead-sensitive path of state-items to target such that
|
||||
* next_sym is in the follow_L set of target in that position.
|
||||
*/
|
||||
gl_list_t shortest_path_from_start (state_item_number target,
|
||||
symbol_number next_sym);
|
||||
state_item_list shortest_path_from_start (state_item_number target,
|
||||
symbol_number next_sym);
|
||||
|
||||
/**
|
||||
* Determine if the given terminal is in the given symbol set or can begin
|
||||
@@ -52,6 +52,6 @@ bool intersect (bitset ts, bitset syms);
|
||||
* to this state-item such that the resulting possible lookahead symbols are
|
||||
* as given.
|
||||
*/
|
||||
gl_list_t lssi_reverse_production (const state_item *si, bitset lookahead);
|
||||
state_item_list lssi_reverse_production (const state_item *si, bitset lookahead);
|
||||
|
||||
#endif /* LSSI_H */
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
#include "files.h"
|
||||
#include "fixits.h"
|
||||
#include "getargs.h"
|
||||
#include "glyphs.h"
|
||||
#include "gram.h"
|
||||
#include "ielr.h"
|
||||
#include "lalr.h"
|
||||
@@ -85,6 +86,7 @@ main (int argc, char *argv[])
|
||||
|
||||
atexit (close_stdout);
|
||||
|
||||
glyphs_init ();
|
||||
uniqstrs_new ();
|
||||
muscle_init ();
|
||||
complain_init ();
|
||||
|
||||
+22
-20
@@ -1,4 +1,4 @@
|
||||
/* A Bison parser, made by GNU Bison 3.6.4.130-76c4d. */
|
||||
/* A Bison parser, made by GNU Bison 3.6.90. */
|
||||
|
||||
/* Bison implementation for Yacc-like parsers in C
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
#define YYBISON 1
|
||||
|
||||
/* Bison version. */
|
||||
#define YYBISON_VERSION "3.6.4.130-76c4d"
|
||||
#define YYBISON_VERSION "3.6.90"
|
||||
|
||||
/* Skeleton name. */
|
||||
#define YYSKELETON_NAME "yacc.c"
|
||||
@@ -234,6 +234,10 @@ typedef enum yysymbol_kind_t yysymbol_kind_t;
|
||||
#include "scan-code.h"
|
||||
#include "scan-gram.h"
|
||||
|
||||
/* Pretend to be at least that version, to check features published
|
||||
in that version while developping it. */
|
||||
static const char* api_version = "3.7";
|
||||
|
||||
static int current_prec = 0;
|
||||
static location current_lhs_loc;
|
||||
static named_ref *current_lhs_named_ref;
|
||||
@@ -623,6 +627,7 @@ union yyalloc
|
||||
/* YYNSTATES -- Number of states. */
|
||||
#define YYNSTATES 167
|
||||
|
||||
/* YYMAXUTOK -- Last valid token kind. */
|
||||
#define YYMAXUTOK 315
|
||||
|
||||
|
||||
@@ -634,19 +639,19 @@ union yyalloc
|
||||
/* YYRLINE[YYN] -- Source line where rule number YYN was defined. */
|
||||
static const yytype_int16 yyrline[] =
|
||||
{
|
||||
0, 308, 308, 317, 318, 322, 323, 329, 333, 338,
|
||||
339, 340, 341, 342, 343, 344, 349, 354, 355, 356,
|
||||
357, 358, 359, 359, 360, 361, 362, 363, 364, 365,
|
||||
366, 367, 371, 372, 381, 382, 386, 397, 401, 405,
|
||||
413, 423, 424, 434, 435, 441, 454, 454, 459, 459,
|
||||
464, 468, 478, 479, 480, 481, 485, 486, 491, 492,
|
||||
496, 497, 501, 502, 503, 516, 525, 529, 533, 541,
|
||||
542, 546, 559, 560, 565, 566, 567, 585, 589, 593,
|
||||
601, 603, 608, 615, 625, 629, 633, 641, 646, 658,
|
||||
659, 665, 666, 667, 674, 674, 682, 683, 684, 689,
|
||||
692, 694, 696, 698, 700, 702, 704, 706, 708, 713,
|
||||
714, 723, 747, 748, 749, 750, 762, 764, 788, 793,
|
||||
794, 799, 807, 808
|
||||
0, 312, 312, 321, 322, 326, 327, 333, 337, 342,
|
||||
343, 344, 345, 346, 347, 348, 353, 358, 359, 360,
|
||||
361, 362, 363, 363, 364, 365, 366, 367, 368, 369,
|
||||
370, 371, 375, 376, 385, 386, 390, 401, 405, 409,
|
||||
417, 427, 428, 438, 439, 445, 458, 458, 463, 463,
|
||||
468, 472, 482, 483, 484, 485, 489, 490, 495, 496,
|
||||
500, 501, 505, 506, 507, 520, 529, 533, 537, 545,
|
||||
546, 550, 563, 564, 569, 570, 571, 589, 593, 597,
|
||||
605, 607, 612, 619, 629, 633, 637, 645, 650, 662,
|
||||
663, 669, 670, 671, 678, 678, 686, 687, 688, 693,
|
||||
696, 698, 700, 702, 704, 706, 708, 710, 712, 717,
|
||||
718, 727, 751, 752, 753, 754, 766, 768, 792, 797,
|
||||
798, 803, 811, 812
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -1748,7 +1753,7 @@ yydestruct (const char *yymsg,
|
||||
int
|
||||
yyparse (void)
|
||||
{
|
||||
/* The lookahead symbol. */
|
||||
/* Lookahead token kind. */
|
||||
int yychar;
|
||||
|
||||
|
||||
@@ -1803,7 +1808,7 @@ YYLTYPE yylloc = yyloc_default;
|
||||
int yyn;
|
||||
/* The return value of yyparse. */
|
||||
int yyresult;
|
||||
/* Lookahead token as an internal (translated) token number. */
|
||||
/* Lookahead symbol kind. */
|
||||
yysymbol_kind_t yytoken = YYSYMBOL_YYEMPTY;
|
||||
/* The variables used to return semantic value and location from the
|
||||
action routines. */
|
||||
@@ -3070,9 +3075,6 @@ handle_require (location const *loc, char const *version_quoted)
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Pretend to be at least that version, to check features published
|
||||
in that version while developping it. */
|
||||
const char* api_version = "3.6";
|
||||
const char* package_version =
|
||||
0 < strverscmp (api_version, PACKAGE_VERSION)
|
||||
? api_version : PACKAGE_VERSION;
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
/* A Bison parser, made by GNU Bison 3.6.4.130-76c4d. */
|
||||
/* A Bison parser, made by GNU Bison 3.6.90. */
|
||||
|
||||
/* Bison interface for Yacc-like parsers in C
|
||||
|
||||
|
||||
+6
-5
@@ -58,6 +58,10 @@
|
||||
#include "scan-code.h"
|
||||
#include "scan-gram.h"
|
||||
|
||||
/* Pretend to be at least that version, to check features published
|
||||
in that version while developping it. */
|
||||
static const char* api_version = "3.7";
|
||||
|
||||
static int current_prec = 0;
|
||||
static location current_lhs_loc;
|
||||
static named_ref *current_lhs_named_ref;
|
||||
@@ -691,8 +695,8 @@ rhs:
|
||||
current_lhs_named_ref); }
|
||||
| rhs symbol named_ref.opt
|
||||
{ grammar_current_rule_symbol_append ($2, @2, $3); }
|
||||
| rhs tag.opt "{...}"[act] named_ref.opt[name]
|
||||
{ grammar_current_rule_action_append ($act, @act, $name, $[tag.opt]); }
|
||||
| rhs tag.opt "{...}"[action] named_ref.opt[name]
|
||||
{ grammar_current_rule_action_append ($action, @action, $name, $[tag.opt]); }
|
||||
| rhs "%?{...}"
|
||||
{ grammar_current_rule_predicate_append ($2, @2); }
|
||||
| rhs "%empty"
|
||||
@@ -1082,9 +1086,6 @@ handle_require (location const *loc, char const *version_quoted)
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Pretend to be at least that version, to check features published
|
||||
in that version while developping it. */
|
||||
const char* api_version = "3.6";
|
||||
const char* package_version =
|
||||
0 < strverscmp (api_version, PACKAGE_VERSION)
|
||||
? api_version : PACKAGE_VERSION;
|
||||
|
||||
+32
-34
@@ -34,7 +34,7 @@ typedef struct parse_state
|
||||
struct si_chunk
|
||||
{
|
||||
// elements newly added in this chunk
|
||||
gl_list_t contents;
|
||||
state_item_list contents;
|
||||
// properties of the linked list this chunk represents
|
||||
const state_item *head_elt;
|
||||
const state_item *tail_elt;
|
||||
@@ -135,7 +135,7 @@ static parse_state *
|
||||
copy_parse_state (bool prepend, parse_state *parent)
|
||||
{
|
||||
parse_state *res = xmalloc (sizeof *res);
|
||||
memcpy (res, parent, sizeof *res);
|
||||
*res = *parent;
|
||||
res->state_items.contents
|
||||
= gl_list_create_empty (GL_LINKED_LIST, NULL, NULL, NULL, true);
|
||||
res->derivs.contents = derivation_list_new ();
|
||||
@@ -252,7 +252,7 @@ parse_state_completed_steps (const parse_state *ps, int *shifts, int *production
|
||||
while (root_ps->parent)
|
||||
root_ps = root_ps->parent;
|
||||
|
||||
gl_list_t sis = root_ps->state_items.contents;
|
||||
state_item_list sis = root_ps->state_items.contents;
|
||||
int count = 0;
|
||||
|
||||
state_item *last = NULL;
|
||||
@@ -337,19 +337,17 @@ parser_pop (parse_state *ps, int deriv_index,
|
||||
for (int i = 0; i < 4; ++i)
|
||||
chunks[i] = gl_list_create_empty (GL_LINKED_LIST, NULL, NULL, NULL, true);
|
||||
for (parse_state *pn = ps; pn != NULL; pn = pn->parent)
|
||||
{
|
||||
if (pn->prepend)
|
||||
{
|
||||
gl_list_add_last (chunks[0], pn->state_items.contents);
|
||||
gl_list_add_last (chunks[2], pn->derivs.contents);
|
||||
}
|
||||
else
|
||||
{
|
||||
gl_list_add_first (chunks[1], pn->state_items.contents);
|
||||
gl_list_add_first (chunks[3], pn->derivs.contents);
|
||||
}
|
||||
}
|
||||
gl_list_t popped_derivs = derivation_list_new ();
|
||||
if (pn->prepend)
|
||||
{
|
||||
gl_list_add_last (chunks[0], pn->state_items.contents);
|
||||
gl_list_add_last (chunks[2], pn->derivs.contents);
|
||||
}
|
||||
else
|
||||
{
|
||||
gl_list_add_first (chunks[1], pn->state_items.contents);
|
||||
gl_list_add_first (chunks[3], pn->derivs.contents);
|
||||
}
|
||||
derivation_list popped_derivs = derivation_list_new ();
|
||||
gl_list_t ret_chunks[4] = { ret->state_items.contents, NULL,
|
||||
ret->derivs.contents, popped_derivs
|
||||
};
|
||||
@@ -390,7 +388,7 @@ parser_pop (parse_state *ps, int deriv_index,
|
||||
}
|
||||
|
||||
void
|
||||
parse_state_lists (parse_state *ps, gl_list_t *sitems,
|
||||
parse_state_lists (parse_state *ps, state_item_list *sitems,
|
||||
derivation_list *derivs)
|
||||
{
|
||||
parse_state *temp = empty_parse_state ();
|
||||
@@ -418,12 +416,12 @@ nullable_closure (parse_state *ps, state_item *si, parse_state_list state_list)
|
||||
for (state_item_number sin = si->trans; sin != -1;
|
||||
prev_sin = sin, sin = state_items[sin].trans)
|
||||
{
|
||||
state_item *psi = state_items + prev_sin;
|
||||
state_item *psi = &state_items[prev_sin];
|
||||
symbol_number sp = item_number_as_symbol_number (*psi->item);
|
||||
if (ISTOKEN (sp) || !nullable[sp - ntokens])
|
||||
break;
|
||||
|
||||
state_item *nsi = state_items + sin;
|
||||
state_item *nsi = &state_items[sin];
|
||||
current_ps = copy_parse_state (false, current_ps);
|
||||
ps_si_append (current_ps, nsi);
|
||||
ps_derivs_append (current_ps, derivation_new (sp, derivation_list_new ()));
|
||||
@@ -431,14 +429,14 @@ nullable_closure (parse_state *ps, state_item *si, parse_state_list state_list)
|
||||
}
|
||||
}
|
||||
|
||||
gl_list_t
|
||||
parse_state_list
|
||||
simulate_transition (parse_state *ps)
|
||||
{
|
||||
const state_item *si = ps->state_items.tail_elt;
|
||||
symbol_number sym = item_number_as_symbol_number (*si->item);
|
||||
// Transition on the same next symbol, taking nullable
|
||||
// symbols into account.
|
||||
gl_list_t result = parse_state_list_new ();
|
||||
parse_state_list result = parse_state_list_new ();
|
||||
state_item_number si_next = si->trans;
|
||||
// check for disabled transition, shouldn't happen
|
||||
// as any state_items that lead to these should be
|
||||
@@ -446,11 +444,11 @@ simulate_transition (parse_state *ps)
|
||||
if (si_next < 0)
|
||||
return result;
|
||||
parse_state *next_ps = copy_parse_state (false, ps);
|
||||
ps_si_append (next_ps, state_items + si_next);
|
||||
ps_si_append (next_ps, &state_items[si_next]);
|
||||
ps_derivs_append (next_ps, derivation_new_leaf (sym));
|
||||
parse_state_list_append (result, next_ps);
|
||||
|
||||
nullable_closure (next_ps, state_items + si_next, result);
|
||||
nullable_closure (next_ps, &state_items[si_next], result);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -473,10 +471,10 @@ compatible (symbol_number sym1, symbol_number sym2)
|
||||
return false;
|
||||
}
|
||||
|
||||
gl_list_t
|
||||
parse_state_list
|
||||
simulate_production (parse_state *ps, symbol_number compat_sym)
|
||||
{
|
||||
gl_list_t result = parse_state_list_new ();
|
||||
parse_state_list result = parse_state_list_new ();
|
||||
const state_item *si = parse_state_tail (ps);
|
||||
if (si->prods)
|
||||
{
|
||||
@@ -486,7 +484,7 @@ simulate_production (parse_state *ps, symbol_number compat_sym)
|
||||
{
|
||||
// Take production step only if lhs is not nullable and
|
||||
// if first rhs symbol is compatible with compat_sym
|
||||
state_item *next = state_items + sin;
|
||||
state_item *next = &state_items[sin];
|
||||
item_number *itm1 = next->item;
|
||||
if (!compatible (*itm1, compat_sym) || !production_allowed (si, next))
|
||||
continue;
|
||||
@@ -504,10 +502,10 @@ simulate_production (parse_state *ps, symbol_number compat_sym)
|
||||
// simulates a reduction on the given parse state, conflict_item is the
|
||||
// item associated with ps's conflict. symbol_set is a lookahead set this
|
||||
// reduction must be compatible with
|
||||
gl_list_t
|
||||
parse_state_list
|
||||
simulate_reduction (parse_state *ps, int rule_len, bitset symbol_set)
|
||||
{
|
||||
gl_list_t result = parse_state_list_new ();
|
||||
parse_state_list result = parse_state_list_new ();
|
||||
|
||||
int s_size = ps->state_items.total_size;
|
||||
int d_size = ps->derivs.total_size;
|
||||
@@ -529,7 +527,7 @@ simulate_reduction (parse_state *ps, int rule_len, bitset symbol_set)
|
||||
if (s_size != rule_len + 1)
|
||||
{
|
||||
state_item *tail = (state_item *) new_root->state_items.tail_elt;
|
||||
ps_si_append (new_root, state_items + tail->trans);
|
||||
ps_si_append (new_root, &state_items[tail->trans]);
|
||||
parse_state_list_append (result, new_root);
|
||||
}
|
||||
else
|
||||
@@ -537,7 +535,7 @@ simulate_reduction (parse_state *ps, int rule_len, bitset symbol_set)
|
||||
// The head state_item is a production item, so we need to prepend
|
||||
// with possible source state-items.
|
||||
const state_item *head = ps->state_items.head_elt;
|
||||
gl_list_t prev = lssi_reverse_production (head, symbol_set);
|
||||
state_item_list prev = lssi_reverse_production (head, symbol_set);
|
||||
// TODO: better understand what causes this case.
|
||||
if (gl_list_size (prev) == 0)
|
||||
{
|
||||
@@ -560,7 +558,7 @@ simulate_reduction (parse_state *ps, int rule_len, bitset symbol_set)
|
||||
copy = copy_parse_state (false, copy);
|
||||
struct si_chunk *sis = ©->state_items;
|
||||
const state_item *tail = sis->tail_elt;
|
||||
ps_si_append (copy, state_items + tail->trans);
|
||||
ps_si_append (copy, &state_items[tail->trans]);
|
||||
parse_state_list_append (result, copy);
|
||||
nullable_closure (copy, (state_item *) sis->tail_elt, result);
|
||||
}
|
||||
@@ -570,10 +568,10 @@ simulate_reduction (parse_state *ps, int rule_len, bitset symbol_set)
|
||||
return result;
|
||||
}
|
||||
|
||||
gl_list_t
|
||||
parse_state_list
|
||||
parser_prepend (parse_state *ps)
|
||||
{
|
||||
gl_list_t res = parse_state_list_new ();
|
||||
parse_state_list res = parse_state_list_new ();
|
||||
const state_item *head = ps->state_items.head_elt;
|
||||
symbol_number prepend_sym =
|
||||
item_number_as_symbol_number (*(head->item - 1));
|
||||
@@ -582,7 +580,7 @@ parser_prepend (parse_state *ps)
|
||||
BITSET_FOR_EACH (biter, head->revs, sin, 0)
|
||||
{
|
||||
parse_state *copy = copy_parse_state (true, ps);
|
||||
ps_si_prepend (copy, state_items + sin);
|
||||
ps_si_prepend (copy, &state_items[sin]);
|
||||
if (SI_TRANSITION (head))
|
||||
ps_derivs_prepend (copy, derivation_new_leaf (prepend_sym));
|
||||
parse_state_list_append (res, copy);
|
||||
|
||||
@@ -113,7 +113,7 @@ int parse_state_length (const parse_state *ps);
|
||||
int parse_state_depth (const parse_state *ps);
|
||||
|
||||
/* returns the linked lists that the parse state is supposed to represent */
|
||||
void parse_state_lists (parse_state *ps, gl_list_t *state_items,
|
||||
void parse_state_lists (parse_state *ps, state_item_list *state_items,
|
||||
derivation_list *derivs);
|
||||
|
||||
/* various functions that return a list of states based off of
|
||||
|
||||
+3
-3
@@ -96,7 +96,7 @@ print_core (struct obstack *oout, state *s)
|
||||
obstack_sgrow (oout, " %empty");
|
||||
|
||||
/* Experimental feature: display the lookahead tokens. */
|
||||
if (report_flag & report_lookahead_tokens
|
||||
if (report_flag & report_lookaheads
|
||||
&& item_number_is_rule_number (*sp1))
|
||||
{
|
||||
/* Find the reduction we are handling. */
|
||||
@@ -104,13 +104,13 @@ print_core (struct obstack *oout, state *s)
|
||||
int redno = state_reduction_find (s, r);
|
||||
|
||||
/* Print them if there are. */
|
||||
if (reds->lookahead_tokens && redno != -1)
|
||||
if (reds->lookaheads && redno != -1)
|
||||
{
|
||||
bitset_iterator biter;
|
||||
int k;
|
||||
char const *sep = "";
|
||||
obstack_sgrow (oout, " [");
|
||||
BITSET_FOR_EACH (biter, reds->lookahead_tokens[redno], k, 0)
|
||||
BITSET_FOR_EACH (biter, reds->lookaheads[redno], k, 0)
|
||||
{
|
||||
obstack_sgrow (oout, sep);
|
||||
obstack_backslash (oout, symbols[k]->tag);
|
||||
|
||||
+29
-22
@@ -86,12 +86,12 @@ print_core (FILE *out, int level, state *s)
|
||||
reductions *reds = s->reductions;
|
||||
int red = state_reduction_find (s, r);
|
||||
/* Print item with lookaheads if there are. */
|
||||
if (reds->lookahead_tokens && red != -1)
|
||||
if (reds->lookaheads && red != -1)
|
||||
{
|
||||
xml_printf (out, level + 1,
|
||||
"<item rule-number=\"%d\" dot=\"%d\">",
|
||||
r->number, sp1 - sp);
|
||||
state_rule_lookahead_tokens_print_xml (s, r,
|
||||
state_rule_lookaheads_print_xml (s, r,
|
||||
out, level + 2);
|
||||
xml_puts (out, level + 1, "</item>");
|
||||
printed = true;
|
||||
@@ -202,26 +202,26 @@ print_errs (FILE *out, int level, state *s)
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------.
|
||||
| Report a reduction of RULE on LOOKAHEAD_TOKEN (which can be 'default'). |
|
||||
| If not ENABLED, the rule is masked by a shift or a reduce (S/R and |
|
||||
| R/R conflicts). |
|
||||
`-------------------------------------------------------------------------*/
|
||||
/*-------------------------------------------------------------------.
|
||||
| Report a reduction of RULE on LOOKAHEAD (which can be 'default'). |
|
||||
| If not ENABLED, the rule is masked by a shift or a reduce (S/R and |
|
||||
| R/R conflicts). |
|
||||
`-------------------------------------------------------------------*/
|
||||
|
||||
static void
|
||||
print_reduction (FILE *out, int level, char const *lookahead_token,
|
||||
print_reduction (FILE *out, int level, char const *lookahead,
|
||||
rule *r, bool enabled)
|
||||
{
|
||||
if (r->number)
|
||||
xml_printf (out, level,
|
||||
"<reduction symbol=\"%s\" rule=\"%d\" enabled=\"%s\"/>",
|
||||
xml_escape (lookahead_token),
|
||||
xml_escape (lookahead),
|
||||
r->number,
|
||||
enabled ? "true" : "false");
|
||||
else
|
||||
xml_printf (out, level,
|
||||
"<reduction symbol=\"%s\" rule=\"accept\" enabled=\"%s\"/>",
|
||||
xml_escape (lookahead_token),
|
||||
xml_escape (lookahead),
|
||||
enabled ? "true" : "false");
|
||||
}
|
||||
|
||||
@@ -258,13 +258,13 @@ print_reductions (FILE *out, int level, state *s)
|
||||
if (default_reduction)
|
||||
report = true;
|
||||
|
||||
if (reds->lookahead_tokens)
|
||||
if (reds->lookaheads)
|
||||
for (i = 0; i < ntokens; i++)
|
||||
{
|
||||
bool count = bitset_test (no_reduce_set, i);
|
||||
|
||||
for (j = 0; j < reds->num; ++j)
|
||||
if (bitset_test (reds->lookahead_tokens[j], i))
|
||||
if (bitset_test (reds->lookaheads[j], i))
|
||||
{
|
||||
if (! count)
|
||||
{
|
||||
@@ -289,14 +289,14 @@ print_reductions (FILE *out, int level, state *s)
|
||||
xml_puts (out, level, "<reductions>");
|
||||
|
||||
/* Report lookahead tokens (or $default) and reductions. */
|
||||
if (reds->lookahead_tokens)
|
||||
if (reds->lookaheads)
|
||||
for (i = 0; i < ntokens; i++)
|
||||
{
|
||||
bool defaulted = false;
|
||||
bool count = bitset_test (no_reduce_set, i);
|
||||
|
||||
for (j = 0; j < reds->num; ++j)
|
||||
if (bitset_test (reds->lookahead_tokens[j], i))
|
||||
if (bitset_test (reds->lookaheads[j], i))
|
||||
{
|
||||
if (! count)
|
||||
{
|
||||
@@ -382,14 +382,17 @@ print_grammar (FILE *out, int level)
|
||||
for (int i = 0; i < max_code + 1; i++)
|
||||
if (token_translations[i] != undeftoken->content->number)
|
||||
{
|
||||
char const *tag = symbols[token_translations[i]]->tag;
|
||||
int precedence = symbols[token_translations[i]]->content->prec;
|
||||
assoc associativity = symbols[token_translations[i]]->content->assoc;
|
||||
symbol const *sym = symbols[token_translations[i]];
|
||||
char const *tag = sym->tag;
|
||||
char const *type = sym->content->type_name;
|
||||
int precedence = sym->content->prec;
|
||||
assoc associativity = sym->content->assoc;
|
||||
xml_indent (out, level + 2);
|
||||
fprintf (out,
|
||||
"<terminal symbol-number=\"%d\" token-number=\"%d\""
|
||||
" name=\"%s\" usefulness=\"%s\"",
|
||||
token_translations[i], i, xml_escape (tag),
|
||||
" name=\"%s\" type=\"%s\" usefulness=\"%s\"",
|
||||
token_translations[i], i, xml_escape_n (0, tag),
|
||||
type ? xml_escape_n (1, type) : "",
|
||||
reduce_token_unused_in_grammar (token_translations[i])
|
||||
? "unused-in-grammar" : "useful");
|
||||
if (precedence)
|
||||
@@ -404,12 +407,16 @@ print_grammar (FILE *out, int level)
|
||||
xml_puts (out, level + 1, "<nonterminals>");
|
||||
for (symbol_number i = ntokens; i < nsyms + nuseless_nonterminals; i++)
|
||||
{
|
||||
char const *tag = symbols[i]->tag;
|
||||
symbol const *sym = symbols[i];
|
||||
char const *tag = sym->tag;
|
||||
char const *type = sym->content->type_name;
|
||||
xml_printf (out, level + 2,
|
||||
"<nonterminal symbol-number=\"%d\" name=\"%s\""
|
||||
" type=\"%s\""
|
||||
" usefulness=\"%s\"/>",
|
||||
i, xml_escape (tag),
|
||||
reduce_nonterminal_useless_in_grammar (symbols[i]->content)
|
||||
i, xml_escape_n (0, tag),
|
||||
type ? xml_escape_n (1, type) : "",
|
||||
reduce_nonterminal_useless_in_grammar (sym->content)
|
||||
? "useless-in-grammar" : "useful");
|
||||
}
|
||||
xml_puts (out, level + 1, "</nonterminals>");
|
||||
|
||||
+22
-21
@@ -90,9 +90,9 @@ print_core (FILE *out, const state *s)
|
||||
previous_rule = r;
|
||||
|
||||
/* Display the lookahead tokens? */
|
||||
if (report_flag & report_lookahead_tokens
|
||||
if (report_flag & report_lookaheads
|
||||
&& item_number_is_rule_number (*sp1))
|
||||
state_rule_lookahead_tokens_print (s, r, out);
|
||||
state_rule_lookaheads_print (s, r, out);
|
||||
fputc ('\n', out);
|
||||
}
|
||||
}
|
||||
@@ -180,19 +180,19 @@ print_errs (FILE *out, const state *s)
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------.
|
||||
| Report a reduction of RULE on LOOKAHEAD_TOKEN (which can be 'default'). |
|
||||
| If not ENABLED, the rule is masked by a shift or a reduce (S/R and |
|
||||
| R/R conflicts). |
|
||||
`-------------------------------------------------------------------------*/
|
||||
/*-------------------------------------------------------------------.
|
||||
| Report a reduction of RULE on LOOKAHEAD (which can be 'default'). |
|
||||
| If not ENABLED, the rule is masked by a shift or a reduce (S/R and |
|
||||
| R/R conflicts). |
|
||||
`-------------------------------------------------------------------*/
|
||||
|
||||
static void
|
||||
print_reduction (FILE *out, size_t width,
|
||||
const char *lookahead_token,
|
||||
const char *lookahead,
|
||||
rule *r, bool enabled)
|
||||
{
|
||||
fprintf (out, " %s", lookahead_token);
|
||||
for (int j = width - mbswidth (lookahead_token, 0); j > 0; --j)
|
||||
fprintf (out, " %s", lookahead);
|
||||
for (int j = width - mbswidth (lookahead, 0); j > 0; --j)
|
||||
fputc (' ', out);
|
||||
if (!enabled)
|
||||
fputc ('[', out);
|
||||
@@ -239,13 +239,13 @@ print_reductions (FILE *out, const state *s)
|
||||
if (default_reduction)
|
||||
width = mbswidth (_("$default"), 0);
|
||||
|
||||
if (reds->lookahead_tokens)
|
||||
if (reds->lookaheads)
|
||||
for (int i = 0; i < ntokens; i++)
|
||||
{
|
||||
bool count = bitset_test (no_reduce_set, i);
|
||||
|
||||
for (int j = 0; j < reds->num; ++j)
|
||||
if (bitset_test (reds->lookahead_tokens[j], i))
|
||||
if (bitset_test (reds->lookaheads[j], i))
|
||||
{
|
||||
if (! count)
|
||||
{
|
||||
@@ -268,7 +268,7 @@ print_reductions (FILE *out, const state *s)
|
||||
bool default_reduction_only = true;
|
||||
|
||||
/* Report lookahead tokens (or $default) and reductions. */
|
||||
if (reds->lookahead_tokens)
|
||||
if (reds->lookaheads)
|
||||
for (int i = 0; i < ntokens; i++)
|
||||
{
|
||||
bool defaulted = false;
|
||||
@@ -277,7 +277,7 @@ print_reductions (FILE *out, const state *s)
|
||||
default_reduction_only = false;
|
||||
|
||||
for (int j = 0; j < reds->num; ++j)
|
||||
if (bitset_test (reds->lookahead_tokens[j], i))
|
||||
if (bitset_test (reds->lookaheads[j], i))
|
||||
{
|
||||
if (! count)
|
||||
{
|
||||
@@ -377,11 +377,11 @@ print_terminal_symbols (FILE *out)
|
||||
for (int i = 0; i < max_code + 1; ++i)
|
||||
if (token_translations[i] != undeftoken->content->number)
|
||||
{
|
||||
const char *tag = symbols[token_translations[i]]->tag;
|
||||
const symbol *sym = symbols[token_translations[i]];
|
||||
const char *tag = sym->tag;
|
||||
fprintf (out, "%4s%s", "", tag);
|
||||
if (symbols[token_translations[i]]->content->type_name)
|
||||
fprintf (out, " <%s>",
|
||||
symbols[token_translations[i]]->content->type_name);
|
||||
if (sym->content->type_name)
|
||||
fprintf (out, " <%s>", sym->content->type_name);
|
||||
fprintf (out, " (%d)", i);
|
||||
|
||||
for (rule_number r = 0; r < nrules; r++)
|
||||
@@ -403,7 +403,8 @@ print_nonterminal_symbols (FILE *out)
|
||||
fprintf (out, "%s\n\n", _("Nonterminals, with rules where they appear"));
|
||||
for (symbol_number i = ntokens; i < nsyms; i++)
|
||||
{
|
||||
const char *tag = symbols[i]->tag;
|
||||
const symbol *sym = symbols[i];
|
||||
const char *tag = sym->tag;
|
||||
bool on_left = false;
|
||||
bool on_right = false;
|
||||
|
||||
@@ -418,9 +419,9 @@ print_nonterminal_symbols (FILE *out)
|
||||
|
||||
int column = 4 + mbswidth (tag, 0);
|
||||
fprintf (out, "%4s%s", "", tag);
|
||||
if (symbols[i]->content->type_name)
|
||||
if (sym->content->type_name)
|
||||
column += fprintf (out, " <%s>",
|
||||
symbols[i]->content->type_name);
|
||||
sym->content->type_name);
|
||||
fprintf (out, " (%d)\n", i);
|
||||
|
||||
if (on_left)
|
||||
|
||||
+4
-6
@@ -695,12 +695,10 @@ packgram (void)
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------.
|
||||
| Read in the grammar specification and record it in the format |
|
||||
| described in gram.h. All actions are copied into ACTION_OBSTACK, |
|
||||
| in each case forming the body of a C function (YYACTION) which |
|
||||
| contains a switch statement to decide which action to execute. |
|
||||
`------------------------------------------------------------------*/
|
||||
/*--------------------------------------------------------------.
|
||||
| Read in the grammar specification and record it in the format |
|
||||
| described in gram.h. |
|
||||
`--------------------------------------------------------------*/
|
||||
|
||||
void
|
||||
reader (const char *gram)
|
||||
|
||||
@@ -145,6 +145,7 @@ void code_props_symbol_action_init (code_props *self, char const *code,
|
||||
location code_loc);
|
||||
|
||||
/**
|
||||
* \param type type for midrule actions
|
||||
* \pre
|
||||
* - <tt>self != NULL</tt>.
|
||||
* - <tt>code != NULL</tt>.
|
||||
|
||||
+32
-34
@@ -144,13 +144,13 @@ init_state_items (void)
|
||||
for (int j = 0; j < s->nitems; ++j)
|
||||
{
|
||||
state_item_set (sidx, s, s->items[j]);
|
||||
state_item *si = state_items + sidx;
|
||||
state_item *si = &state_items[sidx];
|
||||
const rule *r = item_rule (si->item);
|
||||
if (rule_search_idx < red->num && red->rules[rule_search_idx] < r)
|
||||
++rule_search_idx;
|
||||
if (rule_search_idx < red->num && r == red->rules[rule_search_idx])
|
||||
{
|
||||
bitsetv lookahead = red->lookahead_tokens;
|
||||
bitsetv lookahead = red->lookaheads;
|
||||
if (lookahead)
|
||||
si->lookahead = lookahead[rule_search_idx];
|
||||
}
|
||||
@@ -163,7 +163,7 @@ init_state_items (void)
|
||||
state_item_set (sidx, s, off);
|
||||
if (item_number_is_rule_number (ritem[off]))
|
||||
{
|
||||
bitsetv lookahead = red->lookahead_tokens;
|
||||
bitsetv lookahead = red->lookaheads;
|
||||
if (lookahead)
|
||||
state_items[sidx].lookahead = lookahead[rule_search_idx];
|
||||
++rule_search_idx;
|
||||
@@ -211,7 +211,7 @@ init_trans (void)
|
||||
for (int j = 0; j < t->num; ++j)
|
||||
if (!TRANSITION_IS_DISABLED (t, j))
|
||||
hash_xinsert (transition_set, t->states[j]);
|
||||
for (int j = state_item_map[i]; j < state_item_map[i + 1]; ++j)
|
||||
for (state_item_number j = state_item_map[i]; j < state_item_map[i + 1]; ++j)
|
||||
{
|
||||
item_number *item = state_items[j].item;
|
||||
if (item_number_is_rule_number (*item))
|
||||
@@ -222,16 +222,14 @@ init_trans (void)
|
||||
// find the item in the destination state that corresponds
|
||||
// to the transition of item
|
||||
for (int k = 0; k < dst->nitems; ++k)
|
||||
{
|
||||
if (item + 1 == ritem + dst->items[k])
|
||||
{
|
||||
state_item_number dstSI =
|
||||
state_item_index_lookup (dst->number, k);
|
||||
if (item + 1 == ritem + dst->items[k])
|
||||
{
|
||||
state_item_number dstSI =
|
||||
state_item_index_lookup (dst->number, k);
|
||||
|
||||
state_items[j].trans = dstSI;
|
||||
bitset_set (state_items[dstSI].revs, j);
|
||||
break;
|
||||
}
|
||||
state_items[j].trans = dstSI;
|
||||
bitset_set (state_items[dstSI].revs, j);
|
||||
break;
|
||||
}
|
||||
}
|
||||
hash_free (transition_set);
|
||||
@@ -250,10 +248,10 @@ init_prods (void)
|
||||
|
||||
// Add the nitems of state to skip to the production portion
|
||||
// of that state's state_items
|
||||
for (int j = state_item_map[i] + s->nitems;
|
||||
for (state_item_number j = state_item_map[i] + s->nitems;
|
||||
j < state_item_map[i + 1]; ++j)
|
||||
{
|
||||
state_item *src = state_items + j;
|
||||
state_item *src = &state_items[j];
|
||||
item_number *item = src->item;
|
||||
symbol_number lhs = item_rule (item)->lhs->number;
|
||||
bitset itms = hash_pair_lookup (closure_map, lhs);
|
||||
@@ -266,9 +264,9 @@ init_prods (void)
|
||||
}
|
||||
// For each item with a dot followed by a nonterminal,
|
||||
// try to create a production edge.
|
||||
for (int j = state_item_map[i]; j < state_item_map[i + 1]; ++j)
|
||||
for (state_item_number j = state_item_map[i]; j < state_item_map[i + 1]; ++j)
|
||||
{
|
||||
state_item *src = state_items + j;
|
||||
state_item *src = &state_items[j];
|
||||
item_number item = *(src->item);
|
||||
// Skip reduce items and items with terminals after the dot
|
||||
if (item_number_is_rule_number (item) || ISTOKEN (item))
|
||||
@@ -301,12 +299,12 @@ gen_lookaheads (void)
|
||||
{
|
||||
for (state_item_number i = 0; i < nstate_items; ++i)
|
||||
{
|
||||
state_item *si = state_items + i;
|
||||
state_item *si = &state_items[i];
|
||||
if (item_number_is_symbol_number (*(si->item)) || !si->lookahead)
|
||||
continue;
|
||||
|
||||
bitset lookahead = si->lookahead;
|
||||
gl_list_t queue =
|
||||
state_item_list queue =
|
||||
gl_list_create (GL_LINKED_LIST, NULL, NULL, NULL, true, 1,
|
||||
(const void **) &si);
|
||||
|
||||
@@ -339,7 +337,7 @@ init_firsts (void)
|
||||
firsts = bitsetv_create (nnterms, nsyms, BITSET_FIXED);
|
||||
for (rule_number i = 0; i < nrules; ++i)
|
||||
{
|
||||
rule *r = rules + i;
|
||||
rule *r = &rules[i];
|
||||
item_number *n = r->rhs;
|
||||
// Iterate through nullable nonterminals to try to find a terminal.
|
||||
while (item_number_is_symbol_number (*n) && ISVAR (*n)
|
||||
@@ -357,7 +355,7 @@ init_firsts (void)
|
||||
change = false;
|
||||
for (rule_number i = 0; i < nrules; ++i)
|
||||
{
|
||||
rule *r = rules + i;
|
||||
rule *r = &rules[i];
|
||||
symbol_number lhs = r->lhs->number;
|
||||
bitset f_lhs = FIRSTS (lhs);
|
||||
for (item_number *n = r->rhs;
|
||||
@@ -392,7 +390,7 @@ disable_state_item (state_item *si)
|
||||
static void
|
||||
prune_forward (const state_item *si)
|
||||
{
|
||||
gl_list_t queue =
|
||||
state_item_list queue =
|
||||
gl_list_create (GL_LINKED_LIST, NULL, NULL, NULL, true, 1,
|
||||
(const void **) &si);
|
||||
|
||||
@@ -401,7 +399,7 @@ prune_forward (const state_item *si)
|
||||
state_item *dsi = (state_item *) gl_list_get_at (queue, 0);
|
||||
gl_list_remove_at (queue, 0);
|
||||
if (dsi->trans >= 0)
|
||||
gl_list_add_last (queue, state_items + dsi->trans);
|
||||
gl_list_add_last (queue, &state_items[dsi->trans]);
|
||||
|
||||
if (dsi->prods)
|
||||
{
|
||||
@@ -409,7 +407,7 @@ prune_forward (const state_item *si)
|
||||
state_item_number sin;
|
||||
BITSET_FOR_EACH (biter, dsi->prods, sin, 0)
|
||||
{
|
||||
const state_item *prod = state_items + sin;
|
||||
const state_item *prod = &state_items[sin];
|
||||
bitset_reset (prod->revs, dsi - state_items);
|
||||
if (bitset_empty_p (prod->revs))
|
||||
gl_list_add_last (queue, prod);
|
||||
@@ -427,7 +425,7 @@ prune_forward (const state_item *si)
|
||||
static void
|
||||
prune_backward (const state_item *si)
|
||||
{
|
||||
gl_list_t queue =
|
||||
state_item_list queue =
|
||||
gl_list_create (GL_LINKED_LIST, NULL, NULL, NULL, true, 1,
|
||||
(const void **) &si);
|
||||
|
||||
@@ -441,7 +439,7 @@ prune_backward (const state_item *si)
|
||||
{
|
||||
if (SI_DISABLED (sin))
|
||||
continue;
|
||||
state_item *rev = state_items + sin;
|
||||
state_item *rev = &state_items[sin];
|
||||
if (rev->prods)
|
||||
{
|
||||
bitset_reset (rev->prods, dsi - state_items);
|
||||
@@ -466,7 +464,7 @@ prune_disabled_paths (void)
|
||||
{
|
||||
for (int i = nstate_items - 1; i >= 0; --i)
|
||||
{
|
||||
state_item *si = state_items + i;
|
||||
state_item *si = &state_items[i];
|
||||
if (si->trans == -1 && item_number_is_symbol_number (*si->item))
|
||||
{
|
||||
prune_forward (si);
|
||||
@@ -494,9 +492,9 @@ state_items_report (void)
|
||||
for (state_number i = 0; i < nstates; ++i)
|
||||
{
|
||||
printf ("State %d:\n", i);
|
||||
for (int j = state_item_map[i]; j < state_item_map[i + 1]; ++j)
|
||||
for (state_item_number j = state_item_map[i]; j < state_item_map[i + 1]; ++j)
|
||||
{
|
||||
state_item *si = state_items + j;
|
||||
state_item *si = &state_items[j];
|
||||
item_print (si->item, NULL, stdout);
|
||||
if (SI_DISABLED (j))
|
||||
{
|
||||
@@ -508,7 +506,7 @@ state_items_report (void)
|
||||
if (si->trans >= 0)
|
||||
{
|
||||
fputs (" -> ", stdout);
|
||||
print_state_item (state_items + si->trans, stdout, "");
|
||||
print_state_item (&state_items[si->trans], stdout, "");
|
||||
}
|
||||
|
||||
bitset sets[2] = { si->prods, si->revs };
|
||||
@@ -523,7 +521,7 @@ state_items_report (void)
|
||||
BITSET_FOR_EACH (biter, b, sin, 0)
|
||||
{
|
||||
fputs (txt[seti], stdout);
|
||||
print_state_item (state_items + sin, stdout, "");
|
||||
print_state_item (&state_items[sin], stdout, "");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -562,10 +560,10 @@ state_items_init (void)
|
||||
void
|
||||
state_items_free (void)
|
||||
{
|
||||
for (int i = 0; i < nstate_items; ++i)
|
||||
for (state_item_number i = 0; i < nstate_items; ++i)
|
||||
if (!SI_DISABLED (i))
|
||||
{
|
||||
state_item *si = state_items + i;
|
||||
state_item *si = &state_items[i];
|
||||
if (si->prods)
|
||||
bitset_free (si->prods);
|
||||
bitset_free (si->revs);
|
||||
@@ -594,5 +592,5 @@ production_allowed (const state_item *si, const state_item *next)
|
||||
if (prec1 == prec2 && s1->assoc == left_assoc)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
+12
-8
@@ -28,16 +28,16 @@
|
||||
# include "state.h"
|
||||
|
||||
/* Initializes a graph connecting (state, production item) pairs to
|
||||
pairs they can make a transition or production step to. This graph
|
||||
pairs they can make a transition or production step to. This graph
|
||||
is used to search for paths that represent counterexamples of some
|
||||
conflict.
|
||||
|
||||
state_items is an array of state state-item pairs ordered by state.
|
||||
state_item_map maps state numbers to the first item which
|
||||
corresponds to it in the array. A state's portion in state_items
|
||||
begins with its items in the same order as it was in the
|
||||
state. This is then followed by productions from the closure of the
|
||||
state in order by rule.
|
||||
corresponds to it in the array. A state's portion in state_items
|
||||
begins with its items in the same order as it was in the state.
|
||||
This is then followed by productions from the closure of the state
|
||||
in order by rule.
|
||||
|
||||
There are two type of edges in this graph transitions and
|
||||
productions. Transitions are the same as transitions from the
|
||||
@@ -53,9 +53,9 @@
|
||||
production edges, and all others will have reverse transition
|
||||
edges. */
|
||||
|
||||
# define SI_DISABLED(sin) (state_items[sin].trans == -2)
|
||||
# define SI_PRODUCTION(si) ((si) == state_items || *((si)->item - 1) < 0)
|
||||
# define SI_TRANSITION(si) ((si) != state_items && *((si)->item - 1) >= 0)
|
||||
# define SI_DISABLED(Sin) (state_items[Sin].trans == -2)
|
||||
# define SI_PRODUCTION(Si) ((Si) == state_items || *((Si)->item - 1) < 0)
|
||||
# define SI_TRANSITION(Si) ((Si) != state_items && *((Si)->item - 1) >= 0)
|
||||
|
||||
typedef int state_item_number;
|
||||
|
||||
@@ -69,6 +69,9 @@ typedef struct
|
||||
bitset lookahead;
|
||||
} state_item;
|
||||
|
||||
// A path of state-items.
|
||||
typedef gl_list_t state_item_list;
|
||||
|
||||
extern bitsetv firsts;
|
||||
# define FIRSTS(sym) firsts[(sym) - ntokens]
|
||||
|
||||
@@ -92,6 +95,7 @@ void state_items_free (void);
|
||||
|
||||
bool production_allowed (const state_item *si, const state_item *next);
|
||||
|
||||
// Iterating on a state_item_list.
|
||||
static inline bool
|
||||
state_item_list_next (gl_list_iterator_t *it, state_item **si)
|
||||
{
|
||||
|
||||
+7
-7
@@ -101,7 +101,7 @@ reductions_new (int num, rule **reds)
|
||||
size_t rules_size = num * sizeof *reds;
|
||||
reductions *res = xmalloc (offsetof (reductions, rules) + rules_size);
|
||||
res->num = num;
|
||||
res->lookahead_tokens = NULL;
|
||||
res->lookaheads = NULL;
|
||||
memcpy (res->rules, reds, rules_size);
|
||||
return res;
|
||||
}
|
||||
@@ -260,20 +260,20 @@ state_errs_set (state *s, int num, symbol **tokens)
|
||||
`--------------------------------------------------*/
|
||||
|
||||
void
|
||||
state_rule_lookahead_tokens_print (state const *s, rule const *r, FILE *out)
|
||||
state_rule_lookaheads_print (state const *s, rule const *r, FILE *out)
|
||||
{
|
||||
/* Find the reduction we are handling. */
|
||||
reductions *reds = s->reductions;
|
||||
int red = state_reduction_find (s, r);
|
||||
|
||||
/* Print them if there are. */
|
||||
if (reds->lookahead_tokens && red != -1)
|
||||
if (reds->lookaheads && red != -1)
|
||||
{
|
||||
bitset_iterator biter;
|
||||
int k;
|
||||
char const *sep = "";
|
||||
fprintf (out, " [");
|
||||
BITSET_FOR_EACH (biter, reds->lookahead_tokens[red], k, 0)
|
||||
BITSET_FOR_EACH (biter, reds->lookaheads[red], k, 0)
|
||||
{
|
||||
fprintf (out, "%s%s", sep, symbols[k]->tag);
|
||||
sep = ", ";
|
||||
@@ -283,7 +283,7 @@ state_rule_lookahead_tokens_print (state const *s, rule const *r, FILE *out)
|
||||
}
|
||||
|
||||
void
|
||||
state_rule_lookahead_tokens_print_xml (state const *s, rule const *r,
|
||||
state_rule_lookaheads_print_xml (state const *s, rule const *r,
|
||||
FILE *out, int level)
|
||||
{
|
||||
/* Find the reduction we are handling. */
|
||||
@@ -291,12 +291,12 @@ state_rule_lookahead_tokens_print_xml (state const *s, rule const *r,
|
||||
int red = state_reduction_find (s, r);
|
||||
|
||||
/* Print them if there are. */
|
||||
if (reds->lookahead_tokens && red != -1)
|
||||
if (reds->lookaheads && red != -1)
|
||||
{
|
||||
bitset_iterator biter;
|
||||
int k;
|
||||
xml_puts (out, level, "<lookaheads>");
|
||||
BITSET_FOR_EACH (biter, reds->lookahead_tokens[red], k, 0)
|
||||
BITSET_FOR_EACH (biter, reds->lookaheads[red], k, 0)
|
||||
{
|
||||
xml_printf (out, level + 1, "<symbol>%s</symbol>",
|
||||
xml_escape (symbols[k]->tag));
|
||||
|
||||
+5
-5
@@ -62,7 +62,7 @@
|
||||
|
||||
Each reductions structure describes the possible reductions at the
|
||||
state whose number is in the number field. rules is an array of
|
||||
num rules. lookahead_tokens is an array of bitsets, one per rule.
|
||||
num rules. lookaheads is an array of bitsets, one per rule.
|
||||
|
||||
Conflict resolution can decide that certain tokens in certain
|
||||
states should explicitly be errors (for implementing %nonassoc).
|
||||
@@ -187,7 +187,7 @@ errs *errs_new (int num, symbol **tokens);
|
||||
typedef struct
|
||||
{
|
||||
int num;
|
||||
bitset *lookahead_tokens;
|
||||
bitset *lookaheads;
|
||||
/* Sorted ascendingly on rule number. */
|
||||
rule *rules[1];
|
||||
} reductions;
|
||||
@@ -254,9 +254,9 @@ void state_errs_set (state *s, int num, symbol **errors);
|
||||
|
||||
/* Print on OUT all the lookahead tokens such that this STATE wants to
|
||||
reduce R. */
|
||||
void state_rule_lookahead_tokens_print (state const *s, rule const *r, FILE *out);
|
||||
void state_rule_lookahead_tokens_print_xml (state const *s, rule const *r,
|
||||
FILE *out, int level);
|
||||
void state_rule_lookaheads_print (state const *s, rule const *r, FILE *out);
|
||||
void state_rule_lookaheads_print_xml (state const *s, rule const *r,
|
||||
FILE *out, int level);
|
||||
|
||||
/* Create/destroy the states hash table. */
|
||||
void state_hash_new (void);
|
||||
|
||||
+4
-4
@@ -200,7 +200,7 @@ conflict_row (state *s)
|
||||
/* Find all reductions for token J, and record all that do not
|
||||
match ACTROW[J]. */
|
||||
for (int i = 0; i < reds->num; i += 1)
|
||||
if (bitset_test (reds->lookahead_tokens[i], j)
|
||||
if (bitset_test (reds->lookaheads[i], j)
|
||||
&& (actrow[j]
|
||||
!= rule_number_as_item_number (reds->rules[i]->number)))
|
||||
{
|
||||
@@ -247,7 +247,7 @@ action_row (state *s)
|
||||
|
||||
reductions *reds = s->reductions;
|
||||
bool conflicted = false;
|
||||
if (reds->lookahead_tokens)
|
||||
if (reds->lookaheads)
|
||||
/* loop over all the rules available here which require
|
||||
lookahead (in reverse order to give precedence to the first
|
||||
rule) */
|
||||
@@ -257,7 +257,7 @@ action_row (state *s)
|
||||
{
|
||||
bitset_iterator biter;
|
||||
int j;
|
||||
BITSET_FOR_EACH (biter, reds->lookahead_tokens[i], j, 0)
|
||||
BITSET_FOR_EACH (biter, reds->lookaheads[i], j, 0)
|
||||
{
|
||||
/* and record this rule as the rule to use if that
|
||||
token follows. */
|
||||
@@ -308,7 +308,7 @@ action_row (state *s)
|
||||
}
|
||||
|
||||
/* Turn off default reductions where requested by the user. See
|
||||
state_lookahead_tokens_count in lalr.c to understand when states are
|
||||
state_lookaheads_count in lalr.c to understand when states are
|
||||
labeled as consistent. */
|
||||
{
|
||||
char *default_reductions =
|
||||
|
||||
+92
-44
@@ -726,7 +726,7 @@ AT_BISON_OPTION_POPDEFS
|
||||
AT_BISON_CHECK([[-Dlr.type=canonical-lr -o input.c input.y]],
|
||||
[[0]], [[]],
|
||||
[[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_PARSER_CHECK([[input]], [[1]], [[]],
|
||||
@@ -737,7 +737,7 @@ AT_PARSER_CHECK([[input]], [[1]], [[]],
|
||||
AT_BISON_CHECK([[-Dlr.type=canonical-lr -Dparse.lac=full \
|
||||
-o input.c input.y]], [[0]], [[]],
|
||||
[[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_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]],
|
||||
[[0]], [[]],
|
||||
[[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_PARSER_CHECK([[input]], [[1]], [[]],
|
||||
@@ -773,7 +773,7 @@ exp: exp OP exp | NUM;
|
||||
|
||||
AT_BISON_CHECK([-o input.c --report=all input.y], 0, [],
|
||||
[[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.
|
||||
@@ -861,12 +861,18 @@ State 5
|
||||
OP [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
|
||||
Example exp OP exp . OP exp
|
||||
First derivation exp ::=[ exp ::=[ exp OP exp . ] OP exp ]
|
||||
Second derivation exp ::=[ exp OP exp ::=[ exp . OP exp ] ]
|
||||
Example: exp OP exp . OP exp
|
||||
Shift derivation
|
||||
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, [],
|
||||
[[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]
|
||||
]])
|
||||
|
||||
@@ -1119,7 +1125,7 @@ m4_popdef([AT_TEST])
|
||||
# else.
|
||||
|
||||
AT_SETUP([Defaulted Conflicted Reduction])
|
||||
AT_KEYWORDS([report])
|
||||
AT_KEYWORDS([cex report])
|
||||
|
||||
AT_DATA([input.y],
|
||||
[[%%
|
||||
@@ -1131,7 +1137,7 @@ id : '0';
|
||||
|
||||
AT_BISON_CHECK([-o input.c --report=all input.y], 0, [],
|
||||
[[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]
|
||||
]])
|
||||
|
||||
@@ -1203,12 +1209,18 @@ State 1
|
||||
$end [reduce using rule 4 (id)]
|
||||
$default reduce using rule 3 (num)
|
||||
|
||||
Reduce/reduce conflict on token $end:
|
||||
reduce/reduce conflict on token $end:
|
||||
3 num: '0' .
|
||||
4 id: '0' .
|
||||
Example '0' .
|
||||
First derivation exp ::=[ num ::=[ '0' . ] ]
|
||||
Second derivation exp ::=[ id ::=[ '0' . ] ]
|
||||
Example: '0' .
|
||||
First reduce derivation
|
||||
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, [],
|
||||
[[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
|
||||
|
||||
@@ -1297,7 +1309,7 @@ exp: exp OP exp | NUM;
|
||||
|
||||
AT_BISON_CHECK([-o input.c input.y], 1, [],
|
||||
[[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
|
||||
|
||||
@@ -1317,7 +1329,7 @@ a: 'a';
|
||||
|
||||
AT_BISON_CHECK([-o input.c input.y], 1, [],
|
||||
[[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
|
||||
|
||||
@@ -1518,7 +1530,7 @@ e: e '+' e
|
||||
|
||||
AT_BISON_CHECK([-Wall -o input.c input.y], 0, [],
|
||||
[[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:2.1-5: warning: useless precedence and associativity for '*' [-Wprecedence]
|
||||
]])
|
||||
@@ -1579,6 +1591,8 @@ AT_CLEANUP
|
||||
|
||||
AT_SETUP([[Unreachable States After Conflict Resolution]])
|
||||
|
||||
AT_KEYWORDS([cex report])
|
||||
|
||||
# If conflict resolution makes states unreachable, remove those states, report
|
||||
# rules that are then unused, and don't report conflicts in those states. Test
|
||||
# what happens when a nonterminal becomes useless as a result of state removal
|
||||
@@ -1624,7 +1638,7 @@ reported_conflicts:
|
||||
AT_BISON_CHECK([[--report=all input.y]], 0, [],
|
||||
[[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
|
||||
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: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]
|
||||
@@ -1750,21 +1764,33 @@ State 4
|
||||
|
||||
reported_conflicts go to state 6
|
||||
|
||||
Shift/reduce conflict on token 'a':
|
||||
shift/reduce conflict on token 'a':
|
||||
10 reported_conflicts: . %empty
|
||||
8 reported_conflicts: . 'a'
|
||||
First example resolved_conflict . 'a'
|
||||
First derivation start ::=[ resolved_conflict reported_conflicts ::=[ . ] 'a' ]
|
||||
Second example resolved_conflict . 'a' 'a'
|
||||
Second derivation start ::=[ resolved_conflict reported_conflicts ::=[ . 'a' ] 'a' ]
|
||||
First example: resolved_conflict . 'a' 'a'
|
||||
Shift derivation
|
||||
start
|
||||
`-> resolved_conflict reported_conflicts 'a'
|
||||
`-> . 'a'
|
||||
Second example: resolved_conflict . 'a'
|
||||
Reduce derivation
|
||||
start
|
||||
`-> resolved_conflict reported_conflicts 'a'
|
||||
`-> .
|
||||
|
||||
Shift/reduce conflict on token 'a':
|
||||
shift/reduce conflict on token 'a':
|
||||
10 reported_conflicts: . %empty
|
||||
9 reported_conflicts: . 'a'
|
||||
First example resolved_conflict . 'a'
|
||||
First derivation start ::=[ resolved_conflict reported_conflicts ::=[ . ] 'a' ]
|
||||
Second example resolved_conflict . 'a' 'a'
|
||||
Second derivation start ::=[ resolved_conflict reported_conflicts ::=[ . 'a' ] 'a' ]
|
||||
First example: resolved_conflict . 'a' 'a'
|
||||
Shift derivation
|
||||
start
|
||||
`-> resolved_conflict reported_conflicts 'a'
|
||||
`-> . 'a'
|
||||
Second example: resolved_conflict . 'a'
|
||||
Reduce derivation
|
||||
start
|
||||
`-> resolved_conflict reported_conflicts 'a'
|
||||
`-> .
|
||||
|
||||
|
||||
|
||||
@@ -1777,12 +1803,16 @@ State 5
|
||||
'a' [reduce using rule 9 (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' .
|
||||
9 reported_conflicts: 'a' .
|
||||
Example 'a' .
|
||||
First derivation reported_conflicts ::=[ 'a' . ]
|
||||
Second derivation reported_conflicts ::=[ 'a' . ]
|
||||
Example: 'a' .
|
||||
First reduce derivation
|
||||
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, [],
|
||||
[[input-keep.y: warning: 2 shift/reduce conflicts [-Wconflicts-sr]
|
||||
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: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]
|
||||
@@ -1904,6 +1934,8 @@ AT_CLEANUP
|
||||
|
||||
AT_SETUP([[%nonassoc error actions for multiple reductions in a state]])
|
||||
|
||||
AT_KEYWORDS([cex report])
|
||||
|
||||
AT_DATA([[input.y]],
|
||||
[[%nonassoc 'a' 'b' 'c'
|
||||
%%
|
||||
@@ -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 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
|
||||
13 empty_c3: . %empty
|
||||
Example . 'c'
|
||||
First derivation start ::=[ empty_c2 ::=[ . ] 'c' ]
|
||||
Second derivation start ::=[ empty_c3 ::=[ . ] 'c' ]
|
||||
Example: . 'c'
|
||||
First reduce derivation
|
||||
start
|
||||
`-> empty_c2 'c'
|
||||
`-> .
|
||||
Second reduce derivation
|
||||
start
|
||||
`-> empty_c3 'c'
|
||||
`-> .
|
||||
|
||||
|
||||
|
||||
@@ -2000,7 +2038,7 @@ exp: 'a' | 'a';
|
||||
AT_BISON_CHECK([[2.y]], [[0]], [],
|
||||
[[2.y: warning: %expect-rr applies only to GLR parsers [-Wother]
|
||||
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]
|
||||
]])
|
||||
|
||||
@@ -2037,15 +2075,14 @@ B: ;
|
||||
AT_BISON_CHECK([[sr-rr.y]], [[0]], [[]],
|
||||
[[sr-rr.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
|
||||
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]], [[]],
|
||||
[[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]], [[]],
|
||||
[[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]])[
|
||||
else
|
||||
{
|
||||
issue_note=false
|
||||
if test -z "$sr_exp_i" && test "$sr_count" -ne 0; then
|
||||
echo "warning: $sr_count shift/reduce conflicts"
|
||||
issue_note=true
|
||||
elif test "$sr_exp_i" -ne "$sr_count"; then
|
||||
echo "error: shift/reduce conflicts: $sr_count found, $sr_exp_i expected"
|
||||
if test "$sr_count" -ne 0; then
|
||||
issue_note=true
|
||||
fi
|
||||
fi
|
||||
if test -z "$rr_exp_i" && test "$rr_count" -ne 0; then
|
||||
echo "warning: $rr_count reduce/reduce conflicts"
|
||||
issue_note=true
|
||||
elif test "$rr_exp_i" -ne "$rr_count"; then
|
||||
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
|
||||
} | sed -e "s/^/$file: /" > 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]])[
|
||||
fi
|
||||
done
|
||||
|
||||
+559
-183
@@ -17,13 +17,23 @@
|
||||
|
||||
AT_BANNER([[Counterexamples.]])
|
||||
|
||||
# AT_BISON_CHECK_CEX(TREE, FLAT)
|
||||
# ------------------------------
|
||||
m4_define([AT_BISON_CHECK_CEX],
|
||||
[AT_DATA([experr], [$4])
|
||||
sed -e ['s/time limit exceeded: [0-9][.0-9]*/time limit exceeded: XXX/g'] \
|
||||
experr >expout
|
||||
AT_BISON_CHECK([-Wcounterexamples $1], [$2], [$3], [stderr])
|
||||
[AT_KEYWORDS([cex])
|
||||
|
||||
AT_BISON_CHECK([-Wcounterexamples input.y], [0], [], [stderr])
|
||||
# FIXME: Avoid trailing white spaces.
|
||||
AT_CHECK([[sed -e 's/time limit exceeded: [0-9][.0-9]*/time limit exceeded: XXX/g;s/ *$//;' stderr]],
|
||||
[], [$1])
|
||||
|
||||
m4_pushdef([AT_SET_ENV_IF],
|
||||
[[YYFLAT=1; export YYFLAT;]]m4_defn([AT_SET_ENV_IF]))
|
||||
AT_BISON_CHECK([-Wcounterexamples input.y], [0], [], [stderr])
|
||||
AT_CHECK([[sed -e 's/time limit exceeded: [0-9][.0-9]*/time limit exceeded: XXX/g' stderr]],
|
||||
[], [expout])
|
||||
[], [$2])
|
||||
m4_popdef([AT_SET_ENV_IF])
|
||||
|
||||
])
|
||||
|
||||
## --------------------- ##
|
||||
@@ -31,7 +41,6 @@ AT_CHECK([[sed -e 's/time limit exceeded: [0-9][.0-9]*/time limit exceeded: XXX/
|
||||
## --------------------- ##
|
||||
|
||||
AT_SETUP([Unifying S/R])
|
||||
AT_KEYWORDS([cex])
|
||||
|
||||
AT_DATA([[input.y]],
|
||||
[[%token A B C
|
||||
@@ -43,13 +52,25 @@ x: B | B C;
|
||||
y: A | A B;
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK_CEX([input.y], [], [],
|
||||
AT_BISON_CHECK_CEX(
|
||||
[[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
|
||||
Shift/reduce conflict on token B:
|
||||
Example A . B C
|
||||
First derivation s ::=[ a ::=[ A . ] x ::=[ B C ] ]
|
||||
Second derivation s ::=[ y ::=[ A . B ] c ::=[ C ] ]
|
||||
|
||||
input.y: warning: shift/reduce conflict on token B [-Wcounterexamples]
|
||||
Example: A . B C
|
||||
Shift derivation
|
||||
s
|
||||
`-> y c
|
||||
`-> A . B `-> C
|
||||
Reduce derivation
|
||||
s
|
||||
`-> a x
|
||||
`-> A . `-> B C
|
||||
input.y:4.4: warning: rule useless in parser due to conflicts [-Wother]
|
||||
]],
|
||||
[[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
|
||||
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]
|
||||
]])
|
||||
|
||||
@@ -60,7 +81,6 @@ AT_CLEANUP
|
||||
## ------------------- ##
|
||||
|
||||
AT_SETUP([Deep Unifying S/R])
|
||||
AT_KEYWORDS([cex])
|
||||
|
||||
AT_DATA([[input.y]],
|
||||
[[%token A B C
|
||||
@@ -72,18 +92,46 @@ a: A | A a;
|
||||
bc: B bc C | B C;
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK_CEX([input.y], [], [],
|
||||
AT_BISON_CHECK_CEX(
|
||||
[[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
|
||||
Shift/reduce conflict on token B:
|
||||
Example A . B C
|
||||
First derivation s ::=[ a ::=[ A . ] bc ::=[ B C ] ]
|
||||
Second derivation s ::=[ ac ::=[ A ac ::=[ b ::=[ . B ] ] C ] ]
|
||||
|
||||
Shift/reduce conflict on token B:
|
||||
Example A A . B B C C
|
||||
First derivation s ::=[ a ::=[ A a ::=[ A . ] ] bc ::=[ B bc ::=[ B C ] C ] ]
|
||||
Second derivation s ::=[ ac ::=[ A ac ::=[ A ac ::=[ b ::=[ . b ::=[ B B ] ] ] C ] C ] ]
|
||||
|
||||
input.y: warning: shift/reduce conflict on token B [-Wcounterexamples]
|
||||
Example: A . B C
|
||||
Shift derivation
|
||||
s
|
||||
`-> ac
|
||||
`-> A ac C
|
||||
`-> b
|
||||
`-> . B
|
||||
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]
|
||||
]])
|
||||
|
||||
@@ -94,7 +142,6 @@ AT_CLEANUP
|
||||
## ------------------------------------ ##
|
||||
|
||||
AT_SETUP([S/R Conflict with Nullable Symbols])
|
||||
AT_KEYWORDS([cex])
|
||||
|
||||
AT_DATA([[input.y]],
|
||||
[[%token A B X Y
|
||||
@@ -107,19 +154,47 @@ y: %empty | Y y;
|
||||
xby: B | X xby Y;
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK_CEX([input.y], [], [],
|
||||
AT_BISON_CHECK_CEX(
|
||||
[[input.y: warning: 2 shift/reduce conflicts [-Wconflicts-sr]
|
||||
Shift/reduce conflict on token B:
|
||||
Example A . B
|
||||
First derivation s ::=[ ax ::=[ A x ::=[ . ] ] by ::=[ B y ::=[ ] ] ]
|
||||
Second derivation s ::=[ A xby ::=[ . B ] ]
|
||||
|
||||
Shift/reduce conflict on token B:
|
||||
First example A X . B y $end
|
||||
First derivation $accept ::=[ s ::=[ ax ::=[ A x ::=[ X x ::=[ . ] ] ] by ::=[ B y ] ] $end ]
|
||||
Second example A X . B Y $end
|
||||
Second derivation $accept ::=[ s ::=[ A xby ::=[ X xby ::=[ . B ] Y ] ] $end ]
|
||||
|
||||
input.y: warning: shift/reduce conflict on token B [-Wcounterexamples]
|
||||
Example: A . B
|
||||
Shift derivation
|
||||
s
|
||||
`-> A xby
|
||||
`-> . B
|
||||
Reduce derivation
|
||||
s
|
||||
`-> ax by
|
||||
`-> 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]
|
||||
]])
|
||||
|
||||
@@ -130,7 +205,6 @@ AT_CLEANUP
|
||||
## ---------------------------- ##
|
||||
|
||||
AT_SETUP([Non-unifying Ambiguous S/R])
|
||||
AT_KEYWORDS([cex])
|
||||
|
||||
AT_DATA([[input.y]],
|
||||
[[%token A B C D E
|
||||
@@ -143,14 +217,31 @@ cd: C D;
|
||||
bc: B C;
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK_CEX([input.y], [], [],
|
||||
AT_BISON_CHECK_CEX(
|
||||
[[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
|
||||
Shift/reduce conflict on token C:
|
||||
First example B . C D $end
|
||||
First derivation $accept ::=[ g ::=[ x ::=[ b ::=[ B . ] cd ::=[ C D ] ] ] $end ]
|
||||
Second example B . C $end
|
||||
Second derivation $accept ::=[ g ::=[ x ::=[ bc ::=[ B . C ] ] ] $end ]
|
||||
|
||||
input.y: warning: shift/reduce conflict on token C [-Wcounterexamples]
|
||||
First example: B . C $end
|
||||
Shift derivation
|
||||
$accept
|
||||
`-> g $end
|
||||
`-> x
|
||||
`-> bc
|
||||
`-> B . C
|
||||
Second example: B . C D $end
|
||||
Reduce derivation
|
||||
$accept
|
||||
`-> g $end
|
||||
`-> x
|
||||
`-> b cd
|
||||
`-> B . `-> C D
|
||||
input.y:6.4: warning: rule useless in parser due to conflicts [-Wother]
|
||||
]],
|
||||
[[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
|
||||
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]
|
||||
]])
|
||||
|
||||
@@ -161,7 +252,6 @@ AT_CLEANUP
|
||||
## ------------------------------ ##
|
||||
|
||||
AT_SETUP([Non-unifying Unambiguous S/R])
|
||||
AT_KEYWORDS([cex])
|
||||
|
||||
AT_DATA([[input.y]],
|
||||
[[%token A B
|
||||
@@ -172,14 +262,31 @@ x: A;
|
||||
y: A A B;
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK_CEX([input.y], [], [],
|
||||
AT_BISON_CHECK_CEX(
|
||||
[[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
|
||||
Shift/reduce conflict on token A:
|
||||
First example A . A $end
|
||||
First derivation $accept ::=[ s ::=[ s ::=[ t ::=[ x ::=[ A . ] ] ] t ::=[ x ::=[ A ] ] ] $end ]
|
||||
Second example A . A B $end
|
||||
Second derivation $accept ::=[ s ::=[ t ::=[ y ::=[ A . A B ] ] ] $end ]
|
||||
|
||||
input.y: warning: shift/reduce conflict on token A [-Wcounterexamples]
|
||||
First example: A . A B $end
|
||||
Shift derivation
|
||||
$accept
|
||||
`-> s $end
|
||||
`-> t
|
||||
`-> y
|
||||
`-> A . A B
|
||||
Second example: A . A $end
|
||||
Reduce derivation
|
||||
$accept
|
||||
`-> s $end
|
||||
`-> s t
|
||||
`-> t `-> x
|
||||
`-> x `-> A
|
||||
`-> A .
|
||||
]],
|
||||
[[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
|
||||
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
|
||||
@@ -189,7 +296,6 @@ AT_CLEANUP
|
||||
## ----------------------- ##
|
||||
|
||||
AT_SETUP([S/R after first token])
|
||||
AT_KEYWORDS([cex])
|
||||
|
||||
AT_DATA([[input.y]],
|
||||
[[%token A B X Y
|
||||
@@ -205,19 +311,45 @@ xy: X Y;
|
||||
y: Y;
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK_CEX([input.y], [], [],
|
||||
AT_BISON_CHECK_CEX(
|
||||
[[input.y: warning: 2 shift/reduce conflicts [-Wconflicts-sr]
|
||||
Shift/reduce conflict on token A:
|
||||
Example b . A X X Y
|
||||
First derivation a ::=[ r ::=[ b . ] t ::=[ A x ::=[ X ] xy ::=[ X Y ] ] ]
|
||||
Second derivation a ::=[ s ::=[ b . xx ::=[ A X X ] y ::=[ Y ] ] ]
|
||||
|
||||
Shift/reduce conflict on token X:
|
||||
First example X . X xy
|
||||
First derivation a ::=[ x ::=[ X . ] t ::=[ X xy ] ]
|
||||
Second example A X . X
|
||||
Second derivation a ::=[ t ::=[ A xx ::=[ X . X ] ] ]
|
||||
|
||||
input.y: warning: shift/reduce conflict on token A [-Wcounterexamples]
|
||||
Example: b . A X X Y
|
||||
Shift derivation
|
||||
a
|
||||
`-> s
|
||||
`-> b . xx y
|
||||
`-> A X X `-> Y
|
||||
Reduce derivation
|
||||
a
|
||||
`-> 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:8.4: warning: rule useless in parser due to conflicts [-Wother]
|
||||
]])
|
||||
@@ -229,7 +361,6 @@ AT_CLEANUP
|
||||
## ----------------------------- ##
|
||||
|
||||
AT_SETUP([Unifying R/R counterexample])
|
||||
AT_KEYWORDS([cex])
|
||||
|
||||
AT_DATA([[input.y]],
|
||||
[[%token A
|
||||
@@ -238,13 +369,24 @@ a : A b ;
|
||||
b : A | b;
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK_CEX([input.y], [], [],
|
||||
AT_BISON_CHECK_CEX(
|
||||
[[input.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
|
||||
Reduce/reduce conflict on token $end:
|
||||
Example A b .
|
||||
First derivation a ::=[ A b . ]
|
||||
Second derivation a ::=[ A b ::=[ b . ] ]
|
||||
|
||||
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: 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]
|
||||
]])
|
||||
|
||||
@@ -255,7 +397,6 @@ AT_CLEANUP
|
||||
## --------------------------------- ##
|
||||
|
||||
AT_SETUP([Non-unifying R/R LR(1) conflict])
|
||||
AT_KEYWORDS([cex])
|
||||
|
||||
AT_DATA([[input.y]],
|
||||
[[%token A B C D
|
||||
@@ -265,14 +406,29 @@ a: D;
|
||||
b: D;
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK_CEX([input.y], [], [],
|
||||
AT_BISON_CHECK_CEX(
|
||||
[[input.y: warning: 2 reduce/reduce conflicts [-Wconflicts-rr]
|
||||
Reduce/reduce conflict on tokens A, C:
|
||||
First example D . A $end
|
||||
First derivation $accept ::=[ s ::=[ a ::=[ D . ] A ] $end ]
|
||||
Second example B D . A $end
|
||||
Second derivation $accept ::=[ s ::=[ B b ::=[ D . ] A ] $end ]
|
||||
|
||||
input.y: warning: reduce/reduce conflict on tokens A, C [-Wcounterexamples]
|
||||
First example: D . A $end
|
||||
First reduce derivation
|
||||
$accept
|
||||
`-> 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]
|
||||
]])
|
||||
|
||||
@@ -283,7 +439,6 @@ AT_CLEANUP
|
||||
## --------------------------------- ##
|
||||
|
||||
AT_SETUP([Non-unifying R/R LR(2) conflict])
|
||||
AT_KEYWORDS([cex])
|
||||
|
||||
AT_DATA([[input.y]],
|
||||
[[%token H J K X
|
||||
@@ -293,15 +448,31 @@ a: H i;
|
||||
i: X | i J K;
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK_CEX([input.y], [], [],
|
||||
AT_BISON_CHECK_CEX(
|
||||
[[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
|
||||
Shift/reduce conflict on token J:
|
||||
input.y: warning: shift/reduce conflict on token J [-Wcounterexamples]
|
||||
time limit exceeded: XXX
|
||||
First example H i . J $end
|
||||
First derivation $accept ::=[ s ::=[ a ::=[ H i . ] J ] $end ]
|
||||
Second example H i . J K $end
|
||||
Second derivation $accept ::=[ a ::=[ H i ::=[ i . J K ] ] $end ]
|
||||
|
||||
First example: H i . J K $end
|
||||
Shift derivation
|
||||
$accept
|
||||
`-> a $end
|
||||
`-> H i
|
||||
`-> i . J K
|
||||
Second example: H i . J $end
|
||||
Reduce derivation
|
||||
$accept
|
||||
`-> s $end
|
||||
`-> a J
|
||||
`-> H i .
|
||||
input.y:4.4-6: warning: rule useless in parser due to conflicts [-Wother]
|
||||
]],
|
||||
[[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
|
||||
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]
|
||||
]])
|
||||
|
||||
@@ -315,7 +486,6 @@ AT_CLEANUP
|
||||
# graph search
|
||||
|
||||
AT_SETUP([Cex Search Prepend])
|
||||
AT_KEYWORDS([cex])
|
||||
|
||||
AT_DATA([[input.y]],
|
||||
[[%token N A B C D
|
||||
@@ -326,18 +496,45 @@ a: A;
|
||||
b: A B C | A B D;
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK_CEX([input.y], [], [],
|
||||
AT_BISON_CHECK_CEX(
|
||||
[[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
|
||||
Shift/reduce conflict on token B:
|
||||
Example N A . B C
|
||||
First derivation s ::=[ n ::=[ N a ::=[ A . ] B ] C ]
|
||||
Second derivation s ::=[ n ::=[ N b ::=[ A . B C ] ] ]
|
||||
|
||||
Shift/reduce conflict on token B:
|
||||
Example N N A . B D C
|
||||
First derivation s ::=[ n ::=[ N n ::=[ N a ::=[ A . ] B ] D ] C ]
|
||||
Second derivation s ::=[ n ::=[ N n ::=[ N b ::=[ A . B D ] ] C ] ]
|
||||
|
||||
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 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]
|
||||
]])
|
||||
|
||||
@@ -351,7 +548,6 @@ AT_CLEANUP
|
||||
# precedence/associativity directives work.
|
||||
|
||||
AT_SETUP([R/R cex with prec])
|
||||
AT_KEYWORDS([cex])
|
||||
|
||||
AT_DATA([[input.y]],
|
||||
[[%left b
|
||||
@@ -363,18 +559,46 @@ B : A b A;
|
||||
C : A c A;
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK_CEX([input.y], [], [],
|
||||
AT_BISON_CHECK_CEX(
|
||||
[[input.y: warning: 4 reduce/reduce conflicts [-Wconflicts-rr]
|
||||
Reduce/reduce conflict on tokens b, c:
|
||||
Example B . b c
|
||||
First derivation S ::=[ B ::=[ A ::=[ B . ] b A ::=[ ] ] C ::=[ A ::=[ ] c A ::=[ ] ] ]
|
||||
Second derivation S ::=[ B C ::=[ A ::=[ B ::=[ A ::=[ . ] b A ::=[ ] ] ] c A ::=[ ] ] ]
|
||||
|
||||
Reduce/reduce conflict on tokens b, c:
|
||||
Example C . c b
|
||||
First derivation S ::=[ C ::=[ A ::=[ C . ] c A ::=[ ] ] B ::=[ A ::=[ ] b A ::=[ ] ] ]
|
||||
Second derivation S ::=[ C B ::=[ A ::=[ C ::=[ A ::=[ . ] c A ::=[ ] ] ] b A ::=[ ] ] ]
|
||||
|
||||
input.y: warning: reduce/reduce conflict on tokens b, c [-Wcounterexamples]
|
||||
Example: B . b c
|
||||
First reduce derivation
|
||||
S
|
||||
`-> B C
|
||||
`-> A b A `-> A c A
|
||||
`-> B . `-> %empty `-> %empty `-> %empty
|
||||
Second reduce derivation
|
||||
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
|
||||
@@ -384,7 +608,6 @@ AT_CLEANUP
|
||||
## ------------------- ##
|
||||
|
||||
AT_SETUP([Null nonterminals])
|
||||
AT_KEYWORDS([cex])
|
||||
|
||||
AT_DATA([[input.y]],
|
||||
[[%token A
|
||||
@@ -395,58 +618,172 @@ c : ;
|
||||
d : a | c A | d;
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK_CEX([input.y], [], [],
|
||||
AT_BISON_CHECK_CEX(
|
||||
[[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
|
||||
input.y: warning: 6 reduce/reduce conflicts [-Wconflicts-rr]
|
||||
Reduce/reduce conflict on token A:
|
||||
First example . c A A $end
|
||||
First derivation $accept ::=[ a ::=[ b ::=[ . ] d ::=[ c A A ] ] $end ]
|
||||
Second example . c A A $end
|
||||
Second derivation $accept ::=[ a ::=[ c ::=[ . ] d ::=[ c A A ] ] $end ]
|
||||
|
||||
Reduce/reduce conflict on token A:
|
||||
input.y: warning: reduce/reduce conflict on token A [-Wcounterexamples]
|
||||
First example: . c A A $end
|
||||
First reduce derivation
|
||||
$accept
|
||||
`-> a $end
|
||||
`-> b d
|
||||
`-> . `-> 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
|
||||
First example b . c A A $end
|
||||
First derivation $accept ::=[ a ::=[ b d ::=[ a ::=[ b ::=[ . ] d ::=[ c A A ] ] ] ] $end ]
|
||||
Second example b . A $end
|
||||
Second derivation $accept ::=[ a ::=[ b d ::=[ c ::=[ . ] A ] ] $end ]
|
||||
|
||||
Reduce/reduce conflict on token A:
|
||||
First example: b . c A A $end
|
||||
First reduce derivation
|
||||
$accept
|
||||
`-> a $end
|
||||
`-> b d
|
||||
`-> 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
|
||||
First example c . c A A $end
|
||||
First derivation $accept ::=[ a ::=[ c d ::=[ a ::=[ b ::=[ . ] d ::=[ c A A ] ] ] ] $end ]
|
||||
Second example c . A $end
|
||||
Second derivation $accept ::=[ a ::=[ c d ::=[ c ::=[ . ] A ] ] $end ]
|
||||
|
||||
Shift/reduce conflict on token A:
|
||||
First example: c . c A A $end
|
||||
First reduce derivation
|
||||
$accept
|
||||
`-> a $end
|
||||
`-> c d
|
||||
`-> 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
|
||||
First example b c . c A A $end
|
||||
First derivation $accept ::=[ a ::=[ b d ::=[ a ::=[ c d ::=[ a ::=[ b ::=[ . ] d ::=[ c A A ] ] ] ] ] ] $end ]
|
||||
Second example b c . A
|
||||
Second derivation a ::=[ b d ::=[ c . A ] ]
|
||||
|
||||
Reduce/reduce conflict on token A:
|
||||
First example b c . c A A $end
|
||||
First derivation $accept ::=[ a ::=[ b d ::=[ a ::=[ c d ::=[ a ::=[ b ::=[ . ] d ::=[ c A A ] ] ] ] ] ] $end ]
|
||||
Second example b c . A $end
|
||||
Second derivation $accept ::=[ a ::=[ b d ::=[ a ::=[ c d ::=[ c ::=[ . ] A ] ] ] ] $end ]
|
||||
|
||||
Shift/reduce conflict on token A:
|
||||
First example b c . A $end
|
||||
First derivation $accept ::=[ a ::=[ b d ::=[ a ::=[ c d ::=[ c ::=[ . ] A ] ] ] ] $end ]
|
||||
Second example b c . A
|
||||
Second derivation a ::=[ b d ::=[ c . A ] ]
|
||||
|
||||
Reduce/reduce conflict on token $end:
|
||||
Example b d .
|
||||
First derivation a ::=[ b d . ]
|
||||
Second derivation a ::=[ b d ::=[ d . ] ]
|
||||
|
||||
Reduce/reduce conflict on token $end:
|
||||
Example c d .
|
||||
First derivation a ::=[ c d . ]
|
||||
Second derivation a ::=[ c d ::=[ d . ] ]
|
||||
|
||||
First example: b c . A
|
||||
Shift derivation
|
||||
a
|
||||
`-> b d
|
||||
`-> c . A
|
||||
Second example: b c . c A A $end
|
||||
Reduce derivation
|
||||
$accept
|
||||
`-> a $end
|
||||
`-> b d
|
||||
`-> a
|
||||
`-> c d
|
||||
`-> a
|
||||
`-> b d
|
||||
`-> . `-> c A A
|
||||
input.y: warning: reduce/reduce conflict on token A [-Wcounterexamples]
|
||||
First example: b c . c A A $end
|
||||
First reduce derivation
|
||||
$accept
|
||||
`-> a $end
|
||||
`-> b d
|
||||
`-> a
|
||||
`-> c d
|
||||
`-> a
|
||||
`-> b 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:6.15: warning: rule useless in parser due to conflicts [-Wother]
|
||||
]])
|
||||
@@ -458,7 +795,6 @@ AT_CLEANUP
|
||||
## --------------------------- ##
|
||||
|
||||
AT_SETUP([Non-unifying Prefix Share])
|
||||
AT_KEYWORDS([cex])
|
||||
|
||||
# Tests for a counterexample which should start its derivation
|
||||
# at a shared symbol rather than the start symbol.
|
||||
@@ -471,13 +807,26 @@ a: H i J J
|
||||
i: %empty | i J;
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK_CEX([input.y], [], [],
|
||||
AT_BISON_CHECK_CEX(
|
||||
[[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
|
||||
Shift/reduce conflict on token J:
|
||||
Example H i J . J J
|
||||
First derivation s ::=[ a ::=[ H i ::=[ i J . ] J J ] ]
|
||||
Second derivation s ::=[ a ::=[ H i J . J ] J ]
|
||||
|
||||
input.y: warning: shift/reduce conflict on token J [-Wcounterexamples]
|
||||
Example: H i J . J J
|
||||
Shift derivation
|
||||
s
|
||||
`-> a J
|
||||
`-> H i J . J
|
||||
Reduce derivation
|
||||
s
|
||||
`-> a
|
||||
`-> H i J J
|
||||
`-> i J .
|
||||
input.y:5.13-15: warning: rule useless in parser due to conflicts [-Wother]
|
||||
]],
|
||||
[[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
|
||||
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]
|
||||
]])
|
||||
|
||||
@@ -491,7 +840,6 @@ AT_CLEANUP
|
||||
# are derived correctly.
|
||||
|
||||
AT_SETUP([Deep Null Unifying])
|
||||
AT_KEYWORDS([cex])
|
||||
|
||||
AT_DATA([[input.y]],
|
||||
[[%token A D
|
||||
@@ -503,13 +851,26 @@ c: %empty
|
||||
d: D;
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK_CEX([input.y], [], [],
|
||||
AT_BISON_CHECK_CEX(
|
||||
[[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
|
||||
Shift/reduce conflict on token D:
|
||||
Example A a . D
|
||||
First derivation s ::=[ A a a ::=[ b ::=[ c ::=[ . ] ] ] d ::=[ D ] ]
|
||||
Second derivation s ::=[ A a d ::=[ . D ] ]
|
||||
|
||||
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 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
|
||||
@@ -521,7 +882,6 @@ AT_CLEANUP
|
||||
# Tests that expand_to_conflict works with nullable sybols
|
||||
|
||||
AT_SETUP([Deep Null Non-unifying])
|
||||
AT_KEYWORDS([cex])
|
||||
|
||||
AT_DATA([[input.y]],
|
||||
[[%token A D E
|
||||
@@ -533,14 +893,30 @@ c: %empty
|
||||
d: D;
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK_CEX([input.y], [], [],
|
||||
AT_BISON_CHECK_CEX(
|
||||
[[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
|
||||
Shift/reduce conflict on token D:
|
||||
First example A a . D E $end
|
||||
First derivation $accept ::=[ s ::=[ A a a ::=[ b ::=[ c ::=[ . ] ] ] d ::=[ D ] E ] $end ]
|
||||
Second example A a . D $end
|
||||
Second derivation $accept ::=[ s ::=[ A a d ::=[ . D ] ] $end ]
|
||||
|
||||
input.y: warning: shift/reduce conflict on token D [-Wcounterexamples]
|
||||
First example: A a . D $end
|
||||
Shift derivation
|
||||
$accept
|
||||
`-> s $end
|
||||
`-> A a d
|
||||
`-> . D
|
||||
Second example: A a . D E $end
|
||||
Reduce derivation
|
||||
$accept
|
||||
`-> s $end
|
||||
`-> A a a d E
|
||||
`-> b `-> D
|
||||
`-> c
|
||||
`-> .
|
||||
]],
|
||||
[[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
|
||||
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
|
||||
|
||||
+105
-26
@@ -28,6 +28,8 @@ m4_pushdef([AT_TEST],
|
||||
AT_SETUP([$1])
|
||||
AT_KEYWORDS([diagnostics])
|
||||
|
||||
m4_if(m4_index([$1], [Counterexample]), [-1], [], [AT_KEYWORDS([cex])])
|
||||
|
||||
# We need UTF-8 support for correct screen-width computation of UTF-8
|
||||
# characters. Skip the test if not available.
|
||||
locale=`locale -a | $EGREP '^en_US\.(UTF-8|utf8)$' | sed 1q`
|
||||
@@ -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])
|
||||
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.
|
||||
# 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
|
||||
# environment.
|
||||
# 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
|
||||
@@ -533,34 +535,111 @@ exp
|
||||
]],
|
||||
[1],
|
||||
[[input.y: <error>error:</error> shift/reduce conflicts: 4 found, 0 expected
|
||||
Shift/reduce conflict on token "+":
|
||||
Example <cex-0><cex-1><cex-leaf>exp</cex-leaf> <cex-leaf>"+"</cex-leaf> <cex-leaf>exp</cex-leaf> <cex-dot>•</cex-dot></cex-1> <cex-leaf>"+"</cex-leaf> <cex-leaf>exp</cex-leaf></cex-0>
|
||||
First derivation <cex-0><cex-step>exp ::=[ </cex-step><cex-1><cex-step>exp ::=[ </cex-step><cex-leaf>exp</cex-leaf> <cex-leaf>"+"</cex-leaf> <cex-leaf>exp</cex-leaf> <cex-dot>•</cex-dot><cex-step> ]</cex-step></cex-1> <cex-leaf>"+"</cex-leaf> <cex-leaf>exp</cex-leaf><cex-step> ]</cex-step></cex-0>
|
||||
Example <cex-0><cex-leaf>exp</cex-leaf> <cex-leaf>"+"</cex-leaf><cex-1> <cex-leaf>exp</cex-leaf> <cex-dot>•</cex-dot> <cex-leaf>"+"</cex-leaf> <cex-leaf>exp</cex-leaf></cex-1></cex-0>
|
||||
Second derivation <cex-0><cex-step>exp ::=[ </cex-step><cex-leaf>exp</cex-leaf> <cex-leaf>"+"</cex-leaf><cex-1> <cex-step>exp ::=[ </cex-step><cex-leaf>exp</cex-leaf> <cex-dot>•</cex-dot> <cex-leaf>"+"</cex-leaf> <cex-leaf>exp</cex-leaf><cex-step> ]</cex-step></cex-1><cex-step> ]</cex-step></cex-0>
|
||||
|
||||
Shift/reduce conflict on token "else":
|
||||
Example <cex-0><cex-leaf>"if"</cex-leaf> <cex-leaf>exp</cex-leaf> <cex-leaf>"then"</cex-leaf><cex-1> <cex-leaf>"if"</cex-leaf> <cex-leaf>exp</cex-leaf> <cex-leaf>"then"</cex-leaf> <cex-leaf>exp</cex-leaf> <cex-dot>•</cex-dot></cex-1> <cex-leaf>"else"</cex-leaf> <cex-leaf>exp</cex-leaf></cex-0>
|
||||
First derivation <cex-0><cex-step>exp ::=[ </cex-step><cex-leaf>"if"</cex-leaf> <cex-leaf>exp</cex-leaf> <cex-leaf>"then"</cex-leaf><cex-1> <cex-step>exp ::=[ </cex-step><cex-leaf>"if"</cex-leaf> <cex-leaf>exp</cex-leaf> <cex-leaf>"then"</cex-leaf> <cex-leaf>exp</cex-leaf> <cex-dot>•</cex-dot><cex-step> ]</cex-step></cex-1> <cex-leaf>"else"</cex-leaf> <cex-leaf>exp</cex-leaf><cex-step> ]</cex-step></cex-0>
|
||||
Example <cex-0><cex-leaf>"if"</cex-leaf> <cex-leaf>exp</cex-leaf> <cex-leaf>"then"</cex-leaf><cex-1> <cex-leaf>"if"</cex-leaf> <cex-leaf>exp</cex-leaf> <cex-leaf>"then"</cex-leaf> <cex-leaf>exp</cex-leaf> <cex-dot>•</cex-dot> <cex-leaf>"else"</cex-leaf> <cex-leaf>exp</cex-leaf></cex-1></cex-0>
|
||||
Second derivation <cex-0><cex-step>exp ::=[ </cex-step><cex-leaf>"if"</cex-leaf> <cex-leaf>exp</cex-leaf> <cex-leaf>"then"</cex-leaf><cex-1> <cex-step>exp ::=[ </cex-step><cex-leaf>"if"</cex-leaf> <cex-leaf>exp</cex-leaf> <cex-leaf>"then"</cex-leaf> <cex-leaf>exp</cex-leaf> <cex-dot>•</cex-dot> <cex-leaf>"else"</cex-leaf> <cex-leaf>exp</cex-leaf><cex-step> ]</cex-step></cex-1><cex-step> ]</cex-step></cex-0>
|
||||
|
||||
Shift/reduce conflict on token "+":
|
||||
Example <cex-0><cex-1><cex-leaf>"if"</cex-leaf> <cex-leaf>exp</cex-leaf> <cex-leaf>"then"</cex-leaf> <cex-leaf>exp</cex-leaf> <cex-dot>•</cex-dot></cex-1> <cex-leaf>"+"</cex-leaf> <cex-leaf>exp</cex-leaf></cex-0>
|
||||
First derivation <cex-0><cex-step>exp ::=[ </cex-step><cex-1><cex-step>exp ::=[ </cex-step><cex-leaf>"if"</cex-leaf> <cex-leaf>exp</cex-leaf> <cex-leaf>"then"</cex-leaf> <cex-leaf>exp</cex-leaf> <cex-dot>•</cex-dot><cex-step> ]</cex-step></cex-1> <cex-leaf>"+"</cex-leaf> <cex-leaf>exp</cex-leaf><cex-step> ]</cex-step></cex-0>
|
||||
Example <cex-0><cex-leaf>"if"</cex-leaf> <cex-leaf>exp</cex-leaf> <cex-leaf>"then"</cex-leaf><cex-1> <cex-leaf>exp</cex-leaf> <cex-dot>•</cex-dot> <cex-leaf>"+"</cex-leaf> <cex-leaf>exp</cex-leaf></cex-1></cex-0>
|
||||
Second derivation <cex-0><cex-step>exp ::=[ </cex-step><cex-leaf>"if"</cex-leaf> <cex-leaf>exp</cex-leaf> <cex-leaf>"then"</cex-leaf><cex-1> <cex-step>exp ::=[ </cex-step><cex-leaf>exp</cex-leaf> <cex-dot>•</cex-dot> <cex-leaf>"+"</cex-leaf> <cex-leaf>exp</cex-leaf><cex-step> ]</cex-step></cex-1><cex-step> ]</cex-step></cex-0>
|
||||
|
||||
Shift/reduce conflict on token "+":
|
||||
Example <cex-0><cex-1><cex-leaf>"if"</cex-leaf> <cex-leaf>exp</cex-leaf> <cex-leaf>"then"</cex-leaf> <cex-leaf>exp</cex-leaf> <cex-leaf>"else"</cex-leaf> <cex-leaf>exp</cex-leaf> <cex-dot>•</cex-dot></cex-1> <cex-leaf>"+"</cex-leaf> <cex-leaf>exp</cex-leaf></cex-0>
|
||||
First derivation <cex-0><cex-step>exp ::=[ </cex-step><cex-1><cex-step>exp ::=[ </cex-step><cex-leaf>"if"</cex-leaf> <cex-leaf>exp</cex-leaf> <cex-leaf>"then"</cex-leaf> <cex-leaf>exp</cex-leaf> <cex-leaf>"else"</cex-leaf> <cex-leaf>exp</cex-leaf> <cex-dot>•</cex-dot><cex-step> ]</cex-step></cex-1> <cex-leaf>"+"</cex-leaf> <cex-leaf>exp</cex-leaf><cex-step> ]</cex-step></cex-0>
|
||||
Example <cex-0><cex-leaf>"if"</cex-leaf> <cex-leaf>exp</cex-leaf> <cex-leaf>"then"</cex-leaf> <cex-leaf>exp</cex-leaf> <cex-leaf>"else"</cex-leaf><cex-1> <cex-leaf>exp</cex-leaf> <cex-dot>•</cex-dot> <cex-leaf>"+"</cex-leaf> <cex-leaf>exp</cex-leaf></cex-1></cex-0>
|
||||
Second derivation <cex-0><cex-step>exp ::=[ </cex-step><cex-leaf>"if"</cex-leaf> <cex-leaf>exp</cex-leaf> <cex-leaf>"then"</cex-leaf> <cex-leaf>exp</cex-leaf> <cex-leaf>"else"</cex-leaf><cex-1> <cex-step>exp ::=[ </cex-step><cex-leaf>exp</cex-leaf> <cex-dot>•</cex-dot> <cex-leaf>"+"</cex-leaf> <cex-leaf>exp</cex-leaf><cex-step> ]</cex-step></cex-1><cex-step> ]</cex-step></cex-0>
|
||||
|
||||
input.y: <warning>warning:</warning> shift/reduce conflict on token "+" [<warning>-Wcounterexamples</warning>]
|
||||
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>
|
||||
Shift derivation
|
||||
<cex-0><cex-step>exp</cex-step></cex-0>
|
||||
<cex-0><cex-step>↳ <cex-leaf>exp</cex-leaf><cex-leaf> "+"</cex-leaf><cex-1><cex-step> exp</cex-step></cex-1></cex-step></cex-0>
|
||||
<cex-1><cex-step> ↳ <cex-leaf>exp</cex-leaf><cex-dot> •</cex-dot><cex-leaf> "+"</cex-leaf><cex-leaf> exp</cex-leaf></cex-step></cex-1>
|
||||
Example: <cex-0><cex-1><cex-leaf>exp</cex-leaf> <cex-leaf>"+"</cex-leaf> <cex-leaf>exp</cex-leaf> <cex-dot>•</cex-dot></cex-1> <cex-leaf>"+"</cex-leaf> <cex-leaf>exp</cex-leaf></cex-0>
|
||||
Reduce derivation
|
||||
<cex-0><cex-step>exp</cex-step></cex-0>
|
||||
<cex-0><cex-step>↳ <cex-1><cex-step>exp</cex-step></cex-1><cex-leaf> "+"</cex-leaf><cex-leaf> exp</cex-leaf></cex-step></cex-0>
|
||||
<cex-1><cex-step> ↳ <cex-leaf>exp</cex-leaf><cex-leaf> "+"</cex-leaf><cex-leaf> exp</cex-leaf><cex-dot> •</cex-dot></cex-step></cex-1>
|
||||
input.y: <warning>warning:</warning> shift/reduce conflict on token "else" [<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>"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>
|
||||
Shift derivation
|
||||
<cex-0><cex-step>exp</cex-step></cex-0>
|
||||
<cex-0><cex-step>↳ <cex-leaf>"if"</cex-leaf><cex-leaf> exp</cex-leaf><cex-leaf> "then"</cex-leaf><cex-1><cex-step> exp</cex-step></cex-1></cex-step></cex-0>
|
||||
<cex-1><cex-step> ↳ <cex-leaf>"if"</cex-leaf><cex-leaf> exp</cex-leaf><cex-leaf> "then"</cex-leaf><cex-leaf> exp</cex-leaf><cex-dot> •</cex-dot><cex-leaf> "else"</cex-leaf><cex-leaf> exp</cex-leaf></cex-step></cex-1>
|
||||
Example: <cex-0><cex-leaf>"if"</cex-leaf> <cex-leaf>exp</cex-leaf> <cex-leaf>"then"</cex-leaf><cex-1> <cex-leaf>"if"</cex-leaf> <cex-leaf>exp</cex-leaf> <cex-leaf>"then"</cex-leaf> <cex-leaf>exp</cex-leaf> <cex-dot>•</cex-dot></cex-1> <cex-leaf>"else"</cex-leaf> <cex-leaf>exp</cex-leaf></cex-0>
|
||||
Reduce derivation
|
||||
<cex-0><cex-step>exp</cex-step></cex-0>
|
||||
<cex-0><cex-step>↳ <cex-leaf>"if"</cex-leaf><cex-leaf> exp</cex-leaf><cex-leaf> "then"</cex-leaf><cex-1><cex-step> exp</cex-step></cex-1><cex-leaf> "else"</cex-leaf><cex-leaf> exp</cex-leaf></cex-step></cex-0>
|
||||
<cex-1><cex-step> ↳ <cex-leaf>"if"</cex-leaf><cex-leaf> exp</cex-leaf><cex-leaf> "then"</cex-leaf><cex-leaf> exp</cex-leaf><cex-dot> •</cex-dot></cex-step></cex-1>
|
||||
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])
|
||||
|
||||
|
||||
+2
-2
@@ -434,7 +434,7 @@ input.y:323.10: warning: empty rule without %empty [-Wempty-rule]
|
||||
]AT_COND_CASE([[canonical LR]],
|
||||
[[input.y: warning: 265 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:44.1-5: warning: useless associativity for YNUMBER, 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: 78 shift/reduce conflicts [-Wconflicts-sr]
|
||||
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:53.1-6: warning: useless associativity for HASSIGN, 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, [],
|
||||
[[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_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, [],
|
||||
[[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])
|
||||
|
||||
@@ -350,7 +350,7 @@ AT_BISON_OPTION_POPDEFS
|
||||
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: 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])
|
||||
|
||||
@@ -447,7 +447,7 @@ AT_BISON_OPTION_POPDEFS
|
||||
|
||||
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: 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])
|
||||
|
||||
@@ -505,7 +505,7 @@ AT_BISON_OPTION_POPDEFS
|
||||
|
||||
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: 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])
|
||||
|
||||
@@ -555,7 +555,7 @@ AT_BISON_OPTION_POPDEFS
|
||||
|
||||
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: 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])
|
||||
|
||||
@@ -646,7 +646,7 @@ AT_BISON_OPTION_POPDEFS
|
||||
|
||||
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: 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])
|
||||
|
||||
@@ -737,7 +737,7 @@ AT_BISON_OPTION_POPDEFS
|
||||
|
||||
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: 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])
|
||||
|
||||
@@ -819,7 +819,7 @@ AT_BISON_OPTION_POPDEFS
|
||||
|
||||
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: 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])
|
||||
|
||||
@@ -877,7 +877,7 @@ AT_BISON_OPTION_POPDEFS
|
||||
|
||||
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: 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])
|
||||
|
||||
@@ -937,7 +937,7 @@ AT_BISON_OPTION_POPDEFS
|
||||
|
||||
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: 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])
|
||||
|
||||
@@ -1060,7 +1060,7 @@ AT_BISON_OPTION_POPDEFS
|
||||
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 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])
|
||||
|
||||
@@ -1392,7 +1392,7 @@ AT_BISON_OPTION_POPDEFS
|
||||
|
||||
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: 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])
|
||||
|
||||
@@ -1487,7 +1487,7 @@ AT_BISON_OPTION_POPDEFS
|
||||
|
||||
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: 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])
|
||||
|
||||
@@ -1549,7 +1549,7 @@ AT_BISON_OPTION_POPDEFS
|
||||
|
||||
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: 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])
|
||||
|
||||
@@ -1625,7 +1625,7 @@ AT_BISON_OPTION_POPDEFS
|
||||
|
||||
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: 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])
|
||||
|
||||
@@ -1719,7 +1719,7 @@ d: /* nada. */;
|
||||
|
||||
AT_BISON_CHECK([[-o input.c input.y]], 0, [],
|
||||
[[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])
|
||||
|
||||
|
||||
@@ -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:13.16-29: note: previous definition
|
||||
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]
|
||||
]])
|
||||
|
||||
|
||||
+8
-3
@@ -1169,11 +1169,16 @@ m4_define([AT_BISON_CHECK_XML],
|
||||
[cp xml-tests/test.output expout]
|
||||
AT_CHECK([[$XSLTPROC \
|
||||
`]]AT_SET_ENV[[ bison --print-datadir`/xslt/xml2text.xsl \
|
||||
xml-tests/test.xml]], [[0]], [expout])
|
||||
xml-tests/test.xml]], [[0]], [stdout])
|
||||
# xml2text and xml2dot always use '•', while --report uses '•' or '.'
|
||||
# depending on the locale, and the test suite is run with the plain
|
||||
# C locale.
|
||||
AT_CHECK([[sed -e 's/•/./g' stdout]], [], [expout])
|
||||
[sort xml-tests/test.gv > expout]
|
||||
AT_CHECK([[$XSLTPROC \
|
||||
`]]AT_SET_ENV[[ bison --print-datadir`/xslt/xml2dot.xsl \
|
||||
xml-tests/test.xml | sort]], [[0]], [expout])
|
||||
xml-tests/test.xml | sort | sed -e 's/•/./g']],
|
||||
[[0]], [stdout])
|
||||
[rm -rf xml-tests expout]
|
||||
AT_RESTORE_SPECIAL_FILES
|
||||
[fi]])
|
||||
@@ -1194,7 +1199,7 @@ m4_define([AT_BISON_CHECK_XML],
|
||||
# The testsuite verbose output, at least, will be incorrect, but nothing may
|
||||
# fail to make sure you notice.
|
||||
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
|
||||
|
||||
@@ -36,6 +36,14 @@ $(top_srcdir)/%D%/package.m4: $(top_srcdir)/configure
|
||||
} >$@.tmp
|
||||
$(AM_V_at)mv $@.tmp $@
|
||||
|
||||
|
||||
# Update the test cases. Consider the latest test results to be the
|
||||
# correct expectations, and change the test cases to match them.
|
||||
.PHONY: update-tests
|
||||
update-tests:
|
||||
$(AM_V_GEN)cd $(top_srcdir) \
|
||||
&& build-aux/update-test $(abs_builddir)/%D%/testsuite.dir/*/testsuite.log
|
||||
|
||||
## ------------------------- ##
|
||||
## Generate the test suite. ##
|
||||
## ------------------------- ##
|
||||
|
||||
+1
-1
@@ -1300,7 +1300,7 @@ dnl INPUT
|
||||
dnl BISON-STDERR
|
||||
[AT_COND_CASE([[LALR]],
|
||||
[[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
|
||||
|
||||
+746
-79
@@ -764,24 +764,24 @@ AT_CHECK([[sed -e 's/bison-xml-report version="[^"]*"/bison-xml-report version="
|
||||
</rule>
|
||||
</rules>
|
||||
<terminals>
|
||||
<terminal symbol-number="0" token-number="0" name=""end of file"" usefulness="useful"/>
|
||||
<terminal symbol-number="1" token-number="256" name="error" usefulness="useful"/>
|
||||
<terminal symbol-number="3" token-number="258" name="":="" usefulness="useful"/>
|
||||
<terminal symbol-number="4" token-number="259" name=""incr"" usefulness="useful"/>
|
||||
<terminal symbol-number="5" token-number="260" name=""identifier"" usefulness="useful"/>
|
||||
<terminal symbol-number="6" token-number="261" name=""number"" usefulness="useful"/>
|
||||
<terminal symbol-number="7" token-number="262" name=""("" usefulness="useful"/>
|
||||
<terminal symbol-number="8" token-number="263" name="")"" usefulness="useful"/>
|
||||
<terminal symbol-number="0" token-number="0" name=""end of file"" type="" usefulness="useful"/>
|
||||
<terminal symbol-number="1" token-number="256" name="error" type="" usefulness="useful"/>
|
||||
<terminal symbol-number="3" token-number="258" name="":="" type="" usefulness="useful"/>
|
||||
<terminal symbol-number="4" token-number="259" name=""incr"" type="" usefulness="useful"/>
|
||||
<terminal symbol-number="5" token-number="260" name=""identifier"" type="std::string" usefulness="useful"/>
|
||||
<terminal symbol-number="6" token-number="261" name=""number"" type="int" usefulness="useful"/>
|
||||
<terminal symbol-number="7" token-number="262" name=""("" type="" usefulness="useful"/>
|
||||
<terminal symbol-number="8" token-number="263" name="")"" type="" usefulness="useful"/>
|
||||
</terminals>
|
||||
<nonterminals>
|
||||
<nonterminal symbol-number="9" name="$accept" usefulness="useful"/>
|
||||
<nonterminal symbol-number="10" name="unit" usefulness="useful"/>
|
||||
<nonterminal symbol-number="11" name="assignments" usefulness="useful"/>
|
||||
<nonterminal symbol-number="12" name="assignment" usefulness="useful"/>
|
||||
<nonterminal symbol-number="13" name="id" usefulness="useful"/>
|
||||
<nonterminal symbol-number="14" name="exp" usefulness="useful"/>
|
||||
<nonterminal symbol-number="15" name="@1" usefulness="useful"/>
|
||||
<nonterminal symbol-number="16" name="@2" usefulness="useful"/>
|
||||
<nonterminal symbol-number="9" name="$accept" type="" usefulness="useful"/>
|
||||
<nonterminal symbol-number="10" name="unit" type="" usefulness="useful"/>
|
||||
<nonterminal symbol-number="11" name="assignments" type="" usefulness="useful"/>
|
||||
<nonterminal symbol-number="12" name="assignment" type="" usefulness="useful"/>
|
||||
<nonterminal symbol-number="13" name="id" type="std::string" usefulness="useful"/>
|
||||
<nonterminal symbol-number="14" name="exp" type="int" usefulness="useful"/>
|
||||
<nonterminal symbol-number="15" name="@1" type="int" usefulness="useful"/>
|
||||
<nonterminal symbol-number="16" name="@2" type="int" usefulness="useful"/>
|
||||
</nonterminals>
|
||||
</grammar>
|
||||
|
||||
@@ -1137,6 +1137,373 @@ AT_CHECK([[sed -e 's/bison-xml-report version="[^"]*"/bison-xml-report version="
|
||||
</bison-xml-report>
|
||||
]])
|
||||
|
||||
# Check HTML output.
|
||||
if test x"$XSLTPROC" != x""; then
|
||||
AT_CHECK([[$XSLTPROC \
|
||||
`]]AT_SET_ENV[[ bison --print-datadir`/xslt/xml2xhtml.xsl \
|
||||
input.xml | \
|
||||
sed -e 's/GNU Bison [0-9][-.0-9a-z]*/GNU Bison VERSION/' \
|
||||
>input.html]])
|
||||
|
||||
AT_CHECK([cat input.html], [],
|
||||
[[<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:bison="http://www.gnu.org/software/bison/">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
|
||||
<title>input.yy - GNU Bison XML Automaton Report</title>
|
||||
<style type="text/css">
|
||||
body {
|
||||
font-family: "Nimbus Sans L", Arial, sans-serif;
|
||||
font-size: 9pt;
|
||||
}
|
||||
a:link {
|
||||
color: #1f00ff;
|
||||
text-decoration: none;
|
||||
}
|
||||
a:visited {
|
||||
color: #1f00ff;
|
||||
text-decoration: none;
|
||||
}
|
||||
a:hover {
|
||||
color: red;
|
||||
}
|
||||
#menu a {
|
||||
text-decoration: underline;
|
||||
}
|
||||
.i {
|
||||
font-style: italic;
|
||||
}
|
||||
.pre {
|
||||
font-family: monospace;
|
||||
white-space: pre;
|
||||
}
|
||||
ol.decimal {
|
||||
list-style-type: decimal;
|
||||
}
|
||||
ol.lower-alpha {
|
||||
list-style-type: lower-alpha;
|
||||
}
|
||||
.dot {
|
||||
color: #cc0000;
|
||||
}
|
||||
#footer {
|
||||
margin-top: 3.5em;
|
||||
font-size: 7pt;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body><h1>GNU Bison XML Automaton Report</h1><p>
|
||||
input grammar: <span class="i">input.yy</span></p>
|
||||
|
||||
<h3>Table of Contents</h3><ul id="menu"><li><a href="#reductions">Reductions</a><ul class="lower-alpha"><li><a href="#nonterminals_useless_in_grammar">Nonterminals useless in grammar</a></li><li><a href="#terminals_unused_in_grammar">Terminals unused in grammar</a></li><li><a href="#rules_useless_in_grammar">Rules useless in grammar</a></li></ul></li><li><a href="#conflicts">Conflicts</a></li><li><a href="#grammar">Grammar</a><ul class="lower-alpha"><li><a href="#grammar">Itemset</a></li><li><a href="#terminals">Terminal symbols</a></li><li><a href="#nonterminals">Nonterminal symbols</a></li></ul></li><li><a href="#automaton">Automaton</a></li></ul><h2><a name="reductions" id="reductions"></a> Reductions</h2><h3><a name="nonterminals_useless_in_grammar" id="nonterminals_useless_in_grammar"></a> Nonterminals useless in grammar</h3>
|
||||
|
||||
<h3><a name="terminals_unused_in_grammar" id="terminals_unused_in_grammar"></a> Terminals unused in grammar</h3>
|
||||
|
||||
<h3><a name="rules_useless_in_grammar" id="rules_useless_in_grammar"></a> Rules useless in grammar</h3>
|
||||
<h2><a name="conflicts" id="conflicts"></a> Conflicts</h2>
|
||||
|
||||
<h2><a name="grammar" id="grammar"></a> Grammar</h2>
|
||||
<p class="pre">
|
||||
<a name="rule_0" id="rule_0"> 0</a> <span class="i">$accept</span> → <span class="i">unit</span> <b>"end of file"</b>
|
||||
|
||||
<a name="rule_1" id="rule_1"> 1</a> <span class="i">unit</span> → <span class="i">assignments</span> <span class="i">exp</span>
|
||||
|
||||
<a name="rule_2" id="rule_2"> 2</a> <span class="i">assignments</span> → %empty
|
||||
<a name="rule_3" id="rule_3"> 3</a> | <span class="i">assignments</span> <span class="i">assignment</span>
|
||||
|
||||
<a name="rule_4" id="rule_4"> 4</a> <span class="i">assignment</span> → <span class="i">id</span> <b>":="</b> <span class="i">exp</span>
|
||||
|
||||
<a name="rule_5" id="rule_5"> 5</a> <span class="i">id</span> → <b>"identifier"</b>
|
||||
|
||||
<a name="rule_6" id="rule_6"> 6</a> <span class="i">@1</span> → %empty
|
||||
|
||||
<a name="rule_7" id="rule_7"> 7</a> <span class="i">@2</span> → %empty
|
||||
|
||||
<a name="rule_8" id="rule_8"> 8</a> <span class="i">exp</span> → <b>"incr"</b> <span class="i">exp</span> <span class="i">@1</span> <span class="i">@2</span> <span class="i">exp</span>
|
||||
<a name="rule_9" id="rule_9"> 9</a> | <b>"("</b> <span class="i">exp</span> <b>")"</b>
|
||||
<a name="rule_10" id="rule_10"> 10</a> | <b>"identifier"</b>
|
||||
<a name="rule_11" id="rule_11"> 11</a> | <b>"number"</b>
|
||||
</p>
|
||||
|
||||
<h3><a name="terminals" id="terminals"></a> Terminals, with rules where they appear</h3>
|
||||
|
||||
<ul>
|
||||
<li><b>"end of file"</b> (0) <a href="#rule_0">0</a></li>
|
||||
<li><b>error</b> (256)</li>
|
||||
<li><b>":="</b> (258) <a href="#rule_4">4</a></li>
|
||||
<li><b>"incr"</b> (259) <a href="#rule_8">8</a></li>
|
||||
<li><b>"identifier"</b> <std::string> (260) <a href="#rule_5">5</a> <a href="#rule_10">10</a></li>
|
||||
<li><b>"number"</b> <int> (261) <a href="#rule_11">11</a></li>
|
||||
<li><b>"("</b> (262) <a href="#rule_9">9</a></li>
|
||||
<li><b>")"</b> (263) <a href="#rule_9">9</a></li>
|
||||
</ul>
|
||||
|
||||
<h3><a name="nonterminals" id="nonterminals"></a> Nonterminals, with rules where they appear</h3>
|
||||
|
||||
<ul>
|
||||
<li><b>$accept</b> (9)
|
||||
<ul>
|
||||
<li>on left: <a href="#rule_0">0</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><b>unit</b> (10)
|
||||
<ul>
|
||||
<li>on left: <a href="#rule_1">1</a></li>
|
||||
<li>on right: <a href="#rule_0">0</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><b>assignments</b> (11)
|
||||
<ul>
|
||||
<li>on left: <a href="#rule_2">2</a> <a href="#rule_3">3</a></li>
|
||||
<li>on right: <a href="#rule_1">1</a> <a href="#rule_3">3</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><b>assignment</b> (12)
|
||||
<ul>
|
||||
<li>on left: <a href="#rule_4">4</a></li>
|
||||
<li>on right: <a href="#rule_3">3</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><b>id</b> <std::string> (13)
|
||||
<ul>
|
||||
<li>on left: <a href="#rule_5">5</a></li>
|
||||
<li>on right: <a href="#rule_4">4</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><b>exp</b> <int> (14)
|
||||
<ul>
|
||||
<li>on left: <a href="#rule_8">8</a> <a href="#rule_9">9</a> <a href="#rule_10">10</a> <a href="#rule_11">11</a></li>
|
||||
<li>on right: <a href="#rule_1">1</a> <a href="#rule_4">4</a> <a href="#rule_8">8</a> <a href="#rule_9">9</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><b>@1</b> <int> (15)
|
||||
<ul>
|
||||
<li>on left: <a href="#rule_6">6</a></li>
|
||||
<li>on right: <a href="#rule_8">8</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><b>@2</b> <int> (16)
|
||||
<ul>
|
||||
<li>on left: <a href="#rule_7">7</a></li>
|
||||
<li>on right: <a href="#rule_8">8</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul><h2><a name="automaton" id="automaton"></a> Automaton</h2>
|
||||
|
||||
<h3><a name="state_0" id="state_0"></a>State 0</h3>
|
||||
|
||||
<p class="pre"> <a href="#rule_0"> 0</a> <span class="i">$accept</span> → <span class="dot">•</span> <span class="i">unit</span> <b>"end of file"</b>
|
||||
<a href="#rule_1"> 1</a> <span class="i">unit</span> → <span class="dot">•</span> <span class="i">assignments</span> <span class="i">exp</span>
|
||||
<a href="#rule_2"> 2</a> <span class="i">assignments</span> → <span class="dot">•</span> %empty
|
||||
<a href="#rule_3"> 3</a> | <span class="dot">•</span> <span class="i">assignments</span> <span class="i">assignment</span>
|
||||
|
||||
$default <a href="#rule_2">reduce using rule 2</a> (assignments)
|
||||
|
||||
unit <a href="#state_1">go to state 1</a>
|
||||
assignments <a href="#state_2">go to state 2</a>
|
||||
</p>
|
||||
|
||||
<h3><a name="state_1" id="state_1"></a>State 1</h3>
|
||||
|
||||
<p class="pre"> <a href="#rule_0"> 0</a> <span class="i">$accept</span> → <span class="i">unit</span> <span class="dot">•</span> <b>"end of file"</b>
|
||||
|
||||
"end of file" <a href="#state_3">shift, and go to state 3</a>
|
||||
</p>
|
||||
|
||||
<h3><a name="state_2" id="state_2"></a>State 2</h3>
|
||||
|
||||
<p class="pre"> <a href="#rule_1"> 1</a> <span class="i">unit</span> → <span class="i">assignments</span> <span class="dot">•</span> <span class="i">exp</span>
|
||||
<a href="#rule_3"> 3</a> <span class="i">assignments</span> → <span class="i">assignments</span> <span class="dot">•</span> <span class="i">assignment</span>
|
||||
<a href="#rule_4"> 4</a> <span class="i">assignment</span> → <span class="dot">•</span> <span class="i">id</span> <b>":="</b> <span class="i">exp</span>
|
||||
<a href="#rule_5"> 5</a> <span class="i">id</span> → <span class="dot">•</span> <b>"identifier"</b>
|
||||
<a href="#rule_8"> 8</a> <span class="i">exp</span> → <span class="dot">•</span> <b>"incr"</b> <span class="i">exp</span> <span class="i">@1</span> <span class="i">@2</span> <span class="i">exp</span>
|
||||
<a href="#rule_9"> 9</a> | <span class="dot">•</span> <b>"("</b> <span class="i">exp</span> <b>")"</b>
|
||||
<a href="#rule_10"> 10</a> | <span class="dot">•</span> <b>"identifier"</b>
|
||||
<a href="#rule_11"> 11</a> | <span class="dot">•</span> <b>"number"</b>
|
||||
|
||||
"incr" <a href="#state_4">shift, and go to state 4</a>
|
||||
"identifier" <a href="#state_5">shift, and go to state 5</a>
|
||||
"number" <a href="#state_6">shift, and go to state 6</a>
|
||||
"(" <a href="#state_7">shift, and go to state 7</a>
|
||||
|
||||
assignment <a href="#state_8">go to state 8</a>
|
||||
id <a href="#state_9">go to state 9</a>
|
||||
exp <a href="#state_10">go to state 10</a>
|
||||
</p>
|
||||
|
||||
<h3><a name="state_3" id="state_3"></a>State 3</h3>
|
||||
|
||||
<p class="pre"> <a href="#rule_0"> 0</a> <span class="i">$accept</span> → <span class="i">unit</span> <b>"end of file"</b> <span class="dot">•</span>
|
||||
|
||||
$default accept
|
||||
</p>
|
||||
|
||||
<h3><a name="state_4" id="state_4"></a>State 4</h3>
|
||||
|
||||
<p class="pre"> <a href="#rule_8"> 8</a> <span class="i">exp</span> → <span class="dot">•</span> <b>"incr"</b> <span class="i">exp</span> <span class="i">@1</span> <span class="i">@2</span> <span class="i">exp</span>
|
||||
<a href="#rule_8"> 8</a> | <b>"incr"</b> <span class="dot">•</span> <span class="i">exp</span> <span class="i">@1</span> <span class="i">@2</span> <span class="i">exp</span>
|
||||
<a href="#rule_9"> 9</a> | <span class="dot">•</span> <b>"("</b> <span class="i">exp</span> <b>")"</b>
|
||||
<a href="#rule_10"> 10</a> | <span class="dot">•</span> <b>"identifier"</b>
|
||||
<a href="#rule_11"> 11</a> | <span class="dot">•</span> <b>"number"</b>
|
||||
|
||||
"incr" <a href="#state_4">shift, and go to state 4</a>
|
||||
"identifier" <a href="#state_11">shift, and go to state 11</a>
|
||||
"number" <a href="#state_6">shift, and go to state 6</a>
|
||||
"(" <a href="#state_7">shift, and go to state 7</a>
|
||||
|
||||
exp <a href="#state_12">go to state 12</a>
|
||||
</p>
|
||||
|
||||
<h3><a name="state_5" id="state_5"></a>State 5</h3>
|
||||
|
||||
<p class="pre"> <a href="#rule_5"> 5</a> <span class="i">id</span> → <b>"identifier"</b> <span class="dot">•</span> [":="]
|
||||
<a href="#rule_10"> 10</a> <span class="i">exp</span> → <b>"identifier"</b> <span class="dot">•</span> ["end of file"]
|
||||
|
||||
"end of file" <a href="#rule_10">reduce using rule 10</a> (exp)
|
||||
$default <a href="#rule_5">reduce using rule 5</a> (id)
|
||||
</p>
|
||||
|
||||
<h3><a name="state_6" id="state_6"></a>State 6</h3>
|
||||
|
||||
<p class="pre"> <a href="#rule_11"> 11</a> <span class="i">exp</span> → <b>"number"</b> <span class="dot">•</span>
|
||||
|
||||
$default <a href="#rule_11">reduce using rule 11</a> (exp)
|
||||
</p>
|
||||
|
||||
<h3><a name="state_7" id="state_7"></a>State 7</h3>
|
||||
|
||||
<p class="pre"> <a href="#rule_8"> 8</a> <span class="i">exp</span> → <span class="dot">•</span> <b>"incr"</b> <span class="i">exp</span> <span class="i">@1</span> <span class="i">@2</span> <span class="i">exp</span>
|
||||
<a href="#rule_9"> 9</a> | <span class="dot">•</span> <b>"("</b> <span class="i">exp</span> <b>")"</b>
|
||||
<a href="#rule_9"> 9</a> | <b>"("</b> <span class="dot">•</span> <span class="i">exp</span> <b>")"</b>
|
||||
<a href="#rule_10"> 10</a> | <span class="dot">•</span> <b>"identifier"</b>
|
||||
<a href="#rule_11"> 11</a> | <span class="dot">•</span> <b>"number"</b>
|
||||
|
||||
"incr" <a href="#state_4">shift, and go to state 4</a>
|
||||
"identifier" <a href="#state_11">shift, and go to state 11</a>
|
||||
"number" <a href="#state_6">shift, and go to state 6</a>
|
||||
"(" <a href="#state_7">shift, and go to state 7</a>
|
||||
|
||||
exp <a href="#state_13">go to state 13</a>
|
||||
</p>
|
||||
|
||||
<h3><a name="state_8" id="state_8"></a>State 8</h3>
|
||||
|
||||
<p class="pre"> <a href="#rule_3"> 3</a> <span class="i">assignments</span> → <span class="i">assignments</span> <span class="i">assignment</span> <span class="dot">•</span>
|
||||
|
||||
$default <a href="#rule_3">reduce using rule 3</a> (assignments)
|
||||
</p>
|
||||
|
||||
<h3><a name="state_9" id="state_9"></a>State 9</h3>
|
||||
|
||||
<p class="pre"> <a href="#rule_4"> 4</a> <span class="i">assignment</span> → <span class="i">id</span> <span class="dot">•</span> <b>":="</b> <span class="i">exp</span>
|
||||
|
||||
":=" <a href="#state_14">shift, and go to state 14</a>
|
||||
</p>
|
||||
|
||||
<h3><a name="state_10" id="state_10"></a>State 10</h3>
|
||||
|
||||
<p class="pre"> <a href="#rule_1"> 1</a> <span class="i">unit</span> → <span class="i">assignments</span> <span class="i">exp</span> <span class="dot">•</span>
|
||||
|
||||
$default <a href="#rule_1">reduce using rule 1</a> (unit)
|
||||
</p>
|
||||
|
||||
<h3><a name="state_11" id="state_11"></a>State 11</h3>
|
||||
|
||||
<p class="pre"> <a href="#rule_10"> 10</a> <span class="i">exp</span> → <b>"identifier"</b> <span class="dot">•</span>
|
||||
|
||||
$default <a href="#rule_10">reduce using rule 10</a> (exp)
|
||||
</p>
|
||||
|
||||
<h3><a name="state_12" id="state_12"></a>State 12</h3>
|
||||
|
||||
<p class="pre"> <a href="#rule_6"> 6</a> <span class="i">@1</span> → <span class="dot">•</span> %empty
|
||||
<a href="#rule_8"> 8</a> <span class="i">exp</span> → <b>"incr"</b> <span class="i">exp</span> <span class="dot">•</span> <span class="i">@1</span> <span class="i">@2</span> <span class="i">exp</span>
|
||||
|
||||
$default <a href="#rule_6">reduce using rule 6</a> (@1)
|
||||
|
||||
@1 <a href="#state_15">go to state 15</a>
|
||||
</p>
|
||||
|
||||
<h3><a name="state_13" id="state_13"></a>State 13</h3>
|
||||
|
||||
<p class="pre"> <a href="#rule_9"> 9</a> <span class="i">exp</span> → <b>"("</b> <span class="i">exp</span> <span class="dot">•</span> <b>")"</b>
|
||||
|
||||
")" <a href="#state_16">shift, and go to state 16</a>
|
||||
</p>
|
||||
|
||||
<h3><a name="state_14" id="state_14"></a>State 14</h3>
|
||||
|
||||
<p class="pre"> <a href="#rule_4"> 4</a> <span class="i">assignment</span> → <span class="i">id</span> <b>":="</b> <span class="dot">•</span> <span class="i">exp</span>
|
||||
<a href="#rule_8"> 8</a> <span class="i">exp</span> → <span class="dot">•</span> <b>"incr"</b> <span class="i">exp</span> <span class="i">@1</span> <span class="i">@2</span> <span class="i">exp</span>
|
||||
<a href="#rule_9"> 9</a> | <span class="dot">•</span> <b>"("</b> <span class="i">exp</span> <b>")"</b>
|
||||
<a href="#rule_10"> 10</a> | <span class="dot">•</span> <b>"identifier"</b>
|
||||
<a href="#rule_11"> 11</a> | <span class="dot">•</span> <b>"number"</b>
|
||||
|
||||
"incr" <a href="#state_4">shift, and go to state 4</a>
|
||||
"identifier" <a href="#state_11">shift, and go to state 11</a>
|
||||
"number" <a href="#state_6">shift, and go to state 6</a>
|
||||
"(" <a href="#state_7">shift, and go to state 7</a>
|
||||
|
||||
exp <a href="#state_17">go to state 17</a>
|
||||
</p>
|
||||
|
||||
<h3><a name="state_15" id="state_15"></a>State 15</h3>
|
||||
|
||||
<p class="pre"> <a href="#rule_7"> 7</a> <span class="i">@2</span> → <span class="dot">•</span> %empty
|
||||
<a href="#rule_8"> 8</a> <span class="i">exp</span> → <b>"incr"</b> <span class="i">exp</span> <span class="i">@1</span> <span class="dot">•</span> <span class="i">@2</span> <span class="i">exp</span>
|
||||
|
||||
$default <a href="#rule_7">reduce using rule 7</a> (@2)
|
||||
|
||||
@2 <a href="#state_18">go to state 18</a>
|
||||
</p>
|
||||
|
||||
<h3><a name="state_16" id="state_16"></a>State 16</h3>
|
||||
|
||||
<p class="pre"> <a href="#rule_9"> 9</a> <span class="i">exp</span> → <b>"("</b> <span class="i">exp</span> <b>")"</b> <span class="dot">•</span>
|
||||
|
||||
$default <a href="#rule_9">reduce using rule 9</a> (exp)
|
||||
</p>
|
||||
|
||||
<h3><a name="state_17" id="state_17"></a>State 17</h3>
|
||||
|
||||
<p class="pre"> <a href="#rule_4"> 4</a> <span class="i">assignment</span> → <span class="i">id</span> <b>":="</b> <span class="i">exp</span> <span class="dot">•</span>
|
||||
|
||||
$default <a href="#rule_4">reduce using rule 4</a> (assignment)
|
||||
</p>
|
||||
|
||||
<h3><a name="state_18" id="state_18"></a>State 18</h3>
|
||||
|
||||
<p class="pre"> <a href="#rule_8"> 8</a> <span class="i">exp</span> → <span class="dot">•</span> <b>"incr"</b> <span class="i">exp</span> <span class="i">@1</span> <span class="i">@2</span> <span class="i">exp</span>
|
||||
<a href="#rule_8"> 8</a> | <b>"incr"</b> <span class="i">exp</span> <span class="i">@1</span> <span class="i">@2</span> <span class="dot">•</span> <span class="i">exp</span>
|
||||
<a href="#rule_9"> 9</a> | <span class="dot">•</span> <b>"("</b> <span class="i">exp</span> <b>")"</b>
|
||||
<a href="#rule_10"> 10</a> | <span class="dot">•</span> <b>"identifier"</b>
|
||||
<a href="#rule_11"> 11</a> | <span class="dot">•</span> <b>"number"</b>
|
||||
|
||||
"incr" <a href="#state_4">shift, and go to state 4</a>
|
||||
"identifier" <a href="#state_11">shift, and go to state 11</a>
|
||||
"number" <a href="#state_6">shift, and go to state 6</a>
|
||||
"(" <a href="#state_7">shift, and go to state 7</a>
|
||||
|
||||
exp <a href="#state_19">go to state 19</a>
|
||||
</p>
|
||||
|
||||
<h3><a name="state_19" id="state_19"></a>State 19</h3>
|
||||
|
||||
<p class="pre"> <a href="#rule_8"> 8</a> <span class="i">exp</span> → <b>"incr"</b> <span class="i">exp</span> <span class="i">@1</span> <span class="i">@2</span> <span class="i">exp</span> <span class="dot">•</span>
|
||||
|
||||
$default <a href="#rule_8">reduce using rule 8</a> (exp)
|
||||
</p>
|
||||
|
||||
<div id="footer"><hr />This document was generated using
|
||||
<a href="http://www.gnu.org/software/bison/" title="GNU Bison">
|
||||
GNU Bison VERSION</a>
|
||||
XML Automaton Report.<br />
|
||||
Verbatim copying and distribution of this entire page is
|
||||
permitted in any medium, provided this notice is preserved.</div></body>
|
||||
</html>
|
||||
]])
|
||||
fi
|
||||
|
||||
AT_BISON_OPTION_POPDEFS
|
||||
AT_CLEANUP
|
||||
@@ -1170,41 +1537,70 @@ exp
|
||||
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 reduce/reduce conflicts [-Wconflicts-rr]
|
||||
Shift/reduce conflict on token "⊕":
|
||||
Example exp "+" exp • "⊕" exp
|
||||
First derivation exp ::=[ exp ::=[ exp "+" exp • ] "⊕" exp ]
|
||||
Second derivation exp ::=[ exp "+" exp ::=[ exp • "⊕" exp ] ]
|
||||
|
||||
Reduce/reduce conflict on tokens $end, "+", "⊕":
|
||||
Example exp "+" exp •
|
||||
First derivation exp ::=[ exp "+" exp • ]
|
||||
Second derivation exp ::=[ exp "+" exp • ]
|
||||
|
||||
Shift/reduce conflict on token "⊕":
|
||||
Example exp "+" exp • "⊕" exp
|
||||
First derivation exp ::=[ exp ::=[ exp "+" exp • ] "⊕" exp ]
|
||||
Second derivation exp ::=[ exp "+" exp ::=[ exp • "⊕" exp ] ]
|
||||
|
||||
Shift/reduce conflict on token "⊕":
|
||||
Example exp "⊕" exp • "⊕" exp
|
||||
First derivation exp ::=[ exp ::=[ exp "⊕" exp • ] "⊕" exp ]
|
||||
Second derivation exp ::=[ exp "⊕" exp ::=[ exp • "⊕" exp ] ]
|
||||
|
||||
Shift/reduce conflict on token "+":
|
||||
Example exp "⊕" exp • "+" exp
|
||||
First derivation exp ::=[ exp ::=[ exp "⊕" exp • ] "+" exp ]
|
||||
Second derivation exp ::=[ exp "⊕" exp ::=[ exp • "+" exp ] ]
|
||||
|
||||
Shift/reduce conflict on token "+":
|
||||
Example exp "⊕" exp • "+" exp
|
||||
First derivation exp ::=[ exp ::=[ exp "⊕" exp • ] "+" exp ]
|
||||
Second derivation exp ::=[ exp "⊕" exp ::=[ exp • "+" exp ] ]
|
||||
|
||||
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: reduce/reduce conflict on tokens $end, "+", "⊕" [-Wcounterexamples]
|
||||
Example: exp "+" exp •
|
||||
First reduce derivation
|
||||
exp
|
||||
↳ exp "+" exp •
|
||||
Second reduce derivation
|
||||
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: 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]
|
||||
]])
|
||||
|
||||
# Check the contents of the report.
|
||||
AT_CHECK([cat input.output], [],
|
||||
# FIXME: Avoid trailing white spaces.
|
||||
AT_CHECK([sed -e 's/ *$//' input.output], [],
|
||||
[[Rules useless in parser due to conflicts
|
||||
|
||||
3 exp: exp "+" exp
|
||||
@@ -1343,26 +1739,42 @@ State 7
|
||||
|
||||
Conflict between rule 2 and token "+" resolved as reduce (%left "+").
|
||||
|
||||
Shift/reduce conflict on token "⊕":
|
||||
shift/reduce conflict on token "⊕":
|
||||
2 exp: exp "+" exp •
|
||||
1 exp: exp • "⊕" exp
|
||||
Example exp "+" exp • "⊕" exp
|
||||
First derivation exp ::=[ exp ::=[ exp "+" exp • ] "⊕" exp ]
|
||||
Second derivation exp ::=[ exp "+" exp ::=[ exp • "⊕" exp ] ]
|
||||
Example: exp "+" exp • "⊕" exp
|
||||
Shift derivation
|
||||
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 •
|
||||
3 exp: exp "+" exp •
|
||||
Example exp "+" exp •
|
||||
First derivation exp ::=[ exp "+" exp • ]
|
||||
Second derivation exp ::=[ exp "+" exp • ]
|
||||
Example: exp "+" exp •
|
||||
First reduce derivation
|
||||
exp
|
||||
↳ exp "+" exp •
|
||||
Second reduce derivation
|
||||
exp
|
||||
↳ exp "+" exp •
|
||||
|
||||
Shift/reduce conflict on token "⊕":
|
||||
shift/reduce conflict on token "⊕":
|
||||
3 exp: exp "+" exp •
|
||||
1 exp: exp • "⊕" exp
|
||||
Example exp "+" exp • "⊕" exp
|
||||
First derivation exp ::=[ exp ::=[ exp "+" exp • ] "⊕" exp ]
|
||||
Second derivation exp ::=[ exp "+" exp ::=[ exp • "⊕" exp ] ]
|
||||
Example: exp "+" exp • "⊕" exp
|
||||
Shift derivation
|
||||
exp
|
||||
↳ exp "+" exp
|
||||
↳ exp • "⊕" exp
|
||||
Reduce derivation
|
||||
exp
|
||||
↳ exp "⊕" exp
|
||||
↳ exp "+" exp •
|
||||
|
||||
|
||||
|
||||
@@ -1380,26 +1792,44 @@ State 8
|
||||
"⊕" [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
|
||||
Example exp "⊕" exp • "⊕" exp
|
||||
First derivation exp ::=[ exp ::=[ exp "⊕" exp • ] "⊕" exp ]
|
||||
Second derivation exp ::=[ exp "⊕" exp ::=[ exp • "⊕" exp ] ]
|
||||
Example: exp "⊕" exp • "⊕" exp
|
||||
Shift derivation
|
||||
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 •
|
||||
2 exp: exp • "+" exp
|
||||
Example exp "⊕" exp • "+" exp
|
||||
First derivation exp ::=[ exp ::=[ exp "⊕" exp • ] "+" exp ]
|
||||
Second derivation exp ::=[ exp "⊕" exp ::=[ exp • "+" exp ] ]
|
||||
Example: exp "⊕" exp • "+" exp
|
||||
Shift derivation
|
||||
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 •
|
||||
3 exp: exp • "+" exp
|
||||
Example exp "⊕" exp • "+" exp
|
||||
First derivation exp ::=[ exp ::=[ exp "⊕" exp • ] "+" exp ]
|
||||
Second derivation exp ::=[ exp "⊕" exp ::=[ exp • "+" exp ] ]
|
||||
Example: exp "⊕" exp • "+" exp
|
||||
Shift derivation
|
||||
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>
|
||||
</rules>
|
||||
<terminals>
|
||||
<terminal symbol-number="0" token-number="0" name="$end" usefulness="useful"/>
|
||||
<terminal symbol-number="1" token-number="256" name="error" usefulness="useful"/>
|
||||
<terminal symbol-number="3" token-number="258" name=""+"" usefulness="useful" prec="1" assoc="left"/>
|
||||
<terminal symbol-number="4" token-number="259" name=""⊕"" usefulness="useful"/>
|
||||
<terminal symbol-number="5" token-number="260" name=""number"" usefulness="useful"/>
|
||||
<terminal symbol-number="6" token-number="261" name=""Ñùṃéℝô"" usefulness="useful"/>
|
||||
<terminal symbol-number="0" token-number="0" name="$end" type="" usefulness="useful"/>
|
||||
<terminal symbol-number="1" token-number="256" name="error" type="" usefulness="useful"/>
|
||||
<terminal symbol-number="3" token-number="258" name=""+"" type="" usefulness="useful" prec="1" assoc="left"/>
|
||||
<terminal symbol-number="4" token-number="259" name=""⊕"" type="" usefulness="useful"/>
|
||||
<terminal symbol-number="5" token-number="260" name=""number"" type="" usefulness="useful"/>
|
||||
<terminal symbol-number="6" token-number="261" name=""Ñùṃéℝô"" type="" usefulness="useful"/>
|
||||
</terminals>
|
||||
<nonterminals>
|
||||
<nonterminal symbol-number="7" name="$accept" usefulness="useful"/>
|
||||
<nonterminal symbol-number="8" name="exp" usefulness="useful"/>
|
||||
<nonterminal symbol-number="7" name="$accept" type="" usefulness="useful"/>
|
||||
<nonterminal symbol-number="8" name="exp" type="" usefulness="useful"/>
|
||||
</nonterminals>
|
||||
</grammar>
|
||||
|
||||
@@ -1725,6 +2155,243 @@ AT_CHECK([[sed -e 's/bison-xml-report version="[^"]*"/bison-xml-report version="
|
||||
</bison-xml-report>
|
||||
]])
|
||||
|
||||
# Check HTML output.
|
||||
if test x"$XSLTPROC" != x""; then
|
||||
AT_CHECK([[$XSLTPROC \
|
||||
`]]AT_SET_ENV[[ bison --print-datadir`/xslt/xml2xhtml.xsl \
|
||||
input.xml | \
|
||||
sed -e 's/GNU Bison [0-9][-.0-9a-z]*/GNU Bison VERSION/' \
|
||||
>input.html]])
|
||||
|
||||
AT_CHECK([cat input.html], [],
|
||||
[[<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:bison="http://www.gnu.org/software/bison/">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
|
||||
<title>input.y - GNU Bison XML Automaton Report</title>
|
||||
<style type="text/css">
|
||||
body {
|
||||
font-family: "Nimbus Sans L", Arial, sans-serif;
|
||||
font-size: 9pt;
|
||||
}
|
||||
a:link {
|
||||
color: #1f00ff;
|
||||
text-decoration: none;
|
||||
}
|
||||
a:visited {
|
||||
color: #1f00ff;
|
||||
text-decoration: none;
|
||||
}
|
||||
a:hover {
|
||||
color: red;
|
||||
}
|
||||
#menu a {
|
||||
text-decoration: underline;
|
||||
}
|
||||
.i {
|
||||
font-style: italic;
|
||||
}
|
||||
.pre {
|
||||
font-family: monospace;
|
||||
white-space: pre;
|
||||
}
|
||||
ol.decimal {
|
||||
list-style-type: decimal;
|
||||
}
|
||||
ol.lower-alpha {
|
||||
list-style-type: lower-alpha;
|
||||
}
|
||||
.dot {
|
||||
color: #cc0000;
|
||||
}
|
||||
#footer {
|
||||
margin-top: 3.5em;
|
||||
font-size: 7pt;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body><h1>GNU Bison XML Automaton Report</h1><p>
|
||||
input grammar: <span class="i">input.y</span></p>
|
||||
|
||||
<h3>Table of Contents</h3><ul id="menu"><li><a href="#reductions">Reductions</a><ul class="lower-alpha"><li><a href="#nonterminals_useless_in_grammar">Nonterminals useless in grammar</a></li><li><a href="#terminals_unused_in_grammar">Terminals unused in grammar</a></li><li><a href="#rules_useless_in_grammar">Rules useless in grammar</a></li><li><a href="#rules_useless_in_parser">Rules useless in parser due to conflicts</a></li></ul></li><li><a href="#conflicts">Conflicts</a></li><li><a href="#grammar">Grammar</a><ul class="lower-alpha"><li><a href="#grammar">Itemset</a></li><li><a href="#terminals">Terminal symbols</a></li><li><a href="#nonterminals">Nonterminal symbols</a></li></ul></li><li><a href="#automaton">Automaton</a></li></ul><h2><a name="reductions" id="reductions"></a> Reductions</h2><h3><a name="nonterminals_useless_in_grammar" id="nonterminals_useless_in_grammar"></a> Nonterminals useless in grammar</h3>
|
||||
|
||||
<h3><a name="terminals_unused_in_grammar" id="terminals_unused_in_grammar"></a> Terminals unused in grammar</h3>
|
||||
|
||||
<h3><a name="rules_useless_in_grammar" id="rules_useless_in_grammar"></a> Rules useless in grammar</h3>
|
||||
<h2><a name="rules_useless_in_parser" id="rules_useless_in_parser"></a> Rules useless in parser due to conflicts</h2>
|
||||
<p class="pre">
|
||||
<a href="#rule_3"> 3</a> <span class="i">exp</span> → <span class="i">exp</span> <b>"+"</b> <span class="i">exp</span>
|
||||
</p>
|
||||
|
||||
<h2><a name="conflicts" id="conflicts"></a> Conflicts</h2>
|
||||
|
||||
<p class="pre"><a href="#state_7">State 7</a> conflicts: 1 shift/reduce, 3 reduce/reduce
|
||||
<a href="#state_8">State 8</a> conflicts: 2 shift/reduce
|
||||
|
||||
|
||||
</p><h2><a name="grammar" id="grammar"></a> Grammar</h2>
|
||||
<p class="pre">
|
||||
<a name="rule_0" id="rule_0"> 0</a> <span class="i">$accept</span> → <span class="i">exp</span> <b>$end</b>
|
||||
|
||||
<a name="rule_1" id="rule_1"> 1</a> <span class="i">exp</span> → <span class="i">exp</span> <b>"⊕"</b> <span class="i">exp</span>
|
||||
<a name="rule_2" id="rule_2"> 2</a> | <span class="i">exp</span> <b>"+"</b> <span class="i">exp</span>
|
||||
<a name="rule_3" id="rule_3"> 3</a> | <span class="i">exp</span> <b>"+"</b> <span class="i">exp</span>
|
||||
<a name="rule_4" id="rule_4"> 4</a> | <b>"number"</b>
|
||||
<a name="rule_5" id="rule_5"> 5</a> | <b>"Ñùṃéℝô"</b>
|
||||
</p>
|
||||
|
||||
<h3><a name="terminals" id="terminals"></a> Terminals, with rules where they appear</h3>
|
||||
|
||||
<ul>
|
||||
<li><b>$end</b> (0) <a href="#rule_0">0</a></li>
|
||||
<li><b>error</b> (256)</li>
|
||||
<li><b>"+"</b> (258) <a href="#rule_2">2</a> <a href="#rule_3">3</a></li>
|
||||
<li><b>"⊕"</b> (259) <a href="#rule_1">1</a></li>
|
||||
<li><b>"number"</b> (260) <a href="#rule_4">4</a></li>
|
||||
<li><b>"Ñùṃéℝô"</b> (261) <a href="#rule_5">5</a></li>
|
||||
</ul>
|
||||
|
||||
<h3><a name="nonterminals" id="nonterminals"></a> Nonterminals, with rules where they appear</h3>
|
||||
|
||||
<ul>
|
||||
<li><b>$accept</b> (7)
|
||||
<ul>
|
||||
<li>on left: <a href="#rule_0">0</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><b>exp</b> (8)
|
||||
<ul>
|
||||
<li>on left: <a href="#rule_1">1</a> <a href="#rule_2">2</a> <a href="#rule_3">3</a> <a href="#rule_4">4</a> <a href="#rule_5">5</a></li>
|
||||
<li>on right: <a href="#rule_0">0</a> <a href="#rule_1">1</a> <a href="#rule_2">2</a> <a href="#rule_3">3</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul><h2><a name="automaton" id="automaton"></a> Automaton</h2>
|
||||
|
||||
<h3><a name="state_0" id="state_0"></a>State 0</h3>
|
||||
|
||||
<p class="pre"> <a href="#rule_0"> 0</a> <span class="i">$accept</span> → <span class="dot">•</span> <span class="i">exp</span> <b>$end</b>
|
||||
<a href="#rule_1"> 1</a> <span class="i">exp</span> → <span class="dot">•</span> <span class="i">exp</span> <b>"⊕"</b> <span class="i">exp</span>
|
||||
<a href="#rule_2"> 2</a> | <span class="dot">•</span> <span class="i">exp</span> <b>"+"</b> <span class="i">exp</span>
|
||||
<a href="#rule_3"> 3</a> | <span class="dot">•</span> <span class="i">exp</span> <b>"+"</b> <span class="i">exp</span>
|
||||
<a href="#rule_4"> 4</a> | <span class="dot">•</span> <b>"number"</b>
|
||||
<a href="#rule_5"> 5</a> | <span class="dot">•</span> <b>"Ñùṃéℝô"</b>
|
||||
|
||||
"number" <a href="#state_1">shift, and go to state 1</a>
|
||||
"Ñùṃéℝô" <a href="#state_2">shift, and go to state 2</a>
|
||||
|
||||
exp <a href="#state_3">go to state 3</a>
|
||||
</p>
|
||||
|
||||
<h3><a name="state_1" id="state_1"></a>State 1</h3>
|
||||
|
||||
<p class="pre"> <a href="#rule_4"> 4</a> <span class="i">exp</span> → <b>"number"</b> <span class="dot">•</span>
|
||||
|
||||
$default <a href="#rule_4">reduce using rule 4</a> (exp)
|
||||
</p>
|
||||
|
||||
<h3><a name="state_2" id="state_2"></a>State 2</h3>
|
||||
|
||||
<p class="pre"> <a href="#rule_5"> 5</a> <span class="i">exp</span> → <b>"Ñùṃéℝô"</b> <span class="dot">•</span>
|
||||
|
||||
$default <a href="#rule_5">reduce using rule 5</a> (exp)
|
||||
</p>
|
||||
|
||||
<h3><a name="state_3" id="state_3"></a>State 3</h3>
|
||||
|
||||
<p class="pre"> <a href="#rule_0"> 0</a> <span class="i">$accept</span> → <span class="i">exp</span> <span class="dot">•</span> <b>$end</b>
|
||||
<a href="#rule_1"> 1</a> <span class="i">exp</span> → <span class="i">exp</span> <span class="dot">•</span> <b>"⊕"</b> <span class="i">exp</span>
|
||||
<a href="#rule_2"> 2</a> | <span class="i">exp</span> <span class="dot">•</span> <b>"+"</b> <span class="i">exp</span>
|
||||
<a href="#rule_3"> 3</a> | <span class="i">exp</span> <span class="dot">•</span> <b>"+"</b> <span class="i">exp</span>
|
||||
|
||||
$end <a href="#state_4">shift, and go to state 4</a>
|
||||
"+" <a href="#state_5">shift, and go to state 5</a>
|
||||
"⊕" <a href="#state_6">shift, and go to state 6</a>
|
||||
</p>
|
||||
|
||||
<h3><a name="state_4" id="state_4"></a>State 4</h3>
|
||||
|
||||
<p class="pre"> <a href="#rule_0"> 0</a> <span class="i">$accept</span> → <span class="i">exp</span> <b>$end</b> <span class="dot">•</span>
|
||||
|
||||
$default accept
|
||||
</p>
|
||||
|
||||
<h3><a name="state_5" id="state_5"></a>State 5</h3>
|
||||
|
||||
<p class="pre"> <a href="#rule_1"> 1</a> <span class="i">exp</span> → <span class="dot">•</span> <span class="i">exp</span> <b>"⊕"</b> <span class="i">exp</span>
|
||||
<a href="#rule_2"> 2</a> | <span class="dot">•</span> <span class="i">exp</span> <b>"+"</b> <span class="i">exp</span>
|
||||
<a href="#rule_2"> 2</a> | <span class="i">exp</span> <b>"+"</b> <span class="dot">•</span> <span class="i">exp</span>
|
||||
<a href="#rule_3"> 3</a> | <span class="dot">•</span> <span class="i">exp</span> <b>"+"</b> <span class="i">exp</span>
|
||||
<a href="#rule_3"> 3</a> | <span class="i">exp</span> <b>"+"</b> <span class="dot">•</span> <span class="i">exp</span>
|
||||
<a href="#rule_4"> 4</a> | <span class="dot">•</span> <b>"number"</b>
|
||||
<a href="#rule_5"> 5</a> | <span class="dot">•</span> <b>"Ñùṃéℝô"</b>
|
||||
|
||||
"number" <a href="#state_1">shift, and go to state 1</a>
|
||||
"Ñùṃéℝô" <a href="#state_2">shift, and go to state 2</a>
|
||||
|
||||
exp <a href="#state_7">go to state 7</a>
|
||||
</p>
|
||||
|
||||
<h3><a name="state_6" id="state_6"></a>State 6</h3>
|
||||
|
||||
<p class="pre"> <a href="#rule_1"> 1</a> <span class="i">exp</span> → <span class="dot">•</span> <span class="i">exp</span> <b>"⊕"</b> <span class="i">exp</span>
|
||||
<a href="#rule_1"> 1</a> | <span class="i">exp</span> <b>"⊕"</b> <span class="dot">•</span> <span class="i">exp</span>
|
||||
<a href="#rule_2"> 2</a> | <span class="dot">•</span> <span class="i">exp</span> <b>"+"</b> <span class="i">exp</span>
|
||||
<a href="#rule_3"> 3</a> | <span class="dot">•</span> <span class="i">exp</span> <b>"+"</b> <span class="i">exp</span>
|
||||
<a href="#rule_4"> 4</a> | <span class="dot">•</span> <b>"number"</b>
|
||||
<a href="#rule_5"> 5</a> | <span class="dot">•</span> <b>"Ñùṃéℝô"</b>
|
||||
|
||||
"number" <a href="#state_1">shift, and go to state 1</a>
|
||||
"Ñùṃéℝô" <a href="#state_2">shift, and go to state 2</a>
|
||||
|
||||
exp <a href="#state_8">go to state 8</a>
|
||||
</p>
|
||||
|
||||
<h3><a name="state_7" id="state_7"></a>State 7</h3>
|
||||
|
||||
<p class="pre"> <a href="#rule_1"> 1</a> <span class="i">exp</span> → <span class="i">exp</span> <span class="dot">•</span> <b>"⊕"</b> <span class="i">exp</span>
|
||||
<a href="#rule_2"> 2</a> | <span class="i">exp</span> <span class="dot">•</span> <b>"+"</b> <span class="i">exp</span>
|
||||
<a href="#rule_2"> 2</a> | <span class="i">exp</span> <b>"+"</b> <span class="i">exp</span> <span class="dot">•</span> [$end, "+", "⊕"]
|
||||
<a href="#rule_3"> 3</a> | <span class="i">exp</span> <span class="dot">•</span> <b>"+"</b> <span class="i">exp</span>
|
||||
<a href="#rule_3"> 3</a> | <span class="i">exp</span> <b>"+"</b> <span class="i">exp</span> <span class="dot">•</span> [$end, "+", "⊕"]
|
||||
|
||||
"⊕" <a href="#state_6">shift, and go to state 6</a>
|
||||
|
||||
$end <a href="#rule_2">reduce using rule 2</a> (exp)
|
||||
$end [<a href="#rule_3">reduce using rule 3</a> (exp)]
|
||||
"+" <a href="#rule_2">reduce using rule 2</a> (exp)
|
||||
"+" [<a href="#rule_3">reduce using rule 3</a> (exp)]
|
||||
"⊕" [<a href="#rule_2">reduce using rule 2</a> (exp)]
|
||||
"⊕" [<a href="#rule_3">reduce using rule 3</a> (exp)]
|
||||
$default <a href="#rule_2">reduce using rule 2</a> (exp)
|
||||
|
||||
Conflict between <a href="#rule_2">rule 2</a> and token "+" resolved as reduce (%left "+").
|
||||
</p>
|
||||
|
||||
<h3><a name="state_8" id="state_8"></a>State 8</h3>
|
||||
|
||||
<p class="pre"> <a href="#rule_1"> 1</a> <span class="i">exp</span> → <span class="i">exp</span> <span class="dot">•</span> <b>"⊕"</b> <span class="i">exp</span>
|
||||
<a href="#rule_1"> 1</a> | <span class="i">exp</span> <b>"⊕"</b> <span class="i">exp</span> <span class="dot">•</span> [$end, "+", "⊕"]
|
||||
<a href="#rule_2"> 2</a> | <span class="i">exp</span> <span class="dot">•</span> <b>"+"</b> <span class="i">exp</span>
|
||||
<a href="#rule_3"> 3</a> | <span class="i">exp</span> <span class="dot">•</span> <b>"+"</b> <span class="i">exp</span>
|
||||
|
||||
"+" <a href="#state_5">shift, and go to state 5</a>
|
||||
"⊕" <a href="#state_6">shift, and go to state 6</a>
|
||||
|
||||
"+" [<a href="#rule_1">reduce using rule 1</a> (exp)]
|
||||
"⊕" [<a href="#rule_1">reduce using rule 1</a> (exp)]
|
||||
$default <a href="#rule_1">reduce using rule 1</a> (exp)
|
||||
</p>
|
||||
|
||||
<div id="footer"><hr />This document was generated using
|
||||
<a href="http://www.gnu.org/software/bison/" title="GNU Bison">
|
||||
GNU Bison VERSION</a>
|
||||
XML Automaton Report.<br />
|
||||
Verbatim copying and distribution of this entire page is
|
||||
permitted in any medium, provided this notice is preserved.</div></body>
|
||||
</html>
|
||||
]])
|
||||
fi
|
||||
|
||||
AT_BISON_OPTION_POPDEFS
|
||||
AT_CLEANUP
|
||||
|
||||
+1
-1
@@ -285,7 +285,7 @@ term: 'n'
|
||||
|
||||
AT_BISON_CHECK([[-fcaret input.y]], [], [],
|
||||
[[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]
|
||||
2 | expr: term | term | term | term | term | term
|
||||
| ^~~~
|
||||
|
||||
+4
-4
@@ -283,11 +283,11 @@ m4_popdef([AT_TEST])
|
||||
## Many lookahead tokens. ##
|
||||
## ------------------------ ##
|
||||
|
||||
# AT_DATA_LOOKAHEAD_TOKENS_GRAMMAR(FILE-NAME, SIZE)
|
||||
# --------------------------------------------------
|
||||
# AT_DATA_LOOKAHEADS_GRAMMAR(FILE-NAME, SIZE)
|
||||
# -------------------------------------------
|
||||
# Create FILE-NAME, containing a self checking parser for a grammar
|
||||
# requiring SIZE lookahead tokens.
|
||||
m4_define([AT_DATA_LOOKAHEAD_TOKENS_GRAMMAR],
|
||||
m4_define([AT_DATA_LOOKAHEADS_GRAMMAR],
|
||||
[AT_BISON_OPTION_PUSHDEFS
|
||||
AT_DATA([[gengram.pl]],
|
||||
[[#! /usr/bin/perl -w
|
||||
@@ -384,7 +384,7 @@ AT_BISON_OPTION_POPDEFS
|
||||
|
||||
AT_SETUP([Many lookahead tokens])
|
||||
|
||||
AT_DATA_LOOKAHEAD_TOKENS_GRAMMAR([input.y], [1000])
|
||||
AT_DATA_LOOKAHEADS_GRAMMAR([input.y], [1000])
|
||||
|
||||
# GNU m4 requires about 70 MiB for this test on a 32-bit host.
|
||||
# Ask for 200 MiB, which should be plenty even on a 64-bit host.
|
||||
|
||||
Reference in New Issue
Block a user