mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-08-08 10:15:14 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9beba1919c | ||
|
|
80ebbe7330 | ||
|
|
028df02a9f | ||
|
|
71dfc86d58 | ||
|
|
5c1069c7d8 | ||
|
|
3fc3ef658e | ||
|
|
dd6e78360a | ||
|
|
eeb5d6f11b | ||
|
|
70441b5ab1 | ||
|
|
7538d8dc1a | ||
|
|
b07b5ce423 | ||
|
|
157e91dcc6 | ||
|
|
b820718adf | ||
|
|
6e6e11795c | ||
|
|
6bfdf22c50 | ||
|
|
d432079f8a | ||
|
|
b6ac175a1c | ||
|
|
5f90ef59a4 | ||
|
|
10ee04479f | ||
|
|
c09524cf8f | ||
|
|
28152fc10a | ||
|
|
9babd05a90 | ||
|
|
3e94b12ddd | ||
|
|
7cb6de2533 | ||
|
|
4ec4309cce | ||
|
|
ca96df89b2 | ||
|
|
2142e59155 | ||
|
|
a75072476e | ||
|
|
7c47598d4f | ||
|
|
fdaedc780a | ||
|
|
85f5e3b9d5 | ||
|
|
c3a4686a03 | ||
|
|
9cdfd86cbb | ||
|
|
659376b590 | ||
|
|
0343acbe89 | ||
|
|
5d9ccd5a87 | ||
|
|
ad9b8a069f | ||
|
|
ec3375ab4e | ||
|
|
12c8e427c7 | ||
|
|
9f8f3d2e77 | ||
|
|
108724c2e7 | ||
|
|
da0f993fb9 | ||
|
|
075a879052 | ||
|
|
a7ded4284e | ||
|
|
a5c55bb758 | ||
|
|
bc5aa8e274 | ||
|
|
0a82bf5c07 | ||
|
|
a70e75b8a4 | ||
|
|
3afa9757da | ||
|
|
36f37568ba | ||
|
|
f2c568d3ef | ||
|
|
bb7860d208 | ||
|
|
8bb81e2048 | ||
|
|
84059ea508 | ||
|
|
024f00fd11 | ||
|
|
0af06e091b | ||
|
|
1d291901b4 | ||
|
|
f387ffc1d3 | ||
|
|
9307c173c7 | ||
|
|
15ba35a51b | ||
|
|
db66acc5d0 | ||
|
|
3477ced42b | ||
|
|
348b5039fd | ||
|
|
07cdeda9f8 | ||
|
|
c2ba260487 | ||
|
|
e4e3cbce77 | ||
|
|
b2a00ed5dd | ||
|
|
3c5f73fe51 | ||
|
|
dabde7c560 | ||
|
|
272da17cfd | ||
|
|
4b802d6417 | ||
|
|
7f1e9249d0 | ||
|
|
6d86d26b33 | ||
|
|
80db1029e6 | ||
|
|
6118406c3e | ||
|
|
a83202a436 | ||
|
|
9de593aba7 | ||
|
|
6fc9f13aef | ||
|
|
d4b195ece6 | ||
|
|
85032e9630 | ||
|
|
7e16706f7b | ||
|
|
b7d2b854be | ||
|
|
93f9e527ca | ||
|
|
0c0cf6f5a4 | ||
|
|
413d318940 | ||
|
|
cb7bdc251d | ||
|
|
e814ddc92f | ||
|
|
b293d4fbca | ||
|
|
952479fca7 | ||
|
|
e14825ecb7 | ||
|
|
98823ea402 | ||
|
|
ad40c80a03 | ||
|
|
3c7cc7dc4f | ||
|
|
410d37b994 | ||
|
|
9b6065303b | ||
|
|
5325292e5d | ||
|
|
ca403f672c | ||
|
|
5c554ea8a3 | ||
|
|
7eee2ccbd2 | ||
|
|
f99314765b | ||
|
|
9ba3c5ceb9 | ||
|
|
4bd4cdf377 | ||
|
|
ae0889d805 | ||
|
|
a9c2549c27 | ||
|
|
fb032a28df | ||
|
|
59a2053c83 | ||
|
|
e1caae6b48 | ||
|
|
c4cf4cc2f5 | ||
|
|
15c61fb712 | ||
|
|
f6eb1ac87b | ||
|
|
b96528b48c | ||
|
|
4511e43245 | ||
|
|
306fc3ec00 | ||
|
|
f08110cb50 | ||
|
|
c61b282d77 | ||
|
|
2d1d2f87f9 | ||
|
|
f50fff58d1 | ||
|
|
e0ab5c324a | ||
|
|
c80b404dfa | ||
|
|
96b881094b | ||
|
|
fdba54a961 | ||
|
|
d50a3e450e | ||
|
|
47186ec460 | ||
|
|
1efe31185f | ||
|
|
9acc9d2aee | ||
|
|
dc8fe0678a | ||
|
|
a70e21215a | ||
|
|
638de51289 | ||
|
|
b46afca5be | ||
|
|
0dc20612c0 | ||
|
|
6dc09317fb | ||
|
|
fc0dbb3bba | ||
|
|
de93a0728b | ||
|
|
689b184983 | ||
|
|
b4582f1918 | ||
|
|
77a8b84fc8 | ||
|
|
b27bba5ced | ||
|
|
7a525fa06f | ||
|
|
c7037bfcb0 | ||
|
|
874e75975b | ||
|
|
51f12cffd2 | ||
|
|
c94456986d | ||
|
|
fb144c021c | ||
|
|
5aaa93ae72 | ||
|
|
cd99a1a923 | ||
|
|
d53bbd5f06 | ||
|
|
615bad4186 | ||
|
|
4f6d1f5fdc | ||
|
|
4fd2e5c22a | ||
|
|
7e0b792d12 | ||
|
|
d7e8aaa271 | ||
|
|
30a8d580fa | ||
|
|
119dedb591 | ||
|
|
d85ea95d6f | ||
|
|
a9911528e0 | ||
|
|
17fb1d0377 | ||
|
|
a9f9f317b5 | ||
|
|
4524e17616 | ||
|
|
c93aec904a | ||
|
|
3a9529eaed | ||
|
|
c1494a7871 | ||
|
|
0923da74e8 | ||
|
|
0a4a7178c8 | ||
|
|
da4d38f830 | ||
|
|
769322e01e | ||
|
|
19418cfc75 | ||
|
|
42d5a16f8d | ||
|
|
118c4bd3a1 | ||
|
|
82133a6103 | ||
|
|
cca770a156 | ||
|
|
430ca0fc63 | ||
|
|
983364d76a | ||
|
|
6833b1be47 | ||
|
|
4aa731d110 | ||
|
|
3ad6d862b7 | ||
|
|
3fa59c32fc | ||
|
|
47612d987b | ||
|
|
3a98be5284 | ||
|
|
fbdff2bc38 | ||
|
|
3bcc090758 | ||
|
|
5433b0a84b | ||
|
|
21c812e2f0 | ||
|
|
442c8d85aa | ||
|
|
428999c117 | ||
|
|
b52a2172a1 | ||
|
|
8d01c60e9c | ||
|
|
c13b3c02d3 | ||
|
|
f859462658 | ||
|
|
dc8b16424a | ||
|
|
5bac3ddcee | ||
|
|
594cae57ca | ||
|
|
e51e89856a | ||
|
|
c2a06bf791 | ||
|
|
8733959954 | ||
|
|
31b8b8f179 | ||
|
|
e2199d0fb2 | ||
|
|
c1884d3002 | ||
|
|
ab1208e263 | ||
|
|
74d1e881a7 | ||
|
|
f30067ed51 | ||
|
|
630448ba6b | ||
|
|
1283dc7243 | ||
|
|
e3d4b42f58 | ||
|
|
f67c1ce937 | ||
|
|
5a4e606275 | ||
|
|
83f2eb3737 | ||
|
|
3911aba39a | ||
|
|
8bc45673d5 | ||
|
|
fbe5abd23d | ||
|
|
c09f2e4c7b | ||
|
|
ac3d5b76f7 | ||
|
|
edfcca8481 | ||
|
|
92e943bd24 | ||
|
|
e40da7b6b3 | ||
|
|
70b3c8fb20 | ||
|
|
e9b7641cca | ||
|
|
321fac2193 | ||
|
|
2777b73166 | ||
|
|
89296e3962 | ||
|
|
bb97a2a37b | ||
|
|
8a22b557b9 | ||
|
|
92dc8bf23b | ||
|
|
c18dbfcb06 | ||
|
|
94701b4e5e | ||
|
|
3e6826aff1 | ||
|
|
9466c734c5 | ||
|
|
b9a533d63e | ||
|
|
d0e44162b5 | ||
|
|
8db99c54f4 | ||
|
|
2157ced3dd | ||
|
|
59653c8efd | ||
|
|
2a07cb0f2d | ||
|
|
734ce73bf2 | ||
|
|
baea8cf9fa | ||
|
|
636c9a8042 | ||
|
|
7dc942dca3 | ||
|
|
32bb53870b | ||
|
|
27109d9d4a | ||
|
|
2b4451c4af | ||
|
|
c0f3b55b25 | ||
|
|
20d657c1dd | ||
|
|
b00fa62e95 | ||
|
|
8e44b24ba8 | ||
|
|
6692df8992 | ||
|
|
cc04459cfe | ||
|
|
ee4ec08513 | ||
|
|
13bb2b78b3 | ||
|
|
848a17fa33 | ||
|
|
c6a39f8409 | ||
|
|
df34ad7c6e | ||
|
|
0a82316e54 | ||
|
|
611348e67b | ||
|
|
fe0102d4d5 | ||
|
|
718cb1ab38 | ||
|
|
08f657f4a4 | ||
|
|
7292ed6e64 | ||
|
|
3f473dd2d7 | ||
|
|
03d33fd3a4 | ||
|
|
0a6c2e6400 | ||
|
|
640b1313d7 | ||
|
|
66706a7c19 | ||
|
|
80664353b2 | ||
|
|
d6fbeb2798 | ||
|
|
b33817f8bb | ||
|
|
c97dbc46af | ||
|
|
b2d35f5cb8 | ||
|
|
855d46678a | ||
|
|
178a033e8b | ||
|
|
c8006f4637 | ||
|
|
5b65b3d543 | ||
|
|
2b52bd1644 | ||
|
|
9ee51ece65 | ||
|
|
2313f891bd | ||
|
|
42fe808292 | ||
|
|
4beefee4bf | ||
|
|
3301849f0f | ||
|
|
349ea900f5 | ||
|
|
1b85ac4586 | ||
|
|
2ec6df3b07 | ||
|
|
e72eda7aee | ||
|
|
4f24f5f304 | ||
|
|
12b5924939 | ||
|
|
d4188398f1 | ||
|
|
8ab625e517 | ||
|
|
edf6aa7d3b | ||
|
|
4aec17af93 | ||
|
|
c98b8856e6 | ||
|
|
4ec49a8585 | ||
|
|
627d275a3a | ||
|
|
84a84560c3 | ||
|
|
0e78a9028e | ||
|
|
24233748ec | ||
|
|
9840e5b621 | ||
|
|
8eede447db | ||
|
|
5b19f91ccf | ||
|
|
7fe9205b9f | ||
|
|
d798851e48 | ||
|
|
5af04b99dd | ||
|
|
38cdb2aba2 | ||
|
|
5629305131 | ||
|
|
e5854bbddd | ||
|
|
10305f3e94 | ||
|
|
2ca158c893 | ||
|
|
336089123f | ||
|
|
593724366f | ||
|
|
0e51f6146a | ||
|
|
5945da031e | ||
|
|
b9b13602ed | ||
|
|
23472033ee | ||
|
|
d0ea78ca47 | ||
|
|
7cc9107053 | ||
|
|
25ded505a3 | ||
|
|
6c0ba6089a | ||
|
|
70ee8c77a8 | ||
|
|
e9a43ed4ae | ||
|
|
a38d0b9145 | ||
|
|
4b0cd01fb7 | ||
|
|
0328cbad64 | ||
|
|
3b80811cfa | ||
|
|
10eb13007e | ||
|
|
dc15b62a7c | ||
|
|
4252134ba4 | ||
|
|
5a31cda4c3 | ||
|
|
34e6e8815a | ||
|
|
b5aee13b82 | ||
|
|
660f3d4732 | ||
|
|
abf5f7f90e | ||
|
|
d49da0101a | ||
|
|
fa8aca1ed4 | ||
|
|
829ac9caed | ||
|
|
f7a7310433 | ||
|
|
d156910453 | ||
|
|
1995d9e2f2 | ||
|
|
c223baee63 | ||
|
|
787052f074 | ||
|
|
042b916c0e | ||
|
|
57848d9262 | ||
|
|
8d7cd5e84d | ||
|
|
0cd16ae964 | ||
|
|
98691fcd2d | ||
|
|
2347e959d4 | ||
|
|
36143b5ecc | ||
|
|
7cd195b30a | ||
|
|
e66673aa64 | ||
|
|
3829bd6262 | ||
|
|
72360b51a5 | ||
|
|
4bbda69f1e | ||
|
|
4855b98554 | ||
|
|
cd40ec9526 | ||
|
|
a7daa63cb7 | ||
|
|
2e5592b3ab | ||
|
|
9b18cac96b | ||
|
|
c19c1e7ec5 | ||
|
|
15cf0095d3 | ||
|
|
3ff7db34a2 | ||
|
|
d441a34791 | ||
|
|
f4d33ff4b4 | ||
|
|
683040b324 | ||
|
|
d9cf99b6a5 | ||
|
|
a6805bb8d9 | ||
|
|
a0b044186b | ||
|
|
01af4ad9c3 | ||
|
|
ed324578a2 | ||
|
|
05d6b54703 | ||
|
|
78d0e5e671 | ||
|
|
85ccc1bab3 | ||
|
|
4646be7db4 | ||
|
|
8eaddf326b | ||
|
|
db68f61595 | ||
|
|
7eca26e87b | ||
|
|
e50ec28153 | ||
|
|
f7f2c99c28 | ||
|
|
f9b360663b | ||
|
|
3add9ffbde | ||
|
|
f296669c0f | ||
|
|
de638df104 | ||
|
|
8dc60543c8 | ||
|
|
f8cd049ecc | ||
|
|
72946549ed | ||
|
|
bad4fc09a7 | ||
|
|
aac79ca103 | ||
|
|
843f99886c | ||
|
|
647453a614 | ||
|
|
d4ffb69424 | ||
|
|
0711dca9d9 | ||
|
|
f5d4b64909 | ||
|
|
b327f38832 | ||
|
|
75c3746ce2 | ||
|
|
b329f0b5df | ||
|
|
12a5cc07e0 | ||
|
|
27b5d92563 | ||
|
|
34476c449a | ||
|
|
795a59aba4 | ||
|
|
243fa94ce2 | ||
|
|
11995fec50 | ||
|
|
c654eb481c | ||
|
|
5c37f5994d | ||
|
|
952a61b62e | ||
|
|
cf8f805d36 | ||
|
|
2bc886dc02 | ||
|
|
b5e6d9c4ca | ||
|
|
3ae2a22a05 | ||
|
|
146a8eb101 | ||
|
|
4428e8e8b3 | ||
|
|
00e47b11d2 | ||
|
|
cf8723de0d | ||
|
|
8bfc319f8e | ||
|
|
1c5b05ad31 | ||
|
|
b7e2cac2aa | ||
|
|
93d6a5ba4d | ||
|
|
5d711972b8 | ||
|
|
0d8407440c | ||
|
|
1df4b746da | ||
|
|
f3f7f6e1dc | ||
|
|
38abe1e1b7 | ||
|
|
6e1d83c8a8 | ||
|
|
8032dde383 | ||
|
|
f3bcb3de0e | ||
|
|
325ec7d324 | ||
|
|
82d913741b | ||
|
|
3c36d871fa | ||
|
|
2becdace96 | ||
|
|
115a947f08 | ||
|
|
b63e3a3352 | ||
|
|
ef09bf065a |
+2
-1
@@ -1 +1,2 @@
|
||||
|
||||
*.at diff=autotest
|
||||
*.texi diff=texinfo
|
||||
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
# To use this gitconfig file, run
|
||||
#
|
||||
# git config --local include.path ../.gitconfig
|
||||
#
|
||||
# It adds an `[include]` section in .git/config.
|
||||
# See <https://git-scm.com/docs/git-config#_includes>.
|
||||
|
||||
[diff "autotest"]
|
||||
xfuncname = "^((m4_define|m4_pushdef|AT_SETUP).*)$"
|
||||
|
||||
[diff "texinfo"]
|
||||
xfuncname = "^@node .*$"
|
||||
+1
-1
@@ -1 +1 @@
|
||||
3.7.5
|
||||
3.8.1
|
||||
|
||||
+78
-38
@@ -44,6 +44,8 @@ jobs:
|
||||
- git fetch --unshallow || true
|
||||
- git submodule update --init --recursive
|
||||
|
||||
# As of 2021-08, we don't have Autoconf 2.71 on Ubuntu.
|
||||
- sed -i 's/AC_PREREQ(\[2\.71\])/AC_PREREQ([2.69])/g' configure.ac
|
||||
- ./bootstrap
|
||||
- ./configure --enable-gcc-warnings || { cat config.log && false; }
|
||||
- make -j2
|
||||
@@ -71,53 +73,53 @@ jobs:
|
||||
|
||||
# Start with three completely different environments, to get errors asap.
|
||||
|
||||
- name: "GCC 10 -O3"
|
||||
- name: "GCC 11 -O3"
|
||||
stage: check
|
||||
os: linux
|
||||
dist: bionic
|
||||
addons: &gcc10
|
||||
addons: &gcc11
|
||||
apt:
|
||||
sources:
|
||||
# See https://github.com/travis-ci/apt-source-safelist/issues/410.
|
||||
- sourceline: 'ppa:ubuntu-toolchain-r/test'
|
||||
packages: g++-10
|
||||
packages: g++-11
|
||||
env:
|
||||
- CC=gcc-10
|
||||
- CXX=g++-10
|
||||
- CC=gcc-11
|
||||
- CXX=g++-11
|
||||
- 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 10 libc++ and ASAN part 1"
|
||||
- name: "Clang 11 libc++ and ASAN part 1"
|
||||
stage: check
|
||||
os: linux
|
||||
dist: bionic
|
||||
addons: &clang10
|
||||
addons: &clang11
|
||||
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-10 main'
|
||||
- sourceline: 'deb http://apt.llvm.org/bionic/ llvm-toolchain-bionic-11 main'
|
||||
key_url: 'https://apt.llvm.org/llvm-snapshot.gpg.key'
|
||||
packages:
|
||||
- clang-10
|
||||
- libc++-10-dev
|
||||
- libc++abi-10-dev
|
||||
- clang-11
|
||||
- libc++-11-dev
|
||||
- libc++abi-11-dev
|
||||
env:
|
||||
# Do not use ASAN with ubuntu's libc++: https://bugs.llvm.org/show_bug.cgi?id=17379
|
||||
- CC='clang-10 -fsanitize=address'
|
||||
- CXX='clang++-10 -fsanitize=address -stdlib=libc++'
|
||||
- CC='clang-11 -fsanitize=address'
|
||||
- CXX='clang++-11 -fsanitize=address -stdlib=libc++'
|
||||
- PART=1
|
||||
|
||||
- name: "Clang 10 libc++ and ASAN part 2"
|
||||
- name: "Clang 11 libc++ and ASAN part 2"
|
||||
stage: check
|
||||
os: linux
|
||||
dist: bionic
|
||||
addons: *clang10
|
||||
addons: *clang11
|
||||
env:
|
||||
# Do not use ASAN with ubuntu's libc++: https://bugs.llvm.org/show_bug.cgi?id=17379
|
||||
- CC='clang-10 -fsanitize=address'
|
||||
- CXX='clang++-10 -fsanitize=address -stdlib=libc++'
|
||||
- CC='clang-11 -fsanitize=address'
|
||||
- CXX='clang++-11 -fsanitize=address -stdlib=libc++'
|
||||
- PART=2
|
||||
|
||||
# See https://github.com/simd-everywhere/simde/blob/master/.travis.yml
|
||||
@@ -139,19 +141,19 @@ jobs:
|
||||
packages:
|
||||
- intel-oneapi-icc
|
||||
|
||||
- name: "ARM64: GCC 10 -O2 part 1"
|
||||
- name: "ARM64: GCC 11 -O2 part 1"
|
||||
stage: check
|
||||
os: linux
|
||||
arch: arm64
|
||||
dist: bionic
|
||||
addons: *gcc10
|
||||
addons: *gcc11
|
||||
env:
|
||||
- CC=gcc-10
|
||||
- CXX=g++-10
|
||||
- CC=gcc-11
|
||||
- CXX=g++-11
|
||||
- CONFIGUREFLAGS='CPPFLAGS=-DNDEBUG CFLAGS=-O2 CXXFLAGS=-O2'
|
||||
- PART=1
|
||||
|
||||
- name: "PPC64le: GCC 10 -O2 part 1"
|
||||
- name: "PPC64le: GCC 11 -O2 part 1"
|
||||
stage: check
|
||||
os: linux
|
||||
arch: ppc64le
|
||||
@@ -161,22 +163,22 @@ jobs:
|
||||
sources:
|
||||
# See https://github.com/travis-ci/apt-source-safelist/issues/410.
|
||||
- sourceline: 'ppa:ubuntu-toolchain-r/test'
|
||||
packages: g++-10
|
||||
packages: g++-11
|
||||
env:
|
||||
- CC=gcc-10
|
||||
- CXX=g++-10
|
||||
- CC=gcc-11
|
||||
- CXX=g++-11
|
||||
- CONFIGUREFLAGS='CFLAGS=-O2 CXXFLAGS=-O2'
|
||||
- PART=1
|
||||
|
||||
- name: "s390x: GCC 10 -O2 part 1"
|
||||
- name: "s390x: GCC 11 -O2 part 1"
|
||||
stage: check
|
||||
os: linux
|
||||
arch: s390x
|
||||
dist: bionic
|
||||
addons: *gcc10
|
||||
addons: *gcc11
|
||||
env:
|
||||
- CC=gcc-10
|
||||
- CXX=g++-10
|
||||
- CC=gcc-11
|
||||
- CXX=g++-11
|
||||
- CONFIGUREFLAGS='CFLAGS=-O2 CXXFLAGS=-O2'
|
||||
- PART=1
|
||||
|
||||
@@ -184,7 +186,24 @@ jobs:
|
||||
## GCC. ##
|
||||
## ----- ##
|
||||
|
||||
- name: "GCC 9 with sanitizers part 1"
|
||||
- name: "GCC 10 with sanitizers part 1"
|
||||
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'
|
||||
packages: g++-10
|
||||
env:
|
||||
- CC='gcc-10 -fsanitize=undefined,address -fno-omit-frame-pointer'
|
||||
- CXX='g++-10 -fsanitize=undefined,address -fno-omit-frame-pointer'
|
||||
- CONFIGUREFLAGS='CFLAGS=-O1 CXXFLAGS=-O1'
|
||||
- PART=1
|
||||
|
||||
# With glr2.cc, we run out of time with the full test suite.
|
||||
- name: "GCC 9 part 1"
|
||||
stage: check
|
||||
os: linux
|
||||
dist: bionic
|
||||
@@ -195,12 +214,12 @@ jobs:
|
||||
- sourceline: 'ppa:ubuntu-toolchain-r/test'
|
||||
packages: g++-9
|
||||
env:
|
||||
- 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'
|
||||
- CC=gcc-9
|
||||
- CXX=g++-9
|
||||
- PART=1
|
||||
|
||||
- name: "GCC 8"
|
||||
# With glr2.cc, we run out of time with the full test suite.
|
||||
- name: "GCC 8 part 1"
|
||||
stage: check
|
||||
os: linux
|
||||
dist: bionic
|
||||
@@ -210,6 +229,7 @@ jobs:
|
||||
env:
|
||||
- CC=gcc-8
|
||||
- CXX=g++-8
|
||||
- PART=1
|
||||
|
||||
- name: "GCC 7"
|
||||
stage: check
|
||||
@@ -298,7 +318,28 @@ jobs:
|
||||
## Clang. ##
|
||||
## ------- ##
|
||||
|
||||
- name: "Clang 9 -O3"
|
||||
- name: "Clang 10 -O3, libc++, part 1"
|
||||
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-10 main'
|
||||
key_url: 'https://apt.llvm.org/llvm-snapshot.gpg.key'
|
||||
packages:
|
||||
- clang-10
|
||||
- libc++-10-dev
|
||||
- libc++abi-10-dev
|
||||
env:
|
||||
- CC='clang-10'
|
||||
- CXX='clang++-10 -stdlib=libc++'
|
||||
- CONFIGUREFLAGS='CPPFLAGS=-DNDEBUG CFLAGS=-O3 CXXFLAGS=-O3'
|
||||
- PART=1
|
||||
|
||||
- name: "Clang 9 and libc++"
|
||||
stage: check
|
||||
os: linux
|
||||
dist: bionic
|
||||
@@ -316,9 +357,8 @@ jobs:
|
||||
env:
|
||||
- CC='clang-9'
|
||||
- CXX='clang++-9 -stdlib=libc++'
|
||||
- CONFIGUREFLAGS='CPPFLAGS=-DNDEBUG CFLAGS=-O3 CXXFLAGS=-O3'
|
||||
|
||||
- name: "Clang 8"
|
||||
- name: "Clang 8 and libc++"
|
||||
stage: check
|
||||
os: linux
|
||||
dist: bionic
|
||||
@@ -332,7 +372,7 @@ jobs:
|
||||
- CC=clang-8
|
||||
- CXX='clang++-8 -stdlib=libc++'
|
||||
|
||||
- name: "Clang 7"
|
||||
- name: "Clang 7 and libc++"
|
||||
stage: check
|
||||
os: linux
|
||||
dist: bionic
|
||||
|
||||
@@ -76,6 +76,13 @@ include tests/local.mk
|
||||
clean-local:
|
||||
rm -rf $(CLEANDIRS)
|
||||
|
||||
.PHONY: gitsort
|
||||
gitsort:
|
||||
cd $(srcdir) \
|
||||
&& for i in $$(git ls-files '*.gitignore' | grep -v doc); do \
|
||||
LC_ALL=C sort $$i -o $$i; \
|
||||
done
|
||||
|
||||
# See comments in build-aux/git-version-gen. However, we make .version depend
|
||||
# on configure so that .version and VERSION/PACKAGE_VERSION stay in sync in the
|
||||
# working copy (for example, when you run autoreconf && make). Allowing these
|
||||
|
||||
@@ -1,5 +1,143 @@
|
||||
GNU Bison NEWS
|
||||
|
||||
* Noteworthy changes in release 3.8.2 (2021-09-25) [stable]
|
||||
|
||||
Fixed portability issues of bison on Cygwin.
|
||||
|
||||
Improvements in glr2.cc: add support for custom error messages (`%define
|
||||
parse.error custom`), allow linking several parsers together.
|
||||
|
||||
* Noteworthy changes in release 3.8.1 (2021-09-11) [stable]
|
||||
|
||||
The generation of prototypes for yylex and yyerror in Yacc mode is
|
||||
breaking existing grammar files. To avoid breaking too many grammars, the
|
||||
prototypes are now generated when `-y/--yacc` is used *and* the
|
||||
`POSIXLY_CORRECT` environment variable is defined.
|
||||
|
||||
Avoid using `-y`/`--yacc` simply to comply with Yacc's file name
|
||||
conventions, rather, use `-o y.tab.c`. Autoconf's AC_PROG_YACC macro uses
|
||||
`-y`. Avoid it if possible, for instance by using gnulib's gl_PROG_BISON.
|
||||
|
||||
* Noteworthy changes in release 3.8 (2021-09-07) [stable]
|
||||
|
||||
** Backward incompatible changes
|
||||
|
||||
In conformance with the recommendations of the Graphviz team
|
||||
(https://marc.info/?l=graphviz-devel&m=129418103126092), `-g`/`--graph`
|
||||
now generates a *.gv file by default, instead of *.dot. A transition
|
||||
started in Bison 3.4.
|
||||
|
||||
To comply with the latest POSIX standard, in Yacc compatibility mode
|
||||
(options `-y`/`--yacc`) Bison now generates prototypes for yyerror and
|
||||
yylex. In some situations, this is breaking compatibility: if the user
|
||||
has already declared these functions but with some differences (e.g., to
|
||||
declare them as static, or to use specific attributes), the generated
|
||||
parser will fail to compile. To disable these prototypes, #define yyerror
|
||||
(to `yyerror`), and likewise for yylex.
|
||||
|
||||
** Deprecated features
|
||||
|
||||
Support for the YYPRINT macro is removed. It worked only with yacc.c and
|
||||
only for tokens. It was obsoleted by %printer, introduced in Bison 1.50
|
||||
(November 2002).
|
||||
|
||||
It has always been recommended to prefer `%define api.value.type foo` to
|
||||
`#define YYSTYPE foo`. The latter is supported in C for compatibility
|
||||
with Yacc, but not in C++. Warnings are now issued if `#define YYSTYPE`
|
||||
is used in C++, and eventually support will be removed.
|
||||
|
||||
In C++ code, prefer value_type to semantic_type to denote the semantic
|
||||
value type, which is specified by the `api.value.type` %define variable.
|
||||
|
||||
** New features
|
||||
|
||||
*** A skeleton for the D programming language
|
||||
|
||||
The "lalr1.d" skeleton is now officially part of Bison.
|
||||
|
||||
It was originally contributed by Oliver Mangold, based on Paolo Bonzini's
|
||||
lalr1.java, and was improved by H. S. Teoh. Adela Vais then took over
|
||||
maintenance and invested a lot of efforts to complete, test and document
|
||||
it.
|
||||
|
||||
It now supports all the bells and whistles of the other deterministic
|
||||
parsers, which include: pull/push interfaces, verbose and custom error
|
||||
messages, lookahead correction, token constructors, internationalization,
|
||||
locations, printers, token and symbol prefixes, etc.
|
||||
|
||||
Two examples demonstrate the D parsers: a basic one (examples/d/simple),
|
||||
and an advanced one (examples/d/calc).
|
||||
|
||||
*** Option -H, --header and directive %header
|
||||
|
||||
The option `-H`/`--header` supersedes the option `--defines`, and the
|
||||
directive %header supersedes %defines. Both `--defines` and `%defines`
|
||||
are, of course, maintained for backward compatibility.
|
||||
|
||||
*** Option --html
|
||||
|
||||
Since version 2.4 Bison can be used to generate HTML reports. However it
|
||||
was a two-step process: first bison must be invoked with option `--xml`,
|
||||
and then xsltproc must be run to the convert the XML reports into HTML.
|
||||
|
||||
The new option `--html` combines these steps. The xsltproc program must
|
||||
be available.
|
||||
|
||||
*** A C++ native GLR parser
|
||||
|
||||
A new version of the C++ GLR parser was added: "glr2.cc". It generates
|
||||
"true C++11", instead of a C++ wrapper around a C parser as does the
|
||||
existing "glr.cc" parser. As a first significant consequence, it supports
|
||||
`%define api.value.type variant`, contrary to glr.cc.
|
||||
|
||||
It should be upward compatible in terms of interface, feature and
|
||||
performance to "glr.cc". To try it out, simply use
|
||||
|
||||
%skeleton "glr2.cc"
|
||||
|
||||
It will eventually replace "glr.cc". However we need user feedback on
|
||||
this skeleton. _Please_ report your results and comments about it.
|
||||
|
||||
*** Counterexamples
|
||||
|
||||
Counterexamples now show the rule numbers, and always show ε for rules
|
||||
with an empty right-hand side. For instance
|
||||
|
||||
exp
|
||||
↳ 1: e1 e2 "a"
|
||||
↳ 3: ε • ↳ 1: ε
|
||||
|
||||
instead of
|
||||
|
||||
exp
|
||||
↳ e1 e2 "a"
|
||||
↳ • ↳ ε
|
||||
|
||||
*** Lookahead correction in Java
|
||||
|
||||
The Java skeleton (lalr1.java) now supports LAC, via the `parse.lac`
|
||||
%define variable.
|
||||
|
||||
*** Abort parsing for memory exhaustion (C)
|
||||
|
||||
User actions may now use `YYNOMEM` (similar to `YYACCEPT` and `YYABORT`)
|
||||
to abort the current parse with memory exhaustion.
|
||||
|
||||
*** Printing locations in debug traces (C)
|
||||
|
||||
The `YYLOCATION_PRINT(File, Loc)` macro prints a location. It is defined
|
||||
when (i) locations are enabled, (ii) the default type for locations is
|
||||
used, (iii) debug traces are enabled, and (iv) `YYLOCATION_PRINT` is not
|
||||
already defined.
|
||||
|
||||
Users may define `YYLOCATION_PRINT` to cover other cases.
|
||||
|
||||
*** GLR traces
|
||||
|
||||
There were no debug traces for deferred calls to user actions. They are
|
||||
logged now.
|
||||
|
||||
|
||||
* Noteworthy changes in release 3.7.6 (2021-03-08) [stable]
|
||||
|
||||
** Bug fixes
|
||||
@@ -67,6 +205,7 @@ GNU Bison NEWS
|
||||
skeleton) used to be defined to 1. It is now defined to the version of
|
||||
Bison as an integer (e.g., 30704 for version 3.7.4).
|
||||
|
||||
|
||||
* Noteworthy changes in release 3.7.3 (2020-10-13) [stable]
|
||||
|
||||
** Bug fixes
|
||||
@@ -77,6 +216,7 @@ GNU Bison NEWS
|
||||
|
||||
Fix incorrect use of yytname in glr.cc.
|
||||
|
||||
|
||||
* Noteworthy changes in release 3.7.2 (2020-09-05) [stable]
|
||||
|
||||
This release of Bison fixes all known bugs reported for Bison in MITRE's
|
||||
@@ -777,7 +917,7 @@ GNU Bison NEWS
|
||||
Also, because string aliases need not be defined, typos such as "baz"
|
||||
instead of "bar" will be not reported.
|
||||
|
||||
The option -Wdangling-alias catches these situations. On
|
||||
The option `-Wdangling-alias` catches these situations. On
|
||||
|
||||
%token BAR "bar"
|
||||
%type <ival> foo "foo"
|
||||
@@ -793,7 +933,7 @@ GNU Bison NEWS
|
||||
| foo: "baz" {}
|
||||
| ^~~~~
|
||||
|
||||
The -Wall option does not (yet?) include -Wdangling-alias.
|
||||
The `-Wall` option does not (yet?) include `-Wdangling-alias`.
|
||||
|
||||
*** Better POSIX Yacc compatibility diagnostics
|
||||
|
||||
@@ -4569,7 +4709,7 @@ 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: Heimbigner AST src ast Makefile srcdir MinGW xxlex XXSTYPE CVE
|
||||
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
|
||||
@@ -4580,6 +4720,8 @@ 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 Wcex Nonunifying rcex
|
||||
LocalWords: Vais xsltproc YYNOMEM YYLOCATION signedness YYBISON MITRE's
|
||||
LocalWords: libreadline YYMALLOC YYFREE MSVC redefinitions POSIXLY
|
||||
|
||||
Local Variables:
|
||||
ispell-dictionary: "american"
|
||||
|
||||
@@ -7,7 +7,7 @@ simple desk calculators to complex programming languages.
|
||||
|
||||
Bison is upward compatible with Yacc: all properly-written Yacc grammars
|
||||
work with Bison with no change. Anyone familiar with Yacc should be able to
|
||||
use Bison with little trouble. You need to be fluent in C, C++ or Java
|
||||
use Bison with little trouble. You need to be fluent in C, C++, D or Java
|
||||
programming in order to use Bison.
|
||||
|
||||
Bison and the parsers it generates are portable, they do not require any
|
||||
|
||||
+101
-32
@@ -346,12 +346,14 @@ 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.
|
||||
Because we are standardizing the code, it is currently inconsistent. Treat
|
||||
acronyms as words: `YYLacStack`, not `YYLACStack`.
|
||||
|
||||
Use a 2-space indentation (Google) rather than 4 (Oracle).
|
||||
|
||||
Don't use the "yy" prefix for public members: "getExpectedTokens", not
|
||||
"yyexpectedTokens" or "yygetExpectedTokens".
|
||||
Don't use the `yy` prefix for public members: `getExpectedTokens`, not
|
||||
`yyexpectedTokens` or `yygetExpectedTokens`. Keep the `yy` prefix though
|
||||
for private details.
|
||||
|
||||
## Commit Messages
|
||||
Imitate the style we use. Use `git log` to get sources of inspiration.
|
||||
@@ -386,6 +388,11 @@ In examples/, there is a number of ready-to-use examples (see
|
||||
suites run by `make check`. The test results are in local `*.log` files
|
||||
(e.g., `$build/examples/c/calc/calc.log`).
|
||||
|
||||
To check only the examples, run `make check-examples`. To check just one
|
||||
example,
|
||||
|
||||
make check-examples TESTS='examples/c/bistromathic/bistromathic.test'
|
||||
|
||||
### The Main Test Suite
|
||||
The main test suite, in tests/, is written on top of GNU Autotest, which is
|
||||
part of Autoconf. Run `info autoconf 'Using Autotest'` to read the
|
||||
@@ -399,28 +406,23 @@ contains lots of details that should help diagnosing issues, including build
|
||||
issues. The per-test logs are more convenient when working locally.
|
||||
|
||||
#### TESTSUITEFLAGS
|
||||
To run just the main test suite, run `make check-local`.
|
||||
To run just the main test suite, run `make check-tests`.
|
||||
|
||||
The default is for make check-local to run all tests sequentially. This can
|
||||
be very time consuming when checking repeatedly or on slower setups. This
|
||||
can be sped up in two ways:
|
||||
The default is for `make check-tests` to run all tests sequentially. This
|
||||
can be very time consuming when checking repeatedly or on slower setups.
|
||||
This can be sped up in two ways.
|
||||
|
||||
Using -j, in a make-like fashion, for example:
|
||||
1. Using -j, in a make-like fashion, for example:
|
||||
|
||||
$ make check-local TESTSUITEFLAGS='-j8'
|
||||
$ make check-tests TESTSUITEFLAGS='-j8'
|
||||
|
||||
Actually, when using GNU Make, TESTSUITEFLAGS defaults to the -jN passed to
|
||||
it, so you may simply run
|
||||
When using GNU Make, TESTSUITEFLAGS defaults to the -jN passed to it, so you
|
||||
may simply run
|
||||
|
||||
$ make check-local -j8
|
||||
$ make check-tests -j8
|
||||
|
||||
Running only the tests of a certain category, as specified in the AT files
|
||||
with AT_KEYWORDS([[category]]). Categories include:
|
||||
- c++, for c++ parsers
|
||||
- deprec, for tests concerning deprecated constructs.
|
||||
- glr, for glr parsers
|
||||
- java, for java parsers
|
||||
- report, for automaton dumps
|
||||
2. Running only the tests of a certain category. See
|
||||
[tests/README.md](tests/README.md#keywords) for the list of categories.
|
||||
|
||||
To get a list of all the tests (and their keywords for -k), run
|
||||
|
||||
@@ -428,11 +430,11 @@ To get a list of all the tests (and their keywords for -k), run
|
||||
|
||||
To run a specific set of tests, use -k (for "keyword"). For example:
|
||||
|
||||
$ make check-local TESTSUITEFLAGS='-k c++'
|
||||
$ make check-tests TESTSUITEFLAGS='-k c++'
|
||||
|
||||
Both can be combined.
|
||||
|
||||
$ make check-local TESTSUITEFLAGS='-j8 -k c++'
|
||||
$ make check-tests TESTSUITEFLAGS='-j8 -k c++'
|
||||
|
||||
To rerun the tests that failed:
|
||||
|
||||
@@ -462,28 +464,55 @@ Use the `javaexec.sh` script. For instance to run the parser of test case
|
||||
|
||||
## 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
|
||||
useful. Here's one way to set them 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'
|
||||
```
|
||||
$ ./configure -C --enable-gcc-warnings \
|
||||
CPPFLAGS='-isystem /opt/local/include' \
|
||||
CC='gcc-mp-10 -fsanitize=address -fsanitize=undefined' \
|
||||
CFLAGS='-ggdb' \
|
||||
CXX='g++-mp-10.0 -fsanitize=address -fsanitize=undefined' \
|
||||
CXXFLAGS='-ggdb' \
|
||||
LDFLAGS='-L/opt/local/lib'
|
||||
```
|
||||
|
||||
2. Compile
|
||||
|
||||
3. Generate debug symbols:
|
||||
|
||||
$ dsymutil src/bison
|
||||
```
|
||||
$ dsymutil src/bison
|
||||
```
|
||||
|
||||
4. Run the tests with leak detection enabled
|
||||
(`ASAN_OPTIONS=detect_leaks=1`). E.g. for counterexamples:
|
||||
```
|
||||
$ make check-tests TESTSUITEFLAGS='-j5 -k cex' ASAN_OPTIONS=detect_leaks=1
|
||||
```
|
||||
|
||||
$ make check-local TESTSUITEFLAGS='-j5 -k cex' ASAN_OPTIONS=detect_leaks=1
|
||||
5. You might need a suppression file. See
|
||||
https://github.com/google/sanitizers/wiki/AddressSanitizerLeakSanitizer#suppressions.
|
||||
With G++ on a Mac, you might need a suppression file (say `leak.supp`)
|
||||
that contains:
|
||||
|
||||
```
|
||||
leak:std::clog
|
||||
```
|
||||
|
||||
and pass the additional flags
|
||||
`LSAN_OPTIONS=suppressions=$PWD/leak.supp,print_suppressions=0`
|
||||
|
||||
6. To run the debugger, you might want something like this:
|
||||
```
|
||||
$ YYDEBUG=1 \
|
||||
UBSAN_OPTIONS=print_stacktrace=1 \
|
||||
LSAN_OPTIONS=suppressions=$PWD/leak.supp,print_suppressions=0 \
|
||||
ASAN_OPTIONS=detect_leaks=1 \
|
||||
lldb -- ./_build/tests/testsuite.dir/712/glr-regr2a ./_build/tests/testsuite.dir/712/input1.txt
|
||||
```
|
||||
|
||||
In lldb to set a break on ubsan, try `rbreak ^__ubsan_handle_`.
|
||||
|
||||
## make maintainer-check-valgrind
|
||||
This target uses valgrind both to check bison, and the generated parsers.
|
||||
@@ -560,6 +589,46 @@ re-run the tests, run:
|
||||
make check
|
||||
|
||||
|
||||
## Docker
|
||||
|
||||
Running old compilers is not very easy. Docker can be used for some of
|
||||
them. Have a look at .travis.yml for setups. Move the tarball in `/tmp`
|
||||
and run, for instance:
|
||||
|
||||
```
|
||||
docker run -v /tmp:/tmp -it ubuntu:xenial
|
||||
```
|
||||
|
||||
This way, the host and guest machines share `/tmp`.
|
||||
|
||||
### GCC 4.6
|
||||
On Ubuntu Xenial.
|
||||
|
||||
```
|
||||
apt-get update
|
||||
apt-get install software-properties-common
|
||||
apt-add-repository -y "ppa:ubuntu-toolchain-r/test"
|
||||
apt-get update
|
||||
apt-get install -y gcc-4.6 g++-4.6 m4 make
|
||||
```
|
||||
|
||||
## Stow
|
||||
|
||||
If you want to install several versions of Bison using GNU Stow, do
|
||||
something like this:
|
||||
|
||||
```
|
||||
for v in 3.7 3.7.1
|
||||
do
|
||||
cd /tmp
|
||||
wget https://ftp.gnu.org/gnu/bison/bison-$v.tar.xz
|
||||
tar xf bison-$v.tar.xz
|
||||
cd bison-$v
|
||||
./configure --prefix /usr/local/stow/bison-$v
|
||||
make -j4
|
||||
sudo make install
|
||||
done
|
||||
```
|
||||
|
||||
Release Procedure
|
||||
=================
|
||||
|
||||
@@ -34,6 +34,7 @@ Bob Rossi [email protected]
|
||||
Brandon Lucia [email protected]
|
||||
Brooks Moses [email protected]
|
||||
Bruce Lilly [email protected]
|
||||
Bruno Belanyi [email protected]
|
||||
Bruno Haible [email protected]
|
||||
Charles-Henri de Boysson [email protected]
|
||||
Christian Burger [email protected]
|
||||
|
||||
@@ -1,11 +1,41 @@
|
||||
* Soon
|
||||
** gnulib
|
||||
Bruno notes:
|
||||
** scan-code
|
||||
The default case is scanning char-per-char.
|
||||
|
||||
> I haven't looked deeply, but it strikes me that gnulib/lib/bitset/array.c
|
||||
> does not make use of the 'ffsl' function, nor or the 'integer_length_l'
|
||||
> function. Maybe because in Bison, all bitsets are so dense that it does
|
||||
> not give a performance advantage?
|
||||
/* By default, grow the string obstack with the input. */
|
||||
.|\n STRING_GROW ();
|
||||
|
||||
make it more eager?
|
||||
|
||||
** Missing tests
|
||||
commit 2c294c132528ede23d8ae4959783a67e9ff05ac5
|
||||
Author: Vincent Imbimbo <[email protected]>
|
||||
Date: Sat Jan 23 13:25:18 2021 -0500
|
||||
|
||||
cex: fix state-item pruning
|
||||
|
||||
See https://lists.gnu.org/r/bug-bison/2021-01/msg00002.html
|
||||
|
||||
** pos_set_set
|
||||
The current approach is correct, but with poor performances. Bitsets need
|
||||
to support 'assign' and 'shift'. And instead of extending POS_SET just for
|
||||
the out-of-range new values, we need something like doubling the size.
|
||||
|
||||
** glr
|
||||
There is no test with "Parse on stack %ld rejected by rule %d" in it.
|
||||
|
||||
** yyrline etc.
|
||||
Clarify that rule numbers in the skeletons are 1-based.
|
||||
|
||||
** Macros in C++
|
||||
There are many macros that should obey api.prefix: YY_CPLUSPLUS, YY_MOVE,
|
||||
etc.
|
||||
|
||||
** yyerrok in Java
|
||||
And add tests in calc.at, to prepare work for D.
|
||||
|
||||
** YYERROR and yynerrs
|
||||
We are missing some cases. Write a test case, and check all the skeletons.
|
||||
|
||||
** Cex
|
||||
*** Improve gnulib
|
||||
@@ -66,10 +96,6 @@ enough.
|
||||
*** calc.at
|
||||
Stop hard-coding "Calc". Adjust local.at (look for FIXME).
|
||||
|
||||
** A dev warning for b4_
|
||||
Maybe we should check for m4_ and b4_ leaking out of the m4 processing, as
|
||||
Autoconf does. It would have caught over-quotation issues.
|
||||
|
||||
** doc
|
||||
I feel it's ugly to use the GNU style to declare functions in the doc. It
|
||||
generates tons of white space in the page, and may contribute to bad page
|
||||
@@ -157,10 +183,48 @@ Les catégories d'avertissements incluent :
|
||||
|
||||
Line -1 and -3 should mention CATEGORIE, not CATEGORY.
|
||||
|
||||
* Bison 3.8
|
||||
** Rewrite glr.cc
|
||||
Get rid of scaffolding in glr.c.
|
||||
* Bison 3.9
|
||||
** Rewrite glr.cc (currently glr2.cc)
|
||||
*** custom error messages
|
||||
|
||||
*** Remove jumps
|
||||
We can probably replace setjmp/longjmp with exceptions. That would help
|
||||
tremendously other languages such as D and Java that probably have no
|
||||
similar feature. If we remove jumps, we probably no longer need _Noreturn,
|
||||
so simplify `b4_attribute_define([noreturn])` into `b4_attribute_define`.
|
||||
|
||||
After discussing with Valentin, it was decided that it's better to stay with
|
||||
jumps, since in some places exceptions are ruled out from C++.
|
||||
|
||||
*** Coding style
|
||||
Move to our coding conventions. In particular names such as yy_glr_stack,
|
||||
not yyGLRStack.
|
||||
|
||||
*** yydebug
|
||||
It should be a member of the parser object, see lalr1.cc. Let the parser
|
||||
object decide what the debug stream is, rather than open coding std::cerr.
|
||||
|
||||
*** Avoid pointers
|
||||
There are many places where pointers should be replaced with references.
|
||||
Some occurrences were fixed, but now some have improper names:
|
||||
|
||||
-yygetToken (int *yycharp, ]b4_namespace_ref[::]b4_parser_class[& yyparser][]b4_pure_if([, glr_stack* yystackp])[]b4_user_formals[)
|
||||
+yygetToken (int& yycharp, ]b4_namespace_ref[::]b4_parser_class[& yyparser][]b4_pure_if([, glr_stack* yystackp])[]b4_user_formals[)
|
||||
|
||||
yycharp is no longer a Pointer. And yystackp should probably also be a reference.
|
||||
|
||||
*** parse.assert
|
||||
Currently all the assertions are enabled. Once we are confident in glr2.cc,
|
||||
let parse.assert use the same approach as in lalr1.cc.
|
||||
|
||||
*** debug_stream
|
||||
Stop using std::cerr everywhere.
|
||||
|
||||
*** glr.c
|
||||
When glr2.cc fully replaces glr.cc, get rid of the glr.cc scaffolding in
|
||||
glr.c.
|
||||
|
||||
* Chains
|
||||
** 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.,
|
||||
@@ -215,6 +279,10 @@ functions.
|
||||
states/nstates, rules/nrules, ..., ritem/nritems
|
||||
Fix the latter.
|
||||
|
||||
*** m4: slot, type, type_tag
|
||||
The meaning of type_tag varies depending on api.value.type. We should avoid
|
||||
that and using clear definitions with stable semantics.
|
||||
|
||||
* D programming language
|
||||
There's a number of features that are missing, here sorted in _suggested_
|
||||
order of implementation.
|
||||
@@ -224,240 +292,8 @@ are. Keep the same variable names. If you change the wording in one place,
|
||||
do it in the others too. In other words: make sure to keep the
|
||||
maintenance *simple* by avoiding any gratuitous difference.
|
||||
|
||||
** Rename the D example
|
||||
Move the current content of examples/d into examples/d/simple.
|
||||
|
||||
** Create a second example
|
||||
Duplicate examples/d/simple into examples/d/calc.
|
||||
|
||||
** Add location tracking to d/calc
|
||||
Look at the examples in the other languages to see how to do that.
|
||||
|
||||
** yysymbol_name
|
||||
The SymbolKind is an enum. For a given SymbolKind we want to get its string
|
||||
representation. Currently it's a separate table in the parser that does
|
||||
that:
|
||||
|
||||
/* Symbol kinds. */
|
||||
public enum SymbolKind
|
||||
{
|
||||
S_YYEMPTY = -2, /* No symbol. */
|
||||
S_YYEOF = 0, /* "end of file" */
|
||||
S_YYerror = 1, /* error */
|
||||
S_YYUNDEF = 2, /* "invalid token" */
|
||||
S_EQ = 3, /* "=" */
|
||||
...
|
||||
S_input = 14, /* input */
|
||||
S_line = 15, /* line */
|
||||
S_exp = 16, /* exp */
|
||||
};
|
||||
|
||||
...
|
||||
|
||||
/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
|
||||
First, the terminals, then, starting at \a yyntokens_, nonterminals. */
|
||||
private static immutable string[] yytname_ =
|
||||
[
|
||||
"\"end of file\"", "error", "\"invalid token\"", "\"=\"", "\"+\"",
|
||||
"\"-\"", "\"*\"", "\"/\"", "\"(\"", "\")\"", "\"end of line\"",
|
||||
"\"number\"", "UNARY", "$accept", "input", "line", "exp", null
|
||||
];
|
||||
|
||||
...
|
||||
|
||||
So to get a symbol kind, one runs `yytname_[yykind]`.
|
||||
|
||||
Is there a way to attach this conversion to string to SymbolKind? In Java
|
||||
for instance, we have:
|
||||
|
||||
public enum SymbolKind
|
||||
{
|
||||
S_YYEOF(0), /* "end of file" */
|
||||
S_YYerror(1), /* error */
|
||||
S_YYUNDEF(2), /* "invalid token" */
|
||||
...
|
||||
S_input(16), /* input */
|
||||
S_line(17), /* line */
|
||||
S_exp(18); /* exp */
|
||||
|
||||
private final int yycode_;
|
||||
|
||||
SymbolKind (int n) {
|
||||
this.yycode_ = n;
|
||||
}
|
||||
...
|
||||
/* YYNAMES_[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
|
||||
First, the terminals, then, starting at \a YYNTOKENS_, nonterminals. */
|
||||
private static final String[] yynames_ = yynames_init();
|
||||
private static final String[] yynames_init()
|
||||
{
|
||||
return new String[]
|
||||
{
|
||||
i18n("end of file"), i18n("error"), i18n("invalid token"), "!", "+", "-", "*",
|
||||
"/", "^", "(", ")", "=", i18n("end of line"), i18n("number"), "NEG",
|
||||
"$accept", "input", "line", "exp", null
|
||||
};
|
||||
}
|
||||
|
||||
/* The user-facing name of this symbol. */
|
||||
public final String getName() {
|
||||
return yynames_[yycode_];
|
||||
}
|
||||
};
|
||||
|
||||
which allows to write more naturally `yykind.getName()` rather than
|
||||
`yytname_[yykind]`. Is there something comparable in (idiomatic) D?
|
||||
|
||||
** Change the return value of yylex
|
||||
Historically people were allowed to return any int from the scanner (which
|
||||
is convenient and allows `return '+'` from the scanner). Akim tends to see
|
||||
this as an error, we should restrict the return values to TokenKind (not to
|
||||
be confused with SymbolKind).
|
||||
|
||||
In the case of D, without the history, we have the choice to support or not
|
||||
`int`. If we want to _keep_ `int`, is there a way, say via introspection,
|
||||
to support both signatures of yylex? If we don't keep `int`, just move to
|
||||
TokenKind.
|
||||
|
||||
** Documentation
|
||||
Write documentation about D support in doc/bison.texi. Imitate the Java
|
||||
documentation. You should be more succinct IMHO.
|
||||
|
||||
** Complete Symbols
|
||||
The current interface from the scanner to the parser is somewhat clumsy: the
|
||||
token kind is returned by yylex, but the value and location are stored in
|
||||
the scanner. This reflects the fact that the implementation of the parser
|
||||
uses three variables to deal with each parsed symbol: its kind, its value,
|
||||
its location.
|
||||
|
||||
So today the scanner of examples/d/calc.d (no locations) looks like:
|
||||
|
||||
if (input.front.isNumber)
|
||||
{
|
||||
import std.conv : parse;
|
||||
semanticVal_.ival = input.parse!int;
|
||||
return TokenKind.NUM;
|
||||
}
|
||||
|
||||
and the generated parser:
|
||||
|
||||
/* Read a lookahead token. */
|
||||
if (yychar == TokenKind.YYEMPTY)
|
||||
{
|
||||
yychar = yylex ();
|
||||
yylval = yylexer.semanticVal;
|
||||
}
|
||||
|
||||
The parser class should feature a `Symbol` type which binds together kind,
|
||||
value and location, and the scanner should be able to return an instance of
|
||||
that type. Something like
|
||||
|
||||
if (input.front.isNumber)
|
||||
{
|
||||
import std.conv : parse;
|
||||
return parser.Symbol (TokenKind.NUM, input.parse!int);
|
||||
}
|
||||
|
||||
** Token Constructors
|
||||
In the previous example it is possible to mix incorrectly kinds and values,
|
||||
and for instance:
|
||||
|
||||
return parser.Symbol (TokenKind.NUM, "Hello, World!\n");
|
||||
|
||||
attaches a string value to NUM kind (wrong, of course). When
|
||||
api.token.constructor is set, in C++, Bison generated "token constructors":
|
||||
parser.make_NUM. parser.make_PLUS, parser.make_STRING, etc. The previous
|
||||
example becomes
|
||||
|
||||
return parser.make_NUM ("Hello, World!\n");
|
||||
|
||||
which would easily be caught by the type checker.
|
||||
|
||||
** Lookahead Correction
|
||||
Add support for LAC to the D skeleton. It should not be too hard: look how
|
||||
this is done in lalr1.cc, and mock it.
|
||||
|
||||
** Push Parser
|
||||
Add support for push parser. Do not start a nice skeleton, just enhance the
|
||||
current one to support push parsers. This is going to be a tougher nut to
|
||||
crack.
|
||||
|
||||
First, you need to understand well how the push parser is expected to work.
|
||||
To this end:
|
||||
- read the doc
|
||||
- look at examples/c/pushcalc
|
||||
- create an example of a Java push parser.
|
||||
- have a look at the generated parser in Java, which has the advantage of
|
||||
being already based on a parser object, instead of just a function.
|
||||
|
||||
The C case is harder to read, but it may help too. Keep in mind that
|
||||
because there's no object to maintain state, the C push parser uses some
|
||||
struct (yypstate) to preserve this state. We don't need this in D, the
|
||||
parser object will suffice.
|
||||
|
||||
I think working directly on the skeleton to add push-parser support is not
|
||||
the simplest path. I suggest that you (1) transform a generated parser into
|
||||
a push parser by hand, and then (2) transform lalr1.d to generate such a
|
||||
parser.
|
||||
|
||||
Use `git commit` frequently to make sure you keep track of your progress.
|
||||
|
||||
*** (1.a) Prepare pull parser by hand
|
||||
Copy again one of the D examples into say examples/d/pushcalc. Also
|
||||
check-in the generated parser to facilitate experimentation.
|
||||
|
||||
- find local variables of yyparse should become members of the parser object
|
||||
(so that we preserve state from one call to the next).
|
||||
|
||||
- do it in your generated D parser. We don't need an equivalent for
|
||||
yypstate, because we already have it: that the parser object itself.
|
||||
|
||||
- have your *pull*-parser (i.e., the good old yy::parser::parse()) work
|
||||
properly this way. Write and run tests. That's one of the reasons I
|
||||
suggest using examples/d/calc as a starting point: it already has tests,
|
||||
you can/should add more.
|
||||
|
||||
At this point you have a pull-parser which you prepared to turn into a
|
||||
push-parser.
|
||||
|
||||
*** (1.b) Turn pull parser into push parser by hand
|
||||
|
||||
- look again at how push parsers are implemented in Java/C to see what needs
|
||||
to change in yyparse so that the control is inverted: parse() will
|
||||
be *given* the tokens, instead of having to call yylex itself. When I say
|
||||
"look at C", I think your best option are (i) yacc.c (look for b4_push_if)
|
||||
and (ii) examples/c/pushcalc.
|
||||
|
||||
- rename parse() as push_parse(Symbol yyla) (or push_parse(TokenKind, Value,
|
||||
Location)) that takes the symbol as argument. That's the push parser we
|
||||
are looking for.
|
||||
|
||||
- define a new parse() function which has the same signature as the usual
|
||||
pull-parser, that repeatedly calls the push_parse function. Something
|
||||
like this:
|
||||
|
||||
int parse ()
|
||||
{
|
||||
int status = 0;
|
||||
do {
|
||||
status = this->push_parse (yylex());
|
||||
} while (status == YYPUSH_MORE);
|
||||
return status;
|
||||
}
|
||||
|
||||
- show me that parser, so that we can validate the approach.
|
||||
|
||||
*** (2) Port that into the skeleton
|
||||
- once we agree on the API of the push parser, implement it into lalr1.d.
|
||||
You will probaby need help on this regard, but imitation, again, should
|
||||
help.
|
||||
|
||||
- have example/d/pushcalc work properly and pass tests
|
||||
|
||||
- add tests in the "real" test suite. Do that in tests/calc.at. I can
|
||||
help.
|
||||
|
||||
- document
|
||||
** CI
|
||||
Check when gdc and ldc.
|
||||
|
||||
** GLR Parser
|
||||
This is very ambitious. That's the final boss. There are currently no
|
||||
@@ -498,7 +334,6 @@ define it to the same type as the C ptrdiff_t type.
|
||||
* Completion
|
||||
Several features are not available in all the back-ends.
|
||||
|
||||
- lac: D, Java (easy)
|
||||
- push parsers: glr.c, glr.cc, lalr1.cc (not very difficult)
|
||||
- token constructors: Java, C, D (a bit difficult)
|
||||
- glr: D, Java (super difficult)
|
||||
@@ -513,9 +348,6 @@ $ ./tests/testsuite -l | grep errors | sed q
|
||||
38: input.at:1730 errors
|
||||
|
||||
* Short term
|
||||
** Get rid of YYPRINT and b4_toknum
|
||||
Besides yytoknum is wrong when api.token.raw is defined.
|
||||
|
||||
** Better design for diagnostics
|
||||
The current implementation of diagnostics is ad hoc, it grew organically.
|
||||
It works as a series of calls to several functions, with dependency of the
|
||||
@@ -633,23 +465,6 @@ It would be a very nice source of inspiration for the other languages.
|
||||
|
||||
Valentin Tolmer is working on this.
|
||||
|
||||
** yychar == YYEMPTY
|
||||
The code in yyerrlab reads:
|
||||
|
||||
if (yychar <= YYEOF)
|
||||
{
|
||||
/* Return failure if at end of input. */
|
||||
if (yychar == YYEOF)
|
||||
YYABORT;
|
||||
}
|
||||
|
||||
There are only two yychar that can be <= YYEOF: YYEMPTY and YYEOF.
|
||||
But I can't produce the situation where yychar is YYEMPTY here, is it
|
||||
really possible? The test suite does not exercise this case.
|
||||
|
||||
This shows that it would be interesting to manage to install skeleton
|
||||
coverage analysis to the test suite.
|
||||
|
||||
* From lalr1.cc to yacc.c
|
||||
** Single stack
|
||||
Merging the three stacks in lalr1.cc simplified the code, prompted for
|
||||
@@ -702,6 +517,9 @@ https://github.com/scfc/bison-php/blob/master/data/lalr1.php
|
||||
https://lists.gnu.org/r/bison-patches/2013-09/msg00000.html and following
|
||||
|
||||
** Multiple start symbols
|
||||
Revert a70e75b8a41755ab96ab211a0ea111ac68a4aadd.
|
||||
Revert tests: disable "Multistart reports".
|
||||
|
||||
Would be very useful when parsing closely related languages. The idea is to
|
||||
declare several start symbols, for instance
|
||||
|
||||
@@ -723,6 +541,21 @@ happen with yy_start: stmt | expr). Then adjust the skeletons so that this
|
||||
initial token (YY_START_STMT, YY_START_EXPR) be shifted first in the
|
||||
corresponding parse function.
|
||||
|
||||
*** Number of useless symbols
|
||||
AT_TEST(
|
||||
[[%start exp;
|
||||
exp: exp;]],
|
||||
[[input.y: warning: 2 nonterminals useless in grammar [-Wother]
|
||||
input.y: warning: 2 rules useless in grammar [-Wother]
|
||||
input.y:2.8-10: error: start symbol exp does not derive any sentence]])
|
||||
|
||||
We should say "1 nonterminal": the other one is $accept, which should not
|
||||
participate in the count.
|
||||
|
||||
*** Tokens
|
||||
Do we want to disallow terminal start symbols? The limitation is not
|
||||
technical. Can it be useful to someone to "parse" a token?
|
||||
|
||||
** %include
|
||||
This is a popular demand. We already made many changes in the parser that
|
||||
should make this reasonably easy to implement.
|
||||
@@ -737,7 +570,7 @@ them together, paying attention to keep separate bits separated, in pseudo
|
||||
name spaces.
|
||||
|
||||
** Push parsers
|
||||
There is demand for push parsers in Java and C++. And GLR I guess.
|
||||
There is demand for push parsers in C++.
|
||||
|
||||
** Generate code instead of tables
|
||||
This is certainly quite a lot of work. See
|
||||
@@ -860,8 +693,8 @@ Equip the parser with a means to create the (visual) parse tree.
|
||||
# LocalWords: nterm bitsetv ielr ritem nstates nrules nritems yysymbol EQ
|
||||
# LocalWords: SymbolKind YYEMPTY YYUNDEF YYTNAME NUM yyntokens yytname sed
|
||||
# LocalWords: nonterminals yykind yycode YYNAMES yynames init getName conv
|
||||
# LocalWords: TokenKind semanticVal ival yychar yylval yylexer Tolmer hoc
|
||||
# LocalWords: Sobisch YYPTRDIFF ptrdiff Autotest YYPRINT toknum yytoknum
|
||||
# LocalWords: TokenKind ival yychar yylval yylexer Tolmer hoc
|
||||
# LocalWords: Sobisch YYPTRDIFF ptrdiff Autotest toknum yytoknum
|
||||
# LocalWords: sym Wother stderr FP fixits xgettext fdiagnostics Graphviz
|
||||
# LocalWords: graphviz VCG bitset xml bw maint yytoken YYABORT deps
|
||||
# LocalWords: YYACCEPT yytranslate nonnegative destructors yyerrlab repo
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
#! /bin/sh
|
||||
# Print a version string.
|
||||
scriptversion=2020-04-13.15; # UTC
|
||||
scriptversion=2021-04-11.09; # UTC
|
||||
|
||||
# Bootstrap this package from checked-out sources.
|
||||
|
||||
# Copyright (C) 2003-2020 Free Software Foundation, Inc.
|
||||
# Copyright (C) 2003-2021 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
@@ -47,7 +47,7 @@ PERL="${PERL-perl}"
|
||||
|
||||
me=$0
|
||||
|
||||
default_gnulib_url=git://git.sv.gnu.org/gnulib
|
||||
default_gnulib_url=https://git.savannah.gnu.org/git/gnulib.git
|
||||
|
||||
usage() {
|
||||
cat <<EOF
|
||||
@@ -71,7 +71,9 @@ Options:
|
||||
--no-git do not use git to update gnulib. Requires that
|
||||
--gnulib-srcdir point to a correct gnulib snapshot
|
||||
--skip-po do not download po files
|
||||
|
||||
EOF
|
||||
bootstrap_print_option_usage_hook
|
||||
cat <<EOF
|
||||
If the file $me.conf exists in the same directory as this script, its
|
||||
contents are read as shell variables to configure the bootstrap.
|
||||
|
||||
@@ -113,6 +115,12 @@ Running without arguments will suffice in most cases.
|
||||
EOF
|
||||
}
|
||||
|
||||
copyright_year=`echo "$scriptversion" | sed -e 's/[^0-9].*//'`
|
||||
copyright="Copyright (C) ${copyright_year} Free Software Foundation, Inc.
|
||||
License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>.
|
||||
This is free software: you are free to change and redistribute it.
|
||||
There is NO WARRANTY, to the extent permitted by law."
|
||||
|
||||
# warnf_ FORMAT-STRING ARG1...
|
||||
warnf_ ()
|
||||
{
|
||||
@@ -154,6 +162,18 @@ gnulib_files=
|
||||
: ${AUTOPOINT=autopoint}
|
||||
: ${AUTORECONF=autoreconf}
|
||||
|
||||
# A function to be called for each unrecognized option. Returns 0 if
|
||||
# the option in $1 has been processed by the function. Returns 1 if
|
||||
# the option has not been processed by the function. Override it via
|
||||
# your own definition in bootstrap.conf
|
||||
|
||||
bootstrap_option_hook() { return 1; }
|
||||
|
||||
# A function to be called in order to print the --help information
|
||||
# corresponding to user-defined command-line options.
|
||||
|
||||
bootstrap_print_option_usage_hook() { :; }
|
||||
|
||||
# A function to be called right after gnulib-tool is run.
|
||||
# Override it via your own definition in bootstrap.conf.
|
||||
bootstrap_post_import_hook() { :; }
|
||||
@@ -170,7 +190,7 @@ po_download_command_format=\
|
||||
https://translationproject.org/latest/%s/"
|
||||
|
||||
# Prefer a non-empty tarname (4th argument of AC_INIT if given), else
|
||||
# fall back to the package name (1st argument with munging)
|
||||
# fall back to the package name (1st argument with munging).
|
||||
extract_package_name='
|
||||
/^AC_INIT(\[*/{
|
||||
s///
|
||||
@@ -187,8 +207,11 @@ extract_package_name='
|
||||
p
|
||||
}
|
||||
'
|
||||
package=$(sed -n "$extract_package_name" configure.ac) \
|
||||
|| die 'cannot find package name in configure.ac'
|
||||
package=$(${AUTOCONF:-autoconf} --trace AC_INIT:\$4 configure.ac 2>/dev/null)
|
||||
if test -z "$package"; then
|
||||
package=$(sed -n "$extract_package_name" configure.ac) \
|
||||
|| die 'cannot find package name in configure.ac'
|
||||
fi
|
||||
gnulib_name=lib$package
|
||||
|
||||
build_aux=build-aux
|
||||
@@ -320,6 +343,12 @@ do
|
||||
--help)
|
||||
usage
|
||||
exit;;
|
||||
--version)
|
||||
set -e
|
||||
echo "bootstrap $scriptversion"
|
||||
echo "$copyright"
|
||||
exit 0
|
||||
;;
|
||||
--gnulib-srcdir=*)
|
||||
GNULIB_SRCDIR=${option#--gnulib-srcdir=};;
|
||||
--skip-po)
|
||||
@@ -335,7 +364,7 @@ do
|
||||
--no-git)
|
||||
use_git=false;;
|
||||
*)
|
||||
die "$option: unknown option";;
|
||||
bootstrap_option_hook $option || die "$option: unknown option";;
|
||||
esac
|
||||
done
|
||||
|
||||
|
||||
+4
-3
@@ -22,11 +22,12 @@ gnulib_modules='
|
||||
calloc-posix close closeout config-h c-strcase
|
||||
configmake
|
||||
dirname
|
||||
error extensions
|
||||
error execute extensions
|
||||
fdl fopen-safer fstrcmp
|
||||
getopt-gnu
|
||||
gettext-h git-version-gen gitlog-to-changelog
|
||||
gpl-3.0 intprops inttypes isnan javacomp-script
|
||||
hash-map
|
||||
javaexec-script
|
||||
ldexpl
|
||||
libtextstyle-optional
|
||||
@@ -44,7 +45,7 @@ gnulib_modules='
|
||||
realloc-posix
|
||||
relocatable-prog relocatable-script
|
||||
rename
|
||||
spawn-pipe stdbool stpcpy stpncpy strdup-posix strerror strverscmp
|
||||
spawn-pipe stdbool stpcpy stpncpy strdup-posix strerror strtod strverscmp
|
||||
sys_ioctl
|
||||
termios
|
||||
timevar
|
||||
@@ -58,7 +59,7 @@ gnulib_modules='
|
||||
xconcat-filename
|
||||
xhash
|
||||
xlist
|
||||
xmemdup0
|
||||
xmap xmemdup0
|
||||
xstrndup
|
||||
|
||||
fprintf-posix printf-posix snprintf-posix sprintf-posix
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/announce-gen
|
||||
/compile
|
||||
/config.guess
|
||||
/config.libpath
|
||||
/config.rpath
|
||||
/config.rpath~
|
||||
/config.sub
|
||||
@@ -11,20 +12,19 @@
|
||||
/gitlog-to-changelog
|
||||
/gnu-web-doc-update
|
||||
/gnupload
|
||||
/install-reloc
|
||||
/install-sh
|
||||
/javacomp.sh.in
|
||||
/javaexec.sh.in
|
||||
/libtool-reloc
|
||||
/mdate-sh
|
||||
/missing
|
||||
/prefix-gnulib-mk
|
||||
/reloc-ldflags
|
||||
/relocatable.sh.in
|
||||
/test-driver
|
||||
/texinfo.tex
|
||||
/update-copyright
|
||||
/useless-if-before-free
|
||||
/vc-list-files
|
||||
/ylwrap
|
||||
/config.libpath
|
||||
/install-reloc
|
||||
/reloc-ldflags
|
||||
/relocatable.sh.in
|
||||
/libtool-reloc
|
||||
|
||||
@@ -42,7 +42,7 @@ url_dir_list = \
|
||||
# Tests not to run as part of "make distcheck".
|
||||
local-checks-to-skip = \
|
||||
sc_immutable_NEWS \
|
||||
sc_prohibit_atoi_atof
|
||||
sc_indent
|
||||
|
||||
# The local directory containing the checked-out copy of gnulib used in
|
||||
# this release. Used solely to get a date for the "announcement" target.
|
||||
@@ -156,14 +156,15 @@ exclude = \
|
||||
$(call exclude, \
|
||||
bindtextdomain=^lib/main.c$$ \
|
||||
cast_of_argument_to_free=^src/muscle-tab.c$$ \
|
||||
copyright_check=gnulib/lib/version-etc.c$$ \
|
||||
error_message_uppercase=etc/bench.pl.in$$ \
|
||||
file_system=^doc/Doxyfile.in$$ \
|
||||
po_check=^tests|(^po/POTFILES.in|.md)$$ \
|
||||
preprocessor_indentation=^data/|^lib/|^src/parse-gram.[ch]$$ \
|
||||
program_name=^lib/main.c$$ \
|
||||
prohibit_always-defined_macros=^data/skeletons/yacc.c$$ \
|
||||
prohibit_always-defined_macros+=?|^src/(parse-gram.c|system.h)$$ \
|
||||
prohibit_always-defined_macros+=?|^tests/regression.at$$ \
|
||||
prohibit_atoi_atof=^(doc|etc|examples|tests)/ \
|
||||
prohibit_doubled_word=^tests/named-refs.at$$ \
|
||||
prohibit_magic_number_exit=^doc/bison.texi$$ \
|
||||
prohibit_magic_number_exit+=?|^tests/(conflicts|regression).at$$ \
|
||||
|
||||
+6
-10
@@ -15,12 +15,7 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
# In order for some versions of Sun Studio to compile our C++ test cases
|
||||
# correctly, we need Autoconf 2.64 or better to handle the restrict
|
||||
# keyword in at least string.h from gnulib. We need Autoconf 2.68 or
|
||||
# better to avoid a typo in the 'configure --help' entry for the YACC
|
||||
# environment variable.
|
||||
AC_PREREQ([2.68])
|
||||
AC_PREREQ([2.71])
|
||||
m4_pattern_forbid([^_?(gl_[A-Z]|AX_|BISON_)])
|
||||
m4_pattern_allow([^BISON_USE_NLS$])
|
||||
|
||||
@@ -54,7 +49,7 @@ AM_SILENT_RULES([yes])
|
||||
AC_CONFIG_HEADERS([lib/config.h:lib/config.in.h])
|
||||
|
||||
# Checks for the compiler.
|
||||
AC_PROG_CC_STDC
|
||||
AC_PROG_CC
|
||||
AC_PROG_CXX
|
||||
|
||||
# Gnulib (early checks).
|
||||
@@ -84,7 +79,8 @@ BISON_CXXSTD([03])
|
||||
BISON_CXXSTD([11])
|
||||
BISON_CXXSTD([14])
|
||||
BISON_CXXSTD([17])
|
||||
BISON_CXXSTD([2a])
|
||||
BISON_CXXSTD([20])
|
||||
BISON_CXXSTD([2b])
|
||||
AM_CONDITIONAL([ENABLE_CXX11], [test x"$CXX11_CXXFLAGS" != x])
|
||||
AM_CONDITIONAL([ENABLE_CXX14], [test x"$CXX14_CXXFLAGS" != x])
|
||||
AC_LANG_POP([C++])
|
||||
@@ -133,7 +129,7 @@ if test "$enable_gcc_warnings" = yes; then
|
||||
warn_common='-Wall -Wextra
|
||||
-Wcast-align -Wchar-subscripts
|
||||
-fparse-all-comments -Wdocumentation
|
||||
-Wformat -Wimplicit-fallthrough -Wnull-dereference
|
||||
-Wformat -Wimplicit-fallthrough -Wmismatched-dealloc -Wnull-dereference
|
||||
-Wno-sign-compare -Wno-tautological-constant-out-of-range-compare
|
||||
-Wpointer-arith -Wshadow -Wstrict-aliasing
|
||||
-Wwrite-strings
|
||||
@@ -251,7 +247,7 @@ AM_CONDITIONAL([ENABLE_JAVA], [test x"$CONF_JAVAC" != x && test x"$CONF_JAVA" !=
|
||||
|
||||
|
||||
AC_ARG_ENABLE([yacc],
|
||||
[AC_HELP_STRING([--disable-yacc],
|
||||
[AS_HELP_STRING([--disable-yacc],
|
||||
[do not build a yacc command or an -ly library])],
|
||||
, [enable_yacc=yes])
|
||||
AM_CONDITIONAL([ENABLE_YACC], [test "$enable_yacc" = yes])
|
||||
|
||||
+16
-2
@@ -73,15 +73,29 @@ skeletons. If you are to write a new skeleton, please, implement them for
|
||||
your language. Overall, be sure to follow the same patterns as the existing
|
||||
skeletons.
|
||||
|
||||
## Vocabulary
|
||||
|
||||
We use "formal arguments", or "formals" for short, to denote the declared
|
||||
parameters of a function (e.g., `int argc, const char **argv`). Yes, this
|
||||
is somewhat contradictory with `param` in the `%param` directives.
|
||||
|
||||
We use "effective arguments", or "args" for short, to denote the values
|
||||
passed in function calls (e.g., `argc, argv`).
|
||||
|
||||
## Symbols
|
||||
|
||||
### `b4_symbol(NUM, FIELD)`
|
||||
In order to unify the handling of the various aspects of symbols (tag, type
|
||||
name, whether terminal, etc.), bison.exe defines one macro per (token,
|
||||
field), where field can `has_id`, `id`, etc.: see
|
||||
`prepare_symbols_definitions()` in `src/output.c`.
|
||||
`prepare_symbol_definitions()` in `src/output.c`.
|
||||
|
||||
The macro `b4_symbol(NUM, FIELD)` gives access to the following FIELDS:
|
||||
NUM can be:
|
||||
- `empty` to denote the "empty" pseudo-symbol when it exists,
|
||||
- `eof`, `error`, or `undef`
|
||||
- a symbol number.
|
||||
|
||||
FIELD can be:
|
||||
|
||||
- `has_id`: 0 or 1
|
||||
Whether the symbol has an `id`.
|
||||
|
||||
+1
-1
@@ -28,6 +28,7 @@ dist_skeletons_DATA = \
|
||||
data/skeletons/c.m4 \
|
||||
data/skeletons/glr.c \
|
||||
data/skeletons/glr.cc \
|
||||
data/skeletons/glr2.cc \
|
||||
data/skeletons/java-skel.m4 \
|
||||
data/skeletons/java.m4 \
|
||||
data/skeletons/lalr1.cc \
|
||||
@@ -40,7 +41,6 @@ dist_skeletons_DATA = \
|
||||
|
||||
# Experimental support for the D language.
|
||||
dist_skeletons_DATA += \
|
||||
data/skeletons/README-D.txt \
|
||||
data/skeletons/d-skel.m4 \
|
||||
data/skeletons/d.m4 \
|
||||
data/skeletons/lalr1.d
|
||||
|
||||
@@ -1,60 +0,0 @@
|
||||
Some usage notes for the D Parser:
|
||||
|
||||
- it is a port of the Java parser, so interface is very similar.
|
||||
|
||||
- the lexer class needs to implement the interface 'Lexer' (similar to
|
||||
java). It typically (depending on options) looks like this:
|
||||
|
||||
public interface Lexer
|
||||
{
|
||||
/**
|
||||
* Method to retrieve the beginning position of the last scanned token.
|
||||
* @return the position at which the last scanned token starts. */
|
||||
@property YYPosition startPos ();
|
||||
|
||||
/**
|
||||
* Method to retrieve the ending position of the last scanned token.
|
||||
* @return the first position beyond the last scanned token. */
|
||||
@property YYPosition endPos ();
|
||||
|
||||
/**
|
||||
* Method to retrieve the semantic value of the last scanned token.
|
||||
* @return the semantic value of the last scanned token. */
|
||||
@property YYSemanticType semanticVal ();
|
||||
|
||||
/**
|
||||
* Entry point for the scanner. Returns the token identifier corresponding
|
||||
* to the next token and prepares to return the semantic value
|
||||
* and beginning/ending positions of the token.
|
||||
* @return the token identifier corresponding to the next token. */
|
||||
TokenKind yylex ();
|
||||
|
||||
/**
|
||||
* Entry point for error reporting. Emits an error
|
||||
* referring to the given location in a user-defined way.
|
||||
*
|
||||
* @param loc The location of the element to which the
|
||||
* error message is related
|
||||
* @param s The string for the error message. */
|
||||
void yyerror (YYLocation loc, string s);
|
||||
}
|
||||
|
||||
- semantic types are handled by D unions (same as for C/C++ parsers)
|
||||
|
||||
- the following (non-standard) %defines are supported:
|
||||
|
||||
%define package "<package_name>"
|
||||
%define api.parser.class "my_class_name>"
|
||||
%define position_type "my_position_type"
|
||||
%define location_type "my_location_type"
|
||||
|
||||
- the following declarations basically work like in C/C++:
|
||||
|
||||
%locations
|
||||
%error-verbose
|
||||
%parse-param
|
||||
%initial-action
|
||||
%code
|
||||
%union
|
||||
|
||||
- %destructor is not yet supported
|
||||
+51
-27
@@ -261,6 +261,13 @@ m4_define([b4_fatal_at],
|
||||
[b4_error([[fatal]], $@)dnl
|
||||
m4_exit(1)])
|
||||
|
||||
# b4_canary(MSG)
|
||||
# --------------
|
||||
# Issue a warning on stderr and in the output. Used in the test suite
|
||||
# to catch spurious m4 evaluations.
|
||||
m4_define([b4_canary],
|
||||
[m4_errprintn([dead canary: $1])DEAD CANARY($1)])
|
||||
|
||||
|
||||
## ------------ ##
|
||||
## Data Types. ##
|
||||
@@ -332,14 +339,14 @@ number is the opposite. If YYTABLE_NINF, syntax error.]])
|
||||
$1([check], [b4_check])
|
||||
|
||||
$1([stos], [b4_stos],
|
||||
[[YYSTOS[STATE-NUM] -- The (internal number of the) accessing
|
||||
symbol of state STATE-NUM.]])
|
||||
[[YYSTOS[STATE-NUM] -- The symbol kind of the accessing symbol of
|
||||
state STATE-NUM.]])
|
||||
|
||||
$1([r1], [b4_r1],
|
||||
[[YYR1[YYN] -- Symbol number of symbol that rule YYN derives.]])
|
||||
[[YYR1[RULE-NUM] -- Symbol kind of the left-hand side of rule RULE-NUM.]])
|
||||
|
||||
$1([r2], [b4_r2],
|
||||
[[YYR2[YYN] -- Number of symbols on the right hand side of rule YYN.]])
|
||||
[[YYR2[RULE-NUM] -- Number of symbols on the right-hand side of rule RULE-NUM.]])
|
||||
])
|
||||
|
||||
|
||||
@@ -391,9 +398,9 @@ m4_define([b4_$3_if],
|
||||
# b4_FLAG_if(IF-TRUE, IF-FALSE)
|
||||
# -----------------------------
|
||||
# Expand IF-TRUE, if FLAG is true, IF-FALSE otherwise.
|
||||
b4_define_flag_if([defines]) # Whether headers are requested.
|
||||
b4_define_flag_if([glr]) # Whether a GLR parser is requested.
|
||||
b4_define_flag_if([has_translations]) # Whether some tokens are internationalized.
|
||||
b4_define_flag_if([header]) # Whether a header is requested.
|
||||
b4_define_flag_if([nondeterministic]) # Whether conflicts should be handled.
|
||||
b4_define_flag_if([token_table]) # Whether yytoken_table is demanded.
|
||||
b4_define_flag_if([yacc]) # Whether POSIX Yacc is emulated.
|
||||
@@ -404,6 +411,10 @@ b4_define_flag_if([yacc]) # Whether POSIX Yacc is emulated.
|
||||
m4_define([b4_glr_cc_if],
|
||||
[m4_if(b4_skeleton, ["glr.cc"], $@)])
|
||||
|
||||
# b4_glr2_cc_if([IF-TRUE], [IF-FALSE])
|
||||
# ------------------------------------
|
||||
m4_define([b4_glr2_cc_if],
|
||||
[m4_if(b4_skeleton, ["glr2.cc"], $@)])
|
||||
|
||||
## --------- ##
|
||||
## Symbols. ##
|
||||
@@ -480,16 +491,20 @@ m4_define([b4_symbol_slot],
|
||||
|
||||
# b4_symbol(NUM, FIELD)
|
||||
# ---------------------
|
||||
# Fetch FIELD of symbol #NUM (or "orig NUM"). Fail if undefined.
|
||||
# Fetch FIELD of symbol #NUM (or "orig NUM", or "empty"). Fail if undefined.
|
||||
#
|
||||
# If FIELD = id, prepend the token prefix.
|
||||
m4_define([b4_symbol],
|
||||
[m4_case([$2],
|
||||
[id], [b4_symbol_token_kind([$1])],
|
||||
[kind_base], [b4_symbol_kind_base([$1])],
|
||||
[kind], [b4_symbol_kind([$1])],
|
||||
[slot], [b4_symbol_slot([$1])],
|
||||
[_b4_symbol($@)])])
|
||||
[m4_if([$1], [empty], [b4_symbol([-2], [$2])],
|
||||
[$1], [eof], [b4_symbol([0], [$2])],
|
||||
[$1], [error], [b4_symbol([1], [$2])],
|
||||
[$1], [undef], [b4_symbol([2], [$2])],
|
||||
[m4_case([$2],
|
||||
[id], [b4_symbol_token_kind([$1])],
|
||||
[kind_base], [b4_symbol_kind_base([$1])],
|
||||
[kind], [b4_symbol_kind([$1])],
|
||||
[slot], [b4_symbol_slot([$1])],
|
||||
[_b4_symbol($@)])])])
|
||||
|
||||
|
||||
# b4_symbol_if(NUM, FIELD, IF-TRUE, IF-FALSE)
|
||||
@@ -551,7 +566,7 @@ m4_defn([b4_actions_])[]dnl
|
||||
break;
|
||||
}dnl
|
||||
],
|
||||
[YY_USE (m4_default([$2], [yykind]));])dnl
|
||||
[b4_use(m4_default([$2], [yykind]));])dnl
|
||||
m4_popdef([b4_actions_])dnl
|
||||
])
|
||||
|
||||
@@ -967,15 +982,18 @@ m4_define([b4_percent_define_flag_if],
|
||||
# For example:
|
||||
#
|
||||
# b4_percent_define_default([[foo]], [[default value]])
|
||||
m4_define([_b4_percent_define_define],
|
||||
[m4_define([b4_percent_define(]$1[)], [$2])dnl
|
||||
m4_define([b4_percent_define_kind(]$1[)],
|
||||
[m4_default([$3], [keyword])])dnl
|
||||
m4_define([b4_percent_define_loc(]$1[)],
|
||||
[[[[<skeleton default value>:-1.-1]],
|
||||
[[<skeleton default value>:-1.-1]]]])dnl
|
||||
m4_define([b4_percent_define_syncline(]$1[)], [[]])])
|
||||
|
||||
m4_define([b4_percent_define_default],
|
||||
[_b4_percent_define_ifdef([$1], [],
|
||||
[m4_define([b4_percent_define(]$1[)], [$2])dnl
|
||||
m4_define([b4_percent_define_kind(]$1[)],
|
||||
[m4_default([$3], [keyword])])dnl
|
||||
m4_define([b4_percent_define_loc(]$1[)],
|
||||
[[[[<skeleton default value>:-1.-1]],
|
||||
[[<skeleton default value>:-1.-1]]]])dnl
|
||||
m4_define([b4_percent_define_syncline(]$1[)], [[]])])])
|
||||
[_b4_percent_define_define($@)])])
|
||||
|
||||
|
||||
# b4_percent_define_if_define(NAME, [VARIABLE = NAME])
|
||||
@@ -985,11 +1003,12 @@ m4_define([b4_percent_define_default],
|
||||
# to '_'.
|
||||
m4_define([_b4_percent_define_if_define],
|
||||
[m4_define(m4_bpatsubst([b4_$1_if], [[-.]], [_]),
|
||||
[b4_percent_define_flag_if(m4_default([$2], [$1]),
|
||||
[$3], [$4])])])
|
||||
[b4_percent_define_default([m4_default([$2], [$1])], [[false]])dnl
|
||||
b4_percent_define_flag_if(m4_default([$2], [$1]),
|
||||
[$3], [$4])])])
|
||||
|
||||
m4_define([b4_percent_define_if_define],
|
||||
[b4_percent_define_default([m4_default([$2], [$1])], [[false]])
|
||||
_b4_percent_define_if_define([$1], [$2], $[1], $[2])])
|
||||
[_b4_percent_define_if_define([$1], [$2], $[1], $[2])])
|
||||
|
||||
|
||||
# b4_percent_define_check_kind(VARIABLE, KIND, [DIAGNOSTIC = complain])
|
||||
@@ -1095,6 +1114,7 @@ b4_percent_define_if_define([token_ctor], [api.token.constructor])
|
||||
b4_percent_define_if_define([locations]) # Whether locations are tracked.
|
||||
b4_percent_define_if_define([parse.assert])
|
||||
b4_percent_define_if_define([parse.trace])
|
||||
b4_percent_define_if_define([posix])
|
||||
|
||||
|
||||
# b4_bison_locations_if([IF-TRUE])
|
||||
@@ -1124,14 +1144,18 @@ m4_define([b4_parse_error_bmatch],
|
||||
|
||||
|
||||
|
||||
# b4_union_if([IF-UNION-ARE-USED], [IF-NOT])
|
||||
# b4_variant_if([IF-VARIANT-ARE-USED], [IF-NOT])
|
||||
# ----------------------------------------------
|
||||
b4_percent_define_if_define([variant])
|
||||
# Depend on whether api.value.type is union, or variant.
|
||||
m4_define([b4_union_flag], [[0]])
|
||||
m4_define([b4_variant_flag], [[0]])
|
||||
b4_percent_define_ifdef([[api.value.type]],
|
||||
[m4_case(b4_percent_define_get_kind([[api.value.type]]), [keyword],
|
||||
[m4_case(b4_percent_define_get([[api.value.type]]), [variant],
|
||||
[m4_define([b4_variant_flag], [[1]])])])])
|
||||
[m4_case(b4_percent_define_get([[api.value.type]]),
|
||||
[union], [m4_define([b4_union_flag], [[1]])],
|
||||
[variant], [m4_define([b4_variant_flag], [[1]])])])])
|
||||
b4_define_flag_if([union])
|
||||
b4_define_flag_if([variant])
|
||||
|
||||
|
||||
|
||||
+107
-47
@@ -109,7 +109,6 @@ 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]))
|
||||
|
||||
b4_percent_define_default([[global_tokens_and_yystype]], [[false]])
|
||||
b4_percent_define_default([[define_location_comparison]],
|
||||
[m4_if(b4_percent_define_get([[filename_type]]),
|
||||
[std::string], [[true]], [[false]])])
|
||||
@@ -193,7 +192,7 @@ m4_define([b4_declare_symbol_enum],
|
||||
[[enum symbol_kind_type
|
||||
{
|
||||
YYNTOKENS = ]b4_tokens_number[, ///< Number of tokens.
|
||||
]b4_symbol(-2, kind_base)[ = -2,
|
||||
]b4_symbol(empty, kind_base)[ = -2,
|
||||
]b4_symbol_foreach([ b4_symbol_enum])dnl
|
||||
[ };]])
|
||||
|
||||
@@ -207,16 +206,16 @@ m4_define([b4_declare_symbol_enum],
|
||||
|
||||
# b4_value_type_declare
|
||||
# ---------------------
|
||||
# Declare semantic_type.
|
||||
# Declare value_type.
|
||||
m4_define([b4_value_type_declare],
|
||||
[b4_value_type_setup[]dnl
|
||||
[ /// Symbol semantic values.
|
||||
]m4_bmatch(b4_percent_define_get_kind([[api.value.type]]),
|
||||
[code],
|
||||
[[ typedef ]b4_percent_define_get([[api.value.type]])[ semantic_type;]],
|
||||
[[ typedef ]b4_percent_define_get([[api.value.type]])[ value_type;]],
|
||||
[m4_bmatch(b4_percent_define_get([[api.value.type]]),
|
||||
[union\|union-directive],
|
||||
[[ union semantic_type
|
||||
[[ union value_type
|
||||
{
|
||||
]b4_user_union_members[
|
||||
};]])])dnl
|
||||
@@ -228,11 +227,19 @@ m4_define([b4_value_type_declare],
|
||||
# Define the public types: token, semantic value, location, and so forth.
|
||||
# Depending on %define token_lex, may be output in the header or source file.
|
||||
m4_define([b4_public_types_declare],
|
||||
[[#ifndef ]b4_api_PREFIX[STYPE
|
||||
]b4_value_type_declare[
|
||||
[b4_glr2_cc_if(
|
||||
[b4_value_type_declare],
|
||||
[[#ifdef ]b4_api_PREFIX[STYPE
|
||||
# ifdef __GNUC__
|
||||
# pragma GCC message "bison: do not #define ]b4_api_PREFIX[STYPE in C++, use %define api.value.type"
|
||||
# endif
|
||||
typedef ]b4_api_PREFIX[STYPE value_type;
|
||||
#else
|
||||
typedef ]b4_api_PREFIX[STYPE semantic_type;
|
||||
#endif]b4_locations_if([
|
||||
]b4_value_type_declare[
|
||||
#endif
|
||||
/// Backward compatibility (Bison 3.8).
|
||||
typedef value_type semantic_type;
|
||||
]])[]b4_locations_if([
|
||||
/// Symbol locations.
|
||||
typedef b4_percent_define_get([[api.location.type]],
|
||||
[[location]]) location_type;])[
|
||||
@@ -258,16 +265,16 @@ m4_define([b4_public_types_declare],
|
||||
/// Token kinds.
|
||||
struct token
|
||||
{
|
||||
]b4_token_enums[
|
||||
]b4_token_enums[]b4_glr2_cc_if([], [[
|
||||
/// Backward compatibility alias (Bison 3.6).
|
||||
typedef token_kind_type yytokentype;
|
||||
typedef token_kind_type yytokentype;]])[
|
||||
};
|
||||
|
||||
/// Token kind, as returned by yylex.
|
||||
typedef token::yytokentype token_kind_type;
|
||||
typedef token::token_kind_type token_kind_type;]b4_glr2_cc_if([], [[
|
||||
|
||||
/// Backward compatibility alias (Bison 3.6).
|
||||
typedef token_kind_type token_type;
|
||||
typedef token_kind_type token_type;]])[
|
||||
|
||||
/// Symbol kinds.
|
||||
struct symbol_kind
|
||||
@@ -301,7 +308,7 @@ m4_define([b4_symbol_type_define],
|
||||
typedef Base super_type;
|
||||
|
||||
/// Default constructor.
|
||||
basic_symbol ()
|
||||
basic_symbol () YY_NOEXCEPT
|
||||
: value ()]b4_locations_if([
|
||||
, location ()])[
|
||||
{}
|
||||
@@ -330,7 +337,7 @@ m4_define([b4_symbol_type_define],
|
||||
|
||||
/// Constructor for symbols with semantic value.
|
||||
basic_symbol (typename Base::kind_type t,
|
||||
YY_RVREF (semantic_type) v]b4_locations_if([,
|
||||
YY_RVREF (value_type) v]b4_locations_if([,
|
||||
YY_RVREF (location_type) l])[);
|
||||
]])[
|
||||
/// Destroy the symbol.
|
||||
@@ -339,6 +346,30 @@ m4_define([b4_symbol_type_define],
|
||||
clear ();
|
||||
}
|
||||
|
||||
]b4_glr2_cc_if([[
|
||||
/// Copy assignment.
|
||||
basic_symbol& operator= (const basic_symbol& that)
|
||||
{
|
||||
Base::operator= (that);]b4_variant_if([[
|
||||
]b4_symbol_variant([this->kind ()], [value], [copy],
|
||||
[that.value])], [[
|
||||
value = that.value]])[;]b4_locations_if([[
|
||||
location = that.location;]])[
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// Move assignment.
|
||||
basic_symbol& operator= (basic_symbol&& that)
|
||||
{
|
||||
Base::operator= (std::move (that));]b4_variant_if([[
|
||||
]b4_symbol_variant([this->kind ()], [value], [move],
|
||||
[std::move (that.value)])], [[
|
||||
value = std::move (that.value)]])[;]b4_locations_if([[
|
||||
location = std::move (that.location);]])[
|
||||
return *this;
|
||||
}
|
||||
]])[
|
||||
|
||||
/// Destroy contents, and record that is empty.
|
||||
void clear () YY_NOEXCEPT
|
||||
{]b4_variant_if([[
|
||||
@@ -379,10 +410,10 @@ m4_define([b4_symbol_type_define],
|
||||
std::string name () const YY_NOEXCEPT
|
||||
{
|
||||
return ]b4_parser_class[::symbol_name (this->kind ());
|
||||
}]])[
|
||||
}]])[]b4_glr2_cc_if([], [[
|
||||
|
||||
/// Backward compatibility (Bison 3.6).
|
||||
symbol_kind_type type_get () const YY_NOEXCEPT;
|
||||
symbol_kind_type type_get () const YY_NOEXCEPT;]])[
|
||||
|
||||
/// Whether empty.
|
||||
bool empty () const YY_NOEXCEPT;
|
||||
@@ -391,7 +422,7 @@ m4_define([b4_symbol_type_define],
|
||||
void move (basic_symbol& s);
|
||||
|
||||
/// The semantic value.
|
||||
semantic_type value;]b4_locations_if([
|
||||
value_type value;]b4_locations_if([
|
||||
|
||||
/// The location.
|
||||
location_type location;])[
|
||||
@@ -406,22 +437,30 @@ m4_define([b4_symbol_type_define],
|
||||
/// Type access provider for token (enum) based symbols.
|
||||
struct by_kind
|
||||
{
|
||||
/// Default constructor.
|
||||
by_kind ();
|
||||
|
||||
#if 201103L <= YY_CPLUSPLUS
|
||||
/// Move constructor.
|
||||
by_kind (by_kind&& that);
|
||||
#endif
|
||||
|
||||
/// Copy constructor.
|
||||
by_kind (const by_kind& that);
|
||||
|
||||
/// The symbol kind as needed by the constructor.
|
||||
typedef token_kind_type kind_type;
|
||||
|
||||
/// Default constructor.
|
||||
by_kind () YY_NOEXCEPT;
|
||||
|
||||
#if 201103L <= YY_CPLUSPLUS
|
||||
/// Move constructor.
|
||||
by_kind (by_kind&& that) YY_NOEXCEPT;
|
||||
#endif
|
||||
|
||||
/// Copy constructor.
|
||||
by_kind (const by_kind& that) YY_NOEXCEPT;
|
||||
|
||||
/// Constructor from (external) token numbers.
|
||||
by_kind (kind_type t);
|
||||
by_kind (kind_type t) YY_NOEXCEPT;
|
||||
|
||||
]b4_glr2_cc_if([[
|
||||
/// Copy assignment.
|
||||
by_kind& operator= (const by_kind& that);
|
||||
|
||||
/// Move assignment.
|
||||
by_kind& operator= (by_kind&& that);
|
||||
]])[
|
||||
|
||||
/// Record that this symbol is empty.
|
||||
void clear () YY_NOEXCEPT;
|
||||
@@ -431,18 +470,18 @@ m4_define([b4_symbol_type_define],
|
||||
|
||||
/// The (internal) type number (corresponding to \a type).
|
||||
/// \a empty when empty.
|
||||
symbol_kind_type kind () const YY_NOEXCEPT;
|
||||
symbol_kind_type kind () const YY_NOEXCEPT;]b4_glr2_cc_if([], [[
|
||||
|
||||
/// Backward compatibility (Bison 3.6).
|
||||
symbol_kind_type type_get () const YY_NOEXCEPT;
|
||||
symbol_kind_type type_get () const YY_NOEXCEPT;]])[
|
||||
|
||||
/// The symbol kind.
|
||||
/// \a ]b4_symbol_prefix[YYEMPTY when empty.
|
||||
symbol_kind_type kind_;
|
||||
};
|
||||
};]b4_glr2_cc_if([], [[
|
||||
|
||||
/// Backward compatibility for a private implementation detail (Bison 3.6).
|
||||
typedef by_kind by_type;
|
||||
typedef by_kind by_type;]])[
|
||||
|
||||
/// "External" symbols: returned by the scanner.
|
||||
struct symbol_type : basic_symbol<by_kind>
|
||||
@@ -451,10 +490,10 @@ m4_define([b4_symbol_type_define],
|
||||
typedef basic_symbol<by_kind> super_type;
|
||||
|
||||
/// Empty symbol.
|
||||
symbol_type () {}
|
||||
symbol_type () YY_NOEXCEPT {}
|
||||
|
||||
/// Constructor for valueless symbols, and symbols from each type.
|
||||
]b4_type_foreach([_b4_token_constructor_define])dnl
|
||||
]b4_type_foreach([_b4_symbol_constructor_define])dnl
|
||||
])[};
|
||||
]])
|
||||
|
||||
@@ -488,7 +527,7 @@ m4_define([b4_public_types_define],
|
||||
template <typename Base>
|
||||
]b4_parser_class[::basic_symbol<Base>::basic_symbol (]b4_join(
|
||||
[typename Base::kind_type t],
|
||||
[YY_RVREF (semantic_type) v],
|
||||
[YY_RVREF (value_type) v],
|
||||
b4_locations_if([YY_RVREF (location_type) l]))[)
|
||||
: Base (t)
|
||||
, value (]b4_variant_if([], [YY_MOVE (v)])[)]b4_locations_if([
|
||||
@@ -497,18 +536,20 @@ m4_define([b4_public_types_define],
|
||||
(void) v;
|
||||
]b4_symbol_variant([this->kind ()], [value], [YY_MOVE_OR_COPY], [YY_MOVE (v)])])[}]])[
|
||||
|
||||
]b4_glr2_cc_if([], [[
|
||||
template <typename Base>
|
||||
]b4_parser_class[::symbol_kind_type
|
||||
]b4_parser_class[::basic_symbol<Base>::type_get () const YY_NOEXCEPT
|
||||
{
|
||||
return this->kind ();
|
||||
}
|
||||
]])[
|
||||
|
||||
template <typename Base>
|
||||
bool
|
||||
]b4_parser_class[::basic_symbol<Base>::empty () const YY_NOEXCEPT
|
||||
{
|
||||
return this->kind () == ]b4_symbol(-2, kind)[;
|
||||
return this->kind () == ]b4_symbol(empty, kind)[;
|
||||
}
|
||||
|
||||
template <typename Base>
|
||||
@@ -523,30 +564,47 @@ m4_define([b4_public_types_define],
|
||||
}
|
||||
|
||||
// by_kind.
|
||||
]b4_inline([$1])b4_parser_class[::by_kind::by_kind ()
|
||||
: kind_ (]b4_symbol(-2, kind)[)
|
||||
]b4_inline([$1])b4_parser_class[::by_kind::by_kind () YY_NOEXCEPT
|
||||
: kind_ (]b4_symbol(empty, kind)[)
|
||||
{}
|
||||
|
||||
#if 201103L <= YY_CPLUSPLUS
|
||||
]b4_inline([$1])b4_parser_class[::by_kind::by_kind (by_kind&& that)
|
||||
]b4_inline([$1])b4_parser_class[::by_kind::by_kind (by_kind&& that) YY_NOEXCEPT
|
||||
: kind_ (that.kind_)
|
||||
{
|
||||
that.clear ();
|
||||
}
|
||||
#endif
|
||||
|
||||
]b4_inline([$1])b4_parser_class[::by_kind::by_kind (const by_kind& that)
|
||||
]b4_inline([$1])b4_parser_class[::by_kind::by_kind (const by_kind& that) YY_NOEXCEPT
|
||||
: kind_ (that.kind_)
|
||||
{}
|
||||
|
||||
]b4_inline([$1])b4_parser_class[::by_kind::by_kind (token_kind_type t)
|
||||
]b4_inline([$1])b4_parser_class[::by_kind::by_kind (token_kind_type t) YY_NOEXCEPT
|
||||
: kind_ (yytranslate_ (t))
|
||||
{}
|
||||
|
||||
]b4_glr2_cc_if([[
|
||||
]b4_inline([$1])]b4_parser_class[::by_kind&
|
||||
b4_parser_class[::by_kind::by_kind::operator= (const by_kind& that)
|
||||
{
|
||||
kind_ = that.kind_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
]b4_inline([$1])]b4_parser_class[::by_kind&
|
||||
b4_parser_class[::by_kind::by_kind::operator= (by_kind&& that)
|
||||
{
|
||||
kind_ = that.kind_;
|
||||
that.clear ();
|
||||
return *this;
|
||||
}
|
||||
]])[
|
||||
|
||||
]b4_inline([$1])[void
|
||||
]b4_parser_class[::by_kind::clear () YY_NOEXCEPT
|
||||
{
|
||||
kind_ = ]b4_symbol(-2, kind)[;
|
||||
kind_ = ]b4_symbol(empty, kind)[;
|
||||
}
|
||||
|
||||
]b4_inline([$1])[void
|
||||
@@ -562,17 +620,19 @@ m4_define([b4_public_types_define],
|
||||
return kind_;
|
||||
}
|
||||
|
||||
]b4_glr2_cc_if([], [[
|
||||
]b4_inline([$1])[]b4_parser_class[::symbol_kind_type
|
||||
]b4_parser_class[::by_kind::type_get () const YY_NOEXCEPT
|
||||
{
|
||||
return this->kind ();
|
||||
}
|
||||
]])[
|
||||
]])
|
||||
|
||||
|
||||
# b4_token_constructor_define
|
||||
# ----------------------------
|
||||
# Define symbol constructors for all the value types.
|
||||
# Define make_FOO for all the token kinds.
|
||||
# Use at class-level. Redefined in variant.hh.
|
||||
m4_define([b4_token_constructor_define], [])
|
||||
|
||||
@@ -583,7 +643,7 @@ m4_define([b4_token_constructor_define], [])
|
||||
# sometimes in the cc file.
|
||||
m4_define([b4_yytranslate_define],
|
||||
[ b4_inline([$1])b4_parser_class[::symbol_kind_type
|
||||
]b4_parser_class[::yytranslate_ (int t)
|
||||
]b4_parser_class[::yytranslate_ (int t) YY_NOEXCEPT
|
||||
{
|
||||
]b4_api_token_raw_if(
|
||||
[[ return static_cast<symbol_kind_type> (t);]],
|
||||
@@ -601,7 +661,7 @@ m4_define([b4_yytranslate_define],
|
||||
if (t <= 0)
|
||||
return symbol_kind::]b4_symbol_prefix[YYEOF;
|
||||
else if (t <= code_max)
|
||||
return YY_CAST (symbol_kind_type, translate_table[t]);
|
||||
return static_cast <symbol_kind_type> (translate_table[t]);
|
||||
else
|
||||
return symbol_kind::]b4_symbol_prefix[YYUNDEF;]])[
|
||||
}
|
||||
|
||||
+76
-46
@@ -107,27 +107,32 @@ b4_percent_define_default([[api.symbol.prefix]], [[YYSYMBOL_]])
|
||||
## Pure/impure interfaces. ##
|
||||
## ------------------------ ##
|
||||
|
||||
# b4_lex_formals
|
||||
# --------------
|
||||
# b4_yylex_formals
|
||||
# ----------------
|
||||
# All the yylex formal arguments.
|
||||
# b4_lex_param arrives quoted twice, but we want to keep only one level.
|
||||
m4_define([b4_lex_formals],
|
||||
[b4_pure_if([[[[YYSTYPE *yylvalp]], [[&yylval]]][]dnl
|
||||
b4_locations_if([, [[YYLTYPE *yyllocp], [&yylloc]]])])dnl
|
||||
m4_define([b4_yylex_formals],
|
||||
[b4_pure_if([[[b4_api_PREFIX[STYPE *yylvalp]], [[&yylval]]][]dnl
|
||||
b4_locations_if([, [b4_api_PREFIX[LTYPE *yyllocp], [&yylloc]]])])dnl
|
||||
m4_ifdef([b4_lex_param], [, ]b4_lex_param)])
|
||||
|
||||
|
||||
# b4_lex
|
||||
# ------
|
||||
# b4_yylex
|
||||
# --------
|
||||
# Call yylex.
|
||||
m4_define([b4_lex],
|
||||
[b4_function_call([yylex], [int], b4_lex_formals)])
|
||||
m4_define([b4_yylex],
|
||||
[b4_function_call([yylex], [int], b4_yylex_formals)])
|
||||
|
||||
|
||||
# b4_user_args
|
||||
# ------------
|
||||
m4_define([b4_user_args],
|
||||
[m4_ifset([b4_parse_param], [, b4_args(b4_parse_param)])])
|
||||
[m4_ifset([b4_parse_param], [, b4_user_args_no_comma])])
|
||||
|
||||
# b4_user_args_no_comma
|
||||
# ---------------------
|
||||
m4_define([b4_user_args_no_comma],
|
||||
[m4_ifset([b4_parse_param], [b4_args(b4_parse_param)])])
|
||||
|
||||
|
||||
# b4_user_formals
|
||||
@@ -158,13 +163,20 @@ m4_popdef([$2])dnl
|
||||
m4_popdef([$1])dnl
|
||||
])])
|
||||
|
||||
|
||||
# b4_use(EXPR)
|
||||
# ------------
|
||||
# Pacify the compiler about some maybe unused value.
|
||||
m4_define([b4_use],
|
||||
[YY_USE ($1)])
|
||||
|
||||
# b4_parse_param_use([VAL], [LOC])
|
||||
# --------------------------------
|
||||
# 'YY_USE' VAL, LOC if locations are enabled, and all the parse-params.
|
||||
m4_define([b4_parse_param_use],
|
||||
[m4_ifvaln([$1], [ YY_USE ([$1]);])dnl
|
||||
b4_locations_if([m4_ifvaln([$2], [ YY_USE ([$2]);])])dnl
|
||||
b4_parse_param_for([Decl], [Formal], [ YY_USE (Formal);
|
||||
[m4_ifvaln([$1], [ b4_use([$1]);])dnl
|
||||
b4_locations_if([m4_ifvaln([$2], [ b4_use([$2]);])])dnl
|
||||
b4_parse_param_for([Decl], [Formal], [ b4_use(Formal);
|
||||
])dnl
|
||||
])
|
||||
|
||||
@@ -381,7 +393,7 @@ dnl use C' _Noreturn in C++, to avoid -Wc11-extensions warnings.
|
||||
# elif ((!defined __cplusplus || defined __clang__) \
|
||||
&& (201112 <= (defined __STDC_VERSION__ ? __STDC_VERSION__ : 0) \
|
||||
|| (!defined __STRICT_ANSI__ \
|
||||
&& (__4 < __GNUC__ + (7 <= __GNUC_MINOR__) \
|
||||
&& (4 < __GNUC__ + (7 <= __GNUC_MINOR__) \
|
||||
|| (defined __apple_build_version__ \
|
||||
? 6000000 <= __apple_build_version__ \
|
||||
: 3 < __clang_major__ + (5 <= __clang_minor__))))))
|
||||
@@ -403,12 +415,18 @@ dnl use C' _Noreturn in C++, to avoid -Wc11-extensions warnings.
|
||||
# define YY_USE(E) /* empty */
|
||||
#endif
|
||||
|
||||
#if defined __GNUC__ && ! defined __ICC && 407 <= __GNUC__ * 100 + __GNUC_MINOR__
|
||||
/* Suppress an incorrect diagnostic about yylval being uninitialized. */
|
||||
# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
|
||||
#if defined __GNUC__ && ! defined __ICC && 406 <= __GNUC__ * 100 + __GNUC_MINOR__
|
||||
# if __GNUC__ * 100 + __GNUC_MINOR__ < 407
|
||||
# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
|
||||
_Pragma ("GCC diagnostic push") \
|
||||
_Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")
|
||||
# else
|
||||
# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
|
||||
_Pragma ("GCC diagnostic push") \
|
||||
_Pragma ("GCC diagnostic ignored \"-Wuninitialized\"") \
|
||||
_Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"")
|
||||
# endif
|
||||
# define YY_IGNORE_MAYBE_UNINITIALIZED_END \
|
||||
_Pragma ("GCC diagnostic pop")
|
||||
#else
|
||||
@@ -488,7 +506,7 @@ m4_define([b4_null], [YY_NULLPTR])
|
||||
# -------------------------------------------------------------
|
||||
# Define "yy<TABLE-NAME>" whose contents is CONTENT.
|
||||
m4_define([b4_integral_parser_table_define],
|
||||
[m4_ifvaln([$3], [b4_comment([$3], [ ])])dnl
|
||||
[m4_ifvaln([$3], [b4_comment([$3])])dnl
|
||||
static const b4_int_type_for([$2]) yy$1[[]] =
|
||||
{
|
||||
$2
|
||||
@@ -507,7 +525,7 @@ static const b4_int_type_for([$2]) yy$1[[]] =
|
||||
m4_define([b4_symbol(-2, id)], [b4_api_PREFIX[][EMPTY]])
|
||||
m4_define([b4_symbol(-2, tag)], [[No symbol.]])
|
||||
|
||||
m4_if(b4_symbol(0, id), [YYEOF],
|
||||
m4_if(b4_symbol(eof, id), [YYEOF],
|
||||
[m4_define([b4_symbol(0, id)], [b4_api_PREFIX[][EOF]])])
|
||||
m4_define([b4_symbol(1, id)], [b4_api_PREFIX[][error]])
|
||||
m4_define([b4_symbol(2, id)], [b4_api_PREFIX[][UNDEF]])
|
||||
@@ -524,7 +542,7 @@ m4_define([b4_token_define],
|
||||
# Output the definition of the tokens.
|
||||
m4_define([b4_token_defines],
|
||||
[[/* Token kinds. */
|
||||
#define ]b4_symbol([-2], [id])[ -2
|
||||
#define ]b4_symbol(empty, [id])[ -2
|
||||
]m4_join([
|
||||
], b4_symbol_map([b4_token_define]))
|
||||
])
|
||||
@@ -552,7 +570,7 @@ m4_define([b4_token_enums],
|
||||
# define ]b4_api_PREFIX[TOKENTYPE
|
||||
enum ]b4_api_prefix[tokentype
|
||||
{
|
||||
]b4_symbol([-2], [id])[ = -2,
|
||||
]b4_symbol(empty, [id])[ = -2,
|
||||
]b4_symbol_foreach([b4_token_enum])dnl
|
||||
[ };
|
||||
typedef enum ]b4_api_prefix[tokentype ]b4_api_prefix[token_kind_t;
|
||||
@@ -602,7 +620,7 @@ m4_define([b4_declare_symbol_enum],
|
||||
[[/* Symbol kind. */
|
||||
enum yysymbol_kind_t
|
||||
{
|
||||
]b4_symbol([-2], kind_base)[ = -2,
|
||||
]b4_symbol(empty, [kind_base])[ = -2,
|
||||
]b4_symbol_foreach([b4_symbol_enum])dnl
|
||||
[};
|
||||
typedef enum yysymbol_kind_t yysymbol_kind_t;
|
||||
@@ -644,6 +662,14 @@ m4_define([b4_formal],
|
||||
[$1])
|
||||
|
||||
|
||||
# b4_function_declare(NAME, RETURN-VALUE, [DECL1, NAME1], ...)
|
||||
# ------------------------------------------------------------
|
||||
# Declare the function NAME.
|
||||
m4_define([b4_function_declare],
|
||||
[$2 $1 (b4_formals(m4_shift2($@)));[]dnl
|
||||
])
|
||||
|
||||
|
||||
|
||||
## --------------------- ##
|
||||
## Calling C functions. ##
|
||||
@@ -743,13 +769,6 @@ yy_symbol_value_print (FILE *yyo,
|
||||
]b4_parse_param_use([yyoutput], [yylocationp])dnl
|
||||
[ if (!yyvaluep)
|
||||
return;]
|
||||
dnl glr.c does not feature yytoknum.
|
||||
m4_if(b4_skeleton, ["yacc.c"],
|
||||
[[# ifdef YYPRINT
|
||||
if (yykind < YYNTOKENS)
|
||||
YYPRINT (yyo, yytoknum[yykind], *yyvaluep);
|
||||
# endif
|
||||
]])dnl
|
||||
b4_percent_code_get([[pre-printer]])dnl
|
||||
YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
|
||||
b4_symbol_actions([printer])
|
||||
@@ -770,7 +789,7 @@ yy_symbol_print (FILE *yyo,
|
||||
YYFPRINTF (yyo, "%s %s (",
|
||||
yykind < YYNTOKENS ? "token" : "nterm", yysymbol_name (yykind));
|
||||
|
||||
]b4_locations_if([ YY_LOCATION_PRINT (yyo, *yylocationp);
|
||||
]b4_locations_if([ YYLOCATION_PRINT (yyo, yylocationp);
|
||||
YYFPRINTF (yyo, ": ");
|
||||
])dnl
|
||||
[ yy_symbol_value_print (yyo, yykind, yyvaluep]dnl
|
||||
@@ -957,7 +976,7 @@ struct ]b4_api_PREFIX[LTYPE
|
||||
|
||||
# b4_declare_yylstype
|
||||
# -------------------
|
||||
# Declarations that might either go into the header (if --defines) or
|
||||
# Declarations that might either go into the header (if --header) or
|
||||
# in the parser body. Declare YYSTYPE/YYLTYPE, and yylval/yylloc.
|
||||
m4_define([b4_declare_yylstype],
|
||||
[b4_value_type_define[]b4_locations_if([
|
||||
@@ -1027,17 +1046,24 @@ m4_define([b4_yylloc_default_define],
|
||||
#endif
|
||||
]])
|
||||
|
||||
# b4_yy_location_print_define
|
||||
# ---------------------------
|
||||
# Define YY_LOCATION_PRINT.
|
||||
m4_define([b4_yy_location_print_define],
|
||||
# b4_yylocation_print_define
|
||||
# --------------------------
|
||||
# Define YYLOCATION_PRINT.
|
||||
m4_define([b4_yylocation_print_define],
|
||||
[b4_locations_if([[
|
||||
/* YY_LOCATION_PRINT -- Print the location on the stream.
|
||||
/* YYLOCATION_PRINT -- Print the location on the stream.
|
||||
This macro was not mandated originally: define only if we know
|
||||
we won't break user code: when these are the locations we know. */
|
||||
|
||||
# ifndef YY_LOCATION_PRINT
|
||||
# if defined ]b4_api_PREFIX[LTYPE_IS_TRIVIAL && ]b4_api_PREFIX[LTYPE_IS_TRIVIAL
|
||||
# ifndef YYLOCATION_PRINT
|
||||
|
||||
# if defined YY_LOCATION_PRINT
|
||||
|
||||
/* Temporary convenience wrapper in case some people defined the
|
||||
undocumented and private YY_LOCATION_PRINT macros. */
|
||||
# define YYLOCATION_PRINT(File, Loc) YY_LOCATION_PRINT(File, *(Loc))
|
||||
|
||||
# elif defined ]b4_api_PREFIX[LTYPE_IS_TRIVIAL && ]b4_api_PREFIX[LTYPE_IS_TRIVIAL
|
||||
|
||||
/* Print *YYLOCP on YYO. Private, do not rely on its existence. */
|
||||
|
||||
@@ -1065,19 +1091,23 @@ yy_location_print_ (FILE *yyo, YYLTYPE const * const yylocp)
|
||||
res += YYFPRINTF (yyo, "-%d", end_col);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
# define YY_LOCATION_PRINT(File, Loc) \
|
||||
yy_location_print_ (File, &(Loc))
|
||||
# define YYLOCATION_PRINT yy_location_print_
|
||||
|
||||
/* Temporary convenience wrapper in case some people defined the
|
||||
undocumented and private YY_LOCATION_PRINT macros. */
|
||||
# define YY_LOCATION_PRINT(File, Loc) YYLOCATION_PRINT(File, &(Loc))
|
||||
|
||||
# else
|
||||
# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
|
||||
|
||||
# define YYLOCATION_PRINT(File, Loc) ((void) 0)
|
||||
/* Temporary convenience wrapper in case some people defined the
|
||||
undocumented and private YY_LOCATION_PRINT macros. */
|
||||
# define YY_LOCATION_PRINT YYLOCATION_PRINT
|
||||
|
||||
# endif
|
||||
# endif /* !defined YY_LOCATION_PRINT */]],
|
||||
[[/* This macro is provided for backward compatibility. */
|
||||
# ifndef YY_LOCATION_PRINT
|
||||
# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
|
||||
# endif]])
|
||||
# endif /* !defined YYLOCATION_PRINT */]])
|
||||
])
|
||||
|
||||
# b4_yyloc_default
|
||||
|
||||
+283
-28
@@ -18,24 +18,33 @@
|
||||
# along with this program. If not, see <https://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]).
|
||||
#
|
||||
# Prefix all the output lines with PREFIX.
|
||||
m4_define([_b4_comment],
|
||||
[$2[]m4_bpatsubst(m4_expand([[$1]]), [
|
||||
\(.\)], [
|
||||
$3\1])$4])
|
||||
m4_include(b4_skeletonsdir/[c-like.m4])
|
||||
|
||||
|
||||
# b4_comment(TEXT, [PREFIX])
|
||||
# --------------------------
|
||||
# Put TEXT in comment. Prefix all the output lines with PREFIX.
|
||||
m4_define([b4_comment],
|
||||
[_b4_comment([$1], [$2/* ], [$2 ], [ */])])
|
||||
# b4_symbol_action(SYMBOL-NUM, ACTION)
|
||||
# ------------------------------------
|
||||
# Run the action ACTION ("destructor" or "printer") for SYMBOL-NUM.
|
||||
m4_define([b4_symbol_action],
|
||||
[b4_symbol_if([$1], [has_$2],
|
||||
[b4_dollar_pushdef([yyval],
|
||||
[$1],
|
||||
[],
|
||||
[yyloc])dnl
|
||||
_b4_symbol_case([$1])[]dnl
|
||||
b4_syncline([b4_symbol([$1], [$2_line])], [b4_symbol([$1], [$2_file])])dnl
|
||||
b4_symbol([$1], [$2])
|
||||
b4_syncline([@oline@], [@ofile@])dnl
|
||||
break;
|
||||
|
||||
b4_dollar_popdef[]dnl
|
||||
])])
|
||||
|
||||
|
||||
# b4_use(EXPR)
|
||||
# ------------
|
||||
# Pacify the compiler about some maybe unused value.
|
||||
m4_define([b4_use],
|
||||
[])
|
||||
|
||||
|
||||
# b4_sync_start(LINE, FILE)
|
||||
@@ -58,6 +67,23 @@ m4_define([b4_percent_define_get3],
|
||||
[m4_ifval(m4_quote(b4_percent_define_get([$1])),
|
||||
[$2[]b4_percent_define_get([$1])[]$3], [$4])])
|
||||
|
||||
# b4_percent_define_if_get2(ARG1, ARG2, DEF, NOT)
|
||||
# -----------------------------------------------
|
||||
# Expand to the value of DEF if ARG1 or ARG2 are %define'ed,
|
||||
# otherwise NOT.
|
||||
m4_define([b4_percent_define_if_get2],
|
||||
[m4_ifval(m4_quote(b4_percent_define_get([$1])),
|
||||
[$3], [m4_ifval(m4_quote(b4_percent_define_get([$2])),
|
||||
[$3], [$4])])])
|
||||
|
||||
# b4_percent_define_class_before_interface(CLASS, INTERFACE)
|
||||
# ----------------------------------------------------------
|
||||
# Expand to a ', ' if both a class and an interface have been %define'ed
|
||||
m4_define([b4_percent_define_class_before_interface],
|
||||
[m4_ifval(m4_quote(b4_percent_define_get([$1])),
|
||||
[m4_ifval(m4_quote(b4_percent_define_get([$2])),
|
||||
[, ])])])
|
||||
|
||||
|
||||
# b4_flag_value(BOOLEAN-FLAG)
|
||||
# ---------------------------
|
||||
@@ -78,8 +104,10 @@ b4_percent_define_flag_if([api.parser.public], [public ])dnl
|
||||
b4_percent_define_flag_if([api.parser.abstract], [abstract ])dnl
|
||||
b4_percent_define_flag_if([api.parser.final], [final ])dnl
|
||||
[class ]b4_parser_class[]dnl
|
||||
b4_percent_define_get3([api.parser.extends], [ extends ])dnl
|
||||
b4_percent_define_get3([api.parser.implements], [ implements ])])
|
||||
b4_percent_define_if_get2([api.parser.extends], [api.parser.implements], [ : ])dnl
|
||||
b4_percent_define_get([api.parser.extends])dnl
|
||||
b4_percent_define_class_before_interface([api.parser.extends], [api.parser.implements])dnl
|
||||
b4_percent_define_get([api.parser.implements])])
|
||||
|
||||
|
||||
# b4_lexer_if(TRUE, FALSE)
|
||||
@@ -153,6 +181,7 @@ private static immutable b4_int_type_for([$2])[[]] yy$1_ =
|
||||
## ------------- ##
|
||||
|
||||
m4_define([b4_symbol(-2, id)], [[YYEMPTY]])
|
||||
b4_percent_define_default([[api.token.raw]], [[true]])
|
||||
|
||||
# b4_token_enum(TOKEN-NAME, TOKEN-NUMBER)
|
||||
# ---------------------------------------
|
||||
@@ -167,19 +196,49 @@ m4_define([b4_token_enum],
|
||||
m4_define([b4_token_enums],
|
||||
[/* Token kinds. */
|
||||
public enum TokenKind {
|
||||
]b4_symbol_kind([-2])[ = -2,
|
||||
]b4_symbol(empty, id)[ = -2,
|
||||
b4_symbol_foreach([b4_token_enum])dnl
|
||||
}
|
||||
])
|
||||
|
||||
# b4_symbol_translate(STRING)
|
||||
# ---------------------------
|
||||
# Used by "bison" in the array of symbol names to mark those that
|
||||
# require translation.
|
||||
m4_define([b4_symbol_translate],
|
||||
[[_($1)]])
|
||||
|
||||
|
||||
# _b4_token_constructor_define(SYMBOL-NUM)
|
||||
# ----------------------------------------
|
||||
# Define Symbol.FOO for SYMBOL-NUM.
|
||||
m4_define([_b4_token_constructor_define],
|
||||
[b4_token_visible_if([$1],
|
||||
[[
|
||||
static auto ]b4_symbol([$1], [id])[(]b4_symbol_if([$1], [has_type],
|
||||
[b4_union_if([b4_symbol([$1], [type]],
|
||||
[[typeof(YYSemanticType.]b4_symbol([$1], [type])[]])) [val]])dnl
|
||||
[]b4_locations_if([b4_symbol_if([$1], [has_type], [[, ]])[Location l]])[)
|
||||
{
|
||||
return Symbol(TokenKind.]b4_symbol([$1], [id])[]b4_symbol_if([$1], [has_type],
|
||||
[[, val]])[]b4_locations_if([[, l]])[);
|
||||
}]])])
|
||||
|
||||
# b4_token_constructor_define
|
||||
# ---------------------------
|
||||
# Define Symbol.FOO for each token kind FOO.
|
||||
m4_define([b4_token_constructor_define],
|
||||
[[
|
||||
/* Implementation of token constructors for each symbol type visible to
|
||||
* the user. The code generates static methods that have the same names
|
||||
* as the TokenKinds.
|
||||
*/]b4_symbol_foreach([_b4_token_constructor_define])dnl
|
||||
])
|
||||
|
||||
## -------------- ##
|
||||
## Symbol kinds. ##
|
||||
## -------------- ##
|
||||
|
||||
b4_percent_define_default([[api.symbol.prefix]], [[S_]])
|
||||
|
||||
# b4_symbol_kind(NUM)
|
||||
# -------------------
|
||||
m4_define([b4_symbol_kind],
|
||||
@@ -204,16 +263,46 @@ m4_define([b4_symbol_enum],
|
||||
# to use a signed type, which matters for yytoken.
|
||||
m4_define([b4_declare_symbol_enum],
|
||||
[[ /* Symbol kinds. */
|
||||
public enum SymbolKind
|
||||
struct SymbolKind
|
||||
{
|
||||
]b4_symbol(-2, kind_base)[ = -2, /* No symbol. */
|
||||
enum
|
||||
{
|
||||
]b4_symbol(empty, kind_base)[ = -2, /* No symbol. */
|
||||
]b4_symbol_foreach([b4_symbol_enum])dnl
|
||||
[ };
|
||||
]])])
|
||||
[ }
|
||||
|
||||
private int yycode_;
|
||||
alias yycode_ this;
|
||||
|
||||
this(int code)
|
||||
{
|
||||
yycode_ = code;
|
||||
}
|
||||
|
||||
/* 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. */
|
||||
final void toString(W)(W sink) const
|
||||
if (isOutputRange!(W, char))
|
||||
{
|
||||
immutable string[] yy_sname = @{
|
||||
]b4_symbol_names[
|
||||
@};]b4_has_translations_if([[
|
||||
/* YYTRANSLATABLE[SYMBOL-NUM] -- Whether YY_SNAME[SYMBOL-NUM] is
|
||||
internationalizable. */
|
||||
immutable ]b4_int_type_for([b4_translatable])[[] yytranslatable = @{
|
||||
]b4_translatable[
|
||||
@};]])[
|
||||
|
||||
put(sink, yy_sname[yycode_]);
|
||||
}
|
||||
}
|
||||
]])
|
||||
|
||||
|
||||
|
||||
# b4-case(ID, CODE, [COMMENTS])
|
||||
# b4_case(ID, CODE, [COMMENTS])
|
||||
# -----------------------------
|
||||
m4_define([b4_case], [ case $1:m4_ifval([$3], [ b4_comment([$3])])
|
||||
$2
|
||||
@@ -240,6 +329,109 @@ m4_define([b4_location_type], b4_percent_define_ifdef([[location_type]],[b4_perc
|
||||
m4_define([b4_position_type], b4_percent_define_ifdef([[position_type]],[b4_percent_define_get([[position_type]])],[YYPosition]))
|
||||
|
||||
|
||||
## ---------------- ##
|
||||
## api.value.type. ##
|
||||
## ---------------- ##
|
||||
|
||||
|
||||
# ---------------------- #
|
||||
# api.value.type=union. #
|
||||
# ---------------------- #
|
||||
|
||||
# b4_symbol_type_register(SYMBOL-NUM)
|
||||
# -----------------------------------
|
||||
# Symbol SYMBOL-NUM has a type (for union) instead of a type-tag.
|
||||
# Extend the definition of %union's body (b4_union_members) with a
|
||||
# field of that type, and extend the symbol's "type" field to point to
|
||||
# the field name, instead of the type name.
|
||||
m4_define([b4_symbol_type_register],
|
||||
[m4_define([b4_symbol($1, type_tag)],
|
||||
[b4_symbol_if([$1], [has_id],
|
||||
[b4_symbol([$1], [id])],
|
||||
[yykind_[]b4_symbol([$1], [number])])])dnl
|
||||
m4_append([b4_union_members],
|
||||
m4_expand([m4_format([ %-40s %s],
|
||||
m4_expand([b4_symbol([$1], [type]) b4_symbol([$1], [type_tag]);]),
|
||||
[b4_symbol_tag_comment([$1])])]))
|
||||
])
|
||||
|
||||
|
||||
# b4_type_define_tag(SYMBOL1-NUM, ...)
|
||||
# ------------------------------------
|
||||
# For the batch of symbols SYMBOL1-NUM... (which all have the same
|
||||
# type), enhance the %union definition for each of them, and set
|
||||
# there "type" field to the field tag name, instead of the type name.
|
||||
m4_define([b4_type_define_tag],
|
||||
[b4_symbol_if([$1], [has_type],
|
||||
[m4_map([b4_symbol_type_register], [$@])])
|
||||
])
|
||||
|
||||
|
||||
# b4_symbol_value_union(VAL, SYMBOL-NUM, [TYPE])
|
||||
# ----------------------------------------------
|
||||
# Same of b4_symbol_value, but when api.value.type=union.
|
||||
m4_define([b4_symbol_value_union],
|
||||
[m4_ifval([$3],
|
||||
[(*($3*)(&$1))],
|
||||
[m4_ifval([$2],
|
||||
[b4_symbol_if([$2], [has_type],
|
||||
[($1.b4_symbol([$2], [type_tag]))],
|
||||
[$1])],
|
||||
[$1])])])
|
||||
|
||||
|
||||
# b4_value_type_setup_union
|
||||
# -------------------------
|
||||
# Setup support for api.value.type=union. Symbols are defined with a
|
||||
# type instead of a union member name: build the corresponding union,
|
||||
# and give the symbols their tag.
|
||||
m4_define([b4_value_type_setup_union],
|
||||
[m4_define([b4_union_members])
|
||||
b4_type_foreach([b4_type_define_tag])
|
||||
m4_copy_force([b4_symbol_value_union], [b4_symbol_value])
|
||||
])
|
||||
|
||||
|
||||
# _b4_value_type_setup_keyword
|
||||
# ----------------------------
|
||||
# api.value.type is defined with a keyword/string syntax. Check if
|
||||
# that is properly defined, and prepare its use.
|
||||
m4_define([_b4_value_type_setup_keyword],
|
||||
[b4_percent_define_check_values([[[[api.value.type]],
|
||||
[[none]],
|
||||
[[union]],
|
||||
[[union-directive]],
|
||||
[[yystype]]]])dnl
|
||||
m4_case(b4_percent_define_get([[api.value.type]]),
|
||||
[union], [b4_value_type_setup_union])])
|
||||
|
||||
|
||||
# b4_value_type_setup
|
||||
# -------------------
|
||||
# Check if api.value.type is properly defined, and possibly prepare
|
||||
# its use.
|
||||
b4_define_silent([b4_value_type_setup],
|
||||
[
|
||||
# Define default value.
|
||||
b4_percent_define_ifdef([[api.value.type]], [],
|
||||
[# %union => api.value.type=union-directive
|
||||
m4_ifdef([b4_union_members],
|
||||
[m4_define([b4_percent_define_kind(api.value.type)], [keyword])
|
||||
m4_define([b4_percent_define(api.value.type)], [union-directive])],
|
||||
[# no tag seen => api.value.type={int}
|
||||
m4_if(b4_tag_seen_flag, 0,
|
||||
[m4_define([b4_percent_define_kind(api.value.type)], [code])
|
||||
m4_define([b4_percent_define(api.value.type)], [int])],
|
||||
[# otherwise api.value.type=yystype
|
||||
m4_define([b4_percent_define_kind(api.value.type)], [keyword])
|
||||
m4_define([b4_percent_define(api.value.type)], [yystype])])])])
|
||||
|
||||
# Set up.
|
||||
m4_bmatch(b4_percent_define_get_kind([[api.value.type]]),
|
||||
[keyword], [_b4_value_type_setup_keyword])
|
||||
])
|
||||
|
||||
|
||||
## ----------------- ##
|
||||
## Semantic Values. ##
|
||||
## ----------------- ##
|
||||
@@ -286,7 +478,7 @@ m4_define([b4_lhs_location],
|
||||
# Expansion of @POS, where the current rule has RULE-LENGTH symbols
|
||||
# on RHS.
|
||||
m4_define([b4_rhs_location],
|
||||
[yystack.locationAt ([$1], [$2])])
|
||||
[yystack.locationAt (b4_subtract($@))])
|
||||
|
||||
|
||||
# b4_lex_param
|
||||
@@ -371,3 +563,66 @@ m4_define([b4_var_decls],
|
||||
], [$@])])
|
||||
m4_define([b4_var_decl],
|
||||
[ protected $1;])
|
||||
|
||||
|
||||
# b4_public_types_declare
|
||||
# -----------------------
|
||||
# Define the public types: token, semantic value, location, and so forth.
|
||||
# Depending on %define token_lex, may be output in the header or source file.
|
||||
m4_define([b4_public_types_declare],
|
||||
[[
|
||||
alias Symbol = ]b4_parser_class[.Symbol;
|
||||
alias Value = ]b4_yystype[;]b4_locations_if([[
|
||||
alias Location = ]b4_location_type[;
|
||||
alias Position = ]b4_position_type[;]b4_push_if([[
|
||||
alias PUSH_MORE = ]b4_parser_class[.YYPUSH_MORE;
|
||||
alias ABORT = ]b4_parser_class[.YYABORT;
|
||||
alias ACCEPT = ]b4_parser_class[.YYACCEPT;]])[]])[
|
||||
]])
|
||||
|
||||
|
||||
# b4_basic_symbol_constructor_define
|
||||
# ----------------------------------
|
||||
# Create Symbol struct constructors for all the visible types.
|
||||
m4_define([b4_basic_symbol_constructor_define],
|
||||
[b4_token_visible_if([$1],
|
||||
[[ this(TokenKind token]b4_symbol_if([$1], [has_type],
|
||||
[[, ]b4_union_if([], [[typeof(YYSemanticType.]])b4_symbol([$1], [type])dnl
|
||||
[]b4_union_if([], [[) ]])[ val]])[]b4_locations_if([[, Location loc]])[)
|
||||
{
|
||||
kind = yytranslate_(token);]b4_union_if([b4_symbol_if([$1], [has_type], [[
|
||||
static foreach (member; __traits(allMembers, YYSemanticType))
|
||||
{
|
||||
static if (is(typeof(mixin("value_." ~ member)) == ]b4_symbol([$1], [type])[))
|
||||
{
|
||||
mixin("value_." ~ member ~ " = val;");
|
||||
}
|
||||
}]])], [b4_symbol_if([$1], [has_type], [[
|
||||
value_.]b4_symbol([$1], [type])[ = val;]])])[]b4_locations_if([
|
||||
location_ = loc;])[
|
||||
}
|
||||
]])])
|
||||
|
||||
|
||||
# b4_symbol_type_define
|
||||
# ---------------------
|
||||
# Define symbol_type, the external type for symbols used for symbol
|
||||
# constructors.
|
||||
m4_define([b4_symbol_type_define],
|
||||
[[
|
||||
/**
|
||||
* A complete symbol
|
||||
*/
|
||||
struct Symbol
|
||||
{
|
||||
private SymbolKind kind;
|
||||
private Value value_;]b4_locations_if([[
|
||||
private Location location_;]])[
|
||||
|
||||
]b4_type_foreach([b4_basic_symbol_constructor_define])[
|
||||
SymbolKind token() { return kind; }
|
||||
Value value() { return value_; }]b4_locations_if([[
|
||||
Location location() { return location_; }]])[
|
||||
]b4_token_ctor_if([b4_token_constructor_define])[
|
||||
}
|
||||
]])
|
||||
|
||||
+144
-130
@@ -32,7 +32,9 @@ m4_if(b4_skeleton, ["glr.c"],
|
||||
m4_define_default([b4_stack_depth_max], [10000])
|
||||
m4_define_default([b4_stack_depth_init], [200])
|
||||
|
||||
|
||||
# Included header.
|
||||
b4_percent_define_default([[api.header.include]],
|
||||
[["@basename(]b4_spec_header_file[@)"]])
|
||||
|
||||
## ------------------------ ##
|
||||
## Pure/impure interfaces. ##
|
||||
@@ -122,7 +124,7 @@ m4_define([b4_rhs_data],
|
||||
# --------------------------------------------------
|
||||
# Expansion of $$ or $<TYPE>$, for symbol SYMBOL-NUM.
|
||||
m4_define([b4_rhs_value],
|
||||
[b4_symbol_value([b4_rhs_data([$1], [$2]).yysemantics.yysval], [$3], [$4])])
|
||||
[b4_symbol_value([b4_rhs_data([$1], [$2]).yysemantics.yyval], [$3], [$4])])
|
||||
|
||||
|
||||
|
||||
@@ -160,7 +162,7 @@ m4_define([b4_call_merger],
|
||||
|
||||
# b4_shared_declarations
|
||||
# ----------------------
|
||||
# Declaration that might either go into the header (if --defines)
|
||||
# Declaration that might either go into the header (if --header)
|
||||
# or open coded in the parser body. glr.cc has its own definition.
|
||||
m4_if(b4_skeleton, ["glr.c"],
|
||||
[m4_define([b4_shared_declarations],
|
||||
@@ -194,7 +196,7 @@ int ]b4_prefix[parse (]m4_ifset([b4_parse_param], [b4_formals(b4_parse_param)],
|
||||
|
||||
# glr.cc produces its own header.
|
||||
b4_glr_cc_if([],
|
||||
[b4_defines_if(
|
||||
[b4_header_if(
|
||||
[b4_output_begin([b4_spec_header_file])
|
||||
b4_copyright([Skeleton interface for Bison GLR parsers in C],
|
||||
[2002-2015, 2018-2021])[
|
||||
@@ -237,8 +239,8 @@ b4_copyright([Skeleton implementation for Bison GLR parsers in C],
|
||||
]b4_cast_define[
|
||||
]b4_null_define[
|
||||
|
||||
]b4_defines_if([[#include "@basename(]b4_spec_header_file[@)"]],
|
||||
[b4_shared_declarations])[
|
||||
]b4_header_if([[#include ]b4_percent_define_get([[api.header.include]])],
|
||||
[b4_shared_declarations])[
|
||||
|
||||
]b4_glr_cc_if([b4_glr_cc_setup],
|
||||
[b4_declare_symbol_enum])[
|
||||
@@ -440,7 +442,7 @@ int yychar;])[
|
||||
|
||||
enum { YYENOMEM = -2 };
|
||||
|
||||
typedef enum { yyok, yyaccept, yyabort, yyerr } YYRESULTTAG;
|
||||
typedef enum { yyok, yyaccept, yyabort, yyerr, yynomem } YYRESULTTAG;
|
||||
|
||||
#define YYCHK(YYE) \
|
||||
do { \
|
||||
@@ -505,10 +507,11 @@ typedef struct yySemanticOption yySemanticOption;
|
||||
typedef union yyGLRStackItem yyGLRStackItem;
|
||||
typedef struct yyGLRStack yyGLRStack;
|
||||
|
||||
struct yyGLRState {
|
||||
struct yyGLRState
|
||||
{
|
||||
/** Type tag: always true. */
|
||||
yybool yyisState;
|
||||
/** Type tag for yysemantics. If true, yysval applies, otherwise
|
||||
/** Type tag for yysemantics. If true, yyval applies, otherwise
|
||||
* yyfirstVal applies. */
|
||||
yybool yyresolved;
|
||||
/** Number of corresponding LALR(1) machine state. */
|
||||
@@ -523,24 +526,26 @@ struct yyGLRState {
|
||||
* yynext. */
|
||||
yySemanticOption* yyfirstVal;
|
||||
/** Semantic value for this state. */
|
||||
YYSTYPE yysval;
|
||||
YYSTYPE yyval;
|
||||
} yysemantics;]b4_locations_if([[
|
||||
/** Source location for this state. */
|
||||
YYLTYPE yyloc;]])[
|
||||
};
|
||||
|
||||
struct yyGLRStateSet {
|
||||
struct yyGLRStateSet
|
||||
{
|
||||
yyGLRState** yystates;
|
||||
/** During nondeterministic operation, yylookaheadNeeds tracks which
|
||||
* stacks have actually needed the current lookahead. During deterministic
|
||||
* operation, yylookaheadNeeds[0] is not maintained since it would merely
|
||||
* duplicate yychar != ]b4_symbol(-2, id)[. */
|
||||
* duplicate yychar != ]b4_symbol(empty, id)[. */
|
||||
yybool* yylookaheadNeeds;
|
||||
YYPTRDIFF_T yysize;
|
||||
YYPTRDIFF_T yycapacity;
|
||||
};
|
||||
|
||||
struct yySemanticOption {
|
||||
struct yySemanticOption
|
||||
{
|
||||
/** Type tag: always false. */
|
||||
yybool yyisState;
|
||||
/** Rule number for this reduction */
|
||||
@@ -646,6 +651,13 @@ yysymbol_name (yysymbol_kind_t yysymbol)
|
||||
}]])[
|
||||
#endif
|
||||
|
||||
/** Left-hand-side symbol for rule #YYRULE. */
|
||||
static inline yysymbol_kind_t
|
||||
yylhsNonterm (yyRuleNum yyrule)
|
||||
{
|
||||
return YY_CAST (yysymbol_kind_t, yyr1[yyrule]);
|
||||
}
|
||||
|
||||
#if ]b4_api_PREFIX[DEBUG
|
||||
|
||||
# ifndef YYFPRINTF
|
||||
@@ -671,7 +683,7 @@ yysymbol_name (yysymbol_kind_t yysymbol)
|
||||
YY_IGNORE_USELESS_CAST_END \
|
||||
} while (0)
|
||||
|
||||
]b4_yy_location_print_define[
|
||||
]b4_yylocation_print_define[
|
||||
|
||||
]b4_yy_symbol_print_define[
|
||||
|
||||
@@ -685,6 +697,16 @@ yysymbol_name (yysymbol_kind_t yysymbol)
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
static inline void
|
||||
yy_reduce_print (yybool yynormal, yyGLRStackItem* yyvsp, YYPTRDIFF_T yyk,
|
||||
yyRuleNum yyrule]b4_user_formals[);
|
||||
|
||||
# define YY_REDUCE_PRINT(Args) \
|
||||
do { \
|
||||
if (yydebug) \
|
||||
yy_reduce_print Args; \
|
||||
} while (0)
|
||||
|
||||
/* Nonzero means print parse trace. It is left uninitialized so that
|
||||
multiple parsers can coexist. */
|
||||
int yydebug;
|
||||
@@ -698,6 +720,7 @@ static void yypdumpstack (yyGLRStack* yystackp)
|
||||
|
||||
# define YY_DPRINTF(Args) do {} while (yyfalse)
|
||||
# define YY_SYMBOL_PRINT(Title, Kind, Value, Location)
|
||||
# define YY_REDUCE_PRINT(Args)
|
||||
|
||||
#endif /* !]b4_api_PREFIX[DEBUG */
|
||||
|
||||
@@ -800,9 +823,9 @@ yyfillin (yyGLRStackItem *yyvsp, int yylow0, int yylow1)
|
||||
#endif
|
||||
yyvsp[i].yystate.yyresolved = s->yyresolved;
|
||||
if (s->yyresolved)
|
||||
yyvsp[i].yystate.yysemantics.yysval = s->yysemantics.yysval;
|
||||
yyvsp[i].yystate.yysemantics.yyval = s->yysemantics.yyval;
|
||||
else
|
||||
/* The effect of using yysval or yyloc (in an immediate rule) is
|
||||
/* The effect of using yyval or yyloc (in an immediate rule) is
|
||||
* undefined. */
|
||||
yyvsp[i].yystate.yysemantics.yyfirstVal = YY_NULLPTR;]b4_locations_if([[
|
||||
yyvsp[i].yystate.yyloc = s->yyloc;]])[
|
||||
@@ -818,14 +841,14 @@ yygetToken (int *yycharp][]b4_pure_if([, yyGLRStack* yystackp])[]b4_user_formals
|
||||
{
|
||||
yysymbol_kind_t yytoken;
|
||||
]b4_parse_param_use()dnl
|
||||
[ if (*yycharp == ]b4_symbol(-2, id)[)
|
||||
[ if (*yycharp == ]b4_symbol(empty, id)[)
|
||||
{
|
||||
YY_DPRINTF ((stderr, "Reading a token\n"));]b4_glr_cc_if([[
|
||||
#if YY_EXCEPTIONS
|
||||
try
|
||||
{
|
||||
#endif // YY_EXCEPTIONS
|
||||
*yycharp = ]b4_lex[;
|
||||
*yycharp = ]b4_yylex[;
|
||||
#if YY_EXCEPTIONS
|
||||
}
|
||||
catch (const ]b4_namespace_ref[::]b4_parser_class[::syntax_error& yyexc)
|
||||
@@ -836,14 +859,14 @@ yygetToken (int *yycharp][]b4_pure_if([, yyGLRStack* yystackp])[]b4_user_formals
|
||||
// Map errors caught in the scanner to the undefined token,
|
||||
// so that error handling is started. However, record this
|
||||
// with this special value of yychar.
|
||||
*yycharp = ]b4_symbol(1, id)[;
|
||||
*yycharp = ]b4_symbol(error, id)[;
|
||||
}
|
||||
#endif // YY_EXCEPTIONS]], [[
|
||||
*yycharp = ]b4_lex[;]])[
|
||||
*yycharp = ]b4_yylex[;]])[
|
||||
}
|
||||
if (*yycharp <= ]b4_symbol(0, [id])[)
|
||||
if (*yycharp <= ]b4_symbol(eof, [id])[)
|
||||
{
|
||||
*yycharp = ]b4_symbol(0, [id])[;
|
||||
*yycharp = ]b4_symbol(eof, [id])[;
|
||||
yytoken = ]b4_symbol_prefix[YYEOF;
|
||||
YY_DPRINTF ((stderr, "Now at end of input.\n"));
|
||||
}
|
||||
@@ -875,28 +898,31 @@ yyfill (yyGLRStackItem *yyvsp, int *yylow, int yylow1, yybool yynormal)
|
||||
* and top stack item YYVSP. YYLVALP points to place to put semantic
|
||||
* value ($$), and yylocp points to place for location information
|
||||
* (@@$). Returns yyok for normal return, yyaccept for YYACCEPT,
|
||||
* yyerr for YYERROR, yyabort for YYABORT. */
|
||||
* yyerr for YYERROR, yyabort for YYABORT, yynomem for YYNOMEM. */
|
||||
static YYRESULTTAG
|
||||
yyuserAction (yyRuleNum yyn, int yyrhslen, yyGLRStackItem* yyvsp,
|
||||
yyGLRStack* yystackp,
|
||||
yyuserAction (yyRuleNum yyrule, int yyrhslen, yyGLRStackItem* yyvsp,
|
||||
yyGLRStack* yystackp, YYPTRDIFF_T yyk,
|
||||
YYSTYPE* yyvalp]b4_locuser_formals[)
|
||||
{
|
||||
yybool yynormal YY_ATTRIBUTE_UNUSED = yystackp->yysplitPoint == YY_NULLPTR;
|
||||
int yylow;
|
||||
const yybool yynormal YY_ATTRIBUTE_UNUSED = yystackp->yysplitPoint == YY_NULLPTR;
|
||||
int yylow = 1;
|
||||
]b4_parse_param_use([yyvalp], [yylocp])dnl
|
||||
[ YY_USE (yyrhslen);
|
||||
[ YY_USE (yyk);
|
||||
YY_USE (yyrhslen);
|
||||
# undef yyerrok
|
||||
# define yyerrok (yystackp->yyerrState = 0)
|
||||
# undef YYACCEPT
|
||||
# define YYACCEPT return yyaccept
|
||||
# undef YYABORT
|
||||
# define YYABORT return yyabort
|
||||
# undef YYNOMEM
|
||||
# define YYNOMEM return yynomem
|
||||
# undef YYERROR
|
||||
# define YYERROR return yyerrok, yyerr
|
||||
# undef YYRECOVERING
|
||||
# define YYRECOVERING() (yystackp->yyerrState != 0)
|
||||
# undef yyclearin
|
||||
# define yyclearin (yychar = ]b4_symbol(-2, id)[)
|
||||
# define yyclearin (yychar = ]b4_symbol(empty, id)[)
|
||||
# undef YYFILL
|
||||
# define YYFILL(N) yyfill (yyvsp, &yylow, (N), yynormal)
|
||||
# undef YYBACKUP
|
||||
@@ -904,21 +930,23 @@ yyuserAction (yyRuleNum yyn, int yyrhslen, yyGLRStackItem* yyvsp,
|
||||
return yyerror (]b4_yyerror_args[YY_("syntax error: cannot back up")), \
|
||||
yyerrok, yyerr
|
||||
|
||||
yylow = 1;
|
||||
if (yyrhslen == 0)
|
||||
*yyvalp = yyval_default;
|
||||
else
|
||||
*yyvalp = yyvsp[YYFILL (1-yyrhslen)].yystate.yysemantics.yysval;]b4_locations_if([[
|
||||
*yyvalp = yyvsp[YYFILL (1-yyrhslen)].yystate.yysemantics.yyval;]b4_locations_if([[
|
||||
/* Default location. */
|
||||
YYLLOC_DEFAULT ((*yylocp), (yyvsp - yyrhslen), yyrhslen);
|
||||
yystackp->yyerror_range[1].yystate.yyloc = *yylocp;
|
||||
]])[]b4_glr_cc_if([[
|
||||
yystackp->yyerror_range[1].yystate.yyloc = *yylocp;]])[
|
||||
/* If yyk == -1, we are running a deferred action on a temporary
|
||||
stack. In that case, YY_REDUCE_PRINT must not play with YYFILL,
|
||||
so pretend the stack is "normal". */
|
||||
YY_REDUCE_PRINT ((yynormal || yyk == -1, yyvsp, yyk, yyrule]b4_user_args[));]b4_glr_cc_if([[
|
||||
#if YY_EXCEPTIONS
|
||||
typedef ]b4_namespace_ref[::]b4_parser_class[::syntax_error syntax_error;
|
||||
try
|
||||
{
|
||||
#endif // YY_EXCEPTIONS]])[
|
||||
switch (yyn)
|
||||
switch (yyrule)
|
||||
{
|
||||
]b4_user_actions[
|
||||
default: break;
|
||||
@@ -933,11 +961,13 @@ yyuserAction (yyRuleNum yyn, int yyrhslen, yyGLRStackItem* yyvsp,
|
||||
YYERROR;
|
||||
}
|
||||
#endif // YY_EXCEPTIONS]])[
|
||||
YY_SYMBOL_PRINT ("-> $$ =", yylhsNonterm (yyrule), yyvalp, yylocp);
|
||||
|
||||
return yyok;
|
||||
# undef yyerrok
|
||||
# undef YYABORT
|
||||
# undef YYACCEPT
|
||||
# undef YYNOMEM
|
||||
# undef YYERROR
|
||||
# undef YYBACKUP
|
||||
# undef yyclearin
|
||||
@@ -974,7 +1004,7 @@ yydestroyGLRState (char const *yymsg, yyGLRState *yys]b4_user_formals[)
|
||||
{
|
||||
if (yys->yyresolved)
|
||||
yydestruct (yymsg, yy_accessing_symbol (yys->yylrState),
|
||||
&yys->yysemantics.yysval]b4_locuser_args([&yys->yyloc])[);
|
||||
&yys->yysemantics.yyval]b4_locuser_args([&yys->yyloc])[);
|
||||
else
|
||||
{
|
||||
#if ]b4_api_PREFIX[DEBUG
|
||||
@@ -1001,13 +1031,6 @@ yydestroyGLRState (char const *yymsg, yyGLRState *yys]b4_user_formals[)
|
||||
}
|
||||
}
|
||||
|
||||
/** Left-hand-side symbol for rule #YYRULE. */
|
||||
static inline yysymbol_kind_t
|
||||
yylhsNonterm (yyRuleNum yyrule)
|
||||
{
|
||||
return YY_CAST (yysymbol_kind_t, yyr1[yyrule]);
|
||||
}
|
||||
|
||||
#define yypact_value_is_default(Yyn) \
|
||||
]b4_table_value_equals([[pact]], [[Yyn]], [b4_pact_ninf], [YYPACT_NINF])[
|
||||
|
||||
@@ -1041,7 +1064,7 @@ static inline int
|
||||
yygetLRActions (yy_state_t yystate, yysymbol_kind_t yytoken, const short** yyconflicts)
|
||||
{
|
||||
int yyindex = yypact[yystate] + yytoken;
|
||||
if (yytoken == ]b4_symbol(1, kind)[)
|
||||
if (yytoken == ]b4_symbol(error, kind)[)
|
||||
{
|
||||
// This is the error token.
|
||||
*yyconflicts = yyconfl;
|
||||
@@ -1128,7 +1151,7 @@ yyaddDeferredAction (yyGLRStack* yystackp, YYPTRDIFF_T yyk, yyGLRState* yystate,
|
||||
yynewOption->yyloc = yylloc;])[
|
||||
}
|
||||
else
|
||||
yynewOption->yyrawchar = ]b4_symbol(-2, id)[;
|
||||
yynewOption->yyrawchar = ]b4_symbol(empty, id)[;
|
||||
yynewOption->yynext = yystate->yysemantics.yyfirstVal;
|
||||
yystate->yysemantics.yyfirstVal = yynewOption;
|
||||
|
||||
@@ -1349,7 +1372,7 @@ yyglrShift (yyGLRStack* yystackp, YYPTRDIFF_T yyk, yy_state_t yylrState,
|
||||
yynewState->yyposn = yyposn;
|
||||
yynewState->yyresolved = yytrue;
|
||||
yynewState->yypred = yystackp->yytops.yystates[yyk];
|
||||
yynewState->yysemantics.yysval = *yyvalp;]b4_locations_if([
|
||||
yynewState->yysemantics.yyval = *yyvalp;]b4_locations_if([
|
||||
yynewState->yyloc = *yylocp;])[
|
||||
yystackp->yytops.yystates[yyk] = yynewState;
|
||||
|
||||
@@ -1377,14 +1400,7 @@ yyglrShiftDefer (yyGLRStack* yystackp, YYPTRDIFF_T yyk, yy_state_t yylrState,
|
||||
yyaddDeferredAction (yystackp, yyk, yynewState, yyrhs, yyrule);
|
||||
}
|
||||
|
||||
#if !]b4_api_PREFIX[DEBUG
|
||||
# define YY_REDUCE_PRINT(Args)
|
||||
#else
|
||||
# define YY_REDUCE_PRINT(Args) \
|
||||
do { \
|
||||
if (yydebug) \
|
||||
yy_reduce_print Args; \
|
||||
} while (0)
|
||||
#if ]b4_api_PREFIX[DEBUG
|
||||
|
||||
/*----------------------------------------------------------------------.
|
||||
| Report that stack #YYK of *YYSTACKP is going to be reduced by YYRULE. |
|
||||
@@ -1407,7 +1423,7 @@ yy_reduce_print (yybool yynormal, yyGLRStackItem* yyvsp, YYPTRDIFF_T yyk,
|
||||
YY_FPRINTF ((stderr, " $%d = ", yyi + 1));
|
||||
yy_symbol_print (stderr,
|
||||
yy_accessing_symbol (yyvsp[yyi - yynrhs + 1].yystate.yylrState),
|
||||
&yyvsp[yyi - yynrhs + 1].yystate.yysemantics.yysval]b4_locations_if([,
|
||||
&yyvsp[yyi - yynrhs + 1].yystate.yysemantics.yyval]b4_locations_if([,
|
||||
&]b4_rhs_location(yynrhs, yyi + 1))[]dnl
|
||||
b4_user_args[);
|
||||
if (!yyvsp[yyi - yynrhs + 1].yystate.yyresolved)
|
||||
@@ -1438,8 +1454,7 @@ yydoAction (yyGLRStack* yystackp, YYPTRDIFF_T yyk, yyRuleNum yyrule,
|
||||
yystackp->yynextFree -= yynrhs;
|
||||
yystackp->yyspaceLeft += yynrhs;
|
||||
yystackp->yytops.yystates[0] = & yystackp->yynextFree[-1].yystate;
|
||||
YY_REDUCE_PRINT ((yytrue, yyrhs, yyk, yyrule]b4_user_args[));
|
||||
return yyuserAction (yyrule, yynrhs, yyrhs, yystackp,
|
||||
return yyuserAction (yyrule, yynrhs, yyrhs, yystackp, yyk,
|
||||
yyvalp]b4_locuser_args[);
|
||||
}
|
||||
else
|
||||
@@ -1458,9 +1473,8 @@ yydoAction (yyGLRStack* yystackp, YYPTRDIFF_T yyk, yyRuleNum yyrule,
|
||||
}
|
||||
yyupdateSplit (yystackp, yys);
|
||||
yystackp->yytops.yystates[yyk] = yys;
|
||||
YY_REDUCE_PRINT ((yyfalse, yyrhsVals + YYMAXRHS + YYMAXLEFT - 1, yyk, yyrule]b4_user_args[));
|
||||
return yyuserAction (yyrule, yynrhs, yyrhsVals + YYMAXRHS + YYMAXLEFT - 1,
|
||||
yystackp, yyvalp]b4_locuser_args[);
|
||||
yystackp, yyk, yyvalp]b4_locuser_args[);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1483,21 +1497,20 @@ yyglrReduce (yyGLRStack* yystackp, YYPTRDIFF_T yyk, yyRuleNum yyrule,
|
||||
|
||||
if (yyforceEval || yystackp->yysplitPoint == YY_NULLPTR)
|
||||
{
|
||||
YYSTYPE yysval;]b4_locations_if([[
|
||||
YYSTYPE yyval;]b4_locations_if([[
|
||||
YYLTYPE yyloc;]])[
|
||||
|
||||
YYRESULTTAG yyflag = yydoAction (yystackp, yyk, yyrule, &yysval]b4_locuser_args([&yyloc])[);
|
||||
YYRESULTTAG yyflag = yydoAction (yystackp, yyk, yyrule, &yyval]b4_locuser_args([&yyloc])[);
|
||||
if (yyflag == yyerr && yystackp->yysplitPoint != YY_NULLPTR)
|
||||
YY_DPRINTF ((stderr,
|
||||
"Parse on stack %ld rejected by rule %d (line %d).\n",
|
||||
YY_CAST (long, yyk), yyrule - 1, yyrline[yyrule - 1]));
|
||||
YY_CAST (long, yyk), yyrule - 1, yyrline[yyrule]));
|
||||
if (yyflag != yyok)
|
||||
return yyflag;
|
||||
YY_SYMBOL_PRINT ("-> $$ =", yylhsNonterm (yyrule), &yysval, &yyloc);
|
||||
yyglrShift (yystackp, yyk,
|
||||
yyLRgotoState (yystackp->yytops.yystates[yyk]->yylrState,
|
||||
yylhsNonterm (yyrule)),
|
||||
yyposn, &yysval]b4_locations_if([, &yyloc])[);
|
||||
yyposn, &yyval]b4_locations_if([, &yyloc])[);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1517,7 +1530,7 @@ yyglrReduce (yyGLRStack* yystackp, YYPTRDIFF_T yyk, yyRuleNum yyrule,
|
||||
YY_DPRINTF ((stderr,
|
||||
"Reduced stack %ld by rule %d (line %d); action deferred. "
|
||||
"Now in state %d.\n",
|
||||
YY_CAST (long, yyk), yyrule - 1, yyrline[yyrule - 1],
|
||||
YY_CAST (long, yyk), yyrule - 1, yyrline[yyrule],
|
||||
yynewLRState));
|
||||
for (yyi = 0; yyi < yystackp->yytops.yysize; yyi += 1)
|
||||
if (yyi != yyk && yystackp->yytops.yystates[yyi] != YY_NULLPTR)
|
||||
@@ -1628,12 +1641,12 @@ yymergeOptionSets (yySemanticOption* yyy0, yySemanticOption* yyy1)
|
||||
else if (yys0->yyresolved)
|
||||
{
|
||||
yys1->yyresolved = yytrue;
|
||||
yys1->yysemantics.yysval = yys0->yysemantics.yysval;
|
||||
yys1->yysemantics.yyval = yys0->yysemantics.yyval;
|
||||
}
|
||||
else if (yys1->yyresolved)
|
||||
{
|
||||
yys0->yyresolved = yytrue;
|
||||
yys0->yysemantics.yysval = yys1->yysemantics.yysval;
|
||||
yys0->yysemantics.yyval = yys1->yysemantics.yyval;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1687,8 +1700,8 @@ yypreference (yySemanticOption* y0, yySemanticOption* y1)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static YYRESULTTAG yyresolveValue (yyGLRState* yys,
|
||||
yyGLRStack* yystackp]b4_user_formals[);
|
||||
static YYRESULTTAG
|
||||
yyresolveValue (yyGLRState* yys, yyGLRStack* yystackp]b4_user_formals[);
|
||||
|
||||
|
||||
/** Resolve the previous YYN states starting at and including state YYS
|
||||
@@ -1744,7 +1757,7 @@ yyresolveAction (yySemanticOption* yyopt, yyGLRStack* yystackp,
|
||||
yylloc = yyopt->yyloc;])[
|
||||
yyflag = yyuserAction (yyopt->yyrule, yynrhs,
|
||||
yyrhsVals + YYMAXRHS + YYMAXLEFT - 1,
|
||||
yystackp, yyvalp]b4_locuser_args[);
|
||||
yystackp, -1, yyvalp]b4_locuser_args[);
|
||||
yychar = yychar_current;
|
||||
yylval = yylval_current;]b4_locations_if([
|
||||
yylloc = yylloc_current;])[
|
||||
@@ -1879,7 +1892,7 @@ yyresolveValue (yyGLRState* yys, yyGLRStack* yystackp]b4_user_formals[)
|
||||
yySemanticOption* yybest = yyoptionList;
|
||||
yySemanticOption** yypp;
|
||||
yybool yymerge = yyfalse;
|
||||
YYSTYPE yysval;
|
||||
YYSTYPE yyval;
|
||||
YYRESULTTAG yyflag;]b4_locations_if([
|
||||
YYLTYPE *yylocp = &yys->yyloc;])[
|
||||
|
||||
@@ -1923,33 +1936,33 @@ yyresolveValue (yyGLRState* yys, yyGLRStack* yystackp]b4_user_formals[)
|
||||
{
|
||||
yySemanticOption* yyp;
|
||||
int yyprec = yydprec[yybest->yyrule];
|
||||
yyflag = yyresolveAction (yybest, yystackp, &yysval]b4_locuser_args[);
|
||||
yyflag = yyresolveAction (yybest, yystackp, &yyval]b4_locuser_args[);
|
||||
if (yyflag == yyok)
|
||||
for (yyp = yybest->yynext; yyp != YY_NULLPTR; yyp = yyp->yynext)
|
||||
{
|
||||
if (yyprec == yydprec[yyp->yyrule])
|
||||
{
|
||||
YYSTYPE yysval_other;]b4_locations_if([
|
||||
YYSTYPE yyval_other;]b4_locations_if([
|
||||
YYLTYPE yydummy;])[
|
||||
yyflag = yyresolveAction (yyp, yystackp, &yysval_other]b4_locuser_args([&yydummy])[);
|
||||
yyflag = yyresolveAction (yyp, yystackp, &yyval_other]b4_locuser_args([&yydummy])[);
|
||||
if (yyflag != yyok)
|
||||
{
|
||||
yydestruct ("Cleanup: discarding incompletely merged value for",
|
||||
yy_accessing_symbol (yys->yylrState),
|
||||
&yysval]b4_locuser_args[);
|
||||
&yyval]b4_locuser_args[);
|
||||
break;
|
||||
}
|
||||
yyuserMerge (yymerger[yyp->yyrule], &yysval, &yysval_other);
|
||||
yyuserMerge (yymerger[yyp->yyrule], &yyval, &yyval_other);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
yyflag = yyresolveAction (yybest, yystackp, &yysval]b4_locuser_args([yylocp])[);
|
||||
yyflag = yyresolveAction (yybest, yystackp, &yyval]b4_locuser_args([yylocp])[);
|
||||
|
||||
if (yyflag == yyok)
|
||||
{
|
||||
yys->yyresolved = yytrue;
|
||||
yys->yysemantics.yysval = yysval;
|
||||
yys->yysemantics.yyval = yyval;
|
||||
}
|
||||
else
|
||||
yys->yysemantics.yyfirstVal = YY_NULLPTR;
|
||||
@@ -1974,18 +1987,24 @@ yyresolveStack (yyGLRStack* yystackp]b4_user_formals[)
|
||||
return yyok;
|
||||
}
|
||||
|
||||
/** Called when returning to deterministic operation to clean up the extra
|
||||
* stacks. */
|
||||
static void
|
||||
yycompressStack (yyGLRStack* yystackp)
|
||||
{
|
||||
yyGLRState* yyp, *yyq, *yyr;
|
||||
/* yyr is the state after the split point. */
|
||||
yyGLRState *yyr;
|
||||
|
||||
if (yystackp->yytops.yysize != 1 || yystackp->yysplitPoint == YY_NULLPTR)
|
||||
return;
|
||||
|
||||
for (yyp = yystackp->yytops.yystates[0], yyq = yyp->yypred, yyr = YY_NULLPTR;
|
||||
yyp != yystackp->yysplitPoint;
|
||||
yyr = yyp, yyp = yyq, yyq = yyp->yypred)
|
||||
yyp->yypred = yyr;
|
||||
{
|
||||
yyGLRState *yyp, *yyq;
|
||||
for (yyp = yystackp->yytops.yystates[0], yyq = yyp->yypred, yyr = YY_NULLPTR;
|
||||
yyp != yystackp->yysplitPoint;
|
||||
yyr = yyp, yyp = yyq, yyq = yyp->yypred)
|
||||
yyp->yypred = yyr;
|
||||
}
|
||||
|
||||
yystackp->yyspaceLeft += yystackp->yynextFree - yystackp->yyitems;
|
||||
yystackp->yynextFree = YY_REINTERPRET_CAST (yyGLRStackItem*, yystackp->yysplitPoint) + 1;
|
||||
@@ -2119,7 +2138,7 @@ yypcontext_expected_tokens (const yyGLRStack* yystackp,
|
||||
int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
|
||||
int yyx;
|
||||
for (yyx = yyxbegin; yyx < yyxend; ++yyx)
|
||||
if (yycheck[yyx + yyn] == yyx && yyx != ]b4_symbol(1, kind)[
|
||||
if (yycheck[yyx + yyn] == yyx && yyx != ]b4_symbol(error, kind)[
|
||||
&& !yytable_value_is_error (yytable[yyx + yyn]))
|
||||
{
|
||||
if (!yyarg)
|
||||
@@ -2131,7 +2150,7 @@ yypcontext_expected_tokens (const yyGLRStack* yystackp,
|
||||
}
|
||||
}
|
||||
if (yyarg && yycount == 0 && 0 < yyargn)
|
||||
yyarg[0] = ]b4_symbol(-2, kind)[;
|
||||
yyarg[0] = ]b4_symbol(empty, kind)[;
|
||||
return yycount;
|
||||
}]])[
|
||||
|
||||
@@ -2150,15 +2169,15 @@ static yysymbol_kind_t
|
||||
yypcontext_token (const yyGLRStack *yystackp)
|
||||
{
|
||||
YY_USE (yystackp);
|
||||
yysymbol_kind_t yytoken = yychar == ]b4_symbol(-2, id)[ ? ]b4_symbol(-2, kind)[ : YYTRANSLATE (yychar);
|
||||
yysymbol_kind_t yytoken = yychar == ]b4_symbol(empty, id)[ ? ]b4_symbol(empty, kind)[ : YYTRANSLATE (yychar);
|
||||
return yytoken;
|
||||
}
|
||||
|
||||
]b4_locations_if([[/* The location of the lookahead of this context. */
|
||||
static YYLTYPE *
|
||||
static const YYLTYPE *
|
||||
yypcontext_location (const yyGLRStack *yystackp) YY_ATTRIBUTE_UNUSED;
|
||||
|
||||
static YYLTYPE *
|
||||
static const YYLTYPE *
|
||||
yypcontext_location (const yyGLRStack *yystackp)
|
||||
{
|
||||
YY_USE (yystackp);
|
||||
@@ -2169,7 +2188,7 @@ yypcontext_location (const yyGLRStack *yystackp)
|
||||
yy_syntax_error_arguments (const yyGLRStack* yystackp,
|
||||
yysymbol_kind_t yyarg[], int yyargn)
|
||||
{
|
||||
yysymbol_kind_t yytoken = yychar == ]b4_symbol(-2, id)[ ? ]b4_symbol(-2, kind)[ : YYTRANSLATE (yychar);
|
||||
yysymbol_kind_t yytoken = yychar == ]b4_symbol(empty, id)[ ? ]b4_symbol(empty, kind)[ : YYTRANSLATE (yychar);
|
||||
/* Actual size of YYARG. */
|
||||
int yycount = 0;
|
||||
/* There are many possibilities here to consider:
|
||||
@@ -2185,12 +2204,7 @@ yy_syntax_error_arguments (const yyGLRStack* yystackp,
|
||||
- Don't assume there isn't a lookahead just because this state is a
|
||||
consistent state with a default action. There might have been a
|
||||
previous inconsistent state, consistent state with a non-default
|
||||
action, or user semantic action that manipulated yychar.]b4_lac_if([[
|
||||
In the first two cases, it might appear that the current syntax
|
||||
error should have been detected in the previous state when yy_lac
|
||||
was invoked. However, at that time, there might have been a
|
||||
different syntax error that discarded a different initial context
|
||||
during error recovery, leaving behind the current lookahead.]], [[
|
||||
action, or user semantic action that manipulated yychar.
|
||||
- Of course, the expected token list depends on states to have
|
||||
correct lookahead information, and it depends on the parser not
|
||||
to perform extra reductions after fetching a lookahead from the
|
||||
@@ -2198,9 +2212,9 @@ yy_syntax_error_arguments (const yyGLRStack* yystackp,
|
||||
(from LALR or IELR) and default reductions corrupt the expected
|
||||
token list. However, the list is correct for canonical LR with
|
||||
one exception: it will still contain any token that will not be
|
||||
accepted due to an error action in a later state.]])[
|
||||
accepted due to an error action in a later state.
|
||||
*/
|
||||
if (yytoken != ]b4_symbol(-2, kind)[)
|
||||
if (yytoken != ]b4_symbol(empty, kind)[)
|
||||
{
|
||||
int yyn;
|
||||
if (yyarg)
|
||||
@@ -2327,9 +2341,9 @@ yyrecoverSyntaxError (yyGLRStack* yystackp]b4_user_formals[)
|
||||
{
|
||||
yysymbol_kind_t yytoken;
|
||||
int yyj;
|
||||
if (yychar == ]b4_symbol(0, [id])[)
|
||||
if (yychar == ]b4_symbol(eof, [id])[)
|
||||
yyFail (yystackp][]b4_lpure_args[, YY_NULLPTR);
|
||||
if (yychar != ]b4_symbol(-2, id)[)
|
||||
if (yychar != ]b4_symbol(empty, id)[)
|
||||
{]b4_locations_if([[
|
||||
/* We throw away the lookahead, but the error range
|
||||
of the shifted error token must take it into account. */
|
||||
@@ -2341,7 +2355,7 @@ yyrecoverSyntaxError (yyGLRStack* yystackp]b4_user_formals[)
|
||||
yytoken = YYTRANSLATE (yychar);
|
||||
yydestruct ("Error: discarding",
|
||||
yytoken, &yylval]b4_locuser_args([&yylloc])[);
|
||||
yychar = ]b4_symbol(-2, id)[;
|
||||
yychar = ]b4_symbol(empty, id)[;
|
||||
}
|
||||
yytoken = ]b4_yygetToken_call[;
|
||||
yyj = yypact[yystackp->yytops.yystates[0]->yylrState];
|
||||
@@ -2379,8 +2393,8 @@ yyrecoverSyntaxError (yyGLRStack* yystackp]b4_user_formals[)
|
||||
int yyj = yypact[yys->yylrState];
|
||||
if (! yypact_value_is_default (yyj))
|
||||
{
|
||||
yyj += ]b4_symbol(1, kind)[;
|
||||
if (0 <= yyj && yyj <= YYLAST && yycheck[yyj] == ]b4_symbol(1, kind)[
|
||||
yyj += ]b4_symbol(error, kind)[;
|
||||
if (0 <= yyj && yyj <= YYLAST && yycheck[yyj] == ]b4_symbol(error, kind)[
|
||||
&& yyisShiftAction (yytable[yyj]))
|
||||
{
|
||||
/* Shift the error token. */
|
||||
@@ -2408,20 +2422,16 @@ yyrecoverSyntaxError (yyGLRStack* yystackp]b4_user_formals[)
|
||||
yyFail (yystackp][]b4_lpure_args[, YY_NULLPTR);
|
||||
}
|
||||
|
||||
#define YYCHK1(YYE) \
|
||||
do { \
|
||||
switch (YYE) { \
|
||||
case yyok: \
|
||||
break; \
|
||||
case yyabort: \
|
||||
goto yyabortlab; \
|
||||
case yyaccept: \
|
||||
goto yyacceptlab; \
|
||||
case yyerr: \
|
||||
goto yyuser_error; \
|
||||
default: \
|
||||
goto yybuglab; \
|
||||
} \
|
||||
#define YYCHK1(YYE) \
|
||||
do { \
|
||||
switch (YYE) { \
|
||||
case yyok: break; \
|
||||
case yyabort: goto yyabortlab; \
|
||||
case yyaccept: goto yyacceptlab; \
|
||||
case yyerr: goto yyuser_error; \
|
||||
case yynomem: goto yyexhaustedlab; \
|
||||
default: goto yybuglab; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/*----------.
|
||||
@@ -2438,7 +2448,7 @@ int
|
||||
|
||||
YY_DPRINTF ((stderr, "Starting parse\n"));
|
||||
|
||||
yychar = ]b4_symbol(-2, id)[;
|
||||
yychar = ]b4_symbol(empty, id)[;
|
||||
yylval = yyval_default;]b4_locations_if([
|
||||
yylloc = yyloc_default;])[
|
||||
]m4_ifdef([b4_initial_action], [
|
||||
@@ -2492,7 +2502,7 @@ b4_dollar_popdef])[]dnl
|
||||
if (yyisShiftAction (yyaction))
|
||||
{
|
||||
YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
|
||||
yychar = ]b4_symbol(-2, id)[;
|
||||
yychar = ]b4_symbol(empty, id)[;
|
||||
yyposn += 1;
|
||||
yyglrShift (&yystack, 0, yyaction, yyposn, &yylval]b4_locations_if([, &yylloc])[);
|
||||
if (0 < yystack.yyerrState)
|
||||
@@ -2503,7 +2513,7 @@ b4_dollar_popdef])[]dnl
|
||||
yystack.yyerror_range[1].yystate.yyloc = yylloc;]])[
|
||||
/* Issue an error message unless the scanner already
|
||||
did. */
|
||||
if (yychar != ]b4_symbol(1, id)[)
|
||||
if (yychar != ]b4_symbol(error, id)[)
|
||||
yyreportSyntaxError (&yystack]b4_user_args[);
|
||||
goto yyuser_error;
|
||||
}
|
||||
@@ -2519,7 +2529,7 @@ b4_dollar_popdef])[]dnl
|
||||
YYPTRDIFF_T yys;
|
||||
|
||||
for (yys = 0; yys < yystack.yytops.yysize; yys += 1)
|
||||
yystackp->yytops.yylookaheadNeeds[yys] = yychar != ]b4_symbol(-2, id)[;
|
||||
yystackp->yytops.yylookaheadNeeds[yys] = yychar != ]b4_symbol(empty, id)[;
|
||||
|
||||
/* yyprocessOneStack returns one of three things:
|
||||
|
||||
@@ -2557,11 +2567,11 @@ b4_dollar_popdef])[]dnl
|
||||
|
||||
/* If any yyglrShift call fails, it will fail after shifting. Thus,
|
||||
a copy of yylval will already be on stack 0 in the event of a
|
||||
failure in the following loop. Thus, yychar is set to ]b4_symbol(-2, id)[
|
||||
failure in the following loop. Thus, yychar is set to ]b4_symbol(empty, id)[
|
||||
before the loop to make sure the user destructor for yylval isn't
|
||||
called twice. */
|
||||
yytoken_to_shift = YYTRANSLATE (yychar);
|
||||
yychar = ]b4_symbol(-2, id)[;
|
||||
yychar = ]b4_symbol(empty, id)[;
|
||||
yyposn += 1;
|
||||
for (yys = 0; yys < yystack.yytops.yysize; yys += 1)
|
||||
{
|
||||
@@ -2574,7 +2584,7 @@ b4_dollar_popdef])[]dnl
|
||||
YY_SYMBOL_PRINT ("shifting", yytoken_to_shift, &yylval, &yylloc);
|
||||
yyglrShift (&yystack, yys, yyaction, yyposn,
|
||||
&yylval]b4_locations_if([, &yylloc])[);
|
||||
YY_DPRINTF ((stderr, "Stack %ld now in state #%d\n",
|
||||
YY_DPRINTF ((stderr, "Stack %ld now in state %d\n",
|
||||
YY_CAST (long, yys),
|
||||
yystack.yytops.yystates[yys]->yylrState));
|
||||
}
|
||||
@@ -2595,7 +2605,7 @@ b4_dollar_popdef])[]dnl
|
||||
|
||||
yyacceptlab:
|
||||
yyresult = 0;
|
||||
goto yyreturn;
|
||||
goto yyreturnlab;
|
||||
|
||||
yybuglab:
|
||||
YY_ASSERT (yyfalse);
|
||||
@@ -2603,15 +2613,15 @@ b4_dollar_popdef])[]dnl
|
||||
|
||||
yyabortlab:
|
||||
yyresult = 1;
|
||||
goto yyreturn;
|
||||
goto yyreturnlab;
|
||||
|
||||
yyexhaustedlab:
|
||||
yyerror (]b4_lyyerror_args[YY_("memory exhausted"));
|
||||
yyresult = 2;
|
||||
goto yyreturn;
|
||||
goto yyreturnlab;
|
||||
|
||||
yyreturn:
|
||||
if (yychar != ]b4_symbol(-2, id)[)
|
||||
yyreturnlab:
|
||||
if (yychar != ]b4_symbol(empty, id)[)
|
||||
yydestruct ("Cleanup: discarding lookahead",
|
||||
YYTRANSLATE (yychar), &yylval]b4_locuser_args([&yylloc])[);
|
||||
|
||||
@@ -2649,6 +2659,7 @@ b4_dollar_popdef])[]dnl
|
||||
|
||||
/* DEBUGGING ONLY */
|
||||
#if ]b4_api_PREFIX[DEBUG
|
||||
/* Print *YYS and its predecessors. */
|
||||
static void
|
||||
yy_yypstack (yyGLRState* yys)
|
||||
{
|
||||
@@ -2660,22 +2671,25 @@ yy_yypstack (yyGLRState* yys)
|
||||
YY_FPRINTF ((stderr, "%d@@%ld", yys->yylrState, YY_CAST (long, yys->yyposn)));
|
||||
}
|
||||
|
||||
/* Print YYS (possibly NULL) and its predecessors. */
|
||||
static void
|
||||
yypstates (yyGLRState* yyst)
|
||||
yypstates (yyGLRState* yys)
|
||||
{
|
||||
if (yyst == YY_NULLPTR)
|
||||
if (yys == YY_NULLPTR)
|
||||
YY_FPRINTF ((stderr, "<null>"));
|
||||
else
|
||||
yy_yypstack (yyst);
|
||||
yy_yypstack (yys);
|
||||
YY_FPRINTF ((stderr, "\n"));
|
||||
}
|
||||
|
||||
/* Print the stack #YYK. */
|
||||
static void
|
||||
yypstack (yyGLRStack* yystackp, YYPTRDIFF_T yyk)
|
||||
{
|
||||
yypstates (yystackp->yytops.yystates[yyk]);
|
||||
}
|
||||
|
||||
/* Print all the stacks. */
|
||||
static void
|
||||
yypdumpstack (yyGLRStack* yystackp)
|
||||
{
|
||||
|
||||
+35
-35
@@ -78,7 +78,7 @@ m4_define([b4_yy_symbol_print_define],
|
||||
|
||||
static void
|
||||
yy_symbol_print (FILE *, ]b4_namespace_ref::b4_parser_class[::symbol_kind_type yytoken,
|
||||
const ]b4_namespace_ref::b4_parser_class[::semantic_type *yyvaluep]b4_locations_if([[,
|
||||
const ]b4_namespace_ref::b4_parser_class[::value_type *yyvaluep]b4_locations_if([[,
|
||||
const ]b4_namespace_ref::b4_parser_class[::location_type *yylocationp]])[]b4_user_formals[)
|
||||
{
|
||||
]b4_parse_param_use[]dnl
|
||||
@@ -154,7 +154,7 @@ m4_pushdef([b4_parse_param], m4_defn([b4_parse_param_orig]))dnl
|
||||
|
||||
void
|
||||
]b4_parser_class[::yy_symbol_value_print_ (symbol_kind_type yykind,
|
||||
const semantic_type* yyvaluep]b4_locations_if([[,
|
||||
const value_type* yyvaluep]b4_locations_if([[,
|
||||
const location_type* yylocationp]])[) const
|
||||
{]b4_locations_if([[
|
||||
YY_USE (yylocationp);]])[
|
||||
@@ -168,7 +168,7 @@ m4_pushdef([b4_parse_param], m4_defn([b4_parse_param_orig]))dnl
|
||||
|
||||
void
|
||||
]b4_parser_class[::yy_symbol_print_ (symbol_kind_type yykind,
|
||||
const semantic_type* yyvaluep]b4_locations_if([[,
|
||||
const value_type* yyvaluep]b4_locations_if([[,
|
||||
const location_type* yylocationp]])[) const
|
||||
{
|
||||
*yycdebug_ << (yykind < YYNTOKENS ? "token" : "nterm")
|
||||
@@ -221,15 +221,33 @@ m4_define([b4_define_symbol_kind],
|
||||
# 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])[
|
||||
[[]b4_attribute_define[
|
||||
]b4_null_define[
|
||||
|
||||
// This skeleton is based on C, yet compiles it as C++.
|
||||
// So expect warnings about C style casts.
|
||||
#if defined __clang__ && 306 <= __clang_major__ * 100 + __clang_minor__
|
||||
# pragma clang diagnostic ignored "-Wold-style-cast"
|
||||
#elif defined __GNUC__ && 406 <= __GNUC__ * 100 + __GNUC_MINOR__
|
||||
# pragma GCC diagnostic ignored "-Wold-style-cast"
|
||||
#endif
|
||||
|
||||
// On MacOS, PTRDIFF_MAX is defined as long long, which Clang's
|
||||
// -pedantic reports as being a C++11 extension.
|
||||
#if defined __APPLE__ && YY_CPLUSPLUS < 201103L \
|
||||
&& defined __clang__ && 4 <= __clang_major__
|
||||
# pragma clang diagnostic ignored "-Wc++11-long-long"
|
||||
#endif
|
||||
|
||||
#undef ]b4_symbol(empty, [id])[
|
||||
#define ]b4_symbol(empty, [id])[ ]b4_namespace_ref[::]b4_parser_class[::token::]b4_symbol(empty, [id])[
|
||||
#undef ]b4_symbol(eof, [id])[
|
||||
#define ]b4_symbol(eof, [id])[ ]b4_namespace_ref[::]b4_parser_class[::token::]b4_symbol(eof, [id])[
|
||||
#undef ]b4_symbol(error, [id])[
|
||||
#define ]b4_symbol(error, [id])[ ]b4_namespace_ref[::]b4_parser_class[::token::]b4_symbol(error, [id])[
|
||||
|
||||
#ifndef ]b4_api_PREFIX[STYPE
|
||||
# define ]b4_api_PREFIX[STYPE ]b4_namespace_ref[::]b4_parser_class[::semantic_type
|
||||
# define ]b4_api_PREFIX[STYPE ]b4_namespace_ref[::]b4_parser_class[::value_type
|
||||
#endif
|
||||
#ifndef ]b4_api_PREFIX[LTYPE
|
||||
# define ]b4_api_PREFIX[LTYPE ]b4_namespace_ref[::]b4_parser_class[::location_type
|
||||
@@ -252,9 +270,9 @@ m4_define([b4_undef_symbol_kind],
|
||||
# -----------------
|
||||
# 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])[
|
||||
[[#undef ]b4_symbol(empty, [id])[
|
||||
#undef ]b4_symbol(eof, [id])[
|
||||
#undef ]b4_symbol(error, [id])[
|
||||
|
||||
]b4_undef_symbol_kind(-2)dnl
|
||||
b4_symbol_foreach([b4_undef_symbol_kind])dnl
|
||||
@@ -263,7 +281,7 @@ 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)
|
||||
# Declaration that might either go into the header (if --header, $1 = hh)
|
||||
# or in the implementation file.
|
||||
m4_define([b4_shared_declarations],
|
||||
[m4_pushdef([b4_parse_param], m4_defn([b4_parse_param_orig]))dnl
|
||||
@@ -277,24 +295,6 @@ b4_percent_code_get([[requires]])[
|
||||
[[# include ]b4_location_include])[
|
||||
]b4_variant_if([b4_variant_includes])[
|
||||
|
||||
]b4_attribute_define[
|
||||
]b4_null_define[
|
||||
|
||||
// This skeleton is based on C, yet compiles it as C++.
|
||||
// So expect warnings about C style casts.
|
||||
#if defined __clang__ && 306 <= __clang_major__ * 100 + __clang_minor__
|
||||
# pragma clang diagnostic ignored "-Wold-style-cast"
|
||||
#elif defined __GNUC__ && 406 <= __GNUC__ * 100 + __GNUC_MINOR__
|
||||
# pragma GCC diagnostic ignored "-Wold-style-cast"
|
||||
#endif
|
||||
|
||||
// On MacOS, PTRDIFF_MAX is defined as long long, which Clang's
|
||||
// -pedantic reports as being a C++11 extension.
|
||||
#if defined __APPLE__ && YY_CPLUSPLUS < 201103L \
|
||||
&& defined __clang__ && 4 <= __clang_major__
|
||||
# pragma clang diagnostic ignored "-Wc++11-long-long"
|
||||
#endif
|
||||
|
||||
// Whether we are compiled with exception support.
|
||||
#ifndef YY_EXCEPTIONS
|
||||
# if defined __GNUC__ && !defined __EXCEPTIONS
|
||||
@@ -355,14 +355,14 @@ b4_percent_code_get([[requires]])[
|
||||
/// \param yyvaluep Its semantic value.]b4_locations_if([[
|
||||
/// \param yylocationp Its location.]])[
|
||||
virtual void yy_symbol_value_print_ (symbol_kind_type yykind,
|
||||
const semantic_type* yyvaluep]b4_locations_if([[,
|
||||
const value_type* yyvaluep]b4_locations_if([[,
|
||||
const location_type* yylocationp]])[) const;
|
||||
/// \brief Report a symbol on the debug stream.
|
||||
/// \param yykind The symbol kind.
|
||||
/// \param yyvaluep Its semantic value.]b4_locations_if([[
|
||||
/// \param yylocationp Its location.]])[
|
||||
virtual void yy_symbol_print_ (symbol_kind_type yykind,
|
||||
const semantic_type* yyvaluep]b4_locations_if([[,
|
||||
const value_type* yyvaluep]b4_locations_if([[,
|
||||
const location_type* yylocationp]])[) const;
|
||||
private:
|
||||
/// Debug stream.
|
||||
@@ -378,7 +378,7 @@ b4_percent_code_get([[requires]])[
|
||||
]m4_popdef([b4_parse_param])dnl
|
||||
])[
|
||||
|
||||
]b4_defines_if(
|
||||
]b4_header_if(
|
||||
[b4_output_begin([b4_spec_header_file])
|
||||
b4_copyright([Skeleton interface for Bison GLR parsers in C++],
|
||||
[2002-2015, 2018-2021])[
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
+72
-60
@@ -20,8 +20,7 @@ m4_include(b4_skeletonsdir/[c++.m4])
|
||||
# api.value.type=variant is valid.
|
||||
m4_define([b4_value_type_setup_variant])
|
||||
|
||||
# Check the value of %define parse.lac, where LAC stands for lookahead
|
||||
# correction.
|
||||
# parse.lac
|
||||
b4_percent_define_default([[parse.lac]], [[none]])
|
||||
b4_percent_define_check_values([[[[parse.lac]], [[full]], [[none]]]])
|
||||
b4_define_flag_if([lac])
|
||||
@@ -146,16 +145,16 @@ b4_dollar_popdef[]dnl
|
||||
])])
|
||||
|
||||
|
||||
# b4_lex
|
||||
# ------
|
||||
# b4_yylex
|
||||
# --------
|
||||
# Call yylex.
|
||||
m4_define([b4_lex],
|
||||
m4_define([b4_yylex],
|
||||
[b4_token_ctor_if(
|
||||
[b4_function_call([yylex],
|
||||
[symbol_type], m4_ifdef([b4_lex_param], b4_lex_param))],
|
||||
[b4_function_call([yylex], [int],
|
||||
[b4_api_PREFIX[STYPE*], [&yyla.value]][]dnl
|
||||
b4_locations_if([, [[location*], [&yyla.location]]])dnl
|
||||
[[value_type *], [&yyla.value]][]dnl
|
||||
b4_locations_if([, [[location_type *], [&yyla.location]]])dnl
|
||||
m4_ifdef([b4_lex_param], [, ]b4_lex_param))])])
|
||||
|
||||
|
||||
@@ -174,7 +173,7 @@ b4_variant_if([m4_include(b4_skeletonsdir/[variant.hh])])
|
||||
|
||||
# b4_shared_declarations(hh|cc)
|
||||
# -----------------------------
|
||||
# Declaration that might either go into the header (if --defines, $1 = hh)
|
||||
# Declaration that might either go into the header (if --header, $1 = hh)
|
||||
# or in the implementation file.
|
||||
m4_define([b4_shared_declarations],
|
||||
[b4_percent_code_get([[requires]])[
|
||||
@@ -307,11 +306,11 @@ m4_define([b4_shared_declarations],
|
||||
/// Stored state numbers (used for stacks).
|
||||
typedef ]b4_int_type(0, m4_eval(b4_states_number - 1))[ state_type;
|
||||
]b4_parse_error_bmatch(
|
||||
[custom], [[
|
||||
[custom], [[
|
||||
/// Report a syntax error
|
||||
/// \param yyctx the context in which the error occurred.
|
||||
void report_syntax_error (const context& yyctx) const;]],
|
||||
[detailed\|verbose], [[
|
||||
[detailed\|verbose], [[
|
||||
/// The arguments of the error message.
|
||||
int yy_syntax_error_arguments_ (const context& yyctx,
|
||||
symbol_kind_type yyarg[], int yyargn) const;
|
||||
@@ -326,19 +325,19 @@ m4_define([b4_shared_declarations],
|
||||
|
||||
/// Whether the given \c yypact_ value indicates a defaulted state.
|
||||
/// \param yyvalue the value to check
|
||||
static bool yy_pact_value_is_default_ (int yyvalue);
|
||||
static bool yy_pact_value_is_default_ (int yyvalue) YY_NOEXCEPT;
|
||||
|
||||
/// Whether the given \c yytable_ value indicates a syntax error.
|
||||
/// \param yyvalue the value to check
|
||||
static bool yy_table_value_is_error_ (int yyvalue);
|
||||
static bool yy_table_value_is_error_ (int yyvalue) YY_NOEXCEPT;
|
||||
|
||||
static const ]b4_int_type(b4_pact_ninf, b4_pact_ninf)[ yypact_ninf_;
|
||||
static const ]b4_int_type(b4_table_ninf, b4_table_ninf)[ yytable_ninf_;
|
||||
|
||||
/// Convert a scanner token kind \a t to a symbol kind.
|
||||
/// In theory \a t should be a token_kind_type, but character literals
|
||||
/// are valid, yet not members of the token_type enum.
|
||||
static symbol_kind_type yytranslate_ (int t);
|
||||
/// are valid, yet not members of the token_kind_type enum.
|
||||
static symbol_kind_type yytranslate_ (int t) YY_NOEXCEPT;
|
||||
|
||||
]b4_parse_error_bmatch(
|
||||
[simple],
|
||||
@@ -408,7 +407,7 @@ m4_define([b4_shared_declarations],
|
||||
void move (by_state& that);
|
||||
|
||||
/// The symbol kind (corresponding to \a state).
|
||||
/// \a ]b4_symbol(-2, kind)[ when empty.
|
||||
/// \a ]b4_symbol(empty, kind)[ when empty.
|
||||
symbol_kind_type kind () const YY_NOEXCEPT;
|
||||
|
||||
/// The state number used to denote an empty symbol.
|
||||
@@ -475,7 +474,7 @@ m4_define([b4_shared_declarations],
|
||||
void yypush_ (const char* m, state_type s, YY_MOVE_REF (symbol_type) sym);
|
||||
|
||||
/// Pop \a n symbols from the stack.
|
||||
void yypop_ (int n = 1);
|
||||
void yypop_ (int n = 1) YY_NOEXCEPT;
|
||||
|
||||
/// Constants.
|
||||
enum
|
||||
@@ -494,16 +493,21 @@ m4_define([b4_shared_declarations],
|
||||
]b4_namespace_close[
|
||||
|
||||
]b4_percent_code_get([[provides]])[
|
||||
]])
|
||||
]])[
|
||||
|
||||
|
||||
## -------------- ##
|
||||
## Output files. ##
|
||||
## -------------- ##
|
||||
|
||||
b4_defines_if(
|
||||
[b4_output_begin([b4_spec_header_file])
|
||||
b4_copyright([Skeleton interface for Bison LALR(1) parsers in C++])
|
||||
[
|
||||
# ------------- #
|
||||
# Header file. #
|
||||
# ------------- #
|
||||
|
||||
]b4_header_if([[
|
||||
]b4_output_begin([b4_spec_header_file])[
|
||||
]b4_copyright([Skeleton interface for Bison LALR(1) parsers in C++])[
|
||||
|
||||
/**
|
||||
** \file ]b4_spec_mapped_header_file[
|
||||
** Define the ]b4_namespace_ref[::parser class.
|
||||
@@ -516,10 +520,14 @@ b4_copyright([Skeleton interface for Bison LALR(1) parsers in C++])
|
||||
]b4_shared_declarations(hh)[
|
||||
]b4_cpp_guard_close([b4_spec_mapped_header_file])[
|
||||
]b4_output_end[
|
||||
]])
|
||||
]])[
|
||||
|
||||
|
||||
b4_output_begin([b4_parser_file_name])[
|
||||
# --------------------- #
|
||||
# Implementation file. #
|
||||
# --------------------- #
|
||||
|
||||
]b4_output_begin([b4_parser_file_name])[
|
||||
]b4_copyright([Skeleton implementation for Bison LALR(1) parsers in C++])[
|
||||
]b4_disclaimer[
|
||||
]b4_percent_code_get([[top]])[]dnl
|
||||
@@ -530,7 +538,7 @@ m4_if(b4_prefix, [yy], [],
|
||||
|
||||
]b4_user_pre_prologue[
|
||||
|
||||
]b4_defines_if([[#include "@basename(]b4_spec_header_file[@)"]],
|
||||
]b4_header_if([[#include "@basename(]b4_spec_header_file[@)"]],
|
||||
[b4_shared_declarations([cc])])[
|
||||
|
||||
]b4_user_post_prologue[
|
||||
@@ -629,9 +637,9 @@ m4_if(b4_prefix, [yy], [],
|
||||
]b4_parser_class[::syntax_error::~syntax_error () YY_NOEXCEPT YY_NOTHROW
|
||||
{}
|
||||
|
||||
/*---------------.
|
||||
| symbol kinds. |
|
||||
`---------------*/
|
||||
/*---------.
|
||||
| symbol. |
|
||||
`---------*/
|
||||
|
||||
]b4_token_ctor_if([], [b4_public_types_define([cc])])[
|
||||
|
||||
@@ -665,7 +673,7 @@ m4_if(b4_prefix, [yy], [],
|
||||
]b4_parser_class[::by_state::kind () const YY_NOEXCEPT
|
||||
{
|
||||
if (state == empty_state)
|
||||
return ]b4_symbol(-2, kind)[;
|
||||
return ]b4_symbol(empty, kind)[;
|
||||
else
|
||||
return YY_CAST (symbol_kind_type, yystos_[+state]);
|
||||
}
|
||||
@@ -690,7 +698,7 @@ m4_if(b4_prefix, [yy], [],
|
||||
b4_symbol_variant([that.kind ()],
|
||||
[value], [move], [YY_MOVE (that.value)])])[
|
||||
// that is emptied.
|
||||
that.kind_ = ]b4_symbol(-2, kind)[;
|
||||
that.kind_ = ]b4_symbol(empty, kind)[;
|
||||
}
|
||||
|
||||
#if YY_CPLUSPLUS < 201103L
|
||||
@@ -771,7 +779,7 @@ m4_if(b4_prefix, [yy], [],
|
||||
}
|
||||
|
||||
void
|
||||
]b4_parser_class[::yypop_ (int n)
|
||||
]b4_parser_class[::yypop_ (int n) YY_NOEXCEPT
|
||||
{
|
||||
yystack_.pop (n);
|
||||
}
|
||||
@@ -814,13 +822,13 @@ m4_if(b4_prefix, [yy], [],
|
||||
}
|
||||
|
||||
bool
|
||||
]b4_parser_class[::yy_pact_value_is_default_ (int yyvalue)
|
||||
]b4_parser_class[::yy_pact_value_is_default_ (int yyvalue) YY_NOEXCEPT
|
||||
{
|
||||
return yyvalue == yypact_ninf_;
|
||||
}
|
||||
|
||||
bool
|
||||
]b4_parser_class[::yy_table_value_is_error_ (int yyvalue)
|
||||
]b4_parser_class[::yy_table_value_is_error_ (int yyvalue) YY_NOEXCEPT
|
||||
{
|
||||
return yyvalue == yytable_ninf_;
|
||||
}
|
||||
@@ -851,8 +859,8 @@ m4_if(b4_prefix, [yy], [],
|
||||
/// The return value of parse ().
|
||||
int yyresult;]b4_lac_if([[
|
||||
|
||||
/// Discard the LAC context in case there still is one left from a
|
||||
/// previous invocation.
|
||||
// Discard the LAC context in case there still is one left from a
|
||||
// previous invocation.
|
||||
yy_lac_discard_ ("init");]])[
|
||||
|
||||
#if YY_EXCEPTIONS
|
||||
@@ -904,9 +912,9 @@ b4_dollar_popdef])[]dnl
|
||||
try
|
||||
#endif // YY_EXCEPTIONS
|
||||
{]b4_token_ctor_if([[
|
||||
symbol_type yylookahead (]b4_lex[);
|
||||
symbol_type yylookahead (]b4_yylex[);
|
||||
yyla.move (yylookahead);]], [[
|
||||
yyla.kind_ = yytranslate_ (]b4_lex[);]])[
|
||||
yyla.kind_ = yytranslate_ (]b4_yylex[);]])[
|
||||
}
|
||||
#if YY_EXCEPTIONS
|
||||
catch (const syntax_error& yyexc)
|
||||
@@ -919,13 +927,13 @@ b4_dollar_popdef])[]dnl
|
||||
}
|
||||
YY_SYMBOL_PRINT ("Next token is", yyla);
|
||||
|
||||
if (yyla.kind () == ]b4_symbol(1, kind)[)
|
||||
if (yyla.kind () == ]b4_symbol(error, 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_ = ]b4_symbol(2, kind)[;
|
||||
yyla.kind_ = ]b4_symbol(undef, kind)[;
|
||||
goto yyerrlab1;
|
||||
}
|
||||
|
||||
@@ -935,7 +943,7 @@ b4_dollar_popdef])[]dnl
|
||||
if (yyn < 0 || yylast_ < yyn || yycheck_[yyn] != yyla.kind ())
|
||||
{]b4_lac_if([[
|
||||
if (!yy_lac_establish_ (yyla.kind ()))
|
||||
goto yyerrlab;]])[
|
||||
goto yyerrlab;]])[
|
||||
goto yydefault;
|
||||
}
|
||||
|
||||
@@ -946,7 +954,7 @@ b4_dollar_popdef])[]dnl
|
||||
if (yy_table_value_is_error_ (yyn))
|
||||
goto yyerrlab;]b4_lac_if([[
|
||||
if (!yy_lac_establish_ (yyla.kind ()))
|
||||
goto yyerrlab;
|
||||
goto yyerrlab;
|
||||
]])[
|
||||
yyn = -yyn;
|
||||
goto yyreduce;
|
||||
@@ -979,11 +987,11 @@ b4_dollar_popdef])[]dnl
|
||||
yylen = yyr2_[yyn];
|
||||
{
|
||||
stack_symbol_type yylhs;
|
||||
yylhs.state = yy_lr_goto_state_ (yystack_[yylen].state, yyr1_[yyn]);]b4_variant_if([
|
||||
yylhs.state = yy_lr_goto_state_ (yystack_[yylen].state, yyr1_[yyn]);]b4_variant_if([[
|
||||
/* Variants are always initialized to an empty instance of the
|
||||
correct type. The default '$$ = $1' action is NOT applied
|
||||
when using variants. */
|
||||
b4_symbol_variant([[yyr1_@{yyn@}]], [yylhs.value], [emplace])], [
|
||||
]b4_symbol_variant([[yyr1_@{yyn@}]], [yylhs.value], [emplace])], [[
|
||||
/* If YYLEN is nonzero, implement the default value of the
|
||||
action: '$$ = $1'. Otherwise, use the top of the stack.
|
||||
|
||||
@@ -993,7 +1001,7 @@ b4_dollar_popdef])[]dnl
|
||||
if (yylen)
|
||||
yylhs.value = yystack_@{yylen - 1@}.value;
|
||||
else
|
||||
yylhs.value = yystack_@{0@}.value;])[
|
||||
yylhs.value = yystack_@{0@}.value;]])[
|
||||
]b4_locations_if([dnl
|
||||
[
|
||||
// Default location.
|
||||
@@ -1062,7 +1070,7 @@ b4_dollar_popdef])[]dnl
|
||||
error, discard it. */
|
||||
|
||||
// Return failure if at end of input.
|
||||
if (yyla.kind () == ]b4_symbol(0, kind)[)
|
||||
if (yyla.kind () == ]b4_symbol(eof, kind)[)
|
||||
YYABORT;
|
||||
else if (!yyla.empty ())
|
||||
{
|
||||
@@ -1103,9 +1111,9 @@ b4_dollar_popdef])[]dnl
|
||||
yyn = yypact_[+yystack_[0].state];
|
||||
if (!yy_pact_value_is_default_ (yyn))
|
||||
{
|
||||
yyn += ]b4_symbol(1, kind)[;
|
||||
yyn += ]b4_symbol(error, kind)[;
|
||||
if (0 <= yyn && yyn <= yylast_
|
||||
&& yycheck_[yyn] == ]b4_symbol(1, kind)[)
|
||||
&& yycheck_[yyn] == ]b4_symbol(error, kind)[)
|
||||
{
|
||||
yyn = yytable_[yyn];
|
||||
if (0 < yyn)
|
||||
@@ -1297,8 +1305,8 @@ b4_dollar_popdef])[]dnl
|
||||
for (int yyx = 0; yyx < YYNTOKENS; ++yyx)
|
||||
{
|
||||
symbol_kind_type yysym = YY_CAST (symbol_kind_type, yyx);
|
||||
if (yysym != ]b4_symbol(1, kind)[
|
||||
&& yysym != ]b4_symbol(2, kind)[
|
||||
if (yysym != ]b4_symbol(error, kind)[
|
||||
&& yysym != ]b4_symbol(undef, kind)[
|
||||
&& yyparser_.yy_lac_check_ (yysym))
|
||||
{
|
||||
if (!yyarg)
|
||||
@@ -1309,18 +1317,18 @@ b4_dollar_popdef])[]dnl
|
||||
yyarg[yycount++] = yysym;
|
||||
}
|
||||
}]], [[
|
||||
int yyn = yypact_[+yyparser_.yystack_[0].state];
|
||||
const int yyn = yypact_[+yyparser_.yystack_[0].state];
|
||||
if (!yy_pact_value_is_default_ (yyn))
|
||||
{
|
||||
/* Start YYX at -YYN if negative to avoid negative indexes in
|
||||
YYCHECK. In other words, skip the first -YYN actions for
|
||||
this state because they are default actions. */
|
||||
int yyxbegin = yyn < 0 ? -yyn : 0;
|
||||
const int yyxbegin = yyn < 0 ? -yyn : 0;
|
||||
// Stay within bounds of both yycheck and yytname.
|
||||
int yychecklim = yylast_ - yyn + 1;
|
||||
int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
|
||||
const int yychecklim = yylast_ - yyn + 1;
|
||||
const int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
|
||||
for (int yyx = yyxbegin; yyx < yyxend; ++yyx)
|
||||
if (yycheck_[yyx + yyn] == yyx && yyx != ]b4_symbol(1, kind)[
|
||||
if (yycheck_[yyx + yyn] == yyx && yyx != ]b4_symbol(error, kind)[
|
||||
&& !yy_table_value_is_error_ (yytable_[yyx + yyn]))
|
||||
{
|
||||
if (!yyarg)
|
||||
@@ -1333,11 +1341,13 @@ b4_dollar_popdef])[]dnl
|
||||
}
|
||||
]])[
|
||||
if (yyarg && yycount == 0 && 0 < yyargn)
|
||||
yyarg[0] = ]b4_symbol(-2, kind)[;
|
||||
yyarg[0] = ]b4_symbol(empty, kind)[;
|
||||
return yycount;
|
||||
}
|
||||
|
||||
]])b4_lac_if([[
|
||||
]])[
|
||||
|
||||
]b4_lac_if([[
|
||||
bool
|
||||
]b4_parser_class[::yy_lac_check_ (symbol_kind_type yytoken) const
|
||||
{
|
||||
@@ -1442,7 +1452,9 @@ b4_dollar_popdef])[]dnl
|
||||
follows. If no initial context is currently established for the
|
||||
current lookahead, then check if that lookahead can eventually be
|
||||
shifted if syntactic actions continue from the current context. */
|
||||
if (!yy_lac_established_)
|
||||
if (yy_lac_established_)
|
||||
return true;
|
||||
else
|
||||
{
|
||||
#if ]b4_api_PREFIX[DEBUG
|
||||
YYCDEBUG << "LAC: initial context established for "
|
||||
@@ -1451,12 +1463,11 @@ b4_dollar_popdef])[]dnl
|
||||
yy_lac_established_ = true;
|
||||
return yy_lac_check_ (yytoken);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Discard any previous initial lookahead context.
|
||||
void
|
||||
]b4_parser_class[::yy_lac_discard_ (const char* evt)
|
||||
]b4_parser_class[::yy_lac_discard_ (const char* event)
|
||||
{
|
||||
/* Discard any previous initial lookahead context because of Event,
|
||||
which may be a lookahead change or an invalidation of the currently
|
||||
@@ -1472,11 +1483,12 @@ b4_dollar_popdef])[]dnl
|
||||
if (yy_lac_established_)
|
||||
{
|
||||
YYCDEBUG << "LAC: initial context discarded due to "
|
||||
<< evt << '\n';
|
||||
<< event << '\n';
|
||||
yy_lac_established_ = false;
|
||||
}
|
||||
}]])b4_parse_error_bmatch([detailed\|verbose], [[
|
||||
}]])[
|
||||
|
||||
]b4_parse_error_bmatch([detailed\|verbose], [[
|
||||
int
|
||||
]b4_parser_class[::yy_syntax_error_arguments_ (const context& yyctx,
|
||||
symbol_kind_type yyarg[], int yyargn) const
|
||||
|
||||
+665
-262
File diff suppressed because it is too large
Load Diff
+296
-103
@@ -1,4 +1,4 @@
|
||||
# Java skeleton for Bison -*- autoconf -*-
|
||||
# Java skeleton for Bison -*- java -*-
|
||||
|
||||
# Copyright (C) 2007-2015, 2018-2021 Free Software Foundation, Inc.
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
m4_include(b4_skeletonsdir/[java.m4])
|
||||
|
||||
b4_defines_if([b4_complain([%defines does not make sense in Java])])
|
||||
b4_header_if([b4_complain([%header/%defines does not make sense in Java])])
|
||||
|
||||
m4_define([b4_symbol_no_destructor_assert],
|
||||
[b4_symbol_if([$1], [has_destructor],
|
||||
@@ -25,7 +25,10 @@ m4_define([b4_symbol_no_destructor_assert],
|
||||
[%destructor does not make sense in Java])])])
|
||||
b4_symbol_foreach([b4_symbol_no_destructor_assert])
|
||||
|
||||
# Setup some macros for api.push-pull.
|
||||
## --------------- ##
|
||||
## api.push-pull. ##
|
||||
## --------------- ##
|
||||
|
||||
b4_percent_define_default([[api.push-pull]], [[pull]])
|
||||
b4_percent_define_check_values([[[[api.push-pull]],
|
||||
[[pull]], [[push]], [[both]]]])
|
||||
@@ -52,7 +55,8 @@ b4_use_push_for_pull_if([
|
||||
# Define a macro to encapsulate the parse state variables. This
|
||||
# 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],[[
|
||||
m4_define([b4_define_state],
|
||||
[[
|
||||
/* Lookahead token kind. */
|
||||
int yychar = YYEMPTY_;
|
||||
/* Lookahead symbol kind. */
|
||||
@@ -74,9 +78,22 @@ m4_define([b4_define_state],[[
|
||||
|
||||
/* Semantic value of the lookahead. */
|
||||
]b4_yystype[ yylval = null;
|
||||
]])[
|
||||
]])
|
||||
|
||||
]b4_output_begin([b4_parser_file_name])[
|
||||
# parse.lac
|
||||
b4_percent_define_default([[parse.lac]], [[none]])
|
||||
b4_percent_define_check_values([[[[parse.lac]], [[full]], [[none]]]])
|
||||
b4_define_flag_if([lac])
|
||||
m4_define([b4_lac_flag],
|
||||
[m4_if(b4_percent_define_get([[parse.lac]]),
|
||||
[none], [[0]], [[1]])])
|
||||
|
||||
|
||||
## ------------- ##
|
||||
## Parser File. ##
|
||||
## ------------- ##
|
||||
|
||||
b4_output_begin([b4_parser_file_name])[
|
||||
]b4_copyright([Skeleton implementation for Bison LALR(1) parsers in Java],
|
||||
[2007-2015, 2018-2021])[
|
||||
]b4_disclaimer[
|
||||
@@ -85,6 +102,7 @@ m4_define([b4_define_state],[[
|
||||
]b4_user_pre_prologue[
|
||||
]b4_user_post_prologue[
|
||||
import java.text.MessageFormat;
|
||||
import java.util.ArrayList;
|
||||
]b4_percent_code_get([[imports]])[
|
||||
/**
|
||||
* A Bison parser, automatically generated from <tt>]m4_bpatsubst(b4_file_name, [^"\(.*\)"$], [\1])[</tt>.
|
||||
@@ -157,11 +175,11 @@ import java.text.MessageFormat;
|
||||
* <code>]b4_position_type[</code> should override the <code>equals</code>
|
||||
* method.
|
||||
*/
|
||||
public String toString () {
|
||||
public String toString() {
|
||||
if (begin.equals (end))
|
||||
return begin.toString ();
|
||||
return begin.toString();
|
||||
else
|
||||
return begin.toString () + "-" + end.toString ();
|
||||
return begin.toString() + "-" + end.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -181,8 +199,8 @@ import java.text.MessageFormat;
|
||||
*/
|
||||
public interface Lexer {
|
||||
]b4_token_enums[
|
||||
/** Deprecated, use ]b4_symbol(0, id)[ instead. */
|
||||
public static final int EOF = ]b4_symbol(0, id)[;
|
||||
/** Deprecated, use ]b4_symbol(eof, id)[ instead. */
|
||||
public static final int EOF = ]b4_symbol(eof, id)[;
|
||||
]b4_pull_if([b4_locations_if([[
|
||||
/**
|
||||
* Method to retrieve the beginning position of the last scanned token.
|
||||
@@ -226,7 +244,7 @@ import java.text.MessageFormat;
|
||||
*
|
||||
* @@param ctx The context of the error.
|
||||
*/
|
||||
void reportSyntaxError (][Context ctx);
|
||||
void reportSyntaxError(Context ctx);
|
||||
]])[
|
||||
}
|
||||
|
||||
@@ -247,10 +265,12 @@ import java.text.MessageFormat;
|
||||
/**
|
||||
* Instantiates the Bison-generated parser.
|
||||
*/
|
||||
public ]b4_parser_class (b4_parse_param_decl([b4_lex_param_decl])[)]b4_maybe_throws([b4_init_throws])[
|
||||
public ]b4_parser_class[(]b4_parse_param_decl([b4_lex_param_decl])[)]b4_maybe_throws([b4_init_throws])[
|
||||
{
|
||||
]b4_percent_code_get([[init]])[
|
||||
this.yylexer = new YYLexer (]b4_lex_param_call[);
|
||||
]b4_percent_code_get([[init]])[]b4_lac_if([[
|
||||
this.yylacStack = new ArrayList<Integer>();
|
||||
this.yylacEstablished = false;]])[
|
||||
this.yylexer = new YYLexer(]b4_lex_param_call[);
|
||||
]b4_parse_param_cons[
|
||||
}
|
||||
]])[
|
||||
@@ -259,9 +279,11 @@ import java.text.MessageFormat;
|
||||
* Instantiates the Bison-generated parser.
|
||||
* @@param yylexer The scanner that will supply tokens to the parser.
|
||||
*/
|
||||
]b4_lexer_if([[protected]], [[public]]) b4_parser_class[ (]b4_parse_param_decl([[Lexer yylexer]])[)]b4_maybe_throws([b4_init_throws])[
|
||||
]b4_lexer_if([[protected]], [[public]]) b4_parser_class[(]b4_parse_param_decl([[Lexer yylexer]])[)]b4_maybe_throws([b4_init_throws])[
|
||||
{
|
||||
]b4_percent_code_get([[init]])[
|
||||
]b4_percent_code_get([[init]])[]b4_lac_if([[
|
||||
this.yylacStack = new ArrayList<Integer>();
|
||||
this.yylacEstablished = false;]])[
|
||||
this.yylexer = yylexer;
|
||||
]b4_parse_param_cons[
|
||||
}
|
||||
@@ -272,13 +294,13 @@ import java.text.MessageFormat;
|
||||
/**
|
||||
* The <tt>PrintStream</tt> on which the debugging output is printed.
|
||||
*/
|
||||
public final java.io.PrintStream getDebugStream () { return yyDebugStream; }
|
||||
public final java.io.PrintStream getDebugStream() { return yyDebugStream; }
|
||||
|
||||
/**
|
||||
* Set the <tt>PrintStream</tt> on which the debug output is printed.
|
||||
* @@param s The stream that is used for debugging output.
|
||||
*/
|
||||
public final void setDebugStream (java.io.PrintStream s) { yyDebugStream = s; }
|
||||
public final void setDebugStream(java.io.PrintStream s) { yyDebugStream = s; }
|
||||
|
||||
private int yydebug = 0;
|
||||
|
||||
@@ -286,14 +308,14 @@ import java.text.MessageFormat;
|
||||
* Answer the verbosity of the debugging output; 0 means that all kinds of
|
||||
* output from the parser are suppressed.
|
||||
*/
|
||||
public final int getDebugLevel () { return yydebug; }
|
||||
public final int getDebugLevel() { return yydebug; }
|
||||
|
||||
/**
|
||||
* Set the verbosity of the debugging output; 0 means that all kinds of
|
||||
* output from the parser are suppressed.
|
||||
* @@param level The verbosity level for debugging output.
|
||||
*/
|
||||
public final void setDebugLevel (int level) { yydebug = level; }
|
||||
public final void setDebugLevel(int level) { yydebug = level; }
|
||||
]])[
|
||||
|
||||
private int yynerrs = 0;
|
||||
@@ -301,7 +323,7 @@ import java.text.MessageFormat;
|
||||
/**
|
||||
* The number of syntax errors so far.
|
||||
*/
|
||||
public final int getNumberOfErrors () { return yynerrs; }
|
||||
public final int getNumberOfErrors() { return yynerrs; }
|
||||
|
||||
/**
|
||||
* Print an error message via the lexer.
|
||||
@@ -330,9 +352,14 @@ import java.text.MessageFormat;
|
||||
yylexer.yyerror(new ]b4_location_type[ (pos), msg);
|
||||
}]])[
|
||||
]b4_parse_trace_if([[
|
||||
protected final void yycdebug (String s) {
|
||||
protected final void yycdebugNnl(String s) {
|
||||
if (0 < yydebug)
|
||||
yyDebugStream.println (s);
|
||||
yyDebugStream.print(s);
|
||||
}
|
||||
|
||||
protected final void yycdebug(String s) {
|
||||
if (0 < yydebug)
|
||||
yyDebugStream.println(s);
|
||||
}]])[
|
||||
|
||||
private final class YYStack {
|
||||
@@ -343,65 +370,63 @@ import java.text.MessageFormat;
|
||||
public int size = 16;
|
||||
public int height = -1;
|
||||
|
||||
public final void push (int state, ]b4_yystype[ value]b4_locations_if([, ]b4_location_type[ loc])[) {
|
||||
public final void push(int state, ]b4_yystype[ value]b4_locations_if([, ]b4_location_type[ loc])[) {
|
||||
height++;
|
||||
if (size == height)
|
||||
{
|
||||
int[] newStateStack = new int[size * 2];
|
||||
System.arraycopy (stateStack, 0, newStateStack, 0, height);
|
||||
stateStack = newStateStack;]b4_locations_if([[
|
||||
]b4_location_type[[] newLocStack = new ]b4_location_type[[size * 2];
|
||||
System.arraycopy (locStack, 0, newLocStack, 0, height);
|
||||
locStack = newLocStack;]])
|
||||
if (size == height) {
|
||||
int[] newStateStack = new int[size * 2];
|
||||
System.arraycopy(stateStack, 0, newStateStack, 0, height);
|
||||
stateStack = newStateStack;]b4_locations_if([[
|
||||
]b4_location_type[[] newLocStack = new ]b4_location_type[[size * 2];
|
||||
System.arraycopy(locStack, 0, newLocStack, 0, height);
|
||||
locStack = newLocStack;]])
|
||||
|
||||
b4_yystype[[] newValueStack = new ]b4_yystype[[size * 2];
|
||||
System.arraycopy (valueStack, 0, newValueStack, 0, height);
|
||||
valueStack = newValueStack;
|
||||
b4_yystype[[] newValueStack = new ]b4_yystype[[size * 2];
|
||||
System.arraycopy(valueStack, 0, newValueStack, 0, height);
|
||||
valueStack = newValueStack;
|
||||
|
||||
size *= 2;
|
||||
}
|
||||
size *= 2;
|
||||
}
|
||||
|
||||
stateStack[height] = state;]b4_locations_if([[
|
||||
locStack[height] = loc;]])[
|
||||
valueStack[height] = value;
|
||||
}
|
||||
|
||||
public final void pop () {
|
||||
pop (1);
|
||||
public final void pop() {
|
||||
pop(1);
|
||||
}
|
||||
|
||||
public final void pop (int num) {
|
||||
public final void pop(int num) {
|
||||
// Avoid memory leaks... garbage collection is a white lie!
|
||||
if (0 < num) {
|
||||
java.util.Arrays.fill (valueStack, height - num + 1, height + 1, null);]b4_locations_if([[
|
||||
java.util.Arrays.fill (locStack, height - num + 1, height + 1, null);]])[
|
||||
java.util.Arrays.fill(valueStack, height - num + 1, height + 1, null);]b4_locations_if([[
|
||||
java.util.Arrays.fill(locStack, height - num + 1, height + 1, null);]])[
|
||||
}
|
||||
height -= num;
|
||||
}
|
||||
|
||||
public final int stateAt (int i) {
|
||||
public final int stateAt(int i) {
|
||||
return stateStack[height - i];
|
||||
}
|
||||
]b4_locations_if([[
|
||||
|
||||
public final ]b4_location_type[ locationAt (int i) {
|
||||
public final ]b4_location_type[ locationAt(int i) {
|
||||
return locStack[height - i];
|
||||
}
|
||||
]])[
|
||||
public final ]b4_yystype[ valueAt (int i) {
|
||||
public final ]b4_yystype[ valueAt(int i) {
|
||||
return valueStack[height - i];
|
||||
}
|
||||
|
||||
// Print the state stack on the debug stream.
|
||||
public void print (java.io.PrintStream out) {
|
||||
public void print(java.io.PrintStream out) {
|
||||
out.print ("Stack now");
|
||||
|
||||
for (int i = 0; i <= height; i++)
|
||||
{
|
||||
out.print (' ');
|
||||
out.print (stateStack[i]);
|
||||
}
|
||||
out.println ();
|
||||
for (int i = 0; i <= height; i++) {
|
||||
out.print(' ');
|
||||
out.print(stateStack[i]);
|
||||
}
|
||||
out.println();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -458,8 +483,7 @@ import java.text.MessageFormat;
|
||||
* @@param yystate the current state
|
||||
* @@param yysym the nonterminal to push on the stack
|
||||
*/
|
||||
private int yyLRGotoState (int yystate, int yysym)
|
||||
{
|
||||
private int yyLRGotoState(int yystate, int yysym) {
|
||||
int yyr = yypgoto_[yysym - YYNTOKENS_] + yystate;
|
||||
if (0 <= yyr && yyr <= YYLAST_ && yycheck_[yyr] == yystate)
|
||||
return yytable_[yyr];
|
||||
@@ -536,7 +560,12 @@ import java.text.MessageFormat;
|
||||
/* @@$. */
|
||||
]b4_location_type[ yyloc;]])[
|
||||
]b4_push_if([],[[
|
||||
]b4_define_state[]b4_parse_trace_if([[
|
||||
]b4_define_state[
|
||||
]b4_lac_if([[
|
||||
// Discard the LAC context in case there still is one left from a
|
||||
// previous invocation.
|
||||
yylacDiscard("init");]])[
|
||||
]b4_parse_trace_if([[
|
||||
yycdebug ("Starting parse");]])[
|
||||
yyerrstatus_ = 0;
|
||||
yynerrs = 0;
|
||||
@@ -614,14 +643,14 @@ b4_dollar_popdef[]dnl
|
||||
yySymbolPrint("Next token is", yytoken,
|
||||
yylval]b4_locations_if([, yylloc])[);]])[
|
||||
|
||||
if (yytoken == ]b4_symbol(1, kind)[)
|
||||
if (yytoken == ]b4_symbol(error, 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_symbol(2, id)[;
|
||||
yytoken = ]b4_symbol(2, kind)[;]b4_locations_if([[
|
||||
yychar = Lexer.]b4_symbol(undef, id)[;
|
||||
yytoken = ]b4_symbol(undef, kind)[;]b4_locations_if([[
|
||||
yyerrloc = yylloc;]])[
|
||||
label = YYERRLAB1;
|
||||
}
|
||||
@@ -630,19 +659,24 @@ 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())
|
||||
if (yyn < 0 || YYLAST_ < yyn || yycheck_[yyn] != yytoken.getCode()) {]b4_lac_if([[
|
||||
if (!yylacEstablish(yystack, yytoken)) {
|
||||
label = YYERRLAB;
|
||||
} else]])[
|
||||
label = YYDEFAULT;
|
||||
}
|
||||
|
||||
/* <= 0 means reduce or error. */
|
||||
else if ((yyn = yytable_[yyn]) <= 0)
|
||||
{
|
||||
if (yyTableValueIsError (yyn))
|
||||
if (yyTableValueIsError(yyn)) {
|
||||
label = YYERRLAB;
|
||||
else
|
||||
{
|
||||
yyn = -yyn;
|
||||
label = YYREDUCE;
|
||||
}
|
||||
}]b4_lac_if([[ else if (!yylacEstablish(yystack, yytoken)) {
|
||||
label = YYERRLAB;
|
||||
}]])[ else {
|
||||
yyn = -yyn;
|
||||
label = YYREDUCE;
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
@@ -660,7 +694,8 @@ b4_dollar_popdef[]dnl
|
||||
--yyerrstatus_;
|
||||
|
||||
yystate = yyn;
|
||||
yystack.push (yystate, yylval]b4_locations_if([, yylloc])[);
|
||||
yystack.push(yystate, yylval]b4_locations_if([, yylloc])[);]b4_lac_if([[
|
||||
yylacDiscard("shift");]])[
|
||||
label = YYNEWSTATE;
|
||||
}
|
||||
}
|
||||
@@ -683,7 +718,7 @@ b4_dollar_popdef[]dnl
|
||||
case YYREDUCE:
|
||||
yylen = yyr2_[yyn];
|
||||
label = yyaction(yyn, yystack, yylen);
|
||||
yystate = yystack.stateAt (0);
|
||||
yystate = yystack.stateAt(0);
|
||||
break;
|
||||
|
||||
/*------------------------------------.
|
||||
@@ -696,7 +731,7 @@ b4_dollar_popdef[]dnl
|
||||
++yynerrs;
|
||||
if (yychar == YYEMPTY_)
|
||||
yytoken = null;
|
||||
yyreportSyntaxError (new Context (yystack, yytoken]b4_locations_if([[, yylloc]])[));
|
||||
yyreportSyntaxError(new Context(this, yystack, yytoken]b4_locations_if([[, yylloc]])[));
|
||||
}
|
||||
]b4_locations_if([[
|
||||
yyerrloc = yylloc;]])[
|
||||
@@ -705,10 +740,10 @@ b4_dollar_popdef[]dnl
|
||||
/* If just tried and failed to reuse lookahead token after an
|
||||
error, discard it. */
|
||||
|
||||
if (yychar <= Lexer.]b4_symbol(0, id)[)
|
||||
if (yychar <= Lexer.]b4_symbol(eof, id)[)
|
||||
{
|
||||
/* Return failure if at end of input. */
|
||||
if (yychar == Lexer.]b4_symbol(0, id)[)
|
||||
if (yychar == Lexer.]b4_symbol(eof, id)[)
|
||||
]b4_push_if([{label = YYABORT; break;}], [return false;])[
|
||||
}
|
||||
else
|
||||
@@ -729,7 +764,7 @@ b4_dollar_popdef[]dnl
|
||||
this YYERROR. */
|
||||
yystack.pop (yylen);
|
||||
yylen = 0;
|
||||
yystate = yystack.stateAt (0);
|
||||
yystate = yystack.stateAt(0);
|
||||
label = YYERRLAB1;
|
||||
break;
|
||||
|
||||
@@ -745,9 +780,9 @@ b4_dollar_popdef[]dnl
|
||||
yyn = yypact_[yystate];
|
||||
if (!yyPactValueIsDefault (yyn))
|
||||
{
|
||||
yyn += ]b4_symbol(1, kind)[.getCode();
|
||||
yyn += ]b4_symbol(error, kind)[.getCode();
|
||||
if (0 <= yyn && yyn <= YYLAST_
|
||||
&& yycheck_[yyn] == ]b4_symbol(1, kind)[.getCode())
|
||||
&& yycheck_[yyn] == ]b4_symbol(error, kind)[.getCode())
|
||||
{
|
||||
yyn = yytable_[yyn];
|
||||
if (0 < yyn)
|
||||
@@ -763,7 +798,7 @@ b4_dollar_popdef[]dnl
|
||||
]b4_locations_if([[
|
||||
yyerrloc = yystack.locationAt (0);]])[
|
||||
yystack.pop ();
|
||||
yystate = yystack.stateAt (0);]b4_parse_trace_if([[
|
||||
yystate = yystack.stateAt(0);]b4_parse_trace_if([[
|
||||
if (0 < yydebug)
|
||||
yystack.print (yyDebugStream);]])[
|
||||
}
|
||||
@@ -779,7 +814,8 @@ b4_dollar_popdef[]dnl
|
||||
yyloc = yylloc (yystack, 2);
|
||||
yystack.pop (2);]])[
|
||||
|
||||
/* Shift the error token. */]b4_parse_trace_if([[
|
||||
/* Shift the error token. */]b4_lac_if([[
|
||||
yylacDiscard("error recovery");]])[]b4_parse_trace_if([[
|
||||
yySymbolPrint("Shifting", SymbolKind.get(yystos_[yyn]),
|
||||
yylval]b4_locations_if([, yyloc])[);]])[
|
||||
|
||||
@@ -815,7 +851,9 @@ b4_dollar_popdef[]dnl
|
||||
this.yyn = 0;
|
||||
this.yylen = 0;
|
||||
this.yystate = 0;
|
||||
this.yystack = new YYStack ();
|
||||
this.yystack = new YYStack();]b4_lac_if([[
|
||||
this.yylacStack = new ArrayList<Integer>();
|
||||
this.yylacEstablished = false;]])[
|
||||
this.label = YYNEWSTATE;
|
||||
|
||||
/* Error handling. */
|
||||
@@ -875,23 +913,22 @@ b4_dollar_popdef[]dnl
|
||||
* Information needed to get the list of expected tokens and to forge
|
||||
* a syntax error diagnostic.
|
||||
*/
|
||||
public static final class Context
|
||||
{
|
||||
Context (YYStack stack, SymbolKind token]b4_locations_if([[, ]b4_location_type[ loc]])[)
|
||||
{
|
||||
public static final class Context {
|
||||
Context(]b4_parser_class[ parser, YYStack stack, SymbolKind token]b4_locations_if([[, ]b4_location_type[ loc]])[) {
|
||||
yyparser = parser;
|
||||
yystack = stack;
|
||||
yytoken = token;]b4_locations_if([[
|
||||
yylocation = loc;]])[
|
||||
}
|
||||
|
||||
private ]b4_parser_class[ yyparser;
|
||||
private YYStack yystack;
|
||||
|
||||
|
||||
/**
|
||||
* The symbol kind of the lookahead token.
|
||||
*/
|
||||
public final SymbolKind getToken ()
|
||||
{
|
||||
public final SymbolKind getToken() {
|
||||
return yytoken;
|
||||
}
|
||||
|
||||
@@ -900,8 +937,7 @@ b4_dollar_popdef[]dnl
|
||||
/**
|
||||
* The location of the lookahead.
|
||||
*/
|
||||
public final ]b4_location_type[ getLocation ()
|
||||
{
|
||||
public final ]b4_location_type[ getLocation() {
|
||||
return yylocation;
|
||||
}
|
||||
|
||||
@@ -914,16 +950,34 @@ b4_dollar_popdef[]dnl
|
||||
* YYARG is null, return the number of expected tokens (guaranteed to
|
||||
* be less than YYNTOKENS).
|
||||
*/
|
||||
int getExpectedTokens (SymbolKind yyarg[], int yyargn)
|
||||
{
|
||||
int getExpectedTokens(SymbolKind yyarg[], int yyargn) {
|
||||
return getExpectedTokens (yyarg, 0, yyargn);
|
||||
}
|
||||
|
||||
int getExpectedTokens (SymbolKind yyarg[], int yyoffset, int yyargn)
|
||||
{
|
||||
int yycount = yyoffset;
|
||||
int yyn = yypact_[this.yystack.stateAt (0)];
|
||||
if (!yyPactValueIsDefault (yyn))
|
||||
int getExpectedTokens(SymbolKind yyarg[], int yyoffset, int yyargn) {
|
||||
int yycount = yyoffset;]b4_lac_if([b4_parse_trace_if([[
|
||||
// Execute LAC once. We don't care if it is successful, we
|
||||
// only do it for the sake of debugging output.
|
||||
if (!yyparser.yylacEstablished)
|
||||
yyparser.yylacCheck(yystack, yytoken);
|
||||
]])[
|
||||
for (int yyx = 0; yyx < YYNTOKENS_; ++yyx)
|
||||
{
|
||||
SymbolKind yysym = SymbolKind.get(yyx);
|
||||
if (yysym != ]b4_symbol(error, kind)[
|
||||
&& yysym != ]b4_symbol(undef, kind)[
|
||||
&& yyparser.yylacCheck(yystack, yysym))
|
||||
{
|
||||
if (yyarg == null)
|
||||
yycount += 1;
|
||||
else if (yycount == yyargn)
|
||||
return 0;
|
||||
else
|
||||
yyarg[yycount++] = yysym;
|
||||
}
|
||||
}]], [[
|
||||
int yyn = yypact_[this.yystack.stateAt(0)];
|
||||
if (!yyPactValueIsDefault(yyn))
|
||||
{
|
||||
/* Start YYX at -YYN if negative to avoid negative
|
||||
indexes in YYCHECK. In other words, skip the first
|
||||
@@ -934,7 +988,7 @@ 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 != ]b4_symbol(1, kind)[.getCode()
|
||||
if (yycheck_[yyx + yyn] == yyx && yyx != ]b4_symbol(error, kind)[.getCode()
|
||||
&& !yyTableValueIsError(yytable_[yyx + yyn]))
|
||||
{
|
||||
if (yyarg == null)
|
||||
@@ -944,17 +998,158 @@ b4_dollar_popdef[]dnl
|
||||
else
|
||||
yyarg[yycount++] = SymbolKind.get(yyx);
|
||||
}
|
||||
}
|
||||
}]])[
|
||||
if (yyarg != null && yycount == yyoffset && yyoffset < yyargn)
|
||||
yyarg[yycount] = null;
|
||||
return yycount - yyoffset;
|
||||
}
|
||||
}
|
||||
|
||||
]b4_lac_if([[
|
||||
/** Check the lookahead yytoken.
|
||||
* \returns true iff the token will be eventually shifted.
|
||||
*/
|
||||
boolean yylacCheck(YYStack yystack, SymbolKind yytoken)
|
||||
{
|
||||
// Logically, the yylacStack's lifetime is confined to this function.
|
||||
// Clear it, to get rid of potential left-overs from previous call.
|
||||
yylacStack.clear();
|
||||
// Reduce until we encounter a shift and thereby accept the token.
|
||||
yycdebugNnl("LAC: checking lookahead " + yytoken.getName() + ":");
|
||||
int lacTop = 0;
|
||||
while (true)
|
||||
{
|
||||
int topState = (yylacStack.isEmpty()
|
||||
? yystack.stateAt(lacTop)
|
||||
: yylacStack.get(yylacStack.size() - 1));
|
||||
int yyrule = yypact_[topState];
|
||||
if (yyPactValueIsDefault(yyrule)
|
||||
|| (yyrule += yytoken.getCode()) < 0 || YYLAST_ < yyrule
|
||||
|| yycheck_[yyrule] != yytoken.getCode())
|
||||
{
|
||||
// Use the default action.
|
||||
yyrule = yydefact_[+topState];
|
||||
if (yyrule == 0) {
|
||||
yycdebug(" Err");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Use the action from yytable.
|
||||
yyrule = yytable_[yyrule];
|
||||
if (yyTableValueIsError(yyrule)) {
|
||||
yycdebug(" Err");
|
||||
return false;
|
||||
}
|
||||
if (0 < yyrule) {
|
||||
yycdebug(" S" + yyrule);
|
||||
return true;
|
||||
}
|
||||
yyrule = -yyrule;
|
||||
}
|
||||
// By now we know we have to simulate a reduce.
|
||||
yycdebugNnl(" R" + (yyrule - 1));
|
||||
// Pop the corresponding number of values from the stack.
|
||||
{
|
||||
int yylen = yyr2_[yyrule];
|
||||
// First pop from the LAC stack as many tokens as possible.
|
||||
int lacSize = yylacStack.size();
|
||||
if (yylen < lacSize) {
|
||||
// yylacStack.setSize(lacSize - yylen);
|
||||
for (/* Nothing */; 0 < yylen; yylen -= 1) {
|
||||
yylacStack.remove(yylacStack.size() - 1);
|
||||
}
|
||||
yylen = 0;
|
||||
} else if (lacSize != 0) {
|
||||
yylacStack.clear();
|
||||
yylen -= lacSize;
|
||||
}
|
||||
// Only afterwards look at the main stack.
|
||||
// We simulate popping elements by incrementing lacTop.
|
||||
lacTop += yylen;
|
||||
}
|
||||
// Keep topState in sync with the updated stack.
|
||||
topState = (yylacStack.isEmpty()
|
||||
? yystack.stateAt(lacTop)
|
||||
: yylacStack.get(yylacStack.size() - 1));
|
||||
// Push the resulting state of the reduction.
|
||||
int state = yyLRGotoState(topState, yyr1_[yyrule]);
|
||||
yycdebugNnl(" G" + state);
|
||||
yylacStack.add(state);
|
||||
}
|
||||
}
|
||||
|
||||
/** Establish the initial context if no initial context currently exists.
|
||||
* \returns true iff the token will be eventually shifted.
|
||||
*/
|
||||
boolean yylacEstablish(YYStack yystack, SymbolKind yytoken) {
|
||||
/* Establish the initial context for the current lookahead if no initial
|
||||
context is currently established.
|
||||
|
||||
We define a context as a snapshot of the parser stacks. We define
|
||||
the initial context for a lookahead as the context in which the
|
||||
parser initially examines that lookahead in order to select a
|
||||
syntactic action. Thus, if the lookahead eventually proves
|
||||
syntactically unacceptable (possibly in a later context reached via a
|
||||
series of reductions), the initial context can be used to determine
|
||||
the exact set of tokens that would be syntactically acceptable in the
|
||||
lookahead's place. Moreover, it is the context after which any
|
||||
further semantic actions would be erroneous because they would be
|
||||
determined by a syntactically unacceptable token.
|
||||
|
||||
yylacEstablish should be invoked when a reduction is about to be
|
||||
performed in an inconsistent state (which, for the purposes of LAC,
|
||||
includes consistent states that don't know they're consistent because
|
||||
their default reductions have been disabled).
|
||||
|
||||
For parse.lac=full, the implementation of yylacEstablish is as
|
||||
follows. If no initial context is currently established for the
|
||||
current lookahead, then check if that lookahead can eventually be
|
||||
shifted if syntactic actions continue from the current context. */
|
||||
if (yylacEstablished) {
|
||||
return true;
|
||||
} else {
|
||||
yycdebug("LAC: initial context established for " + yytoken.getName());
|
||||
yylacEstablished = true;
|
||||
return yylacCheck(yystack, yytoken);
|
||||
}
|
||||
}
|
||||
|
||||
/** Discard any previous initial lookahead context because of event.
|
||||
* \param event the event which caused the lookahead to be discarded.
|
||||
* Only used for debbuging output. */
|
||||
void yylacDiscard(String event) {
|
||||
/* Discard any previous initial lookahead context because of Event,
|
||||
which may be a lookahead change or an invalidation of the currently
|
||||
established initial context for the current lookahead.
|
||||
|
||||
The most common example of a lookahead change is a shift. An example
|
||||
of both cases is syntax error recovery. That is, a syntax error
|
||||
occurs when the lookahead is syntactically erroneous for the
|
||||
currently established initial context, so error recovery manipulates
|
||||
the parser stacks to try to find a new initial context in which the
|
||||
current lookahead is syntactically acceptable. If it fails to find
|
||||
such a context, it discards the lookahead. */
|
||||
if (yylacEstablished) {
|
||||
yycdebug("LAC: initial context discarded due to " + event);
|
||||
yylacEstablished = false;
|
||||
}
|
||||
}
|
||||
|
||||
/** The stack for LAC.
|
||||
* Logically, the yylacStack's lifetime is confined to the function
|
||||
* yylacCheck. We just store it as a member of this class to hold
|
||||
* on to the memory and to avoid frequent reallocations.
|
||||
*/
|
||||
ArrayList<Integer> yylacStack;
|
||||
/** Whether an initial LAC context was established. */
|
||||
boolean yylacEstablished;
|
||||
]])[
|
||||
|
||||
]b4_parse_error_bmatch(
|
||||
[detailed\|verbose], [[
|
||||
private int yysyntaxErrorArguments (Context yyctx, SymbolKind[] yyarg, int yyargn)
|
||||
{
|
||||
private int yysyntaxErrorArguments(Context yyctx, SymbolKind[] yyarg, int yyargn) {
|
||||
/* There are many possibilities here to consider:
|
||||
- If this state is a consistent state with a default action,
|
||||
then the only way this function was invoked is if the
|
||||
@@ -1032,8 +1227,7 @@ b4_dollar_popdef[]dnl
|
||||
* Whether the given <code>yypact_</code> value indicates a defaulted state.
|
||||
* @@param yyvalue the value to check
|
||||
*/
|
||||
private static boolean yyPactValueIsDefault (int yyvalue)
|
||||
{
|
||||
private static boolean yyPactValueIsDefault(int yyvalue) {
|
||||
return yyvalue == yypact_ninf_;
|
||||
}
|
||||
|
||||
@@ -1042,8 +1236,7 @@ b4_dollar_popdef[]dnl
|
||||
* value indicates a syntax error.
|
||||
* @@param yyvalue the value to check
|
||||
*/
|
||||
private static boolean yyTableValueIsError (int yyvalue)
|
||||
{
|
||||
private static boolean yyTableValueIsError(int yyvalue) {
|
||||
return yyvalue == yytable_ninf_;
|
||||
}
|
||||
|
||||
@@ -1072,7 +1265,7 @@ 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)])[);
|
||||
}]])[
|
||||
@@ -1089,11 +1282,11 @@ b4_dollar_popdef[]dnl
|
||||
// Last valid token kind.
|
||||
int code_max = ]b4_code_max[;
|
||||
if (t <= 0)
|
||||
return ]b4_symbol(0, kind)[;
|
||||
return ]b4_symbol(eof, kind)[;
|
||||
else if (t <= code_max)
|
||||
return SymbolKind.get(yytranslate_table_[t]);
|
||||
else
|
||||
return ]b4_symbol(2, kind)[;
|
||||
return ]b4_symbol(undef, kind)[;
|
||||
}
|
||||
]b4_integral_parser_table_define([translate_table], [b4_translate])[
|
||||
]])[
|
||||
|
||||
@@ -19,20 +19,13 @@ m4_pushdef([b4_copyright_years],
|
||||
[2002-2015, 2018-2021])
|
||||
|
||||
|
||||
# b4_position_file
|
||||
# ----------------
|
||||
# Name of the file containing the position class, if we want this file.
|
||||
b4_defines_if([b4_required_version_if([30200], [],
|
||||
[m4_define([b4_position_file], [position.hh])])])])
|
||||
|
||||
|
||||
# b4_location_file
|
||||
# ----------------
|
||||
# Name of the file containing the position/location class,
|
||||
# if we want this file.
|
||||
b4_percent_define_check_file([b4_location_file],
|
||||
[[api.location.file]],
|
||||
b4_defines_if([[location.hh]]))
|
||||
b4_header_if([[location.hh]]))
|
||||
|
||||
# b4_location_include
|
||||
# -------------------
|
||||
@@ -54,6 +47,16 @@ m4_ifdef([b4_location_file],
|
||||
])
|
||||
|
||||
|
||||
# b4_position_file
|
||||
# ----------------
|
||||
# Name of the file containing the position class, if we want this file.
|
||||
b4_header_if(
|
||||
[b4_required_version_if(
|
||||
[30200], [],
|
||||
[m4_ifdef([b4_location_file],
|
||||
[m4_define([b4_position_file], [position.hh])])])])
|
||||
|
||||
|
||||
|
||||
# b4_location_define
|
||||
# ------------------
|
||||
|
||||
@@ -19,8 +19,8 @@
|
||||
# b4_stack_file
|
||||
# -------------
|
||||
# Name of the file containing the stack class, if we want this file.
|
||||
b4_defines_if([b4_required_version_if([30200], [],
|
||||
[m4_define([b4_stack_file], [stack.hh])])])
|
||||
b4_header_if([b4_required_version_if([30200], [],
|
||||
[m4_define([b4_stack_file], [stack.hh])])])
|
||||
|
||||
|
||||
# b4_stack_define
|
||||
@@ -37,7 +37,7 @@ m4_define([b4_stack_define],
|
||||
typedef typename S::size_type size_type;
|
||||
typedef typename std::ptrdiff_t index_type;
|
||||
|
||||
stack (size_type n = 200)
|
||||
stack (size_type n = 200) YY_NOEXCEPT
|
||||
: seq_ (n)
|
||||
{}
|
||||
|
||||
@@ -116,7 +116,7 @@ m4_define([b4_stack_define],
|
||||
class slice
|
||||
{
|
||||
public:
|
||||
slice (const stack& stack, index_type range)
|
||||
slice (const stack& stack, index_type range) YY_NOEXCEPT
|
||||
: stack_ (stack)
|
||||
, range_ (range)
|
||||
{}
|
||||
|
||||
+28
-26
@@ -94,28 +94,28 @@ m4_define([b4_variant_includes],
|
||||
|
||||
# b4_value_type_declare
|
||||
# ---------------------
|
||||
# Define semantic_type.
|
||||
# Define value_type.
|
||||
m4_define([b4_value_type_declare],
|
||||
[[ /// A buffer to store and retrieve objects.
|
||||
///
|
||||
/// Sort of a variant, but does not keep track of the nature
|
||||
/// of the stored data, since that knowledge is available
|
||||
/// via the current parser state.
|
||||
class semantic_type
|
||||
class value_type
|
||||
{
|
||||
public:
|
||||
/// Type of *this.
|
||||
typedef semantic_type self_type;
|
||||
typedef value_type self_type;
|
||||
|
||||
/// Empty construction.
|
||||
semantic_type () YY_NOEXCEPT
|
||||
: yybuffer_ ()]b4_parse_assert_if([
|
||||
value_type () YY_NOEXCEPT
|
||||
: yyraw_ ()]b4_parse_assert_if([
|
||||
, yytypeid_ (YY_NULLPTR)])[
|
||||
{}
|
||||
|
||||
/// Construct and fill.
|
||||
template <typename T>
|
||||
semantic_type (YY_RVREF (T) t)]b4_parse_assert_if([
|
||||
value_type (YY_RVREF (T) t)]b4_parse_assert_if([
|
||||
: yytypeid_ (&typeid (T))])[
|
||||
{]b4_parse_assert_if([[
|
||||
]b4_assert[ (sizeof (T) <= size);]])[
|
||||
@@ -124,13 +124,13 @@ m4_define([b4_value_type_declare],
|
||||
|
||||
#if 201103L <= YY_CPLUSPLUS
|
||||
/// Non copyable.
|
||||
semantic_type (const self_type&) = delete;
|
||||
value_type (const self_type&) = delete;
|
||||
/// Non copyable.
|
||||
self_type& operator= (const self_type&) = delete;
|
||||
#endif
|
||||
|
||||
/// Destruction, allowed only if empty.
|
||||
~semantic_type () YY_NOEXCEPT
|
||||
~value_type () YY_NOEXCEPT
|
||||
{]b4_parse_assert_if([
|
||||
]b4_assert[ (!yytypeid_);
|
||||
])[}
|
||||
@@ -274,7 +274,7 @@ m4_define([b4_value_type_declare],
|
||||
private:
|
||||
#if YY_CPLUSPLUS < 201103L
|
||||
/// Non copyable.
|
||||
semantic_type (const self_type&);
|
||||
value_type (const self_type&);
|
||||
/// Non copyable.
|
||||
self_type& operator= (const self_type&);
|
||||
#endif
|
||||
@@ -284,7 +284,7 @@ m4_define([b4_value_type_declare],
|
||||
T*
|
||||
yyas_ () YY_NOEXCEPT
|
||||
{
|
||||
void *yyp = yybuffer_.yyraw;
|
||||
void *yyp = yyraw_;
|
||||
return static_cast<T*> (yyp);
|
||||
}
|
||||
|
||||
@@ -293,7 +293,7 @@ m4_define([b4_value_type_declare],
|
||||
const T*
|
||||
yyas_ () const YY_NOEXCEPT
|
||||
{
|
||||
const void *yyp = yybuffer_.yyraw;
|
||||
const void *yyp = yyraw_;
|
||||
return static_cast<const T*> (yyp);
|
||||
}
|
||||
|
||||
@@ -308,10 +308,10 @@ m4_define([b4_value_type_declare],
|
||||
union
|
||||
{
|
||||
/// Strongest alignment constraints.
|
||||
long double yyalign_me;
|
||||
long double yyalign_me_;
|
||||
/// A buffer large enough to store any of the semantic values.
|
||||
char yyraw[size];
|
||||
} yybuffer_;]b4_parse_assert_if([
|
||||
char yyraw_[size];
|
||||
};]b4_parse_assert_if([
|
||||
|
||||
/// Whether the content is built: if defined, the name of the stored type.
|
||||
const std::type_info *yytypeid_;])[
|
||||
@@ -458,11 +458,11 @@ m4_define([b4_tok_in],
|
||||
|
||||
|
||||
|
||||
# _b4_token_constructor_define(SYMBOL-NUM...)
|
||||
# -------------------------------------------
|
||||
# Define a unique make_symbol for all the SYMBOL-NUM (they
|
||||
# _b4_symbol_constructor_define(SYMBOL-NUM...)
|
||||
# --------------------------------------------
|
||||
# Define a symbol_type constructor common to all the SYMBOL-NUM (they
|
||||
# have the same type). Use at class-level.
|
||||
m4_define([_b4_token_constructor_define],
|
||||
m4_define([_b4_symbol_constructor_define],
|
||||
[m4_ifval(_b4_includes_tokens($@),
|
||||
[[#if 201103L <= YY_CPLUSPLUS
|
||||
symbol_type (]b4_join(
|
||||
@@ -470,21 +470,23 @@ m4_define([_b4_token_constructor_define],
|
||||
b4_symbol_if([$1], [has_type],
|
||||
[b4_symbol([$1], [type]) v]),
|
||||
b4_locations_if([location_type l]))[)
|
||||
: super_type(]b4_join([token_type (tok)],
|
||||
b4_symbol_if([$1], [has_type], [std::move (v)]),
|
||||
b4_locations_if([std::move (l)]))[)
|
||||
: super_type (]b4_join([token_kind_type (tok)],
|
||||
b4_symbol_if([$1], [has_type], [std::move (v)]),
|
||||
b4_locations_if([std::move (l)]))[)
|
||||
#else
|
||||
symbol_type (]b4_join(
|
||||
[int tok],
|
||||
b4_symbol_if([$1], [has_type],
|
||||
[const b4_symbol([$1], [type])& v]),
|
||||
b4_locations_if([const location_type& l]))[)
|
||||
: super_type(]b4_join([token_type (tok)],
|
||||
b4_symbol_if([$1], [has_type], [v]),
|
||||
b4_locations_if([l]))[)
|
||||
: super_type (]b4_join([token_kind_type (tok)],
|
||||
b4_symbol_if([$1], [has_type], [v]),
|
||||
b4_locations_if([l]))[)
|
||||
#endif
|
||||
{]b4_parse_assert_if([[
|
||||
#if !defined _MSC_VER || defined __clang__
|
||||
]b4_assert[ (]b4_tok_in($@)[);
|
||||
#endif
|
||||
]])[}
|
||||
]])])
|
||||
|
||||
@@ -517,7 +519,7 @@ m4_define([b4_basic_symbol_constructor_define],
|
||||
|
||||
# b4_token_constructor_define
|
||||
# ---------------------------
|
||||
# Define the overloaded versions of make_symbol for all the value types.
|
||||
# Define the overloaded versions of make_FOO for all the token kinds.
|
||||
m4_define([b4_token_constructor_define],
|
||||
[ // Implementation of make_symbol for each symbol type.
|
||||
[ // Implementation of make_symbol for each token kind.
|
||||
b4_symbol_foreach([_b4_token_maker_define])])
|
||||
|
||||
+176
-70
@@ -22,6 +22,7 @@ m4_pushdef([b4_copyright_years],
|
||||
|
||||
m4_include(b4_skeletonsdir/[c.m4])
|
||||
|
||||
|
||||
## ---------- ##
|
||||
## api.pure. ##
|
||||
## ---------- ##
|
||||
@@ -101,6 +102,16 @@ m4_define([b4_yyerror_arg_loc_if],
|
||||
[1], [m4_ifset([b4_parse_param], [$1])],
|
||||
[2], [$1])])])
|
||||
|
||||
# b4_yyerror_formals
|
||||
# ------------------
|
||||
m4_define([b4_yyerror_formals],
|
||||
[b4_pure_if([b4_locations_if([, [[const ]b4_api_PREFIX[LTYPE *yyllocp], [&yylloc]]])[]dnl
|
||||
m4_ifdef([b4_parse_param], [, b4_parse_param])[]dnl
|
||||
,])dnl
|
||||
[[const char *msg], [msg]]])
|
||||
|
||||
|
||||
|
||||
# b4_yyerror_args
|
||||
# ---------------
|
||||
# Arguments passed to yyerror: user args plus yylloc.
|
||||
@@ -115,6 +126,16 @@ m4_ifset([b4_parse_param], [b4_args(b4_parse_param), ])])
|
||||
## ----------------- ##
|
||||
|
||||
|
||||
# b4_accept([SYMBOL-NUM])
|
||||
# -----------------------
|
||||
# Used in actions of the rules of accept, the initial symbol, to call
|
||||
# YYACCEPT. If SYMBOL-NUM is specified, run "yyvalue->SLOT = $2;"
|
||||
# before, using the slot of SYMBOL-NUM.
|
||||
m4_define([b4_accept],
|
||||
[m4_ifval([$1],
|
||||
[b4_symbol_value(yyimpl->yyvalue, [$1]) = b4_rhs_value(2, 1, [$1]); ]) YYACCEPT])
|
||||
|
||||
|
||||
# b4_lhs_value(SYMBOL-NUM, [TYPE])
|
||||
# --------------------------------
|
||||
# See README.
|
||||
@@ -154,14 +175,61 @@ m4_define([b4_rhs_location],
|
||||
## Declarations. ##
|
||||
## -------------- ##
|
||||
|
||||
# _b4_declare_sub_yyparse(START-SYMBOL-NUM, SWITCHING-TOKEN-SYMBOL-NUM)
|
||||
# ---------------------------------------------------------------------
|
||||
# Define the return type of the parsing function for SYMBOL-NUM, and
|
||||
# declare its parsing function.
|
||||
m4_define([_b4_declare_sub_yyparse],
|
||||
[[
|
||||
// Return type when parsing one ]_b4_symbol($1, tag)[.
|
||||
typedef struct
|
||||
{]b4_symbol_if([$1], [has_type], [[
|
||||
]_b4_symbol($1, type)[ yyvalue;]])[
|
||||
int yystatus;
|
||||
int yynerrs;
|
||||
} ]b4_prefix[parse_]_b4_symbol($1, id)[_t;
|
||||
|
||||
// Parse one ]_b4_symbol($1, tag)[.
|
||||
]b4_prefix[parse_]_b4_symbol($1, id)[_t ]b4_prefix[parse_]_b4_symbol($1, id)[ (]m4_ifset([b4_parse_param], [b4_formals(b4_parse_param)], [void])[);
|
||||
]])
|
||||
|
||||
|
||||
# _b4_first_switching_token
|
||||
# -------------------------
|
||||
m4_define([b4_first], [$1])
|
||||
m4_define([b4_second], [$2])
|
||||
m4_define([_b4_first_switching_token],
|
||||
[b4_second(b4_first(b4_start_symbols))])
|
||||
|
||||
|
||||
# _b4_define_sub_yyparse(START-SYMBOL-NUM, SWITCHING-TOKEN-SYMBOL-NUM)
|
||||
# --------------------------------------------------------------------
|
||||
# Define the parsing function for START-SYMBOL-NUM.
|
||||
m4_define([_b4_define_sub_yyparse],
|
||||
[[
|
||||
]b4_prefix[parse_]_b4_symbol($1, id)[_t
|
||||
]b4_prefix[parse_]_b4_symbol($1, id)[ (]m4_ifset([b4_parse_param], [b4_formals(b4_parse_param)], [void])[)
|
||||
{
|
||||
]b4_prefix[parse_]_b4_symbol($1, id)[_t yyres;
|
||||
yy_parse_impl_t yyimpl;
|
||||
yyres.yystatus = yy_parse_impl (]b4_symbol($2, id)[, &yyimpl]m4_ifset([b4_parse_param],
|
||||
[[, ]b4_args(b4_parse_param)])[);]b4_symbol_if([$1], [has_type], [[
|
||||
yyres.yyvalue = yyimpl.yyvalue.]b4_symbol($1, slot)[;]])[
|
||||
yyres.yynerrs = yyimpl.yynerrs;
|
||||
return yyres;
|
||||
}
|
||||
]])
|
||||
|
||||
|
||||
# b4_declare_scanner_communication_variables
|
||||
# ------------------------------------------
|
||||
# Declare the variables that are global, or local to YYPARSE if
|
||||
# pure-parser.
|
||||
m4_define([b4_declare_scanner_communication_variables], [[
|
||||
/* Lookahead token kind. */
|
||||
]m4_ifdef([b4_start_symbols], [],
|
||||
[[/* Lookahead token kind. */
|
||||
int yychar;
|
||||
|
||||
]])[
|
||||
]b4_pure_if([[
|
||||
/* The semantic value of the lookahead symbol. */
|
||||
/* Default value used for initialization, for pacifying older GCCs
|
||||
@@ -276,11 +344,14 @@ int ]b4_prefix[push_parse (]b4_prefix[pstate *ps]b4_pure_if([[,
|
||||
void ]b4_prefix[pstate_delete (]b4_prefix[pstate *ps);
|
||||
]])
|
||||
|
||||
|
||||
# _b4_declare_yyparse
|
||||
# -------------------
|
||||
# When not the push parser.
|
||||
m4_define([_b4_declare_yyparse],
|
||||
[[int ]b4_prefix[parse (]m4_ifset([b4_parse_param], [b4_formals(b4_parse_param)], [void])[);]])
|
||||
[[int ]b4_prefix[parse (]m4_ifset([b4_parse_param], [b4_formals(b4_parse_param)], [void])[);
|
||||
]m4_ifdef([b4_start_symbols],
|
||||
[m4_map([_b4_declare_sub_yyparse], m4_defn([b4_start_symbols]))])])
|
||||
|
||||
|
||||
# b4_declare_yyparse
|
||||
@@ -291,16 +362,32 @@ m4_define([b4_declare_yyparse],
|
||||
])
|
||||
|
||||
|
||||
# b4_declare_yyerror_and_yylex
|
||||
# ----------------------------
|
||||
# Comply with POSIX Yacc.
|
||||
# <https://austingroupbugs.net/view.php?id=1388#c5220>
|
||||
m4_define([b4_declare_yyerror_and_yylex],
|
||||
[b4_posix_if([[#if !defined ]b4_prefix[error && !defined ]b4_api_PREFIX[ERROR_IS_DECLARED
|
||||
]b4_function_declare([b4_prefix[error]], void, b4_yyerror_formals)[
|
||||
#endif
|
||||
#if !defined ]b4_prefix[lex && !defined ]b4_api_PREFIX[LEX_IS_DECLARED
|
||||
]b4_function_declare([b4_prefix[lex]], int, b4_yylex_formals)[
|
||||
#endif
|
||||
]])dnl
|
||||
])
|
||||
|
||||
|
||||
# b4_shared_declarations
|
||||
# ----------------------
|
||||
# Declaration that might either go into the header (if --defines)
|
||||
# or open coded in the parser body.
|
||||
# Declarations that might either go into the header (if --header)
|
||||
# or into the implementation file.
|
||||
m4_define([b4_shared_declarations],
|
||||
[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_yyerror_and_yylex[
|
||||
]b4_declare_yyparse[
|
||||
]b4_percent_code_get([[provides]])[
|
||||
]b4_cpp_guard_close([b4_spec_mapped_header_file])[]dnl
|
||||
@@ -330,13 +417,13 @@ m4_if(b4_spec_header_file, [y.tab.h], [],
|
||||
## -------------- ##
|
||||
|
||||
|
||||
b4_defines_if([[
|
||||
b4_header_if([[
|
||||
]b4_output_begin([b4_spec_header_file])[
|
||||
]b4_copyright([Bison interface for Yacc-like parsers in C])[
|
||||
]b4_disclaimer[
|
||||
]b4_shared_declarations[
|
||||
]b4_output_end[
|
||||
]])# b4_defines_if
|
||||
]])# b4_header_if
|
||||
|
||||
b4_output_begin([b4_parser_file_name])[
|
||||
]b4_copyright([Bison implementation for Yacc-like parsers in C])[
|
||||
@@ -641,15 +728,6 @@ yysymbol_name (yysymbol_kind_t yysymbol)
|
||||
}]])[
|
||||
#endif
|
||||
|
||||
#ifdef YYPRINT
|
||||
/* YYTOKNUM[NUM] -- (External) token number corresponding to the
|
||||
(internal) symbol number NUM (which must be that of a token). */
|
||||
static const ]b4_int_type_for([b4_toknum])[ yytoknum[] =
|
||||
{
|
||||
]b4_toknum[
|
||||
};
|
||||
#endif
|
||||
|
||||
#define YYPACT_NINF (]b4_pact_ninf[)
|
||||
|
||||
#define yypact_value_is_default(Yyn) \
|
||||
@@ -665,18 +743,19 @@ static const ]b4_int_type_for([b4_toknum])[ yytoknum[] =
|
||||
enum { YYENOMEM = -2 };
|
||||
|
||||
#define yyerrok (yyerrstatus = 0)
|
||||
#define yyclearin (yychar = ]b4_symbol(-2, id)[)
|
||||
#define yyclearin (yychar = ]b4_symbol(empty, id)[)
|
||||
|
||||
#define YYACCEPT goto yyacceptlab
|
||||
#define YYABORT goto yyabortlab
|
||||
#define YYERROR goto yyerrorlab
|
||||
#define YYNOMEM goto yyexhaustedlab
|
||||
|
||||
|
||||
#define YYRECOVERING() (!!yyerrstatus)
|
||||
|
||||
#define YYBACKUP(Token, Value) \
|
||||
do \
|
||||
if (yychar == ]b4_symbol(-2, id)[) \
|
||||
if (yychar == ]b4_symbol(empty, id)[) \
|
||||
{ \
|
||||
yychar = (Token); \
|
||||
yylval = (Value); \
|
||||
@@ -693,8 +772,8 @@ enum { YYENOMEM = -2 };
|
||||
while (0)
|
||||
|
||||
/* Backward compatibility with an undocumented macro.
|
||||
Use ]b4_symbol(1, id)[ or ]b4_symbol(2, id)[. */
|
||||
#define YYERRCODE ]b4_symbol(2, id)[
|
||||
Use ]b4_symbol(error, id)[ or ]b4_symbol(undef, id)[. */
|
||||
#define YYERRCODE ]b4_symbol(undef, id)[
|
||||
]b4_locations_if([[
|
||||
]b4_yylloc_default_define[
|
||||
#define YYRHSLOC(Rhs, K) ((Rhs)[K])
|
||||
@@ -714,7 +793,7 @@ do { \
|
||||
YYFPRINTF Args; \
|
||||
} while (0)
|
||||
|
||||
]b4_yy_location_print_define[
|
||||
]b4_yylocation_print_define[
|
||||
|
||||
# define YY_SYMBOL_PRINT(Title, Kind, Value, Location) \
|
||||
do { \
|
||||
@@ -925,7 +1004,7 @@ do { \
|
||||
switch (yy_lac (yyesa, &yyes, &yyes_capacity, yyssp, yytoken)) \
|
||||
{ \
|
||||
case YYENOMEM: \
|
||||
goto yyexhaustedlab; \
|
||||
YYNOMEM; \
|
||||
case 1: \
|
||||
goto yyerrlab; \
|
||||
} \
|
||||
@@ -1103,7 +1182,7 @@ yypcontext_expected_tokens (const yypcontext_t *yyctx,
|
||||
for (yyx = 0; yyx < YYNTOKENS; ++yyx)
|
||||
{
|
||||
yysymbol_kind_t yysym = YY_CAST (yysymbol_kind_t, yyx);
|
||||
if (yysym != ]b4_symbol(1, kind)[ && yysym != ]b4_symbol_prefix[YYUNDEF)
|
||||
if (yysym != ]b4_symbol(error, kind)[ && yysym != ]b4_symbol_prefix[YYUNDEF)
|
||||
switch (yy_lac (]b4_push_if([[yyps->yyesa, &yyps->yyes, &yyps->yyes_capacity, yyps->yyssp, yysym]],
|
||||
[[yyctx->yyesa, yyctx->yyes, yyctx->yyes_capacity, yyctx->yyssp, yysym]])[))
|
||||
{
|
||||
@@ -1132,7 +1211,7 @@ yypcontext_expected_tokens (const yypcontext_t *yyctx,
|
||||
int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
|
||||
int yyx;
|
||||
for (yyx = yyxbegin; yyx < yyxend; ++yyx)
|
||||
if (yycheck[yyx + yyn] == yyx && yyx != ]b4_symbol(1, kind)[
|
||||
if (yycheck[yyx + yyn] == yyx && yyx != ]b4_symbol(error, kind)[
|
||||
&& !yytable_value_is_error (yytable[yyx + yyn]))
|
||||
{
|
||||
if (!yyarg)
|
||||
@@ -1144,7 +1223,7 @@ yypcontext_expected_tokens (const yypcontext_t *yyctx,
|
||||
}
|
||||
}]])[
|
||||
if (yyarg && yycount == 0 && 0 < yyargn)
|
||||
yyarg[0] = ]b4_symbol(-2, kind)[;
|
||||
yyarg[0] = ]b4_symbol(empty, kind)[;
|
||||
return yycount;
|
||||
}
|
||||
|
||||
@@ -1307,7 +1386,7 @@ yy_syntax_error_arguments (const yypcontext_t *yyctx,
|
||||
one exception: it will still contain any token that will not be
|
||||
accepted due to an error action in a later state.]])[
|
||||
*/
|
||||
if (yyctx->yytoken != ]b4_symbol(-2, kind)[)
|
||||
if (yyctx->yytoken != ]b4_symbol(empty, kind)[)
|
||||
{
|
||||
int yyn;]b4_lac_if([[
|
||||
YYDPRINTF ((stderr, "Constructing syntax error message\n"));]])[
|
||||
@@ -1453,7 +1532,7 @@ yypull_parse (yypstate *yyps]b4_user_formals[)
|
||||
int yystatus;
|
||||
do {
|
||||
]b4_pure_if([[ YYSTYPE yylval;
|
||||
int ]])[yychar = ]b4_lex[;
|
||||
int ]])[yychar = ]b4_yylex[;
|
||||
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);
|
||||
return yystatus;
|
||||
@@ -1534,8 +1613,31 @@ yypush_parse (yypstate *yyps]b4_pure_if([[,
|
||||
| yyparse. |
|
||||
`----------*/
|
||||
|
||||
]m4_ifdef([b4_start_symbols],
|
||||
[[// Extract data from the parser.
|
||||
typedef struct
|
||||
{
|
||||
YYSTYPE yyvalue;
|
||||
int yynerrs;
|
||||
} yy_parse_impl_t;
|
||||
|
||||
// Run a full parse, using YYCHAR as switching token.
|
||||
static int
|
||||
yy_parse_impl (int yychar, yy_parse_impl_t *yyimpl]m4_ifset([b4_parse_param], [, b4_formals(b4_parse_param)])[);
|
||||
|
||||
]m4_map([_b4_define_sub_yyparse], m4_defn([b4_start_symbols]))[
|
||||
|
||||
int
|
||||
yyparse (]m4_ifset([b4_parse_param], [b4_formals(b4_parse_param)], [void])[)]])[
|
||||
yyparse (]m4_ifset([b4_parse_param], [b4_formals(b4_parse_param)], [void])[)
|
||||
{
|
||||
return yy_parse_impl (]b4_symbol(_b4_first_switching_token, id)[, YY_NULLPTR]m4_ifset([b4_parse_param],
|
||||
[[, ]b4_args(b4_parse_param)])[);
|
||||
}
|
||||
|
||||
static int
|
||||
yy_parse_impl (int yychar, yy_parse_impl_t *yyimpl]m4_ifset([b4_parse_param], [, b4_formals(b4_parse_param)])[)]],
|
||||
[[int
|
||||
yyparse (]m4_ifset([b4_parse_param], [b4_formals(b4_parse_param)], [void])[)]])])[
|
||||
{]b4_pure_if([b4_declare_scanner_communication_variables
|
||||
])b4_push_if([b4_pure_if([], [[
|
||||
int yypushed_char = yychar;
|
||||
@@ -1550,7 +1652,7 @@ yyparse (]m4_ifset([b4_parse_param], [b4_formals(b4_parse_param)], [void])[)]])[
|
||||
/* The return value of yyparse. */
|
||||
int yyresult;
|
||||
/* Lookahead symbol kind. */
|
||||
yysymbol_kind_t yytoken = ]b4_symbol(-2, kind)[;
|
||||
yysymbol_kind_t yytoken = ]b4_symbol(empty, kind)[;
|
||||
/* The variables used to return semantic value and location from the
|
||||
action routines. */
|
||||
YYSTYPE yyval;]b4_locations_if([[
|
||||
@@ -1587,7 +1689,9 @@ yyparse (]m4_ifset([b4_parse_param], [b4_formals(b4_parse_param)], [void])[)]])[
|
||||
|
||||
YYDPRINTF ((stderr, "Starting parse\n"));
|
||||
|
||||
yychar = ]b4_symbol(-2, id)[; /* Cause a token to be read. */
|
||||
]m4_ifdef([b4_start_symbols], [],
|
||||
[[ yychar = ]b4_symbol(empty, id)[; /* Cause a token to be read. */
|
||||
]])[
|
||||
]m4_ifdef([b4_initial_action], [
|
||||
b4_dollar_pushdef([m4_define([b4_dollar_dollar_used])yylval], [], [],
|
||||
[b4_push_if([b4_pure_if([*])yypushed_loc], [yylloc])])dnl
|
||||
@@ -1622,7 +1726,7 @@ yysetstate:
|
||||
|
||||
if (yyss + yystacksize - 1 <= yyssp)
|
||||
#if !defined yyoverflow && !defined YYSTACK_RELOCATE
|
||||
goto yyexhaustedlab;
|
||||
YYNOMEM;
|
||||
#else
|
||||
{
|
||||
/* Get the current used size of the three stacks, in elements. */
|
||||
@@ -1653,7 +1757,7 @@ yysetstate:
|
||||
# else /* defined YYSTACK_RELOCATE */
|
||||
/* Extend the stack our own way. */
|
||||
if (YYMAXDEPTH <= yystacksize)
|
||||
goto yyexhaustedlab;
|
||||
YYNOMEM;
|
||||
yystacksize *= 2;
|
||||
if (YYMAXDEPTH < yystacksize)
|
||||
yystacksize = YYMAXDEPTH;
|
||||
@@ -1664,7 +1768,7 @@ yysetstate:
|
||||
YY_CAST (union yyalloc *,
|
||||
YYSTACK_ALLOC (YY_CAST (YYSIZE_T, YYSTACK_BYTES (yystacksize))));
|
||||
if (! yyptr)
|
||||
goto yyexhaustedlab;
|
||||
YYNOMEM;
|
||||
YYSTACK_RELOCATE (yyss_alloc, yyss);
|
||||
YYSTACK_RELOCATE (yyvs_alloc, yyvs);]b4_locations_if([
|
||||
YYSTACK_RELOCATE (yyls_alloc, yyls);])[
|
||||
@@ -1688,8 +1792,9 @@ yysetstate:
|
||||
}
|
||||
#endif /* !defined yyoverflow && !defined YYSTACK_RELOCATE */
|
||||
|
||||
]m4_ifdef([b4_start_symbols], [], [[
|
||||
if (yystate == YYFINAL)
|
||||
YYACCEPT;
|
||||
YYACCEPT;]])[
|
||||
|
||||
goto yybackup;
|
||||
|
||||
@@ -1709,7 +1814,7 @@ yybackup:
|
||||
/* Not known => get a lookahead token if don't already have one. */
|
||||
|
||||
/* YYCHAR is either empty, or end-of-input, or a valid lookahead. */
|
||||
if (yychar == ]b4_symbol(-2, id)[)
|
||||
if (yychar == ]b4_symbol(empty, id)[)
|
||||
{]b4_push_if([[
|
||||
if (!yyps->yynew)
|
||||
{]b4_use_push_for_pull_if([], [[
|
||||
@@ -1731,23 +1836,23 @@ yyread_pushed_token:]])[
|
||||
yylval = *yypushed_val;]b4_locations_if([[
|
||||
if (yypushed_loc)
|
||||
yylloc = *yypushed_loc;]])])], [[
|
||||
yychar = ]b4_lex[;]])[
|
||||
yychar = ]b4_yylex[;]])[
|
||||
}
|
||||
|
||||
if (yychar <= ]b4_symbol(0, [id])[)
|
||||
if (yychar <= ]b4_symbol(eof, [id])[)
|
||||
{
|
||||
yychar = ]b4_symbol(0, [id])[;
|
||||
yytoken = ]b4_symbol(0, [kind])[;
|
||||
yychar = ]b4_symbol(eof, [id])[;
|
||||
yytoken = ]b4_symbol(eof, [kind])[;
|
||||
YYDPRINTF ((stderr, "Now at end of input.\n"));
|
||||
}
|
||||
else if (yychar == ]b4_symbol(1, [id])[)
|
||||
else if (yychar == ]b4_symbol(error, [id])[)
|
||||
{
|
||||
/* 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 = ]b4_symbol(2, [id])[;
|
||||
yytoken = ]b4_symbol(1, [kind])[;]b4_locations_if([[
|
||||
yychar = ]b4_symbol(undef, [id])[;
|
||||
yytoken = ]b4_symbol(error, [kind])[;]b4_locations_if([[
|
||||
yyerror_range[1] = yylloc;]])[
|
||||
goto yyerrlab1;
|
||||
}
|
||||
@@ -1770,9 +1875,9 @@ yyread_pushed_token:]])[
|
||||
if (yyn <= 0)
|
||||
{
|
||||
if (yytable_value_is_error (yyn))
|
||||
goto yyerrlab;]b4_lac_if([[
|
||||
goto yyerrlab;
|
||||
yyn = -yyn;]b4_lac_if([[
|
||||
YY_LAC_ESTABLISH;]])[
|
||||
yyn = -yyn;
|
||||
goto yyreduce;
|
||||
}
|
||||
|
||||
@@ -1790,7 +1895,7 @@ yyread_pushed_token:]])[
|
||||
*++yylsp = yylloc;])[
|
||||
|
||||
/* Discard the shifted token. */
|
||||
yychar = ]b4_symbol(-2, id)[;]b4_lac_if([[
|
||||
yychar = ]b4_symbol(empty, id)[;]b4_lac_if([[
|
||||
YY_LAC_DISCARD ("shift");]])[
|
||||
goto yynewstate;
|
||||
|
||||
@@ -1881,7 +1986,7 @@ yyreduce:
|
||||
yyerrlab:
|
||||
/* Make sure we have latest lookahead translation. See comments at
|
||||
user semantic actions for why this is necessary. */
|
||||
yytoken = yychar == ]b4_symbol(-2, id)[ ? ]b4_symbol(-2, kind)[ : YYTRANSLATE (yychar);
|
||||
yytoken = yychar == ]b4_symbol(empty, id)[ ? ]b4_symbol(empty, kind)[ : YYTRANSLATE (yychar);
|
||||
/* If not already recovering from an error, report this error. */
|
||||
if (!yyerrstatus)
|
||||
{
|
||||
@@ -1891,11 +1996,11 @@ yyerrlab:
|
||||
[[ {
|
||||
yypcontext_t yyctx
|
||||
= {]b4_push_if([[yyps]], [[yyssp]b4_lac_if([[, yyesa, &yyes, &yyes_capacity]])])[, yytoken]b4_locations_if([[, &yylloc]])[};]b4_lac_if([[
|
||||
if (yychar != ]b4_symbol(-2, id)[)
|
||||
if (yychar != ]b4_symbol(empty, id)[)
|
||||
YY_LAC_ESTABLISH;]])[
|
||||
if (yyreport_syntax_error (&yyctx]m4_ifset([b4_parse_param],
|
||||
[[, ]b4_args(b4_parse_param)])[) == 2)
|
||||
goto yyexhaustedlab;
|
||||
[[, ]b4_args(b4_parse_param)])[) == 2)
|
||||
YYNOMEM;
|
||||
}]],
|
||||
[simple],
|
||||
[[ yyerror (]b4_yyerror_args[YY_("syntax error"));]],
|
||||
@@ -1904,7 +2009,7 @@ yyerrlab:
|
||||
= {]b4_push_if([[yyps]], [[yyssp]b4_lac_if([[, yyesa, &yyes, &yyes_capacity]])])[, yytoken]b4_locations_if([[, &yylloc]])[};
|
||||
char const *yymsgp = YY_("syntax error");
|
||||
int yysyntax_error_status;]b4_lac_if([[
|
||||
if (yychar != ]b4_symbol(-2, id)[)
|
||||
if (yychar != ]b4_symbol(empty, id)[)
|
||||
YY_LAC_ESTABLISH;]])[
|
||||
yysyntax_error_status = yysyntax_error (&yymsg_alloc, &yymsg, &yyctx);
|
||||
if (yysyntax_error_status == 0)
|
||||
@@ -1930,7 +2035,7 @@ yyerrlab:
|
||||
}
|
||||
yyerror (]b4_yyerror_args[yymsgp);
|
||||
if (yysyntax_error_status == YYENOMEM)
|
||||
goto yyexhaustedlab;
|
||||
YYNOMEM;
|
||||
}]])[
|
||||
}
|
||||
]b4_locations_if([[
|
||||
@@ -1940,17 +2045,17 @@ yyerrlab:
|
||||
/* If just tried and failed to reuse lookahead token after an
|
||||
error, discard it. */
|
||||
|
||||
if (yychar <= ]b4_symbol(0, [id])[)
|
||||
if (yychar <= ]b4_symbol(eof, [id])[)
|
||||
{
|
||||
/* Return failure if at end of input. */
|
||||
if (yychar == ]b4_symbol(0, [id])[)
|
||||
if (yychar == ]b4_symbol(eof, [id])[)
|
||||
YYABORT;
|
||||
}
|
||||
else
|
||||
{
|
||||
yydestruct ("Error: discarding",
|
||||
yytoken, &yylval]b4_locations_if([, &yylloc])[]b4_user_args[);
|
||||
yychar = ]b4_symbol(-2, id)[;
|
||||
yychar = ]b4_symbol(empty, id)[;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1967,6 +2072,7 @@ yyerrorlab:
|
||||
label yyerrorlab therefore never appears in user code. */
|
||||
if (0)
|
||||
YYERROR;
|
||||
++yynerrs;
|
||||
|
||||
/* Do not reclaim the symbols of the rule whose action triggered
|
||||
this YYERROR. */
|
||||
@@ -1989,8 +2095,8 @@ yyerrlab1:
|
||||
yyn = yypact[yystate];
|
||||
if (!yypact_value_is_default (yyn))
|
||||
{
|
||||
yyn += ]b4_symbol(1, kind)[;
|
||||
if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == ]b4_symbol(1, kind)[)
|
||||
yyn += ]b4_symbol(error, kind)[;
|
||||
if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == ]b4_symbol(error, kind)[)
|
||||
{
|
||||
yyn = yytable[yyn];
|
||||
if (0 < yyn)
|
||||
@@ -2034,7 +2140,7 @@ yyerrlab1:
|
||||
`-------------------------------------*/
|
||||
yyacceptlab:
|
||||
yyresult = 0;
|
||||
goto yyreturn;
|
||||
goto yyreturnlab;
|
||||
|
||||
|
||||
/*-----------------------------------.
|
||||
@@ -2042,25 +2148,23 @@ yyacceptlab:
|
||||
`-----------------------------------*/
|
||||
yyabortlab:
|
||||
yyresult = 1;
|
||||
goto yyreturn;
|
||||
goto yyreturnlab;
|
||||
|
||||
|
||||
#if ]b4_lac_if([[1]], [b4_parse_error_case([simple], [[!defined yyoverflow]], [[1]])])[
|
||||
/*-------------------------------------------------.
|
||||
| yyexhaustedlab -- memory exhaustion comes here. |
|
||||
`-------------------------------------------------*/
|
||||
/*-----------------------------------------------------------.
|
||||
| yyexhaustedlab -- YYNOMEM (memory exhaustion) comes here. |
|
||||
`-----------------------------------------------------------*/
|
||||
yyexhaustedlab:
|
||||
yyerror (]b4_yyerror_args[YY_("memory exhausted"));
|
||||
yyresult = 2;
|
||||
goto yyreturn;
|
||||
#endif
|
||||
goto yyreturnlab;
|
||||
|
||||
|
||||
/*-------------------------------------------------------.
|
||||
| yyreturn -- parsing is finished, clean up and return. |
|
||||
`-------------------------------------------------------*/
|
||||
yyreturn:
|
||||
if (yychar != ]b4_symbol(-2, id)[)
|
||||
/*----------------------------------------------------------.
|
||||
| yyreturnlab -- parsing is finished, clean up and return. |
|
||||
`----------------------------------------------------------*/
|
||||
yyreturnlab:
|
||||
if (yychar != ]b4_symbol(empty, id)[)
|
||||
{
|
||||
/* Make sure we have latest lookahead translation. See comments at
|
||||
user semantic actions for why this is necessary. */
|
||||
@@ -2094,7 +2198,9 @@ yypushreturn:]], [[
|
||||
YYSTACK_FREE (yyes);]])])[
|
||||
]b4_parse_error_bmatch([detailed\|verbose],
|
||||
[[ if (yymsg != yymsgbuf)
|
||||
YYSTACK_FREE (yymsg);]])[
|
||||
YYSTACK_FREE (yymsg);]])[]m4_ifdef([b4_start_symbols], [[
|
||||
if (yyimpl)
|
||||
yyimpl->yynerrs = yynerrs;]])[
|
||||
return yyresult;
|
||||
}
|
||||
]b4_push_if([b4_parse_state_variable_macros([b4_macro_undef])])[
|
||||
|
||||
+3
-3
@@ -22,15 +22,15 @@
|
||||
/bison.ps
|
||||
/cross-options.texi
|
||||
/fdl.texi
|
||||
/figs/*.eps
|
||||
/figs/*.svg
|
||||
/gendocs_template
|
||||
/gendocs_template_min
|
||||
/gpl-3.0.texi
|
||||
/refcard.dvi
|
||||
/refcard.log
|
||||
/refcard.ps
|
||||
/relocatable.texi
|
||||
/stamp-vti
|
||||
/version.texi
|
||||
/yacc.1
|
||||
/relocatable.texi
|
||||
/figs/*.eps
|
||||
/figs/*.svg
|
||||
|
||||
+124
-57
@@ -1,4 +1,4 @@
|
||||
# Doxyfile 1.8.18
|
||||
# Doxyfile 1.9.1
|
||||
|
||||
# This file describes the settings to be used by the documentation system
|
||||
# doxygen (www.doxygen.org) for a project.
|
||||
@@ -32,13 +32,13 @@ DOXYFILE_ENCODING = UTF-8
|
||||
# title of most generated pages and in a few other places.
|
||||
# The default value is: My Project.
|
||||
|
||||
PROJECT_NAME = "@PACKAGE_NAME@"
|
||||
PROJECT_NAME = @PACKAGE_NAME@
|
||||
|
||||
# The PROJECT_NUMBER tag can be used to enter a project or revision number. This
|
||||
# could be handy for archiving the generated documentation or if some version
|
||||
# control system is used.
|
||||
|
||||
PROJECT_NUMBER = "@PACKAGE_VERSION@"
|
||||
PROJECT_NUMBER = @PACKAGE_VERSION@
|
||||
|
||||
# Using the PROJECT_BRIEF tag one can provide an optional one line description
|
||||
# for a project that appears at the top of each page and should give viewer a
|
||||
@@ -217,6 +217,14 @@ QT_AUTOBRIEF = NO
|
||||
|
||||
MULTILINE_CPP_IS_BRIEF = NO
|
||||
|
||||
# By default Python docstrings are displayed as preformatted text and doxygen's
|
||||
# special commands cannot be used. By setting PYTHON_DOCSTRING to NO the
|
||||
# doxygen's special commands can be used and the contents of the docstring
|
||||
# documentation blocks is shown as doxygen documentation.
|
||||
# The default value is: YES.
|
||||
|
||||
PYTHON_DOCSTRING = YES
|
||||
|
||||
# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the
|
||||
# documentation from any documented member that it re-implements.
|
||||
# The default value is: YES.
|
||||
@@ -305,7 +313,10 @@ OPTIMIZE_OUTPUT_SLICE = NO
|
||||
# Note: For files without extension you can use no_extension as a placeholder.
|
||||
#
|
||||
# Note that for custom extensions you also need to set FILE_PATTERNS otherwise
|
||||
# the files are not read by doxygen.
|
||||
# the files are not read by doxygen. When specifying no_extension you should add
|
||||
# * to the FILE_PATTERNS.
|
||||
#
|
||||
# Note see also the list of default file extension mappings.
|
||||
|
||||
EXTENSION_MAPPING =
|
||||
|
||||
@@ -439,6 +450,19 @@ TYPEDEF_HIDES_STRUCT = NO
|
||||
|
||||
LOOKUP_CACHE_SIZE = 0
|
||||
|
||||
# The NUM_PROC_THREADS specifies the number threads doxygen is allowed to use
|
||||
# during processing. When set to 0 doxygen will based this on the number of
|
||||
# cores available in the system. You can set it explicitly to a value larger
|
||||
# than 0 to get more control over the balance between CPU load and processing
|
||||
# speed. At this moment only the input processing can be done using multiple
|
||||
# threads. Since this is still an experimental feature the default is set to 1,
|
||||
# which efficively disables parallel processing. Please report any issues you
|
||||
# encounter. Generating dot graphs in parallel is controlled by the
|
||||
# DOT_NUM_THREADS setting.
|
||||
# Minimum value: 0, maximum value: 32, default value: 1.
|
||||
|
||||
NUM_PROC_THREADS = 1
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Build related configuration options
|
||||
#---------------------------------------------------------------------------
|
||||
@@ -502,6 +526,13 @@ EXTRACT_LOCAL_METHODS = NO
|
||||
|
||||
EXTRACT_ANON_NSPACES = NO
|
||||
|
||||
# If this flag is set to YES, the name of an unnamed parameter in a declaration
|
||||
# will be determined by the corresponding definition. By default unnamed
|
||||
# parameters remain unnamed in the output.
|
||||
# The default value is: YES.
|
||||
|
||||
RESOLVE_UNNAMED_PARAMS = YES
|
||||
|
||||
# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all
|
||||
# undocumented members inside documented classes or files. If set to NO these
|
||||
# members will be included in the various overviews, but no documentation
|
||||
@@ -539,11 +570,18 @@ HIDE_IN_BODY_DOCS = NO
|
||||
|
||||
INTERNAL_DOCS = NO
|
||||
|
||||
# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file
|
||||
# names in lower-case letters. If set to YES, upper-case letters are also
|
||||
# allowed. This is useful if you have classes or files whose names only differ
|
||||
# in case and if your file system supports case sensitive file names. Windows
|
||||
# (including Cygwin) ands Mac users are advised to set this option to NO.
|
||||
# With the correct setting of option CASE_SENSE_NAMES doxygen will better be
|
||||
# able to match the capabilities of the underlying filesystem. In case the
|
||||
# filesystem is case sensitive (i.e. it supports files in the same directory
|
||||
# whose names only differ in casing), the option must be set to YES to properly
|
||||
# deal with such files in case they appear in the input. For filesystems that
|
||||
# are not case sensitive the option should be be set to NO to properly deal with
|
||||
# output files written for symbols that only differ in casing, such as for two
|
||||
# classes, one named CLASS and the other named Class, and to also support
|
||||
# references to files without having to specify the exact matching casing. On
|
||||
# Windows (including Cygwin) and MacOS, users should typically set this option
|
||||
# to NO, whereas on Linux or other Unix flavors it should typically be set to
|
||||
# YES.
|
||||
# The default value is: system dependent.
|
||||
|
||||
CASE_SENSE_NAMES = YES
|
||||
@@ -782,7 +820,10 @@ WARN_IF_DOC_ERROR = YES
|
||||
WARN_NO_PARAMDOC = NO
|
||||
|
||||
# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when
|
||||
# a warning is encountered.
|
||||
# a warning is encountered. If the WARN_AS_ERROR tag is set to FAIL_ON_WARNINGS
|
||||
# then doxygen will continue running as if WARN_AS_ERROR tag is set to NO, but
|
||||
# at the end of the doxygen process doxygen will return with a non-zero status.
|
||||
# Possible values are: NO, YES and FAIL_ON_WARNINGS.
|
||||
# The default value is: NO.
|
||||
|
||||
WARN_AS_ERROR = NO
|
||||
@@ -819,8 +860,8 @@ INPUT = @top_srcdir@/src \
|
||||
# This tag can be used to specify the character encoding of the source files
|
||||
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
|
||||
# libiconv (or the iconv built into libc) for the transcoding. See the libiconv
|
||||
# documentation (see: https://www.gnu.org/software/libiconv/) for the list of
|
||||
# possible encodings.
|
||||
# documentation (see:
|
||||
# https://www.gnu.org/software/libiconv/) for the list of possible encodings.
|
||||
# The default value is: UTF-8.
|
||||
|
||||
INPUT_ENCODING = UTF-8
|
||||
@@ -833,13 +874,15 @@ INPUT_ENCODING = UTF-8
|
||||
# need to set EXTENSION_MAPPING for the extension otherwise the files are not
|
||||
# read by doxygen.
|
||||
#
|
||||
# Note the list of default checked file patterns might differ from the list of
|
||||
# default file extension mappings.
|
||||
#
|
||||
# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp,
|
||||
# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h,
|
||||
# *.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, *.f18, *.f, *.for, *.vhd,
|
||||
# *.vhdl, *.ucf, *.qsf and *.ice.
|
||||
# *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, *.f18, *.f, *.for, *.vhd, *.vhdl,
|
||||
# *.ucf, *.qsf and *.ice.
|
||||
|
||||
FILE_PATTERNS = *.c \
|
||||
*.h \
|
||||
@@ -1069,13 +1112,6 @@ VERBATIM_HEADERS = YES
|
||||
|
||||
ALPHABETICAL_INDEX = YES
|
||||
|
||||
# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in
|
||||
# which the alphabetical index list will be split.
|
||||
# Minimum value: 1, maximum value: 20, default value: 5.
|
||||
# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
|
||||
|
||||
COLS_IN_ALPHA_INDEX = 5
|
||||
|
||||
# In case all classes in a project start with a common prefix, all classes will
|
||||
# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag
|
||||
# can be used to specify a prefix (or a list of prefixes) that should be ignored
|
||||
@@ -1246,10 +1282,11 @@ HTML_INDEX_NUM_ENTRIES = 100
|
||||
|
||||
# If the GENERATE_DOCSET tag is set to YES, additional index files will be
|
||||
# generated that can be used as input for Apple's Xcode 3 integrated development
|
||||
# environment (see: https://developer.apple.com/xcode/), introduced with OSX
|
||||
# 10.5 (Leopard). To create a documentation set, doxygen will generate a
|
||||
# Makefile in the HTML output directory. Running make will produce the docset in
|
||||
# that directory and running make install will install the docset in
|
||||
# environment (see:
|
||||
# https://developer.apple.com/xcode/), introduced with OSX 10.5 (Leopard). To
|
||||
# create a documentation set, doxygen will generate a Makefile in the HTML
|
||||
# output directory. Running make will produce the docset in that directory and
|
||||
# running make install will install the docset in
|
||||
# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at
|
||||
# startup. See https://developer.apple.com/library/archive/featuredarticles/Doxy
|
||||
# genXcode/_index.html for more information.
|
||||
@@ -1291,8 +1328,8 @@ DOCSET_PUBLISHER_NAME = Publisher
|
||||
# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three
|
||||
# additional HTML index files: index.hhp, index.hhc, and index.hhk. The
|
||||
# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop
|
||||
# (see: https://www.microsoft.com/en-us/download/details.aspx?id=21138) on
|
||||
# Windows.
|
||||
# (see:
|
||||
# https://www.microsoft.com/en-us/download/details.aspx?id=21138) on Windows.
|
||||
#
|
||||
# The HTML Help Workshop contains a compiler that can convert all HTML output
|
||||
# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML
|
||||
@@ -1322,7 +1359,7 @@ CHM_FILE =
|
||||
HHC_LOCATION =
|
||||
|
||||
# The GENERATE_CHI flag controls if a separate .chi index file is generated
|
||||
# (YES) or that it should be included in the master .chm file (NO).
|
||||
# (YES) or that it should be included in the main .chm file (NO).
|
||||
# The default value is: NO.
|
||||
# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
|
||||
|
||||
@@ -1367,7 +1404,8 @@ QCH_FILE =
|
||||
|
||||
# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help
|
||||
# Project output. For more information please see Qt Help Project / Namespace
|
||||
# (see: https://doc.qt.io/archives/qt-4.8/qthelpproject.html#namespace).
|
||||
# (see:
|
||||
# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#namespace).
|
||||
# The default value is: org.doxygen.Project.
|
||||
# This tag requires that the tag GENERATE_QHP is set to YES.
|
||||
|
||||
@@ -1375,8 +1413,8 @@ QHP_NAMESPACE = org.doxygen.Project
|
||||
|
||||
# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt
|
||||
# Help Project output. For more information please see Qt Help Project / Virtual
|
||||
# Folders (see: https://doc.qt.io/archives/qt-4.8/qthelpproject.html#virtual-
|
||||
# folders).
|
||||
# Folders (see:
|
||||
# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#virtual-folders).
|
||||
# The default value is: doc.
|
||||
# This tag requires that the tag GENERATE_QHP is set to YES.
|
||||
|
||||
@@ -1384,16 +1422,16 @@ QHP_VIRTUAL_FOLDER = doc
|
||||
|
||||
# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom
|
||||
# filter to add. For more information please see Qt Help Project / Custom
|
||||
# Filters (see: https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-
|
||||
# filters).
|
||||
# Filters (see:
|
||||
# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-filters).
|
||||
# This tag requires that the tag GENERATE_QHP is set to YES.
|
||||
|
||||
QHP_CUST_FILTER_NAME =
|
||||
|
||||
# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the
|
||||
# custom filter to add. For more information please see Qt Help Project / Custom
|
||||
# Filters (see: https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-
|
||||
# filters).
|
||||
# Filters (see:
|
||||
# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-filters).
|
||||
# This tag requires that the tag GENERATE_QHP is set to YES.
|
||||
|
||||
QHP_CUST_FILTER_ATTRS =
|
||||
@@ -1405,9 +1443,9 @@ QHP_CUST_FILTER_ATTRS =
|
||||
|
||||
QHP_SECT_FILTER_ATTRS =
|
||||
|
||||
# The QHG_LOCATION tag can be used to specify the location of Qt's
|
||||
# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the
|
||||
# generated .qhp file.
|
||||
# The QHG_LOCATION tag can be used to specify the location (absolute path
|
||||
# including file name) of Qt's qhelpgenerator. If non-empty doxygen will try to
|
||||
# run qhelpgenerator on the generated .qhp file.
|
||||
# This tag requires that the tag GENERATE_QHP is set to YES.
|
||||
|
||||
QHG_LOCATION =
|
||||
@@ -1488,8 +1526,8 @@ EXT_LINKS_IN_WINDOW = NO
|
||||
# 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.
|
||||
# Possible values are: png (the default) and svg (looks nicer but requires the
|
||||
# pdf2svg or inkscape tool).
|
||||
# The default value is: png.
|
||||
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||
|
||||
@@ -1533,8 +1571,8 @@ FORMULA_MACROFILE =
|
||||
USE_MATHJAX = NO
|
||||
|
||||
# When MathJax is enabled you can set the default output format to be used for
|
||||
# the MathJax output. See the MathJax site
|
||||
# <https://docs.mathjax.org/en/latest/> for more details.
|
||||
# the MathJax output. See the MathJax site (see:
|
||||
# http://docs.mathjax.org/en/v2.7-latest/output.html) for more details.
|
||||
# Possible values are: HTML-CSS (which is slower, but has the best
|
||||
# compatibility), NativeMML (i.e. MathML) and SVG.
|
||||
# The default value is: HTML-CSS.
|
||||
@@ -1564,7 +1602,8 @@ MATHJAX_EXTENSIONS =
|
||||
|
||||
# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces
|
||||
# of code that will be used on startup of the MathJax code. See the MathJax site
|
||||
# <https://docs.mathjax.org/en/latest/> for more details. For an
|
||||
# (see:
|
||||
# http://docs.mathjax.org/en/v2.7-latest/output.html) for more details. For an
|
||||
# example see the documentation.
|
||||
# This tag requires that the tag USE_MATHJAX is set to YES.
|
||||
|
||||
@@ -1611,7 +1650,8 @@ SERVER_BASED_SEARCH = NO
|
||||
#
|
||||
# Doxygen ships with an example indexer (doxyindexer) and search engine
|
||||
# (doxysearch.cgi) which are based on the open source search engine library
|
||||
# Xapian (see: https://xapian.org/).
|
||||
# Xapian (see:
|
||||
# https://xapian.org/).
|
||||
#
|
||||
# See the section "External Indexing and Searching" for details.
|
||||
# The default value is: NO.
|
||||
@@ -1624,8 +1664,9 @@ EXTERNAL_SEARCH = NO
|
||||
#
|
||||
# Doxygen ships with an example indexer (doxyindexer) and search engine
|
||||
# (doxysearch.cgi) which are based on the open source search engine library
|
||||
# Xapian (see: https://xapian.org/). See the section "External Indexing and
|
||||
# Searching" for details.
|
||||
# Xapian (see:
|
||||
# https://xapian.org/). See the section "External Indexing and Searching" for
|
||||
# details.
|
||||
# This tag requires that the tag SEARCHENGINE is set to YES.
|
||||
|
||||
SEARCHENGINE_URL =
|
||||
@@ -1789,9 +1830,11 @@ LATEX_EXTRA_FILES =
|
||||
|
||||
PDF_HYPERLINKS = YES
|
||||
|
||||
# If the USE_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate
|
||||
# the PDF file directly from the LaTeX files. Set this option to YES, to get a
|
||||
# higher quality PDF documentation.
|
||||
# If the USE_PDFLATEX tag is set to YES, doxygen will use the engine as
|
||||
# specified with LATEX_CMD_NAME to generate the PDF file directly from the LaTeX
|
||||
# files. Set this option to YES, to get a higher quality PDF documentation.
|
||||
#
|
||||
# See also section LATEX_CMD_NAME for selecting the engine.
|
||||
# The default value is: YES.
|
||||
# This tag requires that the tag GENERATE_LATEX is set to YES.
|
||||
|
||||
@@ -2222,9 +2265,9 @@ HIDE_UNDOC_RELATIONS = YES
|
||||
|
||||
# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
|
||||
# available from the path. This tool is part of Graphviz (see:
|
||||
# https://www.graphviz.org/), a graph visualization toolkit from AT&T
|
||||
# and Lucent Bell Labs. The other options in this section have no
|
||||
# effect if this option is set to NO
|
||||
# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent
|
||||
# Bell Labs. The other options in this section have no effect if this option is
|
||||
# set to NO
|
||||
# The default value is: NO.
|
||||
|
||||
HAVE_DOT = YES
|
||||
@@ -2304,10 +2347,32 @@ UML_LOOK = NO
|
||||
# but if the number exceeds 15, the total amount of fields shown is limited to
|
||||
# 10.
|
||||
# Minimum value: 0, maximum value: 100, default value: 10.
|
||||
# This tag requires that the tag HAVE_DOT is set to YES.
|
||||
# This tag requires that the tag UML_LOOK is set to YES.
|
||||
|
||||
UML_LIMIT_NUM_FIELDS = 10
|
||||
|
||||
# If the DOT_UML_DETAILS tag is set to NO, doxygen will show attributes and
|
||||
# methods without types and arguments in the UML graphs. If the DOT_UML_DETAILS
|
||||
# tag is set to YES, doxygen will add type and arguments for attributes and
|
||||
# methods in the UML graphs. If the DOT_UML_DETAILS tag is set to NONE, doxygen
|
||||
# will not generate fields with class member information in the UML graphs. The
|
||||
# class diagrams will look similar to the default class diagrams but using UML
|
||||
# notation for the relationships.
|
||||
# Possible values are: NO, YES and NONE.
|
||||
# The default value is: NO.
|
||||
# This tag requires that the tag UML_LOOK is set to YES.
|
||||
|
||||
DOT_UML_DETAILS = NO
|
||||
|
||||
# The DOT_WRAP_THRESHOLD tag can be used to set the maximum number of characters
|
||||
# to display on a single line. If the actual line length exceeds this threshold
|
||||
# significantly it will wrapped across multiple lines. Some heuristics are apply
|
||||
# to avoid ugly line breaks.
|
||||
# Minimum value: 0, maximum value: 1000, default value: 17.
|
||||
# This tag requires that the tag HAVE_DOT is set to YES.
|
||||
|
||||
DOT_WRAP_THRESHOLD = 17
|
||||
|
||||
# If the TEMPLATE_RELATIONS tag is set to YES then the inheritance and
|
||||
# collaboration graphs will show the relations between templates and their
|
||||
# instances.
|
||||
@@ -2377,7 +2442,7 @@ DIRECTORY_GRAPH = YES
|
||||
# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
|
||||
# generated by dot. For an explanation of the image formats see the section
|
||||
# output formats in the documentation of the dot tool (Graphviz (see:
|
||||
# https://www.graphviz.org/)).
|
||||
# http://www.graphviz.org/)).
|
||||
# Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order
|
||||
# to make the SVG files visible in IE 9+ (other browsers do not have this
|
||||
# requirement).
|
||||
@@ -2497,9 +2562,11 @@ DOT_MULTI_TARGETS = NO
|
||||
|
||||
GENERATE_LEGEND = YES
|
||||
|
||||
# If the DOT_CLEANUP tag is set to YES, doxygen will remove the intermediate dot
|
||||
# If the DOT_CLEANUP tag is set to YES, doxygen will remove the intermediate
|
||||
# files that are used to generate the various graphs.
|
||||
#
|
||||
# Note: This setting is not only used for dot files but also for msc and
|
||||
# plantuml temporary files.
|
||||
# The default value is: YES.
|
||||
# This tag requires that the tag HAVE_DOT is set to YES.
|
||||
|
||||
DOT_CLEANUP = YES
|
||||
|
||||
+913
-376
File diff suppressed because it is too large
Load Diff
+1
-1
@@ -581,7 +581,7 @@ sub generate_grammar_list ($$@)
|
||||
or die;
|
||||
print $out <<EOF;
|
||||
%language "C++"
|
||||
%defines
|
||||
%header
|
||||
%locations
|
||||
$directives
|
||||
|
||||
|
||||
@@ -11,8 +11,8 @@ variant-11: CXXFLAGS = -std=c++11
|
||||
|
||||
all: $(PROGS)
|
||||
|
||||
%.cc %.hh: %.yy
|
||||
$(BISON) $(BISONFLAGS) -o $*.cc $<
|
||||
%.cc %.hh %.html %.gv: %.yy
|
||||
$(BISON) $(BISONFLAGS) --html --graph -o $*.cc $<
|
||||
|
||||
%: %.cc
|
||||
$(CXX) $(CXXFLAGS) -o$@ $<
|
||||
|
||||
@@ -39,6 +39,15 @@ 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).
|
||||
|
||||
## glr
|
||||
|
||||
This example demonstrates the use of GLR parsers to handle (local)
|
||||
ambiguities in the C++ language. See the node "Merging GLR Parses" in
|
||||
Bison's documentation.
|
||||
|
||||
It uses (Bison) variants to store objects as semantic values. It also
|
||||
demonstrates custom error messages in C++.
|
||||
|
||||
<!---
|
||||
|
||||
Local Variables:
|
||||
|
||||
@@ -5,12 +5,11 @@ BASE = calc++
|
||||
BISON = bison
|
||||
CXX = g++
|
||||
FLEX = flex
|
||||
XSLTPROC = xsltproc
|
||||
|
||||
all: $(BASE)
|
||||
|
||||
%.cc %.hh %.xml %.gv: %.yy
|
||||
$(BISON) $(BISONFLAGS) --xml --graph=$*.gv -o $*.cc $<
|
||||
%.cc %.hh %.html %.gv: %.yy
|
||||
$(BISON) $(BISONFLAGS) --html --graph -o $*.cc $<
|
||||
|
||||
%.cc: %.ll
|
||||
$(FLEX) $(FLEXFLAGS) -o$@ $<
|
||||
@@ -29,10 +28,6 @@ run: $(BASE)
|
||||
@echo "Type arithmetic expressions. Quit with ctrl-d."
|
||||
./$< -
|
||||
|
||||
html: parser.html
|
||||
%.html: %.xml
|
||||
$(XSLTPROC) $(XSLTPROCFLAGS) -o $@ $$($(BISON) --print-datadir)/xslt/xml2xhtml.xsl $<
|
||||
|
||||
CLEANFILES = \
|
||||
$(BASE) *.o \
|
||||
parser.hh parser.cc parser.output parser.xml parser.html parser.gv location.hh \
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
## Parser generation. ##
|
||||
## ------------------- ##
|
||||
|
||||
%D%/parser.stamp: $(dependencies)
|
||||
SUFFIXES += .yy .stamp
|
||||
.yy.stamp:
|
||||
$(AM_V_YACC)rm -f $@
|
||||
@@ -26,12 +25,13 @@ SUFFIXES += .yy .stamp
|
||||
$(AM_V_at)$(YACCCOMPILE) -o $*.cc $<
|
||||
$(AM_V_at)mv -f $@.tmp $@
|
||||
|
||||
%D%/parser.stamp: $(dependencies)
|
||||
$(calcxx_sources_generated): %D%/parser.stamp
|
||||
@test -f $@ || rm -f %D%/parser.stamp
|
||||
@test -f $@ || $(MAKE) $(AM_MAKEFLAGS) %D%/parser.stamp
|
||||
CLEANFILES += \
|
||||
$(calcxx_sources_generated) \
|
||||
%D%/parser.dot \
|
||||
%D%/parser.gv \
|
||||
%D%/parser.output \
|
||||
%D%/parser.stamp \
|
||||
%D%/scanner.cc
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
# This Makefile is designed to be simple and readable. It does not
|
||||
# aim at portability. It requires GNU Make.
|
||||
|
||||
BASE = c++-types
|
||||
BISON = bison
|
||||
|
||||
all: $(BASE)
|
||||
|
||||
%.c %.h %.html %.gv: %.y
|
||||
$(BISON) $(BISONFLAGS) --header --html --graph -o $*.c $<
|
||||
|
||||
$(BASE): $(BASE).o
|
||||
$(CC) $(CFLAGS) -o $@ $^
|
||||
|
||||
run: $(BASE)
|
||||
@echo "Type C++ declarations or expressions. Quit with ctrl-d."
|
||||
./$<
|
||||
|
||||
CLEANFILES = \
|
||||
$(BASE) *.o $(BASE).[ch] $(BASE).output $(BASE).xml $(BASE).html $(BASE).gv
|
||||
|
||||
clean:
|
||||
rm -f $(CLEANFILES)
|
||||
@@ -0,0 +1,27 @@
|
||||
# glr
|
||||
|
||||
This example demonstrates the use of GLR parsers to handle (local)
|
||||
ambiguities in the C++ language. See the node "Merging GLR Parses" in
|
||||
Bison's documentation.
|
||||
|
||||
It uses (Bison) variants to store objects as semantic values. It also
|
||||
demonstrates custom error messages in C++.
|
||||
|
||||
<!---
|
||||
Local Variables:
|
||||
fill-column: 76
|
||||
ispell-dictionary: "american"
|
||||
End:
|
||||
|
||||
Copyright (C) 2020-2021 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.
|
||||
|
||||
--->
|
||||
@@ -0,0 +1,173 @@
|
||||
/*
|
||||
Copyright (C) 2020-2021 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <cstddef> // nullptr_t
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
|
||||
// Type erasure 101 <https://stackoverflow.com/a/26199467/1353549>.
|
||||
class NodeInterface;
|
||||
|
||||
class Node
|
||||
{
|
||||
public:
|
||||
Node (const Node& node) = default;
|
||||
Node (Node&& node) = default;
|
||||
Node () = default;
|
||||
~Node () = default;
|
||||
|
||||
template <typename T,
|
||||
// SFINAE block using this ctor as a copy/move ctor:
|
||||
std::enable_if_t<!std::is_same<Node, std::decay_t<T>>::value, int>* = nullptr>
|
||||
Node (T&& t);
|
||||
|
||||
Node& operator= (const Node& node) = default;
|
||||
Node& operator= (Node&& node) = default;
|
||||
|
||||
explicit operator bool () const
|
||||
{
|
||||
return impl_ != nullptr;
|
||||
}
|
||||
|
||||
std::ostream& print (std::ostream& o) const;
|
||||
|
||||
std::shared_ptr<NodeInterface> impl_;
|
||||
};
|
||||
|
||||
static std::ostream&
|
||||
operator<< (std::ostream& o, const Node &node)
|
||||
{
|
||||
return node.print (o);
|
||||
}
|
||||
|
||||
class NodeInterface
|
||||
{
|
||||
public:
|
||||
virtual ~NodeInterface () = default;
|
||||
virtual std::ostream& print (std::ostream& o) const = 0;
|
||||
};
|
||||
|
||||
|
||||
std::ostream& Node::print (std::ostream& o) const
|
||||
{
|
||||
if (impl_)
|
||||
impl_->print (o);
|
||||
return o;
|
||||
}
|
||||
|
||||
|
||||
template <typename T,
|
||||
std::enable_if_t<!std::is_same<std::nullptr_t, std::decay_t<T>>::value, int>* = nullptr>
|
||||
struct NodeImpl : public NodeInterface
|
||||
{
|
||||
template <typename U>
|
||||
explicit NodeImpl (U&& u)
|
||||
: t{std::forward<U> (u)}
|
||||
{}
|
||||
virtual ~NodeImpl () = default;
|
||||
virtual std::ostream& print (std::ostream& o) const
|
||||
{
|
||||
return o << t;
|
||||
}
|
||||
|
||||
T t;
|
||||
};
|
||||
|
||||
|
||||
template <typename T,
|
||||
std::enable_if_t<!std::is_same<Node, std::decay_t<T>>::value, int>*>
|
||||
Node::Node (T&& t)
|
||||
: impl_ (new NodeImpl<std::decay_t<T>>{std::forward<T> (t)})
|
||||
{}
|
||||
|
||||
class Nterm
|
||||
{
|
||||
public:
|
||||
Nterm (std::string form,
|
||||
Node child0 = Node (), Node child1 = Node (), Node child2 = Node ())
|
||||
: form_ (std::move (form))
|
||||
{
|
||||
children_[0] = child0;
|
||||
children_[1] = child1;
|
||||
children_[2] = child2;
|
||||
}
|
||||
|
||||
friend std::ostream& operator<< (std::ostream& o, const Nterm& t)
|
||||
{
|
||||
o << t.form_;
|
||||
if (t.children_[0])
|
||||
{
|
||||
o << '(' << t.children_[0];
|
||||
if (t.children_[1])
|
||||
o << ", " << t.children_[1];
|
||||
if (t.children_[2])
|
||||
o << ", " << t.children_[2];
|
||||
o << ')';
|
||||
}
|
||||
return o;
|
||||
}
|
||||
|
||||
private:
|
||||
std::string form_;
|
||||
Node children_[3];
|
||||
};
|
||||
|
||||
|
||||
|
||||
class Term
|
||||
{
|
||||
public:
|
||||
Term (std::string text)
|
||||
: text_ (std::move (text))
|
||||
{}
|
||||
|
||||
friend std::ostream& operator<< (std::ostream& o, const Term& t)
|
||||
{
|
||||
return o << t.text_;
|
||||
}
|
||||
|
||||
private:
|
||||
std::string text_;
|
||||
};
|
||||
|
||||
#ifdef TEST
|
||||
int main ()
|
||||
{
|
||||
Node n0;
|
||||
std::cout << n0 << '\n';
|
||||
|
||||
Node n;
|
||||
n = n0;
|
||||
std::cout << n0 << '\n';
|
||||
|
||||
Term t1 = Term ("T");
|
||||
std::cout << t1 << '\n';
|
||||
|
||||
n = t1;
|
||||
std::cout << n << '\n';
|
||||
std::cout << Nterm ("+", t1, t1) << '\n';
|
||||
|
||||
auto n1
|
||||
= Nterm ("<OR>",
|
||||
Nterm ("<declare>", Term ("T"), Term ("x")),
|
||||
Nterm ("<cast>", Term ("x"), Term ("T")));
|
||||
std::cout << n1 << '\n';
|
||||
|
||||
n = n1;
|
||||
std::cout << n1 << '\n';
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,50 @@
|
||||
#! /bin/sh
|
||||
|
||||
# Copyright (C) 2020-2021 Free Software Foundation, Inc.
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
cat >input <<EOF
|
||||
z + q;
|
||||
|
||||
T x;
|
||||
|
||||
T x = y;
|
||||
|
||||
x = y;
|
||||
EOF
|
||||
run 0 "\
|
||||
1.0-5: +(z, q)
|
||||
3.0-3: <declare>(T, x)
|
||||
5.0-7: <init-declare>(T, x, y)
|
||||
7.0-5: =(x, y)"
|
||||
|
||||
cat >input <<EOF
|
||||
T (x) + y;
|
||||
|
||||
T (x);
|
||||
|
||||
T (y) = z + q;
|
||||
|
||||
T (y y) = z + q;
|
||||
|
||||
z + q;
|
||||
EOF
|
||||
run 0 "\
|
||||
1.0-9: +(<cast>(x, T), y)
|
||||
3.0-5: <OR>(<declare>(T, x), <cast>(x, T))
|
||||
5.0-13: <OR>(<init-declare>(T, y, +(z, q)), =(<cast>(y, T), +(z, q)))
|
||||
7.0-15: <error>
|
||||
9.0-5: +(z, q)
|
||||
err: 7.5: syntax error on token identifier (expected = or + or ))"
|
||||
@@ -0,0 +1,257 @@
|
||||
/* -*- C++ -*-
|
||||
Copyright (C) 2020-2021 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* Simplified C++ Type and Expression Grammar.
|
||||
Written by Paul Hilfinger for Bison's test suite. */
|
||||
|
||||
%require "3.8"
|
||||
%glr-parser
|
||||
%skeleton "glr2.cc"
|
||||
%define parse.assert
|
||||
%define api.token.constructor
|
||||
%header
|
||||
%locations
|
||||
%debug
|
||||
|
||||
// Custom error messages.
|
||||
%define parse.error custom
|
||||
|
||||
%code requires
|
||||
{
|
||||
#include "ast.hh"
|
||||
}
|
||||
|
||||
%define api.value.type variant
|
||||
|
||||
%code
|
||||
{
|
||||
#include <cassert>
|
||||
#include <cctype>
|
||||
#include <fstream>
|
||||
#include <cstring>
|
||||
|
||||
// Merge two semantic values.
|
||||
static Node
|
||||
stmt_merge (const Node& x0, const Node& x1);
|
||||
|
||||
// Fetch a token.
|
||||
static yy::parser::symbol_type
|
||||
yylex ();
|
||||
}
|
||||
|
||||
%expect-rr 1
|
||||
|
||||
%type <Node> TYPENAME ID stmt expr decl declarator
|
||||
%printer { yyo << $$; } <Node>
|
||||
|
||||
%token
|
||||
TYPENAME "typename"
|
||||
ID "identifier"
|
||||
SEMICOLON ";"
|
||||
EQUAL "="
|
||||
PLUS "+"
|
||||
LPAREN "("
|
||||
RPAREN ")"
|
||||
|
||||
%right "="
|
||||
%left "+"
|
||||
|
||||
%%
|
||||
|
||||
prog : %empty
|
||||
| prog stmt { std::cout << @2 << ": " << $2 << '\n'; }
|
||||
;
|
||||
|
||||
stmt : expr ";" %merge <stmt_merge> { $$ = $1; }
|
||||
| decl %merge <stmt_merge>
|
||||
| error ";" { $$ = Nterm ("<error>"); }
|
||||
;
|
||||
|
||||
expr : ID
|
||||
| TYPENAME "(" expr ")" { $$ = Nterm ("<cast>", $3, $1); }
|
||||
| expr "+" expr { $$ = Nterm ("+", $1, $3); }
|
||||
| expr "=" expr { $$ = Nterm ("=", $1, $3); }
|
||||
;
|
||||
|
||||
decl : TYPENAME declarator ";"
|
||||
{ $$ = Nterm ("<declare>", $1, $2); }
|
||||
| TYPENAME declarator "=" expr ";"
|
||||
{ $$ = Nterm ("<init-declare>", $1, $2, $4); }
|
||||
;
|
||||
|
||||
declarator
|
||||
: ID
|
||||
| "(" declarator ")" { $$ = $2; }
|
||||
;
|
||||
|
||||
%%
|
||||
std::istream* input = nullptr;
|
||||
yy::parser::location_type loc;
|
||||
|
||||
|
||||
/*---------.
|
||||
| Parser. |
|
||||
`---------*/
|
||||
|
||||
// Generate a custom error message.
|
||||
void
|
||||
yy::parser::report_syntax_error (const context& ctx) const
|
||||
{
|
||||
std::cerr << ctx.location () << ": syntax error";
|
||||
if (!ctx.lookahead ().empty ())
|
||||
std::cerr << " on token " << ctx.lookahead ().name ();
|
||||
{
|
||||
enum { TOKENMAX = 10 };
|
||||
symbol_kind_type expected[TOKENMAX];
|
||||
int n = ctx.expected_tokens (expected, TOKENMAX);
|
||||
if (0 < n)
|
||||
{
|
||||
for (int i = 0; i < n; ++i)
|
||||
std::cerr << (i == 0 ? " (expected " : " or ")
|
||||
<< symbol_name (expected[i]);
|
||||
std::cerr << ')';
|
||||
}
|
||||
}
|
||||
std::cerr << '\n';
|
||||
}
|
||||
|
||||
// Report the error to the user.
|
||||
void
|
||||
yy::parser::error (const location_type& l, const std::string& m)
|
||||
{
|
||||
std::cerr << l << ": " << m << '\n';
|
||||
}
|
||||
|
||||
// Fetch the next token.
|
||||
static yy::parser::symbol_type
|
||||
yylex ()
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
loc.step ();
|
||||
loc += 1;
|
||||
assert (!input->eof ());
|
||||
switch (int c = input->get ())
|
||||
{
|
||||
case EOF:
|
||||
return yy::parser::make_YYEOF (loc);
|
||||
case '\t':
|
||||
loc.end.column = (loc.end.column + 7) & ~7;
|
||||
loc.step ();
|
||||
break;
|
||||
case ' ': case '\f':
|
||||
loc.step ();
|
||||
break;
|
||||
case '\n':
|
||||
loc.lines (1);
|
||||
loc.end.column = 0;
|
||||
loc.step ();
|
||||
break;
|
||||
case '+':
|
||||
return yy::parser::make_PLUS (loc);
|
||||
case '=':
|
||||
return yy::parser::make_EQUAL (loc);
|
||||
case '(':
|
||||
return yy::parser::make_LPAREN (loc);
|
||||
case ')':
|
||||
return yy::parser::make_RPAREN (loc);
|
||||
case ';':
|
||||
return yy::parser::make_SEMICOLON (loc);
|
||||
default:
|
||||
if (isalpha (c))
|
||||
{
|
||||
std::string form;
|
||||
do
|
||||
{
|
||||
form += static_cast<char> (c);
|
||||
loc += 1;
|
||||
c = input->get ();
|
||||
}
|
||||
while (isalnum (c) || c == '_');
|
||||
input->unget ();
|
||||
loc -= 1;
|
||||
if (isupper (static_cast <unsigned char> (form[0])))
|
||||
return yy::parser::make_TYPENAME (Term (form), loc);
|
||||
else
|
||||
return yy::parser::make_ID (Term (form), loc);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto msg = "invalid character: " + std::string(1, static_cast<char> (c));
|
||||
throw yy::parser::syntax_error (loc, msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Merge two semantic values as an AST including both alternatives.
|
||||
static Node
|
||||
stmt_merge (const Node& x0, const Node& x1)
|
||||
{
|
||||
return Nterm ("<OR>", x0, x1);
|
||||
}
|
||||
|
||||
|
||||
/*-------.
|
||||
| Main. |
|
||||
`-------*/
|
||||
|
||||
// Parse `file` using parser `parse`.
|
||||
int
|
||||
process (yy::parser& parse, const std::string& file)
|
||||
{
|
||||
bool is_stdin = file == "-" || file.empty ();
|
||||
if (is_stdin)
|
||||
input = &std::cin;
|
||||
else
|
||||
input = new std::ifstream (file.c_str ());
|
||||
loc.initialize (nullptr, 1, 0);
|
||||
int status = parse ();
|
||||
if (!is_stdin)
|
||||
delete input;
|
||||
return status;
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
yy::parser parse;
|
||||
|
||||
if (getenv ("YYDEBUG"))
|
||||
parse.set_debug_level (1);
|
||||
|
||||
bool ran = false;
|
||||
for (int i = 1; i < argc; ++i)
|
||||
// Enable parse traces on option -p.
|
||||
if (strcmp (argv[i], "-p") == 0)
|
||||
parse.set_debug_level (1);
|
||||
else
|
||||
{
|
||||
int status = process (parse, argv[i]);
|
||||
ran = true;
|
||||
if (!status)
|
||||
return status;
|
||||
}
|
||||
|
||||
if (!ran)
|
||||
{
|
||||
int status = process (parse, "");
|
||||
if (!status)
|
||||
return status;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
## Copyright (C) 2020-2021 Free Software Foundation, Inc.
|
||||
##
|
||||
## This program is free software: you can redistribute it and/or modify
|
||||
## it under the terms of the GNU General Public License as published by
|
||||
## the Free Software Foundation, either version 3 of the License, or
|
||||
## (at your option) any later version.
|
||||
##
|
||||
## This program is distributed in the hope that it will be useful,
|
||||
## but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
## GNU General Public License for more details.
|
||||
##
|
||||
## You should have received a copy of the GNU General Public License
|
||||
## along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
glrxxdir = $(docdir)/%D%
|
||||
|
||||
## ----------- ##
|
||||
## c++-types. ##
|
||||
## ----------- ##
|
||||
|
||||
%D%/c++-types.stamp: $(dependencies)
|
||||
$(nodist_%C%_c___types_SOURCES): %D%/c++-types.stamp
|
||||
@test -f $@ || rm -f %D%/c++-types.stamp
|
||||
@test -f $@ || $(MAKE) $(AM_MAKEFLAGS) %D%/c++-types.stamp
|
||||
CLEANFILES += \
|
||||
$(nodist_%C%_c___types_SOURCES) \
|
||||
%D%/c++-types.stamp \
|
||||
%D%/c++-types.output \
|
||||
%D%/location.hh
|
||||
CLEANDIRS += %D%/*.dSYM
|
||||
|
||||
## -------------------- ##
|
||||
## Building & testing. ##
|
||||
## -------------------- ##
|
||||
|
||||
# Avoid using BUILT_SOURCES which is too global.
|
||||
$(%C%_c___types_OBJECTS): $(cxx_types_sources_generated)
|
||||
|
||||
if ENABLE_CXX14
|
||||
check_PROGRAMS += %D%/c++-types
|
||||
dist_%C%_c___types_SOURCES = \
|
||||
%D%/ast.hh
|
||||
nodist_%C%_c___types_SOURCES = \
|
||||
%D%/c++-types.cc \
|
||||
%D%/c++-types.hh
|
||||
# Don't use gnulib's system headers.
|
||||
%C%_c___types_CPPFLAGS = -I$(top_srcdir)/%D% -I$(top_builddir)/%D%
|
||||
%C%_c___types_CXXFLAGS = $(CXX14_CXXFLAGS) $(WARN_CXXFLAGS_TEST)
|
||||
TESTS += %D%/c++-types.test
|
||||
endif ENABLE_CXX14
|
||||
EXTRA_DIST += %D%/c++-types.yy %D%/c++-types.test
|
||||
@@ -15,6 +15,7 @@
|
||||
|
||||
cxxdir = $(docdir)/%D%
|
||||
include %D%/calc++/local.mk
|
||||
include %D%/glr/local.mk
|
||||
|
||||
## -------- ##
|
||||
## Simple. ##
|
||||
@@ -29,7 +30,7 @@ simple_extracted = %D%/simple.yy
|
||||
simple_sources = $(simple_extracted)
|
||||
extracted += $(simple_extracted)
|
||||
|
||||
if ENABLE_CXX14
|
||||
if ENABLE_CXX11
|
||||
check_PROGRAMS += %D%/simple
|
||||
nodist_%C%_simple_SOURCES = $(simple_sources)
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ This example demonstrates best practices when using Bison.
|
||||
push-parser API to feed the parser with the incoming tokens.
|
||||
- It features an interactive command line with completion based on the
|
||||
parser state, based on `yyexpected_tokens`.
|
||||
- It uses Bison's standard catalogue for internationalization of generated
|
||||
- It uses Bison's standard catalog for internationalization of generated
|
||||
messages.
|
||||
- It uses a custom syntax error with location, lookahead correction and
|
||||
token internationalization.
|
||||
|
||||
@@ -3,14 +3,13 @@
|
||||
|
||||
BASE = bistromathic
|
||||
BISON = bison
|
||||
XSLTPROC = xsltproc
|
||||
|
||||
# We need to find the headers and libs for readline (and possibly intl).
|
||||
# You probably need to customize this for your own environment.
|
||||
CPPFLAGS = -I/opt/local/include
|
||||
LDFLAGS = -L/opt/local/lib
|
||||
|
||||
# Find the translation catalogue for Bison's generated messagess.
|
||||
# Find the translation catalog for Bison's generated messagess.
|
||||
BISON_LOCALEDIR = $(shell $(BISON) $(BISON_FLAGS) --print-localedir)
|
||||
CPPFLAGS += -DENABLE_NLS -DBISON_LOCALEDIR='"$(BISON_LOCALEDIR)"'
|
||||
|
||||
@@ -18,8 +17,8 @@ LIBS = -lreadline -lm # In some environments, -lintl is needed.
|
||||
|
||||
all: $(BASE)
|
||||
|
||||
%.c %.h %.xml %.gv: %.y
|
||||
$(BISON) $(BISONFLAGS) --defines --xml --graph=$*.gv -o $*.c $<
|
||||
%.c %.h %.html %.xml %.gv: %.y
|
||||
$(BISON) $(BISONFLAGS) --header --html --graph -o $*.c $<
|
||||
|
||||
$(BASE): parse.o
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) -o $@ $^ $(LDFLAGS) $(LIBS)
|
||||
@@ -28,10 +27,6 @@ run: $(BASE)
|
||||
@echo "Type bistromathic expressions. Quit with ctrl-d."
|
||||
./$<
|
||||
|
||||
html: $(BASE).html
|
||||
%.html: %.xml
|
||||
$(XSLTPROC) $(XSLTPROCFLAGS) -o $@ $$($(BISON) --print-datadir)/xslt/xml2xhtml.xsl $<
|
||||
|
||||
CLEANFILES = \
|
||||
$(BASE) *.o \
|
||||
parse.[ch] parse.output parse.xml parse.html parse.gv
|
||||
|
||||
@@ -9,7 +9,7 @@ This example demonstrates best practices when using Bison.
|
||||
push-parser API to feed the parser with the incoming tokens.
|
||||
- It features an interactive command line with completion based on the
|
||||
parser state, based on `yyexpected_tokens`.
|
||||
- It uses Bison's standard catalogue for internationalization of generated
|
||||
- It uses Bison's standard catalog for internationalization of generated
|
||||
messages.
|
||||
- It uses a custom syntax error with location, lookahead correction and
|
||||
token internationalization.
|
||||
|
||||
@@ -306,10 +306,17 @@ esac
|
||||
sed -e 's/\\t/ /g' >input <<EOF
|
||||
(1+\t\t
|
||||
EOF
|
||||
run 0 '> (1+
|
||||
# Nuke the possible trailing white spaces in the effective output.
|
||||
# This is to cope with some readlines that pad all the suggestions
|
||||
# with white spaces (for alignment), including the last one on a line.
|
||||
#
|
||||
# See for instance <https://trac.macports.org/ticket/59927#comment:48>
|
||||
# and its test-suite.log:
|
||||
# <https://trac.macports.org/attachment/ticket/59927/bison-3.7.6-test-10.13.test-suite.log>
|
||||
run -t 0 '> (1+
|
||||
( - atan cos exp ln number sin sqrt
|
||||
> (1+
|
||||
> ''
|
||||
>
|
||||
err: 1.4: syntax error: expected - or ( or number or function or variable before end of file
|
||||
err: 1 | (1+
|
||||
err: | ^'
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
# define YYENABLE_NLS 1
|
||||
# include <libintl.h>
|
||||
// Unless specified otherwise, we expect bistromathic's own
|
||||
// catalogue to be installed in the same tree as Bison's catalogue.
|
||||
// catalog to be installed in the same tree as Bison's catalog.
|
||||
# ifndef LOCALEDIR
|
||||
# define LOCALEDIR BISON_LOCALEDIR
|
||||
# endif
|
||||
@@ -87,13 +87,17 @@
|
||||
yytoken_kind_t
|
||||
yylex (const char **line, YYSTYPE *yylval, YYLTYPE *yylloc,
|
||||
const user_context *uctx);
|
||||
void yyerror (YYLTYPE *loc, const user_context *uctx,
|
||||
void yyerror (const YYLTYPE *loc, const user_context *uctx,
|
||||
char const *format, ...)
|
||||
__attribute__ ((__format__ (__printf__, 3, 4)));
|
||||
}
|
||||
|
||||
// Emitted in the implementation file.
|
||||
%code {
|
||||
// Print *LOC on OUT.
|
||||
static void location_print (FILE *out, YYLTYPE const * const loc);
|
||||
#define YYLOCATION_PRINT location_print
|
||||
|
||||
#if defined ENABLE_NLS && ENABLE_NLS
|
||||
# define _(Msgid) gettext (Msgid)
|
||||
#else
|
||||
@@ -117,13 +121,13 @@
|
||||
// with TOK_ (e.g., TOK_EOF).
|
||||
%define api.token.prefix {TOK_}
|
||||
|
||||
// Customized syntax error messages (see yyreport_syntax_error).
|
||||
// Customized syntax error messages (see yyreport_syntax_error)...
|
||||
%define parse.error custom
|
||||
|
||||
// with locations.
|
||||
// ... with locations...
|
||||
%locations
|
||||
|
||||
// and accurate list of expected tokens.
|
||||
// ... and accurate list of expected tokens.
|
||||
%define parse.lac full
|
||||
|
||||
// Generate the parser description file (calc.output).
|
||||
@@ -187,7 +191,7 @@ exp:
|
||||
{
|
||||
if ($r == 0)
|
||||
{
|
||||
yyerror (&@$, uctx, "error: division by zero");
|
||||
yyerror (&@$, uctx, _("error: division by zero"));
|
||||
YYERROR;
|
||||
}
|
||||
else
|
||||
@@ -269,6 +273,26 @@ symbol_count (void)
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*------------.
|
||||
| Locations. |
|
||||
`------------*/
|
||||
|
||||
// Print *LOC on OUT. Do it in a compact way, that avoids redundancy.
|
||||
|
||||
static void
|
||||
location_print (FILE *out, YYLTYPE const * const loc)
|
||||
{
|
||||
fprintf (out, "%d.%d", loc->first_line, loc->first_column);
|
||||
|
||||
int end_col = 0 != loc->last_column ? loc->last_column - 1 : 0;
|
||||
if (loc->first_line < loc->last_line)
|
||||
fprintf (out, "-%d.%d", loc->last_line, end_col);
|
||||
else if (loc->first_column < end_col)
|
||||
fprintf (out, "-%d", end_col);
|
||||
}
|
||||
|
||||
|
||||
/*----------.
|
||||
| Scanner. |
|
||||
`----------*/
|
||||
@@ -345,7 +369,7 @@ yylex (const char **line, YYSTYPE *yylval, YYLTYPE *yylloc,
|
||||
|
||||
// Stray characters.
|
||||
default:
|
||||
yyerror (yylloc, uctx, "syntax error: invalid character: %c", c);
|
||||
yyerror (yylloc, uctx, _("syntax error: invalid character: %c"), c);
|
||||
return TOK_YYerror;
|
||||
}
|
||||
}
|
||||
@@ -403,7 +427,7 @@ yyreport_syntax_error (const yypcontext_t *ctx, const user_context *uctx)
|
||||
// %@: location.
|
||||
if (format[0] == '%' && format[1] == '@')
|
||||
{
|
||||
YY_LOCATION_PRINT (stderr, *loc);
|
||||
YYLOCATION_PRINT (stderr, loc);
|
||||
format += 2;
|
||||
}
|
||||
// %u: unexpected token.
|
||||
@@ -441,13 +465,14 @@ yyreport_syntax_error (const yypcontext_t *ctx, const user_context *uctx)
|
||||
}
|
||||
|
||||
|
||||
// Called by yyparse on error.
|
||||
void yyerror (YYLTYPE *loc, const user_context *uctx, char const *format, ...)
|
||||
// Called by yyparse on errors to report the error to the user.
|
||||
void
|
||||
yyerror (const YYLTYPE *loc, const user_context *uctx, char const *format, ...)
|
||||
{
|
||||
if (uctx->silent)
|
||||
return;
|
||||
|
||||
YY_LOCATION_PRINT (stderr, *loc);
|
||||
YYLOCATION_PRINT (stderr, loc);
|
||||
fputs (": ", stderr);
|
||||
va_list args;
|
||||
va_start (args, format);
|
||||
@@ -638,10 +663,10 @@ main (int argc, char const* argv[])
|
||||
#if defined ENABLE_NLS && ENABLE_NLS
|
||||
// Set up internationalization.
|
||||
setlocale (LC_ALL, "");
|
||||
// Use Bison's standard translation catalogue for error messages
|
||||
// Use Bison's standard translation catalog for error messages
|
||||
// (the generated messages).
|
||||
bindtextdomain ("bison-runtime", BISON_LOCALEDIR);
|
||||
// The translation catalogue of bistromathic is actually included in
|
||||
// The translation catalog of bistromathic is actually included in
|
||||
// Bison's. In your own project, use the name of your project.
|
||||
bindtextdomain ("bison", LOCALEDIR);
|
||||
textdomain ("bison");
|
||||
|
||||
@@ -3,12 +3,11 @@
|
||||
|
||||
BASE = calc
|
||||
BISON = bison
|
||||
XSLTPROC = xsltproc
|
||||
|
||||
all: $(BASE)
|
||||
|
||||
%.c %.h %.xml %.gv: %.y
|
||||
$(BISON) $(BISONFLAGS) --defines --xml --graph=$*.gv -o $*.c $<
|
||||
%.c %.h %.html %.xml %.gv: %.y
|
||||
$(BISON) $(BISONFLAGS) --header --html --graph -o $*.c $<
|
||||
|
||||
$(BASE): $(BASE).o
|
||||
$(CC) $(CFLAGS) -o $@ $^
|
||||
@@ -17,10 +16,6 @@ run: $(BASE)
|
||||
@echo "Type arithmetic expressions. Quit with ctrl-d."
|
||||
./$<
|
||||
|
||||
html: $(BASE).html
|
||||
%.html: %.xml
|
||||
$(XSLTPROC) $(XSLTPROCFLAGS) -o $@ $$($(BISON) --print-datadir)/xslt/xml2xhtml.xsl $<
|
||||
|
||||
CLEANFILES = \
|
||||
$(BASE) *.o $(BASE).[ch] $(BASE).output $(BASE).xml $(BASE).html $(BASE).gv
|
||||
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
# This Makefile is designed to be simple and readable. It does not
|
||||
# aim at portability. It requires GNU Make.
|
||||
|
||||
BASE = c++-types
|
||||
BISON = bison
|
||||
|
||||
all: $(BASE)
|
||||
|
||||
%.c %.h %.xml %.gv: %.y
|
||||
$(BISON) $(BISONFLAGS) --header --graph -o $*.c $<
|
||||
|
||||
$(BASE): $(BASE).o
|
||||
$(CC) $(CFLAGS) -o $@ $^
|
||||
|
||||
run: $(BASE)
|
||||
@echo "Type C++ declarations or expressions. Quit with ctrl-d."
|
||||
./$<
|
||||
|
||||
CLEANFILES = \
|
||||
$(BASE) *.o $(BASE).[ch] $(BASE).output $(BASE).xml $(BASE).html $(BASE).gv
|
||||
|
||||
clean:
|
||||
rm -f $(CLEANFILES)
|
||||
@@ -0,0 +1,24 @@
|
||||
# glr
|
||||
|
||||
This example demonstrates the use of GLR parsers to handle (local)
|
||||
ambiguities in the C++ language. See the node "Merging GLR Parses" in
|
||||
Bison's documentation.
|
||||
|
||||
<!---
|
||||
Local Variables:
|
||||
fill-column: 76
|
||||
ispell-dictionary: "american"
|
||||
End:
|
||||
|
||||
Copyright (C) 2020-2021 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.
|
||||
|
||||
--->
|
||||
@@ -0,0 +1,47 @@
|
||||
#! /bin/sh
|
||||
|
||||
# Copyright (C) 2020-2021 Free Software Foundation, Inc.
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
cat >input <<EOF
|
||||
z + q;
|
||||
|
||||
T x;
|
||||
|
||||
T x = y;
|
||||
|
||||
x = y;
|
||||
|
||||
T (x) + y;
|
||||
|
||||
T (x);
|
||||
|
||||
T (y) = z + q;
|
||||
|
||||
T (y y) = z + q;
|
||||
|
||||
z + q;
|
||||
EOF
|
||||
run 0 "\
|
||||
1.0-5: +(z, q)
|
||||
3.0-3: <declare>(T, x)
|
||||
5.0-7: <init-declare>(T, x, y)
|
||||
7.0-5: =(x, y)
|
||||
9.0-9: +(<cast>(x, T), y)
|
||||
11.0-5: <OR>(<declare>(T, x), <cast>(x, T))
|
||||
13.0-13: <OR>(<init-declare>(T, y, +(z, q)), =(<cast>(y, T), +(z, q)))
|
||||
15.0-15: <error>
|
||||
17.0-5: +(z, q)
|
||||
err: 15.5: syntax error, unexpected identifier, expecting '=' or '+' or ')'"
|
||||
@@ -0,0 +1,340 @@
|
||||
/* -*- C -*-
|
||||
Copyright (C) 2020-2021 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* Simplified C++ Type and Expression Grammar.
|
||||
Written by Paul Hilfinger for Bison's test suite. */
|
||||
|
||||
%define api.pure
|
||||
%header
|
||||
%define api.header.include {"c++-types.h"}
|
||||
%locations
|
||||
%debug
|
||||
|
||||
/* Nice error messages with details. */
|
||||
%define parse.error detailed
|
||||
|
||||
%code requires
|
||||
{
|
||||
union Node {
|
||||
struct {
|
||||
int isNterm;
|
||||
int parents;
|
||||
} nodeInfo;
|
||||
struct {
|
||||
int isNterm; /* 1 */
|
||||
int parents;
|
||||
char const *form;
|
||||
union Node *children[3];
|
||||
} nterm;
|
||||
struct {
|
||||
int isNterm; /* 0 */
|
||||
int parents;
|
||||
char *text;
|
||||
} term;
|
||||
};
|
||||
typedef union Node Node;
|
||||
}
|
||||
|
||||
%define api.value.type union
|
||||
|
||||
%code
|
||||
{
|
||||
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
static Node *new_nterm (char const *, Node *, Node *, Node *);
|
||||
static Node *new_term (char *);
|
||||
static void free_node (Node *);
|
||||
static char *node_to_string (const Node *);
|
||||
static void node_print (FILE *, const Node *);
|
||||
static Node *stmt_merge (YYSTYPE x0, YYSTYPE x1);
|
||||
|
||||
static void yyerror (YYLTYPE const * const loc, const char *msg);
|
||||
static yytoken_kind_t yylex (YYSTYPE *lval, YYLTYPE *lloc);
|
||||
}
|
||||
|
||||
%expect-rr 1
|
||||
|
||||
%token
|
||||
TYPENAME "typename"
|
||||
ID "identifier"
|
||||
|
||||
%right '='
|
||||
%left '+'
|
||||
|
||||
%glr-parser
|
||||
|
||||
%type <Node *> stmt expr decl declarator TYPENAME ID
|
||||
%destructor { free_node ($$); } <Node *>
|
||||
%printer { node_print (yyo, $$); } <Node *>
|
||||
|
||||
%%
|
||||
|
||||
prog : %empty
|
||||
| prog stmt {
|
||||
YYLOCATION_PRINT (stdout, &@2);
|
||||
fputs (": ", stdout);
|
||||
node_print (stdout, $2);
|
||||
putc ('\n', stdout);
|
||||
fflush (stdout);
|
||||
free_node ($2);
|
||||
}
|
||||
;
|
||||
|
||||
stmt : expr ';' %merge <stmt_merge> { $$ = $1; }
|
||||
| decl %merge <stmt_merge>
|
||||
| error ';' { $$ = new_nterm ("<error>", NULL, NULL, NULL); }
|
||||
;
|
||||
|
||||
expr : ID
|
||||
| TYPENAME '(' expr ')'
|
||||
{ $$ = new_nterm ("<cast>(%s, %s)", $3, $1, NULL); }
|
||||
| expr '+' expr { $$ = new_nterm ("+(%s, %s)", $1, $3, NULL); }
|
||||
| expr '=' expr { $$ = new_nterm ("=(%s, %s)", $1, $3, NULL); }
|
||||
;
|
||||
|
||||
decl : TYPENAME declarator ';'
|
||||
{ $$ = new_nterm ("<declare>(%s, %s)", $1, $2, NULL); }
|
||||
| TYPENAME declarator '=' expr ';'
|
||||
{ $$ = new_nterm ("<init-declare>(%s, %s, %s)", $1,
|
||||
$2, $4); }
|
||||
;
|
||||
|
||||
declarator
|
||||
: ID
|
||||
| '(' declarator ')' { $$ = $2; }
|
||||
;
|
||||
|
||||
%%
|
||||
|
||||
/* A C error reporting function. */
|
||||
static void
|
||||
yyerror (YYLTYPE const * const loc, const char *msg)
|
||||
{
|
||||
YYLOCATION_PRINT (stderr, loc);
|
||||
fprintf (stderr, ": %s\n", msg);
|
||||
}
|
||||
|
||||
/* The input file. */
|
||||
FILE * input = NULL;
|
||||
|
||||
yytoken_kind_t
|
||||
yylex (YYSTYPE *lval, YYLTYPE *lloc)
|
||||
{
|
||||
static int lineNum = 1;
|
||||
static int colNum = 0;
|
||||
|
||||
while (1)
|
||||
{
|
||||
int c;
|
||||
assert (!feof (input));
|
||||
c = getc (input);
|
||||
switch (c)
|
||||
{
|
||||
case EOF:
|
||||
return 0;
|
||||
case '\t':
|
||||
colNum = (colNum + 7) & ~7;
|
||||
break;
|
||||
case ' ': case '\f':
|
||||
colNum += 1;
|
||||
break;
|
||||
case '\n':
|
||||
lineNum += 1;
|
||||
colNum = 0;
|
||||
break;
|
||||
default:
|
||||
{
|
||||
yytoken_kind_t tok;
|
||||
lloc->first_line = lloc->last_line = lineNum;
|
||||
lloc->first_column = colNum;
|
||||
if (isalpha (c))
|
||||
{
|
||||
char buffer[256];
|
||||
unsigned i = 0;
|
||||
|
||||
do
|
||||
{
|
||||
buffer[i++] = (char) c;
|
||||
colNum += 1;
|
||||
assert (i != sizeof buffer - 1);
|
||||
c = getc (input);
|
||||
}
|
||||
while (isalnum (c) || c == '_');
|
||||
|
||||
ungetc (c, input);
|
||||
buffer[i++] = 0;
|
||||
if (isupper ((unsigned char) buffer[0]))
|
||||
{
|
||||
tok = TYPENAME;
|
||||
lval->TYPENAME = new_term (strcpy (malloc (i), buffer));
|
||||
}
|
||||
else
|
||||
{
|
||||
tok = ID;
|
||||
lval->ID = new_term (strcpy (malloc (i), buffer));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
colNum += 1;
|
||||
tok = c;
|
||||
}
|
||||
lloc->last_column = colNum;
|
||||
return tok;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static Node *
|
||||
new_nterm (char const *form, Node *child0, Node *child1, Node *child2)
|
||||
{
|
||||
Node *res = malloc (sizeof *res);
|
||||
res->nterm.isNterm = 1;
|
||||
res->nterm.parents = 0;
|
||||
res->nterm.form = form;
|
||||
res->nterm.children[0] = child0;
|
||||
if (child0)
|
||||
child0->nodeInfo.parents += 1;
|
||||
res->nterm.children[1] = child1;
|
||||
if (child1)
|
||||
child1->nodeInfo.parents += 1;
|
||||
res->nterm.children[2] = child2;
|
||||
if (child2)
|
||||
child2->nodeInfo.parents += 1;
|
||||
return res;
|
||||
}
|
||||
|
||||
static Node *
|
||||
new_term (char *text)
|
||||
{
|
||||
Node *res = malloc (sizeof *res);
|
||||
res->term.isNterm = 0;
|
||||
res->term.parents = 0;
|
||||
res->term.text = text;
|
||||
return res;
|
||||
}
|
||||
|
||||
static void
|
||||
free_node (Node *node)
|
||||
{
|
||||
if (!node)
|
||||
return;
|
||||
node->nodeInfo.parents -= 1;
|
||||
/* Free only if 0 (last parent) or -1 (no parents). */
|
||||
if (node->nodeInfo.parents > 0)
|
||||
return;
|
||||
if (node->nodeInfo.isNterm == 1)
|
||||
{
|
||||
free_node (node->nterm.children[0]);
|
||||
free_node (node->nterm.children[1]);
|
||||
free_node (node->nterm.children[2]);
|
||||
}
|
||||
else
|
||||
free (node->term.text);
|
||||
free (node);
|
||||
}
|
||||
|
||||
static char *
|
||||
node_to_string (const Node *node)
|
||||
{
|
||||
char *res;
|
||||
if (!node)
|
||||
{
|
||||
res = malloc (1);
|
||||
res[0] = 0;
|
||||
}
|
||||
else if (node->nodeInfo.isNterm == 1)
|
||||
{
|
||||
char *child0 = node_to_string (node->nterm.children[0]);
|
||||
char *child1 = node_to_string (node->nterm.children[1]);
|
||||
char *child2 = node_to_string (node->nterm.children[2]);
|
||||
res = malloc (strlen (node->nterm.form) + strlen (child0)
|
||||
+ strlen (child1) + strlen (child2) + 1);
|
||||
sprintf (res, node->nterm.form, child0, child1, child2);
|
||||
free (child2);
|
||||
free (child1);
|
||||
free (child0);
|
||||
}
|
||||
else
|
||||
res = strdup (node->term.text);
|
||||
return res;
|
||||
}
|
||||
|
||||
static void
|
||||
node_print (FILE *out, const Node *n)
|
||||
{
|
||||
char *str = node_to_string (n);
|
||||
fputs (str, out);
|
||||
free (str);
|
||||
}
|
||||
|
||||
|
||||
static Node *
|
||||
stmt_merge (YYSTYPE x0, YYSTYPE x1)
|
||||
{
|
||||
return new_nterm ("<OR>(%s, %s)", x0.stmt, x1.stmt, NULL);
|
||||
}
|
||||
|
||||
static int
|
||||
process (const char *file)
|
||||
{
|
||||
int is_stdin = !file || strcmp (file, "-") == 0;
|
||||
if (is_stdin)
|
||||
input = stdin;
|
||||
else
|
||||
input = fopen (file, "r");
|
||||
assert (input);
|
||||
int status = yyparse ();
|
||||
if (!is_stdin)
|
||||
fclose (input);
|
||||
return status;
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
if (getenv ("YYDEBUG"))
|
||||
yydebug = 1;
|
||||
|
||||
int ran = 0;
|
||||
for (int i = 1; i < argc; ++i)
|
||||
// Enable parse traces on option -p.
|
||||
if (strcmp (argv[i], "-p") == 0)
|
||||
yydebug = 1;
|
||||
else
|
||||
{
|
||||
int status = process (argv[i]);
|
||||
ran = 1;
|
||||
if (!status)
|
||||
return status;
|
||||
}
|
||||
|
||||
if (!ran)
|
||||
{
|
||||
int status = process (NULL);
|
||||
if (!status)
|
||||
return status;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
## Copyright (C) 2020-2021 Free Software Foundation, Inc.
|
||||
##
|
||||
## This program is free software: you can redistribute it and/or modify
|
||||
## it under the terms of the GNU General Public License as published by
|
||||
## the Free Software Foundation, either version 3 of the License, or
|
||||
## (at your option) any later version.
|
||||
##
|
||||
## This program is distributed in the hope that it will be useful,
|
||||
## but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
## GNU General Public License for more details.
|
||||
##
|
||||
## You should have received a copy of the GNU General Public License
|
||||
## along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
glrdir = $(docdir)/%D%
|
||||
|
||||
## ----------- ##
|
||||
## c++-types. ##
|
||||
## ----------- ##
|
||||
|
||||
check_PROGRAMS += %D%/c++-types
|
||||
TESTS += %D%/c++-types.test
|
||||
EXTRA_DIST += %D%/c++-types.test
|
||||
nodist_%C%_c___types_SOURCES = %D%/c++-types.y
|
||||
%D%/c++-types.c: $(dependencies)
|
||||
|
||||
# Don't use gnulib's system headers.
|
||||
%C%_c___types_CPPFLAGS = -I$(top_srcdir)/%D% -I$(top_builddir)/%D%
|
||||
%C%_c___types_CFLAGS = $(TEST_CFLAGS)
|
||||
|
||||
dist_glr_DATA = %D%/c++-types.y %D%/Makefile %D%/README.md
|
||||
CLEANFILES += %D%/c++-types.[ch] %D%/c++-types.output
|
||||
CLEANDIRS += %D%/*.dSYM
|
||||
@@ -4,12 +4,11 @@
|
||||
BASE = lexcalc
|
||||
BISON = bison
|
||||
FLEX = flex
|
||||
XSLTPROC = xsltproc
|
||||
|
||||
all: $(BASE)
|
||||
|
||||
%.c %.h %.xml %.gv: %.y
|
||||
$(BISON) $(BISONFLAGS) --defines --xml --graph=$*.gv -o $*.c $<
|
||||
%.c %.h %.html %.xml %.gv: %.y
|
||||
$(BISON) $(BISONFLAGS) --header --html --graph -o $*.c $<
|
||||
|
||||
%.c: %.l
|
||||
$(FLEX) $(FLEXFLAGS) -o$@ $<
|
||||
@@ -22,10 +21,6 @@ run: $(BASE)
|
||||
@echo "Type arithmetic expressions. Quit with ctrl-d."
|
||||
./$<
|
||||
|
||||
html: parse.html
|
||||
%.html: %.xml
|
||||
$(XSLTPROC) $(XSLTPROCFLAGS) -o $@ $$($(BISON) --print-datadir)/xslt/xml2xhtml.xsl $<
|
||||
|
||||
CLEANFILES = \
|
||||
$(BASE) *.o \
|
||||
parse.[ch] parse.output parse.xml parse.html parse.gv \
|
||||
|
||||
@@ -20,6 +20,15 @@ cat >input <<EOF
|
||||
EOF
|
||||
run 0 7
|
||||
|
||||
cat >input <<EOF
|
||||
1
|
||||
2
|
||||
3
|
||||
EOF
|
||||
run 0 '1
|
||||
2
|
||||
3'
|
||||
|
||||
cat >input <<EOF
|
||||
(1+2) * 3
|
||||
EOF
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
yytoken_kind_t yylex (YYSTYPE* yylval, YYLTYPE *yylloc, int *nerrs)
|
||||
YY_DECL;
|
||||
|
||||
void yyerror (YYLTYPE *loc, int *nerrs, const char *msg);
|
||||
void yyerror (const YYLTYPE *loc, int *nerrs, const char *msg);
|
||||
}
|
||||
|
||||
// Emitted on top of the implementation file.
|
||||
@@ -36,6 +36,7 @@
|
||||
{
|
||||
#include <stdio.h> // printf.
|
||||
#include <stdlib.h> // getenv.
|
||||
#include <string.h> // strcmp.
|
||||
}
|
||||
|
||||
// Include the header in the implementation rather than duplicating it.
|
||||
@@ -114,18 +115,23 @@ exp:
|
||||
%%
|
||||
// Epilogue (C code).
|
||||
|
||||
void yyerror (YYLTYPE *loc, int *nerrs, const char *msg)
|
||||
void yyerror (const YYLTYPE *loc, int *nerrs, const char *msg)
|
||||
{
|
||||
YY_LOCATION_PRINT (stderr, *loc);
|
||||
YYLOCATION_PRINT (stderr, loc);
|
||||
fprintf (stderr, ": %s\n", msg);
|
||||
++*nerrs;
|
||||
}
|
||||
|
||||
int main (void)
|
||||
int main (int argc, const char *argv[])
|
||||
{
|
||||
int nerrs = 0;
|
||||
// Possibly enable parser runtime debugging.
|
||||
yydebug = !!getenv ("YYDEBUG");
|
||||
// Enable parse traces on option -p.
|
||||
for (int i = 1; i < argc; ++i)
|
||||
if (strcmp (argv[i], "-p") == 0)
|
||||
yydebug = 1;
|
||||
|
||||
int nerrs = 0;
|
||||
yyparse (&nerrs);
|
||||
// Exit on failure if there were errors.
|
||||
return !!nerrs;
|
||||
|
||||
@@ -18,6 +18,7 @@ dist_c_DATA = %D%/README.md
|
||||
|
||||
include %D%/bistromathic/local.mk
|
||||
include %D%/calc/local.mk
|
||||
include %D%/glr/local.mk
|
||||
include %D%/lexcalc/local.mk
|
||||
include %D%/mfcalc/local.mk
|
||||
include %D%/pushcalc/local.mk
|
||||
|
||||
@@ -3,12 +3,11 @@
|
||||
|
||||
BASE = mfcalc
|
||||
BISON = bison
|
||||
XSLTPROC = xsltproc
|
||||
|
||||
all: $(BASE)
|
||||
|
||||
%.c %.xml %.gv: %.y
|
||||
$(BISON) $(BISONFLAGS) --xml --graph=$*.gv -o $*.c $<
|
||||
%.c %.html %.gv: %.y
|
||||
$(BISON) $(BISONFLAGS) --html --graph -o $*.c $<
|
||||
|
||||
%: %.c
|
||||
$(CC) $(CFLAGS) -o $@ $<
|
||||
@@ -17,9 +16,5 @@ run: $(BASE)
|
||||
@echo "Type arithmetic expressions. Quit with ctrl-d."
|
||||
./$<
|
||||
|
||||
html: $(BASE).html
|
||||
%.html: %.xml
|
||||
$(XSLTPROC) $(XSLTPROCFLAGS) -o $@ $$($(BISON) --print-datadir)/xslt/xml2xhtml.xsl $<
|
||||
|
||||
clean:
|
||||
rm -f $(BASE) $(BASE).c $(BASE).html $(BASE).xml $(BASE).gv $(BASE).output
|
||||
|
||||
@@ -3,12 +3,11 @@
|
||||
|
||||
BASE = calc
|
||||
BISON = bison
|
||||
XSLTPROC = xsltproc
|
||||
|
||||
all: $(BASE)
|
||||
|
||||
%.c %.h %.xml %.gv: %.y
|
||||
$(BISON) $(BISONFLAGS) --defines --xml --graph=$*.gv -o $*.c $<
|
||||
%.c %.h %.html %.gv: %.y
|
||||
$(BISON) $(BISONFLAGS) --header --html --graph -o $*.c $<
|
||||
|
||||
$(BASE): $(BASE).o
|
||||
$(CC) $(CFLAGS) -o $@ $^
|
||||
@@ -17,10 +16,6 @@ run: $(BASE)
|
||||
@echo "Type arithmetic expressions. Quit with ctrl-d."
|
||||
./$<
|
||||
|
||||
html: $(BASE).html
|
||||
%.html: %.xml
|
||||
$(XSLTPROC) $(XSLTPROCFLAGS) -o $@ $$($(BISON) --print-datadir)/xslt/xml2xhtml.xsl $<
|
||||
|
||||
CLEANFILES = \
|
||||
$(BASE) *.o $(BASE).[ch] $(BASE).output $(BASE).xml $(BASE).html $(BASE).gv
|
||||
|
||||
|
||||
@@ -4,12 +4,11 @@
|
||||
BASE = reccalc
|
||||
BISON = bison
|
||||
FLEX = flex
|
||||
XSLTPROC = xsltproc
|
||||
|
||||
all: $(BASE)
|
||||
|
||||
%.c %.h %.xml %.gv: %.y
|
||||
$(BISON) $(BISONFLAGS) --defines --xml --graph=$*.gv -o $*.c $<
|
||||
$(BISON) $(BISONFLAGS) --header --graph -o $*.c $<
|
||||
|
||||
%.c %.h: %.l
|
||||
$(FLEX) $(FLEXFLAGS) -o$*.c --header=$*.h $<
|
||||
@@ -23,10 +22,6 @@ run: $(BASE)
|
||||
@echo "Type arithmetic expressions. Quit with ctrl-d."
|
||||
./$<
|
||||
|
||||
html: parse.html
|
||||
%.html: %.xml
|
||||
$(XSLTPROC) $(XSLTPROCFLAGS) -o $@ $$($(BISON) --print-datadir)/xslt/xml2xhtml.xsl $<
|
||||
|
||||
CLEANFILES = \
|
||||
$(BASE) *.o \
|
||||
parse.[ch] parse.output parse.xml parse.html parse.gv \
|
||||
|
||||
@@ -3,12 +3,11 @@
|
||||
|
||||
BASE = rpcalc
|
||||
BISON = bison
|
||||
XSLTPROC = xsltproc
|
||||
|
||||
all: $(BASE)
|
||||
|
||||
%.c %.xml %.gv: %.y
|
||||
$(BISON) $(BISONFLAGS) --xml --graph=$*.gv -o $*.c $<
|
||||
%.c %.html %.gv: %.y
|
||||
$(BISON) $(BISONFLAGS) --html --graph -o $*.c $<
|
||||
|
||||
%: %.c
|
||||
$(CC) $(CFLAGS) -o $@ $<
|
||||
@@ -17,9 +16,5 @@ run: $(BASE)
|
||||
@echo "Type arithmetic expressions in Reverse Polish Notation. Quit with ctrl-d."
|
||||
./$<
|
||||
|
||||
html: $(BASE).html
|
||||
%.html: %.xml
|
||||
$(XSLTPROC) $(XSLTPROCFLAGS) -o $@ $$($(BISON) --print-datadir)/xslt/xml2xhtml.xsl $<
|
||||
|
||||
clean:
|
||||
rm -f $(BASE) $(BASE).c $(BASE).html $(BASE).xml $(BASE).gv
|
||||
|
||||
@@ -5,9 +5,12 @@ This directory contains examples of Bison grammar files in D.
|
||||
You can run `make` to compile these examples. And `make clean` to tidy
|
||||
afterwards.
|
||||
|
||||
## d/calc.y
|
||||
## d/simple.y
|
||||
The usual calculator.
|
||||
|
||||
## d/calc.y
|
||||
A richer implementation of the calculator, with location tracking.
|
||||
|
||||
<!---
|
||||
|
||||
Local Variables:
|
||||
|
||||
@@ -3,12 +3,11 @@
|
||||
|
||||
BISON = bison
|
||||
DC = dmd
|
||||
XSLTPROC = xsltproc
|
||||
|
||||
all: calc
|
||||
|
||||
%.d %.xml %.gv: %.y
|
||||
$(BISON) $(BISONFLAGS) --xml --graph=$*.gv -o $*.d $<
|
||||
%.d %.html %.gv: %.y
|
||||
$(BISON) $(BISONFLAGS) --html --graph -o $*.d $<
|
||||
|
||||
%: %.d
|
||||
$(DC) $(DCFLAGS) $<
|
||||
@@ -17,9 +16,5 @@ run: calc
|
||||
@echo "Type arithmetic expressions. Quit with ctrl-d."
|
||||
./$<
|
||||
|
||||
html: calc.html
|
||||
%.html: %.xml
|
||||
$(XSLTPROC) $(XSLTPROCFLAGS) -o $@ $$($(BISON) --print-datadir)/xslt/xml2xhtml.xsl $<
|
||||
|
||||
clean:
|
||||
rm -f calc calc.d calc.xml calc.gv calc.html *.o
|
||||
@@ -0,0 +1,51 @@
|
||||
#! /bin/sh
|
||||
|
||||
# Copyright (C) 2018-2021 Free Software Foundation, Inc.
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
cat >input <<EOF
|
||||
1 + 2 * 3
|
||||
EOF
|
||||
run 0 7
|
||||
|
||||
cat >input <<EOF
|
||||
+1 + +2 * +3
|
||||
EOF
|
||||
run 0 7
|
||||
|
||||
cat >input <<EOF
|
||||
-1 + -2 * -3
|
||||
EOF
|
||||
run 0 5
|
||||
|
||||
cat >input <<EOF
|
||||
1 + 2 * * 3
|
||||
EOF
|
||||
run 1 "err: 1.9: syntax error, unexpected *, expecting + or - or ( or number"
|
||||
|
||||
cat >input <<EOF
|
||||
1111 + 1111 2222
|
||||
EOF
|
||||
run 1 "err: 1.13-16: syntax error, unexpected number"
|
||||
|
||||
cat >input <<EOF
|
||||
1 +
|
||||
EOF
|
||||
run 1 "err: 1.4-2.0: syntax error, unexpected end of line, expecting + or - or ( or number"
|
||||
|
||||
cat >input <<EOF
|
||||
99 009
|
||||
EOF
|
||||
run 1 "err: 1.4-6: syntax error, unexpected number"
|
||||
@@ -0,0 +1,188 @@
|
||||
/* Parser and scanner for calc in D. -*- D -*-
|
||||
|
||||
Copyright (C) 2018-2021 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 <https://www.gnu.org/licenses/>. */
|
||||
|
||||
%language "D"
|
||||
|
||||
%define api.parser.class {Calc}
|
||||
%define api.push-pull push
|
||||
%define api.token.constructor
|
||||
%define api.value.type union
|
||||
%define parse.error detailed
|
||||
%define parse.trace
|
||||
|
||||
%locations
|
||||
|
||||
/* Bison Declarations */
|
||||
%token PLUS "+"
|
||||
MINUS "-"
|
||||
STAR "*"
|
||||
SLASH "/"
|
||||
LPAR "("
|
||||
RPAR ")"
|
||||
EOL "end of line"
|
||||
%token <int> NUM "number"
|
||||
%type <int> exp
|
||||
%printer { yyo.write($$); } <int>
|
||||
|
||||
%left "-" "+"
|
||||
%left "*" "/"
|
||||
%precedence UNARY /* unary operators */
|
||||
|
||||
/* Grammar follows */
|
||||
%%
|
||||
input:
|
||||
line
|
||||
| input line
|
||||
;
|
||||
|
||||
line:
|
||||
EOL
|
||||
| exp EOL { writeln ($exp); }
|
||||
| error EOL { yyerrok(); }
|
||||
;
|
||||
|
||||
exp:
|
||||
NUM { $$ = $1; }
|
||||
| exp "+" exp { $$ = $1 + $3; }
|
||||
| exp "-" exp { $$ = $1 - $3; }
|
||||
| exp "*" exp { $$ = $1 * $3; }
|
||||
| exp "/" exp { $$ = $1 / $3; }
|
||||
| "+" exp %prec UNARY { $$ = $2; }
|
||||
| "-" exp %prec UNARY { $$ = -$2; }
|
||||
| "(" exp ")" { $$ = $2; }
|
||||
;
|
||||
|
||||
%%
|
||||
import std.range.primitives;
|
||||
import std.stdio;
|
||||
|
||||
auto calcLexer(R)(R range)
|
||||
if (isInputRange!R && is(ElementType!R : dchar))
|
||||
{
|
||||
return new CalcLexer!R(range);
|
||||
}
|
||||
|
||||
auto calcLexer(File f)
|
||||
{
|
||||
import std.algorithm : map, joiner;
|
||||
import std.utf : byDchar;
|
||||
|
||||
return f.byChunk(1024) // avoid making a syscall roundtrip per char
|
||||
.map!(chunk => cast(char[]) chunk) // because byChunk returns ubyte[]
|
||||
.joiner // combine chunks into a single virtual range of char
|
||||
.calcLexer; // forward to other overload
|
||||
}
|
||||
|
||||
class CalcLexer(R) : Lexer
|
||||
if (isInputRange!R && is(ElementType!R : dchar))
|
||||
{
|
||||
R input;
|
||||
|
||||
this(R r) { input = r; }
|
||||
|
||||
Location location;
|
||||
|
||||
// Should be a local in main, shared with %parse-param.
|
||||
int exit_status = 0;
|
||||
|
||||
void yyerror(const Location loc, string s)
|
||||
{
|
||||
exit_status = 1;
|
||||
stderr.writeln(loc.toString(), ": ", s);
|
||||
}
|
||||
|
||||
Symbol yylex()
|
||||
{
|
||||
import std.uni : isWhite, isNumber;
|
||||
|
||||
// Skip initial spaces
|
||||
while (!input.empty && input.front != '\n' && isWhite(input.front))
|
||||
{
|
||||
location.end.column++;
|
||||
input.popFront;
|
||||
}
|
||||
location.step();
|
||||
|
||||
if (input.empty)
|
||||
return Symbol.YYEOF(location);
|
||||
|
||||
// Numbers.
|
||||
if (input.front.isNumber)
|
||||
{
|
||||
import std.compiler : version_minor;
|
||||
static if (version_minor >= 95)
|
||||
{
|
||||
// from Dlang v2.095.0 onwards std.conv.parse reports
|
||||
// the number of consumed characters
|
||||
import std.typecons : Flag, Yes;
|
||||
import std.conv : parse;
|
||||
auto parsed = parse!(int, R, Yes.doCount)(input);
|
||||
int ival = parsed.data;
|
||||
location.end.column += cast(int) parsed.count;
|
||||
}
|
||||
else
|
||||
{
|
||||
auto copy = input;
|
||||
import std.conv : parse;
|
||||
int ival = input.parse!int;
|
||||
while (!input.empty && copy.front != input.front)
|
||||
{
|
||||
location.end.column++;
|
||||
copy.popFront;
|
||||
}
|
||||
}
|
||||
return Symbol.NUM(ival, location);
|
||||
}
|
||||
|
||||
// Individual characters
|
||||
auto ch = input.front;
|
||||
input.popFront;
|
||||
location.end.column++;
|
||||
switch (ch)
|
||||
{
|
||||
case '+': return Symbol.PLUS(location);
|
||||
case '-': return Symbol.MINUS(location);
|
||||
case '*': return Symbol.STAR(location);
|
||||
case '/': return Symbol.SLASH(location);
|
||||
case '(': return Symbol.LPAR(location);
|
||||
case ')': return Symbol.RPAR(location);
|
||||
case '\n':
|
||||
{
|
||||
location.end.line++;
|
||||
location.end.column = 1;
|
||||
return Symbol.EOL(location);
|
||||
}
|
||||
default: assert(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
auto l = calcLexer(stdin);
|
||||
auto p = new Calc(l);
|
||||
import core.stdc.stdlib : getenv;
|
||||
if (getenv("YYDEBUG"))
|
||||
p.setDebugLevel(1);
|
||||
int status;
|
||||
do {
|
||||
status = p.pushParse(l.yylex());
|
||||
} while (status == PUSH_MORE);
|
||||
return l.exit_status;
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
## Copyright (C) 2018-2021 Free Software Foundation, Inc.
|
||||
##
|
||||
## This program is free software: you can redistribute it and/or modify
|
||||
## it under the terms of the GNU General Public License as published by
|
||||
## the Free Software Foundation, either version 3 of the License, or
|
||||
## (at your option) any later version.
|
||||
##
|
||||
## This program is distributed in the hope that it will be useful,
|
||||
## but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
## GNU General Public License for more details.
|
||||
##
|
||||
## You should have received a copy of the GNU General Public License
|
||||
## along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
calcddir = $(docdir)/%D%
|
||||
|
||||
## ------ ##
|
||||
## Calc. ##
|
||||
## ------ ##
|
||||
|
||||
if ENABLE_D
|
||||
check_SCRIPTS += %D%/calc
|
||||
TESTS += %D%/calc.test
|
||||
endif
|
||||
EXTRA_DIST += %D%/calc.test
|
||||
|
||||
%D%/calc.d: %D%/calc.y $(dependencies)
|
||||
$(AM_V_GEN)$(MKDIR_P) %D%
|
||||
$(AM_V_at)$(BISON) -o $@ $(srcdir)/%D%/calc.y
|
||||
|
||||
%D%/calc: %D%/calc.d
|
||||
$(AM_V_GEN) $(DC) $(DCFLAGS) -of$@ %D%/calc.d
|
||||
|
||||
dist_calcd_DATA = %D%/calc.y %D%/Makefile
|
||||
CLEANFILES += %D%/calc %D%/calc.[do]
|
||||
+3
-19
@@ -14,23 +14,7 @@
|
||||
## along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
ddir = $(docdir)/%D%
|
||||
dist_d_DATA = %D%/README.md
|
||||
|
||||
## ------ ##
|
||||
## Calc. ##
|
||||
## ------ ##
|
||||
|
||||
if ENABLE_D
|
||||
check_SCRIPTS += %D%/calc
|
||||
TESTS += %D%/calc.test
|
||||
endif
|
||||
EXTRA_DIST += %D%/calc.test
|
||||
|
||||
%D%/calc.d: %D%/calc.y $(dependencies)
|
||||
$(AM_V_GEN)$(MKDIR_P) %D%
|
||||
$(AM_V_at)$(BISON) -o $@ $(srcdir)/%D%/calc.y
|
||||
|
||||
%D%/calc: %D%/calc.d
|
||||
$(AM_V_GEN) $(DC) $(DCFLAGS) -of$@ %D%/calc.d
|
||||
|
||||
dist_d_DATA = %D%/calc.y %D%/Makefile %D%/README.md
|
||||
CLEANFILES += %D%/calc %D%/calc.[do]
|
||||
include %D%/calc/local.mk
|
||||
include %D%/simple/local.mk
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
# This Makefile is designed to be simple and readable. It does not
|
||||
# aim at portability. It requires GNU Make.
|
||||
|
||||
BISON = bison
|
||||
DC = dmd
|
||||
|
||||
all: calc
|
||||
|
||||
%.d %.html %.gv: %.y
|
||||
$(BISON) $(BISONFLAGS) --html --graph -o $*.d $<
|
||||
|
||||
%: %.d
|
||||
$(DC) $(DCFLAGS) $<
|
||||
|
||||
run: calc
|
||||
@echo "Type arithmetic expressions. Quit with ctrl-d."
|
||||
./$<
|
||||
|
||||
clean:
|
||||
rm -f calc calc.d calc.xml calc.gv calc.html *.o
|
||||
@@ -20,6 +20,16 @@ cat >input <<EOF
|
||||
EOF
|
||||
run 0 7
|
||||
|
||||
cat >input <<EOF
|
||||
+1 + +2 * +3
|
||||
EOF
|
||||
run 0 7
|
||||
|
||||
cat >input <<EOF
|
||||
-1 + -2 * -3
|
||||
EOF
|
||||
run 0 5
|
||||
|
||||
cat >input <<EOF
|
||||
1 + 2 * * 3
|
||||
EOF
|
||||
@@ -20,15 +20,14 @@
|
||||
%language "D"
|
||||
|
||||
%define api.parser.class {Calc}
|
||||
%define parse.error verbose
|
||||
%define parse.error detailed
|
||||
|
||||
%union {
|
||||
int ival;
|
||||
}
|
||||
|
||||
/* Bison Declarations */
|
||||
%token EQ "="
|
||||
PLUS "+"
|
||||
%token PLUS "+"
|
||||
MINUS "-"
|
||||
STAR "*"
|
||||
SLASH "/"
|
||||
@@ -52,7 +51,7 @@ input:
|
||||
line:
|
||||
EOL
|
||||
| exp EOL { writeln ($exp); }
|
||||
| error EOL
|
||||
| error EOL { yyerrok(); }
|
||||
;
|
||||
|
||||
exp:
|
||||
@@ -61,7 +60,7 @@ exp:
|
||||
| exp "-" exp { $$ = $1 - $3; }
|
||||
| exp "*" exp { $$ = $1 * $3; }
|
||||
| exp "/" exp { $$ = $1 / $3; }
|
||||
| "+" exp %prec UNARY { $$ = -$2; }
|
||||
| "+" exp %prec UNARY { $$ = $2; }
|
||||
| "-" exp %prec UNARY { $$ = -$2; }
|
||||
| "(" exp ")" { $$ = $2; }
|
||||
;
|
||||
@@ -71,12 +70,12 @@ import std.range.primitives;
|
||||
import std.stdio;
|
||||
|
||||
auto calcLexer(R)(R range)
|
||||
if (isInputRange!R && is (ElementType!R : dchar))
|
||||
if (isInputRange!R && is(ElementType!R : dchar))
|
||||
{
|
||||
return new CalcLexer!R(range);
|
||||
}
|
||||
|
||||
auto calcLexer (File f)
|
||||
auto calcLexer(File f)
|
||||
{
|
||||
import std.algorithm : map, joiner;
|
||||
import std.utf : byDchar;
|
||||
@@ -88,7 +87,7 @@ auto calcLexer (File f)
|
||||
}
|
||||
|
||||
class CalcLexer(R) : Lexer
|
||||
if (isInputRange!R && is (ElementType!R : dchar))
|
||||
if (isInputRange!R && is(ElementType!R : dchar))
|
||||
{
|
||||
R input;
|
||||
|
||||
@@ -97,60 +96,51 @@ class CalcLexer(R) : Lexer
|
||||
// Should be a local in main, shared with %parse-param.
|
||||
int exit_status = 0;
|
||||
|
||||
public void yyerror (string s)
|
||||
public void yyerror(string s)
|
||||
{
|
||||
exit_status = 1;
|
||||
stderr.writeln (s);
|
||||
stderr.writeln(s);
|
||||
}
|
||||
|
||||
YYSemanticType semanticVal_;
|
||||
|
||||
public final @property YYSemanticType semanticVal ()
|
||||
{
|
||||
return semanticVal_;
|
||||
}
|
||||
|
||||
int yylex ()
|
||||
Symbol yylex()
|
||||
{
|
||||
import std.uni : isWhite, isNumber;
|
||||
|
||||
// Skip initial spaces
|
||||
while (!input.empty && input.front != '\n' && isWhite (input.front))
|
||||
while (!input.empty && input.front != '\n' && isWhite(input.front))
|
||||
input.popFront;
|
||||
|
||||
if (input.empty)
|
||||
return TokenKind.YYEOF;
|
||||
return Symbol(TokenKind.YYEOF);
|
||||
|
||||
// Numbers.
|
||||
if (input.front.isNumber)
|
||||
{
|
||||
import std.conv : parse;
|
||||
semanticVal_.ival = input.parse!int;
|
||||
return TokenKind.NUM;
|
||||
}
|
||||
{
|
||||
import std.conv : parse;
|
||||
return Symbol(TokenKind.NUM, input.parse!int);
|
||||
}
|
||||
|
||||
// Individual characters
|
||||
auto ch = input.front;
|
||||
input.popFront;
|
||||
switch (ch)
|
||||
{
|
||||
case '=': return TokenKind.EQ;
|
||||
case '+': return TokenKind.PLUS;
|
||||
case '-': return TokenKind.MINUS;
|
||||
case '*': return TokenKind.STAR;
|
||||
case '/': return TokenKind.SLASH;
|
||||
case '(': return TokenKind.LPAR;
|
||||
case ')': return TokenKind.RPAR;
|
||||
case '\n': return TokenKind.EOL;
|
||||
{
|
||||
case '+': return Symbol(TokenKind.PLUS);
|
||||
case '-': return Symbol(TokenKind.MINUS);
|
||||
case '*': return Symbol(TokenKind.STAR);
|
||||
case '/': return Symbol(TokenKind.SLASH);
|
||||
case '(': return Symbol(TokenKind.LPAR);
|
||||
case ')': return Symbol(TokenKind.RPAR);
|
||||
case '\n': return Symbol(TokenKind.EOL);
|
||||
default: assert(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main ()
|
||||
int main()
|
||||
{
|
||||
auto l = calcLexer (stdin);
|
||||
auto p = new Calc (l);
|
||||
p.parse ();
|
||||
auto l = calcLexer(stdin);
|
||||
auto p = new Calc(l);
|
||||
p.parse();
|
||||
return l.exit_status;
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
## Copyright (C) 2018-2021 Free Software Foundation, Inc.
|
||||
##
|
||||
## This program is free software: you can redistribute it and/or modify
|
||||
## it under the terms of the GNU General Public License as published by
|
||||
## the Free Software Foundation, either version 3 of the License, or
|
||||
## (at your option) any later version.
|
||||
##
|
||||
## This program is distributed in the hope that it will be useful,
|
||||
## but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
## GNU General Public License for more details.
|
||||
##
|
||||
## You should have received a copy of the GNU General Public License
|
||||
## along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
simpleddir = $(docdir)/%D%
|
||||
|
||||
## ------ ##
|
||||
## Calc. ##
|
||||
## ------ ##
|
||||
|
||||
if ENABLE_D
|
||||
check_SCRIPTS += %D%/calc
|
||||
TESTS += %D%/calc.test
|
||||
endif
|
||||
EXTRA_DIST += %D%/calc.test
|
||||
|
||||
%D%/calc.d: %D%/calc.y $(dependencies)
|
||||
$(AM_V_GEN)$(MKDIR_P) %D%
|
||||
$(AM_V_at)$(BISON) -o $@ $(srcdir)/%D%/calc.y
|
||||
|
||||
%D%/calc: %D%/calc.d
|
||||
$(AM_V_GEN) $(DC) $(DCFLAGS) -of$@ %D%/calc.d
|
||||
|
||||
dist_simpled_DATA = %D%/calc.y %D%/Makefile
|
||||
CLEANFILES += %D%/calc %D%/calc.[do]
|
||||
+10
-8
@@ -23,21 +23,21 @@
|
||||
|
||||
# Look for @example environments preceded with lines such as:
|
||||
#
|
||||
# @comment file calc.y
|
||||
# @comment file c/mfcalc/calc.y
|
||||
# or
|
||||
# @comment file calc.y: 3
|
||||
# @comment file c/mfcalc/calc.y: 3
|
||||
#
|
||||
# and output their content in that file (calc.y). When numbers are
|
||||
# provided, use them to decide the output order (block numbered 1 is
|
||||
# output before block 2, even if the latter appears before). The same
|
||||
# number may be used several time, in which case the order of
|
||||
# and output their content in that file (c/mfcalc/calc.y). When
|
||||
# numbers are provided, use them to decide the output order (block 1
|
||||
# is output before block 2, even if the latter appears before). The
|
||||
# same number may be used several time, in which case the order of
|
||||
# appearance is used.
|
||||
#
|
||||
# Use @ignore for code to extract that must not be part of the
|
||||
# documentation. For instance:
|
||||
#
|
||||
# @ignore
|
||||
# @comment file: calc++/scanner.ll
|
||||
# @comment file: c++/calc++/scanner.ll
|
||||
# @example
|
||||
# // Work around an incompatibility in Flex.
|
||||
# # undef yywrap
|
||||
@@ -87,7 +87,9 @@ sub message($)
|
||||
# The list of files we should extract.
|
||||
my @file_wanted;
|
||||
|
||||
# Whether we should extract that file, and then under which path.
|
||||
# Whether we should extract that file, and then under which path. We
|
||||
# check if the prefix matches. So for instance if "foo/bar.y" is
|
||||
# wanted (i.e., in @FILE_WANTED), "file: bar.y" matches.
|
||||
sub file_wanted ($)
|
||||
{
|
||||
my ($f) = @_;
|
||||
|
||||
@@ -23,11 +23,17 @@
|
||||
%define api.parser.public
|
||||
%define api.push-pull push
|
||||
|
||||
// Customized syntax error messages (see reportSyntaxError)...
|
||||
%define parse.error custom
|
||||
%define parse.trace
|
||||
|
||||
// ... with locations...
|
||||
%locations
|
||||
|
||||
// ... and accurate list of expected tokens.
|
||||
%define parse.lac full
|
||||
|
||||
%define parse.trace
|
||||
|
||||
%code imports {
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
@@ -199,7 +205,7 @@ class CalcLexer implements Calc.Lexer {
|
||||
end.column = 0;
|
||||
return EOL;
|
||||
case StreamTokenizer.TT_WORD:
|
||||
yylval = new Integer(st.sval);
|
||||
yylval = Integer.parseInt(st.sval);
|
||||
end.set(reader.getPreviousPosition());
|
||||
return NUM;
|
||||
case ' ': case '\t':
|
||||
|
||||
@@ -4,12 +4,11 @@
|
||||
BISON = bison
|
||||
JAVAC = javac
|
||||
JAVA = java
|
||||
XSLTPROC = xsltproc
|
||||
|
||||
all: Calc.class
|
||||
|
||||
%.java %.xml %.gv: %.y
|
||||
$(BISON) $(BISONFLAGS) --xml --graph=$*.gv -o $*.java $<
|
||||
%.java %.html %.gv: %.y
|
||||
$(BISON) $(BISONFLAGS) --html --graph -o $*.java $<
|
||||
|
||||
%.class: %.java
|
||||
$(JAVAC) $(JAVACFLAGS) $<
|
||||
@@ -18,9 +17,5 @@ run: Calc.class
|
||||
@echo "Type arithmetic expressions. Quit with ctrl-d."
|
||||
$(JAVA) $(JAVAFLAGS) Calc
|
||||
|
||||
html: Calc.html
|
||||
%.html: %.xml
|
||||
$(XSLTPROC) $(XSLTPROCFLAGS) -o $@ $$($(BISON) --print-datadir)/xslt/xml2xhtml.xsl $<
|
||||
|
||||
clean:
|
||||
rm -f *.class Calc.java Calc.html Calc.xml Calc.gv
|
||||
|
||||
@@ -116,7 +116,7 @@ class CalcLexer implements Calc.Lexer {
|
||||
case StreamTokenizer.TT_EOL:
|
||||
return (int) '\n';
|
||||
case StreamTokenizer.TT_WORD:
|
||||
yylval = new Integer(st.sval);
|
||||
yylval = Integer.parseInt(st.sval);
|
||||
return NUM;
|
||||
default:
|
||||
return ttype;
|
||||
|
||||
@@ -4,12 +4,11 @@
|
||||
BISON = bison
|
||||
JAVAC = javac
|
||||
JAVA = java
|
||||
XSLTPROC = xsltproc
|
||||
|
||||
all: Calc.class
|
||||
|
||||
%.java %.xml %.gv: %.y
|
||||
$(BISON) $(BISONFLAGS) --xml --graph=$*.gv -o $*.java $<
|
||||
%.java %.html %.gv: %.y
|
||||
$(BISON) $(BISONFLAGS) --html --graph -o $*.java $<
|
||||
|
||||
%.class: %.java
|
||||
$(JAVAC) $(JAVACFLAGS) $<
|
||||
@@ -18,9 +17,5 @@ run: Calc.class
|
||||
@echo "Type arithmetic expressions. Quit with ctrl-d."
|
||||
$(JAVA) $(JAVAFLAGS) Calc
|
||||
|
||||
html: Calc.html
|
||||
%.html: %.xml
|
||||
$(XSLTPROC) $(XSLTPROCFLAGS) -o $@ $$($(BISON) --print-datadir)/xslt/xml2xhtml.xsl $<
|
||||
|
||||
clean:
|
||||
rm -f *.class Calc.java Calc.html Calc.xml Calc.gv
|
||||
|
||||
@@ -93,6 +93,9 @@ dist_examples_DATA = %D%/README.md
|
||||
|
||||
CLEANDIRS += %D%/*.dSYM
|
||||
|
||||
.PHONY: check-examples
|
||||
check-examples: check-TESTS
|
||||
|
||||
include %D%/c/local.mk
|
||||
include %D%/c++/local.mk
|
||||
include %D%/d/local.mk
|
||||
|
||||
+13
-6
@@ -91,18 +91,21 @@ skip ()
|
||||
}
|
||||
|
||||
|
||||
# run [-noerr, -n] EXPECTED-EXIT-STATUS EXPECTED-OUTPUT [PARSER-OPTIONS]
|
||||
# ----------------------------------------------------------------------
|
||||
# run [-n, -noerr, -t] EXPECTED-EXIT-STATUS EXPECTED-OUTPUT [PARSER-OPTIONS]
|
||||
# --------------------------------------------------------------------------
|
||||
# -n: no final end-of-line in expected-output
|
||||
# -noerr: ignore stderr, otherwise merge it into effective output.
|
||||
# -n: not final end-of-line in expected-output
|
||||
# -t: nuke the possible trailing white spaces in the effective output.
|
||||
run ()
|
||||
{
|
||||
noerr=false
|
||||
echo=echo
|
||||
noerr=false
|
||||
rstrip=false
|
||||
while true; do
|
||||
case $1 in
|
||||
(-noerr) noerr=true; shift;;
|
||||
(-n) echo=printf; shift;;
|
||||
(-noerr) noerr=true; shift;;
|
||||
(-t) rstrip=true; shift;;
|
||||
(*) break;;
|
||||
esac
|
||||
done
|
||||
@@ -129,7 +132,11 @@ run ()
|
||||
|
||||
# Combine effective output and error streams.
|
||||
{
|
||||
cat out_eff
|
||||
if $rstrip; then
|
||||
sed -e 's/ *$//g' out_eff
|
||||
else
|
||||
cat out_eff
|
||||
fi
|
||||
if ! $noerr; then
|
||||
sed -e 's/^/err: /g' \
|
||||
-e 's/Reducing stack by rule .* (line .*):/Reducing stack by rule XX (line XXX):/g' \
|
||||
|
||||
+1
-1
Submodule gnulib updated: 839ed059f4...7818455627
@@ -1,4 +1,3 @@
|
||||
/remove-potcdate.sin~
|
||||
/*.gmo
|
||||
/*.po
|
||||
/LINGUAS
|
||||
@@ -18,4 +17,5 @@
|
||||
/quot.sed
|
||||
/remove-potcdate.sed
|
||||
/remove-potcdate.sin
|
||||
/remove-potcdate.sin~
|
||||
/stamp-po
|
||||
|
||||
+70
-2
@@ -5,6 +5,7 @@
|
||||
/.deps
|
||||
/.dirstamp
|
||||
/_Noreturn.h
|
||||
/access.c
|
||||
/alignof.h
|
||||
/alloca.h
|
||||
/alloca.in.h
|
||||
@@ -18,6 +19,7 @@
|
||||
/asnprintf.c
|
||||
/asprintf.c
|
||||
/assure.h
|
||||
/at-func.c
|
||||
/attribute.h
|
||||
/basename-lgpl.c
|
||||
/basename-lgpl.h
|
||||
@@ -40,15 +42,20 @@
|
||||
/c-strncasecmp.c
|
||||
/calloc.c
|
||||
/canonicalize-lgpl.c
|
||||
/canonicalize.c
|
||||
/canonicalize.h
|
||||
/careadlinkat.c
|
||||
/careadlinkat.h
|
||||
/cdefs.h
|
||||
/charset.alias
|
||||
/chdir-long.c
|
||||
/chdir-long.h
|
||||
/cloexec.c
|
||||
/cloexec.h
|
||||
/close-stream.c
|
||||
/close-stream.h
|
||||
/close.c
|
||||
/closedir.c
|
||||
/closeout.c
|
||||
/closeout.h
|
||||
/concat-filename.c
|
||||
@@ -57,20 +64,28 @@
|
||||
/config.in.h
|
||||
/configmake.h
|
||||
/diffseq.h
|
||||
/dirent-private.h
|
||||
/dirent.in.h
|
||||
/dirfd.c
|
||||
/dirname-lgpl.c
|
||||
/dirname.c
|
||||
/dirname.h
|
||||
/dup-safer-flag.c
|
||||
/dup-safer.c
|
||||
/dup.c
|
||||
/dup2.c
|
||||
/eloop-threshold.h
|
||||
/errno.h
|
||||
/errno.in.h
|
||||
/error.c
|
||||
/error.h
|
||||
/execute.c
|
||||
/execute.h
|
||||
/exitfail.c
|
||||
/exitfail.h
|
||||
/fatal-signal.c
|
||||
/fatal-signal.h
|
||||
/fchdir.c
|
||||
/fcntl.c
|
||||
/fcntl.h
|
||||
/fcntl.in.h
|
||||
@@ -78,7 +93,17 @@
|
||||
/fd-hook.h
|
||||
/fd-safer-flag.c
|
||||
/fd-safer.c
|
||||
/fdopendir.c
|
||||
/ffs.c
|
||||
/ffsl.c
|
||||
/ffsl.h
|
||||
/file-set.c
|
||||
/file-set.h
|
||||
/filename.h
|
||||
/filenamecat-lgpl.c
|
||||
/filenamecat.h
|
||||
/findprog-in.c
|
||||
/findprog.h
|
||||
/float+.h
|
||||
/float.c
|
||||
/float.h
|
||||
@@ -89,14 +114,18 @@
|
||||
/fpending.h
|
||||
/fprintf.c
|
||||
/fpucw.h
|
||||
/free.c
|
||||
/frexp.c
|
||||
/frexpl.c
|
||||
/fseterr.c
|
||||
/fseterr.h
|
||||
/fstat.c
|
||||
/fstatat.c
|
||||
/fstrcmp.c
|
||||
/fstrcmp.h
|
||||
/fsync.c
|
||||
/getcwd-lgpl.c
|
||||
/getcwd.c
|
||||
/getdelim.c
|
||||
/getdtablesize.c
|
||||
/gethrxtime.c
|
||||
@@ -133,10 +162,14 @@
|
||||
/gl_anytreehash_list2.h
|
||||
/gl_array_list.c
|
||||
/gl_array_list.h
|
||||
/gl_hash_map.c
|
||||
/gl_hash_map.h
|
||||
/gl_linked_list.c
|
||||
/gl_linked_list.h
|
||||
/gl_list.c
|
||||
/gl_list.h
|
||||
/gl_map.c
|
||||
/gl_map.h
|
||||
/gl_oset.c
|
||||
/gl_oset.h
|
||||
/gl_rbtree_ordered.h
|
||||
@@ -146,11 +179,19 @@
|
||||
/gl_rbtreehash_list.h
|
||||
/gl_xlist.c
|
||||
/gl_xlist.h
|
||||
/gl_xmap.c
|
||||
/gl_xmap.h
|
||||
/gnulib.mk
|
||||
/hard-locale.c
|
||||
/hard-locale.h
|
||||
/hash-pjw.c
|
||||
/hash-pjw.h
|
||||
/hash-triple-simple.c
|
||||
/hash-triple.h
|
||||
/hash.c
|
||||
/hash.h
|
||||
/ialloc.c
|
||||
/ialloc.h
|
||||
/iconv.c
|
||||
/iconv.h
|
||||
/iconv.in.h
|
||||
@@ -168,6 +209,10 @@
|
||||
/iconv_open-zos.gperf
|
||||
/iconv_open-zos.h
|
||||
/iconv_open.c
|
||||
/idx.h
|
||||
/integer_length.c
|
||||
/integer_length.h
|
||||
/integer_length_l.c
|
||||
/intprops.h
|
||||
/inttypes.h
|
||||
/inttypes.in.h
|
||||
@@ -213,6 +258,8 @@
|
||||
/mbtowc-lock.h
|
||||
/memchr.c
|
||||
/memchr.valgrind
|
||||
/mempcpy.c
|
||||
/memrchr.c
|
||||
/minmax.h
|
||||
/msvc-inval.c
|
||||
/msvc-inval.h
|
||||
@@ -222,9 +269,18 @@
|
||||
/obstack.h
|
||||
/obstack_printf.c
|
||||
/open.c
|
||||
/openat-die.c
|
||||
/openat-priv.h
|
||||
/openat-proc.c
|
||||
/openat.c
|
||||
/openat.h
|
||||
/opendir.c
|
||||
/os2-spawn.c
|
||||
/os2-spawn.h
|
||||
/pathmax.h
|
||||
/perror.c
|
||||
/pipe-safer.c
|
||||
/pipe.c
|
||||
/pipe2-safer.c
|
||||
/pipe2.c
|
||||
/printf-args.c
|
||||
@@ -245,20 +301,26 @@
|
||||
/raise.c
|
||||
/rawmemchr.c
|
||||
/rawmemchr.valgrind
|
||||
/readdir.c
|
||||
/readline.c
|
||||
/readline.h
|
||||
/readlink.c
|
||||
/realloc.c
|
||||
/reallocarray.c
|
||||
/ref-add.sed
|
||||
/ref-del.sed
|
||||
/relocatable.c
|
||||
/relocatable.h
|
||||
/relocwrapper.c
|
||||
/rename.c
|
||||
/rewinddir.c
|
||||
/rmdir.c
|
||||
/same-inode.h
|
||||
/save-cwd.c
|
||||
/save-cwd.h
|
||||
/sched.h
|
||||
/sched.in.h
|
||||
/scratch_buffer.h
|
||||
/setenv.c
|
||||
/setlocale-lock.c
|
||||
/setlocale_null.c
|
||||
@@ -276,8 +338,10 @@
|
||||
/snprintf.c
|
||||
/spawn-pipe.c
|
||||
/spawn-pipe.h
|
||||
/spawn.c
|
||||
/spawn.h
|
||||
/spawn.in.h
|
||||
/spawn_faction_addchdir.c
|
||||
/spawn_faction_addclose.c
|
||||
/spawn_faction_adddup2.c
|
||||
/spawn_faction_addopen.c
|
||||
@@ -287,6 +351,7 @@
|
||||
/spawnattr_destroy.c
|
||||
/spawnattr_init.c
|
||||
/spawnattr_setflags.c
|
||||
/spawnattr_setpgroup.c
|
||||
/spawnattr_setsigmask.c
|
||||
/spawni.c
|
||||
/spawnp.c
|
||||
@@ -297,6 +362,7 @@
|
||||
/stat-w32.c
|
||||
/stat-w32.h
|
||||
/stat.c
|
||||
/stdalign.in.h
|
||||
/stdbool.h
|
||||
/stdbool.in.h
|
||||
/stddef.h
|
||||
@@ -322,9 +388,11 @@
|
||||
/strerror_r.c
|
||||
/string.h
|
||||
/string.in.h
|
||||
/strings.in.h
|
||||
/stripslash.c
|
||||
/strndup.c
|
||||
/strnlen.c
|
||||
/strtod.c
|
||||
/strverscmp.c
|
||||
/sys
|
||||
/sys_ioctl.in.h
|
||||
@@ -365,7 +433,6 @@
|
||||
/unlink.c
|
||||
/unlocked-io.h
|
||||
/unsetenv.c
|
||||
/unused-parameter.h
|
||||
/vasnprintf.c
|
||||
/vasnprintf.h
|
||||
/vasprintf.c
|
||||
@@ -373,7 +440,6 @@
|
||||
/vfprintf.c
|
||||
/vsnprintf.c
|
||||
/vsprintf.c
|
||||
/w32spawn.h
|
||||
/wait-process.c
|
||||
/wait-process.h
|
||||
/waitpid.c
|
||||
@@ -393,6 +459,8 @@
|
||||
/windows-recmutex.h
|
||||
/windows-rwlock.c
|
||||
/windows-rwlock.h
|
||||
/windows-spawn.c
|
||||
/windows-spawn.h
|
||||
/windows-tls.c
|
||||
/windows-tls.h
|
||||
/xalloc-die.c
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
/scratch_buffer.h
|
||||
/scratch_buffer_dupfree.c
|
||||
/scratch_buffer_grow.c
|
||||
/scratch_buffer_grow_preserve.c
|
||||
/scratch_buffer_set_array_size.c
|
||||
@@ -53,6 +53,7 @@ DEFTIMEVAR (tv_conflicts , "conflicts")
|
||||
/* Time spent outputting results. */
|
||||
DEFTIMEVAR (tv_report , "outputting report")
|
||||
DEFTIMEVAR (tv_graph , "outputting graph")
|
||||
DEFTIMEVAR (tv_html , "outputting html")
|
||||
DEFTIMEVAR (tv_xml , "outputting xml")
|
||||
DEFTIMEVAR (tv_actions , "parser action tables")
|
||||
DEFTIMEVAR (tv_parser , "outputting parser")
|
||||
|
||||
@@ -2,23 +2,32 @@
|
||||
/00gnulib.m4
|
||||
/__inline.m4
|
||||
/absolute-header.m4
|
||||
/access.m4
|
||||
/alloca.m4
|
||||
/asm-underscore.m4
|
||||
/assert.m4
|
||||
/builtin-expect.m4
|
||||
/calloc.m4
|
||||
/canonicalize.m4
|
||||
/chdir-long.m4
|
||||
/clock_time.m4
|
||||
/close.m4
|
||||
/closedir.m4
|
||||
/codeset.m4
|
||||
/config-h.m4
|
||||
/configmake.m4
|
||||
/d-ino.m4
|
||||
/dirent_h.m4
|
||||
/dirfd.m4
|
||||
/double-slash-root.m4
|
||||
/dup.m4
|
||||
/dup2.m4
|
||||
/eaccess.m4
|
||||
/eealloc.m4
|
||||
/environ.m4
|
||||
/errno_h.m4
|
||||
/error.m4
|
||||
/execute.m4
|
||||
/exponentd.m4
|
||||
/exponentf.m4
|
||||
/exponentl.m4
|
||||
@@ -26,24 +35,36 @@
|
||||
/extern-inline.m4
|
||||
/extern-inline.m4~
|
||||
/fatal-signal.m4
|
||||
/fchdir.m4
|
||||
/fcntl-o.m4
|
||||
/fcntl.m4
|
||||
/fcntl_h.m4
|
||||
/fdopendir.m4
|
||||
/ffs.m4
|
||||
/ffsl.m4
|
||||
/filenamecat.m4
|
||||
/findprog-in.m4
|
||||
/float_h.m4
|
||||
/fopen.m4
|
||||
/fpending.m4
|
||||
/fpieee.m4
|
||||
/fprintf-posix.m4
|
||||
/free.m4
|
||||
/frexp.m4
|
||||
/frexpl.m4
|
||||
/fseterr.m4
|
||||
/fstat.m4
|
||||
/fstatat.m4
|
||||
/fsync.m4
|
||||
/getcwd-abort-bug.m4
|
||||
/getcwd-path-max.m4
|
||||
/getcwd.m4
|
||||
/getdelim.m4
|
||||
/getdtablesize.m4
|
||||
/gethrxtime.m4
|
||||
/getline.m4
|
||||
/getopt.m4
|
||||
/getpagesize.m4
|
||||
/getprogname.m4
|
||||
/getrusage.m4
|
||||
/gettext.m4
|
||||
@@ -110,6 +131,8 @@
|
||||
/mbstate_t.m4
|
||||
/mbswidth.m4
|
||||
/memchr.m4
|
||||
/mempcpy.m4
|
||||
/memrchr.m4
|
||||
/minmax.m4
|
||||
/mmap-anon.m4
|
||||
/mode_t.m4
|
||||
@@ -126,12 +149,16 @@
|
||||
/open-cloexec.m4
|
||||
/open-slash.m4
|
||||
/open.m4
|
||||
/openat.m4
|
||||
/opendir.m4
|
||||
/pathmax.m4
|
||||
/perror.m4
|
||||
/pid_t.m4
|
||||
/pipe.m4
|
||||
/pipe2.m4
|
||||
/po.m4
|
||||
/posix_spawn.m4
|
||||
/posix_spawn_faction_addchdir.m4
|
||||
/printf-frexp.m4
|
||||
/printf-frexpl.m4
|
||||
/printf-posix-rpl.m4
|
||||
@@ -143,13 +170,17 @@
|
||||
/quotearg.m4
|
||||
/raise.m4
|
||||
/rawmemchr.m4
|
||||
/readdir.m4
|
||||
/readline.m4
|
||||
/readlink.m4
|
||||
/realloc.m4
|
||||
/reallocarray.m4
|
||||
/relocatable-lib.m4
|
||||
/relocatable.m4
|
||||
/rename.m4
|
||||
/rewinddir.m4
|
||||
/rmdir.m4
|
||||
/save-cwd.m4
|
||||
/sched_h.m4
|
||||
/setenv.m4
|
||||
/setlocale_null.m4
|
||||
@@ -169,6 +200,7 @@
|
||||
/stat-time.m4
|
||||
/stat.m4
|
||||
/std-gnu11.m4
|
||||
/stdalign.m4
|
||||
/stdbool.m4
|
||||
/stddef_h.m4
|
||||
/stdint.m4
|
||||
@@ -182,8 +214,10 @@
|
||||
/strerror.m4
|
||||
/strerror_r.m4
|
||||
/string_h.m4
|
||||
/strings_h.m4
|
||||
/strndup.m4
|
||||
/strnlen.m4
|
||||
/strtod.m4
|
||||
/strverscmp.m4
|
||||
/sys_ioctl_h.m4
|
||||
/sys_resource_h.m4
|
||||
@@ -224,4 +258,5 @@
|
||||
/xalloc.m4
|
||||
/xsize.m4
|
||||
/xstrndup.m4
|
||||
/year2038.m4
|
||||
/zzgnulib.m4
|
||||
|
||||
+49
-18
@@ -7,22 +7,22 @@
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
m4_define([_BISON_CXXSTD_98_snippet],
|
||||
[#include <vector>
|
||||
|
||||
typedef std::vector<int> ints;
|
||||
])
|
||||
[[]])
|
||||
|
||||
m4_define([_BISON_CXXSTD_03_snippet],
|
||||
[])
|
||||
[[]])
|
||||
|
||||
m4_define([_BISON_CXXSTD_11_snippet],
|
||||
[#include <algorithm>
|
||||
[[ // C++11
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <memory>
|
||||
#include <set>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <utility> // std::swap
|
||||
#include <vector>
|
||||
|
||||
// C++11
|
||||
template <typename T>
|
||||
struct check
|
||||
{
|
||||
@@ -66,10 +66,26 @@ m4_define([_BISON_CXXSTD_11_snippet],
|
||||
|
||||
// GCC 4.8.2 on Solaris 11.3 does not support to_string.
|
||||
auto e = std::to_string(42);
|
||||
])
|
||||
|
||||
// Needed by glr2.cc.
|
||||
void cxx11_vector_data ()
|
||||
{
|
||||
std::vector<int> ints;
|
||||
ints.emplace_back (42);
|
||||
assert (ints.data () == &ints[0]);
|
||||
}
|
||||
|
||||
// Needed by glr2.cc.
|
||||
void cxx11_array_swap ()
|
||||
{
|
||||
int i0[4] = { 1, 2, 3, 4 };
|
||||
int i1[4] = { 5, 6, 7, 8 };
|
||||
std::swap (i0, i1);
|
||||
}
|
||||
]])
|
||||
|
||||
m4_define([_BISON_CXXSTD_14_snippet],
|
||||
[ // C++14
|
||||
[[ // C++14
|
||||
void mismatch()
|
||||
{
|
||||
using ints = std::vector<int>;
|
||||
@@ -78,20 +94,24 @@ m4_define([_BISON_CXXSTD_14_snippet],
|
||||
std::mismatch(std::begin(v1), std::end(v1),
|
||||
std::begin(v2), std::end(v2));
|
||||
}
|
||||
])
|
||||
]])
|
||||
|
||||
m4_define([_BISON_CXXSTD_17_snippet],
|
||||
[ // C++17
|
||||
[[ // C++17
|
||||
namespace ns1::ns2::ns3 {}
|
||||
|
||||
#include <optional>
|
||||
auto opt_string = std::optional<std::string>{};
|
||||
auto out = std::ostringstream{};
|
||||
])
|
||||
]])
|
||||
|
||||
m4_define([_BISON_CXXSTD_2A_snippet],
|
||||
[ // C++2A
|
||||
])
|
||||
m4_define([_BISON_CXXSTD_20_snippet],
|
||||
[[ // C++20
|
||||
]])
|
||||
|
||||
m4_define([_BISON_CXXSTD_2B_snippet],
|
||||
[[ // C++2B
|
||||
]])
|
||||
|
||||
|
||||
m4_define([_BISON_CXXSTD_testbody(98)],
|
||||
@@ -129,14 +149,25 @@ _BISON_CXXSTD_14_snippet
|
||||
_BISON_CXXSTD_17_snippet
|
||||
])])
|
||||
|
||||
m4_define([_BISON_CXXSTD_testbody(2a)],
|
||||
m4_define([_BISON_CXXSTD_testbody(20)],
|
||||
[AC_LANG_PROGRAM([
|
||||
_BISON_CXXSTD_98_snippet
|
||||
_BISON_CXXSTD_03_snippet
|
||||
_BISON_CXXSTD_11_snippet
|
||||
_BISON_CXXSTD_14_snippet
|
||||
_BISON_CXXSTD_17_snippet
|
||||
_BISON_CXXSTD_2A_snippet
|
||||
_BISON_CXXSTD_20_snippet
|
||||
])])
|
||||
|
||||
m4_define([_BISON_CXXSTD_testbody(2b)],
|
||||
[AC_LANG_PROGRAM([
|
||||
_BISON_CXXSTD_98_snippet
|
||||
_BISON_CXXSTD_03_snippet
|
||||
_BISON_CXXSTD_11_snippet
|
||||
_BISON_CXXSTD_14_snippet
|
||||
_BISON_CXXSTD_17_snippet
|
||||
_BISON_CXXSTD_20_snippet
|
||||
_BISON_CXXSTD_2B_snippet
|
||||
])])
|
||||
|
||||
|
||||
@@ -148,7 +179,7 @@ m4_define([_BISON_CXXSTD_testbody],
|
||||
|
||||
# BISON_CXXSTD(STD)
|
||||
# -----------------
|
||||
# Check whether the C++ compiler support STD (11, 98, 2a, etc.).
|
||||
# Check whether the C++ compiler supports STD (11, 98, 2b, etc.).
|
||||
# If it does, AC_SUBST 'CXX<STD>_CXXFLAGS' to the corresponding flags.
|
||||
AC_DEFUN([BISON_CXXSTD],
|
||||
[AC_REQUIRE([AC_PROG_CXX])
|
||||
|
||||
@@ -27,12 +27,13 @@ AC_DEFUN([BISON_TEST_FOR_WORKING_CXX_COMPILER],
|
||||
bison_cv_cxx_works=no
|
||||
AC_COMPILE_IFELSE(
|
||||
[AC_LANG_PROGRAM(
|
||||
[#include <cstdlib>
|
||||
[[
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <string>
|
||||
using namespace std;],
|
||||
[std::cerr << "";
|
||||
using namespace std;]],
|
||||
[[std::cerr << "";
|
||||
cout << "";
|
||||
typedef std::pair<unsigned, int> uipair;
|
||||
std::map<unsigned, int> m;
|
||||
@@ -40,7 +41,7 @@ AC_DEFUN([BISON_TEST_FOR_WORKING_CXX_COMPILER],
|
||||
m.insert (uipair (4, -4));
|
||||
for (i = m.begin (); i != m.end (); ++i)
|
||||
if (i->first != 4)
|
||||
return 1;])],
|
||||
return 1;]])],
|
||||
[AS_IF([AC_TRY_COMMAND([$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_objext $LIBS >&AS_MESSAGE_LOG_FD])],
|
||||
[AS_IF([test "$cross_compiling" = yes],
|
||||
[bison_cv_cxx_works=cross],
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
/*~
|
||||
/*.gmo
|
||||
/*.po
|
||||
/*~
|
||||
/.reference
|
||||
/LINGUAS
|
||||
/Makefile
|
||||
|
||||
@@ -14,6 +14,7 @@ src/main.c
|
||||
src/muscle-tab.c
|
||||
src/parse-gram.y
|
||||
src/print-graph.c
|
||||
src/print-xml.c
|
||||
src/print.c
|
||||
src/reader.c
|
||||
src/reduce.c
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*~
|
||||
/*.gmo
|
||||
/*.po
|
||||
/*~
|
||||
/.reference
|
||||
/LINGUAS
|
||||
/Makefile
|
||||
|
||||
@@ -57,12 +57,12 @@
|
||||
|
||||
/** The time limit before printing an assurance message to the user to
|
||||
* indicate that the search is still running. */
|
||||
#define ASSURANCE_LIMIT 2.0f
|
||||
#define ASSURANCE_LIMIT 2.0
|
||||
|
||||
/* The time limit before giving up looking for unifying counterexample. */
|
||||
static float time_limit = 5.0f;
|
||||
static double time_limit = 5.0;
|
||||
|
||||
#define CUMULATIVE_TIME_LIMIT 120.0f
|
||||
#define CUMULATIVE_TIME_LIMIT 120.0
|
||||
|
||||
// This is the fastest way to get the tail node from the gl_list API.
|
||||
static gl_list_node_t
|
||||
@@ -289,7 +289,8 @@ expand_to_conflict (state_item_number start, symbol_number conflict_sym)
|
||||
derivation_list_append (result, derivation_new_leaf (*i));
|
||||
symbol_number lhs =
|
||||
rules[item_number_as_rule_number (*i)].lhs->number;
|
||||
derivation *deriv = derivation_new (lhs, result);
|
||||
derivation *deriv = derivation_new (lhs, result,
|
||||
state_item_rule (si));
|
||||
result = derivation_list_new ();
|
||||
derivation_list_append (result, deriv);
|
||||
}
|
||||
@@ -423,7 +424,7 @@ complete_diverging_example (symbol_number conflict_sym,
|
||||
derivation_list_prepend (result, derivation_new_leaf (*i));
|
||||
}
|
||||
// completing the derivation
|
||||
derivation *new_deriv = derivation_new (r->lhs->number, result);
|
||||
derivation *new_deriv = derivation_new (r->lhs->number, result, r);
|
||||
result = derivation_list_new ();
|
||||
derivation_list_append (result, new_deriv);
|
||||
}
|
||||
@@ -1163,7 +1164,7 @@ unifying_example (state_item_number itm1,
|
||||
}
|
||||
if (TIME_LIMIT_ENFORCED)
|
||||
{
|
||||
float time_passed = difftime (time (NULL), start);
|
||||
double time_passed = difftime (time (NULL), start);
|
||||
if (!assurance_printed && time_passed > ASSURANCE_LIMIT
|
||||
&& stage3result)
|
||||
{
|
||||
@@ -1217,7 +1218,7 @@ counterexample_init (void)
|
||||
if (cp)
|
||||
{
|
||||
char *end = NULL;
|
||||
float v = strtof (cp, &end);
|
||||
double v = strtod (cp, &end);
|
||||
if (*end == '\0' && errno == 0)
|
||||
time_limit = v;
|
||||
}
|
||||
|
||||
+40
-2
@@ -25,6 +25,7 @@
|
||||
#include <c-ctype.h>
|
||||
#include <gl_linked_list.h>
|
||||
#include <mbswidth.h>
|
||||
#include <vasnprintf.h>
|
||||
|
||||
#include "system.h"
|
||||
#include "complain.h"
|
||||
@@ -34,13 +35,15 @@ struct derivation
|
||||
symbol_number sym;
|
||||
derivation_list children;
|
||||
int reference_count;
|
||||
// The rule SYM -> CHILDREN.
|
||||
const rule *rule;
|
||||
// Color assigned for styling. Guarantees that the derivation is
|
||||
// always displayed with the same color, independently of the order
|
||||
// in which the derivations are traversed.
|
||||
int color;
|
||||
};
|
||||
|
||||
static derivation d_dot = { -1, NULL, -1, -1 };
|
||||
static derivation d_dot = { -1, NULL, -1, NULL, -1 };
|
||||
|
||||
derivation *
|
||||
derivation_dot (void)
|
||||
@@ -74,12 +77,14 @@ void derivation_list_free (derivation_list dl)
|
||||
}
|
||||
|
||||
derivation *
|
||||
derivation_new (symbol_number sym, derivation_list children)
|
||||
derivation_new (symbol_number sym, derivation_list children,
|
||||
const rule *r)
|
||||
{
|
||||
derivation *res = xmalloc (sizeof *res);
|
||||
res->sym = sym;
|
||||
res->children = children;
|
||||
res->reference_count = 0;
|
||||
res->rule = r;
|
||||
res->color = -1;
|
||||
return res;
|
||||
}
|
||||
@@ -205,6 +210,23 @@ fputs_if (bool cond, FILE *out, int *padding, const char *s)
|
||||
return res;
|
||||
}
|
||||
|
||||
static int
|
||||
fprintf_if (bool cond, FILE *out, int *padding, const char *fmt, ...)
|
||||
{
|
||||
char buf[256];
|
||||
size_t len = sizeof (buf);
|
||||
va_list args;
|
||||
va_start (args, fmt);
|
||||
char *cp = vasnprintf (buf, &len, fmt, args);
|
||||
va_end (args);
|
||||
if (!cp)
|
||||
xalloc_die ();
|
||||
int res = fputs_if (cond, out, padding, cp);
|
||||
if (cp != buf)
|
||||
free (cp);
|
||||
return res;
|
||||
}
|
||||
|
||||
// The width taken to report this derivation recursively down to its
|
||||
// leaves.
|
||||
static int
|
||||
@@ -217,11 +239,19 @@ derivation_width (const derivation *deriv)
|
||||
|
||||
// Arrow and space.
|
||||
int children_width = down_arrow_width;
|
||||
children_width += snprintf (NULL, 0, "%d: ", deriv->rule->number);
|
||||
if (gl_list_size (deriv->children) == 0)
|
||||
// Empty rhs.
|
||||
children_width += empty_width;
|
||||
else
|
||||
{
|
||||
if (gl_list_size (deriv->children) == 1
|
||||
&& gl_list_get_first (deriv->children) == &d_dot)
|
||||
{
|
||||
children_width += empty_width;
|
||||
children_width += derivation_separator_width;
|
||||
}
|
||||
|
||||
derivation *child;
|
||||
for (gl_list_iterator_t it = gl_list_iterator (deriv->children);
|
||||
derivation_list_next (&it, &child);
|
||||
@@ -281,11 +311,19 @@ derivation_print_tree_impl (const derivation *deriv, FILE *out,
|
||||
else
|
||||
{
|
||||
res += fputs_if (depth == 1, out, padding, down_arrow);
|
||||
res += fprintf_if (depth == 1, out, padding, "%d: ", deriv->rule->number);
|
||||
if (gl_list_size (deriv->children) == 0)
|
||||
// Empty rhs.
|
||||
res += fputs_if (depth == 1, out, padding, empty);
|
||||
else
|
||||
{
|
||||
if (gl_list_size (deriv->children) == 1
|
||||
&& gl_list_get_first (deriv->children) == &d_dot)
|
||||
{
|
||||
res += fputs_if (depth == 1, out, padding, empty);
|
||||
res += fputs_if (depth == 1, out, padding, derivation_separator);
|
||||
}
|
||||
|
||||
bool first = true;
|
||||
derivation *child;
|
||||
for (gl_list_iterator_t it = gl_list_iterator (deriv->children);
|
||||
|
||||
+5
-2
@@ -54,11 +54,14 @@ 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);
|
||||
// rule_num is the number of the rule SYM -> CHILDREN.
|
||||
derivation *
|
||||
derivation_new (symbol_number sym, derivation_list children,
|
||||
const rule *r);
|
||||
|
||||
static inline derivation *derivation_new_leaf (symbol_number sym)
|
||||
{
|
||||
return derivation_new (sym, NULL);
|
||||
return derivation_new (sym, NULL, NULL);
|
||||
}
|
||||
|
||||
// Number of symbols.
|
||||
|
||||
+97
-42
@@ -26,7 +26,9 @@
|
||||
#include <error.h>
|
||||
#include <get-errno.h>
|
||||
#include <gl_array_list.h>
|
||||
#include <gl_hash_map.h>
|
||||
#include <gl_xlist.h>
|
||||
#include <gl_xmap.h>
|
||||
#include <quote.h>
|
||||
#include <quotearg.h>
|
||||
#include <relocatable.h> /* relocate2 */
|
||||
@@ -55,9 +57,9 @@ char const *spec_name_prefix = NULL; /* for -p. */
|
||||
location spec_name_prefix_loc = EMPTY_LOCATION_INIT;
|
||||
char *spec_verbose_file = NULL; /* for --verbose. */
|
||||
char *spec_graph_file = NULL; /* for -g. */
|
||||
char *spec_html_file = NULL; /* for --html. */
|
||||
char *spec_xml_file = NULL; /* for -x. */
|
||||
char *spec_header_file = NULL; /* for --defines. */
|
||||
char *spec_mapped_header_file = NULL;
|
||||
char *spec_header_file = NULL; /* for --header. */
|
||||
char *parser_file_name;
|
||||
|
||||
/* All computed output file names. */
|
||||
@@ -94,7 +96,6 @@ 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;
|
||||
@@ -108,6 +109,10 @@ struct prefix_map
|
||||
};
|
||||
|
||||
static gl_list_t prefix_maps = NULL;
|
||||
|
||||
/* Map file names to prefix-mapped file names. */
|
||||
static gl_map_t mapped_files = NULL;
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------.
|
||||
| Return a newly allocated string composed of the concatenation of |
|
||||
@@ -171,41 +176,88 @@ 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)
|
||||
/* The mapped name of FILENAME, allocated, if there are prefix maps.
|
||||
Otherwise NULL. */
|
||||
static char *
|
||||
map_file_name_alloc (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);
|
||||
}
|
||||
assert (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 *res = xmalloc (newprefix_len + strlen (filename) - oldprefix_len + 1);
|
||||
|
||||
char *end = stpcpy (s, p->newprefix);
|
||||
char *end = stpcpy (res, p->newprefix);
|
||||
stpcpy (end, filename + oldprefix_len);
|
||||
|
||||
return s;
|
||||
return res;
|
||||
}
|
||||
|
||||
static bool
|
||||
string_equals (const void *x1, const void *x2)
|
||||
{
|
||||
const char *s1 = x1;
|
||||
const char *s2 = x2;
|
||||
return STREQ (s1, s2);
|
||||
}
|
||||
|
||||
/* A hash function for NUL-terminated char* strings using
|
||||
the method described by Bruno Haible.
|
||||
See https://www.haible.de/bruno/hashfunc.html. */
|
||||
static size_t
|
||||
string_hash (const void *x)
|
||||
{
|
||||
#define SIZE_BITS (sizeof (size_t) * CHAR_BIT)
|
||||
|
||||
const char *s = x;
|
||||
size_t h = 0;
|
||||
|
||||
for (; *s; s++)
|
||||
h = *s + ((h << 9) | (h >> (SIZE_BITS - 9)));
|
||||
|
||||
return h;
|
||||
}
|
||||
|
||||
static void
|
||||
string_free (const void *cp)
|
||||
{
|
||||
void *p = (void*) cp;
|
||||
free (p);
|
||||
}
|
||||
|
||||
const char *
|
||||
map_file_name (char const *filename)
|
||||
{
|
||||
if (!filename || !prefix_maps)
|
||||
return filename;
|
||||
if (!mapped_files)
|
||||
mapped_files
|
||||
= gl_map_nx_create_empty (GL_HASH_MAP,
|
||||
string_equals, string_hash,
|
||||
string_free, string_free);
|
||||
const void *res = gl_map_get (mapped_files, filename);
|
||||
if (!res)
|
||||
{
|
||||
res = map_file_name_alloc (filename);
|
||||
gl_map_put (mapped_files, xstrdup (filename), res);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -216,17 +268,16 @@ prefix_map_free (struct prefix_map *p)
|
||||
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);
|
||||
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);
|
||||
@@ -411,7 +462,7 @@ compute_output_file_names (void)
|
||||
? xstrdup (spec_outfile)
|
||||
: concat2 (all_but_ext, src_extension));
|
||||
|
||||
if (defines_flag)
|
||||
if (header_flag)
|
||||
{
|
||||
if (! spec_header_file)
|
||||
spec_header_file = concat2 (all_but_ext, header_extension);
|
||||
@@ -420,11 +471,17 @@ compute_output_file_names (void)
|
||||
if (graph_flag)
|
||||
{
|
||||
if (! spec_graph_file)
|
||||
spec_graph_file = concat2 (all_but_tab_ext,
|
||||
304 <= required_version ? ".gv" : ".dot");
|
||||
spec_graph_file = concat2 (all_but_tab_ext, ".gv");
|
||||
output_file_name_check (&spec_graph_file, false);
|
||||
}
|
||||
|
||||
if (html_flag)
|
||||
{
|
||||
if (! spec_html_file)
|
||||
spec_html_file = concat2 (all_but_tab_ext, ".html");
|
||||
output_file_name_check (&spec_html_file, false);
|
||||
}
|
||||
|
||||
if (xml_flag)
|
||||
{
|
||||
if (! spec_xml_file)
|
||||
@@ -439,9 +496,6 @@ 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);
|
||||
@@ -526,12 +580,11 @@ output_file_names_free (void)
|
||||
free (all_but_ext);
|
||||
free (spec_verbose_file);
|
||||
free (spec_graph_file);
|
||||
free (spec_html_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);
|
||||
@@ -539,4 +592,6 @@ output_file_names_free (void)
|
||||
|
||||
if (prefix_maps)
|
||||
gl_list_free (prefix_maps);
|
||||
if (mapped_files)
|
||||
gl_map_free (mapped_files);
|
||||
}
|
||||
|
||||
+12
-9
@@ -44,21 +44,18 @@ extern char *spec_verbose_file;
|
||||
/* File name specified for the output graph. */
|
||||
extern char *spec_graph_file;
|
||||
|
||||
/* File name specified for the xml output. */
|
||||
/* File name specified for the HTML output. */
|
||||
extern char *spec_html_file;
|
||||
|
||||
/* File name specified for the XML output. */
|
||||
extern char *spec_xml_file;
|
||||
|
||||
/* File name specified with --defines. */
|
||||
/* File name specified with --header. */
|
||||
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. */
|
||||
@@ -91,7 +88,13 @@ 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);
|
||||
/* Given an input file path, return a string that contains the path
|
||||
with the file prefix mapping rules applied, or NULL if the input
|
||||
was NULL. Do not free the return value. */
|
||||
const char *map_file_name (char const *filename);
|
||||
|
||||
/* Add 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);
|
||||
|
||||
#endif /* !FILES_H_ */
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user