parsanol 1.3.100-aarch64-linux → 1.3.101-aarch64-linux
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/lib/parsanol/3.2/parsanol_native.so +2 -2
- data/lib/parsanol/3.3/parsanol_native.so +2 -2
- data/lib/parsanol/3.4/parsanol_native.so +2 -2
- data/lib/parsanol/4.0/parsanol_native.so +2 -2
- data/lib/parsanol/atoms/repetition.rb +4 -0
- data/lib/parsanol/native/libparsanol.so +2 -2
- data/lib/parsanol/parg/artifact.rb +46 -6
- data/lib/parsanol/recovery.rb +24 -0
- data/lib/parsanol/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 85697303ffb8cb62ebb1208abc799e13e7ce23075778507e00d9141e7f25c9bb
|
|
4
|
+
data.tar.gz: 6238cca1d4d96d79a98bb4ac9b3dc2a1414c4e91866d930b2e38ab2a731bcf96
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 727fe32b864fabf84910df147d2739f77feff1954eae6c8c56718360e902ad5d4fbba04d01e7f70e257168d75e7f9c835dd9c96f4778b62afcb098c6f68b7d51
|
|
7
|
+
data.tar.gz: b33624dd05ee196ed99cc4b579d65d9e3b5894487928069d5b85908c8afe9b7dae9e82b418f77d0b329f9ace95442b14bf2e94d3b76076c6543a6b8b4eb8f072
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
[diffend] Oversized file quarantined before diffing.
|
|
2
2
|
name: data/lib/parsanol/3.2/parsanol_native.so
|
|
3
|
-
size:
|
|
4
|
-
sha256:
|
|
3
|
+
size: 40713576 bytes
|
|
4
|
+
sha256: 9046a412696fbea40f4abd5a490259c0238b129077d12c50f547a07a6898a3a2
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
[diffend] Oversized file quarantined before diffing.
|
|
2
2
|
name: data/lib/parsanol/3.3/parsanol_native.so
|
|
3
|
-
size:
|
|
4
|
-
sha256:
|
|
3
|
+
size: 40948672 bytes
|
|
4
|
+
sha256: 2baac404ddacf6abfd49f0603b886aede63153b76f800213bc5e47905322ecfc
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
[diffend] Oversized file quarantined before diffing.
|
|
2
2
|
name: data/lib/parsanol/3.4/parsanol_native.so
|
|
3
|
-
size:
|
|
4
|
-
sha256:
|
|
3
|
+
size: 40944224 bytes
|
|
4
|
+
sha256: 1156950191ccfa3f28bd3b4b73c5e5134d8602f3298a96ca6807713c4c4acfbe
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
[diffend] Oversized file quarantined before diffing.
|
|
2
2
|
name: data/lib/parsanol/4.0/parsanol_native.so
|
|
3
|
-
size:
|
|
4
|
-
sha256:
|
|
3
|
+
size: 40954248 bytes
|
|
4
|
+
sha256: 20539d7248054b4ccc12d1ced93f60f8a5565b8a215f41cf0bbb94de30c891e7
|
|
@@ -211,6 +211,7 @@ module Parsanol
|
|
|
211
211
|
|
|
212
212
|
# Check minimum bound
|
|
213
213
|
if occurrence < @min
|
|
214
|
+
Recovery.stash_partial(source.bytepos, result[1, occurrence], @result_tag)
|
|
214
215
|
source.bytepos = start_pos
|
|
215
216
|
return context.err_at(self, source, min_error, start_pos,
|
|
216
217
|
failure_children(last_failure))
|
|
@@ -218,6 +219,9 @@ module Parsanol
|
|
|
218
219
|
|
|
219
220
|
# Check complete consumption
|
|
220
221
|
if consume_all && source.chars_left.positive?
|
|
222
|
+
# R1.5: the partial run IS the best partial root — stash it
|
|
223
|
+
# before reporting the leftover-input failure.
|
|
224
|
+
Recovery.stash_partial(source.bytepos, result[1, occurrence], @result_tag)
|
|
221
225
|
return context.err(self, source, @extra_error,
|
|
222
226
|
failure_children(last_failure))
|
|
223
227
|
end
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
[diffend] Oversized file quarantined before diffing.
|
|
2
2
|
name: data/lib/parsanol/native/libparsanol.so
|
|
3
|
-
size:
|
|
4
|
-
sha256:
|
|
3
|
+
size: 36503920 bytes
|
|
4
|
+
sha256: 3edc47eb5bb795d4ffc067e423fe23a20eb513b1454686e3e146a1d7bc43fd87
|
|
@@ -217,14 +217,51 @@ module Parsanol
|
|
|
217
217
|
shape = parse(entry_name, input, mode: mode)
|
|
218
218
|
{ "ok" => true, "shape" => shape }
|
|
219
219
|
rescue Parsanol::ParseFailed => e
|
|
220
|
+
# The journaling re-parse fails at the same point with the
|
|
221
|
+
# interpreter's deepest cause — report ITS error, not the
|
|
222
|
+
# initial parse's (the native FFI's coarse failure position
|
|
223
|
+
# loses the deepest offset).
|
|
224
|
+
captures, reparse_error = recovery_journal(entry_name, input, mode)
|
|
220
225
|
{ "ok" => false,
|
|
221
|
-
"error" => recovery_error(e),
|
|
222
|
-
"captures" =>
|
|
226
|
+
"error" => reparse_error || recovery_error(e),
|
|
227
|
+
"captures" => captures,
|
|
228
|
+
"partial" => recovery_partial(entry_name) }
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
# R1.5 (TODO.sota/1): the deepest repetition prefix the failed
|
|
232
|
+
# journaling pass matched, shaped like the root (the item array
|
|
233
|
+
# under the root rule's name). Nil when nothing matched.
|
|
234
|
+
def recovery_partial(entry_name)
|
|
235
|
+
stash = Parsanol::Recovery.take_partial
|
|
236
|
+
return nil if stash.nil?
|
|
237
|
+
|
|
238
|
+
_end_pos, items, _tag = stash
|
|
239
|
+
# The stash holds raw per-iteration results; the root atom's
|
|
240
|
+
# flatten (the same laws the success shape goes through) turns
|
|
241
|
+
# sequence-tagged iterations into their shaped values.
|
|
242
|
+
flattened = items.map { |item| root_atom(entry_name).flatten(item) }
|
|
243
|
+
root_name = entry(entry_name)["root"].to_sym
|
|
244
|
+
{ root_name => flattened }
|
|
223
245
|
end
|
|
224
246
|
|
|
225
247
|
def recovery_error(err)
|
|
226
|
-
|
|
227
|
-
|
|
248
|
+
cause = err.parse_failure_cause
|
|
249
|
+
# The raised cause can sit shallower than the real failure (a
|
|
250
|
+
# consume-all leftover reported at the partial run's end);
|
|
251
|
+
# recovery annotations carry the DEEPEST position in the cause
|
|
252
|
+
# tree — the same semantics as the rs engine's failure wire.
|
|
253
|
+
{ "offset" => cause && deepest_position(cause),
|
|
254
|
+
"message" => err.message }
|
|
255
|
+
end
|
|
256
|
+
|
|
257
|
+
def deepest_position(cause)
|
|
258
|
+
max = cause.position
|
|
259
|
+
Array(cause.children).each do |child|
|
|
260
|
+
next if child.nil?
|
|
261
|
+
|
|
262
|
+
max = [max, deepest_position(child)].max
|
|
263
|
+
end
|
|
264
|
+
max
|
|
228
265
|
end
|
|
229
266
|
|
|
230
267
|
# Journaling re-parse — always on the Ruby engine (journaling
|
|
@@ -233,18 +270,21 @@ module Parsanol
|
|
|
233
270
|
# by the differential specs, so the observed captures agree.
|
|
234
271
|
def recovery_journal(entry_name, input, _mode)
|
|
235
272
|
Parsanol::Recovery.start_journal
|
|
273
|
+
reparse_error = nil
|
|
236
274
|
begin
|
|
237
275
|
parse(entry_name, input, mode: :ruby)
|
|
238
|
-
rescue Parsanol::ParseFailed
|
|
276
|
+
rescue Parsanol::ParseFailed => e
|
|
239
277
|
# expected: the journaling pass fails at the same point
|
|
278
|
+
reparse_error = recovery_error(e)
|
|
240
279
|
end
|
|
241
|
-
Parsanol::Recovery.stop_journal.each_with_object({}) do |(name, value), out|
|
|
280
|
+
captures = Parsanol::Recovery.stop_journal.each_with_object({}) do |(name, value), out|
|
|
242
281
|
# Both the initial attempt and the diagnostic re-parse journal
|
|
243
282
|
# into the shared thread-local; identical observations dedupe.
|
|
244
283
|
wire = value.is_a?(Slice) ? slice_wire(value) : value
|
|
245
284
|
(out[name.to_s] ||= []) << wire
|
|
246
285
|
out[name.to_s].uniq!
|
|
247
286
|
end
|
|
287
|
+
[captures, reparse_error]
|
|
248
288
|
end
|
|
249
289
|
|
|
250
290
|
def slice_wire(slice)
|
data/lib/parsanol/recovery.rb
CHANGED
|
@@ -11,6 +11,10 @@ module Parsanol
|
|
|
11
11
|
def start_journal
|
|
12
12
|
Thread.current[:parsanol_recovery_journal] = []
|
|
13
13
|
Thread.current[:parsanol_recovery_journaling] = true
|
|
14
|
+
# R1.5 partial-tree collection rides the journaling (recovery)
|
|
15
|
+
# pass: success paths never touch the stash.
|
|
16
|
+
Thread.current[:parsanol_recovery_partial] = nil
|
|
17
|
+
Thread.current[:parsanol_recovery_collect_partial] = true
|
|
14
18
|
end
|
|
15
19
|
|
|
16
20
|
# Stops journaling and returns the journal: [name, value] pairs in
|
|
@@ -29,5 +33,25 @@ module Parsanol
|
|
|
29
33
|
def journaling?
|
|
30
34
|
Thread.current[:parsanol_recovery_journaling] == true
|
|
31
35
|
end
|
|
36
|
+
|
|
37
|
+
# R1.5: the deepest repetition prefix matched before the failure.
|
|
38
|
+
# Repetition failure paths call stash_partial; the furthest-reaching
|
|
39
|
+
# prefix wins. [end_pos, items, tag]
|
|
40
|
+
def stash_partial(end_pos, items, tag)
|
|
41
|
+
return unless Thread.current[:parsanol_recovery_collect_partial]
|
|
42
|
+
return if items.empty? # nothing matched: no partial, like rs
|
|
43
|
+
|
|
44
|
+
current = Thread.current[:parsanol_recovery_partial]
|
|
45
|
+
return if current && current[0] >= end_pos
|
|
46
|
+
|
|
47
|
+
Thread.current[:parsanol_recovery_partial] = [end_pos, items.dup, tag]
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def take_partial
|
|
51
|
+
value = Thread.current[:parsanol_recovery_partial]
|
|
52
|
+
Thread.current[:parsanol_recovery_partial] = nil
|
|
53
|
+
Thread.current[:parsanol_recovery_collect_partial] = nil
|
|
54
|
+
value
|
|
55
|
+
end
|
|
32
56
|
end
|
|
33
57
|
end
|
data/lib/parsanol/version.rb
CHANGED