parsanol 1.3.127-aarch64-linux → 1.3.128-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 +2 -2
- 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/atoms/base.rb +15 -0
- data/lib/parsanol/native/libparsanol.so +2 -2
- data/lib/parsanol/parg/artifact.rb +12 -15
- data/lib/parsanol/parg/cli.rb +0 -5
- data/lib/parsanol/parg/compiler.rb +7 -54
- data/lib/parsanol/parg/diff.rb +5 -2
- data/lib/parsanol/parg/document.rb +3 -5
- data/lib/parsanol/parg/frontend.rb +7 -6
- data/lib/parsanol/parg/lsp.rb +4 -2
- data/lib/parsanol/parg/parser.rb +11 -14
- 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: '02418bfb9f910e8356cb4687038d4b10fb06aa4361c3c70931fc40fb009acf04'
|
|
4
|
+
data.tar.gz: e2d7436638cc3bc2b59723926f6bb0f058c7a9639a920557e877e581c7eb4858
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: eadd8f3cbe44778cf540608271a6fe42478ab974c0501b86316808d42b9b75dd6cfc2c38ebdbcf13b3add7372c94b12ae714a1c729d227983eaaf0e2632a1328
|
|
7
|
+
data.tar.gz: 483b9b6d55db586b5e9945f121abb7bad8d59b2764b6c25e9ad663dacd9a00f342c41306fc9cd6ce909350022645fa93b03436cdfad33182834833fb129306ea
|
|
@@ -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:
|
|
4
|
-
sha256:
|
|
3
|
+
size: 46909480 bytes
|
|
4
|
+
sha256: b5917afaec0bf088952709bbc9d466d9523d43d2f69e61fbb93ae7cf34b7a8d4
|
|
@@ -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: 47140352 bytes
|
|
4
|
+
sha256: 82f28bcb6c308d92666a8db53df981bda6989a5f5d69a3eb74dc6cfb53a0edd9
|
|
@@ -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: 47136024 bytes
|
|
4
|
+
sha256: 6b3c06517eb782506624ab7f9126df5bbc144943bafc64ade94e5b5be46e8dbf
|
|
@@ -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: 47146000 bytes
|
|
4
|
+
sha256: bc1b98e9825576ef8b9519ced50fd0bce2c0f3a41d0c37d36a2fdc6485117f57
|
data/lib/parsanol/atoms/base.rb
CHANGED
|
@@ -253,6 +253,14 @@ module Parsanol
|
|
|
253
253
|
# consumer's file:line:col degrades to "line 1 char 1" when the
|
|
254
254
|
# interpreter raises the outermost sequence instead. Explicit
|
|
255
255
|
# reporters (Tree for full cause trees) are honored unchanged.
|
|
256
|
+
#
|
|
257
|
+
# A CUSTOM reporter's #err/#err_at return value is
|
|
258
|
+
# "implementation-specific" (ErrorReporter::Base) — it observes
|
|
259
|
+
# the failure events but is not obliged to hand back a Cause. The
|
|
260
|
+
# raise-able cause is then derived by re-parsing with the #265
|
|
261
|
+
# default, so the raised ParseFailed still carries the
|
|
262
|
+
# deepest-failure diagnostics (the interpreter tier crashed with
|
|
263
|
+
# NoMethodError on the reporter's raw return value before).
|
|
256
264
|
def report_detailed_error(input, consume_all, reporter, _initial_error, compatibility: :strict)
|
|
257
265
|
input.bytepos = 0
|
|
258
266
|
error_reporter = reporter ||
|
|
@@ -263,6 +271,13 @@ module Parsanol
|
|
|
263
271
|
# Second parse should also fail
|
|
264
272
|
raise "Invariant violation: parse succeeded during error reporting" if success
|
|
265
273
|
|
|
274
|
+
unless cause.is_a?(Parsanol::Cause)
|
|
275
|
+
input.bytepos = 0
|
|
276
|
+
success, cause = run_with_context(input, Parsanol::ErrorReporter::Deepest.new,
|
|
277
|
+
consume_all, **context_options)
|
|
278
|
+
raise "Invariant violation: parse succeeded during error reporting" if success
|
|
279
|
+
end
|
|
280
|
+
|
|
266
281
|
cause.raise
|
|
267
282
|
end
|
|
268
283
|
end
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
[diffend] Oversized file quarantined before diffing.
|
|
2
2
|
name: data/lib/parsanol/native/libparsanol.so
|
|
3
|
-
size:
|
|
4
|
-
sha256:
|
|
3
|
+
size: 42614960 bytes
|
|
4
|
+
sha256: 585cf127dcd5f801311d35755fc7a4373e1b7f24734ee69383c804751141b4f2
|
|
@@ -26,15 +26,14 @@ module Parsanol
|
|
|
26
26
|
|
|
27
27
|
SUPPORTED_SHAPE = "parsanol-tree/v2"
|
|
28
28
|
|
|
29
|
-
#
|
|
30
|
-
# 1
|
|
31
|
-
SUPPORTED_EDITIONS = [
|
|
29
|
+
# Edition 2 (named trees + explicit spans) is the only edition —
|
|
30
|
+
# edition-1 artifacts are rejected with the fix named.
|
|
31
|
+
SUPPORTED_EDITIONS = [2].freeze
|
|
32
32
|
|
|
33
33
|
# The header and envelope spellings that have shipped: the quoted
|
|
34
|
-
# v-
|
|
34
|
+
# v-form stays loadable so artifacts baked before the numeric
|
|
35
35
|
# surface remain readable.
|
|
36
36
|
EDITION_ALIASES = {
|
|
37
|
-
1 => 1, "1" => 1, "v1" => 1, "classic" => 1,
|
|
38
37
|
2 => 2, "2" => 2, "v2" => 2
|
|
39
38
|
}.freeze
|
|
40
39
|
|
|
@@ -50,14 +49,13 @@ module Parsanol
|
|
|
50
49
|
bindings = envelope["bindings"]
|
|
51
50
|
validate_bindings!(bindings) unless bindings.nil?
|
|
52
51
|
@envelope = envelope
|
|
53
|
-
# The declared edition must be one this runtime understands
|
|
54
|
-
#
|
|
55
|
-
|
|
56
|
-
edition = EDITION_ALIASES[envelope.fetch("edition", 1)]
|
|
52
|
+
# The declared edition must be one this runtime understands.
|
|
53
|
+
# Absent field = a pre-1.3.109 edition-1 artifact — rejected.
|
|
54
|
+
edition = EDITION_ALIASES[envelope.fetch("edition", 2)]
|
|
57
55
|
unless SUPPORTED_EDITIONS.include?(edition)
|
|
58
56
|
raise ArtifactError,
|
|
59
|
-
"artifact declares edition #{envelope['edition'].inspect};
|
|
60
|
-
"
|
|
57
|
+
"artifact declares edition #{envelope['edition'].inspect}; edition 1 " \
|
|
58
|
+
"was removed — recompile the grammar with edition \"v2\""
|
|
61
59
|
end
|
|
62
60
|
@path = path
|
|
63
61
|
@tables_dir = tables_dir
|
|
@@ -71,11 +69,10 @@ module Parsanol
|
|
|
71
69
|
|
|
72
70
|
def version = envelope["version"]
|
|
73
71
|
|
|
74
|
-
# The edition the artifact's trees carry
|
|
75
|
-
#
|
|
76
|
-
# "v2" (or omit it) normalize here.
|
|
72
|
+
# The edition the artifact's trees carry (always 2). Legacy
|
|
73
|
+
# artifacts that spell the field "v2" normalize here.
|
|
77
74
|
def edition
|
|
78
|
-
EDITION_ALIASES.fetch(envelope.fetch("edition",
|
|
75
|
+
EDITION_ALIASES.fetch(envelope.fetch("edition", 2))
|
|
79
76
|
end
|
|
80
77
|
|
|
81
78
|
# Freshness (parsanol-ruby#209): what source revision and compiler
|
data/lib/parsanol/parg/cli.rb
CHANGED
|
@@ -116,7 +116,6 @@ module Parsanol
|
|
|
116
116
|
# upgrade suggestions on top.
|
|
117
117
|
def lint
|
|
118
118
|
source = @argv.shift
|
|
119
|
-
@captures_radar = @argv.delete("--captures") ? true : false
|
|
120
119
|
tables = @tables_dir || default_tables_dir(source)
|
|
121
120
|
document = Parsanol::PARG::Parser.new(PARG.read_utf8(source)).parse
|
|
122
121
|
Parsanol::PARG::Imports.merge!(document, [File.dirname(source)])
|
|
@@ -132,10 +131,6 @@ module Parsanol
|
|
|
132
131
|
Lints::CoreRuleDuplicates.new.warnings(document, compiler)
|
|
133
132
|
.each { |upgrade| puts "upgrade: #{upgrade}" }
|
|
134
133
|
end
|
|
135
|
-
if @captures_radar
|
|
136
|
-
# The migration radar (ruby#304): what modern mode would name.
|
|
137
|
-
compiler.modern_radar.each { |line| puts "captures: #{line}" }
|
|
138
|
-
end
|
|
139
134
|
0
|
|
140
135
|
rescue Parsanol::PARG::ParseError, Parsanol::PARG::Error => e
|
|
141
136
|
warn "#{e.class}: #{e.message}"
|
|
@@ -252,18 +252,17 @@ module Parsanol
|
|
|
252
252
|
|
|
253
253
|
# Modern mode (ruby#304, the #315 spec): every rule reference
|
|
254
254
|
# that produces no capture is wrapped in Named(rule_name) at
|
|
255
|
-
# compile time — the tree shape consumers read
|
|
256
|
-
#
|
|
257
|
-
# Named atoms; identity rides the differential corpus.
|
|
255
|
+
# compile time — the tree shape consumers read. Edition 2 is the
|
|
256
|
+
# only edition, so the wrap is unconditional. Engines see
|
|
257
|
+
# ordinary Named atoms; identity rides the differential corpus.
|
|
258
258
|
def apply_modern_captures(atom, rule_name)
|
|
259
|
-
return atom if @document.edition == "v1"
|
|
260
259
|
# A glue rule's own body compiles unwrapped (parsanol-ruby#364):
|
|
261
260
|
# the declaration means the tree never sees this subtree named,
|
|
262
261
|
# inside or out.
|
|
263
262
|
return atom if glue_rule?(rule_name)
|
|
264
263
|
# A capture spans the rules it references (ruby#400): their
|
|
265
264
|
# bodies compile unwrapped so the capture's value equals its
|
|
266
|
-
#
|
|
265
|
+
# span-joined value.
|
|
267
266
|
return atom if captured_reachable?(rule_name)
|
|
268
267
|
|
|
269
268
|
wrap_uncaptured(atom)
|
|
@@ -505,52 +504,6 @@ module Parsanol
|
|
|
505
504
|
end
|
|
506
505
|
end
|
|
507
506
|
|
|
508
|
-
# The migration radar (ruby#304 `parg lint --captures`): for a
|
|
509
|
-
# LEGACY grammar, every rule reference modern mode would wrap —
|
|
510
|
-
# reference site, target rule. The compiler's state is warm
|
|
511
|
-
# (all rules built) when the lint calls this.
|
|
512
|
-
def modern_radar
|
|
513
|
-
# The radar is the classic dialect's migration tool: on a v2
|
|
514
|
-
# grammar every reference is already named.
|
|
515
|
-
return [] if @document.edition != "v1"
|
|
516
|
-
|
|
517
|
-
lines = []
|
|
518
|
-
@document.rules.each_key do |name|
|
|
519
|
-
atom = @atom_cache[name]
|
|
520
|
-
next unless atom
|
|
521
|
-
|
|
522
|
-
radar_walk(atom, name, lines, [])
|
|
523
|
-
end
|
|
524
|
-
lines
|
|
525
|
-
end
|
|
526
|
-
|
|
527
|
-
def radar_walk(atom, site, lines, seen)
|
|
528
|
-
return if seen.include?(atom.object_id)
|
|
529
|
-
|
|
530
|
-
seen << atom.object_id
|
|
531
|
-
case atom
|
|
532
|
-
when Atoms::Named then nil
|
|
533
|
-
when Atoms::Entity
|
|
534
|
-
# Mirror wrap_uncaptured's verdicts: trivia glue, declared
|
|
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.
|
|
538
|
-
unless trivia_only?(atom.rule_name.to_s, { atom.rule_name.to_s => true }) ||
|
|
539
|
-
glue_rule?(atom.rule_name.to_s) ||
|
|
540
|
-
captured_reachable?(atom.rule_name.to_s) ||
|
|
541
|
-
produces_capture?(atom.parslet)
|
|
542
|
-
lines << "rule #{site}: reference to #{atom.rule_name} produces no capture -- " \
|
|
543
|
-
"modern mode would name it #{atom.rule_name}"
|
|
544
|
-
end
|
|
545
|
-
radar_walk(atom.parslet, site, lines, seen)
|
|
546
|
-
when Atoms::Sequence, Atoms::Alternative
|
|
547
|
-
kids = atom.respond_to?(:alternatives) ? atom.alternatives : atom.parslets
|
|
548
|
-
kids.each { |child| radar_walk(child, site, lines, seen) }
|
|
549
|
-
when Atoms::Repetition
|
|
550
|
-
radar_walk(atom.parslet, site, lines, seen)
|
|
551
|
-
end
|
|
552
|
-
end
|
|
553
|
-
|
|
554
507
|
def atom_for(name)
|
|
555
508
|
inject_core_rules!
|
|
556
509
|
expand_left_recursion! unless @expanded
|
|
@@ -1424,9 +1377,9 @@ module Parsanol
|
|
|
1424
1377
|
}
|
|
1425
1378
|
# ruby#304: the envelope always names the capture edition —
|
|
1426
1379
|
# consumers read the tree-shape contract before parsing. The
|
|
1427
|
-
# numeric form is canonical:
|
|
1428
|
-
#
|
|
1429
|
-
envelope["edition"] =
|
|
1380
|
+
# numeric form is canonical: 2 = fully named trees + explicit
|
|
1381
|
+
# spans, the only edition.
|
|
1382
|
+
envelope["edition"] = 2
|
|
1430
1383
|
if @document.skip_declaration
|
|
1431
1384
|
# parsanol-ruby#134: declared trivia rule. Injection is baked
|
|
1432
1385
|
# into the compiled trees (plain atom kinds), so consumers
|
data/lib/parsanol/parg/diff.rb
CHANGED
|
@@ -181,9 +181,12 @@ module Parsanol
|
|
|
181
181
|
end
|
|
182
182
|
|
|
183
183
|
# Artifacts baked before the numeric surface spell the edition
|
|
184
|
-
#
|
|
184
|
+
# Edition 2 is the only edition; envelopes that omit the field or
|
|
185
|
+
# spell it "v2" normalize to 2. Removed spellings (1/"v1"/"classic")
|
|
186
|
+
# pass through, so a legacy envelope still diffs as an edition
|
|
187
|
+
# change.
|
|
185
188
|
def edition_level(envelope)
|
|
186
|
-
declared = envelope.fetch("edition",
|
|
189
|
+
declared = envelope.fetch("edition", 2)
|
|
187
190
|
Artifact::EDITION_ALIASES.fetch(declared, declared)
|
|
188
191
|
end
|
|
189
192
|
|
|
@@ -35,11 +35,9 @@ module Parsanol
|
|
|
35
35
|
|
|
36
36
|
def initialize
|
|
37
37
|
@grammar_name = nil
|
|
38
|
-
#
|
|
39
|
-
#
|
|
40
|
-
|
|
41
|
-
# "v2" is the named-trees opt-in via the grammar header.
|
|
42
|
-
@edition = "v1"
|
|
38
|
+
# Edition 2 (named trees + explicit spans) is the only edition —
|
|
39
|
+
# edition 1 was removed. Header declaration stays optional.
|
|
40
|
+
@edition = "v2"
|
|
43
41
|
@version = "0.0.0"
|
|
44
42
|
@source = nil
|
|
45
43
|
@rules = {}
|
|
@@ -123,12 +123,13 @@ module Parsanol
|
|
|
123
123
|
document.grammar_name = Regexp.last_match(1)
|
|
124
124
|
document.version = Regexp.last_match(2)
|
|
125
125
|
tail = stripped.match(EDITION_TAIL)
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
126
|
+
level = tail.nil? ? "2" : (tail[:number] || tail[:quoted] || tail[:mode])
|
|
127
|
+
unless ["2", "v2"].include?(level)
|
|
128
|
+
raise ParseError,
|
|
129
|
+
"edition #{level.inspect} is not supported -- edition 1 was " \
|
|
130
|
+
"removed; write edition \"v2\" (named trees + spans)"
|
|
131
|
+
end
|
|
132
|
+
document.edition = "v2"
|
|
132
133
|
doc_comments = []
|
|
133
134
|
when NAMED_SECTION
|
|
134
135
|
state[:section] = Regexp.last_match(1)
|
data/lib/parsanol/parg/lsp.rb
CHANGED
|
@@ -524,8 +524,10 @@ module Parsanol
|
|
|
524
524
|
if SelfHost.available?
|
|
525
525
|
begin
|
|
526
526
|
SelfHost.validate(source)
|
|
527
|
-
rescue Parsanol::ParseFailed
|
|
528
|
-
#
|
|
527
|
+
rescue Parsanol::ParseFailed, ArtifactError
|
|
528
|
+
# a stale artifact (e.g. a sibling baked at a removed
|
|
529
|
+
# edition) must not break diagnostics — fall through to
|
|
530
|
+
# line 0
|
|
529
531
|
end
|
|
530
532
|
end
|
|
531
533
|
diagnostics << diagnostic(line, e.message)
|
data/lib/parsanol/parg/parser.rb
CHANGED
|
@@ -18,11 +18,11 @@ module Parsanol
|
|
|
18
18
|
|
|
19
19
|
IN_BLOCK_SECTIONS = %w[entry bindings preprocess test].freeze
|
|
20
20
|
|
|
21
|
-
# The header's edition spellings: the bare
|
|
22
|
-
# (Rust's Cargo.toml model); the quoted
|
|
23
|
-
#
|
|
21
|
+
# The header's edition spellings: the bare number is canonical
|
|
22
|
+
# (Rust's Cargo.toml model); the quoted form stays accepted as an
|
|
23
|
+
# alias. Edition 1 was removed — grammars declaring it fail with
|
|
24
|
+
# the fix named.
|
|
24
25
|
EDITIONS = {
|
|
25
|
-
"1" => "v1", "v1" => "v1", "classic" => "v1",
|
|
26
26
|
"2" => "v2", "v2" => "v2"
|
|
27
27
|
}.freeze
|
|
28
28
|
|
|
@@ -242,13 +242,12 @@ module Parsanol
|
|
|
242
242
|
when :str then unquote(token.value)
|
|
243
243
|
else
|
|
244
244
|
raise ParseError,
|
|
245
|
-
"edition must be
|
|
246
|
-
"(\"v1\", \"v2\", \"classic\")"
|
|
245
|
+
"edition must be the number 2 or the quoted alias \"v2\""
|
|
247
246
|
end
|
|
248
247
|
EDITIONS.fetch(raw) do
|
|
249
248
|
raise ParseError,
|
|
250
|
-
"
|
|
251
|
-
"
|
|
249
|
+
"edition #{raw.inspect} is not supported -- edition 1 was " \
|
|
250
|
+
"removed; write edition \"v2\" (named trees + spans)"
|
|
252
251
|
end
|
|
253
252
|
end
|
|
254
253
|
|
|
@@ -258,11 +257,9 @@ module Parsanol
|
|
|
258
257
|
document.version = unquote(expect(:str).value)
|
|
259
258
|
# `edition` — the language edition (ruby#304, ruby#357's
|
|
260
259
|
# consolidation; Rust's Cargo.toml `edition` is the model):
|
|
261
|
-
#
|
|
262
|
-
#
|
|
263
|
-
#
|
|
264
|
-
# explicit spans. The edition is canonicalized here —
|
|
265
|
-
# everything downstream only ever sees "v1"/"v2". The
|
|
260
|
+
# edition 2 = fully named trees + explicit spans, and the ONLY
|
|
261
|
+
# edition (edition 1 was removed). The edition is canonicalized
|
|
262
|
+
# here — everything downstream only ever sees "v2". The
|
|
266
263
|
# pre-1.3.113 `mode` alias was removed (the owner's
|
|
267
264
|
# 2026-10-31 ruling): the header fails with the fix named.
|
|
268
265
|
if peek&.type == :ident && peek.value == "edition"
|
|
@@ -270,7 +267,7 @@ module Parsanol
|
|
|
270
267
|
document.edition = edition_value
|
|
271
268
|
elsif peek&.type == :ident && peek.value == "mode"
|
|
272
269
|
raise ParseError,
|
|
273
|
-
'the grammar header keyword is edition; mode (the pre-1.3.113 alias) was removed — write edition "
|
|
270
|
+
'the grammar header keyword is edition; mode (the pre-1.3.113 alias) was removed — write edition "v2"'
|
|
274
271
|
end
|
|
275
272
|
punct("{")
|
|
276
273
|
skip_newlines
|
data/lib/parsanol/version.rb
CHANGED