mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-08-08 10:15:14 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2d90916067 | ||
|
|
91e5a23ff2 | ||
|
|
d4ae66c371 | ||
|
|
70fb574717 | ||
|
|
0820f16ca8 | ||
|
|
49f1e5f428 | ||
|
|
238692ad77 | ||
|
|
5f95583da7 | ||
|
|
964fb2aa6f | ||
|
|
7c0d36b760 | ||
|
|
b4d18c7fc6 | ||
|
|
3e6e51cf5c | ||
|
|
d309bd9f9f | ||
|
|
203f7230ec | ||
|
|
156e548341 | ||
|
|
526ef45f30 | ||
|
|
d7f7fcd9c7 | ||
|
|
0fd542c3e0 | ||
|
|
413908e5a4 | ||
|
|
84ef175287 | ||
|
|
5234c8390f | ||
|
|
21f7690570 | ||
|
|
edb39c29a2 | ||
|
|
1247d94ba6 | ||
|
|
ed9a821caa | ||
|
|
330552ea49 | ||
|
|
7c609859ee | ||
|
|
ed10c308fa | ||
|
|
b91566edd1 | ||
|
|
29520abb3b | ||
|
|
2491de1eef | ||
|
|
ec207d1bb2 | ||
|
|
688b3404a2 | ||
|
|
cd6ef1e7d7 | ||
|
|
2b518d621f | ||
|
|
1ae4f1d329 | ||
|
|
160df55c56 | ||
|
|
e0b0a67b86 | ||
|
|
0e5cbd38b2 | ||
|
|
feb0bb0a59 | ||
|
|
d796e11f8f | ||
|
|
0895858d8e | ||
|
|
4efb2f7bd2 | ||
|
|
eeafc706e8 | ||
|
|
cf6d8d0631 | ||
|
|
8f44164443 | ||
|
|
1001f48416 | ||
|
|
3be228f64c | ||
|
|
670c7e7a75 | ||
|
|
c4b1a2b68f | ||
|
|
b65bd16e45 | ||
|
|
0f120354b6 | ||
|
|
69e3b405d9 | ||
|
|
3dd8f2305a | ||
|
|
9e75066819 | ||
|
|
efb65daa36 | ||
|
|
e077bf1ebc | ||
|
|
c35e829a76 | ||
|
|
d4f854e5b2 | ||
|
|
35c0fe6789 | ||
|
|
22f62414f9 | ||
|
|
9206b15c4e | ||
|
|
5edac5e15a | ||
|
|
1c3189734c | ||
|
|
c662b23735 | ||
|
|
627fecb19e | ||
|
|
2a069f22c6 | ||
|
|
3f4ffea6f2 | ||
|
|
251e1b137f | ||
|
|
efbcadeca7 | ||
|
|
e4d33cf579 | ||
|
|
5855da4722 | ||
|
|
5d5e1df1dc | ||
|
|
cef13e11f5 | ||
|
|
b7fbfd050e | ||
|
|
e088b4f90f | ||
|
|
c857ed4f72 | ||
|
|
1998606a90 | ||
|
|
b0bb4cde2e | ||
|
|
d2acc4b401 | ||
|
|
a53c6026cd | ||
|
|
ae5edcc23b | ||
|
|
296e2f90ab | ||
|
|
1ccb4be02b | ||
|
|
421662ec88 | ||
|
|
39be113b1f | ||
|
|
2101b0e210 | ||
|
|
b1327c56f7 | ||
|
|
ae03b16785 | ||
|
|
7e16bd2cae | ||
|
|
508ac09939 | ||
|
|
0535d2a608 | ||
|
|
94f7606db6 | ||
|
|
de5be4a693 | ||
|
|
03a6b439f6 | ||
|
|
742910838e | ||
|
|
52ce2a008b | ||
|
|
bb311cfbed | ||
|
|
518dc6ca26 | ||
|
|
6a1a681fd2 | ||
|
|
dd878d1851 | ||
|
|
6ed813c122 | ||
|
|
1ec93ca2a2 | ||
|
|
12f4091de4 | ||
|
|
8ece778cb8 | ||
|
|
f32ba07f94 | ||
|
|
50cd3f16de | ||
|
|
37da3c4b42 | ||
|
|
79bae4d6bb | ||
|
|
23f7554188 | ||
|
|
3ff248ebfe | ||
|
|
4e1a5aae96 | ||
|
|
8e70880af1 | ||
|
|
3fea8fade8 | ||
|
|
e7aff57122 | ||
|
|
339d11badf | ||
|
|
99260caef9 | ||
|
|
c19af5cbb4 | ||
|
|
b54181ff9b | ||
|
|
86c45be582 | ||
|
|
b5e0351c3e | ||
|
|
150b2318ed | ||
|
|
35c4a8e65e | ||
|
|
fc39ccab6b | ||
|
|
9a33fb9317 | ||
|
|
866bc6a49f | ||
|
|
e8619330e8 | ||
|
|
193dc86965 | ||
|
|
51fa2ab0a2 | ||
|
|
2d8c3edbf8 | ||
|
|
4590071287 | ||
|
|
ac3b6c18a5 | ||
|
|
f3ef847539 | ||
|
|
16f2353723 | ||
|
|
da5317cc9d | ||
|
|
e0cb91a922 | ||
|
|
482b370540 | ||
|
|
66283fb625 | ||
|
|
93c849ef0d | ||
|
|
6279945003 | ||
|
|
dcb6c972a2 | ||
|
|
af0441cfd2 | ||
|
|
bbb63b1ca9 | ||
|
|
ac54d19eba | ||
|
|
5807dd9279 | ||
|
|
94bfdf3b4b | ||
|
|
f80890c4bb | ||
|
|
1ebc2ac55c | ||
|
|
94952779b6 | ||
|
|
ed7d5c2b5b | ||
|
|
1ce02e13c3 | ||
|
|
8ef0b12eb7 | ||
|
|
e6d83116ae | ||
|
|
4d9fa28ba8 | ||
|
|
a100a3c4c1 | ||
|
|
b18ceb50f1 | ||
|
|
ff4d67ede8 | ||
|
|
465babb635 | ||
|
|
22c3839168 | ||
|
|
4619b32dc0 | ||
|
|
ad921890c1 | ||
|
|
6a28e6d412 | ||
|
|
f4495da337 | ||
|
|
dbaed0bbf2 | ||
|
|
78c7fb6460 | ||
|
|
14ce500508 | ||
|
|
acba58ac59 | ||
|
|
da29809969 | ||
|
|
87e4895189 | ||
|
|
01e3f45f83 | ||
|
|
9c21da3363 | ||
|
|
febf6115a0 | ||
|
|
11b5bac7bf | ||
|
|
b61bf2f0e8 | ||
|
|
091943f265 | ||
|
|
bf98d94f4f | ||
|
|
6bb37dbe27 | ||
|
|
c3585f41ef | ||
|
|
6525abdc83 | ||
|
|
2b63c54f5a | ||
|
|
2da399d15f | ||
|
|
19f45df02b | ||
|
|
2ab4058de0 | ||
|
|
f2277c3fec | ||
|
|
fb49a10e2c | ||
|
|
f049a57eec | ||
|
|
0c77d69721 | ||
|
|
307fcdee00 | ||
|
|
d26d10ad6c | ||
|
|
1b4108da3e | ||
|
|
53bfc7df94 | ||
|
|
a5fb4a88ef | ||
|
|
54df196d49 | ||
|
|
52bb6f0525 | ||
|
|
76dab18af3 | ||
|
|
c982974f33 | ||
|
|
dc2a3578b7 | ||
|
|
9661b2fcbc | ||
|
|
d9a9b054ae | ||
|
|
cb9f4cb543 | ||
|
|
b86dcaf40b | ||
|
|
0fafbbdefb | ||
|
|
4b85b969d0 | ||
|
|
7727693711 | ||
|
|
ce27796b74 | ||
|
|
6135fdc152 | ||
|
|
f1497356e8 | ||
|
|
1429569362 | ||
|
|
506c368ab2 | ||
|
|
4f9dc3bdc1 | ||
|
|
0d81be2dc7 | ||
|
|
32f44f4bfb | ||
|
|
38a8287813 | ||
|
|
df752784c2 | ||
|
|
292409e91e | ||
|
|
eea56d70d9 | ||
|
|
6e2de439e6 | ||
|
|
e33cd4b824 | ||
|
|
0669780ff8 | ||
|
|
160df220b1 | ||
|
|
da5c072a62 | ||
|
|
73ac8ff409 |
+1
-1
@@ -1 +1 @@
|
||||
3.5.91
|
||||
3.6.90
|
||||
|
||||
+69
-47
@@ -29,12 +29,13 @@ jobs:
|
||||
clone: true
|
||||
dist: bionic
|
||||
script:
|
||||
- sudo apt-get install -qq autoconf automake autopoint flex gettext graphviz help2man m4 texinfo
|
||||
- sudo apt-get install -qq autoconf automake autopoint flex gettext gperf graphviz help2man m4 texinfo
|
||||
- autoconf --version
|
||||
- automake --version
|
||||
- autopoint --version
|
||||
- dot -V
|
||||
- gettext --version
|
||||
- gperf --version
|
||||
- help2man --version
|
||||
- makeinfo --version
|
||||
- m4 --version
|
||||
@@ -46,7 +47,7 @@ jobs:
|
||||
- ./bootstrap
|
||||
- ./configure --enable-gcc-warnings || { cat config.log && false; }
|
||||
- make -j2
|
||||
- make -j2 dist
|
||||
- make -j2 dist-xz
|
||||
# Can help understanding why we get "dirty" tarballs.
|
||||
- git status
|
||||
- dist=$(echo bison*.xz)
|
||||
@@ -69,53 +70,53 @@ jobs:
|
||||
|
||||
# Start with three completely different environments, to get errors asap.
|
||||
|
||||
- name: "GCC 9 -O3"
|
||||
- name: "GCC 10 -O3"
|
||||
stage: check
|
||||
os: linux
|
||||
dist: bionic
|
||||
addons: &gcc9
|
||||
addons: &gcc10
|
||||
apt:
|
||||
sources:
|
||||
# See https://github.com/travis-ci/apt-source-safelist/issues/410.
|
||||
- sourceline: 'ppa:ubuntu-toolchain-r/test'
|
||||
packages: g++-9
|
||||
packages: g++-10
|
||||
env:
|
||||
- CC=gcc-9
|
||||
- CXX=g++-9
|
||||
- CC=gcc-10
|
||||
- CXX=g++-10
|
||||
- CONFIGUREFLAGS='CPPFLAGS=-DNDEBUG CFLAGS=-O3 CXXFLAGS=-O3'
|
||||
|
||||
# ASAN is time consuming, and we timeout the 50min granted by
|
||||
# Travis if we run all the tests in one go. Run in two parts.
|
||||
- name: "Clang 9 libc++ and ASAN part 1"
|
||||
- name: "Clang 10 libc++ and ASAN part 1"
|
||||
stage: check
|
||||
os: linux
|
||||
dist: bionic
|
||||
addons: &clang9
|
||||
addons: &clang10
|
||||
apt:
|
||||
sources:
|
||||
# See https://github.com/travis-ci/apt-source-safelist/issues/410.
|
||||
- sourceline: 'ppa:ubuntu-toolchain-r/test'
|
||||
- sourceline: 'deb http://apt.llvm.org/bionic/ llvm-toolchain-bionic-9 main'
|
||||
- sourceline: 'deb http://apt.llvm.org/bionic/ llvm-toolchain-bionic-10 main'
|
||||
key_url: 'https://apt.llvm.org/llvm-snapshot.gpg.key'
|
||||
packages:
|
||||
- clang-9
|
||||
- libc++-9-dev
|
||||
- libc++abi-9-dev
|
||||
- clang-10
|
||||
- libc++-10-dev
|
||||
- libc++abi-10-dev
|
||||
env:
|
||||
# Do not use ASAN with ubuntu's libc++: https://bugs.llvm.org/show_bug.cgi?id=17379
|
||||
- CC='clang-9 -fsanitize=address'
|
||||
- CXX='clang++-9 -fsanitize=address -stdlib=libc++'
|
||||
- CC='clang-10 -fsanitize=address'
|
||||
- CXX='clang++-10 -fsanitize=address -stdlib=libc++'
|
||||
- PART=1
|
||||
|
||||
- name: "Clang 9 libc++ and ASAN part 2"
|
||||
- name: "Clang 10 libc++ and ASAN part 2"
|
||||
stage: check
|
||||
os: linux
|
||||
dist: bionic
|
||||
addons: *clang9
|
||||
addons: *clang10
|
||||
env:
|
||||
# Do not use ASAN with ubuntu's libc++: https://bugs.llvm.org/show_bug.cgi?id=17379
|
||||
- CC='clang-9 -fsanitize=address'
|
||||
- CXX='clang++-9 -fsanitize=address -stdlib=libc++'
|
||||
- CC='clang-10 -fsanitize=address'
|
||||
- CXX='clang++-10 -fsanitize=address -stdlib=libc++'
|
||||
- PART=2
|
||||
|
||||
- name: "ICC"
|
||||
@@ -135,62 +136,64 @@ jobs:
|
||||
packages:
|
||||
- intel-oneapi-icc
|
||||
|
||||
## ------- ##
|
||||
## First. ##
|
||||
## ------- ##
|
||||
|
||||
# Start with three completely different environments, to get
|
||||
# errors asap.
|
||||
|
||||
- name: "ARM64: GCC 9 -O3 part 1"
|
||||
- name: "ARM64: GCC 10 -O2 part 1"
|
||||
stage: check
|
||||
os: linux
|
||||
arch: arm64
|
||||
dist: bionic
|
||||
addons: *gcc9
|
||||
addons: *gcc10
|
||||
env:
|
||||
- CC=gcc-9
|
||||
- CXX=g++-9
|
||||
- CONFIGUREFLAGS='CPPFLAGS=-DNDEBUG CFLAGS=-O3 CXXFLAGS=-O3'
|
||||
- CC=gcc-10
|
||||
- CXX=g++-10
|
||||
- CONFIGUREFLAGS='CPPFLAGS=-DNDEBUG CFLAGS=-O2 CXXFLAGS=-O2'
|
||||
- PART=1
|
||||
|
||||
- name: "PPC64le: GCC 9 part 1"
|
||||
- name: "PPC64le: GCC 10 -O2 part 1"
|
||||
stage: check
|
||||
os: linux
|
||||
arch: ppc64le
|
||||
dist: bionic
|
||||
addons: *gcc9
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
# See https://github.com/travis-ci/apt-source-safelist/issues/410.
|
||||
- sourceline: 'ppa:ubuntu-toolchain-r/test'
|
||||
packages: g++-10
|
||||
env:
|
||||
- CC=gcc-9
|
||||
- CXX=g++-9
|
||||
- CONFIGUREFLAGS='CFLAGS=-O3 CXXFLAGS=-O3'
|
||||
- CC=gcc-10
|
||||
- CXX=g++-10
|
||||
- CONFIGUREFLAGS='CFLAGS=-O2 CXXFLAGS=-O2'
|
||||
- PART=1
|
||||
|
||||
- name: "s390x: GCC 9 part 1"
|
||||
- name: "s390x: GCC 10 -O2 part 1"
|
||||
stage: check
|
||||
os: linux
|
||||
arch: s390x
|
||||
dist: bionic
|
||||
addons: *gcc9
|
||||
addons: *gcc10
|
||||
env:
|
||||
- CC=gcc-9
|
||||
- CXX=g++-9
|
||||
- CONFIGUREFLAGS='CFLAGS=-O3 CXXFLAGS=-O3'
|
||||
- CC=gcc-10
|
||||
- CXX=g++-10
|
||||
- CONFIGUREFLAGS='CFLAGS=-O2 CXXFLAGS=-O2'
|
||||
- PART=1
|
||||
|
||||
## ----- ##
|
||||
## GCC. ##
|
||||
## ----- ##
|
||||
|
||||
- name: "GCC 8 with sanitizers part 1"
|
||||
- name: "GCC 9 with sanitizers part 1"
|
||||
stage: check
|
||||
os: linux
|
||||
dist: bionic
|
||||
addons:
|
||||
apt:
|
||||
packages: g++-8
|
||||
sources:
|
||||
# See https://github.com/travis-ci/apt-source-safelist/issues/410.
|
||||
- sourceline: 'ppa:ubuntu-toolchain-r/test'
|
||||
packages: g++-9
|
||||
env:
|
||||
- CC='gcc-8 -fsanitize=undefined,address -fno-omit-frame-pointer'
|
||||
- CXX='g++-8 -fsanitize=undefined,address -fno-omit-frame-pointer'
|
||||
- CC='gcc-9 -fsanitize=undefined,address -fno-omit-frame-pointer'
|
||||
- CXX='g++-9 -fsanitize=undefined,address -fno-omit-frame-pointer'
|
||||
- CONFIGUREFLAGS='CFLAGS=-O1 CXXFLAGS=-O1'
|
||||
- PART=1
|
||||
|
||||
@@ -292,7 +295,27 @@ jobs:
|
||||
## Clang. ##
|
||||
## ------- ##
|
||||
|
||||
- name: "Clang 8 -O3"
|
||||
- name: "Clang 9 -O3"
|
||||
stage: check
|
||||
os: linux
|
||||
dist: bionic
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
# See https://github.com/travis-ci/apt-source-safelist/issues/410.
|
||||
- sourceline: 'ppa:ubuntu-toolchain-r/test'
|
||||
- sourceline: 'deb http://apt.llvm.org/bionic/ llvm-toolchain-bionic-9 main'
|
||||
key_url: 'https://apt.llvm.org/llvm-snapshot.gpg.key'
|
||||
packages:
|
||||
- clang-9
|
||||
- libc++-9-dev
|
||||
- libc++abi-9-dev
|
||||
env:
|
||||
- CC='clang-9'
|
||||
- CXX='clang++-9 -stdlib=libc++'
|
||||
- CONFIGUREFLAGS='CPPFLAGS=-DNDEBUG CFLAGS=-O3 CXXFLAGS=-O3'
|
||||
|
||||
- name: "Clang 8"
|
||||
stage: check
|
||||
os: linux
|
||||
dist: bionic
|
||||
@@ -305,7 +328,6 @@ jobs:
|
||||
env:
|
||||
- CC=clang-8
|
||||
- CXX='clang++-8 -stdlib=libc++'
|
||||
- CONFIGUREFLAGS='CPPFLAGS=-DNDEBUG CFLAGS=-O3 CXXFLAGS=-O3'
|
||||
|
||||
- name: "Clang 7"
|
||||
stage: check
|
||||
|
||||
+12
@@ -127,3 +127,15 @@ gen-ChangeLog:
|
||||
--since=$(gen_start_date) > $$cl.tmp && \
|
||||
mv -f $$cl.tmp $$cl; \
|
||||
fi
|
||||
|
||||
# Useful to debug.
|
||||
.c.i:
|
||||
$(CC) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -o $@ -E $<
|
||||
|
||||
.PHONY: codespell
|
||||
codespell:
|
||||
$(AM_V_GEN) cd $(srcdir) \
|
||||
&& codespell \
|
||||
--regex "[\\w\\-'’\`]+\+*" \
|
||||
--ignore-words-list "ba,circularly,cloneable,copyable,define'd,dout,froms,iff,ifset,od,ois" \
|
||||
$$(git ls-files data doc lib src tests)
|
||||
|
||||
@@ -1,35 +1,202 @@
|
||||
GNU Bison NEWS
|
||||
|
||||
* Noteworthy changes in release 3.5.92 (2020-05-03) [beta]
|
||||
* Noteworthy changes in release 3.6.91 (2020-07-09) [beta]
|
||||
|
||||
** Bug fixes
|
||||
|
||||
Portability issues.
|
||||
|
||||
More documentation.
|
||||
|
||||
Backward compatibility issues with C++.
|
||||
* Noteworthy changes in release 3.6.90 (2020-07-04) [beta]
|
||||
|
||||
* Noteworthy changes in release 3.5.91 (2020-04-29) [stable]
|
||||
** Deprecated features
|
||||
|
||||
The YYPRINT macro, which works only with yacc.c and only for tokens, was
|
||||
obsoleted long ago by %printer, introduced in Bison 1.50 (November 2002).
|
||||
It is deprecated and its support will be removed eventually.
|
||||
|
||||
In conformance with the recommendations of the Graphviz team, in the next
|
||||
version Bison the option `--graph` will generate a *.gv file by default,
|
||||
instead of *.dot. A transition started in Bison 3.4.
|
||||
|
||||
** New features
|
||||
|
||||
*** Returning the error token
|
||||
*** Counterexample Generation
|
||||
|
||||
When the scanner returns an invalid token or the undefined token
|
||||
(YYUNDEF), the parser generates an error message and enters error
|
||||
recovery. Because of that error message, most scanners that find lexical
|
||||
errors generate an error message, and then ignore the invalid input
|
||||
without entering the error-recovery.
|
||||
Contributed by Vincent Imbimbo.
|
||||
|
||||
The scanners may now return YYerror, the error token, to enter the
|
||||
error-recovery mode without triggering an additional error message. See
|
||||
the bistromathic for an example.
|
||||
When given `--report=counterexamples` or `-Wcounterexamples`, bison will
|
||||
now output counterexamples for conflicts in the grammar. These are
|
||||
strings in the grammar which can be parsed in two ways due to the
|
||||
conflict. For example:
|
||||
|
||||
*** The bistromathic features internationalization
|
||||
Example exp '+' exp • '/' exp
|
||||
First derivation exp ::=[ exp ::=[ exp '+' exp • ] '/' exp ]
|
||||
Second derivation exp ::=[ exp '+' exp ::=[ exp • '/' exp ] ]
|
||||
|
||||
Its way to build the error message is more general and is easy to use in
|
||||
other projects.
|
||||
When Bison is installed with text styling enabled, the example is actually
|
||||
shown twice, with colors highlighting the ambiguity.
|
||||
|
||||
* Noteworthy changes in release 3.5.90 (2020-04-18) [beta]
|
||||
This is a shift/reduce conflict caused by none of the operators having
|
||||
precedence, so the example can be parsed in the two ways shown. When
|
||||
bison cannot find an example that can be derived in two ways, it instead
|
||||
generates two examples that are the same up until the dot:
|
||||
|
||||
First example expr • ID $end
|
||||
First derivation $accept ::=[ s ::=[ a ::=[ expr • ] ID ] $end ]
|
||||
Second example expr • ID ',' ID $end
|
||||
Second derivation $accept ::=[ s ::=[ a ::=[ expr ::=[ expr • ID ',' ] ] ID ] $end ]
|
||||
|
||||
In these cases, the parser usually doesn't have enough lookahead to
|
||||
differentiate the two given examples.
|
||||
|
||||
The counterexamples are "focused": in two different ways. First, they do
|
||||
not clutter the output with all the derivations from the start symbol,
|
||||
rather they start on the "conflicted nonterminal". They go straight to the
|
||||
point. Second, they don't "expand" nonterminal symbols uselessly.
|
||||
|
||||
*** File prefix mapping
|
||||
|
||||
Contributed by Joshua Watt.
|
||||
|
||||
Bison learned a new argument, `--file-prefix-map OLD=NEW`. Any file path
|
||||
in the output (specifically `#line` directives and `#ifdef` header guards)
|
||||
that begins with the prefix OLD will have it replaced with the prefix NEW,
|
||||
similar to the `-ffile-prefix-map` in GCC. This option can be used to
|
||||
make bison output reproducible.
|
||||
|
||||
** Changes
|
||||
|
||||
*** Relocatable installation
|
||||
|
||||
When installed to be relocatable (via `configure --enable-relocatable`),
|
||||
bison will now also look for a relocated m4.
|
||||
|
||||
*** C++ file names
|
||||
|
||||
The `filename_type` %define variable was renamed `api.filename.type`.
|
||||
Instead of
|
||||
|
||||
%define filename_type "symbol"
|
||||
|
||||
write
|
||||
|
||||
%define api.filename.type {symbol}
|
||||
|
||||
(Or let `bison --update` do it for you).
|
||||
|
||||
It now defaults to `const std::string` instead of `std::string`.
|
||||
|
||||
*** Deprecated %define variable names
|
||||
|
||||
The following variables have been renamed for consistency. Backward
|
||||
compatibility is ensured, but upgrading is recommended.
|
||||
|
||||
filename_type -> api.filename.type
|
||||
package -> api.package
|
||||
|
||||
*** Push parsers no longer clear their state when parsing is finished
|
||||
|
||||
Previously push-parsers cleared their state when parsing was finished (on
|
||||
success and on failure). This made it impossible to check if there were
|
||||
parse errors, since `yynerrs` was also reset. This can be especially
|
||||
troublesome when used in autocompletion, since a parser with error
|
||||
recovery would suggest (irrelevant) expected tokens even if there were
|
||||
failure.
|
||||
|
||||
Now the parser state can be examined when parsing is finished. The parser
|
||||
state is reset when starting a new parse.
|
||||
|
||||
** Bug fixes
|
||||
|
||||
*** Include the generated header (yacc.c)
|
||||
|
||||
Historically, when --defines was used, bison generated a header and pasted
|
||||
an exact copy of it into the generated parser implementation file. Since
|
||||
Bison 3.4 it is possible to specify that the header should be `#include`d,
|
||||
and how. For instance
|
||||
|
||||
%define api.header.include {"parse.h"}
|
||||
|
||||
or
|
||||
|
||||
%define api.header.include {<parser/parse.h>}
|
||||
|
||||
Now api.header.include defaults to `"header-basename"`, as was intended in
|
||||
Bison 3.4, where `header-basename` is the basename of the generated
|
||||
header. This is disabled when the generated header is `y.tab.h`, to
|
||||
comply with Automake's ylwrap.
|
||||
|
||||
*** String aliases are faithfully propagated
|
||||
|
||||
Bison used to interpret user strings (i.e., decoding backslash escapes)
|
||||
when reading them, and to escape them (i.e., issue non-printable
|
||||
characters as backslash escapes, taking the locale into account) when
|
||||
outputting them. As a consequence non-ASCII strings (say in UTF-8) ended
|
||||
up "ciphered" as sequences of backslash escapes. This happened not only
|
||||
in the generated sources (where the compiler will reinterpret them), but
|
||||
also in all the generated reports (text, xml, html, dot, etc.). Reports
|
||||
were therefore not readable when string aliases were not pure ASCII.
|
||||
Worse yet: the output depended on the user's locale.
|
||||
|
||||
Now Bison faithfully treats the string aliases exactly the way the user
|
||||
spelled them. This fixes all the aforementioned problems. However, now,
|
||||
string aliases semantically equivalent but syntactically different (e.g.,
|
||||
"A", "\x41", "\101") are considered to be different.
|
||||
|
||||
*** Crash when generating IELR
|
||||
|
||||
An old, well hidden, bug in the generation of IELR parsers was fixed.
|
||||
|
||||
|
||||
* Noteworthy changes in release 3.6.4 (2020-06-15) [stable]
|
||||
|
||||
** Bug fixes
|
||||
|
||||
In glr.cc some internal macros leaked in the user's code, and could damage
|
||||
access to the token kinds.
|
||||
|
||||
|
||||
* Noteworthy changes in release 3.6.3 (2020-06-03) [stable]
|
||||
|
||||
** Bug fixes
|
||||
|
||||
Incorrect comments in the generated parsers.
|
||||
|
||||
Warnings in push parsers (yacc.c).
|
||||
|
||||
Incorrect display of gotos in LAC traces (lalr1.cc).
|
||||
|
||||
|
||||
* Noteworthy changes in release 3.6.2 (2020-05-17) [stable]
|
||||
|
||||
** Bug fixes
|
||||
|
||||
Some tests were fixed.
|
||||
|
||||
When token aliases contain comment delimiters:
|
||||
|
||||
%token FOO "/* foo */"
|
||||
|
||||
bison used to emit "nested" comments, which is invalid C.
|
||||
|
||||
|
||||
* Noteworthy changes in release 3.6.1 (2020-05-10) [stable]
|
||||
|
||||
** Bug fixes
|
||||
|
||||
Restored ANSI-C compliance in yacc.c.
|
||||
|
||||
GNU readline portability issues.
|
||||
|
||||
In C++, yy::parser::symbol_name is now a public member, as was intended.
|
||||
|
||||
** New features
|
||||
|
||||
In C++, yy::parser::symbol_type now has a public name() member function.
|
||||
|
||||
|
||||
* Noteworthy changes in release 3.6 (2020-05-08) [stable]
|
||||
|
||||
** Backward incompatible changes
|
||||
|
||||
@@ -134,6 +301,18 @@ GNU Bison NEWS
|
||||
It makes little sense to use this feature without enabling LAC (lookahead
|
||||
correction).
|
||||
|
||||
*** Returning the error token
|
||||
|
||||
When the scanner returns an invalid token or the undefined token
|
||||
(YYUNDEF), the parser generates an error message and enters error
|
||||
recovery. Because of that error message, most scanners that find lexical
|
||||
errors generate an error message, and then ignore the invalid input
|
||||
without entering the error-recovery.
|
||||
|
||||
The scanners may now return YYerror, the error token, to enter the
|
||||
error-recovery mode without triggering an additional error message. See
|
||||
the bistromathic for an example.
|
||||
|
||||
*** Deep overhaul of the symbol and token kinds
|
||||
|
||||
To avoid the confusion with types in programming languages, we now refer
|
||||
@@ -239,6 +418,7 @@ GNU Bison NEWS
|
||||
autocompletion on the existing variables, rather than of the word
|
||||
"variable".
|
||||
|
||||
|
||||
* Noteworthy changes in release 3.5.4 (2020-04-05) [stable]
|
||||
|
||||
** WARNING: Future backward-incompatibilities!
|
||||
@@ -259,6 +439,7 @@ GNU Bison NEWS
|
||||
|
||||
Fix api.token.raw support in Java.
|
||||
|
||||
|
||||
* Noteworthy changes in release 3.5.3 (2020-03-08) [stable]
|
||||
|
||||
** Bug fixes
|
||||
@@ -269,6 +450,7 @@ GNU Bison NEWS
|
||||
|
||||
Several unlikely crashes found by fuzzing have been fixed.
|
||||
|
||||
|
||||
* Noteworthy changes in release 3.5.2 (2020-02-13) [stable]
|
||||
|
||||
** Bug fixes
|
||||
@@ -278,6 +460,7 @@ GNU Bison NEWS
|
||||
The lalr1.cc skeleton properly rejects unsupported values for parse.lac
|
||||
(as yacc.c does).
|
||||
|
||||
|
||||
* Noteworthy changes in release 3.5.1 (2020-01-19) [stable]
|
||||
|
||||
** Bug fixes
|
||||
@@ -286,6 +469,7 @@ GNU Bison NEWS
|
||||
|
||||
Fix compiler warnings.
|
||||
|
||||
|
||||
* Noteworthy changes in release 3.5 (2019-12-11) [stable]
|
||||
|
||||
** Backward incompatible changes
|
||||
@@ -493,6 +677,7 @@ GNU Bison NEWS
|
||||
|
||||
In Java, %define api.prefix was ignored. It now behaves as expected.
|
||||
|
||||
|
||||
* Noteworthy changes in release 3.4.2 (2019-09-12) [stable]
|
||||
|
||||
** Bug fixes
|
||||
@@ -510,12 +695,14 @@ GNU Bison NEWS
|
||||
When lone carriage-return characters appeared in the input file,
|
||||
diagnostics could hang forever.
|
||||
|
||||
|
||||
* Noteworthy changes in release 3.4.1 (2019-05-22) [stable]
|
||||
|
||||
** Bug fixes
|
||||
|
||||
Portability fixes.
|
||||
|
||||
|
||||
* Noteworthy changes in release 3.4 (2019-05-19) [stable]
|
||||
|
||||
** Deprecated features
|
||||
@@ -656,6 +843,7 @@ GNU Bison NEWS
|
||||
system, in December 1987. See the NEWS of Bison 3.3 for the previous
|
||||
oldest bug.
|
||||
|
||||
|
||||
* Noteworthy changes in release 3.3.2 (2019-02-03) [stable]
|
||||
|
||||
** Bug fixes
|
||||
@@ -663,6 +851,7 @@ GNU Bison NEWS
|
||||
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
|
||||
@@ -670,6 +859,7 @@ GNU Bison NEWS
|
||||
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
|
||||
@@ -812,11 +1002,11 @@ GNU Bison NEWS
|
||||
|
||||
...
|
||||
|
||||
Looking at the output from -v, one can see that the shift-reduce conflict
|
||||
Looking at the output from -v, one can see that the shift/reduce conflict
|
||||
here is due to the fact that the parser does not know whether to reduce
|
||||
arguments to argument_list until it sees the token _after_ the following
|
||||
','. By marking the rule with %expect 1 (because there is a conflict in
|
||||
one state), we document the source of the 1 overall shift-reduce conflict.
|
||||
one state), we document the source of the 1 overall shift/reduce conflict.
|
||||
|
||||
In GLR parsers, we can use %expect-rr in a rule for reduce/reduce
|
||||
conflicts. In this case, we mark each of the conflicting rules. For
|
||||
@@ -931,7 +1121,7 @@ GNU Bison NEWS
|
||||
|
||||
** Bug fixes
|
||||
|
||||
*** Incorrect number of reduce-reduce conflicts
|
||||
*** Incorrect number of reduce/reduce conflicts
|
||||
|
||||
On a grammar such as
|
||||
|
||||
@@ -985,6 +1175,7 @@ GNU Bison NEWS
|
||||
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]
|
||||
|
||||
** Bug fixes
|
||||
@@ -993,6 +1184,7 @@ GNU Bison NEWS
|
||||
|
||||
Always provide a copy constructor for symbol_type, even in modern C++.
|
||||
|
||||
|
||||
* Noteworthy changes in release 3.2.3 (2018-12-18) [stable]
|
||||
|
||||
** Bug fixes
|
||||
@@ -1000,12 +1192,14 @@ GNU Bison NEWS
|
||||
Properly support token constructors in C++ with types that include commas
|
||||
(e.g., std::pair<int, int>). A regression introduced in Bison 3.2.
|
||||
|
||||
|
||||
* Noteworthy changes in release 3.2.2 (2018-11-21) [stable]
|
||||
|
||||
** Bug fixes
|
||||
|
||||
C++ portability issues.
|
||||
|
||||
|
||||
* Noteworthy changes in release 3.2.1 (2018-11-09) [stable]
|
||||
|
||||
** Bug fixes
|
||||
@@ -1013,6 +1207,7 @@ GNU Bison NEWS
|
||||
Several portability issues have been fixed in the build system, in the
|
||||
test suite, and in the generated parsers in C++.
|
||||
|
||||
|
||||
* Noteworthy changes in release 3.2 (2018-10-29) [stable]
|
||||
|
||||
** Backward incompatible changes
|
||||
@@ -1179,6 +1374,7 @@ GNU Bison NEWS
|
||||
|
||||
Portability/warning issues with Flex.
|
||||
|
||||
|
||||
* Noteworthy changes in release 3.1 (2018-08-27) [stable]
|
||||
|
||||
** Backward incompatible changes
|
||||
@@ -1319,6 +1515,7 @@ GNU Bison NEWS
|
||||
Useless code was removed from C++ parsers, and some of the generated
|
||||
constructors are more 'natural'.
|
||||
|
||||
|
||||
* Noteworthy changes in release 3.0.5 (2018-05-27) [stable]
|
||||
|
||||
** Bug fixes
|
||||
@@ -1349,6 +1546,7 @@ GNU Bison NEWS
|
||||
|
||||
On some platforms, some Java and/or C++ tests were failing.
|
||||
|
||||
|
||||
* Noteworthy changes in release 3.0.4 (2015-01-23) [stable]
|
||||
|
||||
** Bug fixes
|
||||
@@ -1361,6 +1559,7 @@ GNU Bison NEWS
|
||||
|
||||
Several portability issues in tests were fixed.
|
||||
|
||||
|
||||
* Noteworthy changes in release 3.0.3 (2015-01-15) [stable]
|
||||
|
||||
** Bug fixes
|
||||
@@ -1417,6 +1616,7 @@ GNU Bison NEWS
|
||||
- calc++
|
||||
a calculator in C++ using variant support and token constructors.
|
||||
|
||||
|
||||
* Noteworthy changes in release 3.0.2 (2013-12-05) [stable]
|
||||
|
||||
** Bug fixes
|
||||
@@ -1441,6 +1641,7 @@ GNU Bison NEWS
|
||||
When C++ variant support is enabled, an error triggered via YYERROR, but
|
||||
not caught via error recovery, resulted in a double deletion.
|
||||
|
||||
|
||||
* Noteworthy changes in release 3.0.1 (2013-11-12) [stable]
|
||||
|
||||
** Bug fixes
|
||||
@@ -1472,6 +1673,7 @@ GNU Bison NEWS
|
||||
|
||||
Bugs and portability issues.
|
||||
|
||||
|
||||
* Noteworthy changes in release 3.0 (2013-07-25) [stable]
|
||||
|
||||
** WARNING: Future backward-incompatibilities!
|
||||
@@ -1842,7 +2044,7 @@ GNU Bison NEWS
|
||||
%error-verbose directive is deprecated in favor of "%define parse.error
|
||||
verbose".
|
||||
|
||||
** Renamed %define variables
|
||||
** Deprecated %define variable names
|
||||
|
||||
The following variables have been renamed for consistency. Backward
|
||||
compatibility is ensured, but upgrading is recommended.
|
||||
@@ -2068,6 +2270,7 @@ GNU Bison NEWS
|
||||
There are operator- and operator-= for 'location'. Negative line/column
|
||||
increments can no longer underflow the resulting value.
|
||||
|
||||
|
||||
* Noteworthy changes in release 2.7.1 (2013-04-15) [stable]
|
||||
|
||||
** Bug fixes
|
||||
@@ -2078,6 +2281,7 @@ GNU Bison NEWS
|
||||
|
||||
*** Fix some compiler warnings (lalr1.cc)
|
||||
|
||||
|
||||
* Noteworthy changes in release 2.7 (2012-12-12) [stable]
|
||||
|
||||
** Bug fixes
|
||||
@@ -2202,6 +2406,7 @@ GNU Bison NEWS
|
||||
|
||||
The translation of midrule actions is now described.
|
||||
|
||||
|
||||
* Noteworthy changes in release 2.6.5 (2012-11-07) [stable]
|
||||
|
||||
We consider compiler warnings about Bison generated parsers to be bugs.
|
||||
@@ -2221,10 +2426,12 @@ GNU Bison NEWS
|
||||
When possible, yylloc is correctly initialized before calling yylex. It
|
||||
is no longer necessary to initialize it in the %initial-action.
|
||||
|
||||
|
||||
* Noteworthy changes in release 2.6.4 (2012-10-23) [stable]
|
||||
|
||||
Bison 2.6.3's --version was incorrect. This release fixes this issue.
|
||||
|
||||
|
||||
* Noteworthy changes in release 2.6.3 (2012-10-22) [stable]
|
||||
|
||||
** Bug fixes
|
||||
@@ -2269,6 +2476,7 @@ GNU Bison NEWS
|
||||
"function declared 'noreturn' should not return") have also been
|
||||
addressed.
|
||||
|
||||
|
||||
* Noteworthy changes in release 2.6.2 (2012-08-03) [stable]
|
||||
|
||||
** Bug fixes
|
||||
@@ -2285,6 +2493,7 @@ GNU Bison NEWS
|
||||
|
||||
The generated files no longer end (nor start) with empty lines.
|
||||
|
||||
|
||||
* Noteworthy changes in release 2.6.1 (2012-07-30) [stable]
|
||||
|
||||
Bison no longer executes user-specified M4 code when processing a grammar.
|
||||
@@ -2323,6 +2532,7 @@ GNU Bison NEWS
|
||||
will display two values for each typed and untyped symbol (provided
|
||||
that YYSTYPE has both "ival" and "fval" fields).
|
||||
|
||||
|
||||
* Noteworthy changes in release 2.6 (2012-07-19) [stable]
|
||||
|
||||
** Future changes
|
||||
@@ -2456,6 +2666,7 @@ GNU Bison NEWS
|
||||
|
||||
#endif /* !BAR_FOO_H */ #endif /* !BAR_FOO_H */
|
||||
|
||||
|
||||
* Noteworthy changes in release 2.5.1 (2012-06-05) [stable]
|
||||
|
||||
** Future changes:
|
||||
@@ -2553,6 +2764,7 @@ GNU Bison NEWS
|
||||
Running "make install-pdf" (or -dvi, -html, -info, and -ps) no longer
|
||||
halts in the middle of its course.
|
||||
|
||||
|
||||
* Noteworthy changes in release 2.5 (2011-05-14)
|
||||
|
||||
** Grammar symbol names can now contain non-initial dashes:
|
||||
@@ -2908,6 +3120,7 @@ GNU Bison NEWS
|
||||
|
||||
This bug has been fixed.
|
||||
|
||||
|
||||
* Noteworthy changes in release 2.4.3 (2010-08-05)
|
||||
|
||||
** Bison now obeys -Werror and --warnings=error for warnings about
|
||||
@@ -2928,6 +3141,7 @@ GNU Bison NEWS
|
||||
|
||||
** Minor documentation fixes.
|
||||
|
||||
|
||||
* Noteworthy changes in release 2.4.2 (2010-03-20)
|
||||
|
||||
** Some portability problems that resulted in failures and livelocks
|
||||
@@ -3022,6 +3236,7 @@ GNU Bison NEWS
|
||||
message translations were not installed although supported by the
|
||||
host system.
|
||||
|
||||
|
||||
* Noteworthy changes in release 2.4.1 (2008-12-11)
|
||||
|
||||
** In the GLR defines file, unexpanded M4 macros in the yylval and yylloc
|
||||
@@ -3047,6 +3262,7 @@ GNU Bison NEWS
|
||||
|
||||
** A few minor improvements to the Bison manual.
|
||||
|
||||
|
||||
* Noteworthy changes in release 2.4 (2008-11-02)
|
||||
|
||||
** %language is an experimental feature.
|
||||
@@ -3062,6 +3278,7 @@ GNU Bison NEWS
|
||||
** Several bugs in the C++ skeleton and the experimental Java skeleton have been
|
||||
fixed.
|
||||
|
||||
|
||||
* Noteworthy changes in release 2.3b (2008-05-27)
|
||||
|
||||
** The quotes around NAME that used to be required in the following directive
|
||||
@@ -3248,6 +3465,7 @@ GNU Bison NEWS
|
||||
** The nonfunctional --no-parser, -n, and %no-parser options have been
|
||||
completely removed from Bison.
|
||||
|
||||
|
||||
* Noteworthy changes in release 2.3a (2006-09-13)
|
||||
|
||||
** Instead of %union, you can define and use your own union type
|
||||
@@ -3362,6 +3580,7 @@ GNU Bison NEWS
|
||||
The old spelling still works, but is not documented and may be removed
|
||||
in a future release.
|
||||
|
||||
|
||||
* Noteworthy changes in release 2.3 (2006-06-05)
|
||||
|
||||
** GLR grammars should now use "YYRECOVERING ()" instead of "YYRECOVERING",
|
||||
@@ -3370,6 +3589,7 @@ GNU Bison NEWS
|
||||
** It is now documented that any definition of YYSTYPE or YYLTYPE should
|
||||
be to a type name that does not contain parentheses or brackets.
|
||||
|
||||
|
||||
* Noteworthy changes in release 2.2 (2006-05-19)
|
||||
|
||||
** The distribution terms for all Bison-generated parsers now permit
|
||||
@@ -3452,6 +3672,7 @@ GNU Bison NEWS
|
||||
|
||||
** DJGPP support added.
|
||||
|
||||
|
||||
* Noteworthy changes in release 2.1 (2005-09-16)
|
||||
|
||||
** The C++ lalr1.cc skeleton supports %lex-param.
|
||||
@@ -3478,6 +3699,7 @@ GNU Bison NEWS
|
||||
print 'syntax error, unexpected number' instead of 'syntax error,
|
||||
unexpected "number"'.
|
||||
|
||||
|
||||
* Noteworthy changes in release 2.0 (2004-12-25)
|
||||
|
||||
** Possibly-incompatible changes
|
||||
@@ -3541,6 +3763,7 @@ GNU Bison NEWS
|
||||
|
||||
- Semicolons are now allowed before "|" in grammar rules, as POSIX requires.
|
||||
|
||||
|
||||
* Noteworthy changes in release 1.875 (2003-01-01)
|
||||
|
||||
** The documentation license has been upgraded to version 1.2
|
||||
@@ -3661,6 +3884,7 @@ GNU Bison NEWS
|
||||
ago, but nobody noticed until we recently asked someone to try
|
||||
building Bison with a K&R C compiler.
|
||||
|
||||
|
||||
* Noteworthy changes in release 1.75 (2002-10-14)
|
||||
|
||||
** Bison should now work on 64-bit hosts.
|
||||
@@ -3692,6 +3916,7 @@ GNU Bison NEWS
|
||||
was incorrectly rejected: $1 is defined in the second midrule
|
||||
action, and is equal to the $$ of the first midrule action.
|
||||
|
||||
|
||||
* Noteworthy changes in release 1.50 (2002-10-04)
|
||||
|
||||
** GLR parsing
|
||||
@@ -3836,6 +4061,7 @@ GNU Bison NEWS
|
||||
|
||||
** GNU M4 is now required when using Bison.
|
||||
|
||||
|
||||
* Noteworthy changes in release 1.35 (2002-03-25)
|
||||
|
||||
** C Skeleton
|
||||
@@ -3851,6 +4077,7 @@ GNU Bison NEWS
|
||||
This kludge also addresses some C++ problems when the stack was
|
||||
extended.
|
||||
|
||||
|
||||
* Noteworthy changes in release 1.34 (2002-03-12)
|
||||
|
||||
** File name clashes are detected
|
||||
@@ -3871,6 +4098,7 @@ GNU Bison NEWS
|
||||
|
||||
** Fix test suite portability problems.
|
||||
|
||||
|
||||
* Noteworthy changes in release 1.33 (2002-02-07)
|
||||
|
||||
** Fix C++ issues
|
||||
@@ -3880,6 +4108,7 @@ GNU Bison NEWS
|
||||
** Catch invalid @n
|
||||
As is done with $n.
|
||||
|
||||
|
||||
* Noteworthy changes in release 1.32 (2002-01-23)
|
||||
|
||||
** Fix Yacc output file names
|
||||
@@ -3888,6 +4117,7 @@ GNU Bison NEWS
|
||||
|
||||
** Italian, Dutch translations
|
||||
|
||||
|
||||
* Noteworthy changes in release 1.31 (2002-01-14)
|
||||
|
||||
** Many Bug Fixes
|
||||
@@ -3975,6 +4205,7 @@ GNU Bison NEWS
|
||||
** --output
|
||||
New, aliasing "--output-file".
|
||||
|
||||
|
||||
* Noteworthy changes in release 1.30 (2001-10-26)
|
||||
|
||||
** "--defines" and "--graph" have now an optional argument which is the
|
||||
@@ -3986,6 +4217,7 @@ GNU Bison NEWS
|
||||
|
||||
** Portability fixes.
|
||||
|
||||
|
||||
* Noteworthy changes in release 1.29 (2001-09-07)
|
||||
|
||||
** The output file does not define const, as this caused problems when used
|
||||
@@ -4021,6 +4253,7 @@ GNU Bison NEWS
|
||||
** @$
|
||||
Automatic location tracking.
|
||||
|
||||
|
||||
* Noteworthy changes in release 1.28 (1999-07-06)
|
||||
|
||||
** Should compile better now with K&R compilers.
|
||||
@@ -4031,11 +4264,13 @@ GNU Bison NEWS
|
||||
|
||||
** There is now a FAQ.
|
||||
|
||||
|
||||
* Noteworthy changes in release 1.27
|
||||
|
||||
** The make rule which prevented bison.simple from being created on
|
||||
some systems has been fixed.
|
||||
|
||||
|
||||
* Noteworthy changes in release 1.26
|
||||
|
||||
** Bison now uses Automake.
|
||||
@@ -4053,6 +4288,7 @@ GNU Bison NEWS
|
||||
** Generated parsers should now work even on operating systems which do
|
||||
not provide alloca().
|
||||
|
||||
|
||||
* Noteworthy changes in release 1.25 (1995-10-16)
|
||||
|
||||
** Errors in the input grammar are not fatal; Bison keeps reading
|
||||
@@ -4078,6 +4314,7 @@ the parser engine; a project can now use its own parser engine.
|
||||
The actions go into a separate file called NAME.act, in the form of
|
||||
a switch statement body.
|
||||
|
||||
|
||||
* Noteworthy changes in release 1.23
|
||||
|
||||
The user can define YYPARSE_PARAM as the name of an argument to be
|
||||
@@ -4087,72 +4324,69 @@ by casting it to the proper pointer type.
|
||||
|
||||
Line numbers in output file corrected.
|
||||
|
||||
|
||||
* Noteworthy changes in release 1.22
|
||||
|
||||
--help option added.
|
||||
|
||||
|
||||
* Noteworthy changes in release 1.20
|
||||
|
||||
Output file does not redefine const for C++.
|
||||
|
||||
-----
|
||||
|
||||
Copyright (C) 1995-2015, 2018-2020 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of Bison, the GNU Parser Generator.
|
||||
|
||||
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/>.
|
||||
|
||||
LocalWords: yacc YYBACKUP glr GCC lalr ArrayIndexOutOfBoundsException nullptr
|
||||
LocalWords: cplusplus liby rpl fprintf mfcalc Wyacc stmt cond expr mk sym lr
|
||||
LocalWords: IELR ielr Lookahead YYERROR nonassoc LALR's api lookaheads yychar
|
||||
LocalWords: destructor lookahead YYRHSLOC YYLLOC Rhs ifndef YYFAIL cpp sr rr
|
||||
LocalWords: preprocessor initializer Wno Wnone Werror FreeBSD prec livelocks
|
||||
LocalWords: Solaris AIX UX RHEL Tru LHS gcc's Wundef YYENABLE NLS YYLTYPE VCG
|
||||
LocalWords: yyerror cpp's Wunused yylval yylloc prepend yyparse yylex yypush
|
||||
LocalWords: Graphviz xml nonterminals midrule destructor's YYSTYPE typedef ly
|
||||
LocalWords: CHR chr printf stdout namespace preprocessing enum pre include's
|
||||
LocalWords: YYRECOVERING nonfree destructors YYABORT YYACCEPT params enums de
|
||||
LocalWords: struct yystype DJGPP lex param Haible NUM alloca YYSTACK NUL goto
|
||||
LocalWords: YYMAXDEPTH Unescaped UCNs YYLTYPE's yyltype typedefs inline Yaccs
|
||||
LocalWords: Heriyanto Reenable dprec Hilfinger Eggert MYEOF Folle Menezes EOF
|
||||
LocalWords: Lackovic define's itemset Groff Gettext malloc NEWS'ed YYDEBUG YY
|
||||
LocalWords: namespaces strerror const autoconfiguration Dconst Autoconf's FDL
|
||||
LocalWords: Automake TMPDIR LESSEQ ylwrap endif yydebug YYTOKEN YYLSP ival hh
|
||||
LocalWords: extern YYTOKENTYPE TOKENTYPE yytokentype tokentype STYPE lval pdf
|
||||
LocalWords: lang yyoutput dvi html ps POSIX lvalp llocp Wother nterm arg init
|
||||
LocalWords: TOK calc yyo fval Wconflicts parsers yystackp yyval yynerrs
|
||||
LocalWords: Théophile Ranquet Santet fno fnone stype associativity Tolmer
|
||||
LocalWords: Wprecedence Rassoul Wempty Paolo Bonzini parser's Michiel loc
|
||||
LocalWords: redeclaration sval fcaret reentrant XSLT xsl Wmaybe yyvsp Tedi
|
||||
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 bw
|
||||
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 backend Teoh
|
||||
LocalWords: YYPRINT Mangold Bonzini's Wdangling exVal baz checkable gcc
|
||||
LocalWords: fsanitize Vogelsgesang lis redeclared stdint automata yytname
|
||||
LocalWords: yysymbol yytnamerr yyreport ctx ARGMAX yysyntax stderr LPAREN
|
||||
LocalWords: symrec yypcontext TOKENMAX yyexpected YYEMPTY yypstate YYEOF
|
||||
LocalWords: autocompletion bistromathic submessages Cayuela lexcalc hoc
|
||||
LocalWords: yytoken YYUNDEF YYerror
|
||||
LocalWords: yacc YYBACKUP glr GCC lalr ArrayIndexOutOfBoundsException nullptr
|
||||
LocalWords: cplusplus liby rpl fprintf mfcalc Wyacc stmt cond expr mk sym lr
|
||||
LocalWords: IELR ielr Lookahead YYERROR nonassoc LALR's api lookaheads yychar
|
||||
LocalWords: destructor lookahead YYRHSLOC YYLLOC Rhs ifndef YYFAIL cpp sr rr
|
||||
LocalWords: preprocessor initializer Wno Wnone Werror FreeBSD prec livelocks
|
||||
LocalWords: Solaris AIX UX RHEL Tru LHS gcc's Wundef YYENABLE NLS YYLTYPE VCG
|
||||
LocalWords: yyerror cpp's Wunused yylval yylloc prepend yyparse yylex yypush
|
||||
LocalWords: Graphviz xml nonterminals midrule destructor's YYSTYPE typedef ly
|
||||
LocalWords: CHR chr printf stdout namespace preprocessing enum pre include's
|
||||
LocalWords: YYRECOVERING nonfree destructors YYABORT YYACCEPT params enums de
|
||||
LocalWords: struct yystype DJGPP lex param Haible NUM alloca YYSTACK NUL goto
|
||||
LocalWords: YYMAXDEPTH Unescaped UCNs YYLTYPE's yyltype typedefs inline Yaccs
|
||||
LocalWords: Heriyanto Reenable dprec Hilfinger Eggert MYEOF Folle Menezes EOF
|
||||
LocalWords: Lackovic define's itemset Groff Gettext malloc NEWS'ed YYDEBUG YY
|
||||
LocalWords: namespaces strerror const autoconfiguration Dconst Autoconf's FDL
|
||||
LocalWords: Automake TMPDIR LESSEQ ylwrap endif yydebug YYTOKEN YYLSP ival hh
|
||||
LocalWords: extern YYTOKENTYPE TOKENTYPE yytokentype tokentype STYPE lval pdf
|
||||
LocalWords: lang yyoutput dvi html ps POSIX lvalp llocp Wother nterm arg init
|
||||
LocalWords: TOK calc yyo fval Wconflicts parsers yystackp yyval yynerrs
|
||||
LocalWords: Théophile Ranquet Santet fno fnone stype associativity Tolmer
|
||||
LocalWords: Wprecedence Rassoul Wempty Paolo Bonzini parser's Michiel loc
|
||||
LocalWords: redeclaration sval fcaret reentrant XSLT xsl Wmaybe yyvsp Tedi
|
||||
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 bw
|
||||
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 backend Teoh
|
||||
LocalWords: YYPRINT Mangold Bonzini's Wdangling exVal baz checkable gcc
|
||||
LocalWords: fsanitize Vogelsgesang lis redeclared stdint automata yytname
|
||||
LocalWords: yysymbol yytnamerr yyreport ctx ARGMAX yysyntax stderr LPAREN
|
||||
LocalWords: symrec yypcontext TOKENMAX yyexpected YYEMPTY yypstate YYEOF
|
||||
LocalWords: autocompletion bistromathic submessages Cayuela lexcalc hoc
|
||||
LocalWords: yytoken YYUNDEF YYerror basename Automake's UTF ifdef ffile
|
||||
LocalWords: gotos readline Imbimbo Wcounterexamples
|
||||
|
||||
Local Variables:
|
||||
ispell-dictionary: "american"
|
||||
mode: outline
|
||||
fill-column: 76
|
||||
End:
|
||||
|
||||
Copyright (C) 1995-2015, 2018-2020 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of Bison, the GNU Parser Generator.
|
||||
|
||||
Permission is granted to copy, distribute and/or modify this document
|
||||
under the terms of the GNU Free Documentation License, Version 1.3 or
|
||||
any later version published by the Free Software Foundation; with no
|
||||
Invariant Sections, with no Front-Cover Texts, and with no Back-Cover
|
||||
Texts. A copy of the license is included in the "GNU Free
|
||||
Documentation License" file as part of this distribution.
|
||||
|
||||
@@ -17,17 +17,18 @@ GNU Bison's home page is https://gnu.org/software/bison/.
|
||||
|
||||
# Installation
|
||||
## Build from git
|
||||
Here are basic installation instructions for a repository checkout:
|
||||
The [README-hacking.md file](README-hacking.md) is about building, modifying
|
||||
and checking Bison. See its "Working from the Repository" section to build
|
||||
Bison from the git repo. Roughly, run:
|
||||
|
||||
$ git submodule update --init
|
||||
$ ./bootstrap
|
||||
|
||||
then proceed with the usual `configure && make` steps.
|
||||
|
||||
The file README-hacking.md is about building, modifying and checking Bison.
|
||||
|
||||
## Build from tarball
|
||||
See the file INSTALL for generic compilation and installation instructions.
|
||||
See the [INSTALL file](INSTALL] for generic compilation and installation
|
||||
instructions.
|
||||
|
||||
Bison requires GNU m4 1.4.6 or later. See
|
||||
https://ftp.gnu.org/gnu/m4/m4-1.4.6.tar.gz.
|
||||
@@ -100,6 +101,16 @@ that the range specifies every single year in that closed interval.
|
||||
|
||||
<!--
|
||||
|
||||
LocalWords: parsers ngettext Texinfo pdf html YYYY ZZZZ ispell american md
|
||||
LocalWords: MERCHANTABILITY GLR LALR IELR submodule init README src bw
|
||||
LocalWords: Relocatability symlinks symlink
|
||||
|
||||
Local Variables:
|
||||
mode: markdown
|
||||
fill-column: 76
|
||||
ispell-dictionary: "american"
|
||||
End:
|
||||
|
||||
Copyright (C) 1992, 1998-1999, 2003-2005, 2008-2015, 2018-2020 Free
|
||||
Software Foundation, Inc.
|
||||
|
||||
@@ -112,14 +123,4 @@ Invariant Sections, with no Front-Cover Texts, and with no Back-Cover
|
||||
Texts. A copy of the license is included in the "GNU Free
|
||||
Documentation License" file as part of this distribution.
|
||||
|
||||
Local Variables:
|
||||
mode: markdown
|
||||
fill-column: 76
|
||||
ispell-dictionary: "american"
|
||||
End:
|
||||
|
||||
LocalWords: parsers ngettext Texinfo pdf html YYYY ZZZZ ispell american md
|
||||
LocalWords: MERCHANTABILITY GLR LALR IELR submodule init README src bw
|
||||
LocalWords: Relocatability symlinks symlink
|
||||
|
||||
-->
|
||||
|
||||
+232
-153
@@ -5,151 +5,6 @@ Everything related to the development of Bison is on Savannah:
|
||||
http://savannah.gnu.org/projects/bison/.
|
||||
|
||||
|
||||
Administrivia
|
||||
=============
|
||||
|
||||
## If you incorporate a change from somebody on the net:
|
||||
First, if it is a large change, you must make sure they have signed the
|
||||
appropriate paperwork. Second, be sure to add their name and email address
|
||||
to THANKS.
|
||||
|
||||
## If a change fixes a test, mention the test in the commit message.
|
||||
|
||||
## Bug reports
|
||||
If somebody reports a new bug, mention his name in the commit message and in
|
||||
the test case you write. Put him into THANKS.
|
||||
|
||||
The correct response to most actual bugs is to write a new test case which
|
||||
demonstrates the bug. Then fix the bug, re-run the test suite, and check
|
||||
everything in.
|
||||
|
||||
|
||||
|
||||
Hacking
|
||||
=======
|
||||
|
||||
## Visible Changes
|
||||
Which include serious bug fixes, must be mentioned in NEWS.
|
||||
|
||||
## Translations
|
||||
Only user visible strings are to be translated: error messages, bits of the
|
||||
.output file etc. This excludes impossible error messages (comparable to
|
||||
assert/abort), and all the --trace output which is meant for the maintainers
|
||||
only.
|
||||
|
||||
## Syntax highlighting
|
||||
It's quite nice to be in C++ mode when editing lalr1.cc for instance.
|
||||
However tools such as Emacs will be fooled by the fact that braces and
|
||||
parens do not nest, as in `[[}]]`. As a consequence you might be misguided
|
||||
by its visual pairing to parens. The m4-mode is safer. Unfortunately the
|
||||
m4-mode is also fooled by `#` which is sees as a comment, stops pairing with
|
||||
parens/brackets that are inside...
|
||||
|
||||
## Coding Style
|
||||
Do not add horizontal tab characters to any file in Bison's repository
|
||||
except where required. For example, do not use tabs to format C code.
|
||||
However, make files, ChangeLog, and some regular expressions require tabs.
|
||||
Also, test cases might need to contain tabs to check that Bison properly
|
||||
processes tabs in its input.
|
||||
|
||||
Prefer "res" as the name of the local variable that will be "return"ed by
|
||||
the function.
|
||||
|
||||
### Bison
|
||||
Follow the GNU Coding Standards.
|
||||
|
||||
Don't reinvent the wheel: we use gnulib, which features many components.
|
||||
Actually, Bison has legacy code that we should replace with gnulib modules
|
||||
(e.g., many ad hoc implementations of lists).
|
||||
|
||||
### Skeletons
|
||||
We try to use the "typical" coding style for each language.
|
||||
|
||||
#### CPP
|
||||
We indent the CPP directives this way:
|
||||
|
||||
```
|
||||
#if FOO
|
||||
# if BAR
|
||||
# define BAZ
|
||||
# endif
|
||||
#endif
|
||||
```
|
||||
|
||||
Don't indent with leading spaces in the skeletons (it's ok in the grammar
|
||||
files though, e.g., in `%code {...}` blocks).
|
||||
|
||||
On occasions, use `cppi -c` to see where we stand. We don't aim at full
|
||||
correctness: depending `-d`, some bits can be in the *.c file, or the *.h
|
||||
file within the double-inclusion cpp-guards. In that case, favor the case
|
||||
of the *.h file, but don't waste time on this.
|
||||
|
||||
Don't hesitate to leave a comment on the `#endif` (e.g., `#endif /* FOO
|
||||
*/`), especially for long blocks.
|
||||
|
||||
There is no conistency on `! defined` vs. `!defined`. The day gnulib
|
||||
decides, we'll follow them.
|
||||
|
||||
#### C/C++
|
||||
Follow the GNU Coding Standards.
|
||||
|
||||
The `glr.c` skeleton was implemented with `camlCase`. We are migrating it
|
||||
to `snake_case`. Because we are standardizing the code, it is currently
|
||||
inconsistent.
|
||||
|
||||
Use `YYFOO` and `yyfoo` for entities that are exposed to the user. They are
|
||||
part of our contract with the users wrt backward compatibility.
|
||||
|
||||
Use `YY_FOO` and `yy_foo` for private matters. Users should not use them,
|
||||
we are free to change them without fear of backward compatibility issues.
|
||||
|
||||
Use `*_t` for types, especially for `yy*_t` in which case we shouldn't worry
|
||||
about the C standard introducing such a name.
|
||||
|
||||
#### C++
|
||||
Follow the C++ Core Guidelines
|
||||
(http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines). The Google
|
||||
ones may be interesting too
|
||||
(https://google.github.io/styleguide/cppguide.html).
|
||||
|
||||
Our enumerators, such as the kinds (symbol and token kinds), should be lower
|
||||
case, but it was too late to follow that track for token kinds, and symbol
|
||||
kind enumerators are made to be consistent with them.
|
||||
|
||||
Use `*_type` for type aliases. Use `foo_get()` and `foo_set(v)` for
|
||||
accessors, or simply `foo()` and `foo(v)`.
|
||||
|
||||
Use the `yy` prefix for private stuff, but there's no need for it in the
|
||||
public API. The `yy` prefix is already taken care of via the namespace.
|
||||
|
||||
#### Java
|
||||
We follow https://www.oracle.com/technetwork/java/codeconventions-150003.pdf
|
||||
and https://google.github.io/styleguide/javaguide.html. Unfortunately at
|
||||
some point some GNU Coding Style was installed in Java, but it's an error.
|
||||
So we should for instance stop putting spaces in function calls. Because we
|
||||
are standardizing the code, it is currently inconsistent.
|
||||
|
||||
Use a 2-space indentation (Google) rather than 4 (Oracle).
|
||||
|
||||
Don't use the "yy" prefix for public members: "getExpectedTokens", not
|
||||
"yyexpectedTokens" or "yygetExpectedTokens".
|
||||
|
||||
## Commit Messages
|
||||
Imitate the style we use. Use `git log` to get sources of inspiration.
|
||||
|
||||
If the changes have a small impact on Bison's generated parser, embed these
|
||||
changes in the commit itself. If the impact is large, first push all the
|
||||
changes except those about src/parse-gram.[ch], and then another commit
|
||||
named "regen" which is only about them.
|
||||
|
||||
## Debugging
|
||||
Bison supports tracing of its various steps, via the `--trace` option.
|
||||
Since it is not meant for the end user, it is not displayed by `bison
|
||||
--help`, nor is it documented in the manual. Instead, run `bison
|
||||
--trace=help`.
|
||||
|
||||
|
||||
|
||||
Working from the Repository
|
||||
===========================
|
||||
|
||||
@@ -168,6 +23,7 @@ tools we depend upon, including:
|
||||
- Automake <http://www.gnu.org/software/automake/>
|
||||
- Flex <http://www.gnu.org/software/flex/>
|
||||
- Gettext <http://www.gnu.org/software/gettext/>
|
||||
- Gperf <http://www.gnu.org/software/gperf/>
|
||||
- Graphviz <http://www.graphviz.org>
|
||||
- Gzip <http://www.gnu.org/software/gzip/>
|
||||
- Help2man <http://www.gnu.org/software/help2man/>
|
||||
@@ -184,7 +40,7 @@ above packages depends on your system. The following shell command should
|
||||
work for Debian-based systems such as Ubuntu:
|
||||
|
||||
sudo apt-get install \
|
||||
autoconf automake autopoint flex graphviz help2man texinfo valgrind
|
||||
autoconf automake autopoint flex gperf graphviz help2man texinfo valgrind
|
||||
|
||||
Bison is written using Bison grammars, so there are bootstrapping issues.
|
||||
The bootstrap script attempts to discover when the C code generated from the
|
||||
@@ -322,6 +178,201 @@ version, compile bison, then force it to recreate the files:
|
||||
$ make -C _build
|
||||
|
||||
|
||||
Administrivia
|
||||
=============
|
||||
|
||||
## If you incorporate a change from somebody on the net:
|
||||
First, if it is a large change, you must make sure they have signed the
|
||||
appropriate paperwork. Second, be sure to add their name and email address
|
||||
to THANKS.
|
||||
|
||||
## If a change fixes a test, mention the test in the commit message.
|
||||
|
||||
## Bug reports
|
||||
If somebody reports a new bug, mention his name in the commit message and in
|
||||
the test case you write. Put him into THANKS.
|
||||
|
||||
The correct response to most actual bugs is to write a new test case which
|
||||
demonstrates the bug. Then fix the bug, re-run the test suite, and check
|
||||
everything in.
|
||||
|
||||
|
||||
|
||||
Hacking
|
||||
=======
|
||||
|
||||
## Visible Changes
|
||||
Which include serious bug fixes, must be mentioned in NEWS.
|
||||
|
||||
## Translations
|
||||
Only user visible strings are to be translated: error messages, bits of the
|
||||
.output file etc. This excludes impossible error messages (comparable to
|
||||
assert/abort), and all the --trace output which is meant for the maintainers
|
||||
only.
|
||||
|
||||
## Vocabulary
|
||||
- "lookahead", not "look-ahead".
|
||||
- "midrule", not "mid-rule".
|
||||
- "nonterminal", not "variable" or "non-terminal" or "non terminal".
|
||||
Abbreviated as "nterm".
|
||||
- "shift/reduce" and "reduce/reduce", not "shift-reduce" or "shift reduce",
|
||||
etc.
|
||||
|
||||
## Syntax Highlighting
|
||||
It's quite nice to be in C++ mode when editing lalr1.cc for instance.
|
||||
However tools such as Emacs will be fooled by the fact that braces and
|
||||
parens do not nest, as in `[[}]]`. As a consequence you might be misguided
|
||||
by its visual pairing to parens. The m4-mode is safer. Unfortunately the
|
||||
m4-mode is also fooled by `#` which is sees as a comment, stops pairing with
|
||||
parens/brackets that are inside...
|
||||
|
||||
## Implementation Notes
|
||||
There are several places with interesting details about the implementation:
|
||||
- [Understanding C parsers generated by GNU
|
||||
Bison](https://www.cs.uic.edu/~spopuri/cparser.html) by Satya Kiran Popuri,
|
||||
is a wonderful piece of work that explains the implementation of Bison,
|
||||
- [src/gram.h](src/gram.h) documents the way the grammar is represented
|
||||
- [src/tables.h](src/tables.h) documents the generated tables
|
||||
- [data/README.md](data/README.md) contains details about the m4 implementation
|
||||
|
||||
## Coding Style
|
||||
Do not add horizontal tab characters to any file in Bison's repository
|
||||
except where required. For example, do not use tabs to format C code.
|
||||
However, make files, ChangeLog, and some regular expressions require tabs.
|
||||
Also, test cases might need to contain tabs to check that Bison properly
|
||||
processes tabs in its input.
|
||||
|
||||
Prefer `res` as the name of the local variable that will be "return"ed by
|
||||
the function.
|
||||
|
||||
In writing arithmetic comparisons, use "<" and "<=" rather than ">" and ">="
|
||||
(http://www.gelato.unsw.edu.au/archives/git/0505/4507.html).
|
||||
|
||||
### Bison
|
||||
Follow the GNU Coding Standards.
|
||||
|
||||
Don't reinvent the wheel: we use gnulib, which features many components.
|
||||
Actually, Bison has legacy code that we should replace with gnulib modules
|
||||
(e.g., many ad hoc implementations of lists).
|
||||
|
||||
#### Includes
|
||||
The `#include` directives follow an order:
|
||||
- first section for *.c files is `<config.h>`. Don't include it in header
|
||||
files
|
||||
- then, for *.c files, the corresponding *.h file
|
||||
- then possibly the `"system.h"` header
|
||||
- then the system headers.
|
||||
Consider headers from `lib/` like system headers (i.e., `#include
|
||||
<verify.h>`, not `#include "verify.h"`).
|
||||
- then headers from src/ with double quotes (`#include "getargs.h"`).
|
||||
|
||||
Keep headers sorted alphabetically in each section.
|
||||
|
||||
See also the [Header
|
||||
files](https://www.gnu.org/software/gnulib/manual/html_node/Header-files.html)
|
||||
and the [Implementation
|
||||
files](https://www.gnu.org/software/gnulib/manual/html_node/Implementation-files.html#Implementation-files)
|
||||
nodes of the gnulib documentation.
|
||||
|
||||
Some source files are in the build tree (e.g., `src/scan-gram.c` made from
|
||||
`src/scan-gram.l`). For them to find the headers from `src/`, we actually
|
||||
use `#include "src/getargs.h"` instead of `#include "getargs.h"`---that
|
||||
saves us from additional `-I` flags.
|
||||
|
||||
### Skeletons
|
||||
We try to use the "typical" coding style for each language.
|
||||
|
||||
#### CPP
|
||||
We indent the CPP directives this way:
|
||||
|
||||
```
|
||||
#if FOO
|
||||
# if BAR
|
||||
# define BAZ
|
||||
# endif
|
||||
#endif
|
||||
```
|
||||
|
||||
Don't indent with leading spaces in the skeletons (it's OK in the grammar
|
||||
files though, e.g., in `%code {...}` blocks).
|
||||
|
||||
On occasions, use `cppi -c` to see where we stand. We don't aim at full
|
||||
correctness: depending `-d`, some bits can be in the *.c file, or the *.h
|
||||
file within the double-inclusion cpp-guards. In that case, favor the case
|
||||
of the *.h file, but don't waste time on this.
|
||||
|
||||
Don't hesitate to leave a comment on the `#endif` (e.g., `#endif /* FOO
|
||||
*/`), especially for long blocks.
|
||||
|
||||
There is no consistency on `! defined` vs. `!defined`. The day gnulib
|
||||
decides, we'll follow them.
|
||||
|
||||
#### C/C++
|
||||
Follow the GNU Coding Standards.
|
||||
|
||||
The `glr.c` skeleton was implemented with `camlCase`. We are migrating it
|
||||
to `snake_case`. Because we are gradually standardizing the code, it is
|
||||
currently inconsistent.
|
||||
|
||||
Use `YYFOO` and `yyfoo` for entities that are exposed to the user. They are
|
||||
part of our contract with the users wrt backward compatibility.
|
||||
|
||||
Use `YY_FOO` and `yy_foo` for private matters. Users should not use them,
|
||||
we are free to change them without fear of backward compatibility issues.
|
||||
|
||||
Use `*_t` for types, especially for `yy*_t` in which case we shouldn't worry
|
||||
about the C standard introducing such a name.
|
||||
|
||||
#### C++
|
||||
Follow the [C++ Core
|
||||
Guidelines](http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines).
|
||||
The [Google ones](https://google.github.io/styleguide/cppguide.html) may be
|
||||
interesting too.
|
||||
|
||||
Our enumerators, such as the kinds (symbol and token kinds), should be lower
|
||||
case, but it was too late to follow that track for token kinds, and symbol
|
||||
kind enumerators are made to be consistent with them.
|
||||
|
||||
Use `*_type` for type aliases. Use `foo_get()` and `foo_set(v)` for
|
||||
accessors, or simply `foo()` and `foo(v)`.
|
||||
|
||||
Use the `yy` prefix for private stuff, but there's no need for it in the
|
||||
public API. The `yy` prefix is already taken care of via the namespace.
|
||||
|
||||
#### Java
|
||||
We follow the [Java Code
|
||||
Conventions](https://www.oracle.com/technetwork/java/codeconventions-150003.pdf)
|
||||
and [Google Java Style
|
||||
Guide](https://google.github.io/styleguide/javaguide.html). Unfortunately
|
||||
at some point some GNU Coding Style was installed in Java, but it's an
|
||||
error. So we should for instance stop putting spaces in function calls.
|
||||
Because we are standardizing the code, it is currently inconsistent.
|
||||
|
||||
Use a 2-space indentation (Google) rather than 4 (Oracle).
|
||||
|
||||
Don't use the "yy" prefix for public members: "getExpectedTokens", not
|
||||
"yyexpectedTokens" or "yygetExpectedTokens".
|
||||
|
||||
## Commit Messages
|
||||
Imitate the style we use. Use `git log` to get sources of inspiration.
|
||||
|
||||
If the changes have a small impact on Bison's generated parser, embed these
|
||||
changes in the commit itself. If the impact is large, first push all the
|
||||
changes except those about src/parse-gram.[ch], and then another commit
|
||||
named "regen" which is only about them.
|
||||
|
||||
## Debugging
|
||||
Bison supports tracing of its various steps, via the `--trace` option.
|
||||
Since it is not meant for the end user, it is not displayed by `bison
|
||||
--help`, nor is it documented in the manual. Instead, run `bison
|
||||
--trace=help`.
|
||||
|
||||
## Documentation
|
||||
Use `@option` for options and options with their argument if they have no
|
||||
space (e.g., `@option{-Dfoo=bar}`). However, use `@samp` elsewhere (e.g.,
|
||||
`@samp{-I foo}`).
|
||||
|
||||
|
||||
Test Suite
|
||||
==========
|
||||
|
||||
@@ -331,9 +382,9 @@ examples, and the main test suite.
|
||||
|
||||
### The Examples
|
||||
In examples/, there is a number of ready-to-use examples (see
|
||||
examples/README.md). These examples have small test suites run by `make
|
||||
check`. The test results are in local `*.log` files (e.g.,
|
||||
`$build/examples/c/calc/calc.log`).
|
||||
[examples/README.md](examples/README.md)). These examples have small test
|
||||
suites run by `make check`. The test results are in local `*.log` files
|
||||
(e.g., `$build/examples/c/calc/calc.log`).
|
||||
|
||||
### The Main Test Suite
|
||||
The main test suite, in tests/, is written on top of GNU Autotest, which is
|
||||
@@ -409,6 +460,31 @@ Use the `javaexec.sh` script. For instance to run the parser of test case
|
||||
|
||||
$ sh ./_build/javaexec.sh -cp ./_build/tests/testsuite.dir/504 Calc
|
||||
|
||||
## Using Sanitizers
|
||||
Address sanitizer (ASAN) and undefined-behavior sanitizer (UBSAN) are very
|
||||
useful. Here's one way to set ASAN up with GCC 10 on Mac Ports
|
||||
|
||||
1. Configure with
|
||||
|
||||
$ ./configure -C --enable-gcc-warnings \
|
||||
CPPFLAGS='-isystem /opt/local/include' \
|
||||
CC='gcc-mp-10 -fsanitize=address' \
|
||||
CFLAGS='-ggdb' \
|
||||
CXX='g++-mp-10.0 -fsanitize=address' \
|
||||
CXXFLAGS='-ggdb' \
|
||||
LDFLAGS='-L/opt/local/lib'
|
||||
|
||||
2. Compile
|
||||
|
||||
3. Generate debug symbols:
|
||||
|
||||
$ dsymutil src/bison
|
||||
|
||||
4. Run the tests with leak detection enabled
|
||||
(`ASAN_OPTIONS=detect_leaks=1`). E.g. for counterexamples:
|
||||
|
||||
$ make check-local TESTSUITEFLAGS='-j5 -k cex' ASAN_OPTIONS=detect_leaks=1
|
||||
|
||||
## make maintainer-check-valgrind
|
||||
This target uses valgrind both to check bison, and the generated parsers.
|
||||
|
||||
@@ -488,7 +564,8 @@ re-run the tests, run:
|
||||
Release Procedure
|
||||
=================
|
||||
|
||||
See README-release.
|
||||
See the [README-release file](README-release), created when the package is
|
||||
bootstrapped.
|
||||
|
||||
<!--
|
||||
|
||||
@@ -524,8 +601,10 @@ LocalWords: symlinks vti html lt POSIX Cc'ed Graphviz Texinfo autoconf jN
|
||||
LocalWords: automake autopoint graphviz texinfo PROG Wother parsers YYFOO
|
||||
LocalWords: TESTSUITEFLAGS deprec struct gnulib's getopt config ggdb yyfoo
|
||||
LocalWords: bitset fsanitize symlink CFLAGS MERCHANTABILITY ispell wrt YY
|
||||
LocalWords: american Administrivia camlCase yy accessors namespace src
|
||||
LocalWords: getExpectedTokens yyexpectedTokens yygetExpectedTokens
|
||||
LocalWords: regen dogfooding Autotest testsuite
|
||||
LocalWords: american Administrivia camlCase yy accessors namespace src hoc
|
||||
LocalWords: getExpectedTokens yyexpectedTokens yygetExpectedTokens parens
|
||||
LocalWords: regen dogfooding Autotest testsuite getargs CPP BAZ endif cppi
|
||||
LocalWords: cpp javaexec cp Calc ASAN UBSAN CPPFLAGS isystem CXX cex Gperf
|
||||
LocalWords: CXXFLAGS LDFLAGS dsymutil gperf
|
||||
|
||||
-->
|
||||
|
||||
@@ -1,4 +1,43 @@
|
||||
* Bison 3.6
|
||||
* Bison 3.7
|
||||
** Cex
|
||||
*** Improve gnulib
|
||||
Don't do this (counterexample.c):
|
||||
|
||||
// This is the fastest way to get the tail node from the gl_list API.
|
||||
gl_list_node_t
|
||||
list_get_end (gl_list_t list)
|
||||
{
|
||||
gl_list_node_t sentinel = gl_list_add_last (list, NULL);
|
||||
gl_list_node_t res = gl_list_previous_node (list, sentinel);
|
||||
gl_list_remove_node (list, sentinel);
|
||||
return res;
|
||||
}
|
||||
|
||||
*** Ambiguous rewriting
|
||||
If the user is stupid enough to have equal rules, then the derivations are
|
||||
harder to read:
|
||||
|
||||
Reduce/reduce conflict on tokens $end, "+", "⊕":
|
||||
2 exp: exp "+" exp .
|
||||
3 exp: exp "+" exp .
|
||||
Example exp "+" exp •
|
||||
First derivation exp ::=[ exp "+" exp • ]
|
||||
Example exp "+" exp •
|
||||
Second derivation exp ::=[ exp "+" exp • ]
|
||||
|
||||
Do we care about this? In color, we use twice the same color here, but we
|
||||
could try to use the same color for the same rule.
|
||||
|
||||
*** XML reports
|
||||
Show the counterexamples. This is going to be really hard and/or painful.
|
||||
Unless we play it dumb (little structure).
|
||||
|
||||
** Bistromathic
|
||||
- How about not evaluating incomplete lines when the text is not finished
|
||||
(as shells do).
|
||||
|
||||
- Caret diagnostics
|
||||
|
||||
** Questions
|
||||
*** Java
|
||||
- Should i18n be part of the Lexer? Currently it's a static method of
|
||||
@@ -28,24 +67,6 @@ enough.
|
||||
*** calc.at
|
||||
Stop hard-coding "Calc". Adjust local.at (look for FIXME).
|
||||
|
||||
* Bison 3.7
|
||||
** Counter example generation
|
||||
See https://github.com/akimd/bison/pull/15.
|
||||
|
||||
** Clean up
|
||||
Rename user_token_number for tokens as "code". It's not a "user number",
|
||||
it's the token code, and the user can control it, but this code always
|
||||
exists.
|
||||
|
||||
See also USER_NUMBER_UNDEFINED and NUMBER_UNDEFINED.
|
||||
|
||||
Rename endtoken as eoftoken.
|
||||
|
||||
Also do it in data/skeletons.
|
||||
|
||||
Don't rename in Bison 3.6 (it would be logical to do so) because that
|
||||
would probably create many conflicts in Vincent's work (see previous point).
|
||||
|
||||
** A dev warning for b4_
|
||||
Maybe we should check for m4_ and b4_ leaking out of the m4 processing, as
|
||||
Autoconf does. It would have caught overquotation issues.
|
||||
@@ -56,7 +77,7 @@ generates tons of white space in the page, and may contribute to bad page
|
||||
breaks.
|
||||
|
||||
** consistency
|
||||
token vs terminal, variable vs non terminal.
|
||||
token vs terminal.
|
||||
|
||||
** api.token.raw
|
||||
The YYUNDEFTOK could be assigned a semantic value so that yyerror could be
|
||||
@@ -118,7 +139,29 @@ Rici:
|
||||
> At a minimum, the fact that yyclearin does not invoke the %destructor
|
||||
> should be highlighted in the documentation, since it is not at all obvious.
|
||||
|
||||
** Issues in i18n
|
||||
|
||||
Les catégories d'avertissements incluent :
|
||||
conflicts-sr conflits S/R (activé par défaut)
|
||||
conflicts-rr conflits R/R (activé par défaut)
|
||||
dangling-alias l'alias chaîne n'est pas attaché à un symbole
|
||||
deprecated construction obsolète
|
||||
empty-rule règle vide sans %empty
|
||||
midrule-values valeurs de règle intermédiaire non définies ou inutilisées
|
||||
precedence priorité et associativité inutiles
|
||||
yacc incompatibilités avec POSIX Yacc
|
||||
other tous les autres avertissements (activé par défaut)
|
||||
all tous les avertissements sauf « dangling-alias » et « yacc »
|
||||
no-CATEGORY désactiver les avertissements dans CATEGORIE
|
||||
none désactiver tous les avertissements
|
||||
error[=CATEGORY] traiter les avertissements comme des erreurs
|
||||
|
||||
Line -1 and -3 should mention CATEGORIE, not CATEGORY.
|
||||
|
||||
* Bison 3.8
|
||||
** Rewrite glr.cc
|
||||
Get rid of scaffolding in glr.c.
|
||||
|
||||
** Unit rules / Injection rules (Akim Demaille)
|
||||
Maybe we could expand unit rules (or "injections", see
|
||||
https://homepages.cwi.nl/~daybuild/daily-books/syntax/2-sdf/sdf.html), i.e.,
|
||||
@@ -192,10 +235,10 @@ define it to the same type as the C ptrdiff_t type.
|
||||
* Completion
|
||||
Several features are not available in all the backends.
|
||||
|
||||
- push parsers: glr.c, glr.cc, lalr1.cc
|
||||
- lac: D, Java
|
||||
- glr: D, Java
|
||||
- token constructors: Java, C, D
|
||||
- lac: D, Java (easy)
|
||||
- push parsers: glr.c, glr.cc, lalr1.cc (not very difficult)
|
||||
- token constructors: Java, C, D (a bit difficult)
|
||||
- glr: D, Java (super difficult)
|
||||
|
||||
* Bugs
|
||||
** Autotest has quotation issues
|
||||
@@ -385,16 +428,6 @@ undocumented ''features''. Maybe an empty action ought to be
|
||||
presented too. Shall we try to make a single grammar with all these
|
||||
features, or should we have several very small grammars?
|
||||
|
||||
** --report=conflict-path
|
||||
Provide better assistance for understanding the conflicts by providing
|
||||
a sample text exhibiting the (LALR) ambiguity. See the paper from
|
||||
DeRemer and Penello: they already provide the algorithm.
|
||||
|
||||
** Statically check for potential ambiguities in GLR grammars
|
||||
See <http://www.lsv.fr/~schmitz/pub/expamb.pdf> for an approach.
|
||||
An Experimental Ambiguity Detection Tool ∗ Sylvain Schmitz
|
||||
LORIA, INRIA Nancy - Grand Est, Nancy, France
|
||||
|
||||
* Extensions
|
||||
** More languages?
|
||||
Well, only if there is really some demand for it.
|
||||
@@ -485,13 +518,6 @@ XML output for GNU Bison and gcc
|
||||
XML output for GNU Bison
|
||||
http://yaxx.sourceforge.net/
|
||||
|
||||
** Counterexample generation
|
||||
https://lists.gnu.org/archive/html/bug-bison/2016-06/msg00000.html
|
||||
http://www.cs.cornell.edu/andru/papers/cupex/
|
||||
|
||||
Andrew Myers and Vincent Imbimbo are working on this item, see
|
||||
https://github.com/akimd/bison/issues/12
|
||||
|
||||
* Coding system independence
|
||||
Paul notes:
|
||||
|
||||
@@ -568,15 +594,9 @@ 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/>.
|
||||
Permission is granted to copy, distribute and/or modify this document
|
||||
under the terms of the GNU Free Documentation License, Version 1.3 or
|
||||
any later version published by the Free Software Foundation; with no
|
||||
Invariant Sections, with no Front-Cover Texts, and with no Back-Cover
|
||||
Texts. A copy of the license is included in the "GNU Free
|
||||
Documentation License" file as part of this distribution.
|
||||
|
||||
+4
-2
@@ -17,7 +17,7 @@
|
||||
|
||||
# gnulib modules used by this package.
|
||||
gnulib_modules='
|
||||
argmatch array-list assert assure
|
||||
argmatch array-list assert assure attribute
|
||||
bitsetv
|
||||
calloc-posix close closeout config-h c-strcase
|
||||
configmake
|
||||
@@ -30,6 +30,7 @@ gnulib_modules='
|
||||
javaexec-script
|
||||
ldexpl
|
||||
libtextstyle-optional
|
||||
linked-list
|
||||
malloc-gnu
|
||||
mbfile mbswidth
|
||||
non-recursive-gnulib-prefix-hack
|
||||
@@ -37,6 +38,7 @@ gnulib_modules='
|
||||
obstack-printf
|
||||
perror progname
|
||||
quote quotearg
|
||||
rbtreehash-list
|
||||
readline
|
||||
readme-release
|
||||
realloc-posix
|
||||
@@ -44,7 +46,7 @@ gnulib_modules='
|
||||
rename
|
||||
spawn-pipe stdbool stpcpy strdup-posix strerror strverscmp
|
||||
timevar
|
||||
unistd unistd-safer unlink unlocked-io
|
||||
unicodeio unistd unistd-safer unlink unlocked-io
|
||||
update-copyright unsetenv verify
|
||||
warnings
|
||||
winsz-ioctl
|
||||
|
||||
@@ -73,6 +73,11 @@ def diff_to_re(match):
|
||||
is_diff = True
|
||||
to.append(l)
|
||||
if is_diff:
|
||||
# Do not run s//SOMETHING/g (with an emty pattern), that won't
|
||||
# work well...
|
||||
if frm == []:
|
||||
trace("no from for", match.group(1))
|
||||
return
|
||||
frm = "\n".join(frm)
|
||||
to = "\n".join(to)
|
||||
subst[frm] = to
|
||||
@@ -112,4 +117,6 @@ def process(logfile):
|
||||
|
||||
for logfile in args.logs:
|
||||
trace("FILE:", logfile)
|
||||
if os.path.isdir(logfile):
|
||||
logfile = os.path.join(logfile, 'testsuite.log')
|
||||
process(logfile)
|
||||
|
||||
@@ -51,7 +51,7 @@ gnulib_dir = $(srcdir)/gnulib
|
||||
bootstrap-tools = autoconf,automake,flex,gettext,gnulib
|
||||
|
||||
announcement_Cc_ = \
|
||||
[email protected], [email protected], bison-patches@gnu.org, \
|
||||
[email protected], bison-announce@gnu.org, \
|
||||
[email protected]
|
||||
|
||||
update-copyright: update-b4-copyright update-package-copyright-year
|
||||
|
||||
+15
-7
@@ -36,10 +36,8 @@ AC_DEFINE_UNQUOTED([PACKAGE_COPYRIGHT_YEAR], [$PACKAGE_COPYRIGHT_YEAR],
|
||||
AC_CONFIG_AUX_DIR([build-aux])
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
|
||||
# We use Automake 1.14's %D% and %C%.
|
||||
#
|
||||
# When we move to Automake 1.16, simplify examples/c/reccalc/local.mk.
|
||||
# Our CI runs on Xenial, which has only Automake 1.15.
|
||||
# Our CI build the packages on Bionic, which has only Automake 1.15.
|
||||
#
|
||||
# We want gnits strictness only when rolling a stable release. For
|
||||
# release candidates, we use version strings like 2.4.3_rc1, but gnits
|
||||
@@ -47,7 +45,7 @@ AC_CONFIG_MACRO_DIR([m4])
|
||||
# releases, we want to be able run make dist without being required to
|
||||
# add a bogus NEWS entry. In that case, the version string
|
||||
# automatically contains a dash, which we also let disable gnits.
|
||||
AM_INIT_AUTOMAKE([1.14 dist-xz nostdinc
|
||||
AM_INIT_AUTOMAKE([1.15 dist-lzip dist-xz nostdinc
|
||||
color-tests parallel-tests
|
||||
silent-rules]
|
||||
m4_bmatch(m4_defn([AC_PACKAGE_VERSION]), [[-_]],
|
||||
@@ -134,10 +132,12 @@ if test "$enable_gcc_warnings" = yes; then
|
||||
-fparse-all-comments -Wdocumentation
|
||||
-Wformat -Wimplicit-fallthrough -Wnull-dereference
|
||||
-Wno-sign-compare -Wno-tautological-constant-out-of-range-compare
|
||||
-Wpointer-arith -Wshadow
|
||||
-Wpointer-arith -Wshadow -Wstrict-aliasing
|
||||
-Wwrite-strings
|
||||
-wr188 -wr2259 -wr3179'
|
||||
warn_c='-Wbad-function-cast -Wstrict-prototypes'
|
||||
warn_c='-Wbad-function-cast
|
||||
-Wmissing-prototypes
|
||||
-Wstrict-prototypes'
|
||||
warn_cxx='-Wextra-semi -Wnoexcept -Wold-style-cast -Wundefined-func-template
|
||||
-Wweak-vtables'
|
||||
# Warnings for the test suite only.
|
||||
@@ -262,7 +262,8 @@ if ! "$LEX_IS_FLEX" || test "X$LEX" = X:; then
|
||||
LEX=:
|
||||
fi
|
||||
AM_CONDITIONAL([FLEX_WORKS], [$LEX_IS_FLEX && $FLEX_SUPPORTS_HEADER_OPT])
|
||||
AM_CONDITIONAL([FLEX_CXX_WORKS], [$LEX_WORKS && test $bison_cv_cxx_works = yes])
|
||||
AM_CONDITIONAL([FLEX_CXX_WORKS],
|
||||
[$LEX_IS_FLEX && $FLEX_SUPPORTS_HEADER_OPT && test $bison_cv_cxx_works = yes])
|
||||
AC_PROG_YACC
|
||||
AC_PROG_RANLIB
|
||||
AC_PROG_GNU_M4
|
||||
@@ -331,6 +332,13 @@ AC_MSG_RESULT([$suppfile])
|
||||
# Whether we cannot run the compiled bison.
|
||||
AM_CONDITIONAL([CROSS_COMPILING], [test "$cross_compiling" = yes])
|
||||
|
||||
# Build bistromathic if we have the lib and both readline/readline.h
|
||||
# and readline/history.h.
|
||||
AM_CONDITIONAL([ENABLE_BISTROMATHIC],
|
||||
[test "$gl_cv_lib_readline" != no &&
|
||||
test "$ac_cv_header_readline_readline_h" = yes &&
|
||||
test "$ac_cv_header_readline_history_h" = yes])
|
||||
|
||||
AM_MISSING_PROG([AUTOM4TE], [autom4te])
|
||||
# Needed by tests/atlocal.in.
|
||||
AC_SUBST([GCC])
|
||||
|
||||
+24
-16
@@ -1,6 +1,6 @@
|
||||
This directory contains data needed by Bison.
|
||||
|
||||
# Directory content
|
||||
# Directory Content
|
||||
## Skeletons
|
||||
Bison skeletons: the general shapes of the different parser kinds, that are
|
||||
specialized for specific grammars by the bison program.
|
||||
@@ -48,7 +48,7 @@ various formats.
|
||||
- xml2xhtml.xsl
|
||||
Conversion into XHTML.
|
||||
|
||||
# Implementation note about the skeletons
|
||||
# Implementation Notes About the Skeletons
|
||||
|
||||
"Skeleton" in Bison parlance means "backend": a skeleton is fed by the bison
|
||||
executable with LR tables, facts about the symbols, etc. and they generate
|
||||
@@ -84,29 +84,35 @@ field), where field can `has_id`, `id`, etc.: see
|
||||
The macro `b4_symbol(NUM, FIELD)` gives access to the following FIELDS:
|
||||
|
||||
- `has_id`: 0 or 1
|
||||
Whether the symbol has an id.
|
||||
Whether the symbol has an `id`.
|
||||
|
||||
- `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. This is
|
||||
used to define the token kind (i.e., the enum used by the return value of
|
||||
yylex).
|
||||
- `id`: string (e.g., `exp`, `NUM`, or `TOK_NUM` with api.token.prefix)
|
||||
If `has_id`, the name of the token kind (prefixed by api.token.prefix if
|
||||
defined), otherwise empty. Guaranteed to be usable as a C identifier.
|
||||
This is used to define the token kind (i.e., the enum used by the return
|
||||
value of yylex). Should be named `token_kind`.
|
||||
|
||||
- `tag`: string
|
||||
A human representation of the symbol. Can be 'foo', 'foo.id', '"foo"' etc.
|
||||
A human readable representation of the symbol. Can be `'foo'`,
|
||||
`'foo.id'`, `'"foo"'` etc.
|
||||
|
||||
- `user_number`: integer
|
||||
The code associated to the `id`.
|
||||
- `code`: integer
|
||||
The token code associated to the token kind `id`.
|
||||
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.
|
||||
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
|
||||
Whether this is a terminal symbol.
|
||||
|
||||
- `kind_base`: string (e.g., `YYSYMBOL_exp`, `YYSYMBOL_NUM`)
|
||||
The base of the symbol kind, i.e., the enumerator of this symbol (token or
|
||||
nonterminal) which is mapped to its `number`.
|
||||
|
||||
- `kind`: string
|
||||
The symbol kind, i.e., the enumerator of this symbol (token or nonterminal)
|
||||
which is mapping to its `number`.
|
||||
Same as `kind_base`, but possibly with a prefix in some languages. E.g.,
|
||||
EOF's `kind_base` and `kind` are `YYSYMBOL_YYEOF` in C, but are
|
||||
`S_YYEMPTY` and `symbol_kind::S_YYEMPTY` in C++.
|
||||
|
||||
- `number`: integer
|
||||
The code associated to the `kind`.
|
||||
@@ -173,7 +179,7 @@ The data corresponding to the symbol `#POS`, where the current rule has
|
||||
Expansion of `$<TYPE>POS`, where the current rule has `RULE-LENGTH` symbols
|
||||
on RHS.
|
||||
|
||||
-----
|
||||
<!--
|
||||
|
||||
Local Variables:
|
||||
mode: markdown
|
||||
@@ -197,3 +203,5 @@ 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/>.
|
||||
|
||||
-->
|
||||
|
||||
@@ -30,5 +30,28 @@
|
||||
/* "Sections" in traces (--trace). */
|
||||
.trace0 { color: green; }
|
||||
|
||||
/* Syntax error messages. */
|
||||
.expected { color: green; }
|
||||
.unexpected { color: red; }
|
||||
|
||||
|
||||
/* Counterexamples. */
|
||||
|
||||
/* Cex: point in rule. */
|
||||
.cex-dot { color: red; }
|
||||
|
||||
/* Cex: coloring various rules. */
|
||||
.cex-0 { color: yellow; }
|
||||
.cex-1 { color: green; }
|
||||
.cex-2 { color: blue; }
|
||||
.cex-3 { color: purple; }
|
||||
.cex-4 { color: violet; }
|
||||
.cex-5 { color: orange; }
|
||||
.cex-6 { color: brown; }
|
||||
.cex-7 { color: mauve; }
|
||||
|
||||
/* Cex: derivation rewriting steps. */
|
||||
.cex-step { font-style: italic; }
|
||||
|
||||
/* Cex: leaves of a derivation. */
|
||||
.cex-leaf { font-weight: 600; }
|
||||
|
||||
@@ -34,6 +34,7 @@ dist_skeletons_DATA = \
|
||||
data/skeletons/lalr1.java \
|
||||
data/skeletons/location.cc \
|
||||
data/skeletons/stack.hh \
|
||||
data/skeletons/traceon.m4 \
|
||||
data/skeletons/variant.hh \
|
||||
data/skeletons/yacc.c
|
||||
|
||||
|
||||
+41
-10
@@ -19,6 +19,29 @@
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
|
||||
# m4_gsub(STRING, RE1, SUBST1, RE2, SUBST2, ...)
|
||||
# ----------------------------------------------
|
||||
# m4 equivalent of
|
||||
#
|
||||
# $_ = STRING;
|
||||
# s/RE1/SUBST1/g;
|
||||
# s/RE2/SUBST2/g;
|
||||
# ...
|
||||
#
|
||||
# Really similar to m4_bpatsubsts, but behaves properly with quotes.
|
||||
# See m4.at's "Generating Comments". Super inelegant, but so far, I
|
||||
# did not find any better solution.
|
||||
m4_define([b4_gsub],
|
||||
[m4_bpatsubst(m4_bpatsubst(m4_bpatsubst([[[[$1]]]],
|
||||
[$2], [$3]),
|
||||
[$4], [$5]),
|
||||
[$6], [$7])])
|
||||
|
||||
# m4_shift2 and m4_shift3 are provided by m4sugar.
|
||||
m4_define([m4_shift4], [m4_shift(m4_shift(m4_shift(m4_shift($@))))])
|
||||
|
||||
|
||||
## ---------------- ##
|
||||
## Identification. ##
|
||||
## ---------------- ##
|
||||
@@ -162,7 +185,7 @@ m4_define([b4_error],
|
||||
[b4_cat([[@complain][(]$1[@,]$2[@,]$3[@,]$4[]]dnl
|
||||
[m4_if([$#], [4], [],
|
||||
[m4_foreach([b4_arg],
|
||||
m4_dquote(m4_shift(m4_shift(m4_shift(m4_shift($@))))),
|
||||
m4_dquote(m4_shift4($@)),
|
||||
[[@,]b4_arg])])[@)]])])
|
||||
|
||||
# b4_warn(FORMAT, [ARG1], [ARG2], ...)
|
||||
@@ -415,14 +438,14 @@ m4_define([b4_symbol_token_kind],
|
||||
_b4_symbol([$1], [id])])
|
||||
|
||||
|
||||
# b4_symbol_kind(NUM)
|
||||
# -------------------
|
||||
# b4_symbol_kind_base(NUM)
|
||||
# ------------------------
|
||||
# Build the name of the kind of this symbol. It must always exist,
|
||||
# otherwise some symbols might not be represented in the enum, which
|
||||
# might be compiled into too small a type to contain all the symbol
|
||||
# numbers.
|
||||
m4_define([b4_symbol_prefix], [b4_percent_define_get([api.symbol.prefix])])
|
||||
m4_define([b4_symbol_kind],
|
||||
m4_define([b4_symbol_kind_base],
|
||||
[b4_percent_define_get([api.symbol.prefix])dnl
|
||||
m4_case([$1],
|
||||
[-2], [[YYEMPTY]],
|
||||
@@ -435,6 +458,13 @@ m4_case([$1],
|
||||
[m4_bpatsubst([$1-][]_b4_symbol([$1], [tag]), [[^a-zA-Z_0-9]+], [_])])])])])
|
||||
|
||||
|
||||
# b4_symbol_kind(NUM)
|
||||
# -------------------
|
||||
# Same as b4_symbol_kind, but possibly with a prefix in some
|
||||
# languages. E.g., EOF's kind_base and kind are YYSYMBOL_YYEOF in C,
|
||||
# but are S_YYEMPTY and symbol_kind::S_YYEMPTY in C++.
|
||||
m4_copy([b4_symbol_kind_base], [b4_symbol_kind])
|
||||
|
||||
# b4_symbol(NUM, FIELD)
|
||||
# ---------------------
|
||||
# Fetch FIELD of symbol #NUM (or "orig NUM"). Fail if undefined.
|
||||
@@ -442,8 +472,9 @@ m4_case([$1],
|
||||
# If FIELD = id, prepend the token prefix.
|
||||
m4_define([b4_symbol],
|
||||
[m4_case([$2],
|
||||
[id], [b4_symbol_token_kind([$1])],
|
||||
[kind], [b4_symbol_kind([$1])],
|
||||
[id], [b4_symbol_token_kind([$1])],
|
||||
[kind_base], [b4_symbol_kind_base([$1])],
|
||||
[kind], [b4_symbol_kind([$1])],
|
||||
[_b4_symbol($@)])])
|
||||
|
||||
|
||||
@@ -516,7 +547,7 @@ m4_popdef([b4_actions_])dnl
|
||||
# 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])])
|
||||
[case b4_symbol([$1], [kind]): b4_symbol_tag_comment([$1])])
|
||||
])
|
||||
|
||||
|
||||
@@ -564,8 +595,8 @@ m4_define([b4_any_token_visible_if],
|
||||
m4_define([b4_token_format],
|
||||
[b4_token_visible_if([$2],
|
||||
[m4_format([[$1]],
|
||||
m4_expand(b4_symbol([$2], [id])),
|
||||
m4_expand(b4_symbol([$2], b4_api_token_raw_if([[number]], [[user_number]]))))])])
|
||||
b4_symbol([$2], [id]),
|
||||
b4_symbol([$2], b4_api_token_raw_if([[number]], [[code]])))])])
|
||||
|
||||
|
||||
# b4_last_enum_token
|
||||
@@ -727,7 +758,7 @@ m4_define([b4_check_user_names],
|
||||
[m4_pushdef([b4_occurrence], b4_occurrence)dnl
|
||||
m4_pushdef([b4_user_name], m4_car(b4_occurrence))dnl
|
||||
m4_pushdef([b4_start], m4_car(m4_shift(b4_occurrence)))dnl
|
||||
m4_pushdef([b4_end], m4_shift(m4_shift(b4_occurrence)))dnl
|
||||
m4_pushdef([b4_end], m4_shift2(b4_occurrence))dnl
|
||||
m4_ifndef($3[(]m4_quote(b4_user_name)[)],
|
||||
[b4_complain_at([b4_start], [b4_end],
|
||||
[[%s '%s' is not used]],
|
||||
|
||||
+44
-11
@@ -105,7 +105,7 @@ b4_percent_define_default([[api.parser.class]], [[parser]])
|
||||
#
|
||||
# b4_percent_define_default([[api.location.type]], [[location]])
|
||||
|
||||
b4_percent_define_default([[filename_type]], [[std::string]])
|
||||
b4_percent_define_default([[api.filename.type]], [[const std::string]])
|
||||
# Make it a warning for those who used betas of Bison 3.0.
|
||||
b4_percent_define_default([[api.namespace]], m4_defn([b4_prefix]))
|
||||
|
||||
@@ -193,7 +193,7 @@ m4_define([b4_declare_symbol_enum],
|
||||
[[enum symbol_kind_type
|
||||
{
|
||||
YYNTOKENS = ]b4_tokens_number[, ///< Number of tokens.
|
||||
]b4_symbol_kind([-2])[ = -2,
|
||||
]b4_symbol(-2, kind_base)[ = -2,
|
||||
]b4_symbol_foreach([ b4_symbol_enum])dnl
|
||||
[ };]])
|
||||
|
||||
@@ -259,14 +259,14 @@ m4_define([b4_public_types_declare],
|
||||
struct token
|
||||
{
|
||||
]b4_token_enums[
|
||||
/// Backward compatibility alias.
|
||||
/// Backward compatibility alias (Bison 3.6).
|
||||
typedef token_kind_type yytokentype;
|
||||
};
|
||||
|
||||
/// Token kind, as returned by yylex.
|
||||
typedef token::yytokentype token_kind_type;
|
||||
|
||||
/// Backward compatibility alias.
|
||||
/// Backward compatibility alias (Bison 3.6).
|
||||
typedef token_kind_type token_type;
|
||||
|
||||
/// Symbol kinds.
|
||||
@@ -357,7 +357,30 @@ m4_define([b4_symbol_type_define],
|
||||
Base::clear ();
|
||||
}
|
||||
|
||||
/// Backward compatibility.
|
||||
]b4_parse_error_bmatch(
|
||||
[custom\|detailed],
|
||||
[[ /// The user-facing name of this symbol.
|
||||
const char *name () const YY_NOEXCEPT
|
||||
{
|
||||
return ]b4_parser_class[::symbol_name (this->kind ());
|
||||
}]],
|
||||
[simple],
|
||||
[[#if ]b4_api_PREFIX[DEBUG || ]b4_token_table_flag[
|
||||
/// The user-facing name of this symbol.
|
||||
const char *name () const YY_NOEXCEPT
|
||||
{
|
||||
return ]b4_parser_class[::symbol_name (this->kind ());
|
||||
}
|
||||
#endif // #if ]b4_api_PREFIX[DEBUG || ]b4_token_table_flag[
|
||||
]],
|
||||
[verbose],
|
||||
[[ /// The user-facing name of this symbol.
|
||||
std::string name () const YY_NOEXCEPT
|
||||
{
|
||||
return ]b4_parser_class[::symbol_name (this->kind ());
|
||||
}]])[
|
||||
|
||||
/// Backward compatibility (Bison 3.6).
|
||||
symbol_kind_type type_get () const YY_NOEXCEPT;
|
||||
|
||||
/// Whether empty.
|
||||
@@ -409,12 +432,15 @@ m4_define([b4_symbol_type_define],
|
||||
/// \a empty when empty.
|
||||
symbol_kind_type kind () const YY_NOEXCEPT;
|
||||
|
||||
/// Backward compatibility (Bison 3.6).
|
||||
symbol_kind_type type_get () const YY_NOEXCEPT;
|
||||
|
||||
/// The symbol kind.
|
||||
/// \a ]b4_symbol_prefix[YYEMPTY when empty.
|
||||
symbol_kind_type kind_;
|
||||
};
|
||||
|
||||
/// Backward compatibility for a private implementation detail.
|
||||
/// Backward compatibility for a private implementation detail (Bison 3.6).
|
||||
typedef by_kind by_type;
|
||||
|
||||
/// "External" symbols: returned by the scanner.
|
||||
@@ -481,7 +507,7 @@ m4_define([b4_public_types_define],
|
||||
bool
|
||||
]b4_parser_class[::basic_symbol<Base>::empty () const YY_NOEXCEPT
|
||||
{
|
||||
return this->kind () == symbol_kind::]b4_symbol_prefix[YYEMPTY;
|
||||
return this->kind () == ]b4_symbol(-2, kind)[;
|
||||
}
|
||||
|
||||
template <typename Base>
|
||||
@@ -497,7 +523,7 @@ m4_define([b4_public_types_define],
|
||||
|
||||
// by_kind.
|
||||
]b4_inline([$1])b4_parser_class[::by_kind::by_kind ()
|
||||
: kind_ (symbol_kind::]b4_symbol_prefix[YYEMPTY)
|
||||
: kind_ (]b4_symbol(-2, kind)[)
|
||||
{}
|
||||
|
||||
#if 201103L <= YY_CPLUSPLUS
|
||||
@@ -519,7 +545,7 @@ m4_define([b4_public_types_define],
|
||||
]b4_inline([$1])[void
|
||||
]b4_parser_class[::by_kind::clear ()
|
||||
{
|
||||
kind_ = symbol_kind::]b4_symbol_prefix[YYEMPTY;
|
||||
kind_ = ]b4_symbol(-2, kind)[;
|
||||
}
|
||||
|
||||
]b4_inline([$1])[void
|
||||
@@ -534,6 +560,12 @@ m4_define([b4_public_types_define],
|
||||
{
|
||||
return kind_;
|
||||
}
|
||||
|
||||
]b4_inline([$1])[]b4_parser_class[::symbol_kind_type
|
||||
]b4_parser_class[::by_kind::type_get () const YY_NOEXCEPT
|
||||
{
|
||||
return this->kind ();
|
||||
}
|
||||
]])
|
||||
|
||||
|
||||
@@ -562,11 +594,12 @@ m4_define([b4_yytranslate_define],
|
||||
{
|
||||
]b4_translate[
|
||||
};
|
||||
const int user_token_number_max_ = ]b4_user_token_number_max[;
|
||||
// Last valid token kind.
|
||||
const int code_max = ]b4_code_max[;
|
||||
|
||||
if (t <= 0)
|
||||
return symbol_kind::]b4_symbol_prefix[YYEOF;
|
||||
else if (t <= user_token_number_max_)
|
||||
else if (t <= code_max)
|
||||
return YY_CAST (symbol_kind_type, translate_table[t]);
|
||||
else
|
||||
return symbol_kind::]b4_symbol_prefix[YYUNDEF;]])[
|
||||
|
||||
@@ -17,15 +17,21 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
# _b4_comment(TEXT, OPEN, CONTINUE, END)
|
||||
# --------------------------------------
|
||||
# Put TEXT in comment. Avoid trailing spaces: don't indent empty lines.
|
||||
# Avoid adding indentation to the first line, as the indentation comes
|
||||
# from OPEN. That's why we don't patsubst([$1], [^\(.\)], [ \1]).
|
||||
# Turn "*/" in TEXT into "* /" so that we don't unexpectedly close
|
||||
# the comments before its end.
|
||||
#
|
||||
# Prefix all the output lines with PREFIX.
|
||||
m4_define([_b4_comment],
|
||||
[$2[]m4_bpatsubst(m4_expand([[$1]]), [
|
||||
[$2[]b4_gsub(m4_expand([$1]),
|
||||
[[*]/], [*\\/],
|
||||
[/[*]], [/\\*],
|
||||
[
|
||||
\(.\)], [
|
||||
$3\1])$4])
|
||||
|
||||
|
||||
+66
-10
@@ -205,7 +205,11 @@ m4_define([b4_c99_int_type],
|
||||
# Define private types suitable for holding small integers in C99 or later.
|
||||
m4_define([b4_c99_int_type_define],
|
||||
[m4_copy_force([b4_c99_int_type], [b4_int_type])dnl
|
||||
[/* On compilers that do not define __PTRDIFF_MAX__ etc., make sure
|
||||
[#ifdef short
|
||||
# undef short
|
||||
#endif
|
||||
|
||||
/* On compilers that do not define __PTRDIFF_MAX__ etc., make sure
|
||||
<limits.h> and (if available) <stdint.h> are included
|
||||
so that the code can choose integer types of a good width. */
|
||||
|
||||
@@ -261,6 +265,50 @@ typedef int yytype_uint16;
|
||||
#endif]])
|
||||
|
||||
|
||||
# b4_sizes_types_define
|
||||
# ---------------------
|
||||
# Define YYPTRDIFF_T/YYPTRDIFF_MAXIMUM, YYSIZE_T/YYSIZE_MAXIMUM,
|
||||
# and YYSIZEOF.
|
||||
m4_define([b4_sizes_types_define],
|
||||
[[#ifndef YYPTRDIFF_T
|
||||
# if defined __PTRDIFF_TYPE__ && defined __PTRDIFF_MAX__
|
||||
# define YYPTRDIFF_T __PTRDIFF_TYPE__
|
||||
# define YYPTRDIFF_MAXIMUM __PTRDIFF_MAX__
|
||||
# elif defined PTRDIFF_MAX
|
||||
# ifndef ptrdiff_t
|
||||
# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
|
||||
# endif
|
||||
# define YYPTRDIFF_T ptrdiff_t
|
||||
# define YYPTRDIFF_MAXIMUM PTRDIFF_MAX
|
||||
# else
|
||||
# define YYPTRDIFF_T long
|
||||
# define YYPTRDIFF_MAXIMUM LONG_MAX
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef YYSIZE_T
|
||||
# ifdef __SIZE_TYPE__
|
||||
# define YYSIZE_T __SIZE_TYPE__
|
||||
# elif defined size_t
|
||||
# define YYSIZE_T size_t
|
||||
# elif defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__
|
||||
# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
|
||||
# define YYSIZE_T size_t
|
||||
# else
|
||||
# define YYSIZE_T unsigned
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#define YYSIZE_MAXIMUM \
|
||||
YY_CAST (YYPTRDIFF_T, \
|
||||
(YYPTRDIFF_MAXIMUM < YY_CAST (YYSIZE_T, -1) \
|
||||
? YYPTRDIFF_MAXIMUM \
|
||||
: YY_CAST (YYSIZE_T, -1)))
|
||||
|
||||
#define YYSIZEOF(X) YY_CAST (YYPTRDIFF_T, sizeof (X))
|
||||
]])
|
||||
|
||||
|
||||
# b4_int_type_for(NAME)
|
||||
# ---------------------
|
||||
# Return a narrow int type able to handle numbers ranging from
|
||||
@@ -307,15 +355,23 @@ m4_define([b4_attribute_define],
|
||||
#endif
|
||||
|
||||
]m4_bmatch([$1], [\bnoreturn\b], [[/* The _Noreturn keyword of C11. */
|
||||
]dnl This is an exact copy of lib/_Noreturn.h.
|
||||
]dnl This is close to lib/_Noreturn.h, except that we do enable
|
||||
dnl the use of [[noreturn]], because _Noreturn is used in places
|
||||
dnl where [[noreturn]] works in C++. We need this in particular
|
||||
dnl because of glr.cc which compiles code from glr.c in C++.
|
||||
dnl And the C++ compiler chokes on _Noreturn. Also, we do not
|
||||
dnl use C' _Noreturn in C++, to avoid -Wc11-extensions warnings.
|
||||
[#ifndef _Noreturn
|
||||
# if (defined __cplusplus \
|
||||
&& ((201103 <= __cplusplus && !(__GNUC__ == 4 && __GNUC_MINOR__ == 7)) \
|
||||
|| (defined _MSC_VER && 1900 <= _MSC_VER)))
|
||||
# define _Noreturn [[noreturn]]
|
||||
# elif ((!defined __cplusplus || defined __clang__) \
|
||||
# elif (!defined __cplusplus \
|
||||
&& (201112 <= (defined __STDC_VERSION__ ? __STDC_VERSION__ : 0) \
|
||||
|| 4 < __GNUC__ + (7 <= __GNUC_MINOR__)))
|
||||
|| 4 < __GNUC__ + (7 <= __GNUC_MINOR__) \
|
||||
|| (defined __apple_build_version__ \
|
||||
? 6000000 <= __apple_build_version__ \
|
||||
: 3 < __clang_major__ + (5 <= __clang_minor__))))
|
||||
/* _Noreturn works as-is. */
|
||||
# elif 2 < __GNUC__ + (8 <= __GNUC_MINOR__) || 0x5110 <= __SUNPRO_C
|
||||
# define _Noreturn __attribute__ ((__noreturn__))
|
||||
@@ -467,7 +523,7 @@ m4_define([b4_token_enum],
|
||||
[m4_format([ %-30s %s],
|
||||
m4_format([[%s = %s%s%s]],
|
||||
b4_symbol([$1], [id]),
|
||||
b4_symbol([$1], b4_api_token_raw_if([[number]], [[user_number]])),
|
||||
b4_symbol([$1], b4_api_token_raw_if([[number]], [[code]])),
|
||||
m4_if([$1], b4_last_enum_token, [], [[,]])),
|
||||
[b4_symbol_tag_comment([$1])])])])
|
||||
|
||||
@@ -516,7 +572,7 @@ m4_define([b4_symbol_translate],
|
||||
m4_define([b4_symbol_enum],
|
||||
[m4_format([ %-40s %s],
|
||||
m4_format([[%s = %s%s%s]],
|
||||
b4_symbol([$1], [kind]),
|
||||
b4_symbol([$1], [kind_base]),
|
||||
[$1],
|
||||
m4_if([$1], b4_last_symbol, [], [[,]])),
|
||||
[b4_symbol_tag_comment([$1])])])
|
||||
@@ -531,7 +587,7 @@ m4_define([b4_declare_symbol_enum],
|
||||
[[/* Symbol kind. */
|
||||
enum yysymbol_kind_t
|
||||
{
|
||||
]b4_symbol_kind([-2])[ = -2,
|
||||
]b4_symbol([-2], kind_base)[ = -2,
|
||||
]b4_symbol_foreach([b4_symbol_enum])dnl
|
||||
[};
|
||||
typedef enum yysymbol_kind_t yysymbol_kind_t;
|
||||
@@ -610,10 +666,10 @@ m4_define([b4_sync_start], [[#]line $1 $2])
|
||||
## User actions. ##
|
||||
## -------------- ##
|
||||
|
||||
# b4_case(LABEL, STATEMENTS)
|
||||
# --------------------------
|
||||
# b4_case(LABEL, STATEMENTS, [COMMENTS])
|
||||
# --------------------------------------
|
||||
m4_define([b4_case],
|
||||
[ case $1:
|
||||
[ case $1:m4_ifval([$3], [ b4_comment([$3])])
|
||||
$2
|
||||
b4_syncline([@oline@], [@ofile@])dnl
|
||||
break;])
|
||||
|
||||
+12
-5
@@ -152,6 +152,8 @@ private static immutable b4_int_type_for([$2])[[]] yy$1_ =
|
||||
## Token kinds. ##
|
||||
## ------------- ##
|
||||
|
||||
m4_define([b4_symbol(-2, id)], [[YYEMPTY]])
|
||||
|
||||
# b4_token_enum(TOKEN-NAME, TOKEN-NUMBER)
|
||||
# ---------------------------------------
|
||||
# Output the definition of this token as an enum.
|
||||
@@ -178,6 +180,11 @@ b4_symbol_foreach([b4_token_enum])dnl
|
||||
|
||||
b4_percent_define_default([[api.symbol.prefix]], [[S_]])
|
||||
|
||||
# b4_symbol_kind(NUM)
|
||||
# -------------------
|
||||
m4_define([b4_symbol_kind],
|
||||
[SymbolKind.b4_symbol_kind_base($@)])
|
||||
|
||||
|
||||
# b4_symbol_enum(SYMBOL-NUM)
|
||||
# --------------------------
|
||||
@@ -185,7 +192,7 @@ b4_percent_define_default([[api.symbol.prefix]], [[S_]])
|
||||
m4_define([b4_symbol_enum],
|
||||
[m4_format([ %-30s %s],
|
||||
m4_format([[%s = %s,]],
|
||||
b4_symbol([$1], [kind]),
|
||||
b4_symbol([$1], [kind_base]),
|
||||
[$1]),
|
||||
[b4_symbol_tag_comment([$1])])])
|
||||
|
||||
@@ -199,16 +206,16 @@ m4_define([b4_declare_symbol_enum],
|
||||
[[ /* Symbol kinds. */
|
||||
public enum SymbolKind
|
||||
{
|
||||
]b4_symbol_kind([-2])[ = -2, /* No symbol. */
|
||||
]b4_symbol(-2, kind_base)[ = -2, /* No symbol. */
|
||||
]b4_symbol_foreach([b4_symbol_enum])dnl
|
||||
[ };
|
||||
]])])
|
||||
|
||||
|
||||
|
||||
# b4-case(ID, CODE)
|
||||
# -----------------
|
||||
m4_define([b4_case], [ case $1:
|
||||
# b4-case(ID, CODE, [COMMENTS])
|
||||
# -----------------------------
|
||||
m4_define([b4_case], [ case $1:m4_ifval([$3], [ b4_comment([$3])])
|
||||
$2
|
||||
break;])
|
||||
|
||||
|
||||
+62
-59
@@ -189,9 +189,9 @@ b4_glr_cc_if([],
|
||||
[b4_output_begin([b4_spec_header_file])
|
||||
b4_copyright([Skeleton interface for Bison GLR parsers in C],
|
||||
[2002-2015, 2018-2020])[
|
||||
]b4_cpp_guard_open([b4_spec_header_file])[
|
||||
]b4_cpp_guard_open([b4_spec_mapped_header_file])[
|
||||
]b4_shared_declarations[
|
||||
]b4_cpp_guard_close([b4_spec_header_file])[
|
||||
]b4_cpp_guard_close([b4_spec_mapped_header_file])[
|
||||
]b4_output_end[
|
||||
]])])
|
||||
|
||||
@@ -230,7 +230,9 @@ b4_copyright([Skeleton implementation for Bison GLR parsers in C],
|
||||
|
||||
]b4_defines_if([[#include "@basename(]b4_spec_header_file[@)"]],
|
||||
[b4_shared_declarations])[
|
||||
]b4_declare_symbol_enum[
|
||||
|
||||
]b4_glr_cc_if([b4_glr_cc_setup],
|
||||
[b4_declare_symbol_enum])[
|
||||
|
||||
/* Default (constant) value used for initialization for null
|
||||
right-hand sides. Unlike the standard yacc.c template, here we set
|
||||
@@ -249,6 +251,7 @@ static YYLTYPE yyloc_default][]b4_yyloc_default;])[
|
||||
#include <string.h>
|
||||
|
||||
]b4_c99_int_type_define[
|
||||
]b4_sizes_types_define[
|
||||
|
||||
#ifndef YY_
|
||||
# if defined YYENABLE_NLS && YYENABLE_NLS
|
||||
@@ -277,9 +280,6 @@ static YYLTYPE yyloc_default][]b4_yyloc_default;])[
|
||||
# define YYREALLOC realloc
|
||||
#endif
|
||||
|
||||
#define YYSIZEMAX \
|
||||
(PTRDIFF_MAX < SIZE_MAX ? PTRDIFF_MAX : YY_CAST (ptrdiff_t, SIZE_MAX))
|
||||
|
||||
#ifdef __cplusplus
|
||||
typedef bool yybool;
|
||||
# define yytrue true
|
||||
@@ -333,8 +333,8 @@ static YYLTYPE yyloc_default][]b4_yyloc_default;])[
|
||||
accessed by $0, $-1, etc., in any rule. */
|
||||
#define YYMAXLEFT ]b4_max_left_semantic_context[
|
||||
|
||||
/* YYMAXUTOK -- Last valid token number (for yychar). */
|
||||
#define YYMAXUTOK ]b4_user_token_number_max[
|
||||
/* YYMAXUTOK -- Last valid token kind. */
|
||||
#define YYMAXUTOK ]b4_code_max[
|
||||
|
||||
/* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM
|
||||
as returned by yylex, with out-of-bounds checking. */
|
||||
@@ -507,7 +507,7 @@ struct yyGLRState {
|
||||
/** Preceding state in this stack */
|
||||
yyGLRState* yypred;
|
||||
/** Source position of the last token produced by my symbol */
|
||||
ptrdiff_t yyposn;
|
||||
YYPTRDIFF_T yyposn;
|
||||
union {
|
||||
/** First in a chain of alternative reductions producing the
|
||||
* nonterminal corresponding to this state, threaded through
|
||||
@@ -527,8 +527,8 @@ struct yyGLRStateSet {
|
||||
* operation, yylookaheadNeeds[0] is not maintained since it would merely
|
||||
* duplicate yychar != ]b4_symbol(-2, id)[. */
|
||||
yybool* yylookaheadNeeds;
|
||||
ptrdiff_t yysize;
|
||||
ptrdiff_t yycapacity;
|
||||
YYPTRDIFF_T yysize;
|
||||
YYPTRDIFF_T yycapacity;
|
||||
};
|
||||
|
||||
struct yySemanticOption {
|
||||
@@ -568,7 +568,7 @@ struct yyGLRStack {
|
||||
YYJMP_BUF yyexception_buffer;
|
||||
yyGLRStackItem* yyitems;
|
||||
yyGLRStackItem* yynextFree;
|
||||
ptrdiff_t yyspaceLeft;
|
||||
YYPTRDIFF_T yyspaceLeft;
|
||||
yyGLRState* yysplitPoint;
|
||||
yyGLRState* yylastDeleted;
|
||||
yyGLRStateSet yytops;
|
||||
@@ -680,7 +680,7 @@ yysymbol_name (yysymbol_kind_t yysymbol)
|
||||
multiple parsers can coexist. */
|
||||
int yydebug;
|
||||
|
||||
static void yypstack (yyGLRStack* yystackp, ptrdiff_t yyk)
|
||||
static void yypstack (yyGLRStack* yystackp, YYPTRDIFF_T yyk)
|
||||
YY_ATTRIBUTE_UNUSED;
|
||||
static void yypdumpstack (yyGLRStack* yystackp)
|
||||
YY_ATTRIBUTE_UNUSED;
|
||||
@@ -696,7 +696,7 @@ static void yypdumpstack (yyGLRStack* yystackp)
|
||||
[simple],
|
||||
[[]],
|
||||
[[#ifndef yystrlen
|
||||
# define yystrlen(S) (YY_CAST (ptrdiff_t, strlen (S)))
|
||||
# define yystrlen(S) (YY_CAST (YYPTRDIFF_T, strlen (S)))
|
||||
#endif
|
||||
|
||||
]b4_parse_error_bmatch(
|
||||
@@ -731,12 +731,12 @@ yystpcpy (char *yydest, const char *yysrc)
|
||||
backslash-backslash). YYSTR is taken from yytname. If YYRES is
|
||||
null, do not copy; instead, return the length of what the result
|
||||
would have been. */
|
||||
static ptrdiff_t
|
||||
static YYPTRDIFF_T
|
||||
yytnamerr (char *yyres, const char *yystr)
|
||||
{
|
||||
if (*yystr == '"')
|
||||
{
|
||||
ptrdiff_t yyn = 0;
|
||||
YYPTRDIFF_T yyn = 0;
|
||||
char const *yyp = yystr;
|
||||
|
||||
for (;;)
|
||||
@@ -1104,7 +1104,7 @@ yynewGLRStackItem (yyGLRStack* yystackp, yybool yyisState)
|
||||
* alternative actions for YYSTATE. Assumes that YYRHS comes from
|
||||
* stack #YYK of *YYSTACKP. */
|
||||
static void
|
||||
yyaddDeferredAction (yyGLRStack* yystackp, ptrdiff_t yyk, yyGLRState* yystate,
|
||||
yyaddDeferredAction (yyGLRStack* yystackp, YYPTRDIFF_T yyk, yyGLRState* yystate,
|
||||
yyGLRState* yyrhs, yyRuleNum yyrule)
|
||||
{
|
||||
yySemanticOption* yynewOption =
|
||||
@@ -1136,14 +1136,14 @@ yyinitStateSet (yyGLRStateSet* yyset)
|
||||
yyset->yycapacity = 16;
|
||||
yyset->yystates
|
||||
= YY_CAST (yyGLRState**,
|
||||
YYMALLOC (YY_CAST (size_t, yyset->yycapacity)
|
||||
YYMALLOC (YY_CAST (YYSIZE_T, yyset->yycapacity)
|
||||
* sizeof yyset->yystates[0]));
|
||||
if (! yyset->yystates)
|
||||
return yyfalse;
|
||||
yyset->yystates[0] = YY_NULLPTR;
|
||||
yyset->yylookaheadNeeds
|
||||
= YY_CAST (yybool*,
|
||||
YYMALLOC (YY_CAST (size_t, yyset->yycapacity)
|
||||
YYMALLOC (YY_CAST (YYSIZE_T, yyset->yycapacity)
|
||||
* sizeof yyset->yylookaheadNeeds[0]));
|
||||
if (! yyset->yylookaheadNeeds)
|
||||
{
|
||||
@@ -1152,7 +1152,7 @@ yyinitStateSet (yyGLRStateSet* yyset)
|
||||
}
|
||||
memset (yyset->yylookaheadNeeds,
|
||||
0,
|
||||
YY_CAST (size_t, yyset->yycapacity) * sizeof yyset->yylookaheadNeeds[0]);
|
||||
YY_CAST (YYSIZE_T, yyset->yycapacity) * sizeof yyset->yylookaheadNeeds[0]);
|
||||
return yytrue;
|
||||
}
|
||||
|
||||
@@ -1165,14 +1165,14 @@ static void yyfreeStateSet (yyGLRStateSet* yyset)
|
||||
/** Initialize *YYSTACKP to a single empty stack, with total maximum
|
||||
* capacity for all stacks of YYSIZE. */
|
||||
static yybool
|
||||
yyinitGLRStack (yyGLRStack* yystackp, ptrdiff_t yysize)
|
||||
yyinitGLRStack (yyGLRStack* yystackp, YYPTRDIFF_T yysize)
|
||||
{
|
||||
yystackp->yyerrState = 0;
|
||||
yynerrs = 0;
|
||||
yystackp->yyspaceLeft = yysize;
|
||||
yystackp->yyitems
|
||||
= YY_CAST (yyGLRStackItem*,
|
||||
YYMALLOC (YY_CAST (size_t, yysize)
|
||||
YYMALLOC (YY_CAST (YYSIZE_T, yysize)
|
||||
* sizeof yystackp->yynextFree[0]));
|
||||
if (!yystackp->yyitems)
|
||||
return yyfalse;
|
||||
@@ -1198,9 +1198,9 @@ yyexpandGLRStack (yyGLRStack* yystackp)
|
||||
{
|
||||
yyGLRStackItem* yynewItems;
|
||||
yyGLRStackItem* yyp0, *yyp1;
|
||||
ptrdiff_t yynewSize;
|
||||
ptrdiff_t yyn;
|
||||
ptrdiff_t yysize = yystackp->yynextFree - yystackp->yyitems;
|
||||
YYPTRDIFF_T yynewSize;
|
||||
YYPTRDIFF_T yyn;
|
||||
YYPTRDIFF_T yysize = yystackp->yynextFree - yystackp->yyitems;
|
||||
if (YYMAXDEPTH - YYHEADROOM < yysize)
|
||||
yyMemoryExhausted (yystackp);
|
||||
yynewSize = 2*yysize;
|
||||
@@ -1208,7 +1208,7 @@ yyexpandGLRStack (yyGLRStack* yystackp)
|
||||
yynewSize = YYMAXDEPTH;
|
||||
yynewItems
|
||||
= YY_CAST (yyGLRStackItem*,
|
||||
YYMALLOC (YY_CAST (size_t, yynewSize)
|
||||
YYMALLOC (YY_CAST (YYSIZE_T, yynewSize)
|
||||
* sizeof yynewItems[0]));
|
||||
if (! yynewItems)
|
||||
yyMemoryExhausted (yystackp);
|
||||
@@ -1273,7 +1273,7 @@ yyupdateSplit (yyGLRStack* yystackp, yyGLRState* yys)
|
||||
|
||||
/** Invalidate stack #YYK in *YYSTACKP. */
|
||||
static inline void
|
||||
yymarkStackDeleted (yyGLRStack* yystackp, ptrdiff_t yyk)
|
||||
yymarkStackDeleted (yyGLRStack* yystackp, YYPTRDIFF_T yyk)
|
||||
{
|
||||
if (yystackp->yytops.yystates[yyk] != YY_NULLPTR)
|
||||
yystackp->yylastDeleted = yystackp->yytops.yystates[yyk];
|
||||
@@ -1297,7 +1297,7 @@ yyundeleteLastStack (yyGLRStack* yystackp)
|
||||
static inline void
|
||||
yyremoveDeletes (yyGLRStack* yystackp)
|
||||
{
|
||||
ptrdiff_t yyi, yyj;
|
||||
YYPTRDIFF_T yyi, yyj;
|
||||
yyi = yyj = 0;
|
||||
while (yyj < yystackp->yytops.yysize)
|
||||
{
|
||||
@@ -1330,8 +1330,8 @@ yyremoveDeletes (yyGLRStack* yystackp)
|
||||
* state YYLRSTATE, at input position YYPOSN, with (resolved) semantic
|
||||
* value *YYVALP and source location *YYLOCP. */
|
||||
static inline void
|
||||
yyglrShift (yyGLRStack* yystackp, ptrdiff_t yyk, yy_state_t yylrState,
|
||||
ptrdiff_t yyposn,
|
||||
yyglrShift (yyGLRStack* yystackp, YYPTRDIFF_T yyk, yy_state_t yylrState,
|
||||
YYPTRDIFF_T yyposn,
|
||||
YYSTYPE* yyvalp]b4_locations_if([, YYLTYPE* yylocp])[)
|
||||
{
|
||||
yyGLRState* yynewState = &yynewGLRStackItem (yystackp, yytrue)->yystate;
|
||||
@@ -1351,8 +1351,8 @@ yyglrShift (yyGLRStack* yystackp, ptrdiff_t yyk, yy_state_t yylrState,
|
||||
* state YYLRSTATE, at input position YYPOSN, with the (unresolved)
|
||||
* semantic value of YYRHS under the action for YYRULE. */
|
||||
static inline void
|
||||
yyglrShiftDefer (yyGLRStack* yystackp, ptrdiff_t yyk, yy_state_t yylrState,
|
||||
ptrdiff_t yyposn, yyGLRState* yyrhs, yyRuleNum yyrule)
|
||||
yyglrShiftDefer (yyGLRStack* yystackp, YYPTRDIFF_T yyk, yy_state_t yylrState,
|
||||
YYPTRDIFF_T yyposn, yyGLRState* yyrhs, yyRuleNum yyrule)
|
||||
{
|
||||
yyGLRState* yynewState = &yynewGLRStackItem (yystackp, yytrue)->yystate;
|
||||
YY_ASSERT (yynewState->yyisState);
|
||||
@@ -1382,7 +1382,7 @@ yyglrShiftDefer (yyGLRStack* yystackp, ptrdiff_t yyk, yy_state_t yylrState,
|
||||
`----------------------------------------------------------------------*/
|
||||
|
||||
static inline void
|
||||
yy_reduce_print (yybool yynormal, yyGLRStackItem* yyvsp, ptrdiff_t yyk,
|
||||
yy_reduce_print (yybool yynormal, yyGLRStackItem* yyvsp, YYPTRDIFF_T yyk,
|
||||
yyRuleNum yyrule]b4_user_formals[)
|
||||
{
|
||||
int yynrhs = yyrhsLength (yyrule);]b4_locations_if([
|
||||
@@ -1415,7 +1415,7 @@ yy_reduce_print (yybool yynormal, yyGLRStackItem* yyvsp, ptrdiff_t yyk,
|
||||
* and *YYLOCP to the computed location (if any). Return value is as
|
||||
* for userAction. */
|
||||
static inline YYRESULTTAG
|
||||
yydoAction (yyGLRStack* yystackp, ptrdiff_t yyk, yyRuleNum yyrule,
|
||||
yydoAction (yyGLRStack* yystackp, YYPTRDIFF_T yyk, yyRuleNum yyrule,
|
||||
YYSTYPE* yyvalp]b4_locuser_formals[)
|
||||
{
|
||||
int yynrhs = yyrhsLength (yyrule);
|
||||
@@ -1467,10 +1467,10 @@ yydoAction (yyGLRStack* yystackp, ptrdiff_t yyk, yyRuleNum yyrule,
|
||||
* added to the options for the existing state's semantic value.
|
||||
*/
|
||||
static inline YYRESULTTAG
|
||||
yyglrReduce (yyGLRStack* yystackp, ptrdiff_t yyk, yyRuleNum yyrule,
|
||||
yyglrReduce (yyGLRStack* yystackp, YYPTRDIFF_T yyk, yyRuleNum yyrule,
|
||||
yybool yyforceEval]b4_user_formals[)
|
||||
{
|
||||
ptrdiff_t yyposn = yystackp->yytops.yystates[yyk]->yyposn;
|
||||
YYPTRDIFF_T yyposn = yystackp->yytops.yystates[yyk]->yyposn;
|
||||
|
||||
if (yyforceEval || yystackp->yysplitPoint == YY_NULLPTR)
|
||||
{
|
||||
@@ -1492,7 +1492,7 @@ yyglrReduce (yyGLRStack* yystackp, ptrdiff_t yyk, yyRuleNum yyrule,
|
||||
}
|
||||
else
|
||||
{
|
||||
ptrdiff_t yyi;
|
||||
YYPTRDIFF_T yyi;
|
||||
int yyn;
|
||||
yyGLRState* yys, *yys0 = yystackp->yytops.yystates[yyk];
|
||||
yy_state_t yynewLRState;
|
||||
@@ -1534,8 +1534,8 @@ yyglrReduce (yyGLRStack* yystackp, ptrdiff_t yyk, yyRuleNum yyrule,
|
||||
return yyok;
|
||||
}
|
||||
|
||||
static ptrdiff_t
|
||||
yysplitStack (yyGLRStack* yystackp, ptrdiff_t yyk)
|
||||
static YYPTRDIFF_T
|
||||
yysplitStack (yyGLRStack* yystackp, YYPTRDIFF_T yyk)
|
||||
{
|
||||
if (yystackp->yysplitPoint == YY_NULLPTR)
|
||||
{
|
||||
@@ -1544,8 +1544,8 @@ yysplitStack (yyGLRStack* yystackp, ptrdiff_t yyk)
|
||||
}
|
||||
if (yystackp->yytops.yycapacity <= yystackp->yytops.yysize)
|
||||
{
|
||||
ptrdiff_t state_size = sizeof yystackp->yytops.yystates[0];
|
||||
ptrdiff_t half_max_capacity = YYSIZEMAX / 2 / state_size;
|
||||
YYPTRDIFF_T state_size = YYSIZEOF (yystackp->yytops.yystates[0]);
|
||||
YYPTRDIFF_T half_max_capacity = YYSIZE_MAXIMUM / 2 / state_size;
|
||||
if (half_max_capacity < yystackp->yytops.yycapacity)
|
||||
yyMemoryExhausted (yystackp);
|
||||
yystackp->yytops.yycapacity *= 2;
|
||||
@@ -1554,7 +1554,7 @@ yysplitStack (yyGLRStack* yystackp, ptrdiff_t yyk)
|
||||
yyGLRState** yynewStates
|
||||
= YY_CAST (yyGLRState**,
|
||||
YYREALLOC (yystackp->yytops.yystates,
|
||||
(YY_CAST (size_t, yystackp->yytops.yycapacity)
|
||||
(YY_CAST (YYSIZE_T, yystackp->yytops.yycapacity)
|
||||
* sizeof yynewStates[0])));
|
||||
if (yynewStates == YY_NULLPTR)
|
||||
yyMemoryExhausted (yystackp);
|
||||
@@ -1565,7 +1565,7 @@ yysplitStack (yyGLRStack* yystackp, ptrdiff_t yyk)
|
||||
yybool* yynewLookaheadNeeds
|
||||
= YY_CAST (yybool*,
|
||||
YYREALLOC (yystackp->yytops.yylookaheadNeeds,
|
||||
(YY_CAST (size_t, yystackp->yytops.yycapacity)
|
||||
(YY_CAST (YYSIZE_T, yystackp->yytops.yycapacity)
|
||||
* sizeof yynewLookaheadNeeds[0])));
|
||||
if (yynewLookaheadNeeds == YY_NULLPTR)
|
||||
yyMemoryExhausted (yystackp);
|
||||
@@ -1996,8 +1996,8 @@ yycompressStack (yyGLRStack* yystackp)
|
||||
}
|
||||
|
||||
static YYRESULTTAG
|
||||
yyprocessOneStack (yyGLRStack* yystackp, ptrdiff_t yyk,
|
||||
ptrdiff_t yyposn]b4_pure_formals[)
|
||||
yyprocessOneStack (yyGLRStack* yystackp, YYPTRDIFF_T yyk,
|
||||
YYPTRDIFF_T yyposn]b4_pure_formals[)
|
||||
{
|
||||
while (yystackp->yytops.yystates[yyk] != YY_NULLPTR)
|
||||
{
|
||||
@@ -2040,7 +2040,7 @@ yyprocessOneStack (yyGLRStack* yystackp, ptrdiff_t yyk,
|
||||
for (/* nothing */; *yyconflicts; yyconflicts += 1)
|
||||
{
|
||||
YYRESULTTAG yyflag;
|
||||
ptrdiff_t yynewStack = yysplitStack (yystackp, yyk);
|
||||
YYPTRDIFF_T yynewStack = yysplitStack (yystackp, yyk);
|
||||
YY_DPRINTF ((stderr, "Splitting off stack %ld from %ld.\n",
|
||||
YY_CAST (long, yynewStack), YY_CAST (long, yyk)));
|
||||
yyflag = yyglrReduce (yystackp, yynewStack,
|
||||
@@ -2121,6 +2121,8 @@ yypcontext_expected_tokens (const yyGLRStack* yystackp,
|
||||
yyarg[yycount++] = YY_CAST (yysymbol_kind_t, yyx);
|
||||
}
|
||||
}
|
||||
if (yyarg && yycount == 0 && 0 < yyargn)
|
||||
yyarg[0] = ]b4_symbol(-2, kind)[;
|
||||
return yycount;
|
||||
}]])[
|
||||
|
||||
@@ -2228,7 +2230,7 @@ yyreportSyntaxError (yyGLRStack* yystackp]b4_user_formals[)
|
||||
one per "expected"). */
|
||||
yysymbol_kind_t yyarg[YYARGS_MAX];
|
||||
/* Cumulated lengths of YYARG. */
|
||||
ptrdiff_t yysize = 0;
|
||||
YYPTRDIFF_T yysize = 0;
|
||||
|
||||
/* Actual size of YYARG. */
|
||||
int yycount
|
||||
@@ -2259,11 +2261,11 @@ yyreportSyntaxError (yyGLRStack* yystackp]b4_user_formals[)
|
||||
int yyi;
|
||||
for (yyi = 0; yyi < yycount; ++yyi)
|
||||
{
|
||||
ptrdiff_t yysz
|
||||
YYPTRDIFF_T yysz
|
||||
= ]b4_parse_error_case(
|
||||
[verbose], [[yytnamerr (YY_NULLPTR, yytname[yyarg[yyi]])]],
|
||||
[[yystrlen (yysymbol_name (yyarg[yyi]))]]);[
|
||||
if (YYSIZEMAX - yysize < yysz)
|
||||
if (YYSIZE_MAXIMUM - yysize < yysz)
|
||||
yysize_overflow = yytrue;
|
||||
else
|
||||
yysize += yysz;
|
||||
@@ -2271,7 +2273,7 @@ yyreportSyntaxError (yyGLRStack* yystackp]b4_user_formals[)
|
||||
}
|
||||
|
||||
if (!yysize_overflow)
|
||||
yymsg = YY_CAST (char *, YYMALLOC (YY_CAST (size_t, yysize)));
|
||||
yymsg = YY_CAST (char *, YYMALLOC (YY_CAST (YYSIZE_T, yysize)));
|
||||
|
||||
if (yymsg)
|
||||
{
|
||||
@@ -2348,7 +2350,7 @@ yyrecoverSyntaxError (yyGLRStack* yystackp]b4_user_formals[)
|
||||
|
||||
/* Reduce to one stack. */
|
||||
{
|
||||
ptrdiff_t yyk;
|
||||
YYPTRDIFF_T yyk;
|
||||
for (yyk = 0; yyk < yystackp->yytops.yysize; yyk += 1)
|
||||
if (yystackp->yytops.yystates[yyk] != YY_NULLPTR)
|
||||
break;
|
||||
@@ -2423,7 +2425,7 @@ yyparse (]m4_ifset([b4_parse_param], [b4_formals(b4_parse_param)], [void])[)
|
||||
int yyresult;
|
||||
yyGLRStack yystack;
|
||||
yyGLRStack* const yystackp = &yystack;
|
||||
ptrdiff_t yyposn;
|
||||
YYPTRDIFF_T yyposn;
|
||||
|
||||
YY_DPRINTF ((stderr, "Starting parse\n"));
|
||||
|
||||
@@ -2505,7 +2507,7 @@ b4_dollar_popdef])[]dnl
|
||||
while (yytrue)
|
||||
{
|
||||
yysymbol_kind_t yytoken_to_shift;
|
||||
ptrdiff_t yys;
|
||||
YYPTRDIFF_T yys;
|
||||
|
||||
for (yys = 0; yys < yystack.yytops.yysize; yys += 1)
|
||||
yystackp->yytops.yylookaheadNeeds[yys] = yychar != ]b4_symbol(-2, id)[;
|
||||
@@ -2612,8 +2614,8 @@ b4_dollar_popdef])[]dnl
|
||||
yyGLRState** yystates = yystack.yytops.yystates;
|
||||
if (yystates)
|
||||
{
|
||||
ptrdiff_t yysize = yystack.yytops.yysize;
|
||||
ptrdiff_t yyk;
|
||||
YYPTRDIFF_T yysize = yystack.yytops.yysize;
|
||||
YYPTRDIFF_T yyk;
|
||||
for (yyk = 0; yyk < yysize; yyk += 1)
|
||||
if (yystates[yyk])
|
||||
{
|
||||
@@ -2660,7 +2662,7 @@ yypstates (yyGLRState* yyst)
|
||||
}
|
||||
|
||||
static void
|
||||
yypstack (yyGLRStack* yystackp, ptrdiff_t yyk)
|
||||
yypstack (yyGLRStack* yystackp, YYPTRDIFF_T yyk)
|
||||
{
|
||||
yypstates (yystackp->yytops.yystates[yyk]);
|
||||
}
|
||||
@@ -2705,7 +2707,7 @@ yypdumpstack (yyGLRStack* yystackp)
|
||||
|
||||
YY_FPRINTF ((stderr, "Tops:"));
|
||||
{
|
||||
ptrdiff_t yyi;
|
||||
YYPTRDIFF_T yyi;
|
||||
for (yyi = 0; yyi < yystackp->yytops.yysize; yyi += 1)
|
||||
YY_FPRINTF ((stderr, "%ld: %ld; ", YY_CAST (long, yyi),
|
||||
YYINDEX (yystackp->yytops.yystates[yyi])));
|
||||
@@ -2731,7 +2733,8 @@ m4_if(b4_prefix, [yy], [],
|
||||
#define yynerrs ]b4_prefix[nerrs]b4_locations_if([[
|
||||
#define yylloc ]b4_prefix[lloc]])])[
|
||||
|
||||
]m4_ifdef([b4_pre_epilogue], [b4_pre_epilogue])[]dnl This is a hack for glr.cc. To remove when we have a better glr.cc.
|
||||
b4_percent_code_get([[epilogue]])[]dnl
|
||||
]b4_glr_cc_if([b4_glr_cc_pre_epilogue
|
||||
b4_glr_cc_cleanup])[
|
||||
]b4_percent_code_get([[epilogue]])[]dnl
|
||||
b4_epilogue[]dnl
|
||||
b4_output_end
|
||||
|
||||
+57
-44
@@ -66,12 +66,6 @@ m4_defn([b4_parse_param]))],
|
||||
[[b4_namespace_ref::b4_parser_class[& yyparser], [[yyparser]]]])
|
||||
])
|
||||
|
||||
# b4_declare_symbol_enum
|
||||
# ----------------------
|
||||
m4_append([b4_declare_symbol_enum],
|
||||
[[typedef symbol_kind_type yysymbol_kind_t;
|
||||
]])
|
||||
|
||||
|
||||
# b4_yy_symbol_print_define
|
||||
# -------------------------
|
||||
@@ -105,15 +99,9 @@ yyerror (]b4_locations_if([[const ]b4_namespace_ref::b4_parser_class[::location_
|
||||
]])[]m4_ifset([b4_parse_param], [b4_formals(b4_parse_param),
|
||||
])[const char* msg);]])[
|
||||
|
||||
]b4_percent_define_flag_if([[global_tokens_and_yystype]], [],
|
||||
[m4_define([b4_pre_epilogue],
|
||||
[[/* The user is using the C++ token kind, not the C one. */
|
||||
#undef ]b4_symbol(0, [id])
|
||||
])])[
|
||||
|
||||
# Hijack the epilogue to define implementations (yyerror, parser member
|
||||
# Inserted before the epilogue to define implementations (yyerror, parser member
|
||||
# functions etc.).
|
||||
]m4_append([b4_epilogue],
|
||||
]m4_define([b4_glr_cc_pre_epilogue],
|
||||
[b4_syncline([@oline@], [@ofile@])dnl
|
||||
[
|
||||
/*------------------.
|
||||
@@ -222,6 +210,57 @@ b4_namespace_close[]dnl
|
||||
])
|
||||
|
||||
|
||||
m4_define([b4_define_symbol_kind],
|
||||
[m4_format([#define %-15s %s],
|
||||
b4_symbol($][1, kind_base),
|
||||
b4_namespace_ref[::]b4_parser_class[::symbol_kind::]b4_symbol($1, kind_base))
|
||||
])
|
||||
|
||||
# b4_glr_cc_setup
|
||||
# ---------------
|
||||
# Setup redirections for glr.c: Map the names used in c.m4 to the ones used
|
||||
# in c++.m4.
|
||||
m4_define([b4_glr_cc_setup],
|
||||
[[#undef ]b4_symbol(-2, [id])[
|
||||
#define ]b4_symbol(-2, [id])[ ]b4_namespace_ref[::]b4_parser_class[::token::]b4_symbol(-2, [id])[
|
||||
#undef ]b4_symbol(0, [id])[
|
||||
#define ]b4_symbol(0, [id])[ ]b4_namespace_ref[::]b4_parser_class[::token::]b4_symbol(0, [id])[
|
||||
#undef ]b4_symbol(1, [id])[
|
||||
#define ]b4_symbol(1, [id])[ ]b4_namespace_ref[::]b4_parser_class[::token::]b4_symbol(1, [id])[
|
||||
|
||||
#ifndef ]b4_api_PREFIX[STYPE
|
||||
# define ]b4_api_PREFIX[STYPE ]b4_namespace_ref[::]b4_parser_class[::semantic_type
|
||||
#endif
|
||||
#ifndef ]b4_api_PREFIX[LTYPE
|
||||
# define ]b4_api_PREFIX[LTYPE ]b4_namespace_ref[::]b4_parser_class[::location_type
|
||||
#endif
|
||||
|
||||
typedef ]b4_namespace_ref[::]b4_parser_class[::symbol_kind_type yysymbol_kind_t;
|
||||
|
||||
// Expose C++ symbol kinds to C.
|
||||
]b4_define_symbol_kind(-2)dnl
|
||||
b4_symbol_foreach([b4_define_symbol_kind])])[
|
||||
]])
|
||||
|
||||
|
||||
m4_define([b4_undef_symbol_kind],
|
||||
[[#undef ]b4_symbol($1, kind_base)[
|
||||
]])
|
||||
|
||||
|
||||
# b4_glr_cc_cleanup
|
||||
# -----------------
|
||||
# Remove redirections for glr.c.
|
||||
m4_define([b4_glr_cc_cleanup],
|
||||
[[#undef ]b4_symbol(-2, [id])[
|
||||
#undef ]b4_symbol(0, [id])[
|
||||
#undef ]b4_symbol(1, [id])[
|
||||
|
||||
]b4_undef_symbol_kind(-2)dnl
|
||||
b4_symbol_foreach([b4_undef_symbol_kind])dnl
|
||||
])
|
||||
|
||||
|
||||
# b4_shared_declarations(hh|cc)
|
||||
# -----------------------------
|
||||
# Declaration that might either go into the header (if --defines, $1 = hh)
|
||||
@@ -333,48 +372,22 @@ b4_percent_code_get([[requires]])[
|
||||
]b4_parse_param_vars[
|
||||
};
|
||||
|
||||
]dnl Redirections for glr.c.
|
||||
b4_percent_define_flag_if([[global_tokens_and_yystype]],
|
||||
[b4_token_defines
|
||||
])[
|
||||
]b4_namespace_close[
|
||||
|
||||
]dnl Map the name used in c.m4 to the one used in c++.m4.
|
||||
[#undef ]b4_symbol(-2, [id])[
|
||||
#define ]b4_symbol(-2, [id])[ ]b4_namespace_ref[::]b4_parser_class[::token::]b4_symbol(-2, [id])[
|
||||
#undef ]b4_symbol(0, [id])[
|
||||
#define ]b4_symbol(0, [id])[ ]b4_namespace_ref[::]b4_parser_class[::token::]b4_symbol(0, [id])[
|
||||
#undef ]b4_symbol(1, [id])[
|
||||
#define ]b4_symbol(1, [id])[ ]b4_namespace_ref[::]b4_parser_class[::token::]b4_symbol(1, [id])[
|
||||
|
||||
#ifndef ]b4_api_PREFIX[STYPE
|
||||
# define ]b4_api_PREFIX[STYPE ]b4_namespace_ref[::]b4_parser_class[::semantic_type
|
||||
#endif
|
||||
#ifndef ]b4_api_PREFIX[LTYPE
|
||||
# define ]b4_api_PREFIX[LTYPE ]b4_namespace_ref[::]b4_parser_class[::location_type
|
||||
#endif
|
||||
|
||||
]m4_define([b4_declare_symbol_enum],
|
||||
[[typedef ]b4_namespace_ref[::]b4_parser_class[::symbol_kind_type yysymbol_kind_t;
|
||||
#define ]b4_symbol_prefix[YYEMPTY ]b4_namespace_ref[::]b4_parser_class[::symbol_kind::]b4_symbol_prefix[YYEMPTY
|
||||
#define ]b4_symbol_prefix[YYerror ]b4_namespace_ref[::]b4_parser_class[::symbol_kind::]b4_symbol_prefix[YYerror
|
||||
#define ]b4_symbol_prefix[YYEOF ]b4_namespace_ref[::]b4_parser_class[::symbol_kind::]b4_symbol_prefix[YYEOF
|
||||
#define ]b4_symbol_prefix[YYUNDEF ]b4_namespace_ref[::]b4_parser_class[::symbol_kind::]b4_symbol_prefix[YYUNDEF
|
||||
]])[
|
||||
]b4_percent_code_get([[provides]])[
|
||||
]m4_popdef([b4_parse_param])dnl
|
||||
])
|
||||
])[
|
||||
|
||||
b4_defines_if(
|
||||
]b4_defines_if(
|
||||
[b4_output_begin([b4_spec_header_file])
|
||||
b4_copyright([Skeleton interface for Bison GLR parsers in C++],
|
||||
[2002-2015, 2018-2020])[
|
||||
// C++ GLR parser skeleton written by Akim Demaille.
|
||||
|
||||
]b4_disclaimer[
|
||||
]b4_cpp_guard_open([b4_spec_header_file])[
|
||||
]b4_cpp_guard_open([b4_spec_mapped_header_file])[
|
||||
]b4_shared_declarations[
|
||||
]b4_cpp_guard_close([b4_spec_header_file])[
|
||||
]b4_cpp_guard_close([b4_spec_mapped_header_file])[
|
||||
]b4_output_end])
|
||||
|
||||
# Let glr.c (and b4_shared_declarations) believe that the user
|
||||
|
||||
+12
-5
@@ -143,7 +143,7 @@ m4_define([b4_token_enum],
|
||||
]],
|
||||
b4_symbol([$1], [tag]),
|
||||
b4_symbol([$1], [id]),
|
||||
b4_symbol([$1], b4_api_token_raw_if([[number]], [[user_number]])))])])
|
||||
b4_symbol([$1], b4_api_token_raw_if([[number]], [[code]])))])])
|
||||
|
||||
|
||||
# b4_token_enums
|
||||
@@ -159,13 +159,20 @@ b4_symbol_foreach([b4_token_enum])])])
|
||||
## Symbol kinds. ##
|
||||
## -------------- ##
|
||||
|
||||
|
||||
# b4_symbol_kind(NUM)
|
||||
# -------------------
|
||||
m4_define([b4_symbol_kind],
|
||||
[SymbolKind.b4_symbol_kind_base($@)])
|
||||
|
||||
|
||||
# b4_symbol_enum(SYMBOL-NUM)
|
||||
# --------------------------
|
||||
# Output the definition of this symbol as an enum.
|
||||
m4_define([b4_symbol_enum],
|
||||
[m4_format([ %-30s %s],
|
||||
m4_format([[%s(%s)%s]],
|
||||
b4_symbol([$1], [kind]),
|
||||
b4_symbol([$1], [kind_base]),
|
||||
[$1],
|
||||
m4_if([$1], b4_last_symbol, [[;]], [[,]])),
|
||||
[b4_symbol_tag_comment([$1])])])
|
||||
@@ -255,11 +262,11 @@ m4_define([b4_declare_symbol_enum],
|
||||
|
||||
|
||||
|
||||
# b4_case(ID, CODE)
|
||||
# -----------------
|
||||
# b4_case(ID, CODE, [COMMENTS])
|
||||
# -----------------------------
|
||||
# We need to fool Java's stupid unreachable code detection.
|
||||
m4_define([b4_case],
|
||||
[ case $1:
|
||||
[ case $1:m4_ifval([$3], [ b4_comment([$3])])
|
||||
if (yyn == $1)
|
||||
$2;
|
||||
break;
|
||||
|
||||
+122
-114
@@ -59,6 +59,13 @@ m4_define([b4_integral_parser_table_define],
|
||||
};dnl
|
||||
])
|
||||
|
||||
|
||||
# b4_symbol_kind(NUM)
|
||||
# -------------------
|
||||
m4_define([b4_symbol_kind],
|
||||
[symbol_kind::b4_symbol_kind_base($@)])
|
||||
|
||||
|
||||
# b4_symbol_value_template(VAL, SYMBOL-NUM, [TYPE])
|
||||
# -------------------------------------------------
|
||||
# Same as b4_symbol_value, but used in a template method. It makes
|
||||
@@ -241,6 +248,23 @@ m4_define([b4_shared_declarations],
|
||||
/// Report a syntax error.
|
||||
void error (const syntax_error& err);
|
||||
|
||||
]b4_parse_error_bmatch(
|
||||
[custom\|detailed],
|
||||
[[ /// The user-facing name of the symbol whose (internal) number is
|
||||
/// YYSYMBOL. No bounds checking.
|
||||
static const char *symbol_name (symbol_kind_type yysymbol);]],
|
||||
[simple],
|
||||
[[#if ]b4_api_PREFIX[DEBUG || ]b4_token_table_flag[
|
||||
/// The user-facing name of the symbol whose (internal) number is
|
||||
/// YYSYMBOL. No bounds checking.
|
||||
static const char *symbol_name (symbol_kind_type yysymbol);
|
||||
#endif // #if ]b4_api_PREFIX[DEBUG || ]b4_token_table_flag[
|
||||
]],
|
||||
[verbose],
|
||||
[[ /// The user-facing name of the symbol whose (internal) number is
|
||||
/// YYSYMBOL. No bounds checking.
|
||||
static std::string symbol_name (symbol_kind_type yysymbol);]])[
|
||||
|
||||
]b4_token_constructor_define[
|
||||
]b4_parse_error_bmatch([custom\|detailed\|verbose], [[
|
||||
class context
|
||||
@@ -317,26 +341,14 @@ m4_define([b4_shared_declarations],
|
||||
static symbol_kind_type yytranslate_ (int t);
|
||||
|
||||
]b4_parse_error_bmatch(
|
||||
[custom\|detailed],
|
||||
[[ /// The user-facing name of the symbol whose (internal) number is
|
||||
/// YYSYMBOL. No bounds checking.
|
||||
static const char *symbol_name (symbol_kind_type yysymbol);]],
|
||||
[simple],
|
||||
[[#if ]b4_api_PREFIX[DEBUG || ]b4_token_table_flag[
|
||||
/// The user-facing name of the symbol whose (internal) number is
|
||||
/// YYSYMBOL. No bounds checking.
|
||||
static const char *symbol_name (symbol_kind_type yysymbol);
|
||||
|
||||
/// For a symbol, its name in clear.
|
||||
static const char* const yytname_[];
|
||||
#endif // #if ]b4_api_PREFIX[DEBUG || ]b4_token_table_flag[
|
||||
]],
|
||||
[verbose],
|
||||
[[ /// The user-facing name of the symbol whose (internal) number is
|
||||
/// YYSYMBOL. No bounds checking.
|
||||
static std::string symbol_name (symbol_kind_type yysymbol);
|
||||
|
||||
/// Convert the symbol name \a n to a form suitable for a diagnostic.
|
||||
[[ /// Convert the symbol name \a n to a form suitable for a diagnostic.
|
||||
static std::string yytnamerr_ (const char *yystr);
|
||||
|
||||
/// For a symbol, its name in clear.
|
||||
@@ -474,20 +486,13 @@ m4_define([b4_shared_declarations],
|
||||
};
|
||||
|
||||
]b4_parse_param_vars[
|
||||
]b4_percent_code_get([[yy_bison_internal_hook]])[
|
||||
};
|
||||
|
||||
]b4_token_ctor_if([b4_yytranslate_define([$1])[
|
||||
]b4_public_types_define([$1])])[
|
||||
]b4_namespace_close[
|
||||
|
||||
]b4_percent_define_flag_if([[global_tokens_and_yystype]],
|
||||
[b4_token_defines
|
||||
|
||||
#ifndef ]b4_api_PREFIX[STYPE
|
||||
// Redirection for backward compatibility.
|
||||
# define ]b4_api_PREFIX[STYPE b4_namespace_ref::b4_parser_class::semantic_type
|
||||
#endif
|
||||
])[
|
||||
]b4_percent_code_get([[provides]])[
|
||||
]])
|
||||
|
||||
@@ -500,16 +505,16 @@ b4_defines_if(
|
||||
b4_copyright([Skeleton interface for Bison LALR(1) parsers in C++])
|
||||
[
|
||||
/**
|
||||
** \file ]b4_spec_header_file[
|
||||
** \file ]b4_spec_mapped_header_file[
|
||||
** Define the ]b4_namespace_ref[::parser class.
|
||||
*/
|
||||
|
||||
// C++ LALR(1) parser skeleton written by Akim Demaille.
|
||||
|
||||
]b4_disclaimer[
|
||||
]b4_cpp_guard_open([b4_spec_header_file])[
|
||||
]b4_cpp_guard_open([b4_spec_mapped_header_file])[
|
||||
]b4_shared_declarations(hh)[
|
||||
]b4_cpp_guard_close([b4_spec_header_file])[
|
||||
]b4_cpp_guard_close([b4_spec_mapped_header_file])[
|
||||
]b4_output_end[
|
||||
]])
|
||||
|
||||
@@ -607,83 +612,6 @@ m4_if(b4_prefix, [yy], [],
|
||||
#define YYRECOVERING() (!!yyerrstatus_)
|
||||
|
||||
]b4_namespace_open[
|
||||
]b4_parse_error_bmatch([custom\|detailed],
|
||||
[[ const char *
|
||||
]b4_parser_class[::symbol_name (symbol_kind_type yysymbol)
|
||||
{
|
||||
static const char *const yy_sname[] =
|
||||
{
|
||||
]b4_symbol_names[
|
||||
};]b4_has_translations_if([[
|
||||
/* YYTRANSLATABLE[SYMBOL-NUM] -- Whether YY_SNAME[SYMBOL-NUM] is
|
||||
internationalizable. */
|
||||
static ]b4_int_type_for([b4_translatable])[ yytranslatable[] =
|
||||
{
|
||||
]b4_translatable[
|
||||
};
|
||||
return (yysymbol < YYNTOKENS && yytranslatable[yysymbol]
|
||||
? _(yy_sname[yysymbol])
|
||||
: yy_sname[yysymbol]);]], [[
|
||||
return yy_sname[yysymbol];]])[
|
||||
}
|
||||
]],
|
||||
[simple],
|
||||
[[#if ]b4_api_PREFIX[DEBUG || ]b4_token_table_flag[
|
||||
const char *
|
||||
]b4_parser_class[::symbol_name (symbol_kind_type yysymbol)
|
||||
{
|
||||
return yytname_[yysymbol];
|
||||
}
|
||||
#endif // #if ]b4_api_PREFIX[DEBUG || ]b4_token_table_flag[
|
||||
]],
|
||||
[verbose],
|
||||
[[ /* Return YYSTR after stripping away unnecessary quotes and
|
||||
backslashes, so that it's suitable for yyerror. The heuristic is
|
||||
that double-quoting is unnecessary unless the string contains an
|
||||
apostrophe, a comma, or backslash (other than backslash-backslash).
|
||||
YYSTR is taken from yytname. */
|
||||
std::string
|
||||
]b4_parser_class[::yytnamerr_ (const char *yystr)
|
||||
{
|
||||
if (*yystr == '"')
|
||||
{
|
||||
std::string yyr;
|
||||
char const *yyp = yystr;
|
||||
|
||||
for (;;)
|
||||
switch (*++yyp)
|
||||
{
|
||||
case '\'':
|
||||
case ',':
|
||||
goto do_not_strip_quotes;
|
||||
|
||||
case '\\':
|
||||
if (*++yyp != '\\')
|
||||
goto do_not_strip_quotes;
|
||||
else
|
||||
goto append;
|
||||
|
||||
append:
|
||||
default:
|
||||
yyr += *yyp;
|
||||
break;
|
||||
|
||||
case '"':
|
||||
return yyr;
|
||||
}
|
||||
do_not_strip_quotes: ;
|
||||
}
|
||||
|
||||
return yystr;
|
||||
}
|
||||
|
||||
std::string
|
||||
]b4_parser_class[::symbol_name (symbol_kind_type yysymbol)
|
||||
{
|
||||
return yytnamerr_ (yytname_[yysymbol]);
|
||||
}
|
||||
]])[
|
||||
|
||||
/// Build a parser object.
|
||||
]b4_parser_class::b4_parser_class[ (]b4_parse_param_decl[)
|
||||
#if ]b4_api_PREFIX[DEBUG
|
||||
@@ -737,7 +665,7 @@ m4_if(b4_prefix, [yy], [],
|
||||
]b4_parser_class[::by_state::kind () const YY_NOEXCEPT
|
||||
{
|
||||
if (state == empty_state)
|
||||
return symbol_kind::]b4_symbol(-2, kind)[;
|
||||
return ]b4_symbol(-2, kind)[;
|
||||
else
|
||||
return YY_CAST (symbol_kind_type, yystos_[+state]);
|
||||
}
|
||||
@@ -762,7 +690,7 @@ m4_if(b4_prefix, [yy], [],
|
||||
b4_symbol_variant([that.kind ()],
|
||||
[value], [move], [YY_MOVE (that.value)])])[
|
||||
// that is emptied.
|
||||
that.kind_ = symbol_kind::]b4_symbol(-2, kind)[;
|
||||
that.kind_ = ]b4_symbol(-2, kind)[;
|
||||
}
|
||||
|
||||
#if YY_CPLUSPLUS < 201103L
|
||||
@@ -815,7 +743,7 @@ m4_if(b4_prefix, [yy], [],
|
||||
{
|
||||
symbol_kind_type yykind = yysym.kind ();
|
||||
yyo << (yykind < YYNTOKENS ? "token" : "nterm")
|
||||
<< ' ' << symbol_name (yykind) << " ("]b4_locations_if([
|
||||
<< ' ' << yysym.name () << " ("]b4_locations_if([
|
||||
<< yysym.location << ": "])[;
|
||||
]b4_symbol_actions([printer])[
|
||||
yyo << ')';
|
||||
@@ -991,13 +919,13 @@ b4_dollar_popdef])[]dnl
|
||||
}
|
||||
YY_SYMBOL_PRINT ("Next token is", yyla);
|
||||
|
||||
if (yyla.kind () == ]symbol_kind::b4_symbol(1, kind)[)
|
||||
if (yyla.kind () == ]b4_symbol(1, kind)[)
|
||||
{
|
||||
// The scanner already issued an error message, process directly
|
||||
// to error recovery. But do not keep the error token as
|
||||
// lookahead, it is too special and may lead us to an endless
|
||||
// loop in error recovery. */
|
||||
yyla.kind_ = ]symbol_kind::b4_symbol(2, kind)[;
|
||||
yyla.kind_ = ]b4_symbol(2, kind)[;
|
||||
goto yyerrlab1;
|
||||
}
|
||||
|
||||
@@ -1134,7 +1062,7 @@ b4_dollar_popdef])[]dnl
|
||||
error, discard it. */
|
||||
|
||||
// Return failure if at end of input.
|
||||
if (yyla.kind () == symbol_kind::]b4_symbol_prefix[YYEOF)
|
||||
if (yyla.kind () == ]b4_symbol(0, kind)[)
|
||||
YYABORT;
|
||||
else if (!yyla.empty ())
|
||||
{
|
||||
@@ -1175,9 +1103,9 @@ b4_dollar_popdef])[]dnl
|
||||
yyn = yypact_[+yystack_[0].state];
|
||||
if (!yy_pact_value_is_default_ (yyn))
|
||||
{
|
||||
yyn += symbol_kind::]b4_symbol(1, kind)[;
|
||||
yyn += ]b4_symbol(1, kind)[;
|
||||
if (0 <= yyn && yyn <= yylast_
|
||||
&& yycheck_[yyn] == symbol_kind::]b4_symbol(1, kind)[)
|
||||
&& yycheck_[yyn] == ]b4_symbol(1, kind)[)
|
||||
{
|
||||
yyn = yytable_[yyn];
|
||||
if (0 < yyn)
|
||||
@@ -1267,8 +1195,86 @@ b4_dollar_popdef])[]dnl
|
||||
{
|
||||
error (]b4_join(b4_locations_if([yyexc.location]),
|
||||
[[yyexc.what ()]])[);
|
||||
}]b4_parse_error_bmatch([custom\|detailed\|verbose], [[
|
||||
}
|
||||
|
||||
]b4_parse_error_bmatch([custom\|detailed],
|
||||
[[ const char *
|
||||
]b4_parser_class[::symbol_name (symbol_kind_type yysymbol)
|
||||
{
|
||||
static const char *const yy_sname[] =
|
||||
{
|
||||
]b4_symbol_names[
|
||||
};]b4_has_translations_if([[
|
||||
/* YYTRANSLATABLE[SYMBOL-NUM] -- Whether YY_SNAME[SYMBOL-NUM] is
|
||||
internationalizable. */
|
||||
static ]b4_int_type_for([b4_translatable])[ yytranslatable[] =
|
||||
{
|
||||
]b4_translatable[
|
||||
};
|
||||
return (yysymbol < YYNTOKENS && yytranslatable[yysymbol]
|
||||
? _(yy_sname[yysymbol])
|
||||
: yy_sname[yysymbol]);]], [[
|
||||
return yy_sname[yysymbol];]])[
|
||||
}
|
||||
]],
|
||||
[simple],
|
||||
[[#if ]b4_api_PREFIX[DEBUG || ]b4_token_table_flag[
|
||||
const char *
|
||||
]b4_parser_class[::symbol_name (symbol_kind_type yysymbol)
|
||||
{
|
||||
return yytname_[yysymbol];
|
||||
}
|
||||
#endif // #if ]b4_api_PREFIX[DEBUG || ]b4_token_table_flag[
|
||||
]],
|
||||
[verbose],
|
||||
[[ /* Return YYSTR after stripping away unnecessary quotes and
|
||||
backslashes, so that it's suitable for yyerror. The heuristic is
|
||||
that double-quoting is unnecessary unless the string contains an
|
||||
apostrophe, a comma, or backslash (other than backslash-backslash).
|
||||
YYSTR is taken from yytname. */
|
||||
std::string
|
||||
]b4_parser_class[::yytnamerr_ (const char *yystr)
|
||||
{
|
||||
if (*yystr == '"')
|
||||
{
|
||||
std::string yyr;
|
||||
char const *yyp = yystr;
|
||||
|
||||
for (;;)
|
||||
switch (*++yyp)
|
||||
{
|
||||
case '\'':
|
||||
case ',':
|
||||
goto do_not_strip_quotes;
|
||||
|
||||
case '\\':
|
||||
if (*++yyp != '\\')
|
||||
goto do_not_strip_quotes;
|
||||
else
|
||||
goto append;
|
||||
|
||||
append:
|
||||
default:
|
||||
yyr += *yyp;
|
||||
break;
|
||||
|
||||
case '"':
|
||||
return yyr;
|
||||
}
|
||||
do_not_strip_quotes: ;
|
||||
}
|
||||
|
||||
return yystr;
|
||||
}
|
||||
|
||||
std::string
|
||||
]b4_parser_class[::symbol_name (symbol_kind_type yysymbol)
|
||||
{
|
||||
return yytnamerr_ (yytname_[yysymbol]);
|
||||
}
|
||||
]])[
|
||||
|
||||
]b4_parse_error_bmatch([custom\|detailed\|verbose], [[
|
||||
// ]b4_parser_class[::context.
|
||||
]b4_parser_class[::context::context (const ]b4_parser_class[& yyparser, const symbol_type& yyla)
|
||||
: yyparser_ (yyparser)
|
||||
@@ -1291,8 +1297,8 @@ b4_dollar_popdef])[]dnl
|
||||
for (int yyx = 0; yyx < YYNTOKENS; ++yyx)
|
||||
{
|
||||
symbol_kind_type yysym = YY_CAST (symbol_kind_type, yyx);
|
||||
if (yysym != symbol_kind::]b4_symbol(1, kind)[
|
||||
&& yysym != symbol_kind::]b4_symbol_prefix[YYUNDEF
|
||||
if (yysym != ]b4_symbol(1, kind)[
|
||||
&& yysym != ]b4_symbol(2, kind)[
|
||||
&& yyparser_.yy_lac_check_ (yysym))
|
||||
{
|
||||
if (!yyarg)
|
||||
@@ -1314,7 +1320,7 @@ b4_dollar_popdef])[]dnl
|
||||
int yychecklim = yylast_ - yyn + 1;
|
||||
int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
|
||||
for (int yyx = yyxbegin; yyx < yyxend; ++yyx)
|
||||
if (yycheck_[yyx + yyn] == yyx && yyx != symbol_kind::]b4_symbol(1, kind)[
|
||||
if (yycheck_[yyx + yyn] == yyx && yyx != ]b4_symbol(1, kind)[
|
||||
&& !yy_table_value_is_error_ (yytable_[yyx + yyn]))
|
||||
{
|
||||
if (!yyarg)
|
||||
@@ -1326,6 +1332,8 @@ b4_dollar_popdef])[]dnl
|
||||
}
|
||||
}
|
||||
]])[
|
||||
if (yyarg && yycount == 0 && 0 < yyargn)
|
||||
yyarg[0] = ]b4_symbol(-2, kind)[;
|
||||
return yycount;
|
||||
}
|
||||
|
||||
@@ -1402,7 +1410,7 @@ b4_dollar_popdef])[]dnl
|
||||
: yylac_stack_.back ());
|
||||
// Push the resulting state of the reduction.
|
||||
state_type state = yy_lr_goto_state_ (top_state, yyr1_[yyrule]);
|
||||
YYCDEBUG << " G" << state;
|
||||
YYCDEBUG << " G" << int (state);
|
||||
yylac_stack_.push_back (state);
|
||||
}
|
||||
}
|
||||
|
||||
+18
-16
@@ -428,9 +428,10 @@ b4_locations_if([, ref ]b4_location_type[ yylocationp])[)
|
||||
*/
|
||||
public bool parse ()
|
||||
{
|
||||
/// Lookahead and lookahead in internal form.
|
||||
// Lookahead token kind.
|
||||
int yychar = TokenKind.YYEMPTY;
|
||||
SymbolKind yytoken = SymbolKind.]b4_symbol(-2, kind)[;
|
||||
// Lookahead symbol kind.
|
||||
SymbolKind yytoken = ]b4_symbol(-2, kind)[;
|
||||
|
||||
/* State. */
|
||||
int yyn = 0;
|
||||
@@ -509,14 +510,14 @@ m4_popdef([b4_at_dollar])])dnl
|
||||
yytoken = yytranslate_ (yychar);]b4_parse_trace_if([[
|
||||
yy_symbol_print ("Next token is", yytoken, yylval]b4_locations_if([, yylloc])[);]])[
|
||||
|
||||
if (yytoken == SymbolKind.]b4_symbol(1, kind)[)
|
||||
if (yytoken == ]b4_symbol(1, kind)[)
|
||||
{
|
||||
// The scanner already issued an error message, process directly
|
||||
// to error recovery. But do not keep the error token as
|
||||
// lookahead, it is too special and may lead us to an endless
|
||||
// loop in error recovery. */
|
||||
yychar = TokenKind.YYUNDEF;
|
||||
yytoken = SymbolKind.]b4_symbol_prefix[YYUNDEF;]b4_locations_if([[
|
||||
yychar = TokenKind.]b4_symbol(2, id)[;
|
||||
yytoken = ]b4_symbol(2, kind)[;]b4_locations_if([[
|
||||
yyerrloc = yylloc;]])[
|
||||
label = YYERRLAB1;
|
||||
}
|
||||
@@ -587,8 +588,8 @@ m4_popdef([b4_at_dollar])])dnl
|
||||
if (yyerrstatus_ == 0)
|
||||
{
|
||||
++yynerrs_;
|
||||
if (yychar == TokenKind.YYEMPTY)
|
||||
yytoken = SymbolKind.]b4_symbol(-2, kind)[;
|
||||
if (yychar == TokenKind.]b4_symbol(-2, id)[)
|
||||
yytoken = ]b4_symbol(-2, kind)[;
|
||||
yyerror (]b4_locations_if([yylloc, ])[yysyntax_error (yystate, yytoken));
|
||||
}
|
||||
]b4_locations_if([
|
||||
@@ -638,8 +639,8 @@ m4_popdef([b4_at_dollar])])dnl
|
||||
yyn = yypact_[yystate];
|
||||
if (!yy_pact_value_is_default_ (yyn))
|
||||
{
|
||||
yyn += SymbolKind.]b4_symbol(1, kind)[;
|
||||
if (0 <= yyn && yyn <= yylast_ && yycheck_[yyn] == SymbolKind.]b4_symbol(1, kind)[)
|
||||
yyn += ]b4_symbol(1, kind)[;
|
||||
if (0 <= yyn && yyn <= yylast_ && yycheck_[yyn] == ]b4_symbol(1, kind)[)
|
||||
{
|
||||
yyn = yytable_[yyn];
|
||||
if (0 < yyn)
|
||||
@@ -726,7 +727,7 @@ m4_popdef([b4_at_dollar])])dnl
|
||||
will still contain any token that will not be accepted due
|
||||
to an error action in a later state.
|
||||
*/
|
||||
if (tok != SymbolKind.]b4_symbol(-2, kind)[)
|
||||
if (tok != ]b4_symbol(-2, kind)[)
|
||||
{
|
||||
// FIXME: This method of building the message is not compatible
|
||||
// with internationalization.
|
||||
@@ -745,14 +746,14 @@ m4_popdef([b4_at_dollar])])dnl
|
||||
int yyxend = yychecklim < yyntokens_ ? yychecklim : yyntokens_;
|
||||
int count = 0;
|
||||
for (int x = yyxbegin; x < yyxend; ++x)
|
||||
if (yycheck_[x + yyn] == x && x != SymbolKind.]b4_symbol(1, kind)[
|
||||
if (yycheck_[x + yyn] == x && x != ]b4_symbol(1, kind)[
|
||||
&& !yy_table_value_is_error_ (yytable_[x + yyn]))
|
||||
++count;
|
||||
if (count < 5)
|
||||
{
|
||||
count = 0;
|
||||
for (int x = yyxbegin; x < yyxend; ++x)
|
||||
if (yycheck_[x + yyn] == x && x != SymbolKind.]b4_symbol(1, kind)[
|
||||
if (yycheck_[x + yyn] == x && x != ]b4_symbol(1, kind)[
|
||||
&& !yy_table_value_is_error_ (yytable_[x + yyn]))
|
||||
{
|
||||
res ~= count++ == 0 ? ", expecting " : " or ";
|
||||
@@ -841,17 +842,18 @@ m4_popdef([b4_at_dollar])])dnl
|
||||
]b4_translate[
|
||||
@};
|
||||
|
||||
immutable int user_token_number_max_ = ]b4_user_token_number_max[;
|
||||
// Last valid token kind.
|
||||
immutable int code_max = ]b4_code_max[;
|
||||
|
||||
if (t <= 0)
|
||||
return SymbolKind.]b4_symbol_prefix[YYEOF;
|
||||
else if (t <= user_token_number_max_)
|
||||
return ]b4_symbol(0, kind)[;
|
||||
else if (t <= code_max)
|
||||
{
|
||||
import std.conv : to;
|
||||
return to!SymbolKind (translate_table[t]);
|
||||
}
|
||||
else
|
||||
return SymbolKind.]b4_symbol_prefix[YYUNDEF;]])[
|
||||
return ]b4_symbol(2, kind)[;]])[
|
||||
}
|
||||
|
||||
private static immutable int yylast_ = ]b4_last[;
|
||||
|
||||
+31
-27
@@ -53,8 +53,9 @@ b4_use_push_for_pull_if([
|
||||
# allows them to be defined either in parse() when doing pull parsing,
|
||||
# or as class instance variable when doing push parsing.
|
||||
m4_define([b4_define_state],[[
|
||||
/* Lookahead and lookahead in internal form. */
|
||||
/* Lookahead token kind. */
|
||||
int yychar = YYEMPTY_;
|
||||
/* Lookahead symbol kind. */
|
||||
SymbolKind yytoken = null;
|
||||
|
||||
/* State. */
|
||||
@@ -79,7 +80,7 @@ m4_define([b4_define_state],[[
|
||||
]b4_copyright([Skeleton implementation for Bison LALR(1) parsers in Java],
|
||||
[2007-2015, 2018-2020])[
|
||||
]b4_disclaimer[
|
||||
]b4_percent_define_ifdef([package], [package b4_percent_define_get([package]);[
|
||||
]b4_percent_define_ifdef([api.package], [package b4_percent_define_get([api.package]);[
|
||||
]])[
|
||||
]b4_user_pre_prologue[
|
||||
]b4_user_post_prologue[
|
||||
@@ -602,9 +603,9 @@ b4_dollar_popdef[]dnl
|
||||
push_token_consumed = false;]], [b4_parse_trace_if([[
|
||||
yycdebug ("Reading a token");]])[
|
||||
yychar = yylexer.yylex ();
|
||||
yylval = yylexer.getLVal ();]b4_locations_if([
|
||||
yylloc = new b4_location_type (yylexer.getStartPos (),
|
||||
yylexer.getEndPos ());])[
|
||||
yylval = yylexer.getLVal();]b4_locations_if([[
|
||||
yylloc = new ]b4_location_type[(yylexer.getStartPos(),
|
||||
yylexer.getEndPos());]])[
|
||||
]])[
|
||||
}
|
||||
|
||||
@@ -613,14 +614,14 @@ b4_dollar_popdef[]dnl
|
||||
yySymbolPrint("Next token is", yytoken,
|
||||
yylval]b4_locations_if([, yylloc])[);]])[
|
||||
|
||||
if (yytoken == SymbolKind.]b4_symbol_prefix[YYerror)
|
||||
if (yytoken == ]b4_symbol(1, kind)[)
|
||||
{
|
||||
// The scanner already issued an error message, process directly
|
||||
// to error recovery. But do not keep the error token as
|
||||
// lookahead, it is too special and may lead us to an endless
|
||||
// loop in error recovery. */
|
||||
yychar = Lexer.]b4_percent_define_get([api.token.prefix])[YYUNDEF;
|
||||
yytoken = SymbolKind.]b4_symbol_prefix[YYUNDEF;]b4_locations_if([[
|
||||
yychar = Lexer.]b4_symbol(2, id)[;
|
||||
yytoken = ]b4_symbol(2, kind)[;]b4_locations_if([[
|
||||
yyerrloc = yylloc;]])[
|
||||
label = YYERRLAB1;
|
||||
}
|
||||
@@ -628,8 +629,8 @@ b4_dollar_popdef[]dnl
|
||||
{
|
||||
/* If the proper action on seeing token YYTOKEN is to reduce or to
|
||||
detect an error, take that action. */
|
||||
yyn += yytoken.getCode ();
|
||||
if (yyn < 0 || YYLAST_ < yyn || yycheck_[yyn] != yytoken.getCode ())
|
||||
yyn += yytoken.getCode();
|
||||
if (yyn < 0 || YYLAST_ < yyn || yycheck_[yyn] != yytoken.getCode())
|
||||
label = YYDEFAULT;
|
||||
|
||||
/* <= 0 means reduce or error. */
|
||||
@@ -744,9 +745,9 @@ b4_dollar_popdef[]dnl
|
||||
yyn = yypact_[yystate];
|
||||
if (!yyPactValueIsDefault (yyn))
|
||||
{
|
||||
yyn += SymbolKind.]b4_symbol(1, kind)[.getCode ();
|
||||
yyn += ]b4_symbol(1, kind)[.getCode();
|
||||
if (0 <= yyn && yyn <= YYLAST_
|
||||
&& yycheck_[yyn] == SymbolKind.]b4_symbol(1, kind)[.getCode ())
|
||||
&& yycheck_[yyn] == ]b4_symbol(1, kind)[.getCode())
|
||||
{
|
||||
yyn = yytable_[yyn];
|
||||
if (0 < yyn)
|
||||
@@ -779,7 +780,7 @@ b4_dollar_popdef[]dnl
|
||||
yystack.pop (2);]])[
|
||||
|
||||
/* Shift the error token. */]b4_parse_trace_if([[
|
||||
yySymbolPrint("Shifting", SymbolKind.get (yystos_[yyn]),
|
||||
yySymbolPrint("Shifting", SymbolKind.get(yystos_[yyn]),
|
||||
yylval]b4_locations_if([, yyloc])[);]])[
|
||||
|
||||
yystate = yyn;
|
||||
@@ -933,17 +934,19 @@ b4_dollar_popdef[]dnl
|
||||
int yychecklim = YYLAST_ - yyn + 1;
|
||||
int yyxend = yychecklim < NTOKENS ? yychecklim : NTOKENS;
|
||||
for (int yyx = yyxbegin; yyx < yyxend; ++yyx)
|
||||
if (yycheck_[yyx + yyn] == yyx && yyx != SymbolKind.]b4_symbol(1, kind)[.getCode ()
|
||||
&& !yyTableValueIsError (yytable_[yyx + yyn]))
|
||||
if (yycheck_[yyx + yyn] == yyx && yyx != ]b4_symbol(1, kind)[.getCode()
|
||||
&& !yyTableValueIsError(yytable_[yyx + yyn]))
|
||||
{
|
||||
if (yyarg == null)
|
||||
yycount += 1;
|
||||
else if (yycount == yyargn)
|
||||
return 0; // FIXME: this is incorrect.
|
||||
else
|
||||
yyarg[yycount++] = SymbolKind.get (yyx);
|
||||
yyarg[yycount++] = SymbolKind.get(yyx);
|
||||
}
|
||||
}
|
||||
if (yyarg != null && yycount == yyoffset && yyoffset < yyargn)
|
||||
yyarg[yycount] = null;
|
||||
return yycount - yyoffset;
|
||||
}
|
||||
}
|
||||
@@ -979,12 +982,12 @@ b4_dollar_popdef[]dnl
|
||||
to an error action in a later state.
|
||||
*/
|
||||
int yycount = 0;
|
||||
if (yyctx.getToken () != null)
|
||||
if (yyctx.getToken() != null)
|
||||
{
|
||||
if (yyarg != null)
|
||||
yyarg[yycount] = yyctx.getToken ();
|
||||
yyarg[yycount] = yyctx.getToken();
|
||||
yycount += 1;
|
||||
yycount += yyctx.getExpectedTokens (yyarg, 1, yyargn);
|
||||
yycount += yyctx.getExpectedTokens(yyarg, 1, yyargn);
|
||||
}
|
||||
return yycount;
|
||||
}
|
||||
@@ -1069,27 +1072,28 @@ b4_dollar_popdef[]dnl
|
||||
/* The symbols being reduced. */
|
||||
for (int yyi = 0; yyi < yynrhs; yyi++)
|
||||
yySymbolPrint(" $" + (yyi + 1) + " =",
|
||||
SymbolKind.get (yystos_[yystack.stateAt (yynrhs - (yyi + 1))]),
|
||||
SymbolKind.get(yystos_[yystack.stateAt (yynrhs - (yyi + 1))]),
|
||||
]b4_rhs_data(yynrhs, yyi + 1)b4_locations_if([,
|
||||
b4_rhs_location(yynrhs, yyi + 1)])[);
|
||||
}]])[
|
||||
|
||||
/* YYTRANSLATE_(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM
|
||||
as returned by yylex, with out-of-bounds checking. */
|
||||
private static final SymbolKind yytranslate_ (int t)
|
||||
private static final SymbolKind yytranslate_(int t)
|
||||
]b4_api_token_raw_if(dnl
|
||||
[[ {
|
||||
return SymbolKind.get (t);
|
||||
return SymbolKind.get(t);
|
||||
}
|
||||
]],
|
||||
[[ {
|
||||
int user_token_number_max_ = ]b4_user_token_number_max[;
|
||||
// Last valid token kind.
|
||||
int code_max = ]b4_code_max[;
|
||||
if (t <= 0)
|
||||
return SymbolKind.]b4_symbol_prefix[YYEOF;
|
||||
else if (t <= user_token_number_max_)
|
||||
return SymbolKind.get (yytranslate_table_[t]);
|
||||
return ]b4_symbol(0, kind)[;
|
||||
else if (t <= code_max)
|
||||
return SymbolKind.get(yytranslate_table_[t]);
|
||||
else
|
||||
return SymbolKind.]b4_symbol_prefix[YYUNDEF;
|
||||
return ]b4_symbol(2, kind)[;
|
||||
}
|
||||
]b4_integral_parser_table_define([translate_table], [b4_translate])[
|
||||
]])[
|
||||
|
||||
@@ -48,7 +48,7 @@ m4_ifdef([b4_location_file],
|
||||
["b4_location_file"])])
|
||||
m4_define([b4_location_path],
|
||||
b4_percent_define_get([[api.location.include]],
|
||||
["b4_dir_prefix[]b4_location_file"]))
|
||||
["b4_mapped_dir_prefix[]b4_location_file"]))
|
||||
m4_define([b4_location_path],
|
||||
m4_substr(m4_defn([b4_location_path]), 1, m4_eval(m4_len(m4_defn([b4_location_path])) - 2)))
|
||||
])
|
||||
@@ -63,11 +63,13 @@ m4_define([b4_location_define],
|
||||
class position
|
||||
{
|
||||
public:
|
||||
/// Type for file name.
|
||||
typedef ]b4_percent_define_get([[api.filename.type]])[ filename_type;
|
||||
/// Type for line and column numbers.
|
||||
typedef int counter_type;
|
||||
]m4_ifdef([b4_location_constructors], [[
|
||||
/// Construct a position.
|
||||
explicit position (]b4_percent_define_get([[filename_type]])[* f = YY_NULLPTR,
|
||||
explicit position (filename_type* f = YY_NULLPTR,
|
||||
counter_type l = ]b4_location_initial_line[,
|
||||
counter_type c = ]b4_location_initial_column[)
|
||||
: filename (f)
|
||||
@@ -77,7 +79,7 @@ m4_define([b4_location_define],
|
||||
|
||||
]])[
|
||||
/// Initialization.
|
||||
void initialize (]b4_percent_define_get([[filename_type]])[* fn = YY_NULLPTR,
|
||||
void initialize (filename_type* fn = YY_NULLPTR,
|
||||
counter_type l = ]b4_location_initial_line[,
|
||||
counter_type c = ]b4_location_initial_column[)
|
||||
{
|
||||
@@ -106,7 +108,7 @@ m4_define([b4_location_define],
|
||||
/** \} */
|
||||
|
||||
/// File name to which this position refers.
|
||||
]b4_percent_define_get([[filename_type]])[* filename;
|
||||
filename_type* filename;
|
||||
/// Current line number.
|
||||
counter_type line;
|
||||
/// Current column number.
|
||||
@@ -184,6 +186,8 @@ m4_define([b4_location_define],
|
||||
class location
|
||||
{
|
||||
public:
|
||||
/// Type for file name.
|
||||
typedef position::filename_type filename_type;
|
||||
/// Type for line and column numbers.
|
||||
typedef position::counter_type counter_type;
|
||||
]m4_ifdef([b4_location_constructors], [
|
||||
@@ -200,7 +204,7 @@ m4_define([b4_location_define],
|
||||
{}
|
||||
|
||||
/// Construct a 0-width location in \a f, \a l, \a c.
|
||||
explicit location (]b4_percent_define_get([[filename_type]])[* f,
|
||||
explicit location (filename_type* f,
|
||||
counter_type l = ]b4_location_initial_line[,
|
||||
counter_type c = ]b4_location_initial_column[)
|
||||
: begin (f, l, c)
|
||||
@@ -209,7 +213,7 @@ m4_define([b4_location_define],
|
||||
|
||||
])[
|
||||
/// Initialization.
|
||||
void initialize (]b4_percent_define_get([[filename_type]])[* f = YY_NULLPTR,
|
||||
void initialize (filename_type* f = YY_NULLPTR,
|
||||
counter_type l = ]b4_location_initial_line[,
|
||||
counter_type c = ]b4_location_initial_column[)
|
||||
{
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
dnl GNU M4 treats -dV in a position-independent manner.
|
||||
m4_debugmode(V)m4_traceon()dnl
|
||||
@@ -392,7 +392,7 @@ m4_define([_b4_type_clause],
|
||||
[b4_symbol_if([$1], [is_token],
|
||||
[b4_symbol_if([$1], [has_id],
|
||||
[tok == token::b4_symbol([$1], [id])],
|
||||
[tok == b4_symbol([$1], [user_number])])])])
|
||||
[tok == b4_symbol([$1], [code])])])])
|
||||
|
||||
|
||||
# _b4_token_constructor_define(SYMBOL-NUM...)
|
||||
|
||||
+102
-138
@@ -48,6 +48,10 @@ m4_define([b4_pure_if],
|
||||
## api.push-pull. ##
|
||||
## --------------- ##
|
||||
|
||||
# b4_pull_if, b4_push_if
|
||||
# ----------------------
|
||||
# Whether the pull/push APIs are needed. Both can be enabled.
|
||||
|
||||
b4_percent_define_default([[api.push-pull]], [[pull]])
|
||||
b4_percent_define_check_values([[[[api.push-pull]],
|
||||
[[pull]], [[push]], [[both]]]])
|
||||
@@ -155,7 +159,7 @@ m4_define([b4_rhs_location],
|
||||
# Declare the variables that are global, or local to YYPARSE if
|
||||
# pure-parser.
|
||||
m4_define([b4_declare_scanner_communication_variables], [[
|
||||
/* The lookahead symbol. */
|
||||
/* Lookahead token kind. */
|
||||
int yychar;
|
||||
|
||||
]b4_pure_if([[
|
||||
@@ -176,68 +180,47 @@ YYLTYPE yylloc]b4_yyloc_default[;]])[
|
||||
int yynerrs;]])])
|
||||
|
||||
|
||||
# b4_declare_parser_state_variables
|
||||
# ---------------------------------
|
||||
# b4_declare_parser_state_variables([INIT])
|
||||
# -----------------------------------------
|
||||
# Declare all the variables that are needed to maintain the parser state
|
||||
# between calls to yypush_parse.
|
||||
# If INIT is non-null, initialize these variables.
|
||||
m4_define([b4_declare_parser_state_variables],
|
||||
[b4_pure_if([[
|
||||
/* Number of syntax errors so far. */
|
||||
int yynerrs;
|
||||
int yynerrs]m4_ifval([$1], [ = 0])[;
|
||||
]])[
|
||||
yy_state_fast_t yystate;
|
||||
yy_state_fast_t yystate]m4_ifval([$1], [ = 0])[;
|
||||
/* Number of tokens to shift before error messages enabled. */
|
||||
int yyerrstatus;
|
||||
int yyerrstatus]m4_ifval([$1], [ = 0])[;
|
||||
|
||||
/* The stacks and their tools:
|
||||
'yyss': related to states.
|
||||
'yyvs': related to semantic values.]b4_locations_if([[
|
||||
'yyls': related to locations.]])[
|
||||
|
||||
Refer to the stacks through separate pointers, to allow yyoverflow
|
||||
/* Refer to the stacks through separate pointers, to allow yyoverflow
|
||||
to reallocate them elsewhere. */
|
||||
|
||||
/* Their size. */
|
||||
YYPTRDIFF_T yystacksize;
|
||||
YYPTRDIFF_T yystacksize]m4_ifval([$1], [ = YYINITDEPTH])[;
|
||||
|
||||
/* The state stack. */
|
||||
/* The state stack: array, bottom, top. */
|
||||
yy_state_t yyssa[YYINITDEPTH];
|
||||
yy_state_t *yyss;
|
||||
yy_state_t *yyssp;
|
||||
yy_state_t *yyss]m4_ifval([$1], [ = yyssa])[;
|
||||
yy_state_t *yyssp]m4_ifval([$1], [ = yyss])[;
|
||||
|
||||
/* The semantic value stack. */
|
||||
/* The semantic value stack: array, bottom, top. */
|
||||
YYSTYPE yyvsa[YYINITDEPTH];
|
||||
YYSTYPE *yyvs;
|
||||
YYSTYPE *yyvsp;]b4_locations_if([[
|
||||
YYSTYPE *yyvs]m4_ifval([$1], [ = yyvsa])[;
|
||||
YYSTYPE *yyvsp]m4_ifval([$1], [ = yyvs])[;]b4_locations_if([[
|
||||
|
||||
/* The location stack. */
|
||||
/* The location stack: array, bottom, top. */
|
||||
YYLTYPE yylsa[YYINITDEPTH];
|
||||
YYLTYPE *yyls;
|
||||
YYLTYPE *yylsp;]])[]b4_lac_if([[
|
||||
YYLTYPE *yyls]m4_ifval([$1], [ = yylsa])[;
|
||||
YYLTYPE *yylsp]m4_ifval([$1], [ = yyls])[;]])[]b4_lac_if([[
|
||||
|
||||
yy_state_t yyesa@{]b4_percent_define_get([[parse.lac.es-capacity-initial]])[@};
|
||||
yy_state_t *yyes;
|
||||
YYPTRDIFF_T yyes_capacity;]])])
|
||||
|
||||
|
||||
# b4_initialize_parser_state_variables
|
||||
# ------------------------------------
|
||||
# Initialize these variables.
|
||||
m4_define([b4_initialize_parser_state_variables],
|
||||
[[ yynerrs = 0;
|
||||
yystate = 0;
|
||||
yyerrstatus = 0;
|
||||
|
||||
yystacksize = YYINITDEPTH;
|
||||
yyssp = yyss = yyssa;
|
||||
yyvsp = yyvs = yyvsa;]b4_locations_if([[
|
||||
yylsp = yyls = yylsa;]])[]b4_lac_if([[
|
||||
|
||||
yyes = yyesa;
|
||||
yyes_capacity = ]b4_percent_define_get([[parse.lac.es-capacity-initial]])[;
|
||||
if (YYMAXDEPTH < yyes_capacity)
|
||||
yyes_capacity = YYMAXDEPTH;]])[
|
||||
]])
|
||||
yy_state_t *yyes]m4_ifval([$1], [ = yyesa])[;
|
||||
YYPTRDIFF_T yyes_capacity][]m4_ifval([$1],
|
||||
[m4_do([ = b4_percent_define_get([[parse.lac.es-capacity-initial]]) < YYMAXDEPTH],
|
||||
[ ? b4_percent_define_get([[parse.lac.es-capacity-initial]])],
|
||||
[ : YYMAXDEPTH])])[;]])])
|
||||
|
||||
|
||||
m4_define([b4_macro_define],
|
||||
@@ -313,14 +296,14 @@ m4_define([b4_declare_yyparse],
|
||||
# Declaration that might either go into the header (if --defines)
|
||||
# or open coded in the parser body.
|
||||
m4_define([b4_shared_declarations],
|
||||
[b4_cpp_guard_open([b4_spec_header_file])[
|
||||
[b4_cpp_guard_open([b4_spec_mapped_header_file])[
|
||||
]b4_declare_yydebug[
|
||||
]b4_percent_code_get([[requires]])[
|
||||
]b4_token_enums_defines[
|
||||
]b4_declare_yylstype[
|
||||
]b4_declare_yyparse[
|
||||
]b4_percent_code_get([[provides]])[
|
||||
]b4_cpp_guard_close([b4_spec_header_file])[]dnl
|
||||
]b4_cpp_guard_close([b4_spec_mapped_header_file])[]dnl
|
||||
])
|
||||
|
||||
|
||||
@@ -335,7 +318,7 @@ m4_define([b4_header_include_if],
|
||||
[$2])],
|
||||
[$2])])
|
||||
|
||||
m4_if(b4_spec_header_file, [[y.tab.h]],
|
||||
m4_if(b4_spec_header_file, [y.tab.h], [],
|
||||
[b4_percent_define_default([[api.header.include]],
|
||||
[["@basename(]b4_spec_header_file[@)"]])])
|
||||
|
||||
@@ -403,50 +386,10 @@ m4_if(b4_api_prefix, [yy], [],
|
||||
]b4_declare_symbol_enum[
|
||||
|
||||
]b4_user_post_prologue[
|
||||
]b4_percent_code_get[]dnl
|
||||
|
||||
[#ifdef short
|
||||
# undef short
|
||||
#endif
|
||||
|
||||
]b4_percent_code_get[
|
||||
]b4_c99_int_type_define[
|
||||
|
||||
#ifndef YYPTRDIFF_T
|
||||
# if defined __PTRDIFF_TYPE__ && defined __PTRDIFF_MAX__
|
||||
# define YYPTRDIFF_T __PTRDIFF_TYPE__
|
||||
# define YYPTRDIFF_MAXIMUM __PTRDIFF_MAX__
|
||||
# elif defined PTRDIFF_MAX
|
||||
# ifndef ptrdiff_t
|
||||
# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
|
||||
# endif
|
||||
# define YYPTRDIFF_T ptrdiff_t
|
||||
# define YYPTRDIFF_MAXIMUM PTRDIFF_MAX
|
||||
# else
|
||||
# define YYPTRDIFF_T long
|
||||
# define YYPTRDIFF_MAXIMUM LONG_MAX
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef YYSIZE_T
|
||||
# ifdef __SIZE_TYPE__
|
||||
# define YYSIZE_T __SIZE_TYPE__
|
||||
# elif defined size_t
|
||||
# define YYSIZE_T size_t
|
||||
# elif defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__
|
||||
# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
|
||||
# define YYSIZE_T size_t
|
||||
# else
|
||||
# define YYSIZE_T unsigned
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#define YYSIZE_MAXIMUM \
|
||||
YY_CAST (YYPTRDIFF_T, \
|
||||
(YYPTRDIFF_MAXIMUM < YY_CAST (YYSIZE_T, -1) \
|
||||
? YYPTRDIFF_MAXIMUM \
|
||||
: YY_CAST (YYSIZE_T, -1)))
|
||||
|
||||
#define YYSIZEOF(X) YY_CAST (YYPTRDIFF_T, sizeof (X))
|
||||
]b4_sizes_types_define[
|
||||
|
||||
/* Stored state numbers (used for stacks). */
|
||||
typedef ]b4_int_type(0, m4_eval(b4_states_number - 1))[ yy_state_t;
|
||||
@@ -632,7 +575,8 @@ union yyalloc
|
||||
/* YYNSTATES -- Number of states. */
|
||||
#define YYNSTATES ]b4_states_number[
|
||||
|
||||
#define YYMAXUTOK ]b4_user_token_number_max[
|
||||
/* YYMAXUTOK -- Last valid token kind. */
|
||||
#define YYMAXUTOK ]b4_code_max[
|
||||
|
||||
|
||||
/* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM
|
||||
@@ -869,7 +813,8 @@ int yydebug;
|
||||
/* Parser data structure. */
|
||||
struct yypstate
|
||||
{]b4_declare_parser_state_variables[
|
||||
/* Whether this instance has not started parsing yet. */
|
||||
/* Whether this instance has not started parsing yet.
|
||||
* If 2, it corresponds to a finished parsing. */
|
||||
int yynew;
|
||||
};]b4_pure_if([], [[
|
||||
|
||||
@@ -1198,6 +1143,8 @@ yypcontext_expected_tokens (const yypcontext_t *yyctx,
|
||||
yyarg[yycount++] = YY_CAST (yysymbol_kind_t, yyx);
|
||||
}
|
||||
}]])[
|
||||
if (yyarg && yycount == 0 && 0 < yyargn)
|
||||
yyarg[0] = ]b4_symbol(-2, kind)[;
|
||||
return yycount;
|
||||
}
|
||||
|
||||
@@ -1482,49 +1429,54 @@ yysyntax_error (YYPTRDIFF_T *yymsg_alloc, char **yymsg,
|
||||
int
|
||||
yyparse (]m4_ifset([b4_parse_param], [b4_formals(b4_parse_param)], [void])[)
|
||||
{
|
||||
return yypull_parse (YY_NULLPTR]b4_user_args[);
|
||||
yypstate *yyps = yypstate_new ();
|
||||
if (!yyps)
|
||||
{]b4_pure_if([b4_locations_if([[
|
||||
static YYLTYPE yyloc_default][]b4_yyloc_default[;
|
||||
YYLTYPE yylloc = yyloc_default;]])[
|
||||
yyerror (]b4_yyerror_args[YY_("memory exhausted"));]], [[
|
||||
if (!yypstate_allocated)
|
||||
yyerror (]b4_yyerror_args[YY_("memory exhausted"));]])[
|
||||
return 2;
|
||||
}
|
||||
int yystatus = yypull_parse (yyps]b4_user_args[);
|
||||
yypstate_delete (yyps);
|
||||
return yystatus;
|
||||
}
|
||||
|
||||
int
|
||||
yypull_parse (yypstate *yyps]b4_user_formals[)
|
||||
{]b4_pure_if([b4_locations_if([[
|
||||
{
|
||||
YY_ASSERT (yyps);]b4_pure_if([b4_locations_if([[
|
||||
static YYLTYPE yyloc_default][]b4_yyloc_default[;
|
||||
YYLTYPE yylloc = yyloc_default;]])])[
|
||||
yypstate *yyps_local;
|
||||
if (yyps)
|
||||
yyps_local = yyps;
|
||||
else
|
||||
{
|
||||
yyps_local = yypstate_new ();
|
||||
if (!yyps_local)
|
||||
{]b4_pure_if([[
|
||||
yyerror (]b4_yyerror_args[YY_("memory exhausted"));]], [[
|
||||
if (!yypstate_allocated)
|
||||
yyerror (]b4_yyerror_args[YY_("memory exhausted"));]])[
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
int yystatus;
|
||||
do {
|
||||
]b4_pure_if([[ YYSTYPE yylval;
|
||||
int ]])[yychar = ]b4_lex[;
|
||||
yystatus = yypush_parse (yyps_local]b4_pure_if([[, yychar, &yylval]b4_locations_if([[, &yylloc]])])m4_ifset([b4_parse_param], [, b4_args(b4_parse_param)])[);
|
||||
yystatus = yypush_parse (yyps]b4_pure_if([[, yychar, &yylval]b4_locations_if([[, &yylloc]])])m4_ifset([b4_parse_param], [, b4_args(b4_parse_param)])[);
|
||||
} while (yystatus == YYPUSH_MORE);
|
||||
if (!yyps)
|
||||
yypstate_delete (yyps_local);
|
||||
return yystatus;
|
||||
}]])[
|
||||
|
||||
]b4_parse_state_variable_macros([b4_pstate_macro_define])[
|
||||
|
||||
/* Initialize the parser data structure. */
|
||||
void
|
||||
static void
|
||||
yypstate_clear (yypstate *yyps)
|
||||
{
|
||||
]b4_initialize_parser_state_variables[
|
||||
yynerrs = 0;
|
||||
yystate = 0;
|
||||
yyerrstatus = 0;
|
||||
|
||||
yyssp = yyss;
|
||||
yyvsp = yyvs;]b4_locations_if([[
|
||||
yylsp = yyls;]])[
|
||||
|
||||
/* Initialize the state stack, in case yypcontext_expected_tokens is
|
||||
called before the first call to yyparse. */
|
||||
*yyssp = 0;
|
||||
yyps->yynew = 1;
|
||||
}
|
||||
|
||||
/* Initialize the parser data structure. */
|
||||
@@ -1536,9 +1488,16 @@ yypstate_new (void)
|
||||
return YY_NULLPTR;]])[
|
||||
yyps = YY_CAST (yypstate *, malloc (sizeof *yyps));
|
||||
if (!yyps)
|
||||
return YY_NULLPTR;
|
||||
yyps->yynew = 1;]b4_pure_if([], [[
|
||||
return YY_NULLPTR;]b4_pure_if([], [[
|
||||
yypstate_allocated = 1;]])[
|
||||
yystacksize = YYINITDEPTH;
|
||||
yyss = yyssa;
|
||||
yyvs = yyvsa;]b4_locations_if([[
|
||||
yyls = yylsa;]])[]b4_lac_if([[
|
||||
yyes = yyesa;
|
||||
yyes_capacity = ]b4_percent_define_get([[parse.lac.es-capacity-initial]])[;
|
||||
if (YYMAXDEPTH < yyes_capacity)
|
||||
yyes_capacity = YYMAXDEPTH;]])[
|
||||
yypstate_clear (yyps);
|
||||
return yyps;
|
||||
}
|
||||
@@ -1551,10 +1510,10 @@ yypstate_delete (yypstate *yyps)
|
||||
#ifndef yyoverflow
|
||||
/* If the stack was reallocated but the parse did not complete, then the
|
||||
stack still needs to be freed. */
|
||||
if (!yyps->yynew && yyss != yyssa)
|
||||
if (yyss != yyssa)
|
||||
YYSTACK_FREE (yyss);
|
||||
#endif]b4_lac_if([[
|
||||
if (!yyps->yynew && yyes != yyesa)
|
||||
if (yyes != yyesa)
|
||||
YYSTACK_FREE (yyes);]])[
|
||||
free (yyps);]b4_pure_if([], [[
|
||||
yypstate_allocated = 0;]])[
|
||||
@@ -1583,14 +1542,14 @@ yyparse (]m4_ifset([b4_parse_param], [b4_formals(b4_parse_param)], [void])[)]])[
|
||||
YYSTYPE yypushed_val = yylval;]b4_locations_if([[
|
||||
YYLTYPE yypushed_loc = yylloc;]])
|
||||
])],
|
||||
[b4_declare_parser_state_variables
|
||||
[b4_declare_parser_state_variables([init])
|
||||
])b4_lac_if([[
|
||||
/* Whether LAC context is established. A Boolean. */
|
||||
int yy_lac_established = 0;]])[
|
||||
int yyn;
|
||||
/* The return value of yyparse. */
|
||||
int yyresult;
|
||||
/* Lookahead token as an internal (translated) token number. */
|
||||
/* Lookahead symbol kind. */
|
||||
yysymbol_kind_t yytoken = ]b4_symbol(-2, kind)[;
|
||||
/* The variables used to return semantic value and location from the
|
||||
action routines. */
|
||||
@@ -1610,14 +1569,19 @@ yyparse (]m4_ifset([b4_parse_param], [b4_formals(b4_parse_param)], [void])[)]])[
|
||||
|
||||
/* The number of symbols on the RHS of the reduced rule.
|
||||
Keep to zero when no symbol should be popped. */
|
||||
int yylen = 0;
|
||||
]b4_push_if([[
|
||||
if (!yyps->yynew)
|
||||
int yylen = 0;]b4_push_if([[
|
||||
|
||||
switch (yyps->yynew)
|
||||
{
|
||||
case 2:
|
||||
yypstate_clear (yyps);
|
||||
goto case_0;
|
||||
|
||||
case_0:
|
||||
case 0:
|
||||
yyn = yypact[yystate];
|
||||
goto yyread_pushed_token;
|
||||
}]], [
|
||||
b4_initialize_parser_state_variables])[
|
||||
}]])[
|
||||
|
||||
YYDPRINTF ((stderr, "Starting parse\n"));
|
||||
|
||||
@@ -2017,7 +1981,7 @@ yyerrorlab:
|
||||
yyerrlab1:
|
||||
yyerrstatus = 3; /* Each real token shifted decrements this. */
|
||||
|
||||
// Pop stack until we find a state that shifts the error token.
|
||||
/* Pop stack until we find a state that shifts the error token. */
|
||||
for (;;)
|
||||
{
|
||||
yyn = yypact[yystate];
|
||||
@@ -2086,13 +2050,13 @@ yyabortlab:
|
||||
yyexhaustedlab:
|
||||
yyerror (]b4_yyerror_args[YY_("memory exhausted"));
|
||||
yyresult = 2;
|
||||
/* Fall through. */
|
||||
goto yyreturn;
|
||||
#endif
|
||||
|
||||
|
||||
/*-----------------------------------------------------.
|
||||
| yyreturn -- parsing is finished, return the result. |
|
||||
`-----------------------------------------------------*/
|
||||
/*-------------------------------------------------------.
|
||||
| yyreturn -- parsing is finished, clean up and return. |
|
||||
`-------------------------------------------------------*/
|
||||
yyreturn:
|
||||
if (yychar != ]b4_symbol(-2, id)[)
|
||||
{
|
||||
@@ -2111,21 +2075,21 @@ yyreturn:
|
||||
yydestruct ("Cleanup: popping",
|
||||
YY_ACCESSING_SYMBOL (+*yyssp), yyvsp]b4_locations_if([, yylsp])[]b4_user_args[);
|
||||
YYPOPSTACK (1);
|
||||
}
|
||||
}]b4_push_if([[
|
||||
yyps->yynew = 2;
|
||||
goto yypushreturn;
|
||||
|
||||
|
||||
/*-------------------------.
|
||||
| yypushreturn -- return. |
|
||||
`-------------------------*/
|
||||
yypushreturn:]], [[
|
||||
#ifndef yyoverflow
|
||||
if (yyss != yyssa)
|
||||
YYSTACK_FREE (yyss);
|
||||
#endif]b4_lac_if([[
|
||||
if (yyes != yyesa)
|
||||
YYSTACK_FREE (yyes);]])b4_push_if([[
|
||||
yypstate_clear (yyps);
|
||||
yyps->yynew = 1;
|
||||
|
||||
|
||||
/*-----------------------------------------.
|
||||
| yypushreturn -- ask for the next token. |
|
||||
`-----------------------------------------*/
|
||||
yypushreturn:]])[
|
||||
YYSTACK_FREE (yyes);]])])[
|
||||
]b4_parse_error_bmatch([detailed\|verbose],
|
||||
[[ if (yymsg != yymsgbuf)
|
||||
YYSTACK_FREE (yymsg);]])[
|
||||
|
||||
@@ -159,7 +159,7 @@
|
||||
<xsl:param name="prev-rule-number"
|
||||
select="preceding-sibling::item[1]/@rule-number"/>
|
||||
<xsl:apply-templates select="key('bison:ruleByNumber', @rule-number)">
|
||||
<xsl:with-param name="point" select="@point"/>
|
||||
<xsl:with-param name="dot" select="@dot"/>
|
||||
<xsl:with-param name="num" select="@rule-number"/>
|
||||
<xsl:with-param name="prev-lhs"
|
||||
select="key('bison:ruleByNumber', $prev-rule-number)/lhs[text()]"
|
||||
@@ -169,7 +169,7 @@
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="rule">
|
||||
<xsl:param name="point"/>
|
||||
<xsl:param name="dot"/>
|
||||
<xsl:param name="num"/>
|
||||
<xsl:param name="prev-lhs"/>
|
||||
<xsl:text> </xsl:text>
|
||||
@@ -198,14 +198,14 @@
|
||||
<xsl:text>:</xsl:text>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
<xsl:if test="$point = 0">
|
||||
<xsl:if test="$dot = 0">
|
||||
<xsl:text> .</xsl:text>
|
||||
</xsl:if>
|
||||
|
||||
<!-- RHS -->
|
||||
<xsl:for-each select="rhs/symbol|rhs/empty">
|
||||
<xsl:apply-templates select="."/>
|
||||
<xsl:if test="$point = position()">
|
||||
<xsl:if test="$dot = position()">
|
||||
<xsl:text> .</xsl:text>
|
||||
</xsl:if>
|
||||
</xsl:for-each>
|
||||
|
||||
@@ -300,7 +300,7 @@
|
||||
name="prev-lhs"
|
||||
select="key('bison:ruleByNumber', $prev-rule-number)/lhs[text()]"
|
||||
/>
|
||||
<xsl:with-param name="point" select="@point"/>
|
||||
<xsl:with-param name="dot" select="@dot"/>
|
||||
<xsl:with-param name="lookaheads">
|
||||
<xsl:apply-templates select="lookaheads"/>
|
||||
</xsl:with-param>
|
||||
@@ -311,7 +311,7 @@
|
||||
<xsl:param name="itemset"/>
|
||||
<xsl:param name="pad"/>
|
||||
<xsl:param name="prev-lhs"/>
|
||||
<xsl:param name="point"/>
|
||||
<xsl:param name="dot"/>
|
||||
<xsl:param name="lookaheads"/>
|
||||
|
||||
<xsl:if test="$itemset != 'true' and not($prev-lhs = lhs[text()])">
|
||||
@@ -347,11 +347,11 @@
|
||||
|
||||
<!-- RHS -->
|
||||
<xsl:for-each select="rhs/*">
|
||||
<xsl:if test="position() = $point + 1">
|
||||
<xsl:if test="position() = $dot + 1">
|
||||
<xsl:text> .</xsl:text>
|
||||
</xsl:if>
|
||||
<xsl:apply-templates select="."/>
|
||||
<xsl:if test="position() = last() and position() = $point">
|
||||
<xsl:if test="position() = last() and position() = $dot">
|
||||
<xsl:text> .</xsl:text>
|
||||
</xsl:if>
|
||||
</xsl:for-each>
|
||||
|
||||
@@ -75,7 +75,7 @@
|
||||
ol.lower-alpha {
|
||||
list-style-type: lower-alpha;
|
||||
}
|
||||
.point {
|
||||
.dot {
|
||||
color: #cc0000;
|
||||
}
|
||||
#footer {
|
||||
@@ -457,7 +457,7 @@
|
||||
<xsl:with-param name="prev-lhs"
|
||||
select="key('bison:ruleByNumber', $prev-rule-number)/lhs[text()]"
|
||||
/>
|
||||
<xsl:with-param name="point" select="@point"/>
|
||||
<xsl:with-param name="dot" select="@dot"/>
|
||||
<xsl:with-param name="lookaheads">
|
||||
<xsl:apply-templates select="lookaheads"/>
|
||||
</xsl:with-param>
|
||||
@@ -468,7 +468,7 @@
|
||||
<xsl:param name="itemset"/>
|
||||
<xsl:param name="pad"/>
|
||||
<xsl:param name="prev-lhs"/>
|
||||
<xsl:param name="point"/>
|
||||
<xsl:param name="dot"/>
|
||||
<xsl:param name="lookaheads"/>
|
||||
|
||||
<xsl:if test="$itemset != 'true' and not($prev-lhs = lhs[text()])">
|
||||
@@ -529,14 +529,14 @@
|
||||
|
||||
<!-- RHS -->
|
||||
<xsl:for-each select="rhs/*">
|
||||
<xsl:if test="position() = $point + 1">
|
||||
<xsl:if test="position() = $dot + 1">
|
||||
<xsl:text> </xsl:text>
|
||||
<span class="point">.</span>
|
||||
<span class="dot">•</span>
|
||||
</xsl:if>
|
||||
<xsl:apply-templates select="."/>
|
||||
<xsl:if test="position() = last() and position() = $point">
|
||||
<xsl:if test="position() = last() and position() = $dot">
|
||||
<xsl:text> </xsl:text>
|
||||
<span class="point">.</span>
|
||||
<span class="dot">•</span>
|
||||
</xsl:if>
|
||||
</xsl:for-each>
|
||||
<xsl:if test="$lookaheads">
|
||||
|
||||
+19
-14
@@ -1,4 +1,4 @@
|
||||
# Doxyfile 1.8.17
|
||||
# Doxyfile 1.8.18
|
||||
|
||||
# This file describes the settings to be used by the documentation system
|
||||
# doxygen (www.doxygen.org) for a project.
|
||||
@@ -253,12 +253,6 @@ TAB_SIZE = 8
|
||||
|
||||
ALIASES =
|
||||
|
||||
# This tag can be used to specify a number of word-keyword mappings (TCL only).
|
||||
# A mapping has the form "name=value". For example adding "class=itcl::class"
|
||||
# will allow you to use the command class in the itcl::class meaning.
|
||||
|
||||
TCL_SUBST =
|
||||
|
||||
# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
|
||||
# only. Doxygen will then generate output that is more tailored for C. For
|
||||
# instance, some of the names that are used will be different. The list of all
|
||||
@@ -300,13 +294,13 @@ OPTIMIZE_OUTPUT_SLICE = NO
|
||||
# extension. Doxygen has a built-in mapping, but you can override or extend it
|
||||
# using this tag. The format is ext=language, where ext is a file extension, and
|
||||
# language is one of the parsers supported by doxygen: IDL, Java, JavaScript,
|
||||
# Csharp (C#), C, C++, D, PHP, md (Markdown), Objective-C, Python, Slice,
|
||||
# Csharp (C#), C, C++, D, PHP, md (Markdown), Objective-C, Python, Slice, VHDL,
|
||||
# Fortran (fixed format Fortran: FortranFixed, free formatted Fortran:
|
||||
# FortranFree, unknown formatted Fortran: Fortran. In the later case the parser
|
||||
# tries to guess whether the code is fixed or free formatted code, this is the
|
||||
# default for Fortran type files), VHDL, tcl. For instance to make doxygen treat
|
||||
# .inc files as Fortran files (default is PHP), and .f files as C (default is
|
||||
# Fortran), use: inc=Fortran f=C.
|
||||
# default for Fortran type files). For instance to make doxygen treat .inc files
|
||||
# as Fortran files (default is PHP), and .f files as C (default is Fortran),
|
||||
# use: inc=Fortran f=C.
|
||||
#
|
||||
# Note: For files without extension you can use no_extension as a placeholder.
|
||||
#
|
||||
@@ -844,7 +838,7 @@ INPUT_ENCODING = UTF-8
|
||||
# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc,
|
||||
# *.m, *.markdown, *.md, *.mm, *.dox (to be provided as doxygen C comment),
|
||||
# *.doc (to be provided as doxygen C comment), *.txt (to be provided as doxygen
|
||||
# C comment), *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, *.f, *.for, *.tcl, *.vhd,
|
||||
# C comment), *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, *.f18, *.f, *.for, *.vhd,
|
||||
# *.vhdl, *.ucf, *.qsf and *.ice.
|
||||
|
||||
FILE_PATTERNS = *.c \
|
||||
@@ -1490,6 +1484,17 @@ TREEVIEW_WIDTH = 250
|
||||
|
||||
EXT_LINKS_IN_WINDOW = NO
|
||||
|
||||
# If the HTML_FORMULA_FORMAT option is set to svg, doxygen will use the pdf2svg
|
||||
# tool (see https://github.com/dawbarton/pdf2svg) or inkscape (see
|
||||
# https://inkscape.org) to generate formulas as SVG images instead of PNGs for
|
||||
# the HTML output. These images will generally look nicer at scaled resolutions.
|
||||
# Possible values are: png The default and svg Looks nicer but requires the
|
||||
# pdf2svg tool.
|
||||
# The default value is: png.
|
||||
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||
|
||||
HTML_FORMULA_FORMAT = png
|
||||
|
||||
# Use this tag to change the font size of LaTeX formulas included as images in
|
||||
# the HTML documentation. When you change the font size after a successful
|
||||
# doxygen run you need to manually remove any form_*.png images from the HTML
|
||||
@@ -1545,7 +1550,7 @@ MATHJAX_FORMAT = HTML-CSS
|
||||
# Content Delivery Network so you can quickly see the result without installing
|
||||
# MathJax. However, it is strongly recommended to install a local copy of
|
||||
# MathJax from https://www.mathjax.org before deployment.
|
||||
# The default value is: https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/.
|
||||
# The default value is: https://cdn.jsdelivr.net/npm/mathjax@2.
|
||||
# This tag requires that the tag USE_MATHJAX is set to YES.
|
||||
|
||||
MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest
|
||||
@@ -1715,7 +1720,7 @@ COMPACT_LATEX = NO
|
||||
# The default value is: a4.
|
||||
# This tag requires that the tag GENERATE_LATEX is set to YES.
|
||||
|
||||
PAPER_TYPE = a4wide
|
||||
PAPER_TYPE = a4
|
||||
|
||||
# The EXTRA_PACKAGES tag can be used to specify one or more LaTeX package names
|
||||
# that should be included in the LaTeX output. The package can be specified just
|
||||
|
||||
+962
-304
File diff suppressed because it is too large
Load Diff
@@ -3,7 +3,7 @@ digraph "reduce.y"
|
||||
node [fontname=courier shape=box]
|
||||
edge [fontname=courier]
|
||||
|
||||
1 [label="State 1\n 3 a: \"0\" . [\".\"]\l 4 b: \"0\" . [\";\"]\l"]
|
||||
1 [label="State 1\n 3 a: \"0\" • [\".\"]\l 4 b: \"0\" • [\";\"]\l"]
|
||||
1 -> "1R3" [label="" style=solid]
|
||||
"1R3" [style=filled shape=diamond fillcolor=yellowgreen label="R3"]
|
||||
1 -> "1R4" [label="[\";\"]" style=solid]
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
.------------------.
|
||||
| State 1 |
|
||||
| 3 a: "0" . [";"] |
|
||||
| 4 b: "0" . ["."] |
|
||||
| 3 a: "0" • [";"] |
|
||||
| 4 b: "0" • ["."] |
|
||||
`------------------'
|
||||
/ \
|
||||
/ \ ["."]
|
||||
|
||||
@@ -3,7 +3,7 @@ digraph "shift.y"
|
||||
node [fontname=courier shape=box]
|
||||
edge [fontname=courier]
|
||||
|
||||
3 [label="State 3\n 1 exp: a . \".\"\l"]
|
||||
3 [label="State 3\n 1 exp: a • \".\"\l"]
|
||||
3 -> 6 [style=solid label="\".\""]
|
||||
6 [label="State 6\n 1 exp: a \".\" .\l"]
|
||||
6 [label="State 6\n 1 exp: a \".\" •\l"]
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.----------------.
|
||||
| State 3 |
|
||||
| 1 exp: a . ";" |
|
||||
| 1 exp: a • ";" |
|
||||
`----------------'
|
||||
|
|
||||
| ";"
|
||||
@@ -8,5 +8,5 @@
|
||||
v
|
||||
.----------------.
|
||||
| State 6 |
|
||||
| 1 exp: a ";" . |
|
||||
| 1 exp: a ";" • |
|
||||
`----------------'
|
||||
|
||||
+9
-9
@@ -2,34 +2,34 @@
|
||||
// Report bugs to <[email protected]>.
|
||||
// Home page: <http://www.gnu.org/software/bison/>.
|
||||
|
||||
digraph "/tmp/fo.y"
|
||||
digraph "example.y"
|
||||
{
|
||||
node [fontname = courier, shape = box, colorscheme = paired6]
|
||||
edge [fontname = courier]
|
||||
|
||||
0 [label="State 0\n\l 0 $accept: . exp $end\l 1 exp: . a \";\"\l 2 | . b \".\"\l 3 a: . \"0\"\l 4 b: . \"0\"\l"]
|
||||
0 [label="State 0\n\l 0 $accept: • exp $end\l 1 exp: • a \";\"\l 2 | • b \".\"\l 3 a: • \"0\"\l 4 b: • \"0\"\l"]
|
||||
0 -> 1 [style=solid label="\"0\""]
|
||||
0 -> 2 [style=dashed label="exp"]
|
||||
0 -> 3 [style=dashed label="a"]
|
||||
0 -> 4 [style=dashed label="b"]
|
||||
1 [label="State 1\n\l 3 a: \"0\" . [\";\"]\l 4 b: \"0\" . [\".\"]\l"]
|
||||
1 [label="State 1\n\l 3 a: \"0\" • [\";\"]\l 4 b: \"0\" • [\".\"]\l"]
|
||||
1 -> "1R3" [style=solid]
|
||||
"1R3" [label="R3", fillcolor=3, shape=diamond, style=filled]
|
||||
1 -> "1R4" [label="[\".\"]", style=solid]
|
||||
"1R4" [label="R4", fillcolor=3, shape=diamond, style=filled]
|
||||
2 [label="State 2\n\l 0 $accept: exp . $end\l"]
|
||||
2 [label="State 2\n\l 0 $accept: exp • $end\l"]
|
||||
2 -> 5 [style=solid label="$end"]
|
||||
3 [label="State 3\n\l 1 exp: a . \";\"\l"]
|
||||
3 [label="State 3\n\l 1 exp: a • \";\"\l"]
|
||||
3 -> 6 [style=solid label="\";\""]
|
||||
4 [label="State 4\n\l 2 exp: b . \".\"\l"]
|
||||
4 [label="State 4\n\l 2 exp: b • \".\"\l"]
|
||||
4 -> 7 [style=solid label="\".\""]
|
||||
5 [label="State 5\n\l 0 $accept: exp $end .\l"]
|
||||
5 [label="State 5\n\l 0 $accept: exp $end •\l"]
|
||||
5 -> "5R0" [style=solid]
|
||||
"5R0" [label="Acc", fillcolor=1, shape=diamond, style=filled]
|
||||
6 [label="State 6\n\l 1 exp: a \";\" .\l"]
|
||||
6 [label="State 6\n\l 1 exp: a \";\" •\l"]
|
||||
6 -> "6R1" [style=solid]
|
||||
"6R1" [label="R1", fillcolor=3, shape=diamond, style=filled]
|
||||
7 [label="State 7\n\l 2 exp: b \".\" .\l"]
|
||||
7 [label="State 7\n\l 2 exp: b \".\" •\l"]
|
||||
7 -> "7R2" [style=solid]
|
||||
"7R2" [label="R2", fillcolor=3, shape=diamond, style=filled]
|
||||
}
|
||||
|
||||
+24
-10
@@ -131,7 +131,7 @@ dist_man_MANS = $(top_srcdir)/%D%/bison.1
|
||||
EXTRA_DIST += $(dist_man_MANS:.1=.x)
|
||||
MAINTAINERCLEANFILES += $(dist_man_MANS)
|
||||
|
||||
# Differences to ignore when comparing the man page (the date).
|
||||
# Differences to ignore when comparing man pages (the date).
|
||||
remove_time_stamp = \
|
||||
sed 's/^\(\.TH[^"]*"[^"]*"[^"]*\)"[^"]*"/\1/'
|
||||
|
||||
@@ -140,17 +140,31 @@ if ! CROSS_COMPILING
|
||||
MAN_DEPS = %D%/bison.help %D%/bison.x $(top_srcdir)/configure
|
||||
endif
|
||||
|
||||
# If we don't have help2man, just touch the target. Maintainers must
|
||||
# have the real thing, so if there's a .git directory, fail hard.
|
||||
#
|
||||
# We shouldn't need this, but on some OS the timestamps in the tarball
|
||||
# leave us no choice. See
|
||||
# https://lists.gnu.org/r/bug-bison/2020-05/msg00055.html.
|
||||
$(top_srcdir)/%D%/bison.1: $(MAN_DEPS)
|
||||
$(AM_V_GEN)$(HELP2MAN) \
|
||||
--include=$(top_srcdir)/%D%/bison.x \
|
||||
--output=$@.tmp tests/bison
|
||||
$(AM_V_at)if $(remove_time_stamp) $@ >$@a.tmp 2>/dev/null && \
|
||||
$(remove_time_stamp) $@.tmp | cmp $@a.tmp - >/dev/null 2>&1; then \
|
||||
touch $@; \
|
||||
else \
|
||||
mv $@.tmp $@; \
|
||||
$(AM_V_GEN)if $(HELP2MAN) --version >/dev/null 2>&1; then \
|
||||
$(HELP2MAN) \
|
||||
--include=$(top_srcdir)/%D%/bison.x \
|
||||
--output=$@.tmp tests/bison && \
|
||||
{ $(remove_time_stamp) $@ >$@a.tmp || true; } && \
|
||||
$(remove_time_stamp) $@.tmp >$@b.tmp && \
|
||||
if diff $@a.tmp $@b.tmp >/dev/null 2>&1; then \
|
||||
touch $@; \
|
||||
else \
|
||||
mv $@.tmp $@; \
|
||||
fi && \
|
||||
rm -f $@*.tmp; \
|
||||
elif test -d $(srcdir)/.git; then \
|
||||
echo >&2 "ERROR: $@: help2man is needed"; \
|
||||
exit 1; \
|
||||
else \
|
||||
touch $@; \
|
||||
fi
|
||||
$(AM_V_at)rm -f $@*.tmp
|
||||
|
||||
if ENABLE_YACC
|
||||
nodist_man_MANS = %D%/yacc.1
|
||||
|
||||
-38
@@ -1,38 +0,0 @@
|
||||
* bench.pl
|
||||
A primitive Perl script to run benches. Currently its only bench is
|
||||
the usual calculator: it has a lightweight processing part (but not
|
||||
null), so it is really emphasizing the cost of the whole parsing
|
||||
(including scanning and I/O).
|
||||
|
||||
Set the envvars BISON and CC to the programs and flags you want to
|
||||
use. They default to bison and gcc. To run a non-installed bison
|
||||
from a tarball built in _build, I suggest the following.
|
||||
|
||||
BISON=_build/tests/bison CC='gcc -O2' ./bench.pl
|
||||
|
||||
(The _build/tests/bison wrapper makes sure that _build/src/bison will
|
||||
use the tarballs' skeletons, not those already installed as a
|
||||
straightforward use of _build/src/bison would.)
|
||||
|
||||
--
|
||||
|
||||
Copyright (C) 2006, 2009-2015, 2018-2020 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of Bison, the GNU Compiler Compiler.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Local Variables:
|
||||
mode: outline
|
||||
End:
|
||||
@@ -0,0 +1,36 @@
|
||||
# bench.pl
|
||||
A primitive Perl script to run benches. Currently its only bench is the
|
||||
usual calculator: it has a lightweight processing part (but not null), so it
|
||||
is really emphasizing the cost of the whole parsing (including scanning and
|
||||
I/O).
|
||||
|
||||
Set the envvars `BISON` and `CC` to the programs and flags you want to use.
|
||||
They default to `bison` and `gcc`. To run a non-installed bison from a
|
||||
tarball built in _build, I suggest the following.
|
||||
|
||||
BISON=_build/tests/bison CC='gcc -O2' ./bench.pl
|
||||
|
||||
(The `_build/tests/bison` wrapper makes sure that `_build/src/bison` will
|
||||
use the tarballs' skeletons, not those already installed as a
|
||||
straightforward use of `_build/src/bison` would.)
|
||||
|
||||
<!--
|
||||
|
||||
Local Variables:
|
||||
mode: markdown
|
||||
fill-column: 76
|
||||
ispell-dictionary: "american"
|
||||
End:
|
||||
|
||||
Copyright (C) 2006, 2009-2015, 2018-2020 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of Bison, the GNU Compiler Compiler.
|
||||
|
||||
Permission is granted to copy, distribute and/or modify this document
|
||||
under the terms of the GNU Free Documentation License, Version 1.3 or
|
||||
any later version published by the Free Software Foundation; with no
|
||||
Invariant Sections, with no Front-Cover Texts, and with no Back-Cover
|
||||
Texts. A copy of the license is included in the "GNU Free
|
||||
Documentation License" file as part of this distribution.
|
||||
|
||||
-->
|
||||
+81
-22
@@ -498,7 +498,8 @@ yylex (void)
|
||||
case '5': case '6': case '7': case '8': case '9':
|
||||
{
|
||||
int nchars = 0;
|
||||
sscanf (input - 1, "%d%n", &yylval.NUM, &nchars);
|
||||
int n = sscanf (input - 1, "%d%n", &yylval.NUM, &nchars);
|
||||
assert (n == 1);
|
||||
input += nchars - 1;
|
||||
return NUM;
|
||||
}
|
||||
@@ -775,7 +776,31 @@ sub run ($)
|
||||
|
||||
##################################################################
|
||||
|
||||
=item C<compile ($base)>
|
||||
=item C<language ($base)>
|
||||
|
||||
The language to use depending on the %language specification in
|
||||
C<$base.y>: C<c> or C<c++>.
|
||||
|
||||
=cut
|
||||
|
||||
sub language ($)
|
||||
{
|
||||
my ($base) = @_;
|
||||
if ($gbench)
|
||||
{
|
||||
"c++";
|
||||
}
|
||||
else
|
||||
{
|
||||
my $language = `sed -ne '/%language "\\(.*\\)"/{s//\\1/;p;q;}' $base.y`;
|
||||
chomp $language;
|
||||
$language eq 'C++' ? "c++" : "c";
|
||||
}
|
||||
}
|
||||
|
||||
##################################################################
|
||||
|
||||
=item C<compiler ($base)>
|
||||
|
||||
The compiler to use depending on the %language specification in
|
||||
C<$base.y>.
|
||||
@@ -785,16 +810,12 @@ C<$base.y>.
|
||||
sub compiler ($)
|
||||
{
|
||||
my ($base) = @_;
|
||||
if ($gbench)
|
||||
{
|
||||
$cxx;
|
||||
}
|
||||
else
|
||||
{
|
||||
my $language = `sed -ne '/%language "\\(.*\\)"/{s//\\1/;p;q;}' $base.y`;
|
||||
chomp $language;
|
||||
$language eq 'C++' ? $cxx : $cc;
|
||||
}
|
||||
my %compiler =
|
||||
(
|
||||
'c++' => $cxx,
|
||||
'c' => $cc,
|
||||
);
|
||||
$compiler{language ($base)};
|
||||
}
|
||||
|
||||
##################################################################
|
||||
@@ -805,21 +826,38 @@ Compile C<$base.y> to an executable.
|
||||
|
||||
=cut
|
||||
|
||||
sub compile ($)
|
||||
sub compile ($$)
|
||||
{
|
||||
my ($base) = @_;
|
||||
my ($makefile, $base) = @_;
|
||||
my $compiler = compiler ($base);
|
||||
|
||||
my $my_bison = `sed -ne '/[/][/] %bison "\\(.*\\)"/{s//\\1/;p;q;}' $base.y`;
|
||||
chop $my_bison;
|
||||
run ((length $my_bison ? $my_bison : $bison) . " $base.y -o $base.c");
|
||||
my %ext =
|
||||
(
|
||||
'c++' => 'cc',
|
||||
'c' => 'c',
|
||||
);
|
||||
my $ext = $ext{language ($base)};
|
||||
if ($gbench)
|
||||
{
|
||||
run "$compiler -c -o $base.o $cflags $base.c";
|
||||
print $makefile <<EOF;
|
||||
$base.$ext: $base.y
|
||||
\t@{[length $my_bison ? $my_bison : $bison]} $base.y -o $base.$ext
|
||||
|
||||
$base.o: $base.$ext
|
||||
\t$compiler -c -o $base.o $cflags $base.$ext
|
||||
EOF
|
||||
}
|
||||
else
|
||||
{
|
||||
run "$compiler -o $base $cflags $base.c";
|
||||
print $makefile <<EOF;
|
||||
$base.$ext: $base.y
|
||||
\t@{[length $my_bison ? $my_bison : $bison]} $base.y -o $base.$ext
|
||||
|
||||
$base: $base.$ext
|
||||
\t$compiler -o $base $cflags $base.$ext
|
||||
EOF
|
||||
}
|
||||
}
|
||||
|
||||
@@ -849,11 +887,13 @@ sub bench_with_timethese ($@)
|
||||
# For each bench, capture the size.
|
||||
my %size;
|
||||
|
||||
my $makefile = new IO::File ">Makefile";
|
||||
while (my ($name, $directives) = each %bench)
|
||||
{
|
||||
generate_grammar ($grammar, $name, $directives);
|
||||
# Compile the executable.
|
||||
compile ($name);
|
||||
compile ($makefile, $name);
|
||||
run "make $name";
|
||||
$bench{$name} = "system ('./$name');";
|
||||
chop($size{$name} = `wc -c <$name`);
|
||||
}
|
||||
@@ -906,6 +946,20 @@ sub bench_with_gbenchmark ($@)
|
||||
my $readme = new IO::File ">README.md";
|
||||
print $readme <<EOF;
|
||||
compiler: $compiler $cflags
|
||||
EOF
|
||||
|
||||
my $makefile = new IO::File ">Makefile";
|
||||
print $makefile <<EOF;
|
||||
.PHONY: bench
|
||||
bench: main
|
||||
\t./main \$(BENCHFLAGS) | tee -a README.md
|
||||
|
||||
# Link the bench cases in a different order to run the bench case in a
|
||||
# different order.
|
||||
.PHONY: rand
|
||||
rand:
|
||||
\t-rm main
|
||||
\tmake bench OBJECTS="\$\$(shuf -e \$(OBJECTS) | xargs)"
|
||||
EOF
|
||||
|
||||
my @obj = ();
|
||||
@@ -916,19 +970,24 @@ EOF
|
||||
print $m;
|
||||
print $readme $m;
|
||||
generate_grammar ($grammar, $base, $directive[$i]);
|
||||
compile ($base);
|
||||
compile ($makefile, $base);
|
||||
push @obj, "$base.o";
|
||||
}
|
||||
|
||||
my $out = new IO::File ">main.c";
|
||||
my $out = new IO::File ">main.cc";
|
||||
print $out <<EOF;
|
||||
#include <benchmark/benchmark.h>
|
||||
|
||||
BENCHMARK_MAIN();
|
||||
EOF
|
||||
|
||||
run "$compiler -o main $cflags main.c @obj -lbenchmark";
|
||||
run "./main | tee -a README.md";
|
||||
print $makefile <<EOF;
|
||||
OBJECTS = @{obj}
|
||||
main: \$(OBJECTS)
|
||||
\t$compiler -o main $cflags main.cc \$(OBJECTS) -lbenchmark
|
||||
EOF
|
||||
|
||||
run "make";
|
||||
}
|
||||
|
||||
######################################################################
|
||||
|
||||
+2
-1
@@ -14,4 +14,5 @@
|
||||
## You should have received a copy of the GNU General Public License
|
||||
## along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
nodist_noinst_SCRIPTS = etc/bench.pl
|
||||
dist_noinst_DATA = %D%/README.md
|
||||
nodist_noinst_SCRIPTS = %D%/bench.pl
|
||||
|
||||
@@ -13,8 +13,8 @@ semantic value.
|
||||
|
||||
Run as `./simple`.
|
||||
|
||||
Extracted from the documentation: "A Simple C++ Example".
|
||||
https://www.gnu.org/software/bison/manual/html_node/A-Simple-C_002b_002b-Example.html
|
||||
Extracted from the documentation: [A Simple C++
|
||||
Example](https://www.gnu.org/software/bison/manual/html_node/A-Simple-C_002b_002b-Example.html).
|
||||
|
||||
## variant.yy - Self-contained example in C++98
|
||||
A variation of simple.yy, in C++98.
|
||||
@@ -36,8 +36,8 @@ starting point for a clean parser in C++. The previous examples are better
|
||||
introductory examples, and the C examples are also useful introductory
|
||||
examples.
|
||||
|
||||
Extracted from the documentation: "A Complete C++ Example".
|
||||
https://www.gnu.org/software/bison/manual/html_node/A-Complete-C_002b_002b-Example.html
|
||||
Extracted from the documentation: [A Complete C++
|
||||
Example](https://www.gnu.org/software/bison/manual/html_node/A-Complete-C_002b_002b-Example.html).
|
||||
|
||||
<!---
|
||||
|
||||
|
||||
@@ -5,9 +5,9 @@ saw the traditional implementation in C, please first read
|
||||
examples/c/lexcalc, which can be seen as a C precursor of this example.
|
||||
|
||||
Read the corresponding chapter in the documentation: "A Complete C++
|
||||
Example". It is also available on line (maybe with a different version of
|
||||
Bison):
|
||||
https://www.gnu.org/software/bison/manual/html_node/A-Complete-C_002b_002b-Example.html
|
||||
Example". It is also available [on
|
||||
line](https://www.gnu.org/software/bison/manual/html_node/A-Complete-C_002b_002b-Example.html)
|
||||
(maybe with a different version of Bison).
|
||||
|
||||
To use it, copy this directory into some work directory, and run `make` to
|
||||
compile the executable, and try it. It is a simple calculator which accepts
|
||||
|
||||
@@ -139,7 +139,7 @@ namespace yy
|
||||
int
|
||||
main (int argc, const char *argv[])
|
||||
{
|
||||
if (2 <= argc && isdigit (*argv[1]))
|
||||
if (2 <= argc && isdigit (static_cast<unsigned char> (*argv[1])))
|
||||
{
|
||||
auto maxl = strtol (argv[1], nullptr, 10);
|
||||
max = INT_MIN <= maxl && maxl <= INT_MAX ? int(maxl) : 4;
|
||||
|
||||
@@ -10,8 +10,8 @@ The first example is that of a simple double-precision Reverse Polish
|
||||
Notation calculator (a calculator using postfix operators). This example
|
||||
provides a good starting point, since operator precedence is not an issue.
|
||||
|
||||
Extracted from the documentation: "Reverse Polish Notation Calculator"
|
||||
https://www.gnu.org/software/bison/manual/html_node/RPN-Calc.html
|
||||
Extracted from the documentation: [Reverse Polish Notation
|
||||
Calculator](https://www.gnu.org/software/bison/manual/html_node/RPN-Calc.html).
|
||||
|
||||
## calc - Simple Calculator
|
||||
This example is slightly more complex than rpcalc: it features infix
|
||||
@@ -24,18 +24,18 @@ A more complete C example: a multi-function calculator. More complex than
|
||||
the previous example. Using precedence directives to support infix
|
||||
operators.
|
||||
|
||||
Extracted from the documentation: "Multi-Function Calculator: mfcalc".
|
||||
https://www.gnu.org/software/bison/manual/html_node/Multi_002dfunction-Calc.html
|
||||
Extracted from the documentation: [Multi-Function Calculator:
|
||||
mfcalc](https://www.gnu.org/software/bison/manual/html_node/Multi_002dfunction-Calc.html).
|
||||
|
||||
## lexcalc - calculator with Flex and Bison
|
||||
The calculator with precedence directives and location tracking. It uses
|
||||
Flex to generate the scanner.
|
||||
|
||||
## reccalc - recursive calculator with Flex and Bison
|
||||
The example builds on top of the previous one to provide a reentrant parser.
|
||||
Such parsers can be called concurrently in different threads, or even
|
||||
recursively. To demonstrate this feature, expressions in parentheses are
|
||||
tokenized as strings, and then recursively parsed from the parser. So
|
||||
This example builds on top of the previous one to provide a reentrant
|
||||
parser. Such parsers can be called concurrently in different threads, or
|
||||
even recursively. To demonstrate this feature, expressions in parentheses
|
||||
are tokenized as strings, and then recursively parsed from the parser. So
|
||||
`(((1)+(2))*((3)+(4)))` uses eight parsers, with a depth of four.
|
||||
|
||||
## pushcalc - calculator implemented with a push parser
|
||||
|
||||
@@ -14,6 +14,9 @@ This example demonstrates best practices when using Bison.
|
||||
- It supports debug traces with semantic values.
|
||||
- It uses named references instead of the traditional $1, $2, etc.
|
||||
|
||||
To customize the interaction with bistromathic, see the GNU Readline user
|
||||
manual (see `info rluserman`).
|
||||
|
||||
<!---
|
||||
Local Variables:
|
||||
fill-column: 76
|
||||
|
||||
@@ -15,6 +15,10 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# Users may customize the behavior of readline, which might break our
|
||||
# expected results.
|
||||
INPUTRC=/dev/null
|
||||
export INPUTRC
|
||||
|
||||
# Beware of portability issues of readline when not feeding it from a
|
||||
# terminal.
|
||||
@@ -28,14 +32,27 @@
|
||||
#
|
||||
# On OpenBSD 6.5 the prompt is displayed, but the input is not
|
||||
# repeated (!). So input "1+2*3\n" gives "> 7\n> \n" as output.
|
||||
#
|
||||
# On AIX, you get some escaping sequence before the prompt:
|
||||
# "<ESC>[?1034h> 1+2*3". It appears to pass the terminfo capability
|
||||
# "smm", to put the terminal in "meta mode": as if the user had hit
|
||||
# META.
|
||||
|
||||
if ! echo '1-1' | prog | grep '>' >/dev/null; then
|
||||
# macOS.
|
||||
echo >perfect '> 0
|
||||
0
|
||||
> '
|
||||
|
||||
echo >ok '0'
|
||||
echo '0' | prog >effective
|
||||
|
||||
echo "checking for readline output..."
|
||||
if diff perfect effective; then
|
||||
# Alles ist gut.
|
||||
strip_prompt=false
|
||||
elif diff ok effective; then
|
||||
strip_prompt=true
|
||||
elif ! echo '1-1' | prog | grep '1-1' >/dev/null; then
|
||||
# OpenBSD 6.5. I don't want to spend time on this.
|
||||
echo "SKIP: this is not the GNU Readline we expect"
|
||||
exit 0
|
||||
else
|
||||
skip "this is not the GNU Readline we expect"
|
||||
fi
|
||||
|
||||
|
||||
@@ -84,7 +101,7 @@ cat >input <<EOF
|
||||
EOF
|
||||
run 0 '> *
|
||||
> ''
|
||||
err: 1.1: syntax error: expected end of file or - or ( or exit or number or function or variable before *'
|
||||
err: 1.1: syntax error: expected end of file or - or ( or exit or number or function etc., before *'
|
||||
|
||||
cat >input <<EOF
|
||||
1 + 2 * * 3
|
||||
@@ -245,14 +262,22 @@ err: Cleanup: popping nterm input (1.1-4: )' -p
|
||||
# From now on, the differences between versions of GNU Readline are
|
||||
# too painful to try to cope with.
|
||||
if $strip_prompt; then
|
||||
echo "SKIP: this is not the GNU Readline we expect"
|
||||
if $exit; then
|
||||
exit 0
|
||||
else
|
||||
exit 1
|
||||
fi
|
||||
echo "SKIP: this is not the GNU Readline we expect"
|
||||
exit $status
|
||||
fi
|
||||
|
||||
# On Windows10/MSYS2 the ^G coming from <tab> completion is not
|
||||
# emitted the same way
|
||||
# (https://lists.gnu.org/r/bug-bison/2020-05/msg00076.html).
|
||||
echo "checking for kernel name... $(uname -s)"
|
||||
case $(uname -s) in
|
||||
(MSYS*)
|
||||
echo "SKIP: this is Windows/MSYS"
|
||||
exit $status
|
||||
;;
|
||||
esac
|
||||
|
||||
|
||||
# Check completion after an operator.
|
||||
sed -e 's/\\t/ /g' >input <<EOF
|
||||
(1+\t\t
|
||||
@@ -281,3 +306,25 @@ end of file exit exp ''
|
||||
0
|
||||
> ''
|
||||
err: '
|
||||
|
||||
# Check that completion prints valid locations even when there is an error.
|
||||
sed -e 's/\\t/ /g' >input <<EOF
|
||||
1++\t
|
||||
EOF
|
||||
run -n 0 '> 1++ ''
|
||||
> ''
|
||||
err: 1.1: syntax error: expected - or ( or number or function or variable before +
|
||||
err: 1.3: syntax error: expected - or ( or number or function or variable before +
|
||||
'
|
||||
|
||||
# And even when the error was recovered from.
|
||||
sed -e 's/\\t/ /g' >input <<EOF
|
||||
(1++2) + 3 +\t\t
|
||||
EOF
|
||||
run -n 0 '> (1++2) + 3 + ''
|
||||
> ''
|
||||
err: 1.1: syntax error: expected - or ( or number or function or variable before +
|
||||
err: 1.1: syntax error: expected - or ( or number or function or variable before +
|
||||
err: 1.4: syntax error: expected - or ( or number or function or variable before +
|
||||
err: 1.15: syntax error: expected - or ( or number or function or variable before end of file
|
||||
'
|
||||
|
||||
@@ -19,19 +19,23 @@ bistromathicdir = $(docdir)/%D%
|
||||
## Bistromathics. ##
|
||||
## --------------- ##
|
||||
|
||||
check_PROGRAMS += %D%/bistromathic
|
||||
TESTS += %D%/bistromathic.test
|
||||
EXTRA_DIST += %D%/bistromathic.test
|
||||
nodist_%C%_bistromathic_SOURCES = %D%/parse.y %D%/parse.h
|
||||
%D%/parse.c: $(dependencies)
|
||||
|
||||
# Don't use gnulib's system headers.
|
||||
%C%_bistromathic_CPPFLAGS = \
|
||||
-DBISON_LOCALEDIR='"$(localdir)"' \
|
||||
-DLOCALEDIR='"$(localdir)"' \
|
||||
-I$(top_srcdir)/%D% -I$(top_builddir)/%D%
|
||||
%C%_bistromathic_LDADD = -lm -lreadline $(LIBINTL)
|
||||
if ENABLE_BISTROMATHIC
|
||||
check_PROGRAMS += %D%/bistromathic
|
||||
TESTS += %D%/bistromathic.test
|
||||
nodist_%C%_bistromathic_SOURCES = %D%/parse.y
|
||||
|
||||
# Don't use gnulib's system headers.
|
||||
%C%_bistromathic_CPPFLAGS = \
|
||||
-DBISON_LOCALEDIR='"$(localdir)"' \
|
||||
-DLOCALEDIR='"$(localdir)"' \
|
||||
-I$(top_srcdir)/%D% -I$(top_builddir)/%D%
|
||||
%C%_bistromathic_CFLAGS = $(TEST_CFLAGS)
|
||||
%C%_bistromathic_LDADD = -lm $(LIBREADLINE) $(LIBINTL)
|
||||
endif
|
||||
|
||||
EXTRA_DIST += %D%/bistromathic.test
|
||||
dist_bistromathic_DATA = %D%/parse.y %D%/Makefile %D%/README.md
|
||||
CLEANFILES += %D%/parse.[ch] %D%/parse.output
|
||||
CLEANDIRS += %D%/*.dSYM
|
||||
|
||||
@@ -1,5 +1,25 @@
|
||||
%require "3.6"
|
||||
/* Parser and scanner for bistromathic. -*- C -*-
|
||||
|
||||
Copyright (C) 2019-2020 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of Bison, the GNU Compiler Compiler.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
%require "3.7"
|
||||
|
||||
// Emitted on top of the implementation file.
|
||||
%code top {
|
||||
#include <ctype.h> // isdigit
|
||||
#include <locale.h> // LC_ALL
|
||||
@@ -24,6 +44,7 @@
|
||||
#endif
|
||||
}
|
||||
|
||||
// Emitted in the header file, before the definition of YYSTYPE.
|
||||
%code requires {
|
||||
// Function type.
|
||||
typedef double (func_t) (double);
|
||||
@@ -46,6 +67,7 @@
|
||||
symrec *getsym (char const *name);
|
||||
}
|
||||
|
||||
// Emitted in the header file, after the definition of YYSTYPE.
|
||||
%code provides {
|
||||
# ifndef __attribute__
|
||||
# ifndef __GNUC__
|
||||
@@ -57,6 +79,7 @@
|
||||
__attribute__ ((__format__ (__printf__, 2, 3)));
|
||||
}
|
||||
|
||||
// Emitted in the implementation file.
|
||||
%code {
|
||||
#if defined ENABLE_NLS && ENABLE_NLS
|
||||
# define _(Msgid) gettext (Msgid)
|
||||
@@ -68,6 +91,9 @@
|
||||
int done = 0;
|
||||
}
|
||||
|
||||
// Include the header in the implementation rather than duplicating it.
|
||||
%define api.header.include {"parse.h"}
|
||||
|
||||
// Don't share global variables between the scanner and the parser.
|
||||
%define api.pure full
|
||||
|
||||
@@ -217,7 +243,7 @@ getsym (char const *name)
|
||||
}
|
||||
|
||||
// How many symbols are registered.
|
||||
int
|
||||
static int
|
||||
symbol_count (void)
|
||||
{
|
||||
int res = 0;
|
||||
@@ -267,7 +293,8 @@ yylex (const char **line, YYSTYPE *yylval, YYLTYPE *yylloc)
|
||||
case '5': case '6': case '7': case '8': case '9':
|
||||
{
|
||||
int nchars = 0;
|
||||
sscanf (*line - 1, "%lf%n", &yylval->TOK_NUM, &nchars);
|
||||
if (sscanf (*line - 1, "%lf%n", &yylval->TOK_NUM, &nchars) != 1)
|
||||
abort ();
|
||||
*line += nchars - 1;
|
||||
yylloc->last_column += nchars - 1;
|
||||
return TOK_NUM;
|
||||
@@ -283,7 +310,8 @@ yylex (const char **line, YYSTYPE *yylval, YYLTYPE *yylloc)
|
||||
{
|
||||
int nchars = 0;
|
||||
char buf[100];
|
||||
sscanf (*line - 1, "%99[a-z]%n", buf, &nchars);
|
||||
if (sscanf (*line - 1, "%99[a-z]%n", buf, &nchars) != 1)
|
||||
abort ();
|
||||
*line += nchars - 1;
|
||||
yylloc->last_column += nchars - 1;
|
||||
if (strcmp (buf, "exit") == 0)
|
||||
@@ -311,12 +339,12 @@ yylex (const char **line, YYSTYPE *yylval, YYLTYPE *yylloc)
|
||||
`---------*/
|
||||
|
||||
|
||||
const char *
|
||||
static const char *
|
||||
error_format_string (int argc)
|
||||
{
|
||||
switch (argc)
|
||||
{
|
||||
default: /* Avoid compiler warnings. */
|
||||
default: // Avoid compiler warnings.
|
||||
case 0: return _("%@: syntax error");
|
||||
case 1: return _("%@: syntax error: unexpected %u");
|
||||
// TRANSLATORS: '%@' is a location in a file, '%u' is an
|
||||
@@ -332,7 +360,7 @@ error_format_string (int argc)
|
||||
case 5: return _("%@: syntax error: expected %0e or %1e or %2e or %3e before %u");
|
||||
case 6: return _("%@: syntax error: expected %0e or %1e or %2e or %3e or %4e before %u");
|
||||
case 7: return _("%@: syntax error: expected %0e or %1e or %2e or %3e or %4e or %5e before %u");
|
||||
case 8: return _("%@: syntax error: expected %0e or %1e or %2e or %3e or %4e or %5e or %6e before %u");
|
||||
case 8: return _("%@: syntax error: expected %0e or %1e or %2e or %3e or %4e or %5e etc., before %u");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -340,12 +368,15 @@ error_format_string (int argc)
|
||||
int
|
||||
yyreport_syntax_error (const yypcontext_t *ctx)
|
||||
{
|
||||
enum { ARGS_MAX = 7 };
|
||||
enum { ARGS_MAX = 6 };
|
||||
yysymbol_kind_t arg[ARGS_MAX];
|
||||
int argsize = yypcontext_expected_tokens (ctx, arg, ARGS_MAX);
|
||||
if (argsize < 0)
|
||||
return argsize;
|
||||
const char *format = error_format_string (1 + argsize);
|
||||
const int too_many_expected_tokens = argsize == 0 && arg[0] != YYSYMBOL_YYEMPTY;
|
||||
if (too_many_expected_tokens)
|
||||
argsize = ARGS_MAX;
|
||||
const char *format = error_format_string (1 + argsize + too_many_expected_tokens);
|
||||
|
||||
while (*format)
|
||||
// %@: location.
|
||||
@@ -362,7 +393,7 @@ yyreport_syntax_error (const yypcontext_t *ctx)
|
||||
}
|
||||
// %0e, %1e...: expected token.
|
||||
else if (format[0] == '%'
|
||||
&& isdigit (format[1])
|
||||
&& isdigit ((unsigned char) format[1])
|
||||
&& format[2] == 'e'
|
||||
&& (format[1] - '0') < argsize)
|
||||
{
|
||||
@@ -393,12 +424,30 @@ void yyerror (YYLTYPE *loc, char const *format, ...)
|
||||
}
|
||||
|
||||
|
||||
// Return a newly allocated copy of at most N bytes of STRING. In
|
||||
// other words, return a copy of the initial segment of length N of
|
||||
// STRING.
|
||||
static char *
|
||||
xstrndup (const char *string, size_t n)
|
||||
{
|
||||
// len = strnlen (string, n), portably.
|
||||
const char *end = memchr (string, '\0', n);
|
||||
size_t len = end ? (size_t) (end - string) : n;
|
||||
char *new = malloc (len + 1);
|
||||
if (!new)
|
||||
abort ();
|
||||
new[len] = '\0';
|
||||
return memcpy (new, string, len);
|
||||
}
|
||||
|
||||
|
||||
/*-----------.
|
||||
| Readline. |
|
||||
`-----------*/
|
||||
|
||||
// Parse (and execute) this line.
|
||||
int process_line (YYLTYPE *lloc, const char *line)
|
||||
static int
|
||||
process_line (YYLTYPE *lloc, const char *line)
|
||||
{
|
||||
yypstate *ps = yypstate_new ();
|
||||
int status = 0;
|
||||
@@ -413,7 +462,8 @@ int process_line (YYLTYPE *lloc, const char *line)
|
||||
}
|
||||
|
||||
// Get the list of possible tokens after INPUT was read.
|
||||
int
|
||||
// Returns a nonnegative.
|
||||
static int
|
||||
expected_tokens (const char *input,
|
||||
int *tokens, int ntokens)
|
||||
{
|
||||
@@ -423,7 +473,7 @@ expected_tokens (const char *input,
|
||||
yypstate *ps = yypstate_new ();
|
||||
int status = 0;
|
||||
do {
|
||||
YYLTYPE lloc;
|
||||
YYLTYPE lloc = { 1, 1, 1, 1 };
|
||||
YYSTYPE lval;
|
||||
int token = yylex (&input, &lval, &lloc);
|
||||
// Don't let the parse know when we reach the end of input.
|
||||
@@ -432,18 +482,25 @@ expected_tokens (const char *input,
|
||||
status = yypush_parse (ps, token, &lval, &lloc);
|
||||
} while (status == YYPUSH_MORE);
|
||||
|
||||
// Then query for the accepted tokens at this point.
|
||||
int res = yypstate_expected_tokens (ps, tokens, ntokens);
|
||||
int res = 0;
|
||||
// If there were parse errors, don't propose completions.
|
||||
if (!ps->yynerrs)
|
||||
{
|
||||
// Then query for the accepted tokens at this point.
|
||||
res = yypstate_expected_tokens (ps, tokens, ntokens);
|
||||
if (res < 0)
|
||||
abort ();
|
||||
}
|
||||
yypstate_delete (ps);
|
||||
return res;
|
||||
}
|
||||
|
||||
/* Attempt to complete on the contents of TEXT. START and END bound the
|
||||
region of rl_line_buffer that contains the word to complete. TEXT is
|
||||
the word to complete. We can use the entire contents of rl_line_buffer
|
||||
in case we want to do some simple parsing. Return the array of matches,
|
||||
or NULL if there aren't any. */
|
||||
char **
|
||||
// Attempt to complete on the contents of TEXT. START and END bound
|
||||
// the region of rl_line_buffer that contains the word to complete.
|
||||
// TEXT is the word to complete. We can use the entire contents of
|
||||
// rl_line_buffer in case we want to do some simple parsing. Return
|
||||
// the array of matches, or NULL if there aren't any.
|
||||
static char **
|
||||
completion (const char *text, int start, int end)
|
||||
{
|
||||
YYDPRINTF ((stderr, "completion (\"%.*s[%.*s]%s\")\n",
|
||||
@@ -453,14 +510,17 @@ completion (const char *text, int start, int end)
|
||||
|
||||
// Get list of token numbers.
|
||||
int tokens[YYNTOKENS];
|
||||
char *line = strndup (rl_line_buffer, start);
|
||||
char *line = xstrndup (rl_line_buffer, (size_t) start);
|
||||
int ntokens = expected_tokens (line, tokens, YYNTOKENS);
|
||||
free (line);
|
||||
|
||||
// Build MATCHES, the list of possible completions.
|
||||
const int len = strlen (text);
|
||||
const size_t len = strlen (text);
|
||||
// Need initial prefix and final NULL.
|
||||
char **matches = calloc (ntokens + symbol_count () + 2, sizeof *matches);
|
||||
char **matches
|
||||
= calloc ((size_t) ntokens + (size_t) symbol_count () + 2, sizeof *matches);
|
||||
if (!matches)
|
||||
abort ();
|
||||
int match = 1;
|
||||
for (int i = 0; i < ntokens; ++i)
|
||||
switch (tokens[i])
|
||||
@@ -490,12 +550,12 @@ completion (const char *text, int start, int end)
|
||||
matches[0] = strdup (text);
|
||||
else
|
||||
{
|
||||
int lcplen = strlen (matches[1]);
|
||||
size_t lcplen = strlen (matches[1]);
|
||||
for (int i = 2; i < match && lcplen; ++i)
|
||||
for (int j = 0; j < lcplen; ++j)
|
||||
for (size_t j = 0; j < lcplen; ++j)
|
||||
if (matches[1][j] != matches[i][j])
|
||||
lcplen = j;
|
||||
matches[0] = strndup (matches[1], lcplen);
|
||||
matches[0] = xstrndup (matches[1], lcplen);
|
||||
}
|
||||
|
||||
if (yydebug)
|
||||
@@ -516,7 +576,8 @@ completion (const char *text, int start, int end)
|
||||
return matches;
|
||||
}
|
||||
|
||||
void init_readline (void)
|
||||
static void
|
||||
init_readline (void)
|
||||
{
|
||||
// Allow conditional parsing of the ~/.inputrc file.
|
||||
rl_readline_name = "bistromathic";
|
||||
@@ -535,7 +596,8 @@ void init_readline (void)
|
||||
| Main. |
|
||||
`-------*/
|
||||
|
||||
int main (int argc, char const* argv[])
|
||||
int
|
||||
main (int argc, char const* argv[])
|
||||
{
|
||||
#if defined ENABLE_NLS && ENABLE_NLS
|
||||
// Set up internationalization.
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
%code top {
|
||||
#include <assert.h>
|
||||
#include <ctype.h> /* isdigit. */
|
||||
#include <stdio.h> /* For printf, etc. */
|
||||
#include <stdio.h> /* printf. */
|
||||
#include <stdlib.h> /* abort. */
|
||||
#include <string.h> /* strcmp. */
|
||||
|
||||
int yylex (void);
|
||||
@@ -73,7 +75,8 @@ yylex (void)
|
||||
if (c == '.' || isdigit (c))
|
||||
{
|
||||
ungetc (c, stdin);
|
||||
scanf ("%lf", &yylval.NUM);
|
||||
if (scanf ("%lf", &yylval.NUM) != 1)
|
||||
abort ();
|
||||
return NUM;
|
||||
}
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@ nodist_%C%_calc_SOURCES = %D%/calc.y
|
||||
|
||||
# Don't use gnulib's system headers.
|
||||
%C%_calc_CPPFLAGS = -I$(top_srcdir)/%D% -I$(top_builddir)/%D%
|
||||
%C%_calc_CFLAGS = $(TEST_CFLAGS)
|
||||
|
||||
dist_calc_DATA = %D%/calc.y %D%/Makefile %D%/README.md
|
||||
CLEANFILES += %D%/calc.[ch] %D%/calc.output %D%/scan.c
|
||||
|
||||
@@ -25,6 +25,8 @@ if FLEX_WORKS
|
||||
nodist_%C%_lexcalc_SOURCES = %D%/parse.y %D%/parse.h %D%/scan.l
|
||||
# Don't use gnulib's system headers.
|
||||
%C%_lexcalc_CPPFLAGS = -I$(top_srcdir)/%D% -I$(top_builddir)/%D%
|
||||
# Fighting warnings triggered by Flex is just too painful.
|
||||
# %C%_lexcalc_CFLAGS = $(TEST_CFLAGS)
|
||||
endif FLEX_WORKS
|
||||
|
||||
%D%/parse.c: $(dependencies)
|
||||
|
||||
@@ -1,3 +1,22 @@
|
||||
/* Parser for lexcalc. -*- C -*-
|
||||
|
||||
Copyright (C) 2018-2020 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of Bison, the GNU Compiler Compiler.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
// Prologue (directives).
|
||||
%expect 0
|
||||
|
||||
@@ -19,6 +38,9 @@
|
||||
#include <stdlib.h> // getenv.
|
||||
}
|
||||
|
||||
// Include the header in the implementation rather than duplicating it.
|
||||
%define api.header.include {"parse.h"}
|
||||
|
||||
// Don't share global variables between the scanner and the parser.
|
||||
%define api.pure full
|
||||
|
||||
|
||||
@@ -1,10 +1,29 @@
|
||||
/* Prologue (directives). -*- C -*- */
|
||||
/* Scanner for lexcalc. -*- C -*-
|
||||
|
||||
Copyright (C) 2018-2020 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of Bison, the GNU Compiler Compiler.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Prologue (directives). */
|
||||
|
||||
/* Disable Flex features we don't need, to avoid warnings. */
|
||||
%option nodefault noinput nounput noyywrap
|
||||
|
||||
%{
|
||||
#include <errno.h> /* errno, ERANGE */
|
||||
#include <errno.h> /* errno, ERANGE */
|
||||
#include <limits.h> /* INT_MIN */
|
||||
#include <stdlib.h> /* strtol */
|
||||
|
||||
@@ -12,7 +31,7 @@
|
||||
|
||||
// Each time a rule is matched, advance the end cursor/position.
|
||||
#define YY_USER_ACTION \
|
||||
yylloc->last_column += yyleng;
|
||||
yylloc->last_column += (int) yyleng;
|
||||
|
||||
// Move the first position onto the last.
|
||||
#define LOCATION_STEP() \
|
||||
|
||||
@@ -31,6 +31,7 @@ nodist_%C%_mfcalc_SOURCES = $(mfcalc_sources)
|
||||
%D%/mfcalc.c: $(dependencies)
|
||||
# Don't use gnulib's system headers.
|
||||
%C%_mfcalc_CPPFLAGS = -I$(top_srcdir)/%D% -I$(top_builddir)/%D%
|
||||
%C%_mfcalc_CFLAGS = $(TEST_CFLAGS)
|
||||
%C%_mfcalc_LDADD = -lm
|
||||
|
||||
dist_TESTS += %D%/mfcalc.test
|
||||
|
||||
@@ -1,7 +1,26 @@
|
||||
/* Parser and scanner for pushcalc. -*- C -*-
|
||||
|
||||
Copyright (C) 2020 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of Bison, the GNU Compiler Compiler.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
%code top {
|
||||
#include <ctype.h> /* isdigit. */
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h> /* For printf, etc. */
|
||||
#include <stdio.h> /* printf. */
|
||||
#include <stdlib.h> /* abort. */
|
||||
#include <string.h> /* strcmp. */
|
||||
}
|
||||
|
||||
@@ -81,7 +100,8 @@ yylex (YYSTYPE *yylval)
|
||||
if (c == '.' || isdigit (c))
|
||||
{
|
||||
ungetc (c, stdin);
|
||||
scanf ("%lf", &yylval->NUM);
|
||||
if (scanf ("%lf", &yylval->NUM) != 1)
|
||||
abort ();
|
||||
return NUM;
|
||||
}
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@ nodist_%C%_calc_SOURCES = %D%/calc.y
|
||||
|
||||
# Don't use gnulib's system headers.
|
||||
%C%_calc_CPPFLAGS = -I$(top_srcdir)/%D% -I$(top_builddir)/%D%
|
||||
%C%_calc_CFLAGS = $(TEST_CFLAGS)
|
||||
|
||||
dist_pushcalc_DATA = %D%/calc.y %D%/Makefile %D%/README.md
|
||||
CLEANFILES += %D%/calc.[ch] %D%/calc.output
|
||||
|
||||
@@ -26,6 +26,8 @@ if FLEX_WORKS
|
||||
BUILT_SOURCES += $(nodist_%C%_reccalc_SOURCES)
|
||||
# Don't use gnulib's system headers.
|
||||
%C%_reccalc_CPPFLAGS = -I$(top_srcdir)/%D% -I$(top_builddir)/%D%
|
||||
# Fighting warnings triggered by Flex is just too painful.
|
||||
# %C%_reccalc_CFLAGS = $(TEST_CFLAGS)
|
||||
endif FLEX_WORKS
|
||||
|
||||
%D%/parse.c: $(dependencies)
|
||||
|
||||
@@ -1,3 +1,22 @@
|
||||
/* Parser for reccalc. -*- C -*-
|
||||
|
||||
Copyright (C) 2019-2020 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of Bison, the GNU Compiler Compiler.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
// Prologue (directives).
|
||||
%expect 0
|
||||
|
||||
@@ -46,14 +65,29 @@
|
||||
result parse (void);
|
||||
}
|
||||
|
||||
// Include the header in the implementation rather than duplicating it.
|
||||
%define api.header.include {"parse.h"}
|
||||
|
||||
// Don't share global variables between the scanner and the parser.
|
||||
%define api.pure full
|
||||
|
||||
// To avoid name clashes (e.g., with C's EOF) prefix token definitions
|
||||
// with TOK_ (e.g., TOK_EOF).
|
||||
%define api.token.prefix {TOK_}
|
||||
|
||||
// Generate YYSTYPE from the types assigned to symbols.
|
||||
%define api.value.type union
|
||||
%define parse.error verbose
|
||||
|
||||
// Error messages with "unexpected XXX, expected XXX...".
|
||||
%define parse.error detailed
|
||||
|
||||
// Enable run-time traces (yydebug).
|
||||
%define parse.trace
|
||||
|
||||
// Generate the parser description file (parse.output).
|
||||
%verbose
|
||||
|
||||
// Scanner and error count are exchanged between main, yyparse and yylex.
|
||||
// Scanner and error count are exchanged between main, yyparse and yylex.
|
||||
%param {yyscan_t scanner}{result *res}
|
||||
|
||||
%token
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
seq 0 >/dev/null || exit 77
|
||||
(seq 0) >/dev/null 2>&1 || skip "gimme one seq"
|
||||
|
||||
cat >input <<EOF
|
||||
1+2*3
|
||||
|
||||
@@ -1,3 +1,22 @@
|
||||
/* Scanner for reccalc. -*- C -*-
|
||||
|
||||
Copyright (C) 2019-2020 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of Bison, the GNU Compiler Compiler.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Prologue (directives). -*- C -*- */
|
||||
|
||||
/* Disable Flex features we don't need, to avoid warnings. */
|
||||
@@ -32,9 +51,9 @@
|
||||
do \
|
||||
capacity = capacity ? 2 * capacity : 128; \
|
||||
while (capacity < size + yyleng + 1); \
|
||||
str = realloc (str, capacity); \
|
||||
str = realloc (str, (size_t) capacity); \
|
||||
} \
|
||||
memcpy (str + size, yytext, yyleng); \
|
||||
memcpy (str + size, yytext, (size_t) yyleng); \
|
||||
size += yyleng; \
|
||||
assert (size < capacity); \
|
||||
} while (0)
|
||||
|
||||
@@ -31,6 +31,7 @@ nodist_%C%_rpcalc_SOURCES = $(rpcalc_sources)
|
||||
%D%/rpcalc.c: $(dependencies)
|
||||
# Don't use gnulib's system headers.
|
||||
%C%_rpcalc_CPPFLAGS = -I$(top_builddir)/%D%
|
||||
%C%_rpcalc_CFLAGS = $(TEST_CFLAGS)
|
||||
%C%_rpcalc_LDADD = -lm
|
||||
|
||||
dist_TESTS += %D%/rpcalc.test
|
||||
|
||||
@@ -1,3 +1,22 @@
|
||||
/* Parser and scanner for calc in D. -*- D -*-
|
||||
|
||||
Copyright (C) 2018-2020 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of Bison, the GNU Compiler Compiler.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
%language "D"
|
||||
|
||||
%define api.parser.class {Calc}
|
||||
|
||||
@@ -1,3 +1,22 @@
|
||||
/* Parser and scanner for calc in Java. -*- Java -*-
|
||||
|
||||
Copyright (C) 2018-2020 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of Bison, the GNU Compiler Compiler.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
%language "Java"
|
||||
|
||||
%define api.parser.class {Calc}
|
||||
|
||||
@@ -1,3 +1,22 @@
|
||||
/* Simple parser and scanner in Java. -*- Java -*-
|
||||
|
||||
Copyright (C) 2018-2020 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of Bison, the GNU Compiler Compiler.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
%language "Java"
|
||||
|
||||
%define api.parser.class {Calc}
|
||||
|
||||
@@ -35,6 +35,9 @@
|
||||
dist_noinst_SCRIPTS = %D%/extexi %D%/test
|
||||
TEST_LOG_COMPILER = $(SHELL) $(top_srcdir)/%D%/test
|
||||
|
||||
TEST_CFLAGS = \
|
||||
$(WARN_CFLAGS) $(WARN_CFLAGS_TEST) $(WERROR_CFLAGS)
|
||||
|
||||
AM_CXXFLAGS = \
|
||||
$(WARN_CXXFLAGS) $(WARN_CXXFLAGS_TEST) $(WERROR_CXXFLAGS)
|
||||
|
||||
|
||||
+30
-8
@@ -25,7 +25,7 @@ medir=$(dirname "$1" | sed -e 's,.*examples/,,')
|
||||
number=1
|
||||
|
||||
# Exit status of this script.
|
||||
exit=true
|
||||
status=0
|
||||
|
||||
# top_builddir.
|
||||
cwd=$(pwd)
|
||||
@@ -34,6 +34,14 @@ cwd=$(pwd)
|
||||
# See bistromathic.test.
|
||||
strip_prompt=false
|
||||
|
||||
# If diff supports --strip-trailing-cr, use it, to avoid EOL issues
|
||||
# when testing Java programs on Windows.
|
||||
echo "checking for diff --strip-trailing-cr..."
|
||||
if diff --strip-trailing-cr "$1" "$1"; then
|
||||
diff_opts=--strip-trailing-cr
|
||||
fi
|
||||
echo "checking for diff --strip-trailing-cr... $diff_opts"
|
||||
|
||||
# The exercised program.
|
||||
abs_medir=$cwd/examples/$medir
|
||||
if test -x "$abs_medir/$me"; then
|
||||
@@ -68,6 +76,20 @@ trap cleanup 0 1 2 13 15
|
||||
mkdir $$.dir
|
||||
cd $$.dir
|
||||
|
||||
|
||||
# skip [MSG]
|
||||
# ----------
|
||||
# Skip this test.
|
||||
skip ()
|
||||
{
|
||||
if test x"$1" != x; then
|
||||
echo "SKIP: $1"
|
||||
fi
|
||||
# See Autoconf's doc on 'trap'.
|
||||
(exit 77); exit 77
|
||||
}
|
||||
|
||||
|
||||
# run [-noerr, -n] EXPECTED-EXIT-STATUS EXPECTED-OUTPUT [PARSER-OPTIONS]
|
||||
# ----------------------------------------------------------------------
|
||||
# -noerr: ignore stderr, otherwise merge it into effective output.
|
||||
@@ -115,7 +137,7 @@ run ()
|
||||
} >eff
|
||||
|
||||
if test $sta_eff -eq $sta_exp; then
|
||||
if cmp eff exp 2>/dev/null; then
|
||||
if diff $diff_opts eff exp >/dev/null 2>&1; then
|
||||
echo "$me: PASS: $number"
|
||||
else
|
||||
echo "$me: FAIL: $number"
|
||||
@@ -126,21 +148,21 @@ run ()
|
||||
echo "$me: effective output:"
|
||||
sed -e 's/^/ /' eff
|
||||
echo "$me: diff:"
|
||||
diff -u exp eff | sed -e 's/^/ /'
|
||||
exit=false
|
||||
diff $diff_opts -u exp eff | sed -e 's/^/ /'
|
||||
status=1
|
||||
fi
|
||||
else
|
||||
echo "$me: FAIL: $number (expected status: $sta_exp, effective: $sta_eff)"
|
||||
cat err_eff
|
||||
exit=false
|
||||
status=1
|
||||
fi
|
||||
number=$(expr $number + 1)
|
||||
}
|
||||
|
||||
# We have cd'd one level deeper.
|
||||
case $1 in
|
||||
/*) . "$1";;
|
||||
*) . "../$1";;
|
||||
/*) . "$1" || status=2;;
|
||||
*) . "../$1" || status=2;;
|
||||
esac
|
||||
|
||||
$exit
|
||||
exit $status
|
||||
|
||||
+1
-1
Submodule gnulib updated: 3db0ae5f4f...12c89745e3
@@ -18,7 +18,9 @@
|
||||
/asnprintf.c
|
||||
/asprintf.c
|
||||
/assure.h
|
||||
/attribute.h
|
||||
/basename-lgpl.c
|
||||
/basename-lgpl.h
|
||||
/basename.c
|
||||
/binary-io.c
|
||||
/binary-io.h
|
||||
@@ -117,10 +119,31 @@
|
||||
/gettext.h
|
||||
/gettime.c
|
||||
/gettimeofday.c
|
||||
/gl_anyhash1.h
|
||||
/gl_anyhash2.h
|
||||
/gl_anyhash_primes.h
|
||||
/gl_anylinked_list1.h
|
||||
/gl_anylinked_list2.h
|
||||
/gl_anyrbtree_list1.h
|
||||
/gl_anyrbtree_list2.h
|
||||
/gl_anytree_list1.h
|
||||
/gl_anytree_list2.h
|
||||
/gl_anytree_oset.h
|
||||
/gl_anytreehash_list1.h
|
||||
/gl_anytreehash_list2.h
|
||||
/gl_array_list.c
|
||||
/gl_array_list.h
|
||||
/gl_linked_list.c
|
||||
/gl_linked_list.h
|
||||
/gl_list.c
|
||||
/gl_list.h
|
||||
/gl_oset.c
|
||||
/gl_oset.h
|
||||
/gl_rbtree_ordered.h
|
||||
/gl_rbtree_oset.c
|
||||
/gl_rbtree_oset.h
|
||||
/gl_rbtreehash_list.c
|
||||
/gl_rbtreehash_list.h
|
||||
/gl_xlist.c
|
||||
/gl_xlist.h
|
||||
/gnulib.mk
|
||||
@@ -128,6 +151,23 @@
|
||||
/hard-locale.h
|
||||
/hash.c
|
||||
/hash.h
|
||||
/iconv.c
|
||||
/iconv.h
|
||||
/iconv.in.h
|
||||
/iconv_close.c
|
||||
/iconv_open-aix.gperf
|
||||
/iconv_open-aix.h
|
||||
/iconv_open-hpux.gperf
|
||||
/iconv_open-hpux.h
|
||||
/iconv_open-irix.gperf
|
||||
/iconv_open-irix.h
|
||||
/iconv_open-osf.gperf
|
||||
/iconv_open-osf.h
|
||||
/iconv_open-solaris.gperf
|
||||
/iconv_open-solaris.h
|
||||
/iconv_open-zos.gperf
|
||||
/iconv_open-zos.h
|
||||
/iconv_open.c
|
||||
/intprops.h
|
||||
/inttypes.h
|
||||
/inttypes.in.h
|
||||
@@ -305,11 +345,16 @@
|
||||
/timespec.h
|
||||
/timevar.c
|
||||
/timevar.h
|
||||
/unicodeio.c
|
||||
/unicodeio.h
|
||||
/unistd--.h
|
||||
/unistd-safer.h
|
||||
/unistd.c
|
||||
/unistd.h
|
||||
/unistd.in.h
|
||||
/unistr.h
|
||||
/unistr.in.h
|
||||
/unistr/
|
||||
/unitypes.h
|
||||
/unitypes.in.h
|
||||
/uniwidth
|
||||
@@ -318,6 +363,7 @@
|
||||
/unlink.c
|
||||
/unlocked-io.h
|
||||
/unsetenv.c
|
||||
/unused-parameter.h
|
||||
/vasnprintf.c
|
||||
/vasnprintf.h
|
||||
/vasprintf.c
|
||||
|
||||
+6
-2
@@ -1,4 +1,3 @@
|
||||
/extern-inline.m4~
|
||||
/*~
|
||||
/00gnulib.m4
|
||||
/__inline.m4
|
||||
@@ -6,6 +5,7 @@
|
||||
/alloca.m4
|
||||
/asm-underscore.m4
|
||||
/assert.m4
|
||||
/builtin-expect.m4
|
||||
/calloc.m4
|
||||
/canonicalize.m4
|
||||
/clock_time.m4
|
||||
@@ -13,7 +13,6 @@
|
||||
/codeset.m4
|
||||
/config-h.m4
|
||||
/configmake.m4
|
||||
/dirname.m4
|
||||
/double-slash-root.m4
|
||||
/dup2.m4
|
||||
/eealloc.m4
|
||||
@@ -25,6 +24,7 @@
|
||||
/exponentl.m4
|
||||
/extensions.m4
|
||||
/extern-inline.m4
|
||||
/extern-inline.m4~
|
||||
/fatal-signal.m4
|
||||
/fcntl-o.m4
|
||||
/fcntl.m4
|
||||
@@ -57,7 +57,10 @@
|
||||
/gnulib-tool.m4
|
||||
/host-cpu-c-abi.m4
|
||||
/iconv.m4
|
||||
/iconv_h.m4
|
||||
/iconv_open.m4
|
||||
/include_next.m4
|
||||
/inline.m4
|
||||
/intdiv0.m4
|
||||
/intl.m4
|
||||
/intldir.m4
|
||||
@@ -192,6 +195,7 @@
|
||||
/timespec.m4
|
||||
/tls.m4
|
||||
/uintmax_t.m4
|
||||
/unicodeio.m4
|
||||
/unistd-safer.m4
|
||||
/unistd_h.m4
|
||||
/unlink.m4
|
||||
|
||||
@@ -2,6 +2,7 @@ examples/c/bistromathic/parse.y
|
||||
examples/java/calc/Calc.y
|
||||
src/complain.c
|
||||
src/conflicts.c
|
||||
src/counterexample.c
|
||||
src/files.c
|
||||
src/fixits.c
|
||||
src/getargs.c
|
||||
|
||||
+160
-175
@@ -18,11 +18,13 @@
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <config.h>
|
||||
#include "system.h"
|
||||
|
||||
#include "AnnotationList.h"
|
||||
#include "lalr.h"
|
||||
|
||||
#include "system.h"
|
||||
|
||||
#include "ielr.h"
|
||||
#include "lalr.h"
|
||||
|
||||
/**
|
||||
* \pre
|
||||
@@ -38,15 +40,14 @@ static AnnotationList*
|
||||
AnnotationList__alloc_on_obstack (ContributionIndex contribution_count,
|
||||
struct obstack *annotations_obstackp)
|
||||
{
|
||||
AnnotationList *result;
|
||||
size_t contributions_size =
|
||||
contribution_count * sizeof result->contributions[0];
|
||||
result = obstack_alloc (annotations_obstackp,
|
||||
offsetof (AnnotationList, contributions)
|
||||
+ contributions_size);
|
||||
result->next = NULL;
|
||||
result->inadequacyNode = NULL;
|
||||
return result;
|
||||
AnnotationList *res;
|
||||
size_t contributions_size = contribution_count * sizeof res->contributions[0];
|
||||
res = obstack_alloc (annotations_obstackp,
|
||||
offsetof (AnnotationList, contributions)
|
||||
+ contributions_size);
|
||||
res->next = NULL;
|
||||
res->inadequacyNode = NULL;
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -102,13 +103,12 @@ AnnotationList__insertInto (AnnotationList *self, AnnotationList **list,
|
||||
for (node = list; *node; node = &(*node)->next)
|
||||
{
|
||||
int cmp = 0;
|
||||
ContributionIndex ci;
|
||||
if (self->inadequacyNode->id < (*node)->inadequacyNode->id)
|
||||
cmp = 1;
|
||||
else if ((*node)->inadequacyNode->id < self->inadequacyNode->id)
|
||||
cmp = -1;
|
||||
else
|
||||
for (ci = 0;
|
||||
for (ContributionIndex ci = 0;
|
||||
cmp == 0 && ci < self->inadequacyNode->contributionCount;
|
||||
++ci)
|
||||
{
|
||||
@@ -120,19 +120,16 @@ AnnotationList__insertInto (AnnotationList *self, AnnotationList **list,
|
||||
else if (AnnotationList__isContributionAlways (*node, ci))
|
||||
cmp = 1;
|
||||
else
|
||||
{
|
||||
size_t item;
|
||||
for (item = 0; cmp == 0 && item < nitems; ++item)
|
||||
{
|
||||
if (!Sbitset__test (self->contributions[ci], item))
|
||||
{
|
||||
if (Sbitset__test ((*node)->contributions[ci], item))
|
||||
cmp = -1;
|
||||
}
|
||||
else if (!Sbitset__test ((*node)->contributions[ci], item))
|
||||
cmp = 1;
|
||||
}
|
||||
}
|
||||
for (size_t item = 0; cmp == 0 && item < nitems; ++item)
|
||||
{
|
||||
if (!Sbitset__test (self->contributions[ci], item))
|
||||
{
|
||||
if (Sbitset__test ((*node)->contributions[ci], item))
|
||||
cmp = -1;
|
||||
}
|
||||
else if (!Sbitset__test ((*node)->contributions[ci], item))
|
||||
cmp = 1;
|
||||
}
|
||||
}
|
||||
if (cmp < 0)
|
||||
{
|
||||
@@ -188,7 +185,7 @@ AnnotationList__compute_conflicted_tokens (bitset shift_tokens,
|
||||
}
|
||||
|
||||
static bool
|
||||
AnnotationList__compute_lhs_contributions (state *s, rule *the_rule,
|
||||
AnnotationList__compute_lhs_contributions (state *s, const rule *the_rule,
|
||||
symbol_number conflicted_token,
|
||||
bitsetv follow_kernel_items,
|
||||
bitsetv always_follows,
|
||||
@@ -232,115 +229,110 @@ AnnotationList__computePredecessorAnnotations (
|
||||
annotation_node->inadequacyNode = self->inadequacyNode;
|
||||
bool potential_contribution = false;
|
||||
bitset *lookaheads = NULL;
|
||||
{
|
||||
for (ContributionIndex ci = 0; ci < self->inadequacyNode->contributionCount; ++ci)
|
||||
{
|
||||
symbol_number contribution_token =
|
||||
InadequacyList__getContributionToken (self->inadequacyNode, ci)
|
||||
->content->number;
|
||||
if (AnnotationList__isContributionAlways (self, ci))
|
||||
{
|
||||
annotation_node->contributions[ci] = NULL;
|
||||
continue;
|
||||
}
|
||||
annotation_node->contributions[ci] =
|
||||
Sbitset__new_on_obstack ((*predecessor)->nitems,
|
||||
annotations_obstackp);
|
||||
|
||||
for (ContributionIndex ci = 0; ci < self->inadequacyNode->contributionCount; ++ci)
|
||||
{
|
||||
symbol_number contribution_token =
|
||||
InadequacyList__getContributionToken (self->inadequacyNode, ci)
|
||||
->content->number;
|
||||
if (AnnotationList__isContributionAlways (self, ci))
|
||||
{
|
||||
size_t predecessor_item = 0;
|
||||
Sbitset sbiter_item;
|
||||
Sbitset__Index self_item;
|
||||
SBITSET__FOR_EACH (self->contributions[ci], s->nitems,
|
||||
sbiter_item, self_item)
|
||||
{
|
||||
/* If this kernel item is the beginning of a RHS, it must be
|
||||
the kernel item in the start state, and so it has an empty
|
||||
lookahead set. Thus, it can't contribute to inadequacies,
|
||||
and so it should never have been identified as a
|
||||
contribution. If, instead, this kernel item is the
|
||||
successor of the start state's kernel item, the lookahead
|
||||
set is still empty, and so it also should never have been
|
||||
identified as a contribution. This situation is fortunate
|
||||
because we want to avoid the - 2 below in both cases. */
|
||||
aver (s->items[self_item] > 1);
|
||||
/* If this kernel item is next to the beginning of the RHS,
|
||||
then check all of the predecessor's goto follows for the
|
||||
LHS. */
|
||||
if (item_number_is_rule_number (ritem[s->items[self_item]
|
||||
- 2]))
|
||||
{
|
||||
int rulei;
|
||||
for (rulei = s->items[self_item];
|
||||
!item_number_is_rule_number (ritem[rulei]);
|
||||
++rulei)
|
||||
continue;
|
||||
Sbitset items;
|
||||
if (AnnotationList__compute_lhs_contributions (
|
||||
*predecessor,
|
||||
&rules[item_number_as_rule_number (ritem[rulei])],
|
||||
contribution_token,
|
||||
follow_kernel_items, always_follows, predecessors,
|
||||
item_lookahead_sets, &items, annotations_obstackp))
|
||||
{
|
||||
obstack_free (annotations_obstackp,
|
||||
annotation_node->contributions[ci]);
|
||||
annotation_node->contributions[ci] = NULL;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
Sbitset__or (annotation_node->contributions[ci],
|
||||
annotation_node->contributions[ci],
|
||||
items, (*predecessor)->nitems);
|
||||
obstack_free (annotations_obstackp, items);
|
||||
}
|
||||
}
|
||||
/* If this kernel item is later in the RHS, then check the
|
||||
predecessor item's lookahead set. */
|
||||
else
|
||||
{
|
||||
/* We don't have to start the predecessor item search at
|
||||
the beginning every time because items from both
|
||||
states are sorted by their indices in ritem. */
|
||||
for (;
|
||||
predecessor_item < (*predecessor)->nitems;
|
||||
++predecessor_item)
|
||||
if ((*predecessor)->items[predecessor_item]
|
||||
== s->items[self_item] - 1)
|
||||
break;
|
||||
aver (predecessor_item != (*predecessor)->nitems);
|
||||
if (ielr_item_has_lookahead (*predecessor, 0,
|
||||
predecessor_item,
|
||||
contribution_token,
|
||||
predecessors,
|
||||
item_lookahead_sets))
|
||||
Sbitset__set (annotation_node->contributions[ci],
|
||||
predecessor_item);
|
||||
}
|
||||
}
|
||||
annotation_node->contributions[ci] = NULL;
|
||||
continue;
|
||||
}
|
||||
if (annotation_node->contributions[ci])
|
||||
annotation_node->contributions[ci] =
|
||||
Sbitset__new_on_obstack ((*predecessor)->nitems,
|
||||
annotations_obstackp);
|
||||
{
|
||||
size_t predecessor_item = 0;
|
||||
Sbitset sbiter_item;
|
||||
Sbitset__Index self_item;
|
||||
SBITSET__FOR_EACH (self->contributions[ci], s->nitems,
|
||||
sbiter_item, self_item)
|
||||
{
|
||||
Sbitset biter;
|
||||
Sbitset__Index i;
|
||||
SBITSET__FOR_EACH (annotation_node->contributions[ci],
|
||||
(*predecessor)->nitems, biter, i)
|
||||
/* If this kernel item is the beginning of a RHS, it must be
|
||||
the kernel item in the start state, and so it has an empty
|
||||
lookahead set. Thus, it can't contribute to inadequacies,
|
||||
and so it should never have been identified as a
|
||||
contribution. If, instead, this kernel item is the
|
||||
successor of the start state's kernel item, the lookahead
|
||||
set is still empty, and so it also should never have been
|
||||
identified as a contribution. This situation is fortunate
|
||||
because we want to avoid the - 2 below in both cases. */
|
||||
aver (s->items[self_item] > 1);
|
||||
/* If this kernel item is next to the beginning of the RHS,
|
||||
then check all of the predecessor's goto follows for the
|
||||
LHS. */
|
||||
if (item_number_is_rule_number (ritem[s->items[self_item] - 2]))
|
||||
{
|
||||
potential_contribution = true;
|
||||
if (!lookaheads)
|
||||
Sbitset items;
|
||||
if (AnnotationList__compute_lhs_contributions (
|
||||
*predecessor,
|
||||
item_rule (&ritem[s->items[self_item]]),
|
||||
contribution_token,
|
||||
follow_kernel_items, always_follows, predecessors,
|
||||
item_lookahead_sets, &items, annotations_obstackp))
|
||||
{
|
||||
lookaheads = xnmalloc ((*predecessor)->nitems,
|
||||
sizeof *lookaheads);
|
||||
for (size_t j = 0; j < (*predecessor)->nitems; ++j)
|
||||
lookaheads[j] = NULL;
|
||||
obstack_free (annotations_obstackp,
|
||||
annotation_node->contributions[ci]);
|
||||
annotation_node->contributions[ci] = NULL;
|
||||
// "Break" out of SBITSET__FOR_EACH.
|
||||
goto after_sbitset__for_each;
|
||||
}
|
||||
if (!lookaheads[i])
|
||||
lookaheads[i] = bitset_create (ntokens, BITSET_FIXED);
|
||||
bitset_set (lookaheads[i], contribution_token);
|
||||
else
|
||||
{
|
||||
Sbitset__or (annotation_node->contributions[ci],
|
||||
annotation_node->contributions[ci],
|
||||
items, (*predecessor)->nitems);
|
||||
obstack_free (annotations_obstackp, items);
|
||||
}
|
||||
}
|
||||
/* If this kernel item is later in the RHS, then check the
|
||||
predecessor item's lookahead set. */
|
||||
else
|
||||
{
|
||||
/* We don't have to start the predecessor item search at
|
||||
the beginning every time because items from both
|
||||
states are sorted by their indices in ritem. */
|
||||
for (;
|
||||
predecessor_item < (*predecessor)->nitems;
|
||||
++predecessor_item)
|
||||
if ((*predecessor)->items[predecessor_item]
|
||||
== s->items[self_item] - 1)
|
||||
break;
|
||||
aver (predecessor_item != (*predecessor)->nitems);
|
||||
if (ielr_item_has_lookahead (*predecessor, 0,
|
||||
predecessor_item,
|
||||
contribution_token,
|
||||
predecessors,
|
||||
item_lookahead_sets))
|
||||
Sbitset__set (annotation_node->contributions[ci],
|
||||
predecessor_item);
|
||||
}
|
||||
}
|
||||
after_sbitset__for_each:;
|
||||
}
|
||||
}
|
||||
if (annotation_node->contributions[ci])
|
||||
{
|
||||
Sbitset biter;
|
||||
Sbitset__Index i;
|
||||
SBITSET__FOR_EACH (annotation_node->contributions[ci],
|
||||
(*predecessor)->nitems, biter, i)
|
||||
{
|
||||
potential_contribution = true;
|
||||
if (!lookaheads)
|
||||
{
|
||||
lookaheads = xnmalloc ((*predecessor)->nitems,
|
||||
sizeof *lookaheads);
|
||||
for (size_t j = 0; j < (*predecessor)->nitems; ++j)
|
||||
lookaheads[j] = NULL;
|
||||
}
|
||||
if (!lookaheads[i])
|
||||
lookaheads[i] = bitset_create (ntokens, BITSET_FIXED);
|
||||
bitset_set (lookaheads[i], contribution_token);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* If the predecessor has any contributions besides just "always" and
|
||||
"never" contributions:
|
||||
@@ -425,11 +417,7 @@ AnnotationList__compute_from_inadequacies (
|
||||
BITSET_FOR_EACH (biter_conflict, conflicted_tokens, conflicted_token, 0)
|
||||
{
|
||||
AnnotationList *annotation_node;
|
||||
/* FIXME: Would a BITSET_FRUGAL or BITEST_SPARSE be more efficient? Now
|
||||
or convert it inside InadequacyList__new_conflict? */
|
||||
bitset actions = bitset_create (s->reductions->num + 1, BITSET_FIXED);
|
||||
ContributionIndex contribution_count = 0;
|
||||
bool potential_contribution = false;
|
||||
|
||||
/* Allocate the annotation node. */
|
||||
{
|
||||
@@ -444,6 +432,11 @@ AnnotationList__compute_from_inadequacies (
|
||||
annotations_obstackp);
|
||||
}
|
||||
|
||||
/* FIXME: Would a BITSET_FRUGAL or BITEST_SPARSE be more efficient? Now
|
||||
or convert it inside InadequacyList__new_conflict? */
|
||||
bitset actions = bitset_create (s->reductions->num + 1, BITSET_FIXED);
|
||||
bool potential_contribution = false;
|
||||
|
||||
/* Add a contribution for each reduction that has conflicted_token as a
|
||||
lookahead. */
|
||||
{
|
||||
@@ -464,11 +457,8 @@ AnnotationList__compute_from_inadequacies (
|
||||
annotations_obstackp);
|
||||
/* Catch item_i up to rule_i. This works because both are
|
||||
sorted on rule number. */
|
||||
while (!item_number_is_rule_number (
|
||||
ritem[s->items[item_i]])
|
||||
|| item_number_as_rule_number (
|
||||
ritem[s->items[item_i]])
|
||||
!= the_rule->number)
|
||||
while (!item_number_is_rule_number (ritem[s->items[item_i]])
|
||||
|| item_number_as_rule_number (ritem[s->items[item_i]]) != the_rule->number)
|
||||
{
|
||||
++item_i;
|
||||
aver (item_i < s->nitems);
|
||||
@@ -571,44 +561,40 @@ AnnotationList__debug (AnnotationList const *self, size_t nitems, int spaces)
|
||||
AnnotationIndex ai;
|
||||
for (a = self, ai = 0; a; a = a->next, ++ai)
|
||||
{
|
||||
for (int j = 0; j < spaces; ++j)
|
||||
putc (' ', stderr);
|
||||
fprintf (stderr, "Annotation %d (manifesting state %d):\n",
|
||||
fprintf (stderr, "%*sAnnotation %d (manifesting state %d):\n",
|
||||
spaces, "",
|
||||
ai, a->inadequacyNode->manifestingState->number);
|
||||
{
|
||||
bitset_bindex rulei
|
||||
= bitset_first (a->inadequacyNode->inadequacy.conflict.actions);
|
||||
for (ContributionIndex ci = 0; ci < a->inadequacyNode->contributionCount; ++ci)
|
||||
{
|
||||
symbol_number token =
|
||||
InadequacyList__getContributionToken (a->inadequacyNode, ci)
|
||||
->content->number;
|
||||
for (int j = 0; j < spaces+2; ++j)
|
||||
putc (' ', stderr);
|
||||
if (ci == InadequacyList__getShiftContributionIndex (
|
||||
a->inadequacyNode))
|
||||
fprintf (stderr, "Contributes shift of token %d.\n", token);
|
||||
else
|
||||
{
|
||||
fprintf (stderr, "Contributes token %d", token);
|
||||
aver (rulei != BITSET_BINDEX_MAX);
|
||||
fprintf (stderr, " as lookahead, rule number %d",
|
||||
a->inadequacyNode->manifestingState
|
||||
->reductions->rules[rulei]->number);
|
||||
rulei =
|
||||
bitset_next (a->inadequacyNode->inadequacy.conflict.actions,
|
||||
rulei+1);
|
||||
if (AnnotationList__isContributionAlways (a, ci))
|
||||
fprintf (stderr, " always.");
|
||||
else
|
||||
{
|
||||
fprintf (stderr, ", items: ");
|
||||
Sbitset__fprint (a->contributions[ci], nitems, stderr);
|
||||
}
|
||||
fprintf (stderr, "\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
bitset_bindex rulei
|
||||
= bitset_first (a->inadequacyNode->inadequacy.conflict.actions);
|
||||
for (ContributionIndex ci = 0; ci < a->inadequacyNode->contributionCount; ++ci)
|
||||
{
|
||||
symbol_number token =
|
||||
InadequacyList__getContributionToken (a->inadequacyNode, ci)
|
||||
->content->number;
|
||||
fprintf (stderr, "%*s", spaces+2, "");
|
||||
if (ci == InadequacyList__getShiftContributionIndex (
|
||||
a->inadequacyNode))
|
||||
fprintf (stderr, "Contributes shift of token %d.\n", token);
|
||||
else
|
||||
{
|
||||
fprintf (stderr, "Contributes token %d", token);
|
||||
aver (rulei != BITSET_BINDEX_MAX);
|
||||
fprintf (stderr, " as lookahead, rule number %d",
|
||||
a->inadequacyNode->manifestingState
|
||||
->reductions->rules[rulei]->number);
|
||||
rulei =
|
||||
bitset_next (a->inadequacyNode->inadequacy.conflict.actions,
|
||||
rulei+1);
|
||||
if (AnnotationList__isContributionAlways (a, ci))
|
||||
fprintf (stderr, " always.");
|
||||
else
|
||||
{
|
||||
fprintf (stderr, ", items: ");
|
||||
Sbitset__fprint (a->contributions[ci], nitems, stderr);
|
||||
}
|
||||
fprintf (stderr, "\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -775,8 +761,7 @@ AnnotationList__computeDominantContribution (AnnotationList const *self,
|
||||
/* R/R conflict, so the reduction with the lowest rule number dominates.
|
||||
Fortunately, contributions are sorted by rule number. */
|
||||
for (ContributionIndex ci = 0; ci < self->inadequacyNode->contributionCount; ++ci)
|
||||
if (AnnotationList__stateMakesContribution (self, nitems, ci,
|
||||
lookaheads))
|
||||
if (AnnotationList__stateMakesContribution (self, nitems, ci, lookaheads))
|
||||
{
|
||||
if (require_split_stable
|
||||
&& !AnnotationList__isContributionAlways (self, ci))
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
# define ANNOTATION_LIST_H_
|
||||
|
||||
# include <bitsetv.h>
|
||||
|
||||
# include "Sbitset.h"
|
||||
# include "InadequacyList.h"
|
||||
# include "state.h"
|
||||
|
||||
@@ -81,6 +81,8 @@ void Sbitset__fprint (Sbitset self, Sbitset__Index nbits, FILE *file);
|
||||
*ptr_self = *ptr_other1 | *ptr_other2; \
|
||||
} while (0)
|
||||
|
||||
/* ATTENTION: there are *two* loops here, "break" and "continue" will
|
||||
not apply to the whole loop, just the inner one. */
|
||||
# define SBITSET__FOR_EACH(SELF, NBITS, ITER, INDEX) \
|
||||
for ((ITER) = (SELF); (ITER) < (SELF) + Sbitset__nbytes (NBITS); ++(ITER)) \
|
||||
if (*(ITER) != 0) \
|
||||
|
||||
+20
-20
@@ -32,7 +32,7 @@
|
||||
#include "symtab.h"
|
||||
|
||||
/* NITEMSET is the size of the array ITEMSET. */
|
||||
item_number *itemset;
|
||||
item_index *itemset;
|
||||
size_t nitemset;
|
||||
|
||||
/* RULESET contains a bit for each rule. CLOSURE sets the bits for
|
||||
@@ -54,16 +54,16 @@ static bitsetv firsts = NULL;
|
||||
`-----------------*/
|
||||
|
||||
static void
|
||||
closure_print (char const *title, item_number const *array, size_t size)
|
||||
closure_print (char const *title, item_index const *array, size_t size)
|
||||
{
|
||||
fprintf (stderr, "Closure: %s\n", title);
|
||||
for (size_t i = 0; i < size; ++i)
|
||||
{
|
||||
fprintf (stderr, " %2d: .", array[i]);
|
||||
item_number *rp;
|
||||
for (rp = &ritem[array[i]]; *rp >= 0; ++rp)
|
||||
for (rp = &ritem[array[i]]; 0 <= *rp; ++rp)
|
||||
fprintf (stderr, " %s", symbols[*rp]->tag);
|
||||
fprintf (stderr, " (rule %d)\n", -*rp - 1);
|
||||
fprintf (stderr, " (rule %d)\n", item_number_as_rule_number (*rp));
|
||||
}
|
||||
fputs ("\n\n", stderr);
|
||||
}
|
||||
@@ -104,21 +104,21 @@ print_fderives (void)
|
||||
fprintf (stderr, "\n\n");
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------.
|
||||
| Set FIRSTS to be an NVARS array of NVARS bitsets indicating which |
|
||||
| items can represent the beginning of the input corresponding to |
|
||||
| which other items. |
|
||||
| |
|
||||
| For example, if some rule expands symbol 5 into the sequence of |
|
||||
| symbols 8 3 20, the symbol 8 can be the beginning of the data for |
|
||||
| symbol 5, so the bit [8 - ntokens] in first[5 - ntokens] (= FIRST |
|
||||
| (5)) is set. |
|
||||
`------------------------------------------------------------------*/
|
||||
/*-------------------------------------------------------------------.
|
||||
| Set FIRSTS to be an NNTERMS array of NNTERMS bitsets indicating |
|
||||
| which items can represent the beginning of the input corresponding |
|
||||
| to which other items. |
|
||||
| |
|
||||
| For example, if some rule expands symbol 5 into the sequence of |
|
||||
| symbols 8 3 20, the symbol 8 can be the beginning of the data for |
|
||||
| symbol 5, so the bit [8 - ntokens] in first[5 - ntokens] (= FIRST |
|
||||
| (5)) is set. |
|
||||
`-------------------------------------------------------------------*/
|
||||
|
||||
static void
|
||||
set_firsts (void)
|
||||
{
|
||||
firsts = bitsetv_create (nvars, nvars, BITSET_FIXED);
|
||||
firsts = bitsetv_create (nnterms, nnterms, BITSET_FIXED);
|
||||
|
||||
for (symbol_number i = ntokens; i < nsyms; ++i)
|
||||
for (symbol_number j = 0; derives[i - ntokens][j]; ++j)
|
||||
@@ -139,8 +139,8 @@ set_firsts (void)
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------.
|
||||
| Set FDERIVES to an NVARS by NRULES matrix of bits indicating which |
|
||||
| rules can help derive the beginning of the data for each |
|
||||
| Set FDERIVES to an NNTERMS by NRULES matrix of bits indicating |
|
||||
| which rules can help derive the beginning of the data for each |
|
||||
| nonterminal. |
|
||||
| |
|
||||
| For example, if symbol 5 can be derived as the sequence of symbols |
|
||||
@@ -151,7 +151,7 @@ set_firsts (void)
|
||||
static void
|
||||
set_fderives (void)
|
||||
{
|
||||
fderives = bitsetv_create (nvars, nrules, BITSET_FIXED);
|
||||
fderives = bitsetv_create (nnterms, nrules, BITSET_FIXED);
|
||||
|
||||
set_firsts ();
|
||||
|
||||
@@ -182,7 +182,7 @@ closure_new (int n)
|
||||
|
||||
|
||||
void
|
||||
closure (item_number const *core, size_t n)
|
||||
closure (item_index const *core, size_t n)
|
||||
{
|
||||
if (trace_flag & trace_closure)
|
||||
closure_print ("input", core, n);
|
||||
@@ -203,7 +203,7 @@ closure (item_number const *core, size_t n)
|
||||
bitset_iterator iter;
|
||||
BITSET_FOR_EACH (iter, ruleset, ruleno, 0)
|
||||
{
|
||||
item_number itemno = rules[ruleno].rhs - ritem;
|
||||
item_index itemno = rules[ruleno].rhs - ritem;
|
||||
while (c < n && core[c] < itemno)
|
||||
{
|
||||
itemset[nitemset] = core[c];
|
||||
|
||||
+4
-4
@@ -30,12 +30,12 @@
|
||||
void closure_new (int n);
|
||||
|
||||
|
||||
/* Given the kernel (aka core) of a state (a sorted vector of item numbers
|
||||
/* Given the kernel (aka core) of a state (a sorted vector of item indices
|
||||
ITEMS, of length N), set up RULESET and ITEMSET to indicate what
|
||||
rules could be run and which items could be accepted when those
|
||||
items are the active ones. */
|
||||
|
||||
void closure (item_number const *items, size_t n);
|
||||
void closure (item_index const *items, size_t n);
|
||||
|
||||
|
||||
/* Free ITEMSET, RULESET and internal data. */
|
||||
@@ -43,12 +43,12 @@ void closure (item_number const *items, size_t n);
|
||||
void closure_free (void);
|
||||
|
||||
|
||||
/* ITEMSET is a sorted vector of item numbers; NITEMSET is its size
|
||||
/* ITEMSET is a sorted vector of item indices; NITEMSET is its size
|
||||
(actually, points to just beyond the end of the part of it that is
|
||||
significant). CLOSURE places there the indices of all items which
|
||||
represent units of input that could arrive next. */
|
||||
|
||||
extern item_number *itemset;
|
||||
extern item_index *itemset;
|
||||
extern size_t nitemset;
|
||||
|
||||
#endif /* !CLOSURE_H_ */
|
||||
|
||||
+35
-18
@@ -23,7 +23,7 @@
|
||||
#include "system.h"
|
||||
|
||||
#include <argmatch.h>
|
||||
#include <ctype.h>
|
||||
#include <c-ctype.h>
|
||||
#include <progname.h>
|
||||
#include <stdarg.h>
|
||||
#include <sys/stat.h>
|
||||
@@ -104,6 +104,23 @@ flush (FILE *out)
|
||||
fflush (out);
|
||||
}
|
||||
|
||||
bool
|
||||
is_styled (FILE *out)
|
||||
{
|
||||
if (out != stderr)
|
||||
return false;
|
||||
if (color_debug)
|
||||
return true;
|
||||
#if HAVE_LIBTEXTSTYLE
|
||||
return (color_mode == color_yes
|
||||
|| color_mode == color_html
|
||||
|| (color_mode == color_tty && isatty (STDERR_FILENO)));
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*------------------------.
|
||||
| --warnings's handling. |
|
||||
`------------------------*/
|
||||
@@ -114,6 +131,7 @@ static const argmatch_warning_doc argmatch_warning_docs[] =
|
||||
{
|
||||
{ "conflicts-sr", N_("S/R conflicts (enabled by default)") },
|
||||
{ "conflicts-rr", N_("R/R conflicts (enabled by default)") },
|
||||
{ "counterexamples", N_("generate conflict counterexamples") },
|
||||
{ "dangling-alias", N_("string aliases not attached to a symbol") },
|
||||
{ "deprecated", N_("obsolete constructs") },
|
||||
{ "empty-rule", N_("empty rules without %empty") },
|
||||
@@ -121,7 +139,7 @@ static const argmatch_warning_doc argmatch_warning_docs[] =
|
||||
{ "precedence", N_("useless precedence and associativity") },
|
||||
{ "yacc", N_("incompatibilities with POSIX Yacc") },
|
||||
{ "other", N_("all other warnings (enabled by default)") },
|
||||
{ "all", N_("all the warnings except 'dangling-alias' and 'yacc'") },
|
||||
{ "all", N_("all the warnings except 'counterexamples', 'dangling-alias' and 'yacc'") },
|
||||
{ "no-CATEGORY", N_("turn off warnings in CATEGORY") },
|
||||
{ "none", N_("turn off all the warnings") },
|
||||
{ "error[=CATEGORY]", N_("treat warnings as errors") },
|
||||
@@ -130,18 +148,19 @@ static const argmatch_warning_doc argmatch_warning_docs[] =
|
||||
|
||||
static const argmatch_warning_arg argmatch_warning_args[] =
|
||||
{
|
||||
{ "all", Wall },
|
||||
{ "conflicts-rr", Wconflicts_rr },
|
||||
{ "conflicts-sr", Wconflicts_sr },
|
||||
{ "dangling-alias", Wdangling_alias },
|
||||
{ "deprecated", Wdeprecated },
|
||||
{ "empty-rule", Wempty_rule },
|
||||
{ "everything", Weverything },
|
||||
{ "midrule-values", Wmidrule_values },
|
||||
{ "none", Wnone },
|
||||
{ "other", Wother },
|
||||
{ "precedence", Wprecedence },
|
||||
{ "yacc", Wyacc },
|
||||
{ "all", Wall },
|
||||
{ "conflicts-rr", Wconflicts_rr },
|
||||
{ "conflicts-sr", Wconflicts_sr },
|
||||
{ "counterexamples", Wcounterexamples }, { "cex", Wcounterexamples }, // Show cex second.
|
||||
{ "dangling-alias", Wdangling_alias },
|
||||
{ "deprecated", Wdeprecated },
|
||||
{ "empty-rule", Wempty_rule },
|
||||
{ "everything", Weverything },
|
||||
{ "midrule-values", Wmidrule_values },
|
||||
{ "none", Wnone },
|
||||
{ "other", Wother },
|
||||
{ "precedence", Wprecedence },
|
||||
{ "yacc", Wyacc },
|
||||
{ NULL, Wnone }
|
||||
};
|
||||
|
||||
@@ -286,9 +305,7 @@ void
|
||||
complain_init_color (void)
|
||||
{
|
||||
#if HAVE_LIBTEXTSTYLE
|
||||
if (color_mode == color_yes
|
||||
|| color_mode == color_html
|
||||
|| (color_mode == color_tty && isatty (STDERR_FILENO)))
|
||||
if (is_styled (stderr))
|
||||
{
|
||||
style_file_prepare ("BISON_STYLE", "BISON_STYLEDIR", pkgdatadir (),
|
||||
"bison-default.css");
|
||||
@@ -609,7 +626,7 @@ syntax_error (location loc,
|
||||
|
||||
while (*format)
|
||||
if (format[0] == '%'
|
||||
&& isdigit (format[1])
|
||||
&& c_isdigit (format[1])
|
||||
&& format[2] == '$'
|
||||
&& format[3] == 's'
|
||||
&& (format[1] - '0') < argc)
|
||||
|
||||
+9
-3
@@ -19,6 +19,8 @@
|
||||
#ifndef COMPLAIN_H_
|
||||
# define COMPLAIN_H_ 1
|
||||
|
||||
# include <attribute.h>
|
||||
|
||||
# include "location.h"
|
||||
|
||||
/*---------------.
|
||||
@@ -34,6 +36,8 @@ void end_use_class (const char *style, FILE *out);
|
||||
/** Flush \a out. */
|
||||
void flush (FILE *out);
|
||||
|
||||
/** Whether there's styling on OUT. */
|
||||
bool is_styled (FILE *out);
|
||||
|
||||
/*-------------.
|
||||
| --warnings. |
|
||||
@@ -44,6 +48,7 @@ typedef enum
|
||||
{
|
||||
warning_conflicts_rr,
|
||||
warning_conflicts_sr,
|
||||
warning_counterexamples,
|
||||
warning_dangling_alias,
|
||||
warning_deprecated,
|
||||
warning_empty_rule,
|
||||
@@ -104,6 +109,7 @@ typedef enum
|
||||
|
||||
Wconflicts_rr = 1 << warning_conflicts_rr,
|
||||
Wconflicts_sr = 1 << warning_conflicts_sr,
|
||||
Wcounterexamples = 1 << warning_counterexamples,
|
||||
Wdangling_alias = 1 << warning_dangling_alias,
|
||||
Wdeprecated = 1 << warning_deprecated,
|
||||
Wempty_rule = 1 << warning_empty_rule,
|
||||
@@ -120,7 +126,7 @@ typedef enum
|
||||
|
||||
/**< All above warnings. */
|
||||
Weverything = ~complaint & ~fatal & ~silent,
|
||||
Wall = Weverything & ~Wdangling_alias & ~Wyacc
|
||||
Wall = Weverything & ~Wcounterexamples & ~Wdangling_alias & ~Wyacc
|
||||
} warnings;
|
||||
|
||||
/** Whether the warnings of \a flags are all unset.
|
||||
@@ -132,7 +138,7 @@ bool warning_is_enabled (warnings flags);
|
||||
|
||||
/** Make a complaint, with maybe a location. */
|
||||
void complain (location const *loc, warnings flags, char const *message, ...)
|
||||
__attribute__ ((__format__ (__printf__, 3, 4)));
|
||||
ATTRIBUTE_FORMAT ((__printf__, 3, 4));
|
||||
|
||||
/** Likewise, but with an \a argc/argv interface. */
|
||||
void complain_args (location const *loc, warnings w,
|
||||
@@ -141,7 +147,7 @@ void complain_args (location const *loc, warnings w,
|
||||
/** Make a subcomplain with location and note. */
|
||||
void subcomplain (location const *loc, warnings flags,
|
||||
char const *message, ...)
|
||||
__attribute__ ((__format__ (__printf__, 3, 4)));
|
||||
ATTRIBUTE_FORMAT ((__printf__, 3, 4));
|
||||
|
||||
|
||||
/** GNU Bison extension not valid with POSIX Yacc. */
|
||||
|
||||
+66
-31
@@ -25,6 +25,7 @@
|
||||
|
||||
#include "complain.h"
|
||||
#include "conflicts.h"
|
||||
#include "counterexample.h"
|
||||
#include "files.h"
|
||||
#include "getargs.h"
|
||||
#include "gram.h"
|
||||
@@ -48,6 +49,12 @@ static struct obstack solved_conflicts_xml_obstack;
|
||||
static bitset shift_set;
|
||||
static bitset lookahead_set;
|
||||
|
||||
bool
|
||||
has_conflicts (const state *s)
|
||||
{
|
||||
return conflicts[s->number];
|
||||
}
|
||||
|
||||
|
||||
|
||||
enum conflict_resolution
|
||||
@@ -219,7 +226,7 @@ log_resolution (rule *r, symbol_number token,
|
||||
|
||||
/*------------------------------------------------------------------.
|
||||
| Turn off the shift recorded for the specified token in the |
|
||||
| specified state. Used when we resolve a shift-reduce conflict in |
|
||||
| specified state. Used when we resolve a shift/reduce conflict in |
|
||||
| favor of the reduction or as an error (%nonassoc). |
|
||||
`------------------------------------------------------------------*/
|
||||
|
||||
@@ -238,7 +245,7 @@ flush_shift (state *s, int token)
|
||||
|
||||
/*--------------------------------------------------------------------.
|
||||
| Turn off the reduce recorded for the specified token in the |
|
||||
| specified lookahead set. Used when we resolve a shift-reduce |
|
||||
| specified lookahead set. Used when we resolve a shift/reduce |
|
||||
| conflict in favor of the shift or as an error (%nonassoc). |
|
||||
`--------------------------------------------------------------------*/
|
||||
|
||||
@@ -250,7 +257,7 @@ flush_reduce (bitset lookahead_tokens, int token)
|
||||
|
||||
|
||||
/*------------------------------------------------------------------.
|
||||
| Attempt to resolve shift-reduce conflict for one rule by means of |
|
||||
| Attempt to resolve shift/reduce conflict for one rule by means of |
|
||||
| precedence declarations. It has already been checked that the |
|
||||
| rule has a precedence. A conflict is resolved by modifying the |
|
||||
| shift or reduce tables so that there is no longer a conflict. |
|
||||
@@ -275,7 +282,7 @@ resolve_sr_conflict (state *s, int ruleno, symbol **errors, int *nerrs)
|
||||
&& bitset_test (lookahead_set, i)
|
||||
&& symbols[i]->content->prec)
|
||||
{
|
||||
/* Shift-reduce conflict occurs for token number i
|
||||
/* Shift/reduce conflict occurs for token number i
|
||||
and it has a precedence.
|
||||
The precedence of shifting is that of token i. */
|
||||
if (symbols[i]->content->prec < redprec)
|
||||
@@ -357,10 +364,11 @@ set_conflicts (state *s, symbol **errors)
|
||||
}
|
||||
|
||||
/* Loop over all rules which require lookahead in this state. First
|
||||
check for shift-reduce conflict, and try to resolve using
|
||||
check for shift/reduce conflict, and try to resolve using
|
||||
precedence. */
|
||||
for (int i = 0; i < reds->num; ++i)
|
||||
if (reds->rules[i]->prec && reds->rules[i]->prec->prec
|
||||
if (reds->rules[i]->prec
|
||||
&& reds->rules[i]->prec->prec
|
||||
&& !bitset_disjoint_p (reds->lookahead_tokens[i], lookahead_set))
|
||||
resolve_sr_conflict (s, i, errors, &nerrs);
|
||||
|
||||
@@ -624,12 +632,20 @@ conflicts_total_count (void)
|
||||
return count_sr_conflicts () + count_rr_conflicts ();
|
||||
}
|
||||
|
||||
/*------------------------------.
|
||||
| Reporting per-rule conflicts. |
|
||||
`------------------------------*/
|
||||
static void
|
||||
report_counterexamples (void)
|
||||
{
|
||||
for (state_number sn = 0; sn < nstates; ++sn)
|
||||
if (conflicts[sn])
|
||||
counterexample_report_state (states[sn], stderr, "");
|
||||
}
|
||||
|
||||
/*------------------------------------------------.
|
||||
| Report per-rule %expect/%expect-rr mismatches. |
|
||||
`------------------------------------------------*/
|
||||
|
||||
static void
|
||||
rule_conflicts_print (void)
|
||||
report_rule_expectation_mismatches (void)
|
||||
{
|
||||
for (rule_number i = 0; i < nrules; i += 1)
|
||||
{
|
||||
@@ -644,13 +660,13 @@ rule_conflicts_print (void)
|
||||
complain (&r->location, complaint,
|
||||
_("shift/reduce conflicts for rule %d:"
|
||||
" %d found, %d expected"),
|
||||
r->user_number, sr, expected_sr);
|
||||
r->code, sr, expected_sr);
|
||||
int rr = count_rule_rr_conflicts (r);
|
||||
if (rr != expected_rr && (rr != 0 || expected_rr != -1))
|
||||
complain (&r->location, complaint,
|
||||
_("reduce/reduce conflicts for rule %d:"
|
||||
" %d found, %d expected"),
|
||||
r->user_number, rr, expected_rr);
|
||||
r->code, rr, expected_rr);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -662,7 +678,7 @@ rule_conflicts_print (void)
|
||||
void
|
||||
conflicts_print (void)
|
||||
{
|
||||
rule_conflicts_print ();
|
||||
report_rule_expectation_mismatches ();
|
||||
|
||||
if (! glr_parser && expected_rr_conflicts != -1)
|
||||
{
|
||||
@@ -670,8 +686,9 @@ conflicts_print (void)
|
||||
expected_rr_conflicts = -1;
|
||||
}
|
||||
|
||||
/* Screams for factoring, but almost useless because of the
|
||||
different strings to translate. */
|
||||
bool has_unexpected_conflicts = false;
|
||||
/* The following two blocks scream for factoring, but i18n support
|
||||
would make it ugly. */
|
||||
{
|
||||
int total = count_sr_conflicts ();
|
||||
/* If %expect is not used, but %expect-rr is, then expect 0 sr. */
|
||||
@@ -682,16 +699,22 @@ conflicts_print (void)
|
||||
if (expected != -1)
|
||||
{
|
||||
if (expected != total)
|
||||
complain (NULL, complaint,
|
||||
_("shift/reduce conflicts: %d found, %d expected"),
|
||||
total, expected);
|
||||
{
|
||||
complain (NULL, complaint,
|
||||
_("shift/reduce conflicts: %d found, %d expected"),
|
||||
total, expected);
|
||||
has_unexpected_conflicts = true;
|
||||
}
|
||||
}
|
||||
else if (total)
|
||||
complain (NULL, Wconflicts_sr,
|
||||
ngettext ("%d shift/reduce conflict",
|
||||
"%d shift/reduce conflicts",
|
||||
total),
|
||||
total);
|
||||
{
|
||||
complain (NULL, Wconflicts_sr,
|
||||
ngettext ("%d shift/reduce conflict",
|
||||
"%d shift/reduce conflicts",
|
||||
total),
|
||||
total);
|
||||
has_unexpected_conflicts = true;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
@@ -704,17 +727,29 @@ conflicts_print (void)
|
||||
if (expected != -1)
|
||||
{
|
||||
if (expected != total)
|
||||
complain (NULL, complaint,
|
||||
_("reduce/reduce conflicts: %d found, %d expected"),
|
||||
total, expected);
|
||||
{
|
||||
complain (NULL, complaint,
|
||||
_("reduce/reduce conflicts: %d found, %d expected"),
|
||||
total, expected);
|
||||
has_unexpected_conflicts = true;
|
||||
}
|
||||
}
|
||||
else if (total)
|
||||
complain (NULL, Wconflicts_rr,
|
||||
ngettext ("%d reduce/reduce conflict",
|
||||
"%d reduce/reduce conflicts",
|
||||
total),
|
||||
total);
|
||||
{
|
||||
complain (NULL, Wconflicts_rr,
|
||||
ngettext ("%d reduce/reduce conflict",
|
||||
"%d reduce/reduce conflicts",
|
||||
total),
|
||||
total);
|
||||
has_unexpected_conflicts = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (warning_is_enabled (Wcounterexamples))
|
||||
report_counterexamples ();
|
||||
else if (has_unexpected_conflicts)
|
||||
complain (NULL, Wother,
|
||||
_("rerun with option '-Wcounterexamples' to generate conflict counterexamples"));
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -41,6 +41,8 @@ int conflicts_total_count (void);
|
||||
void conflicts_output (FILE *out);
|
||||
void conflicts_free (void);
|
||||
|
||||
bool has_conflicts (const state *s);
|
||||
|
||||
/* Were there conflicts? */
|
||||
extern int expected_sr_conflicts;
|
||||
extern int expected_rr_conflicts;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,30 @@
|
||||
/* Conflict counterexample generation
|
||||
|
||||
Copyright (C) 2020 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of Bison, the GNU Compiler Compiler.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef COUNTEREXAMPLE_H
|
||||
# define COUNTEREXAMPLE_H
|
||||
|
||||
# include "state-item.h"
|
||||
|
||||
void counterexample_init (void);
|
||||
void counterexample_free (void);
|
||||
|
||||
void counterexample_report_state (const state *s, FILE *out, const char *prefix);
|
||||
|
||||
#endif /* COUNTEREXAMPLE_H */
|
||||
@@ -0,0 +1,213 @@
|
||||
/* Counterexample derivation trees
|
||||
|
||||
Copyright (C) 2020 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of Bison, the GNU Compiler Compiler.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "derivation.h"
|
||||
|
||||
#include <gl_linked_list.h>
|
||||
|
||||
#include "system.h"
|
||||
#include "complain.h"
|
||||
|
||||
struct derivation
|
||||
{
|
||||
symbol_number sym;
|
||||
gl_list_t children;
|
||||
int reference_count;
|
||||
};
|
||||
|
||||
static derivation d_dot = { -1, NULL, -1 };
|
||||
|
||||
derivation *
|
||||
derivation_dot (void)
|
||||
{
|
||||
return &d_dot;
|
||||
}
|
||||
|
||||
void
|
||||
derivation_list_append (derivation_list dl, derivation *d)
|
||||
{
|
||||
derivation_retain (d);
|
||||
gl_list_add_last (dl, d);
|
||||
}
|
||||
|
||||
void
|
||||
derivation_list_prepend (derivation_list dl, derivation *d)
|
||||
{
|
||||
derivation_retain (d);
|
||||
gl_list_add_first (dl, d);
|
||||
}
|
||||
|
||||
void derivation_list_free (derivation_list dl)
|
||||
{
|
||||
derivation *d = NULL;
|
||||
for (gl_list_iterator_t it = gl_list_iterator (dl);
|
||||
derivation_list_next (&it, &d);
|
||||
)
|
||||
if (d != &d_dot)
|
||||
derivation_free (d);
|
||||
gl_list_free (dl);
|
||||
}
|
||||
|
||||
derivation *
|
||||
derivation_new (symbol_number sym, derivation_list children)
|
||||
{
|
||||
derivation *deriv = xmalloc (sizeof (derivation));
|
||||
deriv->sym = sym;
|
||||
deriv->children = children;
|
||||
deriv->reference_count = 0;
|
||||
return deriv;
|
||||
}
|
||||
|
||||
void
|
||||
derivation_retain (derivation *d)
|
||||
{
|
||||
++d->reference_count;
|
||||
}
|
||||
|
||||
void
|
||||
derivation_free (derivation *d)
|
||||
{
|
||||
if (!d)
|
||||
return;
|
||||
derivation_list free_queue =
|
||||
gl_list_create (GL_LINKED_LIST, NULL, NULL, NULL, true,
|
||||
1, (const void **)&d);
|
||||
while (gl_list_size (free_queue) > 0)
|
||||
{
|
||||
derivation *deriv = (derivation *) gl_list_get_at (free_queue, 0);
|
||||
if (--deriv->reference_count == 0)
|
||||
{
|
||||
if (deriv->children)
|
||||
{
|
||||
derivation *child = NULL;
|
||||
for (gl_list_iterator_t it = gl_list_iterator (deriv->children);
|
||||
derivation_list_next (&it, &child);
|
||||
)
|
||||
if (child != &d_dot)
|
||||
gl_list_add_last (free_queue, child);
|
||||
gl_list_free (deriv->children);
|
||||
}
|
||||
free (deriv);
|
||||
}
|
||||
gl_list_remove_at (free_queue, 0);
|
||||
}
|
||||
gl_list_free (free_queue);
|
||||
}
|
||||
|
||||
size_t
|
||||
derivation_size (const derivation *deriv)
|
||||
{
|
||||
if (!deriv->children)
|
||||
return 1;
|
||||
int size = 1;
|
||||
derivation *child = NULL;
|
||||
for (gl_list_iterator_t it = gl_list_iterator (deriv->children);
|
||||
derivation_list_next (&it, &child);
|
||||
)
|
||||
size += derivation_size (child);
|
||||
return size;
|
||||
}
|
||||
|
||||
/* Print DERIV, colored according to COUNTER.
|
||||
Return false if nothing is printed. */
|
||||
static bool
|
||||
derivation_print_impl (const derivation *deriv, FILE *f,
|
||||
bool leaves_only,
|
||||
int *counter, const char *prefix)
|
||||
{
|
||||
if (deriv->children)
|
||||
{
|
||||
const symbol *sym = symbols[deriv->sym];
|
||||
char style[20];
|
||||
snprintf (style, 20, "cex-%d", *counter);
|
||||
++*counter;
|
||||
begin_use_class (style, f);
|
||||
|
||||
if (!leaves_only)
|
||||
{
|
||||
fputs (prefix, f);
|
||||
begin_use_class ("cex-step", f);
|
||||
fprintf (f, "%s ::=[ ", sym->tag);
|
||||
end_use_class ("cex-step", f);
|
||||
prefix = "";
|
||||
}
|
||||
bool res = false;
|
||||
derivation *child;
|
||||
for (gl_list_iterator_t it = gl_list_iterator (deriv->children);
|
||||
derivation_list_next (&it, &child);
|
||||
)
|
||||
{
|
||||
if (derivation_print_impl (child, f, leaves_only, counter, prefix))
|
||||
{
|
||||
prefix = " ";
|
||||
res = true;
|
||||
}
|
||||
else if (!leaves_only)
|
||||
prefix = " ";
|
||||
}
|
||||
if (!leaves_only)
|
||||
{
|
||||
begin_use_class ("cex-step", f);
|
||||
if (res)
|
||||
fputs (" ]", f);
|
||||
else
|
||||
fputs ("]", f);
|
||||
end_use_class ("cex-step", f);
|
||||
}
|
||||
end_use_class (style, f);
|
||||
return res;
|
||||
}
|
||||
else if (deriv == &d_dot)
|
||||
{
|
||||
fputs (prefix, f);
|
||||
begin_use_class ("cex-dot", f);
|
||||
print_dot (f);
|
||||
end_use_class ("cex-dot", f);
|
||||
}
|
||||
else // leaf.
|
||||
{
|
||||
fputs (prefix, f);
|
||||
const symbol *sym = symbols[deriv->sym];
|
||||
begin_use_class ("cex-leaf", f);
|
||||
fprintf (f, "%s", sym->tag);
|
||||
end_use_class ("cex-leaf", f);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
derivation_print (const derivation *deriv, FILE *out, const char *prefix)
|
||||
{
|
||||
int counter = 0;
|
||||
fputs (prefix, out);
|
||||
derivation_print_impl (deriv, out, false, &counter, "");
|
||||
fputc ('\n', out);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
derivation_print_leaves (const derivation *deriv, FILE *out, const char *prefix)
|
||||
{
|
||||
int counter = 0;
|
||||
fputs (prefix, out);
|
||||
derivation_print_impl (deriv, out, true, &counter, "");
|
||||
fputc ('\n', out);
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
/* Counterexample derivation trees
|
||||
|
||||
Copyright (C) 2020 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of Bison, the GNU Compiler Compiler.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef DERIVATION_H
|
||||
# define DERIVATION_H
|
||||
|
||||
# include <gl_linked_list.h>
|
||||
# include <gl_xlist.h>
|
||||
|
||||
# include "gram.h"
|
||||
|
||||
/* Derivations are trees of symbols such that each nonterminal's
|
||||
children are symbols that produce that nonterminal if they are
|
||||
relevant to the counterexample. The leaves of a derivation form a
|
||||
counterexample when printed. */
|
||||
|
||||
typedef gl_list_t derivation_list;
|
||||
typedef struct derivation derivation;
|
||||
|
||||
static inline derivation_list derivation_list_new (void)
|
||||
{
|
||||
return gl_list_create_empty (GL_LINKED_LIST, NULL, NULL, NULL, true);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
derivation_list_next (gl_list_iterator_t *it, derivation **d)
|
||||
{
|
||||
const void *p = NULL;
|
||||
bool res = gl_list_iterator_next (it, &p, NULL);
|
||||
if (res)
|
||||
*d = (derivation *) p;
|
||||
else
|
||||
gl_list_iterator_free (it);
|
||||
return res;
|
||||
}
|
||||
|
||||
void derivation_list_append (derivation_list dl, derivation *d);
|
||||
void derivation_list_prepend (derivation_list dl, derivation *d);
|
||||
void derivation_list_free (derivation_list dl);
|
||||
|
||||
derivation *derivation_new (symbol_number sym, derivation_list children);
|
||||
|
||||
static inline derivation *derivation_new_leaf (symbol_number sym)
|
||||
{
|
||||
return derivation_new (sym, NULL);
|
||||
}
|
||||
size_t derivation_size (const derivation *deriv);
|
||||
void derivation_print (const derivation *deriv, FILE *out, const char *prefix);
|
||||
void derivation_print_leaves (const derivation *deriv, FILE *out, const char *prefix);
|
||||
void derivation_free (derivation *deriv);
|
||||
void derivation_retain (derivation *deriv);
|
||||
|
||||
derivation *derivation_dot (void);
|
||||
|
||||
#endif /* DERIVATION_H */
|
||||
+4
-4
@@ -47,7 +47,7 @@ print_derives (void)
|
||||
fprintf (stderr, " %s derives\n", symbols[i]->tag);
|
||||
for (rule **rp = derives[i - ntokens]; *rp; ++rp)
|
||||
{
|
||||
fprintf (stderr, " %3d ", (*rp)->user_number);
|
||||
fprintf (stderr, " %3d ", (*rp)->code);
|
||||
rule_rhs_print (*rp, stderr);
|
||||
fprintf (stderr, "\n");
|
||||
}
|
||||
@@ -62,7 +62,7 @@ derives_compute (void)
|
||||
{
|
||||
/* DSET[NTERM - NTOKENS] -- A linked list of the numbers of the rules
|
||||
whose LHS is NTERM. */
|
||||
rule_list **dset = xcalloc (nvars, sizeof *dset);
|
||||
rule_list **dset = xcalloc (nnterms, sizeof *dset);
|
||||
|
||||
/* DELTS[RULE] -- There are NRULES rule number to attach to nterms.
|
||||
Instead of performing NRULES allocations for each, have an array
|
||||
@@ -82,9 +82,9 @@ derives_compute (void)
|
||||
/* DSET contains what we need under the form of a linked list. Make
|
||||
it a single array. */
|
||||
|
||||
derives = xnmalloc (nvars, sizeof *derives);
|
||||
derives = xnmalloc (nnterms, sizeof *derives);
|
||||
/* Q is the storage for DERIVES[...] (DERIVES[0] = q). */
|
||||
rule **q = xnmalloc (nvars + nrules, sizeof *q);
|
||||
rule **q = xnmalloc (nnterms + nrules, sizeof *q);
|
||||
|
||||
for (symbol_number i = ntokens; i < nsyms; ++i)
|
||||
{
|
||||
|
||||
+106
-2
@@ -22,13 +22,18 @@
|
||||
#include "system.h"
|
||||
|
||||
#include <configmake.h> /* PKGDATADIR */
|
||||
#include <error.h>
|
||||
#include <dirname.h>
|
||||
#include <error.h>
|
||||
#include <get-errno.h>
|
||||
#include <gl_array_list.h>
|
||||
#include <gl_xlist.h>
|
||||
#include <quote.h>
|
||||
#include <quotearg.h>
|
||||
#include <relocatable.h> /* relocate2 */
|
||||
#include <stdio-safer.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <xstrndup.h>
|
||||
|
||||
#include "complain.h"
|
||||
@@ -52,6 +57,7 @@ char *spec_verbose_file = NULL; /* for --verbose. */
|
||||
char *spec_graph_file = NULL; /* for -g. */
|
||||
char *spec_xml_file = NULL; /* for -x. */
|
||||
char *spec_header_file = NULL; /* for --defines. */
|
||||
char *spec_mapped_header_file = NULL;
|
||||
char *parser_file_name;
|
||||
|
||||
/* All computed output file names. */
|
||||
@@ -70,7 +76,7 @@ static int generated_files_size = 0;
|
||||
uniqstr grammar_file = NULL;
|
||||
|
||||
/* If --output=dir/foo.c was specified,
|
||||
DIR_PREFIX is 'dir/' and ALL_BUT_EXT and ALL_BUT_TAB_EXT are 'dir/foo'.
|
||||
DIR_PREFIX gis 'dir/' and ALL_BUT_EXT and ALL_BUT_TAB_EXT are 'dir/foo'.
|
||||
|
||||
If --output=dir/foo.tab.c was specified, DIR_PREFIX is 'dir/',
|
||||
ALL_BUT_EXT is 'dir/foo.tab', and ALL_BUT_TAB_EXT is 'dir/foo'.
|
||||
@@ -88,11 +94,20 @@ uniqstr grammar_file = NULL;
|
||||
char *all_but_ext;
|
||||
static char *all_but_tab_ext;
|
||||
char *dir_prefix;
|
||||
char *mapped_dir_prefix;
|
||||
|
||||
/* C source file extension (the parser source). */
|
||||
static char *src_extension = NULL;
|
||||
/* Header file extension (if option '`-d'' is specified). */
|
||||
static char *header_extension = NULL;
|
||||
|
||||
struct prefix_map
|
||||
{
|
||||
char *oldprefix;
|
||||
char *newprefix;
|
||||
};
|
||||
|
||||
static gl_list_t prefix_maps = NULL;
|
||||
|
||||
/*-----------------------------------------------------------------.
|
||||
| Return a newly allocated string composed of the concatenation of |
|
||||
@@ -156,6 +171,70 @@ xfdopen (int fd, char const *mode)
|
||||
return res;
|
||||
}
|
||||
|
||||
/* Given an input file path, returns a dynamically allocated string that
|
||||
contains the path with the file prefix mapping rules applied, or NULL if
|
||||
the input was NULL. */
|
||||
char *
|
||||
map_file_name (char const *filename)
|
||||
{
|
||||
if (!filename)
|
||||
return NULL;
|
||||
|
||||
struct prefix_map const *p = NULL;
|
||||
if (prefix_maps)
|
||||
{
|
||||
void const *ptr;
|
||||
gl_list_iterator_t iter = gl_list_iterator (prefix_maps);
|
||||
while (gl_list_iterator_next (&iter, &ptr, NULL))
|
||||
{
|
||||
p = ptr;
|
||||
if (strncmp (p->oldprefix, filename, strlen (p->oldprefix)) == 0)
|
||||
break;
|
||||
p = NULL;
|
||||
}
|
||||
gl_list_iterator_free (&iter);
|
||||
}
|
||||
|
||||
if (!p)
|
||||
return xstrdup (filename);
|
||||
|
||||
size_t oldprefix_len = strlen (p->oldprefix);
|
||||
size_t newprefix_len = strlen (p->newprefix);
|
||||
char *s = xmalloc (newprefix_len + strlen (filename) - oldprefix_len + 1);
|
||||
|
||||
char *end = stpcpy (s, p->newprefix);
|
||||
stpcpy (end, filename + oldprefix_len);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
static void
|
||||
prefix_map_free (struct prefix_map *p)
|
||||
{
|
||||
free (p->oldprefix);
|
||||
free (p->newprefix);
|
||||
free (p);
|
||||
}
|
||||
|
||||
/* Adds a new file prefix mapping. If a file path starts with oldprefix, it
|
||||
will be replaced with newprefix */
|
||||
void
|
||||
add_prefix_map (char const *oldprefix, char const *newprefix)
|
||||
{
|
||||
if (!prefix_maps)
|
||||
prefix_maps = gl_list_create_empty (GL_ARRAY_LIST,
|
||||
/* equals */ NULL,
|
||||
/* hashcode */ NULL,
|
||||
(gl_listelement_dispose_fn) prefix_map_free,
|
||||
true);
|
||||
|
||||
struct prefix_map *p = xmalloc (sizeof (*p));
|
||||
p->oldprefix = xstrdup (oldprefix);
|
||||
p->newprefix = xstrdup (newprefix);
|
||||
|
||||
gl_list_add_last (prefix_maps, p);
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------.
|
||||
| Compute ALL_BUT_EXT, ALL_BUT_TAB_EXT and output files extensions. |
|
||||
`------------------------------------------------------------------*/
|
||||
@@ -360,6 +439,9 @@ compute_output_file_names (void)
|
||||
output_file_name_check (&spec_verbose_file, false);
|
||||
}
|
||||
|
||||
spec_mapped_header_file = map_file_name (spec_header_file);
|
||||
mapped_dir_prefix = map_file_name (dir_prefix);
|
||||
|
||||
free (all_but_tab_ext);
|
||||
free (src_extension);
|
||||
free (header_extension);
|
||||
@@ -421,6 +503,23 @@ pkgdatadir (void)
|
||||
}
|
||||
}
|
||||
|
||||
char const *
|
||||
m4path (void)
|
||||
{
|
||||
char const *m4 = getenv ("M4");
|
||||
if (m4)
|
||||
return m4;
|
||||
|
||||
/* We don't use relocate2() to store the temporary buffer and re-use
|
||||
it, because m4path() is only called once. */
|
||||
char const *m4_relocated = relocate (M4);
|
||||
struct stat buf;
|
||||
if (stat (m4_relocated, &buf) == 0)
|
||||
return m4_relocated;
|
||||
|
||||
return M4;
|
||||
}
|
||||
|
||||
void
|
||||
output_file_names_free (void)
|
||||
{
|
||||
@@ -429,10 +528,15 @@ output_file_names_free (void)
|
||||
free (spec_graph_file);
|
||||
free (spec_xml_file);
|
||||
free (spec_header_file);
|
||||
free (spec_mapped_header_file);
|
||||
free (parser_file_name);
|
||||
free (dir_prefix);
|
||||
free (mapped_dir_prefix);
|
||||
for (int i = 0; i < generated_files_size; i++)
|
||||
free (generated_files[i].name);
|
||||
free (generated_files);
|
||||
free (relocate_buffer);
|
||||
|
||||
if (prefix_maps)
|
||||
gl_list_free (prefix_maps);
|
||||
}
|
||||
|
||||
+12
@@ -50,9 +50,15 @@ extern char *spec_xml_file;
|
||||
/* File name specified with --defines. */
|
||||
extern char *spec_header_file;
|
||||
|
||||
/* File name specified with --defines, adjusted for mapped prefixes. */
|
||||
extern char *spec_mapped_header_file;
|
||||
|
||||
/* Directory prefix of output file names. */
|
||||
extern char *dir_prefix;
|
||||
|
||||
/* Directory prefix of output file name, adjusted for mapped prefixes. */
|
||||
extern char *mapped_dir_prefix;
|
||||
|
||||
/* The file name as given on the command line.
|
||||
Not named "input_file" because Flex uses this name for an argument,
|
||||
and therefore GCC warns about a name clash. */
|
||||
@@ -64,6 +70,9 @@ extern char *all_but_ext;
|
||||
/* Where our data files are installed. */
|
||||
char const *pkgdatadir (void);
|
||||
|
||||
/* Where the m4 program is installed. */
|
||||
char const *m4path (void);
|
||||
|
||||
void compute_output_file_names (void);
|
||||
void output_file_names_free (void);
|
||||
|
||||
@@ -82,4 +91,7 @@ FILE *xfopen (const char *name, char const *mode);
|
||||
void xfclose (FILE *ptr);
|
||||
FILE *xfdopen (int fd, char const *mode);
|
||||
|
||||
char *map_file_name (char const *filename);
|
||||
void add_prefix_map (char const *oldprefix, char const *newprefix);
|
||||
|
||||
#endif /* !FILES_H_ */
|
||||
|
||||
+13
-12
@@ -21,19 +21,19 @@
|
||||
|
||||
#include "fixits.h"
|
||||
|
||||
#include <error.h>
|
||||
#include <get-errno.h>
|
||||
#include <gl_array_list.h>
|
||||
#include <gl_xlist.h>
|
||||
#include <progname.h>
|
||||
#include <quote.h>
|
||||
#include <quotearg.h>
|
||||
#include <vasnprintf.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"
|
||||
#include "getargs.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@@ -124,10 +124,11 @@ fixits_run (void)
|
||||
FILE *out = xfopen (input, "w");
|
||||
size_t line = 1;
|
||||
size_t offset = 1;
|
||||
fixit const *f = NULL;
|
||||
void const *p = NULL;
|
||||
gl_list_iterator_t iter = gl_list_iterator (fixits);
|
||||
while (gl_list_iterator_next (&iter, (const void**) &f, NULL))
|
||||
while (gl_list_iterator_next (&iter, &p, NULL))
|
||||
{
|
||||
fixit const *f = p;
|
||||
/* Look for the correct line. */
|
||||
while (line < f->location.start.line)
|
||||
{
|
||||
|
||||
+10
-7
@@ -94,22 +94,25 @@ int FLEX_PREFIX (lex_destroy) (void);
|
||||
keep (to construct ID, STRINGS etc.). Use the following macros to
|
||||
use it.
|
||||
|
||||
Use STRING_GROW to append what has just been matched, and
|
||||
STRING_FINISH to end the string (it puts the ending 0).
|
||||
STRING_FINISH also stores this string in LAST_STRING, which can be
|
||||
used, and which is used by STRING_FREE to free the last string. */
|
||||
Use STRING_GROW () to append what has just been matched, and
|
||||
STRING_FINISH () to end the string (it puts the ending 0).
|
||||
STRING_FINISH () also stores this string in LAST_STRING, which can be
|
||||
used, and which is used by STRING_FREE () to free the last string. */
|
||||
|
||||
#ifndef FLEX_NO_OBSTACK
|
||||
|
||||
static struct obstack obstack_for_string;
|
||||
|
||||
# define STRING_GROW \
|
||||
# define STRING_GROW() \
|
||||
obstack_grow (&obstack_for_string, yytext, yyleng)
|
||||
|
||||
# define STRING_FINISH \
|
||||
# define STRING_FINISH() \
|
||||
(last_string = obstack_finish0 (&obstack_for_string))
|
||||
|
||||
# define STRING_FREE \
|
||||
# define STRING_1GROW(Char) \
|
||||
obstack_1grow (&obstack_for_string, Char)
|
||||
|
||||
# define STRING_FREE() \
|
||||
obstack_free (&obstack_for_string, last_string)
|
||||
|
||||
#endif
|
||||
|
||||
+62
-34
@@ -151,8 +151,8 @@ flags_argmatch (const char *opt,
|
||||
*/
|
||||
#define FLAGS_ARGMATCH(FlagName, Args, All) \
|
||||
flags_argmatch ("--" #FlagName, \
|
||||
(xargmatch_fn*) argmatch_## FlagName ## _value, \
|
||||
argmatch_## FlagName ## _usage, \
|
||||
(xargmatch_fn*) argmatch_## FlagName ## _value, \
|
||||
argmatch_ ## FlagName ## _usage, \
|
||||
All, &FlagName ## _flag, Args)
|
||||
|
||||
/*---------------------.
|
||||
@@ -206,23 +206,26 @@ ARGMATCH_DEFINE_GROUP (report, enum report)
|
||||
|
||||
static const argmatch_report_doc argmatch_report_docs[] =
|
||||
{
|
||||
{ "states", N_("describe the states") },
|
||||
{ "itemsets", N_("complete the core item sets with their closure") },
|
||||
{ "lookaheads", N_("explicitly associate lookahead tokens to items") },
|
||||
{ "solved", N_("describe shift/reduce conflicts solving") },
|
||||
{ "all", N_("include all the above information") },
|
||||
{ "none", N_("disable the report") },
|
||||
{ "states", N_("describe the states") },
|
||||
{ "itemsets", N_("complete the core item sets with their closure") },
|
||||
{ "lookaheads", N_("explicitly associate lookahead tokens to items") },
|
||||
{ "solved", N_("describe shift/reduce conflicts solving") },
|
||||
{ "counterexamples", N_("generate conflict counterexamples") },
|
||||
{ "all", N_("include all the above information") },
|
||||
{ "none", N_("disable the report") },
|
||||
{ NULL, NULL },
|
||||
};
|
||||
|
||||
static const argmatch_report_arg argmatch_report_args[] =
|
||||
{
|
||||
{ "none", report_none },
|
||||
{ "states", report_states },
|
||||
{ "itemsets", report_states | report_itemsets },
|
||||
{ "lookaheads", report_states | report_lookahead_tokens },
|
||||
{ "solved", report_states | report_solved_conflicts },
|
||||
{ "all", report_all },
|
||||
{ "none", report_none },
|
||||
{ "states", report_states },
|
||||
{ "itemsets", report_states | report_itemsets },
|
||||
{ "lookaheads", report_states | report_lookahead_tokens },
|
||||
{ "solved", report_states | report_solved_conflicts },
|
||||
{ "counterexamples", report_cex },
|
||||
{ "cex", report_cex },
|
||||
{ "all", report_all },
|
||||
{ NULL, report_none },
|
||||
};
|
||||
|
||||
@@ -257,10 +260,12 @@ static const argmatch_trace_doc argmatch_trace_docs[] =
|
||||
{ "sets", "grammar sets: firsts, nullable etc." },
|
||||
{ "muscles", "m4 definitions passed to the skeleton" },
|
||||
{ "tools", "m4 invocation" },
|
||||
{ "m4", "m4 traces" },
|
||||
{ "m4-early", "m4 traces starting from the start" },
|
||||
{ "m4", "m4 traces starting from the skeleton evaluation" },
|
||||
{ "skeleton", "skeleton postprocessing" },
|
||||
{ "time", "time consumption" },
|
||||
{ "ielr", "IELR conversion" },
|
||||
{ "cex", "counterexample generation"},
|
||||
{ "all", "all of the above" },
|
||||
{ NULL, NULL},
|
||||
};
|
||||
@@ -279,10 +284,12 @@ static const argmatch_trace_arg argmatch_trace_args[] =
|
||||
{ "sets", trace_sets },
|
||||
{ "muscles", trace_muscles },
|
||||
{ "tools", trace_tools },
|
||||
{ "m4-early", trace_m4_early },
|
||||
{ "m4", trace_m4 },
|
||||
{ "skeleton", trace_skeleton },
|
||||
{ "time", trace_time },
|
||||
{ "ielr", trace_ielr },
|
||||
{ "cex", trace_cex },
|
||||
{ "all", trace_all },
|
||||
{ NULL, trace_none},
|
||||
};
|
||||
@@ -337,7 +344,8 @@ const argmatch_feature_group_type argmatch_feature_group =
|
||||
| Display the help message and exit STATUS. |
|
||||
`-------------------------------------------*/
|
||||
|
||||
static void usage (int) ATTRIBUTE_NORETURN;
|
||||
_Noreturn
|
||||
static void usage (int);
|
||||
|
||||
static void
|
||||
usage (int status)
|
||||
@@ -418,15 +426,17 @@ Tuning the Parser:\n\
|
||||
* won't assume that -d also takes an argument. */
|
||||
fputs (_("\
|
||||
Output Files:\n\
|
||||
--defines[=FILE] also produce a header file\n\
|
||||
-d likewise but cannot specify FILE (for POSIX Yacc)\n\
|
||||
-r, --report=THINGS also produce details on the automaton\n\
|
||||
--report-file=FILE write report to FILE\n\
|
||||
-v, --verbose same as '--report=state'\n\
|
||||
-b, --file-prefix=PREFIX specify a PREFIX for output files\n\
|
||||
-o, --output=FILE leave output to FILE\n\
|
||||
-g, --graph[=FILE] also output a graph of the automaton\n\
|
||||
-x, --xml[=FILE] also output an XML report of the automaton\n\
|
||||
--defines[=FILE] also produce a header file\n\
|
||||
-d likewise but cannot specify FILE (for POSIX Yacc)\n\
|
||||
-r, --report=THINGS also produce details on the automaton\n\
|
||||
--report-file=FILE write report to FILE\n\
|
||||
-v, --verbose same as '--report=state'\n\
|
||||
-b, --file-prefix=PREFIX specify a PREFIX for output files\n\
|
||||
-o, --output=FILE leave output to FILE\n\
|
||||
-g, --graph[=FILE] also output a graph of the automaton\n\
|
||||
-x, --xml[=FILE] also output an XML report of the automaton\n\
|
||||
-M, --file-prefix-map=OLD=NEW replace prefix OLD with NEW when writing file paths\n\
|
||||
in output files\n\
|
||||
"), stdout);
|
||||
putc ('\n', stdout);
|
||||
|
||||
@@ -547,6 +557,7 @@ static char const short_options[] =
|
||||
"h"
|
||||
"k"
|
||||
"l"
|
||||
"M:"
|
||||
"o:"
|
||||
"p:"
|
||||
"r:"
|
||||
@@ -598,14 +609,15 @@ static struct option const long_options[] =
|
||||
{ "yacc", no_argument, 0, 'y' },
|
||||
|
||||
/* Output Files. */
|
||||
{ "defines", optional_argument, 0, 'd' },
|
||||
{ "report", required_argument, 0, 'r' },
|
||||
{ "report-file", required_argument, 0, REPORT_FILE_OPTION },
|
||||
{ "verbose", no_argument, 0, 'v' },
|
||||
{ "file-prefix", required_argument, 0, 'b' },
|
||||
{ "output", required_argument, 0, 'o' },
|
||||
{ "graph", optional_argument, 0, 'g' },
|
||||
{ "xml", optional_argument, 0, 'x' },
|
||||
{ "defines", optional_argument, 0, 'd' },
|
||||
{ "report", required_argument, 0, 'r' },
|
||||
{ "report-file", required_argument, 0, REPORT_FILE_OPTION },
|
||||
{ "verbose", no_argument, 0, 'v' },
|
||||
{ "file-prefix", required_argument, 0, 'b' },
|
||||
{ "output", required_argument, 0, 'o' },
|
||||
{ "graph", optional_argument, 0, 'g' },
|
||||
{ "xml", optional_argument, 0, 'x' },
|
||||
{ "file-prefix-map", required_argument, 0, 'M' },
|
||||
|
||||
/* Hidden. */
|
||||
{ "fixed-output-files", no_argument, 0, FIXED_OUTPUT_FILES_OPTION },
|
||||
@@ -711,6 +723,22 @@ getargs (int argc, char *argv[])
|
||||
language_argmatch (optarg, command_line_prio, loc);
|
||||
break;
|
||||
|
||||
case 'M': // -MOLDPREFIX=NEWPREFIX
|
||||
{
|
||||
char *newprefix = strchr (optarg, '=');
|
||||
if (newprefix)
|
||||
{
|
||||
*newprefix = '\0';
|
||||
add_prefix_map (optarg, newprefix + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
complain (&loc, complaint, _("invalid argument for %s: %s"),
|
||||
quote ("--file-prefix-map"), quotearg_n (1, optarg));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 'S':
|
||||
skeleton_arg (optarg, command_line_prio, loc);
|
||||
break;
|
||||
@@ -860,7 +888,7 @@ getargs (int argc, char *argv[])
|
||||
void
|
||||
tr (char *s, char from, char to)
|
||||
{
|
||||
for (; *s; s++)
|
||||
for (; *s; ++s)
|
||||
if (*s == from)
|
||||
*s = to;
|
||||
}
|
||||
|
||||
+8
-5
@@ -79,6 +79,7 @@ enum report
|
||||
report_itemsets = 1 << 1,
|
||||
report_lookahead_tokens = 1 << 2,
|
||||
report_solved_conflicts = 1 << 3,
|
||||
report_cex = 1 << 4,
|
||||
report_all = ~0
|
||||
};
|
||||
/** What appears in the *.output file. */
|
||||
@@ -100,11 +101,13 @@ enum trace
|
||||
trace_grammar = 1 << 7, /**< Reading, reducing the grammar. */
|
||||
trace_time = 1 << 8, /**< Time consumption. */
|
||||
trace_skeleton = 1 << 9, /**< Skeleton postprocessing. */
|
||||
trace_m4 = 1 << 10, /**< M4 traces. */
|
||||
trace_muscles = 1 << 11, /**< M4 definitions of the muscles. */
|
||||
trace_ielr = 1 << 12, /**< IELR conversion. */
|
||||
trace_closure = 1 << 13, /**< Input/output of closure(). */
|
||||
trace_locations = 1 << 14, /**< Full display of locations. */
|
||||
trace_m4_early = 1 << 10, /**< M4 early traces. */
|
||||
trace_m4 = 1 << 11, /**< M4 traces. */
|
||||
trace_muscles = 1 << 12, /**< M4 definitions of the muscles. */
|
||||
trace_ielr = 1 << 13, /**< IELR conversion. */
|
||||
trace_closure = 1 << 14, /**< Input/output of closure(). */
|
||||
trace_locations = 1 << 15, /**< Full display of locations. */
|
||||
trace_cex = 1 << 16, /**< Counterexample generation */
|
||||
trace_all = ~0 /**< All of the above. */
|
||||
};
|
||||
/** What debug items bison displays during its run. */
|
||||
|
||||
+24
-24
@@ -40,25 +40,14 @@ rule_number nrules = 0;
|
||||
symbol **symbols = NULL;
|
||||
int nsyms = 0;
|
||||
int ntokens = 1;
|
||||
int nvars = 0;
|
||||
int nnterms = 0;
|
||||
|
||||
symbol_number *token_translations = NULL;
|
||||
|
||||
int max_user_token_number = 256;
|
||||
int max_code = 256;
|
||||
|
||||
int required_version = 0;
|
||||
|
||||
rule const *
|
||||
item_rule (item_number const *item)
|
||||
{
|
||||
item_number const *sp = item;
|
||||
while (0 <= *sp)
|
||||
++sp;
|
||||
rule_number r = item_number_as_rule_number (*sp);
|
||||
return &rules[r];
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
item_print (item_number *item, rule const *previous_rule, FILE *out)
|
||||
{
|
||||
@@ -67,7 +56,8 @@ item_print (item_number *item, rule const *previous_rule, FILE *out)
|
||||
|
||||
for (item_number *sp = r->rhs; sp < item; sp++)
|
||||
fprintf (out, " %s", symbols[*sp]->tag);
|
||||
fputs (" .", out);
|
||||
putc (' ', out);
|
||||
print_dot (out);
|
||||
if (0 <= *r->rhs)
|
||||
for (item_number *sp = item; 0 <= *sp; ++sp)
|
||||
fprintf (out, " %s", symbols[*sp]->tag);
|
||||
@@ -202,10 +192,10 @@ grammar_rules_partial_print (FILE *out, const char *title,
|
||||
if (first)
|
||||
fprintf (out, "%s\n\n", title);
|
||||
else if (previous_rule && previous_rule->lhs != rules[r].lhs)
|
||||
fputc ('\n', out);
|
||||
putc ('\n', out);
|
||||
first = false;
|
||||
rule_print (&rules[r], previous_rule, out);
|
||||
fputc ('\n', out);
|
||||
putc ('\n', out);
|
||||
previous_rule = &rules[r];
|
||||
}
|
||||
if (!first)
|
||||
@@ -251,15 +241,25 @@ grammar_rules_print_xml (FILE *out, int level)
|
||||
xml_puts (out, level + 1, "<rules/>");
|
||||
}
|
||||
|
||||
static void
|
||||
section (FILE *out, const char *s)
|
||||
{
|
||||
fprintf (out, "%s\n", s);
|
||||
for (int i = strlen (s); 0 < i; --i)
|
||||
putc ('-', out);
|
||||
putc ('\n', out);
|
||||
putc ('\n', out);
|
||||
}
|
||||
|
||||
void
|
||||
grammar_dump (FILE *out, const char *title)
|
||||
{
|
||||
fprintf (out, "%s\n\n", title);
|
||||
fprintf (out,
|
||||
"ntokens = %d, nvars = %d, nsyms = %d, nrules = %d, nritems = %d\n\n",
|
||||
ntokens, nvars, nsyms, nrules, nritems);
|
||||
"ntokens = %d, nnterms = %d, nsyms = %d, nrules = %d, nritems = %d\n\n",
|
||||
ntokens, nnterms, nsyms, nrules, nritems);
|
||||
|
||||
fprintf (out, "Tokens\n------\n\n");
|
||||
section (out, "Tokens");
|
||||
{
|
||||
fprintf (out, "Value Sprec Sassoc Tag\n");
|
||||
|
||||
@@ -271,7 +271,7 @@ grammar_dump (FILE *out, const char *title)
|
||||
fprintf (out, "\n\n");
|
||||
}
|
||||
|
||||
fprintf (out, "Non terminals\n-------------\n\n");
|
||||
section (out, "Nonterminals");
|
||||
{
|
||||
fprintf (out, "Value Tag\n");
|
||||
|
||||
@@ -281,7 +281,7 @@ grammar_dump (FILE *out, const char *title)
|
||||
fprintf (out, "\n\n");
|
||||
}
|
||||
|
||||
fprintf (out, "Rules\n-----\n\n");
|
||||
section (out, "Rules");
|
||||
{
|
||||
fprintf (out,
|
||||
"Num (Prec, Assoc, Useful, UselessChain) Lhs"
|
||||
@@ -303,17 +303,17 @@ grammar_dump (FILE *out, const char *title)
|
||||
/* Dumped the RHS. */
|
||||
for (item_number *rhsp = rule_i->rhs; 0 <= *rhsp; ++rhsp)
|
||||
fprintf (out, " %3d", *rhsp);
|
||||
fputc ('\n', out);
|
||||
putc ('\n', out);
|
||||
}
|
||||
}
|
||||
fprintf (out, "\n\n");
|
||||
|
||||
fprintf (out, "Rules interpreted\n-----------------\n\n");
|
||||
section (out, "Rules interpreted");
|
||||
for (rule_number r = 0; r < nrules + nuseless_productions; ++r)
|
||||
{
|
||||
fprintf (out, "%-5d %s:", r, rules[r].lhs->symbol->tag);
|
||||
rule_rhs_print (&rules[r], out);
|
||||
fputc ('\n', out);
|
||||
putc ('\n', out);
|
||||
}
|
||||
fprintf (out, "\n\n");
|
||||
}
|
||||
|
||||
+41
-6
@@ -23,9 +23,9 @@
|
||||
|
||||
/* Representation of the grammar rules:
|
||||
|
||||
NTOKENS is the number of tokens, and NVARS is the number of
|
||||
NTOKENS is the number of tokens, and NNTERMS is the number of
|
||||
variables (nonterminals). NSYMS is the total number, ntokens +
|
||||
nvars.
|
||||
nnterms.
|
||||
|
||||
Each symbol (either token or variable) receives a symbol number.
|
||||
Numbers 0 to NTOKENS - 1 are for tokens, and NTOKENS to NSYMS - 1
|
||||
@@ -101,6 +101,10 @@
|
||||
|
||||
Associativities are recorded similarly in SYMBOLS[I]->assoc. */
|
||||
|
||||
# include "system.h"
|
||||
|
||||
# include <unicodeio.h>
|
||||
|
||||
# include "location.h"
|
||||
# include "symtab.h"
|
||||
|
||||
@@ -109,13 +113,17 @@
|
||||
|
||||
extern int nsyms;
|
||||
extern int ntokens;
|
||||
extern int nvars;
|
||||
extern int nnterms;
|
||||
|
||||
/* Elements of ritem. */
|
||||
typedef int item_number;
|
||||
# define ITEM_NUMBER_MAX INT_MAX
|
||||
extern item_number *ritem;
|
||||
extern int nritems;
|
||||
|
||||
/* Indices into ritem. */
|
||||
typedef unsigned int item_index;
|
||||
|
||||
/* There is weird relationship between OT1H item_number and OTOH
|
||||
symbol_number and rule_number: we store the latter in
|
||||
item_number. symbol_number values are stored as-is, while
|
||||
@@ -173,7 +181,7 @@ typedef struct
|
||||
{
|
||||
/* The number of the rule in the source. It is usually the index in
|
||||
RULES too, except if there are useless rules. */
|
||||
rule_number user_number;
|
||||
rule_number code;
|
||||
|
||||
/* The index in RULES. Usually the rule number in the source,
|
||||
except if some rules are useless. */
|
||||
@@ -209,8 +217,35 @@ typedef struct
|
||||
extern rule *rules;
|
||||
extern rule_number nrules;
|
||||
|
||||
/* Fallback in case we can't print "•". */
|
||||
static inline long
|
||||
print_dot_fallback (unsigned int code _GL_UNUSED,
|
||||
const char *msg _GL_UNUSED,
|
||||
void *callback_arg)
|
||||
{
|
||||
FILE *out = (FILE *) callback_arg;
|
||||
putc ('.', out);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Print "•", the symbol used to represent a point in an item (aka, a
|
||||
dotted rule). */
|
||||
static inline void
|
||||
print_dot (FILE *out)
|
||||
{
|
||||
unicode_to_mb (0x2022, fwrite_success_callback, print_dot_fallback, out);
|
||||
}
|
||||
|
||||
/* Get the rule associated to this item. ITEM points inside RITEM. */
|
||||
rule const *item_rule (item_number const *item);
|
||||
static inline rule const *
|
||||
item_rule (item_number const *item)
|
||||
{
|
||||
item_number const *sp = item;
|
||||
while (!item_number_is_rule_number (*sp))
|
||||
++sp;
|
||||
rule_number r = item_number_as_rule_number (*sp);
|
||||
return &rules[r];
|
||||
}
|
||||
|
||||
/* Pretty-print this ITEM (as in the report). ITEM points inside
|
||||
RITEM. PREVIOUS_RULE is used to see if the lhs is common, in which
|
||||
@@ -262,7 +297,7 @@ extern symbol **symbols;
|
||||
by the user's yylex routine, it yields the internal token number
|
||||
used by the parser and throughout bison. */
|
||||
extern symbol_number *token_translations;
|
||||
extern int max_user_token_number;
|
||||
extern int max_code;
|
||||
|
||||
|
||||
|
||||
|
||||
+12
-10
@@ -72,18 +72,20 @@ output_edge (int source, int destination, char const *label,
|
||||
{
|
||||
fprintf (fout, " %d -> %d [style=%s", source, destination, style);
|
||||
if (label)
|
||||
fprintf (fout, " label=%s", quote (label));
|
||||
{
|
||||
fputs (" label=\"", fout);
|
||||
for (const char *cp = label; *cp; ++cp)
|
||||
switch (*cp)
|
||||
{
|
||||
case '"': fputs ("\\\"", fout); break;
|
||||
case '\\': fputs ("\\\\", fout); break;
|
||||
default: fputc (*cp, fout); break;
|
||||
}
|
||||
fputc ('"', fout);
|
||||
}
|
||||
fputs ("]\n", fout);
|
||||
}
|
||||
|
||||
char const *
|
||||
escape (char const *name)
|
||||
{
|
||||
char *q = quote (name);
|
||||
q[strlen (q) - 1] = '\0';
|
||||
return q + 1;
|
||||
}
|
||||
|
||||
static void
|
||||
no_reduce_bitset_init (state const *s, bitset *no_reduce_set)
|
||||
{
|
||||
@@ -149,7 +151,7 @@ print_token (struct obstack *out, bool first, char const *tok)
|
||||
{
|
||||
if (! first)
|
||||
obstack_sgrow (out, ", ");
|
||||
obstack_sgrow (out, escape (tok));
|
||||
obstack_backslash (out, tok);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -63,10 +63,4 @@ void output_red (state const *s, reductions const *reds, FILE *fout);
|
||||
*/
|
||||
void finish_graph (FILE *fout);
|
||||
|
||||
/** Escape a lookahead token.
|
||||
*
|
||||
* \param name the token.
|
||||
*/
|
||||
char const *escape (char const *name);
|
||||
|
||||
#endif /* ! GRAPHVIZ_H_ */
|
||||
|
||||
+23
-33
@@ -18,10 +18,11 @@
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <config.h>
|
||||
#include "system.h"
|
||||
|
||||
#include "ielr.h"
|
||||
|
||||
#include "system.h"
|
||||
|
||||
#include <bitset.h>
|
||||
#include <timevar.h>
|
||||
|
||||
@@ -230,7 +231,7 @@ ielr_compute_follow_kernel_items (bitset ritem_sees_lookahead_set,
|
||||
for (goto_number i = 0; i < ngotos; ++i)
|
||||
{
|
||||
size_t nitems = states[from_state[i]]->nitems;
|
||||
item_number *items = states[from_state[i]]->items;
|
||||
item_index *items = states[from_state[i]]->items;
|
||||
for (size_t j = 0; j < nitems; ++j)
|
||||
/* If this item has this goto and if all subsequent symbols in this
|
||||
RHS (if any) are nullable nonterminals, then record this item as
|
||||
@@ -318,7 +319,7 @@ static state ***
|
||||
ielr_compute_predecessors (void)
|
||||
{
|
||||
int *predecessor_counts = xnmalloc (nstates, sizeof *predecessor_counts);
|
||||
state ***result = xnmalloc (nstates, sizeof *result);
|
||||
state ***res = xnmalloc (nstates, sizeof *res);
|
||||
for (state_number i = 0; i < nstates; ++i)
|
||||
predecessor_counts[i] = 0;
|
||||
for (state_number i = 0; i < nstates; ++i)
|
||||
@@ -326,18 +327,18 @@ ielr_compute_predecessors (void)
|
||||
++predecessor_counts[states[i]->transitions->states[j]->number];
|
||||
for (state_number i = 0; i < nstates; ++i)
|
||||
{
|
||||
result[i] = xnmalloc (predecessor_counts[i]+1, sizeof *result[i]);
|
||||
result[i][predecessor_counts[i]] = NULL;
|
||||
res[i] = xnmalloc (predecessor_counts[i]+1, sizeof *res[i]);
|
||||
res[i][predecessor_counts[i]] = NULL;
|
||||
predecessor_counts[i] = 0;
|
||||
}
|
||||
for (state_number i = 0; i < nstates; ++i)
|
||||
for (int j = 0; j < states[i]->transitions->num; ++j)
|
||||
{
|
||||
state_number k = states[i]->transitions->states[j]->number;
|
||||
result[k][predecessor_counts[k]++] = states[i];
|
||||
res[k][predecessor_counts[k]++] = states[i];
|
||||
}
|
||||
free (predecessor_counts);
|
||||
return result;
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -417,14 +418,7 @@ ielr_item_has_lookahead (state *s, symbol_number lhs, size_t item,
|
||||
/* If the LHS symbol of this item isn't known (because this is a
|
||||
top-level invocation), go get it. */
|
||||
if (!lhs)
|
||||
{
|
||||
int i;
|
||||
for (i = s->items[item];
|
||||
!item_number_is_rule_number (ritem[i]);
|
||||
++i)
|
||||
continue;
|
||||
lhs = rules[item_number_as_rule_number (ritem[i])].lhs->number;
|
||||
}
|
||||
lhs = item_rule (&ritem[s->items[item]])->lhs->number;
|
||||
/* If this kernel item is next to the beginning of the RHS, then
|
||||
check all predecessors' goto follows for the LHS. */
|
||||
if (item_number_is_rule_number (ritem[s->items[item] - 2]))
|
||||
@@ -632,17 +626,10 @@ ielr_compute_lookaheads (bitsetv follow_kernel_items, bitsetv always_follows,
|
||||
&& !bitset_empty_p (lookahead_filter[t_item]))
|
||||
{
|
||||
if (item_number_is_rule_number (ritem[t->items[t_item] - 2]))
|
||||
{
|
||||
int rule_item;
|
||||
for (rule_item = t->items[t_item];
|
||||
!item_number_is_rule_number (ritem[rule_item]);
|
||||
++rule_item)
|
||||
;
|
||||
ielr_compute_goto_follow_set (
|
||||
follow_kernel_items, always_follows, s,
|
||||
rules[item_number_as_rule_number (ritem[rule_item])].lhs,
|
||||
lookaheads[t_item]);
|
||||
}
|
||||
ielr_compute_goto_follow_set (
|
||||
follow_kernel_items, always_follows, s,
|
||||
item_rule (&ritem[t->items[t_item]])->lhs,
|
||||
lookaheads[t_item]);
|
||||
else if (s->lookaheads)
|
||||
{
|
||||
/* We don't have to start the s item search at the beginning
|
||||
@@ -709,15 +696,17 @@ ielr_compute_state (bitsetv follow_kernel_items, bitsetv always_follows,
|
||||
/* Determine whether there's an isocore of t with which these lookaheads can
|
||||
be merged. */
|
||||
{
|
||||
AnnotationIndex ai;
|
||||
AnnotationList *a;
|
||||
if (annotation_lists)
|
||||
for (ai = 0, a = annotation_lists[lr0_isocore->state->number];
|
||||
{
|
||||
AnnotationIndex ai;
|
||||
AnnotationList *a;
|
||||
for (ai = 0, a = annotation_lists[lr0_isocore->state->number];
|
||||
a;
|
||||
++ai, a = a->next)
|
||||
work1[ai] =
|
||||
AnnotationList__computeDominantContribution (
|
||||
a, lr0_isocore->state->nitems, lookaheads, false);
|
||||
}
|
||||
for (this_isocorep = &t->state_list;
|
||||
this_isocorep == &t->state_list || *this_isocorep != t->state_list;
|
||||
this_isocorep = &(*this_isocorep)->nextIsocore)
|
||||
@@ -726,6 +715,8 @@ ielr_compute_state (bitsetv follow_kernel_items, bitsetv always_follows,
|
||||
break;
|
||||
if (annotation_lists)
|
||||
{
|
||||
AnnotationIndex ai;
|
||||
AnnotationList *a;
|
||||
for (ai = 0, a = annotation_lists[lr0_isocore->state->number];
|
||||
a;
|
||||
++ai, a = a->next)
|
||||
@@ -789,15 +780,14 @@ ielr_compute_state (bitsetv follow_kernel_items, bitsetv always_follows,
|
||||
actually new. */
|
||||
if (has_lookaheads)
|
||||
{
|
||||
size_t i;
|
||||
if (!(*this_isocorep)->lookaheads)
|
||||
{
|
||||
(*this_isocorep)->lookaheads =
|
||||
xnmalloc (t->nitems, sizeof (*this_isocorep)->lookaheads);
|
||||
for (i = 0; i < t->nitems; ++i)
|
||||
for (size_t i = 0; i < t->nitems; ++i)
|
||||
(*this_isocorep)->lookaheads[i] = NULL;
|
||||
}
|
||||
for (i = 0; i < t->nitems; ++i)
|
||||
for (size_t i = 0; i < t->nitems; ++i)
|
||||
if (!bitset_empty_p (lookaheads[i]))
|
||||
{
|
||||
if (!(*this_isocorep)->lookaheads[i])
|
||||
@@ -1030,7 +1020,7 @@ ielr_split_states (bitsetv follow_kernel_items, bitsetv always_follows,
|
||||
if (!node->state->consistent)
|
||||
{
|
||||
size_t i = 0;
|
||||
item_number *itemset = node->state->items;
|
||||
item_index *itemset = node->state->items;
|
||||
for (size_t r = 0; r < node->state->reductions->num; ++r)
|
||||
{
|
||||
rule *this_rule = node->state->reductions->rules[r];
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user