mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-08-08 18:25:13 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5d501ee728 | ||
|
|
bc5e4541da | ||
|
|
567d1eaa19 | ||
|
|
c08e0863be | ||
|
|
541943ee04 | ||
|
|
dcdd119f69 | ||
|
|
a0bc06b703 | ||
|
|
5e33dfe59d | ||
|
|
2a4e9a358f | ||
|
|
f7b642cff7 | ||
|
|
3da17724ad | ||
|
|
68e3e442f9 | ||
|
|
e432619d11 | ||
|
|
a1b7fef045 | ||
|
|
067e35a8be | ||
|
|
0522047c96 | ||
|
|
3724b50ef9 | ||
|
|
b801b7b670 | ||
|
|
b7aab2dbad | ||
|
|
89e42ffb4b | ||
|
|
6aae4a7378 | ||
|
|
7d4a4300c2 | ||
|
|
31d4ec28bd | ||
|
|
0a5bfb4fda | ||
|
|
12d0b15679 | ||
|
|
cb7dcb011e | ||
|
|
71579c7219 | ||
|
|
2f8a874215 | ||
|
|
ad6f600bb1 | ||
|
|
de4f41eab7 | ||
|
|
e73f086b0d | ||
|
|
8cf098415e | ||
|
|
977e19840d | ||
|
|
d975c2f76e | ||
|
|
0676801b8c | ||
|
|
82aa96e9b1 | ||
|
|
cb65553449 | ||
|
|
f47a1bd622 | ||
|
|
205d372c68 | ||
|
|
07a1243b40 | ||
|
|
ece343d2c2 | ||
|
|
be95a4fe29 | ||
|
|
6accee7716 | ||
|
|
e63f22703e | ||
|
|
fa390dc311 | ||
|
|
17fdf5eca2 | ||
|
|
72b3c1a673 |
+1
-1
@@ -1 +1 @@
|
||||
3.6.93
|
||||
3.7.2
|
||||
|
||||
+4
-1
@@ -50,6 +50,7 @@ jobs:
|
||||
- make -j2 dist-xz
|
||||
# Can help understanding why we get "dirty" tarballs.
|
||||
- git status
|
||||
- git diff
|
||||
- dist=$(echo bison*.xz)
|
||||
|
||||
# Unfortunately we cannot deterministically know the name of the tarball without the full
|
||||
@@ -119,6 +120,8 @@ jobs:
|
||||
- CXX='clang++-10 -fsanitize=address -stdlib=libc++'
|
||||
- PART=2
|
||||
|
||||
# See https://github.com/simd-everywhere/simde/blob/master/.travis.yml
|
||||
# and https://software.intel.com/content/www/us/en/develop/documentation/get-started-with-intel-oneapi-render-linux/top/configure-your-system.html.
|
||||
- name: "ICC"
|
||||
stage: check
|
||||
os: linux
|
||||
@@ -127,7 +130,7 @@ jobs:
|
||||
- CC=icc
|
||||
- CXX=icpc
|
||||
install:
|
||||
- source /opt/intel/inteloneapi/compiler/latest/env/vars.sh
|
||||
- source /opt/intel/oneapi/compiler/latest/env/vars.sh
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
|
||||
@@ -1,5 +1,55 @@
|
||||
GNU Bison NEWS
|
||||
|
||||
* Noteworthy changes in release 3.7.3 (2020-10-13) [stable]
|
||||
|
||||
** Bug fixes
|
||||
|
||||
Fix concurrent build issues.
|
||||
|
||||
The bison executable is no longer linked uselessly against libreadline.
|
||||
|
||||
Fix incorrect use of yytname in glr.cc.
|
||||
|
||||
* Noteworthy changes in release 3.7.2 (2020-09-05) [stable]
|
||||
|
||||
This release of Bison fixes all known bugs reported for Bison in MITRE's
|
||||
Common Vulnerabilities and Exposures (CVE) system. These vulnerabilities
|
||||
are only about bison-the-program itself, not the generated code.
|
||||
|
||||
Although these bugs are typically irrelevant to how Bison is used, they
|
||||
are worth fixing if only to give users peace of mind.
|
||||
|
||||
There is no known vulnerability in the generated parsers.
|
||||
|
||||
** Bug fixes
|
||||
|
||||
Fix concurrent build issues (introduced in Bison 3.5).
|
||||
|
||||
Push parsers always use YYMALLOC/YYFREE (no direct calls to malloc/free).
|
||||
|
||||
Fix portability issues of the test suite, and of bison itself.
|
||||
|
||||
Some unlikely crashes found by fuzzing have been fixed. This is only
|
||||
about bison itself, not the generated parsers.
|
||||
|
||||
|
||||
* Noteworthy changes in release 3.7.1 (2020-08-02) [stable]
|
||||
|
||||
** Bug fixes
|
||||
|
||||
Crash when a token alias contains a NUL byte.
|
||||
|
||||
Portability issues with libtextstyle.
|
||||
|
||||
Portability issues of Bison itself with MSVC.
|
||||
|
||||
** Changes
|
||||
|
||||
Improvements and fixes in the documentation.
|
||||
|
||||
More precise location about symbol type redefinitions.
|
||||
|
||||
|
||||
* Noteworthy changes in release 3.7 (2020-07-23) [stable]
|
||||
|
||||
** Deprecated features
|
||||
@@ -537,7 +587,8 @@ GNU Bison NEWS
|
||||
\005) with incorrect styling. Fixes for similar issues with unexpectedly
|
||||
short lines (e.g., the file was changed between parsing and diagnosing).
|
||||
|
||||
Several unlikely crashes found by fuzzing have been fixed.
|
||||
Some unlikely crashes found by fuzzing have been fixed. This is only
|
||||
about bison itself, not the generated parsers.
|
||||
|
||||
|
||||
* Noteworthy changes in release 3.5.2 (2020-02-13) [stable]
|
||||
|
||||
@@ -42,9 +42,11 @@ installing it. In that case, do not use `src/bison`: it would use the
|
||||
As an experimental feature, diagnostics are now colored, controlled by the
|
||||
`--color` and `--style` options.
|
||||
|
||||
To use them, install the libtextstyle library before configuring Bison. It
|
||||
is available from https://alpha.gnu.org/gnu/gettext/, for instance
|
||||
https://alpha.gnu.org/pub/gnu/gettext/libtextstyle-0.20.5.tar.gz.
|
||||
To use them, install the libtextstyle library, 0.20.5 or newer, before
|
||||
configuring Bison. It is available from https://alpha.gnu.org/gnu/gettext/,
|
||||
for instance https://alpha.gnu.org/gnu/gettext/libtextstyle-0.20.5.tar.gz,
|
||||
or as part of Gettext 0.21 or newer, for instance
|
||||
https://ftp.gnu.org/gnu/gettext/gettext-0.21.tar.gz.
|
||||
|
||||
The option --color supports the following arguments:
|
||||
- always, yes: Enable colors.
|
||||
@@ -61,6 +63,13 @@ To customize the styles, create a CSS file, say `bison-bw.css`, similar to
|
||||
then invoke bison with `--style=bison-bw.css`, or set the `BISON_STYLE`
|
||||
environment variable to `bison-bw.css`.
|
||||
|
||||
In some diagnostics, bison uses libtextstyle to emit special escapes to
|
||||
generate clickable hyperlinks. The environment variable
|
||||
`NO_TERM_HYPERLINKS` can be used to suppress them. This may be useful for
|
||||
terminal emulators which produce garbage output when they receive the escape
|
||||
sequence for a hyperlink. Currently (as of 2020), this affects some versions
|
||||
of emacs, guake, konsole, lxterminal, rxvt, yakuake.
|
||||
|
||||
## Relocatability
|
||||
If you pass `--enable-relocatable` to `configure`, Bison is relocatable.
|
||||
|
||||
|
||||
@@ -106,9 +106,11 @@ Keith Browne [email protected]
|
||||
Ken Moffat [email protected]
|
||||
Kiyoshi Kanazawa [email protected]
|
||||
Lars Maier [email protected]
|
||||
Lars Wendler [email protected]
|
||||
László Várady [email protected]
|
||||
Laurent Mascherpa [email protected]
|
||||
Lie Yan [email protected]
|
||||
Maarten De Braekeleer [email protected]
|
||||
Magnus Fromreide [email protected]
|
||||
Marc Autret [email protected]
|
||||
Marc Mendiola [email protected]
|
||||
@@ -185,6 +187,7 @@ Simon Sobisch [email protected]
|
||||
Stefano Lattarini [email protected]
|
||||
Stephen Cameron [email protected]
|
||||
Steve Murphy [email protected]
|
||||
Suhwan Song [email protected]
|
||||
Sum Wu [email protected]
|
||||
Théophile Ranquet [email protected]
|
||||
Thiru Ramakrishnan [email protected]
|
||||
|
||||
@@ -1,4 +1,12 @@
|
||||
* Bison 3.7
|
||||
* Soon
|
||||
** gnulib
|
||||
Bruno notes:
|
||||
|
||||
> I haven't looked deeply, but it strikes me that gnulib/lib/bitset/array.c
|
||||
> does not make use of the 'ffsl' function, nor or the 'integer_length_l'
|
||||
> function. Maybe because in Bison, all bitsets are so dense that it does
|
||||
> not give a performance advantage?
|
||||
|
||||
** Cex
|
||||
*** Improve gnulib
|
||||
Don't do this (counterexample.c):
|
||||
@@ -48,13 +56,6 @@ Unless we play it dumb (little structure).
|
||||
|
||||
- promote YYEOF rather than EOF.
|
||||
|
||||
*** D
|
||||
- is there a way to attach yysymbol_name to the enum itself? As we did
|
||||
in Java.
|
||||
|
||||
- It would be better to have TokenKind as return value. Can we use
|
||||
reflection to support both output types?
|
||||
|
||||
** YYerror
|
||||
https://git.savannah.gnu.org/gitweb/?p=gettext.git;a=blob;f=gettext-runtime/intl/plural.y;h=a712255af4f2f739c93336d4ff6556d932a426a5;hb=HEAD
|
||||
|
||||
@@ -67,7 +68,7 @@ Stop hard-coding "Calc". Adjust local.at (look for FIXME).
|
||||
|
||||
** A dev warning for b4_
|
||||
Maybe we should check for m4_ and b4_ leaking out of the m4 processing, as
|
||||
Autoconf does. It would have caught overquotation issues.
|
||||
Autoconf does. It would have caught over-quotation issues.
|
||||
|
||||
** doc
|
||||
I feel it's ugly to use the GNU style to declare functions in the doc. It
|
||||
@@ -88,7 +89,7 @@ push parsers on top of pull parser. Which is currently not relevant, since
|
||||
push parsers are measurably slower.
|
||||
|
||||
** %define parse.error formatted
|
||||
How about pushing bistromathics' yyreport_syntax_error as another standard
|
||||
How about pushing Bistromathic's yyreport_syntax_error as another standard
|
||||
way to generate the error message, and leave to the user the task of
|
||||
providing the message formats? Currently in bistro, it reads:
|
||||
|
||||
@@ -202,18 +203,282 @@ The "automaton" and "set" categories are not so useful. We should probably
|
||||
introduce lr(0) and lalr, just the way we have ielr categories. The
|
||||
"closure" function is too verbose, it should probably have its own category.
|
||||
|
||||
"set" can still be used for summariring the important sets. That would make
|
||||
"set" can still be used for summarizing the important sets. That would make
|
||||
tests easy to maintain.
|
||||
|
||||
*** complain.*
|
||||
Rename these guys as "diagnostics.*" (or "diagnose.*"), since that's the
|
||||
name they have in gcc, clang, etc. Likewise for the complain_* series of
|
||||
name they have in GCC, clang, etc. Likewise for the complain_* series of
|
||||
functions.
|
||||
|
||||
*** ritem
|
||||
states/nstates, rules/nrules, ..., ritem/nritems
|
||||
Fix the latter.
|
||||
|
||||
* D programming language
|
||||
There's a number of features that are missing, here sorted in _suggested_
|
||||
order of implementation.
|
||||
|
||||
When copying code from other skeletons, keep the comments exactly as they
|
||||
are. Keep the same variable names. If you change the wording in one place,
|
||||
do it in the others too. In other words: make sure to keep the
|
||||
maintenance *simple* by avoiding any gratuitous difference.
|
||||
|
||||
** Rename the D example
|
||||
Move the current content of examples/d into examples/d/simple.
|
||||
|
||||
** Create a second example
|
||||
Duplicate examples/d/simple into examples/d/calc.
|
||||
|
||||
** Add location tracking to d/calc
|
||||
Look at the examples in the other languages to see how to do that.
|
||||
|
||||
** yysymbol_name
|
||||
The SymbolKind is an enum. For a given SymbolKind we want to get its string
|
||||
representation. Currently it's a separate table in the parser that does
|
||||
that:
|
||||
|
||||
/* Symbol kinds. */
|
||||
public enum SymbolKind
|
||||
{
|
||||
S_YYEMPTY = -2, /* No symbol. */
|
||||
S_YYEOF = 0, /* "end of file" */
|
||||
S_YYerror = 1, /* error */
|
||||
S_YYUNDEF = 2, /* "invalid token" */
|
||||
S_EQ = 3, /* "=" */
|
||||
...
|
||||
S_input = 14, /* input */
|
||||
S_line = 15, /* line */
|
||||
S_exp = 16, /* exp */
|
||||
};
|
||||
|
||||
...
|
||||
|
||||
/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
|
||||
First, the terminals, then, starting at \a yyntokens_, nonterminals. */
|
||||
private static immutable string[] yytname_ =
|
||||
[
|
||||
"\"end of file\"", "error", "\"invalid token\"", "\"=\"", "\"+\"",
|
||||
"\"-\"", "\"*\"", "\"/\"", "\"(\"", "\")\"", "\"end of line\"",
|
||||
"\"number\"", "UNARY", "$accept", "input", "line", "exp", null
|
||||
];
|
||||
|
||||
...
|
||||
|
||||
So to get a symbol kind, one runs `yytname_[yykind]`.
|
||||
|
||||
Is there a way to attach this conversion to string to SymbolKind? In Java
|
||||
for instance, we have:
|
||||
|
||||
public enum SymbolKind
|
||||
{
|
||||
S_YYEOF(0), /* "end of file" */
|
||||
S_YYerror(1), /* error */
|
||||
S_YYUNDEF(2), /* "invalid token" */
|
||||
...
|
||||
S_input(16), /* input */
|
||||
S_line(17), /* line */
|
||||
S_exp(18); /* exp */
|
||||
|
||||
private final int yycode_;
|
||||
|
||||
SymbolKind (int n) {
|
||||
this.yycode_ = n;
|
||||
}
|
||||
...
|
||||
/* YYNAMES_[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
|
||||
First, the terminals, then, starting at \a YYNTOKENS_, nonterminals. */
|
||||
private static final String[] yynames_ = yynames_init();
|
||||
private static final String[] yynames_init()
|
||||
{
|
||||
return new String[]
|
||||
{
|
||||
i18n("end of file"), i18n("error"), i18n("invalid token"), "!", "+", "-", "*",
|
||||
"/", "^", "(", ")", "=", i18n("end of line"), i18n("number"), "NEG",
|
||||
"$accept", "input", "line", "exp", null
|
||||
};
|
||||
}
|
||||
|
||||
/* The user-facing name of this symbol. */
|
||||
public final String getName() {
|
||||
return yynames_[yycode_];
|
||||
}
|
||||
};
|
||||
|
||||
which allows to write more naturally `yykind.getName()` rather than
|
||||
`yytname_[yykind]`. Is there something comparable in (idiomatic) D?
|
||||
|
||||
** Change the return value of yylex
|
||||
Historically people were allowed to return any int from the scanner (which
|
||||
is convenient and allows `return '+'` from the scanner). Akim tends to see
|
||||
this as an error, we should restrict the return values to TokenKind (not to
|
||||
be confused with SymbolKind).
|
||||
|
||||
In the case of D, without the history, we have the choice to support or not
|
||||
`int`. If we want to _keep_ `int`, is there a way, say via introspection,
|
||||
to support both signatures of yylex? If we don't keep `int`, just move to
|
||||
TokenKind.
|
||||
|
||||
** Documentation
|
||||
Write documentation about D support in doc/bison.texi. Imitate the Java
|
||||
documentation. You should be more succinct IMHO.
|
||||
|
||||
** Complete Symbols
|
||||
The current interface from the scanner to the parser is somewhat clumsy: the
|
||||
token kind is returned by yylex, but the value and location are stored in
|
||||
the scanner. This reflects the fact that the implementation of the parser
|
||||
uses three variables to deal with each parsed symbol: its kind, its value,
|
||||
its location.
|
||||
|
||||
So today the scanner of examples/d/calc.d (no locations) looks like:
|
||||
|
||||
if (input.front.isNumber)
|
||||
{
|
||||
import std.conv : parse;
|
||||
semanticVal_.ival = input.parse!int;
|
||||
return TokenKind.NUM;
|
||||
}
|
||||
|
||||
and the generated parser:
|
||||
|
||||
/* Read a lookahead token. */
|
||||
if (yychar == TokenKind.YYEMPTY)
|
||||
{
|
||||
yychar = yylex ();
|
||||
yylval = yylexer.semanticVal;
|
||||
}
|
||||
|
||||
The parser class should feature a `Symbol` type which binds together kind,
|
||||
value and location, and the scanner should be able to return an instance of
|
||||
that type. Something like
|
||||
|
||||
if (input.front.isNumber)
|
||||
{
|
||||
import std.conv : parse;
|
||||
return parser.Symbol (TokenKind.NUM, input.parse!int);
|
||||
}
|
||||
|
||||
** Token Constructors
|
||||
In the previous example it is possible to mix incorrectly kinds and values,
|
||||
and for instance:
|
||||
|
||||
return parser.Symbol (TokenKind.NUM, "Hello, World!\n");
|
||||
|
||||
attaches a string value to NUM kind (wrong, of course). When
|
||||
api.token.constructor is set, in C++, Bison generated "token constructors":
|
||||
parser.make_NUM. parser.make_PLUS, parser.make_STRING, etc. The previous
|
||||
example becomes
|
||||
|
||||
return parser.make_NUM ("Hello, World!\n");
|
||||
|
||||
which would easily be caught by the type checker.
|
||||
|
||||
** Lookahead Correction
|
||||
Add support for LAC to the D skeleton. It should not be too hard: look how
|
||||
this is done in lalr1.cc, and mock it.
|
||||
|
||||
** Push Parser
|
||||
Add support for push parser. Do not start a nice skeleton, just enhance the
|
||||
current one to support push parsers. This is going to be a tougher nut to
|
||||
crack.
|
||||
|
||||
First, you need to understand well how the push parser is expected to work.
|
||||
To this end:
|
||||
- read the doc
|
||||
- look at examples/c/pushcalc
|
||||
- create an example of a Java push parser.
|
||||
- have a look at the generated parser in Java, which has the advantage of
|
||||
being already based on a parser object, instead of just a function.
|
||||
|
||||
The C case is harder to read, but it may help too. Keep in mind that
|
||||
because there's no object to maintain state, the C push parser uses some
|
||||
struct (yypstate) to preserve this state. We don't need this in D, the
|
||||
parser object will suffice.
|
||||
|
||||
I think working directly on the skeleton to add push-parser support is not
|
||||
the simplest path. I suggest that you (1) transform a generated parser into
|
||||
a push parser by hand, and then (2) transform lalr1.d to generate such a
|
||||
parser.
|
||||
|
||||
Use `git commit` frequently to make sure you keep track of your progress.
|
||||
|
||||
*** (1.a) Prepare pull parser by hand
|
||||
Copy again one of the D examples into say examples/d/pushcalc. Also
|
||||
check-in the generated parser to facilitate experimentation.
|
||||
|
||||
- find local variables of yyparse should become members of the parser object
|
||||
(so that we preserve state from one call to the next).
|
||||
|
||||
- do it in your generated D parser. We don't need an equivalent for
|
||||
yypstate, because we already have it: that the parser object itself.
|
||||
|
||||
- have your *pull*-parser (i.e., the good old yy::parser::parse()) work
|
||||
properly this way. Write and run tests. That's one of the reasons I
|
||||
suggest using examples/d/calc as a starting point: it already has tests,
|
||||
you can/should add more.
|
||||
|
||||
At this point you have a pull-parser which you prepared to turn into a
|
||||
push-parser.
|
||||
|
||||
*** (1.b) Turn pull parser into push parser by hand
|
||||
|
||||
- look again at how push parsers are implemented in Java/C to see what needs
|
||||
to change in yyparse so that the control is inverted: parse() will
|
||||
be *given* the tokens, instead of having to call yylex itself. When I say
|
||||
"look at C", I think your best option are (i) yacc.c (look for b4_push_if)
|
||||
and (ii) examples/c/pushcalc.
|
||||
|
||||
- rename parse() as push_parse(Symbol yyla) (or push_parse(TokenKind, Value,
|
||||
Location)) that takes the symbol as argument. That's the push parser we
|
||||
are looking for.
|
||||
|
||||
- define a new parse() function which has the same signature as the usual
|
||||
pull-parser, that repeatedly calls the push_parse function. Something
|
||||
like this:
|
||||
|
||||
int parse ()
|
||||
{
|
||||
int status = 0;
|
||||
do {
|
||||
status = this->push_parse (yylex());
|
||||
} while (status == YYPUSH_MORE);
|
||||
return status;
|
||||
}
|
||||
|
||||
- show me that parser, so that we can validate the approach.
|
||||
|
||||
*** (2) Port that into the skeleton
|
||||
- once we agree on the API of the push parser, implement it into lalr1.d.
|
||||
You will probaby need help on this regard, but imitation, again, should
|
||||
help.
|
||||
|
||||
- have example/d/pushcalc work properly and pass tests
|
||||
|
||||
- add tests in the "real" test suite. Do that in tests/calc.at. I can
|
||||
help.
|
||||
|
||||
- document
|
||||
|
||||
** GLR Parser
|
||||
This is very ambitious. That's the final boss. There are currently no
|
||||
"clean" implementation to get inspiration from.
|
||||
|
||||
glr.c is very clean but:
|
||||
- is low-level C
|
||||
- is a different skeleton from yacc.c
|
||||
|
||||
glr.cc is (currently) an ugly hack: a C++ shell around glr.c. Valentin
|
||||
Tolmer is currently rewriting glr.cc to be clean C++, but he is not
|
||||
finished. There will be a lot a common code between lalr1.cc and glr.cc, so
|
||||
eventually I would like them to be fused into a single skeleton, supporting
|
||||
both deterministic and generalized parsing.
|
||||
|
||||
It would be great for D to also support this.
|
||||
|
||||
The basic ideas of GLR are explained here:
|
||||
|
||||
https://www.codeproject.com/Articles/5259825/GLR-Parsing-in-Csharp-How-to-Use-The-Most-Powerful
|
||||
|
||||
* Better error messages
|
||||
The users are not provided with enough tools to forge their error messages.
|
||||
See for instance "Is there an option to change the message produced by
|
||||
@@ -231,7 +496,7 @@ and older C++ compilers. Currently the code defaults to defining it to
|
||||
define it to the same type as the C ptrdiff_t type.
|
||||
|
||||
* Completion
|
||||
Several features are not available in all the backends.
|
||||
Several features are not available in all the back-ends.
|
||||
|
||||
- lac: D, Java (easy)
|
||||
- push parsers: glr.c, glr.cc, lalr1.cc (not very difficult)
|
||||
@@ -301,7 +566,7 @@ opposite side we have some use of \l, which is graphviz-specific, in what
|
||||
should be generic code.
|
||||
|
||||
Little effort seems to have been given to factoring these files and their
|
||||
rint{,-xml} counterpart. We would very much like to re-use the pretty format
|
||||
print{,-xml} counterpart. We would very much like to re-use the pretty format
|
||||
of states from .output for the graphs, etc.
|
||||
|
||||
Since graphviz dies on medium-to-big grammars, maybe consider an other tool?
|
||||
@@ -579,14 +844,39 @@ to bison. If you're interested, I'll work on a patch.
|
||||
Equip the parser with a means to create the (visual) parse tree.
|
||||
|
||||
|
||||
-----
|
||||
|
||||
# LocalWords: Cex gnulib gl Bistromathic TokenKinds yylex enum YYEOF EOF
|
||||
# LocalWords: YYerror gettext af hb YYERRCODE undef calc FIXME dev yyerror
|
||||
# LocalWords: Autoconf YYUNDEFTOK lexemes parsers Bistromathic's yyreport
|
||||
# LocalWords: const argc yacc yyclearin lookahead destructor Rici incluent
|
||||
# LocalWords: yydestruct yydiscardin catégories d'avertissements sr activé
|
||||
# LocalWords: conflits défaut rr l'alias chaîne n'est attaché un symbole
|
||||
# LocalWords: obsolète règle vide midrule valeurs de intermédiaire ou avec
|
||||
# LocalWords: définies inutilisées priorité associativité inutiles POSIX
|
||||
# LocalWords: incompatibilités tous les autres avertissements sauf dans rp
|
||||
# LocalWords: désactiver CATEGORIE traiter comme des erreurs glr Akim bool
|
||||
# LocalWords: Demaille arith lalr goto struct pathlen nullable ntokens lr
|
||||
# LocalWords: nterm bitsetv ielr ritem nstates nrules nritems yysymbol EQ
|
||||
# LocalWords: SymbolKind YYEMPTY YYUNDEF YYTNAME NUM yyntokens yytname sed
|
||||
# LocalWords: nonterminals yykind yycode YYNAMES yynames init getName conv
|
||||
# LocalWords: TokenKind semanticVal ival yychar yylval yylexer Tolmer hoc
|
||||
# LocalWords: Sobisch YYPTRDIFF ptrdiff Autotest YYPRINT toknum yytoknum
|
||||
# LocalWords: sym Wother stderr FP fixits xgettext fdiagnostics Graphviz
|
||||
# LocalWords: graphviz VCG bitset xml bw maint yytoken YYABORT deps
|
||||
# LocalWords: YYACCEPT yytranslate nonnegative destructors yyerrlab repo
|
||||
# LocalWords: backends stmt expr yy Mardle baz qux Vadim Maslow CPP cpp
|
||||
# LocalWords: yydebug gcc UCHAR EBCDIC gung PDP NUL Pre Florian Krohm utf
|
||||
# LocalWords: YYACT YYLLOC YYLSP yyval yyvsp yylen yyloc yylsp endif
|
||||
# LocalWords: ispell american
|
||||
|
||||
Local Variables:
|
||||
mode: outline
|
||||
coding: utf-8
|
||||
fill-column: 76
|
||||
ispell-dictionary: "american"
|
||||
End:
|
||||
|
||||
-----
|
||||
|
||||
Copyright (C) 2001-2004, 2006, 2008-2015, 2018-2020 Free Software
|
||||
Foundation, Inc.
|
||||
|
||||
|
||||
@@ -45,6 +45,8 @@ gnulib_modules='
|
||||
relocatable-prog relocatable-script
|
||||
rename
|
||||
spawn-pipe stdbool stpcpy stpncpy strdup-posix strerror strverscmp
|
||||
sys_ioctl
|
||||
termios
|
||||
timevar
|
||||
unicodeio unistd unistd-safer unlink unlocked-io
|
||||
update-copyright unsetenv verify
|
||||
|
||||
@@ -126,7 +126,7 @@ _sed_rm_comments_q = $(subst ','\'',$(_sed_remove_comments))
|
||||
|
||||
_space_before_paren_exempt =? \\n\\$$
|
||||
_space_before_paren_exempt = \
|
||||
(^ *\#|(LA)?LR\([01]\)|percent_(code|define)|b4_syncline|m4_(define|init)|symbol)
|
||||
(^ *\#|(LA)?LR\([01]\)|percent_(code|define)|b4_syncline|m4_(define|init))
|
||||
# Ensure that there is a space before each open parenthesis in C code.
|
||||
sc_space_before_open_paren:
|
||||
@if $(VC_LIST_EXCEPT) | grep -l '\.[ch]$$' > /dev/null; then \
|
||||
@@ -156,6 +156,7 @@ exclude = \
|
||||
$(call exclude, \
|
||||
bindtextdomain=^lib/main.c$$ \
|
||||
cast_of_argument_to_free=^src/muscle-tab.c$$ \
|
||||
error_message_uppercase=etc/bench.pl.in$$ \
|
||||
po_check=^tests|(^po/POTFILES.in|.md)$$ \
|
||||
preprocessor_indentation=^data/|^lib/|^src/parse-gram.[ch]$$ \
|
||||
program_name=^lib/main.c$$ \
|
||||
|
||||
@@ -60,6 +60,9 @@ AC_PROG_CXX
|
||||
# Gnulib (early checks).
|
||||
gl_EARLY
|
||||
|
||||
# We want ostream_printf and hyperlink support.
|
||||
gl_LIBTEXTSTYLE_OPTIONAL([0.20.5])
|
||||
|
||||
# Gnulib uses '#pragma GCC diagnostic push' to silence some
|
||||
# warnings, but older gcc doesn't support this.
|
||||
AC_CACHE_CHECK([whether pragma GCC diagnostic push works],
|
||||
|
||||
@@ -172,7 +172,7 @@ m4_pushdef([b4_parse_param], m4_defn([b4_parse_param_orig]))dnl
|
||||
const location_type* yylocationp]])[) const
|
||||
{
|
||||
*yycdebug_ << (yykind < YYNTOKENS ? "token" : "nterm")
|
||||
<< ' ' << yytname[yykind] << " ("]b4_locations_if([[
|
||||
<< ' ' << yysymbol_name (yykind) << " ("]b4_locations_if([[
|
||||
<< *yylocationp << ": "]])[;
|
||||
yy_symbol_value_print_ (yykind, yyvaluep]b4_locations_if([[, yylocationp]])[);
|
||||
*yycdebug_ << ')';
|
||||
|
||||
@@ -1486,7 +1486,7 @@ yypstate_new (void)
|
||||
yypstate *yyps;]b4_pure_if([], [[
|
||||
if (yypstate_allocated)
|
||||
return YY_NULLPTR;]])[
|
||||
yyps = YY_CAST (yypstate *, malloc (sizeof *yyps));
|
||||
yyps = YY_CAST (yypstate *, YYMALLOC (sizeof *yyps));
|
||||
if (!yyps)
|
||||
return YY_NULLPTR;]b4_pure_if([], [[
|
||||
yypstate_allocated = 1;]])[
|
||||
@@ -1515,7 +1515,7 @@ yypstate_delete (yypstate *yyps)
|
||||
#endif]b4_lac_if([[
|
||||
if (yyes != yyesa)
|
||||
YYSTACK_FREE (yyes);]])[
|
||||
free (yyps);]b4_pure_if([], [[
|
||||
YYFREE (yyps);]b4_pure_if([], [[
|
||||
yypstate_allocated = 0;]])[
|
||||
}
|
||||
}
|
||||
|
||||
+105
-79
@@ -57,44 +57,57 @@
|
||||
\gdef\colorPurple{%
|
||||
\setcolor{\rgbPurple}%
|
||||
}
|
||||
\gdef\colorOff{%
|
||||
\setcolor{\maincolor}%
|
||||
}
|
||||
|
||||
\gdef\rgbError{0.80 0 0}
|
||||
\gdef\colorError{%
|
||||
\gdef\diagError{%
|
||||
\setcolor{\rgbError}%
|
||||
}
|
||||
\gdef\rgbNotice{0 0 0.80}
|
||||
\gdef\colorNotice{%
|
||||
\gdef\diagNotice{%
|
||||
\setcolor{\rgbNotice}%
|
||||
}
|
||||
\gdef\colorOff{%
|
||||
\gdef\rgbWarning{0.50 0 0.50}
|
||||
\gdef\diagWarning{%
|
||||
\setcolor{\rgbWarning}%
|
||||
}
|
||||
\gdef\diagOff{%
|
||||
\setcolor{\maincolor}%
|
||||
}
|
||||
@end tex
|
||||
|
||||
@ifnottex
|
||||
@macro colorGreen
|
||||
@inlineraw{html, <b style="color:green">}
|
||||
@inlineraw{html, <span style="color:green">}
|
||||
@end macro
|
||||
@macro colorYellow
|
||||
@inlineraw{html, <b style="color:#ff8000">}
|
||||
@inlineraw{html, <span style="color:#ff8000">}
|
||||
@end macro
|
||||
@macro colorRed
|
||||
@inlineraw{html, <b style="color:red">}
|
||||
@inlineraw{html, <span style="color:red">}
|
||||
@end macro
|
||||
@macro colorBlue
|
||||
@inlineraw{html, <b style="color:blue">}
|
||||
@inlineraw{html, <span style="color:blue">}
|
||||
@end macro
|
||||
@macro colorPurple
|
||||
@inlineraw{html, <b style="color:darkviolet">}
|
||||
@end macro
|
||||
|
||||
@macro colorError
|
||||
@inlineraw{html, <b style="color:red">}
|
||||
@end macro
|
||||
@macro colorNotice
|
||||
@inlineraw{html, <b style="color:darkcyan">}
|
||||
@inlineraw{html, <span style="color:darkviolet">}
|
||||
@end macro
|
||||
@macro colorOff
|
||||
@inlineraw{html, </span>}
|
||||
@end macro
|
||||
|
||||
@macro diagError
|
||||
@inlineraw{html, <b style="color:red">}
|
||||
@end macro
|
||||
@macro diagNotice
|
||||
@inlineraw{html, <b style="color:darkcyan">}
|
||||
@end macro
|
||||
@macro diagWarning
|
||||
@inlineraw{html, <b style="color:darkviolet">}
|
||||
@end macro
|
||||
@macro diagOff
|
||||
@inlineraw{html, </b>}
|
||||
@end macro
|
||||
@end ifnottex
|
||||
@@ -120,15 +133,15 @@
|
||||
@end macro
|
||||
|
||||
@macro dwarning{text}
|
||||
@purple{\text\}
|
||||
@diagWarning{}\text\@diagOff{}
|
||||
@end macro
|
||||
|
||||
@macro derror{text}
|
||||
@colorError{}\text\@colorOff{}
|
||||
@diagError{}\text\@diagOff{}
|
||||
@end macro
|
||||
|
||||
@macro dnotice{text}
|
||||
@colorNotice{}\text\@colorOff{}
|
||||
@diagNotice{}\text\@diagOff{}
|
||||
@end macro
|
||||
|
||||
@finalout
|
||||
@@ -6283,7 +6296,10 @@ Introduced in Bison 3.3 to replace @code{parser_class_name}.
|
||||
|
||||
@item Default Value: @code{YY} for Java, @code{yy} otherwise.
|
||||
|
||||
@item History: introduced in Bison 2.6
|
||||
@item History:
|
||||
introduced in Bison 2.6, with its argument in double quotes. Uses braces
|
||||
since Bison 3.0 (double quotes are still supported for backward
|
||||
compatibility).
|
||||
@end itemize
|
||||
@end deffn
|
||||
|
||||
@@ -8302,7 +8318,53 @@ write an unambiguous grammar, but that is very hard to do in this case.)
|
||||
This particular ambiguity was first encountered in the specifications of
|
||||
Algol 60 and is called the ``dangling @code{else}'' ambiguity.
|
||||
|
||||
To avoid warnings from Bison about predictable, legitimate shift/reduce
|
||||
To assist the grammar author in understanding the nature of each conflict,
|
||||
Bison can be asked to generate ``counterexamples''. In the present case it
|
||||
actually even proves that the grammar is ambiguous by exhibiting a string
|
||||
with two different parses:
|
||||
|
||||
@macro danglingElseCex
|
||||
@group
|
||||
@ifnottex
|
||||
Example: @yellow{"if" expr "then"} @blue{"if" expr "then" stmt} @red{•} @blue{"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 ifnottex
|
||||
@iftex
|
||||
Example: @yellow{"if" expr "then"} @blue{"if" expr "then" stmt} @red{•} @blue{"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 iftex
|
||||
@end group
|
||||
@end macro
|
||||
@example
|
||||
@danglingElseCex
|
||||
@end example
|
||||
|
||||
@noindent
|
||||
@xref{Counterexamples}, for more details.
|
||||
|
||||
@sp 1
|
||||
|
||||
To avoid warnings from Bison about predictable, @emph{legitimate} shift/reduce
|
||||
conflicts, you can use the @code{%expect @var{n}} declaration.
|
||||
There will be no warning as long as the number of shift/reduce conflicts
|
||||
is exactly @var{n}, and Bison will report an error if there is a
|
||||
@@ -8693,7 +8755,8 @@ maybeword:
|
||||
@end example
|
||||
|
||||
@noindent
|
||||
The error is an ambiguity: there is more than one way to parse a single
|
||||
The error is an ambiguity: as counterexample generation would demonstrate
|
||||
(@pxref{Counterexamples}), there is more than one way to parse a single
|
||||
@code{word} into a @code{sequence}. It could be reduced to a
|
||||
@code{maybeword} and then into a @code{sequence} via the second rule.
|
||||
Alternatively, nothing-at-all could be reduced into a @code{sequence}
|
||||
@@ -8890,12 +8953,14 @@ name_list:
|
||||
It would seem that this grammar can be parsed with only a single token of
|
||||
lookahead: when a @code{param_spec} is being read, an @code{"id"} is a
|
||||
@code{name} if a comma or colon follows, or a @code{type} if another
|
||||
@code{"id"} follows. In other words, this grammar is LR(1).
|
||||
@code{"id"} follows. In other words, this grammar is LR(1). Yet Bison
|
||||
finds one reduce/reduce conflict, for which counterexample generation
|
||||
(@pxref{Counterexamples}) would find a @emph{nonunifying} example.
|
||||
|
||||
@cindex LR
|
||||
@cindex LALR
|
||||
However, for historical reasons, Bison cannot by default handle all
|
||||
LR(1) grammars.
|
||||
This is because Bison does not handle all LR(1) grammars @emph{by default},
|
||||
for historical reasons.
|
||||
In this grammar, two contexts, that after an @code{"id"} at the beginning
|
||||
of a @code{param_spec} and likewise at the beginning of a
|
||||
@code{return_spec}, are similar enough that Bison assumes they are the
|
||||
@@ -9870,6 +9935,9 @@ and understand the parser run-time traces (@pxref{Tracing}).
|
||||
|
||||
@node Counterexamples
|
||||
@section Generation of Counterexamples
|
||||
@cindex cex
|
||||
@cindex counterexamples
|
||||
@cindex conflict counterexamples
|
||||
|
||||
Solving conflicts is probably the most delicate part of the design of an LR
|
||||
parser, as demonstrated by the number of sections devoted to them in this
|
||||
@@ -9886,8 +9954,8 @@ That task is made much easier thanks to the generation of counterexamples,
|
||||
initially developed by Chinawat Isradisaikul and Andrew Myers
|
||||
@pcite{Isradisaikul 2015}.
|
||||
|
||||
As a first example, see the example grammar of @ref{Shift/Reduce}, which
|
||||
features on shift/reduce conflict:
|
||||
As a first example, see the grammar of @ref{Shift/Reduce}, which features
|
||||
one shift/reduce conflict:
|
||||
|
||||
@c see doc/if-then-else.y
|
||||
@example
|
||||
@@ -9901,49 +9969,14 @@ Let's rerun @command{bison} with the option
|
||||
@option{-Wcex}/@option{-Wcounterexamples}@inlinefmt{info, (the following
|
||||
output is actually in color)}:
|
||||
|
||||
@ifnottex
|
||||
@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"} "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
|
||||
@danglingElseCex
|
||||
@end example
|
||||
@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"} "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 example
|
||||
@end iftex
|
||||
|
||||
This shows two different derivations for one single expression. That
|
||||
demonstrates that the grammar is ambiguous.
|
||||
This shows two different derivations for one single expression, which proves
|
||||
that the grammar is ambiguous.
|
||||
|
||||
@sp 1
|
||||
|
||||
@@ -9966,13 +9999,13 @@ 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}]
|
||||
@end group
|
||||
@ifnottex
|
||||
@group
|
||||
sequence.y: @dwarning{warning}: shift/reduce conflict on token "word" [@dwarning{-Wcounterexamples}]
|
||||
Example: @red{•} @green{"word"}
|
||||
@@ -10017,15 +10050,8 @@ sequence.y:8.3-45: @dwarning{warning}: rule useless in parser due to conflicts [
|
||||
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"}
|
||||
@@ -10070,8 +10096,8 @@ sequence.y:8.3-45: @dwarning{warning}: rule useless in parser due to conflicts [
|
||||
8 | @dwarning{%empty @{ printf ("empty maybeword\n"); @}}
|
||||
| @dwarning{^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}
|
||||
@end group
|
||||
@end example
|
||||
@end iftex
|
||||
@end example
|
||||
|
||||
Each of these three conflicts, again, prove that the grammar is ambiguous.
|
||||
For instance, the second conflict (the reduce/reduce one) shows that the
|
||||
@@ -10096,10 +10122,10 @@ expr: %empty | expr ID ','
|
||||
|
||||
@command{bison} reports:
|
||||
|
||||
@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}]
|
||||
@ifnottex
|
||||
@group
|
||||
First example: @purple{expr} @red{•} @purple{ID ','} @green{ID} @yellow{$end}
|
||||
Shift derivation
|
||||
@@ -10120,12 +10146,8 @@ ids.y:4.4-7: @dwarning{warning}: rule useless in parser due to conflicts [@dwarn
|
||||
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
|
||||
@@ -10146,8 +10168,8 @@ ids.y:4.4-7: @dwarning{warning}: rule useless in parser due to conflicts [@dwarn
|
||||
4 | a: expr
|
||||
| ^~~~
|
||||
@end group
|
||||
@end example
|
||||
@end iftex
|
||||
@end example
|
||||
|
||||
This conflict is caused by the parser not having enough information to know
|
||||
the difference between these two examples. The parser would need an
|
||||
@@ -15631,6 +15653,10 @@ permitted. @xref{Language and Grammar}.
|
||||
A sequence of tokens and/or nonterminals, with one dot, that demonstrates a
|
||||
conflict. The dot marks the place where the conflict occurs.
|
||||
|
||||
@cindex unifying counterexample
|
||||
@cindex counterexample, unifying
|
||||
@cindex nonunifying counterexample
|
||||
@cindex counterexample, nonunifying
|
||||
A @emph{unifying} counterexample is a single string that has two different
|
||||
parses; its existence proves that the grammar is ambiguous. When a unifying
|
||||
counterexample cannot be found in reasonable time, a @emph{nonunifying}
|
||||
|
||||
+1
-1
@@ -57,7 +57,7 @@ MAINTAINERCLEANFILES = $(CROSS_OPTIONS_TEXI)
|
||||
|
||||
# Fix Info's @code in @deftype
|
||||
# https://lists.gnu.org/archive/html/help-texinfo/2019-11/msg00004.html
|
||||
all: $(srcdir)/$(%C%_bison).info.bak
|
||||
all-local: $(srcdir)/$(%C%_bison).info.bak
|
||||
$(srcdir)/$(%C%_bison).info.bak: $(srcdir)/$(%C%_bison).info
|
||||
$(AM_V_GEN) $(PERL) -pi.bak -0777 \
|
||||
-e 's{(^ --.*\n(?: {10}.*\n)*)}' \
|
||||
|
||||
+41
-29
@@ -185,13 +185,13 @@ my $verbose = 1;
|
||||
|
||||
=over 4
|
||||
|
||||
=item C<verbose($level, $message)>
|
||||
=item C<verbose ($level, $message)>
|
||||
|
||||
Report the C<$message> is C<$level> E<lt>= C<$verbose>.
|
||||
|
||||
=cut
|
||||
|
||||
sub verbose($$)
|
||||
sub verbose ($$)
|
||||
{
|
||||
my ($level, $message) = @_;
|
||||
print STDERR $message
|
||||
@@ -201,13 +201,13 @@ sub verbose($$)
|
||||
|
||||
######################################################################
|
||||
|
||||
=item C<directives($bench, @directive)>
|
||||
=item C<directives ($bench, @directive)>
|
||||
|
||||
Format the list of directives for Bison for bench named C<$bench>.
|
||||
|
||||
=cut
|
||||
|
||||
sub directives($@)
|
||||
sub directives ($@)
|
||||
{
|
||||
my ($bench, @directive) = @_;
|
||||
my $res = "/* Directives for bench '$bench'. */\n";
|
||||
@@ -218,6 +218,27 @@ sub directives($@)
|
||||
|
||||
######################################################################
|
||||
|
||||
=item C<is_pure (@directive)>
|
||||
|
||||
Whether api.pure is set.
|
||||
|
||||
=cut
|
||||
|
||||
sub is_pure (@)
|
||||
{
|
||||
my (@directive) = @_;
|
||||
for my $dir (@directive)
|
||||
{
|
||||
if ($dir =~ /\A%define api.pure/)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
######################################################################
|
||||
|
||||
=item C<generate_grammar_triangular ($base, $max, @directive)>
|
||||
|
||||
Create a large triangular grammar which looks like :
|
||||
@@ -389,18 +410,14 @@ sub generate_grammar_calc ($$@)
|
||||
%define api.value.type union
|
||||
$directives
|
||||
|
||||
%{
|
||||
%code provides {
|
||||
static int power (int base, int exponent);
|
||||
/* yyerror receives the location if:
|
||||
- %location & %pure & %glr
|
||||
- %location & %pure & %yacc & %parse-param. */
|
||||
static void yyerror (const char *s);
|
||||
#if YYPURE
|
||||
static int yylex (YYSTYPE* yylvalp);
|
||||
#else
|
||||
static int yylex (void);
|
||||
#endif
|
||||
%}
|
||||
static int yylex (@{[is_pure (@directive) ? "YYSTYPE *yylvalp" : "void"]});
|
||||
}
|
||||
|
||||
/* Bison Declarations */
|
||||
%token
|
||||
@@ -467,12 +484,7 @@ yyerror (const char *s)
|
||||
}
|
||||
|
||||
static int
|
||||
#if YYPURE
|
||||
# define yylval (*yylvalp)
|
||||
yylex (YYSTYPE* yylvalp)
|
||||
#else
|
||||
yylex (void)
|
||||
#endif
|
||||
yylex (@{[is_pure (@directive) ? "YYSTYPE *yylvalp" : "void"]})
|
||||
{
|
||||
int c;
|
||||
|
||||
@@ -498,7 +510,7 @@ yylex (void)
|
||||
case '5': case '6': case '7': case '8': case '9':
|
||||
{
|
||||
int nchars = 0;
|
||||
int n = sscanf (input - 1, "%d%n", &yylval.NUM, &nchars);
|
||||
int n = sscanf (input - 1, "%d%n", &@{[is_pure (@directive) ? "yylvalp->" : "yylval."]}NUM, &nchars);
|
||||
assert (n == 1);
|
||||
input += nchars - 1;
|
||||
return NUM;
|
||||
@@ -506,7 +518,7 @@ yylex (void)
|
||||
|
||||
default:
|
||||
yyerror ("error: invalid character");
|
||||
return yylex ();
|
||||
return yylex (@{[is_pure (@directive) ? "yylvalp" : ""]});
|
||||
}
|
||||
}
|
||||
EOF
|
||||
@@ -592,10 +604,10 @@ $directives
|
||||
// Prototype of the yylex function providing subsequent tokens.
|
||||
static
|
||||
#if USE_TOKEN_CTOR
|
||||
yy::parser::symbol_type yylex();
|
||||
yy::parser::symbol_type yylex ();
|
||||
#else
|
||||
yy::parser::token_type yylex(yy::parser::semantic_type* yylvalp,
|
||||
yy::parser::location_type* yyllocp);
|
||||
yy::parser::token_type yylex (yy::parser::semantic_type *yylvalp,
|
||||
yy::parser::location_type *yyllocp);
|
||||
#endif
|
||||
|
||||
// Conversion to string.
|
||||
@@ -618,8 +630,8 @@ EOF
|
||||
print $out <<'EOF';
|
||||
%token <std::string> TEXT
|
||||
%token <int> NUMBER
|
||||
%printer { std::cerr << "Number: " << $$; } <int>
|
||||
%printer { std::cerr << "Text: " << $$; } <std::string>
|
||||
%printer { yyo << "Number: " << $$; } <int>
|
||||
%printer { yyo << "Text: " << $$; } <std::string>
|
||||
%type <std::string> text result
|
||||
|
||||
%%
|
||||
@@ -641,8 +653,8 @@ EOF
|
||||
%union {int ival; std::string* sval;}
|
||||
%token <sval> TEXT
|
||||
%token <ival> NUMBER
|
||||
%printer { std::cerr << "Number: " << $$; } <ival>
|
||||
%printer { std::cerr << "Text: " << *$$; } <sval>
|
||||
%printer { yyo << "Number: " << $$; } <ival>
|
||||
%printer { yyo << "Text: " << *$$; } <sval>
|
||||
%type <sval> text result
|
||||
|
||||
%%
|
||||
@@ -664,10 +676,10 @@ EOF
|
||||
|
||||
static
|
||||
#if USE_TOKEN_CTOR
|
||||
yy::parser::symbol_type yylex()
|
||||
yy::parser::symbol_type yylex ()
|
||||
#else
|
||||
yy::parser::token_type yylex(yy::parser::semantic_type* yylvalp,
|
||||
yy::parser::location_type* yyllocp)
|
||||
yy::parser::token_type yylex (yy::parser::semantic_type *yylvalp,
|
||||
yy::parser::location_type *yyllocp)
|
||||
#endif
|
||||
{
|
||||
typedef yy::parser::location_type location_type;
|
||||
|
||||
@@ -251,29 +251,29 @@ err: Next token is token ) (1.4: )
|
||||
err: Shifting token ) (1.4: )
|
||||
err: Entering state 20
|
||||
err: Stack now 0 2 10 20
|
||||
err: Reducing stack by rule 15 (line 151):
|
||||
err: Reducing stack by rule XX (line XXX):
|
||||
err: $1 = token ( (1.1: )
|
||||
err: $2 = token error (1.2-3: )
|
||||
err: $3 = token ) (1.4: )
|
||||
err: -> $$ = nterm exp (1.1-4: 666)
|
||||
err: Entering state 7
|
||||
err: Stack now 0 7
|
||||
err: Entering state 8
|
||||
err: Stack now 0 8
|
||||
err: Return for a new token:
|
||||
err: Reading a token
|
||||
err: Now at end of input.
|
||||
err: LAC: initial context established for end of file
|
||||
err: LAC: checking lookahead end of file: R2 G8 S19
|
||||
err: Reducing stack by rule 2 (line 126):
|
||||
err: LAC: checking lookahead end of file: R2 G7 S14
|
||||
err: Reducing stack by rule XX (line XXX):
|
||||
err: $1 = nterm exp (1.1-4: 666)
|
||||
err: -> $$ = nterm input (1.1-4: )
|
||||
err: Entering state 8
|
||||
err: Stack now 0 8
|
||||
err: Entering state 7
|
||||
err: Stack now 0 7
|
||||
err: Now at end of input.
|
||||
err: Shifting token end of file (1.5: )
|
||||
err: LAC: initial context discarded due to shift
|
||||
err: Entering state 19
|
||||
err: Stack now 0 8 19
|
||||
err: Stack now 0 8 19
|
||||
err: Entering state 14
|
||||
err: Stack now 0 7 14
|
||||
err: Stack now 0 7 14
|
||||
err: Cleanup: popping token end of file (1.5: )
|
||||
err: Cleanup: popping nterm input (1.1-4: )' -p
|
||||
|
||||
|
||||
@@ -31,6 +31,13 @@ endif FLEX_WORKS
|
||||
|
||||
%D%/parse.c: $(dependencies)
|
||||
|
||||
# Tell Make scan.o depends on parse.h, except that Make sees only
|
||||
# parse.c, not parse.h. We can't use BUILT_SOURCES to this end, since
|
||||
# we use the built bison.
|
||||
%D%/lexcalc$(DASH)scan.o: %D%/parse.c
|
||||
# Likewise, but for Automake before 1.16.
|
||||
%D%/examples_c_lexcalc_lexcalc$(DASH)scan.o: %D%/parse.c
|
||||
|
||||
EXTRA_DIST += %D%/lexcalc.test
|
||||
dist_lexcalc_DATA = %D%/parse.y %D%/scan.l %D%/Makefile %D%/README.md
|
||||
CLEANFILES += %D%/parse.[ch] %D%/scan.c %D%/parse.output
|
||||
|
||||
+1
-1
@@ -27,7 +27,7 @@ EXTRA_DIST += %D%/calc.test
|
||||
|
||||
%D%/calc.d: %D%/calc.y $(dependencies)
|
||||
$(AM_V_GEN)$(MKDIR_P) %D%
|
||||
$(AM_V_at)$(BISON) $(srcdir)/%D%/calc.y -o $@
|
||||
$(AM_V_at)$(BISON) -o $@ $(srcdir)/%D%/calc.y
|
||||
|
||||
%D%/calc: %D%/calc.d
|
||||
$(AM_V_GEN) $(DC) $(DCFLAGS) -of$@ %D%/calc.d
|
||||
|
||||
@@ -27,7 +27,7 @@ EXTRA_DIST += %D%/Calc.test
|
||||
|
||||
%D%/Calc.java: %D%/Calc.y $(dependencies)
|
||||
$(AM_V_GEN)$(MKDIR_P) %D%
|
||||
$(AM_V_at)$(BISON) $(srcdir)/%D%/Calc.y -o $@
|
||||
$(AM_V_at)$(BISON) -o $@ $(srcdir)/%D%/Calc.y
|
||||
|
||||
%D%/Calc.class: %D%/Calc.java
|
||||
$(AM_V_GEN) $(SHELL) $(top_builddir)/javacomp.sh %D%/Calc.java
|
||||
|
||||
@@ -27,7 +27,7 @@ EXTRA_DIST += %D%/Calc.test
|
||||
|
||||
%D%/Calc.java: %D%/Calc.y $(dependencies)
|
||||
$(AM_V_GEN)$(MKDIR_P) %D%
|
||||
$(AM_V_at)$(BISON) $(srcdir)/%D%/Calc.y -o $@
|
||||
$(AM_V_at)$(BISON) -o $@ $(srcdir)/%D%/Calc.y
|
||||
|
||||
%D%/Calc.class: %D%/Calc.java
|
||||
$(AM_V_GEN) $(SHELL) $(top_builddir)/javacomp.sh %D%/Calc.java
|
||||
|
||||
+1
-1
Submodule gnulib updated: ac34618e85...160d5e7d9a
+3
-2
@@ -192,8 +192,6 @@
|
||||
/localcharset.h
|
||||
/locale.h
|
||||
/locale.in.h
|
||||
/localtime-buffer.c
|
||||
/localtime-buffer.h
|
||||
/lstat.c
|
||||
/malloc.c
|
||||
/malloca.c
|
||||
@@ -338,8 +336,11 @@
|
||||
/sys_types.in.h
|
||||
/sys_wait.in.h
|
||||
/sysexits.in.h
|
||||
/termios.h
|
||||
/termios.in.h
|
||||
/textstyle.h
|
||||
/textstyle.in.h
|
||||
/thread-optim.h
|
||||
/time.h
|
||||
/time.in.h
|
||||
/timespec.c
|
||||
|
||||
+4
-1
@@ -97,7 +97,6 @@
|
||||
/locale-ja.m4
|
||||
/locale-zh.m4
|
||||
/locale_h.m4
|
||||
/localtime-buffer.m4
|
||||
/lock.m4
|
||||
/longlong.m4
|
||||
/lstat.m4
|
||||
@@ -117,6 +116,7 @@
|
||||
/msvc-inval.m4
|
||||
/msvc-nothrow.m4
|
||||
/multiarch.m4
|
||||
/musl.m4
|
||||
/nls.m4
|
||||
/nocrash.m4
|
||||
/non-recursive-gnulib-prefix-hack.m4
|
||||
@@ -128,6 +128,7 @@
|
||||
/open.m4
|
||||
/pathmax.m4
|
||||
/perror.m4
|
||||
/pid_t.m4
|
||||
/pipe2.m4
|
||||
/po.m4
|
||||
/posix_spawn.m4
|
||||
@@ -184,6 +185,7 @@
|
||||
/strndup.m4
|
||||
/strnlen.m4
|
||||
/strverscmp.m4
|
||||
/sys_ioctl_h.m4
|
||||
/sys_resource_h.m4
|
||||
/sys_socket_h.m4
|
||||
/sys_stat_h.m4
|
||||
@@ -191,6 +193,7 @@
|
||||
/sys_times_h.m4
|
||||
/sys_types_h.m4
|
||||
/sys_wait_h.m4
|
||||
/termios_h.m4
|
||||
/threadlib.m4
|
||||
/time_h.m4
|
||||
/timespec.m4
|
||||
|
||||
+12
-17
@@ -113,13 +113,8 @@ free_counterexample (counterexample *cex)
|
||||
free (cex);
|
||||
}
|
||||
|
||||
static int max (int a, int b)
|
||||
{
|
||||
return a < b ? b : a;
|
||||
}
|
||||
|
||||
static void
|
||||
print_counterexample (const counterexample *cex, FILE *out, const char *prefix)
|
||||
counterexample_print (const counterexample *cex, FILE *out, const char *prefix)
|
||||
{
|
||||
const bool flat = getenv ("YYFLAT");
|
||||
const char *example1_label
|
||||
@@ -131,8 +126,8 @@ print_counterexample (const counterexample *cex, FILE *out, const char *prefix)
|
||||
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)));
|
||||
max_int (max_int (mbswidth (example1_label, 0), mbswidth (example2_label, 0)),
|
||||
max_int (mbswidth (deriv1_label, 0), mbswidth (deriv2_label, 0)));
|
||||
if (flat)
|
||||
fprintf (out, " %s%s%*s ", prefix,
|
||||
example1_label, width - mbswidth (example1_label, 0), "");
|
||||
@@ -526,7 +521,7 @@ nonunifying_shift_path (state_item_list reduce_path, state_item *shift_conflict)
|
||||
for (gl_list_iterator_t it = gl_list_iterator (result);
|
||||
state_item_list_next (&it, &sip);
|
||||
)
|
||||
print_state_item (sip, stderr, "");
|
||||
state_item_print (sip, stderr, "");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -717,10 +712,10 @@ ssb_equals (const search_state_bundle *s1, const search_state_bundle *s2)
|
||||
typedef gl_list_t ssb_list;
|
||||
|
||||
static size_t
|
||||
visited_hasher (const search_state *ss, size_t maximum)
|
||||
visited_hasher (const search_state *ss, size_t max)
|
||||
{
|
||||
return (parse_state_hasher (ss->states[0], maximum)
|
||||
+ parse_state_hasher (ss->states[1], maximum)) % maximum;
|
||||
return (parse_state_hasher (ss->states[0], max)
|
||||
+ parse_state_hasher (ss->states[1], max)) % max;
|
||||
}
|
||||
|
||||
static bool
|
||||
@@ -1267,7 +1262,7 @@ counterexample_report (state_item_number itm1, state_item_number itm2,
|
||||
: example_from_path (shift_reduce, itm2, shortest_path, next_sym);
|
||||
|
||||
gl_list_free (shortest_path);
|
||||
print_counterexample (cex, out, prefix);
|
||||
counterexample_print (cex, out, prefix);
|
||||
free_counterexample (cex);
|
||||
}
|
||||
|
||||
@@ -1290,8 +1285,8 @@ counterexample_report_shift_reduce (state_item_number itm1, state_item_number it
|
||||
// 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);
|
||||
state_item_print (&state_items[itm1], out, prefix);
|
||||
state_item_print (&state_items[itm2], out, prefix);
|
||||
}
|
||||
counterexample_report (itm1, itm2, next_sym, true, out, prefix);
|
||||
}
|
||||
@@ -1334,8 +1329,8 @@ counterexample_report_reduce_reduce (state_item_number itm1, state_item_number i
|
||||
// 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);
|
||||
state_item_print (&state_items[itm1], out, prefix);
|
||||
state_item_print (&state_items[itm2], out, prefix);
|
||||
}
|
||||
counterexample_report (itm1, itm2, bitset_first (conflict_syms),
|
||||
false, out, prefix);
|
||||
|
||||
+8
-14
@@ -76,12 +76,12 @@ void derivation_list_free (derivation_list dl)
|
||||
derivation *
|
||||
derivation_new (symbol_number sym, derivation_list children)
|
||||
{
|
||||
derivation *deriv = xmalloc (sizeof (derivation));
|
||||
deriv->sym = sym;
|
||||
deriv->children = children;
|
||||
deriv->reference_count = 0;
|
||||
deriv->color = -1;
|
||||
return deriv;
|
||||
derivation *res = xmalloc (sizeof *res);
|
||||
res->sym = sym;
|
||||
res->children = children;
|
||||
res->reference_count = 0;
|
||||
res->color = -1;
|
||||
return res;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -135,12 +135,6 @@ derivation_size (const derivation *deriv)
|
||||
}
|
||||
|
||||
|
||||
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)
|
||||
@@ -154,7 +148,7 @@ derivation_depth (const derivation *deriv)
|
||||
for (gl_list_iterator_t it = gl_list_iterator (deriv->children);
|
||||
derivation_list_next (&it, &child);
|
||||
)
|
||||
res = max (res, derivation_depth (child));
|
||||
res = max_int (res, derivation_depth (child));
|
||||
return res + 1;
|
||||
}
|
||||
else
|
||||
@@ -237,7 +231,7 @@ derivation_width (const derivation *deriv)
|
||||
// No separator at the beginning.
|
||||
children_width -= derivation_separator_width;
|
||||
}
|
||||
return max (self_width, children_width);
|
||||
return max_int (self_width, children_width);
|
||||
}
|
||||
else if (deriv == &d_dot)
|
||||
{
|
||||
|
||||
+9
-1
@@ -112,7 +112,15 @@ static struct obstack obstack_for_string;
|
||||
# define STRING_1GROW(Char) \
|
||||
obstack_1grow (&obstack_for_string, Char)
|
||||
|
||||
# define STRING_FREE() \
|
||||
# ifdef NDEBUG
|
||||
# define STRING_FREE() \
|
||||
obstack_free (&obstack_for_string, last_string)
|
||||
# else
|
||||
# define STRING_FREE() \
|
||||
do { \
|
||||
obstack_free (&obstack_for_string, last_string); \
|
||||
last_string = NULL; \
|
||||
} while (0)
|
||||
# endif
|
||||
|
||||
#endif
|
||||
|
||||
+1
-1
@@ -423,7 +423,7 @@ ielr_item_has_lookahead (state *s, symbol_number lhs, size_t item,
|
||||
check all predecessors' goto follows for the LHS. */
|
||||
if (item_number_is_rule_number (ritem[s->items[item] - 2]))
|
||||
{
|
||||
aver (lhs != accept->content->number);
|
||||
aver (lhs != acceptsymbol->content->number);
|
||||
for (state **predecessor = predecessors[s->number];
|
||||
*predecessor;
|
||||
++predecessor)
|
||||
|
||||
@@ -143,7 +143,6 @@ src_bison_LDADD = \
|
||||
$(LIB_SETLOCALE_NULL) \
|
||||
$(LIBICONV) \
|
||||
$(LIBINTL) \
|
||||
$(LIBREADLINE) \
|
||||
$(LIBTEXTSTYLE)
|
||||
|
||||
|
||||
|
||||
+3
-13
@@ -40,18 +40,6 @@
|
||||
|
||||
location const empty_loc = EMPTY_LOCATION_INIT;
|
||||
|
||||
static int
|
||||
min_int (int a, int b)
|
||||
{
|
||||
return a < b ? a : b;
|
||||
}
|
||||
|
||||
static int
|
||||
max_int (int a, int b)
|
||||
{
|
||||
return a >= b ? a : b;
|
||||
}
|
||||
|
||||
/* The terminal width. Not less than 40. */
|
||||
static int
|
||||
columns (void)
|
||||
@@ -167,7 +155,9 @@ int
|
||||
location_print (location loc, FILE *out)
|
||||
{
|
||||
int res = 0;
|
||||
if (trace_flag & trace_locations)
|
||||
if (location_empty (loc))
|
||||
res += fprintf (out, "(empty location)");
|
||||
else if (trace_flag & trace_locations)
|
||||
{
|
||||
res += boundary_print (&loc.start, out);
|
||||
res += fprintf (out, "-");
|
||||
|
||||
+1
-1
@@ -256,7 +256,7 @@ shortest_path_from_start (state_item_number target, symbol_number next_sym)
|
||||
gl_list_iterator_t it = gl_list_iterator (res);
|
||||
const void *sip;
|
||||
while (gl_list_iterator_next (&it, &sip, NULL))
|
||||
print_state_item ((state_item *) sip, stdout, "");
|
||||
state_item_print ((state_item *) sip, stdout, "");
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
+4
-4
@@ -249,7 +249,7 @@ prepare_symbol_names (char const *muscle_name)
|
||||
if (i)
|
||||
obstack_1grow (&format_obstack, ' ');
|
||||
if (translatable)
|
||||
obstack_sgrow (&format_obstack, "]b4_symbol_translate([");
|
||||
obstack_sgrow (&format_obstack, "]b4_symbol_translate""([");
|
||||
obstack_escape (&format_obstack, cp);
|
||||
if (translatable)
|
||||
obstack_sgrow (&format_obstack, "])[");
|
||||
@@ -554,7 +554,7 @@ prepare_symbol_definitions (void)
|
||||
/* Map "orig NUM" to new numbers. See data/README. */
|
||||
for (symbol_number i = ntokens; i < nsyms + nuseless_nonterminals; ++i)
|
||||
{
|
||||
obstack_printf (&format_obstack, "symbol(orig %d, number)", i);
|
||||
obstack_printf (&format_obstack, "symbol""(orig %d, number)", i);
|
||||
const char *key = obstack_finish0 (&format_obstack);
|
||||
MUSCLE_INSERT_INT (key, nterm_map ? nterm_map[i - ntokens] : i);
|
||||
}
|
||||
@@ -565,12 +565,12 @@ prepare_symbol_definitions (void)
|
||||
const char *key;
|
||||
|
||||
#define SET_KEY(Entry) \
|
||||
obstack_printf (&format_obstack, "symbol(%d, %s)", \
|
||||
obstack_printf (&format_obstack, "symbol""(%d, %s)", \
|
||||
i, Entry); \
|
||||
key = obstack_finish0 (&format_obstack);
|
||||
|
||||
#define SET_KEY2(Entry, Suffix) \
|
||||
obstack_printf (&format_obstack, "symbol(%d, %s_%s)", \
|
||||
obstack_printf (&format_obstack, "symbol""(%d, %s_%s)", \
|
||||
i, Entry, Suffix); \
|
||||
key = obstack_finish0 (&format_obstack);
|
||||
|
||||
|
||||
+22
-23
@@ -1,4 +1,4 @@
|
||||
/* A Bison parser, made by GNU Bison 3.6.90. */
|
||||
/* A Bison parser, made by GNU Bison 3.7.14-eb26-dirty. */
|
||||
|
||||
/* Bison implementation for Yacc-like parsers in C
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
#define YYBISON 1
|
||||
|
||||
/* Bison version. */
|
||||
#define YYBISON_VERSION "3.6.90"
|
||||
#define YYBISON_VERSION "3.7.14-eb26-dirty"
|
||||
|
||||
/* Skeleton name. */
|
||||
#define YYSKELETON_NAME "yacc.c"
|
||||
@@ -149,7 +149,7 @@ enum yysymbol_kind_t
|
||||
YYSYMBOL_BRACED_CODE = 41, /* "{...}" */
|
||||
YYSYMBOL_BRACED_PREDICATE = 42, /* "%?{...}" */
|
||||
YYSYMBOL_BRACKETED_ID = 43, /* "[identifier]" */
|
||||
YYSYMBOL_CHAR = 44, /* "character literal" */
|
||||
YYSYMBOL_CHAR_LITERAL = 44, /* "character literal" */
|
||||
YYSYMBOL_COLON = 45, /* ":" */
|
||||
YYSYMBOL_EPILOGUE = 46, /* "epilogue" */
|
||||
YYSYMBOL_EQUAL = 47, /* "=" */
|
||||
@@ -162,7 +162,7 @@ enum yysymbol_kind_t
|
||||
YYSYMBOL_TAG = 54, /* "<tag>" */
|
||||
YYSYMBOL_TAG_ANY = 55, /* "<*>" */
|
||||
YYSYMBOL_TAG_NONE = 56, /* "<>" */
|
||||
YYSYMBOL_INT = 57, /* "integer literal" */
|
||||
YYSYMBOL_INT_LITERAL = 57, /* "integer literal" */
|
||||
YYSYMBOL_PERCENT_PARAM = 58, /* "%param" */
|
||||
YYSYMBOL_PERCENT_UNION = 59, /* "%union" */
|
||||
YYSYMBOL_PERCENT_EMPTY = 60, /* "%empty" */
|
||||
@@ -1115,8 +1115,8 @@ tron (yyo);
|
||||
{ fprintf (yyo, "[%s]", ((*yyvaluep).BRACKETED_ID)); }
|
||||
break;
|
||||
|
||||
case YYSYMBOL_CHAR: /* "character literal" */
|
||||
{ fputs (char_name (((*yyvaluep).CHAR)), yyo); }
|
||||
case YYSYMBOL_CHAR_LITERAL: /* "character literal" */
|
||||
{ fputs (char_name (((*yyvaluep).CHAR_LITERAL)), yyo); }
|
||||
break;
|
||||
|
||||
case YYSYMBOL_EPILOGUE: /* "epilogue" */
|
||||
@@ -1139,8 +1139,8 @@ tron (yyo);
|
||||
{ fprintf (yyo, "<%s>", ((*yyvaluep).TAG)); }
|
||||
break;
|
||||
|
||||
case YYSYMBOL_INT: /* "integer literal" */
|
||||
{ fprintf (yyo, "%d", ((*yyvaluep).INT)); }
|
||||
case YYSYMBOL_INT_LITERAL: /* "integer literal" */
|
||||
{ fprintf (yyo, "%d", ((*yyvaluep).INT_LITERAL)); }
|
||||
break;
|
||||
|
||||
case YYSYMBOL_PERCENT_PARAM: /* "%param" */
|
||||
@@ -2087,11 +2087,11 @@ yyreduce:
|
||||
break;
|
||||
|
||||
case 12: /* prologue_declaration: "%expect" "integer literal" */
|
||||
{ expected_sr_conflicts = (yyvsp[0].INT); }
|
||||
{ expected_sr_conflicts = (yyvsp[0].INT_LITERAL); }
|
||||
break;
|
||||
|
||||
case 13: /* prologue_declaration: "%expect-rr" "integer literal" */
|
||||
{ expected_rr_conflicts = (yyvsp[0].INT); }
|
||||
{ expected_rr_conflicts = (yyvsp[0].INT_LITERAL); }
|
||||
break;
|
||||
|
||||
case 14: /* prologue_declaration: "%file-prefix" "string" */
|
||||
@@ -2339,13 +2339,13 @@ yyreduce:
|
||||
|
||||
case 67: /* token_decls: "<tag>" token_decl.1 */
|
||||
{
|
||||
(yyval.token_decls) = symbol_list_type_set ((yyvsp[0].yykind_80), (yyvsp[-1].TAG), (yylsp[-1]));
|
||||
(yyval.token_decls) = symbol_list_type_set ((yyvsp[0].yykind_80), (yyvsp[-1].TAG));
|
||||
}
|
||||
break;
|
||||
|
||||
case 68: /* token_decls: token_decls "<tag>" token_decl.1 */
|
||||
{
|
||||
(yyval.token_decls) = symbol_list_append ((yyvsp[-2].token_decls), symbol_list_type_set ((yyvsp[0].yykind_80), (yyvsp[-1].TAG), (yylsp[-1])));
|
||||
(yyval.token_decls) = symbol_list_append ((yyvsp[-2].token_decls), symbol_list_type_set ((yyvsp[0].yykind_80), (yyvsp[-1].TAG)));
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -2396,13 +2396,13 @@ yyreduce:
|
||||
|
||||
case 78: /* token_decls_for_prec: "<tag>" token_decl_for_prec.1 */
|
||||
{
|
||||
(yyval.token_decls_for_prec) = symbol_list_type_set ((yyvsp[0].yykind_85), (yyvsp[-1].TAG), (yylsp[-1]));
|
||||
(yyval.token_decls_for_prec) = symbol_list_type_set ((yyvsp[0].yykind_85), (yyvsp[-1].TAG));
|
||||
}
|
||||
break;
|
||||
|
||||
case 79: /* token_decls_for_prec: token_decls_for_prec "<tag>" token_decl_for_prec.1 */
|
||||
{
|
||||
(yyval.token_decls_for_prec) = symbol_list_append ((yyvsp[-2].token_decls_for_prec), symbol_list_type_set ((yyvsp[0].yykind_85), (yyvsp[-1].TAG), (yylsp[-1])));
|
||||
(yyval.token_decls_for_prec) = symbol_list_append ((yyvsp[-2].token_decls_for_prec), symbol_list_type_set ((yyvsp[0].yykind_85), (yyvsp[-1].TAG)));
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -2431,13 +2431,13 @@ yyreduce:
|
||||
|
||||
case 85: /* symbol_decls: "<tag>" symbol_decl.1 */
|
||||
{
|
||||
(yyval.symbol_decls) = symbol_list_type_set ((yyvsp[0].yykind_88), (yyvsp[-1].TAG), (yylsp[-1]));
|
||||
(yyval.symbol_decls) = symbol_list_type_set ((yyvsp[0].yykind_88), (yyvsp[-1].TAG));
|
||||
}
|
||||
break;
|
||||
|
||||
case 86: /* symbol_decls: symbol_decls "<tag>" symbol_decl.1 */
|
||||
{
|
||||
(yyval.symbol_decls) = symbol_list_append ((yyvsp[-2].symbol_decls), symbol_list_type_set ((yyvsp[0].yykind_88), (yyvsp[-1].TAG), (yylsp[-1])));
|
||||
(yyval.symbol_decls) = symbol_list_append ((yyvsp[-2].symbol_decls), symbol_list_type_set ((yyvsp[0].yykind_88), (yyvsp[-1].TAG)));
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -2506,7 +2506,7 @@ yyreduce:
|
||||
break;
|
||||
|
||||
case 105: /* rhs: rhs "%dprec" "integer literal" */
|
||||
{ grammar_current_rule_dprec_set ((yyvsp[0].INT), (yylsp[0])); }
|
||||
{ grammar_current_rule_dprec_set ((yyvsp[0].INT_LITERAL), (yylsp[0])); }
|
||||
break;
|
||||
|
||||
case 106: /* rhs: rhs "%merge" "<tag>" */
|
||||
@@ -2514,11 +2514,11 @@ yyreduce:
|
||||
break;
|
||||
|
||||
case 107: /* rhs: rhs "%expect" "integer literal" */
|
||||
{ grammar_current_rule_expect_sr ((yyvsp[0].INT), (yylsp[0])); }
|
||||
{ grammar_current_rule_expect_sr ((yyvsp[0].INT_LITERAL), (yylsp[0])); }
|
||||
break;
|
||||
|
||||
case 108: /* rhs: rhs "%expect-rr" "integer literal" */
|
||||
{ grammar_current_rule_expect_rr ((yyvsp[0].INT), (yylsp[0])); }
|
||||
{ grammar_current_rule_expect_rr ((yyvsp[0].INT_LITERAL), (yylsp[0])); }
|
||||
break;
|
||||
|
||||
case 109: /* named_ref.opt: %empty */
|
||||
@@ -2566,9 +2566,9 @@ yyreduce:
|
||||
location loc = muscle_percent_define_get_loc (var);
|
||||
subcomplain (&loc, complaint, _("definition of %s"), var);
|
||||
}
|
||||
(yyval.id) = symbol_get (char_name ((yyvsp[0].CHAR)), (yylsp[0]));
|
||||
(yyval.id) = symbol_get (char_name ((yyvsp[0].CHAR_LITERAL)), (yylsp[0]));
|
||||
symbol_class_set ((yyval.id), token_sym, (yylsp[0]), false);
|
||||
symbol_code_set ((yyval.id), (yyvsp[0].CHAR), (yylsp[0]));
|
||||
symbol_code_set ((yyval.id), (yyvsp[0].CHAR_LITERAL), (yylsp[0]));
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -3147,8 +3147,7 @@ char_name (char c)
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
static void
|
||||
current_lhs (symbol *sym, location loc, named_ref *ref)
|
||||
{
|
||||
current_lhs_symbol = sym;
|
||||
|
||||
+5
-5
@@ -1,4 +1,4 @@
|
||||
/* A Bison parser, made by GNU Bison 3.6.90. */
|
||||
/* A Bison parser, made by GNU Bison 3.7.14-eb26-dirty. */
|
||||
|
||||
/* Bison interface for Yacc-like parsers in C
|
||||
|
||||
@@ -123,7 +123,7 @@ extern int gram_debug;
|
||||
BRACED_CODE = 41, /* "{...}" */
|
||||
BRACED_PREDICATE = 42, /* "%?{...}" */
|
||||
BRACKETED_ID = 43, /* "[identifier]" */
|
||||
CHAR = 44, /* "character literal" */
|
||||
CHAR_LITERAL = 44, /* "character literal" */
|
||||
COLON = 45, /* ":" */
|
||||
EPILOGUE = 46, /* "epilogue" */
|
||||
EQUAL = 47, /* "=" */
|
||||
@@ -136,7 +136,7 @@ extern int gram_debug;
|
||||
TAG = 54, /* "<tag>" */
|
||||
TAG_ANY = 55, /* "<*>" */
|
||||
TAG_NONE = 56, /* "<>" */
|
||||
INT = 57, /* "integer literal" */
|
||||
INT_LITERAL = 57, /* "integer literal" */
|
||||
PERCENT_PARAM = 58, /* "%param" */
|
||||
PERCENT_UNION = 59, /* "%union" */
|
||||
PERCENT_EMPTY = 60 /* "%empty" */
|
||||
@@ -156,7 +156,7 @@ union GRAM_STYPE
|
||||
char* EPILOGUE; /* "epilogue" */
|
||||
char* PROLOGUE; /* "%{...%}" */
|
||||
code_props_type code_props_type; /* code_props_type */
|
||||
int INT; /* "integer literal" */
|
||||
int INT_LITERAL; /* "integer literal" */
|
||||
int yykind_82; /* int.opt */
|
||||
named_ref* yykind_95; /* named_ref.opt */
|
||||
param_type PERCENT_PARAM; /* "%param" */
|
||||
@@ -188,7 +188,7 @@ union GRAM_STYPE
|
||||
uniqstr yykind_74; /* tag.opt */
|
||||
uniqstr tag; /* tag */
|
||||
uniqstr variable; /* variable */
|
||||
unsigned char CHAR; /* "character literal" */
|
||||
unsigned char CHAR_LITERAL; /* "character literal" */
|
||||
value_type value; /* value */
|
||||
|
||||
|
||||
|
||||
+17
-18
@@ -214,7 +214,7 @@
|
||||
BRACED_CODE "{...}"
|
||||
BRACED_PREDICATE "%?{...}"
|
||||
BRACKETED_ID _("[identifier]")
|
||||
CHAR _("character literal")
|
||||
CHAR_LITERAL _("character literal")
|
||||
COLON ":"
|
||||
EPILOGUE _("epilogue")
|
||||
EQUAL "="
|
||||
@@ -232,7 +232,7 @@
|
||||
%code pre-printer {tron (yyo);}
|
||||
%code post-printer {troff (yyo);}
|
||||
|
||||
%type <unsigned char> CHAR
|
||||
%type <unsigned char> CHAR_LITERAL
|
||||
%printer { fputs (char_name ($$), yyo); } <unsigned char>
|
||||
|
||||
%type <char*> "{...}" "%?{...}" "%{...%}" EPILOGUE STRING TSTRING
|
||||
@@ -249,7 +249,7 @@
|
||||
%printer { fprintf (yyo, "%%%s", $$); } PERCENT_FLAG
|
||||
%printer { fprintf (yyo, "<%s>", $$); } TAG tag
|
||||
|
||||
%token <int> INT _("integer literal")
|
||||
%token <int> INT_LITERAL _("integer literal")
|
||||
%printer { fprintf (yyo, "%d", $$); } <int>
|
||||
|
||||
%type <symbol*> id id_colon string_as_id symbol token_decl token_decl_for_prec
|
||||
@@ -342,8 +342,8 @@ prologue_declaration:
|
||||
| "%defines" { defines_flag = true; }
|
||||
| "%defines" STRING { handle_defines ($2); }
|
||||
| "%error-verbose" { handle_error_verbose (&@$, $1); }
|
||||
| "%expect" INT { expected_sr_conflicts = $2; }
|
||||
| "%expect-rr" INT { expected_rr_conflicts = $2; }
|
||||
| "%expect" INT_LITERAL { expected_sr_conflicts = $2; }
|
||||
| "%expect-rr" INT_LITERAL { expected_rr_conflicts = $2; }
|
||||
| "%file-prefix" STRING { handle_file_prefix (&@$, &@1, $1, $2); }
|
||||
| "%glr-parser"
|
||||
{
|
||||
@@ -532,11 +532,11 @@ token_decls:
|
||||
}
|
||||
| TAG token_decl.1[syms]
|
||||
{
|
||||
$$ = symbol_list_type_set ($syms, $TAG, @TAG);
|
||||
$$ = symbol_list_type_set ($syms, $TAG);
|
||||
}
|
||||
| token_decls TAG token_decl.1[syms]
|
||||
{
|
||||
$$ = symbol_list_append ($1, symbol_list_type_set ($syms, $TAG, @TAG));
|
||||
$$ = symbol_list_append ($1, symbol_list_type_set ($syms, $TAG));
|
||||
}
|
||||
;
|
||||
|
||||
@@ -561,7 +561,7 @@ token_decl:
|
||||
%type <int> int.opt;
|
||||
int.opt:
|
||||
%empty { $$ = -1; }
|
||||
| INT
|
||||
| INT_LITERAL
|
||||
;
|
||||
|
||||
%type <symbol*> alias;
|
||||
@@ -592,11 +592,11 @@ token_decls_for_prec:
|
||||
}
|
||||
| TAG token_decl_for_prec.1[syms]
|
||||
{
|
||||
$$ = symbol_list_type_set ($syms, $TAG, @TAG);
|
||||
$$ = symbol_list_type_set ($syms, $TAG);
|
||||
}
|
||||
| token_decls_for_prec TAG token_decl_for_prec.1[syms]
|
||||
{
|
||||
$$ = symbol_list_append ($1, symbol_list_type_set ($syms, $TAG, @TAG));
|
||||
$$ = symbol_list_append ($1, symbol_list_type_set ($syms, $TAG));
|
||||
}
|
||||
;
|
||||
|
||||
@@ -632,11 +632,11 @@ symbol_decls:
|
||||
}
|
||||
| TAG symbol_decl.1[syms]
|
||||
{
|
||||
$$ = symbol_list_type_set ($syms, $TAG, @TAG);
|
||||
$$ = symbol_list_type_set ($syms, $TAG);
|
||||
}
|
||||
| symbol_decls TAG symbol_decl.1[syms]
|
||||
{
|
||||
$$ = symbol_list_append ($1, symbol_list_type_set ($syms, $TAG, @TAG));
|
||||
$$ = symbol_list_append ($1, symbol_list_type_set ($syms, $TAG));
|
||||
}
|
||||
;
|
||||
|
||||
@@ -703,13 +703,13 @@ rhs:
|
||||
{ grammar_current_rule_empty_set (@2); }
|
||||
| rhs "%prec" symbol
|
||||
{ grammar_current_rule_prec_set ($3, @3); }
|
||||
| rhs "%dprec" INT
|
||||
| rhs "%dprec" INT_LITERAL
|
||||
{ grammar_current_rule_dprec_set ($3, @3); }
|
||||
| rhs "%merge" TAG
|
||||
{ grammar_current_rule_merge_set ($3, @3); }
|
||||
| rhs "%expect" INT
|
||||
| rhs "%expect" INT_LITERAL
|
||||
{ grammar_current_rule_expect_sr ($3, @3); }
|
||||
| rhs "%expect-rr" INT
|
||||
| rhs "%expect-rr" INT_LITERAL
|
||||
{ grammar_current_rule_expect_rr ($3, @3); }
|
||||
;
|
||||
|
||||
@@ -765,7 +765,7 @@ value:
|
||||
id:
|
||||
ID
|
||||
{ $$ = symbol_from_uniqstr ($1, @1); }
|
||||
| CHAR
|
||||
| CHAR_LITERAL
|
||||
{
|
||||
const char *var = "api.token.raw";
|
||||
if (current_class == nterm_sym)
|
||||
@@ -1158,8 +1158,7 @@ char_name (char c)
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
static void
|
||||
current_lhs (symbol *sym, location loc, named_ref *ref)
|
||||
{
|
||||
current_lhs_symbol = sym;
|
||||
|
||||
+15
-19
@@ -28,19 +28,19 @@
|
||||
#include "lssi.h"
|
||||
#include "nullable.h"
|
||||
|
||||
typedef struct parse_state
|
||||
struct parse_state
|
||||
{
|
||||
// path of state-items the parser has traversed
|
||||
// Path of state-items the parser has traversed.
|
||||
struct si_chunk
|
||||
{
|
||||
// elements newly added in this chunk
|
||||
// Elements newly added in this chunk.
|
||||
state_item_list contents;
|
||||
// properties of the linked list this chunk represents
|
||||
// Properties of the linked list this chunk represents.
|
||||
const state_item *head_elt;
|
||||
const state_item *tail_elt;
|
||||
size_t total_size;
|
||||
} state_items;
|
||||
// list of derivations of the symbols
|
||||
// List of derivations of the symbols.
|
||||
struct deriv_chunk
|
||||
{
|
||||
derivation_list contents;
|
||||
@@ -50,18 +50,15 @@ typedef struct parse_state
|
||||
} derivs;
|
||||
struct parse_state *parent;
|
||||
int reference_count;
|
||||
// incremented during productions,
|
||||
// decremented during reductions
|
||||
// Incremented during productions, decremented during reductions.
|
||||
int depth;
|
||||
// whether the contents of the chunks should be
|
||||
// prepended or appended to the list the chunks
|
||||
// represent
|
||||
// Whether the contents of the chunks should be prepended or
|
||||
// appended to the list the chunks represent.
|
||||
bool prepend;
|
||||
// causes chunk contents to be freed when the
|
||||
// reference count is one. Used when only the chunk metadata
|
||||
// will be needed.
|
||||
// Causes chunk contents to be freed when the reference count is
|
||||
// one. Used when only the chunk metadata will be needed.
|
||||
bool free_contents_early;
|
||||
} parse_state;
|
||||
};
|
||||
|
||||
|
||||
static void
|
||||
@@ -438,9 +435,8 @@ simulate_transition (parse_state *ps)
|
||||
// symbols into account.
|
||||
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
|
||||
// disabled.
|
||||
// Check for disabled transition, shouldn't happen as any
|
||||
// state_items that lead to these should be disabled.
|
||||
if (si_next < 0)
|
||||
return result;
|
||||
parse_state *next_ps = copy_parse_state (false, ps);
|
||||
@@ -594,8 +590,8 @@ print_parse_state (parse_state *ps)
|
||||
FILE *out = stderr;
|
||||
fprintf (out, "(size %zu depth %d rc %d)\n",
|
||||
ps->state_items.total_size, ps->depth, ps->reference_count);
|
||||
print_state_item (ps->state_items.head_elt, out, "");
|
||||
print_state_item (ps->state_items.tail_elt, out, "");
|
||||
state_item_print (ps->state_items.head_elt, out, "");
|
||||
state_item_print (ps->state_items.tail_elt, out, "");
|
||||
if (ps->derivs.total_size > 0)
|
||||
derivation_print (ps->derivs.head_elt, out, "");
|
||||
putc ('\n', out);
|
||||
|
||||
+8
-5
@@ -406,8 +406,8 @@ grammar_midrule_action (void)
|
||||
action. Create the MIDRULE. */
|
||||
location dummy_loc = current_rule->action_props.location;
|
||||
symbol *dummy = dummy_symbol_get (dummy_loc);
|
||||
symbol_type_set(dummy,
|
||||
current_rule->action_props.type, current_rule->action_props.location);
|
||||
symbol_type_set (dummy,
|
||||
current_rule->action_props.type, current_rule->action_props.location);
|
||||
symbol_list *midrule = symbol_list_sym_new (dummy, dummy_loc);
|
||||
|
||||
/* Remember named_ref of previous action. */
|
||||
@@ -804,7 +804,7 @@ check_and_convert_grammar (void)
|
||||
|
||||
$accept: %start $end. */
|
||||
{
|
||||
symbol_list *p = symbol_list_sym_new (accept, empty_loc);
|
||||
symbol_list *p = symbol_list_sym_new (acceptsymbol, empty_loc);
|
||||
p->rhs_loc = grammar->rhs_loc;
|
||||
p->next = symbol_list_sym_new (startsymbol, empty_loc);
|
||||
p->next->next = symbol_list_sym_new (eoftoken, empty_loc);
|
||||
@@ -815,8 +815,11 @@ check_and_convert_grammar (void)
|
||||
grammar = p;
|
||||
}
|
||||
|
||||
aver (nsyms <= SYMBOL_NUMBER_MAXIMUM);
|
||||
aver (nsyms == ntokens + nnterms);
|
||||
if (SYMBOL_NUMBER_MAXIMUM - nnterms < ntokens)
|
||||
complain (NULL, fatal, "too many symbols in input grammar (limit is %d)",
|
||||
SYMBOL_NUMBER_MAXIMUM);
|
||||
|
||||
nsyms = ntokens + nnterms;
|
||||
|
||||
/* Assign the symbols their symbol numbers. */
|
||||
symbols_pack ();
|
||||
|
||||
+4
-4
@@ -160,9 +160,9 @@ inaccessable_symbols (void)
|
||||
bitset Pp = bitset_create (nrules, BITSET_FIXED);
|
||||
|
||||
/* If the start symbol isn't useful, then nothing will be useful. */
|
||||
if (bitset_test (N, accept->content->number - ntokens))
|
||||
if (bitset_test (N, acceptsymbol->content->number - ntokens))
|
||||
{
|
||||
bitset_set (V, accept->content->number);
|
||||
bitset_set (V, acceptsymbol->content->number);
|
||||
|
||||
while (1)
|
||||
{
|
||||
@@ -301,7 +301,7 @@ nonterminals_reduce (void)
|
||||
for (item_number *rhsp = rules[r].rhs; 0 <= *rhsp; ++rhsp)
|
||||
if (ISVAR (*rhsp))
|
||||
*rhsp = symbol_number_as_item_number (nterm_map[*rhsp - ntokens]);
|
||||
accept->content->number = nterm_map[accept->content->number - ntokens];
|
||||
acceptsymbol->content->number = nterm_map[acceptsymbol->content->number - ntokens];
|
||||
}
|
||||
|
||||
nsyms -= nuseless_nonterminals;
|
||||
@@ -381,7 +381,7 @@ reduce_grammar (void)
|
||||
{
|
||||
reduce_print ();
|
||||
|
||||
if (!bitset_test (N, accept->content->number - ntokens))
|
||||
if (!bitset_test (N, acceptsymbol->content->number - ntokens))
|
||||
complain (&startsymbol_loc, fatal,
|
||||
_("start symbol %s does not derive any sentence"),
|
||||
startsymbol->tag);
|
||||
|
||||
+21
-12
@@ -322,8 +322,8 @@ eqopt ({sp}=)?
|
||||
BEGIN SC_AFTER_IDENTIFIER;
|
||||
}
|
||||
|
||||
{int} RETURN_VALUE (INT, scan_integer (yytext, 10, *loc));
|
||||
{xint} RETURN_VALUE (INT, scan_integer (yytext, 16, *loc));
|
||||
{int} RETURN_VALUE (INT_LITERAL, scan_integer (yytext, 10, *loc));
|
||||
{xint} RETURN_VALUE (INT_LITERAL, scan_integer (yytext, 16, *loc));
|
||||
|
||||
/* Identifiers may not start with a digit. Yet, don't silently
|
||||
accept "1FOO" as "1 FOO". */
|
||||
@@ -403,6 +403,7 @@ eqopt ({sp}=)?
|
||||
{
|
||||
\0 {
|
||||
complain (loc, complaint, _("invalid null character"));
|
||||
STRING_FINISH ();
|
||||
STRING_FREE ();
|
||||
return GRAM_error;
|
||||
}
|
||||
@@ -566,6 +567,8 @@ eqopt ({sp}=)?
|
||||
_("POSIX Yacc does not support string literals"));
|
||||
RETURN_VALUE (STRING, last_string);
|
||||
}
|
||||
<<EOF>> unexpected_eof (token_start, "\"");
|
||||
"\n" unexpected_newline (token_start, "\"");
|
||||
}
|
||||
|
||||
<SC_ESCAPED_TSTRING>
|
||||
@@ -579,13 +582,10 @@ eqopt ({sp}=)?
|
||||
_("POSIX Yacc does not support string literals"));
|
||||
RETURN_VALUE (TSTRING, last_string);
|
||||
}
|
||||
<<EOF>> unexpected_eof (token_start, "\")");
|
||||
"\n" unexpected_newline (token_start, "\")");
|
||||
}
|
||||
|
||||
<SC_ESCAPED_STRING,SC_ESCAPED_TSTRING>
|
||||
{
|
||||
<<EOF>> unexpected_eof (token_start, "\"");
|
||||
"\n" unexpected_newline (token_start, "\"");
|
||||
}
|
||||
|
||||
|
||||
/*----------------------------------------------------------.
|
||||
@@ -599,7 +599,6 @@ eqopt ({sp}=)?
|
||||
STRING_FINISH ();
|
||||
BEGIN INITIAL;
|
||||
loc->start = token_start;
|
||||
val->CHAR = last_string[0];
|
||||
|
||||
if (last_string[0] == '\0')
|
||||
{
|
||||
@@ -615,8 +614,9 @@ eqopt ({sp}=)?
|
||||
}
|
||||
else
|
||||
{
|
||||
val->CHAR_LITERAL = last_string[0];
|
||||
STRING_FREE ();
|
||||
return CHAR;
|
||||
return CHAR_LITERAL;
|
||||
}
|
||||
}
|
||||
{eol} unexpected_newline (token_start, "'");
|
||||
@@ -691,6 +691,15 @@ eqopt ({sp}=)?
|
||||
p);
|
||||
STRING_1GROW ('?');
|
||||
}
|
||||
|
||||
"\\" {
|
||||
// None of the other rules matched: the last character of this
|
||||
// file is "\". But Flex does not support "\\<<EOF>>".
|
||||
unexpected_eof (token_start,
|
||||
YY_START == SC_ESCAPED_CHARACTER ? "?'"
|
||||
: YY_START == SC_ESCAPED_STRING ? "?\""
|
||||
: "?\")");
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------.
|
||||
@@ -933,9 +942,9 @@ convert_ucn_to_byte (char const *ucn)
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------.
|
||||
| Handle '#line INT( "FILE")?\n'. ARGS has already skipped '#line '. |
|
||||
`---------------------------------------------------------------------*/
|
||||
/*----------------------------------------------------------------------------.
|
||||
| Handle '#line INT_LITERAL( "FILE")?\n'. ARGS has already skipped '#line '. |
|
||||
`----------------------------------------------------------------------------*/
|
||||
|
||||
static void
|
||||
handle_syncline (char *args, location loc)
|
||||
|
||||
+3
-3
@@ -475,7 +475,7 @@ prune_disabled_paths (void)
|
||||
}
|
||||
|
||||
void
|
||||
print_state_item (const state_item *si, FILE *out, const char *prefix)
|
||||
state_item_print (const state_item *si, FILE *out, const char *prefix)
|
||||
{
|
||||
fputs (prefix, out);
|
||||
item_print (si->item, NULL, out);
|
||||
@@ -506,7 +506,7 @@ state_items_report (void)
|
||||
if (si->trans >= 0)
|
||||
{
|
||||
fputs (" -> ", stdout);
|
||||
print_state_item (&state_items[si->trans], stdout, "");
|
||||
state_item_print (&state_items[si->trans], stdout, "");
|
||||
}
|
||||
|
||||
bitset sets[2] = { si->prods, si->revs };
|
||||
@@ -521,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, "");
|
||||
state_item_print (&state_items[sin], stdout, "");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-1
@@ -90,9 +90,10 @@ state_item_index_lookup (state_number s, state_item_number off)
|
||||
}
|
||||
|
||||
void state_items_init (void);
|
||||
void print_state_item (const state_item *si, FILE *out, const char *prefix);
|
||||
void state_items_free (void);
|
||||
|
||||
void state_item_print (const state_item *si, FILE *out, const char *prefix);
|
||||
|
||||
bool production_allowed (const state_item *si, const state_item *next);
|
||||
|
||||
// Iterating on a state_item_list.
|
||||
|
||||
+2
-2
@@ -83,10 +83,10 @@ symbol_list_type_new (uniqstr type_name, location loc)
|
||||
|
||||
|
||||
symbol_list *
|
||||
symbol_list_type_set (symbol_list *syms, uniqstr type_name, location loc)
|
||||
symbol_list_type_set (symbol_list *syms, uniqstr type_name)
|
||||
{
|
||||
for (symbol_list *l = syms; l; l = l->next)
|
||||
symbol_type_set (l->content.sym, type_name, loc);
|
||||
symbol_type_set (l->content.sym, type_name, l->sym_loc);
|
||||
return syms;
|
||||
}
|
||||
|
||||
|
||||
+1
-2
@@ -110,8 +110,7 @@ symbol_list *symbol_list_type_new (uniqstr type_name, location loc);
|
||||
|
||||
/** Assign the type \c type_name to all the members of \c syms.
|
||||
** \returns \c syms */
|
||||
symbol_list *symbol_list_type_set (symbol_list *syms,
|
||||
uniqstr type_name, location loc);
|
||||
symbol_list *symbol_list_type_set (symbol_list *syms, uniqstr type_name);
|
||||
|
||||
/** Print this list.
|
||||
|
||||
|
||||
+33
-36
@@ -59,7 +59,7 @@ static semantic_type **semantic_types_sorted = NULL;
|
||||
symbol *errtoken = NULL;
|
||||
symbol *undeftoken = NULL;
|
||||
symbol *eoftoken = NULL;
|
||||
symbol *accept = NULL;
|
||||
symbol *acceptsymbol = NULL;
|
||||
symbol *startsymbol = NULL;
|
||||
location startsymbol_loc;
|
||||
|
||||
@@ -137,11 +137,6 @@ symbol_new (uniqstr tag, location loc)
|
||||
res->alias = NULL;
|
||||
res->content = sym_content_new (res);
|
||||
res->is_alias = false;
|
||||
|
||||
if (nsyms == SYMBOL_NUMBER_MAXIMUM)
|
||||
complain (NULL, fatal, _("too many symbols in input grammar (limit is %d)"),
|
||||
SYMBOL_NUMBER_MAXIMUM);
|
||||
nsyms++;
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -182,11 +177,11 @@ symbol_free (void *ptr)
|
||||
*/
|
||||
|
||||
static void
|
||||
symbols_sort (symbol **first, symbol **second)
|
||||
symbols_sort (const symbol **first, const symbol **second)
|
||||
{
|
||||
if (0 < location_cmp ((*first)->location, (*second)->location))
|
||||
{
|
||||
symbol* tmp = *first;
|
||||
const symbol* tmp = *first;
|
||||
*first = *second;
|
||||
*second = tmp;
|
||||
}
|
||||
@@ -243,7 +238,11 @@ semantic_type_new (uniqstr tag, const location *loc)
|
||||
| Print a symbol. |
|
||||
`-----------------*/
|
||||
|
||||
#define SYMBOL_ATTR_PRINT(Attr) \
|
||||
#define SYMBOL_INT_ATTR_PRINT(Attr) \
|
||||
if (s->content) \
|
||||
fprintf (f, " %s = %d", #Attr, s->content->Attr)
|
||||
|
||||
#define SYMBOL_STR_ATTR_PRINT(Attr) \
|
||||
if (s->content && s->content->Attr) \
|
||||
fprintf (f, " %s { %s }", #Attr, s->content->Attr)
|
||||
|
||||
@@ -264,7 +263,11 @@ symbol_print (symbol const *s, FILE *f)
|
||||
: c == nterm_sym ? "nterm"
|
||||
: NULL, /* abort. */
|
||||
s->tag);
|
||||
SYMBOL_ATTR_PRINT (type_name);
|
||||
putc (' ', f);
|
||||
location_print (s->location, f);
|
||||
SYMBOL_INT_ATTR_PRINT (code);
|
||||
SYMBOL_INT_ATTR_PRINT (number);
|
||||
SYMBOL_STR_ATTR_PRINT (type_name);
|
||||
SYMBOL_CODE_PRINT (destructor);
|
||||
SYMBOL_CODE_PRINT (printer);
|
||||
}
|
||||
@@ -371,7 +374,7 @@ symbol_from_uniqstr_fuzzy (const uniqstr key)
|
||||
}
|
||||
|
||||
static void
|
||||
complain_symbol_undeclared (symbol *sym)
|
||||
complain_symbol_undeclared (const symbol *sym)
|
||||
{
|
||||
assert (sym->content->status != declared);
|
||||
const symbol *best = symbol_from_uniqstr_fuzzy (sym->tag);
|
||||
@@ -398,7 +401,10 @@ void
|
||||
symbol_location_as_lhs_set (symbol *sym, location loc)
|
||||
{
|
||||
if (!sym->location_of_lhs)
|
||||
sym->location = loc;
|
||||
{
|
||||
sym->location = loc;
|
||||
sym->location_of_lhs = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -548,10 +554,6 @@ symbol_class_set (symbol *sym, symbol_class class, location loc, bool declaring)
|
||||
if (class == token_sym && s->class == pct_type_sym)
|
||||
complain_pct_type_on_token (&sym->location);
|
||||
|
||||
if (class == nterm_sym && s->class != nterm_sym)
|
||||
s->number = nnterms++;
|
||||
else if (class == token_sym && s->number == NUMBER_UNDEFINED)
|
||||
s->number = ntokens++;
|
||||
s->class = class;
|
||||
|
||||
if (declaring)
|
||||
@@ -573,9 +575,9 @@ symbol_class_set (symbol *sym, symbol_class class, location loc, bool declaring)
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------.
|
||||
| Set the USER_TOKEN_NUMBER associated with SYM. |
|
||||
`------------------------------------------------*/
|
||||
/*----------------------------.
|
||||
| Set the token code of SYM. |
|
||||
`----------------------------*/
|
||||
|
||||
void
|
||||
symbol_code_set (symbol *sym, int code, location loc)
|
||||
@@ -598,10 +600,6 @@ symbol_code_set (symbol *sym, int code, location loc)
|
||||
if (code == 0 && !eoftoken)
|
||||
{
|
||||
eoftoken = sym->content->symbol;
|
||||
/* It is always mapped to 0, so it was already counted in
|
||||
NTOKENS. */
|
||||
if (eoftoken->content->number != NUMBER_UNDEFINED)
|
||||
--ntokens;
|
||||
eoftoken->content->number = 0;
|
||||
}
|
||||
}
|
||||
@@ -621,9 +619,11 @@ symbol_check_defined (symbol *sym)
|
||||
{
|
||||
complain_symbol_undeclared (sym);
|
||||
s->class = nterm_sym;
|
||||
s->number = nnterms++;
|
||||
}
|
||||
|
||||
if (s->number == NUMBER_UNDEFINED)
|
||||
s->number = s->class == token_sym ? ntokens++ : nnterms++;
|
||||
|
||||
if (s->class == token_sym
|
||||
&& sym->tag[0] == '"'
|
||||
&& !sym->is_alias)
|
||||
@@ -742,7 +742,7 @@ symbol_pack (symbol *sym)
|
||||
}
|
||||
|
||||
static void
|
||||
complain_code_redeclared (int num, symbol *first, symbol *second)
|
||||
complain_code_redeclared (int num, const symbol *first, const symbol *second)
|
||||
{
|
||||
symbols_sort (&first, &second);
|
||||
complain (&second->location, complaint,
|
||||
@@ -758,13 +758,11 @@ complain_code_redeclared (int num, symbol *first, symbol *second)
|
||||
`-------------------------------------------------*/
|
||||
|
||||
static void
|
||||
symbol_translation (symbol *sym)
|
||||
symbol_translation (const symbol *sym)
|
||||
{
|
||||
/* Nonterminal? */
|
||||
if (sym->content->class == token_sym
|
||||
&& !sym->is_alias)
|
||||
if (sym->content->class == token_sym && !sym->is_alias)
|
||||
{
|
||||
/* A token which translation has already been set?*/
|
||||
/* A token whose translation has already been set? */
|
||||
if (token_translations[sym->content->code]
|
||||
!= undeftoken->content->number)
|
||||
complain_code_redeclared
|
||||
@@ -849,10 +847,10 @@ symbols_new (void)
|
||||
hash_symbol_comparator,
|
||||
symbol_free);
|
||||
|
||||
/* Construct the accept symbol. */
|
||||
accept = symbol_get ("$accept", empty_loc);
|
||||
accept->content->class = nterm_sym;
|
||||
accept->content->number = nnterms++;
|
||||
/* Construct the acceptsymbol symbol. */
|
||||
acceptsymbol = symbol_get ("$accept", empty_loc);
|
||||
acceptsymbol->content->class = nterm_sym;
|
||||
acceptsymbol->content->number = nnterms++;
|
||||
|
||||
/* Construct the YYerror/"error" token */
|
||||
errtoken = symbol_get ("YYerror", empty_loc);
|
||||
@@ -969,7 +967,6 @@ dummy_symbol_get (location loc)
|
||||
assure (len < sizeof buf);
|
||||
symbol *sym = symbol_get (buf, loc);
|
||||
sym->content->class = nterm_sym;
|
||||
sym->content->number = nnterms++;
|
||||
return sym;
|
||||
}
|
||||
|
||||
@@ -1002,7 +999,7 @@ symbol_cmp (void const *a, void const *b)
|
||||
}
|
||||
|
||||
/* Store in *SORTED an array of pointers to the symbols contained in
|
||||
TABLE, sorted (alphabetically) by tag. */
|
||||
TABLE, sorted by order of appearance (i.e., by location). */
|
||||
|
||||
static void
|
||||
table_sort (struct hash_table *table, symbol ***sorted)
|
||||
|
||||
+2
-2
@@ -227,7 +227,7 @@ void symbol_precedence_set (symbol *sym, int prec, assoc a, location loc);
|
||||
void symbol_class_set (symbol *sym, symbol_class class, location loc,
|
||||
bool declaring);
|
||||
|
||||
/** Set the \c code associated with \c sym. */
|
||||
/** Set the token \c code of \c sym, specified by the user at \c loc. */
|
||||
void symbol_code_set (symbol *sym, int code, location loc);
|
||||
|
||||
|
||||
@@ -245,7 +245,7 @@ extern symbol *eoftoken;
|
||||
/** The genuine start symbol.
|
||||
|
||||
$accept: start-symbol $end */
|
||||
extern symbol *accept;
|
||||
extern symbol *acceptsymbol;
|
||||
|
||||
/** The user start symbol. */
|
||||
extern symbol *startsymbol;
|
||||
|
||||
@@ -131,6 +131,22 @@ typedef size_t uintptr_t;
|
||||
# include <stdbool.h>
|
||||
|
||||
|
||||
/*-----------.
|
||||
| Integers. |
|
||||
`-----------*/
|
||||
|
||||
static inline int
|
||||
min_int (int a, int b)
|
||||
{
|
||||
return a < b ? a : b;
|
||||
}
|
||||
|
||||
static inline int
|
||||
max_int (int a, int b)
|
||||
{
|
||||
return a >= b ? a : b;
|
||||
}
|
||||
|
||||
|
||||
/*-------------.
|
||||
| Assertions. |
|
||||
|
||||
@@ -915,6 +915,12 @@ AT_BISON_OPTION_PUSHDEFS([$1])
|
||||
|
||||
AT_DATA_CALC_Y([$1])
|
||||
AT_FULL_COMPILE(AT_JAVA_IF([[Calc]], [[calc]]), AT_DEFINES_IF([[lex], [main]], [[], []]), [$2], [-Wno-deprecated])
|
||||
|
||||
AT_YACC_IF(
|
||||
[# No direct calls to malloc/free.
|
||||
AT_CHECK([[$EGREP '(malloc|free) *\(' calc.[ch] | $EGREP -v 'INFRINGES ON USER NAME SPACE']],
|
||||
[1])])
|
||||
|
||||
AT_PUSH_IF([AT_JAVA_IF(
|
||||
[# Verify that this is a push parser.
|
||||
AT_CHECK_JAVA_GREP([[Calc.java]],
|
||||
|
||||
+166
-19
@@ -1,4 +1,4 @@
|
||||
# Checking the Bison scanner. -*- Autotest -*-
|
||||
# Checking the Bison reader. -*- Autotest -*-
|
||||
|
||||
# Copyright (C) 2002-2015, 2018-2020 Free Software Foundation, Inc.
|
||||
|
||||
@@ -78,10 +78,13 @@ AT_CLEANUP
|
||||
## Invalid inputs. ##
|
||||
## ---------------- ##
|
||||
|
||||
# The truly bad guys no human would write, but easily uncovered by
|
||||
# fuzzers.
|
||||
AT_SETUP([Invalid inputs])
|
||||
|
||||
AT_DATA([input.y],
|
||||
[[\000\001\002\377?
|
||||
"\000"
|
||||
%%
|
||||
?
|
||||
default: 'a' }
|
||||
@@ -92,21 +95,50 @@ default: 'a' }
|
||||
]])
|
||||
AT_PERL_REQUIRE([[-pi -e 's/\\(\d{3})/chr(oct($1))/ge' input.y]])
|
||||
|
||||
AT_BISON_CHECK([input.y], [1], [],
|
||||
AT_BISON_CHECK([-fcaret input.y], [1], [], [stderr])
|
||||
|
||||
# Autotest's diffing, when there are NUL bytes, just reports "binary
|
||||
# files differ". So don't leave NUL bytes.
|
||||
AT_PERL_CHECK([[-p -e 's{([\0\377])}{sprintf "\\x%02x", ord($1)}ge' stderr]], [],
|
||||
[[input.y:1.1-2: error: invalid characters: '\0\001\002\377?'
|
||||
input.y:3.1: error: invalid character: '?'
|
||||
input.y:4.14: error: invalid character: '}'
|
||||
input.y:5.1: error: invalid character: '%'
|
||||
input.y:5.2: error: invalid character: '&'
|
||||
input.y:6.1-17: error: invalid directive: '%a-does-not-exist'
|
||||
input.y:7.1: error: invalid character: '%'
|
||||
input.y:7.2: error: invalid character: '-'
|
||||
input.y:8.1-9.0: error: missing '%}' at end of file
|
||||
1 | \x00\xff?
|
||||
| ^~
|
||||
input.y:2.2: error: invalid null character
|
||||
2 | "\x00"
|
||||
| ^
|
||||
input.y:4.1: error: invalid character: '?'
|
||||
4 | ?
|
||||
| ^
|
||||
input.y:5.14: error: invalid character: '}'
|
||||
5 | default: 'a' }
|
||||
| ^
|
||||
input.y:6.1: error: invalid character: '%'
|
||||
6 | %&
|
||||
| ^
|
||||
input.y:6.2: error: invalid character: '&'
|
||||
6 | %&
|
||||
| ^
|
||||
input.y:7.1-17: error: invalid directive: '%a-does-not-exist'
|
||||
7 | %a-does-not-exist
|
||||
| ^~~~~~~~~~~~~~~~~
|
||||
input.y:8.1: error: invalid character: '%'
|
||||
8 | %-
|
||||
| ^
|
||||
input.y:8.2: error: invalid character: '-'
|
||||
8 | %-
|
||||
| ^
|
||||
input.y:9.1-10.0: error: missing '%}' at end of file
|
||||
9 | %{
|
||||
| ^~
|
||||
]])
|
||||
|
||||
AT_CLEANUP
|
||||
|
||||
|
||||
## ------------------------ ##
|
||||
## Invalid inputs with {}. ##
|
||||
## ------------------------ ##
|
||||
|
||||
AT_SETUP([Invalid inputs with {}])
|
||||
|
||||
# We used to SEGV here. See
|
||||
@@ -788,6 +820,33 @@ input.y:3.8-10: note: previous declaration
|
||||
AT_CLEANUP
|
||||
|
||||
|
||||
## ---------------- ##
|
||||
## EOF redeclared. ##
|
||||
## ---------------- ##
|
||||
|
||||
AT_SETUP([EOF redeclared])
|
||||
|
||||
# We used to crash when redefining a token after having defined EOF.
|
||||
# See https://lists.gnu.org/r/bug-bison/2020-08/msg00008.html.
|
||||
|
||||
AT_DATA([[input.y]],
|
||||
[[%token FOO BAR FOO 0
|
||||
%%
|
||||
input: %empty
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK([-fcaret input.y], [0], [],
|
||||
[[input.y:1.16-18: warning: symbol FOO redeclared [-Wother]
|
||||
1 | %token FOO BAR FOO 0
|
||||
| ^~~
|
||||
input.y:1.8-10: note: previous declaration
|
||||
1 | %token FOO BAR FOO 0
|
||||
| ^~~
|
||||
]])
|
||||
|
||||
AT_CLEANUP
|
||||
|
||||
|
||||
## --------------------------- ##
|
||||
## Symbol class redefinition. ##
|
||||
## --------------------------- ##
|
||||
@@ -1224,12 +1283,12 @@ AT_TEST([[%token foo "foo"
|
||||
%%
|
||||
exp: foo;
|
||||
]],
|
||||
[[input.y:3.7-11: error: %type redeclaration for foo
|
||||
[[input.y:3.13-15: error: %type redeclaration for foo
|
||||
3 | %type <baz> foo
|
||||
| ^~~~~
|
||||
input.y:2.7-11: note: previous declaration
|
||||
| ^~~
|
||||
input.y:2.13-17: note: previous declaration
|
||||
2 | %type <bar> "foo"
|
||||
| ^~~~~
|
||||
| ^~~~~
|
||||
]])
|
||||
|
||||
AT_TEST([[%token foo "foo"
|
||||
@@ -1336,11 +1395,6 @@ AT_CLEANUP
|
||||
AT_SETUP([Torturing the Scanner])
|
||||
|
||||
AT_BISON_OPTION_PUSHDEFS
|
||||
AT_DATA([input.y], [])
|
||||
AT_BISON_CHECK([input.y], [1], [],
|
||||
[[input.y:1.1: error: unexpected end of file
|
||||
]])
|
||||
|
||||
|
||||
AT_DATA([input.y],
|
||||
[{}
|
||||
@@ -2447,6 +2501,99 @@ input.y:5.19: error: invalid character after \-escape: \001
|
||||
AT_CLEANUP
|
||||
|
||||
|
||||
## ------------------------ ##
|
||||
## Unexpected end of file. ##
|
||||
## ------------------------ ##
|
||||
|
||||
AT_SETUP([[Unexpected end of file]])
|
||||
|
||||
|
||||
AT_DATA([input.y], [])
|
||||
AT_BISON_CHECK([-fcaret input.y], [1], [],
|
||||
[[input.y:1.1: error: unexpected end of file
|
||||
]])
|
||||
|
||||
|
||||
AT_DATA_NO_FINAL_EOL([char.y],
|
||||
[[%token FOO ']])
|
||||
|
||||
AT_BISON_CHECK([-fcaret char.y], [1], [],
|
||||
[[char.y:1.12: error: missing "'" at end of file
|
||||
1 | %token FOO '
|
||||
| ^
|
||||
char.y:1.12: error: empty character literal
|
||||
1 | %token FOO '
|
||||
| ^
|
||||
]])
|
||||
|
||||
|
||||
AT_DATA_NO_FINAL_EOL([escape-in-char.y],
|
||||
[[%token FOO '\]])
|
||||
|
||||
AT_BISON_CHECK([-fcaret escape-in-char.y], [1], [],
|
||||
[[escape-in-char.y:1.12-13: error: missing '?\'' at end of file
|
||||
1 | %token FOO '\
|
||||
| ^~
|
||||
escape-in-char.y:1.14: error: unexpected end of file
|
||||
1 | %token FOO '\
|
||||
| ^
|
||||
]])
|
||||
|
||||
|
||||
AT_DATA_NO_FINAL_EOL([string.y],
|
||||
[[%token FOO "]])
|
||||
|
||||
AT_BISON_CHECK([-fcaret string.y], [1], [],
|
||||
[[string.y:1.12: error: missing '"' at end of file
|
||||
1 | %token FOO "
|
||||
| ^
|
||||
string.y:1.13: error: unexpected end of file
|
||||
1 | %token FOO "
|
||||
| ^
|
||||
]])
|
||||
|
||||
|
||||
AT_DATA_NO_FINAL_EOL([escape-in-string.y],
|
||||
[[%token FOO "\]])
|
||||
|
||||
AT_BISON_CHECK([-fcaret escape-in-string.y], [1], [],
|
||||
[[escape-in-string.y:1.12-13: error: missing '?"' at end of file
|
||||
1 | %token FOO "\
|
||||
| ^~
|
||||
escape-in-string.y:1.14: error: unexpected end of file
|
||||
1 | %token FOO "\
|
||||
| ^
|
||||
]])
|
||||
|
||||
|
||||
AT_DATA_NO_FINAL_EOL([tstring.y],
|
||||
[[%token FOO _("]])
|
||||
|
||||
AT_BISON_CHECK([-fcaret tstring.y], [1], [],
|
||||
[[tstring.y:1.12-14: error: missing '")' at end of file
|
||||
1 | %token FOO _("
|
||||
| ^~~
|
||||
tstring.y:1.15: error: unexpected end of file
|
||||
1 | %token FOO _("
|
||||
| ^
|
||||
]])
|
||||
|
||||
|
||||
AT_DATA_NO_FINAL_EOL([escape-in-tstring.y],
|
||||
[[%token FOO _("\]])
|
||||
|
||||
AT_BISON_CHECK([-fcaret escape-in-tstring.y], [1], [],
|
||||
[[escape-in-tstring.y:1.12-15: error: missing '?")' at end of file
|
||||
1 | %token FOO _("\
|
||||
| ^~~~
|
||||
escape-in-tstring.y:1.16: error: unexpected end of file
|
||||
1 | %token FOO _("\
|
||||
| ^
|
||||
]])
|
||||
|
||||
AT_CLEANUP
|
||||
|
||||
|
||||
## ------------------------- ##
|
||||
## LAC: Errors for %define. ##
|
||||
## ------------------------- ##
|
||||
|
||||
@@ -390,6 +390,7 @@ AT_LOCATION_TYPE_SPAN_IF(
|
||||
|
||||
|
||||
AT_GLR_IF([AT_KEYWORDS([glr])])
|
||||
AT_PUSH_IF([AT_KEYWORDS([push])])
|
||||
])# _AT_BISON_OPTION_PUSHDEFS
|
||||
|
||||
|
||||
|
||||
+2
-2
@@ -759,7 +759,7 @@ AT_TEST([x1],
|
||||
])
|
||||
|
||||
# Check the CPP guard and Doxyen comments.
|
||||
AT_CHECK([sed -ne 's/#line [0-9]\+ "/#line "/p;/INCLUDED/p;/\\file/{p;n;p;}' out/include/ast/loc.hh], [],
|
||||
AT_CHECK([[sed -ne 's/#line [0-9][0-9]* "/#line "/p;/INCLUDED/p;/\\file/{p;n;p;}' out/include/ast/loc.hh]], [],
|
||||
[[ ** \file bar/include/ast/loc.hh
|
||||
** Define the x1::location class.
|
||||
#ifndef YY_YY_BAR_INCLUDE_AST_LOC_HH_INCLUDED
|
||||
@@ -771,7 +771,7 @@ AT_CHECK([sed -ne 's/#line [0-9]\+ "/#line "/p;/INCLUDED/p;/\\file/{p;n;p;}' out
|
||||
#endif // !YY_YY_BAR_INCLUDE_AST_LOC_HH_INCLUDED
|
||||
]])
|
||||
|
||||
AT_CHECK([sed -ne 's/^#line [0-9]\+ "/#line "/p;/INCLUDED/p;/\\file/{p;n;p;}' out/x1.hh], [],
|
||||
AT_CHECK([[sed -ne 's/^#line [0-9][0-9]* "/#line "/p;/INCLUDED/p;/\\file/{p;n;p;}' out/x1.hh]], [],
|
||||
[[ ** \file bar/x1.hh
|
||||
** Define the x1::parser class.
|
||||
#ifndef YY_YY_BAR_X1_HH_INCLUDED
|
||||
|
||||
Reference in New Issue
Block a user