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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4e9d6f048282d103bf86ad942a6a4ab886cdd63e24256fda93f318bf3b49a6af
4
- data.tar.gz: 4fcce5f528a27ab4463064887177e5bbe81f71d75ed2a4740824cdc3ab93224a
3
+ metadata.gz: 3db21b25c629a5b9d907cf661e4bca3274008851581374dddf81f368ee1d7a03
4
+ data.tar.gz: 1717436f9e2cfe65ed10360126cd8324f7e4b4daa78d6225b6d1b48dd7bb9e2d
5
5
  SHA512:
6
- metadata.gz: 85f8051f8ad4c6b7065f3fb88ed2ed482a56517860f59c0938086b2da5859d136b2352149288c1f1a469ef5976f0279999b4e5073e31d67ba0e5f828988ea3d0
7
- data.tar.gz: b24dab2ec2f2146e79bab3cfc56e5d31dadf04980f2c29c9cfa7d9051009e69f699b81c587898e0c5723c63ff444c17c31b518ca427136da2e539aafd54311ac
6
+ metadata.gz: 94e3abd6b86e42bb47bec3ae815ea6e410aa932688a24d2180ab0b4df9dd93275296438bd39d90e9c559175281b16965cf157ac5b6653bd67ba577e5de03897d
7
+ data.tar.gz: 6eab4de294189656931273f67b7d78002796b02f0d38690e7b99294c3a24561441f335d84ba7b05823551e55c37444e313646a43c4d5c98b2859ff6b0ffff0e7
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Parsanol
4
- VERSION = "1.3.79"
4
+ VERSION = "1.3.80"
5
5
  end
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
- if compiler.backtracking_prone
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
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: parsanol
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.79
4
+ version: 1.3.80
5
5
  platform: aarch64-linux
6
6
  authors:
7
7
  - Ribose Inc.