parsanol 1.3.119-arm-linux → 1.3.121-arm-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: 81bf49f5afdc876e55e44e9be0f24f84948fe58dd34e9bb3c6fef9f08275b316
4
- data.tar.gz: d3b812c019d718b6edc6d251788938599aa4a2b2446093d89288d3b85fac880d
3
+ metadata.gz: 74b1f1a2ea59e2c2f224deb5da423ccae5a265bc9e811ce93c43c4a3b61cf920
4
+ data.tar.gz: 6378391994969e589dc1ecd9ac62eca94e695a929183f9b0b791ceb4f6f0546f
5
5
  SHA512:
6
- metadata.gz: 3b7ae9e4c9b77e03272f6e9d91fa10958104f7cb4b9618cc53ea24d1c357267502f75d8a1aeeafd874d5359437894c680de1b4b3a0acb3f0499240eb495e3b59
7
- data.tar.gz: fcec7f75e77ea07c34f0a969644bdef1748d0891a655343f0cfad296bd7a393fe511a8adb23d1d50bbde42562f58795ab0709514759d9f5e0db029f91d03e768
6
+ metadata.gz: fe55b0f7ff3f5f8748f07e73c5996ffdeb834d72b17be1b8abc8e8e673daf80791902cd05a3b0f2fbe8afe37867feef1903e25af8475af8e229e85e5b95dee6c
7
+ data.tar.gz: 56131ae02689ebadb4343462c46ec3560b9a0287fc5fa6d1835c6dd479bdc6ceca3f12bd2ed7df09c2dfdd2221d56dfdb3ad2ff2486a7d6c76033e71f1702933
@@ -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: 39544876 bytes
4
- sha256: e524b352f575dff3f01b7da7c82f2cd45393aa578eb89edf5c3fdf55b23c5ea0
3
+ size: 39740052 bytes
4
+ sha256: b70dc2b64af8f8c052309c13ef755d8a156697af55b2017eec94d1ad43eef2f2
@@ -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: 39730168 bytes
4
- sha256: 88aa66d9210cb706edb129ef923cd4fc797d031122ceb6fa6733b5cfa3239d1c
3
+ size: 39925296 bytes
4
+ sha256: 3d60d5cad8c1bf5f3ae6463c82d31f8a1027a779dc4c35be5004997d2557c862
@@ -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: 39724260 bytes
4
- sha256: 13bc130ed29c503138a1bd14812ef7a02bfb664306a49df3396900f76d48084e
3
+ size: 39919396 bytes
4
+ sha256: ccea4473a43405abe096c873c2c695ba93c271245db30d1b77f04b27df7b47a3
@@ -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: 39733932 bytes
4
- sha256: b0ae5cf41e19fdefb953e27f7d94ca656cebad8762b8ccd278528e87b807860a
3
+ size: 39929152 bytes
4
+ sha256: 4d612343474dca5ded544fa60a9fc23bbc28d7a935ccec5546db3cbd62676540
@@ -1,4 +1,4 @@
1
1
  [diffend] Oversized file quarantined before diffing.
2
2
  name: data/lib/parsanol/native/libparsanol.so
3
- size: 35866044 bytes
4
- sha256: 02e46e493ee557802cc02afb2b06d561113b91bc3850bdd8ec06ab48bb562cf5
3
+ size: 36060976 bytes
4
+ sha256: 2ee2499abdc8e1b8707658bddd5a8a861961057ff0d5276849b33ec2f1e67f31
@@ -178,13 +178,27 @@ module Parsanol
178
178
 
179
179
  def append_atom_structure(atom, visited = {}.compare_by_identity, output = +"")
180
180
  if visited[atom]
181
+ # An Entity's self-reference keeps its name in the
182
+ # fingerprint, mirroring the non-visited branch (ruby#404).
183
+ if atom.is_a?(Parsanol::Atoms::Entity)
184
+ return output << "[:entity, " << atom.rule_name.to_s.inspect << ", [:cycle, " << atom.class.name.inspect << "]]"
185
+ end
186
+
181
187
  return output << "[:cycle, " << atom.class.name.inspect << "]"
182
188
  end
183
189
 
184
190
  visited[atom] = true
185
191
  case atom
186
192
  when Parsanol::Atoms::Entity
187
- append_atom_structure(atom.parslet, visited, output)
193
+ # The rule name belongs in the fingerprint (rs#404-class
194
+ # collision): Entity is transparent in the serialized graph's
195
+ # STRUCTURE only when the target is spelled out, but the JSON
196
+ # keeps the Entity node itself — two webs whose Entities point
197
+ # at different rules share a transparent fingerprint while
198
+ # serializing differently, and the serializer cache then
199
+ # serves one grammar's JSON for the other.
200
+ output << "[:entity, " << atom.rule_name.to_s.inspect << ", "
201
+ append_atom_structure(atom.parslet, visited, output) << "]"
188
202
  when Parsanol::Atoms::Str
189
203
  output << "[:str, " << atom.str.inspect << "]"
190
204
  when Parsanol::Atoms::Re
@@ -261,6 +261,10 @@ module Parsanol
261
261
  # the declaration means the tree never sees this subtree named,
262
262
  # inside or out.
263
263
  return atom if glue_rule?(rule_name)
264
+ # A capture spans the rules it references (ruby#400): their
265
+ # bodies compile unwrapped so the capture's value equals its
266
+ # edition-1 value.
267
+ return atom if captured_reachable?(rule_name)
264
268
 
265
269
  wrap_uncaptured(atom)
266
270
  end
@@ -273,6 +277,57 @@ module Parsanol
273
277
  @document.glue_rules.include?(name.to_s)
274
278
  end
275
279
 
280
+ # The rules a text capture transitively spans (ruby#400): a
281
+ # capture on a reference captures the referenced rule's whole
282
+ # match, so every rule under a capture atom — the direct
283
+ # reference and everything its body transitively references —
284
+ # compiles unwrapped. Edition 2's Named leaves then attach only
285
+ # to non-captured structure, and a capture's value equals its
286
+ # edition-1 value (`{num: "123"}`, never a leaf array).
287
+ def captured_reachable?(name)
288
+ @capture_reachable ||= begin
289
+ seeds = []
290
+ @document.rules.each_value do |node|
291
+ collect_refs_under_captures(node, seeds)
292
+ end
293
+ reachable = []
294
+ until seeds.empty?
295
+ rule = seeds.pop
296
+ next if reachable.include?(rule) || !@document.rules.key?(rule)
297
+
298
+ reachable << rule
299
+ collect_all_refs(@document.rules[rule], seeds)
300
+ end
301
+ reachable
302
+ end
303
+ @capture_reachable.include?(name.to_s)
304
+ end
305
+
306
+ def collect_refs_under_captures(node, out)
307
+ walk = lambda do |n, in_capture|
308
+ case n.kind
309
+ when :ref then out << n.a if in_capture
310
+ when :cap then walk.call(n.b, true)
311
+ when :pred then walk.call(n.b, in_capture)
312
+ when :alt, :seq then n.a.each { |child| walk.call(child, in_capture) }
313
+ when :rep, :opt then walk.call(n.a, in_capture)
314
+ end
315
+ end
316
+ walk.call(node, false)
317
+ end
318
+
319
+ def collect_all_refs(node, out)
320
+ walk = lambda do |n|
321
+ case n.kind
322
+ when :ref then out << n.a
323
+ when :alt, :seq then n.a.each { |child| walk.call(child) }
324
+ when :cap, :pred then walk.call(n.b)
325
+ when :rep, :opt then walk.call(n.a)
326
+ end
327
+ end
328
+ walk.call(node)
329
+ end
330
+
276
331
  def wrap_uncaptured(atom)
277
332
  case atom
278
333
  when Atoms::Named
@@ -289,6 +344,7 @@ module Parsanol
289
344
  # agree by design.
290
345
  if trivia_only?(atom.rule_name.to_s, { atom.rule_name.to_s => true }) ||
291
346
  glue_rule?(atom.rule_name.to_s) ||
347
+ captured_reachable?(atom.rule_name.to_s) ||
292
348
  produces_capture?(atom.parslet)
293
349
  atom
294
350
  else
@@ -476,9 +532,12 @@ module Parsanol
476
532
  when Atoms::Named then nil
477
533
  when Atoms::Entity
478
534
  # Mirror wrap_uncaptured's verdicts: trivia glue, declared
479
- # glue, and capture-producing refs all stay bare.
535
+ # glue, capture-reachable refs (ruby#400 — a capture spans
536
+ # them, so modern mode never names them), and
537
+ # capture-producing refs all stay bare.
480
538
  unless trivia_only?(atom.rule_name.to_s, { atom.rule_name.to_s => true }) ||
481
539
  glue_rule?(atom.rule_name.to_s) ||
540
+ captured_reachable?(atom.rule_name.to_s) ||
482
541
  produces_capture?(atom.parslet)
483
542
  lines << "rule #{site}: reference to #{atom.rule_name} produces no capture -- " \
484
543
  "modern mode would name it #{atom.rule_name}"
@@ -37,8 +37,8 @@ module Parsanol
37
37
  @grammar_name = nil
38
38
  # The default capture dialect is v1 (the owner's reversal,
39
39
  # 2026-10-28): runtime compiles of unpinned sources keep the
40
- # legacy shapes — the pubid fleet froze against them. mode "v2"
41
- # stays the named-trees opt-in via the grammar header.
40
+ # legacy shapes — the pubid fleet froze against them. edition
41
+ # "v2" is the named-trees opt-in via the grammar header.
42
42
  @edition = "v1"
43
43
  @version = "0.0.0"
44
44
  @source = nil
@@ -261,12 +261,16 @@ module Parsanol
261
261
  # the author declares, per grammar, which tree semantics the
262
262
  # grammar means. THE DEFAULT IS 1 (the legacy shapes — the
263
263
  # owner's 2026-10-28 reversal). 2 = fully named trees +
264
- # explicit spans. `mode` remains accepted as a deprecated
265
- # alias for the keyword. The edition is canonicalized here —
266
- # everything downstream only ever sees "v1"/"v2".
267
- if peek&.type == :ident && %w[edition mode].include?(peek.value)
264
+ # explicit spans. The edition is canonicalized here —
265
+ # everything downstream only ever sees "v1"/"v2". The
266
+ # pre-1.3.113 `mode` alias was removed (the owner's
267
+ # 2026-10-31 ruling): the header fails with the fix named.
268
+ if peek&.type == :ident && peek.value == "edition"
268
269
  advance
269
270
  document.edition = edition_value
271
+ elsif peek&.type == :ident && peek.value == "mode"
272
+ raise ParseError,
273
+ 'the grammar header keyword is edition; mode (the pre-1.3.113 alias) was removed — write edition "v1" or edition "v2"'
270
274
  end
271
275
  punct("{")
272
276
  skip_newlines
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Parsanol
4
- VERSION = "1.3.119"
4
+ VERSION = "1.3.121"
5
5
  end
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.119
4
+ version: 1.3.121
5
5
  platform: arm-linux
6
6
  authors:
7
7
  - Ribose Inc.
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2026-10-31 00:00:00.000000000 Z
11
+ date: 2026-11-01 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