mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-08-13 12:45:14 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6675d36e25 | ||
|
|
d0bec3175f | ||
|
|
79e68b6c4d | ||
|
|
5cb74cacd8 | ||
|
|
9c8e6e05b6 | ||
|
|
431774d1f6 | ||
|
|
7d5474e979 | ||
|
|
6b78e50cef | ||
|
|
28769d608e | ||
|
|
a22588bcb9 | ||
|
|
b8c5e5609f | ||
|
|
b81229e1f9 | ||
|
|
815a76f558 | ||
|
|
ea138cd1f1 | ||
|
|
9922f1f877 | ||
|
|
1438b79e80 | ||
|
|
01f3e2969b | ||
|
|
744da03955 | ||
|
|
b28d67b6b0 | ||
|
|
cf890692f1 | ||
|
|
6932023f4d | ||
|
|
fff17fe8fe | ||
|
|
5544615a59 | ||
|
|
346ba14f15 | ||
|
|
4d18195ebc | ||
|
|
dd3e7b3895 | ||
|
|
64a3b6546a | ||
|
|
bad07a7f66 | ||
|
|
88bd814bf1 | ||
|
|
4f9ae5de07 | ||
|
|
78f72a4516 | ||
|
|
c04693d651 | ||
|
|
12191911ba | ||
|
|
d7f27477f4 | ||
|
|
5bad15d7ea | ||
|
|
cd099edf2d | ||
|
|
1e12219775 | ||
|
|
d8c2af56c1 | ||
|
|
cc11bb037c | ||
|
|
121dd98508 | ||
|
|
2eddbd0ac4 | ||
|
|
ee86ea8839 | ||
|
|
a2ad33dca6 | ||
|
|
5b2b7b1ffb | ||
|
|
dc72b3566d | ||
|
|
c47e1174d4 | ||
|
|
093eeb27e9 | ||
|
|
dab23c4a21 | ||
|
|
38a169bec1 | ||
|
|
dc77d6500f | ||
|
|
8262c7dc22 | ||
|
|
44f28d10ee | ||
|
|
44ad466a32 | ||
|
|
a839f4c461 | ||
|
|
9a51c6a128 | ||
|
|
2608b0cf12 | ||
|
|
aa766d1560 | ||
|
|
a7ed13b25f | ||
|
|
2d90916067 | ||
|
|
91e5a23ff2 | ||
|
|
d4ae66c371 | ||
|
|
70fb574717 | ||
|
|
0820f16ca8 | ||
|
|
49f1e5f428 | ||
|
|
238692ad77 | ||
|
|
5f95583da7 | ||
|
|
964fb2aa6f | ||
|
|
7c0d36b760 | ||
|
|
b4d18c7fc6 | ||
|
|
3e6e51cf5c | ||
|
|
d309bd9f9f | ||
|
|
203f7230ec | ||
|
|
156e548341 | ||
|
|
526ef45f30 | ||
|
|
d7f7fcd9c7 | ||
|
|
0fd542c3e0 | ||
|
|
413908e5a4 | ||
|
|
84ef175287 | ||
|
|
5234c8390f | ||
|
|
21f7690570 | ||
|
|
edb39c29a2 | ||
|
|
1247d94ba6 | ||
|
|
ed9a821caa | ||
|
|
330552ea49 | ||
|
|
7c609859ee | ||
|
|
ed10c308fa | ||
|
|
b91566edd1 | ||
|
|
29520abb3b | ||
|
|
2491de1eef | ||
|
|
ec207d1bb2 | ||
|
|
688b3404a2 | ||
|
|
cd6ef1e7d7 | ||
|
|
2b518d621f | ||
|
|
1ae4f1d329 | ||
|
|
160df55c56 | ||
|
|
e0b0a67b86 | ||
|
|
0e5cbd38b2 | ||
|
|
feb0bb0a59 | ||
|
|
d796e11f8f | ||
|
|
0895858d8e | ||
|
|
4efb2f7bd2 | ||
|
|
eeafc706e8 | ||
|
|
cf6d8d0631 | ||
|
|
8f44164443 | ||
|
|
1001f48416 | ||
|
|
3be228f64c | ||
|
|
670c7e7a75 | ||
|
|
c4b1a2b68f | ||
|
|
b65bd16e45 | ||
|
|
0f120354b6 | ||
|
|
69e3b405d9 | ||
|
|
3dd8f2305a | ||
|
|
9e75066819 | ||
|
|
efb65daa36 | ||
|
|
e077bf1ebc | ||
|
|
c35e829a76 | ||
|
|
d4f854e5b2 | ||
|
|
35c0fe6789 | ||
|
|
22f62414f9 | ||
|
|
9206b15c4e | ||
|
|
5edac5e15a | ||
|
|
1c3189734c | ||
|
|
c662b23735 | ||
|
|
627fecb19e | ||
|
|
2a069f22c6 | ||
|
|
3f4ffea6f2 | ||
|
|
251e1b137f | ||
|
|
efbcadeca7 | ||
|
|
e4d33cf579 | ||
|
|
5855da4722 | ||
|
|
5d5e1df1dc | ||
|
|
cef13e11f5 | ||
|
|
b7fbfd050e | ||
|
|
e088b4f90f | ||
|
|
c857ed4f72 | ||
|
|
1998606a90 | ||
|
|
b0bb4cde2e | ||
|
|
d2acc4b401 | ||
|
|
a53c6026cd | ||
|
|
ae5edcc23b | ||
|
|
296e2f90ab | ||
|
|
1ccb4be02b | ||
|
|
421662ec88 | ||
|
|
39be113b1f | ||
|
|
2101b0e210 | ||
|
|
b1327c56f7 | ||
|
|
ae03b16785 | ||
|
|
7e16bd2cae | ||
|
|
508ac09939 | ||
|
|
0535d2a608 | ||
|
|
94f7606db6 | ||
|
|
de5be4a693 | ||
|
|
03a6b439f6 | ||
|
|
742910838e | ||
|
|
52ce2a008b | ||
|
|
bb311cfbed | ||
|
|
518dc6ca26 | ||
|
|
6a1a681fd2 | ||
|
|
dd878d1851 | ||
|
|
6ed813c122 | ||
|
|
1ec93ca2a2 | ||
|
|
12f4091de4 | ||
|
|
8ece778cb8 | ||
|
|
f32ba07f94 | ||
|
|
50cd3f16de | ||
|
|
37da3c4b42 | ||
|
|
79bae4d6bb | ||
|
|
23f7554188 | ||
|
|
3ff248ebfe | ||
|
|
4e1a5aae96 | ||
|
|
8e70880af1 | ||
|
|
3fea8fade8 | ||
|
|
e7aff57122 | ||
|
|
339d11badf | ||
|
|
99260caef9 | ||
|
|
c19af5cbb4 | ||
|
|
b54181ff9b | ||
|
|
86c45be582 | ||
|
|
b5e0351c3e | ||
|
|
150b2318ed | ||
|
|
35c4a8e65e | ||
|
|
fc39ccab6b | ||
|
|
9a33fb9317 | ||
|
|
866bc6a49f | ||
|
|
e8619330e8 | ||
|
|
193dc86965 | ||
|
|
51fa2ab0a2 | ||
|
|
2d8c3edbf8 | ||
|
|
4590071287 | ||
|
|
ac3b6c18a5 | ||
|
|
f3ef847539 | ||
|
|
16f2353723 | ||
|
|
da5317cc9d | ||
|
|
e0cb91a922 | ||
|
|
482b370540 | ||
|
|
66283fb625 | ||
|
|
93c849ef0d | ||
|
|
6279945003 | ||
|
|
dcb6c972a2 | ||
|
|
af0441cfd2 | ||
|
|
bbb63b1ca9 | ||
|
|
ac54d19eba | ||
|
|
5807dd9279 | ||
|
|
94bfdf3b4b | ||
|
|
f80890c4bb | ||
|
|
1ebc2ac55c | ||
|
|
94952779b6 | ||
|
|
ed7d5c2b5b | ||
|
|
1ce02e13c3 | ||
|
|
8ef0b12eb7 | ||
|
|
e6d83116ae | ||
|
|
4d9fa28ba8 | ||
|
|
a100a3c4c1 | ||
|
|
b18ceb50f1 | ||
|
|
ff4d67ede8 | ||
|
|
465babb635 | ||
|
|
22c3839168 | ||
|
|
4619b32dc0 | ||
|
|
ad921890c1 | ||
|
|
6a28e6d412 | ||
|
|
f4495da337 | ||
|
|
dbaed0bbf2 | ||
|
|
78c7fb6460 | ||
|
|
14ce500508 | ||
|
|
acba58ac59 | ||
|
|
da29809969 | ||
|
|
87e4895189 | ||
|
|
01e3f45f83 | ||
|
|
9c21da3363 | ||
|
|
febf6115a0 | ||
|
|
11b5bac7bf | ||
|
|
b61bf2f0e8 | ||
|
|
091943f265 | ||
|
|
bf98d94f4f | ||
|
|
6bb37dbe27 | ||
|
|
c3585f41ef | ||
|
|
6525abdc83 | ||
|
|
2b63c54f5a | ||
|
|
2da399d15f | ||
|
|
19f45df02b | ||
|
|
2ab4058de0 | ||
|
|
f2277c3fec | ||
|
|
fb49a10e2c | ||
|
|
f049a57eec | ||
|
|
0c77d69721 | ||
|
|
307fcdee00 | ||
|
|
d26d10ad6c | ||
|
|
1b4108da3e | ||
|
|
53bfc7df94 | ||
|
|
a5fb4a88ef | ||
|
|
54df196d49 | ||
|
|
52bb6f0525 | ||
|
|
76dab18af3 | ||
|
|
c982974f33 | ||
|
|
dc2a3578b7 | ||
|
|
9661b2fcbc | ||
|
|
d9a9b054ae | ||
|
|
cb9f4cb543 | ||
|
|
b86dcaf40b | ||
|
|
0fafbbdefb | ||
|
|
4b85b969d0 | ||
|
|
7727693711 | ||
|
|
ce27796b74 | ||
|
|
6135fdc152 | ||
|
|
f1497356e8 | ||
|
|
1429569362 | ||
|
|
506c368ab2 | ||
|
|
4f9dc3bdc1 | ||
|
|
0d81be2dc7 | ||
|
|
32f44f4bfb | ||
|
|
38a8287813 | ||
|
|
df752784c2 | ||
|
|
292409e91e | ||
|
|
eea56d70d9 | ||
|
|
6e2de439e6 | ||
|
|
e33cd4b824 | ||
|
|
0669780ff8 | ||
|
|
160df220b1 | ||
|
|
da5c072a62 | ||
|
|
73ac8ff409 | ||
|
|
0e0fb0efc9 | ||
|
|
bb1d776be0 | ||
|
|
d7e1abe656 | ||
|
|
13a1537dba | ||
|
|
ac2ba46053 | ||
|
|
2a7a2c1d3a | ||
|
|
c9b5b68c73 | ||
|
|
26aef31552 | ||
|
|
392f3caef6 | ||
|
|
ccaa8e29f9 | ||
|
|
76c3bccf40 | ||
|
|
6275137378 | ||
|
|
d0571c846f | ||
|
|
8c1002e4b7 | ||
|
|
dbd8fd71ba | ||
|
|
95bac741c3 | ||
|
|
f8ab4d81c0 | ||
|
|
d55c9b001a | ||
|
|
611495999f | ||
|
|
01d5f232a9 | ||
|
|
0407acbc59 | ||
|
|
0c0e778bd1 | ||
|
|
30357ae942 | ||
|
|
fb1d76d9a9 | ||
|
|
a61bc3f9f8 |
+1
-1
@@ -1 +1 @@
|
|||||||
3.5.90
|
3.6.93
|
||||||
|
|||||||
+69
-47
@@ -29,12 +29,13 @@ jobs:
|
|||||||
clone: true
|
clone: true
|
||||||
dist: bionic
|
dist: bionic
|
||||||
script:
|
script:
|
||||||
- sudo apt-get install -qq autoconf automake autopoint flex gettext graphviz help2man m4 texinfo
|
- sudo apt-get install -qq autoconf automake autopoint flex gettext gperf graphviz help2man m4 texinfo
|
||||||
- autoconf --version
|
- autoconf --version
|
||||||
- automake --version
|
- automake --version
|
||||||
- autopoint --version
|
- autopoint --version
|
||||||
- dot -V
|
- dot -V
|
||||||
- gettext --version
|
- gettext --version
|
||||||
|
- gperf --version
|
||||||
- help2man --version
|
- help2man --version
|
||||||
- makeinfo --version
|
- makeinfo --version
|
||||||
- m4 --version
|
- m4 --version
|
||||||
@@ -46,7 +47,7 @@ jobs:
|
|||||||
- ./bootstrap
|
- ./bootstrap
|
||||||
- ./configure --enable-gcc-warnings || { cat config.log && false; }
|
- ./configure --enable-gcc-warnings || { cat config.log && false; }
|
||||||
- make -j2
|
- make -j2
|
||||||
- make -j2 dist
|
- make -j2 dist-xz
|
||||||
# Can help understanding why we get "dirty" tarballs.
|
# Can help understanding why we get "dirty" tarballs.
|
||||||
- git status
|
- git status
|
||||||
- dist=$(echo bison*.xz)
|
- dist=$(echo bison*.xz)
|
||||||
@@ -69,53 +70,53 @@ jobs:
|
|||||||
|
|
||||||
# Start with three completely different environments, to get errors asap.
|
# Start with three completely different environments, to get errors asap.
|
||||||
|
|
||||||
- name: "GCC 9 -O3"
|
- name: "GCC 10 -O3"
|
||||||
stage: check
|
stage: check
|
||||||
os: linux
|
os: linux
|
||||||
dist: bionic
|
dist: bionic
|
||||||
addons: &gcc9
|
addons: &gcc10
|
||||||
apt:
|
apt:
|
||||||
sources:
|
sources:
|
||||||
# See https://github.com/travis-ci/apt-source-safelist/issues/410.
|
# See https://github.com/travis-ci/apt-source-safelist/issues/410.
|
||||||
- sourceline: 'ppa:ubuntu-toolchain-r/test'
|
- sourceline: 'ppa:ubuntu-toolchain-r/test'
|
||||||
packages: g++-9
|
packages: g++-10
|
||||||
env:
|
env:
|
||||||
- CC=gcc-9
|
- CC=gcc-10
|
||||||
- CXX=g++-9
|
- CXX=g++-10
|
||||||
- CONFIGUREFLAGS='CPPFLAGS=-DNDEBUG CFLAGS=-O3 CXXFLAGS=-O3'
|
- CONFIGUREFLAGS='CPPFLAGS=-DNDEBUG CFLAGS=-O3 CXXFLAGS=-O3'
|
||||||
|
|
||||||
# ASAN is time consuming, and we timeout the 50min granted by
|
# 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.
|
# Travis if we run all the tests in one go. Run in two parts.
|
||||||
- name: "Clang 9 libc++ and ASAN part 1"
|
- name: "Clang 10 libc++ and ASAN part 1"
|
||||||
stage: check
|
stage: check
|
||||||
os: linux
|
os: linux
|
||||||
dist: bionic
|
dist: bionic
|
||||||
addons: &clang9
|
addons: &clang10
|
||||||
apt:
|
apt:
|
||||||
sources:
|
sources:
|
||||||
# See https://github.com/travis-ci/apt-source-safelist/issues/410.
|
# See https://github.com/travis-ci/apt-source-safelist/issues/410.
|
||||||
- sourceline: 'ppa:ubuntu-toolchain-r/test'
|
- sourceline: 'ppa:ubuntu-toolchain-r/test'
|
||||||
- sourceline: 'deb http://apt.llvm.org/bionic/ llvm-toolchain-bionic-9 main'
|
- sourceline: 'deb http://apt.llvm.org/bionic/ llvm-toolchain-bionic-10 main'
|
||||||
key_url: 'https://apt.llvm.org/llvm-snapshot.gpg.key'
|
key_url: 'https://apt.llvm.org/llvm-snapshot.gpg.key'
|
||||||
packages:
|
packages:
|
||||||
- clang-9
|
- clang-10
|
||||||
- libc++-9-dev
|
- libc++-10-dev
|
||||||
- libc++abi-9-dev
|
- libc++abi-10-dev
|
||||||
env:
|
env:
|
||||||
# Do not use ASAN with ubuntu's libc++: https://bugs.llvm.org/show_bug.cgi?id=17379
|
# Do not use ASAN with ubuntu's libc++: https://bugs.llvm.org/show_bug.cgi?id=17379
|
||||||
- CC='clang-9 -fsanitize=address'
|
- CC='clang-10 -fsanitize=address'
|
||||||
- CXX='clang++-9 -fsanitize=address -stdlib=libc++'
|
- CXX='clang++-10 -fsanitize=address -stdlib=libc++'
|
||||||
- PART=1
|
- PART=1
|
||||||
|
|
||||||
- name: "Clang 9 libc++ and ASAN part 2"
|
- name: "Clang 10 libc++ and ASAN part 2"
|
||||||
stage: check
|
stage: check
|
||||||
os: linux
|
os: linux
|
||||||
dist: bionic
|
dist: bionic
|
||||||
addons: *clang9
|
addons: *clang10
|
||||||
env:
|
env:
|
||||||
# Do not use ASAN with ubuntu's libc++: https://bugs.llvm.org/show_bug.cgi?id=17379
|
# Do not use ASAN with ubuntu's libc++: https://bugs.llvm.org/show_bug.cgi?id=17379
|
||||||
- CC='clang-9 -fsanitize=address'
|
- CC='clang-10 -fsanitize=address'
|
||||||
- CXX='clang++-9 -fsanitize=address -stdlib=libc++'
|
- CXX='clang++-10 -fsanitize=address -stdlib=libc++'
|
||||||
- PART=2
|
- PART=2
|
||||||
|
|
||||||
- name: "ICC"
|
- name: "ICC"
|
||||||
@@ -135,62 +136,64 @@ jobs:
|
|||||||
packages:
|
packages:
|
||||||
- intel-oneapi-icc
|
- intel-oneapi-icc
|
||||||
|
|
||||||
## ------- ##
|
- name: "ARM64: GCC 10 -O2 part 1"
|
||||||
## First. ##
|
|
||||||
## ------- ##
|
|
||||||
|
|
||||||
# Start with three completely different environments, to get
|
|
||||||
# errors asap.
|
|
||||||
|
|
||||||
- name: "ARM64: GCC 9 -O3 part 1"
|
|
||||||
stage: check
|
stage: check
|
||||||
os: linux
|
os: linux
|
||||||
arch: arm64
|
arch: arm64
|
||||||
dist: bionic
|
dist: bionic
|
||||||
addons: *gcc9
|
addons: *gcc10
|
||||||
env:
|
env:
|
||||||
- CC=gcc-9
|
- CC=gcc-10
|
||||||
- CXX=g++-9
|
- CXX=g++-10
|
||||||
- CONFIGUREFLAGS='CPPFLAGS=-DNDEBUG CFLAGS=-O3 CXXFLAGS=-O3'
|
- CONFIGUREFLAGS='CPPFLAGS=-DNDEBUG CFLAGS=-O2 CXXFLAGS=-O2'
|
||||||
- PART=1
|
- PART=1
|
||||||
|
|
||||||
- name: "PPC64le: GCC 9 part 1"
|
- name: "PPC64le: GCC 10 -O2 part 1"
|
||||||
stage: check
|
stage: check
|
||||||
os: linux
|
os: linux
|
||||||
arch: ppc64le
|
arch: ppc64le
|
||||||
dist: bionic
|
dist: bionic
|
||||||
addons: *gcc9
|
addons:
|
||||||
|
apt:
|
||||||
|
sources:
|
||||||
|
# See https://github.com/travis-ci/apt-source-safelist/issues/410.
|
||||||
|
- sourceline: 'ppa:ubuntu-toolchain-r/test'
|
||||||
|
packages: g++-10
|
||||||
env:
|
env:
|
||||||
- CC=gcc-9
|
- CC=gcc-10
|
||||||
- CXX=g++-9
|
- CXX=g++-10
|
||||||
- CONFIGUREFLAGS='CFLAGS=-O3 CXXFLAGS=-O3'
|
- CONFIGUREFLAGS='CFLAGS=-O2 CXXFLAGS=-O2'
|
||||||
- PART=1
|
- PART=1
|
||||||
|
|
||||||
- name: "s390x: GCC 9 part 1"
|
- name: "s390x: GCC 10 -O2 part 1"
|
||||||
stage: check
|
stage: check
|
||||||
os: linux
|
os: linux
|
||||||
arch: s390x
|
arch: s390x
|
||||||
dist: bionic
|
dist: bionic
|
||||||
addons: *gcc9
|
addons: *gcc10
|
||||||
env:
|
env:
|
||||||
- CC=gcc-9
|
- CC=gcc-10
|
||||||
- CXX=g++-9
|
- CXX=g++-10
|
||||||
- CONFIGUREFLAGS='CFLAGS=-O3 CXXFLAGS=-O3'
|
- CONFIGUREFLAGS='CFLAGS=-O2 CXXFLAGS=-O2'
|
||||||
- PART=1
|
- PART=1
|
||||||
|
|
||||||
## ----- ##
|
## ----- ##
|
||||||
## GCC. ##
|
## GCC. ##
|
||||||
## ----- ##
|
## ----- ##
|
||||||
|
|
||||||
- name: "GCC 8 with sanitizers part 1"
|
- name: "GCC 9 with sanitizers part 1"
|
||||||
|
stage: check
|
||||||
os: linux
|
os: linux
|
||||||
dist: bionic
|
dist: bionic
|
||||||
addons:
|
addons:
|
||||||
apt:
|
apt:
|
||||||
packages: g++-8
|
sources:
|
||||||
|
# See https://github.com/travis-ci/apt-source-safelist/issues/410.
|
||||||
|
- sourceline: 'ppa:ubuntu-toolchain-r/test'
|
||||||
|
packages: g++-9
|
||||||
env:
|
env:
|
||||||
- CC='gcc-8 -fsanitize=undefined,address -fno-omit-frame-pointer'
|
- CC='gcc-9 -fsanitize=undefined,address -fno-omit-frame-pointer'
|
||||||
- CXX='g++-8 -fsanitize=undefined,address -fno-omit-frame-pointer'
|
- CXX='g++-9 -fsanitize=undefined,address -fno-omit-frame-pointer'
|
||||||
- CONFIGUREFLAGS='CFLAGS=-O1 CXXFLAGS=-O1'
|
- CONFIGUREFLAGS='CFLAGS=-O1 CXXFLAGS=-O1'
|
||||||
- PART=1
|
- PART=1
|
||||||
|
|
||||||
@@ -292,7 +295,27 @@ jobs:
|
|||||||
## Clang. ##
|
## Clang. ##
|
||||||
## ------- ##
|
## ------- ##
|
||||||
|
|
||||||
- name: "Clang 8 -O3"
|
- name: "Clang 9 -O3"
|
||||||
|
stage: check
|
||||||
|
os: linux
|
||||||
|
dist: bionic
|
||||||
|
addons:
|
||||||
|
apt:
|
||||||
|
sources:
|
||||||
|
# See https://github.com/travis-ci/apt-source-safelist/issues/410.
|
||||||
|
- sourceline: 'ppa:ubuntu-toolchain-r/test'
|
||||||
|
- sourceline: 'deb http://apt.llvm.org/bionic/ llvm-toolchain-bionic-9 main'
|
||||||
|
key_url: 'https://apt.llvm.org/llvm-snapshot.gpg.key'
|
||||||
|
packages:
|
||||||
|
- clang-9
|
||||||
|
- libc++-9-dev
|
||||||
|
- libc++abi-9-dev
|
||||||
|
env:
|
||||||
|
- CC='clang-9'
|
||||||
|
- CXX='clang++-9 -stdlib=libc++'
|
||||||
|
- CONFIGUREFLAGS='CPPFLAGS=-DNDEBUG CFLAGS=-O3 CXXFLAGS=-O3'
|
||||||
|
|
||||||
|
- name: "Clang 8"
|
||||||
stage: check
|
stage: check
|
||||||
os: linux
|
os: linux
|
||||||
dist: bionic
|
dist: bionic
|
||||||
@@ -305,7 +328,6 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
- CC=clang-8
|
- CC=clang-8
|
||||||
- CXX='clang++-8 -stdlib=libc++'
|
- CXX='clang++-8 -stdlib=libc++'
|
||||||
- CONFIGUREFLAGS='CPPFLAGS=-DNDEBUG CFLAGS=-O3 CXXFLAGS=-O3'
|
|
||||||
|
|
||||||
- name: "Clang 7"
|
- name: "Clang 7"
|
||||||
stage: check
|
stage: check
|
||||||
|
|||||||
+12
@@ -127,3 +127,15 @@ gen-ChangeLog:
|
|||||||
--since=$(gen_start_date) > $$cl.tmp && \
|
--since=$(gen_start_date) > $$cl.tmp && \
|
||||||
mv -f $$cl.tmp $$cl; \
|
mv -f $$cl.tmp $$cl; \
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Useful to debug.
|
||||||
|
.c.i:
|
||||||
|
$(CC) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -o $@ -E $<
|
||||||
|
|
||||||
|
.PHONY: codespell
|
||||||
|
codespell:
|
||||||
|
$(AM_V_GEN) cd $(srcdir) \
|
||||||
|
&& codespell \
|
||||||
|
--regex "[\\w\\-'’\`]+\+*" \
|
||||||
|
--ignore-words-list "ba,circularly,cloneable,copyable,define'd,dout,froms,iff,ifset,od,ois" \
|
||||||
|
$$(git ls-files data doc lib src tests)
|
||||||
|
|||||||
@@ -1,27 +1,291 @@
|
|||||||
GNU Bison NEWS
|
GNU Bison NEWS
|
||||||
|
|
||||||
* Noteworthy changes in release 3.5.91 (2020-04-29) [stable]
|
* Noteworthy changes in release 3.7 (2020-07-23) [stable]
|
||||||
|
|
||||||
|
** Deprecated features
|
||||||
|
|
||||||
|
The YYPRINT macro, which works only with yacc.c and only for tokens, was
|
||||||
|
obsoleted long ago by %printer, introduced in Bison 1.50 (November 2002).
|
||||||
|
It is deprecated and its support will be removed eventually.
|
||||||
|
|
||||||
|
In conformance with the recommendations of the Graphviz team, in the next
|
||||||
|
version Bison the option `--graph` will generate a *.gv file by default,
|
||||||
|
instead of *.dot. A transition started in Bison 3.4.
|
||||||
|
|
||||||
** New features
|
** New features
|
||||||
|
|
||||||
*** Returning the error token
|
*** Counterexample Generation
|
||||||
|
|
||||||
When the scanner returns an invalid token or the undefined token
|
Contributed by Vincent Imbimbo.
|
||||||
(YYUNDEF), the parser generates an error message and enters error
|
|
||||||
recovery. Because of that error message, most scanners that find lexical
|
|
||||||
errors generate an error message, and then ignore the invalid input
|
|
||||||
without entering the error-recovery.
|
|
||||||
|
|
||||||
The scanners may now return YYerror, the error token, to enter the
|
When given `-Wcounterexamples`/`-Wcex`, bison will now output
|
||||||
error-recovery mode without triggering an additional error message. See
|
counterexamples for conflicts.
|
||||||
the bistromathic for an example.
|
|
||||||
|
|
||||||
*** The bistromathic features internationalization
|
**** Unifying Counterexamples
|
||||||
|
|
||||||
Its way to build the error message is more general and is easy to use in
|
Unifying counterexamples are strings which can be parsed in two ways due
|
||||||
other projects.
|
to the conflict. For example on a grammar that contains the usual
|
||||||
|
"dangling else" ambiguity:
|
||||||
|
|
||||||
* Noteworthy changes in release 3.5.90 (2020-04-18) [beta]
|
$ bison else.y
|
||||||
|
else.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
|
||||||
|
else.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
|
||||||
|
|
||||||
|
$ bison else.y -Wcex
|
||||||
|
else.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
|
||||||
|
else.y: warning: shift/reduce conflict on token "else" [-Wcounterexamples]
|
||||||
|
Example: "if" exp "then" "if" exp "then" exp • "else" exp
|
||||||
|
Shift derivation
|
||||||
|
exp
|
||||||
|
↳ "if" exp "then" exp
|
||||||
|
↳ "if" exp "then" exp • "else" exp
|
||||||
|
Example: "if" exp "then" "if" exp "then" exp • "else" exp
|
||||||
|
Reduce derivation
|
||||||
|
exp
|
||||||
|
↳ "if" exp "then" exp "else" exp
|
||||||
|
↳ "if" exp "then" exp •
|
||||||
|
|
||||||
|
When text styling is enabled, colors are used in the examples and the
|
||||||
|
derivations to highlight the structure of both analyses. In this case,
|
||||||
|
|
||||||
|
"if" exp "then" [ "if" exp "then" exp • ] "else" exp
|
||||||
|
|
||||||
|
vs.
|
||||||
|
|
||||||
|
"if" exp "then" [ "if" exp "then" exp • "else" exp ]
|
||||||
|
|
||||||
|
|
||||||
|
The counterexamples are "focused", in two different ways. First, they do
|
||||||
|
not clutter the output with all the derivations from the start symbol,
|
||||||
|
rather they start on the "conflicted nonterminal". They go straight to the
|
||||||
|
point. Second, they don't "expand" nonterminal symbols uselessly.
|
||||||
|
|
||||||
|
**** Nonunifying Counterexamples
|
||||||
|
|
||||||
|
In the case of the dangling else, Bison found an example that can be
|
||||||
|
parsed in two ways (therefore proving that the grammar is ambiguous).
|
||||||
|
When it cannot find such an example, it instead generates two examples
|
||||||
|
that are the same up until the dot:
|
||||||
|
|
||||||
|
$ bison foo.y
|
||||||
|
foo.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
|
||||||
|
foo.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
|
||||||
|
foo.y:4.4-7: warning: rule useless in parser due to conflicts [-Wother]
|
||||||
|
4 | a: expr
|
||||||
|
| ^~~~
|
||||||
|
|
||||||
|
$ bison -Wcex foo.y
|
||||||
|
foo.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
|
||||||
|
foo.y: warning: shift/reduce conflict on token ID [-Wcounterexamples]
|
||||||
|
First example: expr • ID ',' ID $end
|
||||||
|
Shift derivation
|
||||||
|
$accept
|
||||||
|
↳ s $end
|
||||||
|
↳ a ID
|
||||||
|
↳ expr
|
||||||
|
↳ expr • ID ','
|
||||||
|
Second example: expr • ID $end
|
||||||
|
Reduce derivation
|
||||||
|
$accept
|
||||||
|
↳ s $end
|
||||||
|
↳ a ID
|
||||||
|
↳ expr •
|
||||||
|
foo.y:4.4-7: warning: rule useless in parser due to conflicts [-Wother]
|
||||||
|
4 | a: expr
|
||||||
|
| ^~~~
|
||||||
|
|
||||||
|
In these cases, the parser usually doesn't have enough lookahead to
|
||||||
|
differentiate the two given examples.
|
||||||
|
|
||||||
|
**** Reports
|
||||||
|
|
||||||
|
Counterexamples are also included in the report when given
|
||||||
|
`--report=counterexamples`/`-rcex` (or `--report=all`), with more
|
||||||
|
technical details:
|
||||||
|
|
||||||
|
State 7
|
||||||
|
|
||||||
|
1 exp: "if" exp "then" exp • [$end, "then", "else"]
|
||||||
|
2 | "if" exp "then" exp • "else" exp
|
||||||
|
|
||||||
|
"else" shift, and go to state 8
|
||||||
|
|
||||||
|
"else" [reduce using rule 1 (exp)]
|
||||||
|
$default reduce using rule 1 (exp)
|
||||||
|
|
||||||
|
shift/reduce conflict on token "else":
|
||||||
|
1 exp: "if" exp "then" exp •
|
||||||
|
2 exp: "if" exp "then" exp • "else" exp
|
||||||
|
Example: "if" exp "then" "if" exp "then" exp • "else" exp
|
||||||
|
Shift derivation
|
||||||
|
exp
|
||||||
|
↳ "if" exp "then" exp
|
||||||
|
↳ "if" exp "then" exp • "else" exp
|
||||||
|
Example: "if" exp "then" "if" exp "then" exp • "else" exp
|
||||||
|
Reduce derivation
|
||||||
|
exp
|
||||||
|
↳ "if" exp "then" exp "else" exp
|
||||||
|
↳ "if" exp "then" exp •
|
||||||
|
|
||||||
|
*** File prefix mapping
|
||||||
|
|
||||||
|
Contributed by Joshua Watt.
|
||||||
|
|
||||||
|
Bison learned a new argument, `--file-prefix-map OLD=NEW`. Any file path
|
||||||
|
in the output (specifically `#line` directives and `#ifdef` header guards)
|
||||||
|
that begins with the prefix OLD will have it replaced with the prefix NEW,
|
||||||
|
similar to the `-ffile-prefix-map` in GCC. This option can be used to
|
||||||
|
make bison output reproducible.
|
||||||
|
|
||||||
|
** Changes
|
||||||
|
|
||||||
|
*** Diagnostics
|
||||||
|
|
||||||
|
When text styling is enabled and the terminal supports it, the warnings
|
||||||
|
now include hyperlinks to the documentation.
|
||||||
|
|
||||||
|
*** Relocatable installation
|
||||||
|
|
||||||
|
When installed to be relocatable (via `configure --enable-relocatable`),
|
||||||
|
bison will now also look for a relocated m4.
|
||||||
|
|
||||||
|
*** C++ file names
|
||||||
|
|
||||||
|
The `filename_type` %define variable was renamed `api.filename.type`.
|
||||||
|
Instead of
|
||||||
|
|
||||||
|
%define filename_type "symbol"
|
||||||
|
|
||||||
|
write
|
||||||
|
|
||||||
|
%define api.filename.type {symbol}
|
||||||
|
|
||||||
|
(Or let `bison --update` do it for you).
|
||||||
|
|
||||||
|
It now defaults to `const std::string` instead of `std::string`.
|
||||||
|
|
||||||
|
*** Deprecated %define variable names
|
||||||
|
|
||||||
|
The following variables have been renamed for consistency. Backward
|
||||||
|
compatibility is ensured, but upgrading is recommended.
|
||||||
|
|
||||||
|
filename_type -> api.filename.type
|
||||||
|
package -> api.package
|
||||||
|
|
||||||
|
*** Push parsers no longer clear their state when parsing is finished
|
||||||
|
|
||||||
|
Previously push-parsers cleared their state when parsing was finished (on
|
||||||
|
success and on failure). This made it impossible to check if there were
|
||||||
|
parse errors, since `yynerrs` was also reset. This can be especially
|
||||||
|
troublesome when used in autocompletion, since a parser with error
|
||||||
|
recovery would suggest (irrelevant) expected tokens even if there were
|
||||||
|
failure.
|
||||||
|
|
||||||
|
Now the parser state can be examined when parsing is finished. The parser
|
||||||
|
state is reset when starting a new parse.
|
||||||
|
|
||||||
|
** Documentation
|
||||||
|
|
||||||
|
*** Examples
|
||||||
|
|
||||||
|
The bistromathic demonstrates %param and how to quote sources in the error
|
||||||
|
messages:
|
||||||
|
|
||||||
|
> 123 456
|
||||||
|
1.5-7: syntax error: expected end of file or + or - or * or / or ^ before number
|
||||||
|
1 | 123 456
|
||||||
|
| ^~~
|
||||||
|
|
||||||
|
** Bug fixes
|
||||||
|
|
||||||
|
*** Include the generated header (yacc.c)
|
||||||
|
|
||||||
|
Historically, when --defines was used, bison generated a header and pasted
|
||||||
|
an exact copy of it into the generated parser implementation file. Since
|
||||||
|
Bison 3.4 it is possible to specify that the header should be `#include`d,
|
||||||
|
and how. For instance
|
||||||
|
|
||||||
|
%define api.header.include {"parse.h"}
|
||||||
|
|
||||||
|
or
|
||||||
|
|
||||||
|
%define api.header.include {<parser/parse.h>}
|
||||||
|
|
||||||
|
Now api.header.include defaults to `"header-basename"`, as was intended in
|
||||||
|
Bison 3.4, where `header-basename` is the basename of the generated
|
||||||
|
header. This is disabled when the generated header is `y.tab.h`, to
|
||||||
|
comply with Automake's ylwrap.
|
||||||
|
|
||||||
|
*** String aliases are faithfully propagated
|
||||||
|
|
||||||
|
Bison used to interpret user strings (i.e., decoding backslash escapes)
|
||||||
|
when reading them, and to escape them (i.e., issue non-printable
|
||||||
|
characters as backslash escapes, taking the locale into account) when
|
||||||
|
outputting them. As a consequence non-ASCII strings (say in UTF-8) ended
|
||||||
|
up "ciphered" as sequences of backslash escapes. This happened not only
|
||||||
|
in the generated sources (where the compiler will reinterpret them), but
|
||||||
|
also in all the generated reports (text, xml, html, dot, etc.). Reports
|
||||||
|
were therefore not readable when string aliases were not pure ASCII.
|
||||||
|
Worse yet: the output depended on the user's locale.
|
||||||
|
|
||||||
|
Now Bison faithfully treats the string aliases exactly the way the user
|
||||||
|
spelled them. This fixes all the aforementioned problems. However, now,
|
||||||
|
string aliases semantically equivalent but syntactically different (e.g.,
|
||||||
|
"A", "\x41", "\101") are considered to be different.
|
||||||
|
|
||||||
|
*** Crash when generating IELR
|
||||||
|
|
||||||
|
An old, well hidden, bug in the generation of IELR parsers was fixed.
|
||||||
|
|
||||||
|
|
||||||
|
* Noteworthy changes in release 3.6.4 (2020-06-15) [stable]
|
||||||
|
|
||||||
|
** Bug fixes
|
||||||
|
|
||||||
|
In glr.cc some internal macros leaked in the user's code, and could damage
|
||||||
|
access to the token kinds.
|
||||||
|
|
||||||
|
|
||||||
|
* Noteworthy changes in release 3.6.3 (2020-06-03) [stable]
|
||||||
|
|
||||||
|
** Bug fixes
|
||||||
|
|
||||||
|
Incorrect comments in the generated parsers.
|
||||||
|
|
||||||
|
Warnings in push parsers (yacc.c).
|
||||||
|
|
||||||
|
Incorrect display of gotos in LAC traces (lalr1.cc).
|
||||||
|
|
||||||
|
|
||||||
|
* Noteworthy changes in release 3.6.2 (2020-05-17) [stable]
|
||||||
|
|
||||||
|
** Bug fixes
|
||||||
|
|
||||||
|
Some tests were fixed.
|
||||||
|
|
||||||
|
When token aliases contain comment delimiters:
|
||||||
|
|
||||||
|
%token FOO "/* foo */"
|
||||||
|
|
||||||
|
bison used to emit "nested" comments, which is invalid C.
|
||||||
|
|
||||||
|
|
||||||
|
* Noteworthy changes in release 3.6.1 (2020-05-10) [stable]
|
||||||
|
|
||||||
|
** Bug fixes
|
||||||
|
|
||||||
|
Restored ANSI-C compliance in yacc.c.
|
||||||
|
|
||||||
|
GNU readline portability issues.
|
||||||
|
|
||||||
|
In C++, yy::parser::symbol_name is now a public member, as was intended.
|
||||||
|
|
||||||
|
** New features
|
||||||
|
|
||||||
|
In C++, yy::parser::symbol_type now has a public name() member function.
|
||||||
|
|
||||||
|
|
||||||
|
* Noteworthy changes in release 3.6 (2020-05-08) [stable]
|
||||||
|
|
||||||
** Backward incompatible changes
|
** Backward incompatible changes
|
||||||
|
|
||||||
@@ -126,6 +390,18 @@ GNU Bison NEWS
|
|||||||
It makes little sense to use this feature without enabling LAC (lookahead
|
It makes little sense to use this feature without enabling LAC (lookahead
|
||||||
correction).
|
correction).
|
||||||
|
|
||||||
|
*** Returning the error token
|
||||||
|
|
||||||
|
When the scanner returns an invalid token or the undefined token
|
||||||
|
(YYUNDEF), the parser generates an error message and enters error
|
||||||
|
recovery. Because of that error message, most scanners that find lexical
|
||||||
|
errors generate an error message, and then ignore the invalid input
|
||||||
|
without entering the error-recovery.
|
||||||
|
|
||||||
|
The scanners may now return YYerror, the error token, to enter the
|
||||||
|
error-recovery mode without triggering an additional error message. See
|
||||||
|
the bistromathic for an example.
|
||||||
|
|
||||||
*** Deep overhaul of the symbol and token kinds
|
*** Deep overhaul of the symbol and token kinds
|
||||||
|
|
||||||
To avoid the confusion with types in programming languages, we now refer
|
To avoid the confusion with types in programming languages, we now refer
|
||||||
@@ -213,8 +489,8 @@ GNU Bison NEWS
|
|||||||
|
|
||||||
*** Examples
|
*** Examples
|
||||||
|
|
||||||
There are now two examples in examples/java: a very simple calculator, and
|
There are now examples/java: a very simple calculator, and a more complete
|
||||||
one that tracks locations to provide accurate error messages.
|
one (push-parser, location tracking, and debug traces).
|
||||||
|
|
||||||
The lexcalc example (a simple example in C based on Flex and Bison) now
|
The lexcalc example (a simple example in C based on Flex and Bison) now
|
||||||
also demonstrates location tracking.
|
also demonstrates location tracking.
|
||||||
@@ -231,6 +507,7 @@ GNU Bison NEWS
|
|||||||
autocompletion on the existing variables, rather than of the word
|
autocompletion on the existing variables, rather than of the word
|
||||||
"variable".
|
"variable".
|
||||||
|
|
||||||
|
|
||||||
* Noteworthy changes in release 3.5.4 (2020-04-05) [stable]
|
* Noteworthy changes in release 3.5.4 (2020-04-05) [stable]
|
||||||
|
|
||||||
** WARNING: Future backward-incompatibilities!
|
** WARNING: Future backward-incompatibilities!
|
||||||
@@ -251,6 +528,7 @@ GNU Bison NEWS
|
|||||||
|
|
||||||
Fix api.token.raw support in Java.
|
Fix api.token.raw support in Java.
|
||||||
|
|
||||||
|
|
||||||
* Noteworthy changes in release 3.5.3 (2020-03-08) [stable]
|
* Noteworthy changes in release 3.5.3 (2020-03-08) [stable]
|
||||||
|
|
||||||
** Bug fixes
|
** Bug fixes
|
||||||
@@ -261,6 +539,7 @@ GNU Bison NEWS
|
|||||||
|
|
||||||
Several unlikely crashes found by fuzzing have been fixed.
|
Several unlikely crashes found by fuzzing have been fixed.
|
||||||
|
|
||||||
|
|
||||||
* Noteworthy changes in release 3.5.2 (2020-02-13) [stable]
|
* Noteworthy changes in release 3.5.2 (2020-02-13) [stable]
|
||||||
|
|
||||||
** Bug fixes
|
** Bug fixes
|
||||||
@@ -270,6 +549,7 @@ GNU Bison NEWS
|
|||||||
The lalr1.cc skeleton properly rejects unsupported values for parse.lac
|
The lalr1.cc skeleton properly rejects unsupported values for parse.lac
|
||||||
(as yacc.c does).
|
(as yacc.c does).
|
||||||
|
|
||||||
|
|
||||||
* Noteworthy changes in release 3.5.1 (2020-01-19) [stable]
|
* Noteworthy changes in release 3.5.1 (2020-01-19) [stable]
|
||||||
|
|
||||||
** Bug fixes
|
** Bug fixes
|
||||||
@@ -278,6 +558,7 @@ GNU Bison NEWS
|
|||||||
|
|
||||||
Fix compiler warnings.
|
Fix compiler warnings.
|
||||||
|
|
||||||
|
|
||||||
* Noteworthy changes in release 3.5 (2019-12-11) [stable]
|
* Noteworthy changes in release 3.5 (2019-12-11) [stable]
|
||||||
|
|
||||||
** Backward incompatible changes
|
** Backward incompatible changes
|
||||||
@@ -485,6 +766,7 @@ GNU Bison NEWS
|
|||||||
|
|
||||||
In Java, %define api.prefix was ignored. It now behaves as expected.
|
In Java, %define api.prefix was ignored. It now behaves as expected.
|
||||||
|
|
||||||
|
|
||||||
* Noteworthy changes in release 3.4.2 (2019-09-12) [stable]
|
* Noteworthy changes in release 3.4.2 (2019-09-12) [stable]
|
||||||
|
|
||||||
** Bug fixes
|
** Bug fixes
|
||||||
@@ -502,12 +784,14 @@ GNU Bison NEWS
|
|||||||
When lone carriage-return characters appeared in the input file,
|
When lone carriage-return characters appeared in the input file,
|
||||||
diagnostics could hang forever.
|
diagnostics could hang forever.
|
||||||
|
|
||||||
|
|
||||||
* Noteworthy changes in release 3.4.1 (2019-05-22) [stable]
|
* Noteworthy changes in release 3.4.1 (2019-05-22) [stable]
|
||||||
|
|
||||||
** Bug fixes
|
** Bug fixes
|
||||||
|
|
||||||
Portability fixes.
|
Portability fixes.
|
||||||
|
|
||||||
|
|
||||||
* Noteworthy changes in release 3.4 (2019-05-19) [stable]
|
* Noteworthy changes in release 3.4 (2019-05-19) [stable]
|
||||||
|
|
||||||
** Deprecated features
|
** Deprecated features
|
||||||
@@ -648,6 +932,7 @@ GNU Bison NEWS
|
|||||||
system, in December 1987. See the NEWS of Bison 3.3 for the previous
|
system, in December 1987. See the NEWS of Bison 3.3 for the previous
|
||||||
oldest bug.
|
oldest bug.
|
||||||
|
|
||||||
|
|
||||||
* Noteworthy changes in release 3.3.2 (2019-02-03) [stable]
|
* Noteworthy changes in release 3.3.2 (2019-02-03) [stable]
|
||||||
|
|
||||||
** Bug fixes
|
** Bug fixes
|
||||||
@@ -655,6 +940,7 @@ GNU Bison NEWS
|
|||||||
Bison 3.3 failed to generate parsers for grammars with unused nonterminal
|
Bison 3.3 failed to generate parsers for grammars with unused nonterminal
|
||||||
symbols.
|
symbols.
|
||||||
|
|
||||||
|
|
||||||
* Noteworthy changes in release 3.3.1 (2019-01-27) [stable]
|
* Noteworthy changes in release 3.3.1 (2019-01-27) [stable]
|
||||||
|
|
||||||
** Changes
|
** Changes
|
||||||
@@ -662,6 +948,7 @@ GNU Bison NEWS
|
|||||||
The option -y/--yacc used to imply -Werror=yacc, which turns uses of Bison
|
The option -y/--yacc used to imply -Werror=yacc, which turns uses of Bison
|
||||||
extensions into errors. It now makes them simple warnings (-Wyacc).
|
extensions into errors. It now makes them simple warnings (-Wyacc).
|
||||||
|
|
||||||
|
|
||||||
* Noteworthy changes in release 3.3 (2019-01-26) [stable]
|
* Noteworthy changes in release 3.3 (2019-01-26) [stable]
|
||||||
|
|
||||||
A new mailing list was created, Bison Announce. It is low traffic, and is
|
A new mailing list was created, Bison Announce. It is low traffic, and is
|
||||||
@@ -804,11 +1091,11 @@ GNU Bison NEWS
|
|||||||
|
|
||||||
...
|
...
|
||||||
|
|
||||||
Looking at the output from -v, one can see that the shift-reduce conflict
|
Looking at the output from -v, one can see that the shift/reduce conflict
|
||||||
here is due to the fact that the parser does not know whether to reduce
|
here is due to the fact that the parser does not know whether to reduce
|
||||||
arguments to argument_list until it sees the token _after_ the following
|
arguments to argument_list until it sees the token _after_ the following
|
||||||
','. By marking the rule with %expect 1 (because there is a conflict in
|
','. By marking the rule with %expect 1 (because there is a conflict in
|
||||||
one state), we document the source of the 1 overall shift-reduce conflict.
|
one state), we document the source of the 1 overall shift/reduce conflict.
|
||||||
|
|
||||||
In GLR parsers, we can use %expect-rr in a rule for reduce/reduce
|
In GLR parsers, we can use %expect-rr in a rule for reduce/reduce
|
||||||
conflicts. In this case, we mark each of the conflicting rules. For
|
conflicts. In this case, we mark each of the conflicting rules. For
|
||||||
@@ -923,7 +1210,7 @@ GNU Bison NEWS
|
|||||||
|
|
||||||
** Bug fixes
|
** Bug fixes
|
||||||
|
|
||||||
*** Incorrect number of reduce-reduce conflicts
|
*** Incorrect number of reduce/reduce conflicts
|
||||||
|
|
||||||
On a grammar such as
|
On a grammar such as
|
||||||
|
|
||||||
@@ -977,6 +1264,7 @@ GNU Bison NEWS
|
|||||||
literal such as ‘"number"’. The post-fix quantifiers are ‘?’ (zero or
|
literal such as ‘"number"’. The post-fix quantifiers are ‘?’ (zero or
|
||||||
one), ‘*’ (zero or more) and ‘+’ (one or more).
|
one), ‘*’ (zero or more) and ‘+’ (one or more).
|
||||||
|
|
||||||
|
|
||||||
* Noteworthy changes in release 3.2.4 (2018-12-24) [stable]
|
* Noteworthy changes in release 3.2.4 (2018-12-24) [stable]
|
||||||
|
|
||||||
** Bug fixes
|
** Bug fixes
|
||||||
@@ -985,6 +1273,7 @@ GNU Bison NEWS
|
|||||||
|
|
||||||
Always provide a copy constructor for symbol_type, even in modern C++.
|
Always provide a copy constructor for symbol_type, even in modern C++.
|
||||||
|
|
||||||
|
|
||||||
* Noteworthy changes in release 3.2.3 (2018-12-18) [stable]
|
* Noteworthy changes in release 3.2.3 (2018-12-18) [stable]
|
||||||
|
|
||||||
** Bug fixes
|
** Bug fixes
|
||||||
@@ -992,12 +1281,14 @@ GNU Bison NEWS
|
|||||||
Properly support token constructors in C++ with types that include commas
|
Properly support token constructors in C++ with types that include commas
|
||||||
(e.g., std::pair<int, int>). A regression introduced in Bison 3.2.
|
(e.g., std::pair<int, int>). A regression introduced in Bison 3.2.
|
||||||
|
|
||||||
|
|
||||||
* Noteworthy changes in release 3.2.2 (2018-11-21) [stable]
|
* Noteworthy changes in release 3.2.2 (2018-11-21) [stable]
|
||||||
|
|
||||||
** Bug fixes
|
** Bug fixes
|
||||||
|
|
||||||
C++ portability issues.
|
C++ portability issues.
|
||||||
|
|
||||||
|
|
||||||
* Noteworthy changes in release 3.2.1 (2018-11-09) [stable]
|
* Noteworthy changes in release 3.2.1 (2018-11-09) [stable]
|
||||||
|
|
||||||
** Bug fixes
|
** Bug fixes
|
||||||
@@ -1005,6 +1296,7 @@ GNU Bison NEWS
|
|||||||
Several portability issues have been fixed in the build system, in the
|
Several portability issues have been fixed in the build system, in the
|
||||||
test suite, and in the generated parsers in C++.
|
test suite, and in the generated parsers in C++.
|
||||||
|
|
||||||
|
|
||||||
* Noteworthy changes in release 3.2 (2018-10-29) [stable]
|
* Noteworthy changes in release 3.2 (2018-10-29) [stable]
|
||||||
|
|
||||||
** Backward incompatible changes
|
** Backward incompatible changes
|
||||||
@@ -1171,6 +1463,7 @@ GNU Bison NEWS
|
|||||||
|
|
||||||
Portability/warning issues with Flex.
|
Portability/warning issues with Flex.
|
||||||
|
|
||||||
|
|
||||||
* Noteworthy changes in release 3.1 (2018-08-27) [stable]
|
* Noteworthy changes in release 3.1 (2018-08-27) [stable]
|
||||||
|
|
||||||
** Backward incompatible changes
|
** Backward incompatible changes
|
||||||
@@ -1311,6 +1604,7 @@ GNU Bison NEWS
|
|||||||
Useless code was removed from C++ parsers, and some of the generated
|
Useless code was removed from C++ parsers, and some of the generated
|
||||||
constructors are more 'natural'.
|
constructors are more 'natural'.
|
||||||
|
|
||||||
|
|
||||||
* Noteworthy changes in release 3.0.5 (2018-05-27) [stable]
|
* Noteworthy changes in release 3.0.5 (2018-05-27) [stable]
|
||||||
|
|
||||||
** Bug fixes
|
** Bug fixes
|
||||||
@@ -1341,6 +1635,7 @@ GNU Bison NEWS
|
|||||||
|
|
||||||
On some platforms, some Java and/or C++ tests were failing.
|
On some platforms, some Java and/or C++ tests were failing.
|
||||||
|
|
||||||
|
|
||||||
* Noteworthy changes in release 3.0.4 (2015-01-23) [stable]
|
* Noteworthy changes in release 3.0.4 (2015-01-23) [stable]
|
||||||
|
|
||||||
** Bug fixes
|
** Bug fixes
|
||||||
@@ -1353,6 +1648,7 @@ GNU Bison NEWS
|
|||||||
|
|
||||||
Several portability issues in tests were fixed.
|
Several portability issues in tests were fixed.
|
||||||
|
|
||||||
|
|
||||||
* Noteworthy changes in release 3.0.3 (2015-01-15) [stable]
|
* Noteworthy changes in release 3.0.3 (2015-01-15) [stable]
|
||||||
|
|
||||||
** Bug fixes
|
** Bug fixes
|
||||||
@@ -1409,6 +1705,7 @@ GNU Bison NEWS
|
|||||||
- calc++
|
- calc++
|
||||||
a calculator in C++ using variant support and token constructors.
|
a calculator in C++ using variant support and token constructors.
|
||||||
|
|
||||||
|
|
||||||
* Noteworthy changes in release 3.0.2 (2013-12-05) [stable]
|
* Noteworthy changes in release 3.0.2 (2013-12-05) [stable]
|
||||||
|
|
||||||
** Bug fixes
|
** Bug fixes
|
||||||
@@ -1433,6 +1730,7 @@ GNU Bison NEWS
|
|||||||
When C++ variant support is enabled, an error triggered via YYERROR, but
|
When C++ variant support is enabled, an error triggered via YYERROR, but
|
||||||
not caught via error recovery, resulted in a double deletion.
|
not caught via error recovery, resulted in a double deletion.
|
||||||
|
|
||||||
|
|
||||||
* Noteworthy changes in release 3.0.1 (2013-11-12) [stable]
|
* Noteworthy changes in release 3.0.1 (2013-11-12) [stable]
|
||||||
|
|
||||||
** Bug fixes
|
** Bug fixes
|
||||||
@@ -1464,6 +1762,7 @@ GNU Bison NEWS
|
|||||||
|
|
||||||
Bugs and portability issues.
|
Bugs and portability issues.
|
||||||
|
|
||||||
|
|
||||||
* Noteworthy changes in release 3.0 (2013-07-25) [stable]
|
* Noteworthy changes in release 3.0 (2013-07-25) [stable]
|
||||||
|
|
||||||
** WARNING: Future backward-incompatibilities!
|
** WARNING: Future backward-incompatibilities!
|
||||||
@@ -1834,7 +2133,7 @@ GNU Bison NEWS
|
|||||||
%error-verbose directive is deprecated in favor of "%define parse.error
|
%error-verbose directive is deprecated in favor of "%define parse.error
|
||||||
verbose".
|
verbose".
|
||||||
|
|
||||||
** Renamed %define variables
|
** Deprecated %define variable names
|
||||||
|
|
||||||
The following variables have been renamed for consistency. Backward
|
The following variables have been renamed for consistency. Backward
|
||||||
compatibility is ensured, but upgrading is recommended.
|
compatibility is ensured, but upgrading is recommended.
|
||||||
@@ -2060,6 +2359,7 @@ GNU Bison NEWS
|
|||||||
There are operator- and operator-= for 'location'. Negative line/column
|
There are operator- and operator-= for 'location'. Negative line/column
|
||||||
increments can no longer underflow the resulting value.
|
increments can no longer underflow the resulting value.
|
||||||
|
|
||||||
|
|
||||||
* Noteworthy changes in release 2.7.1 (2013-04-15) [stable]
|
* Noteworthy changes in release 2.7.1 (2013-04-15) [stable]
|
||||||
|
|
||||||
** Bug fixes
|
** Bug fixes
|
||||||
@@ -2070,6 +2370,7 @@ GNU Bison NEWS
|
|||||||
|
|
||||||
*** Fix some compiler warnings (lalr1.cc)
|
*** Fix some compiler warnings (lalr1.cc)
|
||||||
|
|
||||||
|
|
||||||
* Noteworthy changes in release 2.7 (2012-12-12) [stable]
|
* Noteworthy changes in release 2.7 (2012-12-12) [stable]
|
||||||
|
|
||||||
** Bug fixes
|
** Bug fixes
|
||||||
@@ -2194,6 +2495,7 @@ GNU Bison NEWS
|
|||||||
|
|
||||||
The translation of midrule actions is now described.
|
The translation of midrule actions is now described.
|
||||||
|
|
||||||
|
|
||||||
* Noteworthy changes in release 2.6.5 (2012-11-07) [stable]
|
* Noteworthy changes in release 2.6.5 (2012-11-07) [stable]
|
||||||
|
|
||||||
We consider compiler warnings about Bison generated parsers to be bugs.
|
We consider compiler warnings about Bison generated parsers to be bugs.
|
||||||
@@ -2213,10 +2515,12 @@ GNU Bison NEWS
|
|||||||
When possible, yylloc is correctly initialized before calling yylex. It
|
When possible, yylloc is correctly initialized before calling yylex. It
|
||||||
is no longer necessary to initialize it in the %initial-action.
|
is no longer necessary to initialize it in the %initial-action.
|
||||||
|
|
||||||
|
|
||||||
* Noteworthy changes in release 2.6.4 (2012-10-23) [stable]
|
* Noteworthy changes in release 2.6.4 (2012-10-23) [stable]
|
||||||
|
|
||||||
Bison 2.6.3's --version was incorrect. This release fixes this issue.
|
Bison 2.6.3's --version was incorrect. This release fixes this issue.
|
||||||
|
|
||||||
|
|
||||||
* Noteworthy changes in release 2.6.3 (2012-10-22) [stable]
|
* Noteworthy changes in release 2.6.3 (2012-10-22) [stable]
|
||||||
|
|
||||||
** Bug fixes
|
** Bug fixes
|
||||||
@@ -2261,6 +2565,7 @@ GNU Bison NEWS
|
|||||||
"function declared 'noreturn' should not return") have also been
|
"function declared 'noreturn' should not return") have also been
|
||||||
addressed.
|
addressed.
|
||||||
|
|
||||||
|
|
||||||
* Noteworthy changes in release 2.6.2 (2012-08-03) [stable]
|
* Noteworthy changes in release 2.6.2 (2012-08-03) [stable]
|
||||||
|
|
||||||
** Bug fixes
|
** Bug fixes
|
||||||
@@ -2277,6 +2582,7 @@ GNU Bison NEWS
|
|||||||
|
|
||||||
The generated files no longer end (nor start) with empty lines.
|
The generated files no longer end (nor start) with empty lines.
|
||||||
|
|
||||||
|
|
||||||
* Noteworthy changes in release 2.6.1 (2012-07-30) [stable]
|
* Noteworthy changes in release 2.6.1 (2012-07-30) [stable]
|
||||||
|
|
||||||
Bison no longer executes user-specified M4 code when processing a grammar.
|
Bison no longer executes user-specified M4 code when processing a grammar.
|
||||||
@@ -2315,6 +2621,7 @@ GNU Bison NEWS
|
|||||||
will display two values for each typed and untyped symbol (provided
|
will display two values for each typed and untyped symbol (provided
|
||||||
that YYSTYPE has both "ival" and "fval" fields).
|
that YYSTYPE has both "ival" and "fval" fields).
|
||||||
|
|
||||||
|
|
||||||
* Noteworthy changes in release 2.6 (2012-07-19) [stable]
|
* Noteworthy changes in release 2.6 (2012-07-19) [stable]
|
||||||
|
|
||||||
** Future changes
|
** Future changes
|
||||||
@@ -2448,6 +2755,7 @@ GNU Bison NEWS
|
|||||||
|
|
||||||
#endif /* !BAR_FOO_H */ #endif /* !BAR_FOO_H */
|
#endif /* !BAR_FOO_H */ #endif /* !BAR_FOO_H */
|
||||||
|
|
||||||
|
|
||||||
* Noteworthy changes in release 2.5.1 (2012-06-05) [stable]
|
* Noteworthy changes in release 2.5.1 (2012-06-05) [stable]
|
||||||
|
|
||||||
** Future changes:
|
** Future changes:
|
||||||
@@ -2545,7 +2853,8 @@ GNU Bison NEWS
|
|||||||
Running "make install-pdf" (or -dvi, -html, -info, and -ps) no longer
|
Running "make install-pdf" (or -dvi, -html, -info, and -ps) no longer
|
||||||
halts in the middle of its course.
|
halts in the middle of its course.
|
||||||
|
|
||||||
* Changes in version 2.5 (2011-05-14):
|
|
||||||
|
* Noteworthy changes in release 2.5 (2011-05-14)
|
||||||
|
|
||||||
** Grammar symbol names can now contain non-initial dashes:
|
** Grammar symbol names can now contain non-initial dashes:
|
||||||
|
|
||||||
@@ -2900,7 +3209,8 @@ GNU Bison NEWS
|
|||||||
|
|
||||||
This bug has been fixed.
|
This bug has been fixed.
|
||||||
|
|
||||||
* Changes in version 2.4.3 (2010-08-05):
|
|
||||||
|
* Noteworthy changes in release 2.4.3 (2010-08-05)
|
||||||
|
|
||||||
** Bison now obeys -Werror and --warnings=error for warnings about
|
** Bison now obeys -Werror and --warnings=error for warnings about
|
||||||
grammar rules that are useless in the parser due to conflicts.
|
grammar rules that are useless in the parser due to conflicts.
|
||||||
@@ -2920,7 +3230,8 @@ GNU Bison NEWS
|
|||||||
|
|
||||||
** Minor documentation fixes.
|
** Minor documentation fixes.
|
||||||
|
|
||||||
* Changes in version 2.4.2 (2010-03-20):
|
|
||||||
|
* Noteworthy changes in release 2.4.2 (2010-03-20)
|
||||||
|
|
||||||
** Some portability problems that resulted in failures and livelocks
|
** Some portability problems that resulted in failures and livelocks
|
||||||
in the test suite on some versions of at least Solaris, AIX, HP-UX,
|
in the test suite on some versions of at least Solaris, AIX, HP-UX,
|
||||||
@@ -3014,7 +3325,8 @@ GNU Bison NEWS
|
|||||||
message translations were not installed although supported by the
|
message translations were not installed although supported by the
|
||||||
host system.
|
host system.
|
||||||
|
|
||||||
* Changes in version 2.4.1 (2008-12-11):
|
|
||||||
|
* Noteworthy changes in release 2.4.1 (2008-12-11)
|
||||||
|
|
||||||
** In the GLR defines file, unexpanded M4 macros in the yylval and yylloc
|
** In the GLR defines file, unexpanded M4 macros in the yylval and yylloc
|
||||||
declarations have been fixed.
|
declarations have been fixed.
|
||||||
@@ -3039,7 +3351,8 @@ GNU Bison NEWS
|
|||||||
|
|
||||||
** A few minor improvements to the Bison manual.
|
** A few minor improvements to the Bison manual.
|
||||||
|
|
||||||
* Changes in version 2.4 (2008-11-02):
|
|
||||||
|
* Noteworthy changes in release 2.4 (2008-11-02)
|
||||||
|
|
||||||
** %language is an experimental feature.
|
** %language is an experimental feature.
|
||||||
|
|
||||||
@@ -3054,7 +3367,8 @@ GNU Bison NEWS
|
|||||||
** Several bugs in the C++ skeleton and the experimental Java skeleton have been
|
** Several bugs in the C++ skeleton and the experimental Java skeleton have been
|
||||||
fixed.
|
fixed.
|
||||||
|
|
||||||
* Changes in version 2.3b (2008-05-27):
|
|
||||||
|
* Noteworthy changes in release 2.3b (2008-05-27)
|
||||||
|
|
||||||
** The quotes around NAME that used to be required in the following directive
|
** The quotes around NAME that used to be required in the following directive
|
||||||
are now deprecated:
|
are now deprecated:
|
||||||
@@ -3240,7 +3554,8 @@ GNU Bison NEWS
|
|||||||
** The nonfunctional --no-parser, -n, and %no-parser options have been
|
** The nonfunctional --no-parser, -n, and %no-parser options have been
|
||||||
completely removed from Bison.
|
completely removed from Bison.
|
||||||
|
|
||||||
* Changes in version 2.3a, 2006-09-13:
|
|
||||||
|
* Noteworthy changes in release 2.3a (2006-09-13)
|
||||||
|
|
||||||
** Instead of %union, you can define and use your own union type
|
** Instead of %union, you can define and use your own union type
|
||||||
YYSTYPE if your grammar contains at least one <type> tag.
|
YYSTYPE if your grammar contains at least one <type> tag.
|
||||||
@@ -3354,7 +3669,8 @@ GNU Bison NEWS
|
|||||||
The old spelling still works, but is not documented and may be removed
|
The old spelling still works, but is not documented and may be removed
|
||||||
in a future release.
|
in a future release.
|
||||||
|
|
||||||
* Changes in version 2.3, 2006-06-05:
|
|
||||||
|
* Noteworthy changes in release 2.3 (2006-06-05)
|
||||||
|
|
||||||
** GLR grammars should now use "YYRECOVERING ()" instead of "YYRECOVERING",
|
** GLR grammars should now use "YYRECOVERING ()" instead of "YYRECOVERING",
|
||||||
for compatibility with LALR(1) grammars.
|
for compatibility with LALR(1) grammars.
|
||||||
@@ -3362,7 +3678,8 @@ GNU Bison NEWS
|
|||||||
** It is now documented that any definition of YYSTYPE or YYLTYPE should
|
** It is now documented that any definition of YYSTYPE or YYLTYPE should
|
||||||
be to a type name that does not contain parentheses or brackets.
|
be to a type name that does not contain parentheses or brackets.
|
||||||
|
|
||||||
* Changes in version 2.2, 2006-05-19:
|
|
||||||
|
* Noteworthy changes in release 2.2 (2006-05-19)
|
||||||
|
|
||||||
** The distribution terms for all Bison-generated parsers now permit
|
** The distribution terms for all Bison-generated parsers now permit
|
||||||
using the parsers in nonfree programs. Previously, this permission
|
using the parsers in nonfree programs. Previously, this permission
|
||||||
@@ -3444,7 +3761,8 @@ GNU Bison NEWS
|
|||||||
|
|
||||||
** DJGPP support added.
|
** DJGPP support added.
|
||||||
|
|
||||||
* Changes in version 2.1, 2005-09-16:
|
|
||||||
|
* Noteworthy changes in release 2.1 (2005-09-16)
|
||||||
|
|
||||||
** The C++ lalr1.cc skeleton supports %lex-param.
|
** The C++ lalr1.cc skeleton supports %lex-param.
|
||||||
|
|
||||||
@@ -3470,7 +3788,8 @@ GNU Bison NEWS
|
|||||||
print 'syntax error, unexpected number' instead of 'syntax error,
|
print 'syntax error, unexpected number' instead of 'syntax error,
|
||||||
unexpected "number"'.
|
unexpected "number"'.
|
||||||
|
|
||||||
* Changes in version 2.0, 2004-12-25:
|
|
||||||
|
* Noteworthy changes in release 2.0 (2004-12-25)
|
||||||
|
|
||||||
** Possibly-incompatible changes
|
** Possibly-incompatible changes
|
||||||
|
|
||||||
@@ -3533,7 +3852,8 @@ GNU Bison NEWS
|
|||||||
|
|
||||||
- Semicolons are now allowed before "|" in grammar rules, as POSIX requires.
|
- Semicolons are now allowed before "|" in grammar rules, as POSIX requires.
|
||||||
|
|
||||||
* Changes in version 1.875, 2003-01-01:
|
|
||||||
|
* Noteworthy changes in release 1.875 (2003-01-01)
|
||||||
|
|
||||||
** The documentation license has been upgraded to version 1.2
|
** The documentation license has been upgraded to version 1.2
|
||||||
of the GNU Free Documentation License.
|
of the GNU Free Documentation License.
|
||||||
@@ -3653,7 +3973,8 @@ GNU Bison NEWS
|
|||||||
ago, but nobody noticed until we recently asked someone to try
|
ago, but nobody noticed until we recently asked someone to try
|
||||||
building Bison with a K&R C compiler.
|
building Bison with a K&R C compiler.
|
||||||
|
|
||||||
* Changes in version 1.75, 2002-10-14:
|
|
||||||
|
* Noteworthy changes in release 1.75 (2002-10-14)
|
||||||
|
|
||||||
** Bison should now work on 64-bit hosts.
|
** Bison should now work on 64-bit hosts.
|
||||||
|
|
||||||
@@ -3684,7 +4005,8 @@ GNU Bison NEWS
|
|||||||
was incorrectly rejected: $1 is defined in the second midrule
|
was incorrectly rejected: $1 is defined in the second midrule
|
||||||
action, and is equal to the $$ of the first midrule action.
|
action, and is equal to the $$ of the first midrule action.
|
||||||
|
|
||||||
* Changes in version 1.50, 2002-10-04:
|
|
||||||
|
* Noteworthy changes in release 1.50 (2002-10-04)
|
||||||
|
|
||||||
** GLR parsing
|
** GLR parsing
|
||||||
The declaration
|
The declaration
|
||||||
@@ -3828,7 +4150,8 @@ GNU Bison NEWS
|
|||||||
|
|
||||||
** GNU M4 is now required when using Bison.
|
** GNU M4 is now required when using Bison.
|
||||||
|
|
||||||
* Changes in version 1.35, 2002-03-25:
|
|
||||||
|
* Noteworthy changes in release 1.35 (2002-03-25)
|
||||||
|
|
||||||
** C Skeleton
|
** C Skeleton
|
||||||
Some projects use Bison's C parser with C++ compilers, and define
|
Some projects use Bison's C parser with C++ compilers, and define
|
||||||
@@ -3843,7 +4166,8 @@ GNU Bison NEWS
|
|||||||
This kludge also addresses some C++ problems when the stack was
|
This kludge also addresses some C++ problems when the stack was
|
||||||
extended.
|
extended.
|
||||||
|
|
||||||
* Changes in version 1.34, 2002-03-12:
|
|
||||||
|
* Noteworthy changes in release 1.34 (2002-03-12)
|
||||||
|
|
||||||
** File name clashes are detected
|
** File name clashes are detected
|
||||||
$ bison foo.y -d -o foo.x
|
$ bison foo.y -d -o foo.x
|
||||||
@@ -3863,7 +4187,8 @@ GNU Bison NEWS
|
|||||||
|
|
||||||
** Fix test suite portability problems.
|
** Fix test suite portability problems.
|
||||||
|
|
||||||
* Changes in version 1.33, 2002-02-07:
|
|
||||||
|
* Noteworthy changes in release 1.33 (2002-02-07)
|
||||||
|
|
||||||
** Fix C++ issues
|
** Fix C++ issues
|
||||||
Groff could not be compiled for the definition of size_t was lacking
|
Groff could not be compiled for the definition of size_t was lacking
|
||||||
@@ -3872,7 +4197,8 @@ GNU Bison NEWS
|
|||||||
** Catch invalid @n
|
** Catch invalid @n
|
||||||
As is done with $n.
|
As is done with $n.
|
||||||
|
|
||||||
* Changes in version 1.32, 2002-01-23:
|
|
||||||
|
* Noteworthy changes in release 1.32 (2002-01-23)
|
||||||
|
|
||||||
** Fix Yacc output file names
|
** Fix Yacc output file names
|
||||||
|
|
||||||
@@ -3880,7 +4206,8 @@ GNU Bison NEWS
|
|||||||
|
|
||||||
** Italian, Dutch translations
|
** Italian, Dutch translations
|
||||||
|
|
||||||
* Changes in version 1.31, 2002-01-14:
|
|
||||||
|
* Noteworthy changes in release 1.31 (2002-01-14)
|
||||||
|
|
||||||
** Many Bug Fixes
|
** Many Bug Fixes
|
||||||
|
|
||||||
@@ -3967,7 +4294,8 @@ GNU Bison NEWS
|
|||||||
** --output
|
** --output
|
||||||
New, aliasing "--output-file".
|
New, aliasing "--output-file".
|
||||||
|
|
||||||
* Changes in version 1.30, 2001-10-26:
|
|
||||||
|
* Noteworthy changes in release 1.30 (2001-10-26)
|
||||||
|
|
||||||
** "--defines" and "--graph" have now an optional argument which is the
|
** "--defines" and "--graph" have now an optional argument which is the
|
||||||
output file name. "-d" and "-g" do not change; they do not take any
|
output file name. "-d" and "-g" do not change; they do not take any
|
||||||
@@ -3978,7 +4306,8 @@ GNU Bison NEWS
|
|||||||
|
|
||||||
** Portability fixes.
|
** Portability fixes.
|
||||||
|
|
||||||
* Changes in version 1.29, 2001-09-07:
|
|
||||||
|
* Noteworthy changes in release 1.29 (2001-09-07)
|
||||||
|
|
||||||
** The output file does not define const, as this caused problems when used
|
** The output file does not define const, as this caused problems when used
|
||||||
with common autoconfiguration schemes. If you still use ancient compilers
|
with common autoconfiguration schemes. If you still use ancient compilers
|
||||||
@@ -4013,7 +4342,8 @@ GNU Bison NEWS
|
|||||||
** @$
|
** @$
|
||||||
Automatic location tracking.
|
Automatic location tracking.
|
||||||
|
|
||||||
* Changes in version 1.28, 1999-07-06:
|
|
||||||
|
* Noteworthy changes in release 1.28 (1999-07-06)
|
||||||
|
|
||||||
** Should compile better now with K&R compilers.
|
** Should compile better now with K&R compilers.
|
||||||
|
|
||||||
@@ -4023,12 +4353,14 @@ GNU Bison NEWS
|
|||||||
|
|
||||||
** There is now a FAQ.
|
** There is now a FAQ.
|
||||||
|
|
||||||
* Changes in version 1.27:
|
|
||||||
|
* Noteworthy changes in release 1.27
|
||||||
|
|
||||||
** The make rule which prevented bison.simple from being created on
|
** The make rule which prevented bison.simple from being created on
|
||||||
some systems has been fixed.
|
some systems has been fixed.
|
||||||
|
|
||||||
* Changes in version 1.26:
|
|
||||||
|
* Noteworthy changes in release 1.26
|
||||||
|
|
||||||
** Bison now uses Automake.
|
** Bison now uses Automake.
|
||||||
|
|
||||||
@@ -4045,7 +4377,8 @@ GNU Bison NEWS
|
|||||||
** Generated parsers should now work even on operating systems which do
|
** Generated parsers should now work even on operating systems which do
|
||||||
not provide alloca().
|
not provide alloca().
|
||||||
|
|
||||||
* Changes in version 1.25, 1995-10-16:
|
|
||||||
|
* Noteworthy changes in release 1.25 (1995-10-16)
|
||||||
|
|
||||||
** Errors in the input grammar are not fatal; Bison keeps reading
|
** Errors in the input grammar are not fatal; Bison keeps reading
|
||||||
the grammar file, and reports all the errors found in it.
|
the grammar file, and reports all the errors found in it.
|
||||||
@@ -4070,7 +4403,8 @@ the parser engine; a project can now use its own parser engine.
|
|||||||
The actions go into a separate file called NAME.act, in the form of
|
The actions go into a separate file called NAME.act, in the form of
|
||||||
a switch statement body.
|
a switch statement body.
|
||||||
|
|
||||||
* Changes in version 1.23:
|
|
||||||
|
* Noteworthy changes in release 1.23
|
||||||
|
|
||||||
The user can define YYPARSE_PARAM as the name of an argument to be
|
The user can define YYPARSE_PARAM as the name of an argument to be
|
||||||
passed into yyparse. The argument should have type void *. It should
|
passed into yyparse. The argument should have type void *. It should
|
||||||
@@ -4079,72 +4413,69 @@ by casting it to the proper pointer type.
|
|||||||
|
|
||||||
Line numbers in output file corrected.
|
Line numbers in output file corrected.
|
||||||
|
|
||||||
* Changes in version 1.22:
|
|
||||||
|
* Noteworthy changes in release 1.22
|
||||||
|
|
||||||
--help option added.
|
--help option added.
|
||||||
|
|
||||||
* Changes in version 1.20:
|
|
||||||
|
* Noteworthy changes in release 1.20
|
||||||
|
|
||||||
Output file does not redefine const for C++.
|
Output file does not redefine const for C++.
|
||||||
|
|
||||||
-----
|
-----
|
||||||
|
|
||||||
Copyright (C) 1995-2015, 2018-2020 Free Software Foundation, Inc.
|
LocalWords: yacc YYBACKUP glr GCC lalr ArrayIndexOutOfBoundsException nullptr
|
||||||
|
LocalWords: cplusplus liby rpl fprintf mfcalc Wyacc stmt cond expr mk sym lr
|
||||||
This file is part of Bison, the GNU Parser Generator.
|
LocalWords: IELR ielr Lookahead YYERROR nonassoc LALR's api lookaheads yychar
|
||||||
|
LocalWords: destructor lookahead YYRHSLOC YYLLOC Rhs ifndef YYFAIL cpp sr rr
|
||||||
This program is free software: you can redistribute it and/or modify
|
LocalWords: preprocessor initializer Wno Wnone Werror FreeBSD prec livelocks
|
||||||
it under the terms of the GNU General Public License as published by
|
LocalWords: Solaris AIX UX RHEL Tru LHS gcc's Wundef YYENABLE NLS YYLTYPE VCG
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
LocalWords: yyerror cpp's Wunused yylval yylloc prepend yyparse yylex yypush
|
||||||
(at your option) any later version.
|
LocalWords: Graphviz xml nonterminals midrule destructor's YYSTYPE typedef ly
|
||||||
|
LocalWords: CHR chr printf stdout namespace preprocessing enum pre include's
|
||||||
This program is distributed in the hope that it will be useful,
|
LocalWords: YYRECOVERING nonfree destructors YYABORT YYACCEPT params enums de
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
LocalWords: struct yystype DJGPP lex param Haible NUM alloca YYSTACK NUL goto
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
LocalWords: YYMAXDEPTH Unescaped UCNs YYLTYPE's yyltype typedefs inline Yaccs
|
||||||
GNU General Public License for more details.
|
LocalWords: Heriyanto Reenable dprec Hilfinger Eggert MYEOF Folle Menezes EOF
|
||||||
|
LocalWords: Lackovic define's itemset Groff Gettext malloc NEWS'ed YYDEBUG YY
|
||||||
You should have received a copy of the GNU General Public License
|
LocalWords: namespaces strerror const autoconfiguration Dconst Autoconf's FDL
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
LocalWords: Automake TMPDIR LESSEQ ylwrap endif yydebug YYTOKEN YYLSP ival hh
|
||||||
|
LocalWords: extern YYTOKENTYPE TOKENTYPE yytokentype tokentype STYPE lval pdf
|
||||||
LocalWords: yacc YYBACKUP glr GCC lalr ArrayIndexOutOfBoundsException nullptr
|
LocalWords: lang yyoutput dvi html ps POSIX lvalp llocp Wother nterm arg init
|
||||||
LocalWords: cplusplus liby rpl fprintf mfcalc Wyacc stmt cond expr mk sym lr
|
LocalWords: TOK calc yyo fval Wconflicts parsers yystackp yyval yynerrs
|
||||||
LocalWords: IELR ielr Lookahead YYERROR nonassoc LALR's api lookaheads yychar
|
LocalWords: Théophile Ranquet Santet fno fnone stype associativity Tolmer
|
||||||
LocalWords: destructor lookahead YYRHSLOC YYLLOC Rhs ifndef YYFAIL cpp sr rr
|
LocalWords: Wprecedence Rassoul Wempty Paolo Bonzini parser's Michiel loc
|
||||||
LocalWords: preprocessor initializer Wno Wnone Werror FreeBSD prec livelocks
|
LocalWords: redeclaration sval fcaret reentrant XSLT xsl Wmaybe yyvsp Tedi
|
||||||
LocalWords: Solaris AIX UX RHEL Tru LHS gcc's Wundef YYENABLE NLS YYLTYPE VCG
|
LocalWords: pragmas noreturn untyped Rozenman unexpanded Wojciech Polak
|
||||||
LocalWords: yyerror cpp's Wunused yylval yylloc prepend yyparse yylex yypush
|
LocalWords: Alexandre MERCHANTABILITY yytype emplace ptr automove lvalues
|
||||||
LocalWords: Graphviz xml nonterminals midrule destructor's YYSTYPE typedef ly
|
LocalWords: nonterminal yy args Pragma dereference yyformat rhs docdir bw
|
||||||
LocalWords: CHR chr printf stdout namespace preprocessing enum pre include's
|
LocalWords: Redeclarations rpcalc Autoconf YFLAGS Makefiles PROG DECL num
|
||||||
LocalWords: YYRECOVERING nonfree destructors YYABORT YYACCEPT params enums de
|
LocalWords: Heimbigner AST src ast Makefile srcdir MinGW xxlex XXSTYPE
|
||||||
LocalWords: struct yystype DJGPP lex param Haible NUM alloca YYSTACK NUL goto
|
LocalWords: XXLTYPE strictfp IDEs ffixit fdiagnostics parseable fixits
|
||||||
LocalWords: YYMAXDEPTH Unescaped UCNs YYLTYPE's yyltype typedefs inline Yaccs
|
LocalWords: Wdeprecated yytext Variadic variadic yyrhs yyphrs RCS README
|
||||||
LocalWords: Heriyanto Reenable dprec Hilfinger Eggert MYEOF Folle Menezes EOF
|
LocalWords: noexcept constexpr ispell american deprecations backend Teoh
|
||||||
LocalWords: Lackovic define's itemset Groff Gettext malloc NEWS'ed YYDEBUG YY
|
LocalWords: YYPRINT Mangold Bonzini's Wdangling exVal baz checkable gcc
|
||||||
LocalWords: namespaces strerror const autoconfiguration Dconst Autoconf's FDL
|
LocalWords: fsanitize Vogelsgesang lis redeclared stdint automata yytname
|
||||||
LocalWords: Automake TMPDIR LESSEQ ylwrap endif yydebug YYTOKEN YYLSP ival hh
|
LocalWords: yysymbol yytnamerr yyreport ctx ARGMAX yysyntax stderr LPAREN
|
||||||
LocalWords: extern YYTOKENTYPE TOKENTYPE yytokentype tokentype STYPE lval pdf
|
LocalWords: symrec yypcontext TOKENMAX yyexpected YYEMPTY yypstate YYEOF
|
||||||
LocalWords: lang yyoutput dvi html ps POSIX lvalp llocp Wother nterm arg init
|
LocalWords: autocompletion bistromathic submessages Cayuela lexcalc hoc
|
||||||
LocalWords: TOK calc yyo fval Wconflicts parsers yystackp yyval yynerrs
|
LocalWords: yytoken YYUNDEF YYerror basename Automake's UTF ifdef ffile
|
||||||
LocalWords: Théophile Ranquet Santet fno fnone stype associativity Tolmer
|
LocalWords: gotos readline Imbimbo Wcounterexamples Wcex Nonunifying rcex
|
||||||
LocalWords: Wprecedence Rassoul Wempty Paolo Bonzini parser's Michiel loc
|
|
||||||
LocalWords: redeclaration sval fcaret reentrant XSLT xsl Wmaybe yyvsp Tedi
|
|
||||||
LocalWords: pragmas noreturn untyped Rozenman unexpanded Wojciech Polak
|
|
||||||
LocalWords: Alexandre MERCHANTABILITY yytype emplace ptr automove lvalues
|
|
||||||
LocalWords: nonterminal yy args Pragma dereference yyformat rhs docdir bw
|
|
||||||
LocalWords: Redeclarations rpcalc Autoconf YFLAGS Makefiles PROG DECL num
|
|
||||||
LocalWords: Heimbigner AST src ast Makefile srcdir MinGW xxlex XXSTYPE
|
|
||||||
LocalWords: XXLTYPE strictfp IDEs ffixit fdiagnostics parseable fixits
|
|
||||||
LocalWords: Wdeprecated yytext Variadic variadic yyrhs yyphrs RCS README
|
|
||||||
LocalWords: noexcept constexpr ispell american deprecations backend Teoh
|
|
||||||
LocalWords: YYPRINT Mangold Bonzini's Wdangling exVal baz checkable gcc
|
|
||||||
LocalWords: fsanitize Vogelsgesang lis redeclared stdint automata yytname
|
|
||||||
LocalWords: yysymbol yytnamerr yyreport ctx ARGMAX yysyntax stderr LPAREN
|
|
||||||
LocalWords: symrec yypcontext TOKENMAX yyexpected YYEMPTY yypstate YYEOF
|
|
||||||
LocalWords: autocompletion bistromathic submessages Cayuela lexcalc hoc
|
|
||||||
LocalWords: yytoken YYUNDEF YYerror
|
|
||||||
|
|
||||||
Local Variables:
|
Local Variables:
|
||||||
ispell-dictionary: "american"
|
ispell-dictionary: "american"
|
||||||
mode: outline
|
mode: outline
|
||||||
fill-column: 76
|
fill-column: 76
|
||||||
End:
|
End:
|
||||||
|
|
||||||
|
Copyright (C) 1995-2015, 2018-2020 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of Bison, the GNU Parser Generator.
|
||||||
|
|
||||||
|
Permission is granted to copy, distribute and/or modify this document
|
||||||
|
under the terms of the GNU Free Documentation License, Version 1.3 or
|
||||||
|
any later version published by the Free Software Foundation; with no
|
||||||
|
Invariant Sections, with no Front-Cover Texts, and with no Back-Cover
|
||||||
|
Texts. A copy of the license is included in the "GNU Free
|
||||||
|
Documentation License" file as part of this distribution.
|
||||||
|
|||||||
@@ -17,17 +17,18 @@ GNU Bison's home page is https://gnu.org/software/bison/.
|
|||||||
|
|
||||||
# Installation
|
# Installation
|
||||||
## Build from git
|
## Build from git
|
||||||
Here are basic installation instructions for a repository checkout:
|
The [README-hacking.md file](README-hacking.md) is about building, modifying
|
||||||
|
and checking Bison. See its "Working from the Repository" section to build
|
||||||
|
Bison from the git repo. Roughly, run:
|
||||||
|
|
||||||
$ git submodule update --init
|
$ git submodule update --init
|
||||||
$ ./bootstrap
|
$ ./bootstrap
|
||||||
|
|
||||||
then proceed with the usual `configure && make` steps.
|
then proceed with the usual `configure && make` steps.
|
||||||
|
|
||||||
The file README-hacking.md is about building, modifying and checking Bison.
|
|
||||||
|
|
||||||
## Build from tarball
|
## Build from tarball
|
||||||
See the file INSTALL for generic compilation and installation instructions.
|
See the [INSTALL file](INSTALL] for generic compilation and installation
|
||||||
|
instructions.
|
||||||
|
|
||||||
Bison requires GNU m4 1.4.6 or later. See
|
Bison requires GNU m4 1.4.6 or later. See
|
||||||
https://ftp.gnu.org/gnu/m4/m4-1.4.6.tar.gz.
|
https://ftp.gnu.org/gnu/m4/m4-1.4.6.tar.gz.
|
||||||
@@ -100,6 +101,16 @@ that the range specifies every single year in that closed interval.
|
|||||||
|
|
||||||
<!--
|
<!--
|
||||||
|
|
||||||
|
LocalWords: parsers ngettext Texinfo pdf html YYYY ZZZZ ispell american md
|
||||||
|
LocalWords: MERCHANTABILITY GLR LALR IELR submodule init README src bw
|
||||||
|
LocalWords: Relocatability symlinks symlink
|
||||||
|
|
||||||
|
Local Variables:
|
||||||
|
mode: markdown
|
||||||
|
fill-column: 76
|
||||||
|
ispell-dictionary: "american"
|
||||||
|
End:
|
||||||
|
|
||||||
Copyright (C) 1992, 1998-1999, 2003-2005, 2008-2015, 2018-2020 Free
|
Copyright (C) 1992, 1998-1999, 2003-2005, 2008-2015, 2018-2020 Free
|
||||||
Software Foundation, Inc.
|
Software Foundation, Inc.
|
||||||
|
|
||||||
@@ -112,14 +123,4 @@ Invariant Sections, with no Front-Cover Texts, and with no Back-Cover
|
|||||||
Texts. A copy of the license is included in the "GNU Free
|
Texts. A copy of the license is included in the "GNU Free
|
||||||
Documentation License" file as part of this distribution.
|
Documentation License" file as part of this distribution.
|
||||||
|
|
||||||
Local Variables:
|
|
||||||
mode: markdown
|
|
||||||
fill-column: 76
|
|
||||||
ispell-dictionary: "american"
|
|
||||||
End:
|
|
||||||
|
|
||||||
LocalWords: parsers ngettext Texinfo pdf html YYYY ZZZZ ispell american md
|
|
||||||
LocalWords: MERCHANTABILITY GLR LALR IELR submodule init README src bw
|
|
||||||
LocalWords: Relocatability symlinks symlink
|
|
||||||
|
|
||||||
-->
|
-->
|
||||||
|
|||||||
+233
-154
@@ -5,151 +5,6 @@ Everything related to the development of Bison is on Savannah:
|
|||||||
http://savannah.gnu.org/projects/bison/.
|
http://savannah.gnu.org/projects/bison/.
|
||||||
|
|
||||||
|
|
||||||
Administrivia
|
|
||||||
=============
|
|
||||||
|
|
||||||
## If you incorporate a change from somebody on the net:
|
|
||||||
First, if it is a large change, you must make sure they have signed the
|
|
||||||
appropriate paperwork. Second, be sure to add their name and email address
|
|
||||||
to THANKS.
|
|
||||||
|
|
||||||
## If a change fixes a test, mention the test in the commit message.
|
|
||||||
|
|
||||||
## Bug reports
|
|
||||||
If somebody reports a new bug, mention his name in the commit message and in
|
|
||||||
the test case you write. Put him into THANKS.
|
|
||||||
|
|
||||||
The correct response to most actual bugs is to write a new test case which
|
|
||||||
demonstrates the bug. Then fix the bug, re-run the test suite, and check
|
|
||||||
everything in.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Hacking
|
|
||||||
=======
|
|
||||||
|
|
||||||
## Visible Changes
|
|
||||||
Which include serious bug fixes, must be mentioned in NEWS.
|
|
||||||
|
|
||||||
## Translations
|
|
||||||
Only user visible strings are to be translated: error messages, bits of the
|
|
||||||
.output file etc. This excludes impossible error messages (comparable to
|
|
||||||
assert/abort), and all the --trace output which is meant for the maintainers
|
|
||||||
only.
|
|
||||||
|
|
||||||
## Syntax highlighting
|
|
||||||
It's quite nice to be in C++ mode when editing lalr1.cc for instance.
|
|
||||||
However tools such as Emacs will be fooled by the fact that braces and
|
|
||||||
parens do not nest, as in `[[}]]`. As a consequence you might be misguided
|
|
||||||
by its visual pairing to parens. The m4-mode is safer. Unfortunately the
|
|
||||||
m4-mode is also fooled by `#` which is sees as a comment, stops pairing with
|
|
||||||
parens/brackets that are inside...
|
|
||||||
|
|
||||||
## Coding Style
|
|
||||||
Do not add horizontal tab characters to any file in Bison's repository
|
|
||||||
except where required. For example, do not use tabs to format C code.
|
|
||||||
However, make files, ChangeLog, and some regular expressions require tabs.
|
|
||||||
Also, test cases might need to contain tabs to check that Bison properly
|
|
||||||
processes tabs in its input.
|
|
||||||
|
|
||||||
Prefer "res" as the name of the local variable that will be "return"ed by
|
|
||||||
the function.
|
|
||||||
|
|
||||||
### Bison
|
|
||||||
Follow the GNU Coding Standards.
|
|
||||||
|
|
||||||
Don't reinvent the wheel: we use gnulib, which features many components.
|
|
||||||
Actually, Bison has legacy code that we should replace with gnulib modules
|
|
||||||
(e.g., many ad hoc implementations of lists).
|
|
||||||
|
|
||||||
### Skeletons
|
|
||||||
We try to use the "typical" coding style for each language.
|
|
||||||
|
|
||||||
#### CPP
|
|
||||||
We indent the CPP directives this way:
|
|
||||||
|
|
||||||
```
|
|
||||||
#if FOO
|
|
||||||
# if BAR
|
|
||||||
# define BAZ
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
```
|
|
||||||
|
|
||||||
Don't indent with leading spaces in the skeletons (it's ok in the grammar
|
|
||||||
files though, e.g., in `%code {...}` blocks).
|
|
||||||
|
|
||||||
On occasions, use `cppi -c` to see where we stand. We don't aim at full
|
|
||||||
correctness: depending `-d`, some bits can be in the *.c file, or the *.h
|
|
||||||
file within the double-inclusion cpp-guards. In that case, favor the case
|
|
||||||
of the *.h file, but don't waste time on this.
|
|
||||||
|
|
||||||
Don't hesitate to leave a comment on the `#endif` (e.g., `#endif /* FOO
|
|
||||||
*/`), especially for long blocks.
|
|
||||||
|
|
||||||
There is no conistency on `! defined` vs. `!defined`. The day gnulib
|
|
||||||
decides, we'll follow them.
|
|
||||||
|
|
||||||
#### C/C++
|
|
||||||
Follow the GNU Coding Standards.
|
|
||||||
|
|
||||||
The `glr.c` skeleton was implemented with `camlCase`. We are migrating it
|
|
||||||
to `snake_case`. Because we are standardizing the code, it is currently
|
|
||||||
inconsistent.
|
|
||||||
|
|
||||||
Use `YYFOO` and `yyfoo` for entities that are exposed to the user. They are
|
|
||||||
part of our contract with the users wrt backward compatibility.
|
|
||||||
|
|
||||||
Use `YY_FOO` and `yy_foo` for private matters. Users should not use them,
|
|
||||||
we are free to change them without fear of backward compatibility issues.
|
|
||||||
|
|
||||||
Use `*_t` for types, especially for `yy*_t` in which case we shouldn't worry
|
|
||||||
about the C standard introducing such a name.
|
|
||||||
|
|
||||||
#### C++
|
|
||||||
Follow the C++ Core Guidelines
|
|
||||||
(http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines). The Google
|
|
||||||
ones may be interesting too
|
|
||||||
(https://google.github.io/styleguide/cppguide.html).
|
|
||||||
|
|
||||||
Our enumerators, such as the kinds (symbol and token kinds), should be lower
|
|
||||||
case, but it was too late to follow that track for token kinds, and symbol
|
|
||||||
kind enumerators are made to be consistent with them.
|
|
||||||
|
|
||||||
Use `*_type` for type aliases. Use `foo_get()` and `foo_set(v)` for
|
|
||||||
accessors, or simply `foo()` and `foo(v)`.
|
|
||||||
|
|
||||||
Use the `yy` prefix for private stuff, but there's no need for it in the
|
|
||||||
public API. The `yy` prefix is already taken care of via the namespace.
|
|
||||||
|
|
||||||
#### Java
|
|
||||||
We follow https://www.oracle.com/technetwork/java/codeconventions-150003.pdf
|
|
||||||
and https://google.github.io/styleguide/javaguide.html. Unfortunately at
|
|
||||||
some point some GNU Coding Style was installed in Java, but it's an error.
|
|
||||||
So we should for instance stop putting spaces in function calls. Because we
|
|
||||||
are standardizing the code, it is currently inconsistent.
|
|
||||||
|
|
||||||
Use a 2-space indentation (Google) rather than 4 (Oracle).
|
|
||||||
|
|
||||||
Don't use the "yy" prefix for public members: "getExpectedTokens", not
|
|
||||||
"yyexpectedTokens" or "yygetExpectedTokens".
|
|
||||||
|
|
||||||
## Commit Messages
|
|
||||||
Imitate the style we use. Use `git log` to get sources of inspiration.
|
|
||||||
|
|
||||||
If the changes have a small impact on Bison's generated parser, embed these
|
|
||||||
changes in the commit itself. If the impact is large, first push all the
|
|
||||||
changes except those about src/parse-gram.[ch], and then another commit
|
|
||||||
named "regen" which is only about them.
|
|
||||||
|
|
||||||
## Debugging
|
|
||||||
Bison supports tracing of its various steps, via the `--trace` option.
|
|
||||||
Since it is not meant for the end user, it is not displayed by `bison
|
|
||||||
--help`, nor is it documented in the manual. Instead, run `bison
|
|
||||||
--trace=help`.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Working from the Repository
|
Working from the Repository
|
||||||
===========================
|
===========================
|
||||||
|
|
||||||
@@ -168,6 +23,7 @@ tools we depend upon, including:
|
|||||||
- Automake <http://www.gnu.org/software/automake/>
|
- Automake <http://www.gnu.org/software/automake/>
|
||||||
- Flex <http://www.gnu.org/software/flex/>
|
- Flex <http://www.gnu.org/software/flex/>
|
||||||
- Gettext <http://www.gnu.org/software/gettext/>
|
- Gettext <http://www.gnu.org/software/gettext/>
|
||||||
|
- Gperf <http://www.gnu.org/software/gperf/>
|
||||||
- Graphviz <http://www.graphviz.org>
|
- Graphviz <http://www.graphviz.org>
|
||||||
- Gzip <http://www.gnu.org/software/gzip/>
|
- Gzip <http://www.gnu.org/software/gzip/>
|
||||||
- Help2man <http://www.gnu.org/software/help2man/>
|
- Help2man <http://www.gnu.org/software/help2man/>
|
||||||
@@ -184,7 +40,7 @@ above packages depends on your system. The following shell command should
|
|||||||
work for Debian-based systems such as Ubuntu:
|
work for Debian-based systems such as Ubuntu:
|
||||||
|
|
||||||
sudo apt-get install \
|
sudo apt-get install \
|
||||||
autoconf automake autopoint flex graphviz help2man texinfo valgrind
|
autoconf automake autopoint flex gperf graphviz help2man texinfo valgrind
|
||||||
|
|
||||||
Bison is written using Bison grammars, so there are bootstrapping issues.
|
Bison is written using Bison grammars, so there are bootstrapping issues.
|
||||||
The bootstrap script attempts to discover when the C code generated from the
|
The bootstrap script attempts to discover when the C code generated from the
|
||||||
@@ -322,6 +178,201 @@ version, compile bison, then force it to recreate the files:
|
|||||||
$ make -C _build
|
$ make -C _build
|
||||||
|
|
||||||
|
|
||||||
|
Administrivia
|
||||||
|
=============
|
||||||
|
|
||||||
|
## If you incorporate a change from somebody on the net:
|
||||||
|
First, if it is a large change, you must make sure they have signed the
|
||||||
|
appropriate paperwork. Second, be sure to add their name and email address
|
||||||
|
to THANKS.
|
||||||
|
|
||||||
|
## If a change fixes a test, mention the test in the commit message.
|
||||||
|
|
||||||
|
## Bug reports
|
||||||
|
If somebody reports a new bug, mention his name in the commit message and in
|
||||||
|
the test case you write. Put him into THANKS.
|
||||||
|
|
||||||
|
The correct response to most actual bugs is to write a new test case which
|
||||||
|
demonstrates the bug. Then fix the bug, re-run the test suite, and check
|
||||||
|
everything in.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Hacking
|
||||||
|
=======
|
||||||
|
|
||||||
|
## Visible Changes
|
||||||
|
Which include serious bug fixes, must be mentioned in NEWS.
|
||||||
|
|
||||||
|
## Translations
|
||||||
|
Only user visible strings are to be translated: error messages, bits of the
|
||||||
|
.output file etc. This excludes impossible error messages (comparable to
|
||||||
|
assert/abort), and all the --trace output which is meant for the maintainers
|
||||||
|
only.
|
||||||
|
|
||||||
|
## Vocabulary
|
||||||
|
- "lookahead", not "look-ahead".
|
||||||
|
- "midrule", not "mid-rule".
|
||||||
|
- "nonterminal", not "variable" or "non-terminal" or "non terminal".
|
||||||
|
Abbreviated as "nterm".
|
||||||
|
- "shift/reduce" and "reduce/reduce", not "shift-reduce" or "shift reduce",
|
||||||
|
etc.
|
||||||
|
|
||||||
|
## Syntax Highlighting
|
||||||
|
It's quite nice to be in C++ mode when editing lalr1.cc for instance.
|
||||||
|
However tools such as Emacs will be fooled by the fact that braces and
|
||||||
|
parens do not nest, as in `[[}]]`. As a consequence you might be misguided
|
||||||
|
by its visual pairing to parens. The m4-mode is safer. Unfortunately the
|
||||||
|
m4-mode is also fooled by `#` which is sees as a comment, stops pairing with
|
||||||
|
parens/brackets that are inside...
|
||||||
|
|
||||||
|
## Implementation Notes
|
||||||
|
There are several places with interesting details about the implementation:
|
||||||
|
- [Understanding C parsers generated by GNU
|
||||||
|
Bison](https://www.cs.uic.edu/~spopuri/cparser.html) by Satya Kiran Popuri,
|
||||||
|
is a wonderful piece of work that explains the implementation of Bison,
|
||||||
|
- [src/gram.h](src/gram.h) documents the way the grammar is represented
|
||||||
|
- [src/tables.h](src/tables.h) documents the generated tables
|
||||||
|
- [data/README.md](data/README.md) contains details about the m4 implementation
|
||||||
|
|
||||||
|
## Coding Style
|
||||||
|
Do not add horizontal tab characters to any file in Bison's repository
|
||||||
|
except where required. For example, do not use tabs to format C code.
|
||||||
|
However, make files, ChangeLog, and some regular expressions require tabs.
|
||||||
|
Also, test cases might need to contain tabs to check that Bison properly
|
||||||
|
processes tabs in its input.
|
||||||
|
|
||||||
|
Prefer `res` as the name of the local variable that will be "return"ed by
|
||||||
|
the function.
|
||||||
|
|
||||||
|
In writing arithmetic comparisons, use "<" and "<=" rather than ">" and ">="
|
||||||
|
(http://www.gelato.unsw.edu.au/archives/git/0505/4507.html).
|
||||||
|
|
||||||
|
### Bison
|
||||||
|
Follow the GNU Coding Standards.
|
||||||
|
|
||||||
|
Don't reinvent the wheel: we use gnulib, which features many components.
|
||||||
|
Actually, Bison has legacy code that we should replace with gnulib modules
|
||||||
|
(e.g., many ad hoc implementations of lists).
|
||||||
|
|
||||||
|
#### Includes
|
||||||
|
The `#include` directives follow an order:
|
||||||
|
- first section for *.c files is `<config.h>`. Don't include it in header
|
||||||
|
files
|
||||||
|
- then, for *.c files, the corresponding *.h file
|
||||||
|
- then possibly the `"system.h"` header
|
||||||
|
- then the system headers.
|
||||||
|
Consider headers from `lib/` like system headers (i.e., `#include
|
||||||
|
<verify.h>`, not `#include "verify.h"`).
|
||||||
|
- then headers from src/ with double quotes (`#include "getargs.h"`).
|
||||||
|
|
||||||
|
Keep headers sorted alphabetically in each section.
|
||||||
|
|
||||||
|
See also the [Header
|
||||||
|
files](https://www.gnu.org/software/gnulib/manual/html_node/Header-files.html)
|
||||||
|
and the [Implementation
|
||||||
|
files](https://www.gnu.org/software/gnulib/manual/html_node/Implementation-files.html#Implementation-files)
|
||||||
|
nodes of the gnulib documentation.
|
||||||
|
|
||||||
|
Some source files are in the build tree (e.g., `src/scan-gram.c` made from
|
||||||
|
`src/scan-gram.l`). For them to find the headers from `src/`, we actually
|
||||||
|
use `#include "src/getargs.h"` instead of `#include "getargs.h"`---that
|
||||||
|
saves us from additional `-I` flags.
|
||||||
|
|
||||||
|
### Skeletons
|
||||||
|
We try to use the "typical" coding style for each language.
|
||||||
|
|
||||||
|
#### CPP
|
||||||
|
We indent the CPP directives this way:
|
||||||
|
|
||||||
|
```
|
||||||
|
#if FOO
|
||||||
|
# if BAR
|
||||||
|
# define BAZ
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
```
|
||||||
|
|
||||||
|
Don't indent with leading spaces in the skeletons (it's OK in the grammar
|
||||||
|
files though, e.g., in `%code {...}` blocks).
|
||||||
|
|
||||||
|
On occasions, use `cppi -c` to see where we stand. We don't aim at full
|
||||||
|
correctness: depending `-d`, some bits can be in the *.c file, or the *.h
|
||||||
|
file within the double-inclusion cpp-guards. In that case, favor the case
|
||||||
|
of the *.h file, but don't waste time on this.
|
||||||
|
|
||||||
|
Don't hesitate to leave a comment on the `#endif` (e.g., `#endif /* FOO
|
||||||
|
*/`), especially for long blocks.
|
||||||
|
|
||||||
|
There is no consistency on `! defined` vs. `!defined`. The day gnulib
|
||||||
|
decides, we'll follow them.
|
||||||
|
|
||||||
|
#### C/C++
|
||||||
|
Follow the GNU Coding Standards.
|
||||||
|
|
||||||
|
The `glr.c` skeleton was implemented with `camlCase`. We are migrating it
|
||||||
|
to `snake_case`. Because we are gradually standardizing the code, it is
|
||||||
|
currently inconsistent.
|
||||||
|
|
||||||
|
Use `YYFOO` and `yyfoo` for entities that are exposed to the user. They are
|
||||||
|
part of our contract with the users wrt backward compatibility.
|
||||||
|
|
||||||
|
Use `YY_FOO` and `yy_foo` for private matters. Users should not use them,
|
||||||
|
we are free to change them without fear of backward compatibility issues.
|
||||||
|
|
||||||
|
Use `*_t` for types, especially for `yy*_t` in which case we shouldn't worry
|
||||||
|
about the C standard introducing such a name.
|
||||||
|
|
||||||
|
#### C++
|
||||||
|
Follow the [C++ Core
|
||||||
|
Guidelines](http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines).
|
||||||
|
The [Google ones](https://google.github.io/styleguide/cppguide.html) may be
|
||||||
|
interesting too.
|
||||||
|
|
||||||
|
Our enumerators, such as the kinds (symbol and token kinds), should be lower
|
||||||
|
case, but it was too late to follow that track for token kinds, and symbol
|
||||||
|
kind enumerators are made to be consistent with them.
|
||||||
|
|
||||||
|
Use `*_type` for type aliases. Use `foo_get()` and `foo_set(v)` for
|
||||||
|
accessors, or simply `foo()` and `foo(v)`.
|
||||||
|
|
||||||
|
Use the `yy` prefix for private stuff, but there's no need for it in the
|
||||||
|
public API. The `yy` prefix is already taken care of via the namespace.
|
||||||
|
|
||||||
|
#### Java
|
||||||
|
We follow the [Java Code
|
||||||
|
Conventions](https://www.oracle.com/technetwork/java/codeconventions-150003.pdf)
|
||||||
|
and [Google Java Style
|
||||||
|
Guide](https://google.github.io/styleguide/javaguide.html). Unfortunately
|
||||||
|
at some point some GNU Coding Style was installed in Java, but it's an
|
||||||
|
error. So we should for instance stop putting spaces in function calls.
|
||||||
|
Because we are standardizing the code, it is currently inconsistent.
|
||||||
|
|
||||||
|
Use a 2-space indentation (Google) rather than 4 (Oracle).
|
||||||
|
|
||||||
|
Don't use the "yy" prefix for public members: "getExpectedTokens", not
|
||||||
|
"yyexpectedTokens" or "yygetExpectedTokens".
|
||||||
|
|
||||||
|
## Commit Messages
|
||||||
|
Imitate the style we use. Use `git log` to get sources of inspiration.
|
||||||
|
|
||||||
|
If the changes have a small impact on Bison's generated parser, embed these
|
||||||
|
changes in the commit itself. If the impact is large, first push all the
|
||||||
|
changes except those about src/parse-gram.[ch], and then another commit
|
||||||
|
named "regen" which is only about them.
|
||||||
|
|
||||||
|
## Debugging
|
||||||
|
Bison supports tracing of its various steps, via the `--trace` option.
|
||||||
|
Since it is not meant for the end user, it is not displayed by `bison
|
||||||
|
--help`, nor is it documented in the manual. Instead, run `bison
|
||||||
|
--trace=help`.
|
||||||
|
|
||||||
|
## Documentation
|
||||||
|
Use `@option` for options and options with their argument if they have no
|
||||||
|
space (e.g., `@option{-Dfoo=bar}`). However, use `@samp` elsewhere (e.g.,
|
||||||
|
`@samp{-I foo}`).
|
||||||
|
|
||||||
|
|
||||||
Test Suite
|
Test Suite
|
||||||
==========
|
==========
|
||||||
|
|
||||||
@@ -331,9 +382,9 @@ examples, and the main test suite.
|
|||||||
|
|
||||||
### The Examples
|
### The Examples
|
||||||
In examples/, there is a number of ready-to-use examples (see
|
In examples/, there is a number of ready-to-use examples (see
|
||||||
examples/README.md). These examples have small test suites run by `make
|
[examples/README.md](examples/README.md)). These examples have small test
|
||||||
check`. The test results are in local `*.log` files (e.g.,
|
suites run by `make check`. The test results are in local `*.log` files
|
||||||
`$build/examples/c/calc/calc.log`).
|
(e.g., `$build/examples/c/calc/calc.log`).
|
||||||
|
|
||||||
### The Main Test Suite
|
### The Main Test Suite
|
||||||
The main test suite, in tests/, is written on top of GNU Autotest, which is
|
The main test suite, in tests/, is written on top of GNU Autotest, which is
|
||||||
@@ -393,7 +444,7 @@ added the `[-Wother]` part to all the warnings). Part of the update can be
|
|||||||
done with a crude tool: `build-aux/update-test`.
|
done with a crude tool: `build-aux/update-test`.
|
||||||
|
|
||||||
Once you ran the test suite, and therefore have many `testsuite.log` files,
|
Once you ran the test suite, and therefore have many `testsuite.log` files,
|
||||||
run, from the source tree:
|
run `make update-tests`. Or, by hand, from the *source* tree:
|
||||||
|
|
||||||
$ ./build-aux/update-test $build/tests/testsuite.dir/*/testsuite.log
|
$ ./build-aux/update-test $build/tests/testsuite.dir/*/testsuite.log
|
||||||
|
|
||||||
@@ -409,6 +460,31 @@ Use the `javaexec.sh` script. For instance to run the parser of test case
|
|||||||
|
|
||||||
$ sh ./_build/javaexec.sh -cp ./_build/tests/testsuite.dir/504 Calc
|
$ sh ./_build/javaexec.sh -cp ./_build/tests/testsuite.dir/504 Calc
|
||||||
|
|
||||||
|
## Using Sanitizers
|
||||||
|
Address sanitizer (ASAN) and undefined-behavior sanitizer (UBSAN) are very
|
||||||
|
useful. Here's one way to set ASAN up with GCC 10 on Mac Ports
|
||||||
|
|
||||||
|
1. Configure with
|
||||||
|
|
||||||
|
$ ./configure -C --enable-gcc-warnings \
|
||||||
|
CPPFLAGS='-isystem /opt/local/include' \
|
||||||
|
CC='gcc-mp-10 -fsanitize=address' \
|
||||||
|
CFLAGS='-ggdb' \
|
||||||
|
CXX='g++-mp-10.0 -fsanitize=address' \
|
||||||
|
CXXFLAGS='-ggdb' \
|
||||||
|
LDFLAGS='-L/opt/local/lib'
|
||||||
|
|
||||||
|
2. Compile
|
||||||
|
|
||||||
|
3. Generate debug symbols:
|
||||||
|
|
||||||
|
$ dsymutil src/bison
|
||||||
|
|
||||||
|
4. Run the tests with leak detection enabled
|
||||||
|
(`ASAN_OPTIONS=detect_leaks=1`). E.g. for counterexamples:
|
||||||
|
|
||||||
|
$ make check-local TESTSUITEFLAGS='-j5 -k cex' ASAN_OPTIONS=detect_leaks=1
|
||||||
|
|
||||||
## make maintainer-check-valgrind
|
## make maintainer-check-valgrind
|
||||||
This target uses valgrind both to check bison, and the generated parsers.
|
This target uses valgrind both to check bison, and the generated parsers.
|
||||||
|
|
||||||
@@ -488,7 +564,8 @@ re-run the tests, run:
|
|||||||
Release Procedure
|
Release Procedure
|
||||||
=================
|
=================
|
||||||
|
|
||||||
See README-release.
|
See the [README-release file](README-release), created when the package is
|
||||||
|
bootstrapped.
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
|
|
||||||
@@ -524,8 +601,10 @@ LocalWords: symlinks vti html lt POSIX Cc'ed Graphviz Texinfo autoconf jN
|
|||||||
LocalWords: automake autopoint graphviz texinfo PROG Wother parsers YYFOO
|
LocalWords: automake autopoint graphviz texinfo PROG Wother parsers YYFOO
|
||||||
LocalWords: TESTSUITEFLAGS deprec struct gnulib's getopt config ggdb yyfoo
|
LocalWords: TESTSUITEFLAGS deprec struct gnulib's getopt config ggdb yyfoo
|
||||||
LocalWords: bitset fsanitize symlink CFLAGS MERCHANTABILITY ispell wrt YY
|
LocalWords: bitset fsanitize symlink CFLAGS MERCHANTABILITY ispell wrt YY
|
||||||
LocalWords: american Administrivia camlCase yy accessors namespace src
|
LocalWords: american Administrivia camlCase yy accessors namespace src hoc
|
||||||
LocalWords: getExpectedTokens yyexpectedTokens yygetExpectedTokens
|
LocalWords: getExpectedTokens yyexpectedTokens yygetExpectedTokens parens
|
||||||
LocalWords: regen dogfooding Autotest testsuite
|
LocalWords: regen dogfooding Autotest testsuite getargs CPP BAZ endif cppi
|
||||||
|
LocalWords: cpp javaexec cp Calc ASAN UBSAN CPPFLAGS isystem CXX cex Gperf
|
||||||
|
LocalWords: CXXFLAGS LDFLAGS dsymutil gperf
|
||||||
|
|
||||||
-->
|
-->
|
||||||
|
|||||||
@@ -1,4 +1,41 @@
|
|||||||
* Bison 3.6
|
* Bison 3.7
|
||||||
|
** Cex
|
||||||
|
*** Improve gnulib
|
||||||
|
Don't do this (counterexample.c):
|
||||||
|
|
||||||
|
// This is the fastest way to get the tail node from the gl_list API.
|
||||||
|
gl_list_node_t
|
||||||
|
list_get_end (gl_list_t list)
|
||||||
|
{
|
||||||
|
gl_list_node_t sentinel = gl_list_add_last (list, NULL);
|
||||||
|
gl_list_node_t res = gl_list_previous_node (list, sentinel);
|
||||||
|
gl_list_remove_node (list, sentinel);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
*** Ambiguous rewriting
|
||||||
|
If the user is stupid enough to have equal rules, then the derivations are
|
||||||
|
harder to read:
|
||||||
|
|
||||||
|
Reduce/reduce conflict on tokens $end, "+", "⊕":
|
||||||
|
2 exp: exp "+" exp .
|
||||||
|
3 exp: exp "+" exp .
|
||||||
|
Example exp "+" exp •
|
||||||
|
First derivation exp ::=[ exp "+" exp • ]
|
||||||
|
Example exp "+" exp •
|
||||||
|
Second derivation exp ::=[ exp "+" exp • ]
|
||||||
|
|
||||||
|
Do we care about this? In color, we use twice the same color here, but we
|
||||||
|
could try to use the same color for the same rule.
|
||||||
|
|
||||||
|
*** XML reports
|
||||||
|
Show the counterexamples. This is going to be really hard and/or painful.
|
||||||
|
Unless we play it dumb (little structure).
|
||||||
|
|
||||||
|
** Bistromathic
|
||||||
|
- How about not evaluating incomplete lines when the text is not finished
|
||||||
|
(as shells do).
|
||||||
|
|
||||||
** Questions
|
** Questions
|
||||||
*** Java
|
*** Java
|
||||||
- Should i18n be part of the Lexer? Currently it's a static method of
|
- Should i18n be part of the Lexer? Currently it's a static method of
|
||||||
@@ -25,30 +62,9 @@ should be updated to not use YYERRCODE. Returning an undef token is good
|
|||||||
enough.
|
enough.
|
||||||
|
|
||||||
** Java
|
** Java
|
||||||
*** Examples
|
|
||||||
Have an example with a push parser. Use autocompletion in that case.
|
|
||||||
|
|
||||||
*** calc.at
|
*** calc.at
|
||||||
Stop hard-coding "Calc". Adjust local.at (look for FIXME).
|
Stop hard-coding "Calc". Adjust local.at (look for FIXME).
|
||||||
|
|
||||||
* Bison 3.7
|
|
||||||
** Counter example generation
|
|
||||||
See https://github.com/akimd/bison/pull/15.
|
|
||||||
|
|
||||||
** Clean up
|
|
||||||
Rename user_token_number for tokens as "code". It's not a "user number",
|
|
||||||
it's the token code, and the user can control it, but this code always
|
|
||||||
exists.
|
|
||||||
|
|
||||||
See also USER_NUMBER_UNDEFINED and NUMBER_UNDEFINED.
|
|
||||||
|
|
||||||
Rename endtoken as eoftoken.
|
|
||||||
|
|
||||||
Also do it in data/skeletons.
|
|
||||||
|
|
||||||
Don't rename in Bison 3.6 (it would be logical to do so) because that
|
|
||||||
would probably create many conflicts in Vincent's work (see previous point).
|
|
||||||
|
|
||||||
** A dev warning for b4_
|
** A dev warning for b4_
|
||||||
Maybe we should check for m4_ and b4_ leaking out of the m4 processing, as
|
Maybe we should check for m4_ and b4_ leaking out of the m4 processing, as
|
||||||
Autoconf does. It would have caught overquotation issues.
|
Autoconf does. It would have caught overquotation issues.
|
||||||
@@ -59,7 +75,7 @@ generates tons of white space in the page, and may contribute to bad page
|
|||||||
breaks.
|
breaks.
|
||||||
|
|
||||||
** consistency
|
** consistency
|
||||||
token vs terminal, variable vs non terminal.
|
token vs terminal.
|
||||||
|
|
||||||
** api.token.raw
|
** api.token.raw
|
||||||
The YYUNDEFTOK could be assigned a semantic value so that yyerror could be
|
The YYUNDEFTOK could be assigned a semantic value so that yyerror could be
|
||||||
@@ -71,8 +87,79 @@ a bad feature. On the other hand, that would make it much harder to sit
|
|||||||
push parsers on top of pull parser. Which is currently not relevant, since
|
push parsers on top of pull parser. Which is currently not relevant, since
|
||||||
push parsers are measurably slower.
|
push parsers are measurably slower.
|
||||||
|
|
||||||
|
** %define parse.error formatted
|
||||||
|
How about pushing bistromathics' yyreport_syntax_error as another standard
|
||||||
|
way to generate the error message, and leave to the user the task of
|
||||||
|
providing the message formats? Currently in bistro, it reads:
|
||||||
|
|
||||||
|
const char *
|
||||||
|
error_format_string (int argc)
|
||||||
|
{
|
||||||
|
switch (argc)
|
||||||
|
{
|
||||||
|
default: /* Avoid compiler warnings. */
|
||||||
|
case 0: return _("%@: syntax error");
|
||||||
|
case 1: return _("%@: syntax error: unexpected %u");
|
||||||
|
// TRANSLATORS: '%@' is a location in a file, '%u' is an
|
||||||
|
// "unexpected token", and '%0e', '%1e'... are expected tokens
|
||||||
|
// at this point.
|
||||||
|
//
|
||||||
|
// For instance on the expression "1 + * 2", you'd get
|
||||||
|
//
|
||||||
|
// 1.5: syntax error: expected - or ( or number or function or variable before *
|
||||||
|
case 2: return _("%@: syntax error: expected %0e before %u");
|
||||||
|
case 3: return _("%@: syntax error: expected %0e or %1e before %u");
|
||||||
|
case 4: return _("%@: syntax error: expected %0e or %1e or %2e before %u");
|
||||||
|
case 5: return _("%@: syntax error: expected %0e or %1e or %2e or %3e before %u");
|
||||||
|
case 6: return _("%@: syntax error: expected %0e or %1e or %2e or %3e or %4e before %u");
|
||||||
|
case 7: return _("%@: syntax error: expected %0e or %1e or %2e or %3e or %4e or %5e before %u");
|
||||||
|
case 8: return _("%@: syntax error: expected %0e or %1e or %2e or %3e or %4e or %5e or %6e before %u");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
The message would have to be generated in a string, and pushed to yyerror.
|
||||||
|
Which will be a pain in the neck in yacc.c.
|
||||||
|
|
||||||
|
If we want to do that, we should think very carefully about the syntax of
|
||||||
|
the format string.
|
||||||
|
|
||||||
|
** yyclearin does not invoke the lookahead token's %destructor
|
||||||
|
https://lists.gnu.org/r/bug-bison/2018-02/msg00000.html
|
||||||
|
Rici:
|
||||||
|
|
||||||
|
> Modifying yyclearin so that it calls yydestruct seems like the simplest
|
||||||
|
> solution to this issue, but it is conceivable that such a change would
|
||||||
|
> break programs which already perform some kind of workaround in order to
|
||||||
|
> destruct the lookahead symbol. So it might be necessary to use some kind of
|
||||||
|
> compatibility %define, or to create a new replacement macro with a
|
||||||
|
> different name such as yydiscardin.
|
||||||
|
>
|
||||||
|
> At a minimum, the fact that yyclearin does not invoke the %destructor
|
||||||
|
> should be highlighted in the documentation, since it is not at all obvious.
|
||||||
|
|
||||||
|
** Issues in i18n
|
||||||
|
|
||||||
|
Les catégories d'avertissements incluent :
|
||||||
|
conflicts-sr conflits S/R (activé par défaut)
|
||||||
|
conflicts-rr conflits R/R (activé par défaut)
|
||||||
|
dangling-alias l'alias chaîne n'est pas attaché à un symbole
|
||||||
|
deprecated construction obsolète
|
||||||
|
empty-rule règle vide sans %empty
|
||||||
|
midrule-values valeurs de règle intermédiaire non définies ou inutilisées
|
||||||
|
precedence priorité et associativité inutiles
|
||||||
|
yacc incompatibilités avec POSIX Yacc
|
||||||
|
other tous les autres avertissements (activé par défaut)
|
||||||
|
all tous les avertissements sauf « dangling-alias » et « yacc »
|
||||||
|
no-CATEGORY désactiver les avertissements dans CATEGORIE
|
||||||
|
none désactiver tous les avertissements
|
||||||
|
error[=CATEGORY] traiter les avertissements comme des erreurs
|
||||||
|
|
||||||
|
Line -1 and -3 should mention CATEGORIE, not CATEGORY.
|
||||||
|
|
||||||
* Bison 3.8
|
* Bison 3.8
|
||||||
|
** Rewrite glr.cc
|
||||||
|
Get rid of scaffolding in glr.c.
|
||||||
|
|
||||||
** Unit rules / Injection rules (Akim Demaille)
|
** Unit rules / Injection rules (Akim Demaille)
|
||||||
Maybe we could expand unit rules (or "injections", see
|
Maybe we could expand unit rules (or "injections", see
|
||||||
https://homepages.cwi.nl/~daybuild/daily-books/syntax/2-sdf/sdf.html), i.e.,
|
https://homepages.cwi.nl/~daybuild/daily-books/syntax/2-sdf/sdf.html), i.e.,
|
||||||
@@ -146,10 +233,10 @@ define it to the same type as the C ptrdiff_t type.
|
|||||||
* Completion
|
* Completion
|
||||||
Several features are not available in all the backends.
|
Several features are not available in all the backends.
|
||||||
|
|
||||||
- push parsers: glr.c, glr.cc, lalr1.cc
|
- lac: D, Java (easy)
|
||||||
- lac: D, Java
|
- push parsers: glr.c, glr.cc, lalr1.cc (not very difficult)
|
||||||
- glr: D, Java
|
- token constructors: Java, C, D (a bit difficult)
|
||||||
- token constructors: Java, C, D
|
- glr: D, Java (super difficult)
|
||||||
|
|
||||||
* Bugs
|
* Bugs
|
||||||
** Autotest has quotation issues
|
** Autotest has quotation issues
|
||||||
@@ -339,22 +426,16 @@ undocumented ''features''. Maybe an empty action ought to be
|
|||||||
presented too. Shall we try to make a single grammar with all these
|
presented too. Shall we try to make a single grammar with all these
|
||||||
features, or should we have several very small grammars?
|
features, or should we have several very small grammars?
|
||||||
|
|
||||||
** --report=conflict-path
|
|
||||||
Provide better assistance for understanding the conflicts by providing
|
|
||||||
a sample text exhibiting the (LALR) ambiguity. See the paper from
|
|
||||||
DeRemer and Penello: they already provide the algorithm.
|
|
||||||
|
|
||||||
** Statically check for potential ambiguities in GLR grammars
|
|
||||||
See <http://www.lsv.fr/~schmitz/pub/expamb.pdf> for an approach.
|
|
||||||
An Experimental Ambiguity Detection Tool ∗ Sylvain Schmitz
|
|
||||||
LORIA, INRIA Nancy - Grand Est, Nancy, France
|
|
||||||
|
|
||||||
* Extensions
|
* Extensions
|
||||||
** More languages?
|
** More languages?
|
||||||
Well, only if there is really some demand for it.
|
Well, only if there is really some demand for it.
|
||||||
|
|
||||||
|
*** PHP
|
||||||
https://github.com/scfc/bison-php/blob/master/data/lalr1.php
|
https://github.com/scfc/bison-php/blob/master/data/lalr1.php
|
||||||
|
|
||||||
|
*** Python
|
||||||
|
https://lists.gnu.org/r/bison-patches/2013-09/msg00000.html and following
|
||||||
|
|
||||||
** Multiple start symbols
|
** Multiple start symbols
|
||||||
Would be very useful when parsing closely related languages. The idea is to
|
Would be very useful when parsing closely related languages. The idea is to
|
||||||
declare several start symbols, for instance
|
declare several start symbols, for instance
|
||||||
@@ -435,13 +516,6 @@ XML output for GNU Bison and gcc
|
|||||||
XML output for GNU Bison
|
XML output for GNU Bison
|
||||||
http://yaxx.sourceforge.net/
|
http://yaxx.sourceforge.net/
|
||||||
|
|
||||||
** Counterexample generation
|
|
||||||
https://lists.gnu.org/archive/html/bug-bison/2016-06/msg00000.html
|
|
||||||
http://www.cs.cornell.edu/andru/papers/cupex/
|
|
||||||
|
|
||||||
Andrew Myers and Vincent Imbimbo are working on this item, see
|
|
||||||
https://github.com/akimd/bison/issues/12
|
|
||||||
|
|
||||||
* Coding system independence
|
* Coding system independence
|
||||||
Paul notes:
|
Paul notes:
|
||||||
|
|
||||||
@@ -518,15 +592,9 @@ Foundation, Inc.
|
|||||||
|
|
||||||
This file is part of Bison, the GNU Compiler Compiler.
|
This file is part of Bison, the GNU Compiler Compiler.
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
Permission is granted to copy, distribute and/or modify this document
|
||||||
it under the terms of the GNU General Public License as published by
|
under the terms of the GNU Free Documentation License, Version 1.3 or
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
any later version published by the Free Software Foundation; with no
|
||||||
(at your option) any later version.
|
Invariant Sections, with no Front-Cover Texts, and with no Back-Cover
|
||||||
|
Texts. A copy of the license is included in the "GNU Free
|
||||||
This program is distributed in the hope that it will be useful,
|
Documentation License" file as part of this distribution.
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|||||||
+5
-3
@@ -17,7 +17,7 @@
|
|||||||
|
|
||||||
# gnulib modules used by this package.
|
# gnulib modules used by this package.
|
||||||
gnulib_modules='
|
gnulib_modules='
|
||||||
argmatch array-list assert assure
|
argmatch array-list assert assure attribute
|
||||||
bitsetv
|
bitsetv
|
||||||
calloc-posix close closeout config-h c-strcase
|
calloc-posix close closeout config-h c-strcase
|
||||||
configmake
|
configmake
|
||||||
@@ -30,6 +30,7 @@ gnulib_modules='
|
|||||||
javaexec-script
|
javaexec-script
|
||||||
ldexpl
|
ldexpl
|
||||||
libtextstyle-optional
|
libtextstyle-optional
|
||||||
|
linked-list
|
||||||
malloc-gnu
|
malloc-gnu
|
||||||
mbfile mbswidth
|
mbfile mbswidth
|
||||||
non-recursive-gnulib-prefix-hack
|
non-recursive-gnulib-prefix-hack
|
||||||
@@ -37,14 +38,15 @@ gnulib_modules='
|
|||||||
obstack-printf
|
obstack-printf
|
||||||
perror progname
|
perror progname
|
||||||
quote quotearg
|
quote quotearg
|
||||||
|
rbtreehash-list
|
||||||
readline
|
readline
|
||||||
readme-release
|
readme-release
|
||||||
realloc-posix
|
realloc-posix
|
||||||
relocatable-prog relocatable-script
|
relocatable-prog relocatable-script
|
||||||
rename
|
rename
|
||||||
spawn-pipe stdbool stpcpy strdup-posix strerror strverscmp
|
spawn-pipe stdbool stpcpy stpncpy strdup-posix strerror strverscmp
|
||||||
timevar
|
timevar
|
||||||
unistd unistd-safer unlink unlocked-io
|
unicodeio unistd unistd-safer unlink unlocked-io
|
||||||
update-copyright unsetenv verify
|
update-copyright unsetenv verify
|
||||||
warnings
|
warnings
|
||||||
winsz-ioctl
|
winsz-ioctl
|
||||||
|
|||||||
@@ -73,6 +73,11 @@ def diff_to_re(match):
|
|||||||
is_diff = True
|
is_diff = True
|
||||||
to.append(l)
|
to.append(l)
|
||||||
if is_diff:
|
if is_diff:
|
||||||
|
# Do not run s//SOMETHING/g (with an emty pattern), that won't
|
||||||
|
# work well...
|
||||||
|
if frm == []:
|
||||||
|
trace("no from for", match.group(1))
|
||||||
|
return
|
||||||
frm = "\n".join(frm)
|
frm = "\n".join(frm)
|
||||||
to = "\n".join(to)
|
to = "\n".join(to)
|
||||||
subst[frm] = to
|
subst[frm] = to
|
||||||
@@ -112,4 +117,6 @@ def process(logfile):
|
|||||||
|
|
||||||
for logfile in args.logs:
|
for logfile in args.logs:
|
||||||
trace("FILE:", logfile)
|
trace("FILE:", logfile)
|
||||||
|
if os.path.isdir(logfile):
|
||||||
|
logfile = os.path.join(logfile, 'testsuite.log')
|
||||||
process(logfile)
|
process(logfile)
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ gnulib_dir = $(srcdir)/gnulib
|
|||||||
bootstrap-tools = autoconf,automake,flex,gettext,gnulib
|
bootstrap-tools = autoconf,automake,flex,gettext,gnulib
|
||||||
|
|
||||||
announcement_Cc_ = \
|
announcement_Cc_ = \
|
||||||
[email protected], [email protected], bison-patches@gnu.org, \
|
[email protected], bison-announce@gnu.org, \
|
||||||
[email protected]
|
[email protected]
|
||||||
|
|
||||||
update-copyright: update-b4-copyright update-package-copyright-year
|
update-copyright: update-b4-copyright update-package-copyright-year
|
||||||
|
|||||||
+15
-8
@@ -36,10 +36,8 @@ AC_DEFINE_UNQUOTED([PACKAGE_COPYRIGHT_YEAR], [$PACKAGE_COPYRIGHT_YEAR],
|
|||||||
AC_CONFIG_AUX_DIR([build-aux])
|
AC_CONFIG_AUX_DIR([build-aux])
|
||||||
AC_CONFIG_MACRO_DIR([m4])
|
AC_CONFIG_MACRO_DIR([m4])
|
||||||
|
|
||||||
# We use Automake 1.14's %D% and %C%.
|
|
||||||
#
|
|
||||||
# When we move to Automake 1.16, simplify examples/c/reccalc/local.mk.
|
# When we move to Automake 1.16, simplify examples/c/reccalc/local.mk.
|
||||||
# Our CI runs on Xenial, which has only Automake 1.15.
|
# Our CI build the packages on Bionic, which has only Automake 1.15.
|
||||||
#
|
#
|
||||||
# We want gnits strictness only when rolling a stable release. For
|
# We want gnits strictness only when rolling a stable release. For
|
||||||
# release candidates, we use version strings like 2.4.3_rc1, but gnits
|
# release candidates, we use version strings like 2.4.3_rc1, but gnits
|
||||||
@@ -47,7 +45,7 @@ AC_CONFIG_MACRO_DIR([m4])
|
|||||||
# releases, we want to be able run make dist without being required to
|
# releases, we want to be able run make dist without being required to
|
||||||
# add a bogus NEWS entry. In that case, the version string
|
# add a bogus NEWS entry. In that case, the version string
|
||||||
# automatically contains a dash, which we also let disable gnits.
|
# automatically contains a dash, which we also let disable gnits.
|
||||||
AM_INIT_AUTOMAKE([1.14 dist-xz nostdinc
|
AM_INIT_AUTOMAKE([1.15 dist-lzip dist-xz nostdinc
|
||||||
color-tests parallel-tests
|
color-tests parallel-tests
|
||||||
silent-rules]
|
silent-rules]
|
||||||
m4_bmatch(m4_defn([AC_PACKAGE_VERSION]), [[-_]],
|
m4_bmatch(m4_defn([AC_PACKAGE_VERSION]), [[-_]],
|
||||||
@@ -134,10 +132,12 @@ if test "$enable_gcc_warnings" = yes; then
|
|||||||
-fparse-all-comments -Wdocumentation
|
-fparse-all-comments -Wdocumentation
|
||||||
-Wformat -Wimplicit-fallthrough -Wnull-dereference
|
-Wformat -Wimplicit-fallthrough -Wnull-dereference
|
||||||
-Wno-sign-compare -Wno-tautological-constant-out-of-range-compare
|
-Wno-sign-compare -Wno-tautological-constant-out-of-range-compare
|
||||||
-Wpointer-arith -Wshadow
|
-Wpointer-arith -Wshadow -Wstrict-aliasing
|
||||||
-Wwrite-strings
|
-Wwrite-strings
|
||||||
-wr188 -wr2259 -wr3179'
|
-wr188 -wr2259 -wr3179'
|
||||||
warn_c='-Wbad-function-cast -Wstrict-prototypes'
|
warn_c='-Wbad-function-cast
|
||||||
|
-Wmissing-prototypes
|
||||||
|
-Wstrict-prototypes'
|
||||||
warn_cxx='-Wextra-semi -Wnoexcept -Wold-style-cast -Wundefined-func-template
|
warn_cxx='-Wextra-semi -Wnoexcept -Wold-style-cast -Wundefined-func-template
|
||||||
-Wweak-vtables'
|
-Wweak-vtables'
|
||||||
# Warnings for the test suite only.
|
# Warnings for the test suite only.
|
||||||
@@ -261,9 +261,9 @@ if ! "$LEX_IS_FLEX" || test "X$LEX" = X:; then
|
|||||||
AC_MSG_WARN([bypassing lex because flex is required])
|
AC_MSG_WARN([bypassing lex because flex is required])
|
||||||
LEX=:
|
LEX=:
|
||||||
fi
|
fi
|
||||||
AM_CONDITIONAL([FLEX_WORKS], [$LEX_IS_FLEX])
|
AM_CONDITIONAL([FLEX_WORKS], [$LEX_IS_FLEX && $FLEX_SUPPORTS_HEADER_OPT])
|
||||||
AM_CONDITIONAL([FLEX_CXX_WORKS],
|
AM_CONDITIONAL([FLEX_CXX_WORKS],
|
||||||
[$LEX_IS_FLEX && test $bison_cv_cxx_works = yes])
|
[$LEX_IS_FLEX && $FLEX_SUPPORTS_HEADER_OPT && test $bison_cv_cxx_works = yes])
|
||||||
AC_PROG_YACC
|
AC_PROG_YACC
|
||||||
AC_PROG_RANLIB
|
AC_PROG_RANLIB
|
||||||
AC_PROG_GNU_M4
|
AC_PROG_GNU_M4
|
||||||
@@ -332,6 +332,13 @@ AC_MSG_RESULT([$suppfile])
|
|||||||
# Whether we cannot run the compiled bison.
|
# Whether we cannot run the compiled bison.
|
||||||
AM_CONDITIONAL([CROSS_COMPILING], [test "$cross_compiling" = yes])
|
AM_CONDITIONAL([CROSS_COMPILING], [test "$cross_compiling" = yes])
|
||||||
|
|
||||||
|
# Build bistromathic if we have the lib and both readline/readline.h
|
||||||
|
# and readline/history.h.
|
||||||
|
AM_CONDITIONAL([ENABLE_BISTROMATHIC],
|
||||||
|
[test "$gl_cv_lib_readline" != no &&
|
||||||
|
test "$ac_cv_header_readline_readline_h" = yes &&
|
||||||
|
test "$ac_cv_header_readline_history_h" = yes])
|
||||||
|
|
||||||
AM_MISSING_PROG([AUTOM4TE], [autom4te])
|
AM_MISSING_PROG([AUTOM4TE], [autom4te])
|
||||||
# Needed by tests/atlocal.in.
|
# Needed by tests/atlocal.in.
|
||||||
AC_SUBST([GCC])
|
AC_SUBST([GCC])
|
||||||
|
|||||||
+24
-16
@@ -1,6 +1,6 @@
|
|||||||
This directory contains data needed by Bison.
|
This directory contains data needed by Bison.
|
||||||
|
|
||||||
# Directory content
|
# Directory Content
|
||||||
## Skeletons
|
## Skeletons
|
||||||
Bison skeletons: the general shapes of the different parser kinds, that are
|
Bison skeletons: the general shapes of the different parser kinds, that are
|
||||||
specialized for specific grammars by the bison program.
|
specialized for specific grammars by the bison program.
|
||||||
@@ -48,7 +48,7 @@ various formats.
|
|||||||
- xml2xhtml.xsl
|
- xml2xhtml.xsl
|
||||||
Conversion into XHTML.
|
Conversion into XHTML.
|
||||||
|
|
||||||
# Implementation note about the skeletons
|
# Implementation Notes About the Skeletons
|
||||||
|
|
||||||
"Skeleton" in Bison parlance means "backend": a skeleton is fed by the bison
|
"Skeleton" in Bison parlance means "backend": a skeleton is fed by the bison
|
||||||
executable with LR tables, facts about the symbols, etc. and they generate
|
executable with LR tables, facts about the symbols, etc. and they generate
|
||||||
@@ -84,29 +84,35 @@ field), where field can `has_id`, `id`, etc.: see
|
|||||||
The macro `b4_symbol(NUM, FIELD)` gives access to the following FIELDS:
|
The macro `b4_symbol(NUM, FIELD)` gives access to the following FIELDS:
|
||||||
|
|
||||||
- `has_id`: 0 or 1
|
- `has_id`: 0 or 1
|
||||||
Whether the symbol has an id.
|
Whether the symbol has an `id`.
|
||||||
|
|
||||||
- `id`: string
|
- `id`: string (e.g., `exp`, `NUM`, or `TOK_NUM` with api.token.prefix)
|
||||||
If has_id, the id (prefixed by api.token.prefix if defined), otherwise
|
If `has_id`, the name of the token kind (prefixed by api.token.prefix if
|
||||||
defined as empty. Guaranteed to be usable as a C identifier. This is
|
defined), otherwise empty. Guaranteed to be usable as a C identifier.
|
||||||
used to define the token kind (i.e., the enum used by the return value of
|
This is used to define the token kind (i.e., the enum used by the return
|
||||||
yylex).
|
value of yylex). Should be named `token_kind`.
|
||||||
|
|
||||||
- `tag`: string
|
- `tag`: string
|
||||||
A human representation of the symbol. Can be 'foo', 'foo.id', '"foo"' etc.
|
A human readable representation of the symbol. Can be `'foo'`,
|
||||||
|
`'foo.id'`, `'"foo"'` etc.
|
||||||
|
|
||||||
- `user_number`: integer
|
- `code`: integer
|
||||||
The code associated to the `id`.
|
The token code associated to the token kind `id`.
|
||||||
The external number as used by yylex. Can be ASCII code when a character,
|
The external number as used by yylex. Can be ASCII code when a character,
|
||||||
some number chosen by bison, or some user number in the case of
|
some number chosen by bison, or some user number in the case of `%token
|
||||||
%token FOO <NUM>. Corresponds to yychar in yacc.c.
|
FOO <NUM>`. Corresponds to `yychar` in `yacc.c`.
|
||||||
|
|
||||||
- `is_token`: 0 or 1
|
- `is_token`: 0 or 1
|
||||||
Whether this is a terminal symbol.
|
Whether this is a terminal symbol.
|
||||||
|
|
||||||
|
- `kind_base`: string (e.g., `YYSYMBOL_exp`, `YYSYMBOL_NUM`)
|
||||||
|
The base of the symbol kind, i.e., the enumerator of this symbol (token or
|
||||||
|
nonterminal) which is mapped to its `number`.
|
||||||
|
|
||||||
- `kind`: string
|
- `kind`: string
|
||||||
The symbol kind, i.e., the enumerator of this symbol (token or nonterminal)
|
Same as `kind_base`, but possibly with a prefix in some languages. E.g.,
|
||||||
which is mapping to its `number`.
|
EOF's `kind_base` and `kind` are `YYSYMBOL_YYEOF` in C, but are
|
||||||
|
`S_YYEMPTY` and `symbol_kind::S_YYEMPTY` in C++.
|
||||||
|
|
||||||
- `number`: integer
|
- `number`: integer
|
||||||
The code associated to the `kind`.
|
The code associated to the `kind`.
|
||||||
@@ -173,7 +179,7 @@ The data corresponding to the symbol `#POS`, where the current rule has
|
|||||||
Expansion of `$<TYPE>POS`, where the current rule has `RULE-LENGTH` symbols
|
Expansion of `$<TYPE>POS`, where the current rule has `RULE-LENGTH` symbols
|
||||||
on RHS.
|
on RHS.
|
||||||
|
|
||||||
-----
|
<!--
|
||||||
|
|
||||||
Local Variables:
|
Local Variables:
|
||||||
mode: markdown
|
mode: markdown
|
||||||
@@ -197,3 +203,5 @@ GNU General Public License for more details.
|
|||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
-->
|
||||||
|
|||||||
@@ -30,5 +30,32 @@
|
|||||||
/* "Sections" in traces (--trace). */
|
/* "Sections" in traces (--trace). */
|
||||||
.trace0 { color: green; }
|
.trace0 { color: green; }
|
||||||
|
|
||||||
|
/* Syntax error messages. */
|
||||||
.expected { color: green; }
|
.expected { color: green; }
|
||||||
.unexpected { color: red; }
|
.unexpected { color: red; }
|
||||||
|
|
||||||
|
|
||||||
|
/* Counterexamples. */
|
||||||
|
|
||||||
|
/* Cex: point in rule. */
|
||||||
|
.cex-dot { color: red; }
|
||||||
|
|
||||||
|
/* Cex: coloring various rules. */
|
||||||
|
.cex-0 { color: yellow; }
|
||||||
|
.cex-1 { color: green; }
|
||||||
|
.cex-2 { color: blue; }
|
||||||
|
.cex-3 { color: purple; }
|
||||||
|
.cex-4 { color: violet; }
|
||||||
|
.cex-5 { color: orange; }
|
||||||
|
.cex-6 { color: brown; }
|
||||||
|
.cex-7 { color: mauve; }
|
||||||
|
.cex-8 { color: #013220; } /* Dark green. */
|
||||||
|
.cex-9 { color: #e75480; } /* Dark pink. */
|
||||||
|
.cex-10 { color: cyan; }
|
||||||
|
.cex-11 { color: orange; }
|
||||||
|
|
||||||
|
/* Cex: derivation rewriting steps. */
|
||||||
|
.cex-step { font-style: italic; }
|
||||||
|
|
||||||
|
/* Cex: leaves of a derivation. */
|
||||||
|
.cex-leaf { font-weight: 600; }
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ dist_skeletons_DATA = \
|
|||||||
data/skeletons/lalr1.java \
|
data/skeletons/lalr1.java \
|
||||||
data/skeletons/location.cc \
|
data/skeletons/location.cc \
|
||||||
data/skeletons/stack.hh \
|
data/skeletons/stack.hh \
|
||||||
|
data/skeletons/traceon.m4 \
|
||||||
data/skeletons/variant.hh \
|
data/skeletons/variant.hh \
|
||||||
data/skeletons/yacc.c
|
data/skeletons/yacc.c
|
||||||
|
|
||||||
|
|||||||
+41
-10
@@ -19,6 +19,29 @@
|
|||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# m4_gsub(STRING, RE1, SUBST1, RE2, SUBST2, ...)
|
||||||
|
# ----------------------------------------------
|
||||||
|
# m4 equivalent of
|
||||||
|
#
|
||||||
|
# $_ = STRING;
|
||||||
|
# s/RE1/SUBST1/g;
|
||||||
|
# s/RE2/SUBST2/g;
|
||||||
|
# ...
|
||||||
|
#
|
||||||
|
# Really similar to m4_bpatsubsts, but behaves properly with quotes.
|
||||||
|
# See m4.at's "Generating Comments". Super inelegant, but so far, I
|
||||||
|
# did not find any better solution.
|
||||||
|
m4_define([b4_gsub],
|
||||||
|
[m4_bpatsubst(m4_bpatsubst(m4_bpatsubst([[[[$1]]]],
|
||||||
|
[$2], [$3]),
|
||||||
|
[$4], [$5]),
|
||||||
|
[$6], [$7])])
|
||||||
|
|
||||||
|
# m4_shift2 and m4_shift3 are provided by m4sugar.
|
||||||
|
m4_define([m4_shift4], [m4_shift(m4_shift(m4_shift(m4_shift($@))))])
|
||||||
|
|
||||||
|
|
||||||
## ---------------- ##
|
## ---------------- ##
|
||||||
## Identification. ##
|
## Identification. ##
|
||||||
## ---------------- ##
|
## ---------------- ##
|
||||||
@@ -162,7 +185,7 @@ m4_define([b4_error],
|
|||||||
[b4_cat([[@complain][(]$1[@,]$2[@,]$3[@,]$4[]]dnl
|
[b4_cat([[@complain][(]$1[@,]$2[@,]$3[@,]$4[]]dnl
|
||||||
[m4_if([$#], [4], [],
|
[m4_if([$#], [4], [],
|
||||||
[m4_foreach([b4_arg],
|
[m4_foreach([b4_arg],
|
||||||
m4_dquote(m4_shift(m4_shift(m4_shift(m4_shift($@))))),
|
m4_dquote(m4_shift4($@)),
|
||||||
[[@,]b4_arg])])[@)]])])
|
[[@,]b4_arg])])[@)]])])
|
||||||
|
|
||||||
# b4_warn(FORMAT, [ARG1], [ARG2], ...)
|
# b4_warn(FORMAT, [ARG1], [ARG2], ...)
|
||||||
@@ -415,14 +438,14 @@ m4_define([b4_symbol_token_kind],
|
|||||||
_b4_symbol([$1], [id])])
|
_b4_symbol([$1], [id])])
|
||||||
|
|
||||||
|
|
||||||
# b4_symbol_kind(NUM)
|
# b4_symbol_kind_base(NUM)
|
||||||
# -------------------
|
# ------------------------
|
||||||
# Build the name of the kind of this symbol. It must always exist,
|
# Build the name of the kind of this symbol. It must always exist,
|
||||||
# otherwise some symbols might not be represented in the enum, which
|
# otherwise some symbols might not be represented in the enum, which
|
||||||
# might be compiled into too small a type to contain all the symbol
|
# might be compiled into too small a type to contain all the symbol
|
||||||
# numbers.
|
# numbers.
|
||||||
m4_define([b4_symbol_prefix], [b4_percent_define_get([api.symbol.prefix])])
|
m4_define([b4_symbol_prefix], [b4_percent_define_get([api.symbol.prefix])])
|
||||||
m4_define([b4_symbol_kind],
|
m4_define([b4_symbol_kind_base],
|
||||||
[b4_percent_define_get([api.symbol.prefix])dnl
|
[b4_percent_define_get([api.symbol.prefix])dnl
|
||||||
m4_case([$1],
|
m4_case([$1],
|
||||||
[-2], [[YYEMPTY]],
|
[-2], [[YYEMPTY]],
|
||||||
@@ -435,6 +458,13 @@ m4_case([$1],
|
|||||||
[m4_bpatsubst([$1-][]_b4_symbol([$1], [tag]), [[^a-zA-Z_0-9]+], [_])])])])])
|
[m4_bpatsubst([$1-][]_b4_symbol([$1], [tag]), [[^a-zA-Z_0-9]+], [_])])])])])
|
||||||
|
|
||||||
|
|
||||||
|
# b4_symbol_kind(NUM)
|
||||||
|
# -------------------
|
||||||
|
# Same as b4_symbol_kind, but possibly with a prefix in some
|
||||||
|
# languages. E.g., EOF's kind_base and kind are YYSYMBOL_YYEOF in C,
|
||||||
|
# but are S_YYEMPTY and symbol_kind::S_YYEMPTY in C++.
|
||||||
|
m4_copy([b4_symbol_kind_base], [b4_symbol_kind])
|
||||||
|
|
||||||
# b4_symbol(NUM, FIELD)
|
# b4_symbol(NUM, FIELD)
|
||||||
# ---------------------
|
# ---------------------
|
||||||
# Fetch FIELD of symbol #NUM (or "orig NUM"). Fail if undefined.
|
# Fetch FIELD of symbol #NUM (or "orig NUM"). Fail if undefined.
|
||||||
@@ -442,8 +472,9 @@ m4_case([$1],
|
|||||||
# If FIELD = id, prepend the token prefix.
|
# If FIELD = id, prepend the token prefix.
|
||||||
m4_define([b4_symbol],
|
m4_define([b4_symbol],
|
||||||
[m4_case([$2],
|
[m4_case([$2],
|
||||||
[id], [b4_symbol_token_kind([$1])],
|
[id], [b4_symbol_token_kind([$1])],
|
||||||
[kind], [b4_symbol_kind([$1])],
|
[kind_base], [b4_symbol_kind_base([$1])],
|
||||||
|
[kind], [b4_symbol_kind([$1])],
|
||||||
[_b4_symbol($@)])])
|
[_b4_symbol($@)])])
|
||||||
|
|
||||||
|
|
||||||
@@ -516,7 +547,7 @@ m4_popdef([b4_actions_])dnl
|
|||||||
# easier to use with m4_map, but then, use []dnl to suppress the last
|
# easier to use with m4_map, but then, use []dnl to suppress the last
|
||||||
# one.
|
# one.
|
||||||
m4_define([_b4_symbol_case],
|
m4_define([_b4_symbol_case],
|
||||||
[case b4_symbol([$1], [number]): b4_symbol_tag_comment([$1])])
|
[case b4_symbol([$1], [kind]): b4_symbol_tag_comment([$1])])
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|
||||||
@@ -564,8 +595,8 @@ m4_define([b4_any_token_visible_if],
|
|||||||
m4_define([b4_token_format],
|
m4_define([b4_token_format],
|
||||||
[b4_token_visible_if([$2],
|
[b4_token_visible_if([$2],
|
||||||
[m4_format([[$1]],
|
[m4_format([[$1]],
|
||||||
m4_expand(b4_symbol([$2], [id])),
|
b4_symbol([$2], [id]),
|
||||||
m4_expand(b4_symbol([$2], b4_api_token_raw_if([[number]], [[user_number]]))))])])
|
b4_symbol([$2], b4_api_token_raw_if([[number]], [[code]])))])])
|
||||||
|
|
||||||
|
|
||||||
# b4_last_enum_token
|
# b4_last_enum_token
|
||||||
@@ -727,7 +758,7 @@ m4_define([b4_check_user_names],
|
|||||||
[m4_pushdef([b4_occurrence], b4_occurrence)dnl
|
[m4_pushdef([b4_occurrence], b4_occurrence)dnl
|
||||||
m4_pushdef([b4_user_name], m4_car(b4_occurrence))dnl
|
m4_pushdef([b4_user_name], m4_car(b4_occurrence))dnl
|
||||||
m4_pushdef([b4_start], m4_car(m4_shift(b4_occurrence)))dnl
|
m4_pushdef([b4_start], m4_car(m4_shift(b4_occurrence)))dnl
|
||||||
m4_pushdef([b4_end], m4_shift(m4_shift(b4_occurrence)))dnl
|
m4_pushdef([b4_end], m4_shift2(b4_occurrence))dnl
|
||||||
m4_ifndef($3[(]m4_quote(b4_user_name)[)],
|
m4_ifndef($3[(]m4_quote(b4_user_name)[)],
|
||||||
[b4_complain_at([b4_start], [b4_end],
|
[b4_complain_at([b4_start], [b4_end],
|
||||||
[[%s '%s' is not used]],
|
[[%s '%s' is not used]],
|
||||||
|
|||||||
+46
-10
@@ -105,7 +105,7 @@ b4_percent_define_default([[api.parser.class]], [[parser]])
|
|||||||
#
|
#
|
||||||
# b4_percent_define_default([[api.location.type]], [[location]])
|
# b4_percent_define_default([[api.location.type]], [[location]])
|
||||||
|
|
||||||
b4_percent_define_default([[filename_type]], [[std::string]])
|
b4_percent_define_default([[api.filename.type]], [[const std::string]])
|
||||||
# Make it a warning for those who used betas of Bison 3.0.
|
# 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([[api.namespace]], m4_defn([b4_prefix]))
|
||||||
|
|
||||||
@@ -193,7 +193,7 @@ m4_define([b4_declare_symbol_enum],
|
|||||||
[[enum symbol_kind_type
|
[[enum symbol_kind_type
|
||||||
{
|
{
|
||||||
YYNTOKENS = ]b4_tokens_number[, ///< Number of tokens.
|
YYNTOKENS = ]b4_tokens_number[, ///< Number of tokens.
|
||||||
]b4_symbol_kind([-2])[ = -2,
|
]b4_symbol(-2, kind_base)[ = -2,
|
||||||
]b4_symbol_foreach([ b4_symbol_enum])dnl
|
]b4_symbol_foreach([ b4_symbol_enum])dnl
|
||||||
[ };]])
|
[ };]])
|
||||||
|
|
||||||
@@ -259,14 +259,14 @@ m4_define([b4_public_types_declare],
|
|||||||
struct token
|
struct token
|
||||||
{
|
{
|
||||||
]b4_token_enums[
|
]b4_token_enums[
|
||||||
/// Backward compatibility alias.
|
/// Backward compatibility alias (Bison 3.6).
|
||||||
typedef token_kind_type yytokentype;
|
typedef token_kind_type yytokentype;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Token kind, as returned by yylex.
|
/// Token kind, as returned by yylex.
|
||||||
typedef token::yytokentype token_kind_type;
|
typedef token::yytokentype token_kind_type;
|
||||||
|
|
||||||
/// Backward compatibility alias.
|
/// Backward compatibility alias (Bison 3.6).
|
||||||
typedef token_kind_type token_type;
|
typedef token_kind_type token_type;
|
||||||
|
|
||||||
/// Symbol kinds.
|
/// Symbol kinds.
|
||||||
@@ -357,7 +357,30 @@ m4_define([b4_symbol_type_define],
|
|||||||
Base::clear ();
|
Base::clear ();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Backward compatibility.
|
]b4_parse_error_bmatch(
|
||||||
|
[custom\|detailed],
|
||||||
|
[[ /// The user-facing name of this symbol.
|
||||||
|
const char *name () const YY_NOEXCEPT
|
||||||
|
{
|
||||||
|
return ]b4_parser_class[::symbol_name (this->kind ());
|
||||||
|
}]],
|
||||||
|
[simple],
|
||||||
|
[[#if ]b4_api_PREFIX[DEBUG || ]b4_token_table_flag[
|
||||||
|
/// The user-facing name of this symbol.
|
||||||
|
const char *name () const YY_NOEXCEPT
|
||||||
|
{
|
||||||
|
return ]b4_parser_class[::symbol_name (this->kind ());
|
||||||
|
}
|
||||||
|
#endif // #if ]b4_api_PREFIX[DEBUG || ]b4_token_table_flag[
|
||||||
|
]],
|
||||||
|
[verbose],
|
||||||
|
[[ /// The user-facing name of this symbol.
|
||||||
|
std::string name () const YY_NOEXCEPT
|
||||||
|
{
|
||||||
|
return ]b4_parser_class[::symbol_name (this->kind ());
|
||||||
|
}]])[
|
||||||
|
|
||||||
|
/// Backward compatibility (Bison 3.6).
|
||||||
symbol_kind_type type_get () const YY_NOEXCEPT;
|
symbol_kind_type type_get () const YY_NOEXCEPT;
|
||||||
|
|
||||||
/// Whether empty.
|
/// Whether empty.
|
||||||
@@ -409,11 +432,17 @@ m4_define([b4_symbol_type_define],
|
|||||||
/// \a empty when empty.
|
/// \a empty when empty.
|
||||||
symbol_kind_type kind () const YY_NOEXCEPT;
|
symbol_kind_type kind () const YY_NOEXCEPT;
|
||||||
|
|
||||||
|
/// Backward compatibility (Bison 3.6).
|
||||||
|
symbol_kind_type type_get () const YY_NOEXCEPT;
|
||||||
|
|
||||||
/// The symbol kind.
|
/// The symbol kind.
|
||||||
/// \a ]b4_symbol_prefix[YYEMPTY when empty.
|
/// \a ]b4_symbol_prefix[YYEMPTY when empty.
|
||||||
symbol_kind_type kind_;
|
symbol_kind_type kind_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Backward compatibility for a private implementation detail (Bison 3.6).
|
||||||
|
typedef by_kind by_type;
|
||||||
|
|
||||||
/// "External" symbols: returned by the scanner.
|
/// "External" symbols: returned by the scanner.
|
||||||
struct symbol_type : basic_symbol<by_kind>
|
struct symbol_type : basic_symbol<by_kind>
|
||||||
{]b4_variant_if([[
|
{]b4_variant_if([[
|
||||||
@@ -478,7 +507,7 @@ m4_define([b4_public_types_define],
|
|||||||
bool
|
bool
|
||||||
]b4_parser_class[::basic_symbol<Base>::empty () const YY_NOEXCEPT
|
]b4_parser_class[::basic_symbol<Base>::empty () const YY_NOEXCEPT
|
||||||
{
|
{
|
||||||
return this->kind () == symbol_kind::]b4_symbol_prefix[YYEMPTY;
|
return this->kind () == ]b4_symbol(-2, kind)[;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Base>
|
template <typename Base>
|
||||||
@@ -494,7 +523,7 @@ m4_define([b4_public_types_define],
|
|||||||
|
|
||||||
// by_kind.
|
// by_kind.
|
||||||
]b4_inline([$1])b4_parser_class[::by_kind::by_kind ()
|
]b4_inline([$1])b4_parser_class[::by_kind::by_kind ()
|
||||||
: kind_ (symbol_kind::]b4_symbol_prefix[YYEMPTY)
|
: kind_ (]b4_symbol(-2, kind)[)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
#if 201103L <= YY_CPLUSPLUS
|
#if 201103L <= YY_CPLUSPLUS
|
||||||
@@ -516,7 +545,7 @@ m4_define([b4_public_types_define],
|
|||||||
]b4_inline([$1])[void
|
]b4_inline([$1])[void
|
||||||
]b4_parser_class[::by_kind::clear ()
|
]b4_parser_class[::by_kind::clear ()
|
||||||
{
|
{
|
||||||
kind_ = symbol_kind::]b4_symbol_prefix[YYEMPTY;
|
kind_ = ]b4_symbol(-2, kind)[;
|
||||||
}
|
}
|
||||||
|
|
||||||
]b4_inline([$1])[void
|
]b4_inline([$1])[void
|
||||||
@@ -531,6 +560,12 @@ m4_define([b4_public_types_define],
|
|||||||
{
|
{
|
||||||
return kind_;
|
return kind_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
]b4_inline([$1])[]b4_parser_class[::symbol_kind_type
|
||||||
|
]b4_parser_class[::by_kind::type_get () const YY_NOEXCEPT
|
||||||
|
{
|
||||||
|
return this->kind ();
|
||||||
|
}
|
||||||
]])
|
]])
|
||||||
|
|
||||||
|
|
||||||
@@ -559,11 +594,12 @@ m4_define([b4_yytranslate_define],
|
|||||||
{
|
{
|
||||||
]b4_translate[
|
]b4_translate[
|
||||||
};
|
};
|
||||||
const int user_token_number_max_ = ]b4_user_token_number_max[;
|
// Last valid token kind.
|
||||||
|
const int code_max = ]b4_code_max[;
|
||||||
|
|
||||||
if (t <= 0)
|
if (t <= 0)
|
||||||
return symbol_kind::]b4_symbol_prefix[YYEOF;
|
return symbol_kind::]b4_symbol_prefix[YYEOF;
|
||||||
else if (t <= user_token_number_max_)
|
else if (t <= code_max)
|
||||||
return YY_CAST (symbol_kind_type, translate_table[t]);
|
return YY_CAST (symbol_kind_type, translate_table[t]);
|
||||||
else
|
else
|
||||||
return symbol_kind::]b4_symbol_prefix[YYUNDEF;]])[
|
return symbol_kind::]b4_symbol_prefix[YYUNDEF;]])[
|
||||||
|
|||||||
@@ -17,15 +17,21 @@
|
|||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
|
||||||
# _b4_comment(TEXT, OPEN, CONTINUE, END)
|
# _b4_comment(TEXT, OPEN, CONTINUE, END)
|
||||||
# --------------------------------------
|
# --------------------------------------
|
||||||
# Put TEXT in comment. Avoid trailing spaces: don't indent empty lines.
|
# Put TEXT in comment. Avoid trailing spaces: don't indent empty lines.
|
||||||
# Avoid adding indentation to the first line, as the indentation comes
|
# Avoid adding indentation to the first line, as the indentation comes
|
||||||
# from OPEN. That's why we don't patsubst([$1], [^\(.\)], [ \1]).
|
# from OPEN. That's why we don't patsubst([$1], [^\(.\)], [ \1]).
|
||||||
|
# Turn "*/" in TEXT into "* /" so that we don't unexpectedly close
|
||||||
|
# the comments before its end.
|
||||||
#
|
#
|
||||||
# Prefix all the output lines with PREFIX.
|
# Prefix all the output lines with PREFIX.
|
||||||
m4_define([_b4_comment],
|
m4_define([_b4_comment],
|
||||||
[$2[]m4_bpatsubst(m4_expand([[$1]]), [
|
[$2[]b4_gsub(m4_expand([$1]),
|
||||||
|
[[*]/], [*\\/],
|
||||||
|
[/[*]], [/\\*],
|
||||||
|
[
|
||||||
\(.\)], [
|
\(.\)], [
|
||||||
$3\1])$4])
|
$3\1])$4])
|
||||||
|
|
||||||
|
|||||||
+66
-10
@@ -205,7 +205,11 @@ m4_define([b4_c99_int_type],
|
|||||||
# Define private types suitable for holding small integers in C99 or later.
|
# Define private types suitable for holding small integers in C99 or later.
|
||||||
m4_define([b4_c99_int_type_define],
|
m4_define([b4_c99_int_type_define],
|
||||||
[m4_copy_force([b4_c99_int_type], [b4_int_type])dnl
|
[m4_copy_force([b4_c99_int_type], [b4_int_type])dnl
|
||||||
[/* On compilers that do not define __PTRDIFF_MAX__ etc., make sure
|
[#ifdef short
|
||||||
|
# undef short
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* On compilers that do not define __PTRDIFF_MAX__ etc., make sure
|
||||||
<limits.h> and (if available) <stdint.h> are included
|
<limits.h> and (if available) <stdint.h> are included
|
||||||
so that the code can choose integer types of a good width. */
|
so that the code can choose integer types of a good width. */
|
||||||
|
|
||||||
@@ -261,6 +265,50 @@ typedef int yytype_uint16;
|
|||||||
#endif]])
|
#endif]])
|
||||||
|
|
||||||
|
|
||||||
|
# b4_sizes_types_define
|
||||||
|
# ---------------------
|
||||||
|
# Define YYPTRDIFF_T/YYPTRDIFF_MAXIMUM, YYSIZE_T/YYSIZE_MAXIMUM,
|
||||||
|
# and YYSIZEOF.
|
||||||
|
m4_define([b4_sizes_types_define],
|
||||||
|
[[#ifndef YYPTRDIFF_T
|
||||||
|
# if defined __PTRDIFF_TYPE__ && defined __PTRDIFF_MAX__
|
||||||
|
# define YYPTRDIFF_T __PTRDIFF_TYPE__
|
||||||
|
# define YYPTRDIFF_MAXIMUM __PTRDIFF_MAX__
|
||||||
|
# elif defined PTRDIFF_MAX
|
||||||
|
# ifndef ptrdiff_t
|
||||||
|
# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
|
||||||
|
# endif
|
||||||
|
# define YYPTRDIFF_T ptrdiff_t
|
||||||
|
# define YYPTRDIFF_MAXIMUM PTRDIFF_MAX
|
||||||
|
# else
|
||||||
|
# define YYPTRDIFF_T long
|
||||||
|
# define YYPTRDIFF_MAXIMUM LONG_MAX
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef YYSIZE_T
|
||||||
|
# ifdef __SIZE_TYPE__
|
||||||
|
# define YYSIZE_T __SIZE_TYPE__
|
||||||
|
# elif defined size_t
|
||||||
|
# define YYSIZE_T size_t
|
||||||
|
# elif defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__
|
||||||
|
# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
|
||||||
|
# define YYSIZE_T size_t
|
||||||
|
# else
|
||||||
|
# define YYSIZE_T unsigned
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define YYSIZE_MAXIMUM \
|
||||||
|
YY_CAST (YYPTRDIFF_T, \
|
||||||
|
(YYPTRDIFF_MAXIMUM < YY_CAST (YYSIZE_T, -1) \
|
||||||
|
? YYPTRDIFF_MAXIMUM \
|
||||||
|
: YY_CAST (YYSIZE_T, -1)))
|
||||||
|
|
||||||
|
#define YYSIZEOF(X) YY_CAST (YYPTRDIFF_T, sizeof (X))
|
||||||
|
]])
|
||||||
|
|
||||||
|
|
||||||
# b4_int_type_for(NAME)
|
# b4_int_type_for(NAME)
|
||||||
# ---------------------
|
# ---------------------
|
||||||
# Return a narrow int type able to handle numbers ranging from
|
# Return a narrow int type able to handle numbers ranging from
|
||||||
@@ -307,15 +355,23 @@ m4_define([b4_attribute_define],
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
]m4_bmatch([$1], [\bnoreturn\b], [[/* The _Noreturn keyword of C11. */
|
]m4_bmatch([$1], [\bnoreturn\b], [[/* The _Noreturn keyword of C11. */
|
||||||
]dnl This is an exact copy of lib/_Noreturn.h.
|
]dnl This is close to lib/_Noreturn.h, except that we do enable
|
||||||
|
dnl the use of [[noreturn]], because _Noreturn is used in places
|
||||||
|
dnl where [[noreturn]] works in C++. We need this in particular
|
||||||
|
dnl because of glr.cc which compiles code from glr.c in C++.
|
||||||
|
dnl And the C++ compiler chokes on _Noreturn. Also, we do not
|
||||||
|
dnl use C' _Noreturn in C++, to avoid -Wc11-extensions warnings.
|
||||||
[#ifndef _Noreturn
|
[#ifndef _Noreturn
|
||||||
# if (defined __cplusplus \
|
# if (defined __cplusplus \
|
||||||
&& ((201103 <= __cplusplus && !(__GNUC__ == 4 && __GNUC_MINOR__ == 7)) \
|
&& ((201103 <= __cplusplus && !(__GNUC__ == 4 && __GNUC_MINOR__ == 7)) \
|
||||||
|| (defined _MSC_VER && 1900 <= _MSC_VER)))
|
|| (defined _MSC_VER && 1900 <= _MSC_VER)))
|
||||||
# define _Noreturn [[noreturn]]
|
# define _Noreturn [[noreturn]]
|
||||||
# elif ((!defined __cplusplus || defined __clang__) \
|
# elif (!defined __cplusplus \
|
||||||
&& (201112 <= (defined __STDC_VERSION__ ? __STDC_VERSION__ : 0) \
|
&& (201112 <= (defined __STDC_VERSION__ ? __STDC_VERSION__ : 0) \
|
||||||
|| 4 < __GNUC__ + (7 <= __GNUC_MINOR__)))
|
|| 4 < __GNUC__ + (7 <= __GNUC_MINOR__) \
|
||||||
|
|| (defined __apple_build_version__ \
|
||||||
|
? 6000000 <= __apple_build_version__ \
|
||||||
|
: 3 < __clang_major__ + (5 <= __clang_minor__))))
|
||||||
/* _Noreturn works as-is. */
|
/* _Noreturn works as-is. */
|
||||||
# elif 2 < __GNUC__ + (8 <= __GNUC_MINOR__) || 0x5110 <= __SUNPRO_C
|
# elif 2 < __GNUC__ + (8 <= __GNUC_MINOR__) || 0x5110 <= __SUNPRO_C
|
||||||
# define _Noreturn __attribute__ ((__noreturn__))
|
# define _Noreturn __attribute__ ((__noreturn__))
|
||||||
@@ -467,7 +523,7 @@ m4_define([b4_token_enum],
|
|||||||
[m4_format([ %-30s %s],
|
[m4_format([ %-30s %s],
|
||||||
m4_format([[%s = %s%s%s]],
|
m4_format([[%s = %s%s%s]],
|
||||||
b4_symbol([$1], [id]),
|
b4_symbol([$1], [id]),
|
||||||
b4_symbol([$1], b4_api_token_raw_if([[number]], [[user_number]])),
|
b4_symbol([$1], b4_api_token_raw_if([[number]], [[code]])),
|
||||||
m4_if([$1], b4_last_enum_token, [], [[,]])),
|
m4_if([$1], b4_last_enum_token, [], [[,]])),
|
||||||
[b4_symbol_tag_comment([$1])])])])
|
[b4_symbol_tag_comment([$1])])])])
|
||||||
|
|
||||||
@@ -516,7 +572,7 @@ m4_define([b4_symbol_translate],
|
|||||||
m4_define([b4_symbol_enum],
|
m4_define([b4_symbol_enum],
|
||||||
[m4_format([ %-40s %s],
|
[m4_format([ %-40s %s],
|
||||||
m4_format([[%s = %s%s%s]],
|
m4_format([[%s = %s%s%s]],
|
||||||
b4_symbol([$1], [kind]),
|
b4_symbol([$1], [kind_base]),
|
||||||
[$1],
|
[$1],
|
||||||
m4_if([$1], b4_last_symbol, [], [[,]])),
|
m4_if([$1], b4_last_symbol, [], [[,]])),
|
||||||
[b4_symbol_tag_comment([$1])])])
|
[b4_symbol_tag_comment([$1])])])
|
||||||
@@ -531,7 +587,7 @@ m4_define([b4_declare_symbol_enum],
|
|||||||
[[/* Symbol kind. */
|
[[/* Symbol kind. */
|
||||||
enum yysymbol_kind_t
|
enum yysymbol_kind_t
|
||||||
{
|
{
|
||||||
]b4_symbol_kind([-2])[ = -2,
|
]b4_symbol([-2], kind_base)[ = -2,
|
||||||
]b4_symbol_foreach([b4_symbol_enum])dnl
|
]b4_symbol_foreach([b4_symbol_enum])dnl
|
||||||
[};
|
[};
|
||||||
typedef enum yysymbol_kind_t yysymbol_kind_t;
|
typedef enum yysymbol_kind_t yysymbol_kind_t;
|
||||||
@@ -610,10 +666,10 @@ m4_define([b4_sync_start], [[#]line $1 $2])
|
|||||||
## User actions. ##
|
## User actions. ##
|
||||||
## -------------- ##
|
## -------------- ##
|
||||||
|
|
||||||
# b4_case(LABEL, STATEMENTS)
|
# b4_case(LABEL, STATEMENTS, [COMMENTS])
|
||||||
# --------------------------
|
# --------------------------------------
|
||||||
m4_define([b4_case],
|
m4_define([b4_case],
|
||||||
[ case $1:
|
[ case $1:m4_ifval([$3], [ b4_comment([$3])])
|
||||||
$2
|
$2
|
||||||
b4_syncline([@oline@], [@ofile@])dnl
|
b4_syncline([@oline@], [@ofile@])dnl
|
||||||
break;])
|
break;])
|
||||||
|
|||||||
+12
-5
@@ -152,6 +152,8 @@ private static immutable b4_int_type_for([$2])[[]] yy$1_ =
|
|||||||
## Token kinds. ##
|
## Token kinds. ##
|
||||||
## ------------- ##
|
## ------------- ##
|
||||||
|
|
||||||
|
m4_define([b4_symbol(-2, id)], [[YYEMPTY]])
|
||||||
|
|
||||||
# b4_token_enum(TOKEN-NAME, TOKEN-NUMBER)
|
# b4_token_enum(TOKEN-NAME, TOKEN-NUMBER)
|
||||||
# ---------------------------------------
|
# ---------------------------------------
|
||||||
# Output the definition of this token as an enum.
|
# Output the definition of this token as an enum.
|
||||||
@@ -178,6 +180,11 @@ b4_symbol_foreach([b4_token_enum])dnl
|
|||||||
|
|
||||||
b4_percent_define_default([[api.symbol.prefix]], [[S_]])
|
b4_percent_define_default([[api.symbol.prefix]], [[S_]])
|
||||||
|
|
||||||
|
# b4_symbol_kind(NUM)
|
||||||
|
# -------------------
|
||||||
|
m4_define([b4_symbol_kind],
|
||||||
|
[SymbolKind.b4_symbol_kind_base($@)])
|
||||||
|
|
||||||
|
|
||||||
# b4_symbol_enum(SYMBOL-NUM)
|
# b4_symbol_enum(SYMBOL-NUM)
|
||||||
# --------------------------
|
# --------------------------
|
||||||
@@ -185,7 +192,7 @@ b4_percent_define_default([[api.symbol.prefix]], [[S_]])
|
|||||||
m4_define([b4_symbol_enum],
|
m4_define([b4_symbol_enum],
|
||||||
[m4_format([ %-30s %s],
|
[m4_format([ %-30s %s],
|
||||||
m4_format([[%s = %s,]],
|
m4_format([[%s = %s,]],
|
||||||
b4_symbol([$1], [kind]),
|
b4_symbol([$1], [kind_base]),
|
||||||
[$1]),
|
[$1]),
|
||||||
[b4_symbol_tag_comment([$1])])])
|
[b4_symbol_tag_comment([$1])])])
|
||||||
|
|
||||||
@@ -199,16 +206,16 @@ m4_define([b4_declare_symbol_enum],
|
|||||||
[[ /* Symbol kinds. */
|
[[ /* Symbol kinds. */
|
||||||
public enum SymbolKind
|
public enum SymbolKind
|
||||||
{
|
{
|
||||||
]b4_symbol_kind([-2])[ = -2, /* No symbol. */
|
]b4_symbol(-2, kind_base)[ = -2, /* No symbol. */
|
||||||
]b4_symbol_foreach([b4_symbol_enum])dnl
|
]b4_symbol_foreach([b4_symbol_enum])dnl
|
||||||
[ };
|
[ };
|
||||||
]])])
|
]])])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# b4-case(ID, CODE)
|
# b4-case(ID, CODE, [COMMENTS])
|
||||||
# -----------------
|
# -----------------------------
|
||||||
m4_define([b4_case], [ case $1:
|
m4_define([b4_case], [ case $1:m4_ifval([$3], [ b4_comment([$3])])
|
||||||
$2
|
$2
|
||||||
break;])
|
break;])
|
||||||
|
|
||||||
|
|||||||
+62
-59
@@ -189,9 +189,9 @@ b4_glr_cc_if([],
|
|||||||
[b4_output_begin([b4_spec_header_file])
|
[b4_output_begin([b4_spec_header_file])
|
||||||
b4_copyright([Skeleton interface for Bison GLR parsers in C],
|
b4_copyright([Skeleton interface for Bison GLR parsers in C],
|
||||||
[2002-2015, 2018-2020])[
|
[2002-2015, 2018-2020])[
|
||||||
]b4_cpp_guard_open([b4_spec_header_file])[
|
]b4_cpp_guard_open([b4_spec_mapped_header_file])[
|
||||||
]b4_shared_declarations[
|
]b4_shared_declarations[
|
||||||
]b4_cpp_guard_close([b4_spec_header_file])[
|
]b4_cpp_guard_close([b4_spec_mapped_header_file])[
|
||||||
]b4_output_end[
|
]b4_output_end[
|
||||||
]])])
|
]])])
|
||||||
|
|
||||||
@@ -230,7 +230,9 @@ b4_copyright([Skeleton implementation for Bison GLR parsers in C],
|
|||||||
|
|
||||||
]b4_defines_if([[#include "@basename(]b4_spec_header_file[@)"]],
|
]b4_defines_if([[#include "@basename(]b4_spec_header_file[@)"]],
|
||||||
[b4_shared_declarations])[
|
[b4_shared_declarations])[
|
||||||
]b4_declare_symbol_enum[
|
|
||||||
|
]b4_glr_cc_if([b4_glr_cc_setup],
|
||||||
|
[b4_declare_symbol_enum])[
|
||||||
|
|
||||||
/* Default (constant) value used for initialization for null
|
/* Default (constant) value used for initialization for null
|
||||||
right-hand sides. Unlike the standard yacc.c template, here we set
|
right-hand sides. Unlike the standard yacc.c template, here we set
|
||||||
@@ -249,6 +251,7 @@ static YYLTYPE yyloc_default][]b4_yyloc_default;])[
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
]b4_c99_int_type_define[
|
]b4_c99_int_type_define[
|
||||||
|
]b4_sizes_types_define[
|
||||||
|
|
||||||
#ifndef YY_
|
#ifndef YY_
|
||||||
# if defined YYENABLE_NLS && YYENABLE_NLS
|
# if defined YYENABLE_NLS && YYENABLE_NLS
|
||||||
@@ -277,9 +280,6 @@ static YYLTYPE yyloc_default][]b4_yyloc_default;])[
|
|||||||
# define YYREALLOC realloc
|
# define YYREALLOC realloc
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define YYSIZEMAX \
|
|
||||||
(PTRDIFF_MAX < SIZE_MAX ? PTRDIFF_MAX : YY_CAST (ptrdiff_t, SIZE_MAX))
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
typedef bool yybool;
|
typedef bool yybool;
|
||||||
# define yytrue true
|
# define yytrue true
|
||||||
@@ -333,8 +333,8 @@ static YYLTYPE yyloc_default][]b4_yyloc_default;])[
|
|||||||
accessed by $0, $-1, etc., in any rule. */
|
accessed by $0, $-1, etc., in any rule. */
|
||||||
#define YYMAXLEFT ]b4_max_left_semantic_context[
|
#define YYMAXLEFT ]b4_max_left_semantic_context[
|
||||||
|
|
||||||
/* YYMAXUTOK -- Last valid token number (for yychar). */
|
/* YYMAXUTOK -- Last valid token kind. */
|
||||||
#define YYMAXUTOK ]b4_user_token_number_max[
|
#define YYMAXUTOK ]b4_code_max[
|
||||||
|
|
||||||
/* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM
|
/* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM
|
||||||
as returned by yylex, with out-of-bounds checking. */
|
as returned by yylex, with out-of-bounds checking. */
|
||||||
@@ -507,7 +507,7 @@ struct yyGLRState {
|
|||||||
/** Preceding state in this stack */
|
/** Preceding state in this stack */
|
||||||
yyGLRState* yypred;
|
yyGLRState* yypred;
|
||||||
/** Source position of the last token produced by my symbol */
|
/** Source position of the last token produced by my symbol */
|
||||||
ptrdiff_t yyposn;
|
YYPTRDIFF_T yyposn;
|
||||||
union {
|
union {
|
||||||
/** First in a chain of alternative reductions producing the
|
/** First in a chain of alternative reductions producing the
|
||||||
* nonterminal corresponding to this state, threaded through
|
* nonterminal corresponding to this state, threaded through
|
||||||
@@ -527,8 +527,8 @@ struct yyGLRStateSet {
|
|||||||
* operation, yylookaheadNeeds[0] is not maintained since it would merely
|
* operation, yylookaheadNeeds[0] is not maintained since it would merely
|
||||||
* duplicate yychar != ]b4_symbol(-2, id)[. */
|
* duplicate yychar != ]b4_symbol(-2, id)[. */
|
||||||
yybool* yylookaheadNeeds;
|
yybool* yylookaheadNeeds;
|
||||||
ptrdiff_t yysize;
|
YYPTRDIFF_T yysize;
|
||||||
ptrdiff_t yycapacity;
|
YYPTRDIFF_T yycapacity;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct yySemanticOption {
|
struct yySemanticOption {
|
||||||
@@ -568,7 +568,7 @@ struct yyGLRStack {
|
|||||||
YYJMP_BUF yyexception_buffer;
|
YYJMP_BUF yyexception_buffer;
|
||||||
yyGLRStackItem* yyitems;
|
yyGLRStackItem* yyitems;
|
||||||
yyGLRStackItem* yynextFree;
|
yyGLRStackItem* yynextFree;
|
||||||
ptrdiff_t yyspaceLeft;
|
YYPTRDIFF_T yyspaceLeft;
|
||||||
yyGLRState* yysplitPoint;
|
yyGLRState* yysplitPoint;
|
||||||
yyGLRState* yylastDeleted;
|
yyGLRState* yylastDeleted;
|
||||||
yyGLRStateSet yytops;
|
yyGLRStateSet yytops;
|
||||||
@@ -680,7 +680,7 @@ yysymbol_name (yysymbol_kind_t yysymbol)
|
|||||||
multiple parsers can coexist. */
|
multiple parsers can coexist. */
|
||||||
int yydebug;
|
int yydebug;
|
||||||
|
|
||||||
static void yypstack (yyGLRStack* yystackp, ptrdiff_t yyk)
|
static void yypstack (yyGLRStack* yystackp, YYPTRDIFF_T yyk)
|
||||||
YY_ATTRIBUTE_UNUSED;
|
YY_ATTRIBUTE_UNUSED;
|
||||||
static void yypdumpstack (yyGLRStack* yystackp)
|
static void yypdumpstack (yyGLRStack* yystackp)
|
||||||
YY_ATTRIBUTE_UNUSED;
|
YY_ATTRIBUTE_UNUSED;
|
||||||
@@ -696,7 +696,7 @@ static void yypdumpstack (yyGLRStack* yystackp)
|
|||||||
[simple],
|
[simple],
|
||||||
[[]],
|
[[]],
|
||||||
[[#ifndef yystrlen
|
[[#ifndef yystrlen
|
||||||
# define yystrlen(S) (YY_CAST (ptrdiff_t, strlen (S)))
|
# define yystrlen(S) (YY_CAST (YYPTRDIFF_T, strlen (S)))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
]b4_parse_error_bmatch(
|
]b4_parse_error_bmatch(
|
||||||
@@ -731,12 +731,12 @@ yystpcpy (char *yydest, const char *yysrc)
|
|||||||
backslash-backslash). YYSTR is taken from yytname. If YYRES is
|
backslash-backslash). YYSTR is taken from yytname. If YYRES is
|
||||||
null, do not copy; instead, return the length of what the result
|
null, do not copy; instead, return the length of what the result
|
||||||
would have been. */
|
would have been. */
|
||||||
static ptrdiff_t
|
static YYPTRDIFF_T
|
||||||
yytnamerr (char *yyres, const char *yystr)
|
yytnamerr (char *yyres, const char *yystr)
|
||||||
{
|
{
|
||||||
if (*yystr == '"')
|
if (*yystr == '"')
|
||||||
{
|
{
|
||||||
ptrdiff_t yyn = 0;
|
YYPTRDIFF_T yyn = 0;
|
||||||
char const *yyp = yystr;
|
char const *yyp = yystr;
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
@@ -1104,7 +1104,7 @@ yynewGLRStackItem (yyGLRStack* yystackp, yybool yyisState)
|
|||||||
* alternative actions for YYSTATE. Assumes that YYRHS comes from
|
* alternative actions for YYSTATE. Assumes that YYRHS comes from
|
||||||
* stack #YYK of *YYSTACKP. */
|
* stack #YYK of *YYSTACKP. */
|
||||||
static void
|
static void
|
||||||
yyaddDeferredAction (yyGLRStack* yystackp, ptrdiff_t yyk, yyGLRState* yystate,
|
yyaddDeferredAction (yyGLRStack* yystackp, YYPTRDIFF_T yyk, yyGLRState* yystate,
|
||||||
yyGLRState* yyrhs, yyRuleNum yyrule)
|
yyGLRState* yyrhs, yyRuleNum yyrule)
|
||||||
{
|
{
|
||||||
yySemanticOption* yynewOption =
|
yySemanticOption* yynewOption =
|
||||||
@@ -1136,14 +1136,14 @@ yyinitStateSet (yyGLRStateSet* yyset)
|
|||||||
yyset->yycapacity = 16;
|
yyset->yycapacity = 16;
|
||||||
yyset->yystates
|
yyset->yystates
|
||||||
= YY_CAST (yyGLRState**,
|
= YY_CAST (yyGLRState**,
|
||||||
YYMALLOC (YY_CAST (size_t, yyset->yycapacity)
|
YYMALLOC (YY_CAST (YYSIZE_T, yyset->yycapacity)
|
||||||
* sizeof yyset->yystates[0]));
|
* sizeof yyset->yystates[0]));
|
||||||
if (! yyset->yystates)
|
if (! yyset->yystates)
|
||||||
return yyfalse;
|
return yyfalse;
|
||||||
yyset->yystates[0] = YY_NULLPTR;
|
yyset->yystates[0] = YY_NULLPTR;
|
||||||
yyset->yylookaheadNeeds
|
yyset->yylookaheadNeeds
|
||||||
= YY_CAST (yybool*,
|
= YY_CAST (yybool*,
|
||||||
YYMALLOC (YY_CAST (size_t, yyset->yycapacity)
|
YYMALLOC (YY_CAST (YYSIZE_T, yyset->yycapacity)
|
||||||
* sizeof yyset->yylookaheadNeeds[0]));
|
* sizeof yyset->yylookaheadNeeds[0]));
|
||||||
if (! yyset->yylookaheadNeeds)
|
if (! yyset->yylookaheadNeeds)
|
||||||
{
|
{
|
||||||
@@ -1152,7 +1152,7 @@ yyinitStateSet (yyGLRStateSet* yyset)
|
|||||||
}
|
}
|
||||||
memset (yyset->yylookaheadNeeds,
|
memset (yyset->yylookaheadNeeds,
|
||||||
0,
|
0,
|
||||||
YY_CAST (size_t, yyset->yycapacity) * sizeof yyset->yylookaheadNeeds[0]);
|
YY_CAST (YYSIZE_T, yyset->yycapacity) * sizeof yyset->yylookaheadNeeds[0]);
|
||||||
return yytrue;
|
return yytrue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1165,14 +1165,14 @@ static void yyfreeStateSet (yyGLRStateSet* yyset)
|
|||||||
/** Initialize *YYSTACKP to a single empty stack, with total maximum
|
/** Initialize *YYSTACKP to a single empty stack, with total maximum
|
||||||
* capacity for all stacks of YYSIZE. */
|
* capacity for all stacks of YYSIZE. */
|
||||||
static yybool
|
static yybool
|
||||||
yyinitGLRStack (yyGLRStack* yystackp, ptrdiff_t yysize)
|
yyinitGLRStack (yyGLRStack* yystackp, YYPTRDIFF_T yysize)
|
||||||
{
|
{
|
||||||
yystackp->yyerrState = 0;
|
yystackp->yyerrState = 0;
|
||||||
yynerrs = 0;
|
yynerrs = 0;
|
||||||
yystackp->yyspaceLeft = yysize;
|
yystackp->yyspaceLeft = yysize;
|
||||||
yystackp->yyitems
|
yystackp->yyitems
|
||||||
= YY_CAST (yyGLRStackItem*,
|
= YY_CAST (yyGLRStackItem*,
|
||||||
YYMALLOC (YY_CAST (size_t, yysize)
|
YYMALLOC (YY_CAST (YYSIZE_T, yysize)
|
||||||
* sizeof yystackp->yynextFree[0]));
|
* sizeof yystackp->yynextFree[0]));
|
||||||
if (!yystackp->yyitems)
|
if (!yystackp->yyitems)
|
||||||
return yyfalse;
|
return yyfalse;
|
||||||
@@ -1198,9 +1198,9 @@ yyexpandGLRStack (yyGLRStack* yystackp)
|
|||||||
{
|
{
|
||||||
yyGLRStackItem* yynewItems;
|
yyGLRStackItem* yynewItems;
|
||||||
yyGLRStackItem* yyp0, *yyp1;
|
yyGLRStackItem* yyp0, *yyp1;
|
||||||
ptrdiff_t yynewSize;
|
YYPTRDIFF_T yynewSize;
|
||||||
ptrdiff_t yyn;
|
YYPTRDIFF_T yyn;
|
||||||
ptrdiff_t yysize = yystackp->yynextFree - yystackp->yyitems;
|
YYPTRDIFF_T yysize = yystackp->yynextFree - yystackp->yyitems;
|
||||||
if (YYMAXDEPTH - YYHEADROOM < yysize)
|
if (YYMAXDEPTH - YYHEADROOM < yysize)
|
||||||
yyMemoryExhausted (yystackp);
|
yyMemoryExhausted (yystackp);
|
||||||
yynewSize = 2*yysize;
|
yynewSize = 2*yysize;
|
||||||
@@ -1208,7 +1208,7 @@ yyexpandGLRStack (yyGLRStack* yystackp)
|
|||||||
yynewSize = YYMAXDEPTH;
|
yynewSize = YYMAXDEPTH;
|
||||||
yynewItems
|
yynewItems
|
||||||
= YY_CAST (yyGLRStackItem*,
|
= YY_CAST (yyGLRStackItem*,
|
||||||
YYMALLOC (YY_CAST (size_t, yynewSize)
|
YYMALLOC (YY_CAST (YYSIZE_T, yynewSize)
|
||||||
* sizeof yynewItems[0]));
|
* sizeof yynewItems[0]));
|
||||||
if (! yynewItems)
|
if (! yynewItems)
|
||||||
yyMemoryExhausted (yystackp);
|
yyMemoryExhausted (yystackp);
|
||||||
@@ -1273,7 +1273,7 @@ yyupdateSplit (yyGLRStack* yystackp, yyGLRState* yys)
|
|||||||
|
|
||||||
/** Invalidate stack #YYK in *YYSTACKP. */
|
/** Invalidate stack #YYK in *YYSTACKP. */
|
||||||
static inline void
|
static inline void
|
||||||
yymarkStackDeleted (yyGLRStack* yystackp, ptrdiff_t yyk)
|
yymarkStackDeleted (yyGLRStack* yystackp, YYPTRDIFF_T yyk)
|
||||||
{
|
{
|
||||||
if (yystackp->yytops.yystates[yyk] != YY_NULLPTR)
|
if (yystackp->yytops.yystates[yyk] != YY_NULLPTR)
|
||||||
yystackp->yylastDeleted = yystackp->yytops.yystates[yyk];
|
yystackp->yylastDeleted = yystackp->yytops.yystates[yyk];
|
||||||
@@ -1297,7 +1297,7 @@ yyundeleteLastStack (yyGLRStack* yystackp)
|
|||||||
static inline void
|
static inline void
|
||||||
yyremoveDeletes (yyGLRStack* yystackp)
|
yyremoveDeletes (yyGLRStack* yystackp)
|
||||||
{
|
{
|
||||||
ptrdiff_t yyi, yyj;
|
YYPTRDIFF_T yyi, yyj;
|
||||||
yyi = yyj = 0;
|
yyi = yyj = 0;
|
||||||
while (yyj < yystackp->yytops.yysize)
|
while (yyj < yystackp->yytops.yysize)
|
||||||
{
|
{
|
||||||
@@ -1330,8 +1330,8 @@ yyremoveDeletes (yyGLRStack* yystackp)
|
|||||||
* state YYLRSTATE, at input position YYPOSN, with (resolved) semantic
|
* state YYLRSTATE, at input position YYPOSN, with (resolved) semantic
|
||||||
* value *YYVALP and source location *YYLOCP. */
|
* value *YYVALP and source location *YYLOCP. */
|
||||||
static inline void
|
static inline void
|
||||||
yyglrShift (yyGLRStack* yystackp, ptrdiff_t yyk, yy_state_t yylrState,
|
yyglrShift (yyGLRStack* yystackp, YYPTRDIFF_T yyk, yy_state_t yylrState,
|
||||||
ptrdiff_t yyposn,
|
YYPTRDIFF_T yyposn,
|
||||||
YYSTYPE* yyvalp]b4_locations_if([, YYLTYPE* yylocp])[)
|
YYSTYPE* yyvalp]b4_locations_if([, YYLTYPE* yylocp])[)
|
||||||
{
|
{
|
||||||
yyGLRState* yynewState = &yynewGLRStackItem (yystackp, yytrue)->yystate;
|
yyGLRState* yynewState = &yynewGLRStackItem (yystackp, yytrue)->yystate;
|
||||||
@@ -1351,8 +1351,8 @@ yyglrShift (yyGLRStack* yystackp, ptrdiff_t yyk, yy_state_t yylrState,
|
|||||||
* state YYLRSTATE, at input position YYPOSN, with the (unresolved)
|
* state YYLRSTATE, at input position YYPOSN, with the (unresolved)
|
||||||
* semantic value of YYRHS under the action for YYRULE. */
|
* semantic value of YYRHS under the action for YYRULE. */
|
||||||
static inline void
|
static inline void
|
||||||
yyglrShiftDefer (yyGLRStack* yystackp, ptrdiff_t yyk, yy_state_t yylrState,
|
yyglrShiftDefer (yyGLRStack* yystackp, YYPTRDIFF_T yyk, yy_state_t yylrState,
|
||||||
ptrdiff_t yyposn, yyGLRState* yyrhs, yyRuleNum yyrule)
|
YYPTRDIFF_T yyposn, yyGLRState* yyrhs, yyRuleNum yyrule)
|
||||||
{
|
{
|
||||||
yyGLRState* yynewState = &yynewGLRStackItem (yystackp, yytrue)->yystate;
|
yyGLRState* yynewState = &yynewGLRStackItem (yystackp, yytrue)->yystate;
|
||||||
YY_ASSERT (yynewState->yyisState);
|
YY_ASSERT (yynewState->yyisState);
|
||||||
@@ -1382,7 +1382,7 @@ yyglrShiftDefer (yyGLRStack* yystackp, ptrdiff_t yyk, yy_state_t yylrState,
|
|||||||
`----------------------------------------------------------------------*/
|
`----------------------------------------------------------------------*/
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
yy_reduce_print (yybool yynormal, yyGLRStackItem* yyvsp, ptrdiff_t yyk,
|
yy_reduce_print (yybool yynormal, yyGLRStackItem* yyvsp, YYPTRDIFF_T yyk,
|
||||||
yyRuleNum yyrule]b4_user_formals[)
|
yyRuleNum yyrule]b4_user_formals[)
|
||||||
{
|
{
|
||||||
int yynrhs = yyrhsLength (yyrule);]b4_locations_if([
|
int yynrhs = yyrhsLength (yyrule);]b4_locations_if([
|
||||||
@@ -1415,7 +1415,7 @@ yy_reduce_print (yybool yynormal, yyGLRStackItem* yyvsp, ptrdiff_t yyk,
|
|||||||
* and *YYLOCP to the computed location (if any). Return value is as
|
* and *YYLOCP to the computed location (if any). Return value is as
|
||||||
* for userAction. */
|
* for userAction. */
|
||||||
static inline YYRESULTTAG
|
static inline YYRESULTTAG
|
||||||
yydoAction (yyGLRStack* yystackp, ptrdiff_t yyk, yyRuleNum yyrule,
|
yydoAction (yyGLRStack* yystackp, YYPTRDIFF_T yyk, yyRuleNum yyrule,
|
||||||
YYSTYPE* yyvalp]b4_locuser_formals[)
|
YYSTYPE* yyvalp]b4_locuser_formals[)
|
||||||
{
|
{
|
||||||
int yynrhs = yyrhsLength (yyrule);
|
int yynrhs = yyrhsLength (yyrule);
|
||||||
@@ -1467,10 +1467,10 @@ yydoAction (yyGLRStack* yystackp, ptrdiff_t yyk, yyRuleNum yyrule,
|
|||||||
* added to the options for the existing state's semantic value.
|
* added to the options for the existing state's semantic value.
|
||||||
*/
|
*/
|
||||||
static inline YYRESULTTAG
|
static inline YYRESULTTAG
|
||||||
yyglrReduce (yyGLRStack* yystackp, ptrdiff_t yyk, yyRuleNum yyrule,
|
yyglrReduce (yyGLRStack* yystackp, YYPTRDIFF_T yyk, yyRuleNum yyrule,
|
||||||
yybool yyforceEval]b4_user_formals[)
|
yybool yyforceEval]b4_user_formals[)
|
||||||
{
|
{
|
||||||
ptrdiff_t yyposn = yystackp->yytops.yystates[yyk]->yyposn;
|
YYPTRDIFF_T yyposn = yystackp->yytops.yystates[yyk]->yyposn;
|
||||||
|
|
||||||
if (yyforceEval || yystackp->yysplitPoint == YY_NULLPTR)
|
if (yyforceEval || yystackp->yysplitPoint == YY_NULLPTR)
|
||||||
{
|
{
|
||||||
@@ -1492,7 +1492,7 @@ yyglrReduce (yyGLRStack* yystackp, ptrdiff_t yyk, yyRuleNum yyrule,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ptrdiff_t yyi;
|
YYPTRDIFF_T yyi;
|
||||||
int yyn;
|
int yyn;
|
||||||
yyGLRState* yys, *yys0 = yystackp->yytops.yystates[yyk];
|
yyGLRState* yys, *yys0 = yystackp->yytops.yystates[yyk];
|
||||||
yy_state_t yynewLRState;
|
yy_state_t yynewLRState;
|
||||||
@@ -1534,8 +1534,8 @@ yyglrReduce (yyGLRStack* yystackp, ptrdiff_t yyk, yyRuleNum yyrule,
|
|||||||
return yyok;
|
return yyok;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ptrdiff_t
|
static YYPTRDIFF_T
|
||||||
yysplitStack (yyGLRStack* yystackp, ptrdiff_t yyk)
|
yysplitStack (yyGLRStack* yystackp, YYPTRDIFF_T yyk)
|
||||||
{
|
{
|
||||||
if (yystackp->yysplitPoint == YY_NULLPTR)
|
if (yystackp->yysplitPoint == YY_NULLPTR)
|
||||||
{
|
{
|
||||||
@@ -1544,8 +1544,8 @@ yysplitStack (yyGLRStack* yystackp, ptrdiff_t yyk)
|
|||||||
}
|
}
|
||||||
if (yystackp->yytops.yycapacity <= yystackp->yytops.yysize)
|
if (yystackp->yytops.yycapacity <= yystackp->yytops.yysize)
|
||||||
{
|
{
|
||||||
ptrdiff_t state_size = sizeof yystackp->yytops.yystates[0];
|
YYPTRDIFF_T state_size = YYSIZEOF (yystackp->yytops.yystates[0]);
|
||||||
ptrdiff_t half_max_capacity = YYSIZEMAX / 2 / state_size;
|
YYPTRDIFF_T half_max_capacity = YYSIZE_MAXIMUM / 2 / state_size;
|
||||||
if (half_max_capacity < yystackp->yytops.yycapacity)
|
if (half_max_capacity < yystackp->yytops.yycapacity)
|
||||||
yyMemoryExhausted (yystackp);
|
yyMemoryExhausted (yystackp);
|
||||||
yystackp->yytops.yycapacity *= 2;
|
yystackp->yytops.yycapacity *= 2;
|
||||||
@@ -1554,7 +1554,7 @@ yysplitStack (yyGLRStack* yystackp, ptrdiff_t yyk)
|
|||||||
yyGLRState** yynewStates
|
yyGLRState** yynewStates
|
||||||
= YY_CAST (yyGLRState**,
|
= YY_CAST (yyGLRState**,
|
||||||
YYREALLOC (yystackp->yytops.yystates,
|
YYREALLOC (yystackp->yytops.yystates,
|
||||||
(YY_CAST (size_t, yystackp->yytops.yycapacity)
|
(YY_CAST (YYSIZE_T, yystackp->yytops.yycapacity)
|
||||||
* sizeof yynewStates[0])));
|
* sizeof yynewStates[0])));
|
||||||
if (yynewStates == YY_NULLPTR)
|
if (yynewStates == YY_NULLPTR)
|
||||||
yyMemoryExhausted (yystackp);
|
yyMemoryExhausted (yystackp);
|
||||||
@@ -1565,7 +1565,7 @@ yysplitStack (yyGLRStack* yystackp, ptrdiff_t yyk)
|
|||||||
yybool* yynewLookaheadNeeds
|
yybool* yynewLookaheadNeeds
|
||||||
= YY_CAST (yybool*,
|
= YY_CAST (yybool*,
|
||||||
YYREALLOC (yystackp->yytops.yylookaheadNeeds,
|
YYREALLOC (yystackp->yytops.yylookaheadNeeds,
|
||||||
(YY_CAST (size_t, yystackp->yytops.yycapacity)
|
(YY_CAST (YYSIZE_T, yystackp->yytops.yycapacity)
|
||||||
* sizeof yynewLookaheadNeeds[0])));
|
* sizeof yynewLookaheadNeeds[0])));
|
||||||
if (yynewLookaheadNeeds == YY_NULLPTR)
|
if (yynewLookaheadNeeds == YY_NULLPTR)
|
||||||
yyMemoryExhausted (yystackp);
|
yyMemoryExhausted (yystackp);
|
||||||
@@ -1996,8 +1996,8 @@ yycompressStack (yyGLRStack* yystackp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static YYRESULTTAG
|
static YYRESULTTAG
|
||||||
yyprocessOneStack (yyGLRStack* yystackp, ptrdiff_t yyk,
|
yyprocessOneStack (yyGLRStack* yystackp, YYPTRDIFF_T yyk,
|
||||||
ptrdiff_t yyposn]b4_pure_formals[)
|
YYPTRDIFF_T yyposn]b4_pure_formals[)
|
||||||
{
|
{
|
||||||
while (yystackp->yytops.yystates[yyk] != YY_NULLPTR)
|
while (yystackp->yytops.yystates[yyk] != YY_NULLPTR)
|
||||||
{
|
{
|
||||||
@@ -2040,7 +2040,7 @@ yyprocessOneStack (yyGLRStack* yystackp, ptrdiff_t yyk,
|
|||||||
for (/* nothing */; *yyconflicts; yyconflicts += 1)
|
for (/* nothing */; *yyconflicts; yyconflicts += 1)
|
||||||
{
|
{
|
||||||
YYRESULTTAG yyflag;
|
YYRESULTTAG yyflag;
|
||||||
ptrdiff_t yynewStack = yysplitStack (yystackp, yyk);
|
YYPTRDIFF_T yynewStack = yysplitStack (yystackp, yyk);
|
||||||
YY_DPRINTF ((stderr, "Splitting off stack %ld from %ld.\n",
|
YY_DPRINTF ((stderr, "Splitting off stack %ld from %ld.\n",
|
||||||
YY_CAST (long, yynewStack), YY_CAST (long, yyk)));
|
YY_CAST (long, yynewStack), YY_CAST (long, yyk)));
|
||||||
yyflag = yyglrReduce (yystackp, yynewStack,
|
yyflag = yyglrReduce (yystackp, yynewStack,
|
||||||
@@ -2121,6 +2121,8 @@ yypcontext_expected_tokens (const yyGLRStack* yystackp,
|
|||||||
yyarg[yycount++] = YY_CAST (yysymbol_kind_t, yyx);
|
yyarg[yycount++] = YY_CAST (yysymbol_kind_t, yyx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (yyarg && yycount == 0 && 0 < yyargn)
|
||||||
|
yyarg[0] = ]b4_symbol(-2, kind)[;
|
||||||
return yycount;
|
return yycount;
|
||||||
}]])[
|
}]])[
|
||||||
|
|
||||||
@@ -2228,7 +2230,7 @@ yyreportSyntaxError (yyGLRStack* yystackp]b4_user_formals[)
|
|||||||
one per "expected"). */
|
one per "expected"). */
|
||||||
yysymbol_kind_t yyarg[YYARGS_MAX];
|
yysymbol_kind_t yyarg[YYARGS_MAX];
|
||||||
/* Cumulated lengths of YYARG. */
|
/* Cumulated lengths of YYARG. */
|
||||||
ptrdiff_t yysize = 0;
|
YYPTRDIFF_T yysize = 0;
|
||||||
|
|
||||||
/* Actual size of YYARG. */
|
/* Actual size of YYARG. */
|
||||||
int yycount
|
int yycount
|
||||||
@@ -2259,11 +2261,11 @@ yyreportSyntaxError (yyGLRStack* yystackp]b4_user_formals[)
|
|||||||
int yyi;
|
int yyi;
|
||||||
for (yyi = 0; yyi < yycount; ++yyi)
|
for (yyi = 0; yyi < yycount; ++yyi)
|
||||||
{
|
{
|
||||||
ptrdiff_t yysz
|
YYPTRDIFF_T yysz
|
||||||
= ]b4_parse_error_case(
|
= ]b4_parse_error_case(
|
||||||
[verbose], [[yytnamerr (YY_NULLPTR, yytname[yyarg[yyi]])]],
|
[verbose], [[yytnamerr (YY_NULLPTR, yytname[yyarg[yyi]])]],
|
||||||
[[yystrlen (yysymbol_name (yyarg[yyi]))]]);[
|
[[yystrlen (yysymbol_name (yyarg[yyi]))]]);[
|
||||||
if (YYSIZEMAX - yysize < yysz)
|
if (YYSIZE_MAXIMUM - yysize < yysz)
|
||||||
yysize_overflow = yytrue;
|
yysize_overflow = yytrue;
|
||||||
else
|
else
|
||||||
yysize += yysz;
|
yysize += yysz;
|
||||||
@@ -2271,7 +2273,7 @@ yyreportSyntaxError (yyGLRStack* yystackp]b4_user_formals[)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!yysize_overflow)
|
if (!yysize_overflow)
|
||||||
yymsg = YY_CAST (char *, YYMALLOC (YY_CAST (size_t, yysize)));
|
yymsg = YY_CAST (char *, YYMALLOC (YY_CAST (YYSIZE_T, yysize)));
|
||||||
|
|
||||||
if (yymsg)
|
if (yymsg)
|
||||||
{
|
{
|
||||||
@@ -2348,7 +2350,7 @@ yyrecoverSyntaxError (yyGLRStack* yystackp]b4_user_formals[)
|
|||||||
|
|
||||||
/* Reduce to one stack. */
|
/* Reduce to one stack. */
|
||||||
{
|
{
|
||||||
ptrdiff_t yyk;
|
YYPTRDIFF_T yyk;
|
||||||
for (yyk = 0; yyk < yystackp->yytops.yysize; yyk += 1)
|
for (yyk = 0; yyk < yystackp->yytops.yysize; yyk += 1)
|
||||||
if (yystackp->yytops.yystates[yyk] != YY_NULLPTR)
|
if (yystackp->yytops.yystates[yyk] != YY_NULLPTR)
|
||||||
break;
|
break;
|
||||||
@@ -2423,7 +2425,7 @@ yyparse (]m4_ifset([b4_parse_param], [b4_formals(b4_parse_param)], [void])[)
|
|||||||
int yyresult;
|
int yyresult;
|
||||||
yyGLRStack yystack;
|
yyGLRStack yystack;
|
||||||
yyGLRStack* const yystackp = &yystack;
|
yyGLRStack* const yystackp = &yystack;
|
||||||
ptrdiff_t yyposn;
|
YYPTRDIFF_T yyposn;
|
||||||
|
|
||||||
YY_DPRINTF ((stderr, "Starting parse\n"));
|
YY_DPRINTF ((stderr, "Starting parse\n"));
|
||||||
|
|
||||||
@@ -2505,7 +2507,7 @@ b4_dollar_popdef])[]dnl
|
|||||||
while (yytrue)
|
while (yytrue)
|
||||||
{
|
{
|
||||||
yysymbol_kind_t yytoken_to_shift;
|
yysymbol_kind_t yytoken_to_shift;
|
||||||
ptrdiff_t yys;
|
YYPTRDIFF_T yys;
|
||||||
|
|
||||||
for (yys = 0; yys < yystack.yytops.yysize; yys += 1)
|
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(-2, id)[;
|
||||||
@@ -2612,8 +2614,8 @@ b4_dollar_popdef])[]dnl
|
|||||||
yyGLRState** yystates = yystack.yytops.yystates;
|
yyGLRState** yystates = yystack.yytops.yystates;
|
||||||
if (yystates)
|
if (yystates)
|
||||||
{
|
{
|
||||||
ptrdiff_t yysize = yystack.yytops.yysize;
|
YYPTRDIFF_T yysize = yystack.yytops.yysize;
|
||||||
ptrdiff_t yyk;
|
YYPTRDIFF_T yyk;
|
||||||
for (yyk = 0; yyk < yysize; yyk += 1)
|
for (yyk = 0; yyk < yysize; yyk += 1)
|
||||||
if (yystates[yyk])
|
if (yystates[yyk])
|
||||||
{
|
{
|
||||||
@@ -2660,7 +2662,7 @@ yypstates (yyGLRState* yyst)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
yypstack (yyGLRStack* yystackp, ptrdiff_t yyk)
|
yypstack (yyGLRStack* yystackp, YYPTRDIFF_T yyk)
|
||||||
{
|
{
|
||||||
yypstates (yystackp->yytops.yystates[yyk]);
|
yypstates (yystackp->yytops.yystates[yyk]);
|
||||||
}
|
}
|
||||||
@@ -2705,7 +2707,7 @@ yypdumpstack (yyGLRStack* yystackp)
|
|||||||
|
|
||||||
YY_FPRINTF ((stderr, "Tops:"));
|
YY_FPRINTF ((stderr, "Tops:"));
|
||||||
{
|
{
|
||||||
ptrdiff_t yyi;
|
YYPTRDIFF_T yyi;
|
||||||
for (yyi = 0; yyi < yystackp->yytops.yysize; yyi += 1)
|
for (yyi = 0; yyi < yystackp->yytops.yysize; yyi += 1)
|
||||||
YY_FPRINTF ((stderr, "%ld: %ld; ", YY_CAST (long, yyi),
|
YY_FPRINTF ((stderr, "%ld: %ld; ", YY_CAST (long, yyi),
|
||||||
YYINDEX (yystackp->yytops.yystates[yyi])));
|
YYINDEX (yystackp->yytops.yystates[yyi])));
|
||||||
@@ -2731,7 +2733,8 @@ m4_if(b4_prefix, [yy], [],
|
|||||||
#define yynerrs ]b4_prefix[nerrs]b4_locations_if([[
|
#define yynerrs ]b4_prefix[nerrs]b4_locations_if([[
|
||||||
#define yylloc ]b4_prefix[lloc]])])[
|
#define yylloc ]b4_prefix[lloc]])])[
|
||||||
|
|
||||||
]m4_ifdef([b4_pre_epilogue], [b4_pre_epilogue])[]dnl This is a hack for glr.cc. To remove when we have a better glr.cc.
|
]b4_glr_cc_if([b4_glr_cc_pre_epilogue
|
||||||
b4_percent_code_get([[epilogue]])[]dnl
|
b4_glr_cc_cleanup])[
|
||||||
|
]b4_percent_code_get([[epilogue]])[]dnl
|
||||||
b4_epilogue[]dnl
|
b4_epilogue[]dnl
|
||||||
b4_output_end
|
b4_output_end
|
||||||
|
|||||||
+57
-44
@@ -66,12 +66,6 @@ m4_defn([b4_parse_param]))],
|
|||||||
[[b4_namespace_ref::b4_parser_class[& yyparser], [[yyparser]]]])
|
[[b4_namespace_ref::b4_parser_class[& yyparser], [[yyparser]]]])
|
||||||
])
|
])
|
||||||
|
|
||||||
# b4_declare_symbol_enum
|
|
||||||
# ----------------------
|
|
||||||
m4_append([b4_declare_symbol_enum],
|
|
||||||
[[typedef symbol_kind_type yysymbol_kind_t;
|
|
||||||
]])
|
|
||||||
|
|
||||||
|
|
||||||
# b4_yy_symbol_print_define
|
# b4_yy_symbol_print_define
|
||||||
# -------------------------
|
# -------------------------
|
||||||
@@ -105,15 +99,9 @@ yyerror (]b4_locations_if([[const ]b4_namespace_ref::b4_parser_class[::location_
|
|||||||
]])[]m4_ifset([b4_parse_param], [b4_formals(b4_parse_param),
|
]])[]m4_ifset([b4_parse_param], [b4_formals(b4_parse_param),
|
||||||
])[const char* msg);]])[
|
])[const char* msg);]])[
|
||||||
|
|
||||||
]b4_percent_define_flag_if([[global_tokens_and_yystype]], [],
|
# Inserted before the epilogue to define implementations (yyerror, parser member
|
||||||
[m4_define([b4_pre_epilogue],
|
|
||||||
[[/* The user is using the C++ token kind, not the C one. */
|
|
||||||
#undef ]b4_symbol(0, [id])
|
|
||||||
])])[
|
|
||||||
|
|
||||||
# Hijack the epilogue to define implementations (yyerror, parser member
|
|
||||||
# functions etc.).
|
# functions etc.).
|
||||||
]m4_append([b4_epilogue],
|
]m4_define([b4_glr_cc_pre_epilogue],
|
||||||
[b4_syncline([@oline@], [@ofile@])dnl
|
[b4_syncline([@oline@], [@ofile@])dnl
|
||||||
[
|
[
|
||||||
/*------------------.
|
/*------------------.
|
||||||
@@ -222,6 +210,57 @@ b4_namespace_close[]dnl
|
|||||||
])
|
])
|
||||||
|
|
||||||
|
|
||||||
|
m4_define([b4_define_symbol_kind],
|
||||||
|
[m4_format([#define %-15s %s],
|
||||||
|
b4_symbol($][1, kind_base),
|
||||||
|
b4_namespace_ref[::]b4_parser_class[::symbol_kind::]b4_symbol($1, kind_base))
|
||||||
|
])
|
||||||
|
|
||||||
|
# b4_glr_cc_setup
|
||||||
|
# ---------------
|
||||||
|
# Setup redirections for glr.c: Map the names used in c.m4 to the ones used
|
||||||
|
# in c++.m4.
|
||||||
|
m4_define([b4_glr_cc_setup],
|
||||||
|
[[#undef ]b4_symbol(-2, [id])[
|
||||||
|
#define ]b4_symbol(-2, [id])[ ]b4_namespace_ref[::]b4_parser_class[::token::]b4_symbol(-2, [id])[
|
||||||
|
#undef ]b4_symbol(0, [id])[
|
||||||
|
#define ]b4_symbol(0, [id])[ ]b4_namespace_ref[::]b4_parser_class[::token::]b4_symbol(0, [id])[
|
||||||
|
#undef ]b4_symbol(1, [id])[
|
||||||
|
#define ]b4_symbol(1, [id])[ ]b4_namespace_ref[::]b4_parser_class[::token::]b4_symbol(1, [id])[
|
||||||
|
|
||||||
|
#ifndef ]b4_api_PREFIX[STYPE
|
||||||
|
# define ]b4_api_PREFIX[STYPE ]b4_namespace_ref[::]b4_parser_class[::semantic_type
|
||||||
|
#endif
|
||||||
|
#ifndef ]b4_api_PREFIX[LTYPE
|
||||||
|
# define ]b4_api_PREFIX[LTYPE ]b4_namespace_ref[::]b4_parser_class[::location_type
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef ]b4_namespace_ref[::]b4_parser_class[::symbol_kind_type yysymbol_kind_t;
|
||||||
|
|
||||||
|
// Expose C++ symbol kinds to C.
|
||||||
|
]b4_define_symbol_kind(-2)dnl
|
||||||
|
b4_symbol_foreach([b4_define_symbol_kind])])[
|
||||||
|
]])
|
||||||
|
|
||||||
|
|
||||||
|
m4_define([b4_undef_symbol_kind],
|
||||||
|
[[#undef ]b4_symbol($1, kind_base)[
|
||||||
|
]])
|
||||||
|
|
||||||
|
|
||||||
|
# b4_glr_cc_cleanup
|
||||||
|
# -----------------
|
||||||
|
# Remove redirections for glr.c.
|
||||||
|
m4_define([b4_glr_cc_cleanup],
|
||||||
|
[[#undef ]b4_symbol(-2, [id])[
|
||||||
|
#undef ]b4_symbol(0, [id])[
|
||||||
|
#undef ]b4_symbol(1, [id])[
|
||||||
|
|
||||||
|
]b4_undef_symbol_kind(-2)dnl
|
||||||
|
b4_symbol_foreach([b4_undef_symbol_kind])dnl
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
# b4_shared_declarations(hh|cc)
|
# 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 --defines, $1 = hh)
|
||||||
@@ -333,48 +372,22 @@ b4_percent_code_get([[requires]])[
|
|||||||
]b4_parse_param_vars[
|
]b4_parse_param_vars[
|
||||||
};
|
};
|
||||||
|
|
||||||
]dnl Redirections for glr.c.
|
|
||||||
b4_percent_define_flag_if([[global_tokens_and_yystype]],
|
|
||||||
[b4_token_defines
|
|
||||||
])[
|
|
||||||
]b4_namespace_close[
|
]b4_namespace_close[
|
||||||
|
|
||||||
]dnl Map the name used in c.m4 to the one used in c++.m4.
|
|
||||||
[#undef ]b4_symbol(-2, [id])[
|
|
||||||
#define ]b4_symbol(-2, [id])[ ]b4_namespace_ref[::]b4_parser_class[::token::]b4_symbol(-2, [id])[
|
|
||||||
#undef ]b4_symbol(0, [id])[
|
|
||||||
#define ]b4_symbol(0, [id])[ ]b4_namespace_ref[::]b4_parser_class[::token::]b4_symbol(0, [id])[
|
|
||||||
#undef ]b4_symbol(1, [id])[
|
|
||||||
#define ]b4_symbol(1, [id])[ ]b4_namespace_ref[::]b4_parser_class[::token::]b4_symbol(1, [id])[
|
|
||||||
|
|
||||||
#ifndef ]b4_api_PREFIX[STYPE
|
|
||||||
# define ]b4_api_PREFIX[STYPE ]b4_namespace_ref[::]b4_parser_class[::semantic_type
|
|
||||||
#endif
|
|
||||||
#ifndef ]b4_api_PREFIX[LTYPE
|
|
||||||
# define ]b4_api_PREFIX[LTYPE ]b4_namespace_ref[::]b4_parser_class[::location_type
|
|
||||||
#endif
|
|
||||||
|
|
||||||
]m4_define([b4_declare_symbol_enum],
|
|
||||||
[[typedef ]b4_namespace_ref[::]b4_parser_class[::symbol_kind_type yysymbol_kind_t;
|
|
||||||
#define ]b4_symbol_prefix[YYEMPTY ]b4_namespace_ref[::]b4_parser_class[::symbol_kind::]b4_symbol_prefix[YYEMPTY
|
|
||||||
#define ]b4_symbol_prefix[YYerror ]b4_namespace_ref[::]b4_parser_class[::symbol_kind::]b4_symbol_prefix[YYerror
|
|
||||||
#define ]b4_symbol_prefix[YYEOF ]b4_namespace_ref[::]b4_parser_class[::symbol_kind::]b4_symbol_prefix[YYEOF
|
|
||||||
#define ]b4_symbol_prefix[YYUNDEF ]b4_namespace_ref[::]b4_parser_class[::symbol_kind::]b4_symbol_prefix[YYUNDEF
|
|
||||||
]])[
|
|
||||||
]b4_percent_code_get([[provides]])[
|
]b4_percent_code_get([[provides]])[
|
||||||
]m4_popdef([b4_parse_param])dnl
|
]m4_popdef([b4_parse_param])dnl
|
||||||
])
|
])[
|
||||||
|
|
||||||
b4_defines_if(
|
]b4_defines_if(
|
||||||
[b4_output_begin([b4_spec_header_file])
|
[b4_output_begin([b4_spec_header_file])
|
||||||
b4_copyright([Skeleton interface for Bison GLR parsers in C++],
|
b4_copyright([Skeleton interface for Bison GLR parsers in C++],
|
||||||
[2002-2015, 2018-2020])[
|
[2002-2015, 2018-2020])[
|
||||||
// C++ GLR parser skeleton written by Akim Demaille.
|
// C++ GLR parser skeleton written by Akim Demaille.
|
||||||
|
|
||||||
]b4_disclaimer[
|
]b4_disclaimer[
|
||||||
]b4_cpp_guard_open([b4_spec_header_file])[
|
]b4_cpp_guard_open([b4_spec_mapped_header_file])[
|
||||||
]b4_shared_declarations[
|
]b4_shared_declarations[
|
||||||
]b4_cpp_guard_close([b4_spec_header_file])[
|
]b4_cpp_guard_close([b4_spec_mapped_header_file])[
|
||||||
]b4_output_end])
|
]b4_output_end])
|
||||||
|
|
||||||
# Let glr.c (and b4_shared_declarations) believe that the user
|
# Let glr.c (and b4_shared_declarations) believe that the user
|
||||||
|
|||||||
+12
-5
@@ -143,7 +143,7 @@ m4_define([b4_token_enum],
|
|||||||
]],
|
]],
|
||||||
b4_symbol([$1], [tag]),
|
b4_symbol([$1], [tag]),
|
||||||
b4_symbol([$1], [id]),
|
b4_symbol([$1], [id]),
|
||||||
b4_symbol([$1], b4_api_token_raw_if([[number]], [[user_number]])))])])
|
b4_symbol([$1], b4_api_token_raw_if([[number]], [[code]])))])])
|
||||||
|
|
||||||
|
|
||||||
# b4_token_enums
|
# b4_token_enums
|
||||||
@@ -159,13 +159,20 @@ b4_symbol_foreach([b4_token_enum])])])
|
|||||||
## Symbol kinds. ##
|
## Symbol kinds. ##
|
||||||
## -------------- ##
|
## -------------- ##
|
||||||
|
|
||||||
|
|
||||||
|
# b4_symbol_kind(NUM)
|
||||||
|
# -------------------
|
||||||
|
m4_define([b4_symbol_kind],
|
||||||
|
[SymbolKind.b4_symbol_kind_base($@)])
|
||||||
|
|
||||||
|
|
||||||
# b4_symbol_enum(SYMBOL-NUM)
|
# b4_symbol_enum(SYMBOL-NUM)
|
||||||
# --------------------------
|
# --------------------------
|
||||||
# Output the definition of this symbol as an enum.
|
# Output the definition of this symbol as an enum.
|
||||||
m4_define([b4_symbol_enum],
|
m4_define([b4_symbol_enum],
|
||||||
[m4_format([ %-30s %s],
|
[m4_format([ %-30s %s],
|
||||||
m4_format([[%s(%s)%s]],
|
m4_format([[%s(%s)%s]],
|
||||||
b4_symbol([$1], [kind]),
|
b4_symbol([$1], [kind_base]),
|
||||||
[$1],
|
[$1],
|
||||||
m4_if([$1], b4_last_symbol, [[;]], [[,]])),
|
m4_if([$1], b4_last_symbol, [[;]], [[,]])),
|
||||||
[b4_symbol_tag_comment([$1])])])
|
[b4_symbol_tag_comment([$1])])])
|
||||||
@@ -255,11 +262,11 @@ m4_define([b4_declare_symbol_enum],
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
# b4_case(ID, CODE)
|
# b4_case(ID, CODE, [COMMENTS])
|
||||||
# -----------------
|
# -----------------------------
|
||||||
# We need to fool Java's stupid unreachable code detection.
|
# We need to fool Java's stupid unreachable code detection.
|
||||||
m4_define([b4_case],
|
m4_define([b4_case],
|
||||||
[ case $1:
|
[ case $1:m4_ifval([$3], [ b4_comment([$3])])
|
||||||
if (yyn == $1)
|
if (yyn == $1)
|
||||||
$2;
|
$2;
|
||||||
break;
|
break;
|
||||||
|
|||||||
+135
-117
@@ -59,6 +59,13 @@ m4_define([b4_integral_parser_table_define],
|
|||||||
};dnl
|
};dnl
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|
||||||
|
# b4_symbol_kind(NUM)
|
||||||
|
# -------------------
|
||||||
|
m4_define([b4_symbol_kind],
|
||||||
|
[symbol_kind::b4_symbol_kind_base($@)])
|
||||||
|
|
||||||
|
|
||||||
# b4_symbol_value_template(VAL, SYMBOL-NUM, [TYPE])
|
# b4_symbol_value_template(VAL, SYMBOL-NUM, [TYPE])
|
||||||
# -------------------------------------------------
|
# -------------------------------------------------
|
||||||
# Same as b4_symbol_value, but used in a template method. It makes
|
# Same as b4_symbol_value, but used in a template method. It makes
|
||||||
@@ -204,6 +211,13 @@ m4_define([b4_shared_declarations],
|
|||||||
]b4_parser_class[ (]b4_parse_param_decl[);
|
]b4_parser_class[ (]b4_parse_param_decl[);
|
||||||
virtual ~]b4_parser_class[ ();
|
virtual ~]b4_parser_class[ ();
|
||||||
|
|
||||||
|
#if 201103L <= YY_CPLUSPLUS
|
||||||
|
/// Non copyable.
|
||||||
|
]b4_parser_class[ (const ]b4_parser_class[&) = delete;
|
||||||
|
/// Non copyable.
|
||||||
|
]b4_parser_class[& operator= (const ]b4_parser_class[&) = delete;
|
||||||
|
#endif
|
||||||
|
|
||||||
/// Parse. An alias for parse ().
|
/// Parse. An alias for parse ().
|
||||||
/// \returns 0 iff parsing succeeded.
|
/// \returns 0 iff parsing succeeded.
|
||||||
int operator() ();
|
int operator() ();
|
||||||
@@ -234,6 +248,23 @@ m4_define([b4_shared_declarations],
|
|||||||
/// Report a syntax error.
|
/// Report a syntax error.
|
||||||
void error (const syntax_error& err);
|
void error (const syntax_error& err);
|
||||||
|
|
||||||
|
]b4_parse_error_bmatch(
|
||||||
|
[custom\|detailed],
|
||||||
|
[[ /// The user-facing name of the symbol whose (internal) number is
|
||||||
|
/// YYSYMBOL. No bounds checking.
|
||||||
|
static const char *symbol_name (symbol_kind_type yysymbol);]],
|
||||||
|
[simple],
|
||||||
|
[[#if ]b4_api_PREFIX[DEBUG || ]b4_token_table_flag[
|
||||||
|
/// The user-facing name of the symbol whose (internal) number is
|
||||||
|
/// YYSYMBOL. No bounds checking.
|
||||||
|
static const char *symbol_name (symbol_kind_type yysymbol);
|
||||||
|
#endif // #if ]b4_api_PREFIX[DEBUG || ]b4_token_table_flag[
|
||||||
|
]],
|
||||||
|
[verbose],
|
||||||
|
[[ /// The user-facing name of the symbol whose (internal) number is
|
||||||
|
/// YYSYMBOL. No bounds checking.
|
||||||
|
static std::string symbol_name (symbol_kind_type yysymbol);]])[
|
||||||
|
|
||||||
]b4_token_constructor_define[
|
]b4_token_constructor_define[
|
||||||
]b4_parse_error_bmatch([custom\|detailed\|verbose], [[
|
]b4_parse_error_bmatch([custom\|detailed\|verbose], [[
|
||||||
class context
|
class context
|
||||||
@@ -255,10 +286,13 @@ m4_define([b4_shared_declarations],
|
|||||||
};
|
};
|
||||||
]])[
|
]])[
|
||||||
private:
|
private:
|
||||||
/// This class is not copyable.
|
#if YY_CPLUSPLUS < 201103L
|
||||||
|
/// Non copyable.
|
||||||
]b4_parser_class[ (const ]b4_parser_class[&);
|
]b4_parser_class[ (const ]b4_parser_class[&);
|
||||||
]b4_parser_class[& operator= (const ]b4_parser_class[&);]b4_lac_if([[
|
/// Non copyable.
|
||||||
|
]b4_parser_class[& operator= (const ]b4_parser_class[&);
|
||||||
|
#endif
|
||||||
|
]b4_lac_if([[
|
||||||
/// Check the lookahead yytoken.
|
/// Check the lookahead yytoken.
|
||||||
/// \returns true iff the token will be eventually shifted.
|
/// \returns true iff the token will be eventually shifted.
|
||||||
bool yy_lac_check_ (symbol_kind_type yytoken) const;
|
bool yy_lac_check_ (symbol_kind_type yytoken) const;
|
||||||
@@ -307,26 +341,14 @@ m4_define([b4_shared_declarations],
|
|||||||
static symbol_kind_type yytranslate_ (int t);
|
static symbol_kind_type yytranslate_ (int t);
|
||||||
|
|
||||||
]b4_parse_error_bmatch(
|
]b4_parse_error_bmatch(
|
||||||
[custom\|detailed],
|
|
||||||
[[ /// The user-facing name of the symbol whose (internal) number is
|
|
||||||
/// YYSYMBOL. No bounds checking.
|
|
||||||
static const char *symbol_name (symbol_kind_type yysymbol);]],
|
|
||||||
[simple],
|
[simple],
|
||||||
[[#if ]b4_api_PREFIX[DEBUG || ]b4_token_table_flag[
|
[[#if ]b4_api_PREFIX[DEBUG || ]b4_token_table_flag[
|
||||||
/// The user-facing name of the symbol whose (internal) number is
|
|
||||||
/// YYSYMBOL. No bounds checking.
|
|
||||||
static const char *symbol_name (symbol_kind_type yysymbol);
|
|
||||||
|
|
||||||
/// For a symbol, its name in clear.
|
/// For a symbol, its name in clear.
|
||||||
static const char* const yytname_[];
|
static const char* const yytname_[];
|
||||||
#endif // #if ]b4_api_PREFIX[DEBUG || ]b4_token_table_flag[
|
#endif // #if ]b4_api_PREFIX[DEBUG || ]b4_token_table_flag[
|
||||||
]],
|
]],
|
||||||
[verbose],
|
[verbose],
|
||||||
[[ /// The user-facing name of the symbol whose (internal) number is
|
[[ /// Convert the symbol name \a n to a form suitable for a diagnostic.
|
||||||
/// YYSYMBOL. No bounds checking.
|
|
||||||
static std::string symbol_name (symbol_kind_type yysymbol);
|
|
||||||
|
|
||||||
/// Convert the symbol name \a n to a form suitable for a diagnostic.
|
|
||||||
static std::string yytnamerr_ (const char *yystr);
|
static std::string yytnamerr_ (const char *yystr);
|
||||||
|
|
||||||
/// For a symbol, its name in clear.
|
/// For a symbol, its name in clear.
|
||||||
@@ -464,20 +486,13 @@ m4_define([b4_shared_declarations],
|
|||||||
};
|
};
|
||||||
|
|
||||||
]b4_parse_param_vars[
|
]b4_parse_param_vars[
|
||||||
|
]b4_percent_code_get([[yy_bison_internal_hook]])[
|
||||||
};
|
};
|
||||||
|
|
||||||
]b4_token_ctor_if([b4_yytranslate_define([$1])[
|
]b4_token_ctor_if([b4_yytranslate_define([$1])[
|
||||||
]b4_public_types_define([$1])])[
|
]b4_public_types_define([$1])])[
|
||||||
]b4_namespace_close[
|
]b4_namespace_close[
|
||||||
|
|
||||||
]b4_percent_define_flag_if([[global_tokens_and_yystype]],
|
|
||||||
[b4_token_defines
|
|
||||||
|
|
||||||
#ifndef ]b4_api_PREFIX[STYPE
|
|
||||||
// Redirection for backward compatibility.
|
|
||||||
# define ]b4_api_PREFIX[STYPE b4_namespace_ref::b4_parser_class::semantic_type
|
|
||||||
#endif
|
|
||||||
])[
|
|
||||||
]b4_percent_code_get([[provides]])[
|
]b4_percent_code_get([[provides]])[
|
||||||
]])
|
]])
|
||||||
|
|
||||||
@@ -490,16 +505,16 @@ b4_defines_if(
|
|||||||
b4_copyright([Skeleton interface for Bison LALR(1) parsers in C++])
|
b4_copyright([Skeleton interface for Bison LALR(1) parsers in C++])
|
||||||
[
|
[
|
||||||
/**
|
/**
|
||||||
** \file ]b4_spec_header_file[
|
** \file ]b4_spec_mapped_header_file[
|
||||||
** Define the ]b4_namespace_ref[::parser class.
|
** Define the ]b4_namespace_ref[::parser class.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// C++ LALR(1) parser skeleton written by Akim Demaille.
|
// C++ LALR(1) parser skeleton written by Akim Demaille.
|
||||||
|
|
||||||
]b4_disclaimer[
|
]b4_disclaimer[
|
||||||
]b4_cpp_guard_open([b4_spec_header_file])[
|
]b4_cpp_guard_open([b4_spec_mapped_header_file])[
|
||||||
]b4_shared_declarations(hh)[
|
]b4_shared_declarations(hh)[
|
||||||
]b4_cpp_guard_close([b4_spec_header_file])[
|
]b4_cpp_guard_close([b4_spec_mapped_header_file])[
|
||||||
]b4_output_end[
|
]b4_output_end[
|
||||||
]])
|
]])
|
||||||
|
|
||||||
@@ -597,83 +612,6 @@ m4_if(b4_prefix, [yy], [],
|
|||||||
#define YYRECOVERING() (!!yyerrstatus_)
|
#define YYRECOVERING() (!!yyerrstatus_)
|
||||||
|
|
||||||
]b4_namespace_open[
|
]b4_namespace_open[
|
||||||
]b4_parse_error_bmatch([custom\|detailed],
|
|
||||||
[[ const char *
|
|
||||||
]b4_parser_class[::symbol_name (symbol_kind_type yysymbol)
|
|
||||||
{
|
|
||||||
static const char *const yy_sname[] =
|
|
||||||
{
|
|
||||||
]b4_symbol_names[
|
|
||||||
};]b4_has_translations_if([[
|
|
||||||
/* YYTRANSLATABLE[SYMBOL-NUM] -- Whether YY_SNAME[SYMBOL-NUM] is
|
|
||||||
internationalizable. */
|
|
||||||
static ]b4_int_type_for([b4_translatable])[ yytranslatable[] =
|
|
||||||
{
|
|
||||||
]b4_translatable[
|
|
||||||
};
|
|
||||||
return (yysymbol < YYNTOKENS && yytranslatable[yysymbol]
|
|
||||||
? _(yy_sname[yysymbol])
|
|
||||||
: yy_sname[yysymbol]);]], [[
|
|
||||||
return yy_sname[yysymbol];]])[
|
|
||||||
}
|
|
||||||
]],
|
|
||||||
[simple],
|
|
||||||
[[#if ]b4_api_PREFIX[DEBUG || ]b4_token_table_flag[
|
|
||||||
const char *
|
|
||||||
]b4_parser_class[::symbol_name (symbol_kind_type yysymbol)
|
|
||||||
{
|
|
||||||
return yytname_[yysymbol];
|
|
||||||
}
|
|
||||||
#endif // #if ]b4_api_PREFIX[DEBUG || ]b4_token_table_flag[
|
|
||||||
]],
|
|
||||||
[verbose],
|
|
||||||
[[ /* Return YYSTR after stripping away unnecessary quotes and
|
|
||||||
backslashes, so that it's suitable for yyerror. The heuristic is
|
|
||||||
that double-quoting is unnecessary unless the string contains an
|
|
||||||
apostrophe, a comma, or backslash (other than backslash-backslash).
|
|
||||||
YYSTR is taken from yytname. */
|
|
||||||
std::string
|
|
||||||
]b4_parser_class[::yytnamerr_ (const char *yystr)
|
|
||||||
{
|
|
||||||
if (*yystr == '"')
|
|
||||||
{
|
|
||||||
std::string yyr;
|
|
||||||
char const *yyp = yystr;
|
|
||||||
|
|
||||||
for (;;)
|
|
||||||
switch (*++yyp)
|
|
||||||
{
|
|
||||||
case '\'':
|
|
||||||
case ',':
|
|
||||||
goto do_not_strip_quotes;
|
|
||||||
|
|
||||||
case '\\':
|
|
||||||
if (*++yyp != '\\')
|
|
||||||
goto do_not_strip_quotes;
|
|
||||||
else
|
|
||||||
goto append;
|
|
||||||
|
|
||||||
append:
|
|
||||||
default:
|
|
||||||
yyr += *yyp;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case '"':
|
|
||||||
return yyr;
|
|
||||||
}
|
|
||||||
do_not_strip_quotes: ;
|
|
||||||
}
|
|
||||||
|
|
||||||
return yystr;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string
|
|
||||||
]b4_parser_class[::symbol_name (symbol_kind_type yysymbol)
|
|
||||||
{
|
|
||||||
return yytnamerr_ (yytname_[yysymbol]);
|
|
||||||
}
|
|
||||||
]])[
|
|
||||||
|
|
||||||
/// Build a parser object.
|
/// Build a parser object.
|
||||||
]b4_parser_class::b4_parser_class[ (]b4_parse_param_decl[)
|
]b4_parser_class::b4_parser_class[ (]b4_parse_param_decl[)
|
||||||
#if ]b4_api_PREFIX[DEBUG
|
#if ]b4_api_PREFIX[DEBUG
|
||||||
@@ -727,7 +665,7 @@ m4_if(b4_prefix, [yy], [],
|
|||||||
]b4_parser_class[::by_state::kind () const YY_NOEXCEPT
|
]b4_parser_class[::by_state::kind () const YY_NOEXCEPT
|
||||||
{
|
{
|
||||||
if (state == empty_state)
|
if (state == empty_state)
|
||||||
return symbol_kind::]b4_symbol(-2, kind)[;
|
return ]b4_symbol(-2, kind)[;
|
||||||
else
|
else
|
||||||
return YY_CAST (symbol_kind_type, yystos_[+state]);
|
return YY_CAST (symbol_kind_type, yystos_[+state]);
|
||||||
}
|
}
|
||||||
@@ -752,7 +690,7 @@ m4_if(b4_prefix, [yy], [],
|
|||||||
b4_symbol_variant([that.kind ()],
|
b4_symbol_variant([that.kind ()],
|
||||||
[value], [move], [YY_MOVE (that.value)])])[
|
[value], [move], [YY_MOVE (that.value)])])[
|
||||||
// that is emptied.
|
// that is emptied.
|
||||||
that.kind_ = symbol_kind::]b4_symbol(-2, kind)[;
|
that.kind_ = ]b4_symbol(-2, kind)[;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if YY_CPLUSPLUS < 201103L
|
#if YY_CPLUSPLUS < 201103L
|
||||||
@@ -805,7 +743,7 @@ m4_if(b4_prefix, [yy], [],
|
|||||||
{
|
{
|
||||||
symbol_kind_type yykind = yysym.kind ();
|
symbol_kind_type yykind = yysym.kind ();
|
||||||
yyo << (yykind < YYNTOKENS ? "token" : "nterm")
|
yyo << (yykind < YYNTOKENS ? "token" : "nterm")
|
||||||
<< ' ' << symbol_name (yykind) << " ("]b4_locations_if([
|
<< ' ' << yysym.name () << " ("]b4_locations_if([
|
||||||
<< yysym.location << ": "])[;
|
<< yysym.location << ": "])[;
|
||||||
]b4_symbol_actions([printer])[
|
]b4_symbol_actions([printer])[
|
||||||
yyo << ')';
|
yyo << ')';
|
||||||
@@ -981,13 +919,13 @@ b4_dollar_popdef])[]dnl
|
|||||||
}
|
}
|
||||||
YY_SYMBOL_PRINT ("Next token is", yyla);
|
YY_SYMBOL_PRINT ("Next token is", yyla);
|
||||||
|
|
||||||
if (yyla.kind () == ]symbol_kind::b4_symbol(1, kind)[)
|
if (yyla.kind () == ]b4_symbol(1, kind)[)
|
||||||
{
|
{
|
||||||
// The scanner already issued an error message, process directly
|
// The scanner already issued an error message, process directly
|
||||||
// to error recovery. But do not keep the error token as
|
// to error recovery. But do not keep the error token as
|
||||||
// lookahead, it is too special and may lead us to an endless
|
// lookahead, it is too special and may lead us to an endless
|
||||||
// loop in error recovery. */
|
// loop in error recovery. */
|
||||||
yyla.kind_ = ]symbol_kind::b4_symbol(2, kind)[;
|
yyla.kind_ = ]b4_symbol(2, kind)[;
|
||||||
goto yyerrlab1;
|
goto yyerrlab1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1124,7 +1062,7 @@ b4_dollar_popdef])[]dnl
|
|||||||
error, discard it. */
|
error, discard it. */
|
||||||
|
|
||||||
// Return failure if at end of input.
|
// Return failure if at end of input.
|
||||||
if (yyla.kind () == symbol_kind::]b4_symbol_prefix[YYEOF)
|
if (yyla.kind () == ]b4_symbol(0, kind)[)
|
||||||
YYABORT;
|
YYABORT;
|
||||||
else if (!yyla.empty ())
|
else if (!yyla.empty ())
|
||||||
{
|
{
|
||||||
@@ -1165,9 +1103,9 @@ b4_dollar_popdef])[]dnl
|
|||||||
yyn = yypact_[+yystack_[0].state];
|
yyn = yypact_[+yystack_[0].state];
|
||||||
if (!yy_pact_value_is_default_ (yyn))
|
if (!yy_pact_value_is_default_ (yyn))
|
||||||
{
|
{
|
||||||
yyn += symbol_kind::]b4_symbol(1, kind)[;
|
yyn += ]b4_symbol(1, kind)[;
|
||||||
if (0 <= yyn && yyn <= yylast_
|
if (0 <= yyn && yyn <= yylast_
|
||||||
&& yycheck_[yyn] == symbol_kind::]b4_symbol(1, kind)[)
|
&& yycheck_[yyn] == ]b4_symbol(1, kind)[)
|
||||||
{
|
{
|
||||||
yyn = yytable_[yyn];
|
yyn = yytable_[yyn];
|
||||||
if (0 < yyn)
|
if (0 < yyn)
|
||||||
@@ -1257,8 +1195,86 @@ b4_dollar_popdef])[]dnl
|
|||||||
{
|
{
|
||||||
error (]b4_join(b4_locations_if([yyexc.location]),
|
error (]b4_join(b4_locations_if([yyexc.location]),
|
||||||
[[yyexc.what ()]])[);
|
[[yyexc.what ()]])[);
|
||||||
}]b4_parse_error_bmatch([custom\|detailed\|verbose], [[
|
}
|
||||||
|
|
||||||
|
]b4_parse_error_bmatch([custom\|detailed],
|
||||||
|
[[ const char *
|
||||||
|
]b4_parser_class[::symbol_name (symbol_kind_type yysymbol)
|
||||||
|
{
|
||||||
|
static const char *const yy_sname[] =
|
||||||
|
{
|
||||||
|
]b4_symbol_names[
|
||||||
|
};]b4_has_translations_if([[
|
||||||
|
/* YYTRANSLATABLE[SYMBOL-NUM] -- Whether YY_SNAME[SYMBOL-NUM] is
|
||||||
|
internationalizable. */
|
||||||
|
static ]b4_int_type_for([b4_translatable])[ yytranslatable[] =
|
||||||
|
{
|
||||||
|
]b4_translatable[
|
||||||
|
};
|
||||||
|
return (yysymbol < YYNTOKENS && yytranslatable[yysymbol]
|
||||||
|
? _(yy_sname[yysymbol])
|
||||||
|
: yy_sname[yysymbol]);]], [[
|
||||||
|
return yy_sname[yysymbol];]])[
|
||||||
|
}
|
||||||
|
]],
|
||||||
|
[simple],
|
||||||
|
[[#if ]b4_api_PREFIX[DEBUG || ]b4_token_table_flag[
|
||||||
|
const char *
|
||||||
|
]b4_parser_class[::symbol_name (symbol_kind_type yysymbol)
|
||||||
|
{
|
||||||
|
return yytname_[yysymbol];
|
||||||
|
}
|
||||||
|
#endif // #if ]b4_api_PREFIX[DEBUG || ]b4_token_table_flag[
|
||||||
|
]],
|
||||||
|
[verbose],
|
||||||
|
[[ /* Return YYSTR after stripping away unnecessary quotes and
|
||||||
|
backslashes, so that it's suitable for yyerror. The heuristic is
|
||||||
|
that double-quoting is unnecessary unless the string contains an
|
||||||
|
apostrophe, a comma, or backslash (other than backslash-backslash).
|
||||||
|
YYSTR is taken from yytname. */
|
||||||
|
std::string
|
||||||
|
]b4_parser_class[::yytnamerr_ (const char *yystr)
|
||||||
|
{
|
||||||
|
if (*yystr == '"')
|
||||||
|
{
|
||||||
|
std::string yyr;
|
||||||
|
char const *yyp = yystr;
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
switch (*++yyp)
|
||||||
|
{
|
||||||
|
case '\'':
|
||||||
|
case ',':
|
||||||
|
goto do_not_strip_quotes;
|
||||||
|
|
||||||
|
case '\\':
|
||||||
|
if (*++yyp != '\\')
|
||||||
|
goto do_not_strip_quotes;
|
||||||
|
else
|
||||||
|
goto append;
|
||||||
|
|
||||||
|
append:
|
||||||
|
default:
|
||||||
|
yyr += *yyp;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '"':
|
||||||
|
return yyr;
|
||||||
|
}
|
||||||
|
do_not_strip_quotes: ;
|
||||||
|
}
|
||||||
|
|
||||||
|
return yystr;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string
|
||||||
|
]b4_parser_class[::symbol_name (symbol_kind_type yysymbol)
|
||||||
|
{
|
||||||
|
return yytnamerr_ (yytname_[yysymbol]);
|
||||||
|
}
|
||||||
|
]])[
|
||||||
|
|
||||||
|
]b4_parse_error_bmatch([custom\|detailed\|verbose], [[
|
||||||
// ]b4_parser_class[::context.
|
// ]b4_parser_class[::context.
|
||||||
]b4_parser_class[::context::context (const ]b4_parser_class[& yyparser, const symbol_type& yyla)
|
]b4_parser_class[::context::context (const ]b4_parser_class[& yyparser, const symbol_type& yyla)
|
||||||
: yyparser_ (yyparser)
|
: yyparser_ (yyparser)
|
||||||
@@ -1281,8 +1297,8 @@ b4_dollar_popdef])[]dnl
|
|||||||
for (int yyx = 0; yyx < YYNTOKENS; ++yyx)
|
for (int yyx = 0; yyx < YYNTOKENS; ++yyx)
|
||||||
{
|
{
|
||||||
symbol_kind_type yysym = YY_CAST (symbol_kind_type, yyx);
|
symbol_kind_type yysym = YY_CAST (symbol_kind_type, yyx);
|
||||||
if (yysym != symbol_kind::]b4_symbol(1, kind)[
|
if (yysym != ]b4_symbol(1, kind)[
|
||||||
&& yysym != symbol_kind::]b4_symbol_prefix[YYUNDEF
|
&& yysym != ]b4_symbol(2, kind)[
|
||||||
&& yyparser_.yy_lac_check_ (yysym))
|
&& yyparser_.yy_lac_check_ (yysym))
|
||||||
{
|
{
|
||||||
if (!yyarg)
|
if (!yyarg)
|
||||||
@@ -1304,7 +1320,7 @@ b4_dollar_popdef])[]dnl
|
|||||||
int yychecklim = yylast_ - yyn + 1;
|
int yychecklim = yylast_ - yyn + 1;
|
||||||
int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
|
int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
|
||||||
for (int yyx = yyxbegin; yyx < yyxend; ++yyx)
|
for (int yyx = yyxbegin; yyx < yyxend; ++yyx)
|
||||||
if (yycheck_[yyx + yyn] == yyx && yyx != symbol_kind::]b4_symbol(1, kind)[
|
if (yycheck_[yyx + yyn] == yyx && yyx != ]b4_symbol(1, kind)[
|
||||||
&& !yy_table_value_is_error_ (yytable_[yyx + yyn]))
|
&& !yy_table_value_is_error_ (yytable_[yyx + yyn]))
|
||||||
{
|
{
|
||||||
if (!yyarg)
|
if (!yyarg)
|
||||||
@@ -1316,6 +1332,8 @@ b4_dollar_popdef])[]dnl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
]])[
|
]])[
|
||||||
|
if (yyarg && yycount == 0 && 0 < yyargn)
|
||||||
|
yyarg[0] = ]b4_symbol(-2, kind)[;
|
||||||
return yycount;
|
return yycount;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1392,7 +1410,7 @@ b4_dollar_popdef])[]dnl
|
|||||||
: yylac_stack_.back ());
|
: yylac_stack_.back ());
|
||||||
// Push the resulting state of the reduction.
|
// Push the resulting state of the reduction.
|
||||||
state_type state = yy_lr_goto_state_ (top_state, yyr1_[yyrule]);
|
state_type state = yy_lr_goto_state_ (top_state, yyr1_[yyrule]);
|
||||||
YYCDEBUG << " G" << state;
|
YYCDEBUG << " G" << int (state);
|
||||||
yylac_stack_.push_back (state);
|
yylac_stack_.push_back (state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+18
-16
@@ -428,9 +428,10 @@ b4_locations_if([, ref ]b4_location_type[ yylocationp])[)
|
|||||||
*/
|
*/
|
||||||
public bool parse ()
|
public bool parse ()
|
||||||
{
|
{
|
||||||
/// Lookahead and lookahead in internal form.
|
// Lookahead token kind.
|
||||||
int yychar = TokenKind.YYEMPTY;
|
int yychar = TokenKind.YYEMPTY;
|
||||||
SymbolKind yytoken = SymbolKind.]b4_symbol(-2, kind)[;
|
// Lookahead symbol kind.
|
||||||
|
SymbolKind yytoken = ]b4_symbol(-2, kind)[;
|
||||||
|
|
||||||
/* State. */
|
/* State. */
|
||||||
int yyn = 0;
|
int yyn = 0;
|
||||||
@@ -509,14 +510,14 @@ m4_popdef([b4_at_dollar])])dnl
|
|||||||
yytoken = yytranslate_ (yychar);]b4_parse_trace_if([[
|
yytoken = yytranslate_ (yychar);]b4_parse_trace_if([[
|
||||||
yy_symbol_print ("Next token is", yytoken, yylval]b4_locations_if([, yylloc])[);]])[
|
yy_symbol_print ("Next token is", yytoken, yylval]b4_locations_if([, yylloc])[);]])[
|
||||||
|
|
||||||
if (yytoken == SymbolKind.]b4_symbol(1, kind)[)
|
if (yytoken == ]b4_symbol(1, kind)[)
|
||||||
{
|
{
|
||||||
// The scanner already issued an error message, process directly
|
// The scanner already issued an error message, process directly
|
||||||
// to error recovery. But do not keep the error token as
|
// to error recovery. But do not keep the error token as
|
||||||
// lookahead, it is too special and may lead us to an endless
|
// lookahead, it is too special and may lead us to an endless
|
||||||
// loop in error recovery. */
|
// loop in error recovery. */
|
||||||
yychar = TokenKind.YYUNDEF;
|
yychar = TokenKind.]b4_symbol(2, id)[;
|
||||||
yytoken = SymbolKind.]b4_symbol_prefix[YYUNDEF;]b4_locations_if([[
|
yytoken = ]b4_symbol(2, kind)[;]b4_locations_if([[
|
||||||
yyerrloc = yylloc;]])[
|
yyerrloc = yylloc;]])[
|
||||||
label = YYERRLAB1;
|
label = YYERRLAB1;
|
||||||
}
|
}
|
||||||
@@ -587,8 +588,8 @@ m4_popdef([b4_at_dollar])])dnl
|
|||||||
if (yyerrstatus_ == 0)
|
if (yyerrstatus_ == 0)
|
||||||
{
|
{
|
||||||
++yynerrs_;
|
++yynerrs_;
|
||||||
if (yychar == TokenKind.YYEMPTY)
|
if (yychar == TokenKind.]b4_symbol(-2, id)[)
|
||||||
yytoken = SymbolKind.]b4_symbol(-2, kind)[;
|
yytoken = ]b4_symbol(-2, kind)[;
|
||||||
yyerror (]b4_locations_if([yylloc, ])[yysyntax_error (yystate, yytoken));
|
yyerror (]b4_locations_if([yylloc, ])[yysyntax_error (yystate, yytoken));
|
||||||
}
|
}
|
||||||
]b4_locations_if([
|
]b4_locations_if([
|
||||||
@@ -638,8 +639,8 @@ m4_popdef([b4_at_dollar])])dnl
|
|||||||
yyn = yypact_[yystate];
|
yyn = yypact_[yystate];
|
||||||
if (!yy_pact_value_is_default_ (yyn))
|
if (!yy_pact_value_is_default_ (yyn))
|
||||||
{
|
{
|
||||||
yyn += SymbolKind.]b4_symbol(1, kind)[;
|
yyn += ]b4_symbol(1, kind)[;
|
||||||
if (0 <= yyn && yyn <= yylast_ && yycheck_[yyn] == SymbolKind.]b4_symbol(1, kind)[)
|
if (0 <= yyn && yyn <= yylast_ && yycheck_[yyn] == ]b4_symbol(1, kind)[)
|
||||||
{
|
{
|
||||||
yyn = yytable_[yyn];
|
yyn = yytable_[yyn];
|
||||||
if (0 < yyn)
|
if (0 < yyn)
|
||||||
@@ -726,7 +727,7 @@ m4_popdef([b4_at_dollar])])dnl
|
|||||||
will still contain any token that will not be accepted due
|
will still contain any token that will not be accepted due
|
||||||
to an error action in a later state.
|
to an error action in a later state.
|
||||||
*/
|
*/
|
||||||
if (tok != SymbolKind.]b4_symbol(-2, kind)[)
|
if (tok != ]b4_symbol(-2, kind)[)
|
||||||
{
|
{
|
||||||
// FIXME: This method of building the message is not compatible
|
// FIXME: This method of building the message is not compatible
|
||||||
// with internationalization.
|
// with internationalization.
|
||||||
@@ -745,14 +746,14 @@ m4_popdef([b4_at_dollar])])dnl
|
|||||||
int yyxend = yychecklim < yyntokens_ ? yychecklim : yyntokens_;
|
int yyxend = yychecklim < yyntokens_ ? yychecklim : yyntokens_;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
for (int x = yyxbegin; x < yyxend; ++x)
|
for (int x = yyxbegin; x < yyxend; ++x)
|
||||||
if (yycheck_[x + yyn] == x && x != SymbolKind.]b4_symbol(1, kind)[
|
if (yycheck_[x + yyn] == x && x != ]b4_symbol(1, kind)[
|
||||||
&& !yy_table_value_is_error_ (yytable_[x + yyn]))
|
&& !yy_table_value_is_error_ (yytable_[x + yyn]))
|
||||||
++count;
|
++count;
|
||||||
if (count < 5)
|
if (count < 5)
|
||||||
{
|
{
|
||||||
count = 0;
|
count = 0;
|
||||||
for (int x = yyxbegin; x < yyxend; ++x)
|
for (int x = yyxbegin; x < yyxend; ++x)
|
||||||
if (yycheck_[x + yyn] == x && x != SymbolKind.]b4_symbol(1, kind)[
|
if (yycheck_[x + yyn] == x && x != ]b4_symbol(1, kind)[
|
||||||
&& !yy_table_value_is_error_ (yytable_[x + yyn]))
|
&& !yy_table_value_is_error_ (yytable_[x + yyn]))
|
||||||
{
|
{
|
||||||
res ~= count++ == 0 ? ", expecting " : " or ";
|
res ~= count++ == 0 ? ", expecting " : " or ";
|
||||||
@@ -841,17 +842,18 @@ m4_popdef([b4_at_dollar])])dnl
|
|||||||
]b4_translate[
|
]b4_translate[
|
||||||
@};
|
@};
|
||||||
|
|
||||||
immutable int user_token_number_max_ = ]b4_user_token_number_max[;
|
// Last valid token kind.
|
||||||
|
immutable int code_max = ]b4_code_max[;
|
||||||
|
|
||||||
if (t <= 0)
|
if (t <= 0)
|
||||||
return SymbolKind.]b4_symbol_prefix[YYEOF;
|
return ]b4_symbol(0, kind)[;
|
||||||
else if (t <= user_token_number_max_)
|
else if (t <= code_max)
|
||||||
{
|
{
|
||||||
import std.conv : to;
|
import std.conv : to;
|
||||||
return to!SymbolKind (translate_table[t]);
|
return to!SymbolKind (translate_table[t]);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return SymbolKind.]b4_symbol_prefix[YYUNDEF;]])[
|
return ]b4_symbol(2, kind)[;]])[
|
||||||
}
|
}
|
||||||
|
|
||||||
private static immutable int yylast_ = ]b4_last[;
|
private static immutable int yylast_ = ]b4_last[;
|
||||||
|
|||||||
+123
-125
@@ -53,8 +53,9 @@ b4_use_push_for_pull_if([
|
|||||||
# allows them to be defined either in parse() when doing pull parsing,
|
# allows them to be defined either in parse() when doing pull parsing,
|
||||||
# or as class instance variable when doing push parsing.
|
# or as class instance variable when doing push parsing.
|
||||||
m4_define([b4_define_state],[[
|
m4_define([b4_define_state],[[
|
||||||
/* Lookahead and lookahead in internal form. */
|
/* Lookahead token kind. */
|
||||||
int yychar = YYEMPTY_;
|
int yychar = YYEMPTY_;
|
||||||
|
/* Lookahead symbol kind. */
|
||||||
SymbolKind yytoken = null;
|
SymbolKind yytoken = null;
|
||||||
|
|
||||||
/* State. */
|
/* State. */
|
||||||
@@ -79,7 +80,7 @@ m4_define([b4_define_state],[[
|
|||||||
]b4_copyright([Skeleton implementation for Bison LALR(1) parsers in Java],
|
]b4_copyright([Skeleton implementation for Bison LALR(1) parsers in Java],
|
||||||
[2007-2015, 2018-2020])[
|
[2007-2015, 2018-2020])[
|
||||||
]b4_disclaimer[
|
]b4_disclaimer[
|
||||||
]b4_percent_define_ifdef([package], [package b4_percent_define_get([package]);[
|
]b4_percent_define_ifdef([api.package], [package b4_percent_define_get([api.package]);[
|
||||||
]])[
|
]])[
|
||||||
]b4_user_pre_prologue[
|
]b4_user_pre_prologue[
|
||||||
]b4_user_post_prologue[
|
]b4_user_post_prologue[
|
||||||
@@ -121,7 +122,7 @@ import java.text.MessageFormat;
|
|||||||
* Locations represent a part of the input through the beginning
|
* Locations represent a part of the input through the beginning
|
||||||
* and ending positions.
|
* and ending positions.
|
||||||
*/
|
*/
|
||||||
public class ]b4_location_type[ {
|
public static class ]b4_location_type[ {
|
||||||
/**
|
/**
|
||||||
* The first, inclusive, position in the range.
|
* The first, inclusive, position in the range.
|
||||||
*/
|
*/
|
||||||
@@ -182,25 +183,24 @@ import java.text.MessageFormat;
|
|||||||
]b4_token_enums[
|
]b4_token_enums[
|
||||||
/** Deprecated, use ]b4_symbol(0, id)[ instead. */
|
/** Deprecated, use ]b4_symbol(0, id)[ instead. */
|
||||||
public static final int EOF = ]b4_symbol(0, id)[;
|
public static final int EOF = ]b4_symbol(0, id)[;
|
||||||
|
]b4_pull_if([b4_locations_if([[
|
||||||
]b4_locations_if([[
|
|
||||||
/**
|
/**
|
||||||
* Method to retrieve the beginning position of the last scanned token.
|
* Method to retrieve the beginning position of the last scanned token.
|
||||||
* @@return the position at which the last scanned token starts.
|
* @@return the position at which the last scanned token starts.
|
||||||
*/
|
*/
|
||||||
]b4_position_type[ getStartPos ();
|
]b4_position_type[ getStartPos();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method to retrieve the ending position of the last scanned token.
|
* Method to retrieve the ending position of the last scanned token.
|
||||||
* @@return the first position beyond the last scanned token.
|
* @@return the first position beyond the last scanned token.
|
||||||
*/
|
*/
|
||||||
]b4_position_type[ getEndPos ();]])[
|
]b4_position_type[ getEndPos();]])[
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method to retrieve the semantic value of the last scanned token.
|
* Method to retrieve the semantic value of the last scanned token.
|
||||||
* @@return the semantic value of the last scanned token.
|
* @@return the semantic value of the last scanned token.
|
||||||
*/
|
*/
|
||||||
]b4_yystype[ getLVal ();
|
]b4_yystype[ getLVal();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Entry point for the scanner. Returns the token identifier corresponding
|
* Entry point for the scanner. Returns the token identifier corresponding
|
||||||
@@ -208,24 +208,25 @@ import java.text.MessageFormat;
|
|||||||
* ]b4_locations_if([and beginning/ending positions ])[of the token.
|
* ]b4_locations_if([and beginning/ending positions ])[of the token.
|
||||||
* @@return the token identifier corresponding to the next token.
|
* @@return the token identifier corresponding to the next token.
|
||||||
*/
|
*/
|
||||||
int yylex ()]b4_maybe_throws([b4_lex_throws])[;
|
int yylex()]b4_maybe_throws([b4_lex_throws])[;
|
||||||
|
]])[
|
||||||
/**
|
/**
|
||||||
* Entry point for error reporting. Emits an error
|
* Emit an error]b4_locations_if([ referring to the given location])[in a user-defined way.
|
||||||
* ]b4_locations_if([referring to the given location ])[in a user-defined way.
|
|
||||||
*
|
*
|
||||||
*]b4_locations_if([[ @@param loc The location of the element to which the
|
*]b4_locations_if([[ @@param loc The location of the element to which the
|
||||||
* error message is related]])[
|
* error message is related.]])[
|
||||||
* @@param msg The string for the error message.
|
* @@param msg The string for the error message.
|
||||||
*/
|
*/
|
||||||
void yyerror (]b4_locations_if([b4_location_type[ loc, ]])[String msg);
|
void yyerror(]b4_locations_if([b4_location_type[ loc, ]])[String msg);
|
||||||
|
|
||||||
]b4_parse_error_bmatch(
|
]b4_parse_error_bmatch(
|
||||||
[custom], [[
|
[custom], [[
|
||||||
/**
|
/**
|
||||||
* Build and emit a syntax error message.
|
* Build and emit a "syntax error" message in a user-defined way.
|
||||||
|
*
|
||||||
|
* @@param ctx The context of the error.
|
||||||
*/
|
*/
|
||||||
void reportSyntaxError (][Context yyctx);
|
void reportSyntaxError (][Context ctx);
|
||||||
]])[
|
]])[
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -307,9 +308,8 @@ import java.text.MessageFormat;
|
|||||||
*]b4_locations_if([[ Use a <code>null</code> location.]])[
|
*]b4_locations_if([[ Use a <code>null</code> location.]])[
|
||||||
* @@param msg The error message.
|
* @@param msg The error message.
|
||||||
*/
|
*/
|
||||||
public final void yyerror (String msg)
|
public final void yyerror(String msg) {
|
||||||
{
|
yylexer.yyerror(]b4_locations_if([[(]b4_location_type[)null, ]])[msg);
|
||||||
yylexer.yyerror (]b4_locations_if([[(]b4_location_type[)null, ]])[msg);
|
|
||||||
}
|
}
|
||||||
]b4_locations_if([[
|
]b4_locations_if([[
|
||||||
/**
|
/**
|
||||||
@@ -317,9 +317,8 @@ import java.text.MessageFormat;
|
|||||||
* @@param loc The location associated with the message.
|
* @@param loc The location associated with the message.
|
||||||
* @@param msg The error message.
|
* @@param msg The error message.
|
||||||
*/
|
*/
|
||||||
public final void yyerror (]b4_location_type[ loc, String msg)
|
public final void yyerror(]b4_location_type[ loc, String msg) {
|
||||||
{
|
yylexer.yyerror(loc, msg);
|
||||||
yylexer.yyerror (loc, msg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -327,9 +326,8 @@ import java.text.MessageFormat;
|
|||||||
* @@param pos The position associated with the message.
|
* @@param pos The position associated with the message.
|
||||||
* @@param msg The error message.
|
* @@param msg The error message.
|
||||||
*/
|
*/
|
||||||
public final void yyerror (]b4_position_type[ pos, String msg)
|
public final void yyerror(]b4_position_type[ pos, String msg) {
|
||||||
{
|
yylexer.yyerror(new ]b4_location_type[ (pos), msg);
|
||||||
yylexer.yyerror (new ]b4_location_type[ (pos), msg);
|
|
||||||
}]])[
|
}]])[
|
||||||
]b4_parse_trace_if([[
|
]b4_parse_trace_if([[
|
||||||
protected final void yycdebug (String s) {
|
protected final void yycdebug (String s) {
|
||||||
@@ -469,7 +467,7 @@ import java.text.MessageFormat;
|
|||||||
return yydefgoto_[yysym - YYNTOKENS_];
|
return yydefgoto_[yysym - YYNTOKENS_];
|
||||||
}
|
}
|
||||||
|
|
||||||
private int yyaction (int yyn, YYStack yystack, int yylen)]b4_maybe_throws([b4_throws])[
|
private int yyaction(int yyn, YYStack yystack, int yylen)]b4_maybe_throws([b4_throws])[
|
||||||
{
|
{
|
||||||
/* If YYLEN is nonzero, implement the default value of the action:
|
/* If YYLEN is nonzero, implement the default value of the action:
|
||||||
'$$ = $1'. Otherwise, use the top of the stack.
|
'$$ = $1'. Otherwise, use the top of the stack.
|
||||||
@@ -477,10 +475,10 @@ import java.text.MessageFormat;
|
|||||||
Otherwise, the following line sets YYVAL to garbage.
|
Otherwise, the following line sets YYVAL to garbage.
|
||||||
This behavior is undocumented and Bison
|
This behavior is undocumented and Bison
|
||||||
users should not rely upon it. */
|
users should not rely upon it. */
|
||||||
]b4_yystype[ yyval = (0 < yylen) ? yystack.valueAt (yylen - 1) : yystack.valueAt (0);]b4_locations_if([[
|
]b4_yystype[ yyval = (0 < yylen) ? yystack.valueAt(yylen - 1) : yystack.valueAt(0);]b4_locations_if([[
|
||||||
]b4_location_type[ yyloc = yylloc (yystack, yylen);]])[]b4_parse_trace_if([[
|
]b4_location_type[ yyloc = yylloc(yystack, yylen);]])[]b4_parse_trace_if([[
|
||||||
|
|
||||||
yyReducePrint (yyn, yystack);]])[
|
yyReducePrint(yyn, yystack);]])[
|
||||||
|
|
||||||
switch (yyn)
|
switch (yyn)
|
||||||
{
|
{
|
||||||
@@ -488,13 +486,13 @@ import java.text.MessageFormat;
|
|||||||
default: break;
|
default: break;
|
||||||
}]b4_parse_trace_if([[
|
}]b4_parse_trace_if([[
|
||||||
|
|
||||||
yySymbolPrint ("-> $$ =", SymbolKind.get (yyr1_[yyn]), yyval]b4_locations_if([, yyloc])[);]])[
|
yySymbolPrint("-> $$ =", SymbolKind.get(yyr1_[yyn]), yyval]b4_locations_if([, yyloc])[);]])[
|
||||||
|
|
||||||
yystack.pop (yylen);
|
yystack.pop(yylen);
|
||||||
yylen = 0;
|
yylen = 0;
|
||||||
/* Shift the result of the reduction. */
|
/* Shift the result of the reduction. */
|
||||||
int yystate = yyLRGotoState (yystack.stateAt (0), yyr1_[yyn]);
|
int yystate = yyLRGotoState(yystack.stateAt(0), yyr1_[yyn]);
|
||||||
yystack.push (yystate, yyval]b4_locations_if([, yyloc])[);
|
yystack.push(yystate, yyval]b4_locations_if([, yyloc])[);
|
||||||
return YYNEWSTATE;
|
return YYNEWSTATE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -504,13 +502,14 @@ import java.text.MessageFormat;
|
|||||||
`--------------------------------*/
|
`--------------------------------*/
|
||||||
|
|
||||||
private void yySymbolPrint(String s, SymbolKind yykind,
|
private void yySymbolPrint(String s, SymbolKind yykind,
|
||||||
]b4_yystype[ yyvalue]b4_locations_if([, ]b4_location_type[ yylocation])[)
|
]b4_yystype[ yyvalue]b4_locations_if([, ]b4_location_type[ yylocation])[) {
|
||||||
{
|
if (0 < yydebug) {
|
||||||
yycdebug (s
|
yycdebug(s
|
||||||
+ (yykind.getCode() < YYNTOKENS_ ? " token " : " nterm ")
|
+ (yykind.getCode() < YYNTOKENS_ ? " token " : " nterm ")
|
||||||
+ yykind.getName() + " ("]b4_locations_if([
|
+ yykind.getName() + " ("]b4_locations_if([
|
||||||
+ yylocation + ": "])[
|
+ yylocation + ": "])[
|
||||||
+ (yyvalue == null ? "(null)" : yyvalue.toString()) + ")");
|
+ (yyvalue == null ? "(null)" : yyvalue.toString()) + ")");
|
||||||
|
}
|
||||||
}]])[
|
}]])[
|
||||||
|
|
||||||
]b4_push_if([],[[
|
]b4_push_if([],[[
|
||||||
@@ -521,7 +520,7 @@ import java.text.MessageFormat;
|
|||||||
* @@return <tt>true</tt> if the parsing succeeds. Note that this does not
|
* @@return <tt>true</tt> if the parsing succeeds. Note that this does not
|
||||||
* imply that there were no syntax errors.
|
* imply that there were no syntax errors.
|
||||||
*/
|
*/
|
||||||
public boolean parse ()]b4_maybe_throws([b4_list2([b4_lex_throws], [b4_throws])])[]])[
|
public boolean parse()]b4_maybe_throws([b4_list2([b4_lex_throws], [b4_throws])])[]])[
|
||||||
]b4_push_if([
|
]b4_push_if([
|
||||||
/**
|
/**
|
||||||
* Push Parse input from external lexer
|
* Push Parse input from external lexer
|
||||||
@@ -532,7 +531,7 @@ import java.text.MessageFormat;
|
|||||||
*
|
*
|
||||||
* @@return <tt>YYACCEPT, YYABORT, YYPUSH_MORE</tt>
|
* @@return <tt>YYACCEPT, YYABORT, YYPUSH_MORE</tt>
|
||||||
*/
|
*/
|
||||||
public int push_parse (int yylextoken, b4_yystype yylexval[]b4_locations_if([, b4_location_type yylexloc]))b4_maybe_throws([b4_list2([b4_lex_throws], [b4_throws])])])[
|
public int push_parse(int yylextoken, b4_yystype yylexval[]b4_locations_if([, b4_location_type yylexloc]))b4_maybe_throws([b4_list2([b4_lex_throws], [b4_throws])])])[
|
||||||
{]b4_locations_if([[
|
{]b4_locations_if([[
|
||||||
/* @@$. */
|
/* @@$. */
|
||||||
]b4_location_type[ yyloc;]])[
|
]b4_location_type[ yyloc;]])[
|
||||||
@@ -604,25 +603,25 @@ b4_dollar_popdef[]dnl
|
|||||||
push_token_consumed = false;]], [b4_parse_trace_if([[
|
push_token_consumed = false;]], [b4_parse_trace_if([[
|
||||||
yycdebug ("Reading a token");]])[
|
yycdebug ("Reading a token");]])[
|
||||||
yychar = yylexer.yylex ();
|
yychar = yylexer.yylex ();
|
||||||
yylval = yylexer.getLVal ();]b4_locations_if([
|
yylval = yylexer.getLVal();]b4_locations_if([[
|
||||||
yylloc = new b4_location_type (yylexer.getStartPos (),
|
yylloc = new ]b4_location_type[(yylexer.getStartPos(),
|
||||||
yylexer.getEndPos ());])[
|
yylexer.getEndPos());]])[
|
||||||
]])[
|
]])[
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Convert token to internal form. */
|
/* Convert token to internal form. */
|
||||||
yytoken = yytranslate_ (yychar);]b4_parse_trace_if([[
|
yytoken = yytranslate_ (yychar);]b4_parse_trace_if([[
|
||||||
yySymbolPrint ("Next token is", yytoken,
|
yySymbolPrint("Next token is", yytoken,
|
||||||
yylval]b4_locations_if([, yylloc])[);]])[
|
yylval]b4_locations_if([, yylloc])[);]])[
|
||||||
|
|
||||||
if (yytoken == SymbolKind.]b4_symbol_prefix[YYerror)
|
if (yytoken == ]b4_symbol(1, kind)[)
|
||||||
{
|
{
|
||||||
// The scanner already issued an error message, process directly
|
// The scanner already issued an error message, process directly
|
||||||
// to error recovery. But do not keep the error token as
|
// to error recovery. But do not keep the error token as
|
||||||
// lookahead, it is too special and may lead us to an endless
|
// lookahead, it is too special and may lead us to an endless
|
||||||
// loop in error recovery. */
|
// loop in error recovery. */
|
||||||
yychar = Lexer.]b4_percent_define_get([api.token.prefix])[YYUNDEF;
|
yychar = Lexer.]b4_symbol(2, id)[;
|
||||||
yytoken = SymbolKind.]b4_symbol_prefix[YYUNDEF;]b4_locations_if([[
|
yytoken = ]b4_symbol(2, kind)[;]b4_locations_if([[
|
||||||
yyerrloc = yylloc;]])[
|
yyerrloc = yylloc;]])[
|
||||||
label = YYERRLAB1;
|
label = YYERRLAB1;
|
||||||
}
|
}
|
||||||
@@ -630,8 +629,8 @@ b4_dollar_popdef[]dnl
|
|||||||
{
|
{
|
||||||
/* If the proper action on seeing token YYTOKEN is to reduce or to
|
/* If the proper action on seeing token YYTOKEN is to reduce or to
|
||||||
detect an error, take that action. */
|
detect an error, take that action. */
|
||||||
yyn += yytoken.getCode ();
|
yyn += yytoken.getCode();
|
||||||
if (yyn < 0 || YYLAST_ < yyn || yycheck_[yyn] != yytoken.getCode ())
|
if (yyn < 0 || YYLAST_ < yyn || yycheck_[yyn] != yytoken.getCode())
|
||||||
label = YYDEFAULT;
|
label = YYDEFAULT;
|
||||||
|
|
||||||
/* <= 0 means reduce or error. */
|
/* <= 0 means reduce or error. */
|
||||||
@@ -649,8 +648,8 @@ b4_dollar_popdef[]dnl
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Shift the lookahead token. */]b4_parse_trace_if([[
|
/* Shift the lookahead token. */]b4_parse_trace_if([[
|
||||||
yySymbolPrint ("Shifting", yytoken,
|
yySymbolPrint("Shifting", yytoken,
|
||||||
yylval]b4_locations_if([, yylloc])[);
|
yylval]b4_locations_if([, yylloc])[);
|
||||||
]])[
|
]])[
|
||||||
/* Discard the token being shifted. */
|
/* Discard the token being shifted. */
|
||||||
yychar = YYEMPTY_;
|
yychar = YYEMPTY_;
|
||||||
@@ -683,7 +682,7 @@ b4_dollar_popdef[]dnl
|
|||||||
`-----------------------------*/
|
`-----------------------------*/
|
||||||
case YYREDUCE:
|
case YYREDUCE:
|
||||||
yylen = yyr2_[yyn];
|
yylen = yyr2_[yyn];
|
||||||
label = yyaction (yyn, yystack, yylen);
|
label = yyaction(yyn, yystack, yylen);
|
||||||
yystate = yystack.stateAt (0);
|
yystate = yystack.stateAt (0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -746,9 +745,9 @@ b4_dollar_popdef[]dnl
|
|||||||
yyn = yypact_[yystate];
|
yyn = yypact_[yystate];
|
||||||
if (!yyPactValueIsDefault (yyn))
|
if (!yyPactValueIsDefault (yyn))
|
||||||
{
|
{
|
||||||
yyn += SymbolKind.]b4_symbol(1, kind)[.getCode ();
|
yyn += ]b4_symbol(1, kind)[.getCode();
|
||||||
if (0 <= yyn && yyn <= YYLAST_
|
if (0 <= yyn && yyn <= YYLAST_
|
||||||
&& yycheck_[yyn] == SymbolKind.]b4_symbol(1, kind)[.getCode ())
|
&& yycheck_[yyn] == ]b4_symbol(1, kind)[.getCode())
|
||||||
{
|
{
|
||||||
yyn = yytable_[yyn];
|
yyn = yytable_[yyn];
|
||||||
if (0 < yyn)
|
if (0 < yyn)
|
||||||
@@ -781,8 +780,8 @@ b4_dollar_popdef[]dnl
|
|||||||
yystack.pop (2);]])[
|
yystack.pop (2);]])[
|
||||||
|
|
||||||
/* Shift the error token. */]b4_parse_trace_if([[
|
/* Shift the error token. */]b4_parse_trace_if([[
|
||||||
yySymbolPrint ("Shifting", SymbolKind.get (yystos_[yyn]),
|
yySymbolPrint("Shifting", SymbolKind.get(yystos_[yyn]),
|
||||||
yylval]b4_locations_if([, yyloc])[);]])[
|
yylval]b4_locations_if([, yyloc])[);]])[
|
||||||
|
|
||||||
yystate = yyn;
|
yystate = yyn;
|
||||||
yystack.push (yyn, yylval]b4_locations_if([, yyloc])[);
|
yystack.push (yyn, yylval]b4_locations_if([, yyloc])[);
|
||||||
@@ -833,7 +832,7 @@ b4_dollar_popdef[]dnl
|
|||||||
this.push_parse_initialized = true;
|
this.push_parse_initialized = true;
|
||||||
|
|
||||||
}
|
}
|
||||||
]b4_locations_if([
|
]b4_locations_if([[
|
||||||
/**
|
/**
|
||||||
* Push parse given input from an external lexer.
|
* Push parse given input from an external lexer.
|
||||||
*
|
*
|
||||||
@@ -843,36 +842,32 @@ b4_dollar_popdef[]dnl
|
|||||||
*
|
*
|
||||||
* @@return <tt>YYACCEPT, YYABORT, YYPUSH_MORE</tt>
|
* @@return <tt>YYACCEPT, YYABORT, YYPUSH_MORE</tt>
|
||||||
*/
|
*/
|
||||||
public int push_parse (int yylextoken, b4_yystype yylexval, b4_position_type yylexpos)b4_maybe_throws([b4_list2([b4_lex_throws], [b4_throws])])
|
public int push_parse(int yylextoken, ]b4_yystype[ yylexval, ]b4_position_type[ yylexpos)]b4_maybe_throws([b4_list2([b4_lex_throws], [b4_throws])])[ {
|
||||||
{
|
return push_parse(yylextoken, yylexval, new ]b4_location_type[(yylexpos));
|
||||||
return push_parse (yylextoken, yylexval, new b4_location_type (yylexpos));
|
|
||||||
}
|
}
|
||||||
])[]])[
|
]])])[
|
||||||
|
|
||||||
]b4_both_if([[
|
]b4_both_if([[
|
||||||
/**
|
/**
|
||||||
* Parse input from the scanner that was specified at object construction
|
* Parse input from the scanner that was specified at object construction
|
||||||
* time. Return whether the end of the input was reached successfully.
|
* time. Return whether the end of the input was reached successfully.
|
||||||
* This version of parse () is defined only when api.push-push=both.
|
* This version of parse() is defined only when api.push-push=both.
|
||||||
*
|
*
|
||||||
* @@return <tt>true</tt> if the parsing succeeds. Note that this does not
|
* @@return <tt>true</tt> if the parsing succeeds. Note that this does not
|
||||||
* imply that there were no syntax errors.
|
* imply that there were no syntax errors.
|
||||||
*/
|
*/
|
||||||
public boolean parse ()]b4_maybe_throws([b4_list2([b4_lex_throws], [b4_throws])])[
|
public boolean parse()]b4_maybe_throws([b4_list2([b4_lex_throws], [b4_throws])])[ {
|
||||||
{
|
if (yylexer == null)
|
||||||
if (yylexer == null)
|
throw new NullPointerException("Null Lexer");
|
||||||
throw new NullPointerException("Null Lexer");
|
int status;
|
||||||
int status;
|
do {
|
||||||
do {
|
int token = yylexer.yylex();
|
||||||
int token = yylexer.yylex();
|
]b4_yystype[ lval = yylexer.getLVal();]b4_locations_if([[
|
||||||
]b4_yystype[ lval = yylexer.getLVal();
|
]b4_location_type[ yyloc = new ]b4_location_type[(yylexer.getStartPos(), yylexer.getEndPos());
|
||||||
]b4_locations_if([dnl
|
status = push_parse(token, lval, yyloc);]], [[
|
||||||
b4_location_type yyloc = new b4_location_type (yylexer.getStartPos (),
|
status = push_parse(token, lval);]])[
|
||||||
yylexer.getEndPos ());])[]b4_locations_if([[
|
} while (status == YYPUSH_MORE);
|
||||||
status = push_parse(token,lval,yyloc);]], [[
|
return status == YYACCEPT;
|
||||||
status = push_parse(token,lval);]])[
|
|
||||||
} while (status == YYPUSH_MORE);
|
|
||||||
return (status == YYACCEPT);
|
|
||||||
}
|
}
|
||||||
]])[
|
]])[
|
||||||
|
|
||||||
@@ -939,17 +934,19 @@ b4_dollar_popdef[]dnl
|
|||||||
int yychecklim = YYLAST_ - yyn + 1;
|
int yychecklim = YYLAST_ - yyn + 1;
|
||||||
int yyxend = yychecklim < NTOKENS ? yychecklim : NTOKENS;
|
int yyxend = yychecklim < NTOKENS ? yychecklim : NTOKENS;
|
||||||
for (int yyx = yyxbegin; yyx < yyxend; ++yyx)
|
for (int yyx = yyxbegin; yyx < yyxend; ++yyx)
|
||||||
if (yycheck_[yyx + yyn] == yyx && yyx != SymbolKind.]b4_symbol(1, kind)[.getCode ()
|
if (yycheck_[yyx + yyn] == yyx && yyx != ]b4_symbol(1, kind)[.getCode()
|
||||||
&& !yyTableValueIsError (yytable_[yyx + yyn]))
|
&& !yyTableValueIsError(yytable_[yyx + yyn]))
|
||||||
{
|
{
|
||||||
if (yyarg == null)
|
if (yyarg == null)
|
||||||
yycount += 1;
|
yycount += 1;
|
||||||
else if (yycount == yyargn)
|
else if (yycount == yyargn)
|
||||||
return 0; // FIXME: this is incorrect.
|
return 0; // FIXME: this is incorrect.
|
||||||
else
|
else
|
||||||
yyarg[yycount++] = SymbolKind.get (yyx);
|
yyarg[yycount++] = SymbolKind.get(yyx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (yyarg != null && yycount == yyoffset && yyoffset < yyargn)
|
||||||
|
yyarg[yycount] = null;
|
||||||
return yycount - yyoffset;
|
return yycount - yyoffset;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -985,50 +982,50 @@ b4_dollar_popdef[]dnl
|
|||||||
to an error action in a later state.
|
to an error action in a later state.
|
||||||
*/
|
*/
|
||||||
int yycount = 0;
|
int yycount = 0;
|
||||||
if (yyctx.getToken () != null)
|
if (yyctx.getToken() != null)
|
||||||
{
|
{
|
||||||
if (yyarg != null)
|
if (yyarg != null)
|
||||||
yyarg[yycount] = yyctx.getToken ();
|
yyarg[yycount] = yyctx.getToken();
|
||||||
yycount += 1;
|
yycount += 1;
|
||||||
yycount += yyctx.getExpectedTokens (yyarg, 1, yyargn);
|
yycount += yyctx.getExpectedTokens(yyarg, 1, yyargn);
|
||||||
}
|
}
|
||||||
return yycount;
|
return yycount;
|
||||||
}
|
}
|
||||||
]])[
|
]])[
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Report a syntax error.
|
* Build and emit a "syntax error" message in a user-defined way.
|
||||||
|
*
|
||||||
|
* @@param ctx The context of the error.
|
||||||
*/
|
*/
|
||||||
private void yyreportSyntaxError (Context yyctx)
|
private void yyreportSyntaxError(Context yyctx) {]b4_parse_error_bmatch(
|
||||||
{]b4_parse_error_bmatch(
|
|
||||||
[custom], [[
|
[custom], [[
|
||||||
yylexer.reportSyntaxError (yyctx);]],
|
yylexer.reportSyntaxError(yyctx);]],
|
||||||
[detailed\|verbose], [[
|
[detailed\|verbose], [[
|
||||||
if (yyErrorVerbose)
|
if (yyErrorVerbose) {
|
||||||
{
|
final int argmax = 5;
|
||||||
final int argmax = 5;
|
SymbolKind[] yyarg = new SymbolKind[argmax];
|
||||||
SymbolKind[] yyarg = new SymbolKind[argmax];
|
int yycount = yysyntaxErrorArguments(yyctx, yyarg, argmax);
|
||||||
int yycount = yysyntaxErrorArguments (yyctx, yyarg, argmax);
|
String[] yystr = new String[yycount];
|
||||||
String[] yystr = new String[yycount];
|
for (int yyi = 0; yyi < yycount; ++yyi) {
|
||||||
for (int yyi = 0; yyi < yycount; ++yyi)
|
yystr[yyi] = yyarg[yyi].getName();
|
||||||
yystr[yyi] = yyarg[yyi].getName();
|
|
||||||
String yyformat;
|
|
||||||
switch (yycount)
|
|
||||||
{
|
|
||||||
default:
|
|
||||||
case 0: yyformat = ]b4_trans(["syntax error"])[; break;
|
|
||||||
case 1: yyformat = ]b4_trans(["syntax error, unexpected {0}"])[; break;
|
|
||||||
case 2: yyformat = ]b4_trans(["syntax error, unexpected {0}, expecting {1}"])[; break;
|
|
||||||
case 3: yyformat = ]b4_trans(["syntax error, unexpected {0}, expecting {1} or {2}"])[; break;
|
|
||||||
case 4: yyformat = ]b4_trans(["syntax error, unexpected {0}, expecting {1} or {2} or {3}"])[; break;
|
|
||||||
case 5: yyformat = ]b4_trans(["syntax error, unexpected {0}, expecting {1} or {2} or {3} or {4}"])[; break;
|
|
||||||
}
|
}
|
||||||
yyerror (]b4_locations_if([[yyctx.yylocation, ]])[new MessageFormat (yyformat).format (yystr));
|
String yyformat;
|
||||||
return;
|
switch (yycount) {
|
||||||
}
|
default:
|
||||||
yyerror (]b4_locations_if([[yyctx.yylocation, ]])["syntax error");]],
|
case 0: yyformat = ]b4_trans(["syntax error"])[; break;
|
||||||
|
case 1: yyformat = ]b4_trans(["syntax error, unexpected {0}"])[; break;
|
||||||
|
case 2: yyformat = ]b4_trans(["syntax error, unexpected {0}, expecting {1}"])[; break;
|
||||||
|
case 3: yyformat = ]b4_trans(["syntax error, unexpected {0}, expecting {1} or {2}"])[; break;
|
||||||
|
case 4: yyformat = ]b4_trans(["syntax error, unexpected {0}, expecting {1} or {2} or {3}"])[; break;
|
||||||
|
case 5: yyformat = ]b4_trans(["syntax error, unexpected {0}, expecting {1} or {2} or {3} or {4}"])[; break;
|
||||||
|
}
|
||||||
|
yyerror(]b4_locations_if([[yyctx.yylocation, ]])[new MessageFormat(yyformat).format(yystr));
|
||||||
|
} else {
|
||||||
|
yyerror(]b4_locations_if([[yyctx.yylocation, ]])[]b4_trans(["syntax error"])[);
|
||||||
|
}]],
|
||||||
[simple], [[
|
[simple], [[
|
||||||
yyerror (]b4_locations_if([[yyctx.yylocation, ]])["syntax error");]])[
|
yyerror(]b4_locations_if([[yyctx.yylocation, ]])[]b4_trans(["syntax error"])[);]])[
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1074,28 +1071,29 @@ b4_dollar_popdef[]dnl
|
|||||||
|
|
||||||
/* The symbols being reduced. */
|
/* The symbols being reduced. */
|
||||||
for (int yyi = 0; yyi < yynrhs; yyi++)
|
for (int yyi = 0; yyi < yynrhs; yyi++)
|
||||||
yySymbolPrint (" $" + (yyi + 1) + " =",
|
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_data(yynrhs, yyi + 1)b4_locations_if([,
|
||||||
b4_rhs_location(yynrhs, yyi + 1)])[);
|
b4_rhs_location(yynrhs, yyi + 1)])[);
|
||||||
}]])[
|
}]])[
|
||||||
|
|
||||||
/* YYTRANSLATE_(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM
|
/* YYTRANSLATE_(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM
|
||||||
as returned by yylex, with out-of-bounds checking. */
|
as returned by yylex, with out-of-bounds checking. */
|
||||||
private static final SymbolKind yytranslate_ (int t)
|
private static final SymbolKind yytranslate_(int t)
|
||||||
]b4_api_token_raw_if(dnl
|
]b4_api_token_raw_if(dnl
|
||||||
[[ {
|
[[ {
|
||||||
return SymbolKind.get (t);
|
return SymbolKind.get(t);
|
||||||
}
|
}
|
||||||
]],
|
]],
|
||||||
[[ {
|
[[ {
|
||||||
int user_token_number_max_ = ]b4_user_token_number_max[;
|
// Last valid token kind.
|
||||||
|
int code_max = ]b4_code_max[;
|
||||||
if (t <= 0)
|
if (t <= 0)
|
||||||
return SymbolKind.]b4_symbol_prefix[YYEOF;
|
return ]b4_symbol(0, kind)[;
|
||||||
else if (t <= user_token_number_max_)
|
else if (t <= code_max)
|
||||||
return SymbolKind.get (yytranslate_table_[t]);
|
return SymbolKind.get(yytranslate_table_[t]);
|
||||||
else
|
else
|
||||||
return SymbolKind.]b4_symbol_prefix[YYUNDEF;
|
return ]b4_symbol(2, kind)[;
|
||||||
}
|
}
|
||||||
]b4_integral_parser_table_define([translate_table], [b4_translate])[
|
]b4_integral_parser_table_define([translate_table], [b4_translate])[
|
||||||
]])[
|
]])[
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ m4_ifdef([b4_location_file],
|
|||||||
["b4_location_file"])])
|
["b4_location_file"])])
|
||||||
m4_define([b4_location_path],
|
m4_define([b4_location_path],
|
||||||
b4_percent_define_get([[api.location.include]],
|
b4_percent_define_get([[api.location.include]],
|
||||||
["b4_dir_prefix[]b4_location_file"]))
|
["b4_mapped_dir_prefix[]b4_location_file"]))
|
||||||
m4_define([b4_location_path],
|
m4_define([b4_location_path],
|
||||||
m4_substr(m4_defn([b4_location_path]), 1, m4_eval(m4_len(m4_defn([b4_location_path])) - 2)))
|
m4_substr(m4_defn([b4_location_path]), 1, m4_eval(m4_len(m4_defn([b4_location_path])) - 2)))
|
||||||
])
|
])
|
||||||
@@ -63,11 +63,13 @@ m4_define([b4_location_define],
|
|||||||
class position
|
class position
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
/// Type for file name.
|
||||||
|
typedef ]b4_percent_define_get([[api.filename.type]])[ filename_type;
|
||||||
/// Type for line and column numbers.
|
/// Type for line and column numbers.
|
||||||
typedef int counter_type;
|
typedef int counter_type;
|
||||||
]m4_ifdef([b4_location_constructors], [[
|
]m4_ifdef([b4_location_constructors], [[
|
||||||
/// Construct a position.
|
/// Construct a position.
|
||||||
explicit position (]b4_percent_define_get([[filename_type]])[* f = YY_NULLPTR,
|
explicit position (filename_type* f = YY_NULLPTR,
|
||||||
counter_type l = ]b4_location_initial_line[,
|
counter_type l = ]b4_location_initial_line[,
|
||||||
counter_type c = ]b4_location_initial_column[)
|
counter_type c = ]b4_location_initial_column[)
|
||||||
: filename (f)
|
: filename (f)
|
||||||
@@ -77,7 +79,7 @@ m4_define([b4_location_define],
|
|||||||
|
|
||||||
]])[
|
]])[
|
||||||
/// Initialization.
|
/// Initialization.
|
||||||
void initialize (]b4_percent_define_get([[filename_type]])[* fn = YY_NULLPTR,
|
void initialize (filename_type* fn = YY_NULLPTR,
|
||||||
counter_type l = ]b4_location_initial_line[,
|
counter_type l = ]b4_location_initial_line[,
|
||||||
counter_type c = ]b4_location_initial_column[)
|
counter_type c = ]b4_location_initial_column[)
|
||||||
{
|
{
|
||||||
@@ -106,7 +108,7 @@ m4_define([b4_location_define],
|
|||||||
/** \} */
|
/** \} */
|
||||||
|
|
||||||
/// File name to which this position refers.
|
/// File name to which this position refers.
|
||||||
]b4_percent_define_get([[filename_type]])[* filename;
|
filename_type* filename;
|
||||||
/// Current line number.
|
/// Current line number.
|
||||||
counter_type line;
|
counter_type line;
|
||||||
/// Current column number.
|
/// Current column number.
|
||||||
@@ -184,6 +186,8 @@ m4_define([b4_location_define],
|
|||||||
class location
|
class location
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
/// Type for file name.
|
||||||
|
typedef position::filename_type filename_type;
|
||||||
/// Type for line and column numbers.
|
/// Type for line and column numbers.
|
||||||
typedef position::counter_type counter_type;
|
typedef position::counter_type counter_type;
|
||||||
]m4_ifdef([b4_location_constructors], [
|
]m4_ifdef([b4_location_constructors], [
|
||||||
@@ -200,7 +204,7 @@ m4_define([b4_location_define],
|
|||||||
{}
|
{}
|
||||||
|
|
||||||
/// Construct a 0-width location in \a f, \a l, \a c.
|
/// Construct a 0-width location in \a f, \a l, \a c.
|
||||||
explicit location (]b4_percent_define_get([[filename_type]])[* f,
|
explicit location (filename_type* f,
|
||||||
counter_type l = ]b4_location_initial_line[,
|
counter_type l = ]b4_location_initial_line[,
|
||||||
counter_type c = ]b4_location_initial_column[)
|
counter_type c = ]b4_location_initial_column[)
|
||||||
: begin (f, l, c)
|
: begin (f, l, c)
|
||||||
@@ -209,7 +213,7 @@ m4_define([b4_location_define],
|
|||||||
|
|
||||||
])[
|
])[
|
||||||
/// Initialization.
|
/// Initialization.
|
||||||
void initialize (]b4_percent_define_get([[filename_type]])[* f = YY_NULLPTR,
|
void initialize (filename_type* f = YY_NULLPTR,
|
||||||
counter_type l = ]b4_location_initial_line[,
|
counter_type l = ]b4_location_initial_line[,
|
||||||
counter_type c = ]b4_location_initial_column[)
|
counter_type c = ]b4_location_initial_column[)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -41,6 +41,13 @@ m4_define([b4_stack_define],
|
|||||||
: seq_ (n)
|
: seq_ (n)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
#if 201103L <= YY_CPLUSPLUS
|
||||||
|
/// Non copyable.
|
||||||
|
stack (const stack&) = delete;
|
||||||
|
/// Non copyable.
|
||||||
|
stack& operator= (const stack&) = delete;
|
||||||
|
#endif
|
||||||
|
|
||||||
/// Random access.
|
/// Random access.
|
||||||
///
|
///
|
||||||
/// Index 0 returns the topmost element.
|
/// Index 0 returns the topmost element.
|
||||||
@@ -126,8 +133,12 @@ m4_define([b4_stack_define],
|
|||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
#if YY_CPLUSPLUS < 201103L
|
||||||
|
/// Non copyable.
|
||||||
stack (const stack&);
|
stack (const stack&);
|
||||||
|
/// Non copyable.
|
||||||
stack& operator= (const stack&);
|
stack& operator= (const stack&);
|
||||||
|
#endif
|
||||||
/// The wrapped container.
|
/// The wrapped container.
|
||||||
S seq_;
|
S seq_;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1,2 @@
|
|||||||
|
dnl GNU M4 treats -dV in a position-independent manner.
|
||||||
|
m4_debugmode(V)m4_traceon()dnl
|
||||||
@@ -115,6 +115,13 @@ m4_define([b4_value_type_declare],
|
|||||||
new (yyas_<T> ()) T (YY_MOVE (t));
|
new (yyas_<T> ()) T (YY_MOVE (t));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 201103L <= YY_CPLUSPLUS
|
||||||
|
/// Non copyable.
|
||||||
|
semantic_type (const self_type&) = delete;
|
||||||
|
/// Non copyable.
|
||||||
|
self_type& operator= (const self_type&) = delete;
|
||||||
|
#endif
|
||||||
|
|
||||||
/// Destruction, allowed only if empty.
|
/// Destruction, allowed only if empty.
|
||||||
~semantic_type () YY_NOEXCEPT
|
~semantic_type () YY_NOEXCEPT
|
||||||
{]b4_parse_assert_if([
|
{]b4_parse_assert_if([
|
||||||
@@ -258,9 +265,12 @@ m4_define([b4_value_type_declare],
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// Prohibit blind copies.
|
#if YY_CPLUSPLUS < 201103L
|
||||||
self_type& operator= (const self_type&);
|
/// Non copyable.
|
||||||
semantic_type (const self_type&);
|
semantic_type (const self_type&);
|
||||||
|
/// Non copyable.
|
||||||
|
self_type& operator= (const self_type&);
|
||||||
|
#endif
|
||||||
|
|
||||||
/// Accessor to raw memory as \a T.
|
/// Accessor to raw memory as \a T.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@@ -382,7 +392,7 @@ m4_define([_b4_type_clause],
|
|||||||
[b4_symbol_if([$1], [is_token],
|
[b4_symbol_if([$1], [is_token],
|
||||||
[b4_symbol_if([$1], [has_id],
|
[b4_symbol_if([$1], [has_id],
|
||||||
[tok == token::b4_symbol([$1], [id])],
|
[tok == token::b4_symbol([$1], [id])],
|
||||||
[tok == b4_symbol([$1], [user_number])])])])
|
[tok == b4_symbol([$1], [code])])])])
|
||||||
|
|
||||||
|
|
||||||
# _b4_token_constructor_define(SYMBOL-NUM...)
|
# _b4_token_constructor_define(SYMBOL-NUM...)
|
||||||
|
|||||||
+108
-145
@@ -48,6 +48,10 @@ m4_define([b4_pure_if],
|
|||||||
## api.push-pull. ##
|
## api.push-pull. ##
|
||||||
## --------------- ##
|
## --------------- ##
|
||||||
|
|
||||||
|
# b4_pull_if, b4_push_if
|
||||||
|
# ----------------------
|
||||||
|
# Whether the pull/push APIs are needed. Both can be enabled.
|
||||||
|
|
||||||
b4_percent_define_default([[api.push-pull]], [[pull]])
|
b4_percent_define_default([[api.push-pull]], [[pull]])
|
||||||
b4_percent_define_check_values([[[[api.push-pull]],
|
b4_percent_define_check_values([[[[api.push-pull]],
|
||||||
[[pull]], [[push]], [[both]]]])
|
[[pull]], [[push]], [[both]]]])
|
||||||
@@ -132,6 +136,7 @@ m4_define([b4_rhs_value],
|
|||||||
# b4_lhs_location()
|
# b4_lhs_location()
|
||||||
# -----------------
|
# -----------------
|
||||||
# Expansion of @$.
|
# Expansion of @$.
|
||||||
|
# Overparenthetized to avoid obscure problems with "foo$$bar = foo$1bar".
|
||||||
m4_define([b4_lhs_location],
|
m4_define([b4_lhs_location],
|
||||||
[(yyloc)])
|
[(yyloc)])
|
||||||
|
|
||||||
@@ -140,6 +145,7 @@ m4_define([b4_lhs_location],
|
|||||||
# ---------------------------------
|
# ---------------------------------
|
||||||
# Expansion of @POS, where the current rule has RULE-LENGTH symbols
|
# Expansion of @POS, where the current rule has RULE-LENGTH symbols
|
||||||
# on RHS.
|
# on RHS.
|
||||||
|
# Overparenthetized to avoid obscure problems with "foo$$bar = foo$1bar".
|
||||||
m4_define([b4_rhs_location],
|
m4_define([b4_rhs_location],
|
||||||
[(yylsp@{b4_subtract([$2], [$1])@})])
|
[(yylsp@{b4_subtract([$2], [$1])@})])
|
||||||
|
|
||||||
@@ -153,7 +159,7 @@ m4_define([b4_rhs_location],
|
|||||||
# Declare the variables that are global, or local to YYPARSE if
|
# Declare the variables that are global, or local to YYPARSE if
|
||||||
# pure-parser.
|
# pure-parser.
|
||||||
m4_define([b4_declare_scanner_communication_variables], [[
|
m4_define([b4_declare_scanner_communication_variables], [[
|
||||||
/* The lookahead symbol. */
|
/* Lookahead token kind. */
|
||||||
int yychar;
|
int yychar;
|
||||||
|
|
||||||
]b4_pure_if([[
|
]b4_pure_if([[
|
||||||
@@ -174,68 +180,47 @@ YYLTYPE yylloc]b4_yyloc_default[;]])[
|
|||||||
int yynerrs;]])])
|
int yynerrs;]])])
|
||||||
|
|
||||||
|
|
||||||
# b4_declare_parser_state_variables
|
# b4_declare_parser_state_variables([INIT])
|
||||||
# ---------------------------------
|
# -----------------------------------------
|
||||||
# Declare all the variables that are needed to maintain the parser state
|
# Declare all the variables that are needed to maintain the parser state
|
||||||
# between calls to yypush_parse.
|
# between calls to yypush_parse.
|
||||||
|
# If INIT is non-null, initialize these variables.
|
||||||
m4_define([b4_declare_parser_state_variables],
|
m4_define([b4_declare_parser_state_variables],
|
||||||
[b4_pure_if([[
|
[b4_pure_if([[
|
||||||
/* Number of syntax errors so far. */
|
/* Number of syntax errors so far. */
|
||||||
int yynerrs;
|
int yynerrs]m4_ifval([$1], [ = 0])[;
|
||||||
]])[
|
]])[
|
||||||
yy_state_fast_t yystate;
|
yy_state_fast_t yystate]m4_ifval([$1], [ = 0])[;
|
||||||
/* Number of tokens to shift before error messages enabled. */
|
/* Number of tokens to shift before error messages enabled. */
|
||||||
int yyerrstatus;
|
int yyerrstatus]m4_ifval([$1], [ = 0])[;
|
||||||
|
|
||||||
/* The stacks and their tools:
|
/* Refer to the stacks through separate pointers, to allow yyoverflow
|
||||||
'yyss': related to states.
|
|
||||||
'yyvs': related to semantic values.]b4_locations_if([[
|
|
||||||
'yyls': related to locations.]])[
|
|
||||||
|
|
||||||
Refer to the stacks through separate pointers, to allow yyoverflow
|
|
||||||
to reallocate them elsewhere. */
|
to reallocate them elsewhere. */
|
||||||
|
|
||||||
/* Their size. */
|
/* Their size. */
|
||||||
YYPTRDIFF_T yystacksize;
|
YYPTRDIFF_T yystacksize]m4_ifval([$1], [ = YYINITDEPTH])[;
|
||||||
|
|
||||||
/* The state stack. */
|
/* The state stack: array, bottom, top. */
|
||||||
yy_state_t yyssa[YYINITDEPTH];
|
yy_state_t yyssa[YYINITDEPTH];
|
||||||
yy_state_t *yyss;
|
yy_state_t *yyss]m4_ifval([$1], [ = yyssa])[;
|
||||||
yy_state_t *yyssp;
|
yy_state_t *yyssp]m4_ifval([$1], [ = yyss])[;
|
||||||
|
|
||||||
/* The semantic value stack. */
|
/* The semantic value stack: array, bottom, top. */
|
||||||
YYSTYPE yyvsa[YYINITDEPTH];
|
YYSTYPE yyvsa[YYINITDEPTH];
|
||||||
YYSTYPE *yyvs;
|
YYSTYPE *yyvs]m4_ifval([$1], [ = yyvsa])[;
|
||||||
YYSTYPE *yyvsp;]b4_locations_if([[
|
YYSTYPE *yyvsp]m4_ifval([$1], [ = yyvs])[;]b4_locations_if([[
|
||||||
|
|
||||||
/* The location stack. */
|
/* The location stack: array, bottom, top. */
|
||||||
YYLTYPE yylsa[YYINITDEPTH];
|
YYLTYPE yylsa[YYINITDEPTH];
|
||||||
YYLTYPE *yyls;
|
YYLTYPE *yyls]m4_ifval([$1], [ = yylsa])[;
|
||||||
YYLTYPE *yylsp;]])[]b4_lac_if([[
|
YYLTYPE *yylsp]m4_ifval([$1], [ = yyls])[;]])[]b4_lac_if([[
|
||||||
|
|
||||||
yy_state_t yyesa@{]b4_percent_define_get([[parse.lac.es-capacity-initial]])[@};
|
yy_state_t yyesa@{]b4_percent_define_get([[parse.lac.es-capacity-initial]])[@};
|
||||||
yy_state_t *yyes;
|
yy_state_t *yyes]m4_ifval([$1], [ = yyesa])[;
|
||||||
YYPTRDIFF_T yyes_capacity;]])])
|
YYPTRDIFF_T yyes_capacity][]m4_ifval([$1],
|
||||||
|
[m4_do([ = b4_percent_define_get([[parse.lac.es-capacity-initial]]) < YYMAXDEPTH],
|
||||||
|
[ ? b4_percent_define_get([[parse.lac.es-capacity-initial]])],
|
||||||
# b4_initialize_parser_state_variables
|
[ : YYMAXDEPTH])])[;]])])
|
||||||
# ------------------------------------
|
|
||||||
# Initialize these variables.
|
|
||||||
m4_define([b4_initialize_parser_state_variables],
|
|
||||||
[[ yynerrs = 0;
|
|
||||||
yystate = 0;
|
|
||||||
yyerrstatus = 0;
|
|
||||||
|
|
||||||
yystacksize = YYINITDEPTH;
|
|
||||||
yyssp = yyss = yyssa;
|
|
||||||
yyvsp = yyvs = yyvsa;]b4_locations_if([[
|
|
||||||
yylsp = yyls = yylsa;]])[]b4_lac_if([[
|
|
||||||
|
|
||||||
yyes = yyesa;
|
|
||||||
yyes_capacity = ]b4_percent_define_get([[parse.lac.es-capacity-initial]])[;
|
|
||||||
if (YYMAXDEPTH < yyes_capacity)
|
|
||||||
yyes_capacity = YYMAXDEPTH;]])[
|
|
||||||
]])
|
|
||||||
|
|
||||||
|
|
||||||
m4_define([b4_macro_define],
|
m4_define([b4_macro_define],
|
||||||
@@ -311,14 +296,14 @@ m4_define([b4_declare_yyparse],
|
|||||||
# Declaration that might either go into the header (if --defines)
|
# Declaration that might either go into the header (if --defines)
|
||||||
# or open coded in the parser body.
|
# or open coded in the parser body.
|
||||||
m4_define([b4_shared_declarations],
|
m4_define([b4_shared_declarations],
|
||||||
[b4_cpp_guard_open([b4_spec_header_file])[
|
[b4_cpp_guard_open([b4_spec_mapped_header_file])[
|
||||||
]b4_declare_yydebug[
|
]b4_declare_yydebug[
|
||||||
]b4_percent_code_get([[requires]])[
|
]b4_percent_code_get([[requires]])[
|
||||||
]b4_token_enums_defines[
|
]b4_token_enums_defines[
|
||||||
]b4_declare_yylstype[
|
]b4_declare_yylstype[
|
||||||
]b4_declare_yyparse[
|
]b4_declare_yyparse[
|
||||||
]b4_percent_code_get([[provides]])[
|
]b4_percent_code_get([[provides]])[
|
||||||
]b4_cpp_guard_close([b4_spec_header_file])[]dnl
|
]b4_cpp_guard_close([b4_spec_mapped_header_file])[]dnl
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|
||||||
@@ -333,7 +318,7 @@ m4_define([b4_header_include_if],
|
|||||||
[$2])],
|
[$2])],
|
||||||
[$2])])
|
[$2])])
|
||||||
|
|
||||||
m4_if(b4_spec_header_file, [[y.tab.h]],
|
m4_if(b4_spec_header_file, [y.tab.h], [],
|
||||||
[b4_percent_define_default([[api.header.include]],
|
[b4_percent_define_default([[api.header.include]],
|
||||||
[["@basename(]b4_spec_header_file[@)"]])])
|
[["@basename(]b4_spec_header_file[@)"]])])
|
||||||
|
|
||||||
@@ -401,50 +386,10 @@ m4_if(b4_api_prefix, [yy], [],
|
|||||||
]b4_declare_symbol_enum[
|
]b4_declare_symbol_enum[
|
||||||
|
|
||||||
]b4_user_post_prologue[
|
]b4_user_post_prologue[
|
||||||
]b4_percent_code_get[]dnl
|
]b4_percent_code_get[
|
||||||
|
|
||||||
[#ifdef short
|
|
||||||
# undef short
|
|
||||||
#endif
|
|
||||||
|
|
||||||
]b4_c99_int_type_define[
|
]b4_c99_int_type_define[
|
||||||
|
|
||||||
#ifndef YYPTRDIFF_T
|
]b4_sizes_types_define[
|
||||||
# if defined __PTRDIFF_TYPE__ && defined __PTRDIFF_MAX__
|
|
||||||
# define YYPTRDIFF_T __PTRDIFF_TYPE__
|
|
||||||
# define YYPTRDIFF_MAXIMUM __PTRDIFF_MAX__
|
|
||||||
# elif defined PTRDIFF_MAX
|
|
||||||
# ifndef ptrdiff_t
|
|
||||||
# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
|
|
||||||
# endif
|
|
||||||
# define YYPTRDIFF_T ptrdiff_t
|
|
||||||
# define YYPTRDIFF_MAXIMUM PTRDIFF_MAX
|
|
||||||
# else
|
|
||||||
# define YYPTRDIFF_T long
|
|
||||||
# define YYPTRDIFF_MAXIMUM LONG_MAX
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef YYSIZE_T
|
|
||||||
# ifdef __SIZE_TYPE__
|
|
||||||
# define YYSIZE_T __SIZE_TYPE__
|
|
||||||
# elif defined size_t
|
|
||||||
# define YYSIZE_T size_t
|
|
||||||
# elif defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__
|
|
||||||
# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
|
|
||||||
# define YYSIZE_T size_t
|
|
||||||
# else
|
|
||||||
# define YYSIZE_T unsigned
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define YYSIZE_MAXIMUM \
|
|
||||||
YY_CAST (YYPTRDIFF_T, \
|
|
||||||
(YYPTRDIFF_MAXIMUM < YY_CAST (YYSIZE_T, -1) \
|
|
||||||
? YYPTRDIFF_MAXIMUM \
|
|
||||||
: YY_CAST (YYSIZE_T, -1)))
|
|
||||||
|
|
||||||
#define YYSIZEOF(X) YY_CAST (YYPTRDIFF_T, sizeof (X))
|
|
||||||
|
|
||||||
/* Stored state numbers (used for stacks). */
|
/* Stored state numbers (used for stacks). */
|
||||||
typedef ]b4_int_type(0, m4_eval(b4_states_number - 1))[ yy_state_t;
|
typedef ]b4_int_type(0, m4_eval(b4_states_number - 1))[ yy_state_t;
|
||||||
@@ -630,7 +575,8 @@ union yyalloc
|
|||||||
/* YYNSTATES -- Number of states. */
|
/* YYNSTATES -- Number of states. */
|
||||||
#define YYNSTATES ]b4_states_number[
|
#define YYNSTATES ]b4_states_number[
|
||||||
|
|
||||||
#define YYMAXUTOK ]b4_user_token_number_max[
|
/* YYMAXUTOK -- Last valid token kind. */
|
||||||
|
#define YYMAXUTOK ]b4_code_max[
|
||||||
|
|
||||||
|
|
||||||
/* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM
|
/* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM
|
||||||
@@ -826,9 +772,8 @@ yy_reduce_print (yy_state_t *yyssp, YYSTYPE *yyvsp,]b4_locations_if([[ YYLTYPE *
|
|||||||
YYFPRINTF (stderr, " $%d = ", yyi + 1);
|
YYFPRINTF (stderr, " $%d = ", yyi + 1);
|
||||||
yy_symbol_print (stderr,
|
yy_symbol_print (stderr,
|
||||||
YY_ACCESSING_SYMBOL (+yyssp[yyi + 1 - yynrhs]),
|
YY_ACCESSING_SYMBOL (+yyssp[yyi + 1 - yynrhs]),
|
||||||
&]b4_rhs_value(yynrhs, yyi + 1)[
|
&]b4_rhs_value(yynrhs, yyi + 1)[]b4_locations_if([,
|
||||||
]b4_locations_if([, &]b4_rhs_location(yynrhs, yyi + 1))[]dnl
|
&]b4_rhs_location(yynrhs, yyi + 1))[]b4_user_args[);
|
||||||
b4_user_args[);
|
|
||||||
YYFPRINTF (stderr, "\n");
|
YYFPRINTF (stderr, "\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -868,7 +813,8 @@ int yydebug;
|
|||||||
/* Parser data structure. */
|
/* Parser data structure. */
|
||||||
struct yypstate
|
struct yypstate
|
||||||
{]b4_declare_parser_state_variables[
|
{]b4_declare_parser_state_variables[
|
||||||
/* Whether this instance has not started parsing yet. */
|
/* Whether this instance has not started parsing yet.
|
||||||
|
* If 2, it corresponds to a finished parsing. */
|
||||||
int yynew;
|
int yynew;
|
||||||
};]b4_pure_if([], [[
|
};]b4_pure_if([], [[
|
||||||
|
|
||||||
@@ -1197,6 +1143,8 @@ yypcontext_expected_tokens (const yypcontext_t *yyctx,
|
|||||||
yyarg[yycount++] = YY_CAST (yysymbol_kind_t, yyx);
|
yyarg[yycount++] = YY_CAST (yysymbol_kind_t, yyx);
|
||||||
}
|
}
|
||||||
}]])[
|
}]])[
|
||||||
|
if (yyarg && yycount == 0 && 0 < yyargn)
|
||||||
|
yyarg[0] = ]b4_symbol(-2, kind)[;
|
||||||
return yycount;
|
return yycount;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1481,49 +1429,54 @@ yysyntax_error (YYPTRDIFF_T *yymsg_alloc, char **yymsg,
|
|||||||
int
|
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 yypull_parse (YY_NULLPTR]b4_user_args[);
|
yypstate *yyps = yypstate_new ();
|
||||||
|
if (!yyps)
|
||||||
|
{]b4_pure_if([b4_locations_if([[
|
||||||
|
static YYLTYPE yyloc_default][]b4_yyloc_default[;
|
||||||
|
YYLTYPE yylloc = yyloc_default;]])[
|
||||||
|
yyerror (]b4_yyerror_args[YY_("memory exhausted"));]], [[
|
||||||
|
if (!yypstate_allocated)
|
||||||
|
yyerror (]b4_yyerror_args[YY_("memory exhausted"));]])[
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
int yystatus = yypull_parse (yyps]b4_user_args[);
|
||||||
|
yypstate_delete (yyps);
|
||||||
|
return yystatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
yypull_parse (yypstate *yyps]b4_user_formals[)
|
yypull_parse (yypstate *yyps]b4_user_formals[)
|
||||||
{]b4_pure_if([b4_locations_if([[
|
{
|
||||||
|
YY_ASSERT (yyps);]b4_pure_if([b4_locations_if([[
|
||||||
static YYLTYPE yyloc_default][]b4_yyloc_default[;
|
static YYLTYPE yyloc_default][]b4_yyloc_default[;
|
||||||
YYLTYPE yylloc = yyloc_default;]])])[
|
YYLTYPE yylloc = yyloc_default;]])])[
|
||||||
yypstate *yyps_local;
|
|
||||||
if (yyps)
|
|
||||||
yyps_local = yyps;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
yyps_local = yypstate_new ();
|
|
||||||
if (!yyps_local)
|
|
||||||
{]b4_pure_if([[
|
|
||||||
yyerror (]b4_yyerror_args[YY_("memory exhausted"));]], [[
|
|
||||||
if (!yypstate_allocated)
|
|
||||||
yyerror (]b4_yyerror_args[YY_("memory exhausted"));]])[
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
int yystatus;
|
int yystatus;
|
||||||
do {
|
do {
|
||||||
]b4_pure_if([[ YYSTYPE yylval;
|
]b4_pure_if([[ YYSTYPE yylval;
|
||||||
int ]])[yychar = ]b4_lex[;
|
int ]])[yychar = ]b4_lex[;
|
||||||
yystatus = yypush_parse (yyps_local]b4_pure_if([[, yychar, &yylval]b4_locations_if([[, &yylloc]])])m4_ifset([b4_parse_param], [, b4_args(b4_parse_param)])[);
|
yystatus = yypush_parse (yyps]b4_pure_if([[, yychar, &yylval]b4_locations_if([[, &yylloc]])])m4_ifset([b4_parse_param], [, b4_args(b4_parse_param)])[);
|
||||||
} while (yystatus == YYPUSH_MORE);
|
} while (yystatus == YYPUSH_MORE);
|
||||||
if (!yyps)
|
|
||||||
yypstate_delete (yyps_local);
|
|
||||||
return yystatus;
|
return yystatus;
|
||||||
}]])[
|
}]])[
|
||||||
|
|
||||||
]b4_parse_state_variable_macros([b4_pstate_macro_define])[
|
]b4_parse_state_variable_macros([b4_pstate_macro_define])[
|
||||||
|
|
||||||
/* Initialize the parser data structure. */
|
/* Initialize the parser data structure. */
|
||||||
void
|
static void
|
||||||
yypstate_clear (yypstate *yyps)
|
yypstate_clear (yypstate *yyps)
|
||||||
{
|
{
|
||||||
]b4_initialize_parser_state_variables[
|
yynerrs = 0;
|
||||||
|
yystate = 0;
|
||||||
|
yyerrstatus = 0;
|
||||||
|
|
||||||
|
yyssp = yyss;
|
||||||
|
yyvsp = yyvs;]b4_locations_if([[
|
||||||
|
yylsp = yyls;]])[
|
||||||
|
|
||||||
/* Initialize the state stack, in case yypcontext_expected_tokens is
|
/* Initialize the state stack, in case yypcontext_expected_tokens is
|
||||||
called before the first call to yyparse. */
|
called before the first call to yyparse. */
|
||||||
*yyssp = 0;
|
*yyssp = 0;
|
||||||
|
yyps->yynew = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize the parser data structure. */
|
/* Initialize the parser data structure. */
|
||||||
@@ -1535,9 +1488,16 @@ yypstate_new (void)
|
|||||||
return YY_NULLPTR;]])[
|
return YY_NULLPTR;]])[
|
||||||
yyps = YY_CAST (yypstate *, malloc (sizeof *yyps));
|
yyps = YY_CAST (yypstate *, malloc (sizeof *yyps));
|
||||||
if (!yyps)
|
if (!yyps)
|
||||||
return YY_NULLPTR;
|
return YY_NULLPTR;]b4_pure_if([], [[
|
||||||
yyps->yynew = 1;]b4_pure_if([], [[
|
|
||||||
yypstate_allocated = 1;]])[
|
yypstate_allocated = 1;]])[
|
||||||
|
yystacksize = YYINITDEPTH;
|
||||||
|
yyss = yyssa;
|
||||||
|
yyvs = yyvsa;]b4_locations_if([[
|
||||||
|
yyls = yylsa;]])[]b4_lac_if([[
|
||||||
|
yyes = yyesa;
|
||||||
|
yyes_capacity = ]b4_percent_define_get([[parse.lac.es-capacity-initial]])[;
|
||||||
|
if (YYMAXDEPTH < yyes_capacity)
|
||||||
|
yyes_capacity = YYMAXDEPTH;]])[
|
||||||
yypstate_clear (yyps);
|
yypstate_clear (yyps);
|
||||||
return yyps;
|
return yyps;
|
||||||
}
|
}
|
||||||
@@ -1550,10 +1510,10 @@ yypstate_delete (yypstate *yyps)
|
|||||||
#ifndef yyoverflow
|
#ifndef yyoverflow
|
||||||
/* If the stack was reallocated but the parse did not complete, then the
|
/* If the stack was reallocated but the parse did not complete, then the
|
||||||
stack still needs to be freed. */
|
stack still needs to be freed. */
|
||||||
if (!yyps->yynew && yyss != yyssa)
|
if (yyss != yyssa)
|
||||||
YYSTACK_FREE (yyss);
|
YYSTACK_FREE (yyss);
|
||||||
#endif]b4_lac_if([[
|
#endif]b4_lac_if([[
|
||||||
if (!yyps->yynew && yyes != yyesa)
|
if (yyes != yyesa)
|
||||||
YYSTACK_FREE (yyes);]])[
|
YYSTACK_FREE (yyes);]])[
|
||||||
free (yyps);]b4_pure_if([], [[
|
free (yyps);]b4_pure_if([], [[
|
||||||
yypstate_allocated = 0;]])[
|
yypstate_allocated = 0;]])[
|
||||||
@@ -1582,14 +1542,14 @@ yyparse (]m4_ifset([b4_parse_param], [b4_formals(b4_parse_param)], [void])[)]])[
|
|||||||
YYSTYPE yypushed_val = yylval;]b4_locations_if([[
|
YYSTYPE yypushed_val = yylval;]b4_locations_if([[
|
||||||
YYLTYPE yypushed_loc = yylloc;]])
|
YYLTYPE yypushed_loc = yylloc;]])
|
||||||
])],
|
])],
|
||||||
[b4_declare_parser_state_variables
|
[b4_declare_parser_state_variables([init])
|
||||||
])b4_lac_if([[
|
])b4_lac_if([[
|
||||||
/* Whether LAC context is established. A Boolean. */
|
/* Whether LAC context is established. A Boolean. */
|
||||||
int yy_lac_established = 0;]])[
|
int yy_lac_established = 0;]])[
|
||||||
int yyn;
|
int yyn;
|
||||||
/* The return value of yyparse. */
|
/* The return value of yyparse. */
|
||||||
int yyresult;
|
int yyresult;
|
||||||
/* Lookahead token as an internal (translated) token number. */
|
/* Lookahead symbol kind. */
|
||||||
yysymbol_kind_t yytoken = ]b4_symbol(-2, kind)[;
|
yysymbol_kind_t yytoken = ]b4_symbol(-2, kind)[;
|
||||||
/* The variables used to return semantic value and location from the
|
/* The variables used to return semantic value and location from the
|
||||||
action routines. */
|
action routines. */
|
||||||
@@ -1609,14 +1569,19 @@ yyparse (]m4_ifset([b4_parse_param], [b4_formals(b4_parse_param)], [void])[)]])[
|
|||||||
|
|
||||||
/* The number of symbols on the RHS of the reduced rule.
|
/* The number of symbols on the RHS of the reduced rule.
|
||||||
Keep to zero when no symbol should be popped. */
|
Keep to zero when no symbol should be popped. */
|
||||||
int yylen = 0;
|
int yylen = 0;]b4_push_if([[
|
||||||
]b4_push_if([[
|
|
||||||
if (!yyps->yynew)
|
switch (yyps->yynew)
|
||||||
{
|
{
|
||||||
|
case 2:
|
||||||
|
yypstate_clear (yyps);
|
||||||
|
goto case_0;
|
||||||
|
|
||||||
|
case_0:
|
||||||
|
case 0:
|
||||||
yyn = yypact[yystate];
|
yyn = yypact[yystate];
|
||||||
goto yyread_pushed_token;
|
goto yyread_pushed_token;
|
||||||
}]], [
|
}]])[
|
||||||
b4_initialize_parser_state_variables])[
|
|
||||||
|
|
||||||
YYDPRINTF ((stderr, "Starting parse\n"));
|
YYDPRINTF ((stderr, "Starting parse\n"));
|
||||||
|
|
||||||
@@ -2016,7 +1981,7 @@ yyerrorlab:
|
|||||||
yyerrlab1:
|
yyerrlab1:
|
||||||
yyerrstatus = 3; /* Each real token shifted decrements this. */
|
yyerrstatus = 3; /* Each real token shifted decrements this. */
|
||||||
|
|
||||||
// Pop stack until we find a state that shifts the error token.
|
/* Pop stack until we find a state that shifts the error token. */
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
yyn = yypact[yystate];
|
yyn = yypact[yystate];
|
||||||
@@ -2052,10 +2017,8 @@ yyerrlab1:
|
|||||||
YY_IGNORE_MAYBE_UNINITIALIZED_END
|
YY_IGNORE_MAYBE_UNINITIALIZED_END
|
||||||
]b4_locations_if([[
|
]b4_locations_if([[
|
||||||
yyerror_range[2] = yylloc;
|
yyerror_range[2] = yylloc;
|
||||||
/* Using YYLLOC is tempting, but would change the location of
|
++yylsp;
|
||||||
the lookahead. YYLOC is available though. */
|
YYLLOC_DEFAULT (*yylsp, yyerror_range, 2);]])[
|
||||||
YYLLOC_DEFAULT (yyloc, yyerror_range, 2);
|
|
||||||
*++yylsp = yyloc;]])[
|
|
||||||
|
|
||||||
/* Shift the error token. */
|
/* Shift the error token. */
|
||||||
YY_SYMBOL_PRINT ("Shifting", YY_ACCESSING_SYMBOL (yyn), yyvsp, yylsp);
|
YY_SYMBOL_PRINT ("Shifting", YY_ACCESSING_SYMBOL (yyn), yyvsp, yylsp);
|
||||||
@@ -2087,13 +2050,13 @@ yyabortlab:
|
|||||||
yyexhaustedlab:
|
yyexhaustedlab:
|
||||||
yyerror (]b4_yyerror_args[YY_("memory exhausted"));
|
yyerror (]b4_yyerror_args[YY_("memory exhausted"));
|
||||||
yyresult = 2;
|
yyresult = 2;
|
||||||
/* Fall through. */
|
goto yyreturn;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------.
|
/*-------------------------------------------------------.
|
||||||
| yyreturn -- parsing is finished, return the result. |
|
| yyreturn -- parsing is finished, clean up and return. |
|
||||||
`-----------------------------------------------------*/
|
`-------------------------------------------------------*/
|
||||||
yyreturn:
|
yyreturn:
|
||||||
if (yychar != ]b4_symbol(-2, id)[)
|
if (yychar != ]b4_symbol(-2, id)[)
|
||||||
{
|
{
|
||||||
@@ -2112,21 +2075,21 @@ yyreturn:
|
|||||||
yydestruct ("Cleanup: popping",
|
yydestruct ("Cleanup: popping",
|
||||||
YY_ACCESSING_SYMBOL (+*yyssp), yyvsp]b4_locations_if([, yylsp])[]b4_user_args[);
|
YY_ACCESSING_SYMBOL (+*yyssp), yyvsp]b4_locations_if([, yylsp])[]b4_user_args[);
|
||||||
YYPOPSTACK (1);
|
YYPOPSTACK (1);
|
||||||
}
|
}]b4_push_if([[
|
||||||
|
yyps->yynew = 2;
|
||||||
|
goto yypushreturn;
|
||||||
|
|
||||||
|
|
||||||
|
/*-------------------------.
|
||||||
|
| yypushreturn -- return. |
|
||||||
|
`-------------------------*/
|
||||||
|
yypushreturn:]], [[
|
||||||
#ifndef yyoverflow
|
#ifndef yyoverflow
|
||||||
if (yyss != yyssa)
|
if (yyss != yyssa)
|
||||||
YYSTACK_FREE (yyss);
|
YYSTACK_FREE (yyss);
|
||||||
#endif]b4_lac_if([[
|
#endif]b4_lac_if([[
|
||||||
if (yyes != yyesa)
|
if (yyes != yyesa)
|
||||||
YYSTACK_FREE (yyes);]])b4_push_if([[
|
YYSTACK_FREE (yyes);]])])[
|
||||||
yypstate_clear (yyps);
|
|
||||||
yyps->yynew = 1;
|
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------.
|
|
||||||
| yypushreturn -- ask for the next token. |
|
|
||||||
`-----------------------------------------*/
|
|
||||||
yypushreturn:]])[
|
|
||||||
]b4_parse_error_bmatch([detailed\|verbose],
|
]b4_parse_error_bmatch([detailed\|verbose],
|
||||||
[[ if (yymsg != yymsgbuf)
|
[[ if (yymsg != yymsgbuf)
|
||||||
YYSTACK_FREE (yymsg);]])[
|
YYSTACK_FREE (yymsg);]])[
|
||||||
|
|||||||
@@ -159,7 +159,7 @@
|
|||||||
<xsl:param name="prev-rule-number"
|
<xsl:param name="prev-rule-number"
|
||||||
select="preceding-sibling::item[1]/@rule-number"/>
|
select="preceding-sibling::item[1]/@rule-number"/>
|
||||||
<xsl:apply-templates select="key('bison:ruleByNumber', @rule-number)">
|
<xsl:apply-templates select="key('bison:ruleByNumber', @rule-number)">
|
||||||
<xsl:with-param name="point" select="@point"/>
|
<xsl:with-param name="dot" select="@dot"/>
|
||||||
<xsl:with-param name="num" select="@rule-number"/>
|
<xsl:with-param name="num" select="@rule-number"/>
|
||||||
<xsl:with-param name="prev-lhs"
|
<xsl:with-param name="prev-lhs"
|
||||||
select="key('bison:ruleByNumber', $prev-rule-number)/lhs[text()]"
|
select="key('bison:ruleByNumber', $prev-rule-number)/lhs[text()]"
|
||||||
@@ -169,7 +169,7 @@
|
|||||||
</xsl:template>
|
</xsl:template>
|
||||||
|
|
||||||
<xsl:template match="rule">
|
<xsl:template match="rule">
|
||||||
<xsl:param name="point"/>
|
<xsl:param name="dot"/>
|
||||||
<xsl:param name="num"/>
|
<xsl:param name="num"/>
|
||||||
<xsl:param name="prev-lhs"/>
|
<xsl:param name="prev-lhs"/>
|
||||||
<xsl:text> </xsl:text>
|
<xsl:text> </xsl:text>
|
||||||
@@ -198,14 +198,14 @@
|
|||||||
<xsl:text>:</xsl:text>
|
<xsl:text>:</xsl:text>
|
||||||
</xsl:otherwise>
|
</xsl:otherwise>
|
||||||
</xsl:choose>
|
</xsl:choose>
|
||||||
<xsl:if test="$point = 0">
|
<xsl:if test="$dot = 0">
|
||||||
<xsl:text> .</xsl:text>
|
<xsl:text> .</xsl:text>
|
||||||
</xsl:if>
|
</xsl:if>
|
||||||
|
|
||||||
<!-- RHS -->
|
<!-- RHS -->
|
||||||
<xsl:for-each select="rhs/symbol|rhs/empty">
|
<xsl:for-each select="rhs/symbol|rhs/empty">
|
||||||
<xsl:apply-templates select="."/>
|
<xsl:apply-templates select="."/>
|
||||||
<xsl:if test="$point = position()">
|
<xsl:if test="$dot = position()">
|
||||||
<xsl:text> .</xsl:text>
|
<xsl:text> .</xsl:text>
|
||||||
</xsl:if>
|
</xsl:if>
|
||||||
</xsl:for-each>
|
</xsl:for-each>
|
||||||
|
|||||||
+18
-10
@@ -52,7 +52,7 @@
|
|||||||
<xsl:if test="nonterminal[@usefulness='useless-in-grammar']">
|
<xsl:if test="nonterminal[@usefulness='useless-in-grammar']">
|
||||||
<xsl:text>Nonterminals useless in grammar </xsl:text>
|
<xsl:text>Nonterminals useless in grammar </xsl:text>
|
||||||
<xsl:for-each select="nonterminal[@usefulness='useless-in-grammar']">
|
<xsl:for-each select="nonterminal[@usefulness='useless-in-grammar']">
|
||||||
<xsl:text> </xsl:text>
|
<xsl:text> </xsl:text>
|
||||||
<xsl:value-of select="@name"/>
|
<xsl:value-of select="@name"/>
|
||||||
<xsl:text> </xsl:text>
|
<xsl:text> </xsl:text>
|
||||||
</xsl:for-each>
|
</xsl:for-each>
|
||||||
@@ -65,7 +65,7 @@
|
|||||||
<xsl:text>Terminals unused in grammar </xsl:text>
|
<xsl:text>Terminals unused in grammar </xsl:text>
|
||||||
<xsl:for-each select="terminal[@usefulness='unused-in-grammar']">
|
<xsl:for-each select="terminal[@usefulness='unused-in-grammar']">
|
||||||
<xsl:sort select="@symbol-number" data-type="number"/>
|
<xsl:sort select="@symbol-number" data-type="number"/>
|
||||||
<xsl:text> </xsl:text>
|
<xsl:text> </xsl:text>
|
||||||
<xsl:value-of select="@name"/>
|
<xsl:value-of select="@name"/>
|
||||||
<xsl:text> </xsl:text>
|
<xsl:text> </xsl:text>
|
||||||
</xsl:for-each>
|
</xsl:for-each>
|
||||||
@@ -136,6 +136,7 @@
|
|||||||
</xsl:template>
|
</xsl:template>
|
||||||
|
|
||||||
<xsl:template match="terminal">
|
<xsl:template match="terminal">
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
<xsl:value-of select="@name"/>
|
<xsl:value-of select="@name"/>
|
||||||
<xsl:call-template name="line-wrap">
|
<xsl:call-template name="line-wrap">
|
||||||
<xsl:with-param name="first-line-length">
|
<xsl:with-param name="first-line-length">
|
||||||
@@ -148,6 +149,9 @@
|
|||||||
</xsl:with-param>
|
</xsl:with-param>
|
||||||
<xsl:with-param name="line-length" select="66" />
|
<xsl:with-param name="line-length" select="66" />
|
||||||
<xsl:with-param name="text">
|
<xsl:with-param name="text">
|
||||||
|
<xsl:if test="string-length(@type) != 0">
|
||||||
|
<xsl:value-of select="concat(' <', @type, '>')"/>
|
||||||
|
</xsl:if>
|
||||||
<xsl:value-of select="concat(' (', @token-number, ')')"/>
|
<xsl:value-of select="concat(' (', @token-number, ')')"/>
|
||||||
<xsl:for-each select="key('bison:ruleByRhs', @name)">
|
<xsl:for-each select="key('bison:ruleByRhs', @name)">
|
||||||
<xsl:value-of select="concat(' ', @number)"/>
|
<xsl:value-of select="concat(' ', @number)"/>
|
||||||
@@ -157,14 +161,18 @@
|
|||||||
</xsl:template>
|
</xsl:template>
|
||||||
|
|
||||||
<xsl:template match="nonterminal">
|
<xsl:template match="nonterminal">
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
<xsl:value-of select="@name"/>
|
<xsl:value-of select="@name"/>
|
||||||
|
<xsl:if test="string-length(@type) != 0">
|
||||||
|
<xsl:value-of select="concat(' <', @type, '>')"/>
|
||||||
|
</xsl:if>
|
||||||
<xsl:value-of select="concat(' (', @symbol-number, ')')"/>
|
<xsl:value-of select="concat(' (', @symbol-number, ')')"/>
|
||||||
<xsl:text> </xsl:text>
|
<xsl:text> </xsl:text>
|
||||||
<xsl:variable name="output">
|
<xsl:variable name="output">
|
||||||
<xsl:call-template name="line-wrap">
|
<xsl:call-template name="line-wrap">
|
||||||
<xsl:with-param name="line-length" select="66" />
|
<xsl:with-param name="line-length" select="66" />
|
||||||
<xsl:with-param name="text">
|
<xsl:with-param name="text">
|
||||||
<xsl:text> </xsl:text>
|
<xsl:text> </xsl:text>
|
||||||
<xsl:if test="key('bison:ruleByLhs', @name)">
|
<xsl:if test="key('bison:ruleByLhs', @name)">
|
||||||
<xsl:text>on@left:</xsl:text>
|
<xsl:text>on@left:</xsl:text>
|
||||||
<xsl:for-each select="key('bison:ruleByLhs', @name)">
|
<xsl:for-each select="key('bison:ruleByLhs', @name)">
|
||||||
@@ -173,7 +181,7 @@
|
|||||||
</xsl:if>
|
</xsl:if>
|
||||||
<xsl:if test="key('bison:ruleByRhs', @name)">
|
<xsl:if test="key('bison:ruleByRhs', @name)">
|
||||||
<xsl:if test="key('bison:ruleByLhs', @name)">
|
<xsl:if test="key('bison:ruleByLhs', @name)">
|
||||||
<xsl:text>, </xsl:text>
|
<xsl:text> </xsl:text>
|
||||||
</xsl:if>
|
</xsl:if>
|
||||||
<xsl:text>on@right:</xsl:text>
|
<xsl:text>on@right:</xsl:text>
|
||||||
<xsl:for-each select="key('bison:ruleByRhs', @name)">
|
<xsl:for-each select="key('bison:ruleByRhs', @name)">
|
||||||
@@ -300,7 +308,7 @@
|
|||||||
name="prev-lhs"
|
name="prev-lhs"
|
||||||
select="key('bison:ruleByNumber', $prev-rule-number)/lhs[text()]"
|
select="key('bison:ruleByNumber', $prev-rule-number)/lhs[text()]"
|
||||||
/>
|
/>
|
||||||
<xsl:with-param name="point" select="@point"/>
|
<xsl:with-param name="dot" select="@dot"/>
|
||||||
<xsl:with-param name="lookaheads">
|
<xsl:with-param name="lookaheads">
|
||||||
<xsl:apply-templates select="lookaheads"/>
|
<xsl:apply-templates select="lookaheads"/>
|
||||||
</xsl:with-param>
|
</xsl:with-param>
|
||||||
@@ -311,7 +319,7 @@
|
|||||||
<xsl:param name="itemset"/>
|
<xsl:param name="itemset"/>
|
||||||
<xsl:param name="pad"/>
|
<xsl:param name="pad"/>
|
||||||
<xsl:param name="prev-lhs"/>
|
<xsl:param name="prev-lhs"/>
|
||||||
<xsl:param name="point"/>
|
<xsl:param name="dot"/>
|
||||||
<xsl:param name="lookaheads"/>
|
<xsl:param name="lookaheads"/>
|
||||||
|
|
||||||
<xsl:if test="$itemset != 'true' and not($prev-lhs = lhs[text()])">
|
<xsl:if test="$itemset != 'true' and not($prev-lhs = lhs[text()])">
|
||||||
@@ -347,12 +355,12 @@
|
|||||||
|
|
||||||
<!-- RHS -->
|
<!-- RHS -->
|
||||||
<xsl:for-each select="rhs/*">
|
<xsl:for-each select="rhs/*">
|
||||||
<xsl:if test="position() = $point + 1">
|
<xsl:if test="position() = $dot + 1">
|
||||||
<xsl:text> .</xsl:text>
|
<xsl:text> •</xsl:text>
|
||||||
</xsl:if>
|
</xsl:if>
|
||||||
<xsl:apply-templates select="."/>
|
<xsl:apply-templates select="."/>
|
||||||
<xsl:if test="position() = last() and position() = $point">
|
<xsl:if test="position() = last() and position() = $dot">
|
||||||
<xsl:text> .</xsl:text>
|
<xsl:text> •</xsl:text>
|
||||||
</xsl:if>
|
</xsl:if>
|
||||||
</xsl:for-each>
|
</xsl:for-each>
|
||||||
<xsl:if test="$lookaheads">
|
<xsl:if test="$lookaheads">
|
||||||
|
|||||||
+79
-55
@@ -75,7 +75,7 @@
|
|||||||
ol.lower-alpha {
|
ol.lower-alpha {
|
||||||
list-style-type: lower-alpha;
|
list-style-type: lower-alpha;
|
||||||
}
|
}
|
||||||
.point {
|
.dot {
|
||||||
color: #cc0000;
|
color: #cc0000;
|
||||||
}
|
}
|
||||||
#footer {
|
#footer {
|
||||||
@@ -227,6 +227,7 @@
|
|||||||
<xsl:text> </xsl:text>
|
<xsl:text> </xsl:text>
|
||||||
<p class="pre">
|
<p class="pre">
|
||||||
<xsl:call-template name="style-rule-set">
|
<xsl:call-template name="style-rule-set">
|
||||||
|
<xsl:with-param name="anchor" select="'true'" />
|
||||||
<xsl:with-param
|
<xsl:with-param
|
||||||
name="rule-set" select="rules/rule[@usefulness!='useless-in-grammar']"
|
name="rule-set" select="rules/rule[@usefulness!='useless-in-grammar']"
|
||||||
/>
|
/>
|
||||||
@@ -238,9 +239,11 @@
|
|||||||
</xsl:template>
|
</xsl:template>
|
||||||
|
|
||||||
<xsl:template name="style-rule-set">
|
<xsl:template name="style-rule-set">
|
||||||
|
<xsl:param name="anchor"/>
|
||||||
<xsl:param name="rule-set"/>
|
<xsl:param name="rule-set"/>
|
||||||
<xsl:for-each select="$rule-set">
|
<xsl:for-each select="$rule-set">
|
||||||
<xsl:apply-templates select=".">
|
<xsl:apply-templates select=".">
|
||||||
|
<xsl:with-param name="anchor" select="$anchor"/>
|
||||||
<xsl:with-param name="pad" select="'3'"/>
|
<xsl:with-param name="pad" select="'3'"/>
|
||||||
<xsl:with-param name="prev-lhs">
|
<xsl:with-param name="prev-lhs">
|
||||||
<xsl:if test="position()>1">
|
<xsl:if test="position()>1">
|
||||||
@@ -306,9 +309,10 @@
|
|||||||
<xsl:text> Terminals, with rules where they appear</xsl:text>
|
<xsl:text> Terminals, with rules where they appear</xsl:text>
|
||||||
</h3>
|
</h3>
|
||||||
<xsl:text> </xsl:text>
|
<xsl:text> </xsl:text>
|
||||||
<p class="pre">
|
<ul>
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
<xsl:apply-templates select="terminal"/>
|
<xsl:apply-templates select="terminal"/>
|
||||||
</p>
|
</ul>
|
||||||
<xsl:text> </xsl:text>
|
<xsl:text> </xsl:text>
|
||||||
</xsl:template>
|
</xsl:template>
|
||||||
|
|
||||||
@@ -318,41 +322,64 @@
|
|||||||
<xsl:text> Nonterminals, with rules where they appear</xsl:text>
|
<xsl:text> Nonterminals, with rules where they appear</xsl:text>
|
||||||
</h3>
|
</h3>
|
||||||
<xsl:text> </xsl:text>
|
<xsl:text> </xsl:text>
|
||||||
<p class="pre">
|
<ul>
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
<xsl:apply-templates
|
<xsl:apply-templates
|
||||||
select="nonterminal[@usefulness!='useless-in-grammar']"
|
select="nonterminal[@usefulness!='useless-in-grammar']"
|
||||||
/>
|
/>
|
||||||
</p>
|
</ul>
|
||||||
</xsl:template>
|
</xsl:template>
|
||||||
|
|
||||||
<xsl:template match="terminal">
|
<xsl:template match="terminal">
|
||||||
<b><xsl:value-of select="@name"/></b>
|
<xsl:text> </xsl:text>
|
||||||
<xsl:value-of select="concat(' (', @token-number, ')')"/>
|
<li>
|
||||||
<xsl:for-each select="key('bison:ruleByRhs', @name)">
|
<b><xsl:value-of select="@name"/></b>
|
||||||
<xsl:apply-templates select="." mode="number-link"/>
|
<xsl:if test="string-length(@type) != 0">
|
||||||
</xsl:for-each>
|
<xsl:value-of select="concat(' <', @type, '>')"/>
|
||||||
|
</xsl:if>
|
||||||
|
<xsl:value-of select="concat(' (', @token-number, ')')"/>
|
||||||
|
<xsl:for-each select="key('bison:ruleByRhs', @name)">
|
||||||
|
<xsl:apply-templates select="." mode="number-link"/>
|
||||||
|
</xsl:for-each>
|
||||||
|
</li>
|
||||||
<xsl:text> </xsl:text>
|
<xsl:text> </xsl:text>
|
||||||
</xsl:template>
|
</xsl:template>
|
||||||
|
|
||||||
<xsl:template match="nonterminal">
|
<xsl:template match="nonterminal">
|
||||||
<b><xsl:value-of select="@name"/></b>
|
<xsl:text> </xsl:text>
|
||||||
<xsl:value-of select="concat(' (', @symbol-number, ')')"/>
|
<li>
|
||||||
<xsl:text> </xsl:text>
|
<b><xsl:value-of select="@name"/></b>
|
||||||
<xsl:if test="key('bison:ruleByLhs', @name)">
|
<xsl:if test="string-length(@type) != 0">
|
||||||
<xsl:text>on left:</xsl:text>
|
<xsl:value-of select="concat(' <', @type, '>')"/>
|
||||||
<xsl:for-each select="key('bison:ruleByLhs', @name)">
|
|
||||||
<xsl:apply-templates select="." mode="number-link"/>
|
|
||||||
</xsl:for-each>
|
|
||||||
</xsl:if>
|
|
||||||
<xsl:if test="key('bison:ruleByRhs', @name)">
|
|
||||||
<xsl:if test="key('bison:ruleByLhs', @name)">
|
|
||||||
<xsl:text> </xsl:text>
|
|
||||||
</xsl:if>
|
</xsl:if>
|
||||||
<xsl:text>on right:</xsl:text>
|
<xsl:value-of select="concat(' (', @symbol-number, ')')"/>
|
||||||
<xsl:for-each select="key('bison:ruleByRhs', @name)">
|
<xsl:text> </xsl:text>
|
||||||
<xsl:apply-templates select="." mode="number-link"/>
|
<ul>
|
||||||
</xsl:for-each>
|
<xsl:text> </xsl:text>
|
||||||
</xsl:if>
|
<xsl:if test="key('bison:ruleByLhs', @name)">
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
<li>
|
||||||
|
<xsl:text>on left:</xsl:text>
|
||||||
|
<xsl:for-each select="key('bison:ruleByLhs', @name)">
|
||||||
|
<xsl:apply-templates select="." mode="number-link"/>
|
||||||
|
</xsl:for-each>
|
||||||
|
</li>
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
</xsl:if>
|
||||||
|
<xsl:if test="key('bison:ruleByRhs', @name)">
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
<li>
|
||||||
|
<xsl:text>on right:</xsl:text>
|
||||||
|
<xsl:for-each select="key('bison:ruleByRhs', @name)">
|
||||||
|
<xsl:apply-templates select="." mode="number-link"/>
|
||||||
|
</xsl:for-each>
|
||||||
|
</li>
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
</xsl:if>
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
</ul>
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
</li>
|
||||||
<xsl:text> </xsl:text>
|
<xsl:text> </xsl:text>
|
||||||
</xsl:template>
|
</xsl:template>
|
||||||
|
|
||||||
@@ -385,7 +412,7 @@
|
|||||||
<xsl:value-of select="concat('state_', @number)"/>
|
<xsl:value-of select="concat('state_', @number)"/>
|
||||||
</xsl:attribute>
|
</xsl:attribute>
|
||||||
</a>
|
</a>
|
||||||
<xsl:text>state </xsl:text>
|
<xsl:text>State </xsl:text>
|
||||||
<xsl:value-of select="@number"/>
|
<xsl:value-of select="@number"/>
|
||||||
</h3>
|
</h3>
|
||||||
<xsl:text> </xsl:text>
|
<xsl:text> </xsl:text>
|
||||||
@@ -457,35 +484,44 @@
|
|||||||
<xsl:with-param name="prev-lhs"
|
<xsl:with-param name="prev-lhs"
|
||||||
select="key('bison:ruleByNumber', $prev-rule-number)/lhs[text()]"
|
select="key('bison:ruleByNumber', $prev-rule-number)/lhs[text()]"
|
||||||
/>
|
/>
|
||||||
<xsl:with-param name="point" select="@point"/>
|
<xsl:with-param name="dot" select="@dot"/>
|
||||||
<xsl:with-param name="lookaheads">
|
<xsl:with-param name="lookaheads">
|
||||||
<xsl:apply-templates select="lookaheads"/>
|
<xsl:apply-templates select="lookaheads"/>
|
||||||
</xsl:with-param>
|
</xsl:with-param>
|
||||||
</xsl:apply-templates>
|
</xsl:apply-templates>
|
||||||
</xsl:template>
|
</xsl:template>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
anchor = 'true': define as an <a> anchor.
|
||||||
|
itemset = 'true': show the items.
|
||||||
|
-->
|
||||||
<xsl:template match="rule">
|
<xsl:template match="rule">
|
||||||
|
<xsl:param name="anchor"/>
|
||||||
<xsl:param name="itemset"/>
|
<xsl:param name="itemset"/>
|
||||||
<xsl:param name="pad"/>
|
<xsl:param name="pad"/>
|
||||||
<xsl:param name="prev-lhs"/>
|
<xsl:param name="prev-lhs"/>
|
||||||
<xsl:param name="point"/>
|
<xsl:param name="dot"/>
|
||||||
<xsl:param name="lookaheads"/>
|
<xsl:param name="lookaheads"/>
|
||||||
|
|
||||||
<xsl:if test="$itemset != 'true' and not($prev-lhs = lhs[text()])">
|
<xsl:if test="$itemset != 'true' and not($prev-lhs = lhs[text()])">
|
||||||
<xsl:text> </xsl:text>
|
<xsl:text> </xsl:text>
|
||||||
</xsl:if>
|
</xsl:if>
|
||||||
|
|
||||||
<xsl:if test="$itemset != 'true'">
|
|
||||||
<a>
|
|
||||||
<xsl:attribute name="name">
|
|
||||||
<xsl:value-of select="concat('rule_', @number)"/>
|
|
||||||
</xsl:attribute>
|
|
||||||
</a>
|
|
||||||
</xsl:if>
|
|
||||||
<xsl:text> </xsl:text>
|
<xsl:text> </xsl:text>
|
||||||
|
|
||||||
<xsl:choose>
|
<xsl:choose>
|
||||||
<xsl:when test="$itemset = 'true'">
|
<xsl:when test="$anchor = 'true'">
|
||||||
|
<a>
|
||||||
|
<xsl:attribute name="name">
|
||||||
|
<xsl:value-of select="concat('rule_', @number)"/>
|
||||||
|
</xsl:attribute>
|
||||||
|
<xsl:call-template name="lpad">
|
||||||
|
<xsl:with-param name="str" select="string(@number)"/>
|
||||||
|
<xsl:with-param name="pad" select="number($pad)"/>
|
||||||
|
</xsl:call-template>
|
||||||
|
</a>
|
||||||
|
</xsl:when>
|
||||||
|
<xsl:otherwise>
|
||||||
<a>
|
<a>
|
||||||
<xsl:attribute name="href">
|
<xsl:attribute name="href">
|
||||||
<xsl:value-of select="concat('#rule_', @number)"/>
|
<xsl:value-of select="concat('#rule_', @number)"/>
|
||||||
@@ -495,25 +531,13 @@
|
|||||||
<xsl:with-param name="pad" select="number($pad)"/>
|
<xsl:with-param name="pad" select="number($pad)"/>
|
||||||
</xsl:call-template>
|
</xsl:call-template>
|
||||||
</a>
|
</a>
|
||||||
</xsl:when>
|
|
||||||
<xsl:otherwise>
|
|
||||||
<xsl:call-template name="lpad">
|
|
||||||
<xsl:with-param name="str" select="string(@number)"/>
|
|
||||||
<xsl:with-param name="pad" select="number($pad)"/>
|
|
||||||
</xsl:call-template>
|
|
||||||
</xsl:otherwise>
|
</xsl:otherwise>
|
||||||
</xsl:choose>
|
</xsl:choose>
|
||||||
<xsl:text> </xsl:text>
|
<xsl:text> </xsl:text>
|
||||||
|
|
||||||
<!-- LHS -->
|
<!-- LHS -->
|
||||||
<xsl:choose>
|
<xsl:choose>
|
||||||
<xsl:when test="$itemset != 'true' and $prev-lhs = lhs[text()]">
|
<xsl:when test="$prev-lhs = lhs[text()]">
|
||||||
<xsl:call-template name="lpad">
|
|
||||||
<xsl:with-param name="str" select="'|'"/>
|
|
||||||
<xsl:with-param name="pad" select="number(string-length(lhs[text()])) + 2"/>
|
|
||||||
</xsl:call-template>
|
|
||||||
</xsl:when>
|
|
||||||
<xsl:when test="$itemset = 'true' and $prev-lhs = lhs[text()]">
|
|
||||||
<xsl:call-template name="lpad">
|
<xsl:call-template name="lpad">
|
||||||
<xsl:with-param name="str" select="'|'"/>
|
<xsl:with-param name="str" select="'|'"/>
|
||||||
<xsl:with-param name="pad" select="number(string-length(lhs[text()])) + 2"/>
|
<xsl:with-param name="pad" select="number(string-length(lhs[text()])) + 2"/>
|
||||||
@@ -529,14 +553,14 @@
|
|||||||
|
|
||||||
<!-- RHS -->
|
<!-- RHS -->
|
||||||
<xsl:for-each select="rhs/*">
|
<xsl:for-each select="rhs/*">
|
||||||
<xsl:if test="position() = $point + 1">
|
<xsl:if test="position() = $dot + 1">
|
||||||
<xsl:text> </xsl:text>
|
<xsl:text> </xsl:text>
|
||||||
<span class="point">.</span>
|
<span class="dot">•</span>
|
||||||
</xsl:if>
|
</xsl:if>
|
||||||
<xsl:apply-templates select="."/>
|
<xsl:apply-templates select="."/>
|
||||||
<xsl:if test="position() = last() and position() = $point">
|
<xsl:if test="position() = last() and position() = $dot">
|
||||||
<xsl:text> </xsl:text>
|
<xsl:text> </xsl:text>
|
||||||
<span class="point">.</span>
|
<span class="dot">•</span>
|
||||||
</xsl:if>
|
</xsl:if>
|
||||||
</xsl:for-each>
|
</xsl:for-each>
|
||||||
<xsl:if test="$lookaheads">
|
<xsl:if test="$lookaheads">
|
||||||
|
|||||||
+19
-14
@@ -1,4 +1,4 @@
|
|||||||
# Doxyfile 1.8.17
|
# Doxyfile 1.8.18
|
||||||
|
|
||||||
# This file describes the settings to be used by the documentation system
|
# This file describes the settings to be used by the documentation system
|
||||||
# doxygen (www.doxygen.org) for a project.
|
# doxygen (www.doxygen.org) for a project.
|
||||||
@@ -253,12 +253,6 @@ TAB_SIZE = 8
|
|||||||
|
|
||||||
ALIASES =
|
ALIASES =
|
||||||
|
|
||||||
# This tag can be used to specify a number of word-keyword mappings (TCL only).
|
|
||||||
# A mapping has the form "name=value". For example adding "class=itcl::class"
|
|
||||||
# will allow you to use the command class in the itcl::class meaning.
|
|
||||||
|
|
||||||
TCL_SUBST =
|
|
||||||
|
|
||||||
# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
|
# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
|
||||||
# only. Doxygen will then generate output that is more tailored for C. For
|
# only. Doxygen will then generate output that is more tailored for C. For
|
||||||
# instance, some of the names that are used will be different. The list of all
|
# instance, some of the names that are used will be different. The list of all
|
||||||
@@ -300,13 +294,13 @@ OPTIMIZE_OUTPUT_SLICE = NO
|
|||||||
# extension. Doxygen has a built-in mapping, but you can override or extend it
|
# extension. Doxygen has a built-in mapping, but you can override or extend it
|
||||||
# using this tag. The format is ext=language, where ext is a file extension, and
|
# using this tag. The format is ext=language, where ext is a file extension, and
|
||||||
# language is one of the parsers supported by doxygen: IDL, Java, JavaScript,
|
# language is one of the parsers supported by doxygen: IDL, Java, JavaScript,
|
||||||
# Csharp (C#), C, C++, D, PHP, md (Markdown), Objective-C, Python, Slice,
|
# Csharp (C#), C, C++, D, PHP, md (Markdown), Objective-C, Python, Slice, VHDL,
|
||||||
# Fortran (fixed format Fortran: FortranFixed, free formatted Fortran:
|
# Fortran (fixed format Fortran: FortranFixed, free formatted Fortran:
|
||||||
# FortranFree, unknown formatted Fortran: Fortran. In the later case the parser
|
# FortranFree, unknown formatted Fortran: Fortran. In the later case the parser
|
||||||
# tries to guess whether the code is fixed or free formatted code, this is the
|
# tries to guess whether the code is fixed or free formatted code, this is the
|
||||||
# default for Fortran type files), VHDL, tcl. For instance to make doxygen treat
|
# default for Fortran type files). For instance to make doxygen treat .inc files
|
||||||
# .inc files as Fortran files (default is PHP), and .f files as C (default is
|
# as Fortran files (default is PHP), and .f files as C (default is Fortran),
|
||||||
# Fortran), use: inc=Fortran f=C.
|
# use: inc=Fortran f=C.
|
||||||
#
|
#
|
||||||
# Note: For files without extension you can use no_extension as a placeholder.
|
# Note: For files without extension you can use no_extension as a placeholder.
|
||||||
#
|
#
|
||||||
@@ -844,7 +838,7 @@ INPUT_ENCODING = UTF-8
|
|||||||
# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc,
|
# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc,
|
||||||
# *.m, *.markdown, *.md, *.mm, *.dox (to be provided as doxygen C comment),
|
# *.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
|
# *.doc (to be provided as doxygen C comment), *.txt (to be provided as doxygen
|
||||||
# C comment), *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, *.f, *.for, *.tcl, *.vhd,
|
# C comment), *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, *.f18, *.f, *.for, *.vhd,
|
||||||
# *.vhdl, *.ucf, *.qsf and *.ice.
|
# *.vhdl, *.ucf, *.qsf and *.ice.
|
||||||
|
|
||||||
FILE_PATTERNS = *.c \
|
FILE_PATTERNS = *.c \
|
||||||
@@ -1490,6 +1484,17 @@ TREEVIEW_WIDTH = 250
|
|||||||
|
|
||||||
EXT_LINKS_IN_WINDOW = NO
|
EXT_LINKS_IN_WINDOW = NO
|
||||||
|
|
||||||
|
# If the HTML_FORMULA_FORMAT option is set to svg, doxygen will use the pdf2svg
|
||||||
|
# tool (see https://github.com/dawbarton/pdf2svg) or inkscape (see
|
||||||
|
# https://inkscape.org) to generate formulas as SVG images instead of PNGs for
|
||||||
|
# the HTML output. These images will generally look nicer at scaled resolutions.
|
||||||
|
# Possible values are: png The default and svg Looks nicer but requires the
|
||||||
|
# pdf2svg tool.
|
||||||
|
# The default value is: png.
|
||||||
|
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||||
|
|
||||||
|
HTML_FORMULA_FORMAT = png
|
||||||
|
|
||||||
# Use this tag to change the font size of LaTeX formulas included as images in
|
# Use this tag to change the font size of LaTeX formulas included as images in
|
||||||
# the HTML documentation. When you change the font size after a successful
|
# the HTML documentation. When you change the font size after a successful
|
||||||
# doxygen run you need to manually remove any form_*.png images from the HTML
|
# doxygen run you need to manually remove any form_*.png images from the HTML
|
||||||
@@ -1545,7 +1550,7 @@ MATHJAX_FORMAT = HTML-CSS
|
|||||||
# Content Delivery Network so you can quickly see the result without installing
|
# Content Delivery Network so you can quickly see the result without installing
|
||||||
# MathJax. However, it is strongly recommended to install a local copy of
|
# MathJax. However, it is strongly recommended to install a local copy of
|
||||||
# MathJax from https://www.mathjax.org before deployment.
|
# MathJax from https://www.mathjax.org before deployment.
|
||||||
# The default value is: https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/.
|
# The default value is: https://cdn.jsdelivr.net/npm/mathjax@2.
|
||||||
# This tag requires that the tag USE_MATHJAX is set to YES.
|
# This tag requires that the tag USE_MATHJAX is set to YES.
|
||||||
|
|
||||||
MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest
|
MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest
|
||||||
@@ -1715,7 +1720,7 @@ COMPACT_LATEX = NO
|
|||||||
# The default value is: a4.
|
# The default value is: a4.
|
||||||
# This tag requires that the tag GENERATE_LATEX is set to YES.
|
# This tag requires that the tag GENERATE_LATEX is set to YES.
|
||||||
|
|
||||||
PAPER_TYPE = a4wide
|
PAPER_TYPE = a4
|
||||||
|
|
||||||
# The EXTRA_PACKAGES tag can be used to specify one or more LaTeX package names
|
# The EXTRA_PACKAGES tag can be used to specify one or more LaTeX package names
|
||||||
# that should be included in the LaTeX output. The package can be specified just
|
# that should be included in the LaTeX output. The package can be specified just
|
||||||
|
|||||||
+1195
-373
File diff suppressed because it is too large
Load Diff
+23
@@ -0,0 +1,23 @@
|
|||||||
|
%union
|
||||||
|
{
|
||||||
|
int ival;
|
||||||
|
const char *sval;
|
||||||
|
}
|
||||||
|
|
||||||
|
%token <ival> NUM
|
||||||
|
%nterm <ival> exp
|
||||||
|
%token <sval> STR
|
||||||
|
%nterm <sval> useless
|
||||||
|
|
||||||
|
%left '+' '-'
|
||||||
|
%left '*'
|
||||||
|
|
||||||
|
%%
|
||||||
|
exp:
|
||||||
|
exp '+' exp
|
||||||
|
| exp '-' exp
|
||||||
|
| exp '*' exp
|
||||||
|
| exp '/' exp
|
||||||
|
| NUM
|
||||||
|
;
|
||||||
|
useless: STR;
|
||||||
@@ -3,7 +3,7 @@ digraph "reduce.y"
|
|||||||
node [fontname=courier shape=box]
|
node [fontname=courier shape=box]
|
||||||
edge [fontname=courier]
|
edge [fontname=courier]
|
||||||
|
|
||||||
1 [label="State 1\n 3 a: \"0\" . [\".\"]\l 4 b: \"0\" . [\";\"]\l"]
|
1 [label="State 1\n 3 a: \"0\" • [\".\"]\l 4 b: \"0\" • [\";\"]\l"]
|
||||||
1 -> "1R3" [label="" style=solid]
|
1 -> "1R3" [label="" style=solid]
|
||||||
"1R3" [style=filled shape=diamond fillcolor=yellowgreen label="R3"]
|
"1R3" [style=filled shape=diamond fillcolor=yellowgreen label="R3"]
|
||||||
1 -> "1R4" [label="[\";\"]" style=solid]
|
1 -> "1R4" [label="[\";\"]" style=solid]
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
.------------------.
|
.------------------.
|
||||||
| State 1 |
|
| State 1 |
|
||||||
| 3 a: "0" . [";"] |
|
| 3 a: "0" • [";"] |
|
||||||
| 4 b: "0" . ["."] |
|
| 4 b: "0" • ["."] |
|
||||||
`------------------'
|
`------------------'
|
||||||
/ \
|
/ \
|
||||||
/ \ ["."]
|
/ \ ["."]
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ digraph "shift.y"
|
|||||||
node [fontname=courier shape=box]
|
node [fontname=courier shape=box]
|
||||||
edge [fontname=courier]
|
edge [fontname=courier]
|
||||||
|
|
||||||
3 [label="State 3\n 1 exp: a . \".\"\l"]
|
3 [label="State 3\n 1 exp: a • \".\"\l"]
|
||||||
3 -> 6 [style=solid label="\".\""]
|
3 -> 6 [style=solid label="\".\""]
|
||||||
6 [label="State 6\n 1 exp: a \".\" .\l"]
|
6 [label="State 6\n 1 exp: a \".\" •\l"]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
.----------------.
|
.----------------.
|
||||||
| State 3 |
|
| State 3 |
|
||||||
| 1 exp: a . ";" |
|
| 1 exp: a • ";" |
|
||||||
`----------------'
|
`----------------'
|
||||||
|
|
|
|
||||||
| ";"
|
| ";"
|
||||||
@@ -8,5 +8,5 @@
|
|||||||
v
|
v
|
||||||
.----------------.
|
.----------------.
|
||||||
| State 6 |
|
| State 6 |
|
||||||
| 1 exp: a ";" . |
|
| 1 exp: a ";" • |
|
||||||
`----------------'
|
`----------------'
|
||||||
|
|||||||
+9
-9
@@ -2,34 +2,34 @@
|
|||||||
// Report bugs to <[email protected]>.
|
// Report bugs to <[email protected]>.
|
||||||
// Home page: <http://www.gnu.org/software/bison/>.
|
// Home page: <http://www.gnu.org/software/bison/>.
|
||||||
|
|
||||||
digraph "/tmp/fo.y"
|
digraph "example.y"
|
||||||
{
|
{
|
||||||
node [fontname = courier, shape = box, colorscheme = paired6]
|
node [fontname = courier, shape = box, colorscheme = paired6]
|
||||||
edge [fontname = courier]
|
edge [fontname = courier]
|
||||||
|
|
||||||
0 [label="State 0\n\l 0 $accept: . exp $end\l 1 exp: . a \";\"\l 2 | . b \".\"\l 3 a: . \"0\"\l 4 b: . \"0\"\l"]
|
0 [label="State 0\n\l 0 $accept: • exp $end\l 1 exp: • a \";\"\l 2 | • b \".\"\l 3 a: • \"0\"\l 4 b: • \"0\"\l"]
|
||||||
0 -> 1 [style=solid label="\"0\""]
|
0 -> 1 [style=solid label="\"0\""]
|
||||||
0 -> 2 [style=dashed label="exp"]
|
0 -> 2 [style=dashed label="exp"]
|
||||||
0 -> 3 [style=dashed label="a"]
|
0 -> 3 [style=dashed label="a"]
|
||||||
0 -> 4 [style=dashed label="b"]
|
0 -> 4 [style=dashed label="b"]
|
||||||
1 [label="State 1\n\l 3 a: \"0\" . [\";\"]\l 4 b: \"0\" . [\".\"]\l"]
|
1 [label="State 1\n\l 3 a: \"0\" • [\";\"]\l 4 b: \"0\" • [\".\"]\l"]
|
||||||
1 -> "1R3" [style=solid]
|
1 -> "1R3" [style=solid]
|
||||||
"1R3" [label="R3", fillcolor=3, shape=diamond, style=filled]
|
"1R3" [label="R3", fillcolor=3, shape=diamond, style=filled]
|
||||||
1 -> "1R4" [label="[\".\"]", style=solid]
|
1 -> "1R4" [label="[\".\"]", style=solid]
|
||||||
"1R4" [label="R4", fillcolor=3, shape=diamond, style=filled]
|
"1R4" [label="R4", fillcolor=3, shape=diamond, style=filled]
|
||||||
2 [label="State 2\n\l 0 $accept: exp . $end\l"]
|
2 [label="State 2\n\l 0 $accept: exp • $end\l"]
|
||||||
2 -> 5 [style=solid label="$end"]
|
2 -> 5 [style=solid label="$end"]
|
||||||
3 [label="State 3\n\l 1 exp: a . \";\"\l"]
|
3 [label="State 3\n\l 1 exp: a • \";\"\l"]
|
||||||
3 -> 6 [style=solid label="\";\""]
|
3 -> 6 [style=solid label="\";\""]
|
||||||
4 [label="State 4\n\l 2 exp: b . \".\"\l"]
|
4 [label="State 4\n\l 2 exp: b • \".\"\l"]
|
||||||
4 -> 7 [style=solid label="\".\""]
|
4 -> 7 [style=solid label="\".\""]
|
||||||
5 [label="State 5\n\l 0 $accept: exp $end .\l"]
|
5 [label="State 5\n\l 0 $accept: exp $end •\l"]
|
||||||
5 -> "5R0" [style=solid]
|
5 -> "5R0" [style=solid]
|
||||||
"5R0" [label="Acc", fillcolor=1, shape=diamond, style=filled]
|
"5R0" [label="Acc", fillcolor=1, shape=diamond, style=filled]
|
||||||
6 [label="State 6\n\l 1 exp: a \";\" .\l"]
|
6 [label="State 6\n\l 1 exp: a \";\" •\l"]
|
||||||
6 -> "6R1" [style=solid]
|
6 -> "6R1" [style=solid]
|
||||||
"6R1" [label="R1", fillcolor=3, shape=diamond, style=filled]
|
"6R1" [label="R1", fillcolor=3, shape=diamond, style=filled]
|
||||||
7 [label="State 7\n\l 2 exp: b \".\" .\l"]
|
7 [label="State 7\n\l 2 exp: b \".\" •\l"]
|
||||||
7 -> "7R2" [style=solid]
|
7 -> "7R2" [style=solid]
|
||||||
"7R2" [label="R2", fillcolor=3, shape=diamond, style=filled]
|
"7R2" [label="R2", fillcolor=3, shape=diamond, style=filled]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
%%
|
||||||
|
stmt:
|
||||||
|
expr
|
||||||
|
| if_stmt
|
||||||
|
;
|
||||||
|
|
||||||
|
if_stmt:
|
||||||
|
"if" expr "then" stmt
|
||||||
|
| "if" expr "then" stmt "else" stmt
|
||||||
|
;
|
||||||
|
|
||||||
|
expr:
|
||||||
|
"identifier"
|
||||||
+24
-10
@@ -131,7 +131,7 @@ dist_man_MANS = $(top_srcdir)/%D%/bison.1
|
|||||||
EXTRA_DIST += $(dist_man_MANS:.1=.x)
|
EXTRA_DIST += $(dist_man_MANS:.1=.x)
|
||||||
MAINTAINERCLEANFILES += $(dist_man_MANS)
|
MAINTAINERCLEANFILES += $(dist_man_MANS)
|
||||||
|
|
||||||
# Differences to ignore when comparing the man page (the date).
|
# Differences to ignore when comparing man pages (the date).
|
||||||
remove_time_stamp = \
|
remove_time_stamp = \
|
||||||
sed 's/^\(\.TH[^"]*"[^"]*"[^"]*\)"[^"]*"/\1/'
|
sed 's/^\(\.TH[^"]*"[^"]*"[^"]*\)"[^"]*"/\1/'
|
||||||
|
|
||||||
@@ -140,17 +140,31 @@ if ! CROSS_COMPILING
|
|||||||
MAN_DEPS = %D%/bison.help %D%/bison.x $(top_srcdir)/configure
|
MAN_DEPS = %D%/bison.help %D%/bison.x $(top_srcdir)/configure
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
# If we don't have help2man, just touch the target. Maintainers must
|
||||||
|
# have the real thing, so if there's a .git directory, fail hard.
|
||||||
|
#
|
||||||
|
# We shouldn't need this, but on some OS the timestamps in the tarball
|
||||||
|
# leave us no choice. See
|
||||||
|
# https://lists.gnu.org/r/bug-bison/2020-05/msg00055.html.
|
||||||
$(top_srcdir)/%D%/bison.1: $(MAN_DEPS)
|
$(top_srcdir)/%D%/bison.1: $(MAN_DEPS)
|
||||||
$(AM_V_GEN)$(HELP2MAN) \
|
$(AM_V_GEN)if $(HELP2MAN) --version >/dev/null 2>&1; then \
|
||||||
--include=$(top_srcdir)/%D%/bison.x \
|
$(HELP2MAN) \
|
||||||
--output=$@.tmp tests/bison
|
--include=$(top_srcdir)/%D%/bison.x \
|
||||||
$(AM_V_at)if $(remove_time_stamp) $@ >$@a.tmp 2>/dev/null && \
|
--output=$@.tmp tests/bison && \
|
||||||
$(remove_time_stamp) $@.tmp | cmp $@a.tmp - >/dev/null 2>&1; then \
|
{ $(remove_time_stamp) $@ >$@a.tmp || true; } && \
|
||||||
touch $@; \
|
$(remove_time_stamp) $@.tmp >$@b.tmp && \
|
||||||
else \
|
if diff $@a.tmp $@b.tmp >/dev/null 2>&1; then \
|
||||||
mv $@.tmp $@; \
|
touch $@; \
|
||||||
|
else \
|
||||||
|
mv $@.tmp $@; \
|
||||||
|
fi && \
|
||||||
|
rm -f $@*.tmp; \
|
||||||
|
elif test -d $(srcdir)/.git; then \
|
||||||
|
echo >&2 "ERROR: $@: help2man is needed"; \
|
||||||
|
exit 1; \
|
||||||
|
else \
|
||||||
|
touch $@; \
|
||||||
fi
|
fi
|
||||||
$(AM_V_at)rm -f $@*.tmp
|
|
||||||
|
|
||||||
if ENABLE_YACC
|
if ENABLE_YACC
|
||||||
nodist_man_MANS = %D%/yacc.1
|
nodist_man_MANS = %D%/yacc.1
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
%%
|
||||||
|
sequence:
|
||||||
|
%empty
|
||||||
|
| maybeword
|
||||||
|
| sequence "word"
|
||||||
|
;
|
||||||
|
maybeword:
|
||||||
|
%empty
|
||||||
|
| "word"
|
||||||
|
;
|
||||||
-38
@@ -1,38 +0,0 @@
|
|||||||
* bench.pl
|
|
||||||
A primitive Perl script to run benches. Currently its only bench is
|
|
||||||
the usual calculator: it has a lightweight processing part (but not
|
|
||||||
null), so it is really emphasizing the cost of the whole parsing
|
|
||||||
(including scanning and I/O).
|
|
||||||
|
|
||||||
Set the envvars BISON and CC to the programs and flags you want to
|
|
||||||
use. They default to bison and gcc. To run a non-installed bison
|
|
||||||
from a tarball built in _build, I suggest the following.
|
|
||||||
|
|
||||||
BISON=_build/tests/bison CC='gcc -O2' ./bench.pl
|
|
||||||
|
|
||||||
(The _build/tests/bison wrapper makes sure that _build/src/bison will
|
|
||||||
use the tarballs' skeletons, not those already installed as a
|
|
||||||
straightforward use of _build/src/bison would.)
|
|
||||||
|
|
||||||
--
|
|
||||||
|
|
||||||
Copyright (C) 2006, 2009-2015, 2018-2020 Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
This file is part of Bison, the GNU Compiler Compiler.
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
Local Variables:
|
|
||||||
mode: outline
|
|
||||||
End:
|
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
# bench.pl
|
||||||
|
A primitive Perl script to run benches. Currently its only bench is the
|
||||||
|
usual calculator: it has a lightweight processing part (but not null), so it
|
||||||
|
is really emphasizing the cost of the whole parsing (including scanning and
|
||||||
|
I/O).
|
||||||
|
|
||||||
|
Set the envvars `BISON` and `CC` to the programs and flags you want to use.
|
||||||
|
They default to `bison` and `gcc`. To run a non-installed bison from a
|
||||||
|
tarball built in _build, I suggest the following.
|
||||||
|
|
||||||
|
BISON=_build/tests/bison CC='gcc -O2' ./bench.pl
|
||||||
|
|
||||||
|
(The `_build/tests/bison` wrapper makes sure that `_build/src/bison` will
|
||||||
|
use the tarballs' skeletons, not those already installed as a
|
||||||
|
straightforward use of `_build/src/bison` would.)
|
||||||
|
|
||||||
|
<!--
|
||||||
|
|
||||||
|
Local Variables:
|
||||||
|
mode: markdown
|
||||||
|
fill-column: 76
|
||||||
|
ispell-dictionary: "american"
|
||||||
|
End:
|
||||||
|
|
||||||
|
Copyright (C) 2006, 2009-2015, 2018-2020 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of Bison, the GNU Compiler Compiler.
|
||||||
|
|
||||||
|
Permission is granted to copy, distribute and/or modify this document
|
||||||
|
under the terms of the GNU Free Documentation License, Version 1.3 or
|
||||||
|
any later version published by the Free Software Foundation; with no
|
||||||
|
Invariant Sections, with no Front-Cover Texts, and with no Back-Cover
|
||||||
|
Texts. A copy of the license is included in the "GNU Free
|
||||||
|
Documentation License" file as part of this distribution.
|
||||||
|
|
||||||
|
-->
|
||||||
+81
-22
@@ -498,7 +498,8 @@ yylex (void)
|
|||||||
case '5': case '6': case '7': case '8': case '9':
|
case '5': case '6': case '7': case '8': case '9':
|
||||||
{
|
{
|
||||||
int nchars = 0;
|
int nchars = 0;
|
||||||
sscanf (input - 1, "%d%n", &yylval.NUM, &nchars);
|
int n = sscanf (input - 1, "%d%n", &yylval.NUM, &nchars);
|
||||||
|
assert (n == 1);
|
||||||
input += nchars - 1;
|
input += nchars - 1;
|
||||||
return NUM;
|
return NUM;
|
||||||
}
|
}
|
||||||
@@ -775,7 +776,31 @@ sub run ($)
|
|||||||
|
|
||||||
##################################################################
|
##################################################################
|
||||||
|
|
||||||
=item C<compile ($base)>
|
=item C<language ($base)>
|
||||||
|
|
||||||
|
The language to use depending on the %language specification in
|
||||||
|
C<$base.y>: C<c> or C<c++>.
|
||||||
|
|
||||||
|
=cut
|
||||||
|
|
||||||
|
sub language ($)
|
||||||
|
{
|
||||||
|
my ($base) = @_;
|
||||||
|
if ($gbench)
|
||||||
|
{
|
||||||
|
"c++";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
my $language = `sed -ne '/%language "\\(.*\\)"/{s//\\1/;p;q;}' $base.y`;
|
||||||
|
chomp $language;
|
||||||
|
$language eq 'C++' ? "c++" : "c";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
##################################################################
|
||||||
|
|
||||||
|
=item C<compiler ($base)>
|
||||||
|
|
||||||
The compiler to use depending on the %language specification in
|
The compiler to use depending on the %language specification in
|
||||||
C<$base.y>.
|
C<$base.y>.
|
||||||
@@ -785,16 +810,12 @@ C<$base.y>.
|
|||||||
sub compiler ($)
|
sub compiler ($)
|
||||||
{
|
{
|
||||||
my ($base) = @_;
|
my ($base) = @_;
|
||||||
if ($gbench)
|
my %compiler =
|
||||||
{
|
(
|
||||||
$cxx;
|
'c++' => $cxx,
|
||||||
}
|
'c' => $cc,
|
||||||
else
|
);
|
||||||
{
|
$compiler{language ($base)};
|
||||||
my $language = `sed -ne '/%language "\\(.*\\)"/{s//\\1/;p;q;}' $base.y`;
|
|
||||||
chomp $language;
|
|
||||||
$language eq 'C++' ? $cxx : $cc;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
##################################################################
|
##################################################################
|
||||||
@@ -805,21 +826,38 @@ Compile C<$base.y> to an executable.
|
|||||||
|
|
||||||
=cut
|
=cut
|
||||||
|
|
||||||
sub compile ($)
|
sub compile ($$)
|
||||||
{
|
{
|
||||||
my ($base) = @_;
|
my ($makefile, $base) = @_;
|
||||||
my $compiler = compiler ($base);
|
my $compiler = compiler ($base);
|
||||||
|
|
||||||
my $my_bison = `sed -ne '/[/][/] %bison "\\(.*\\)"/{s//\\1/;p;q;}' $base.y`;
|
my $my_bison = `sed -ne '/[/][/] %bison "\\(.*\\)"/{s//\\1/;p;q;}' $base.y`;
|
||||||
chop $my_bison;
|
chop $my_bison;
|
||||||
run ((length $my_bison ? $my_bison : $bison) . " $base.y -o $base.c");
|
my %ext =
|
||||||
|
(
|
||||||
|
'c++' => 'cc',
|
||||||
|
'c' => 'c',
|
||||||
|
);
|
||||||
|
my $ext = $ext{language ($base)};
|
||||||
if ($gbench)
|
if ($gbench)
|
||||||
{
|
{
|
||||||
run "$compiler -c -o $base.o $cflags $base.c";
|
print $makefile <<EOF;
|
||||||
|
$base.$ext: $base.y
|
||||||
|
\t@{[length $my_bison ? $my_bison : $bison]} $base.y -o $base.$ext
|
||||||
|
|
||||||
|
$base.o: $base.$ext
|
||||||
|
\t$compiler -c -o $base.o $cflags $base.$ext
|
||||||
|
EOF
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
run "$compiler -o $base $cflags $base.c";
|
print $makefile <<EOF;
|
||||||
|
$base.$ext: $base.y
|
||||||
|
\t@{[length $my_bison ? $my_bison : $bison]} $base.y -o $base.$ext
|
||||||
|
|
||||||
|
$base: $base.$ext
|
||||||
|
\t$compiler -o $base $cflags $base.$ext
|
||||||
|
EOF
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -849,11 +887,13 @@ sub bench_with_timethese ($@)
|
|||||||
# For each bench, capture the size.
|
# For each bench, capture the size.
|
||||||
my %size;
|
my %size;
|
||||||
|
|
||||||
|
my $makefile = new IO::File ">Makefile";
|
||||||
while (my ($name, $directives) = each %bench)
|
while (my ($name, $directives) = each %bench)
|
||||||
{
|
{
|
||||||
generate_grammar ($grammar, $name, $directives);
|
generate_grammar ($grammar, $name, $directives);
|
||||||
# Compile the executable.
|
# Compile the executable.
|
||||||
compile ($name);
|
compile ($makefile, $name);
|
||||||
|
run "make $name";
|
||||||
$bench{$name} = "system ('./$name');";
|
$bench{$name} = "system ('./$name');";
|
||||||
chop($size{$name} = `wc -c <$name`);
|
chop($size{$name} = `wc -c <$name`);
|
||||||
}
|
}
|
||||||
@@ -906,6 +946,20 @@ sub bench_with_gbenchmark ($@)
|
|||||||
my $readme = new IO::File ">README.md";
|
my $readme = new IO::File ">README.md";
|
||||||
print $readme <<EOF;
|
print $readme <<EOF;
|
||||||
compiler: $compiler $cflags
|
compiler: $compiler $cflags
|
||||||
|
EOF
|
||||||
|
|
||||||
|
my $makefile = new IO::File ">Makefile";
|
||||||
|
print $makefile <<EOF;
|
||||||
|
.PHONY: bench
|
||||||
|
bench: main
|
||||||
|
\t./main \$(BENCHFLAGS) | tee -a README.md
|
||||||
|
|
||||||
|
# Link the bench cases in a different order to run the bench case in a
|
||||||
|
# different order.
|
||||||
|
.PHONY: rand
|
||||||
|
rand:
|
||||||
|
\t-rm main
|
||||||
|
\tmake bench OBJECTS="\$\$(shuf -e \$(OBJECTS) | xargs)"
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
my @obj = ();
|
my @obj = ();
|
||||||
@@ -916,19 +970,24 @@ EOF
|
|||||||
print $m;
|
print $m;
|
||||||
print $readme $m;
|
print $readme $m;
|
||||||
generate_grammar ($grammar, $base, $directive[$i]);
|
generate_grammar ($grammar, $base, $directive[$i]);
|
||||||
compile ($base);
|
compile ($makefile, $base);
|
||||||
push @obj, "$base.o";
|
push @obj, "$base.o";
|
||||||
}
|
}
|
||||||
|
|
||||||
my $out = new IO::File ">main.c";
|
my $out = new IO::File ">main.cc";
|
||||||
print $out <<EOF;
|
print $out <<EOF;
|
||||||
#include <benchmark/benchmark.h>
|
#include <benchmark/benchmark.h>
|
||||||
|
|
||||||
BENCHMARK_MAIN();
|
BENCHMARK_MAIN();
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
run "$compiler -o main $cflags main.c @obj -lbenchmark";
|
print $makefile <<EOF;
|
||||||
run "./main | tee -a README.md";
|
OBJECTS = @{obj}
|
||||||
|
main: \$(OBJECTS)
|
||||||
|
\t$compiler -o main $cflags main.cc \$(OBJECTS) -lbenchmark
|
||||||
|
EOF
|
||||||
|
|
||||||
|
run "make";
|
||||||
}
|
}
|
||||||
|
|
||||||
######################################################################
|
######################################################################
|
||||||
|
|||||||
+2
-1
@@ -14,4 +14,5 @@
|
|||||||
## You should have received a copy of the GNU General Public License
|
## You should have received a copy of the GNU General Public License
|
||||||
## along with this program. If not, see <http://www.gnu.org/licenses/>.
|
## along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
nodist_noinst_SCRIPTS = etc/bench.pl
|
dist_noinst_DATA = %D%/README.md
|
||||||
|
nodist_noinst_SCRIPTS = %D%/bench.pl
|
||||||
|
|||||||
@@ -13,8 +13,8 @@ semantic value.
|
|||||||
|
|
||||||
Run as `./simple`.
|
Run as `./simple`.
|
||||||
|
|
||||||
Extracted from the documentation: "A Simple C++ Example".
|
Extracted from the documentation: [A Simple C++
|
||||||
https://www.gnu.org/software/bison/manual/html_node/A-Simple-C_002b_002b-Example.html
|
Example](https://www.gnu.org/software/bison/manual/html_node/A-Simple-C_002b_002b-Example.html).
|
||||||
|
|
||||||
## variant.yy - Self-contained example in C++98
|
## variant.yy - Self-contained example in C++98
|
||||||
A variation of simple.yy, in C++98.
|
A variation of simple.yy, in C++98.
|
||||||
@@ -36,8 +36,8 @@ starting point for a clean parser in C++. The previous examples are better
|
|||||||
introductory examples, and the C examples are also useful introductory
|
introductory examples, and the C examples are also useful introductory
|
||||||
examples.
|
examples.
|
||||||
|
|
||||||
Extracted from the documentation: "A Complete C++ Example".
|
Extracted from the documentation: [A Complete C++
|
||||||
https://www.gnu.org/software/bison/manual/html_node/A-Complete-C_002b_002b-Example.html
|
Example](https://www.gnu.org/software/bison/manual/html_node/A-Complete-C_002b_002b-Example.html).
|
||||||
|
|
||||||
<!---
|
<!---
|
||||||
|
|
||||||
|
|||||||
@@ -5,9 +5,9 @@ saw the traditional implementation in C, please first read
|
|||||||
examples/c/lexcalc, which can be seen as a C precursor of this example.
|
examples/c/lexcalc, which can be seen as a C precursor of this example.
|
||||||
|
|
||||||
Read the corresponding chapter in the documentation: "A Complete C++
|
Read the corresponding chapter in the documentation: "A Complete C++
|
||||||
Example". It is also available on line (maybe with a different version of
|
Example". It is also available [on
|
||||||
Bison):
|
line](https://www.gnu.org/software/bison/manual/html_node/A-Complete-C_002b_002b-Example.html)
|
||||||
https://www.gnu.org/software/bison/manual/html_node/A-Complete-C_002b_002b-Example.html
|
(maybe with a different version of Bison).
|
||||||
|
|
||||||
To use it, copy this directory into some work directory, and run `make` to
|
To use it, copy this directory into some work directory, and run `make` to
|
||||||
compile the executable, and try it. It is a simple calculator which accepts
|
compile the executable, and try it. It is a simple calculator which accepts
|
||||||
|
|||||||
@@ -139,7 +139,7 @@ namespace yy
|
|||||||
int
|
int
|
||||||
main (int argc, const char *argv[])
|
main (int argc, const char *argv[])
|
||||||
{
|
{
|
||||||
if (2 <= argc && isdigit (*argv[1]))
|
if (2 <= argc && isdigit (static_cast<unsigned char> (*argv[1])))
|
||||||
{
|
{
|
||||||
auto maxl = strtol (argv[1], nullptr, 10);
|
auto maxl = strtol (argv[1], nullptr, 10);
|
||||||
max = INT_MIN <= maxl && maxl <= INT_MAX ? int(maxl) : 4;
|
max = INT_MIN <= maxl && maxl <= INT_MAX ? int(maxl) : 4;
|
||||||
|
|||||||
+18
-9
@@ -10,8 +10,8 @@ The first example is that of a simple double-precision Reverse Polish
|
|||||||
Notation calculator (a calculator using postfix operators). This example
|
Notation calculator (a calculator using postfix operators). This example
|
||||||
provides a good starting point, since operator precedence is not an issue.
|
provides a good starting point, since operator precedence is not an issue.
|
||||||
|
|
||||||
Extracted from the documentation: "Reverse Polish Notation Calculator"
|
Extracted from the documentation: [Reverse Polish Notation
|
||||||
https://www.gnu.org/software/bison/manual/html_node/RPN-Calc.html
|
Calculator](https://www.gnu.org/software/bison/manual/html_node/RPN-Calc.html).
|
||||||
|
|
||||||
## calc - Simple Calculator
|
## calc - Simple Calculator
|
||||||
This example is slightly more complex than rpcalc: it features infix
|
This example is slightly more complex than rpcalc: it features infix
|
||||||
@@ -24,18 +24,18 @@ A more complete C example: a multi-function calculator. More complex than
|
|||||||
the previous example. Using precedence directives to support infix
|
the previous example. Using precedence directives to support infix
|
||||||
operators.
|
operators.
|
||||||
|
|
||||||
Extracted from the documentation: "Multi-Function Calculator: mfcalc".
|
Extracted from the documentation: [Multi-Function Calculator:
|
||||||
https://www.gnu.org/software/bison/manual/html_node/Multi_002dfunction-Calc.html
|
mfcalc](https://www.gnu.org/software/bison/manual/html_node/Multi_002dfunction-Calc.html).
|
||||||
|
|
||||||
## lexcalc - calculator with Flex and Bison
|
## lexcalc - calculator with Flex and Bison
|
||||||
The calculator with precedence directives and location tracking. It uses
|
The calculator with precedence directives and location tracking. It uses
|
||||||
Flex to generate the scanner.
|
Flex to generate the scanner.
|
||||||
|
|
||||||
## reccalc - recursive calculator with Flex and Bison
|
## reccalc - recursive calculator with Flex and Bison
|
||||||
The example builds on top of the previous one to provide a reentrant parser.
|
This example builds on top of the previous one to provide a reentrant
|
||||||
Such parsers can be called concurrently in different threads, or even
|
parser. Such parsers can be called concurrently in different threads, or
|
||||||
recursively. To demonstrate this feature, expressions in parentheses are
|
even recursively. To demonstrate this feature, expressions in parentheses
|
||||||
tokenized as strings, and then recursively parsed from the parser. So
|
are tokenized as strings, and then recursively parsed from the parser. So
|
||||||
`(((1)+(2))*((3)+(4)))` uses eight parsers, with a depth of four.
|
`(((1)+(2))*((3)+(4)))` uses eight parsers, with a depth of four.
|
||||||
|
|
||||||
## pushcalc - calculator implemented with a push parser
|
## pushcalc - calculator implemented with a push parser
|
||||||
@@ -53,7 +53,9 @@ push-parser model.
|
|||||||
This example demonstrates best practices when using Bison.
|
This example demonstrates best practices when using Bison.
|
||||||
- Its hand-written scanner tracks locations.
|
- Its hand-written scanner tracks locations.
|
||||||
- Its interface is pure.
|
- Its interface is pure.
|
||||||
- It uses the `error` token to get error recovery.
|
- It uses %params to pass user information to the parser and scanner.
|
||||||
|
- Its scanner uses the `error` token to signal lexical errors and enter
|
||||||
|
error recovery.
|
||||||
- Its interface is "incremental", well suited for interaction: it uses the
|
- Its interface is "incremental", well suited for interaction: it uses the
|
||||||
push-parser API to feed the parser with the incoming tokens.
|
push-parser API to feed the parser with the incoming tokens.
|
||||||
- It features an interactive command line with completion based on the
|
- It features an interactive command line with completion based on the
|
||||||
@@ -62,6 +64,13 @@ This example demonstrates best practices when using Bison.
|
|||||||
messages.
|
messages.
|
||||||
- It uses a custom syntax error with location, lookahead correction and
|
- It uses a custom syntax error with location, lookahead correction and
|
||||||
token internationalization.
|
token internationalization.
|
||||||
|
- Error messages quote the source with squiggles that underline the error:
|
||||||
|
```
|
||||||
|
> 123 456
|
||||||
|
1.5-7: syntax error: expected end of file or + or - or * or / or ^ before number
|
||||||
|
1 | 123 456
|
||||||
|
| ^~~
|
||||||
|
```
|
||||||
- It supports debug traces with semantic values.
|
- It supports debug traces with semantic values.
|
||||||
- It uses named references instead of the traditional $1, $2, etc.
|
- It uses named references instead of the traditional $1, $2, etc.
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ BASE = bistromathic
|
|||||||
BISON = bison
|
BISON = bison
|
||||||
XSLTPROC = xsltproc
|
XSLTPROC = xsltproc
|
||||||
|
|
||||||
# We need to find the headers and libs for readline and intl.
|
# We need to find the headers and libs for readline (and possibly intl).
|
||||||
# You probably need to customize this for your own environment.
|
# You probably need to customize this for your own environment.
|
||||||
CPPFLAGS = -I/opt/local/include
|
CPPFLAGS = -I/opt/local/include
|
||||||
LDFLAGS = -L/opt/local/lib
|
LDFLAGS = -L/opt/local/lib
|
||||||
@@ -14,7 +14,7 @@ LDFLAGS = -L/opt/local/lib
|
|||||||
BISON_LOCALEDIR = $(shell $(BISON) $(BISON_FLAGS) --print-localedir)
|
BISON_LOCALEDIR = $(shell $(BISON) $(BISON_FLAGS) --print-localedir)
|
||||||
CPPFLAGS += -DENABLE_NLS -DBISON_LOCALEDIR='"$(BISON_LOCALEDIR)"'
|
CPPFLAGS += -DENABLE_NLS -DBISON_LOCALEDIR='"$(BISON_LOCALEDIR)"'
|
||||||
|
|
||||||
LIBS = -lreadline -lintl
|
LIBS = -lreadline -lm # In some environments, -lintl is needed.
|
||||||
|
|
||||||
all: $(BASE)
|
all: $(BASE)
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,9 @@
|
|||||||
This example demonstrates best practices when using Bison.
|
This example demonstrates best practices when using Bison.
|
||||||
- Its hand-written scanner tracks locations.
|
- Its hand-written scanner tracks locations.
|
||||||
- Its interface is pure.
|
- Its interface is pure.
|
||||||
- It uses the `error` token to get error recovery.
|
- It uses %params to pass user information to the parser and scanner.
|
||||||
|
- Its scanner uses the `error` token to signal lexical errors and enter
|
||||||
|
error recovery.
|
||||||
- Its interface is "incremental", well suited for interaction: it uses the
|
- Its interface is "incremental", well suited for interaction: it uses the
|
||||||
push-parser API to feed the parser with the incoming tokens.
|
push-parser API to feed the parser with the incoming tokens.
|
||||||
- It features an interactive command line with completion based on the
|
- It features an interactive command line with completion based on the
|
||||||
@@ -11,9 +13,19 @@ This example demonstrates best practices when using Bison.
|
|||||||
messages.
|
messages.
|
||||||
- It uses a custom syntax error with location, lookahead correction and
|
- It uses a custom syntax error with location, lookahead correction and
|
||||||
token internationalization.
|
token internationalization.
|
||||||
|
- Error messages quote the source with squiggles that underline the error:
|
||||||
|
```
|
||||||
|
> 123 456
|
||||||
|
1.5-7: syntax error: expected end of file or + or - or * or / or ^ before number
|
||||||
|
1 | 123 456
|
||||||
|
| ^~~
|
||||||
|
```
|
||||||
- It supports debug traces with semantic values.
|
- It supports debug traces with semantic values.
|
||||||
- It uses named references instead of the traditional $1, $2, etc.
|
- It uses named references instead of the traditional $1, $2, etc.
|
||||||
|
|
||||||
|
To customize the interaction with bistromathic, see the GNU Readline user
|
||||||
|
manual (see `info rluserman`).
|
||||||
|
|
||||||
<!---
|
<!---
|
||||||
Local Variables:
|
Local Variables:
|
||||||
fill-column: 76
|
fill-column: 76
|
||||||
|
|||||||
@@ -15,12 +15,47 @@
|
|||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
# macOS' version of readline does not repeat stdin on stdout in
|
# Users may customize the behavior of readline, which might break our
|
||||||
# non-interactive mode.
|
# expected results.
|
||||||
if ! echo '1-1' | prog | grep '1-1' >/dev/null; then
|
INPUTRC=/dev/null
|
||||||
strip_prompt=true
|
export INPUTRC
|
||||||
|
|
||||||
|
# Beware of portability issues of readline when not feeding it from a
|
||||||
|
# terminal.
|
||||||
|
#
|
||||||
|
# With recent versions of GNU Readline, input "1+2*3\n" gives
|
||||||
|
# "> 1+2*3\n7\n> \n"
|
||||||
|
#
|
||||||
|
# macOS' version does not display the prompt and does not repeat stdin
|
||||||
|
# on stdout, so input "1+2*3\n" gives "7\n" as output. Let's try to
|
||||||
|
# cope with this.
|
||||||
|
#
|
||||||
|
# On OpenBSD 6.5 the prompt is displayed, but the input is not
|
||||||
|
# repeated (!). So input "1+2*3\n" gives "> 7\n> \n" as output.
|
||||||
|
#
|
||||||
|
# On AIX, you get some escaping sequence before the prompt:
|
||||||
|
# "<ESC>[?1034h> 1+2*3". It appears to pass the terminfo capability
|
||||||
|
# "smm", to put the terminal in "meta mode": as if the user had hit
|
||||||
|
# META.
|
||||||
|
|
||||||
|
echo >perfect '> 0
|
||||||
|
0
|
||||||
|
> '
|
||||||
|
|
||||||
|
echo >ok '0'
|
||||||
|
echo '0' | prog >effective
|
||||||
|
|
||||||
|
echo "checking for readline output..."
|
||||||
|
if diff perfect effective; then
|
||||||
|
# Alles ist gut.
|
||||||
|
strip_prompt=false
|
||||||
|
elif diff ok effective; then
|
||||||
|
strip_prompt=true
|
||||||
|
else
|
||||||
|
skip "this is not the GNU Readline we expect"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
cat >input <<EOF
|
cat >input <<EOF
|
||||||
1+2*3
|
1+2*3
|
||||||
EOF
|
EOF
|
||||||
@@ -66,14 +101,28 @@ cat >input <<EOF
|
|||||||
EOF
|
EOF
|
||||||
run 0 '> *
|
run 0 '> *
|
||||||
> ''
|
> ''
|
||||||
err: 1.1: syntax error: expected end of file or - or ( or exit or number or function or variable before *'
|
err: 1.1: syntax error: expected end of file or - or ( or exit or number or function etc., before *
|
||||||
|
err: 1 | *
|
||||||
|
err: | ^'
|
||||||
|
|
||||||
|
# Underline long errors.
|
||||||
|
cat >input <<EOF
|
||||||
|
123 123456
|
||||||
|
EOF
|
||||||
|
run 0 '> 123 123456
|
||||||
|
> ''
|
||||||
|
err: 1.5-10: syntax error: expected end of file or + or - or * or / or ^ before number
|
||||||
|
err: 1 | 123 123456
|
||||||
|
err: | ^~~~~~'
|
||||||
|
|
||||||
cat >input <<EOF
|
cat >input <<EOF
|
||||||
1 + 2 * * 3
|
1 + 2 * * 3
|
||||||
EOF
|
EOF
|
||||||
run 0 '> 1 + 2 * * 3
|
run 0 '> 1 + 2 * * 3
|
||||||
> ''
|
> ''
|
||||||
err: 1.9: syntax error: expected - or ( or number or function or variable before *'
|
err: 1.9: syntax error: expected - or ( or number or function or variable before *
|
||||||
|
err: 1 | 1 + 2 * * 3
|
||||||
|
err: | ^'
|
||||||
|
|
||||||
cat >input <<EOF
|
cat >input <<EOF
|
||||||
1 / 0
|
1 / 0
|
||||||
@@ -97,8 +146,14 @@ run 0 '> ((1 ++ 2) ** 3)
|
|||||||
1332
|
1332
|
||||||
> ''
|
> ''
|
||||||
err: 1.6: syntax error: expected - or ( or number or function or variable before +
|
err: 1.6: syntax error: expected - or ( or number or function or variable before +
|
||||||
|
err: 1 | ((1 ++ 2) ** 3)
|
||||||
|
err: | ^
|
||||||
err: 2.5: syntax error: expected - or ( or number or function or variable before +
|
err: 2.5: syntax error: expected - or ( or number or function or variable before +
|
||||||
err: 2.16: syntax error: expected - or ( or number or function or variable before *'
|
err: 2 | (1 ++ 2) + (3 ** 4)
|
||||||
|
err: | ^
|
||||||
|
err: 2.16: syntax error: expected - or ( or number or function or variable before *
|
||||||
|
err: 2 | (1 ++ 2) + (3 ** 4)
|
||||||
|
err: | ^'
|
||||||
|
|
||||||
# The rule "( error )" should work even if there are no tokens between "(" and ")".
|
# The rule "( error )" should work even if there are no tokens between "(" and ")".
|
||||||
cat >input <<EOF
|
cat >input <<EOF
|
||||||
@@ -107,7 +162,9 @@ EOF
|
|||||||
run 0 '> ()
|
run 0 '> ()
|
||||||
666
|
666
|
||||||
> ''
|
> ''
|
||||||
err: 1.2: syntax error: expected - or ( or number or function or variable before )'
|
err: 1.2: syntax error: expected - or ( or number or function or variable before )
|
||||||
|
err: 1 | ()
|
||||||
|
err: | ^'
|
||||||
|
|
||||||
|
|
||||||
cat >input <<EOF
|
cat >input <<EOF
|
||||||
@@ -154,6 +211,8 @@ err: LAC: checking lookahead function: S5
|
|||||||
err: LAC: checking lookahead variable: S6
|
err: LAC: checking lookahead variable: S6
|
||||||
err: LAC: checking lookahead NEG: Err
|
err: LAC: checking lookahead NEG: Err
|
||||||
err: 1.2: syntax error: expected - or ( or number or function or variable before +
|
err: 1.2: syntax error: expected - or ( or number or function or variable before +
|
||||||
|
err: 1 | (+_)
|
||||||
|
err: | ^
|
||||||
err: LAC: initial context discarded due to error recovery
|
err: LAC: initial context discarded due to error recovery
|
||||||
err: Shifting token error (1.2: )
|
err: Shifting token error (1.2: )
|
||||||
err: Entering state 10
|
err: Entering state 10
|
||||||
@@ -227,14 +286,22 @@ err: Cleanup: popping nterm input (1.1-4: )' -p
|
|||||||
# From now on, the differences between versions of GNU Readline are
|
# From now on, the differences between versions of GNU Readline are
|
||||||
# too painful to try to cope with.
|
# too painful to try to cope with.
|
||||||
if $strip_prompt; then
|
if $strip_prompt; then
|
||||||
echo "SKIP: this is not the GNU Readline we expect"
|
echo "SKIP: this is not the GNU Readline we expect"
|
||||||
if $exit; then
|
exit $status
|
||||||
exit 0
|
|
||||||
else
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# On Windows10/MSYS2 the ^G coming from <tab> completion is not
|
||||||
|
# emitted the same way
|
||||||
|
# (https://lists.gnu.org/r/bug-bison/2020-05/msg00076.html).
|
||||||
|
echo "checking for kernel name... $(uname -s)"
|
||||||
|
case $(uname -s) in
|
||||||
|
(MSYS*)
|
||||||
|
echo "SKIP: this is Windows/MSYS"
|
||||||
|
exit $status
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
|
||||||
# Check completion after an operator.
|
# Check completion after an operator.
|
||||||
sed -e 's/\\t/ /g' >input <<EOF
|
sed -e 's/\\t/ /g' >input <<EOF
|
||||||
(1+\t\t
|
(1+\t\t
|
||||||
@@ -243,7 +310,9 @@ run 0 '> (1+
|
|||||||
( - atan cos exp ln number sin sqrt
|
( - atan cos exp ln number sin sqrt
|
||||||
> (1+
|
> (1+
|
||||||
> ''
|
> ''
|
||||||
err: 1.4: syntax error: expected - or ( or number or function or variable before end of file'
|
err: 1.4: syntax error: expected - or ( or number or function or variable before end of file
|
||||||
|
err: 1 | (1+
|
||||||
|
err: | ^'
|
||||||
|
|
||||||
# Check the completion of a word.
|
# Check the completion of a word.
|
||||||
sed -e 's/\\t/ /g' >input <<EOF
|
sed -e 's/\\t/ /g' >input <<EOF
|
||||||
@@ -251,7 +320,9 @@ sed -e 's/\\t/ /g' >input <<EOF
|
|||||||
EOF
|
EOF
|
||||||
run 0 '> (atan ( ''
|
run 0 '> (atan ( ''
|
||||||
> ''
|
> ''
|
||||||
err: 1.9: syntax error: expected - or ( or number or function or variable before end of file'
|
err: 1.9: syntax error: expected - or ( or number or function or variable before end of file
|
||||||
|
err: 1 | (atan ( ''
|
||||||
|
err: | ^'
|
||||||
|
|
||||||
# Check the completion at the very beginning.
|
# Check the completion at the very beginning.
|
||||||
sed -e 's/\\t/ /g' >input <<EOF
|
sed -e 's/\\t/ /g' >input <<EOF
|
||||||
@@ -263,3 +334,28 @@ end of file exit exp ''
|
|||||||
0
|
0
|
||||||
> ''
|
> ''
|
||||||
err: '
|
err: '
|
||||||
|
|
||||||
|
# Check that completion prints valid locations even when there is an error.
|
||||||
|
sed -e 's/\\t/ /g' >input <<EOF
|
||||||
|
1++\t
|
||||||
|
EOF
|
||||||
|
run -n 0 '> 1++ ''
|
||||||
|
> ''
|
||||||
|
err: 1.3: syntax error: expected - or ( or number or function or variable before +
|
||||||
|
err: 1 | 1++ ''
|
||||||
|
err: | ^
|
||||||
|
'
|
||||||
|
|
||||||
|
# And even when the error was recovered from.
|
||||||
|
sed -e 's/\\t/ /g' >input <<EOF
|
||||||
|
(1++2) + 3 +\t\t
|
||||||
|
EOF
|
||||||
|
run -n 0 '> (1++2) + 3 + ''
|
||||||
|
> ''
|
||||||
|
err: 1.4: syntax error: expected - or ( or number or function or variable before +
|
||||||
|
err: 1 | (1++2) + 3 + ''
|
||||||
|
err: | ^
|
||||||
|
err: 1.15: syntax error: expected - or ( or number or function or variable before end of file
|
||||||
|
err: 1 | (1++2) + 3 + ''
|
||||||
|
err: | ^
|
||||||
|
'
|
||||||
|
|||||||
@@ -19,19 +19,23 @@ bistromathicdir = $(docdir)/%D%
|
|||||||
## Bistromathics. ##
|
## Bistromathics. ##
|
||||||
## --------------- ##
|
## --------------- ##
|
||||||
|
|
||||||
check_PROGRAMS += %D%/bistromathic
|
|
||||||
TESTS += %D%/bistromathic.test
|
|
||||||
EXTRA_DIST += %D%/bistromathic.test
|
|
||||||
nodist_%C%_bistromathic_SOURCES = %D%/parse.y %D%/parse.h
|
|
||||||
%D%/parse.c: $(dependencies)
|
%D%/parse.c: $(dependencies)
|
||||||
|
|
||||||
# Don't use gnulib's system headers.
|
if ENABLE_BISTROMATHIC
|
||||||
%C%_bistromathic_CPPFLAGS = \
|
check_PROGRAMS += %D%/bistromathic
|
||||||
-DBISON_LOCALEDIR='"$(localdir)"' \
|
TESTS += %D%/bistromathic.test
|
||||||
-DLOCALEDIR='"$(localdir)"' \
|
nodist_%C%_bistromathic_SOURCES = %D%/parse.y
|
||||||
-I$(top_srcdir)/%D% -I$(top_builddir)/%D%
|
|
||||||
%C%_bistromathic_LDADD = -lm -lreadline $(LIBINTL)
|
|
||||||
|
|
||||||
|
# Don't use gnulib's system headers.
|
||||||
|
%C%_bistromathic_CPPFLAGS = \
|
||||||
|
-DBISON_LOCALEDIR='"$(localdir)"' \
|
||||||
|
-DLOCALEDIR='"$(localdir)"' \
|
||||||
|
-I$(top_srcdir)/%D% -I$(top_builddir)/%D%
|
||||||
|
%C%_bistromathic_CFLAGS = $(TEST_CFLAGS)
|
||||||
|
%C%_bistromathic_LDADD = -lm $(LIBREADLINE) $(LIBINTL)
|
||||||
|
endif
|
||||||
|
|
||||||
|
EXTRA_DIST += %D%/bistromathic.test
|
||||||
dist_bistromathic_DATA = %D%/parse.y %D%/Makefile %D%/README.md
|
dist_bistromathic_DATA = %D%/parse.y %D%/Makefile %D%/README.md
|
||||||
CLEANFILES += %D%/parse.[ch] %D%/parse.output
|
CLEANFILES += %D%/parse.[ch] %D%/parse.output
|
||||||
CLEANDIRS += %D%/*.dSYM
|
CLEANDIRS += %D%/*.dSYM
|
||||||
|
|||||||
+142
-43
@@ -1,7 +1,28 @@
|
|||||||
%require "3.6"
|
/* Parser and scanner for bistromathic. -*- C -*-
|
||||||
|
|
||||||
|
Copyright (C) 2019-2020 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of Bison, the GNU Compiler Compiler.
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
%require "3.7"
|
||||||
|
|
||||||
|
// Emitted on top of the implementation file.
|
||||||
%code top {
|
%code top {
|
||||||
#include <ctype.h> // isdigit
|
#include <ctype.h> // isdigit
|
||||||
|
#include <locale.h> // LC_ALL
|
||||||
#include <math.h> // cos, sin, etc.
|
#include <math.h> // cos, sin, etc.
|
||||||
#include <stdarg.h> // va_start
|
#include <stdarg.h> // va_start
|
||||||
#include <stdio.h> // printf
|
#include <stdio.h> // printf
|
||||||
@@ -23,6 +44,7 @@
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Emitted in the header file, before the definition of YYSTYPE.
|
||||||
%code requires {
|
%code requires {
|
||||||
// Function type.
|
// Function type.
|
||||||
typedef double (func_t) (double);
|
typedef double (func_t) (double);
|
||||||
@@ -43,19 +65,34 @@
|
|||||||
|
|
||||||
symrec *putsym (char const *name, int sym_type);
|
symrec *putsym (char const *name, int sym_type);
|
||||||
symrec *getsym (char const *name);
|
symrec *getsym (char const *name);
|
||||||
|
|
||||||
|
// Exchanging information with the parser.
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
// Whether to not emit error messages.
|
||||||
|
int silent;
|
||||||
|
// The current input line.
|
||||||
|
const char *line;
|
||||||
|
} user_context;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Emitted in the header file, after the definition of YYSTYPE.
|
||||||
%code provides {
|
%code provides {
|
||||||
# ifndef __attribute__
|
# ifndef __attribute__
|
||||||
# ifndef __GNUC__
|
# ifndef __GNUC__
|
||||||
# define __attribute__(Spec) /* empty */
|
# define __attribute__(Spec) /* empty */
|
||||||
# endif
|
# endif
|
||||||
# endif
|
# endif
|
||||||
int yylex (const char **line, YYSTYPE *yylval, YYLTYPE *yylloc);
|
|
||||||
void yyerror (YYLTYPE *loc, char const *format, ...)
|
yytoken_kind_t
|
||||||
__attribute__ ((__format__ (__printf__, 2, 3)));
|
yylex (const char **line, YYSTYPE *yylval, YYLTYPE *yylloc,
|
||||||
|
const user_context *uctx);
|
||||||
|
void yyerror (YYLTYPE *loc, const user_context *uctx,
|
||||||
|
char const *format, ...)
|
||||||
|
__attribute__ ((__format__ (__printf__, 3, 4)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Emitted in the implementation file.
|
||||||
%code {
|
%code {
|
||||||
#if defined ENABLE_NLS && ENABLE_NLS
|
#if defined ENABLE_NLS && ENABLE_NLS
|
||||||
# define _(Msgid) gettext (Msgid)
|
# define _(Msgid) gettext (Msgid)
|
||||||
@@ -67,6 +104,9 @@
|
|||||||
int done = 0;
|
int done = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Include the header in the implementation rather than duplicating it.
|
||||||
|
%define api.header.include {"parse.h"}
|
||||||
|
|
||||||
// Don't share global variables between the scanner and the parser.
|
// Don't share global variables between the scanner and the parser.
|
||||||
%define api.pure full
|
%define api.pure full
|
||||||
|
|
||||||
@@ -89,6 +129,9 @@
|
|||||||
// Generate the parser description file (calc.output).
|
// Generate the parser description file (calc.output).
|
||||||
%verbose
|
%verbose
|
||||||
|
|
||||||
|
// User information exchanged with the parser and scanner.
|
||||||
|
%param {const user_context *uctx}
|
||||||
|
|
||||||
// Generate YYSTYPE from the types assigned to symbols.
|
// Generate YYSTYPE from the types assigned to symbols.
|
||||||
%define api.value.type union
|
%define api.value.type union
|
||||||
%token
|
%token
|
||||||
@@ -144,7 +187,7 @@ exp:
|
|||||||
{
|
{
|
||||||
if ($r == 0)
|
if ($r == 0)
|
||||||
{
|
{
|
||||||
yyerror (&@$, "error: division by zero");
|
yyerror (&@$, uctx, "error: division by zero");
|
||||||
YYERROR;
|
YYERROR;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -216,7 +259,7 @@ getsym (char const *name)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// How many symbols are registered.
|
// How many symbols are registered.
|
||||||
int
|
static int
|
||||||
symbol_count (void)
|
symbol_count (void)
|
||||||
{
|
{
|
||||||
int res = 0;
|
int res = 0;
|
||||||
@@ -230,8 +273,9 @@ symbol_count (void)
|
|||||||
| Scanner. |
|
| Scanner. |
|
||||||
`----------*/
|
`----------*/
|
||||||
|
|
||||||
int
|
yytoken_kind_t
|
||||||
yylex (const char **line, YYSTYPE *yylval, YYLTYPE *yylloc)
|
yylex (const char **line, YYSTYPE *yylval, YYLTYPE *yylloc,
|
||||||
|
const user_context *uctx)
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
|
|
||||||
@@ -266,7 +310,8 @@ yylex (const char **line, YYSTYPE *yylval, YYLTYPE *yylloc)
|
|||||||
case '5': case '6': case '7': case '8': case '9':
|
case '5': case '6': case '7': case '8': case '9':
|
||||||
{
|
{
|
||||||
int nchars = 0;
|
int nchars = 0;
|
||||||
sscanf (*line - 1, "%lf%n", &yylval->TOK_NUM, &nchars);
|
if (sscanf (*line - 1, "%lf%n", &yylval->TOK_NUM, &nchars) != 1)
|
||||||
|
abort ();
|
||||||
*line += nchars - 1;
|
*line += nchars - 1;
|
||||||
yylloc->last_column += nchars - 1;
|
yylloc->last_column += nchars - 1;
|
||||||
return TOK_NUM;
|
return TOK_NUM;
|
||||||
@@ -282,7 +327,8 @@ yylex (const char **line, YYSTYPE *yylval, YYLTYPE *yylloc)
|
|||||||
{
|
{
|
||||||
int nchars = 0;
|
int nchars = 0;
|
||||||
char buf[100];
|
char buf[100];
|
||||||
sscanf (*line - 1, "%99[a-z]%n", buf, &nchars);
|
if (sscanf (*line - 1, "%99[a-z]%n", buf, &nchars) != 1)
|
||||||
|
abort ();
|
||||||
*line += nchars - 1;
|
*line += nchars - 1;
|
||||||
yylloc->last_column += nchars - 1;
|
yylloc->last_column += nchars - 1;
|
||||||
if (strcmp (buf, "exit") == 0)
|
if (strcmp (buf, "exit") == 0)
|
||||||
@@ -299,7 +345,7 @@ yylex (const char **line, YYSTYPE *yylval, YYLTYPE *yylloc)
|
|||||||
|
|
||||||
// Stray characters.
|
// Stray characters.
|
||||||
default:
|
default:
|
||||||
yyerror (yylloc, "syntax error: invalid character: %c", c);
|
yyerror (yylloc, uctx, "syntax error: invalid character: %c", c);
|
||||||
return TOK_YYerror;
|
return TOK_YYerror;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -310,12 +356,12 @@ yylex (const char **line, YYSTYPE *yylval, YYLTYPE *yylloc)
|
|||||||
`---------*/
|
`---------*/
|
||||||
|
|
||||||
|
|
||||||
const char *
|
static const char *
|
||||||
error_format_string (int argc)
|
error_format_string (int argc)
|
||||||
{
|
{
|
||||||
switch (argc)
|
switch (argc)
|
||||||
{
|
{
|
||||||
default: /* Avoid compiler warnings. */
|
default: // Avoid compiler warnings.
|
||||||
case 0: return _("%@: syntax error");
|
case 0: return _("%@: syntax error");
|
||||||
case 1: return _("%@: syntax error: unexpected %u");
|
case 1: return _("%@: syntax error: unexpected %u");
|
||||||
// TRANSLATORS: '%@' is a location in a file, '%u' is an
|
// TRANSLATORS: '%@' is a location in a file, '%u' is an
|
||||||
@@ -331,26 +377,33 @@ error_format_string (int argc)
|
|||||||
case 5: return _("%@: syntax error: expected %0e or %1e or %2e or %3e before %u");
|
case 5: return _("%@: syntax error: expected %0e or %1e or %2e or %3e before %u");
|
||||||
case 6: return _("%@: syntax error: expected %0e or %1e or %2e or %3e or %4e before %u");
|
case 6: return _("%@: syntax error: expected %0e or %1e or %2e or %3e or %4e before %u");
|
||||||
case 7: return _("%@: syntax error: expected %0e or %1e or %2e or %3e or %4e or %5e before %u");
|
case 7: return _("%@: syntax error: expected %0e or %1e or %2e or %3e or %4e or %5e before %u");
|
||||||
case 8: return _("%@: syntax error: expected %0e or %1e or %2e or %3e or %4e or %5e or %6e before %u");
|
case 8: return _("%@: syntax error: expected %0e or %1e or %2e or %3e or %4e or %5e etc., before %u");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
yyreport_syntax_error (const yypcontext_t *ctx)
|
yyreport_syntax_error (const yypcontext_t *ctx, const user_context *uctx)
|
||||||
{
|
{
|
||||||
enum { ARGS_MAX = 7 };
|
if (uctx->silent)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
enum { ARGS_MAX = 6 };
|
||||||
yysymbol_kind_t arg[ARGS_MAX];
|
yysymbol_kind_t arg[ARGS_MAX];
|
||||||
int argsize = yypcontext_expected_tokens (ctx, arg, ARGS_MAX);
|
int argsize = yypcontext_expected_tokens (ctx, arg, ARGS_MAX);
|
||||||
if (argsize < 0)
|
if (argsize < 0)
|
||||||
return argsize;
|
return argsize;
|
||||||
const char *format = error_format_string (1 + argsize);
|
const int too_many_expected_tokens = argsize == 0 && arg[0] != YYSYMBOL_YYEMPTY;
|
||||||
|
if (too_many_expected_tokens)
|
||||||
|
argsize = ARGS_MAX;
|
||||||
|
const char *format = error_format_string (1 + argsize + too_many_expected_tokens);
|
||||||
|
|
||||||
|
const YYLTYPE *loc = yypcontext_location (ctx);
|
||||||
while (*format)
|
while (*format)
|
||||||
// %@: location.
|
// %@: location.
|
||||||
if (format[0] == '%' && format[1] == '@')
|
if (format[0] == '%' && format[1] == '@')
|
||||||
{
|
{
|
||||||
YY_LOCATION_PRINT (stderr, *yypcontext_location (ctx));
|
YY_LOCATION_PRINT (stderr, *loc);
|
||||||
format += 2;
|
format += 2;
|
||||||
}
|
}
|
||||||
// %u: unexpected token.
|
// %u: unexpected token.
|
||||||
@@ -361,7 +414,7 @@ yyreport_syntax_error (const yypcontext_t *ctx)
|
|||||||
}
|
}
|
||||||
// %0e, %1e...: expected token.
|
// %0e, %1e...: expected token.
|
||||||
else if (format[0] == '%'
|
else if (format[0] == '%'
|
||||||
&& isdigit (format[1])
|
&& isdigit ((unsigned char) format[1])
|
||||||
&& format[2] == 'e'
|
&& format[2] == 'e'
|
||||||
&& (format[1] - '0') < argsize)
|
&& (format[1] - '0') < argsize)
|
||||||
{
|
{
|
||||||
@@ -375,13 +428,25 @@ yyreport_syntax_error (const yypcontext_t *ctx)
|
|||||||
++format;
|
++format;
|
||||||
}
|
}
|
||||||
fputc ('\n', stderr);
|
fputc ('\n', stderr);
|
||||||
|
|
||||||
|
// Quote the source line.
|
||||||
|
{
|
||||||
|
fprintf (stderr, "%5d | %s\n", loc->first_line, uctx->line);
|
||||||
|
fprintf (stderr, "%5s | %*s", "", loc->first_column, "^");
|
||||||
|
for (int i = loc->last_column - loc->first_column - 1; 0 < i; --i)
|
||||||
|
putc ('~', stderr);
|
||||||
|
putc ('\n', stderr);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Called by yyparse on error.
|
// Called by yyparse on error.
|
||||||
void yyerror (YYLTYPE *loc, char const *format, ...)
|
void yyerror (YYLTYPE *loc, const user_context *uctx, char const *format, ...)
|
||||||
{
|
{
|
||||||
|
if (uctx->silent)
|
||||||
|
return;
|
||||||
|
|
||||||
YY_LOCATION_PRINT (stderr, *loc);
|
YY_LOCATION_PRINT (stderr, *loc);
|
||||||
fputs (": ", stderr);
|
fputs (": ", stderr);
|
||||||
va_list args;
|
va_list args;
|
||||||
@@ -392,18 +457,38 @@ void yyerror (YYLTYPE *loc, char const *format, ...)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Return a newly allocated copy of at most N bytes of STRING. In
|
||||||
|
// other words, return a copy of the initial segment of length N of
|
||||||
|
// STRING.
|
||||||
|
static char *
|
||||||
|
xstrndup (const char *string, size_t n)
|
||||||
|
{
|
||||||
|
// len = strnlen (string, n), portably.
|
||||||
|
const char *end = memchr (string, '\0', n);
|
||||||
|
size_t len = end ? (size_t) (end - string) : n;
|
||||||
|
char *new = malloc (len + 1);
|
||||||
|
if (!new)
|
||||||
|
abort ();
|
||||||
|
new[len] = '\0';
|
||||||
|
return memcpy (new, string, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*-----------.
|
/*-----------.
|
||||||
| Readline. |
|
| Readline. |
|
||||||
`-----------*/
|
`-----------*/
|
||||||
|
|
||||||
// Parse (and execute) this line.
|
// Parse (and execute) this line.
|
||||||
int process_line (YYLTYPE *lloc, const char *line)
|
static int
|
||||||
|
process_line (YYLTYPE *lloc, const char *line)
|
||||||
{
|
{
|
||||||
|
user_context uctx = {0, line};
|
||||||
yypstate *ps = yypstate_new ();
|
yypstate *ps = yypstate_new ();
|
||||||
int status = 0;
|
int status = 0;
|
||||||
do {
|
do {
|
||||||
YYSTYPE lval;
|
YYSTYPE lval;
|
||||||
status = yypush_parse (ps, yylex (&line, &lval, lloc), &lval, lloc);
|
yytoken_kind_t token = yylex (&line, &lval, lloc, &uctx);
|
||||||
|
status = yypush_parse (ps, token, &lval, lloc, &uctx);
|
||||||
} while (status == YYPUSH_MORE);
|
} while (status == YYPUSH_MORE);
|
||||||
yypstate_delete (ps);
|
yypstate_delete (ps);
|
||||||
lloc->last_line++;
|
lloc->last_line++;
|
||||||
@@ -412,37 +497,46 @@ int process_line (YYLTYPE *lloc, const char *line)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get the list of possible tokens after INPUT was read.
|
// Get the list of possible tokens after INPUT was read.
|
||||||
int
|
// Returns a nonnegative.
|
||||||
|
static int
|
||||||
expected_tokens (const char *input,
|
expected_tokens (const char *input,
|
||||||
int *tokens, int ntokens)
|
int *tokens, int ntokens)
|
||||||
{
|
{
|
||||||
YYDPRINTF ((stderr, "expected_tokens (\"%s\")", input));
|
YYDPRINTF ((stderr, "expected_tokens (\"%s\")", input));
|
||||||
|
user_context uctx = {1, input};
|
||||||
|
|
||||||
// Parse the current state of the line.
|
// Parse the current state of the line.
|
||||||
yypstate *ps = yypstate_new ();
|
yypstate *ps = yypstate_new ();
|
||||||
int status = 0;
|
int status = 0;
|
||||||
|
YYLTYPE lloc = { 1, 1, 1, 1 };
|
||||||
do {
|
do {
|
||||||
YYLTYPE lloc;
|
|
||||||
YYSTYPE lval;
|
YYSTYPE lval;
|
||||||
int token = yylex (&input, &lval, &lloc);
|
yytoken_kind_t token = yylex (&input, &lval, &lloc, &uctx);
|
||||||
// Don't let the parse know when we reach the end of input.
|
// Don't let the parse know when we reach the end of input.
|
||||||
if (!token)
|
if (token == TOK_YYEOF)
|
||||||
break;
|
break;
|
||||||
status = yypush_parse (ps, token, &lval, &lloc);
|
status = yypush_parse (ps, token, &lval, &lloc, &uctx);
|
||||||
} while (status == YYPUSH_MORE);
|
} while (status == YYPUSH_MORE);
|
||||||
|
|
||||||
// Then query for the accepted tokens at this point.
|
int res = 0;
|
||||||
int res = yypstate_expected_tokens (ps, tokens, ntokens);
|
// If there were parse errors, don't propose completions.
|
||||||
|
if (!ps->yynerrs)
|
||||||
|
{
|
||||||
|
// Then query for the accepted tokens at this point.
|
||||||
|
res = yypstate_expected_tokens (ps, tokens, ntokens);
|
||||||
|
if (res < 0)
|
||||||
|
abort ();
|
||||||
|
}
|
||||||
yypstate_delete (ps);
|
yypstate_delete (ps);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Attempt to complete on the contents of TEXT. START and END bound the
|
// Attempt to complete on the contents of TEXT. START and END bound
|
||||||
region of rl_line_buffer that contains the word to complete. TEXT is
|
// the region of rl_line_buffer that contains the word to complete.
|
||||||
the word to complete. We can use the entire contents of rl_line_buffer
|
// TEXT is the word to complete. We can use the entire contents of
|
||||||
in case we want to do some simple parsing. Return the array of matches,
|
// rl_line_buffer in case we want to do some simple parsing. Return
|
||||||
or NULL if there aren't any. */
|
// the array of matches, or NULL if there aren't any.
|
||||||
char **
|
static char **
|
||||||
completion (const char *text, int start, int end)
|
completion (const char *text, int start, int end)
|
||||||
{
|
{
|
||||||
YYDPRINTF ((stderr, "completion (\"%.*s[%.*s]%s\")\n",
|
YYDPRINTF ((stderr, "completion (\"%.*s[%.*s]%s\")\n",
|
||||||
@@ -452,14 +546,17 @@ completion (const char *text, int start, int end)
|
|||||||
|
|
||||||
// Get list of token numbers.
|
// Get list of token numbers.
|
||||||
int tokens[YYNTOKENS];
|
int tokens[YYNTOKENS];
|
||||||
char *line = strndup (rl_line_buffer, start);
|
char *line = xstrndup (rl_line_buffer, (size_t) start);
|
||||||
int ntokens = expected_tokens (line, tokens, YYNTOKENS);
|
int ntokens = expected_tokens (line, tokens, YYNTOKENS);
|
||||||
free (line);
|
free (line);
|
||||||
|
|
||||||
// Build MATCHES, the list of possible completions.
|
// Build MATCHES, the list of possible completions.
|
||||||
const int len = strlen (text);
|
const size_t len = strlen (text);
|
||||||
// Need initial prefix and final NULL.
|
// Need initial prefix and final NULL.
|
||||||
char **matches = calloc (ntokens + symbol_count () + 2, sizeof *matches);
|
char **matches
|
||||||
|
= calloc ((size_t) ntokens + (size_t) symbol_count () + 2, sizeof *matches);
|
||||||
|
if (!matches)
|
||||||
|
abort ();
|
||||||
int match = 1;
|
int match = 1;
|
||||||
for (int i = 0; i < ntokens; ++i)
|
for (int i = 0; i < ntokens; ++i)
|
||||||
switch (tokens[i])
|
switch (tokens[i])
|
||||||
@@ -489,12 +586,12 @@ completion (const char *text, int start, int end)
|
|||||||
matches[0] = strdup (text);
|
matches[0] = strdup (text);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int lcplen = strlen (matches[1]);
|
size_t lcplen = strlen (matches[1]);
|
||||||
for (int i = 2; i < match && lcplen; ++i)
|
for (int i = 2; i < match && lcplen; ++i)
|
||||||
for (int j = 0; j < lcplen; ++j)
|
for (size_t j = 0; j < lcplen; ++j)
|
||||||
if (matches[1][j] != matches[i][j])
|
if (matches[1][j] != matches[i][j])
|
||||||
lcplen = j;
|
lcplen = j;
|
||||||
matches[0] = strndup (matches[1], lcplen);
|
matches[0] = xstrndup (matches[1], lcplen);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (yydebug)
|
if (yydebug)
|
||||||
@@ -515,7 +612,8 @@ completion (const char *text, int start, int end)
|
|||||||
return matches;
|
return matches;
|
||||||
}
|
}
|
||||||
|
|
||||||
void init_readline (void)
|
static void
|
||||||
|
init_readline (void)
|
||||||
{
|
{
|
||||||
// Allow conditional parsing of the ~/.inputrc file.
|
// Allow conditional parsing of the ~/.inputrc file.
|
||||||
rl_readline_name = "bistromathic";
|
rl_readline_name = "bistromathic";
|
||||||
@@ -534,7 +632,8 @@ void init_readline (void)
|
|||||||
| Main. |
|
| Main. |
|
||||||
`-------*/
|
`-------*/
|
||||||
|
|
||||||
int main (int argc, char const* argv[])
|
int
|
||||||
|
main (int argc, char const* argv[])
|
||||||
{
|
{
|
||||||
#if defined ENABLE_NLS && ENABLE_NLS
|
#if defined ENABLE_NLS && ENABLE_NLS
|
||||||
// Set up internationalization.
|
// Set up internationalization.
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
%code top {
|
%code top {
|
||||||
|
#include <assert.h>
|
||||||
#include <ctype.h> /* isdigit. */
|
#include <ctype.h> /* isdigit. */
|
||||||
#include <stdio.h> /* For printf, etc. */
|
#include <stdio.h> /* printf. */
|
||||||
|
#include <stdlib.h> /* abort. */
|
||||||
#include <string.h> /* strcmp. */
|
#include <string.h> /* strcmp. */
|
||||||
|
|
||||||
int yylex (void);
|
int yylex (void);
|
||||||
@@ -73,7 +75,8 @@ yylex (void)
|
|||||||
if (c == '.' || isdigit (c))
|
if (c == '.' || isdigit (c))
|
||||||
{
|
{
|
||||||
ungetc (c, stdin);
|
ungetc (c, stdin);
|
||||||
scanf ("%lf", &yylval.NUM);
|
if (scanf ("%lf", &yylval.NUM) != 1)
|
||||||
|
abort ();
|
||||||
return NUM;
|
return NUM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ nodist_%C%_calc_SOURCES = %D%/calc.y
|
|||||||
|
|
||||||
# Don't use gnulib's system headers.
|
# Don't use gnulib's system headers.
|
||||||
%C%_calc_CPPFLAGS = -I$(top_srcdir)/%D% -I$(top_builddir)/%D%
|
%C%_calc_CPPFLAGS = -I$(top_srcdir)/%D% -I$(top_builddir)/%D%
|
||||||
|
%C%_calc_CFLAGS = $(TEST_CFLAGS)
|
||||||
|
|
||||||
dist_calc_DATA = %D%/calc.y %D%/Makefile %D%/README.md
|
dist_calc_DATA = %D%/calc.y %D%/Makefile %D%/README.md
|
||||||
CLEANFILES += %D%/calc.[ch] %D%/calc.output %D%/scan.c
|
CLEANFILES += %D%/calc.[ch] %D%/calc.output %D%/scan.c
|
||||||
|
|||||||
@@ -25,6 +25,8 @@ if FLEX_WORKS
|
|||||||
nodist_%C%_lexcalc_SOURCES = %D%/parse.y %D%/parse.h %D%/scan.l
|
nodist_%C%_lexcalc_SOURCES = %D%/parse.y %D%/parse.h %D%/scan.l
|
||||||
# Don't use gnulib's system headers.
|
# Don't use gnulib's system headers.
|
||||||
%C%_lexcalc_CPPFLAGS = -I$(top_srcdir)/%D% -I$(top_builddir)/%D%
|
%C%_lexcalc_CPPFLAGS = -I$(top_srcdir)/%D% -I$(top_builddir)/%D%
|
||||||
|
# Fighting warnings triggered by Flex is just too painful.
|
||||||
|
# %C%_lexcalc_CFLAGS = $(TEST_CFLAGS)
|
||||||
endif FLEX_WORKS
|
endif FLEX_WORKS
|
||||||
|
|
||||||
%D%/parse.c: $(dependencies)
|
%D%/parse.c: $(dependencies)
|
||||||
|
|||||||
@@ -1,3 +1,22 @@
|
|||||||
|
/* Parser for lexcalc. -*- C -*-
|
||||||
|
|
||||||
|
Copyright (C) 2018-2020 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of Bison, the GNU Compiler Compiler.
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
// Prologue (directives).
|
// Prologue (directives).
|
||||||
%expect 0
|
%expect 0
|
||||||
|
|
||||||
@@ -19,6 +38,9 @@
|
|||||||
#include <stdlib.h> // getenv.
|
#include <stdlib.h> // getenv.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Include the header in the implementation rather than duplicating it.
|
||||||
|
%define api.header.include {"parse.h"}
|
||||||
|
|
||||||
// Don't share global variables between the scanner and the parser.
|
// Don't share global variables between the scanner and the parser.
|
||||||
%define api.pure full
|
%define api.pure full
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,29 @@
|
|||||||
/* Prologue (directives). -*- C -*- */
|
/* Scanner for lexcalc. -*- C -*-
|
||||||
|
|
||||||
|
Copyright (C) 2018-2020 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of Bison, the GNU Compiler Compiler.
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
/* Prologue (directives). */
|
||||||
|
|
||||||
/* Disable Flex features we don't need, to avoid warnings. */
|
/* Disable Flex features we don't need, to avoid warnings. */
|
||||||
%option nodefault noinput nounput noyywrap
|
%option nodefault noinput nounput noyywrap
|
||||||
|
|
||||||
%{
|
%{
|
||||||
#include <errno.h> /* errno, ERANGE */
|
#include <errno.h> /* errno, ERANGE */
|
||||||
#include <limits.h> /* INT_MIN */
|
#include <limits.h> /* INT_MIN */
|
||||||
#include <stdlib.h> /* strtol */
|
#include <stdlib.h> /* strtol */
|
||||||
|
|
||||||
@@ -12,7 +31,7 @@
|
|||||||
|
|
||||||
// Each time a rule is matched, advance the end cursor/position.
|
// Each time a rule is matched, advance the end cursor/position.
|
||||||
#define YY_USER_ACTION \
|
#define YY_USER_ACTION \
|
||||||
yylloc->last_column += yyleng;
|
yylloc->last_column += (int) yyleng;
|
||||||
|
|
||||||
// Move the first position onto the last.
|
// Move the first position onto the last.
|
||||||
#define LOCATION_STEP() \
|
#define LOCATION_STEP() \
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ nodist_%C%_mfcalc_SOURCES = $(mfcalc_sources)
|
|||||||
%D%/mfcalc.c: $(dependencies)
|
%D%/mfcalc.c: $(dependencies)
|
||||||
# Don't use gnulib's system headers.
|
# Don't use gnulib's system headers.
|
||||||
%C%_mfcalc_CPPFLAGS = -I$(top_srcdir)/%D% -I$(top_builddir)/%D%
|
%C%_mfcalc_CPPFLAGS = -I$(top_srcdir)/%D% -I$(top_builddir)/%D%
|
||||||
|
%C%_mfcalc_CFLAGS = $(TEST_CFLAGS)
|
||||||
%C%_mfcalc_LDADD = -lm
|
%C%_mfcalc_LDADD = -lm
|
||||||
|
|
||||||
dist_TESTS += %D%/mfcalc.test
|
dist_TESTS += %D%/mfcalc.test
|
||||||
|
|||||||
@@ -1,7 +1,26 @@
|
|||||||
|
/* Parser and scanner for pushcalc. -*- C -*-
|
||||||
|
|
||||||
|
Copyright (C) 2020 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of Bison, the GNU Compiler Compiler.
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
%code top {
|
%code top {
|
||||||
#include <ctype.h> /* isdigit. */
|
#include <ctype.h> /* isdigit. */
|
||||||
#include <stdbool.h>
|
#include <stdio.h> /* printf. */
|
||||||
#include <stdio.h> /* For printf, etc. */
|
#include <stdlib.h> /* abort. */
|
||||||
#include <string.h> /* strcmp. */
|
#include <string.h> /* strcmp. */
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -81,7 +100,8 @@ yylex (YYSTYPE *yylval)
|
|||||||
if (c == '.' || isdigit (c))
|
if (c == '.' || isdigit (c))
|
||||||
{
|
{
|
||||||
ungetc (c, stdin);
|
ungetc (c, stdin);
|
||||||
scanf ("%lf", &yylval->NUM);
|
if (scanf ("%lf", &yylval->NUM) != 1)
|
||||||
|
abort ();
|
||||||
return NUM;
|
return NUM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ nodist_%C%_calc_SOURCES = %D%/calc.y
|
|||||||
|
|
||||||
# Don't use gnulib's system headers.
|
# Don't use gnulib's system headers.
|
||||||
%C%_calc_CPPFLAGS = -I$(top_srcdir)/%D% -I$(top_builddir)/%D%
|
%C%_calc_CPPFLAGS = -I$(top_srcdir)/%D% -I$(top_builddir)/%D%
|
||||||
|
%C%_calc_CFLAGS = $(TEST_CFLAGS)
|
||||||
|
|
||||||
dist_pushcalc_DATA = %D%/calc.y %D%/Makefile %D%/README.md
|
dist_pushcalc_DATA = %D%/calc.y %D%/Makefile %D%/README.md
|
||||||
CLEANFILES += %D%/calc.[ch] %D%/calc.output
|
CLEANFILES += %D%/calc.[ch] %D%/calc.output
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ all: $(BASE)
|
|||||||
$(BISON) $(BISONFLAGS) --defines --xml --graph=$*.gv -o $*.c $<
|
$(BISON) $(BISONFLAGS) --defines --xml --graph=$*.gv -o $*.c $<
|
||||||
|
|
||||||
%.c %.h: %.l
|
%.c %.h: %.l
|
||||||
$(FLEX) $(FLEXFLAGS) -o$*.c --header-file=$*.h $<
|
$(FLEX) $(FLEXFLAGS) -o$*.c --header=$*.h $<
|
||||||
|
|
||||||
scan.o: parse.h
|
scan.o: parse.h
|
||||||
parse.o: scan.h
|
parse.o: scan.h
|
||||||
|
|||||||
@@ -26,6 +26,8 @@ if FLEX_WORKS
|
|||||||
BUILT_SOURCES += $(nodist_%C%_reccalc_SOURCES)
|
BUILT_SOURCES += $(nodist_%C%_reccalc_SOURCES)
|
||||||
# Don't use gnulib's system headers.
|
# Don't use gnulib's system headers.
|
||||||
%C%_reccalc_CPPFLAGS = -I$(top_srcdir)/%D% -I$(top_builddir)/%D%
|
%C%_reccalc_CPPFLAGS = -I$(top_srcdir)/%D% -I$(top_builddir)/%D%
|
||||||
|
# Fighting warnings triggered by Flex is just too painful.
|
||||||
|
# %C%_reccalc_CFLAGS = $(TEST_CFLAGS)
|
||||||
endif FLEX_WORKS
|
endif FLEX_WORKS
|
||||||
|
|
||||||
%D%/parse.c: $(dependencies)
|
%D%/parse.c: $(dependencies)
|
||||||
@@ -69,7 +71,9 @@ DASH = -
|
|||||||
$(AM_V_LEX)rm -f $@ $@.tmp
|
$(AM_V_LEX)rm -f $@ $@.tmp
|
||||||
$(AM_V_at)$(MKDIR_P) %D%
|
$(AM_V_at)$(MKDIR_P) %D%
|
||||||
$(AM_V_at)touch $@.tmp
|
$(AM_V_at)touch $@.tmp
|
||||||
$(AM_V_at)$(LEX) $(AM_LFLAGS) $(LFLAGS) -o%D%/scan.c --header-file=%D%/scan.h $(srcdir)/%D%/scan.l
|
## --header introduced in 2.5.6, renamed as --header-file in 2.6.4.
|
||||||
|
## Backward compatibility ensured since --header is an unambiguous prefix.
|
||||||
|
$(AM_V_at)$(LEX) $(AM_LFLAGS) $(LFLAGS) -o%D%/scan.c --header=%D%/scan.h $(srcdir)/%D%/scan.l
|
||||||
$(AM_V_at)mv $@.tmp $@
|
$(AM_V_at)mv $@.tmp $@
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,22 @@
|
|||||||
|
/* Parser for reccalc. -*- C -*-
|
||||||
|
|
||||||
|
Copyright (C) 2019-2020 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of Bison, the GNU Compiler Compiler.
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
// Prologue (directives).
|
// Prologue (directives).
|
||||||
%expect 0
|
%expect 0
|
||||||
|
|
||||||
@@ -46,14 +65,29 @@
|
|||||||
result parse (void);
|
result parse (void);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Include the header in the implementation rather than duplicating it.
|
||||||
|
%define api.header.include {"parse.h"}
|
||||||
|
|
||||||
|
// Don't share global variables between the scanner and the parser.
|
||||||
%define api.pure full
|
%define api.pure full
|
||||||
|
|
||||||
|
// To avoid name clashes (e.g., with C's EOF) prefix token definitions
|
||||||
|
// with TOK_ (e.g., TOK_EOF).
|
||||||
%define api.token.prefix {TOK_}
|
%define api.token.prefix {TOK_}
|
||||||
|
|
||||||
|
// Generate YYSTYPE from the types assigned to symbols.
|
||||||
%define api.value.type union
|
%define api.value.type union
|
||||||
%define parse.error verbose
|
|
||||||
|
// Error messages with "unexpected XXX, expected XXX...".
|
||||||
|
%define parse.error detailed
|
||||||
|
|
||||||
|
// Enable run-time traces (yydebug).
|
||||||
%define parse.trace
|
%define parse.trace
|
||||||
|
|
||||||
|
// Generate the parser description file (parse.output).
|
||||||
%verbose
|
%verbose
|
||||||
|
|
||||||
// Scanner and error count are exchanged between main, yyparse and yylex.
|
// Scanner and error count are exchanged between main, yyparse and yylex.
|
||||||
%param {yyscan_t scanner}{result *res}
|
%param {yyscan_t scanner}{result *res}
|
||||||
|
|
||||||
%token
|
%token
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
seq 0 >/dev/null || exit 77
|
(seq 0) >/dev/null 2>&1 || skip "gimme one seq"
|
||||||
|
|
||||||
cat >input <<EOF
|
cat >input <<EOF
|
||||||
1+2*3
|
1+2*3
|
||||||
|
|||||||
@@ -1,3 +1,22 @@
|
|||||||
|
/* Scanner for reccalc. -*- C -*-
|
||||||
|
|
||||||
|
Copyright (C) 2019-2020 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of Bison, the GNU Compiler Compiler.
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
/* Prologue (directives). -*- C -*- */
|
/* Prologue (directives). -*- C -*- */
|
||||||
|
|
||||||
/* Disable Flex features we don't need, to avoid warnings. */
|
/* Disable Flex features we don't need, to avoid warnings. */
|
||||||
@@ -32,9 +51,9 @@
|
|||||||
do \
|
do \
|
||||||
capacity = capacity ? 2 * capacity : 128; \
|
capacity = capacity ? 2 * capacity : 128; \
|
||||||
while (capacity < size + yyleng + 1); \
|
while (capacity < size + yyleng + 1); \
|
||||||
str = realloc (str, capacity); \
|
str = realloc (str, (size_t) capacity); \
|
||||||
} \
|
} \
|
||||||
memcpy (str + size, yytext, yyleng); \
|
memcpy (str + size, yytext, (size_t) yyleng); \
|
||||||
size += yyleng; \
|
size += yyleng; \
|
||||||
assert (size < capacity); \
|
assert (size < capacity); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ nodist_%C%_rpcalc_SOURCES = $(rpcalc_sources)
|
|||||||
%D%/rpcalc.c: $(dependencies)
|
%D%/rpcalc.c: $(dependencies)
|
||||||
# Don't use gnulib's system headers.
|
# Don't use gnulib's system headers.
|
||||||
%C%_rpcalc_CPPFLAGS = -I$(top_builddir)/%D%
|
%C%_rpcalc_CPPFLAGS = -I$(top_builddir)/%D%
|
||||||
|
%C%_rpcalc_CFLAGS = $(TEST_CFLAGS)
|
||||||
%C%_rpcalc_LDADD = -lm
|
%C%_rpcalc_LDADD = -lm
|
||||||
|
|
||||||
dist_TESTS += %D%/rpcalc.test
|
dist_TESTS += %D%/rpcalc.test
|
||||||
|
|||||||
@@ -1,3 +1,22 @@
|
|||||||
|
/* Parser and scanner for calc in D. -*- D -*-
|
||||||
|
|
||||||
|
Copyright (C) 2018-2020 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of Bison, the GNU Compiler Compiler.
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
%language "D"
|
%language "D"
|
||||||
|
|
||||||
%define api.parser.class {Calc}
|
%define api.parser.class {Calc}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ afterwards.
|
|||||||
The usual calculator, a very simple version.
|
The usual calculator, a very simple version.
|
||||||
|
|
||||||
## calc/Calc.y
|
## calc/Calc.y
|
||||||
The calculator, but with location tracking and debug traces.
|
The calculator, but with location tracking, debug traces, and a push parser.
|
||||||
|
|
||||||
<!---
|
<!---
|
||||||
|
|
||||||
|
|||||||
+66
-18
@@ -1,7 +1,27 @@
|
|||||||
|
/* Parser and scanner for calc in Java. -*- Java -*-
|
||||||
|
|
||||||
|
Copyright (C) 2018-2020 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of Bison, the GNU Compiler Compiler.
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
%language "Java"
|
%language "Java"
|
||||||
|
|
||||||
%define api.parser.class {Calc}
|
%define api.parser.class {Calc}
|
||||||
%define api.parser.public
|
%define api.parser.public
|
||||||
|
%define api.push-pull push
|
||||||
|
|
||||||
%define parse.error custom
|
%define parse.error custom
|
||||||
%define parse.trace
|
%define parse.trace
|
||||||
@@ -20,12 +40,19 @@
|
|||||||
|
|
||||||
%code {
|
%code {
|
||||||
public static void main(String[] args) throws IOException {
|
public static void main(String[] args) throws IOException {
|
||||||
CalcLexer l = new CalcLexer(System.in);
|
CalcLexer scanner = new CalcLexer(System.in);
|
||||||
Calc p = new Calc(l);
|
Calc parser = new Calc(scanner);
|
||||||
for (String arg : args)
|
for (String arg : args)
|
||||||
if (arg.equals("-p"))
|
if (arg.equals("-p"))
|
||||||
p.setDebugLevel(1);
|
parser.setDebugLevel(1);
|
||||||
if (!p.parse())
|
int status;
|
||||||
|
do {
|
||||||
|
int token = scanner.getToken();
|
||||||
|
Object lval = scanner.getValue();
|
||||||
|
Calc.Location yyloc = scanner.getLocation();
|
||||||
|
status = parser.push_parse(token, lval, yyloc);
|
||||||
|
} while (status == Calc.YYPUSH_MORE);
|
||||||
|
if (status != Calc.YYACCEPT)
|
||||||
System.exit(1);
|
System.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -105,14 +132,17 @@ class CalcLexer implements Calc.Lexer {
|
|||||||
Position start = new Position(1, 0);
|
Position start = new Position(1, 0);
|
||||||
Position end = new Position(1, 0);
|
Position end = new Position(1, 0);
|
||||||
|
|
||||||
public Position getStartPos() {
|
/**
|
||||||
return new Position(start);
|
* The location of the last token read.
|
||||||
}
|
* Implemented with getStartPos and getEndPos in pull parsers.
|
||||||
|
*/
|
||||||
public Position getEndPos() {
|
public Calc.Location getLocation() {
|
||||||
return new Position(end);
|
return new Calc.Location(new Position(start), new Position(end));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build and emit a syntax error message.
|
||||||
|
*/
|
||||||
public void reportSyntaxError(Calc.Context ctx) {
|
public void reportSyntaxError(Calc.Context ctx) {
|
||||||
System.err.print(ctx.getLocation() + ": syntax error");
|
System.err.print(ctx.getLocation() + ": syntax error");
|
||||||
{
|
{
|
||||||
@@ -131,20 +161,33 @@ class CalcLexer implements Calc.Lexer {
|
|||||||
System.err.println("");
|
System.err.println("");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void yyerror(Calc.Location l, String s) {
|
/**
|
||||||
if (l == null)
|
* Emit an error referring to the given location in a user-defined way.
|
||||||
System.err.println(s);
|
*
|
||||||
|
* @@param loc The location of the element to which the
|
||||||
|
* error message is related.
|
||||||
|
* @@param msg The string for the error message.
|
||||||
|
*/
|
||||||
|
public void yyerror(Calc.Location loc, String msg) {
|
||||||
|
if (loc == null)
|
||||||
|
System.err.println(msg);
|
||||||
else
|
else
|
||||||
System.err.println(l + ": " + s);
|
System.err.println(loc + ": " + msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
Integer yylval;
|
Integer yylval;
|
||||||
|
|
||||||
public Object getLVal() {
|
/**
|
||||||
|
* The value of the last token read. Called getLVal in pull parsers.
|
||||||
|
*/
|
||||||
|
public Object getValue() {
|
||||||
return yylval;
|
return yylval;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int yylex() throws IOException {
|
/**
|
||||||
|
* Fetch the next token. Called yylex in pull parsers.
|
||||||
|
*/
|
||||||
|
public int getToken() throws IOException {
|
||||||
start.set(reader.getPosition());
|
start.set(reader.getPosition());
|
||||||
int ttype = st.nextToken();
|
int ttype = st.nextToken();
|
||||||
end.set(reader.getPosition());
|
end.set(reader.getPosition());
|
||||||
@@ -160,7 +203,7 @@ class CalcLexer implements Calc.Lexer {
|
|||||||
end.set(reader.getPreviousPosition());
|
end.set(reader.getPreviousPosition());
|
||||||
return NUM;
|
return NUM;
|
||||||
case ' ': case '\t':
|
case ' ': case '\t':
|
||||||
return yylex();
|
return getToken();
|
||||||
case '!':
|
case '!':
|
||||||
return BANG;
|
return BANG;
|
||||||
case '+':
|
case '+':
|
||||||
@@ -185,7 +228,9 @@ class CalcLexer implements Calc.Lexer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A class defining a point in the input.
|
||||||
|
*/
|
||||||
class Position {
|
class Position {
|
||||||
public int line = 1;
|
public int line = 1;
|
||||||
public int column = 1;
|
public int column = 1;
|
||||||
@@ -227,6 +272,9 @@ class Position {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A Stream reader that keeps track of the current Position.
|
||||||
|
*/
|
||||||
class PositionReader extends BufferedReader {
|
class PositionReader extends BufferedReader {
|
||||||
|
|
||||||
private Position position = new Position();
|
private Position position = new Position();
|
||||||
|
|||||||
@@ -1,3 +1,22 @@
|
|||||||
|
/* Simple parser and scanner in Java. -*- Java -*-
|
||||||
|
|
||||||
|
Copyright (C) 2018-2020 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of Bison, the GNU Compiler Compiler.
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
%language "Java"
|
%language "Java"
|
||||||
|
|
||||||
%define api.parser.class {Calc}
|
%define api.parser.class {Calc}
|
||||||
|
|||||||
@@ -35,6 +35,9 @@
|
|||||||
dist_noinst_SCRIPTS = %D%/extexi %D%/test
|
dist_noinst_SCRIPTS = %D%/extexi %D%/test
|
||||||
TEST_LOG_COMPILER = $(SHELL) $(top_srcdir)/%D%/test
|
TEST_LOG_COMPILER = $(SHELL) $(top_srcdir)/%D%/test
|
||||||
|
|
||||||
|
TEST_CFLAGS = \
|
||||||
|
$(WARN_CFLAGS) $(WARN_CFLAGS_TEST) $(WERROR_CFLAGS)
|
||||||
|
|
||||||
AM_CXXFLAGS = \
|
AM_CXXFLAGS = \
|
||||||
$(WARN_CXXFLAGS) $(WARN_CXXFLAGS_TEST) $(WERROR_CXXFLAGS)
|
$(WARN_CXXFLAGS) $(WARN_CXXFLAGS_TEST) $(WERROR_CXXFLAGS)
|
||||||
|
|
||||||
|
|||||||
+30
-8
@@ -25,7 +25,7 @@ medir=$(dirname "$1" | sed -e 's,.*examples/,,')
|
|||||||
number=1
|
number=1
|
||||||
|
|
||||||
# Exit status of this script.
|
# Exit status of this script.
|
||||||
exit=true
|
status=0
|
||||||
|
|
||||||
# top_builddir.
|
# top_builddir.
|
||||||
cwd=$(pwd)
|
cwd=$(pwd)
|
||||||
@@ -34,6 +34,14 @@ cwd=$(pwd)
|
|||||||
# See bistromathic.test.
|
# See bistromathic.test.
|
||||||
strip_prompt=false
|
strip_prompt=false
|
||||||
|
|
||||||
|
# If diff supports --strip-trailing-cr, use it, to avoid EOL issues
|
||||||
|
# when testing Java programs on Windows.
|
||||||
|
echo "checking for diff --strip-trailing-cr..."
|
||||||
|
if diff --strip-trailing-cr "$1" "$1"; then
|
||||||
|
diff_opts=--strip-trailing-cr
|
||||||
|
fi
|
||||||
|
echo "checking for diff --strip-trailing-cr... $diff_opts"
|
||||||
|
|
||||||
# The exercised program.
|
# The exercised program.
|
||||||
abs_medir=$cwd/examples/$medir
|
abs_medir=$cwd/examples/$medir
|
||||||
if test -x "$abs_medir/$me"; then
|
if test -x "$abs_medir/$me"; then
|
||||||
@@ -68,6 +76,20 @@ trap cleanup 0 1 2 13 15
|
|||||||
mkdir $$.dir
|
mkdir $$.dir
|
||||||
cd $$.dir
|
cd $$.dir
|
||||||
|
|
||||||
|
|
||||||
|
# skip [MSG]
|
||||||
|
# ----------
|
||||||
|
# Skip this test.
|
||||||
|
skip ()
|
||||||
|
{
|
||||||
|
if test x"$1" != x; then
|
||||||
|
echo "SKIP: $1"
|
||||||
|
fi
|
||||||
|
# See Autoconf's doc on 'trap'.
|
||||||
|
(exit 77); exit 77
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
# run [-noerr, -n] EXPECTED-EXIT-STATUS EXPECTED-OUTPUT [PARSER-OPTIONS]
|
# run [-noerr, -n] EXPECTED-EXIT-STATUS EXPECTED-OUTPUT [PARSER-OPTIONS]
|
||||||
# ----------------------------------------------------------------------
|
# ----------------------------------------------------------------------
|
||||||
# -noerr: ignore stderr, otherwise merge it into effective output.
|
# -noerr: ignore stderr, otherwise merge it into effective output.
|
||||||
@@ -115,7 +137,7 @@ run ()
|
|||||||
} >eff
|
} >eff
|
||||||
|
|
||||||
if test $sta_eff -eq $sta_exp; then
|
if test $sta_eff -eq $sta_exp; then
|
||||||
if cmp eff exp 2>/dev/null; then
|
if diff $diff_opts eff exp >/dev/null 2>&1; then
|
||||||
echo "$me: PASS: $number"
|
echo "$me: PASS: $number"
|
||||||
else
|
else
|
||||||
echo "$me: FAIL: $number"
|
echo "$me: FAIL: $number"
|
||||||
@@ -126,21 +148,21 @@ run ()
|
|||||||
echo "$me: effective output:"
|
echo "$me: effective output:"
|
||||||
sed -e 's/^/ /' eff
|
sed -e 's/^/ /' eff
|
||||||
echo "$me: diff:"
|
echo "$me: diff:"
|
||||||
diff -u exp eff | sed -e 's/^/ /'
|
diff $diff_opts -u exp eff | sed -e 's/^/ /'
|
||||||
exit=false
|
status=1
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
echo "$me: FAIL: $number (expected status: $sta_exp, effective: $sta_eff)"
|
echo "$me: FAIL: $number (expected status: $sta_exp, effective: $sta_eff)"
|
||||||
cat err_eff
|
cat err_eff
|
||||||
exit=false
|
status=1
|
||||||
fi
|
fi
|
||||||
number=$(expr $number + 1)
|
number=$(expr $number + 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
# We have cd'd one level deeper.
|
# We have cd'd one level deeper.
|
||||||
case $1 in
|
case $1 in
|
||||||
/*) . "$1";;
|
/*) . "$1" || status=2;;
|
||||||
*) . "../$1";;
|
*) . "../$1" || status=2;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
$exit
|
exit $status
|
||||||
|
|||||||
+1
-1
Submodule gnulib updated: 5ec4d920e4...ac34618e85
@@ -18,7 +18,9 @@
|
|||||||
/asnprintf.c
|
/asnprintf.c
|
||||||
/asprintf.c
|
/asprintf.c
|
||||||
/assure.h
|
/assure.h
|
||||||
|
/attribute.h
|
||||||
/basename-lgpl.c
|
/basename-lgpl.c
|
||||||
|
/basename-lgpl.h
|
||||||
/basename.c
|
/basename.c
|
||||||
/binary-io.c
|
/binary-io.c
|
||||||
/binary-io.h
|
/binary-io.h
|
||||||
@@ -117,10 +119,31 @@
|
|||||||
/gettext.h
|
/gettext.h
|
||||||
/gettime.c
|
/gettime.c
|
||||||
/gettimeofday.c
|
/gettimeofday.c
|
||||||
|
/gl_anyhash1.h
|
||||||
|
/gl_anyhash2.h
|
||||||
|
/gl_anyhash_primes.h
|
||||||
|
/gl_anylinked_list1.h
|
||||||
|
/gl_anylinked_list2.h
|
||||||
|
/gl_anyrbtree_list1.h
|
||||||
|
/gl_anyrbtree_list2.h
|
||||||
|
/gl_anytree_list1.h
|
||||||
|
/gl_anytree_list2.h
|
||||||
|
/gl_anytree_oset.h
|
||||||
|
/gl_anytreehash_list1.h
|
||||||
|
/gl_anytreehash_list2.h
|
||||||
/gl_array_list.c
|
/gl_array_list.c
|
||||||
/gl_array_list.h
|
/gl_array_list.h
|
||||||
|
/gl_linked_list.c
|
||||||
|
/gl_linked_list.h
|
||||||
/gl_list.c
|
/gl_list.c
|
||||||
/gl_list.h
|
/gl_list.h
|
||||||
|
/gl_oset.c
|
||||||
|
/gl_oset.h
|
||||||
|
/gl_rbtree_ordered.h
|
||||||
|
/gl_rbtree_oset.c
|
||||||
|
/gl_rbtree_oset.h
|
||||||
|
/gl_rbtreehash_list.c
|
||||||
|
/gl_rbtreehash_list.h
|
||||||
/gl_xlist.c
|
/gl_xlist.c
|
||||||
/gl_xlist.h
|
/gl_xlist.h
|
||||||
/gnulib.mk
|
/gnulib.mk
|
||||||
@@ -128,6 +151,23 @@
|
|||||||
/hard-locale.h
|
/hard-locale.h
|
||||||
/hash.c
|
/hash.c
|
||||||
/hash.h
|
/hash.h
|
||||||
|
/iconv.c
|
||||||
|
/iconv.h
|
||||||
|
/iconv.in.h
|
||||||
|
/iconv_close.c
|
||||||
|
/iconv_open-aix.gperf
|
||||||
|
/iconv_open-aix.h
|
||||||
|
/iconv_open-hpux.gperf
|
||||||
|
/iconv_open-hpux.h
|
||||||
|
/iconv_open-irix.gperf
|
||||||
|
/iconv_open-irix.h
|
||||||
|
/iconv_open-osf.gperf
|
||||||
|
/iconv_open-osf.h
|
||||||
|
/iconv_open-solaris.gperf
|
||||||
|
/iconv_open-solaris.h
|
||||||
|
/iconv_open-zos.gperf
|
||||||
|
/iconv_open-zos.h
|
||||||
|
/iconv_open.c
|
||||||
/intprops.h
|
/intprops.h
|
||||||
/inttypes.h
|
/inttypes.h
|
||||||
/inttypes.in.h
|
/inttypes.in.h
|
||||||
@@ -273,6 +313,7 @@
|
|||||||
/stdlib.h
|
/stdlib.h
|
||||||
/stdlib.in.h
|
/stdlib.in.h
|
||||||
/stpcpy.c
|
/stpcpy.c
|
||||||
|
/stpncpy.c
|
||||||
/strchrnul.c
|
/strchrnul.c
|
||||||
/strchrnul.valgrind
|
/strchrnul.valgrind
|
||||||
/strdup.c
|
/strdup.c
|
||||||
@@ -305,11 +346,16 @@
|
|||||||
/timespec.h
|
/timespec.h
|
||||||
/timevar.c
|
/timevar.c
|
||||||
/timevar.h
|
/timevar.h
|
||||||
|
/unicodeio.c
|
||||||
|
/unicodeio.h
|
||||||
/unistd--.h
|
/unistd--.h
|
||||||
/unistd-safer.h
|
/unistd-safer.h
|
||||||
/unistd.c
|
/unistd.c
|
||||||
/unistd.h
|
/unistd.h
|
||||||
/unistd.in.h
|
/unistd.in.h
|
||||||
|
/unistr.h
|
||||||
|
/unistr.in.h
|
||||||
|
/unistr/
|
||||||
/unitypes.h
|
/unitypes.h
|
||||||
/unitypes.in.h
|
/unitypes.in.h
|
||||||
/uniwidth
|
/uniwidth
|
||||||
@@ -318,6 +364,7 @@
|
|||||||
/unlink.c
|
/unlink.c
|
||||||
/unlocked-io.h
|
/unlocked-io.h
|
||||||
/unsetenv.c
|
/unsetenv.c
|
||||||
|
/unused-parameter.h
|
||||||
/vasnprintf.c
|
/vasnprintf.c
|
||||||
/vasnprintf.h
|
/vasnprintf.h
|
||||||
/vasprintf.c
|
/vasprintf.c
|
||||||
|
|||||||
+7
-2
@@ -1,4 +1,3 @@
|
|||||||
/extern-inline.m4~
|
|
||||||
/*~
|
/*~
|
||||||
/00gnulib.m4
|
/00gnulib.m4
|
||||||
/__inline.m4
|
/__inline.m4
|
||||||
@@ -6,6 +5,7 @@
|
|||||||
/alloca.m4
|
/alloca.m4
|
||||||
/asm-underscore.m4
|
/asm-underscore.m4
|
||||||
/assert.m4
|
/assert.m4
|
||||||
|
/builtin-expect.m4
|
||||||
/calloc.m4
|
/calloc.m4
|
||||||
/canonicalize.m4
|
/canonicalize.m4
|
||||||
/clock_time.m4
|
/clock_time.m4
|
||||||
@@ -13,7 +13,6 @@
|
|||||||
/codeset.m4
|
/codeset.m4
|
||||||
/config-h.m4
|
/config-h.m4
|
||||||
/configmake.m4
|
/configmake.m4
|
||||||
/dirname.m4
|
|
||||||
/double-slash-root.m4
|
/double-slash-root.m4
|
||||||
/dup2.m4
|
/dup2.m4
|
||||||
/eealloc.m4
|
/eealloc.m4
|
||||||
@@ -25,6 +24,7 @@
|
|||||||
/exponentl.m4
|
/exponentl.m4
|
||||||
/extensions.m4
|
/extensions.m4
|
||||||
/extern-inline.m4
|
/extern-inline.m4
|
||||||
|
/extern-inline.m4~
|
||||||
/fatal-signal.m4
|
/fatal-signal.m4
|
||||||
/fcntl-o.m4
|
/fcntl-o.m4
|
||||||
/fcntl.m4
|
/fcntl.m4
|
||||||
@@ -57,7 +57,10 @@
|
|||||||
/gnulib-tool.m4
|
/gnulib-tool.m4
|
||||||
/host-cpu-c-abi.m4
|
/host-cpu-c-abi.m4
|
||||||
/iconv.m4
|
/iconv.m4
|
||||||
|
/iconv_h.m4
|
||||||
|
/iconv_open.m4
|
||||||
/include_next.m4
|
/include_next.m4
|
||||||
|
/inline.m4
|
||||||
/intdiv0.m4
|
/intdiv0.m4
|
||||||
/intl.m4
|
/intl.m4
|
||||||
/intldir.m4
|
/intldir.m4
|
||||||
@@ -172,6 +175,7 @@
|
|||||||
/stdio_h.m4
|
/stdio_h.m4
|
||||||
/stdlib_h.m4
|
/stdlib_h.m4
|
||||||
/stpcpy.m4
|
/stpcpy.m4
|
||||||
|
/stpncpy.m4
|
||||||
/strchrnul.m4
|
/strchrnul.m4
|
||||||
/strdup.m4
|
/strdup.m4
|
||||||
/strerror.m4
|
/strerror.m4
|
||||||
@@ -192,6 +196,7 @@
|
|||||||
/timespec.m4
|
/timespec.m4
|
||||||
/tls.m4
|
/tls.m4
|
||||||
/uintmax_t.m4
|
/uintmax_t.m4
|
||||||
|
/unicodeio.m4
|
||||||
/unistd-safer.m4
|
/unistd-safer.m4
|
||||||
/unistd_h.m4
|
/unistd_h.m4
|
||||||
/unlink.m4
|
/unlink.m4
|
||||||
|
|||||||
+16
@@ -41,6 +41,22 @@ else
|
|||||||
fi
|
fi
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|
||||||
|
AC_CACHE_CHECK([whether flex supports --header=FILE],
|
||||||
|
[ac_cv_prog_lex_supports_header_opt],
|
||||||
|
[if _AC_DO_VAR([LEX --header=conftest.h conftest.l]); then
|
||||||
|
ac_cv_prog_lex_supports_header_opt=yes
|
||||||
|
else
|
||||||
|
ac_cv_prog_lex_supports_header_opt=no
|
||||||
|
fi
|
||||||
|
])
|
||||||
|
if test "$ac_cv_prog_lex_supports_header_opt" = yes; then
|
||||||
|
FLEX_SUPPORTS_HEADER_OPT=true
|
||||||
|
else
|
||||||
|
FLEX_SUPPORTS_HEADER_OPT=false
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
cat >conftest.l <<_ACEOF[
|
cat >conftest.l <<_ACEOF[
|
||||||
%%
|
%%
|
||||||
a { ECHO; }
|
a { ECHO; }
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ examples/c/bistromathic/parse.y
|
|||||||
examples/java/calc/Calc.y
|
examples/java/calc/Calc.y
|
||||||
src/complain.c
|
src/complain.c
|
||||||
src/conflicts.c
|
src/conflicts.c
|
||||||
|
src/counterexample.c
|
||||||
src/files.c
|
src/files.c
|
||||||
src/fixits.c
|
src/fixits.c
|
||||||
src/getargs.c
|
src/getargs.c
|
||||||
|
|||||||
+165
-180
@@ -18,11 +18,13 @@
|
|||||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#include "system.h"
|
|
||||||
|
|
||||||
#include "AnnotationList.h"
|
#include "AnnotationList.h"
|
||||||
#include "lalr.h"
|
|
||||||
|
#include "system.h"
|
||||||
|
|
||||||
#include "ielr.h"
|
#include "ielr.h"
|
||||||
|
#include "lalr.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \pre
|
* \pre
|
||||||
@@ -38,15 +40,14 @@ static AnnotationList*
|
|||||||
AnnotationList__alloc_on_obstack (ContributionIndex contribution_count,
|
AnnotationList__alloc_on_obstack (ContributionIndex contribution_count,
|
||||||
struct obstack *annotations_obstackp)
|
struct obstack *annotations_obstackp)
|
||||||
{
|
{
|
||||||
AnnotationList *result;
|
AnnotationList *res;
|
||||||
size_t contributions_size =
|
size_t contributions_size = contribution_count * sizeof res->contributions[0];
|
||||||
contribution_count * sizeof result->contributions[0];
|
res = obstack_alloc (annotations_obstackp,
|
||||||
result = obstack_alloc (annotations_obstackp,
|
offsetof (AnnotationList, contributions)
|
||||||
offsetof (AnnotationList, contributions)
|
+ contributions_size);
|
||||||
+ contributions_size);
|
res->next = NULL;
|
||||||
result->next = NULL;
|
res->inadequacyNode = NULL;
|
||||||
result->inadequacyNode = NULL;
|
return res;
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -102,13 +103,12 @@ AnnotationList__insertInto (AnnotationList *self, AnnotationList **list,
|
|||||||
for (node = list; *node; node = &(*node)->next)
|
for (node = list; *node; node = &(*node)->next)
|
||||||
{
|
{
|
||||||
int cmp = 0;
|
int cmp = 0;
|
||||||
ContributionIndex ci;
|
|
||||||
if (self->inadequacyNode->id < (*node)->inadequacyNode->id)
|
if (self->inadequacyNode->id < (*node)->inadequacyNode->id)
|
||||||
cmp = 1;
|
cmp = 1;
|
||||||
else if ((*node)->inadequacyNode->id < self->inadequacyNode->id)
|
else if ((*node)->inadequacyNode->id < self->inadequacyNode->id)
|
||||||
cmp = -1;
|
cmp = -1;
|
||||||
else
|
else
|
||||||
for (ci = 0;
|
for (ContributionIndex ci = 0;
|
||||||
cmp == 0 && ci < self->inadequacyNode->contributionCount;
|
cmp == 0 && ci < self->inadequacyNode->contributionCount;
|
||||||
++ci)
|
++ci)
|
||||||
{
|
{
|
||||||
@@ -120,19 +120,16 @@ AnnotationList__insertInto (AnnotationList *self, AnnotationList **list,
|
|||||||
else if (AnnotationList__isContributionAlways (*node, ci))
|
else if (AnnotationList__isContributionAlways (*node, ci))
|
||||||
cmp = 1;
|
cmp = 1;
|
||||||
else
|
else
|
||||||
{
|
for (size_t item = 0; cmp == 0 && item < nitems; ++item)
|
||||||
size_t item;
|
{
|
||||||
for (item = 0; cmp == 0 && item < nitems; ++item)
|
if (!Sbitset__test (self->contributions[ci], item))
|
||||||
{
|
{
|
||||||
if (!Sbitset__test (self->contributions[ci], item))
|
if (Sbitset__test ((*node)->contributions[ci], item))
|
||||||
{
|
cmp = -1;
|
||||||
if (Sbitset__test ((*node)->contributions[ci], item))
|
}
|
||||||
cmp = -1;
|
else if (!Sbitset__test ((*node)->contributions[ci], item))
|
||||||
}
|
cmp = 1;
|
||||||
else if (!Sbitset__test ((*node)->contributions[ci], item))
|
}
|
||||||
cmp = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (cmp < 0)
|
if (cmp < 0)
|
||||||
{
|
{
|
||||||
@@ -172,10 +169,10 @@ AnnotationList__compute_conflicted_tokens (bitset shift_tokens,
|
|||||||
bitset_copy (tokens, shift_tokens);
|
bitset_copy (tokens, shift_tokens);
|
||||||
for (int i = 0; i < reds->num; ++i)
|
for (int i = 0; i < reds->num; ++i)
|
||||||
{
|
{
|
||||||
bitset_and (conflicted_tokens_rule, tokens, reds->lookahead_tokens[i]);
|
bitset_and (conflicted_tokens_rule, tokens, reds->lookaheads[i]);
|
||||||
bitset_or (conflicted_tokens,
|
bitset_or (conflicted_tokens,
|
||||||
conflicted_tokens, conflicted_tokens_rule);
|
conflicted_tokens, conflicted_tokens_rule);
|
||||||
bitset_or (tokens, tokens, reds->lookahead_tokens[i]);
|
bitset_or (tokens, tokens, reds->lookaheads[i]);
|
||||||
/* Check that rules are sorted on rule number or the next step in
|
/* Check that rules are sorted on rule number or the next step in
|
||||||
AnnotationList__compute_from_inadequacies will misbehave. */
|
AnnotationList__compute_from_inadequacies will misbehave. */
|
||||||
aver (i == 0 || reds->rules[i-1] < reds->rules[i]);
|
aver (i == 0 || reds->rules[i-1] < reds->rules[i]);
|
||||||
@@ -188,7 +185,7 @@ AnnotationList__compute_conflicted_tokens (bitset shift_tokens,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
AnnotationList__compute_lhs_contributions (state *s, rule *the_rule,
|
AnnotationList__compute_lhs_contributions (state *s, const rule *the_rule,
|
||||||
symbol_number conflicted_token,
|
symbol_number conflicted_token,
|
||||||
bitsetv follow_kernel_items,
|
bitsetv follow_kernel_items,
|
||||||
bitsetv always_follows,
|
bitsetv always_follows,
|
||||||
@@ -232,115 +229,110 @@ AnnotationList__computePredecessorAnnotations (
|
|||||||
annotation_node->inadequacyNode = self->inadequacyNode;
|
annotation_node->inadequacyNode = self->inadequacyNode;
|
||||||
bool potential_contribution = false;
|
bool potential_contribution = false;
|
||||||
bitset *lookaheads = NULL;
|
bitset *lookaheads = NULL;
|
||||||
{
|
|
||||||
for (ContributionIndex ci = 0; ci < self->inadequacyNode->contributionCount; ++ci)
|
for (ContributionIndex ci = 0; ci < self->inadequacyNode->contributionCount; ++ci)
|
||||||
{
|
{
|
||||||
symbol_number contribution_token =
|
symbol_number contribution_token =
|
||||||
InadequacyList__getContributionToken (self->inadequacyNode, ci)
|
InadequacyList__getContributionToken (self->inadequacyNode, ci)
|
||||||
->content->number;
|
->content->number;
|
||||||
if (AnnotationList__isContributionAlways (self, ci))
|
if (AnnotationList__isContributionAlways (self, ci))
|
||||||
{
|
|
||||||
annotation_node->contributions[ci] = NULL;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
annotation_node->contributions[ci] =
|
|
||||||
Sbitset__new_on_obstack ((*predecessor)->nitems,
|
|
||||||
annotations_obstackp);
|
|
||||||
{
|
{
|
||||||
size_t predecessor_item = 0;
|
annotation_node->contributions[ci] = NULL;
|
||||||
Sbitset sbiter_item;
|
continue;
|
||||||
Sbitset__Index self_item;
|
|
||||||
SBITSET__FOR_EACH (self->contributions[ci], s->nitems,
|
|
||||||
sbiter_item, self_item)
|
|
||||||
{
|
|
||||||
/* If this kernel item is the beginning of a RHS, it must be
|
|
||||||
the kernel item in the start state, and so it has an empty
|
|
||||||
lookahead set. Thus, it can't contribute to inadequacies,
|
|
||||||
and so it should never have been identified as a
|
|
||||||
contribution. If, instead, this kernel item is the
|
|
||||||
successor of the start state's kernel item, the lookahead
|
|
||||||
set is still empty, and so it also should never have been
|
|
||||||
identified as a contribution. This situation is fortunate
|
|
||||||
because we want to avoid the - 2 below in both cases. */
|
|
||||||
aver (s->items[self_item] > 1);
|
|
||||||
/* If this kernel item is next to the beginning of the RHS,
|
|
||||||
then check all of the predecessor's goto follows for the
|
|
||||||
LHS. */
|
|
||||||
if (item_number_is_rule_number (ritem[s->items[self_item]
|
|
||||||
- 2]))
|
|
||||||
{
|
|
||||||
int rulei;
|
|
||||||
for (rulei = s->items[self_item];
|
|
||||||
!item_number_is_rule_number (ritem[rulei]);
|
|
||||||
++rulei)
|
|
||||||
continue;
|
|
||||||
Sbitset items;
|
|
||||||
if (AnnotationList__compute_lhs_contributions (
|
|
||||||
*predecessor,
|
|
||||||
&rules[item_number_as_rule_number (ritem[rulei])],
|
|
||||||
contribution_token,
|
|
||||||
follow_kernel_items, always_follows, predecessors,
|
|
||||||
item_lookahead_sets, &items, annotations_obstackp))
|
|
||||||
{
|
|
||||||
obstack_free (annotations_obstackp,
|
|
||||||
annotation_node->contributions[ci]);
|
|
||||||
annotation_node->contributions[ci] = NULL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Sbitset__or (annotation_node->contributions[ci],
|
|
||||||
annotation_node->contributions[ci],
|
|
||||||
items, (*predecessor)->nitems);
|
|
||||||
obstack_free (annotations_obstackp, items);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* If this kernel item is later in the RHS, then check the
|
|
||||||
predecessor item's lookahead set. */
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* We don't have to start the predecessor item search at
|
|
||||||
the beginning every time because items from both
|
|
||||||
states are sorted by their indices in ritem. */
|
|
||||||
for (;
|
|
||||||
predecessor_item < (*predecessor)->nitems;
|
|
||||||
++predecessor_item)
|
|
||||||
if ((*predecessor)->items[predecessor_item]
|
|
||||||
== s->items[self_item] - 1)
|
|
||||||
break;
|
|
||||||
aver (predecessor_item != (*predecessor)->nitems);
|
|
||||||
if (ielr_item_has_lookahead (*predecessor, 0,
|
|
||||||
predecessor_item,
|
|
||||||
contribution_token,
|
|
||||||
predecessors,
|
|
||||||
item_lookahead_sets))
|
|
||||||
Sbitset__set (annotation_node->contributions[ci],
|
|
||||||
predecessor_item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (annotation_node->contributions[ci])
|
annotation_node->contributions[ci] =
|
||||||
|
Sbitset__new_on_obstack ((*predecessor)->nitems,
|
||||||
|
annotations_obstackp);
|
||||||
|
{
|
||||||
|
size_t predecessor_item = 0;
|
||||||
|
Sbitset sbiter_item;
|
||||||
|
Sbitset__Index self_item;
|
||||||
|
SBITSET__FOR_EACH (self->contributions[ci], s->nitems,
|
||||||
|
sbiter_item, self_item)
|
||||||
{
|
{
|
||||||
Sbitset biter;
|
/* If this kernel item is the beginning of a RHS, it must be
|
||||||
Sbitset__Index i;
|
the kernel item in the start state, and so it has an empty
|
||||||
SBITSET__FOR_EACH (annotation_node->contributions[ci],
|
lookahead set. Thus, it can't contribute to inadequacies,
|
||||||
(*predecessor)->nitems, biter, i)
|
and so it should never have been identified as a
|
||||||
|
contribution. If, instead, this kernel item is the
|
||||||
|
successor of the start state's kernel item, the lookahead
|
||||||
|
set is still empty, and so it also should never have been
|
||||||
|
identified as a contribution. This situation is fortunate
|
||||||
|
because we want to avoid the - 2 below in both cases. */
|
||||||
|
aver (s->items[self_item] > 1);
|
||||||
|
/* If this kernel item is next to the beginning of the RHS,
|
||||||
|
then check all of the predecessor's goto follows for the
|
||||||
|
LHS. */
|
||||||
|
if (item_number_is_rule_number (ritem[s->items[self_item] - 2]))
|
||||||
{
|
{
|
||||||
potential_contribution = true;
|
Sbitset items;
|
||||||
if (!lookaheads)
|
if (AnnotationList__compute_lhs_contributions (
|
||||||
|
*predecessor,
|
||||||
|
item_rule (&ritem[s->items[self_item]]),
|
||||||
|
contribution_token,
|
||||||
|
follow_kernel_items, always_follows, predecessors,
|
||||||
|
item_lookahead_sets, &items, annotations_obstackp))
|
||||||
{
|
{
|
||||||
lookaheads = xnmalloc ((*predecessor)->nitems,
|
obstack_free (annotations_obstackp,
|
||||||
sizeof *lookaheads);
|
annotation_node->contributions[ci]);
|
||||||
for (size_t j = 0; j < (*predecessor)->nitems; ++j)
|
annotation_node->contributions[ci] = NULL;
|
||||||
lookaheads[j] = NULL;
|
// "Break" out of SBITSET__FOR_EACH.
|
||||||
|
goto after_sbitset__for_each;
|
||||||
}
|
}
|
||||||
if (!lookaheads[i])
|
else
|
||||||
lookaheads[i] = bitset_create (ntokens, BITSET_FIXED);
|
{
|
||||||
bitset_set (lookaheads[i], contribution_token);
|
Sbitset__or (annotation_node->contributions[ci],
|
||||||
|
annotation_node->contributions[ci],
|
||||||
|
items, (*predecessor)->nitems);
|
||||||
|
obstack_free (annotations_obstackp, items);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* If this kernel item is later in the RHS, then check the
|
||||||
|
predecessor item's lookahead set. */
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* We don't have to start the predecessor item search at
|
||||||
|
the beginning every time because items from both
|
||||||
|
states are sorted by their indices in ritem. */
|
||||||
|
for (;
|
||||||
|
predecessor_item < (*predecessor)->nitems;
|
||||||
|
++predecessor_item)
|
||||||
|
if ((*predecessor)->items[predecessor_item]
|
||||||
|
== s->items[self_item] - 1)
|
||||||
|
break;
|
||||||
|
aver (predecessor_item != (*predecessor)->nitems);
|
||||||
|
if (ielr_item_has_lookahead (*predecessor, 0,
|
||||||
|
predecessor_item,
|
||||||
|
contribution_token,
|
||||||
|
predecessors,
|
||||||
|
item_lookahead_sets))
|
||||||
|
Sbitset__set (annotation_node->contributions[ci],
|
||||||
|
predecessor_item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
after_sbitset__for_each:;
|
||||||
}
|
}
|
||||||
}
|
if (annotation_node->contributions[ci])
|
||||||
|
{
|
||||||
|
Sbitset biter;
|
||||||
|
Sbitset__Index i;
|
||||||
|
SBITSET__FOR_EACH (annotation_node->contributions[ci],
|
||||||
|
(*predecessor)->nitems, biter, i)
|
||||||
|
{
|
||||||
|
potential_contribution = true;
|
||||||
|
if (!lookaheads)
|
||||||
|
{
|
||||||
|
lookaheads = xnmalloc ((*predecessor)->nitems,
|
||||||
|
sizeof *lookaheads);
|
||||||
|
for (size_t j = 0; j < (*predecessor)->nitems; ++j)
|
||||||
|
lookaheads[j] = NULL;
|
||||||
|
}
|
||||||
|
if (!lookaheads[i])
|
||||||
|
lookaheads[i] = bitset_create (ntokens, BITSET_FIXED);
|
||||||
|
bitset_set (lookaheads[i], contribution_token);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* If the predecessor has any contributions besides just "always" and
|
/* If the predecessor has any contributions besides just "always" and
|
||||||
"never" contributions:
|
"never" contributions:
|
||||||
@@ -409,7 +401,7 @@ AnnotationList__compute_from_inadequacies (
|
|||||||
struct obstack *annotations_obstackp,
|
struct obstack *annotations_obstackp,
|
||||||
InadequacyListNodeCount *inadequacy_list_node_count)
|
InadequacyListNodeCount *inadequacy_list_node_count)
|
||||||
{
|
{
|
||||||
/* Return an empty list if s->lookahead_tokens = NULL. */
|
/* Return an empty list if s->lookaheads = NULL. */
|
||||||
if (s->consistent)
|
if (s->consistent)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -425,16 +417,12 @@ AnnotationList__compute_from_inadequacies (
|
|||||||
BITSET_FOR_EACH (biter_conflict, conflicted_tokens, conflicted_token, 0)
|
BITSET_FOR_EACH (biter_conflict, conflicted_tokens, conflicted_token, 0)
|
||||||
{
|
{
|
||||||
AnnotationList *annotation_node;
|
AnnotationList *annotation_node;
|
||||||
/* FIXME: Would a BITSET_FRUGAL or BITEST_SPARSE be more efficient? Now
|
|
||||||
or convert it inside InadequacyList__new_conflict? */
|
|
||||||
bitset actions = bitset_create (s->reductions->num + 1, BITSET_FIXED);
|
|
||||||
ContributionIndex contribution_count = 0;
|
ContributionIndex contribution_count = 0;
|
||||||
bool potential_contribution = false;
|
|
||||||
|
|
||||||
/* Allocate the annotation node. */
|
/* Allocate the annotation node. */
|
||||||
{
|
{
|
||||||
for (int rule_i = 0; rule_i < s->reductions->num; ++rule_i)
|
for (int rule_i = 0; rule_i < s->reductions->num; ++rule_i)
|
||||||
if (bitset_test (s->reductions->lookahead_tokens[rule_i],
|
if (bitset_test (s->reductions->lookaheads[rule_i],
|
||||||
conflicted_token))
|
conflicted_token))
|
||||||
++contribution_count;
|
++contribution_count;
|
||||||
if (bitset_test (shift_tokens, conflicted_token))
|
if (bitset_test (shift_tokens, conflicted_token))
|
||||||
@@ -444,6 +432,11 @@ AnnotationList__compute_from_inadequacies (
|
|||||||
annotations_obstackp);
|
annotations_obstackp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* FIXME: Would a BITSET_FRUGAL or BITEST_SPARSE be more efficient? Now
|
||||||
|
or convert it inside InadequacyList__new_conflict? */
|
||||||
|
bitset actions = bitset_create (s->reductions->num + 1, BITSET_FIXED);
|
||||||
|
bool potential_contribution = false;
|
||||||
|
|
||||||
/* Add a contribution for each reduction that has conflicted_token as a
|
/* Add a contribution for each reduction that has conflicted_token as a
|
||||||
lookahead. */
|
lookahead. */
|
||||||
{
|
{
|
||||||
@@ -452,7 +445,7 @@ AnnotationList__compute_from_inadequacies (
|
|||||||
for (int rule_i = 0; rule_i < s->reductions->num; ++rule_i)
|
for (int rule_i = 0; rule_i < s->reductions->num; ++rule_i)
|
||||||
{
|
{
|
||||||
rule *the_rule = s->reductions->rules[rule_i];
|
rule *the_rule = s->reductions->rules[rule_i];
|
||||||
if (bitset_test (s->reductions->lookahead_tokens[rule_i],
|
if (bitset_test (s->reductions->lookaheads[rule_i],
|
||||||
conflicted_token))
|
conflicted_token))
|
||||||
{
|
{
|
||||||
bitset_set (actions, rule_i);
|
bitset_set (actions, rule_i);
|
||||||
@@ -464,11 +457,8 @@ AnnotationList__compute_from_inadequacies (
|
|||||||
annotations_obstackp);
|
annotations_obstackp);
|
||||||
/* Catch item_i up to rule_i. This works because both are
|
/* Catch item_i up to rule_i. This works because both are
|
||||||
sorted on rule number. */
|
sorted on rule number. */
|
||||||
while (!item_number_is_rule_number (
|
while (!item_number_is_rule_number (ritem[s->items[item_i]])
|
||||||
ritem[s->items[item_i]])
|
|| item_number_as_rule_number (ritem[s->items[item_i]]) != the_rule->number)
|
||||||
|| item_number_as_rule_number (
|
|
||||||
ritem[s->items[item_i]])
|
|
||||||
!= the_rule->number)
|
|
||||||
{
|
{
|
||||||
++item_i;
|
++item_i;
|
||||||
aver (item_i < s->nitems);
|
aver (item_i < s->nitems);
|
||||||
@@ -571,44 +561,40 @@ AnnotationList__debug (AnnotationList const *self, size_t nitems, int spaces)
|
|||||||
AnnotationIndex ai;
|
AnnotationIndex ai;
|
||||||
for (a = self, ai = 0; a; a = a->next, ++ai)
|
for (a = self, ai = 0; a; a = a->next, ++ai)
|
||||||
{
|
{
|
||||||
for (int j = 0; j < spaces; ++j)
|
fprintf (stderr, "%*sAnnotation %d (manifesting state %d):\n",
|
||||||
putc (' ', stderr);
|
spaces, "",
|
||||||
fprintf (stderr, "Annotation %d (manifesting state %d):\n",
|
|
||||||
ai, a->inadequacyNode->manifestingState->number);
|
ai, a->inadequacyNode->manifestingState->number);
|
||||||
{
|
bitset_bindex rulei
|
||||||
bitset_bindex rulei
|
= bitset_first (a->inadequacyNode->inadequacy.conflict.actions);
|
||||||
= bitset_first (a->inadequacyNode->inadequacy.conflict.actions);
|
for (ContributionIndex ci = 0; ci < a->inadequacyNode->contributionCount; ++ci)
|
||||||
for (ContributionIndex ci = 0; ci < a->inadequacyNode->contributionCount; ++ci)
|
{
|
||||||
{
|
symbol_number token =
|
||||||
symbol_number token =
|
InadequacyList__getContributionToken (a->inadequacyNode, ci)
|
||||||
InadequacyList__getContributionToken (a->inadequacyNode, ci)
|
->content->number;
|
||||||
->content->number;
|
fprintf (stderr, "%*s", spaces+2, "");
|
||||||
for (int j = 0; j < spaces+2; ++j)
|
if (ci == InadequacyList__getShiftContributionIndex (
|
||||||
putc (' ', stderr);
|
a->inadequacyNode))
|
||||||
if (ci == InadequacyList__getShiftContributionIndex (
|
fprintf (stderr, "Contributes shift of token %d.\n", token);
|
||||||
a->inadequacyNode))
|
else
|
||||||
fprintf (stderr, "Contributes shift of token %d.\n", token);
|
{
|
||||||
else
|
fprintf (stderr, "Contributes token %d", token);
|
||||||
{
|
aver (rulei != BITSET_BINDEX_MAX);
|
||||||
fprintf (stderr, "Contributes token %d", token);
|
fprintf (stderr, " as lookahead, rule number %d",
|
||||||
aver (rulei != BITSET_BINDEX_MAX);
|
a->inadequacyNode->manifestingState
|
||||||
fprintf (stderr, " as lookahead, rule number %d",
|
->reductions->rules[rulei]->number);
|
||||||
a->inadequacyNode->manifestingState
|
rulei =
|
||||||
->reductions->rules[rulei]->number);
|
bitset_next (a->inadequacyNode->inadequacy.conflict.actions,
|
||||||
rulei =
|
rulei+1);
|
||||||
bitset_next (a->inadequacyNode->inadequacy.conflict.actions,
|
if (AnnotationList__isContributionAlways (a, ci))
|
||||||
rulei+1);
|
fprintf (stderr, " always.");
|
||||||
if (AnnotationList__isContributionAlways (a, ci))
|
else
|
||||||
fprintf (stderr, " always.");
|
{
|
||||||
else
|
fprintf (stderr, ", items: ");
|
||||||
{
|
Sbitset__fprint (a->contributions[ci], nitems, stderr);
|
||||||
fprintf (stderr, ", items: ");
|
}
|
||||||
Sbitset__fprint (a->contributions[ci], nitems, stderr);
|
fprintf (stderr, "\n");
|
||||||
}
|
}
|
||||||
fprintf (stderr, "\n");
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -775,8 +761,7 @@ AnnotationList__computeDominantContribution (AnnotationList const *self,
|
|||||||
/* R/R conflict, so the reduction with the lowest rule number dominates.
|
/* R/R conflict, so the reduction with the lowest rule number dominates.
|
||||||
Fortunately, contributions are sorted by rule number. */
|
Fortunately, contributions are sorted by rule number. */
|
||||||
for (ContributionIndex ci = 0; ci < self->inadequacyNode->contributionCount; ++ci)
|
for (ContributionIndex ci = 0; ci < self->inadequacyNode->contributionCount; ++ci)
|
||||||
if (AnnotationList__stateMakesContribution (self, nitems, ci,
|
if (AnnotationList__stateMakesContribution (self, nitems, ci, lookaheads))
|
||||||
lookaheads))
|
|
||||||
{
|
{
|
||||||
if (require_split_stable
|
if (require_split_stable
|
||||||
&& !AnnotationList__isContributionAlways (self, ci))
|
&& !AnnotationList__isContributionAlways (self, ci))
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
# define ANNOTATION_LIST_H_
|
# define ANNOTATION_LIST_H_
|
||||||
|
|
||||||
# include <bitsetv.h>
|
# include <bitsetv.h>
|
||||||
|
|
||||||
# include "Sbitset.h"
|
# include "Sbitset.h"
|
||||||
# include "InadequacyList.h"
|
# include "InadequacyList.h"
|
||||||
# include "state.h"
|
# include "state.h"
|
||||||
|
|||||||
@@ -81,6 +81,8 @@ void Sbitset__fprint (Sbitset self, Sbitset__Index nbits, FILE *file);
|
|||||||
*ptr_self = *ptr_other1 | *ptr_other2; \
|
*ptr_self = *ptr_other1 | *ptr_other2; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
/* ATTENTION: there are *two* loops here, "break" and "continue" will
|
||||||
|
not apply to the whole loop, just the inner one. */
|
||||||
# define SBITSET__FOR_EACH(SELF, NBITS, ITER, INDEX) \
|
# define SBITSET__FOR_EACH(SELF, NBITS, ITER, INDEX) \
|
||||||
for ((ITER) = (SELF); (ITER) < (SELF) + Sbitset__nbytes (NBITS); ++(ITER)) \
|
for ((ITER) = (SELF); (ITER) < (SELF) + Sbitset__nbytes (NBITS); ++(ITER)) \
|
||||||
if (*(ITER) != 0) \
|
if (*(ITER) != 0) \
|
||||||
|
|||||||
+20
-20
@@ -32,7 +32,7 @@
|
|||||||
#include "symtab.h"
|
#include "symtab.h"
|
||||||
|
|
||||||
/* NITEMSET is the size of the array ITEMSET. */
|
/* NITEMSET is the size of the array ITEMSET. */
|
||||||
item_number *itemset;
|
item_index *itemset;
|
||||||
size_t nitemset;
|
size_t nitemset;
|
||||||
|
|
||||||
/* RULESET contains a bit for each rule. CLOSURE sets the bits for
|
/* RULESET contains a bit for each rule. CLOSURE sets the bits for
|
||||||
@@ -54,16 +54,16 @@ static bitsetv firsts = NULL;
|
|||||||
`-----------------*/
|
`-----------------*/
|
||||||
|
|
||||||
static void
|
static void
|
||||||
closure_print (char const *title, item_number const *array, size_t size)
|
closure_print (char const *title, item_index const *array, size_t size)
|
||||||
{
|
{
|
||||||
fprintf (stderr, "Closure: %s\n", title);
|
fprintf (stderr, "Closure: %s\n", title);
|
||||||
for (size_t i = 0; i < size; ++i)
|
for (size_t i = 0; i < size; ++i)
|
||||||
{
|
{
|
||||||
fprintf (stderr, " %2d: .", array[i]);
|
fprintf (stderr, " %2d: .", array[i]);
|
||||||
item_number *rp;
|
item_number *rp;
|
||||||
for (rp = &ritem[array[i]]; *rp >= 0; ++rp)
|
for (rp = &ritem[array[i]]; 0 <= *rp; ++rp)
|
||||||
fprintf (stderr, " %s", symbols[*rp]->tag);
|
fprintf (stderr, " %s", symbols[*rp]->tag);
|
||||||
fprintf (stderr, " (rule %d)\n", -*rp - 1);
|
fprintf (stderr, " (rule %d)\n", item_number_as_rule_number (*rp));
|
||||||
}
|
}
|
||||||
fputs ("\n\n", stderr);
|
fputs ("\n\n", stderr);
|
||||||
}
|
}
|
||||||
@@ -104,21 +104,21 @@ print_fderives (void)
|
|||||||
fprintf (stderr, "\n\n");
|
fprintf (stderr, "\n\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*------------------------------------------------------------------.
|
/*-------------------------------------------------------------------.
|
||||||
| Set FIRSTS to be an NVARS array of NVARS bitsets indicating which |
|
| Set FIRSTS to be an NNTERMS array of NNTERMS bitsets indicating |
|
||||||
| items can represent the beginning of the input corresponding to |
|
| which items can represent the beginning of the input corresponding |
|
||||||
| which other items. |
|
| to which other items. |
|
||||||
| |
|
| |
|
||||||
| For example, if some rule expands symbol 5 into the sequence of |
|
| For example, if some rule expands symbol 5 into the sequence of |
|
||||||
| symbols 8 3 20, the symbol 8 can be the beginning of the data for |
|
| symbols 8 3 20, the symbol 8 can be the beginning of the data for |
|
||||||
| symbol 5, so the bit [8 - ntokens] in first[5 - ntokens] (= FIRST |
|
| symbol 5, so the bit [8 - ntokens] in first[5 - ntokens] (= FIRST |
|
||||||
| (5)) is set. |
|
| (5)) is set. |
|
||||||
`------------------------------------------------------------------*/
|
`-------------------------------------------------------------------*/
|
||||||
|
|
||||||
static void
|
static void
|
||||||
set_firsts (void)
|
set_firsts (void)
|
||||||
{
|
{
|
||||||
firsts = bitsetv_create (nvars, nvars, BITSET_FIXED);
|
firsts = bitsetv_create (nnterms, nnterms, BITSET_FIXED);
|
||||||
|
|
||||||
for (symbol_number i = ntokens; i < nsyms; ++i)
|
for (symbol_number i = ntokens; i < nsyms; ++i)
|
||||||
for (symbol_number j = 0; derives[i - ntokens][j]; ++j)
|
for (symbol_number j = 0; derives[i - ntokens][j]; ++j)
|
||||||
@@ -139,8 +139,8 @@ set_firsts (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*-------------------------------------------------------------------.
|
/*-------------------------------------------------------------------.
|
||||||
| Set FDERIVES to an NVARS by NRULES matrix of bits indicating which |
|
| Set FDERIVES to an NNTERMS by NRULES matrix of bits indicating |
|
||||||
| rules can help derive the beginning of the data for each |
|
| which rules can help derive the beginning of the data for each |
|
||||||
| nonterminal. |
|
| nonterminal. |
|
||||||
| |
|
| |
|
||||||
| For example, if symbol 5 can be derived as the sequence of symbols |
|
| For example, if symbol 5 can be derived as the sequence of symbols |
|
||||||
@@ -151,7 +151,7 @@ set_firsts (void)
|
|||||||
static void
|
static void
|
||||||
set_fderives (void)
|
set_fderives (void)
|
||||||
{
|
{
|
||||||
fderives = bitsetv_create (nvars, nrules, BITSET_FIXED);
|
fderives = bitsetv_create (nnterms, nrules, BITSET_FIXED);
|
||||||
|
|
||||||
set_firsts ();
|
set_firsts ();
|
||||||
|
|
||||||
@@ -182,7 +182,7 @@ closure_new (int n)
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
closure (item_number const *core, size_t n)
|
closure (item_index const *core, size_t n)
|
||||||
{
|
{
|
||||||
if (trace_flag & trace_closure)
|
if (trace_flag & trace_closure)
|
||||||
closure_print ("input", core, n);
|
closure_print ("input", core, n);
|
||||||
@@ -203,7 +203,7 @@ closure (item_number const *core, size_t n)
|
|||||||
bitset_iterator iter;
|
bitset_iterator iter;
|
||||||
BITSET_FOR_EACH (iter, ruleset, ruleno, 0)
|
BITSET_FOR_EACH (iter, ruleset, ruleno, 0)
|
||||||
{
|
{
|
||||||
item_number itemno = rules[ruleno].rhs - ritem;
|
item_index itemno = rules[ruleno].rhs - ritem;
|
||||||
while (c < n && core[c] < itemno)
|
while (c < n && core[c] < itemno)
|
||||||
{
|
{
|
||||||
itemset[nitemset] = core[c];
|
itemset[nitemset] = core[c];
|
||||||
|
|||||||
+4
-4
@@ -30,12 +30,12 @@
|
|||||||
void closure_new (int n);
|
void closure_new (int n);
|
||||||
|
|
||||||
|
|
||||||
/* Given the kernel (aka core) of a state (a sorted vector of item numbers
|
/* Given the kernel (aka core) of a state (a sorted vector of item indices
|
||||||
ITEMS, of length N), set up RULESET and ITEMSET to indicate what
|
ITEMS, of length N), set up RULESET and ITEMSET to indicate what
|
||||||
rules could be run and which items could be accepted when those
|
rules could be run and which items could be accepted when those
|
||||||
items are the active ones. */
|
items are the active ones. */
|
||||||
|
|
||||||
void closure (item_number const *items, size_t n);
|
void closure (item_index const *items, size_t n);
|
||||||
|
|
||||||
|
|
||||||
/* Free ITEMSET, RULESET and internal data. */
|
/* Free ITEMSET, RULESET and internal data. */
|
||||||
@@ -43,12 +43,12 @@ void closure (item_number const *items, size_t n);
|
|||||||
void closure_free (void);
|
void closure_free (void);
|
||||||
|
|
||||||
|
|
||||||
/* ITEMSET is a sorted vector of item numbers; NITEMSET is its size
|
/* ITEMSET is a sorted vector of item indices; NITEMSET is its size
|
||||||
(actually, points to just beyond the end of the part of it that is
|
(actually, points to just beyond the end of the part of it that is
|
||||||
significant). CLOSURE places there the indices of all items which
|
significant). CLOSURE places there the indices of all items which
|
||||||
represent units of input that could arrive next. */
|
represent units of input that could arrive next. */
|
||||||
|
|
||||||
extern item_number *itemset;
|
extern item_index *itemset;
|
||||||
extern size_t nitemset;
|
extern size_t nitemset;
|
||||||
|
|
||||||
#endif /* !CLOSURE_H_ */
|
#endif /* !CLOSURE_H_ */
|
||||||
|
|||||||
+70
-21
@@ -23,7 +23,7 @@
|
|||||||
#include "system.h"
|
#include "system.h"
|
||||||
|
|
||||||
#include <argmatch.h>
|
#include <argmatch.h>
|
||||||
#include <ctype.h>
|
#include <c-ctype.h>
|
||||||
#include <progname.h>
|
#include <progname.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
@@ -35,6 +35,13 @@
|
|||||||
#include "getargs.h"
|
#include "getargs.h"
|
||||||
#include "quote.h"
|
#include "quote.h"
|
||||||
|
|
||||||
|
// The URL of the manual page about diagnostics. Use the per-node
|
||||||
|
// manual, to avoid downloading repeatedly the whole manual over the
|
||||||
|
// Internet.
|
||||||
|
static const char *diagnostics_url
|
||||||
|
= "https://www.gnu.org/software/bison/manual/html_node/Diagnostics.html";
|
||||||
|
|
||||||
|
|
||||||
err_status complaint_status = status_none;
|
err_status complaint_status = status_none;
|
||||||
|
|
||||||
bool warnings_are_errors = false;
|
bool warnings_are_errors = false;
|
||||||
@@ -96,6 +103,20 @@ end_use_class (const char *s, FILE *out)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
begin_hyperlink (FILE *out, const char *ref)
|
||||||
|
{
|
||||||
|
if (out == stderr)
|
||||||
|
styled_ostream_set_hyperlink (errstream, ref, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
end_hyperlink (FILE *out)
|
||||||
|
{
|
||||||
|
if (out == stderr)
|
||||||
|
styled_ostream_set_hyperlink (errstream, NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
flush (FILE *out)
|
flush (FILE *out)
|
||||||
{
|
{
|
||||||
@@ -104,6 +125,23 @@ flush (FILE *out)
|
|||||||
fflush (out);
|
fflush (out);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
is_styled (FILE *out)
|
||||||
|
{
|
||||||
|
if (out != stderr)
|
||||||
|
return false;
|
||||||
|
if (color_debug)
|
||||||
|
return true;
|
||||||
|
#if HAVE_LIBTEXTSTYLE
|
||||||
|
return (color_mode == color_yes
|
||||||
|
|| color_mode == color_html
|
||||||
|
|| (color_mode == color_tty && isatty (STDERR_FILENO)));
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*------------------------.
|
/*------------------------.
|
||||||
| --warnings's handling. |
|
| --warnings's handling. |
|
||||||
`------------------------*/
|
`------------------------*/
|
||||||
@@ -114,6 +152,7 @@ static const argmatch_warning_doc argmatch_warning_docs[] =
|
|||||||
{
|
{
|
||||||
{ "conflicts-sr", N_("S/R conflicts (enabled by default)") },
|
{ "conflicts-sr", N_("S/R conflicts (enabled by default)") },
|
||||||
{ "conflicts-rr", N_("R/R conflicts (enabled by default)") },
|
{ "conflicts-rr", N_("R/R conflicts (enabled by default)") },
|
||||||
|
{ "counterexamples", N_("generate conflict counterexamples") },
|
||||||
{ "dangling-alias", N_("string aliases not attached to a symbol") },
|
{ "dangling-alias", N_("string aliases not attached to a symbol") },
|
||||||
{ "deprecated", N_("obsolete constructs") },
|
{ "deprecated", N_("obsolete constructs") },
|
||||||
{ "empty-rule", N_("empty rules without %empty") },
|
{ "empty-rule", N_("empty rules without %empty") },
|
||||||
@@ -121,7 +160,7 @@ static const argmatch_warning_doc argmatch_warning_docs[] =
|
|||||||
{ "precedence", N_("useless precedence and associativity") },
|
{ "precedence", N_("useless precedence and associativity") },
|
||||||
{ "yacc", N_("incompatibilities with POSIX Yacc") },
|
{ "yacc", N_("incompatibilities with POSIX Yacc") },
|
||||||
{ "other", N_("all other warnings (enabled by default)") },
|
{ "other", N_("all other warnings (enabled by default)") },
|
||||||
{ "all", N_("all the warnings except 'dangling-alias' and 'yacc'") },
|
{ "all", N_("all the warnings except 'counterexamples', 'dangling-alias' and 'yacc'") },
|
||||||
{ "no-CATEGORY", N_("turn off warnings in CATEGORY") },
|
{ "no-CATEGORY", N_("turn off warnings in CATEGORY") },
|
||||||
{ "none", N_("turn off all the warnings") },
|
{ "none", N_("turn off all the warnings") },
|
||||||
{ "error[=CATEGORY]", N_("treat warnings as errors") },
|
{ "error[=CATEGORY]", N_("treat warnings as errors") },
|
||||||
@@ -130,18 +169,19 @@ static const argmatch_warning_doc argmatch_warning_docs[] =
|
|||||||
|
|
||||||
static const argmatch_warning_arg argmatch_warning_args[] =
|
static const argmatch_warning_arg argmatch_warning_args[] =
|
||||||
{
|
{
|
||||||
{ "all", Wall },
|
{ "all", Wall },
|
||||||
{ "conflicts-rr", Wconflicts_rr },
|
{ "conflicts-rr", Wconflicts_rr },
|
||||||
{ "conflicts-sr", Wconflicts_sr },
|
{ "conflicts-sr", Wconflicts_sr },
|
||||||
{ "dangling-alias", Wdangling_alias },
|
{ "counterexamples", Wcounterexamples }, { "cex", Wcounterexamples }, // Show cex second.
|
||||||
{ "deprecated", Wdeprecated },
|
{ "dangling-alias", Wdangling_alias },
|
||||||
{ "empty-rule", Wempty_rule },
|
{ "deprecated", Wdeprecated },
|
||||||
{ "everything", Weverything },
|
{ "empty-rule", Wempty_rule },
|
||||||
{ "midrule-values", Wmidrule_values },
|
{ "everything", Weverything },
|
||||||
{ "none", Wnone },
|
{ "midrule-values", Wmidrule_values },
|
||||||
{ "other", Wother },
|
{ "none", Wnone },
|
||||||
{ "precedence", Wprecedence },
|
{ "other", Wother },
|
||||||
{ "yacc", Wyacc },
|
{ "precedence", Wprecedence },
|
||||||
|
{ "yacc", Wyacc },
|
||||||
{ NULL, Wnone }
|
{ NULL, Wnone }
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -286,9 +326,7 @@ void
|
|||||||
complain_init_color (void)
|
complain_init_color (void)
|
||||||
{
|
{
|
||||||
#if HAVE_LIBTEXTSTYLE
|
#if HAVE_LIBTEXTSTYLE
|
||||||
if (color_mode == color_yes
|
if (is_styled (stderr))
|
||||||
|| color_mode == color_html
|
|
||||||
|| (color_mode == color_tty && isatty (STDERR_FILENO)))
|
|
||||||
{
|
{
|
||||||
style_file_prepare ("BISON_STYLE", "BISON_STYLEDIR", pkgdatadir (),
|
style_file_prepare ("BISON_STYLE", "BISON_STYLEDIR", pkgdatadir (),
|
||||||
"bison-default.css");
|
"bison-default.css");
|
||||||
@@ -410,9 +448,20 @@ warnings_print_categories (warnings warn_flags, FILE *out)
|
|||||||
const char* style = severity_style (s);
|
const char* style = severity_style (s);
|
||||||
fputs (" [", out);
|
fputs (" [", out);
|
||||||
begin_use_class (style, out);
|
begin_use_class (style, out);
|
||||||
fprintf (out, "-W%s%s",
|
// E.g., "counterexamples".
|
||||||
s == severity_error ? "error=" : "",
|
const char *warning = argmatch_warning_argument (&w);
|
||||||
argmatch_warning_argument (&w));
|
char ref[200];
|
||||||
|
snprintf (ref, sizeof ref,
|
||||||
|
"%s#W%s", diagnostics_url, warning);
|
||||||
|
begin_hyperlink (out, ref);
|
||||||
|
ostream_printf (errstream,
|
||||||
|
"-W%s%s",
|
||||||
|
s == severity_error ? "error=" : "",
|
||||||
|
warning);
|
||||||
|
end_hyperlink (out);
|
||||||
|
// Because we mix stdio with ostream I/O, we need to flush
|
||||||
|
// here for sake of color == debug.
|
||||||
|
flush (out);
|
||||||
end_use_class (style, out);
|
end_use_class (style, out);
|
||||||
fputc (']', out);
|
fputc (']', out);
|
||||||
/* Display only the first match, the second is "-Wall". */
|
/* Display only the first match, the second is "-Wall". */
|
||||||
@@ -609,7 +658,7 @@ syntax_error (location loc,
|
|||||||
|
|
||||||
while (*format)
|
while (*format)
|
||||||
if (format[0] == '%'
|
if (format[0] == '%'
|
||||||
&& isdigit (format[1])
|
&& c_isdigit (format[1])
|
||||||
&& format[2] == '$'
|
&& format[2] == '$'
|
||||||
&& format[3] == 's'
|
&& format[3] == 's'
|
||||||
&& (format[1] - '0') < argc)
|
&& (format[1] - '0') < argc)
|
||||||
|
|||||||
+9
-3
@@ -19,6 +19,8 @@
|
|||||||
#ifndef COMPLAIN_H_
|
#ifndef COMPLAIN_H_
|
||||||
# define COMPLAIN_H_ 1
|
# define COMPLAIN_H_ 1
|
||||||
|
|
||||||
|
# include <attribute.h>
|
||||||
|
|
||||||
# include "location.h"
|
# include "location.h"
|
||||||
|
|
||||||
/*---------------.
|
/*---------------.
|
||||||
@@ -34,6 +36,8 @@ void end_use_class (const char *style, FILE *out);
|
|||||||
/** Flush \a out. */
|
/** Flush \a out. */
|
||||||
void flush (FILE *out);
|
void flush (FILE *out);
|
||||||
|
|
||||||
|
/** Whether there's styling on OUT. */
|
||||||
|
bool is_styled (FILE *out);
|
||||||
|
|
||||||
/*-------------.
|
/*-------------.
|
||||||
| --warnings. |
|
| --warnings. |
|
||||||
@@ -44,6 +48,7 @@ typedef enum
|
|||||||
{
|
{
|
||||||
warning_conflicts_rr,
|
warning_conflicts_rr,
|
||||||
warning_conflicts_sr,
|
warning_conflicts_sr,
|
||||||
|
warning_counterexamples,
|
||||||
warning_dangling_alias,
|
warning_dangling_alias,
|
||||||
warning_deprecated,
|
warning_deprecated,
|
||||||
warning_empty_rule,
|
warning_empty_rule,
|
||||||
@@ -104,6 +109,7 @@ typedef enum
|
|||||||
|
|
||||||
Wconflicts_rr = 1 << warning_conflicts_rr,
|
Wconflicts_rr = 1 << warning_conflicts_rr,
|
||||||
Wconflicts_sr = 1 << warning_conflicts_sr,
|
Wconflicts_sr = 1 << warning_conflicts_sr,
|
||||||
|
Wcounterexamples = 1 << warning_counterexamples,
|
||||||
Wdangling_alias = 1 << warning_dangling_alias,
|
Wdangling_alias = 1 << warning_dangling_alias,
|
||||||
Wdeprecated = 1 << warning_deprecated,
|
Wdeprecated = 1 << warning_deprecated,
|
||||||
Wempty_rule = 1 << warning_empty_rule,
|
Wempty_rule = 1 << warning_empty_rule,
|
||||||
@@ -120,7 +126,7 @@ typedef enum
|
|||||||
|
|
||||||
/**< All above warnings. */
|
/**< All above warnings. */
|
||||||
Weverything = ~complaint & ~fatal & ~silent,
|
Weverything = ~complaint & ~fatal & ~silent,
|
||||||
Wall = Weverything & ~Wdangling_alias & ~Wyacc
|
Wall = Weverything & ~Wcounterexamples & ~Wdangling_alias & ~Wyacc
|
||||||
} warnings;
|
} warnings;
|
||||||
|
|
||||||
/** Whether the warnings of \a flags are all unset.
|
/** Whether the warnings of \a flags are all unset.
|
||||||
@@ -132,7 +138,7 @@ bool warning_is_enabled (warnings flags);
|
|||||||
|
|
||||||
/** Make a complaint, with maybe a location. */
|
/** Make a complaint, with maybe a location. */
|
||||||
void complain (location const *loc, warnings flags, char const *message, ...)
|
void complain (location const *loc, warnings flags, char const *message, ...)
|
||||||
__attribute__ ((__format__ (__printf__, 3, 4)));
|
ATTRIBUTE_FORMAT ((__printf__, 3, 4));
|
||||||
|
|
||||||
/** Likewise, but with an \a argc/argv interface. */
|
/** Likewise, but with an \a argc/argv interface. */
|
||||||
void complain_args (location const *loc, warnings w,
|
void complain_args (location const *loc, warnings w,
|
||||||
@@ -141,7 +147,7 @@ void complain_args (location const *loc, warnings w,
|
|||||||
/** Make a subcomplain with location and note. */
|
/** Make a subcomplain with location and note. */
|
||||||
void subcomplain (location const *loc, warnings flags,
|
void subcomplain (location const *loc, warnings flags,
|
||||||
char const *message, ...)
|
char const *message, ...)
|
||||||
__attribute__ ((__format__ (__printf__, 3, 4)));
|
ATTRIBUTE_FORMAT ((__printf__, 3, 4));
|
||||||
|
|
||||||
|
|
||||||
/** GNU Bison extension not valid with POSIX Yacc. */
|
/** GNU Bison extension not valid with POSIX Yacc. */
|
||||||
|
|||||||
+87
-48
@@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
#include "complain.h"
|
#include "complain.h"
|
||||||
#include "conflicts.h"
|
#include "conflicts.h"
|
||||||
|
#include "counterexample.h"
|
||||||
#include "files.h"
|
#include "files.h"
|
||||||
#include "getargs.h"
|
#include "getargs.h"
|
||||||
#include "gram.h"
|
#include "gram.h"
|
||||||
@@ -48,6 +49,12 @@ static struct obstack solved_conflicts_xml_obstack;
|
|||||||
static bitset shift_set;
|
static bitset shift_set;
|
||||||
static bitset lookahead_set;
|
static bitset lookahead_set;
|
||||||
|
|
||||||
|
bool
|
||||||
|
has_conflicts (const state *s)
|
||||||
|
{
|
||||||
|
return conflicts[s->number];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
enum conflict_resolution
|
enum conflict_resolution
|
||||||
@@ -219,7 +226,7 @@ log_resolution (rule *r, symbol_number token,
|
|||||||
|
|
||||||
/*------------------------------------------------------------------.
|
/*------------------------------------------------------------------.
|
||||||
| Turn off the shift recorded for the specified token in the |
|
| Turn off the shift recorded for the specified token in the |
|
||||||
| specified state. Used when we resolve a shift-reduce conflict in |
|
| specified state. Used when we resolve a shift/reduce conflict in |
|
||||||
| favor of the reduction or as an error (%nonassoc). |
|
| favor of the reduction or as an error (%nonassoc). |
|
||||||
`------------------------------------------------------------------*/
|
`------------------------------------------------------------------*/
|
||||||
|
|
||||||
@@ -238,19 +245,19 @@ flush_shift (state *s, int token)
|
|||||||
|
|
||||||
/*--------------------------------------------------------------------.
|
/*--------------------------------------------------------------------.
|
||||||
| Turn off the reduce recorded for the specified token in the |
|
| Turn off the reduce recorded for the specified token in the |
|
||||||
| specified lookahead set. Used when we resolve a shift-reduce |
|
| specified lookahead set. Used when we resolve a shift/reduce |
|
||||||
| conflict in favor of the shift or as an error (%nonassoc). |
|
| conflict in favor of the shift or as an error (%nonassoc). |
|
||||||
`--------------------------------------------------------------------*/
|
`--------------------------------------------------------------------*/
|
||||||
|
|
||||||
static void
|
static void
|
||||||
flush_reduce (bitset lookahead_tokens, int token)
|
flush_reduce (bitset lookaheads, int token)
|
||||||
{
|
{
|
||||||
bitset_reset (lookahead_tokens, token);
|
bitset_reset (lookaheads, token);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------.
|
/*------------------------------------------------------------------.
|
||||||
| Attempt to resolve shift-reduce conflict for one rule by means of |
|
| Attempt to resolve shift/reduce conflict for one rule by means of |
|
||||||
| precedence declarations. It has already been checked that the |
|
| precedence declarations. It has already been checked that the |
|
||||||
| rule has a precedence. A conflict is resolved by modifying the |
|
| rule has a precedence. A conflict is resolved by modifying the |
|
||||||
| shift or reduce tables so that there is no longer a conflict. |
|
| shift or reduce tables so that there is no longer a conflict. |
|
||||||
@@ -268,14 +275,14 @@ resolve_sr_conflict (state *s, int ruleno, symbol **errors, int *nerrs)
|
|||||||
/* Find the rule to reduce by to get precedence of reduction. */
|
/* Find the rule to reduce by to get precedence of reduction. */
|
||||||
rule *redrule = reds->rules[ruleno];
|
rule *redrule = reds->rules[ruleno];
|
||||||
int redprec = redrule->prec->prec;
|
int redprec = redrule->prec->prec;
|
||||||
bitset lookahead_tokens = reds->lookahead_tokens[ruleno];
|
bitset lookaheads = reds->lookaheads[ruleno];
|
||||||
|
|
||||||
for (symbol_number i = 0; i < ntokens; ++i)
|
for (symbol_number i = 0; i < ntokens; ++i)
|
||||||
if (bitset_test (lookahead_tokens, i)
|
if (bitset_test (lookaheads, i)
|
||||||
&& bitset_test (lookahead_set, i)
|
&& bitset_test (lookahead_set, i)
|
||||||
&& symbols[i]->content->prec)
|
&& symbols[i]->content->prec)
|
||||||
{
|
{
|
||||||
/* Shift-reduce conflict occurs for token number i
|
/* Shift/reduce conflict occurs for token number i
|
||||||
and it has a precedence.
|
and it has a precedence.
|
||||||
The precedence of shifting is that of token i. */
|
The precedence of shifting is that of token i. */
|
||||||
if (symbols[i]->content->prec < redprec)
|
if (symbols[i]->content->prec < redprec)
|
||||||
@@ -288,7 +295,7 @@ resolve_sr_conflict (state *s, int ruleno, symbol **errors, int *nerrs)
|
|||||||
{
|
{
|
||||||
register_precedence (i, redrule->prec->number);
|
register_precedence (i, redrule->prec->number);
|
||||||
log_resolution (redrule, i, shift_resolution);
|
log_resolution (redrule, i, shift_resolution);
|
||||||
flush_reduce (lookahead_tokens, i);
|
flush_reduce (lookaheads, i);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
/* Matching precedence levels.
|
/* Matching precedence levels.
|
||||||
@@ -309,7 +316,7 @@ resolve_sr_conflict (state *s, int ruleno, symbol **errors, int *nerrs)
|
|||||||
case right_assoc:
|
case right_assoc:
|
||||||
register_assoc (i, redrule->prec->number);
|
register_assoc (i, redrule->prec->number);
|
||||||
log_resolution (redrule, i, right_resolution);
|
log_resolution (redrule, i, right_resolution);
|
||||||
flush_reduce (lookahead_tokens, i);
|
flush_reduce (lookaheads, i);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case left_assoc:
|
case left_assoc:
|
||||||
@@ -322,7 +329,7 @@ resolve_sr_conflict (state *s, int ruleno, symbol **errors, int *nerrs)
|
|||||||
register_assoc (i, redrule->prec->number);
|
register_assoc (i, redrule->prec->number);
|
||||||
log_resolution (redrule, i, nonassoc_resolution);
|
log_resolution (redrule, i, nonassoc_resolution);
|
||||||
flush_shift (s, i);
|
flush_shift (s, i);
|
||||||
flush_reduce (lookahead_tokens, i);
|
flush_reduce (lookaheads, i);
|
||||||
/* Record an explicit error for this token. */
|
/* Record an explicit error for this token. */
|
||||||
errors[(*nerrs)++] = symbols[i];
|
errors[(*nerrs)++] = symbols[i];
|
||||||
break;
|
break;
|
||||||
@@ -357,11 +364,12 @@ set_conflicts (state *s, symbol **errors)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Loop over all rules which require lookahead in this state. First
|
/* Loop over all rules which require lookahead in this state. First
|
||||||
check for shift-reduce conflict, and try to resolve using
|
check for shift/reduce conflict, and try to resolve using
|
||||||
precedence. */
|
precedence. */
|
||||||
for (int i = 0; i < reds->num; ++i)
|
for (int i = 0; i < reds->num; ++i)
|
||||||
if (reds->rules[i]->prec && reds->rules[i]->prec->prec
|
if (reds->rules[i]->prec
|
||||||
&& !bitset_disjoint_p (reds->lookahead_tokens[i], lookahead_set))
|
&& reds->rules[i]->prec->prec
|
||||||
|
&& !bitset_disjoint_p (reds->lookaheads[i], lookahead_set))
|
||||||
resolve_sr_conflict (s, i, errors, &nerrs);
|
resolve_sr_conflict (s, i, errors, &nerrs);
|
||||||
|
|
||||||
if (nerrs)
|
if (nerrs)
|
||||||
@@ -377,13 +385,13 @@ set_conflicts (state *s, symbol **errors)
|
|||||||
/* Loop over all rules which require lookahead in this state. Check
|
/* Loop over all rules which require lookahead in this state. Check
|
||||||
for conflicts not resolved above.
|
for conflicts not resolved above.
|
||||||
|
|
||||||
reds->lookahead_tokens can be NULL if the LR type is LR(0). */
|
reds->lookaheads can be NULL if the LR type is LR(0). */
|
||||||
if (reds->lookahead_tokens)
|
if (reds->lookaheads)
|
||||||
for (int i = 0; i < reds->num; ++i)
|
for (int i = 0; i < reds->num; ++i)
|
||||||
{
|
{
|
||||||
if (!bitset_disjoint_p (reds->lookahead_tokens[i], lookahead_set))
|
if (!bitset_disjoint_p (reds->lookaheads[i], lookahead_set))
|
||||||
conflicts[s->number] = true;
|
conflicts[s->number] = true;
|
||||||
bitset_or (lookahead_set, lookahead_set, reds->lookahead_tokens[i]);
|
bitset_or (lookahead_set, lookahead_set, reds->lookaheads[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -452,7 +460,7 @@ count_state_sr_conflicts (const state *s)
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < reds->num; ++i)
|
for (int i = 0; i < reds->num; ++i)
|
||||||
bitset_or (lookahead_set, lookahead_set, reds->lookahead_tokens[i]);
|
bitset_or (lookahead_set, lookahead_set, reds->lookaheads[i]);
|
||||||
|
|
||||||
bitset_and (lookahead_set, lookahead_set, shift_set);
|
bitset_and (lookahead_set, lookahead_set, shift_set);
|
||||||
|
|
||||||
@@ -491,7 +499,7 @@ count_state_rr_conflicts (const state *s)
|
|||||||
{
|
{
|
||||||
int count = 0;
|
int count = 0;
|
||||||
for (int j = 0; j < reds->num; ++j)
|
for (int j = 0; j < reds->num; ++j)
|
||||||
count += bitset_test (reds->lookahead_tokens[j], i);
|
count += bitset_test (reds->lookaheads[j], i);
|
||||||
if (2 <= count)
|
if (2 <= count)
|
||||||
res += count-1;
|
res += count-1;
|
||||||
}
|
}
|
||||||
@@ -526,7 +534,7 @@ count_rule_state_sr_conflicts (rule *r, state *s)
|
|||||||
for (int i = 0; i < reds->num; ++i)
|
for (int i = 0; i < reds->num; ++i)
|
||||||
if (reds->rules[i] == r)
|
if (reds->rules[i] == r)
|
||||||
{
|
{
|
||||||
bitset lookaheads = reds->lookahead_tokens[i];
|
bitset lookaheads = reds->lookaheads[i];
|
||||||
int j;
|
int j;
|
||||||
FOR_EACH_SHIFT (trans, j)
|
FOR_EACH_SHIFT (trans, j)
|
||||||
res += bitset_test (lookaheads, TRANSITION_SYMBOL (trans, j));
|
res += bitset_test (lookaheads, TRANSITION_SYMBOL (trans, j));
|
||||||
@@ -568,8 +576,8 @@ count_rule_state_rr_conflicts (rule *r, state *s)
|
|||||||
if (reds->rules[j] != r)
|
if (reds->rules[j] != r)
|
||||||
{
|
{
|
||||||
bitset_and (lookaheads,
|
bitset_and (lookaheads,
|
||||||
reds->lookahead_tokens[i],
|
reds->lookaheads[i],
|
||||||
reds->lookahead_tokens[j]);
|
reds->lookaheads[j]);
|
||||||
res += bitset_count (lookaheads);
|
res += bitset_count (lookaheads);
|
||||||
}
|
}
|
||||||
bitset_free (lookaheads);
|
bitset_free (lookaheads);
|
||||||
@@ -624,12 +632,20 @@ conflicts_total_count (void)
|
|||||||
return count_sr_conflicts () + count_rr_conflicts ();
|
return count_sr_conflicts () + count_rr_conflicts ();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*------------------------------.
|
static void
|
||||||
| Reporting per-rule conflicts. |
|
report_counterexamples (void)
|
||||||
`------------------------------*/
|
{
|
||||||
|
for (state_number sn = 0; sn < nstates; ++sn)
|
||||||
|
if (conflicts[sn])
|
||||||
|
counterexample_report_state (states[sn], stderr, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*------------------------------------------------.
|
||||||
|
| Report per-rule %expect/%expect-rr mismatches. |
|
||||||
|
`------------------------------------------------*/
|
||||||
|
|
||||||
static void
|
static void
|
||||||
rule_conflicts_print (void)
|
report_rule_expectation_mismatches (void)
|
||||||
{
|
{
|
||||||
for (rule_number i = 0; i < nrules; i += 1)
|
for (rule_number i = 0; i < nrules; i += 1)
|
||||||
{
|
{
|
||||||
@@ -644,13 +660,13 @@ rule_conflicts_print (void)
|
|||||||
complain (&r->location, complaint,
|
complain (&r->location, complaint,
|
||||||
_("shift/reduce conflicts for rule %d:"
|
_("shift/reduce conflicts for rule %d:"
|
||||||
" %d found, %d expected"),
|
" %d found, %d expected"),
|
||||||
r->user_number, sr, expected_sr);
|
r->code, sr, expected_sr);
|
||||||
int rr = count_rule_rr_conflicts (r);
|
int rr = count_rule_rr_conflicts (r);
|
||||||
if (rr != expected_rr && (rr != 0 || expected_rr != -1))
|
if (rr != expected_rr && (rr != 0 || expected_rr != -1))
|
||||||
complain (&r->location, complaint,
|
complain (&r->location, complaint,
|
||||||
_("reduce/reduce conflicts for rule %d:"
|
_("reduce/reduce conflicts for rule %d:"
|
||||||
" %d found, %d expected"),
|
" %d found, %d expected"),
|
||||||
r->user_number, rr, expected_rr);
|
r->code, rr, expected_rr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -662,7 +678,7 @@ rule_conflicts_print (void)
|
|||||||
void
|
void
|
||||||
conflicts_print (void)
|
conflicts_print (void)
|
||||||
{
|
{
|
||||||
rule_conflicts_print ();
|
report_rule_expectation_mismatches ();
|
||||||
|
|
||||||
if (! glr_parser && expected_rr_conflicts != -1)
|
if (! glr_parser && expected_rr_conflicts != -1)
|
||||||
{
|
{
|
||||||
@@ -670,8 +686,10 @@ conflicts_print (void)
|
|||||||
expected_rr_conflicts = -1;
|
expected_rr_conflicts = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Screams for factoring, but almost useless because of the
|
// The warning flags used to emit a diagnostic, if we did.
|
||||||
different strings to translate. */
|
warnings unexpected_conflicts_warning = Wnone;
|
||||||
|
/* The following two blocks scream for factoring, but i18n support
|
||||||
|
would make it ugly. */
|
||||||
{
|
{
|
||||||
int total = count_sr_conflicts ();
|
int total = count_sr_conflicts ();
|
||||||
/* If %expect is not used, but %expect-rr is, then expect 0 sr. */
|
/* If %expect is not used, but %expect-rr is, then expect 0 sr. */
|
||||||
@@ -682,16 +700,23 @@ conflicts_print (void)
|
|||||||
if (expected != -1)
|
if (expected != -1)
|
||||||
{
|
{
|
||||||
if (expected != total)
|
if (expected != total)
|
||||||
complain (NULL, complaint,
|
{
|
||||||
_("shift/reduce conflicts: %d found, %d expected"),
|
complain (NULL, complaint,
|
||||||
total, expected);
|
_("shift/reduce conflicts: %d found, %d expected"),
|
||||||
|
total, expected);
|
||||||
|
if (total)
|
||||||
|
unexpected_conflicts_warning = complaint;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (total)
|
else if (total)
|
||||||
complain (NULL, Wconflicts_sr,
|
{
|
||||||
ngettext ("%d shift/reduce conflict",
|
complain (NULL, Wconflicts_sr,
|
||||||
"%d shift/reduce conflicts",
|
ngettext ("%d shift/reduce conflict",
|
||||||
total),
|
"%d shift/reduce conflicts",
|
||||||
total);
|
total),
|
||||||
|
total);
|
||||||
|
unexpected_conflicts_warning = Wconflicts_sr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@@ -704,17 +729,31 @@ conflicts_print (void)
|
|||||||
if (expected != -1)
|
if (expected != -1)
|
||||||
{
|
{
|
||||||
if (expected != total)
|
if (expected != total)
|
||||||
complain (NULL, complaint,
|
{
|
||||||
_("reduce/reduce conflicts: %d found, %d expected"),
|
complain (NULL, complaint,
|
||||||
total, expected);
|
_("reduce/reduce conflicts: %d found, %d expected"),
|
||||||
|
total, expected);
|
||||||
|
if (total)
|
||||||
|
unexpected_conflicts_warning = complaint;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (total)
|
else if (total)
|
||||||
complain (NULL, Wconflicts_rr,
|
{
|
||||||
ngettext ("%d reduce/reduce conflict",
|
complain (NULL, Wconflicts_rr,
|
||||||
"%d reduce/reduce conflicts",
|
ngettext ("%d reduce/reduce conflict",
|
||||||
total),
|
"%d reduce/reduce conflicts",
|
||||||
total);
|
total),
|
||||||
|
total);
|
||||||
|
unexpected_conflicts_warning = Wconflicts_rr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (warning_is_enabled (Wcounterexamples))
|
||||||
|
report_counterexamples ();
|
||||||
|
else if (unexpected_conflicts_warning != Wnone)
|
||||||
|
subcomplain (NULL, unexpected_conflicts_warning,
|
||||||
|
_("rerun with option '-Wcounterexamples'"
|
||||||
|
" to generate conflict counterexamples"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|||||||
@@ -41,6 +41,8 @@ int conflicts_total_count (void);
|
|||||||
void conflicts_output (FILE *out);
|
void conflicts_output (FILE *out);
|
||||||
void conflicts_free (void);
|
void conflicts_free (void);
|
||||||
|
|
||||||
|
bool has_conflicts (const state *s);
|
||||||
|
|
||||||
/* Were there conflicts? */
|
/* Were there conflicts? */
|
||||||
extern int expected_sr_conflicts;
|
extern int expected_sr_conflicts;
|
||||||
extern int expected_rr_conflicts;
|
extern int expected_rr_conflicts;
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,36 @@
|
|||||||
|
/* Conflict counterexample generation
|
||||||
|
|
||||||
|
Copyright (C) 2020 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of Bison, the GNU Compiler Compiler.
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#ifndef COUNTEREXAMPLE_H
|
||||||
|
# define COUNTEREXAMPLE_H
|
||||||
|
|
||||||
|
# include "state.h"
|
||||||
|
|
||||||
|
// Init/deinit this module.
|
||||||
|
void counterexample_init (void);
|
||||||
|
void counterexample_free (void);
|
||||||
|
|
||||||
|
// Print the counterexamples for the conflicts of state S.
|
||||||
|
//
|
||||||
|
// Used both for the warnings on the terminal (OUT = stderr, PREFIX =
|
||||||
|
// ""), and for the reports (OUT != stderr, PREFIX != "").
|
||||||
|
void
|
||||||
|
counterexample_report_state (const state *s, FILE *out, const char *prefix);
|
||||||
|
|
||||||
|
#endif /* COUNTEREXAMPLE_H */
|
||||||
@@ -0,0 +1,444 @@
|
|||||||
|
/* Counterexample derivation trees
|
||||||
|
|
||||||
|
Copyright (C) 2020 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of Bison, the GNU Compiler Compiler.
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#include "derivation.h"
|
||||||
|
#include "glyphs.h"
|
||||||
|
|
||||||
|
#include <c-ctype.h>
|
||||||
|
#include <gl_linked_list.h>
|
||||||
|
#include <mbswidth.h>
|
||||||
|
|
||||||
|
#include "system.h"
|
||||||
|
#include "complain.h"
|
||||||
|
|
||||||
|
struct derivation
|
||||||
|
{
|
||||||
|
symbol_number sym;
|
||||||
|
derivation_list children;
|
||||||
|
int reference_count;
|
||||||
|
// Color assigned for styling. Guarantees that the derivation is
|
||||||
|
// always displayed with the same color, independently of the order
|
||||||
|
// in which the derivations are traversed.
|
||||||
|
int color;
|
||||||
|
};
|
||||||
|
|
||||||
|
static derivation d_dot = { -1, NULL, -1, -1 };
|
||||||
|
|
||||||
|
derivation *
|
||||||
|
derivation_dot (void)
|
||||||
|
{
|
||||||
|
return &d_dot;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
derivation_list_append (derivation_list dl, derivation *d)
|
||||||
|
{
|
||||||
|
derivation_retain (d);
|
||||||
|
gl_list_add_last (dl, d);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
derivation_list_prepend (derivation_list dl, derivation *d)
|
||||||
|
{
|
||||||
|
derivation_retain (d);
|
||||||
|
gl_list_add_first (dl, d);
|
||||||
|
}
|
||||||
|
|
||||||
|
void derivation_list_free (derivation_list dl)
|
||||||
|
{
|
||||||
|
derivation *d = NULL;
|
||||||
|
for (gl_list_iterator_t it = gl_list_iterator (dl);
|
||||||
|
derivation_list_next (&it, &d);
|
||||||
|
)
|
||||||
|
if (d != &d_dot)
|
||||||
|
derivation_free (d);
|
||||||
|
gl_list_free (dl);
|
||||||
|
}
|
||||||
|
|
||||||
|
derivation *
|
||||||
|
derivation_new (symbol_number sym, derivation_list children)
|
||||||
|
{
|
||||||
|
derivation *deriv = xmalloc (sizeof (derivation));
|
||||||
|
deriv->sym = sym;
|
||||||
|
deriv->children = children;
|
||||||
|
deriv->reference_count = 0;
|
||||||
|
deriv->color = -1;
|
||||||
|
return deriv;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
derivation_retain (derivation *d)
|
||||||
|
{
|
||||||
|
++d->reference_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
derivation_free (derivation *d)
|
||||||
|
{
|
||||||
|
if (!d)
|
||||||
|
return;
|
||||||
|
derivation_list free_queue =
|
||||||
|
gl_list_create (GL_LINKED_LIST, NULL, NULL, NULL, true,
|
||||||
|
1, (const void **)&d);
|
||||||
|
while (gl_list_size (free_queue) > 0)
|
||||||
|
{
|
||||||
|
derivation *deriv = (derivation *) gl_list_get_at (free_queue, 0);
|
||||||
|
if (--deriv->reference_count == 0)
|
||||||
|
{
|
||||||
|
if (deriv->children)
|
||||||
|
{
|
||||||
|
derivation *child = NULL;
|
||||||
|
for (gl_list_iterator_t it = gl_list_iterator (deriv->children);
|
||||||
|
derivation_list_next (&it, &child);
|
||||||
|
)
|
||||||
|
if (child != &d_dot)
|
||||||
|
gl_list_add_last (free_queue, child);
|
||||||
|
gl_list_free (deriv->children);
|
||||||
|
}
|
||||||
|
free (deriv);
|
||||||
|
}
|
||||||
|
gl_list_remove_at (free_queue, 0);
|
||||||
|
}
|
||||||
|
gl_list_free (free_queue);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t
|
||||||
|
derivation_size (const derivation *deriv)
|
||||||
|
{
|
||||||
|
if (!deriv->children)
|
||||||
|
return 1;
|
||||||
|
int size = 1;
|
||||||
|
derivation *child = NULL;
|
||||||
|
for (gl_list_iterator_t it = gl_list_iterator (deriv->children);
|
||||||
|
derivation_list_next (&it, &child);
|
||||||
|
)
|
||||||
|
size += derivation_size (child);
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
max (int a, int b)
|
||||||
|
{
|
||||||
|
return a < b ? b : a;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Longest distance from root to leaf.
|
||||||
|
static int
|
||||||
|
derivation_depth (const derivation *deriv)
|
||||||
|
{
|
||||||
|
if (deriv->children)
|
||||||
|
{
|
||||||
|
// Children's depth cannot be 0, even if there are no children
|
||||||
|
// (the case of a derivation with an empty RHS).
|
||||||
|
int res = 1;
|
||||||
|
derivation *child;
|
||||||
|
for (gl_list_iterator_t it = gl_list_iterator (deriv->children);
|
||||||
|
derivation_list_next (&it, &child);
|
||||||
|
)
|
||||||
|
res = max (res, derivation_depth (child));
|
||||||
|
return res + 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
all_spaces (const char *s)
|
||||||
|
{
|
||||||
|
while (c_isspace (*s))
|
||||||
|
s++;
|
||||||
|
return *s == '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Printing the derivation as trees without trailing spaces is
|
||||||
|
// painful: we cannot simply pad one "column" before moving to the
|
||||||
|
// next:
|
||||||
|
//
|
||||||
|
// exp
|
||||||
|
// ↳ x1 e1 foo1 x1
|
||||||
|
// ↳ x2 ↳ ε ↳ foo2 ↳ x2
|
||||||
|
// ↳ x3 ↳ foo3 ↳ x3
|
||||||
|
// ↳ "X" • ↳ x1 foo4 ↳ "X"
|
||||||
|
// ↳ x2 ↳ "quuux"
|
||||||
|
// ↳ x3
|
||||||
|
// ↳ "X"
|
||||||
|
//
|
||||||
|
// It's hard for a column to know that it's "last" to decide whether
|
||||||
|
// to output the right-padding or not. So when we need to pad on the
|
||||||
|
// right to complete a column, we don't output the spaces, we
|
||||||
|
// accumulate the width of padding in *PADDING.
|
||||||
|
//
|
||||||
|
// Each time we actually print something (non space), we flush that
|
||||||
|
// padding. When we _don't_ print something, its width is added to
|
||||||
|
// the current padding.
|
||||||
|
//
|
||||||
|
// This function implements this.
|
||||||
|
//
|
||||||
|
// When COND is true, put S on OUT, preceded by *PADDING white spaces.
|
||||||
|
// Otherwise add the width to *PADDING. Return the width of S.
|
||||||
|
static int
|
||||||
|
fputs_if (bool cond, FILE *out, int *padding, const char *s)
|
||||||
|
{
|
||||||
|
int res = mbswidth (s, 0);
|
||||||
|
if (cond && !all_spaces (s))
|
||||||
|
{
|
||||||
|
fprintf (out, "%*s%s", *padding, "", s);
|
||||||
|
*padding = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*padding += res;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The width taken to report this derivation recursively down to its
|
||||||
|
// leaves.
|
||||||
|
static int
|
||||||
|
derivation_width (const derivation *deriv)
|
||||||
|
{
|
||||||
|
if (deriv->children)
|
||||||
|
{
|
||||||
|
const symbol *sym = symbols[deriv->sym];
|
||||||
|
int self_width = mbswidth (sym->tag, 0);
|
||||||
|
|
||||||
|
// Arrow and space.
|
||||||
|
int children_width = down_arrow_width;
|
||||||
|
if (gl_list_size (deriv->children) == 0)
|
||||||
|
// Empty rhs.
|
||||||
|
children_width += empty_width;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
derivation *child;
|
||||||
|
for (gl_list_iterator_t it = gl_list_iterator (deriv->children);
|
||||||
|
derivation_list_next (&it, &child);
|
||||||
|
)
|
||||||
|
children_width
|
||||||
|
+= derivation_separator_width + derivation_width (child);
|
||||||
|
// No separator at the beginning.
|
||||||
|
children_width -= derivation_separator_width;
|
||||||
|
}
|
||||||
|
return max (self_width, children_width);
|
||||||
|
}
|
||||||
|
else if (deriv == &d_dot)
|
||||||
|
{
|
||||||
|
return dot_width;
|
||||||
|
}
|
||||||
|
else // leaf.
|
||||||
|
{
|
||||||
|
const symbol *sym = symbols[deriv->sym];
|
||||||
|
return mbswidth (sym->tag, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Print DERIV for DEPTH.
|
||||||
|
//
|
||||||
|
// The tree is printed from top to bottom with DEPTH ranging from 0 to
|
||||||
|
// the total depth of the tree. DERIV should only printed when we
|
||||||
|
// reach its depth, i.e., then DEPTH is 0.
|
||||||
|
//
|
||||||
|
// When DEPTH is 1 and we're on a subderivation, then we print the RHS
|
||||||
|
// of the derivation (in DEPTH 0 we printed its LHS).
|
||||||
|
//
|
||||||
|
// Return the "logical printed" width. We might have not have reached
|
||||||
|
// that width, in which case the missing spaces are in *PADDING.
|
||||||
|
static int
|
||||||
|
derivation_print_tree_impl (const derivation *deriv, FILE *out,
|
||||||
|
int depth, int *padding)
|
||||||
|
{
|
||||||
|
const int width = derivation_width (deriv);
|
||||||
|
|
||||||
|
int res = 0;
|
||||||
|
if (deriv->children)
|
||||||
|
{
|
||||||
|
const symbol *sym = symbols[deriv->sym];
|
||||||
|
char style[20];
|
||||||
|
snprintf (style, 20, "cex-%d", deriv->color);
|
||||||
|
|
||||||
|
if (depth == 0 || depth == 1)
|
||||||
|
{
|
||||||
|
begin_use_class (style, out);
|
||||||
|
begin_use_class ("cex-step", out);
|
||||||
|
}
|
||||||
|
if (depth == 0)
|
||||||
|
{
|
||||||
|
res += fputs_if (true, out, padding, sym->tag);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
res += fputs_if (depth == 1, out, padding, down_arrow);
|
||||||
|
if (gl_list_size (deriv->children) == 0)
|
||||||
|
// Empty rhs.
|
||||||
|
res += fputs_if (depth == 1, out, padding, empty);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bool first = true;
|
||||||
|
derivation *child;
|
||||||
|
for (gl_list_iterator_t it = gl_list_iterator (deriv->children);
|
||||||
|
derivation_list_next (&it, &child);
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (!first)
|
||||||
|
res += fputs_if (depth == 1, out, padding, derivation_separator);
|
||||||
|
res += derivation_print_tree_impl (child, out, depth - 1, padding);
|
||||||
|
first = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (depth == 0 || depth == 1)
|
||||||
|
{
|
||||||
|
end_use_class ("cex-step", out);
|
||||||
|
end_use_class (style, out);
|
||||||
|
}
|
||||||
|
*padding += width - res;
|
||||||
|
res = width;
|
||||||
|
}
|
||||||
|
else if (deriv == &d_dot)
|
||||||
|
{
|
||||||
|
if (depth == 0)
|
||||||
|
begin_use_class ("cex-dot", out);
|
||||||
|
res += fputs_if (depth == 0, out, padding, dot);
|
||||||
|
if (depth == 0)
|
||||||
|
end_use_class ("cex-dot", out);
|
||||||
|
}
|
||||||
|
else // leaf.
|
||||||
|
{
|
||||||
|
const symbol *sym = symbols[deriv->sym];
|
||||||
|
if (depth == 0)
|
||||||
|
begin_use_class ("cex-leaf", out);
|
||||||
|
res += fputs_if (depth == 0, out, padding, sym->tag);
|
||||||
|
if (depth == 0)
|
||||||
|
end_use_class ("cex-leaf", out);
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
derivation_print_tree (const derivation *deriv, FILE *out, const char *prefix)
|
||||||
|
{
|
||||||
|
fputc ('\n', out);
|
||||||
|
for (int depth = 0, max_depth = derivation_depth (deriv);
|
||||||
|
depth < max_depth; ++depth)
|
||||||
|
{
|
||||||
|
int padding = 0;
|
||||||
|
fprintf (out, " %s", prefix);
|
||||||
|
derivation_print_tree_impl (deriv, out, depth, &padding);
|
||||||
|
fputc ('\n', out);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Print DERIV, colored according to COUNTER.
|
||||||
|
Return false if nothing is printed. */
|
||||||
|
static bool
|
||||||
|
derivation_print_flat_impl (derivation *deriv, FILE *out,
|
||||||
|
bool leaves_only,
|
||||||
|
int *counter, const char *prefix)
|
||||||
|
{
|
||||||
|
if (deriv->children)
|
||||||
|
{
|
||||||
|
const symbol *sym = symbols[deriv->sym];
|
||||||
|
deriv->color = *counter;
|
||||||
|
++*counter;
|
||||||
|
char style[20];
|
||||||
|
snprintf (style, 20, "cex-%d", deriv->color);
|
||||||
|
begin_use_class (style, out);
|
||||||
|
|
||||||
|
if (!leaves_only)
|
||||||
|
{
|
||||||
|
fputs (prefix, out);
|
||||||
|
begin_use_class ("cex-step", out);
|
||||||
|
fprintf (out, "%s %s [ ", sym->tag, arrow);
|
||||||
|
end_use_class ("cex-step", out);
|
||||||
|
prefix = "";
|
||||||
|
}
|
||||||
|
bool res = false;
|
||||||
|
derivation *child;
|
||||||
|
for (gl_list_iterator_t it = gl_list_iterator (deriv->children);
|
||||||
|
derivation_list_next (&it, &child);
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (derivation_print_flat_impl (child, out,
|
||||||
|
leaves_only, counter, prefix))
|
||||||
|
{
|
||||||
|
prefix = " ";
|
||||||
|
res = true;
|
||||||
|
}
|
||||||
|
else if (!leaves_only)
|
||||||
|
prefix = " ";
|
||||||
|
}
|
||||||
|
if (!leaves_only)
|
||||||
|
{
|
||||||
|
begin_use_class ("cex-step", out);
|
||||||
|
if (res)
|
||||||
|
fputs (" ]", out);
|
||||||
|
else
|
||||||
|
fputs ("]", out);
|
||||||
|
end_use_class ("cex-step", out);
|
||||||
|
}
|
||||||
|
end_use_class (style, out);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
else if (deriv == &d_dot)
|
||||||
|
{
|
||||||
|
fputs (prefix, out);
|
||||||
|
begin_use_class ("cex-dot", out);
|
||||||
|
fputs (dot, out);
|
||||||
|
end_use_class ("cex-dot", out);
|
||||||
|
}
|
||||||
|
else // leaf.
|
||||||
|
{
|
||||||
|
fputs (prefix, out);
|
||||||
|
const symbol *sym = symbols[deriv->sym];
|
||||||
|
begin_use_class ("cex-leaf", out);
|
||||||
|
fprintf (out, "%s", sym->tag);
|
||||||
|
end_use_class ("cex-leaf", out);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
derivation_print_flat (const derivation *deriv, FILE *out, const char *prefix)
|
||||||
|
{
|
||||||
|
int counter = 0;
|
||||||
|
fputs (prefix, out);
|
||||||
|
derivation_print_flat_impl ((derivation *)deriv, out, false, &counter, "");
|
||||||
|
fputc ('\n', out);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
derivation_print_leaves (const derivation *deriv, FILE *out)
|
||||||
|
{
|
||||||
|
int counter = 0;
|
||||||
|
derivation_print_flat_impl ((derivation *)deriv, out, true, &counter, "");
|
||||||
|
fputc ('\n', out);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
derivation_print (const derivation *deriv, FILE *out, const char *prefix)
|
||||||
|
{
|
||||||
|
if (getenv ("YYFLAT"))
|
||||||
|
derivation_print_flat (deriv, out, prefix);
|
||||||
|
else
|
||||||
|
derivation_print_tree (deriv, out, prefix);
|
||||||
|
}
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
/* Counterexample derivation trees
|
||||||
|
|
||||||
|
Copyright (C) 2020 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of Bison, the GNU Compiler Compiler.
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#ifndef DERIVATION_H
|
||||||
|
# define DERIVATION_H
|
||||||
|
|
||||||
|
# include <gl_linked_list.h>
|
||||||
|
# include <gl_xlist.h>
|
||||||
|
|
||||||
|
# include "gram.h"
|
||||||
|
|
||||||
|
/* Derivations are trees of symbols such that each nonterminal's
|
||||||
|
children are symbols that produce that nonterminal if they are
|
||||||
|
relevant to the counterexample. The leaves of a derivation form a
|
||||||
|
counterexample when printed. */
|
||||||
|
|
||||||
|
typedef gl_list_t derivation_list;
|
||||||
|
typedef struct derivation derivation;
|
||||||
|
|
||||||
|
static inline derivation_list derivation_list_new (void)
|
||||||
|
{
|
||||||
|
return gl_list_create_empty (GL_LINKED_LIST, NULL, NULL, NULL, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
derivation_list_next (gl_list_iterator_t *it, derivation **d)
|
||||||
|
{
|
||||||
|
const void *p = NULL;
|
||||||
|
bool res = gl_list_iterator_next (it, &p, NULL);
|
||||||
|
if (res)
|
||||||
|
*d = (derivation *) p;
|
||||||
|
else
|
||||||
|
gl_list_iterator_free (it);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
void derivation_list_append (derivation_list dl, derivation *d);
|
||||||
|
void derivation_list_prepend (derivation_list dl, derivation *d);
|
||||||
|
void derivation_list_free (derivation_list dl);
|
||||||
|
|
||||||
|
derivation *derivation_new (symbol_number sym, derivation_list children);
|
||||||
|
|
||||||
|
static inline derivation *derivation_new_leaf (symbol_number sym)
|
||||||
|
{
|
||||||
|
return derivation_new (sym, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Number of symbols.
|
||||||
|
size_t derivation_size (const derivation *deriv);
|
||||||
|
void derivation_print (const derivation *deriv, FILE *out, const char *prefix);
|
||||||
|
void derivation_print_leaves (const derivation *deriv, FILE *out);
|
||||||
|
void derivation_free (derivation *deriv);
|
||||||
|
void derivation_retain (derivation *deriv);
|
||||||
|
|
||||||
|
// A derivation denoting the position of the dot.
|
||||||
|
derivation *derivation_dot (void);
|
||||||
|
|
||||||
|
#endif /* DERIVATION_H */
|
||||||
+4
-4
@@ -47,7 +47,7 @@ print_derives (void)
|
|||||||
fprintf (stderr, " %s derives\n", symbols[i]->tag);
|
fprintf (stderr, " %s derives\n", symbols[i]->tag);
|
||||||
for (rule **rp = derives[i - ntokens]; *rp; ++rp)
|
for (rule **rp = derives[i - ntokens]; *rp; ++rp)
|
||||||
{
|
{
|
||||||
fprintf (stderr, " %3d ", (*rp)->user_number);
|
fprintf (stderr, " %3d ", (*rp)->code);
|
||||||
rule_rhs_print (*rp, stderr);
|
rule_rhs_print (*rp, stderr);
|
||||||
fprintf (stderr, "\n");
|
fprintf (stderr, "\n");
|
||||||
}
|
}
|
||||||
@@ -62,7 +62,7 @@ derives_compute (void)
|
|||||||
{
|
{
|
||||||
/* DSET[NTERM - NTOKENS] -- A linked list of the numbers of the rules
|
/* DSET[NTERM - NTOKENS] -- A linked list of the numbers of the rules
|
||||||
whose LHS is NTERM. */
|
whose LHS is NTERM. */
|
||||||
rule_list **dset = xcalloc (nvars, sizeof *dset);
|
rule_list **dset = xcalloc (nnterms, sizeof *dset);
|
||||||
|
|
||||||
/* DELTS[RULE] -- There are NRULES rule number to attach to nterms.
|
/* DELTS[RULE] -- There are NRULES rule number to attach to nterms.
|
||||||
Instead of performing NRULES allocations for each, have an array
|
Instead of performing NRULES allocations for each, have an array
|
||||||
@@ -82,9 +82,9 @@ derives_compute (void)
|
|||||||
/* DSET contains what we need under the form of a linked list. Make
|
/* DSET contains what we need under the form of a linked list. Make
|
||||||
it a single array. */
|
it a single array. */
|
||||||
|
|
||||||
derives = xnmalloc (nvars, sizeof *derives);
|
derives = xnmalloc (nnterms, sizeof *derives);
|
||||||
/* Q is the storage for DERIVES[...] (DERIVES[0] = q). */
|
/* Q is the storage for DERIVES[...] (DERIVES[0] = q). */
|
||||||
rule **q = xnmalloc (nvars + nrules, sizeof *q);
|
rule **q = xnmalloc (nnterms + nrules, sizeof *q);
|
||||||
|
|
||||||
for (symbol_number i = ntokens; i < nsyms; ++i)
|
for (symbol_number i = ntokens; i < nsyms; ++i)
|
||||||
{
|
{
|
||||||
|
|||||||
+106
-2
@@ -22,13 +22,18 @@
|
|||||||
#include "system.h"
|
#include "system.h"
|
||||||
|
|
||||||
#include <configmake.h> /* PKGDATADIR */
|
#include <configmake.h> /* PKGDATADIR */
|
||||||
#include <error.h>
|
|
||||||
#include <dirname.h>
|
#include <dirname.h>
|
||||||
|
#include <error.h>
|
||||||
#include <get-errno.h>
|
#include <get-errno.h>
|
||||||
|
#include <gl_array_list.h>
|
||||||
|
#include <gl_xlist.h>
|
||||||
#include <quote.h>
|
#include <quote.h>
|
||||||
#include <quotearg.h>
|
#include <quotearg.h>
|
||||||
#include <relocatable.h> /* relocate2 */
|
#include <relocatable.h> /* relocate2 */
|
||||||
#include <stdio-safer.h>
|
#include <stdio-safer.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <unistd.h>
|
||||||
#include <xstrndup.h>
|
#include <xstrndup.h>
|
||||||
|
|
||||||
#include "complain.h"
|
#include "complain.h"
|
||||||
@@ -52,6 +57,7 @@ char *spec_verbose_file = NULL; /* for --verbose. */
|
|||||||
char *spec_graph_file = NULL; /* for -g. */
|
char *spec_graph_file = NULL; /* for -g. */
|
||||||
char *spec_xml_file = NULL; /* for -x. */
|
char *spec_xml_file = NULL; /* for -x. */
|
||||||
char *spec_header_file = NULL; /* for --defines. */
|
char *spec_header_file = NULL; /* for --defines. */
|
||||||
|
char *spec_mapped_header_file = NULL;
|
||||||
char *parser_file_name;
|
char *parser_file_name;
|
||||||
|
|
||||||
/* All computed output file names. */
|
/* All computed output file names. */
|
||||||
@@ -70,7 +76,7 @@ static int generated_files_size = 0;
|
|||||||
uniqstr grammar_file = NULL;
|
uniqstr grammar_file = NULL;
|
||||||
|
|
||||||
/* If --output=dir/foo.c was specified,
|
/* If --output=dir/foo.c was specified,
|
||||||
DIR_PREFIX is 'dir/' and ALL_BUT_EXT and ALL_BUT_TAB_EXT are 'dir/foo'.
|
DIR_PREFIX gis 'dir/' and ALL_BUT_EXT and ALL_BUT_TAB_EXT are 'dir/foo'.
|
||||||
|
|
||||||
If --output=dir/foo.tab.c was specified, DIR_PREFIX is 'dir/',
|
If --output=dir/foo.tab.c was specified, DIR_PREFIX is 'dir/',
|
||||||
ALL_BUT_EXT is 'dir/foo.tab', and ALL_BUT_TAB_EXT is 'dir/foo'.
|
ALL_BUT_EXT is 'dir/foo.tab', and ALL_BUT_TAB_EXT is 'dir/foo'.
|
||||||
@@ -88,11 +94,20 @@ uniqstr grammar_file = NULL;
|
|||||||
char *all_but_ext;
|
char *all_but_ext;
|
||||||
static char *all_but_tab_ext;
|
static char *all_but_tab_ext;
|
||||||
char *dir_prefix;
|
char *dir_prefix;
|
||||||
|
char *mapped_dir_prefix;
|
||||||
|
|
||||||
/* C source file extension (the parser source). */
|
/* C source file extension (the parser source). */
|
||||||
static char *src_extension = NULL;
|
static char *src_extension = NULL;
|
||||||
/* Header file extension (if option '`-d'' is specified). */
|
/* Header file extension (if option '`-d'' is specified). */
|
||||||
static char *header_extension = NULL;
|
static char *header_extension = NULL;
|
||||||
|
|
||||||
|
struct prefix_map
|
||||||
|
{
|
||||||
|
char *oldprefix;
|
||||||
|
char *newprefix;
|
||||||
|
};
|
||||||
|
|
||||||
|
static gl_list_t prefix_maps = NULL;
|
||||||
|
|
||||||
/*-----------------------------------------------------------------.
|
/*-----------------------------------------------------------------.
|
||||||
| Return a newly allocated string composed of the concatenation of |
|
| Return a newly allocated string composed of the concatenation of |
|
||||||
@@ -156,6 +171,70 @@ xfdopen (int fd, char const *mode)
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Given an input file path, returns a dynamically allocated string that
|
||||||
|
contains the path with the file prefix mapping rules applied, or NULL if
|
||||||
|
the input was NULL. */
|
||||||
|
char *
|
||||||
|
map_file_name (char const *filename)
|
||||||
|
{
|
||||||
|
if (!filename)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
struct prefix_map const *p = NULL;
|
||||||
|
if (prefix_maps)
|
||||||
|
{
|
||||||
|
void const *ptr;
|
||||||
|
gl_list_iterator_t iter = gl_list_iterator (prefix_maps);
|
||||||
|
while (gl_list_iterator_next (&iter, &ptr, NULL))
|
||||||
|
{
|
||||||
|
p = ptr;
|
||||||
|
if (strncmp (p->oldprefix, filename, strlen (p->oldprefix)) == 0)
|
||||||
|
break;
|
||||||
|
p = NULL;
|
||||||
|
}
|
||||||
|
gl_list_iterator_free (&iter);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!p)
|
||||||
|
return xstrdup (filename);
|
||||||
|
|
||||||
|
size_t oldprefix_len = strlen (p->oldprefix);
|
||||||
|
size_t newprefix_len = strlen (p->newprefix);
|
||||||
|
char *s = xmalloc (newprefix_len + strlen (filename) - oldprefix_len + 1);
|
||||||
|
|
||||||
|
char *end = stpcpy (s, p->newprefix);
|
||||||
|
stpcpy (end, filename + oldprefix_len);
|
||||||
|
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
prefix_map_free (struct prefix_map *p)
|
||||||
|
{
|
||||||
|
free (p->oldprefix);
|
||||||
|
free (p->newprefix);
|
||||||
|
free (p);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Adds a new file prefix mapping. If a file path starts with oldprefix, it
|
||||||
|
will be replaced with newprefix */
|
||||||
|
void
|
||||||
|
add_prefix_map (char const *oldprefix, char const *newprefix)
|
||||||
|
{
|
||||||
|
if (!prefix_maps)
|
||||||
|
prefix_maps = gl_list_create_empty (GL_ARRAY_LIST,
|
||||||
|
/* equals */ NULL,
|
||||||
|
/* hashcode */ NULL,
|
||||||
|
(gl_listelement_dispose_fn) prefix_map_free,
|
||||||
|
true);
|
||||||
|
|
||||||
|
struct prefix_map *p = xmalloc (sizeof (*p));
|
||||||
|
p->oldprefix = xstrdup (oldprefix);
|
||||||
|
p->newprefix = xstrdup (newprefix);
|
||||||
|
|
||||||
|
gl_list_add_last (prefix_maps, p);
|
||||||
|
}
|
||||||
|
|
||||||
/*------------------------------------------------------------------.
|
/*------------------------------------------------------------------.
|
||||||
| Compute ALL_BUT_EXT, ALL_BUT_TAB_EXT and output files extensions. |
|
| Compute ALL_BUT_EXT, ALL_BUT_TAB_EXT and output files extensions. |
|
||||||
`------------------------------------------------------------------*/
|
`------------------------------------------------------------------*/
|
||||||
@@ -360,6 +439,9 @@ compute_output_file_names (void)
|
|||||||
output_file_name_check (&spec_verbose_file, false);
|
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 (all_but_tab_ext);
|
||||||
free (src_extension);
|
free (src_extension);
|
||||||
free (header_extension);
|
free (header_extension);
|
||||||
@@ -421,6 +503,23 @@ pkgdatadir (void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char const *
|
||||||
|
m4path (void)
|
||||||
|
{
|
||||||
|
char const *m4 = getenv ("M4");
|
||||||
|
if (m4)
|
||||||
|
return m4;
|
||||||
|
|
||||||
|
/* We don't use relocate2() to store the temporary buffer and re-use
|
||||||
|
it, because m4path() is only called once. */
|
||||||
|
char const *m4_relocated = relocate (M4);
|
||||||
|
struct stat buf;
|
||||||
|
if (stat (m4_relocated, &buf) == 0)
|
||||||
|
return m4_relocated;
|
||||||
|
|
||||||
|
return M4;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
output_file_names_free (void)
|
output_file_names_free (void)
|
||||||
{
|
{
|
||||||
@@ -429,10 +528,15 @@ output_file_names_free (void)
|
|||||||
free (spec_graph_file);
|
free (spec_graph_file);
|
||||||
free (spec_xml_file);
|
free (spec_xml_file);
|
||||||
free (spec_header_file);
|
free (spec_header_file);
|
||||||
|
free (spec_mapped_header_file);
|
||||||
free (parser_file_name);
|
free (parser_file_name);
|
||||||
free (dir_prefix);
|
free (dir_prefix);
|
||||||
|
free (mapped_dir_prefix);
|
||||||
for (int i = 0; i < generated_files_size; i++)
|
for (int i = 0; i < generated_files_size; i++)
|
||||||
free (generated_files[i].name);
|
free (generated_files[i].name);
|
||||||
free (generated_files);
|
free (generated_files);
|
||||||
free (relocate_buffer);
|
free (relocate_buffer);
|
||||||
|
|
||||||
|
if (prefix_maps)
|
||||||
|
gl_list_free (prefix_maps);
|
||||||
}
|
}
|
||||||
|
|||||||
+12
@@ -50,9 +50,15 @@ extern char *spec_xml_file;
|
|||||||
/* File name specified with --defines. */
|
/* File name specified with --defines. */
|
||||||
extern char *spec_header_file;
|
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. */
|
/* Directory prefix of output file names. */
|
||||||
extern char *dir_prefix;
|
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.
|
/* The file name as given on the command line.
|
||||||
Not named "input_file" because Flex uses this name for an argument,
|
Not named "input_file" because Flex uses this name for an argument,
|
||||||
and therefore GCC warns about a name clash. */
|
and therefore GCC warns about a name clash. */
|
||||||
@@ -64,6 +70,9 @@ extern char *all_but_ext;
|
|||||||
/* Where our data files are installed. */
|
/* Where our data files are installed. */
|
||||||
char const *pkgdatadir (void);
|
char const *pkgdatadir (void);
|
||||||
|
|
||||||
|
/* Where the m4 program is installed. */
|
||||||
|
char const *m4path (void);
|
||||||
|
|
||||||
void compute_output_file_names (void);
|
void compute_output_file_names (void);
|
||||||
void output_file_names_free (void);
|
void output_file_names_free (void);
|
||||||
|
|
||||||
@@ -82,4 +91,7 @@ FILE *xfopen (const char *name, char const *mode);
|
|||||||
void xfclose (FILE *ptr);
|
void xfclose (FILE *ptr);
|
||||||
FILE *xfdopen (int fd, char const *mode);
|
FILE *xfdopen (int fd, char const *mode);
|
||||||
|
|
||||||
|
char *map_file_name (char const *filename);
|
||||||
|
void add_prefix_map (char const *oldprefix, char const *newprefix);
|
||||||
|
|
||||||
#endif /* !FILES_H_ */
|
#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