parsanol 1.3.75 → 1.3.77
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 +4 -4
- data/ext/parsanol_cdylib/Cargo.toml +2 -2
- data/ext/parsanol_native/Cargo.toml +4 -3
- data/lib/parsanol/atoms/lookbehind.rb +39 -9
- data/lib/parsanol/native/serializer.rb +11 -9
- data/lib/parsanol/parg/artifact.rb +10 -2
- 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: d50458b2aaf5e7227e08f447b64dcc2197fd3df69e02ad7d9c332f87fdad15ec
|
|
4
|
+
data.tar.gz: 07e542379ad8ffaf5a9c0c317c88f8f2b1a3f9c9bff9d1b54983b8e6bbb70d14
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 4be52cd42ea4ad9773e0d7a0e8bcf718cd485c880594291fcf4c798255d74c1619ed238a82ca81d83f2b1a74392ffb384583e190a2a6a308ae93c1b38cd425ba
|
|
7
|
+
data.tar.gz: 1160ef2ee557c591c7c28894bf24a59570e1ba9f565744cb5cb839d7f33af59a1deeae1ef1906c1211d1cc1fe9c388c0f16e16d4e0aa003442fa15bff74c2c97
|
data/Cargo.lock
CHANGED
|
@@ -307,9 +307,9 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50"
|
|
|
307
307
|
|
|
308
308
|
[[package]]
|
|
309
309
|
name = "parsanol"
|
|
310
|
-
version = "0.
|
|
310
|
+
version = "0.17.0"
|
|
311
311
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
312
|
-
checksum = "
|
|
312
|
+
checksum = "0a96694c55219bc77b62cc838883850952ad4f883cca10c11312a76a380da58d"
|
|
313
313
|
dependencies = [
|
|
314
314
|
"ahash",
|
|
315
315
|
"getrandom 0.3.4",
|
|
@@ -326,9 +326,9 @@ dependencies = [
|
|
|
326
326
|
|
|
327
327
|
[[package]]
|
|
328
328
|
name = "parsanol-derive"
|
|
329
|
-
version = "0.
|
|
329
|
+
version = "0.17.0"
|
|
330
330
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
331
|
-
checksum = "
|
|
331
|
+
checksum = "07917f2daf91d216927237719ae459f068dd29bef53669a2d12dc4b28ad6a1d9"
|
|
332
332
|
dependencies = [
|
|
333
333
|
"proc-macro2",
|
|
334
334
|
"quote",
|
|
@@ -29,9 +29,10 @@ magnus = { version = "0.9" }
|
|
|
29
29
|
|
|
30
30
|
# parsanol parser library (crates.io; 0.12 carries the rs#174 native
|
|
31
31
|
# backtracking fix: dynamic-dependent memoization + outcome cache)
|
|
32
|
-
# parsanol parser library (crates.io; 0.
|
|
33
|
-
#
|
|
34
|
-
|
|
32
|
+
# parsanol parser library (crates.io; 0.17.0 carries the LookSpec regex
|
|
33
|
+
# lookbehind (rs#163 gap 1) and the widened opaque writeback: the
|
|
34
|
+
# lazy-continuation fix, parsanol-ruby#160)
|
|
35
|
+
parsanol = { version = "0.17.0", features = ["ruby"] }
|
|
35
36
|
|
|
36
37
|
# Logging
|
|
37
38
|
log = "0.4"
|
|
@@ -2,30 +2,60 @@
|
|
|
2
2
|
|
|
3
3
|
module Parsanol
|
|
4
4
|
module Atoms
|
|
5
|
-
# Inspects the
|
|
6
|
-
#
|
|
7
|
-
#
|
|
8
|
-
#
|
|
9
|
-
#
|
|
5
|
+
# Inspects the text behind the current position and consumes
|
|
6
|
+
# nothing, yielding nil.
|
|
7
|
+
#
|
|
8
|
+
# Two forms (rs#137/#163):
|
|
9
|
+
# - Literal: the previous +count+ bytes must equal +pattern+
|
|
10
|
+
# (the precedes?/does_not_precede? fixed-window guard).
|
|
11
|
+
# - Regex: +source+ is searched in the preceding text and must
|
|
12
|
+
# end at the position — the CommonMark flanking form, which is
|
|
13
|
+
# class-based, multibyte and variable-length.
|
|
10
14
|
class Lookbehind < Base
|
|
11
|
-
attr_reader :count, :pattern, :positive
|
|
15
|
+
attr_reader :count, :pattern, :regex_source, :positive
|
|
12
16
|
|
|
13
17
|
def initialize(count, pattern, positive: true)
|
|
14
18
|
super()
|
|
15
19
|
@count = count
|
|
16
20
|
@pattern = pattern
|
|
21
|
+
@regex_source = nil
|
|
22
|
+
@compiled = nil
|
|
17
23
|
@positive = positive
|
|
18
24
|
end
|
|
19
25
|
|
|
26
|
+
# Class-based flanking guard: +source+ must match the text
|
|
27
|
+
# ending at the position.
|
|
28
|
+
def self.regex(source, positive: true)
|
|
29
|
+
atom = new(0, "", positive: positive)
|
|
30
|
+
atom.instance_variable_set(:@regex_source, source)
|
|
31
|
+
atom
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def regex?
|
|
35
|
+
!@regex_source.nil?
|
|
36
|
+
end
|
|
37
|
+
|
|
20
38
|
def try(source, _context, _consume_all)
|
|
21
39
|
start = source.bytepos
|
|
22
|
-
|
|
23
|
-
|
|
40
|
+
if regex?
|
|
41
|
+
@compiled ||= Regexp.new("(?:#{@regex_source})\\z")
|
|
42
|
+
matched = @compiled.match?(source.input.byteslice(0, start))
|
|
43
|
+
else
|
|
44
|
+
behind =
|
|
45
|
+
if start >= @count
|
|
46
|
+
source.input.byteslice(start - @count, @count)
|
|
47
|
+
end
|
|
48
|
+
matched = !behind.nil? && behind == @pattern.b
|
|
49
|
+
end
|
|
24
50
|
[matched == @positive, nil]
|
|
25
51
|
end
|
|
26
52
|
|
|
27
53
|
def to_s_inner(_prec)
|
|
28
|
-
|
|
54
|
+
if regex?
|
|
55
|
+
"lookbehind(/#{@regex_source}/, #{@positive ? '+' : '-'})"
|
|
56
|
+
else
|
|
57
|
+
"lookbehind(#{@count}, #{@pattern.inspect}, #{@positive ? '+' : '-'})"
|
|
58
|
+
end
|
|
29
59
|
end
|
|
30
60
|
end
|
|
31
61
|
end
|
|
@@ -103,15 +103,17 @@ module Parsanol
|
|
|
103
103
|
# atoms — empty match yielding a wire constant.
|
|
104
104
|
{ "Constant" => { "value" => serialize_constant_value(atom.value) } }
|
|
105
105
|
when Parsanol::Atoms::Lookbehind
|
|
106
|
-
# rs#137
|
|
107
|
-
#
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
106
|
+
# rs#137/#163: the behind-window test — a fixed
|
|
107
|
+
# literal window or an end-anchored regex (the
|
|
108
|
+
# CommonMark flanking form).
|
|
109
|
+
look = if atom.regex?
|
|
110
|
+
{ "Regex" => { "source" => atom.regex_source } }
|
|
111
|
+
else
|
|
112
|
+
{ "Literal" => { "count" => atom.count,
|
|
113
|
+
"pattern" => atom.pattern } }
|
|
114
|
+
end
|
|
115
|
+
{ "Lookbehind" => { "look" => look,
|
|
116
|
+
"positive" => atom.positive } }
|
|
115
117
|
when Parsanol::Atoms::Ignored
|
|
116
118
|
serialize_ignored(atom)
|
|
117
119
|
else
|
|
@@ -65,8 +65,16 @@ module Parsanol
|
|
|
65
65
|
def parse(entry_name, input, mode: :native)
|
|
66
66
|
case mode
|
|
67
67
|
when :native
|
|
68
|
-
if !envelope["dynamic"]
|
|
69
|
-
|
|
68
|
+
if Native.available? && !envelope["dynamic"]
|
|
69
|
+
# Fast lane (parsanol-ruby#162): the per-instance atom
|
|
70
|
+
# tree rides the DSL serialization/registration caches
|
|
71
|
+
# (GRAMMAR_CACHE / HANDLE_CACHE keyed on the stable root
|
|
72
|
+
# atom), so an artifact parses at compiled speed after
|
|
73
|
+
# the first call. The old path re-serialized the whole
|
|
74
|
+
# grammar JSON and re-registered it per parse (~8x).
|
|
75
|
+
# Dynamic artifacts carry ruby-tier atoms their wire
|
|
76
|
+
# cannot express — they keep the interpreter.
|
|
77
|
+
return root_atom(entry_name).parse(input, mode: :native)
|
|
70
78
|
end
|
|
71
79
|
|
|
72
80
|
root_atom(entry_name).parse(input)
|
data/lib/parsanol/version.rb
CHANGED