parsanol 1.3.79-aarch64-linux → 1.3.80-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/version.rb +1 -1
- data/lib/parsanol/vm.rb +52 -2
- 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: 3db21b25c629a5b9d907cf661e4bca3274008851581374dddf81f368ee1d7a03
|
|
4
|
+
data.tar.gz: 1717436f9e2cfe65ed10360126cd8324f7e4b4daa78d6225b6d1b48dd7bb9e2d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 94e3abd6b86e42bb47bec3ae815ea6e410aa932688a24d2180ab0b4df9dd93275296438bd39d90e9c559175281b16965cf157ac5b6653bd67ba577e5de03897d
|
|
7
|
+
data.tar.gz: 6eab4de294189656931273f67b7d78002796b02f0d38690e7b99294c3a24561441f335d84ba7b05823551e55c37444e313646a43c4d5c98b2859ff6b0ffff0e7
|
data/lib/parsanol/version.rb
CHANGED
data/lib/parsanol/vm.rb
CHANGED
|
@@ -125,11 +125,37 @@ module Parsanol
|
|
|
125
125
|
return nil if cached.equal?(:fallback)
|
|
126
126
|
return cached if key?(cache, root)
|
|
127
127
|
|
|
128
|
+
# Structure-hash probe (rs#166): a fresh parser instance (or a
|
|
129
|
+
# rule called on one) misses the identity key above and would
|
|
130
|
+
# silently recompile the ENTIRE grammar per call — the fresh-
|
|
131
|
+
# parser recompile trap (25x table transforms in coradoc,
|
|
132
|
+
# metanorma/coradoc#265). The structure hash — the same key
|
|
133
|
+
# the native grammar cache uses — lets equivalent grammars
|
|
134
|
+
# share the compiled program; identity stays as the fast
|
|
135
|
+
# first level.
|
|
136
|
+
hashed = (@programs_by_hash ||= {})
|
|
137
|
+
hash_key = begin
|
|
138
|
+
Parsanol::Native::Parser.public_structure_hash(root)
|
|
139
|
+
rescue NotImplementedError
|
|
140
|
+
# A grammar with an unimplemented lazy rule (entities resolve
|
|
141
|
+
# eagerly for hashing) has no stable structure yet; the
|
|
142
|
+
# identity cache above still serves it.
|
|
143
|
+
nil
|
|
144
|
+
end
|
|
145
|
+
if hash_key && (shared = hashed[hash_key]).is_a?(Array)
|
|
146
|
+
# The shared program's compile-time analysis (heavy-memo
|
|
147
|
+
# seeding) covered this structure; the fresh root inherits
|
|
148
|
+
# it so its first parse memoizes like the original's.
|
|
149
|
+
(@heavy ||= {}.compare_by_identity)[root] = true if @heavy_by_hash&.[](hash_key)
|
|
150
|
+
return shared
|
|
151
|
+
end
|
|
152
|
+
|
|
128
153
|
# A grammar the compiler cannot compile — e.g. one containing a
|
|
129
154
|
# lazily resolved Entity that a select-first literal index would
|
|
130
155
|
# never select — falls back to the interpreter, the source of
|
|
131
156
|
# truth. The interpreter resolves such entities lazily, so an
|
|
132
157
|
# unselected branch simply never raises.
|
|
158
|
+
@last_compile_prone = nil
|
|
133
159
|
program =
|
|
134
160
|
begin
|
|
135
161
|
compile(atom)
|
|
@@ -137,6 +163,19 @@ module Parsanol
|
|
|
137
163
|
:fallback
|
|
138
164
|
end
|
|
139
165
|
cache[root] = program
|
|
166
|
+
# Only real programs share. A symbol verdict (:fallback /
|
|
167
|
+
# :oversize) is a property of this particular compile
|
|
168
|
+
# attempt's path, not of the structure: serving it to a later
|
|
169
|
+
# grammar with the same structure would silently send a
|
|
170
|
+
# compile-capable grammar to the interpreter, unseeded — the
|
|
171
|
+
# order-dependent vm_fail_dispatch failure. Verdicts stay
|
|
172
|
+
# identity-local; a fresh root recompiles and re-derives
|
|
173
|
+
# both the verdict and the heavy-memo seed naturally.
|
|
174
|
+
if hash_key && program.is_a?(Array)
|
|
175
|
+
hashed[hash_key] = program
|
|
176
|
+
(@heavy_by_hash ||= {})[hash_key] = @last_compile_prone
|
|
177
|
+
trim_hashed_cache(hashed)
|
|
178
|
+
end
|
|
140
179
|
trim_cache(cache)
|
|
141
180
|
# :fallback = VM-incompatible; :oversize even non-inlined means
|
|
142
181
|
# the grammar is beyond the program cap — the interpreter
|
|
@@ -157,7 +196,9 @@ module Parsanol
|
|
|
157
196
|
|
|
158
197
|
def clear_program_cache
|
|
159
198
|
@programs&.clear
|
|
199
|
+
@programs_by_hash&.clear
|
|
160
200
|
@heavy&.clear
|
|
201
|
+
@heavy_by_hash&.clear
|
|
161
202
|
end
|
|
162
203
|
|
|
163
204
|
# FIFO eviction past the cache limit.
|
|
@@ -166,6 +207,11 @@ module Parsanol
|
|
|
166
207
|
nil
|
|
167
208
|
end
|
|
168
209
|
|
|
210
|
+
def trim_hashed_cache(hashed)
|
|
211
|
+
hashed.shift while hashed.size > PROGRAM_CACHE_LIMIT
|
|
212
|
+
nil
|
|
213
|
+
end
|
|
214
|
+
|
|
169
215
|
# Compiles the grammar rooted at +atom+. Returns the flat program
|
|
170
216
|
# Array, or nil when the grammar uses unsupported atoms.
|
|
171
217
|
def compile(atom)
|
|
@@ -205,8 +251,12 @@ module Parsanol
|
|
|
205
251
|
# rs#166: proneness rides the structure-hash share as a bool —
|
|
206
252
|
# a later identical-structure grammar inherits the seed instead
|
|
207
253
|
# of running its cold start unmemoized because compilation was
|
|
208
|
-
# skipped entirely.
|
|
209
|
-
|
|
254
|
+
# skipped entirely. Recorded on the VM singleton so the share
|
|
255
|
+
# store can read it after this compile; program_for resets it
|
|
256
|
+
# first, so a raised NotImplementedError cannot smear the
|
|
257
|
+
# previous grammar's proneness onto this one.
|
|
258
|
+
@last_compile_prone = compiler.backtracking_prone
|
|
259
|
+
if @last_compile_prone
|
|
210
260
|
(@heavy ||= {}.compare_by_identity)[root] = true
|
|
211
261
|
trim_cache(@heavy)
|
|
212
262
|
end
|