parsanol 1.3.54 → 1.3.57
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.
- checksums.yaml +4 -4
- data/Cargo.lock +97 -23
- data/exe/parsanol +7 -0
- data/ext/parsanol_cdylib/Cargo.toml +1 -1
- data/ext/parsanol_native/Cargo.toml +2 -2
- data/ext/parsanol_native/build.rs +9 -0
- data/ext/parsanol_native/extconf.rb +10 -0
- data/lib/parsanol/atoms/base.rb +1 -1
- data/lib/parsanol/atoms/cut.rb +1 -1
- data/lib/parsanol/atoms/repetition.rb +13 -2
- data/lib/parsanol/cause.rb +1 -1
- data/lib/parsanol/error_reporter/contextual.rb +1 -1
- data/lib/parsanol/lazy_result.rb +12 -3
- data/lib/parsanol/native/serializer.rb +5 -2
- data/lib/parsanol/native/transformer.rb +12 -8
- data/lib/parsanol/native.rb +4 -2
- data/lib/parsanol/parg/artifact.rb +213 -0
- data/lib/parsanol/parg/authoring.rb +110 -0
- data/lib/parsanol/parg/bindings.rb +129 -0
- data/lib/parsanol/parg/cli.rb +251 -0
- data/lib/parsanol/parg/compiler.rb +465 -0
- data/lib/parsanol/parg/derive.rb +28 -0
- data/lib/parsanol/parg/document.rb +69 -0
- data/lib/parsanol/parg/error.rb +18 -0
- data/lib/parsanol/parg/frontend.rb +173 -0
- data/lib/parsanol/parg/import.rb +34 -0
- data/lib/parsanol/parg/importers/abnf.rb +299 -0
- data/lib/parsanol/parg/importers/ebnf.rb +201 -0
- data/lib/parsanol/parg/importers/pest.rb +314 -0
- data/lib/parsanol/parg/imports.rb +87 -0
- data/lib/parsanol/parg/lexer.rb +72 -0
- data/lib/parsanol/parg/lints.rb +171 -0
- data/lib/parsanol/parg/lsp.rb +208 -0
- data/lib/parsanol/parg/lutaml.rb +67 -0
- data/lib/parsanol/parg/node.rb +20 -0
- data/lib/parsanol/parg/parser.rb +458 -0
- data/lib/parsanol/parg/preprocess.rb +36 -0
- data/lib/parsanol/parg/render.rb +44 -0
- data/lib/parsanol/parg/selfhost.rb +49 -0
- data/lib/parsanol/parg/visitor.rb +64 -0
- data/lib/parsanol/parg.rb +38 -0
- data/lib/parsanol/parser.rb +1 -1
- data/lib/parsanol/pattern.rb +1 -1
- data/lib/parsanol/pool.rb +1 -1
- data/lib/parsanol/rope.rb +1 -1
- data/lib/parsanol/slice.rb +4 -6
- data/lib/parsanol/source/line_cache.rb +1 -1
- data/lib/parsanol/source.rb +2 -2
- data/lib/parsanol/version.rb +1 -1
- data/lib/parsanol/vm.rb +95 -5
- data/lib/parsanol.rb +9 -0
- data/parsanol.gemspec +3 -1
- metadata +31 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: dac1ca6df26172acdc4f7a676c018d1a9cf6107f5a2b6643b1274cbd56ba3b8f
|
|
4
|
+
data.tar.gz: bbeebb38922a236a170578538858e2f795e9da94679dd6c7a0cd81576d4542a7
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 9170d4b42f82853d41741475abb92fe26f126fde281b4c1b2f31b6b6004dab21fa7a9a9a23b580b83c86f89978dd021767d5464c79080ef19d9ba68771cd7d23
|
|
7
|
+
data.tar.gz: 633a3b087e6b6d6656e8ddd0db3c0548f6985ea72e43da51537a95d07c480957397b5fe6eda56b8651a2d302cb6b886b5661fc2446dfc4aceb2943a9c31ba2a5
|
data/Cargo.lock
CHANGED
|
@@ -54,6 +54,15 @@ version = "2.13.2"
|
|
|
54
54
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
55
55
|
checksum = "3ded4057c258ba199e2d26386d3af3780957ecaee6c4ef4041c6b4b8b97c0b06"
|
|
56
56
|
|
|
57
|
+
[[package]]
|
|
58
|
+
name = "block-buffer"
|
|
59
|
+
version = "0.12.1"
|
|
60
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
61
|
+
checksum = "d2f6c7dbe95a6ed67ad9f18e57daf93a2f034c524b99fd2b76d18fdfeb6660aa"
|
|
62
|
+
dependencies = [
|
|
63
|
+
"hybrid-array",
|
|
64
|
+
]
|
|
65
|
+
|
|
57
66
|
[[package]]
|
|
58
67
|
name = "bumpalo"
|
|
59
68
|
version = "3.20.3"
|
|
@@ -86,6 +95,41 @@ dependencies = [
|
|
|
86
95
|
"libloading",
|
|
87
96
|
]
|
|
88
97
|
|
|
98
|
+
[[package]]
|
|
99
|
+
name = "const-oid"
|
|
100
|
+
version = "0.10.2"
|
|
101
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
102
|
+
checksum = "a6ef517f0926dd24a1582492c791b6a4818a4d94e789a334894aa15b0d12f55c"
|
|
103
|
+
|
|
104
|
+
[[package]]
|
|
105
|
+
name = "cpufeatures"
|
|
106
|
+
version = "0.3.1"
|
|
107
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
108
|
+
checksum = "5ca28b0ae3115b884660db4118d803791fd6756b6e88f39c0f3f7859060d7566"
|
|
109
|
+
dependencies = [
|
|
110
|
+
"libc",
|
|
111
|
+
]
|
|
112
|
+
|
|
113
|
+
[[package]]
|
|
114
|
+
name = "crypto-common"
|
|
115
|
+
version = "0.2.2"
|
|
116
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
117
|
+
checksum = "ce6e4c961d6cd6c9a86db418387425e8bdeaf05b3c8bc1411e6dca4c252f1453"
|
|
118
|
+
dependencies = [
|
|
119
|
+
"hybrid-array",
|
|
120
|
+
]
|
|
121
|
+
|
|
122
|
+
[[package]]
|
|
123
|
+
name = "digest"
|
|
124
|
+
version = "0.11.3"
|
|
125
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
126
|
+
checksum = "f1dd6dbb5841937940781866fa1281a1ff7bd3bf827091440879f9994983d5c2"
|
|
127
|
+
dependencies = [
|
|
128
|
+
"block-buffer",
|
|
129
|
+
"const-oid",
|
|
130
|
+
"crypto-common",
|
|
131
|
+
]
|
|
132
|
+
|
|
89
133
|
[[package]]
|
|
90
134
|
name = "either"
|
|
91
135
|
version = "1.18.0"
|
|
@@ -148,6 +192,15 @@ dependencies = [
|
|
|
148
192
|
"foldhash",
|
|
149
193
|
]
|
|
150
194
|
|
|
195
|
+
[[package]]
|
|
196
|
+
name = "hybrid-array"
|
|
197
|
+
version = "0.4.15"
|
|
198
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
199
|
+
checksum = "27f864f10dfb56725ce5ce5472bc52252c8f93a4ab86327122cebf62c5f59a17"
|
|
200
|
+
dependencies = [
|
|
201
|
+
"typenum",
|
|
202
|
+
]
|
|
203
|
+
|
|
151
204
|
[[package]]
|
|
152
205
|
name = "itertools"
|
|
153
206
|
version = "0.13.0"
|
|
@@ -165,9 +218,9 @@ checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"
|
|
|
165
218
|
|
|
166
219
|
[[package]]
|
|
167
220
|
name = "js-sys"
|
|
168
|
-
version = "0.3.
|
|
221
|
+
version = "0.3.106"
|
|
169
222
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
170
|
-
checksum = "
|
|
223
|
+
checksum = "7883d941dae510fb2d978fc3fe018c71c9e2892fd38854de3e8b92c2e5ad9cc5"
|
|
171
224
|
dependencies = [
|
|
172
225
|
"cfg-if",
|
|
173
226
|
"wasm-bindgen",
|
|
@@ -203,8 +256,9 @@ checksum = "f9f8bd3e56ce4dfc153cf470fffbfa98c7620958b312ca5c3a4b8d5181fd13c6"
|
|
|
203
256
|
|
|
204
257
|
[[package]]
|
|
205
258
|
name = "magnus"
|
|
206
|
-
version = "0.9.
|
|
207
|
-
source = "
|
|
259
|
+
version = "0.9.1"
|
|
260
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
261
|
+
checksum = "4c01bef153b8d0f086991f0e166474a1d57b738221f9a9c11405d498ac95a44d"
|
|
208
262
|
dependencies = [
|
|
209
263
|
"magnus-macros",
|
|
210
264
|
"rb-sys",
|
|
@@ -214,8 +268,9 @@ dependencies = [
|
|
|
214
268
|
|
|
215
269
|
[[package]]
|
|
216
270
|
name = "magnus-macros"
|
|
217
|
-
version = "0.9.
|
|
218
|
-
source = "
|
|
271
|
+
version = "0.9.1"
|
|
272
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
273
|
+
checksum = "9dafde2eeb66f090e0f326112323eb8324b12cb32b5d1210e541d3df6b0ce77e"
|
|
219
274
|
dependencies = [
|
|
220
275
|
"proc-macro2",
|
|
221
276
|
"quote",
|
|
@@ -252,9 +307,9 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50"
|
|
|
252
307
|
|
|
253
308
|
[[package]]
|
|
254
309
|
name = "parsanol"
|
|
255
|
-
version = "0.
|
|
310
|
+
version = "0.10.1"
|
|
256
311
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
257
|
-
checksum = "
|
|
312
|
+
checksum = "3201f3b6340113ce57871a1405679ad7520a420cb8958777983371a2d4e6bf55"
|
|
258
313
|
dependencies = [
|
|
259
314
|
"ahash",
|
|
260
315
|
"getrandom 0.3.4",
|
|
@@ -263,15 +318,17 @@ dependencies = [
|
|
|
263
318
|
"magnus",
|
|
264
319
|
"parsanol-derive",
|
|
265
320
|
"regex",
|
|
321
|
+
"regex-syntax",
|
|
266
322
|
"serde",
|
|
267
323
|
"serde_json",
|
|
324
|
+
"sha2",
|
|
268
325
|
]
|
|
269
326
|
|
|
270
327
|
[[package]]
|
|
271
328
|
name = "parsanol-derive"
|
|
272
|
-
version = "0.
|
|
329
|
+
version = "0.10.1"
|
|
273
330
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
274
|
-
checksum = "
|
|
331
|
+
checksum = "07bea1e5fb6a78314596116ac62e08ab5c73c201c62cd83715e75309c44e0977"
|
|
275
332
|
dependencies = [
|
|
276
333
|
"proc-macro2",
|
|
277
334
|
"quote",
|
|
@@ -280,7 +337,7 @@ dependencies = [
|
|
|
280
337
|
|
|
281
338
|
[[package]]
|
|
282
339
|
name = "parsanol_cdylib"
|
|
283
|
-
version = "1.3.
|
|
340
|
+
version = "1.3.52"
|
|
284
341
|
dependencies = [
|
|
285
342
|
"parsanol",
|
|
286
343
|
]
|
|
@@ -443,6 +500,17 @@ dependencies = [
|
|
|
443
500
|
"zmij",
|
|
444
501
|
]
|
|
445
502
|
|
|
503
|
+
[[package]]
|
|
504
|
+
name = "sha2"
|
|
505
|
+
version = "0.11.0"
|
|
506
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
507
|
+
checksum = "446ba717509524cb3f22f17ecc096f10f4822d76ab5c0b9822c5f9c284e825f4"
|
|
508
|
+
dependencies = [
|
|
509
|
+
"cfg-if",
|
|
510
|
+
"cpufeatures",
|
|
511
|
+
"digest",
|
|
512
|
+
]
|
|
513
|
+
|
|
446
514
|
[[package]]
|
|
447
515
|
name = "shell-words"
|
|
448
516
|
version = "1.1.1"
|
|
@@ -477,6 +545,12 @@ dependencies = [
|
|
|
477
545
|
"unicode-ident",
|
|
478
546
|
]
|
|
479
547
|
|
|
548
|
+
[[package]]
|
|
549
|
+
name = "typenum"
|
|
550
|
+
version = "1.20.1"
|
|
551
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
552
|
+
checksum = "b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20"
|
|
553
|
+
|
|
480
554
|
[[package]]
|
|
481
555
|
name = "unicode-ident"
|
|
482
556
|
version = "1.0.26"
|
|
@@ -500,9 +574,9 @@ dependencies = [
|
|
|
500
574
|
|
|
501
575
|
[[package]]
|
|
502
576
|
name = "wasm-bindgen"
|
|
503
|
-
version = "0.2.
|
|
577
|
+
version = "0.2.129"
|
|
504
578
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
505
|
-
checksum = "
|
|
579
|
+
checksum = "9bb54f33acc68fd454578d9820b0bde1a1a3d17aa17bb7b6595806d02886d409"
|
|
506
580
|
dependencies = [
|
|
507
581
|
"cfg-if",
|
|
508
582
|
"once_cell",
|
|
@@ -513,9 +587,9 @@ dependencies = [
|
|
|
513
587
|
|
|
514
588
|
[[package]]
|
|
515
589
|
name = "wasm-bindgen-macro"
|
|
516
|
-
version = "0.2.
|
|
590
|
+
version = "0.2.129"
|
|
517
591
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
518
|
-
checksum = "
|
|
592
|
+
checksum = "2e29d0c35b16e224a7eeb5cd2d25e3e1968fbd65604117b44d3b789d00ee8535"
|
|
519
593
|
dependencies = [
|
|
520
594
|
"quote",
|
|
521
595
|
"wasm-bindgen-macro-support",
|
|
@@ -523,9 +597,9 @@ dependencies = [
|
|
|
523
597
|
|
|
524
598
|
[[package]]
|
|
525
599
|
name = "wasm-bindgen-macro-support"
|
|
526
|
-
version = "0.2.
|
|
600
|
+
version = "0.2.129"
|
|
527
601
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
528
|
-
checksum = "
|
|
602
|
+
checksum = "6f501a8bc3719dba86ef8ae4728879c08001bea749eb1333ac5b91e040e2a6b7"
|
|
529
603
|
dependencies = [
|
|
530
604
|
"bumpalo",
|
|
531
605
|
"proc-macro2",
|
|
@@ -536,9 +610,9 @@ dependencies = [
|
|
|
536
610
|
|
|
537
611
|
[[package]]
|
|
538
612
|
name = "wasm-bindgen-shared"
|
|
539
|
-
version = "0.2.
|
|
613
|
+
version = "0.2.129"
|
|
540
614
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
541
|
-
checksum = "
|
|
615
|
+
checksum = "23f0c9c52aa7cd7d77769a4cfe2a9adb1b331f489a41d912ce14513d5ab995c6"
|
|
542
616
|
dependencies = [
|
|
543
617
|
"unicode-ident",
|
|
544
618
|
]
|
|
@@ -557,18 +631,18 @@ checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e"
|
|
|
557
631
|
|
|
558
632
|
[[package]]
|
|
559
633
|
name = "zerocopy"
|
|
560
|
-
version = "0.8.
|
|
634
|
+
version = "0.8.59"
|
|
561
635
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
562
|
-
checksum = "
|
|
636
|
+
checksum = "6df92bf3d9227be3d53173901ddbffac2babc27ae50f397776ffd6dc33f800cb"
|
|
563
637
|
dependencies = [
|
|
564
638
|
"zerocopy-derive",
|
|
565
639
|
]
|
|
566
640
|
|
|
567
641
|
[[package]]
|
|
568
642
|
name = "zerocopy-derive"
|
|
569
|
-
version = "0.8.
|
|
643
|
+
version = "0.8.59"
|
|
570
644
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
571
|
-
checksum = "
|
|
645
|
+
checksum = "ac4f328cf2f05d084e496c3e9c3f33ed0a183656a16e1fcec4d464d8373aec82"
|
|
572
646
|
dependencies = [
|
|
573
647
|
"proc-macro2",
|
|
574
648
|
"quote",
|
data/exe/parsanol
ADDED
|
@@ -27,8 +27,8 @@ rb-sys = { version = "0.9.124", features = ["global-allocator"] }
|
|
|
27
27
|
# magnus for Ruby bindings (from crates.io, patched locally for Ruby 4.0 support)
|
|
28
28
|
magnus = { version = "0.9" }
|
|
29
29
|
|
|
30
|
-
# parsanol parser library (
|
|
31
|
-
parsanol = { version = "0.
|
|
30
|
+
# parsanol parser library (crates.io; 0.10 carries the class fast-path fix)
|
|
31
|
+
parsanol = { version = "0.10", features = ["ruby"] }
|
|
32
32
|
|
|
33
33
|
# Logging
|
|
34
34
|
log = "0.4"
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
fn main() {
|
|
2
|
+
// MRI loadables on macOS resolve ruby symbols from the host process
|
|
3
|
+
// at load time; cargo's cdylib link defaults to failing on undefined
|
|
4
|
+
// symbols, so the flag must come from the top-level package.
|
|
5
|
+
if cfg!(target_os = "macos") {
|
|
6
|
+
println!("cargo:rustc-link-arg=-Wl,-undefined,dynamic_lookup");
|
|
7
|
+
}
|
|
8
|
+
println!("cargo:rerun-if-changed=build.rs");
|
|
9
|
+
}
|
|
@@ -30,6 +30,16 @@ create_rust_makefile("parsanol/parsanol_native") do |r|
|
|
|
30
30
|
# Create debug builds in dev, release in production
|
|
31
31
|
r.profile = ENV.fetch("RB_SYS_CARGO_PROFILE", :dev).to_sym
|
|
32
32
|
|
|
33
|
+
# cargo rustc builds dependency cdylibs verbatim, and parsanol ships
|
|
34
|
+
# a cdylib crate-type (the ffi tier). On macOS every dylib in the
|
|
35
|
+
# build resolves ruby symbols from the host process at load time, so
|
|
36
|
+
# every link must tolerate undefined symbols. (extconf runs as a
|
|
37
|
+
# subprocess, so this must be baked into the Makefile — env changes
|
|
38
|
+
# here would not survive it.)
|
|
39
|
+
if RbConfig::CONFIG["host_os"].include?("darwin")
|
|
40
|
+
r.extra_rustflags = %w[-C link-arg=-Wl,-undefined,dynamic_lookup]
|
|
41
|
+
end
|
|
42
|
+
|
|
33
43
|
# Enable stable API compiled fallback for ruby-head and older Ruby versions
|
|
34
44
|
r.use_stable_api_compiled_fallback = true
|
|
35
45
|
|
data/lib/parsanol/atoms/base.rb
CHANGED
|
@@ -208,7 +208,7 @@ module Parsanol
|
|
|
208
208
|
|
|
209
209
|
# Converts raw input to Source if needed.
|
|
210
210
|
def normalize_input(source)
|
|
211
|
-
source.
|
|
211
|
+
source.is_a?(Parsanol::Source) ? source : Parsanol::Source.new(source)
|
|
212
212
|
end
|
|
213
213
|
|
|
214
214
|
# Detects if we're in a Parser context.
|
data/lib/parsanol/atoms/cut.rb
CHANGED
|
@@ -42,7 +42,7 @@ module Parsanol
|
|
|
42
42
|
# 1. Mark the current position as a cut point
|
|
43
43
|
# 2. Empty the backtrack stack (we won't backtrack past here)
|
|
44
44
|
# 3. Aggressively evict cache entries before this position
|
|
45
|
-
context.cut!(source.bytepos)
|
|
45
|
+
context.cut!(source.bytepos)
|
|
46
46
|
|
|
47
47
|
[success, value]
|
|
48
48
|
end
|
|
@@ -66,7 +66,7 @@ module Parsanol
|
|
|
66
66
|
# @return [Array(Boolean, Object)] result
|
|
67
67
|
def try(source, context, consume_all)
|
|
68
68
|
# Check for tree memoization support
|
|
69
|
-
if context.
|
|
69
|
+
if context.use_tree_memoization?
|
|
70
70
|
return with_tree_cache(source, context, consume_all)
|
|
71
71
|
end
|
|
72
72
|
|
|
@@ -183,6 +183,7 @@ module Parsanol
|
|
|
183
183
|
last_failure = nil
|
|
184
184
|
|
|
185
185
|
loop do
|
|
186
|
+
iteration_start = source.bytepos
|
|
186
187
|
success, value = @parslet.apply(source, context, false)
|
|
187
188
|
|
|
188
189
|
unless success
|
|
@@ -193,6 +194,11 @@ module Parsanol
|
|
|
193
194
|
occurrence += 1
|
|
194
195
|
result[occurrence] = value
|
|
195
196
|
|
|
197
|
+
# A body match that consumes nothing cannot make progress;
|
|
198
|
+
# looping again would re-match empty forever. Count the empty
|
|
199
|
+
# match, then stop — the min check below applies as usual.
|
|
200
|
+
break if source.bytepos == iteration_start
|
|
201
|
+
|
|
196
202
|
break if @max && occurrence >= @max
|
|
197
203
|
end
|
|
198
204
|
|
|
@@ -254,6 +260,7 @@ module Parsanol
|
|
|
254
260
|
last_failure = nil
|
|
255
261
|
|
|
256
262
|
loop do
|
|
263
|
+
iteration_start = source.bytepos
|
|
257
264
|
success, value = @parslet.apply(source, context, false)
|
|
258
265
|
|
|
259
266
|
unless success
|
|
@@ -265,6 +272,10 @@ module Parsanol
|
|
|
265
272
|
result[occurrence] = value
|
|
266
273
|
positions << source.bytepos
|
|
267
274
|
|
|
275
|
+
# Zero-width body match: count it, stop iterating (the min
|
|
276
|
+
# check below applies as usual) — mirrors try_general.
|
|
277
|
+
break if source.bytepos == iteration_start
|
|
278
|
+
|
|
268
279
|
break if @max && occurrence >= @max
|
|
269
280
|
end
|
|
270
281
|
|
|
@@ -287,7 +298,7 @@ module Parsanol
|
|
|
287
298
|
context.store_tree_memo(cache_key, start_pos,
|
|
288
299
|
result[1, occurrence], end_pos)
|
|
289
300
|
end
|
|
290
|
-
context.release_array(positions)
|
|
301
|
+
context.release_array(positions)
|
|
291
302
|
|
|
292
303
|
# Check minimum
|
|
293
304
|
if occurrence < @min
|
data/lib/parsanol/cause.rb
CHANGED
|
@@ -74,7 +74,7 @@ module Parsanol
|
|
|
74
74
|
line_num, col_num = @source.line_and_column(@position)
|
|
75
75
|
|
|
76
76
|
formatted_msg = @message.map do |msg|
|
|
77
|
-
msg.
|
|
77
|
+
msg.is_a?(Parsanol::Slice) ? msg.content.inspect : msg.to_s
|
|
78
78
|
end.join
|
|
79
79
|
|
|
80
80
|
"#{formatted_msg} at line #{line_num} char #{col_num}#{@parsing_label}."
|
|
@@ -72,7 +72,7 @@ module Parsanol
|
|
|
72
72
|
cause = super
|
|
73
73
|
|
|
74
74
|
# Apply label if the atom has one
|
|
75
|
-
if atom.
|
|
75
|
+
if atom.is_a?(Parsanol::Atoms::Base) && (lbl = atom.label)
|
|
76
76
|
maybe_update_label(lbl, src.pos.bytepos)
|
|
77
77
|
cause.set_label(@active_label_text)
|
|
78
78
|
end
|
data/lib/parsanol/lazy_result.rb
CHANGED
|
@@ -103,6 +103,15 @@ module Parsanol
|
|
|
103
103
|
|
|
104
104
|
alias kind_of? is_a?
|
|
105
105
|
|
|
106
|
+
# The delegated interface: Array's full class contract (including
|
|
107
|
+
# Enumerable), computed once against the type rather than probed on
|
|
108
|
+
# instances.
|
|
109
|
+
ARRAY_METHODS = (
|
|
110
|
+
Array.instance_methods(true) + Enumerable.instance_methods + [:to_ary]
|
|
111
|
+
).freeze
|
|
112
|
+
|
|
113
|
+
private_constant :ARRAY_METHODS
|
|
114
|
+
|
|
106
115
|
# Respond to array methods.
|
|
107
116
|
#
|
|
108
117
|
# @param method [Symbol] Method name
|
|
@@ -110,7 +119,7 @@ module Parsanol
|
|
|
110
119
|
# @return [Boolean] true if responds
|
|
111
120
|
#
|
|
112
121
|
def respond_to?(method, include_private = false)
|
|
113
|
-
super ||
|
|
122
|
+
super || ARRAY_METHODS.include?(method)
|
|
114
123
|
end
|
|
115
124
|
|
|
116
125
|
# Delegate unknown methods to materialized array.
|
|
@@ -121,7 +130,7 @@ module Parsanol
|
|
|
121
130
|
# @return [Object] Result of method call
|
|
122
131
|
#
|
|
123
132
|
def method_missing(method, ...)
|
|
124
|
-
if
|
|
133
|
+
if ARRAY_METHODS.include?(method)
|
|
125
134
|
to_a.public_send(method, ...)
|
|
126
135
|
else
|
|
127
136
|
super
|
|
@@ -135,7 +144,7 @@ module Parsanol
|
|
|
135
144
|
# @return [Boolean] true if method is supported
|
|
136
145
|
#
|
|
137
146
|
def respond_to_missing?(method, include_private = false)
|
|
138
|
-
|
|
147
|
+
ARRAY_METHODS.include?(method) || super
|
|
139
148
|
end
|
|
140
149
|
|
|
141
150
|
# Compare with another object.
|
|
@@ -95,9 +95,12 @@ module Parsanol
|
|
|
95
95
|
|
|
96
96
|
def serialize_re(atom)
|
|
97
97
|
# Ruby's Regexp#to_s produces "(?-mix:pattern)" format
|
|
98
|
-
#
|
|
98
|
+
# The pattern must reach the Rust regex engine verbatim, including
|
|
99
|
+
# inline flag groups: stripping (?i:...) silently turned every
|
|
100
|
+
# case-insensitive regex into a case-sensitive one on the native
|
|
101
|
+
# path (the Ruby atom still compiled it with the flag, so the two
|
|
102
|
+
# engines disagreed). Rust regex understands the same inline groups.
|
|
99
103
|
pattern = atom.match
|
|
100
|
-
pattern = ::Regexp.last_match(1) if pattern =~ /^\(\?[-mix]*:(.+)\)$/
|
|
101
104
|
{
|
|
102
105
|
"Re" => {
|
|
103
106
|
"pattern" => pattern,
|
|
@@ -391,15 +391,19 @@ module Parsanol
|
|
|
391
391
|
return left.is_a?(Hash) ? left.merge(right) : left + right
|
|
392
392
|
end
|
|
393
393
|
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
394
|
+
# String-like = String or Slice (both implement to_str). When
|
|
395
|
+
# only ONE side is string-like, the OTHER side wins — the
|
|
396
|
+
# original duck-typed priority, preserved exactly.
|
|
397
|
+
left_stringlike = left.is_a?(String) || left.is_a?(Parsanol::Slice)
|
|
398
|
+
right_stringlike = right.is_a?(String) || right.is_a?(Parsanol::Slice)
|
|
399
|
+
if left_stringlike && right_stringlike
|
|
400
|
+
return right if right.is_a?(Parsanol::Slice)
|
|
401
|
+
return left if left.is_a?(Parsanol::Slice)
|
|
402
|
+
|
|
403
|
+
return left + right
|
|
399
404
|
end
|
|
400
|
-
|
|
401
|
-
return
|
|
402
|
-
return right if left.respond_to?(:to_str)
|
|
405
|
+
return left if right_stringlike
|
|
406
|
+
return right if left_stringlike
|
|
403
407
|
|
|
404
408
|
return left + [right] if right.is_a?(Hash)
|
|
405
409
|
return [left] + right if left.is_a?(Hash)
|
data/lib/parsanol/native.rb
CHANGED
|
@@ -216,7 +216,9 @@ module Parsanol
|
|
|
216
216
|
# cause from that directly — the failure path never needs a
|
|
217
217
|
# reporter reparse. The single interpreter pass below stays only
|
|
218
218
|
# to recover inputs from grammars native cannot express.
|
|
219
|
-
|
|
219
|
+
parsanol_grammar =
|
|
220
|
+
grammar.is_a?(Parsanol::Atoms::Base) || grammar.is_a?(Parsanol::Parser)
|
|
221
|
+
if parsanol_grammar && (m = error.message.match(NATIVE_POS_MARKER))
|
|
220
222
|
source = Parsanol::Source.new(input)
|
|
221
223
|
success, value = grammar.run_with_context(source, nil, true)
|
|
222
224
|
return grammar.finalize_result(value) if success
|
|
@@ -227,7 +229,7 @@ module Parsanol
|
|
|
227
229
|
raise Parsanol::ParseFailed.new(cause.to_s, cause)
|
|
228
230
|
end
|
|
229
231
|
|
|
230
|
-
if
|
|
232
|
+
if parsanol_grammar
|
|
231
233
|
# No native diagnostics (e.g. incomplete-input errors): one
|
|
232
234
|
# interpreter pass with the reporter attached — a success
|
|
233
235
|
# recovers the tree, a failure raises the cause tree.
|