mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-08-09 18:55:14 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
437f6250c5 | ||
|
|
334cb8f222 | ||
|
|
03878edf77 | ||
|
|
cacdfc2f6e | ||
|
|
31788ed4c7 | ||
|
|
69061fed82 | ||
|
|
7a21067bb9 | ||
|
|
ed02d34fbc | ||
|
|
8b0b295569 | ||
|
|
59a108c0a6 | ||
|
|
83ebc8bdb6 | ||
|
|
8023b3153a | ||
|
|
b23ca37ed2 | ||
|
|
bb5e4b659b | ||
|
|
bc8ec1d7bf | ||
|
|
665c5d688c | ||
|
|
53d379b905 | ||
|
|
aa85bfe3a7 | ||
|
|
5ec9c99662 | ||
|
|
36cae8e752 | ||
|
|
7498ede3ab | ||
|
|
27104acdbe | ||
|
|
7b3368a155 | ||
|
|
ec08b369ec | ||
|
|
05b70f47e8 | ||
|
|
626d2f2dca | ||
|
|
5c797b1627 | ||
|
|
ac692b572a | ||
|
|
2f208ee43a | ||
|
|
013a695add | ||
|
|
54ed577da0 | ||
|
|
4a690d3d19 | ||
|
|
cd1a9f076c | ||
|
|
7a0f681cb8 | ||
|
|
eb0f3e79e0 | ||
|
|
25b7421c40 | ||
|
|
e86adac52d | ||
|
|
5879c8dc5a | ||
|
|
d5d148630a | ||
|
|
b443932991 | ||
|
|
f5a646c390 | ||
|
|
f038f0b12f | ||
|
|
b6b397b7f0 | ||
|
|
2c8fb4d126 | ||
|
|
169fe80c7f | ||
|
|
b7e0d3131d | ||
|
|
a634aad9e6 | ||
|
|
ad326ada91 | ||
|
|
a049509d04 | ||
|
|
7c5e508b39 | ||
|
|
55bf52860e | ||
|
|
8575bd06ae | ||
|
|
7c63cc1f6b | ||
|
|
4a41a8ec51 | ||
|
|
ba469451d8 | ||
|
|
8580b268c3 | ||
|
|
41aaa8374c | ||
|
|
79e79be298 | ||
|
|
ffe2e4aaec | ||
|
|
dad14ec3e4 | ||
|
|
a7ff1c75be | ||
|
|
8c3a7687e4 | ||
|
|
72c488aa62 | ||
|
|
a88f8117b0 | ||
|
|
3551d51dd9 | ||
|
|
38b17c36da | ||
|
|
f9db426de6 | ||
|
|
c927c955c8 |
+1
-1
@@ -1 +1 @@
|
||||
3.2.2
|
||||
3.3.1
|
||||
|
||||
+2
-1
@@ -8,7 +8,8 @@ language: cpp
|
||||
env:
|
||||
global:
|
||||
# ICC serial number.
|
||||
secure: ED3w6rzxuE6tVu3oyxha2MoGMRzRQCtinvr9uor1gw9TGKB80esTLx4KyX0xHemUdyQVarFDDQfVS5rf7jSDY8XiWIR6O+2Af9/30gb+8eyngyvACu7E28n+1XHmYWIEHsbvB9mic6C60FBj5sPcDnFWZeyttGL0WooSjYHiw1Egafwqbeu1mD3Aet9OI9VaLQvy0KcWAdVrYWSI9UWLvLM+xPVUjPFko4oS+dTlETzVnmn6JFbZX1OKONtfcvdoDRFBzs3iHm5dQUt/Fz+y/DtKSuvF3zvePHSgF6c8URbEPPjBdh87gkovSLyy+83fVeh4WMkF8b+dGZmikQv6kRsjKJdbQrS8tiMhZlORC5Gfmn4HXNgmapL+paUweakH7UZQHm6d5SZoBgCHNazfqMrywbZsZkGvZTDQIVG1Be7Lhh2BDFbPhPZNDvI9XYiqZP0QSb0BVfeO+AUSRcUPM7TvarxB74jYdfpTBu7sqJP6dSwhcDTEUhHmuLGjzsNm3uTZe8SUw/TGGx5uPTXNsCjJq6ClIOAIYXZTXLbBmIL/NBWCy0MUpD+9zsiknU7vzzq1RfgCCExhvYgosTjBLcX1kKI+eRSU5M44e+xCg4xx0m9WfafbKbhA20FfnWxCFIkZeVpkOOsexJ9zfe0SflVLxkd7vmci5SCBixLVbN0=
|
||||
# See https://github.com/nemequ/icc-travis.
|
||||
secure: B3manbbi0anCAGDJTdAa9TlodzRHeiYD87FKmFzS877dPm8Cm0BDvtUhKBUpBvP8+nbHOWFGrgDmLugSZjTGU+mAxtuQpamUFHvinu0BIk3qtjlqouwvbtIqUu8iiZ3Uqu+xKeAANKRy0YVZGLlEb9F3N119tJ/Fxp1p9bXL1qph+CZ25OFbUgZ2s4F+/AyHMUxJlNXKFe3Qean65hC6edhU3zoaKzr/g/wtbhRmcyWbkOa1dJqzr2yKotcPvrnApGhDzgMKFtohg/t7xfMADDVv6sGS5XNpt25Z+MUCmLg4Z9eD7u109jvRV1eu/jgVafqsthWEhXbuMiFgFhKBKGCNZ0dACIfKZSkFZI6FdM7ovJ6aNhSlxZ2169Ybd22rN1UTHeCQWySPcVVOg5taLVpqe+E8Xhnv4hBO5NrzElWwCMLxIdPUSwVStYvtDr8ZytHWzfot50vSnFKIFpTOr9hP4+AJMVmmqJfaJo2MLBft/q2xkztrMv3lQSj3m4+ma9kPDwXIu9uCutjlnhc00jNx9qegi5VfpAjxcG1R+pX4T20az6ByHk/7LPQsANkT31RJq/jAeD9LEuMOy8miha83q4QuvbFaqPK3PY0el/O1LZaXqLsV2aQ0uqH8YX0l4r5NzHdhb+3lYgvpMBO5ytr/EWJiEyNYV518050IUDE=
|
||||
|
||||
matrix:
|
||||
include:
|
||||
|
||||
@@ -1,6 +1,26 @@
|
||||
GNU Bison NEWS
|
||||
|
||||
* Noteworthy changes in release 3.2.90 (2019-01-12) [beta]
|
||||
* Noteworthy changes in release 3.3.2 (2019-02-03) [stable]
|
||||
|
||||
** Bug fixes
|
||||
|
||||
Bison 3.3 failed to generate parsers for grammars with unused nonterminal
|
||||
symbols.
|
||||
|
||||
* Noteworthy changes in release 3.3.1 (2019-01-27) [stable]
|
||||
|
||||
** Changes
|
||||
|
||||
The option -y/--yacc used to imply -Werror=yacc, which turns uses of Bison
|
||||
extensions into errors. It now makes them simple warnings (-Wyacc).
|
||||
|
||||
* Noteworthy changes in release 3.3 (2019-01-26) [stable]
|
||||
|
||||
A new mailing list was created, Bison Announce. It is low traffic, and is
|
||||
only about announcing new releases and important messages (e.g., polls
|
||||
about major decisions to make).
|
||||
|
||||
https://lists.gnu.org/mailman/listinfo/bison-announce
|
||||
|
||||
** Backward incompatible changes
|
||||
|
||||
@@ -9,6 +29,11 @@ GNU Bison NEWS
|
||||
|
||||
** Deprecated features
|
||||
|
||||
A new feature, --update (see below) helps adjusting existing grammars to
|
||||
deprecations.
|
||||
|
||||
*** Deprecated directives
|
||||
|
||||
The %error-verbose directive is deprecated in favor of '%define
|
||||
parse.error verbose' since Bison 3.0, but no warning was issued.
|
||||
|
||||
@@ -16,9 +41,19 @@ GNU Bison NEWS
|
||||
api.prefix {xx}' since Bison 3.0, but no warning was issued. These
|
||||
directives are slightly different, you might need to adjust your code.
|
||||
%name-prefix renames only symbols with external linkage, while api.prefix
|
||||
also renames types and macros, including @code{YYDEBUG},
|
||||
@code{YYTOKENTYPE}, @code{yytokentype}, @code{YYSTYPE}, @code{YYLTYPE},
|
||||
etc.
|
||||
also renames types and macros, including YYDEBUG, YYTOKENTYPE,
|
||||
yytokentype, YYSTYPE, YYLTYPE, etc.
|
||||
|
||||
Users of Flex that move from '%name-prefix "xx"' to '%define api.prefix
|
||||
{xx}' will typically have to update YY_DECL from
|
||||
|
||||
#define YY_DECL int xxlex (YYSTYPE *yylval, YYLTYPE *yylloc)
|
||||
|
||||
to
|
||||
|
||||
#define YY_DECL int xxlex (XXSTYPE *yylval, XXLTYPE *yylloc)
|
||||
|
||||
*** Deprecated %define variable names
|
||||
|
||||
The following variables, mostly related to parsers in Java, have been
|
||||
renamed for consistency. Backward compatibility is ensured, but upgrading
|
||||
@@ -35,14 +70,66 @@ GNU Bison NEWS
|
||||
|
||||
** New features
|
||||
|
||||
*** Generation of fix-its for IDEs/Editors
|
||||
|
||||
When given the new option -ffixit (aka -fdiagnostics-parseable-fixits),
|
||||
bison now generates machine readable editing instructions to fix some
|
||||
issues. Currently, this is mostly limited to updating deprecated
|
||||
directives and removing duplicates. For instance:
|
||||
|
||||
$ cat foo.y
|
||||
%error-verbose
|
||||
%define parser_class_name "Parser"
|
||||
%define api.parser.class "Parser"
|
||||
%%
|
||||
exp:;
|
||||
|
||||
See the "fix-it:" lines below:
|
||||
|
||||
$ bison -ffixit foo.y
|
||||
foo.y:1.1-14: warning: deprecated directive, use '%define parse.error verbose' [-Wdeprecated]
|
||||
%error-verbose
|
||||
^~~~~~~~~~~~~~
|
||||
fix-it:"foo.y":{1:1-1:15}:"%define parse.error verbose"
|
||||
foo.y:2.1-34: warning: deprecated directive, use '%define api.parser.class {Parser}' [-Wdeprecated]
|
||||
%define parser_class_name "Parser"
|
||||
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
fix-it:"foo.y":{2:1-2:35}:"%define api.parser.class {Parser}"
|
||||
foo.y:3.1-33: error: %define variable 'api.parser.class' redefined
|
||||
%define api.parser.class "Parser"
|
||||
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
foo.y:2.1-34: previous definition
|
||||
%define parser_class_name "Parser"
|
||||
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
fix-it:"foo.y":{3:1-3:34}:""
|
||||
foo.y: warning: fix-its can be applied. Rerun with option '--update'. [-Wother]
|
||||
|
||||
This uses the same output format as GCC and Clang.
|
||||
|
||||
*** Updating grammar files
|
||||
|
||||
Fixes can be applied on the fly. The previous example ends with the
|
||||
suggestion to re-run bison with the option -u/--update, which results in a
|
||||
cleaner grammar file.
|
||||
|
||||
$ bison --update foo.y
|
||||
[...]
|
||||
bison: file 'foo.y' was updated (backup: 'foo.y~')
|
||||
|
||||
$ cat foo.y
|
||||
%define parse.error verbose
|
||||
%define api.parser.class {Parser}
|
||||
%%
|
||||
exp:;
|
||||
|
||||
*** Bison is now relocatable
|
||||
|
||||
If you pass '--enable-relocatable' to 'configure', Bison is relocatable.
|
||||
|
||||
A relocatable program can be moved or copied to a different location on
|
||||
the file system. It can also be used through mount points for network
|
||||
sharing. It is possible to make symlinks to the installed and moved
|
||||
programs, and invoke them through the symlink.
|
||||
sharing. It is possible to make symbolic links to the installed and moved
|
||||
programs, and invoke them through the symbolic link.
|
||||
|
||||
*** %expect and %expect-rr modifiers on individual rules
|
||||
|
||||
@@ -121,7 +208,7 @@ GNU Bison NEWS
|
||||
*** C++: Actual token constructors
|
||||
|
||||
When variants and token constructors are enabled, in addition to the
|
||||
type-safe named token constructors (make_ID, amke_INT, etc.), we now
|
||||
type-safe named token constructors (make_ID, make_INT, etc.), we now
|
||||
generate genuine constructors for symbol_type.
|
||||
|
||||
For instance with these declarations
|
||||
@@ -136,17 +223,18 @@ GNU Bison NEWS
|
||||
symbol_type (int token, const int&);
|
||||
symbol_type (int token);
|
||||
|
||||
which should be used in a Flex-scanner as follows.
|
||||
|
||||
%%
|
||||
[a-z]+ return yy::parser::symbol_type (ID, yytext);
|
||||
[0-9]+ return yy::parser::symbol_type (INT, text_to_int (yytext);
|
||||
":" return yy::parser::symbol_type (’:’);
|
||||
<<EOF>> return yy::parser::symbol_type (0);
|
||||
|
||||
Correct matching between token types and value types is checked via
|
||||
'assert'. For instance, 'symbol_type (ID, 42)' would abort (while
|
||||
'make_ID (42)' would not even compile).
|
||||
'assert'; for instance, 'symbol_type (ID, 42)' would abort. Named
|
||||
constructors are preferable, as they offer better type safety (for
|
||||
instance 'make_ID (42)' would not even compile), but symbol_type
|
||||
constructors may help when token types are discovered at run-time, e.g.,
|
||||
|
||||
[a-z]+ {
|
||||
if (auto i = lookup_keyword (yytext))
|
||||
return yy::parser::symbol_type (i);
|
||||
else
|
||||
return yy::parser::make_ID (yytext);
|
||||
}
|
||||
|
||||
*** C++: Variadic emplace
|
||||
|
||||
@@ -238,7 +326,7 @@ GNU Bison NEWS
|
||||
where TAG denotes a type tag such as ‘<ival>’, ID denotes an identifier
|
||||
such as ‘NUM’, NUMBER a decimal or hexadecimal integer such as ‘300’ or
|
||||
‘0x12d’, CHAR a character literal such as ‘'+'’, and STRING a string
|
||||
literal such as ‘"number"’. The postfix quantifiers are ‘?’ (zero or
|
||||
literal such as ‘"number"’. The post-fix quantifiers are ‘?’ (zero or
|
||||
one), ‘*’ (zero or more) and ‘+’ (one or more).
|
||||
|
||||
* Noteworthy changes in release 3.2.4 (2018-12-24) [stable]
|
||||
@@ -3395,10 +3483,14 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
LocalWords: pragmas noreturn untyped Rozenman unexpanded Wojciech Polak
|
||||
LocalWords: Alexandre MERCHANTABILITY yytype emplace ptr automove lvalues
|
||||
LocalWords: nonterminal yy args Pragma dereference yyformat rhs docdir
|
||||
LocalWords: Redeclarations rpcalc Autoconf YFLAGS Makefiles PROG
|
||||
LocalWords: Heimbigner AST src ast Makefile srcdir MinGW
|
||||
LocalWords: Redeclarations rpcalc Autoconf YFLAGS Makefiles PROG DECL num
|
||||
LocalWords: Heimbigner AST src ast Makefile srcdir MinGW xxlex XXSTYPE
|
||||
LocalWords: XXLTYPE strictfp IDEs ffixit fdiagnostics parseable fixits
|
||||
LocalWords: Wdeprecated yytext Variadic variadic yyrhs yyphrs RCS README
|
||||
LocalWords: noexcept constexpr ispell american deprecations
|
||||
|
||||
Local Variables:
|
||||
ispell-dictionary: "american"
|
||||
mode: outline
|
||||
fill-column: 76
|
||||
End:
|
||||
|
||||
@@ -18,6 +18,7 @@ Antonio Silva Correia [email protected]
|
||||
Arnold Robbins [email protected]
|
||||
Art Haas [email protected]
|
||||
Askar Safin [email protected]
|
||||
Balázs Scheidler [email protected]
|
||||
Baron Schwartz [email protected]
|
||||
Ben Pfaff [email protected]
|
||||
Benoit Perrot [email protected]
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
* Bison 3.4
|
||||
** injection rules
|
||||
** glr.cc
|
||||
move glr.c into the yy namespace
|
||||
** improve syntax errors (UTF-8, internationalization)
|
||||
Bison depends on the current locale. For instance:
|
||||
|
||||
|
||||
+6
-2
@@ -17,7 +17,7 @@
|
||||
|
||||
# gnulib modules used by this package.
|
||||
gnulib_modules='
|
||||
argmatch assert
|
||||
argmatch array-list assert
|
||||
bitsetv
|
||||
calloc-posix close closeout config-h c-strcase
|
||||
configmake
|
||||
@@ -26,7 +26,9 @@ gnulib_modules='
|
||||
getopt-gnu
|
||||
gettext git-version-gen gitlog-to-changelog
|
||||
gpl-3.0 hash inttypes isnan javacomp-script
|
||||
javaexec-script ldexpl malloc-gnu
|
||||
javaexec-script
|
||||
ldexpl
|
||||
malloc-gnu
|
||||
mbswidth
|
||||
non-recursive-gnulib-prefix-hack
|
||||
obstack
|
||||
@@ -36,6 +38,7 @@ gnulib_modules='
|
||||
readme-release
|
||||
realloc-posix
|
||||
relocatable-prog relocatable-script
|
||||
rename
|
||||
spawn-pipe stdbool stpcpy strdup-posix strerror strverscmp
|
||||
timevar
|
||||
unistd unistd-safer unlink unlocked-io
|
||||
@@ -44,6 +47,7 @@ gnulib_modules='
|
||||
xalloc
|
||||
xalloc-die
|
||||
xconcat-filename
|
||||
xlist
|
||||
xmemdup0
|
||||
xstrndup
|
||||
|
||||
|
||||
@@ -48,7 +48,11 @@ while (<STDIN>)
|
||||
# are strings and have the same syntax as on the command line.
|
||||
if ($dir_arg eq 'name[=value]')
|
||||
{
|
||||
$dir_arg = '@var{name} ["@var{value}"]';
|
||||
# -D/-F do not add quotes to the argument.
|
||||
$dir_arg =
|
||||
$dir eq "%define"
|
||||
? '@var{name} [@var{value}]'
|
||||
: '@var{name} ["@var{value}"]';
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -160,6 +160,7 @@ exclude = \
|
||||
$(foreach a,$(1),$(eval $(subst $$,$$$$,exclude_file_name_regexp--sc_$(a))))
|
||||
$(call exclude, \
|
||||
bindtextdomain=^lib/main.c$$ \
|
||||
cast_of_argument_to_free=^src/muscle-tab.c$$ \
|
||||
preprocessor_indentation=^data/|^lib/|^src/parse-gram.[ch]$$ \
|
||||
program_name=^lib/main.c$$ \
|
||||
prohibit_always-defined_macros=^data/skeletons/yacc.c$$ \
|
||||
|
||||
+5
-3
@@ -96,9 +96,11 @@ AM_CONDITIONAL([ENABLE_GCC_WARNINGS], [test "$enable_gcc_warnings" = yes])
|
||||
if test "$enable_gcc_warnings" = yes; then
|
||||
warn_common='-Wall -Wextra -Wno-sign-compare -Wcast-align
|
||||
-fparse-all-comments -Wdocumentation
|
||||
-Wformat -Wnull-dereference -Wpointer-arith -Wwrite-strings'
|
||||
warn_c='-Wbad-function-cast -Wshadow -Wstrict-prototypes'
|
||||
warn_cxx='-Wnoexcept'
|
||||
-Wformat -Wimplicit-fallthrough -Wnull-dereference
|
||||
-Wpointer-arith -Wshadow
|
||||
-Wwrite-strings'
|
||||
warn_c='-Wbad-function-cast -Wstrict-prototypes'
|
||||
warn_cxx='-Wextra-semi -Wnoexcept -Wundefined-func-template -Wweak-vtables'
|
||||
# Warnings for the test suite only.
|
||||
#
|
||||
# -fno-color-diagnostics: Clang's use of colors in the error
|
||||
|
||||
+49
-22
@@ -75,48 +75,75 @@ skeletons.
|
||||
|
||||
## Symbols
|
||||
|
||||
### `b4_symbol(NUM, FIELD)`
|
||||
In order to unify the handling of the various aspects of symbols (tag, type
|
||||
name, whether terminal, etc.), bison.exe defines one macro per (token,
|
||||
field), where field can `has_id`, `id`, etc.: see
|
||||
src/output.c:prepare_symbols_definitions().
|
||||
`prepare_symbols_definitions()` in `src/output.c`.
|
||||
|
||||
The various FIELDS are:
|
||||
The macro `b4_symbol(NUM, FIELD)` gives access to the following FIELDS:
|
||||
|
||||
- `has_id`: 0 or 1.
|
||||
|
||||
- has_id: 0 or 1.
|
||||
Whether the symbol has an id.
|
||||
- id: string
|
||||
If has_id, the id. Guaranteed to be usable as a C identifier.
|
||||
Prefixed by api.token.prefix if defined.
|
||||
- tag: string.
|
||||
|
||||
- `id`: string
|
||||
If has_id, the id (prefixed by api.token.prefix if defined), otherwise
|
||||
defined as empty. Guaranteed to be usable as a C identifier.
|
||||
|
||||
- `tag`: string.
|
||||
A representation of the symbol. Can be 'foo', 'foo.id', '"foo"' etc.
|
||||
- user_number: integer
|
||||
|
||||
- `user_number`: integer
|
||||
The external number as used by yylex. Can be ASCII code when a character,
|
||||
some number chosen by bison, or some user number in the case of
|
||||
%token FOO <NUM>. Corresponds to yychar in yacc.c.
|
||||
- is_token: 0 or 1
|
||||
|
||||
- `is_token`: 0 or 1
|
||||
Whether this is a terminal symbol.
|
||||
- number: integer
|
||||
|
||||
- `number`: integer
|
||||
The internal number (computed from the external number by yytranslate).
|
||||
Corresponds to yytoken in yacc.c. This is the same number that serves as
|
||||
key in b4_symbol(NUM, FIELD).
|
||||
- has_type: 0, 1
|
||||
|
||||
In bison, symbols are first assigned increasing numbers in order of
|
||||
appearance (but tokens first, then nterms). After grammar reduction,
|
||||
unused nterms are then renumbered to appear last (i.e., first tokens, then
|
||||
used nterms and finally unused nterms). This final number NUM is the one
|
||||
contained in this field, and it is the one used as key in `b4_symbol(NUM,
|
||||
FIELD)`.
|
||||
|
||||
The code of the rule actions, however, is emitted before we know what
|
||||
symbols are unused, so they use the original numbers. To avoid confusion,
|
||||
they actually use "orig NUM" instead of just "NUM". bison also emits
|
||||
definitions for `b4_symbol(orig NUM, number)` that map from original
|
||||
numbers to the new ones. `b4_symbol` actually resolves `orig NUM` in the
|
||||
other case, i.e., `b4_symbol(orig 42, tag)` would return the tag of the
|
||||
symbols whose original number was 42.
|
||||
|
||||
- `has_type`: 0, 1
|
||||
Whether has a semantic value.
|
||||
- type_tag: string
|
||||
|
||||
- `type_tag`: string
|
||||
When api.value.type=union, the generated name for the union member.
|
||||
yytype_INT etc. for symbols that has_id, otherwise yytype_1 etc.
|
||||
- type
|
||||
|
||||
- `type`
|
||||
If it has a semantic value, its type tag, or, if variant are used,
|
||||
its type.
|
||||
In the case of api.value.type=union, type is the real type (e.g. int).
|
||||
- has_printer: 0, 1
|
||||
- printer: string
|
||||
- printer_file: string
|
||||
- printer_line: integer
|
||||
|
||||
- `has_printer`: 0, 1
|
||||
- `printer`: string
|
||||
- `printer_file`: string
|
||||
- `printer_line`: integer
|
||||
If the symbol has a printer, everything about it.
|
||||
- has_destructor, destructor, destructor_file, destructor_line
|
||||
|
||||
- `has_destructor`, `destructor`, `destructor_file`, `destructor_line`
|
||||
Likewise.
|
||||
|
||||
### b4_symbol_value(VAL, [SYMBOL-NUM], [TYPE-TAG])
|
||||
### `b4_symbol_value(VAL, [SYMBOL-NUM], [TYPE-TAG])`
|
||||
Expansion of $$, $1, $<TYPE-TAG>3, etc.
|
||||
|
||||
The semantic value from a given VAL.
|
||||
@@ -127,14 +154,14 @@ The semantic value from a given VAL.
|
||||
The result can be used safely, it is put in parens to avoid nasty precedence
|
||||
issues.
|
||||
|
||||
### b4_lhs_value(SYMBOL-NUM, [TYPE])
|
||||
### `b4_lhs_value(SYMBOL-NUM, [TYPE])`
|
||||
Expansion of `$$` or `$<TYPE>$`, for symbol `SYMBOL-NUM`.
|
||||
|
||||
### b4_rhs_data(RULE-LENGTH, POS)
|
||||
### `b4_rhs_data(RULE-LENGTH, POS)`
|
||||
The data corresponding to the symbol `#POS`, where the current rule has
|
||||
`RULE-LENGTH` symbols on RHS.
|
||||
|
||||
### b4_rhs_value(RULE-LENGTH, POS, SYMBOL-NUM, [TYPE])
|
||||
### `b4_rhs_value(RULE-LENGTH, POS, SYMBOL-NUM, [TYPE])`
|
||||
Expansion of `$<TYPE>POS`, where the current rule has `RULE-LENGTH` symbols
|
||||
on RHS.
|
||||
|
||||
|
||||
+18
-5
@@ -389,17 +389,28 @@ m4_define([b4_glr_cc_if],
|
||||
#
|
||||
# The following macros provide access to symbol related values.
|
||||
|
||||
# _b4_symbol(NUM, FIELD)
|
||||
# ----------------------
|
||||
# __b4_symbol(NUM, FIELD)
|
||||
# -----------------------
|
||||
# Recover a FIELD about symbol #NUM. Thanks to m4_indir, fails if
|
||||
# undefined.
|
||||
m4_define([_b4_symbol],
|
||||
m4_define([__b4_symbol],
|
||||
[m4_indir([b4_symbol($1, $2)])])
|
||||
|
||||
|
||||
# _b4_symbol(NUM, FIELD)
|
||||
# ----------------------
|
||||
# Recover a FIELD about symbol #NUM (or "orig NUM"). Fails if
|
||||
# undefined.
|
||||
m4_define([_b4_symbol],
|
||||
[m4_ifdef([b4_symbol($1, number)],
|
||||
[__b4_symbol(m4_indir([b4_symbol($1, number)]), $2)],
|
||||
[__b4_symbol([$1], [$2])])])
|
||||
|
||||
|
||||
|
||||
# b4_symbol(NUM, FIELD)
|
||||
# ---------------------
|
||||
# Recover a FIELD about symbol #NUM. Thanks to m4_indir, fails if
|
||||
# Recover a FIELD about symbol #NUM (or "orig NUM"). Fails if
|
||||
# undefined. If FIELD = id, prepend the token prefix.
|
||||
m4_define([b4_symbol],
|
||||
[m4_case([$2],
|
||||
@@ -480,7 +491,9 @@ m4_popdef([b4_actions_])dnl
|
||||
|
||||
# _b4_symbol_case(SYMBOL-NUM)
|
||||
# ---------------------------
|
||||
# Issue a "case NUM" for SYMBOL-NUM.
|
||||
# Issue a "case NUM" for SYMBOL-NUM. Ends with its EOL to make it
|
||||
# easier to use with m4_map, but then, use []dnl to suppress the last
|
||||
# one.
|
||||
m4_define([_b4_symbol_case],
|
||||
[case b4_symbol([$1], [number]): b4_symbol_tag_comment([$1])])
|
||||
])
|
||||
|
||||
+39
-40
@@ -77,11 +77,13 @@ m4_define([b4_cxx_portability],
|
||||
// Support noexcept when possible.
|
||||
#if 201103L <= YY_CPLUSPLUS
|
||||
# define YY_NOEXCEPT noexcept
|
||||
# define YY_NOTHROW
|
||||
#else
|
||||
# define YY_NOEXCEPT
|
||||
#endif[]dnl
|
||||
# define YY_NOTHROW throw ()
|
||||
#endif
|
||||
|
||||
// Support noexcept when possible.
|
||||
// Support constexpr when possible.
|
||||
#if 201703 <= YY_CPLUSPLUS
|
||||
# define YY_CONSTEXPR constexpr
|
||||
#else
|
||||
@@ -217,7 +219,14 @@ m4_define([b4_public_types_declare],
|
||||
syntax_error (]b4_locations_if([const location_type& l, ])[const std::string& m)
|
||||
: std::runtime_error (m)]b4_locations_if([
|
||||
, location (l)])[
|
||||
{}]b4_locations_if([
|
||||
{}
|
||||
|
||||
syntax_error (const syntax_error& s)
|
||||
: std::runtime_error (s.what ())]b4_locations_if([
|
||||
, location (s.location)])[
|
||||
{}
|
||||
|
||||
~syntax_error () YY_NOEXCEPT YY_NOTHROW;]b4_locations_if([
|
||||
|
||||
location_type location;])[
|
||||
};
|
||||
@@ -260,7 +269,10 @@ m4_define([b4_symbol_type_define],
|
||||
typedef Base super_type;
|
||||
|
||||
/// Default constructor.
|
||||
basic_symbol ();
|
||||
basic_symbol ()
|
||||
: value ()]b4_locations_if([
|
||||
, location ()])[
|
||||
{}
|
||||
|
||||
#if 201103L <= YY_CPLUSPLUS
|
||||
/// Move constructor.
|
||||
@@ -282,10 +294,29 @@ m4_define([b4_symbol_type_define],
|
||||
YY_RVREF (location_type) l])[);
|
||||
]])[
|
||||
/// Destroy the symbol.
|
||||
~basic_symbol ();
|
||||
~basic_symbol ()
|
||||
{
|
||||
clear ();
|
||||
}
|
||||
|
||||
/// Destroy contents, and record that is empty.
|
||||
void clear ();
|
||||
void clear ()
|
||||
{]b4_variant_if([[
|
||||
// User destructor.
|
||||
symbol_number_type yytype = this->type_get ();
|
||||
basic_symbol<Base>& yysym = *this;
|
||||
(void) yysym;
|
||||
switch (yytype)
|
||||
{
|
||||
]b4_symbol_foreach([b4_symbol_destructor])dnl
|
||||
[ default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Type destructor.
|
||||
]b4_symbol_variant([[yytype]], [[value]], [[template destroy]])])[
|
||||
Base::clear ();
|
||||
}
|
||||
|
||||
/// Whether empty.
|
||||
bool empty () const YY_NOEXCEPT;
|
||||
@@ -352,7 +383,7 @@ m4_define([b4_symbol_type_define],
|
||||
typedef basic_symbol<by_type> super_type;
|
||||
|
||||
/// Empty symbol.
|
||||
symbol_type () {};
|
||||
symbol_type () {}
|
||||
|
||||
/// Constructor for valueless symbols, and symbols from each type.
|
||||
]b4_type_foreach([_b4_token_constructor_define])dnl
|
||||
@@ -365,12 +396,6 @@ m4_define([b4_symbol_type_define],
|
||||
# Provide the implementation needed by the public types.
|
||||
m4_define([b4_public_types_define],
|
||||
[[ // basic_symbol.
|
||||
template <typename Base>
|
||||
]b4_parser_class[::basic_symbol<Base>::basic_symbol ()
|
||||
: value ()]b4_locations_if([
|
||||
, location ()])[
|
||||
{}
|
||||
|
||||
#if 201103L <= YY_CPLUSPLUS
|
||||
template <typename Base>
|
||||
]b4_parser_class[::basic_symbol<Base>::basic_symbol (basic_symbol&& that)
|
||||
@@ -416,32 +441,6 @@ m4_define([b4_public_types_define],
|
||||
(void) v;
|
||||
]b4_symbol_variant([this->type_get ()], [value], [YY_MOVE_OR_COPY], [YY_MOVE (v)])])[}]])[
|
||||
|
||||
template <typename Base>
|
||||
]b4_parser_class[::basic_symbol<Base>::~basic_symbol ()
|
||||
{
|
||||
clear ();
|
||||
}
|
||||
|
||||
template <typename Base>
|
||||
void
|
||||
]b4_parser_class[::basic_symbol<Base>::clear ()
|
||||
{]b4_variant_if([[
|
||||
// User destructor.
|
||||
symbol_number_type yytype = this->type_get ();
|
||||
basic_symbol<Base>& yysym = *this;
|
||||
(void) yysym;
|
||||
switch (yytype)
|
||||
{
|
||||
]b4_symbol_foreach([b4_symbol_destructor])dnl
|
||||
[ default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Type destructor.
|
||||
]b4_symbol_variant([[yytype]], [[value]], [[template destroy]])])[
|
||||
Base::clear ();
|
||||
}
|
||||
|
||||
template <typename Base>
|
||||
bool
|
||||
]b4_parser_class[::basic_symbol<Base>::empty () const YY_NOEXCEPT
|
||||
@@ -517,7 +516,7 @@ m4_define([b4_public_types_define],
|
||||
])
|
||||
|
||||
|
||||
# b4_tolen_constructor_define
|
||||
# b4_token_constructor_define
|
||||
# ----------------------------
|
||||
# Define symbol constructors for all the value types.
|
||||
# Use at class-level. Redefined in variant.hh.
|
||||
|
||||
@@ -590,7 +590,10 @@ yytnamerr (char *yyres, const char *yystr)
|
||||
case '\\':
|
||||
if (*++yyp != '\\')
|
||||
goto do_not_strip_quotes;
|
||||
/* Fall through. */
|
||||
else
|
||||
goto append;
|
||||
|
||||
append:
|
||||
default:
|
||||
if (yyres)
|
||||
yyres[yyn] = *yyp;
|
||||
|
||||
@@ -160,6 +160,9 @@ m4_pushdef([b4_parse_param], m4_defn([b4_parse_param_orig]))dnl
|
||||
]b4_parser_class::~b4_parser_class[ ()
|
||||
{}
|
||||
|
||||
]b4_parser_class[::syntax_error::~syntax_error () YY_NOEXCEPT YY_NOTHROW
|
||||
{}
|
||||
|
||||
int
|
||||
]b4_parser_class[::operator() ()
|
||||
{
|
||||
@@ -246,9 +249,12 @@ b4_percent_code_get([[requires]])[
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
]m4_ifdef([b4_location_file],
|
||||
]b4_cxx_portability[
|
||||
]m4_ifdef([b4_location_include],
|
||||
[[# include ]b4_location_include])[
|
||||
]b4_variant_if([b4_variant_includes])[
|
||||
|
||||
]b4_attribute_define[
|
||||
]b4_null_define[
|
||||
|
||||
// Whether we are compiled with exception support.
|
||||
@@ -263,6 +269,7 @@ b4_percent_code_get([[requires]])[
|
||||
]b4_YYDEBUG_define[
|
||||
|
||||
]b4_namespace_open[
|
||||
|
||||
]b4_bison_locations_if([m4_ifndef([b4_location_file],
|
||||
[b4_location_define])])[
|
||||
|
||||
|
||||
+11
-4
@@ -110,7 +110,7 @@ b4_dollar_pushdef([yysym.value],
|
||||
[$1],
|
||||
[],
|
||||
[yysym.location])dnl
|
||||
_b4_symbol_case([$1])
|
||||
_b4_symbol_case([$1])[]dnl
|
||||
b4_syncline([b4_symbol([$1], [$2_line])], [b4_symbol([$1], [$2_file])])
|
||||
b4_symbol([$1], [$2])
|
||||
b4_syncline([@oline@], [@ofile@])
|
||||
@@ -532,7 +532,10 @@ m4_if(b4_prefix, [yy], [],
|
||||
case '\\':
|
||||
if (*++yyp != '\\')
|
||||
goto do_not_strip_quotes;
|
||||
// Fall through.
|
||||
else
|
||||
goto append;
|
||||
|
||||
append:
|
||||
default:
|
||||
yyr += *yyp;
|
||||
break;
|
||||
@@ -559,6 +562,8 @@ m4_if(b4_prefix, [yy], [],
|
||||
]b4_parser_class::~b4_parser_class[ ()
|
||||
{}
|
||||
|
||||
]b4_parser_class[::syntax_error::~syntax_error () YY_NOEXCEPT YY_NOTHROW
|
||||
{}
|
||||
|
||||
/*---------------.
|
||||
| Symbol types. |
|
||||
@@ -659,10 +664,12 @@ m4_if(b4_prefix, [yy], [],
|
||||
std::ostream& yyoutput = yyo;
|
||||
YYUSE (yyoutput);
|
||||
symbol_number_type yytype = yysym.type_get ();
|
||||
#if defined __GNUC__ && ! defined __clang__ && ! defined __ICC && __GNUC__ * 100 + __GNUC_MINOR__ <= 408
|
||||
// Avoid a (spurious) G++ 4.8 warning about "array subscript is
|
||||
// below array bounds".
|
||||
if (yysym.empty ())
|
||||
std::abort ();
|
||||
#endif
|
||||
yyo << (yytype < yyntokens_ ? "token" : "nterm")
|
||||
<< ' ' << yytname_[yytype] << " ("]b4_locations_if([
|
||||
<< yysym.location << ": "])[;
|
||||
@@ -896,8 +903,8 @@ b4_dollar_popdef])[]dnl
|
||||
[
|
||||
// Default location.
|
||||
{
|
||||
slice<stack_symbol_type, stack_type> slice (yystack_, yylen);
|
||||
YYLLOC_DEFAULT (yylhs.location, slice, yylen);
|
||||
stack_type::slice range (yystack_, yylen);
|
||||
YYLLOC_DEFAULT (yylhs.location, range, yylen);
|
||||
yyerror_range[1].location = yylhs.location;
|
||||
}]])[
|
||||
|
||||
|
||||
+20
-21
@@ -122,33 +122,32 @@ m4_define([b4_stack_define],
|
||||
return seq_.rend ();
|
||||
}
|
||||
|
||||
/// Present a slice of the top of a stack.
|
||||
class slice
|
||||
{
|
||||
public:
|
||||
slice (const stack& stack, int range)
|
||||
: stack_ (stack)
|
||||
, range_ (range)
|
||||
{}
|
||||
|
||||
const T&
|
||||
operator[] (int i) const
|
||||
{
|
||||
return stack_[range_ - i];
|
||||
}
|
||||
|
||||
private:
|
||||
const stack& stack_;
|
||||
int range_;
|
||||
};
|
||||
|
||||
private:
|
||||
stack (const stack&);
|
||||
stack& operator= (const stack&);
|
||||
/// The wrapped container.
|
||||
S seq_;
|
||||
};
|
||||
|
||||
/// Present a slice of the top of a stack.
|
||||
template <typename T, typename S = stack<T> >
|
||||
class slice
|
||||
{
|
||||
public:
|
||||
slice (const S& stack, int range)
|
||||
: stack_ (stack)
|
||||
, range_ (range)
|
||||
{}
|
||||
|
||||
const T&
|
||||
operator[] (int i) const
|
||||
{
|
||||
return stack_[range_ - i];
|
||||
}
|
||||
|
||||
private:
|
||||
const S& stack_;
|
||||
int range_;
|
||||
};
|
||||
]])
|
||||
|
||||
m4_ifdef([b4_stack_file],
|
||||
|
||||
@@ -1066,7 +1066,10 @@ yytnamerr (char *yyres, const char *yystr)
|
||||
case '\\':
|
||||
if (*++yyp != '\\')
|
||||
goto do_not_strip_quotes;
|
||||
/* Fall through. */
|
||||
else
|
||||
goto append;
|
||||
|
||||
append:
|
||||
default:
|
||||
if (yyres)
|
||||
yyres[yyn] = *yyp;
|
||||
|
||||
+148
-34
@@ -4278,16 +4278,16 @@ final action does not use @code{$3}). Bison reports these errors when the
|
||||
Bison}):
|
||||
|
||||
@example
|
||||
$ bison -Wmidrule-value mid.y
|
||||
$ @kbd{bison -Wmidrule-value mid.y}
|
||||
@group
|
||||
mid.y:2.6-13: warning: unset value: $$
|
||||
exp: @{ a(); @} "b" @{ $$ = c(); @} @{ d(); @} "e" @{ f = $1; @};
|
||||
^^^^^^^^
|
||||
^~~~~~~~
|
||||
@end group
|
||||
@group
|
||||
mid.y:2.19-31: warning: unused value: $3
|
||||
exp: @{ a(); @} "b" @{ $$ = c(); @} @{ d(); @} "e" @{ f = $1; @};
|
||||
^^^^^^^^^^^^^
|
||||
^~~~~~~~~~~~~
|
||||
@end group
|
||||
@end example
|
||||
|
||||
@@ -6650,6 +6650,28 @@ For example, if you use @samp{%define api.prefix @{c@}}, the names become
|
||||
@code{cparse}, @code{clex}, @dots{}, @code{CSTYPE}, @code{CLTYPE}, and so
|
||||
on.
|
||||
|
||||
Users of Flex must update the signature of the generated @code{yylex}
|
||||
function. Since the Flex scanner usually includes the generated header of
|
||||
the parser (to get the definitions of the tokens, etc.), the most convenient
|
||||
way is to insert the declaration of @code{yylex} in the @code{provides}
|
||||
section:
|
||||
|
||||
@example
|
||||
%define api.prefix @{c@}
|
||||
// Emitted in the header file, after the definition of YYSTYPE.
|
||||
%code provides
|
||||
@{
|
||||
// Tell Flex the expected prototype of yylex.
|
||||
#define YY_DECL \
|
||||
int clex (CSTYPE *yylval, CLTYPE *yylloc)
|
||||
|
||||
// Declare the scanner.
|
||||
YY_DECL;
|
||||
@}
|
||||
@end example
|
||||
|
||||
@sp 1
|
||||
|
||||
The @code{%define} variable @code{api.prefix} works in two different ways.
|
||||
In the implementation file, it works by adding macro definitions to the
|
||||
beginning of the parser implementation file, defining @code{yyparse} as
|
||||
@@ -9309,7 +9331,7 @@ calc.y: warning: 1 nonterminal useless in grammar [-Wother]
|
||||
calc.y: warning: 1 rule useless in grammar [-Wother]
|
||||
calc.y:19.1-7: warning: nonterminal useless in grammar: useless [-Wother]
|
||||
useless: STR;
|
||||
^^^^^^^
|
||||
^~~~~~~
|
||||
calc.y: warning: 7 shift/reduce conflicts [-Wconflicts-sr]
|
||||
@end example
|
||||
|
||||
@@ -9842,12 +9864,12 @@ Used to output an xhtml enhancement of the @samp{.output} file.
|
||||
|
||||
Sample usage (requires @command{xsltproc}):
|
||||
@example
|
||||
$ bison -x gr.y
|
||||
$ @kbd{bison -x gr.y}
|
||||
@group
|
||||
$ bison --print-datadir
|
||||
$ @kbd{bison --print-datadir}
|
||||
/usr/local/share/bison
|
||||
@end group
|
||||
$ xsltproc /usr/local/share/bison/xslt/xml2xhtml.xsl gr.xml >gr.html
|
||||
$ @kbd{xsltproc /usr/local/share/bison/xslt/xml2xhtml.xsl gr.xml >gr.html}
|
||||
@end example
|
||||
|
||||
@c ================================================= Tracing
|
||||
@@ -10247,28 +10269,65 @@ Print the name of the directory containing locale-dependent data.
|
||||
@item --print-datadir
|
||||
Print the name of the directory containing skeletons and XSLT.
|
||||
|
||||
@item -u
|
||||
@item --update
|
||||
Update the grammar file (remove duplicates, update deprecated directives,
|
||||
etc.) and exit (i.e., do not generate any of the output files). Leaves a
|
||||
backup of the original file with a @code{~} appended. For instance:
|
||||
|
||||
@example
|
||||
@group
|
||||
$ @kbd{cat foo.y}
|
||||
%error-verbose
|
||||
%define parse.error verbose
|
||||
%%
|
||||
exp:;
|
||||
@end group
|
||||
@group
|
||||
$ @kbd{bison -u foo.y}
|
||||
foo.y:1.1-14: warning: deprecated directive, use '%define parse.error verbose' [-Wdeprecated]
|
||||
%error-verbose
|
||||
^~~~~~~~~~~~~~
|
||||
foo.y:2.1-27: error: %define variable 'parse.error' redefined
|
||||
%define parse.error verbose
|
||||
^~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
foo.y:1.1-14: previous definition
|
||||
%error-verbose
|
||||
^~~~~~~~~~~~~~
|
||||
bison: file 'foo.y' was updated (backup: 'foo.y~')
|
||||
@end group
|
||||
@group
|
||||
$ @kbd{cat foo.y}
|
||||
%define parse.error verbose
|
||||
%%
|
||||
exp:;
|
||||
@end group
|
||||
@end example
|
||||
|
||||
See the documentation of @option{--feature=fixit} below for more details.
|
||||
|
||||
@item -y
|
||||
@itemx --yacc
|
||||
Act more like the traditional Yacc command. This can cause different
|
||||
diagnostics to be generated, and may change behavior in other minor
|
||||
ways. Most importantly, imitate Yacc's output file name conventions,
|
||||
so that the parser implementation file is called @file{y.tab.c}, and
|
||||
the other outputs are called @file{y.output} and @file{y.tab.h}.
|
||||
Also, if generating a deterministic parser in C, generate
|
||||
@code{#define} statements in addition to an @code{enum} to associate
|
||||
token numbers with token names. Thus, the following shell script can
|
||||
substitute for Yacc, and the Bison distribution contains such a script
|
||||
for compatibility with POSIX:
|
||||
Act more like the traditional @command{yacc} command. This can cause
|
||||
different diagnostics to be generated (it implies @option{-Wyacc}), and may
|
||||
change behavior in other minor ways. Most importantly, imitate Yacc's
|
||||
output file name conventions, so that the parser implementation file is
|
||||
called @file{y.tab.c}, and the other outputs are called @file{y.output} and
|
||||
@file{y.tab.h}. Also, if generating a deterministic parser in C, generate
|
||||
@code{#define} statements in addition to an @code{enum} to associate token
|
||||
numbers with token names. Thus, the following shell script can substitute
|
||||
for Yacc, and the Bison distribution contains such a script for
|
||||
compatibility with POSIX:
|
||||
|
||||
@example
|
||||
#! /bin/sh
|
||||
bison -y "$@@"
|
||||
@end example
|
||||
|
||||
The @option{-y}/@option{--yacc} option is intended for use with
|
||||
traditional Yacc grammars. If your grammar uses a Bison extension
|
||||
like @samp{%glr-parser}, Bison might not be Yacc-compatible even if
|
||||
this option is specified.
|
||||
The @option{-y}/@option{--yacc} option is intended for use with traditional
|
||||
Yacc grammars. If your grammar uses Bison extensions like
|
||||
@samp{%glr-parser}, Bison might not be Yacc-compatible even if this option
|
||||
is specified.
|
||||
|
||||
@item -W [@var{category}]
|
||||
@itemx --warnings[=@var{category}]
|
||||
@@ -10353,17 +10412,17 @@ Bison reports:
|
||||
@group
|
||||
warning: useless precedence and associativity for "="
|
||||
%nonassoc "="
|
||||
^^^
|
||||
^~~
|
||||
@end group
|
||||
@group
|
||||
warning: useless associativity for "*", use %precedence
|
||||
%left "*"
|
||||
^^^
|
||||
^~~
|
||||
@end group
|
||||
@group
|
||||
warning: useless precedence for "("
|
||||
%precedence "("
|
||||
^^^
|
||||
^~~
|
||||
@end group
|
||||
@end example
|
||||
|
||||
@@ -10412,8 +10471,8 @@ the following commands are @emph{not} equivalent, as the first will not treat
|
||||
S/R conflicts as errors.
|
||||
|
||||
@example
|
||||
$ bison -Werror=yacc,conflicts-sr input.y
|
||||
$ bison -Werror=yacc,error=conflicts-sr input.y
|
||||
$ @kbd{bison -Werror=yacc,conflicts-sr input.y}
|
||||
$ @kbd{bison -Werror=yacc,error=conflicts-sr input.y}
|
||||
@end example
|
||||
|
||||
@item -Wno-error
|
||||
@@ -10449,27 +10508,27 @@ When invoked with @option{-fcaret} (or nothing), Bison will report:
|
||||
@group
|
||||
in.y:3.20-23: error: ambiguous reference: '$exp'
|
||||
exp: exp '+' exp @{ $exp = $1 + $2; @};
|
||||
^^^^
|
||||
^~~~
|
||||
@end group
|
||||
@group
|
||||
in.y:3.1-3: refers to: $exp at $$
|
||||
exp: exp '+' exp @{ $exp = $1 + $2; @};
|
||||
^^^
|
||||
^~~
|
||||
@end group
|
||||
@group
|
||||
in.y:3.6-8: refers to: $exp at $1
|
||||
exp: exp '+' exp @{ $exp = $1 + $2; @};
|
||||
^^^
|
||||
^~~
|
||||
@end group
|
||||
@group
|
||||
in.y:3.14-16: refers to: $exp at $3
|
||||
exp: exp '+' exp @{ $exp = $1 + $2; @};
|
||||
^^^
|
||||
^~~
|
||||
@end group
|
||||
@group
|
||||
in.y:3.32-33: error: $2 of 'exp' has no declared type
|
||||
exp: exp '+' exp @{ $exp = $1 + $2; @};
|
||||
^^
|
||||
^~
|
||||
@end group
|
||||
@end example
|
||||
|
||||
@@ -10487,6 +10546,61 @@ in.y:3.32-33: error: $2 of ‘exp’ has no declared type
|
||||
|
||||
This option is activated by default.
|
||||
|
||||
@item fixit
|
||||
@itemx diagnostics-parseable-fixits
|
||||
Show machine-readable fixes, in a manner similar to GCC's and Clang's
|
||||
@option{-fdiagnostics-parseable-fixits}.
|
||||
|
||||
Fix-its are generated for duplicate directives:
|
||||
|
||||
@example
|
||||
@group
|
||||
$ @kbd{cat foo.y}
|
||||
%define api.prefix @{foo@}
|
||||
%define api.prefix @{bar@}
|
||||
%%
|
||||
exp:;
|
||||
@end group
|
||||
|
||||
@group
|
||||
$ @kbd{bison -ffixit foo.y}
|
||||
foo.y:2.1-24: error: %define variable 'api.prefix' redefined
|
||||
%define api.prefix @{bar@}
|
||||
^~~~~~~~~~~~~~~~~~~~~~~~
|
||||
foo.y:1.1-24: previous definition
|
||||
%define api.prefix @{foo@}
|
||||
^~~~~~~~~~~~~~~~~~~~~~~~
|
||||
fix-it:"foo.y":@{2:1-2:25@}:""
|
||||
foo.y: warning: fix-its can be applied. Rerun with option '--update'. [-Wother]
|
||||
@end group
|
||||
@end example
|
||||
|
||||
They are also generated to update deprecated directives, unless
|
||||
@option{-Wno-deprecated} was given:
|
||||
|
||||
@example
|
||||
@group
|
||||
$ @kbd{cat /tmp/foo.yy}
|
||||
%error-verbose
|
||||
%name-prefix "foo"
|
||||
%%
|
||||
exp:;
|
||||
@end group
|
||||
@group
|
||||
$ @kbd{bison foo.y}
|
||||
foo.y:1.1-14: warning: deprecated directive, use '%define parse.error verbose' [-Wdeprecated]
|
||||
%error-verbose
|
||||
^~~~~~~~~~~~~~
|
||||
foo.y:2.1-18: warning: deprecated directive, use '%define api.prefix @{foo@}' [-Wdeprecated]
|
||||
%name-prefix "foo"
|
||||
^~~~~~~~~~~~~~~~~~
|
||||
foo.y: warning: fix-its can be applied. Rerun with option '--update'. [-Wother]
|
||||
@end group
|
||||
@end example
|
||||
|
||||
The fix-its are applied by @command{bison} itself when given the option
|
||||
@option{-u}/@option{--update}. See its documentation above.
|
||||
|
||||
@end table
|
||||
@end table
|
||||
|
||||
@@ -10926,10 +11040,10 @@ int main ()
|
||||
Compile, and run!
|
||||
|
||||
@example
|
||||
$ bison simple.yy -o simple.cc
|
||||
$ g++ -std=c++14 simple.cc -o simple
|
||||
$ @kbd{bison simple.yy -o simple.cc}
|
||||
$ @kbd{g++ -std=c++14 simple.cc -o simple}
|
||||
@group
|
||||
$ ./simple
|
||||
$ @kbd{./simple}
|
||||
@{I have three numbers for you., 1, 2, 3, And that's all!@}
|
||||
@end group
|
||||
@end example
|
||||
|
||||
@@ -15,6 +15,9 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
SHELL=/bin/sh
|
||||
export SHELL
|
||||
|
||||
me=$(basename "$1" .test)
|
||||
medir=$(dirname "$1" | sed -e 's,.*examples/,,')
|
||||
|
||||
|
||||
+1
-1
Submodule gnulib updated: 315eb5ffc1...34881aff40
+45
-36
@@ -8,6 +8,10 @@
|
||||
/alignof.h
|
||||
/alloca.h
|
||||
/alloca.in.h
|
||||
/allocator.c
|
||||
/allocator.h
|
||||
/areadlink.c
|
||||
/areadlink.h
|
||||
/arg-nonnull.h
|
||||
/argmatch.c
|
||||
/argmatch.h
|
||||
@@ -18,6 +22,11 @@
|
||||
/binary-io.h
|
||||
/bitrotate.c
|
||||
/bitrotate.h
|
||||
/bitset.c
|
||||
/bitset.h
|
||||
/bitset/
|
||||
/bitsetv.c
|
||||
/bitsetv.h
|
||||
/c++defs.h
|
||||
/c-ctype.c
|
||||
/c-ctype.h
|
||||
@@ -26,6 +35,9 @@
|
||||
/c-strcaseeq.h
|
||||
/c-strncasecmp.c
|
||||
/calloc.c
|
||||
/canonicalize-lgpl.c
|
||||
/careadlinkat.c
|
||||
/careadlinkat.h
|
||||
/charset.alias
|
||||
/cloexec.c
|
||||
/cloexec.h
|
||||
@@ -78,6 +90,8 @@
|
||||
/fseterr.h
|
||||
/fstat.c
|
||||
/getdtablesize.c
|
||||
/gethrxtime.c
|
||||
/gethrxtime.h
|
||||
/getopt-cdefs.in.h
|
||||
/getopt-core.h
|
||||
/getopt-ext.h
|
||||
@@ -90,7 +104,16 @@
|
||||
/getopt_int.h
|
||||
/getprogname.c
|
||||
/getprogname.h
|
||||
/getrusage.c
|
||||
/gettext.h
|
||||
/gettime.c
|
||||
/gettimeofday.c
|
||||
/gl_array_list.c
|
||||
/gl_array_list.h
|
||||
/gl_list.c
|
||||
/gl_list.h
|
||||
/gl_xlist.c
|
||||
/gl_xlist.h
|
||||
/gnulib.mk
|
||||
/hard-locale.c
|
||||
/hard-locale.h
|
||||
@@ -112,6 +135,8 @@
|
||||
/limits.in.h
|
||||
/localcharset.c
|
||||
/localcharset.h
|
||||
/localtime-buffer.c
|
||||
/localtime-buffer.h
|
||||
/lstat.c
|
||||
/malloc.c
|
||||
/malloca.c
|
||||
@@ -150,17 +175,23 @@
|
||||
/printf.c
|
||||
/progname.c
|
||||
/progname.h
|
||||
/progreloc.c
|
||||
/quote.h
|
||||
/quotearg.c
|
||||
/quotearg.h
|
||||
/raise.c
|
||||
/rawmemchr.c
|
||||
/rawmemchr.valgrind
|
||||
/readlink.c
|
||||
/realloc.c
|
||||
/ref-add.sed
|
||||
/ref-del.sed
|
||||
/relocatable.c
|
||||
/relocatable.h
|
||||
/relocwrapper.c
|
||||
/sched.h
|
||||
/sched.in.h
|
||||
/setenv.c
|
||||
/sig-handler.c
|
||||
/sig-handler.h
|
||||
/sigaction.c
|
||||
@@ -190,6 +221,8 @@
|
||||
/spawnp.c
|
||||
/sprintf.c
|
||||
/stamp-h1
|
||||
/stat-time.c
|
||||
/stat-time.h
|
||||
/stat-w32.c
|
||||
/stat-w32.h
|
||||
/stat.c
|
||||
@@ -223,13 +256,20 @@
|
||||
/strverscmp.c
|
||||
/sys
|
||||
/sys_ioctl.in.h
|
||||
/sys_resource.in.h
|
||||
/sys_socket.in.h
|
||||
/sys_stat.in.h
|
||||
/sys_time.in.h
|
||||
/sys_times.in.h
|
||||
/sys_types.in.h
|
||||
/sys_wait.in.h
|
||||
/sysexits.in.h
|
||||
/time.h
|
||||
/time.in.h
|
||||
/timespec.c
|
||||
/timespec.h
|
||||
/timevar.c
|
||||
/timevar.h
|
||||
/unistd--.h
|
||||
/unistd-safer.h
|
||||
/unistd.c
|
||||
@@ -267,45 +307,14 @@
|
||||
/xmalloc.c
|
||||
/xmemdup0.c
|
||||
/xmemdup0.h
|
||||
/xreadlink.c
|
||||
/xreadlink.h
|
||||
/xsize.c
|
||||
/xsize.h
|
||||
/xstrndup.c
|
||||
/xstrndup.h
|
||||
/stat-time.c
|
||||
/stat-time.h
|
||||
/timevar.c
|
||||
/timevar.h
|
||||
/sys_time.in.h
|
||||
/sys_times.in.h
|
||||
/gethrxtime.c
|
||||
/gethrxtime.h
|
||||
/getrusage.c
|
||||
/gettime.c
|
||||
/gettimeofday.c
|
||||
/localtime-buffer.c
|
||||
/localtime-buffer.h
|
||||
/sys_resource.in.h
|
||||
/timespec.c
|
||||
/timespec.h
|
||||
/xtime.c
|
||||
/xtime.h
|
||||
/bitset.c
|
||||
/bitset.h
|
||||
/bitset/
|
||||
/bitsetv.c
|
||||
/bitsetv.h
|
||||
/allocator.c
|
||||
/allocator.h
|
||||
/areadlink.c
|
||||
/areadlink.h
|
||||
/canonicalize-lgpl.c
|
||||
/careadlinkat.c
|
||||
/careadlinkat.h
|
||||
/progreloc.c
|
||||
/readlink.c
|
||||
/relocatable.c
|
||||
/relocatable.h
|
||||
/relocwrapper.c
|
||||
/setenv.c
|
||||
/xreadlink.c
|
||||
/xreadlink.h
|
||||
/rename.c
|
||||
/rmdir.c
|
||||
/same-inode.h
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
src/complain.c
|
||||
src/conflicts.c
|
||||
src/files.c
|
||||
src/fixits.c
|
||||
src/getargs.c
|
||||
src/gram.c
|
||||
src/graphviz.c
|
||||
|
||||
+28
-4
@@ -28,6 +28,7 @@
|
||||
|
||||
#include "complain.h"
|
||||
#include "files.h"
|
||||
#include "fixits.h"
|
||||
#include "getargs.h"
|
||||
#include "quote.h"
|
||||
|
||||
@@ -278,15 +279,18 @@ error_message (const location *loc, warnings flags, const char *prefix,
|
||||
*indent_ptr = pos;
|
||||
else if (*indent_ptr > pos)
|
||||
fprintf (stderr, "%*s", *indent_ptr - pos, "");
|
||||
indent_ptr = 0;
|
||||
indent_ptr = NULL;
|
||||
}
|
||||
|
||||
if (prefix)
|
||||
fprintf (stderr, "%s: ", prefix);
|
||||
|
||||
vfprintf (stderr, message, args);
|
||||
if (! (flags & silent))
|
||||
/* Print the type of warning, only if this is not a sub message
|
||||
(in which case the prefix is null). */
|
||||
if (! (flags & silent) && prefix)
|
||||
warnings_print_categories (flags, stderr);
|
||||
|
||||
{
|
||||
size_t l = strlen (message);
|
||||
if (l < 2 || message[l - 2] != ':' || message[l - 1] != ' ')
|
||||
@@ -393,6 +397,9 @@ deprecated_directive (location const *loc, char const *old, char const *upd)
|
||||
complain (loc, Wdeprecated,
|
||||
_("deprecated directive: %s, use %s"),
|
||||
quote (old), quote_n (1, upd));
|
||||
/* Register updates only if -Wdeprecated is enabled. */
|
||||
if (warnings_flag[warning_deprecated] != severity_disabled)
|
||||
fixits_register (loc, upd);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -400,7 +407,24 @@ duplicate_directive (char const *directive,
|
||||
location first, location second)
|
||||
{
|
||||
unsigned i = 0;
|
||||
complain (&second, complaint, _("only one %s allowed per rule"), directive);
|
||||
if (feature_flag & feature_caret)
|
||||
complain_indent (&second, Wother, &i, _("duplicate directive"));
|
||||
else
|
||||
complain_indent (&second, Wother, &i, _("duplicate directive: %s"), quote (directive));
|
||||
i += SUB_INDENT;
|
||||
complain_indent (&first, complaint, &i, _("previous declaration"));
|
||||
complain_indent (&first, Wother, &i, _("previous declaration"));
|
||||
fixits_register (&second, "");
|
||||
}
|
||||
|
||||
void
|
||||
duplicate_rule_directive (char const *directive,
|
||||
location first, location second)
|
||||
{
|
||||
unsigned i = 0;
|
||||
complain_indent (&second, complaint, &i,
|
||||
_("only one %s allowed per rule"), directive);
|
||||
i += SUB_INDENT;
|
||||
complain_indent (&first, complaint, &i,
|
||||
_("previous declaration"));
|
||||
fixits_register (&second, "");
|
||||
}
|
||||
|
||||
+5
-1
@@ -126,10 +126,14 @@ void bison_directive (location const *loc, char const *directive);
|
||||
void deprecated_directive (location const *loc,
|
||||
char const *obsolete, char const *updated);
|
||||
|
||||
/** Report a repeated directive for a rule. */
|
||||
/** Report a repeated directive. */
|
||||
void duplicate_directive (char const *directive,
|
||||
location first, location second);
|
||||
|
||||
/** Report a repeated directive for a rule. */
|
||||
void duplicate_rule_directive (char const *directive,
|
||||
location first, location second);
|
||||
|
||||
/** Warnings treated as errors shouldn't stop the execution as regular
|
||||
errors should (because due to their nature, it is safe to go
|
||||
on). Thus, there are three possible execution statuses. */
|
||||
|
||||
+24
-31
@@ -43,7 +43,9 @@
|
||||
|
||||
char const *spec_outfile = NULL; /* for -o. */
|
||||
char const *spec_file_prefix = NULL; /* for -b. */
|
||||
location spec_file_prefix_loc = EMPTY_LOCATION_INIT;
|
||||
char const *spec_name_prefix = NULL; /* for -p. */
|
||||
location spec_name_prefix_loc = EMPTY_LOCATION_INIT;
|
||||
char *spec_verbose_file = NULL; /* for --verbose. */
|
||||
char *spec_graph_file = NULL; /* for -g. */
|
||||
char *spec_xml_file = NULL; /* for -x. */
|
||||
@@ -115,14 +117,12 @@ concat2 (char const *str1, char const *str2)
|
||||
FILE *
|
||||
xfopen (const char *name, const char *mode)
|
||||
{
|
||||
FILE *ptr;
|
||||
|
||||
ptr = fopen_safer (name, mode);
|
||||
if (!ptr)
|
||||
FILE *res = fopen_safer (name, mode);
|
||||
if (!res)
|
||||
error (EXIT_FAILURE, get_errno (),
|
||||
_("%s: cannot open"), quotearg_colon (name));
|
||||
|
||||
return ptr;
|
||||
return res;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------.
|
||||
@@ -243,19 +243,18 @@ file_name_split (const char *file_name,
|
||||
}
|
||||
}
|
||||
|
||||
/* Compute ALL_BUT_EXT and ALL_BUT_TAB_EXT from SPEC_OUTFILE or
|
||||
GRAMMAR_FILE.
|
||||
|
||||
The precise -o name will be used for FTABLE. For other output
|
||||
files, remove the ".c" or ".tab.c" suffix. */
|
||||
|
||||
static void
|
||||
compute_file_name_parts (void)
|
||||
{
|
||||
const char *base, *tab, *ext;
|
||||
|
||||
/* Compute ALL_BUT_EXT and ALL_BUT_TAB_EXT from SPEC_OUTFILE
|
||||
or GRAMMAR_FILE.
|
||||
|
||||
The precise -o name will be used for FTABLE. For other output
|
||||
files, remove the ".c" or ".tab.c" suffix. */
|
||||
if (spec_outfile)
|
||||
{
|
||||
const char *base, *tab, *ext;
|
||||
file_name_split (spec_outfile, &base, &tab, &ext);
|
||||
dir_prefix = xstrndup (spec_outfile, base - spec_outfile);
|
||||
|
||||
@@ -275,6 +274,7 @@ compute_file_name_parts (void)
|
||||
}
|
||||
else
|
||||
{
|
||||
const char *base, *tab, *ext;
|
||||
file_name_split (grammar_file, &base, &tab, &ext);
|
||||
|
||||
if (spec_file_prefix)
|
||||
@@ -285,7 +285,7 @@ compute_file_name_parts (void)
|
||||
last_component (spec_file_prefix) - spec_file_prefix);
|
||||
all_but_tab_ext = xstrdup (spec_file_prefix);
|
||||
}
|
||||
else if (yacc_flag)
|
||||
else if (! location_empty (yacc_loc))
|
||||
{
|
||||
/* If --yacc, then the output is 'y.tab.c'. */
|
||||
dir_prefix = xstrdup ("");
|
||||
@@ -306,7 +306,7 @@ compute_file_name_parts (void)
|
||||
all_but_ext = xstrdup (all_but_tab_ext);
|
||||
|
||||
/* Compute the extensions from the grammar file name. */
|
||||
if (ext && !yacc_flag)
|
||||
if (ext && location_empty (yacc_loc))
|
||||
compute_exts_from_gf (ext);
|
||||
}
|
||||
}
|
||||
@@ -374,16 +374,13 @@ output_file_name_check (char **file_name, bool source)
|
||||
conflict = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < generated_files_size; i++)
|
||||
if (STREQ (generated_files[i].name, *file_name))
|
||||
{
|
||||
complain (NULL, Wother, _("conflicting outputs to file %s"),
|
||||
quote (generated_files[i].name));
|
||||
conflict = true;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < generated_files_size; i++)
|
||||
if (STREQ (generated_files[i].name, *file_name))
|
||||
{
|
||||
complain (NULL, Wother, _("conflicting outputs to file %s"),
|
||||
quote (generated_files[i].name));
|
||||
conflict = true;
|
||||
}
|
||||
if (conflict)
|
||||
{
|
||||
free (*file_name);
|
||||
@@ -401,8 +398,7 @@ output_file_name_check (char **file_name, bool source)
|
||||
void
|
||||
unlink_generated_sources (void)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < generated_files_size; i++)
|
||||
for (int i = 0; i < generated_files_size; i++)
|
||||
if (generated_files[i].is_source)
|
||||
/* Ignore errors. The file might not even exist. */
|
||||
unlink (generated_files[i].name);
|
||||
@@ -418,10 +414,7 @@ output_file_names_free (void)
|
||||
free (spec_defines_file);
|
||||
free (parser_file_name);
|
||||
free (dir_prefix);
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < generated_files_size; i++)
|
||||
free (generated_files[i].name);
|
||||
}
|
||||
for (int i = 0; i < generated_files_size; i++)
|
||||
free (generated_files[i].name);
|
||||
free (generated_files);
|
||||
}
|
||||
|
||||
+4
-1
@@ -21,6 +21,7 @@
|
||||
#ifndef FILES_H_
|
||||
# define FILES_H_
|
||||
|
||||
# include "location.h"
|
||||
# include "uniqstr.h"
|
||||
|
||||
/* File name specified with -o for the output file, or 0 if no -o. */
|
||||
@@ -31,9 +32,11 @@ extern char *parser_file_name;
|
||||
|
||||
/* Symbol prefix specified with -p, or 0 if no -p. */
|
||||
extern const char *spec_name_prefix;
|
||||
extern location spec_name_prefix_loc;
|
||||
|
||||
/* File name prefix specified with -b, or 0 if no -b. */
|
||||
extern char const *spec_file_prefix;
|
||||
extern location spec_file_prefix_loc;
|
||||
|
||||
/* --verbose. */
|
||||
extern char *spec_verbose_file;
|
||||
@@ -55,7 +58,7 @@ extern char *dir_prefix;
|
||||
and therefore GCC warns about a name clash. */
|
||||
extern uniqstr grammar_file;
|
||||
|
||||
/* The current file name. Might change with %include, or with #line. */
|
||||
/* The current file name. Might change with #line. */
|
||||
extern uniqstr current_file;
|
||||
|
||||
/* The computed base for output file names. */
|
||||
|
||||
+212
@@ -0,0 +1,212 @@
|
||||
/* Support for fixing grammar files.
|
||||
|
||||
Copyright (C) 2019 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of Bison, the GNU Compiler Compiler.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "fixits.h"
|
||||
|
||||
#include "system.h"
|
||||
|
||||
#include "error.h"
|
||||
#include "get-errno.h"
|
||||
#include "getargs.h"
|
||||
#include "gl_array_list.h"
|
||||
#include "gl_xlist.h"
|
||||
#include "progname.h"
|
||||
#include "quote.h"
|
||||
#include "quotearg.h"
|
||||
#include "vasnprintf.h"
|
||||
|
||||
#include "files.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
location location;
|
||||
char *fix;
|
||||
} fixit;
|
||||
|
||||
gl_list_t fixits = NULL;
|
||||
|
||||
static fixit *
|
||||
fixit_new (location const *loc, char const* fix)
|
||||
{
|
||||
fixit *res = xmalloc (sizeof *res);
|
||||
res->location = *loc;
|
||||
res->fix = xstrdup (fix);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
fixit_free (fixit *f)
|
||||
{
|
||||
free (f->fix);
|
||||
free (f);
|
||||
}
|
||||
|
||||
|
||||
/* GCC and Clang follow the same pattern.
|
||||
https://gcc.gnu.org/onlinedocs/gcc/Diagnostic-Message-Formatting-Options.html
|
||||
http://clang.llvm.org/docs/UsersManual.html#cmdoption-fdiagnostics-parseable-fixits */
|
||||
static void
|
||||
fixit_print (fixit const *f, FILE *out)
|
||||
{
|
||||
fprintf (out, "fix-it:%s:{%d:%d-%d:%d}:%s\n",
|
||||
quotearg_n_style (1, c_quoting_style, f->location.start.file),
|
||||
f->location.start.line, f->location.start.column,
|
||||
f->location.end.line, f->location.end.column,
|
||||
quotearg_n_style (2, c_quoting_style, f->fix));
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
fixits_register (location const *loc, char const* fix)
|
||||
{
|
||||
if (!fixits)
|
||||
fixits = gl_list_create_empty (GL_ARRAY_LIST,
|
||||
/* equals */ NULL,
|
||||
/* hashcode */ NULL,
|
||||
(gl_listelement_dispose_fn) fixit_free,
|
||||
true);
|
||||
fixit *f = fixit_new (loc, fix);
|
||||
gl_list_add_last (fixits, f);
|
||||
if (feature_flag & feature_fixit_parsable)
|
||||
fixit_print (f, stderr);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
fixits_empty (void)
|
||||
{
|
||||
return !fixits;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
fixits_run (void)
|
||||
{
|
||||
if (!fixits)
|
||||
return;
|
||||
|
||||
/* This is not unlike what is done in location_caret. */
|
||||
uniqstr input = ((fixit *) gl_list_get_at (fixits, 0))->location.start.file;
|
||||
/* Backup the file. */
|
||||
char buf[256];
|
||||
size_t len = sizeof (buf);
|
||||
char *backup = asnprintf (buf, &len, "%s~", input);
|
||||
if (!backup)
|
||||
xalloc_die ();
|
||||
if (rename (input, backup))
|
||||
error (EXIT_FAILURE, get_errno (),
|
||||
_("%s: cannot backup"), quotearg_colon (input));
|
||||
FILE *in = xfopen (backup, "r");
|
||||
FILE *out = xfopen (input, "w");
|
||||
size_t line = 1;
|
||||
size_t offset = 1;
|
||||
fixit const *f = NULL;
|
||||
gl_list_iterator_t iter = gl_list_iterator (fixits);
|
||||
while (gl_list_iterator_next (&iter, (const void**) &f, NULL))
|
||||
{
|
||||
/* Look for the correct line. */
|
||||
while (line < f->location.start.line)
|
||||
{
|
||||
int c = getc (in);
|
||||
if (c == EOF)
|
||||
break;
|
||||
if (c == '\n')
|
||||
{
|
||||
++line;
|
||||
offset = 1;
|
||||
}
|
||||
putc (c, out);
|
||||
}
|
||||
/* Look for the right offset. */
|
||||
while (offset < f->location.start.column)
|
||||
{
|
||||
int c = getc (in);
|
||||
if (c == EOF)
|
||||
break;
|
||||
++offset;
|
||||
putc (c, out);
|
||||
}
|
||||
|
||||
/* Paste the fix instead. */
|
||||
fputs (f->fix, out);
|
||||
|
||||
/* Skip the bad input. */
|
||||
while (line < f->location.end.line)
|
||||
{
|
||||
int c = getc (in);
|
||||
if (c == EOF)
|
||||
break;
|
||||
if (c == '\n')
|
||||
{
|
||||
++line;
|
||||
offset = 1;
|
||||
}
|
||||
}
|
||||
while (offset < f->location.end.column)
|
||||
{
|
||||
int c = getc (in);
|
||||
if (c == EOF)
|
||||
break;
|
||||
++offset;
|
||||
}
|
||||
/* If erasing the content of a full line, also remove the
|
||||
end-of-line. */
|
||||
if (f->fix[0] == 0 && f->location.start.column == 1)
|
||||
{
|
||||
int c = getc (in);
|
||||
if (c == EOF)
|
||||
break;
|
||||
else if (c == '\n')
|
||||
{
|
||||
++line;
|
||||
offset = 1;
|
||||
}
|
||||
else
|
||||
ungetc (c, in);
|
||||
}
|
||||
}
|
||||
/* Paste the rest of the file. */
|
||||
{
|
||||
int c;
|
||||
while ((c = getc (in)) != EOF)
|
||||
putc (c, out);
|
||||
}
|
||||
|
||||
gl_list_iterator_free (&iter);
|
||||
xfclose (out);
|
||||
xfclose (in);
|
||||
fprintf (stderr, "%s: file %s was updated (backup: %s)\n",
|
||||
program_name, quote_n (0, input), quote_n (1, backup));
|
||||
if (backup != buf)
|
||||
free (backup);
|
||||
}
|
||||
|
||||
|
||||
/* Free the registered fixits. */
|
||||
void fixits_free (void)
|
||||
{
|
||||
if (fixits)
|
||||
{
|
||||
gl_list_free (fixits);
|
||||
fixits = NULL;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/* Support for fixing grammar files.
|
||||
|
||||
Copyright (C) 2019 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef FIXITS_H_
|
||||
# define FIXITS_H_ 1
|
||||
|
||||
# include "location.h"
|
||||
|
||||
/* Declare a fix to apply. */
|
||||
void fixits_register (location const *loc, char const* update);
|
||||
|
||||
/* Apply the fixits: update the source file. */
|
||||
void fixits_run (void);
|
||||
|
||||
/* Whether there are no fixits. */
|
||||
bool fixits_empty (void);
|
||||
|
||||
/* Free the registered fixits. */
|
||||
void fixits_free (void);
|
||||
|
||||
#endif /* !FIXITS_H_ */
|
||||
+20
-8
@@ -36,12 +36,13 @@
|
||||
#include "quote.h"
|
||||
#include "uniqstr.h"
|
||||
|
||||
bool defines_flag;
|
||||
bool graph_flag;
|
||||
bool xml_flag;
|
||||
bool no_lines_flag;
|
||||
bool token_table_flag;
|
||||
bool yacc_flag; /* for -y */
|
||||
bool defines_flag = false;
|
||||
bool graph_flag = false;
|
||||
bool xml_flag = false;
|
||||
bool no_lines_flag = false;
|
||||
bool token_table_flag = false;
|
||||
location yacc_loc = EMPTY_LOCATION_INIT;
|
||||
bool update_flag = false; /* for -u */
|
||||
|
||||
bool nondeterministic_parser = false;
|
||||
bool glr_parser = false;
|
||||
@@ -228,6 +229,7 @@ static const char * const feature_args[] =
|
||||
{
|
||||
"none",
|
||||
"caret", "diagnostics-show-caret",
|
||||
"fixit", "diagnostics-parseable-fixits",
|
||||
"all",
|
||||
0
|
||||
};
|
||||
@@ -236,6 +238,7 @@ static const int feature_types[] =
|
||||
{
|
||||
feature_none,
|
||||
feature_caret, feature_caret,
|
||||
feature_fixit_parsable, feature_fixit_parsable,
|
||||
feature_all
|
||||
};
|
||||
|
||||
@@ -281,7 +284,10 @@ Operation modes:\n\
|
||||
-h, --help display this help and exit\n\
|
||||
-V, --version output version information and exit\n\
|
||||
--print-localedir output directory containing locale-dependent data\n\
|
||||
and exit\n\
|
||||
--print-datadir output directory containing skeletons and XSLT\n\
|
||||
and exit\n\
|
||||
-u, --update apply fixes to the source grammar file and exit\n\
|
||||
-y, --yacc emulate POSIX Yacc\n\
|
||||
-W, --warnings[=CATEGORY] report the warnings falling in CATEGORY\n\
|
||||
-f, --feature[=FEATURE] activate miscellaneous features\n\
|
||||
@@ -476,6 +482,7 @@ static char const short_options[] =
|
||||
"p:"
|
||||
"r:"
|
||||
"t"
|
||||
"u" /* --update */
|
||||
"v"
|
||||
"x::"
|
||||
"y"
|
||||
@@ -497,6 +504,7 @@ static struct option const long_options[] =
|
||||
{ "version", no_argument, 0, 'V' },
|
||||
{ "print-localedir", no_argument, 0, PRINT_LOCALEDIR_OPTION },
|
||||
{ "print-datadir", no_argument, 0, PRINT_DATADIR_OPTION },
|
||||
{ "update", no_argument, 0, 'u' },
|
||||
{ "warnings", optional_argument, 0, 'W' },
|
||||
|
||||
/* Parser. */
|
||||
@@ -682,6 +690,10 @@ getargs (int argc, char *argv[])
|
||||
MUSCLE_PERCENT_DEFINE_D);
|
||||
break;
|
||||
|
||||
case 'u':
|
||||
update_flag = true;
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
report_flag |= report_states;
|
||||
break;
|
||||
@@ -696,8 +708,8 @@ getargs (int argc, char *argv[])
|
||||
break;
|
||||
|
||||
case 'y':
|
||||
warning_argmatch ("error=yacc", 0, 6);
|
||||
yacc_flag = true;
|
||||
warning_argmatch ("yacc", 0, 0);
|
||||
yacc_loc = command_line_location ();
|
||||
break;
|
||||
|
||||
case LOCATIONS_OPTION:
|
||||
|
||||
+6
-5
@@ -39,8 +39,8 @@ extern bool graph_flag; /* for -g */
|
||||
extern bool xml_flag; /* for -x */
|
||||
extern bool no_lines_flag; /* for -l */
|
||||
extern bool token_table_flag; /* for -k */
|
||||
extern bool yacc_flag; /* for -y */
|
||||
|
||||
extern location yacc_loc; /* for -y */
|
||||
extern bool update_flag; /* for -u */
|
||||
|
||||
/* GLR_PARSER is true if the input file says to use the GLR
|
||||
(Generalized LR) parser, and to output some additional information
|
||||
@@ -114,9 +114,10 @@ extern int trace_flag;
|
||||
|
||||
enum feature
|
||||
{
|
||||
feature_none = 0, /**< No additional feature. */
|
||||
feature_caret = 1 << 0, /**< Enhance the output of errors with carets. */
|
||||
feature_all = ~0 /**< All above features. */
|
||||
feature_none = 0, /**< No additional feature. */
|
||||
feature_caret = 1 << 0, /**< Output errors with carets. */
|
||||
feature_fixit_parsable = 1 << 1, /**< Issue instructions to fix the sources. */
|
||||
feature_all = ~0 /**< All above features. */
|
||||
};
|
||||
/** What additional features to use. */
|
||||
extern int feature_flag;
|
||||
|
||||
+1
-1
@@ -329,7 +329,7 @@ state_lookahead_tokens_count (state *s, bool default_reduction_only_for_accept)
|
||||
&& default_reduction_only_for_accept))
|
||||
n_lookahead_tokens += rp->num;
|
||||
else
|
||||
s->consistent = 1;
|
||||
s->consistent = true;
|
||||
|
||||
return n_lookahead_tokens;
|
||||
}
|
||||
|
||||
@@ -46,6 +46,8 @@ src_bison_SOURCES = \
|
||||
src/derives.h \
|
||||
src/files.c \
|
||||
src/files.h \
|
||||
src/fixits.c \
|
||||
src/fixits.h \
|
||||
src/flex-scanner.h \
|
||||
src/getargs.c \
|
||||
src/getargs.h \
|
||||
|
||||
+8
-1
@@ -209,13 +209,20 @@ location_caret (location loc, FILE *out)
|
||||
/* Print the carets (at least one), with the same indent as above.*/
|
||||
fprintf (out, " %*s", loc.start.column - 1, "");
|
||||
for (i = loc.start.column; i == loc.start.column || i < len; ++i)
|
||||
putc ('^', out);
|
||||
putc (i == loc.start.column ? '^' : '~', out);
|
||||
}
|
||||
putc ('\n', out);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
location_empty (location loc)
|
||||
{
|
||||
return !loc.start.file && !loc.start.line && !loc.start.column
|
||||
&& !loc.end.file && !loc.end.line && !loc.end.column;
|
||||
}
|
||||
|
||||
void
|
||||
boundary_set_from_string (boundary *bound, char *loc_str)
|
||||
{
|
||||
|
||||
@@ -126,6 +126,9 @@ location_cmp (location a, location b)
|
||||
return res;
|
||||
}
|
||||
|
||||
/* Whether this is the empty location. */
|
||||
bool location_empty (location loc);
|
||||
|
||||
/* LOC_STR must be formatted as 'file:line.column', it will be modified. */
|
||||
void boundary_set_from_string (boundary *bound, char *loc_str);
|
||||
|
||||
|
||||
+45
-26
@@ -35,6 +35,7 @@
|
||||
#include "conflicts.h"
|
||||
#include "derives.h"
|
||||
#include "files.h"
|
||||
#include "fixits.h"
|
||||
#include "getargs.h"
|
||||
#include "gram.h"
|
||||
#include "lalr.h"
|
||||
@@ -154,31 +155,34 @@ main (int argc, char *argv[])
|
||||
|
||||
print_precedence_warnings ();
|
||||
|
||||
/* Output file names. */
|
||||
compute_output_file_names ();
|
||||
|
||||
/* Output the detailed report on the grammar. */
|
||||
if (report_flag)
|
||||
if (!update_flag)
|
||||
{
|
||||
timevar_push (tv_report);
|
||||
print_results ();
|
||||
timevar_pop (tv_report);
|
||||
}
|
||||
/* Output file names. */
|
||||
compute_output_file_names ();
|
||||
|
||||
/* Output the graph. */
|
||||
if (graph_flag)
|
||||
{
|
||||
timevar_push (tv_graph);
|
||||
print_graph ();
|
||||
timevar_pop (tv_graph);
|
||||
}
|
||||
/* Output the detailed report on the grammar. */
|
||||
if (report_flag)
|
||||
{
|
||||
timevar_push (tv_report);
|
||||
print_results ();
|
||||
timevar_pop (tv_report);
|
||||
}
|
||||
|
||||
/* Output xml. */
|
||||
if (xml_flag)
|
||||
{
|
||||
timevar_push (tv_xml);
|
||||
print_xml ();
|
||||
timevar_pop (tv_xml);
|
||||
/* Output the graph. */
|
||||
if (graph_flag)
|
||||
{
|
||||
timevar_push (tv_graph);
|
||||
print_graph ();
|
||||
timevar_pop (tv_graph);
|
||||
}
|
||||
|
||||
/* Output xml. */
|
||||
if (xml_flag)
|
||||
{
|
||||
timevar_push (tv_xml);
|
||||
print_xml ();
|
||||
timevar_pop (tv_xml);
|
||||
}
|
||||
}
|
||||
|
||||
/* Stop if there were errors, to avoid trashing previous output
|
||||
@@ -192,9 +196,12 @@ main (int argc, char *argv[])
|
||||
timevar_pop (tv_free);
|
||||
|
||||
/* Output the tables and the parser to ftable. In file output. */
|
||||
timevar_push (tv_parser);
|
||||
output ();
|
||||
timevar_pop (tv_parser);
|
||||
if (!update_flag)
|
||||
{
|
||||
timevar_push (tv_parser);
|
||||
output ();
|
||||
timevar_pop (tv_parser);
|
||||
}
|
||||
|
||||
timevar_push (tv_free);
|
||||
nullable_free ();
|
||||
@@ -210,7 +217,6 @@ main (int argc, char *argv[])
|
||||
contains things such as user actions, prologue, epilogue etc. */
|
||||
gram_scanner_free ();
|
||||
muscle_free ();
|
||||
uniqstrs_free ();
|
||||
code_scanner_free ();
|
||||
skel_scanner_free ();
|
||||
quotearg_free ();
|
||||
@@ -227,5 +233,18 @@ main (int argc, char *argv[])
|
||||
|
||||
cleanup_caret ();
|
||||
|
||||
/* Fix input file now, even if there are errors: that's less
|
||||
warnings in the following runs. */
|
||||
if (!fixits_empty ())
|
||||
{
|
||||
if (update_flag)
|
||||
fixits_run ();
|
||||
else
|
||||
complain (NULL, Wother,
|
||||
_("fix-its can be applied. Rerun with option '--update'."));
|
||||
fixits_free ();
|
||||
}
|
||||
uniqstrs_free ();
|
||||
|
||||
return complaint_status ? EXIT_FAILURE : EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
+66
-40
@@ -24,6 +24,7 @@
|
||||
|
||||
#include "complain.h"
|
||||
#include "files.h"
|
||||
#include "fixits.h"
|
||||
#include "getargs.h"
|
||||
#include "muscle-tab.h"
|
||||
#include "quote.h"
|
||||
@@ -429,12 +430,14 @@ define_directive (char const *assignment,
|
||||
/** If the \a variable name is obsolete, return the name to use,
|
||||
* otherwise \a variable. If the \a value is obsolete, update it too.
|
||||
*
|
||||
* Allocates the returned value. */
|
||||
* Allocates the returned value if needed, otherwise the returned
|
||||
* value is exactly \a variable. */
|
||||
static
|
||||
char *
|
||||
muscle_percent_variable_update (char const *variable, location variable_loc,
|
||||
char const *
|
||||
muscle_percent_variable_update (char const *variable,
|
||||
muscle_kind kind,
|
||||
char const **value)
|
||||
char const **value,
|
||||
char **old, char **upd)
|
||||
{
|
||||
typedef struct
|
||||
{
|
||||
@@ -444,8 +447,15 @@ muscle_percent_variable_update (char const *variable, location variable_loc,
|
||||
} conversion_type;
|
||||
const conversion_type conversion[] =
|
||||
{
|
||||
{ "%error-verbose", "parse.error=verbose", muscle_keyword },
|
||||
{ "%error_verbose", "parse.error=verbose", muscle_keyword },
|
||||
{ "abstract", "api.parser.abstract", muscle_keyword },
|
||||
{ "annotations", "api.parser.annotations", muscle_code },
|
||||
{ "api.push_pull", "api.push-pull", muscle_keyword },
|
||||
{ "api.tokens.prefix", "api.token.prefix", muscle_code },
|
||||
{ "extends", "api.parser.extends", muscle_keyword },
|
||||
{ "final", "api.parser.final", muscle_keyword },
|
||||
{ "implements", "api.parser.implements", muscle_keyword },
|
||||
{ "lex_symbol", "api.token.constructor", -1 },
|
||||
{ "location_type", "api.location.type", muscle_code },
|
||||
{ "lr.default-reductions", "lr.default-reduction", muscle_keyword },
|
||||
@@ -453,16 +463,11 @@ muscle_percent_variable_update (char const *variable, location variable_loc,
|
||||
{ "lr.keep_unreachable_states", "lr.keep-unreachable-state", muscle_keyword },
|
||||
{ "namespace", "api.namespace", muscle_code },
|
||||
{ "parser_class_name", "api.parser.class", muscle_code },
|
||||
{ "public", "api.parser.public", muscle_keyword },
|
||||
{ "strictfp", "api.parser.strictfp", muscle_keyword },
|
||||
{ "stype", "api.value.type", -1 },
|
||||
{ "variant=", "api.value.type=variant", -1 },
|
||||
{ "variant=true", "api.value.type=variant", -1 },
|
||||
{ "abstract", "api.parser.abstract", muscle_keyword },
|
||||
{ "annotations", "api.parser.annotations", muscle_code },
|
||||
{ "extends", "api.parser.extends", muscle_keyword },
|
||||
{ "final", "api.parser.final", muscle_keyword },
|
||||
{ "implements", "api.parser.implements", muscle_keyword },
|
||||
{ "public", "api.parser.public", muscle_keyword },
|
||||
{ "strictfp", "api.parser.strictfp", muscle_keyword },
|
||||
{ NULL, NULL, -1, }
|
||||
};
|
||||
|
||||
@@ -474,22 +479,25 @@ muscle_percent_variable_update (char const *variable, location variable_loc,
|
||||
&& STREQ (eq + 1, *value))
|
||||
: STREQ (c->obsolete, variable))
|
||||
{
|
||||
char *old = define_directive (c->obsolete, kind, *value);
|
||||
char *upd = define_directive (c->updated, c->kind, *value);
|
||||
deprecated_directive (&variable_loc, old, upd);
|
||||
free (old);
|
||||
free (upd);
|
||||
char *res = xstrdup (c->updated);
|
||||
char *eq2 = strchr (res, '=');
|
||||
if (eq2)
|
||||
{
|
||||
*eq2 = '\0';
|
||||
*value = eq2 + 1;
|
||||
}
|
||||
return res;
|
||||
/* Generate the deprecation warning. */
|
||||
*old = c->obsolete[0] == '%'
|
||||
? xstrdup (c->obsolete)
|
||||
: define_directive (c->obsolete, kind, *value);
|
||||
*upd = define_directive (c->updated, c->kind, *value);
|
||||
/* Update the variable and its value. */
|
||||
{
|
||||
char *res = xstrdup (c->updated);
|
||||
char *eq2 = strchr (res, '=');
|
||||
if (eq2)
|
||||
{
|
||||
*eq2 = '\0';
|
||||
*value = eq2 + 1;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
}
|
||||
}
|
||||
return xstrdup (variable);
|
||||
return variable;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -499,8 +507,11 @@ muscle_percent_define_insert (char const *var, location variable_loc,
|
||||
muscle_percent_define_how how)
|
||||
{
|
||||
/* Backward compatibility. */
|
||||
char *variable
|
||||
= muscle_percent_variable_update (var, variable_loc, kind, &value);
|
||||
char *old = NULL;
|
||||
char *upd = NULL;
|
||||
char const *variable
|
||||
= muscle_percent_variable_update (var, kind,
|
||||
&value, &old, &upd);
|
||||
uniqstr name = muscle_name (variable, NULL);
|
||||
uniqstr loc_name = muscle_name (variable, "loc");
|
||||
uniqstr syncline_name = muscle_name (variable, "syncline");
|
||||
@@ -508,21 +519,33 @@ muscle_percent_define_insert (char const *var, location variable_loc,
|
||||
uniqstr kind_name = muscle_name (variable, "kind");
|
||||
|
||||
/* Command-line options are processed before the grammar file. */
|
||||
if (how == MUSCLE_PERCENT_DEFINE_GRAMMAR_FILE
|
||||
&& muscle_find_const (name))
|
||||
bool warned = false;
|
||||
if (how == MUSCLE_PERCENT_DEFINE_GRAMMAR_FILE)
|
||||
{
|
||||
muscle_percent_define_how how_old = atoi (muscle_find_const (how_name));
|
||||
if (how_old == MUSCLE_PERCENT_DEFINE_F)
|
||||
goto end;
|
||||
unsigned i = 0;
|
||||
complain_indent (&variable_loc, complaint, &i,
|
||||
_("%%define variable %s redefined"),
|
||||
quote (variable));
|
||||
i += SUB_INDENT;
|
||||
location loc = muscle_percent_define_get_loc (variable);
|
||||
complain_indent (&loc, complaint, &i, _("previous definition"));
|
||||
char const *current_value = muscle_find_const (name);
|
||||
if (current_value)
|
||||
{
|
||||
muscle_percent_define_how how_old
|
||||
= atoi (muscle_find_const (how_name));
|
||||
if (how_old == MUSCLE_PERCENT_DEFINE_F)
|
||||
goto end;
|
||||
unsigned i = 0;
|
||||
/* If assigning the same value, make it a warning. */
|
||||
warnings warn = STREQ (value, current_value) ? Wother : complaint;
|
||||
complain_indent (&variable_loc, warn, &i,
|
||||
_("%%define variable %s redefined"),
|
||||
quote (variable));
|
||||
i += SUB_INDENT;
|
||||
location loc = muscle_percent_define_get_loc (variable);
|
||||
complain_indent (&loc, warn, &i, _("previous definition"));
|
||||
fixits_register (&variable_loc, "");
|
||||
warned = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!warned && old && upd)
|
||||
deprecated_directive (&variable_loc, old, upd);
|
||||
|
||||
MUSCLE_INSERT_STRING (name, value);
|
||||
muscle_insert (loc_name, "");
|
||||
muscle_location_grow (loc_name, variable_loc);
|
||||
@@ -533,7 +556,10 @@ muscle_percent_define_insert (char const *var, location variable_loc,
|
||||
MUSCLE_INSERT_INT (how_name, how);
|
||||
MUSCLE_INSERT_STRING (kind_name, muscle_kind_string (kind));
|
||||
end:
|
||||
free (variable);
|
||||
free (old);
|
||||
free (upd);
|
||||
if (variable != var)
|
||||
free ((char *) variable);
|
||||
}
|
||||
|
||||
/* This is used for backward compatibility, e.g., "%define api.pure"
|
||||
|
||||
+10
-1
@@ -38,6 +38,7 @@
|
||||
#include "muscle-tab.h"
|
||||
#include "output.h"
|
||||
#include "reader.h"
|
||||
#include "reduce.h"
|
||||
#include "scan-code.h" /* max_left_semantic_context */
|
||||
#include "scan-skel.h"
|
||||
#include "symtab.h"
|
||||
@@ -414,6 +415,14 @@ merger_output (FILE *out)
|
||||
static void
|
||||
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);
|
||||
const char *key = obstack_finish0 (&format_obstack);
|
||||
MUSCLE_INSERT_INT (key, nterm_map ? nterm_map[i - ntokens] : i);
|
||||
}
|
||||
|
||||
for (int i = 0; i < nsyms; ++i)
|
||||
{
|
||||
symbol *sym = symbols[i];
|
||||
@@ -665,7 +674,7 @@ prepare (void)
|
||||
MUSCLE_INSERT_BOOL ("tag_seen_flag", tag_seen);
|
||||
MUSCLE_INSERT_BOOL ("token_table_flag", token_table_flag);
|
||||
MUSCLE_INSERT_BOOL ("use_push_for_pull_flag", use_push_for_pull_flag);
|
||||
MUSCLE_INSERT_BOOL ("yacc_flag", yacc_flag);
|
||||
MUSCLE_INSERT_BOOL ("yacc_flag", !location_empty (yacc_loc));
|
||||
|
||||
/* File names. */
|
||||
if (spec_name_prefix)
|
||||
|
||||
+861
-716
File diff suppressed because it is too large
Load Diff
+61
-51
@@ -1,8 +1,9 @@
|
||||
/* A Bison parser, made by GNU Bison 3.2.1.108-19b4e. */
|
||||
/* A Bison parser, made by GNU Bison 3.2.90.23-0bbcb-dirty. */
|
||||
|
||||
/* Bison interface for Yacc-like parsers in C
|
||||
|
||||
Copyright (C) 1984, 1989-1990, 2000-2015, 2018 Free Software Foundation, Inc.
|
||||
Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2019 Free Software Foundation,
|
||||
Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -51,11 +52,11 @@
|
||||
extern int gram_debug;
|
||||
#endif
|
||||
/* "%code requires" blocks. */
|
||||
#line 21 "src/parse-gram.y" /* yacc.c:1917 */
|
||||
#line 21 "src/parse-gram.y" /* yacc.c:1921 */
|
||||
|
||||
#include "symlist.h"
|
||||
#include "symtab.h"
|
||||
#line 218 "src/parse-gram.y" /* yacc.c:1917 */
|
||||
#line 239 "src/parse-gram.y" /* yacc.c:1921 */
|
||||
|
||||
typedef enum
|
||||
{
|
||||
@@ -64,7 +65,7 @@ extern int gram_debug;
|
||||
param_parse = 1 << 1,
|
||||
param_both = param_lex | param_parse
|
||||
} param_type;
|
||||
#line 660 "src/parse-gram.y" /* yacc.c:1917 */
|
||||
#line 682 "src/parse-gram.y" /* yacc.c:1921 */
|
||||
|
||||
#include "muscle-tab.h"
|
||||
typedef struct
|
||||
@@ -73,7 +74,7 @@ extern int gram_debug;
|
||||
muscle_kind kind;
|
||||
} value_type;
|
||||
|
||||
#line 77 "src/parse-gram.h" /* yacc.c:1917 */
|
||||
#line 78 "src/parse-gram.h" /* yacc.c:1921 */
|
||||
|
||||
/* Token type. */
|
||||
#ifndef GRAM_TOKENTYPE
|
||||
@@ -98,43 +99,44 @@ extern int gram_debug;
|
||||
PERCENT_DEFAULT_PREC = 272,
|
||||
PERCENT_DEFINE = 273,
|
||||
PERCENT_DEFINES = 274,
|
||||
PERCENT_EXPECT = 275,
|
||||
PERCENT_EXPECT_RR = 276,
|
||||
PERCENT_FLAG = 277,
|
||||
PERCENT_FILE_PREFIX = 278,
|
||||
PERCENT_GLR_PARSER = 279,
|
||||
PERCENT_INITIAL_ACTION = 280,
|
||||
PERCENT_LANGUAGE = 281,
|
||||
PERCENT_NAME_PREFIX = 282,
|
||||
PERCENT_NO_DEFAULT_PREC = 283,
|
||||
PERCENT_NO_LINES = 284,
|
||||
PERCENT_NONDETERMINISTIC_PARSER = 285,
|
||||
PERCENT_OUTPUT = 286,
|
||||
PERCENT_REQUIRE = 287,
|
||||
PERCENT_SKELETON = 288,
|
||||
PERCENT_START = 289,
|
||||
PERCENT_TOKEN_TABLE = 290,
|
||||
PERCENT_VERBOSE = 291,
|
||||
PERCENT_YACC = 292,
|
||||
BRACED_CODE = 293,
|
||||
BRACED_PREDICATE = 294,
|
||||
BRACKETED_ID = 295,
|
||||
CHAR = 296,
|
||||
EPILOGUE = 297,
|
||||
EQUAL = 298,
|
||||
ID = 299,
|
||||
ID_COLON = 300,
|
||||
PERCENT_PERCENT = 301,
|
||||
PIPE = 302,
|
||||
PROLOGUE = 303,
|
||||
SEMICOLON = 304,
|
||||
TAG = 305,
|
||||
TAG_ANY = 306,
|
||||
TAG_NONE = 307,
|
||||
INT = 308,
|
||||
PERCENT_PARAM = 309,
|
||||
PERCENT_UNION = 310,
|
||||
PERCENT_EMPTY = 311
|
||||
PERCENT_ERROR_VERBOSE = 275,
|
||||
PERCENT_EXPECT = 276,
|
||||
PERCENT_EXPECT_RR = 277,
|
||||
PERCENT_FLAG = 278,
|
||||
PERCENT_FILE_PREFIX = 279,
|
||||
PERCENT_GLR_PARSER = 280,
|
||||
PERCENT_INITIAL_ACTION = 281,
|
||||
PERCENT_LANGUAGE = 282,
|
||||
PERCENT_NAME_PREFIX = 283,
|
||||
PERCENT_NO_DEFAULT_PREC = 284,
|
||||
PERCENT_NO_LINES = 285,
|
||||
PERCENT_NONDETERMINISTIC_PARSER = 286,
|
||||
PERCENT_OUTPUT = 287,
|
||||
PERCENT_REQUIRE = 288,
|
||||
PERCENT_SKELETON = 289,
|
||||
PERCENT_START = 290,
|
||||
PERCENT_TOKEN_TABLE = 291,
|
||||
PERCENT_VERBOSE = 292,
|
||||
PERCENT_YACC = 293,
|
||||
BRACED_CODE = 294,
|
||||
BRACED_PREDICATE = 295,
|
||||
BRACKETED_ID = 296,
|
||||
CHAR = 297,
|
||||
EPILOGUE = 298,
|
||||
EQUAL = 299,
|
||||
ID = 300,
|
||||
ID_COLON = 301,
|
||||
PERCENT_PERCENT = 302,
|
||||
PIPE = 303,
|
||||
PROLOGUE = 304,
|
||||
SEMICOLON = 305,
|
||||
TAG = 306,
|
||||
TAG_ANY = 307,
|
||||
TAG_NONE = 308,
|
||||
INT = 309,
|
||||
PERCENT_PARAM = 310,
|
||||
PERCENT_UNION = 311,
|
||||
PERCENT_EMPTY = 312
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -161,9 +163,9 @@ union GRAM_STYPE
|
||||
/* "integer" */
|
||||
int INT;
|
||||
/* int.opt */
|
||||
int yytype_78;
|
||||
int yytype_79;
|
||||
/* named_ref.opt */
|
||||
named_ref* yytype_90;
|
||||
named_ref* yytype_91;
|
||||
/* "%param" */
|
||||
param_type PERCENT_PARAM;
|
||||
/* token_decl */
|
||||
@@ -179,7 +181,7 @@ union GRAM_STYPE
|
||||
/* string_as_id */
|
||||
symbol* string_as_id;
|
||||
/* string_as_id.opt */
|
||||
symbol* yytype_97;
|
||||
symbol* yytype_98;
|
||||
/* generic_symlist */
|
||||
symbol_list* generic_symlist;
|
||||
/* generic_symlist_item */
|
||||
@@ -189,17 +191,25 @@ union GRAM_STYPE
|
||||
/* token_decls */
|
||||
symbol_list* token_decls;
|
||||
/* token_decl.1 */
|
||||
symbol_list* yytype_76;
|
||||
symbol_list* yytype_77;
|
||||
/* token_decls_for_prec */
|
||||
symbol_list* token_decls_for_prec;
|
||||
/* token_decl_for_prec.1 */
|
||||
symbol_list* yytype_80;
|
||||
symbol_list* yytype_81;
|
||||
/* symbol_decls */
|
||||
symbol_list* symbol_decls;
|
||||
/* symbol_decl.1 */
|
||||
symbol_list* yytype_83;
|
||||
symbol_list* yytype_84;
|
||||
/* "%error-verbose" */
|
||||
uniqstr PERCENT_ERROR_VERBOSE;
|
||||
/* "%<flag>" */
|
||||
uniqstr PERCENT_FLAG;
|
||||
/* "%file-prefix" */
|
||||
uniqstr PERCENT_FILE_PREFIX;
|
||||
/* "%name-prefix" */
|
||||
uniqstr PERCENT_NAME_PREFIX;
|
||||
/* "%yacc" */
|
||||
uniqstr PERCENT_YACC;
|
||||
/* "[identifier]" */
|
||||
uniqstr BRACKETED_ID;
|
||||
/* "identifier" */
|
||||
@@ -209,7 +219,7 @@ union GRAM_STYPE
|
||||
/* "<tag>" */
|
||||
uniqstr TAG;
|
||||
/* tag.opt */
|
||||
uniqstr yytype_70;
|
||||
uniqstr yytype_71;
|
||||
/* tag */
|
||||
uniqstr tag;
|
||||
/* variable */
|
||||
@@ -218,7 +228,7 @@ union GRAM_STYPE
|
||||
unsigned char CHAR;
|
||||
/* value */
|
||||
value_type value;
|
||||
#line 222 "src/parse-gram.h" /* yacc.c:1917 */
|
||||
#line 232 "src/parse-gram.h" /* yacc.c:1921 */
|
||||
};
|
||||
|
||||
typedef union GRAM_STYPE GRAM_STYPE;
|
||||
|
||||
+120
-12
@@ -43,8 +43,9 @@
|
||||
#include "named-ref.h"
|
||||
#include "quotearg.h"
|
||||
#include "reader.h"
|
||||
#include "scan-gram.h"
|
||||
#include "scan-code.h"
|
||||
#include "scan-gram.h"
|
||||
#include "vasnprintf.h"
|
||||
#include "xmemdup0.h"
|
||||
|
||||
static int current_prec = 0;
|
||||
@@ -81,11 +82,26 @@
|
||||
string from the scanner (should be CODE). */
|
||||
static char const *translate_code_braceless (char *code, location loc);
|
||||
|
||||
/* Handle a %error-verbose directive. */
|
||||
static void handle_error_verbose (location const *loc, char const *directive);
|
||||
|
||||
/* Handle a %file-prefix directive. */
|
||||
static void handle_file_prefix (location const *loc,
|
||||
location const *dir_loc,
|
||||
char const *directive, char const *value);
|
||||
|
||||
/* Handle a %name-prefix directive. */
|
||||
static void handle_name_prefix (location const *loc,
|
||||
char const *directive, char const *value);
|
||||
|
||||
/* Handle a %require directive. */
|
||||
static void do_require (location const *loc, char const *version);
|
||||
static void handle_require (location const *loc, char const *version);
|
||||
|
||||
/* Handle a %skeleton directive. */
|
||||
static void do_skeleton (location const *loc, char const *skel);
|
||||
static void handle_skeleton (location const *loc, char const *skel);
|
||||
|
||||
/* Handle a %yacc directive. */
|
||||
static void handle_yacc (location const *loc, char const *directive);
|
||||
|
||||
static void gram_error (location const *, char const *);
|
||||
|
||||
@@ -146,6 +162,7 @@
|
||||
PERCENT_DEFAULT_PREC "%default-prec"
|
||||
PERCENT_DEFINE "%define"
|
||||
PERCENT_DEFINES "%defines"
|
||||
PERCENT_ERROR_VERBOSE "%error-verbose"
|
||||
PERCENT_EXPECT "%expect"
|
||||
PERCENT_EXPECT_RR "%expect-rr"
|
||||
PERCENT_FLAG "%<flag>"
|
||||
@@ -190,7 +207,11 @@
|
||||
%printer { fputs (quotearg_style (c_quoting_style, $$), yyo); } STRING
|
||||
%printer { fprintf (yyo, "{\n%s\n}", $$); } <char*>
|
||||
|
||||
%type <uniqstr> BRACKETED_ID ID ID_COLON PERCENT_FLAG TAG tag tag.opt variable
|
||||
%type <uniqstr>
|
||||
BRACKETED_ID ID ID_COLON
|
||||
PERCENT_ERROR_VERBOSE PERCENT_FILE_PREFIX PERCENT_FLAG PERCENT_NAME_PREFIX
|
||||
PERCENT_YACC
|
||||
TAG tag tag.opt variable
|
||||
%printer { fputs ($$, yyo); } <uniqstr>
|
||||
%printer { fprintf (yyo, "[%s]", $$); } BRACKETED_ID
|
||||
%printer { fprintf (yyo, "%s:", $$); } ID_COLON
|
||||
@@ -284,7 +305,7 @@ prologue_declaration:
|
||||
}
|
||||
| "%define" variable value
|
||||
{
|
||||
muscle_percent_define_insert ($2, @2, $3.kind, $3.chars,
|
||||
muscle_percent_define_insert ($2, @$, $3.kind, $3.chars,
|
||||
MUSCLE_PERCENT_DEFINE_GRAMMAR_FILE);
|
||||
}
|
||||
| "%defines" { defines_flag = true; }
|
||||
@@ -293,9 +314,10 @@ prologue_declaration:
|
||||
defines_flag = true;
|
||||
spec_defines_file = xstrdup ($2);
|
||||
}
|
||||
| "%error-verbose" { handle_error_verbose (&@$, $1); }
|
||||
| "%expect" INT { expected_sr_conflicts = $2; }
|
||||
| "%expect-rr" INT { expected_rr_conflicts = $2; }
|
||||
| "%file-prefix" STRING { spec_file_prefix = $2; }
|
||||
| "%file-prefix" STRING { handle_file_prefix (&@$, &@1, $1, $2); }
|
||||
| "%glr-parser"
|
||||
{
|
||||
nondeterministic_parser = true;
|
||||
@@ -307,16 +329,16 @@ prologue_declaration:
|
||||
code_scanner_last_string_free ();
|
||||
}
|
||||
| "%language" STRING { language_argmatch ($2, grammar_prio, @1); }
|
||||
| "%name-prefix" STRING { spec_name_prefix = $2; }
|
||||
| "%name-prefix" STRING { handle_name_prefix (&@$, $1, $2); }
|
||||
| "%no-lines" { no_lines_flag = true; }
|
||||
| "%nondeterministic-parser" { nondeterministic_parser = true; }
|
||||
| "%output" STRING { spec_outfile = $2; }
|
||||
| "%param" { current_param = $1; } params { current_param = param_none; }
|
||||
| "%require" STRING { do_require (&@2, $2); }
|
||||
| "%skeleton" STRING { do_skeleton (&@2, $2); }
|
||||
| "%require" STRING { handle_require (&@2, $2); }
|
||||
| "%skeleton" STRING { handle_skeleton (&@2, $2); }
|
||||
| "%token-table" { token_table_flag = true; }
|
||||
| "%verbose" { report_flag |= report_states; }
|
||||
| "%yacc" { yacc_flag = true; }
|
||||
| "%yacc" { handle_yacc (&@$, $1); }
|
||||
| error ";" { current_class = unknown_sym; yyerrok; }
|
||||
| /*FIXME: Err? What is this horror doing here? */ ";"
|
||||
;
|
||||
@@ -847,7 +869,74 @@ add_param (param_type type, char *decl, location loc)
|
||||
|
||||
|
||||
static void
|
||||
do_require (location const *loc, char const *version)
|
||||
handle_error_verbose (location const *loc, char const *directive)
|
||||
{
|
||||
bison_directive (loc, directive);
|
||||
muscle_percent_define_insert (directive, *loc, muscle_keyword, "",
|
||||
MUSCLE_PERCENT_DEFINE_GRAMMAR_FILE);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
handle_file_prefix (location const *loc,
|
||||
location const *dir_loc,
|
||||
char const *directive, char const *value)
|
||||
{
|
||||
bison_directive (loc, directive);
|
||||
bool warned = false;
|
||||
|
||||
if (location_empty (spec_file_prefix_loc))
|
||||
{
|
||||
spec_file_prefix_loc = *loc;
|
||||
spec_file_prefix = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
duplicate_directive (directive, spec_file_prefix_loc, *loc);
|
||||
warned = true;
|
||||
}
|
||||
|
||||
if (!warned
|
||||
&& STRNEQ (directive, "%file-prefix"))
|
||||
deprecated_directive (dir_loc, directive, "%file-prefix");
|
||||
}
|
||||
|
||||
static void
|
||||
handle_name_prefix (location const *loc,
|
||||
char const *directive, char const *value)
|
||||
{
|
||||
bison_directive (loc, directive);
|
||||
|
||||
char buf1[1024];
|
||||
size_t len1 = sizeof (buf1);
|
||||
char *old = asnprintf (buf1, &len1, "%s\"%s\"", directive, value);
|
||||
if (!old)
|
||||
xalloc_die ();
|
||||
|
||||
if (location_empty (spec_name_prefix_loc))
|
||||
{
|
||||
spec_name_prefix = value;
|
||||
spec_name_prefix_loc = *loc;
|
||||
|
||||
char buf2[1024];
|
||||
size_t len2 = sizeof (buf2);
|
||||
char *new = asnprintf (buf2, &len2, "%%define api.prefix {%s}", value);
|
||||
if (!new)
|
||||
xalloc_die ();
|
||||
deprecated_directive (loc, old, new);
|
||||
if (new != buf2)
|
||||
free (new);
|
||||
}
|
||||
else
|
||||
duplicate_directive (old, spec_file_prefix_loc, *loc);
|
||||
|
||||
if (old != buf1)
|
||||
free (old);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
handle_require (location const *loc, char const *version)
|
||||
{
|
||||
/* Changes of behavior are only on minor version changes, so "3.0.5"
|
||||
is the same as "3.0". */
|
||||
@@ -885,7 +974,7 @@ do_require (location const *loc, char const *version)
|
||||
}
|
||||
|
||||
static void
|
||||
do_skeleton (location const *loc, char const *skel)
|
||||
handle_skeleton (location const *loc, char const *skel)
|
||||
{
|
||||
char const *skeleton_user = skel;
|
||||
if (strchr (skeleton_user, '/'))
|
||||
@@ -909,6 +998,25 @@ do_skeleton (location const *loc, char const *skel)
|
||||
skeleton_arg (skeleton_user, grammar_prio, *loc);
|
||||
}
|
||||
|
||||
static void
|
||||
handle_yacc (location const *loc, char const *directive)
|
||||
{
|
||||
bison_directive (loc, directive);
|
||||
bool warned = false;
|
||||
|
||||
if (location_empty (yacc_loc))
|
||||
yacc_loc = *loc;
|
||||
else
|
||||
{
|
||||
duplicate_directive (directive, yacc_loc, *loc);
|
||||
warned = true;
|
||||
}
|
||||
|
||||
if (!warned
|
||||
&& STRNEQ (directive, "%fixed-output-files")
|
||||
&& STRNEQ (directive, "%yacc"))
|
||||
deprecated_directive (loc, directive, "%fixed-output-files");
|
||||
}
|
||||
|
||||
static void
|
||||
gram_error (location const *loc, char const *msg)
|
||||
|
||||
+8
-8
@@ -467,8 +467,8 @@ grammar_current_rule_prec_set (symbol *precsym, location loc)
|
||||
not defined separately as a token. */
|
||||
symbol_class_set (precsym, token_sym, loc, false);
|
||||
if (current_rule->ruleprec)
|
||||
duplicate_directive ("%prec",
|
||||
current_rule->ruleprec->location, loc);
|
||||
duplicate_rule_directive ("%prec",
|
||||
current_rule->ruleprec->location, loc);
|
||||
else
|
||||
current_rule->ruleprec = precsym;
|
||||
}
|
||||
@@ -483,8 +483,8 @@ grammar_current_rule_empty_set (location loc)
|
||||
if (warning_is_unset (Wempty_rule))
|
||||
warning_argmatch ("empty-rule", 0, 0);
|
||||
if (current_rule->percent_empty_loc.start.file)
|
||||
duplicate_directive ("%empty",
|
||||
current_rule->percent_empty_loc, loc);
|
||||
duplicate_rule_directive ("%empty",
|
||||
current_rule->percent_empty_loc, loc);
|
||||
else
|
||||
current_rule->percent_empty_loc = loc;
|
||||
}
|
||||
@@ -501,8 +501,8 @@ grammar_current_rule_dprec_set (int dprec, location loc)
|
||||
complain (&loc, complaint, _("%s must be followed by positive number"),
|
||||
"%dprec");
|
||||
else if (current_rule->dprec != 0)
|
||||
duplicate_directive ("%dprec",
|
||||
current_rule->dprec_location, loc);
|
||||
duplicate_rule_directive ("%dprec",
|
||||
current_rule->dprec_location, loc);
|
||||
else
|
||||
{
|
||||
current_rule->dprec = dprec;
|
||||
@@ -520,8 +520,8 @@ grammar_current_rule_merge_set (uniqstr name, location loc)
|
||||
complain (&loc, Wother, _("%s affects only GLR parsers"),
|
||||
"%merge");
|
||||
if (current_rule->merger != 0)
|
||||
duplicate_directive ("%merge",
|
||||
current_rule->merger_declaration_location, loc);
|
||||
duplicate_rule_directive ("%merge",
|
||||
current_rule->merger_declaration_location, loc);
|
||||
else
|
||||
{
|
||||
current_rule->merger = get_merge_function (name);
|
||||
|
||||
+13
-12
@@ -259,22 +259,23 @@ reduce_grammar_tables (void)
|
||||
| Remove useless nonterminals. |
|
||||
`------------------------------*/
|
||||
|
||||
symbol_number *nterm_map = NULL;
|
||||
|
||||
static void
|
||||
nonterminals_reduce (void)
|
||||
{
|
||||
nterm_map = xnmalloc (nvars, sizeof *nterm_map);
|
||||
/* Map the nonterminals to their new index: useful first, useless
|
||||
afterwards. Kept for later report. */
|
||||
|
||||
symbol_number *nontermmap = xnmalloc (nvars, sizeof *nontermmap);
|
||||
{
|
||||
symbol_number n = ntokens;
|
||||
for (symbol_number i = ntokens; i < nsyms; ++i)
|
||||
if (bitset_test (V, i))
|
||||
nontermmap[i - ntokens] = n++;
|
||||
nterm_map[i - ntokens] = n++;
|
||||
for (symbol_number i = ntokens; i < nsyms; ++i)
|
||||
if (!bitset_test (V, i))
|
||||
{
|
||||
nontermmap[i - ntokens] = n++;
|
||||
nterm_map[i - ntokens] = n++;
|
||||
if (symbols[i]->content->status != used)
|
||||
complain (&symbols[i]->location, Wother,
|
||||
_("nonterminal useless in grammar: %s"),
|
||||
@@ -282,32 +283,30 @@ nonterminals_reduce (void)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Shuffle elements of tables indexed by symbol number. */
|
||||
{
|
||||
symbol **symbols_sorted = xnmalloc (nvars, sizeof *symbols_sorted);
|
||||
for (symbol_number i = ntokens; i < nsyms; ++i)
|
||||
symbols[i]->content->number = nontermmap[i - ntokens];
|
||||
symbols[i]->content->number = nterm_map[i - ntokens];
|
||||
for (symbol_number i = ntokens; i < nsyms; ++i)
|
||||
symbols_sorted[nontermmap[i - ntokens] - ntokens] = symbols[i];
|
||||
symbols_sorted[nterm_map[i - ntokens] - ntokens] = symbols[i];
|
||||
for (symbol_number i = ntokens; i < nsyms; ++i)
|
||||
symbols[i] = symbols_sorted[i - ntokens];
|
||||
free (symbols_sorted);
|
||||
}
|
||||
|
||||
/* Update nonterminal numbers in the RHS of the rules. LHS are
|
||||
pointers to the symbol structure, they don't need renumbering. */
|
||||
{
|
||||
for (rule_number r = 0; r < nrules; ++r)
|
||||
for (item_number *rhsp = rules[r].rhs; 0 <= *rhsp; ++rhsp)
|
||||
if (ISVAR (*rhsp))
|
||||
*rhsp = symbol_number_as_item_number (nontermmap[*rhsp
|
||||
- ntokens]);
|
||||
accept->content->number = nontermmap[accept->content->number - ntokens];
|
||||
*rhsp = symbol_number_as_item_number (nterm_map[*rhsp - ntokens]);
|
||||
accept->content->number = nterm_map[accept->content->number - ntokens];
|
||||
}
|
||||
|
||||
nsyms -= nuseless_nonterminals;
|
||||
nvars -= nuseless_nonterminals;
|
||||
|
||||
free (nontermmap);
|
||||
}
|
||||
|
||||
|
||||
@@ -433,4 +432,6 @@ reduce_free (void)
|
||||
bitset_free (V);
|
||||
bitset_free (V1);
|
||||
bitset_free (P);
|
||||
free (nterm_map);
|
||||
nterm_map = NULL;
|
||||
}
|
||||
|
||||
@@ -32,6 +32,11 @@ bool reduce_nonterminal_useless_in_grammar (const sym_content *sym);
|
||||
|
||||
void reduce_free (void);
|
||||
|
||||
/** Map initial nterm numbers to the new ones. Built by
|
||||
* reduce_grammar. Size nvars + nuseless_nonterminals. */
|
||||
extern symbol_number *nterm_map;
|
||||
|
||||
extern unsigned nuseless_nonterminals;
|
||||
extern unsigned nuseless_productions;
|
||||
|
||||
#endif /* !REDUCE_H_ */
|
||||
|
||||
+4
-2
@@ -648,7 +648,7 @@ handle_action_dollar (symbol_list *rule, char *text, location dollar_loc)
|
||||
untyped_var_seen = true;
|
||||
}
|
||||
|
||||
obstack_printf (&obstack_for_string, "]b4_lhs_value(%d, ",
|
||||
obstack_printf (&obstack_for_string, "]b4_lhs_value(orig %d, ",
|
||||
sym->content.sym->content->number);
|
||||
obstack_quote (&obstack_for_string, type_name);
|
||||
obstack_sgrow (&obstack_for_string, ")[");
|
||||
@@ -677,7 +677,9 @@ handle_action_dollar (symbol_list *rule, char *text, location dollar_loc)
|
||||
"]b4_rhs_value(%d, %d, ",
|
||||
effective_rule_length, n);
|
||||
if (sym)
|
||||
obstack_printf (&obstack_for_string, "%d, ", sym->content.sym->content->number);
|
||||
obstack_printf (&obstack_for_string, "%s%d, ",
|
||||
sym->content.sym->content->class == nterm_sym ? "orig " : "",
|
||||
sym->content.sym->content->number);
|
||||
else
|
||||
obstack_sgrow (&obstack_for_string, "[], ");
|
||||
|
||||
|
||||
+13
-16
@@ -76,18 +76,17 @@ static size_t no_cr_read (FILE *, char *, size_t);
|
||||
|
||||
#define DEPRECATED(Msg) \
|
||||
do { \
|
||||
size_t i; \
|
||||
deprecated_directive (loc, yytext, Msg); \
|
||||
scanner_cursor.column -= mbsnwidth (Msg, strlen (Msg), 0); \
|
||||
for (i = strlen (Msg); i != 0; --i) \
|
||||
for (size_t i = strlen (Msg); i != 0; --i) \
|
||||
unput (Msg[i - 1]); \
|
||||
} while (0)
|
||||
|
||||
/* A string representing the most recently saved token. */
|
||||
static char *last_string;
|
||||
static char *last_string = NULL;
|
||||
|
||||
/* Bracketed identifier. */
|
||||
static uniqstr bracketed_id_str = 0;
|
||||
static uniqstr bracketed_id_str = NULL;
|
||||
static location bracketed_id_loc;
|
||||
static boundary bracketed_id_start;
|
||||
static int bracketed_id_context_state = 0;
|
||||
@@ -145,7 +144,8 @@ splice (\\[ \f\t\v]*\n)*
|
||||
|
||||
/* An equal sign, with optional leading whitespaces. This is used in some
|
||||
deprecated constructs. */
|
||||
eqopt ([[:space:]]*=)?
|
||||
sp [[:space:]]*
|
||||
eqopt ({sp}=)?
|
||||
|
||||
%%
|
||||
%{
|
||||
@@ -228,8 +228,8 @@ eqopt ([[:space:]]*=)?
|
||||
"%empty" return BISON_DIRECTIVE (EMPTY);
|
||||
"%expect" return BISON_DIRECTIVE (EXPECT);
|
||||
"%expect-rr" return BISON_DIRECTIVE (EXPECT_RR);
|
||||
"%file-prefix" return BISON_DIRECTIVE (FILE_PREFIX);
|
||||
"%fixed-output-files" return BISON_DIRECTIVE (YACC);
|
||||
"%file-prefix" RETURN_VALUE (PERCENT_FILE_PREFIX, uniqstr_new (yytext));
|
||||
"%fixed-output-files" RETURN_VALUE (PERCENT_YACC, uniqstr_new (yytext));
|
||||
"%initial-action" return BISON_DIRECTIVE (INITIAL_ACTION);
|
||||
"%glr-parser" return BISON_DIRECTIVE (GLR_PARSER);
|
||||
"%language" return BISON_DIRECTIVE (LANGUAGE);
|
||||
@@ -259,25 +259,22 @@ eqopt ([[:space:]]*=)?
|
||||
"%type" return PERCENT_TYPE;
|
||||
"%union" return PERCENT_UNION;
|
||||
"%verbose" return BISON_DIRECTIVE (VERBOSE);
|
||||
"%yacc" return BISON_DIRECTIVE (YACC);
|
||||
"%yacc" RETURN_VALUE (PERCENT_YACC, uniqstr_new (yytext));
|
||||
|
||||
/* Deprecated since Bison 3.0 (2013-07-25), but the warning is
|
||||
issued only since Bison 3.3. */
|
||||
"%error-verbose" DEPRECATED ("%define parse.error verbose");
|
||||
"%error-verbose" RETURN_VALUE (PERCENT_ERROR_VERBOSE, uniqstr_new (yytext));
|
||||
|
||||
/* Deprecated since Bison 2.6 (2012-07-19), but the warning is
|
||||
issued only since Bison 3.3. */
|
||||
"%name"[-_]"prefix"{eqopt} {
|
||||
deprecated_directive (loc, yytext, "%define api.prefix");
|
||||
return BISON_DIRECTIVE (NAME_PREFIX);
|
||||
}
|
||||
"%name"[-_]"prefix"{eqopt}{sp} RETURN_VALUE (PERCENT_NAME_PREFIX, uniqstr_new (yytext));
|
||||
|
||||
/* Deprecated since Bison 2.7.90, 2012. */
|
||||
"%default"[-_]"prec" DEPRECATED ("%default-prec");
|
||||
"%error"[-_]"verbose" DEPRECATED ("%define parse.error verbose");
|
||||
"%error"[-_]"verbose" RETURN_VALUE (PERCENT_ERROR_VERBOSE, uniqstr_new (yytext));
|
||||
"%expect"[-_]"rr" DEPRECATED ("%expect-rr");
|
||||
"%file-prefix"{eqopt} DEPRECATED ("%file-prefix");
|
||||
"%fixed"[-_]"output"[-_]"files" DEPRECATED ("%fixed-output-files");
|
||||
"%file-prefix"{eqopt} RETURN_VALUE (PERCENT_FILE_PREFIX, uniqstr_new (yytext));
|
||||
"%fixed"[-_]"output"[-_]"files" RETURN_VALUE (PERCENT_YACC, uniqstr_new (yytext));
|
||||
"%no"[-_]"default"[-_]"prec" DEPRECATED ("%no-default-prec");
|
||||
"%no"[-_]"lines" DEPRECATED ("%no-lines");
|
||||
"%output"{eqopt} DEPRECATED ("%output");
|
||||
|
||||
+1
-1
@@ -143,7 +143,7 @@ state_new (symbol_number accessing_symbol,
|
||||
res->reductions = NULL;
|
||||
res->errs = NULL;
|
||||
res->state_list = NULL;
|
||||
res->consistent = 0;
|
||||
res->consistent = false;
|
||||
res->solved_conflicts = NULL;
|
||||
res->solved_conflicts_xml = NULL;
|
||||
|
||||
|
||||
+5
-3
@@ -81,6 +81,8 @@
|
||||
#ifndef STATE_H_
|
||||
# define STATE_H_
|
||||
|
||||
# include <stdbool.h>
|
||||
|
||||
# include <bitset.h>
|
||||
|
||||
# include "gram.h"
|
||||
@@ -208,9 +210,9 @@ struct state
|
||||
store in this member a reference to the node containing each state. */
|
||||
struct state_list *state_list;
|
||||
|
||||
/* If non-zero, then no lookahead sets on reduce actions are needed to
|
||||
decide what to do in state S. */
|
||||
char consistent;
|
||||
/* Whether no lookahead sets on reduce actions are needed to decide
|
||||
what to do in state S. */
|
||||
bool consistent;
|
||||
|
||||
/* If some conflicts were solved thanks to precedence/associativity,
|
||||
a human readable description of the resolution. */
|
||||
|
||||
+50
-21
@@ -130,7 +130,7 @@ b: {} {};
|
||||
AT_BISON_CHECK([-fcaret -Wempty-rule 1.y], [0], [],
|
||||
[[1.y:11.17-18: warning: empty rule without %empty [-Wempty-rule]
|
||||
a: /* empty. */ {};
|
||||
^^
|
||||
^~
|
||||
]])
|
||||
|
||||
AT_DATA_GRAMMAR([[2.y]],
|
||||
@@ -144,10 +144,10 @@ c: /* empty. */ {};
|
||||
AT_BISON_CHECK([-fcaret 2.y], [0], [],
|
||||
[[2.y:11.17-18: warning: empty rule without %empty [-Wempty-rule]
|
||||
a: /* empty. */ {};
|
||||
^^
|
||||
^~
|
||||
2.y:13.17-18: warning: empty rule without %empty [-Wempty-rule]
|
||||
c: /* empty. */ {};
|
||||
^^
|
||||
^~
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK([-fcaret -Wno-empty-rule 2.y], [0])
|
||||
@@ -170,12 +170,39 @@ exp:
|
||||
AT_BISON_CHECK([-fcaret one.y], [1], [],
|
||||
[[one.y:11.13-18: error: only one %empty allowed per rule
|
||||
%empty {} %empty
|
||||
^^^^^^
|
||||
one.y:11.3-8: previous declaration
|
||||
^~~~~~
|
||||
one.y:11.3-8: previous declaration
|
||||
%empty {} %empty
|
||||
^^^^^^
|
||||
^~~~~~
|
||||
one.y: warning: fix-its can be applied. Rerun with option '--update'. [-Wother]
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK([-fcaret -u one.y], [1], [],
|
||||
[[one.y:11.13-18: error: only one %empty allowed per rule
|
||||
%empty {} %empty
|
||||
^~~~~~
|
||||
one.y:11.3-8: previous declaration
|
||||
%empty {} %empty
|
||||
^~~~~~
|
||||
bison: file 'one.y' was updated (backup: 'one.y~')
|
||||
]])
|
||||
|
||||
AT_CHECK([cat one.y], [],
|
||||
[[%code top {
|
||||
/* Load config.h, and adjust to the compiler.
|
||||
We used to do it here, but each time we add a new line,
|
||||
we have to adjust all the line numbers in error messages.
|
||||
It's simpler to use a constant include to a varying file. */
|
||||
#include <testsuite.h>
|
||||
}
|
||||
|
||||
%%
|
||||
exp:
|
||||
%empty {} @&t@
|
||||
;
|
||||
]])
|
||||
|
||||
|
||||
AT_DATA_GRAMMAR([[two.y]],
|
||||
[[%%
|
||||
exp:
|
||||
@@ -188,13 +215,13 @@ exp:
|
||||
AT_BISON_CHECK([-fcaret two.y], [1], [],
|
||||
[[two.y:11.7-12: error: %empty on non-empty rule
|
||||
'a' %empty {}
|
||||
^^^^^^
|
||||
^~~~~~
|
||||
two.y:12.3-8: error: %empty on non-empty rule
|
||||
| %empty 'a' {}
|
||||
^^^^^^
|
||||
^~~~~~
|
||||
two.y:13.3-8: error: %empty on non-empty rule
|
||||
| %empty {} {}
|
||||
^^^^^^
|
||||
^~~~~~
|
||||
]])
|
||||
|
||||
AT_CLEANUP
|
||||
@@ -516,7 +543,7 @@ AT_DATA_GRAMMAR([[input.y]],
|
||||
|
||||
#define YYINITDEPTH 10
|
||||
#define YYMAXDEPTH 10
|
||||
#define RANGE(Location) ]AT_LALR1_CC_IF([(Location).begin.line, (Location).end.line],
|
||||
#define RANGE(Location) ]AT_CXX_IF([(Location).begin.line, (Location).end.line],
|
||||
[(Location).first_line, (Location).last_line])[
|
||||
|
||||
#define USE(SYM)
|
||||
@@ -545,8 +572,8 @@ AT_LALR1_CC_IF([typedef yy::location YYLTYPE;])[
|
||||
/* FIXME: This %printer isn't actually tested. */
|
||||
%printer
|
||||
{
|
||||
]AT_LALR1_CC_IF([yyo << $$;],
|
||||
[fprintf (yyo, "%d", $$)])[;
|
||||
]AT_CXX_IF([yyo << $$;],
|
||||
[fprintf (yyo, "%d", $$)])[;
|
||||
}
|
||||
'(' 'x' 'y' ')' ';' thing line input '!' raise check-spontaneous-errors END
|
||||
|
||||
@@ -707,9 +734,8 @@ static
|
||||
fprintf (stderr, " (%d@%d-%d)\n", c, RANGE (]AT_LOC[));
|
||||
return source[c];
|
||||
}
|
||||
]AT_LALR1_CC_IF(
|
||||
[static bool yydebug;
|
||||
int
|
||||
]AT_LALR1_CC_IF([static bool yydebug;])[
|
||||
]AT_CXX_IF([int
|
||||
yyparse ()
|
||||
{
|
||||
yy::parser parser;
|
||||
@@ -972,11 +998,14 @@ AT_CLEANUP
|
||||
AT_CHECK_PRINTER_AND_DESTRUCTOR([])
|
||||
AT_CHECK_PRINTER_AND_DESTRUCTOR([], [ with union])
|
||||
|
||||
AT_CHECK_PRINTER_AND_DESTRUCTOR([%glr-parser])
|
||||
AT_CHECK_PRINTER_AND_DESTRUCTOR([%glr-parser], [ with union])
|
||||
|
||||
AT_CHECK_PRINTER_AND_DESTRUCTOR([%defines %skeleton "lalr1.cc"])
|
||||
AT_CHECK_PRINTER_AND_DESTRUCTOR([%defines %skeleton "lalr1.cc"], [ with union])
|
||||
|
||||
AT_CHECK_PRINTER_AND_DESTRUCTOR([%glr-parser])
|
||||
AT_CHECK_PRINTER_AND_DESTRUCTOR([%glr-parser], [ with union])
|
||||
AT_CHECK_PRINTER_AND_DESTRUCTOR([%defines %skeleton "glr.cc"])
|
||||
AT_CHECK_PRINTER_AND_DESTRUCTOR([%defines %skeleton "glr.cc"], [ with union])
|
||||
|
||||
|
||||
|
||||
@@ -1514,16 +1543,16 @@ input.y:32.3-23: warning: unused value: $3 [-Wother]
|
||||
AT_BISON_CHECK([-fcaret -o input.c input.y], 0,,
|
||||
[[input.y:24.57-59: warning: useless %destructor for type <*> [-Wother]
|
||||
%printer { #error "<*> printer should not be used" } <*>
|
||||
^^^
|
||||
^~~
|
||||
input.y:24.57-59: warning: useless %printer for type <*> [-Wother]
|
||||
%printer { #error "<*> printer should not be used" } <*>
|
||||
^^^
|
||||
^~~
|
||||
input.y:33.3-23: warning: unset value: $$ [-Wother]
|
||||
{ @$ = 4; } // Only used.
|
||||
^^^^^^^^^^^^^^^^^^^^^
|
||||
^~~~~~~~~~~~~~~~~~~~~
|
||||
input.y:32.3-23: warning: unused value: $3 [-Wother]
|
||||
{ USE ($$); @$ = 3; } // Only set.
|
||||
^^^^^^^^^^^^^^^^^^^^^
|
||||
^~~~~~~~~~~~~~~~~~~~~
|
||||
]])
|
||||
|
||||
AT_COMPILE([input])
|
||||
|
||||
+6
-6
@@ -249,13 +249,13 @@ exp:
|
||||
AT_BISON_CHECK([[-fcaret input.yy]], [0], [],
|
||||
[[input.yy:16.33-34: warning: multiple occurrences of $2 with api.value.automove [-Wother]
|
||||
| "twice" exp { $$ = $2 + $2; }
|
||||
^^
|
||||
^~
|
||||
input.yy:17.33-36: warning: multiple occurrences of $2 with api.value.automove [-Wother]
|
||||
| "thrice" exp[val] { $$ = $2 + $val + $2; }
|
||||
^^^^
|
||||
^~~~
|
||||
input.yy:17.40-41: warning: multiple occurrences of $2 with api.value.automove [-Wother]
|
||||
| "thrice" exp[val] { $$ = $2 + $val + $2; }
|
||||
^^
|
||||
^~
|
||||
]])
|
||||
|
||||
AT_BISON_OPTION_POPDEFS
|
||||
@@ -420,8 +420,7 @@ namespace yy
|
||||
{
|
||||
static
|
||||
]AT_YYLEX_PROTOTYPE[
|
||||
{]AT_LOCATION_IF([
|
||||
typedef parser::location_type location;])[
|
||||
{
|
||||
// The 5 is a syntax error whose recovery requires that we discard
|
||||
// the lookahead. This tests a regression, see
|
||||
// <http://savannah.gnu.org/support/?108481>.
|
||||
@@ -1243,7 +1242,8 @@ yylex (yy::parser::semantic_type *lvalp)
|
||||
default:
|
||||
lvalp->]AT_VARIANT_IF([build<Object> (res)],
|
||||
[obj = new Object (res)])[;
|
||||
// Fall through.
|
||||
goto zero;
|
||||
zero:
|
||||
case 0:
|
||||
return res;
|
||||
}
|
||||
|
||||
+6
-6
@@ -246,16 +246,16 @@ f: B
|
||||
AT_BISON_CHECK([-Wprecedence -fcaret -o input.c input.y], 0, [],
|
||||
[[input.y:7.1-9: warning: useless precedence and associativity for U [-Wprecedence]
|
||||
%nonassoc U
|
||||
^^^^^^^^^
|
||||
^~~~~~~~~
|
||||
input.y:6.1-6: warning: useless precedence and associativity for V [-Wprecedence]
|
||||
%right V
|
||||
^^^^^^
|
||||
^~~~~~
|
||||
input.y:5.1-5: warning: useless precedence and associativity for W [-Wprecedence]
|
||||
%left W
|
||||
^^^^^
|
||||
^~~~~
|
||||
input.y:2.1-11: warning: useless precedence for Z [-Wprecedence]
|
||||
%precedence Z
|
||||
^^^^^^^^^^^
|
||||
^~~~~~~~~~~
|
||||
]])
|
||||
|
||||
AT_CLEANUP
|
||||
@@ -1367,7 +1367,7 @@ b: %expect-rr 4
|
||||
AT_BISON_CHECK([-fcaret -o input.c input.y], 1, [],
|
||||
[[input.y:12.4-15: error: reduce/reduce conflicts for rule 8: 3 found, 4 expected
|
||||
b: %expect-rr 4
|
||||
^^^^^^^^^^^^
|
||||
^~~~~~~~~~~~
|
||||
]])
|
||||
AT_CLEANUP
|
||||
|
||||
@@ -1396,7 +1396,7 @@ b: %expect-rr 2
|
||||
AT_BISON_CHECK([-fcaret -o input.c input.y], 1, [],
|
||||
[[input.y:12.4-15: error: reduce/reduce conflicts for rule 8: 3 found, 2 expected
|
||||
b: %expect-rr 2
|
||||
^^^^^^^^^^^^
|
||||
^~~~~~~~~~~~
|
||||
]])
|
||||
AT_CLEANUP
|
||||
|
||||
|
||||
+4
-2
@@ -85,7 +85,8 @@ exp: %empty;
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK([--defines -o input.c input.y], [], [],
|
||||
[[input.y:11.1-12: warning: deprecated directive: '%name-prefix', use '%define api.prefix' [-Wdeprecated]
|
||||
[[input.y:11.1-18: warning: deprecated directive: '%name-prefix "my_"', use '%define api.prefix {my_}' [-Wdeprecated]
|
||||
input.y: warning: fix-its can be applied. Rerun with option '--update'. [-Wother]
|
||||
]])
|
||||
|
||||
# YYLTYPE should be defined, and MY_LLOC declared.
|
||||
@@ -125,7 +126,7 @@ AT_BISON_OPTION_PUSHDEFS([$1])
|
||||
AT_DATA_GRAMMAR([input.y],
|
||||
[[$1
|
||||
%define parse.error verbose
|
||||
]AT_VARIANT_IF([], [%union {int integer;}])[
|
||||
]AT_VARIANT_IF([%token <int> 'x'], [%union {int integer;}])[
|
||||
%code {
|
||||
]AT_PUSH_IF([[
|
||||
#if defined __GNUC__ && 7 == __GNUC__
|
||||
@@ -329,6 +330,7 @@ AT_CHECK([[$PERL -n -0777 -e '
|
||||
|YY_MOVE_OR_COPY
|
||||
|YY_MOVE_REF
|
||||
|YY_NOEXCEPT
|
||||
|YY_NOTHROW
|
||||
|YY_NULLPTR
|
||||
|YY_RVREF
|
||||
|YY_\w+_INCLUDED
|
||||
|
||||
+308
-229
File diff suppressed because it is too large
Load Diff
+3
-2
@@ -707,8 +707,9 @@ if test "$POSIXLY_CORRECT_IS_EXPORTED" = false; then
|
||||
# Build expected stderr up to and including the "warnings being
|
||||
# treated as errors" message.
|
||||
]AT_DATA([[experr]], [$4])[
|
||||
$PERL -pi -e 's{(.*): warning: (.*)\[-W(.*)\]$}
|
||||
{$][1: error: $][2\@<:@-Werror=$][3@:>@}' experr
|
||||
$PERL -pi -e 's{(.*): warning:}{$][1: error:};' \
|
||||
-e 's{\[-W(.*)\]$}{@<:@-Werror=$][1@:>@}' \
|
||||
experr
|
||||
]AT_CHECK([[sed 's,.*/$,,' stderr 1>&2]], [[0]], [[]], [experr])[
|
||||
|
||||
# Now check --warnings=error.
|
||||
|
||||
+48
-48
@@ -254,16 +254,16 @@ exp:
|
||||
AT_BISON_CHECK([-fcaret -o test.c test.y], 1, [],
|
||||
[[test.y:52.51-60: error: invalid reference: '$<ival>lo9'
|
||||
| exp[x] '+' { $<ival>$ = $x; } [l] exp[r] { $$ = $<ival>lo9 + $r; }
|
||||
^^^^^^^^^^
|
||||
^~~~~~~~~~
|
||||
test.y:52.3-68: symbol not found in production: lo9
|
||||
| exp[x] '+' { $<ival>$ = $x; } [l] exp[r] { $$ = $<ival>lo9 + $r; }
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
test.y:53.51-60: warning: misleading reference: '$<ival>exp' [-Wother]
|
||||
| exp[x] '-' { $<ival>$ = $x; } [l] exp[r] { $$ = $<ival>exp - $r; }
|
||||
^^^^^^^^^^
|
||||
^~~~~~~~~~
|
||||
test.y:44.1-3: refers to: $exp at $$
|
||||
exp:
|
||||
^^^
|
||||
^~~
|
||||
test.y:53.7: possibly meant: $x, hiding $exp at $1
|
||||
| exp[x] '-' { $<ival>$ = $x; } [l] exp[r] { $$ = $<ival>exp - $r; }
|
||||
^
|
||||
@@ -272,19 +272,19 @@ test.y:53.41: possibly meant: $r, hiding $exp at $4
|
||||
^
|
||||
test.y:54.51-52: error: $l of 'exp' has no declared type
|
||||
| exp[x] '*' { $<ival>$ = $x; } [l] exp[r] { $$ = $l * $r; }
|
||||
^^
|
||||
^~
|
||||
test.y:57.40-43: error: invalid reference: '$r12'
|
||||
| exp[l] '^' exp[r] { $$ = power ($l, $r12); }
|
||||
^^^^
|
||||
^~~~
|
||||
test.y:57.3-47: symbol not found in production: r12
|
||||
| exp[l] '^' exp[r] { $$ = power ($l, $r12); }
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
test.y:58.29-33: error: invalid reference: '$expo'
|
||||
| '(' exp ')' { $$ = $expo; }
|
||||
^^^^^
|
||||
^~~~~
|
||||
test.y:58.3-46: symbol not found in production: expo
|
||||
| '(' exp ')' { $$ = $expo; }
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
]])
|
||||
AT_BISON_OPTION_POPDEFS
|
||||
AT_CLEANUP
|
||||
@@ -423,121 +423,121 @@ test.y:45.41-46: possibly meant: $[then-a].f at $4
|
||||
AT_BISON_CHECK([-fcaret -o test.c test.y], 1, [],
|
||||
[[test.y:24.36-41: error: invalid reference: '$cond1'
|
||||
{ $if_stmt1 = new IfStmt($cond1, $then.f1, $else); };
|
||||
^^^^^^
|
||||
^~~~~~
|
||||
test.y:23.11-24.62: symbol not found in production: cond1
|
||||
if_stmt1: IF expr[cond] THEN stmt[then] ELSE stmt.list[else] FI
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
test.y:26.43-53: error: invalid reference: '$stmt.field'
|
||||
{ $if_stmt2 = new IfStmt($cond, $stmt.field, 0); };
|
||||
^^^^^^^^^^^
|
||||
^~~~~~~~~~~
|
||||
test.y:25.11-26.60: symbol not found in production: stmt
|
||||
if_stmt2: IF expr[cond] THEN stmt[then] FI
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
test.y:25.35-38: possibly meant: $then.field, hiding $stmt.field at $4
|
||||
if_stmt2: IF expr[cond] THEN stmt[then] FI
|
||||
^^^^
|
||||
^~~~
|
||||
test.y:28.43-52: error: invalid reference: '$stmt.list'
|
||||
{ $if_stmt3 = new IfStmt($cond, $stmt.list, 0); };
|
||||
^^^^^^^^^^
|
||||
^~~~~~~~~~
|
||||
test.y:27.11-28.59: symbol not found in production: stmt
|
||||
if_stmt3: IF expr[cond] THEN stmt.list FI
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
test.y:27.30-38: possibly meant: $[stmt.list] at $4
|
||||
if_stmt3: IF expr[cond] THEN stmt.list FI
|
||||
^^^^^^^^^
|
||||
^~~~~~~~~
|
||||
test.y:30.43-46: error: ambiguous reference: '$xyz'
|
||||
{ $if_stmt4 = new IfStmt($cond, $xyz, $cond); };
|
||||
^^^^
|
||||
^~~~
|
||||
test.y:29.35-37: refers to: $xyz at $4
|
||||
if_stmt4: IF expr[cond] THEN stmt[xyz] ELSE stmt[xyz] FI
|
||||
^^^
|
||||
^~~
|
||||
test.y:29.50-52: refers to: $xyz at $6
|
||||
if_stmt4: IF expr[cond] THEN stmt[xyz] ELSE stmt[xyz] FI
|
||||
^^^
|
||||
^~~
|
||||
test.y:32.43-52: error: invalid reference: '$stmt.list'
|
||||
{ $if_stmt5 = new IfStmt($cond, $stmt.list, $else); };
|
||||
^^^^^^^^^^
|
||||
^~~~~~~~~~
|
||||
test.y:31.11-32.63: symbol not found in production: stmt
|
||||
if_stmt5: IF expr[cond] THEN stmt.list[then] ELSE stmt.list[else] FI
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
test.y:31.40-43: possibly meant: $then, hiding $[stmt.list] at $4
|
||||
if_stmt5: IF expr[cond] THEN stmt.list[then] ELSE stmt.list[else] FI
|
||||
^^^^
|
||||
^~~~
|
||||
test.y:31.61-64: possibly meant: $else, hiding $[stmt.list] at $6
|
||||
if_stmt5: IF expr[cond] THEN stmt.list[then] ELSE stmt.list[else] FI
|
||||
^^^^
|
||||
^~~~
|
||||
test.y:34.43-58: error: invalid reference: '$stmt.list.field'
|
||||
{ $if_stmt6 = new IfStmt($cond, $stmt.list.field, $else); };
|
||||
^^^^^^^^^^^^^^^^
|
||||
^~~~~~~~~~~~~~~~
|
||||
test.y:33.11-34.69: symbol not found in production: stmt
|
||||
if_stmt6: IF expr[cond] THEN stmt.list[then] ELSE stmt.list[else] FI
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
test.y:33.40-43: possibly meant: $then.field, hiding $[stmt.list].field at $4
|
||||
if_stmt6: IF expr[cond] THEN stmt.list[then] ELSE stmt.list[else] FI
|
||||
^^^^
|
||||
^~~~
|
||||
test.y:33.61-64: possibly meant: $else.field, hiding $[stmt.list].field at $6
|
||||
if_stmt6: IF expr[cond] THEN stmt.list[then] ELSE stmt.list[else] FI
|
||||
^^^^
|
||||
^~~~
|
||||
test.y:36.43-54: error: invalid reference: '$[stmt.list]'
|
||||
{ $if_stmt7 = new IfStmt($cond, $[stmt.list].field, $else); };
|
||||
^^^^^^^^^^^^
|
||||
^~~~~~~~~~~~
|
||||
test.y:35.11-36.71: symbol not found in production: stmt.list
|
||||
if_stmt7: IF expr[cond] THEN stmt.list[then] ELSE stmt.list[else] FI
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
test.y:35.40-43: possibly meant: $then, hiding $[stmt.list] at $4
|
||||
if_stmt7: IF expr[cond] THEN stmt.list[then] ELSE stmt.list[else] FI
|
||||
^^^^
|
||||
^~~~
|
||||
test.y:35.61-64: possibly meant: $else, hiding $[stmt.list] at $6
|
||||
if_stmt7: IF expr[cond] THEN stmt.list[then] ELSE stmt.list[else] FI
|
||||
^^^^
|
||||
^~~~
|
||||
test.y:38.43-49: error: invalid reference: '$then.1'
|
||||
{ $if_stmt8 = new IfStmt($cond, $then.1, $else); };
|
||||
^^^^^^^
|
||||
^~~~~~~
|
||||
test.y:37.11-38.60: symbol not found in production: then
|
||||
if_stmt8: IF expr[cond] THEN stmt.list[then.1] ELSE stmt.list[else] FI
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
test.y:37.40-45: possibly meant: $[then.1] at $4
|
||||
if_stmt8: IF expr[cond] THEN stmt.list[then.1] ELSE stmt.list[else] FI
|
||||
^^^^^^
|
||||
^~~~~~
|
||||
test.y:40.43-55: error: invalid reference: '$then.1.field'
|
||||
{ $if_stmt9 = new IfStmt($cond, $then.1.field, $else); };
|
||||
^^^^^^^^^^^^^
|
||||
^~~~~~~~~~~~~
|
||||
test.y:39.11-40.66: symbol not found in production: then
|
||||
if_stmt9: IF expr[cond] THEN stmt.list[then.1] ELSE stmt.list[else] FI
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
test.y:39.40-45: possibly meant: $[then.1].field at $4
|
||||
if_stmt9: IF expr[cond] THEN stmt.list[then.1] ELSE stmt.list[else] FI
|
||||
^^^^^^
|
||||
^~~~~~
|
||||
test.y:42.44-50: error: invalid reference: '$stmt.x'
|
||||
{ $if_stmt10 = new IfStmt($cond, $stmt.x, 0); };
|
||||
^^^^^^^
|
||||
^~~~~~~
|
||||
test.y:41.12-42.57: symbol not found in production: stmt
|
||||
if_stmt10: IF expr[cond] THEN stmt[stmt.x] FI
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
test.y:41.36-41: possibly meant: $[stmt.x].x, hiding $stmt.x at $4
|
||||
if_stmt10: IF expr[cond] THEN stmt[stmt.x] FI
|
||||
^^^^^^
|
||||
^~~~~~
|
||||
test.y:41.36-41: possibly meant: $[stmt.x] at $4
|
||||
if_stmt10: IF expr[cond] THEN stmt[stmt.x] FI
|
||||
^^^^^^
|
||||
^~~~~~
|
||||
test.y:44.13-22: error: invalid reference: '$if-stmt-a'
|
||||
{ $if-stmt-a = new IfStmt($cond, $then, $else); };
|
||||
^^^^^^^^^^
|
||||
^~~~~~~~~~
|
||||
test.y:43.12-44.59: symbol not found in production: if
|
||||
if-stmt-a: IF expr[cond] THEN stmt.list[then] ELSE stmt.list[else] FI
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
test.y:43.1-9: possibly meant: $[if-stmt-a] at $$
|
||||
if-stmt-a: IF expr[cond] THEN stmt.list[then] ELSE stmt.list[else] FI
|
||||
^^^^^^^^^
|
||||
^~~~~~~~~
|
||||
test.y:46.46-54: error: invalid reference: '$then-a.f'
|
||||
{ $[if-stmt-b] = new IfStmt($cond, $then-a.f, $else); };
|
||||
^^^^^^^^^
|
||||
^~~~~~~~~
|
||||
test.y:45.12-46.65: symbol not found in production: then
|
||||
if-stmt-b: IF expr[cond] THEN if-stmt-a[then-a] ELSE stmt.list[else] FI
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
test.y:45.41-46: possibly meant: $[then-a].f at $4
|
||||
if-stmt-b: IF expr[cond] THEN if-stmt-a[then-a] ELSE stmt.list[else] FI
|
||||
^^^^^^
|
||||
^~~~~~
|
||||
]])
|
||||
|
||||
AT_CLEANUP
|
||||
|
||||
+1
-1
@@ -154,7 +154,7 @@ start: ;
|
||||
AT_BISON_OPTION_POPDEFS
|
||||
|
||||
AT_BISON_CHECK([[input.y]], [[1]], [],
|
||||
[[input.y:2.9-21: error: %define variable 'api.push-pull' is not used
|
||||
[[input.y:2.1-26: error: %define variable 'api.push-pull' is not used
|
||||
]])
|
||||
|
||||
AT_CLEANUP
|
||||
|
||||
+97
-15
@@ -134,31 +134,31 @@ AT_BISON_CHECK([[-fcaret input.y]], 0, [],
|
||||
input.y: warning: 9 rules useless in grammar [-Wother]
|
||||
input.y:6.1-8: warning: nonterminal useless in grammar: useless1 [-Wother]
|
||||
useless1: '1';
|
||||
^^^^^^^^
|
||||
^~~~~~~~
|
||||
input.y:7.1-8: warning: nonterminal useless in grammar: useless2 [-Wother]
|
||||
useless2: '2';
|
||||
^^^^^^^^
|
||||
^~~~~~~~
|
||||
input.y:8.1-8: warning: nonterminal useless in grammar: useless3 [-Wother]
|
||||
useless3: '3';
|
||||
^^^^^^^^
|
||||
^~~~~~~~
|
||||
input.y:9.1-8: warning: nonterminal useless in grammar: useless4 [-Wother]
|
||||
useless4: '4';
|
||||
^^^^^^^^
|
||||
^~~~~~~~
|
||||
input.y:10.1-8: warning: nonterminal useless in grammar: useless5 [-Wother]
|
||||
useless5: '5';
|
||||
^^^^^^^^
|
||||
^~~~~~~~
|
||||
input.y:11.1-8: warning: nonterminal useless in grammar: useless6 [-Wother]
|
||||
useless6: '6';
|
||||
^^^^^^^^
|
||||
^~~~~~~~
|
||||
input.y:12.1-8: warning: nonterminal useless in grammar: useless7 [-Wother]
|
||||
useless7: '7';
|
||||
^^^^^^^^
|
||||
^~~~~~~~
|
||||
input.y:13.1-8: warning: nonterminal useless in grammar: useless8 [-Wother]
|
||||
useless8: '8';
|
||||
^^^^^^^^
|
||||
^~~~~~~~
|
||||
input.y:14.1-8: warning: nonterminal useless in grammar: useless9 [-Wother]
|
||||
useless9: '9';
|
||||
^^^^^^^^
|
||||
^~~~~~~~
|
||||
]])
|
||||
|
||||
|
||||
@@ -199,6 +199,88 @@ AT_CLEANUP
|
||||
|
||||
|
||||
|
||||
## --------------- ##
|
||||
## Useless Parts. ##
|
||||
## --------------- ##
|
||||
|
||||
AT_SETUP([Useless Parts])
|
||||
|
||||
# We used to emit code that used symbol numbers before the useless
|
||||
# symbol elimination, hence before the renumbering of the useful
|
||||
# symbols. As a result, the evaluation of the skeleton failed because
|
||||
# it used non existing symbol numbers. Which is the happy scenario:
|
||||
# we could use numbers of other existing symbols...
|
||||
# http://lists.gnu.org/archive/html/bug-bison/2019-01/msg00044.html
|
||||
|
||||
AT_BISON_OPTION_PUSHDEFS
|
||||
AT_DATA([[input.y]],
|
||||
[[%code {
|
||||
]AT_YYERROR_DECLARE_EXTERN[
|
||||
]AT_YYLEX_DECLARE_EXTERN[
|
||||
}
|
||||
%union { void* ptr; }
|
||||
%type <ptr> used1
|
||||
%type <ptr> used2
|
||||
|
||||
%%
|
||||
start
|
||||
: used1
|
||||
;
|
||||
|
||||
used1
|
||||
: used2 { $$ = $1; }
|
||||
;
|
||||
|
||||
unused
|
||||
: used2
|
||||
;
|
||||
|
||||
used2
|
||||
: { $$ = YY_NULLPTR; }
|
||||
;
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK([[-fcaret -rall -o input.c input.y]], 0, [],
|
||||
[[input.y: warning: 1 nonterminal useless in grammar [-Wother]
|
||||
input.y: warning: 1 rule useless in grammar [-Wother]
|
||||
input.y:18.1-6: warning: nonterminal useless in grammar: unused [-Wother]
|
||||
unused
|
||||
^~~~~~
|
||||
]])
|
||||
|
||||
|
||||
AT_CHECK([[sed -n '/^State 0/q;/^$/!p' input.output]], 0,
|
||||
[[Nonterminals useless in grammar
|
||||
unused
|
||||
Rules useless in grammar
|
||||
4 unused: used2
|
||||
Grammar
|
||||
0 $accept: start $end
|
||||
1 start: used1
|
||||
2 used1: used2
|
||||
3 used2: %empty
|
||||
Terminals, with rules where they appear
|
||||
$end (0) 0
|
||||
error (256)
|
||||
Nonterminals, with rules where they appear
|
||||
$accept (3)
|
||||
on left: 0
|
||||
start (4)
|
||||
on left: 1, on right: 0
|
||||
used1 <ptr> (5)
|
||||
on left: 2, on right: 1
|
||||
used2 <ptr> (6)
|
||||
on left: 3, on right: 2
|
||||
]])
|
||||
|
||||
# Make sure the generated parser is correct.
|
||||
AT_COMPILE([input.o])
|
||||
|
||||
AT_BISON_OPTION_POPDEFS
|
||||
AT_CLEANUP
|
||||
|
||||
|
||||
|
||||
## ------------------- ##
|
||||
## Reduced Automaton. ##
|
||||
## ------------------- ##
|
||||
@@ -240,13 +322,13 @@ AT_BISON_CHECK([[-fcaret not-reduced.y]], 0, [],
|
||||
not-reduced.y: warning: 3 rules useless in grammar [-Wother]
|
||||
not-reduced.y:14.1-13: warning: nonterminal useless in grammar: not_reachable [-Wother]
|
||||
not_reachable: useful { /* A not reachable action. */ }
|
||||
^^^^^^^^^^^^^
|
||||
^~~~~~~~~~~~~
|
||||
not-reduced.y:17.1-14: warning: nonterminal useless in grammar: non_productive [-Wother]
|
||||
non_productive: non_productive useless_token
|
||||
^^^^^^^^^^^^^^
|
||||
^~~~~~~~~~~~~~
|
||||
not-reduced.y:11.6-57: warning: rule useless in grammar [-Wother]
|
||||
| non_productive { /* A non productive action. */ }
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
]])
|
||||
|
||||
AT_CHECK([[sed -n '/^Grammar/q;/^$/!p' not-reduced.output]], 0,
|
||||
@@ -319,13 +401,13 @@ AT_BISON_CHECK([[-fcaret input.y]], 0, [],
|
||||
input.y: warning: 3 rules useless in grammar [-Wother]
|
||||
input.y:6.1-11: warning: nonterminal useless in grammar: underivable [-Wother]
|
||||
underivable: indirection;
|
||||
^^^^^^^^^^^
|
||||
^~~~~~~~~~~
|
||||
input.y:7.1-11: warning: nonterminal useless in grammar: indirection [-Wother]
|
||||
indirection: underivable;
|
||||
^^^^^^^^^^^
|
||||
^~~~~~~~~~~
|
||||
input.y:5.15-25: warning: rule useless in grammar [-Wother]
|
||||
exp: useful | underivable;
|
||||
^^^^^^^^^^^
|
||||
^~~~~~~~~~~
|
||||
]])
|
||||
|
||||
AT_CHECK([[sed -n '/^Grammar/q;/^$/!p' input.output]], 0,
|
||||
|
||||
+2
-2
@@ -454,10 +454,10 @@ input.y:22.16-63: warning: symbol "\\'?\"\a\b\f\n\r\t\v\001\201\001\201??!" used
|
||||
AT_BISON_CHECK([-fcaret -o input.c input.y], [[0]], [[]],
|
||||
[[input.y:22.8-14: warning: symbol SPECIAL redeclared [-Wother]
|
||||
%token SPECIAL "\\\'\?\"\a\b\f\n\r\t\v\001\201\x001\x000081??!"
|
||||
^^^^^^^
|
||||
^~~~~~~
|
||||
input.y:22.16-63: warning: symbol "\\'?\"\a\b\f\n\r\t\v\001\201\001\201??!" used more than once as a literal string [-Wother]
|
||||
%token SPECIAL "\\\'\?\"\a\b\f\n\r\t\v\001\201\x001\x000081??!"
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
]])
|
||||
AT_COMPILE([input])
|
||||
|
||||
|
||||
+2
-2
@@ -32,7 +32,7 @@ exp: %empty;
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK([[input.y]], [[1]], [[]],
|
||||
[[input.y:2.9-22: error: '%union' and '%define api.value.type' cannot be used together
|
||||
[[input.y:2.1-38: error: '%union' and '%define api.value.type' cannot be used together
|
||||
]])
|
||||
|
||||
AT_CLEANUP
|
||||
@@ -51,7 +51,7 @@ exp: %empty;
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK([[input.y]], [[1]], [[]],
|
||||
[[input.y:2.9-22: error: '%yacc' and '%define api.value.type "union"' cannot be used together
|
||||
[[input.y:2.1-28: error: '%yacc' and '%define api.value.type "union"' cannot be used together
|
||||
]])
|
||||
|
||||
AT_CLEANUP
|
||||
|
||||
Reference in New Issue
Block a user