abnf-rust 2.5.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. abnf_rust-2.5.0/Cargo.lock +311 -0
  2. abnf_rust-2.5.0/Cargo.toml +23 -0
  3. abnf_rust-2.5.0/LICENSE.txt +16 -0
  4. abnf_rust-2.5.0/PKG-INFO +62 -0
  5. abnf_rust-2.5.0/README.md +37 -0
  6. abnf_rust-2.5.0/pyproject.toml +43 -0
  7. abnf_rust-2.5.0/rust/core/Cargo.toml +15 -0
  8. abnf_rust-2.5.0/rust/core/src/alternation.rs +90 -0
  9. abnf_rust-2.5.0/rust/core/src/cache.rs +254 -0
  10. abnf_rust-2.5.0/rust/core/src/casefold.rs +29 -0
  11. abnf_rust-2.5.0/rust/core/src/concatenation.rs +73 -0
  12. abnf_rust-2.5.0/rust/core/src/core_rules.rs +109 -0
  13. abnf_rust-2.5.0/rust/core/src/error.rs +76 -0
  14. abnf_rust-2.5.0/rust/core/src/lib.rs +57 -0
  15. abnf_rust-2.5.0/rust/core/src/literal.rs +329 -0
  16. abnf_rust-2.5.0/rust/core/src/matcher.rs +67 -0
  17. abnf_rust-2.5.0/rust/core/src/meta_grammar.rs +356 -0
  18. abnf_rust-2.5.0/rust/core/src/node.rs +86 -0
  19. abnf_rust-2.5.0/rust/core/src/option.rs +27 -0
  20. abnf_rust-2.5.0/rust/core/src/parser.rs +167 -0
  21. abnf_rust-2.5.0/rust/core/src/prose.rs +13 -0
  22. abnf_rust-2.5.0/rust/core/src/registry.rs +64 -0
  23. abnf_rust-2.5.0/rust/core/src/repetition.rs +189 -0
  24. abnf_rust-2.5.0/rust/core/src/rule.rs +159 -0
  25. abnf_rust-2.5.0/rust/core/src/visitor.rs +414 -0
  26. abnf_rust-2.5.0/rust/core/tests/combinators.rs +181 -0
  27. abnf_rust-2.5.0/rust/core/tests/meta_grammar.rs +139 -0
  28. abnf_rust-2.5.0/rust/pyo3/Cargo.toml +20 -0
  29. abnf_rust-2.5.0/rust/pyo3/src/bootstrap.rs +65 -0
  30. abnf_rust-2.5.0/rust/pyo3/src/bridge.rs +87 -0
  31. abnf_rust-2.5.0/rust/pyo3/src/errors.rs +40 -0
  32. abnf_rust-2.5.0/rust/pyo3/src/external.rs +113 -0
  33. abnf_rust-2.5.0/rust/pyo3/src/hooks.rs +21 -0
  34. abnf_rust-2.5.0/rust/pyo3/src/iter.rs +65 -0
  35. abnf_rust-2.5.0/rust/pyo3/src/lib.rs +56 -0
  36. abnf_rust-2.5.0/rust/pyo3/src/nodes.rs +341 -0
  37. abnf_rust-2.5.0/rust/pyo3/src/offset.rs +99 -0
  38. abnf_rust-2.5.0/rust/pyo3/src/parsers.rs +404 -0
  39. abnf_rust-2.5.0/rust/pyo3/src/recursion.rs +126 -0
  40. abnf_rust-2.5.0/src/abnf_rust/__init__.py +57 -0
@@ -0,0 +1,311 @@
1
+ # This file is automatically @generated by Cargo.
2
+ # It is not intended for manual editing.
3
+ version = 3
4
+
5
+ [[package]]
6
+ name = "abnf-core"
7
+ version = "2.5.0"
8
+ dependencies = [
9
+ "caseless",
10
+ "lru",
11
+ "once_cell",
12
+ "smallvec",
13
+ ]
14
+
15
+ [[package]]
16
+ name = "abnf-rust-ext"
17
+ version = "2.5.0"
18
+ dependencies = [
19
+ "abnf-core",
20
+ "mimalloc",
21
+ "once_cell",
22
+ "pyo3",
23
+ "smallvec",
24
+ ]
25
+
26
+ [[package]]
27
+ name = "allocator-api2"
28
+ version = "0.2.21"
29
+ source = "registry+https://github.com/rust-lang/crates.io-index"
30
+ checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923"
31
+
32
+ [[package]]
33
+ name = "autocfg"
34
+ version = "1.5.0"
35
+ source = "registry+https://github.com/rust-lang/crates.io-index"
36
+ checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
37
+
38
+ [[package]]
39
+ name = "caseless"
40
+ version = "0.2.2"
41
+ source = "registry+https://github.com/rust-lang/crates.io-index"
42
+ checksum = "8b6fd507454086c8edfd769ca6ada439193cdb209c7681712ef6275cccbfe5d8"
43
+ dependencies = [
44
+ "unicode-normalization",
45
+ ]
46
+
47
+ [[package]]
48
+ name = "cc"
49
+ version = "1.2.62"
50
+ source = "registry+https://github.com/rust-lang/crates.io-index"
51
+ checksum = "a1dce859f0832a7d088c4f1119888ab94ef4b5d6795d1ce05afb7fe159d79f98"
52
+ dependencies = [
53
+ "find-msvc-tools",
54
+ "shlex",
55
+ ]
56
+
57
+ [[package]]
58
+ name = "cfg-if"
59
+ version = "1.0.4"
60
+ source = "registry+https://github.com/rust-lang/crates.io-index"
61
+ checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
62
+
63
+ [[package]]
64
+ name = "equivalent"
65
+ version = "1.0.2"
66
+ source = "registry+https://github.com/rust-lang/crates.io-index"
67
+ checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
68
+
69
+ [[package]]
70
+ name = "find-msvc-tools"
71
+ version = "0.1.9"
72
+ source = "registry+https://github.com/rust-lang/crates.io-index"
73
+ checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582"
74
+
75
+ [[package]]
76
+ name = "foldhash"
77
+ version = "0.2.0"
78
+ source = "registry+https://github.com/rust-lang/crates.io-index"
79
+ checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb"
80
+
81
+ [[package]]
82
+ name = "hashbrown"
83
+ version = "0.17.1"
84
+ source = "registry+https://github.com/rust-lang/crates.io-index"
85
+ checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a"
86
+ dependencies = [
87
+ "allocator-api2",
88
+ "equivalent",
89
+ "foldhash",
90
+ ]
91
+
92
+ [[package]]
93
+ name = "heck"
94
+ version = "0.5.0"
95
+ source = "registry+https://github.com/rust-lang/crates.io-index"
96
+ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
97
+
98
+ [[package]]
99
+ name = "indoc"
100
+ version = "2.0.7"
101
+ source = "registry+https://github.com/rust-lang/crates.io-index"
102
+ checksum = "79cf5c93f93228cf8efb3ba362535fb11199ac548a09ce117c9b1adc3030d706"
103
+ dependencies = [
104
+ "rustversion",
105
+ ]
106
+
107
+ [[package]]
108
+ name = "libc"
109
+ version = "0.2.186"
110
+ source = "registry+https://github.com/rust-lang/crates.io-index"
111
+ checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66"
112
+
113
+ [[package]]
114
+ name = "libmimalloc-sys"
115
+ version = "0.1.47"
116
+ source = "registry+https://github.com/rust-lang/crates.io-index"
117
+ checksum = "2d1eacfa31c33ec25e873c136ba5669f00f9866d0688bea7be4d3f7e43067df6"
118
+ dependencies = [
119
+ "cc",
120
+ ]
121
+
122
+ [[package]]
123
+ name = "lru"
124
+ version = "0.18.0"
125
+ source = "registry+https://github.com/rust-lang/crates.io-index"
126
+ checksum = "8a860605968fce16869fd239cf4237a82f3ac470723415db603b0e8b6c8d4fb9"
127
+ dependencies = [
128
+ "hashbrown",
129
+ ]
130
+
131
+ [[package]]
132
+ name = "memoffset"
133
+ version = "0.9.1"
134
+ source = "registry+https://github.com/rust-lang/crates.io-index"
135
+ checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a"
136
+ dependencies = [
137
+ "autocfg",
138
+ ]
139
+
140
+ [[package]]
141
+ name = "mimalloc"
142
+ version = "0.1.50"
143
+ source = "registry+https://github.com/rust-lang/crates.io-index"
144
+ checksum = "b3627c4272df786b9260cabaa46aec1d59c93ede723d4c3ef646c503816b0640"
145
+ dependencies = [
146
+ "libmimalloc-sys",
147
+ ]
148
+
149
+ [[package]]
150
+ name = "once_cell"
151
+ version = "1.21.4"
152
+ source = "registry+https://github.com/rust-lang/crates.io-index"
153
+ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50"
154
+
155
+ [[package]]
156
+ name = "portable-atomic"
157
+ version = "1.13.1"
158
+ source = "registry+https://github.com/rust-lang/crates.io-index"
159
+ checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49"
160
+
161
+ [[package]]
162
+ name = "proc-macro2"
163
+ version = "1.0.106"
164
+ source = "registry+https://github.com/rust-lang/crates.io-index"
165
+ checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934"
166
+ dependencies = [
167
+ "unicode-ident",
168
+ ]
169
+
170
+ [[package]]
171
+ name = "pyo3"
172
+ version = "0.22.6"
173
+ source = "registry+https://github.com/rust-lang/crates.io-index"
174
+ checksum = "f402062616ab18202ae8319da13fa4279883a2b8a9d9f83f20dbade813ce1884"
175
+ dependencies = [
176
+ "cfg-if",
177
+ "indoc",
178
+ "libc",
179
+ "memoffset",
180
+ "once_cell",
181
+ "portable-atomic",
182
+ "pyo3-build-config",
183
+ "pyo3-ffi",
184
+ "pyo3-macros",
185
+ "unindent",
186
+ ]
187
+
188
+ [[package]]
189
+ name = "pyo3-build-config"
190
+ version = "0.22.6"
191
+ source = "registry+https://github.com/rust-lang/crates.io-index"
192
+ checksum = "b14b5775b5ff446dd1056212d778012cbe8a0fbffd368029fd9e25b514479c38"
193
+ dependencies = [
194
+ "once_cell",
195
+ "target-lexicon",
196
+ ]
197
+
198
+ [[package]]
199
+ name = "pyo3-ffi"
200
+ version = "0.22.6"
201
+ source = "registry+https://github.com/rust-lang/crates.io-index"
202
+ checksum = "9ab5bcf04a2cdcbb50c7d6105de943f543f9ed92af55818fd17b660390fc8636"
203
+ dependencies = [
204
+ "libc",
205
+ "pyo3-build-config",
206
+ ]
207
+
208
+ [[package]]
209
+ name = "pyo3-macros"
210
+ version = "0.22.6"
211
+ source = "registry+https://github.com/rust-lang/crates.io-index"
212
+ checksum = "0fd24d897903a9e6d80b968368a34e1525aeb719d568dba8b3d4bfa5dc67d453"
213
+ dependencies = [
214
+ "proc-macro2",
215
+ "pyo3-macros-backend",
216
+ "quote",
217
+ "syn",
218
+ ]
219
+
220
+ [[package]]
221
+ name = "pyo3-macros-backend"
222
+ version = "0.22.6"
223
+ source = "registry+https://github.com/rust-lang/crates.io-index"
224
+ checksum = "36c011a03ba1e50152b4b394b479826cad97e7a21eb52df179cd91ac411cbfbe"
225
+ dependencies = [
226
+ "heck",
227
+ "proc-macro2",
228
+ "pyo3-build-config",
229
+ "quote",
230
+ "syn",
231
+ ]
232
+
233
+ [[package]]
234
+ name = "quote"
235
+ version = "1.0.45"
236
+ source = "registry+https://github.com/rust-lang/crates.io-index"
237
+ checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924"
238
+ dependencies = [
239
+ "proc-macro2",
240
+ ]
241
+
242
+ [[package]]
243
+ name = "rustversion"
244
+ version = "1.0.22"
245
+ source = "registry+https://github.com/rust-lang/crates.io-index"
246
+ checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"
247
+
248
+ [[package]]
249
+ name = "shlex"
250
+ version = "1.3.0"
251
+ source = "registry+https://github.com/rust-lang/crates.io-index"
252
+ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
253
+
254
+ [[package]]
255
+ name = "smallvec"
256
+ version = "1.15.1"
257
+ source = "registry+https://github.com/rust-lang/crates.io-index"
258
+ checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03"
259
+
260
+ [[package]]
261
+ name = "syn"
262
+ version = "2.0.117"
263
+ source = "registry+https://github.com/rust-lang/crates.io-index"
264
+ checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99"
265
+ dependencies = [
266
+ "proc-macro2",
267
+ "quote",
268
+ "unicode-ident",
269
+ ]
270
+
271
+ [[package]]
272
+ name = "target-lexicon"
273
+ version = "0.12.16"
274
+ source = "registry+https://github.com/rust-lang/crates.io-index"
275
+ checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1"
276
+
277
+ [[package]]
278
+ name = "tinyvec"
279
+ version = "1.11.0"
280
+ source = "registry+https://github.com/rust-lang/crates.io-index"
281
+ checksum = "3e61e67053d25a4e82c844e8424039d9745781b3fc4f32b8d55ed50f5f667ef3"
282
+ dependencies = [
283
+ "tinyvec_macros",
284
+ ]
285
+
286
+ [[package]]
287
+ name = "tinyvec_macros"
288
+ version = "0.1.1"
289
+ source = "registry+https://github.com/rust-lang/crates.io-index"
290
+ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
291
+
292
+ [[package]]
293
+ name = "unicode-ident"
294
+ version = "1.0.24"
295
+ source = "registry+https://github.com/rust-lang/crates.io-index"
296
+ checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
297
+
298
+ [[package]]
299
+ name = "unicode-normalization"
300
+ version = "0.1.25"
301
+ source = "registry+https://github.com/rust-lang/crates.io-index"
302
+ checksum = "5fd4f6878c9cb28d874b009da9e8d183b5abc80117c40bbd187a1fde336be6e8"
303
+ dependencies = [
304
+ "tinyvec",
305
+ ]
306
+
307
+ [[package]]
308
+ name = "unindent"
309
+ version = "0.2.4"
310
+ source = "registry+https://github.com/rust-lang/crates.io-index"
311
+ checksum = "7264e107f553ccae879d21fbea1d6724ac785e8c3bfc762137959b5802826ef3"
@@ -0,0 +1,23 @@
1
+ [workspace]
2
+ members = ["rust/core", "rust/pyo3"]
3
+ resolver = "2"
4
+
5
+ [workspace.package]
6
+ # Lock-stepped with the `abnf` distribution; both packages release
7
+ # under the same git tag so the wheels at `pip install abnf==X` and
8
+ # `pip install abnf-rust==X` always come from the same source state.
9
+ version = "2.5.0"
10
+ edition = "2021"
11
+ rust-version = "1.75"
12
+ license = "MIT"
13
+ authors = ["Charles Yeomans <charles@declaresub.com>"]
14
+ repository = "https://github.com/declaresub/abnf"
15
+
16
+ [workspace.dependencies]
17
+ abnf-core = { path = "rust/core", version = "2.5.0" }
18
+ caseless = "0.2"
19
+ lru = "0.18"
20
+ mimalloc = { version = "0.1", default-features = false }
21
+ once_cell = "1"
22
+ pyo3 = "0.22"
23
+ smallvec = "1"
@@ -0,0 +1,16 @@
1
+ Copyright 2020 Charles Yeomans
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software
4
+ and associated documentation files (the "Software"), to deal in the Software without
5
+ restriction, including without limitation the rights to use, copy, modify, merge, publish,
6
+ distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
7
+ Software is furnished to do so, subject to the following conditions:
8
+
9
+ The above copyright notice and this permission notice shall be included in all copies or
10
+ substantial portions of the Software.
11
+
12
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
13
+ BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
14
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
15
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
16
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,62 @@
1
+ Metadata-Version: 2.4
2
+ Name: abnf-rust
3
+ Version: 2.5.0
4
+ Classifier: Development Status :: 4 - Beta
5
+ Classifier: Intended Audience :: Developers
6
+ Classifier: License :: OSI Approved :: MIT License
7
+ Classifier: Programming Language :: Python
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: Programming Language :: Python :: 3.10
10
+ Classifier: Programming Language :: Python :: 3.11
11
+ Classifier: Programming Language :: Python :: 3.12
12
+ Classifier: Programming Language :: Python :: 3.13
13
+ Classifier: Programming Language :: Python :: 3.14
14
+ Classifier: Programming Language :: Rust
15
+ Classifier: Topic :: Software Development :: Code Generators
16
+ Classifier: Topic :: Software Development :: Interpreters
17
+ License-File: LICENSE.txt
18
+ Summary: Rust-backed parser engine for the abnf package.
19
+ Keywords: abnf,parser
20
+ Author-email: Charles Yeomans <charles@declaresub.com>
21
+ Requires-Python: >=3.10
22
+ Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
23
+ Project-URL: Homepage, https://github.com/declaresub/abnf
24
+
25
+ # abnf-rust
26
+
27
+ Rust-backed parser engine for the [`abnf`](https://pypi.org/project/abnf/)
28
+ package.
29
+
30
+ This is a companion distribution: install it via
31
+
32
+ ```
33
+ pip install abnf[rust]
34
+ ```
35
+
36
+ The package supplies the importable Python module `abnf_rust`, a compiled
37
+ extension built with PyO3 that accelerates the combinator engine in
38
+ `abnf.parser`. When `abnf_rust` is importable, `abnf.parser` automatically
39
+ routes its combinator primitives through this module; the pure-Python
40
+ implementation in `abnf._parser_python` remains available as a fallback and
41
+ as the reference for behavior parity.
42
+
43
+ To force the pure-Python backend even when `abnf-rust` is installed, set
44
+ the environment variable `ABNF_NO_RUST=1`.
45
+
46
+ ## Layout
47
+
48
+ * `rust/core/` — pure-Rust parser engine (no Python dependency).
49
+ * `rust/pyo3/` — PyO3 bindings, compiled to `abnf_rust._ext`.
50
+ * `src/abnf_rust/` — Python wrapper package that re-exports the compiled
51
+ symbols.
52
+
53
+ ## Building
54
+
55
+ ```
56
+ maturin develop --manifest-path packages/abnf-rust/Cargo.toml
57
+ ```
58
+
59
+ ## License
60
+
61
+ MIT.
62
+
@@ -0,0 +1,37 @@
1
+ # abnf-rust
2
+
3
+ Rust-backed parser engine for the [`abnf`](https://pypi.org/project/abnf/)
4
+ package.
5
+
6
+ This is a companion distribution: install it via
7
+
8
+ ```
9
+ pip install abnf[rust]
10
+ ```
11
+
12
+ The package supplies the importable Python module `abnf_rust`, a compiled
13
+ extension built with PyO3 that accelerates the combinator engine in
14
+ `abnf.parser`. When `abnf_rust` is importable, `abnf.parser` automatically
15
+ routes its combinator primitives through this module; the pure-Python
16
+ implementation in `abnf._parser_python` remains available as a fallback and
17
+ as the reference for behavior parity.
18
+
19
+ To force the pure-Python backend even when `abnf-rust` is installed, set
20
+ the environment variable `ABNF_NO_RUST=1`.
21
+
22
+ ## Layout
23
+
24
+ * `rust/core/` — pure-Rust parser engine (no Python dependency).
25
+ * `rust/pyo3/` — PyO3 bindings, compiled to `abnf_rust._ext`.
26
+ * `src/abnf_rust/` — Python wrapper package that re-exports the compiled
27
+ symbols.
28
+
29
+ ## Building
30
+
31
+ ```
32
+ maturin develop --manifest-path packages/abnf-rust/Cargo.toml
33
+ ```
34
+
35
+ ## License
36
+
37
+ MIT.
@@ -0,0 +1,43 @@
1
+ [build-system]
2
+ build-backend = "maturin"
3
+ requires = ["maturin>=1.7,<2.0"]
4
+
5
+ [project]
6
+ authors = [
7
+ { email = "charles@declaresub.com", name = "Charles Yeomans" },
8
+ ]
9
+ classifiers = [
10
+ "Development Status :: 4 - Beta",
11
+ "Intended Audience :: Developers",
12
+ "License :: OSI Approved :: MIT License",
13
+ "Programming Language :: Python",
14
+ "Programming Language :: Python :: 3",
15
+ "Programming Language :: Python :: 3.10",
16
+ "Programming Language :: Python :: 3.11",
17
+ "Programming Language :: Python :: 3.12",
18
+ "Programming Language :: Python :: 3.13",
19
+ "Programming Language :: Python :: 3.14",
20
+ "Programming Language :: Rust",
21
+ "Topic :: Software Development :: Code Generators",
22
+ "Topic :: Software Development :: Interpreters",
23
+ ]
24
+ description = "Rust-backed parser engine for the abnf package."
25
+ dynamic = ["version"]
26
+ keywords = ["abnf", "parser"]
27
+ # Maturin auto-detects LICENSE.txt for the wheel METADATA and the
28
+ # `License-File` PKG-INFO header, but does not actually copy the
29
+ # file into the sdist tarball. Listing it explicitly here forces
30
+ # inclusion and keeps the wheel/sdist content in sync.
31
+ license-files = ["LICENSE.txt"]
32
+ name = "abnf-rust"
33
+ readme = "README.md"
34
+ requires-python = ">=3.10"
35
+
36
+ [project.urls]
37
+ Homepage = "https://github.com/declaresub/abnf"
38
+
39
+ [tool.maturin]
40
+ features = ["pyo3/extension-module"]
41
+ manifest-path = "rust/pyo3/Cargo.toml"
42
+ module-name = "abnf_rust._ext"
43
+ python-source = "src"
@@ -0,0 +1,15 @@
1
+ [package]
2
+ authors.workspace = true
3
+ description = "Pure-Rust ABNF parser engine; consumable from any Rust caller."
4
+ edition.workspace = true
5
+ license.workspace = true
6
+ name = "abnf-core"
7
+ repository.workspace = true
8
+ rust-version.workspace = true
9
+ version.workspace = true
10
+
11
+ [dependencies]
12
+ caseless.workspace = true
13
+ lru.workspace = true
14
+ once_cell.workspace = true
15
+ smallvec.workspace = true
@@ -0,0 +1,90 @@
1
+ //! `Alternation` — ABNF `/` operator.
2
+ //!
3
+ //! Mirrors `abnf.parser.Alternation` (`_parser_python.py:126-154`).
4
+ //!
5
+ //! Two modes governed by `first_match`:
6
+ //!
7
+ //! * `false` (default): collect matches from every successful
8
+ //! alternative. The caller (typically `Rule.parse`) re-orders by
9
+ //! longest match.
10
+ //! * `true`: yield matches from the first successful alternative and
11
+ //! stop scanning the remaining ones.
12
+
13
+ use std::sync::atomic::{AtomicBool, Ordering};
14
+
15
+ use smallvec::SmallVec;
16
+
17
+ use crate::concatenation::sort_by_longest;
18
+ use crate::error::ParseError;
19
+ use crate::parser::{ArcParser, MatchList, ParseResult};
20
+
21
+ #[derive(Debug)]
22
+ pub struct Alternation {
23
+ pub parsers: Vec<ArcParser>,
24
+ first_match: AtomicBool,
25
+ }
26
+
27
+ impl Alternation {
28
+ pub fn new(parsers: Vec<ArcParser>) -> Self {
29
+ Self {
30
+ parsers,
31
+ first_match: AtomicBool::new(false),
32
+ }
33
+ }
34
+
35
+ pub fn with_first_match(parsers: Vec<ArcParser>, first_match: bool) -> Self {
36
+ Self {
37
+ parsers,
38
+ first_match: AtomicBool::new(first_match),
39
+ }
40
+ }
41
+
42
+ pub fn first_match(&self) -> bool {
43
+ self.first_match.load(Ordering::Relaxed)
44
+ }
45
+
46
+ pub fn set_first_match(&self, value: bool) {
47
+ self.first_match.store(value, Ordering::Relaxed);
48
+ }
49
+
50
+ pub fn lparse(&self, source: &str, start: usize) -> ParseResult {
51
+ let mut all: MatchList = SmallVec::new();
52
+ let mut found = false;
53
+ let first_match = self.first_match();
54
+ for p in &self.parsers {
55
+ match p.lparse(source, start) {
56
+ Ok(ms) => {
57
+ if !ms.is_empty() {
58
+ found = true;
59
+ }
60
+ all.extend(ms);
61
+ }
62
+ Err(_) => continue,
63
+ }
64
+ // Mirror Python: in first_match mode, return after the
65
+ // first parser that did NOT raise, regardless of whether
66
+ // it yielded any matches.
67
+ if first_match {
68
+ return if found {
69
+ Ok(all)
70
+ } else {
71
+ Ok(SmallVec::new())
72
+ };
73
+ }
74
+ }
75
+ if found {
76
+ // Sort longest-first so downstream consumers (notably
77
+ // `Rule.lparse`, which yields the first match it sees)
78
+ // observe the longest candidate immediately and can
79
+ // short-circuit without materialising the rest. Skip
80
+ // the call entirely when there's nothing to reorder —
81
+ // deterministic grammars hit this fast path constantly.
82
+ if all.len() > 1 {
83
+ sort_by_longest(&mut all);
84
+ }
85
+ Ok(all)
86
+ } else {
87
+ Err(ParseError::new("Alternation", start))
88
+ }
89
+ }
90
+ }