parsanol 1.3.80-aarch64-linux → 1.3.81-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/native/libparsanol.so +2 -2
- data/lib/parsanol/native/parser.rb +13 -0
- data/lib/parsanol/parg/artifact.rb +19 -17
- data/lib/parsanol/parser.rb +26 -2
- data/lib/parsanol/skip.rb +70 -4
- data/lib/parsanol/version.rb +1 -1
- 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: b0c85bb6ed37d4b272d3c2232453260631a9340aba985adaf43ff8d6be9f8b3a
|
|
4
|
+
data.tar.gz: 591430101290d9e3cfcba3b3f725263864f2daa5760c1d083276d8c64fc34dce
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 02cccef1f811a8d99a9da8dc3f19d0c2fa3d5211faa25d779d2f71b26b9fb51135649708171f2fbf9398ffb815d657b2bd2b130039f97b6a155412c059698c76
|
|
7
|
+
data.tar.gz: 643d76aabbeab125985c8841ec79eb5c9481f68b11a9e27e6922b7781238f9eb0ff42a7b4f55d6bb216bc8b9766167db0ce4a63b03ddce64f06bfc5706261d38
|
|
@@ -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: 40098992 bytes
|
|
4
|
+
sha256: 7a192ca31b988dcb7ff09aae8c7f198366ec949ba6d643c6345f7697b733f4f2
|
|
@@ -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: 40334088 bytes
|
|
4
|
+
sha256: a59a1e8331a9da417e8dbaefdefa59632c43094cf0c34c63a71fec3cf4bad616
|
|
@@ -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: 40329752 bytes
|
|
4
|
+
sha256: bb046626dcb81c3ee91852c1bc42c8aa98f931abf6594e9d023331515d300562
|
|
@@ -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: 40339776 bytes
|
|
4
|
+
sha256: 43352d26128f698a3e233303d8bb8844784c12a369f9ca577a476818a1c8b5cd
|
|
@@ -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: 35898616 bytes
|
|
4
|
+
sha256: f604a8ab076f360350c20ba56652a6033209d14f91b7810142c3cbcd04bb7021
|
|
@@ -205,6 +205,19 @@ module Parsanol
|
|
|
205
205
|
[:constant, atom.value.inspect]
|
|
206
206
|
when ::Parsanol::Atoms::Lookbehind
|
|
207
207
|
[:lookbehind, atom.count, atom.pattern, atom.positive]
|
|
208
|
+
# Subclass first: TriviaCapture < Trivia < Ignored (the same
|
|
209
|
+
# dispatch discipline as the serializer's).
|
|
210
|
+
when ::Parsanol::Atoms::TriviaCapture
|
|
211
|
+
# The capturer table differentiates capture-carrying
|
|
212
|
+
# grammars from plain-trivia ones — without it the grammar
|
|
213
|
+
# cache serves one variant's wire to every other and the
|
|
214
|
+
# wrong marker table reaches the engine (parsanol-ruby#180).
|
|
215
|
+
[:trivia_capture, atom.capturers.to_a.sort,
|
|
216
|
+
atom_structure(atom.wrapped_atom, visited)]
|
|
217
|
+
when ::Parsanol::Atoms::Trivia
|
|
218
|
+
[:trivia, atom_structure(atom.wrapped_atom, visited)]
|
|
219
|
+
when ::Parsanol::Atoms::Ignored
|
|
220
|
+
[:ignored, atom_structure(atom.wrapped_atom, visited)]
|
|
208
221
|
else
|
|
209
222
|
[:unknown, atom.class.name]
|
|
210
223
|
end
|
|
@@ -65,24 +65,26 @@ module Parsanol
|
|
|
65
65
|
def parse(entry_name, input, mode: :native)
|
|
66
66
|
case mode
|
|
67
67
|
when :native
|
|
68
|
-
if Native.available?
|
|
69
|
-
# Fast lane (parsanol-ruby#162):
|
|
70
|
-
#
|
|
68
|
+
if Native.available?
|
|
69
|
+
# Fast lane (parsanol-ruby#162): Native.parse with the
|
|
70
|
+
# per-instance root atom registers the grammar once
|
|
71
71
|
# (GRAMMAR_CACHE / HANDLE_CACHE keyed on the stable root
|
|
72
|
-
# atom)
|
|
73
|
-
#
|
|
74
|
-
#
|
|
75
|
-
#
|
|
76
|
-
#
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
72
|
+
# atom) and every parse after the first runs the native
|
|
73
|
+
# engine by handle — the same path a DSL parser's
|
|
74
|
+
# mode: :native takes. Atoms::Base#parse must NOT carry
|
|
75
|
+
# this lane: it ignores :mode, so it would silently run
|
|
76
|
+
# the pure-Ruby VM and its interpreter fallback (the
|
|
77
|
+
# 5-7x real-document gap in #162, and the root-position
|
|
78
|
+
# diagnostics in #171 before the wire fallback).
|
|
79
|
+
#
|
|
80
|
+
# Dynamic-flagged artifacts parse natively too (rs#204):
|
|
81
|
+
# the state atoms (StateSet/StateMatch/StateSwitch)
|
|
82
|
+
# evaluate in the engine, riding the capture store's
|
|
83
|
+
# rollback discipline. Reaching a CustomRef aborts the
|
|
84
|
+
# native pass outright — Native.parse's error path then
|
|
85
|
+
# re-runs the interpreter, so customs stay Ruby-tier with
|
|
86
|
+
# identical trees.
|
|
87
|
+
return Native.parse(root_atom(entry_name), input)
|
|
86
88
|
end
|
|
87
89
|
|
|
88
90
|
root_atom(entry_name).parse(input)
|
data/lib/parsanol/parser.rb
CHANGED
|
@@ -52,7 +52,12 @@ module Parsanol
|
|
|
52
52
|
define_method(:root) do
|
|
53
53
|
atom = __send__(rule_name)
|
|
54
54
|
skip_name = self.class.skip_rule_name
|
|
55
|
-
|
|
55
|
+
if skip_name
|
|
56
|
+
Parsanol::Skip.inject(self, atom, skip_name,
|
|
57
|
+
captures: self.class.skip_captures)[0]
|
|
58
|
+
else
|
|
59
|
+
atom
|
|
60
|
+
end
|
|
56
61
|
end
|
|
57
62
|
end
|
|
58
63
|
|
|
@@ -63,6 +68,13 @@ module Parsanol
|
|
|
63
68
|
# everything it references) builds without injection; it must be
|
|
64
69
|
# non-nullable. Order-independent with +root+.
|
|
65
70
|
#
|
|
71
|
+
# +capture:+ (parsanol-ruby#180) declares trivia capturers — a
|
|
72
|
+
# map of rule name to kind label. Units of the skip rule
|
|
73
|
+
# matching a capturer's leading literal attach to the next
|
|
74
|
+
# Named capture under +comments:+ (the PARG
|
|
75
|
+
# `skip = trivia capture: comments` shape) instead of being
|
|
76
|
+
# discarded; whitespace-shaped units never record.
|
|
77
|
+
#
|
|
66
78
|
# @example
|
|
67
79
|
# class MyParser < Parsanol::Parser
|
|
68
80
|
# rule(:spaces) { match(/[ \t]/).repeat(1) }
|
|
@@ -72,8 +84,14 @@ module Parsanol
|
|
|
72
84
|
# root :doc
|
|
73
85
|
# end
|
|
74
86
|
#
|
|
75
|
-
|
|
87
|
+
# @example capturing comments
|
|
88
|
+
# rule(:trivia) { spaces | line_comment }
|
|
89
|
+
# rule(:line_comment) { str("//") >> match(/[^\n]/).repeat }
|
|
90
|
+
# skip :trivia, capture: { line_comment: :line_comment }
|
|
91
|
+
#
|
|
92
|
+
def skip(rule_name, capture: nil)
|
|
76
93
|
@skip_rule_name = rule_name
|
|
94
|
+
@skip_captures = capture
|
|
77
95
|
nil
|
|
78
96
|
end
|
|
79
97
|
|
|
@@ -82,6 +100,12 @@ module Parsanol
|
|
|
82
100
|
def skip_rule_name
|
|
83
101
|
@skip_rule_name
|
|
84
102
|
end
|
|
103
|
+
|
|
104
|
+
# The declared capturer map ({rule => kind label}), or nil —
|
|
105
|
+
# see {.skip}.
|
|
106
|
+
def skip_captures
|
|
107
|
+
@skip_captures
|
|
108
|
+
end
|
|
85
109
|
end
|
|
86
110
|
|
|
87
111
|
# Delegates matching to the root rule.
|
data/lib/parsanol/skip.rb
CHANGED
|
@@ -13,7 +13,14 @@ module Parsanol
|
|
|
13
13
|
# methods. Returns [injected_root, skip_atom] with the wrapper
|
|
14
14
|
# built and the lint applied, or raises GrammarError for a
|
|
15
15
|
# nullable skip.
|
|
16
|
-
|
|
16
|
+
#
|
|
17
|
+
# +captures+ (parsanol-ruby#180) maps capturer rule names to kind
|
|
18
|
+
# labels (`skip :trivia, capture: { line_comment: :line }`); the
|
|
19
|
+
# injected wrapper becomes a TriviaCapture whose units matching a
|
|
20
|
+
# capturer's leading literal attach to the next Named capture
|
|
21
|
+
# under `comments:` — the PARG `skip = trivia capture: comments`
|
|
22
|
+
# shape. Whitespace-shaped units never record.
|
|
23
|
+
def self.inject(parser_instance, root_atom, skip_rule_name, captures: nil)
|
|
17
24
|
skip_atom = parser_instance.__send__(skip_rule_name)
|
|
18
25
|
skip_atom = skip_atom.parslet while skip_atom.is_a?(Atoms::Entity)
|
|
19
26
|
|
|
@@ -23,10 +30,62 @@ module Parsanol
|
|
|
23
30
|
"empty loops forever at injection points"
|
|
24
31
|
end
|
|
25
32
|
|
|
26
|
-
|
|
33
|
+
markers = capturer_markers(parser_instance, captures)
|
|
34
|
+
injector = Injector.new(skip_atom, markers)
|
|
27
35
|
[injector.inject(root_atom, entry: true), skip_atom]
|
|
28
36
|
end
|
|
29
37
|
|
|
38
|
+
# Derives each capturer's leading literal (the leftmost Str the
|
|
39
|
+
# rule can start with) and keys the marker table by it — the same
|
|
40
|
+
# derivation the PARG compiler applies to its skip declaration. A
|
|
41
|
+
# declared capturer without a derivable, non-blank literal is a
|
|
42
|
+
# declaration error: its units could never be told apart from
|
|
43
|
+
# whitespace-shaped trivia and it would silently record nothing.
|
|
44
|
+
def self.capturer_markers(parser_instance, captures)
|
|
45
|
+
return nil if captures.nil? || captures.empty?
|
|
46
|
+
|
|
47
|
+
captures.each_with_object({}) do |(rule_name, kind), markers|
|
|
48
|
+
atom = parser_instance.__send__(rule_name)
|
|
49
|
+
atom = atom.parslet while atom.is_a?(Atoms::Entity)
|
|
50
|
+
literal = leading_literal(atom)
|
|
51
|
+
if literal.nil? || literal.strip.empty?
|
|
52
|
+
raise GrammarError,
|
|
53
|
+
"skip capturer #{rule_name.inspect} has no leading " \
|
|
54
|
+
"literal: its units cannot be told apart from " \
|
|
55
|
+
"whitespace-shaped trivia"
|
|
56
|
+
end
|
|
57
|
+
markers[literal] = kind || rule_name
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# The leftmost literal the atom can start with, or nil when the
|
|
62
|
+
# shape is not literal-led (alternatives with disagreeing
|
|
63
|
+
# branches, regexes, lookaheads).
|
|
64
|
+
def self.leading_literal(atom)
|
|
65
|
+
case atom
|
|
66
|
+
when Atoms::Str then atom.str
|
|
67
|
+
when Atoms::Sequence
|
|
68
|
+
atom.parslets.each do |child|
|
|
69
|
+
literal = leading_literal(child)
|
|
70
|
+
return literal if literal
|
|
71
|
+
end
|
|
72
|
+
nil
|
|
73
|
+
when Atoms::Alternative
|
|
74
|
+
first = nil
|
|
75
|
+
atom.alternatives.each do |branch|
|
|
76
|
+
literal = leading_literal(branch)
|
|
77
|
+
return nil if literal.nil? || (first && literal != first)
|
|
78
|
+
|
|
79
|
+
first ||= literal
|
|
80
|
+
end
|
|
81
|
+
first
|
|
82
|
+
when Atoms::Repetition
|
|
83
|
+
atom.min&.positive? ? leading_literal(atom.parslet) : nil
|
|
84
|
+
when Atoms::Named, Atoms::Capture, Atoms::Ignored, Atoms::Trivia
|
|
85
|
+
leading_literal(atom.parslet)
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
30
89
|
# The injection walk. Mirrors the PARG compiler's semantics:
|
|
31
90
|
# sequences interleave the wrapper before every child, alternatives
|
|
32
91
|
# and repetitions descend, named captures descend (spans stay
|
|
@@ -34,8 +93,9 @@ module Parsanol
|
|
|
34
93
|
# transparency), bare terminals gain a leading wrapper, and the
|
|
35
94
|
# entry root takes leading and trailing wrappers.
|
|
36
95
|
class Injector
|
|
37
|
-
def initialize(skip_atom)
|
|
96
|
+
def initialize(skip_atom, markers = nil)
|
|
38
97
|
@skip_atom = skip_atom
|
|
98
|
+
@markers = markers
|
|
39
99
|
@wrapper_ids = {}.compare_by_identity
|
|
40
100
|
end
|
|
41
101
|
|
|
@@ -50,7 +110,13 @@ module Parsanol
|
|
|
50
110
|
|
|
51
111
|
def maybe
|
|
52
112
|
@maybe ||= begin
|
|
53
|
-
|
|
113
|
+
inner = Atoms::Repetition.new(@skip_atom, 0, 1)
|
|
114
|
+
wrapper =
|
|
115
|
+
if @markers
|
|
116
|
+
Atoms::TriviaCapture.new(inner, @markers)
|
|
117
|
+
else
|
|
118
|
+
Atoms::Trivia.new(inner)
|
|
119
|
+
end
|
|
54
120
|
@wrapper_ids[wrapper] = true
|
|
55
121
|
wrapper
|
|
56
122
|
end
|
data/lib/parsanol/version.rb
CHANGED
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.81
|
|
5
5
|
platform: aarch64-linux
|
|
6
6
|
authors:
|
|
7
7
|
- Ribose Inc.
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-10-
|
|
11
|
+
date: 2026-10-08 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
|