parsanol 1.3.53-aarch64-linux → 1.3.54-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 +1 -1
- 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/native/libparsanol.so +0 -0
- data/lib/parsanol/version.rb +1 -1
- data/lib/parsanol/vm.rb +37 -12
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: be8d4f6a4a67946ddbbb813adf02a30954c5416bcc90f63cf96793a054e0c254
|
|
4
|
+
data.tar.gz: 7e9bb6ef7ca17ae816aa72158f1ea3768250c5c92359f83bea8475e4e38dcce3
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 9e0bc3a1df3681709814e3365f2d953fe651a2389e6581034f5e499e0508a01b708d155803209c5df605ee88d6d83bc1451dbcccf99d2af226be1aa81d62df3c
|
|
7
|
+
data.tar.gz: a303efad410d36a94a5ad57533a33be0a65eecd3d00ee5ae76661809366bbd02833fced16a67e9749900d7ddb4da99d4a4697e24a24492f093dbd2b348c24028
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
[diffend] Oversized file quarantined before diffing.
|
|
2
2
|
name: data/lib/parsanol/3.2/parsanol_native.so
|
|
3
3
|
size: 34576408 bytes
|
|
4
|
-
sha256:
|
|
4
|
+
sha256: b656b991f63ef61537344a63ecc924cbd7bb244b3b423140c4f25c55eca71720
|
|
@@ -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: 34819576 bytes
|
|
4
|
+
sha256: 8901b2f0c271f2c433dcc5dd040e6a4733e361a8b8c12af36614d37efb6988ec
|
|
@@ -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: 34807032 bytes
|
|
4
|
+
sha256: 07fa808465df343a2ace7616fbde2a438739c386acdea32ea5d4f3b4fe38248c
|
|
@@ -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: 34817040 bytes
|
|
4
|
+
sha256: 0a32795747cbecb3822ed292a87deec5612293fe055858e1f2c3e3c6785db190
|
|
Binary file
|
data/lib/parsanol/version.rb
CHANGED
data/lib/parsanol/vm.rb
CHANGED
|
@@ -156,6 +156,21 @@ module Parsanol
|
|
|
156
156
|
compiler.ops << [HALT, nil, nil, nil]
|
|
157
157
|
return nil unless compiler.append_subroutines
|
|
158
158
|
|
|
159
|
+
# Terminal failures jump to pc = FAIL without testing the pc
|
|
160
|
+
# register on the hot path; the dispatch case instead lands on
|
|
161
|
+
# this dedicated instruction (the last slot in the flat program),
|
|
162
|
+
# whose opcode is FAIL itself.
|
|
163
|
+
compiler.ops << [FAIL, nil, nil, nil]
|
|
164
|
+
|
|
165
|
+
# Structure-seeded memoization: a grammar containing repeat/maybe
|
|
166
|
+
# starts memoized on its very first parse (fresh parser instances
|
|
167
|
+
# included — the seed is recomputed at every compile), so the
|
|
168
|
+
# cold-start never pays the doomed unmemoized exploration.
|
|
169
|
+
if compiler.backtracking_prone
|
|
170
|
+
# rubocop:disable-next Lint/HashCompareByIdentity -- object_id keys match run_for's heavy flag; would otherwise pin every grammar alive
|
|
171
|
+
(@heavy ||= {})[root.object_id] = true
|
|
172
|
+
end
|
|
173
|
+
|
|
159
174
|
compiler.to_program
|
|
160
175
|
end
|
|
161
176
|
|
|
@@ -248,9 +263,10 @@ module Parsanol
|
|
|
248
263
|
@inline = inline
|
|
249
264
|
@subs = {} # [obj_id, flag] => pc or :pending
|
|
250
265
|
@pending = {} # [obj_id, flag] => [[call_idx, body], ...]
|
|
266
|
+
@backtracking_prone = false
|
|
251
267
|
end
|
|
252
268
|
|
|
253
|
-
attr_reader :ops
|
|
269
|
+
attr_reader :ops, :backtracking_prone
|
|
254
270
|
|
|
255
271
|
def to_program
|
|
256
272
|
return :oversize if @ops.size > MAX_PROGRAM
|
|
@@ -608,6 +624,11 @@ module Parsanol
|
|
|
608
624
|
# * unbounded-plus of a single terminal (non-spine sites) -> greedy
|
|
609
625
|
# RUN_* op
|
|
610
626
|
def compile_repetition(atom, consume_all)
|
|
627
|
+
# Any repetition (repeat, maybe, repeat(0)) can re-explore the
|
|
628
|
+
# same rule+position pairs when a later sibling fails; grammars
|
|
629
|
+
# containing one memoize from the first parse instead of waiting
|
|
630
|
+
# for the naive pass to prove the need.
|
|
631
|
+
@backtracking_prone = true
|
|
611
632
|
min = atom.min
|
|
612
633
|
max = atom.max
|
|
613
634
|
return nil if max&.zero?
|
|
@@ -737,6 +758,10 @@ module Parsanol
|
|
|
737
758
|
def execute # rubocop:disable Metrics/MethodLength, Metrics/BlockLength, Metrics/BlockNesting -- single dispatch loop; hot path
|
|
738
759
|
ops = @ops
|
|
739
760
|
input = @input
|
|
761
|
+
# Dedicated FAIL landing instruction appended after HALT and the
|
|
762
|
+
# subroutines: `pc = fail_pc` dispatches straight into when-FAIL
|
|
763
|
+
# on the next cycle, no sentinel comparison per step.
|
|
764
|
+
fail_pc = ops.size - 4
|
|
740
765
|
bytes = input.unpack("C*")
|
|
741
766
|
# Regexp#match?(str, pos) searches FORWARD from pos (unanchored);
|
|
742
767
|
# StringScanner#match? is position-anchored, matching the
|
|
@@ -800,7 +825,7 @@ module Parsanol
|
|
|
800
825
|
pos += ops[pc + 3]
|
|
801
826
|
pc += 4
|
|
802
827
|
else
|
|
803
|
-
pc =
|
|
828
|
+
pc = fail_pc
|
|
804
829
|
end
|
|
805
830
|
when RE
|
|
806
831
|
b = bytes[pos]
|
|
@@ -819,7 +844,7 @@ module Parsanol
|
|
|
819
844
|
pos += w
|
|
820
845
|
pc += 4
|
|
821
846
|
else
|
|
822
|
-
pc =
|
|
847
|
+
pc = fail_pc
|
|
823
848
|
end
|
|
824
849
|
when ANY
|
|
825
850
|
if pos < n
|
|
@@ -829,7 +854,7 @@ module Parsanol
|
|
|
829
854
|
pos += w
|
|
830
855
|
pc += 4
|
|
831
856
|
else
|
|
832
|
-
pc =
|
|
857
|
+
pc = fail_pc
|
|
833
858
|
end
|
|
834
859
|
when SEQ_BEGIN
|
|
835
860
|
rstack << SEQ_MARK
|
|
@@ -878,7 +903,7 @@ module Parsanol
|
|
|
878
903
|
# PENDING — re-entry at the same rule+position (left
|
|
879
904
|
# recursion); the interpreter loops forever here, so
|
|
880
905
|
# failing this path keeps the VM bounded.
|
|
881
|
-
pc =
|
|
906
|
+
pc = fail_pc
|
|
882
907
|
next
|
|
883
908
|
end
|
|
884
909
|
# Memo hit: replay the subroutine's stack effect without
|
|
@@ -926,7 +951,7 @@ module Parsanol
|
|
|
926
951
|
rlen = bt[-BT_STRIDE + 2]
|
|
927
952
|
rstack.slice!(rlen..) if rstack.size > rlen
|
|
928
953
|
bt.pop(BT_STRIDE)
|
|
929
|
-
pc =
|
|
954
|
+
pc = fail_pc
|
|
930
955
|
when DROP
|
|
931
956
|
rstack.pop
|
|
932
957
|
rstack << nil
|
|
@@ -967,7 +992,7 @@ module Parsanol
|
|
|
967
992
|
|
|
968
993
|
if ops[pc + 2] == 1 && pos != n
|
|
969
994
|
frames.slice!(cbase..)
|
|
970
|
-
pc =
|
|
995
|
+
pc = fail_pc
|
|
971
996
|
else
|
|
972
997
|
rbase = frames[cbase + 2]
|
|
973
998
|
values = rstack.pop(rstack.size - rbase)
|
|
@@ -980,7 +1005,7 @@ module Parsanol
|
|
|
980
1005
|
table = ops[pc + 1]
|
|
981
1006
|
b = pos < n ? bytes[pos] : -1
|
|
982
1007
|
target = b == -1 ? -1 : table[b]
|
|
983
|
-
pc = target >= 0 ? target :
|
|
1008
|
+
pc = target >= 0 ? target : fail_pc
|
|
984
1009
|
when SEQ_SIMPLE
|
|
985
1010
|
kids = ops[pc + 1]
|
|
986
1011
|
kn = kids.size
|
|
@@ -1115,7 +1140,7 @@ module Parsanol
|
|
|
1115
1140
|
ki += 4
|
|
1116
1141
|
end
|
|
1117
1142
|
if failed
|
|
1118
|
-
pc =
|
|
1143
|
+
pc = fail_pc
|
|
1119
1144
|
else
|
|
1120
1145
|
rstack << values
|
|
1121
1146
|
pc += 4
|
|
@@ -1180,7 +1205,7 @@ module Parsanol
|
|
|
1180
1205
|
pos += w
|
|
1181
1206
|
end
|
|
1182
1207
|
if min && values.size - 1 < min
|
|
1183
|
-
pc =
|
|
1208
|
+
pc = fail_pc
|
|
1184
1209
|
else
|
|
1185
1210
|
rstack << values
|
|
1186
1211
|
pc += 4
|
|
@@ -1206,14 +1231,14 @@ module Parsanol
|
|
|
1206
1231
|
pos += ln
|
|
1207
1232
|
end
|
|
1208
1233
|
if min && values.size - 1 < min
|
|
1209
|
-
pc =
|
|
1234
|
+
pc = fail_pc
|
|
1210
1235
|
else
|
|
1211
1236
|
rstack << values
|
|
1212
1237
|
pc += 4
|
|
1213
1238
|
end
|
|
1214
1239
|
when HALT
|
|
1215
1240
|
if @consume_all && pos != n
|
|
1216
|
-
pc =
|
|
1241
|
+
pc = fail_pc
|
|
1217
1242
|
next
|
|
1218
1243
|
end
|
|
1219
1244
|
value = VM.materialize(rstack[0], input)
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: parsanol
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.3.
|
|
4
|
+
version: 1.3.54
|
|
5
5
|
platform: aarch64-linux
|
|
6
6
|
authors:
|
|
7
7
|
- Ribose Inc.
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-09-
|
|
11
|
+
date: 2026-09-24 00:00:00.000000000 Z
|
|
12
12
|
dependencies: []
|
|
13
13
|
description: A small Ruby library for constructing parsers in the PEG (Parsing Expression
|
|
14
14
|
Grammar) fashion. Parsanol provides Parslet-compatible API with additional features
|