parsanol 1.3.89-x86_64-linux → 1.3.91-x86_64-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/parg/compiler.rb +17 -1
- data/lib/parsanol/parser.rb +7 -0
- data/lib/parsanol/skip.rb +36 -1
- 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: cc4463b1c2ebdd777a82123af6dbff3971d709251d0e2e4049f3bb83a2d3924e
|
|
4
|
+
data.tar.gz: 660ce6c9b29bbf29a3cb94f3214f53c0a20ce0b60441b1ad633c098cfe030ca5
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e005bb72656514d52014a62827b08a56fb6c491f5edd61af2beb08c1f66bcae2736aa5319cb2fba4c81c116010b468979524af519fd200dd8f2672834f5f3818
|
|
7
|
+
data.tar.gz: 78d2a2f9390e3352ae4333fc856b561d4e64e5d09b0ee04c1c3d46114313f714347f0dfe85eab1eead857a06960fa677133c2130d690712352f5a943ba43c70b
|
|
@@ -421,7 +421,23 @@ module Parsanol
|
|
|
421
421
|
Atoms::Alternative.new(*node.a.map { |child| build_atom(child) })
|
|
422
422
|
when :rep
|
|
423
423
|
Atoms::Repetition.new(build_atom(node.a), node.b, node.c)
|
|
424
|
-
when :opt
|
|
424
|
+
when :opt
|
|
425
|
+
# [ … ] is the OPTIONAL form; a bracket whose elements are all
|
|
426
|
+
# character classes reads as an optional SEQUENCE of single
|
|
427
|
+
# characters (matchable empty — captures come back nil), which
|
|
428
|
+
# is almost certainly a mis-typed multi-range class
|
|
429
|
+
# (parsanol-ruby#201). One class alone stays a legitimate
|
|
430
|
+
# optional ([ %x0D ] — CRLF handling).
|
|
431
|
+
if (content = node.a).kind == :seq && content.a.length > 1 &&
|
|
432
|
+
content.a.all? { |el| el.kind == :class }
|
|
433
|
+
raise CompileError,
|
|
434
|
+
"brackets contain a sequence of character classes: " \
|
|
435
|
+
"[ … ] is the optional form, so each class matches one " \
|
|
436
|
+
"character and the sequence can match empty (an as-capture " \
|
|
437
|
+
"over it yields nil). A multi-range character class is an " \
|
|
438
|
+
"alternation: (%x21-2f / %x3a-40 / …)"
|
|
439
|
+
end
|
|
440
|
+
Atoms::Repetition.new(build_atom(node.a), 0, 1, :maybe)
|
|
425
441
|
when :pred
|
|
426
442
|
if node.c == :behind
|
|
427
443
|
build_lookbehind(node)
|
data/lib/parsanol/parser.rb
CHANGED
|
@@ -77,6 +77,13 @@ module Parsanol
|
|
|
77
77
|
# `skip = trivia capture: comments` shape) instead of being
|
|
78
78
|
# discarded; whitespace-shaped units never record.
|
|
79
79
|
#
|
|
80
|
+
# +exempt:+ (parsanol-ruby#195) lists rule names whose bodies
|
|
81
|
+
# build WITHOUT injection — the DSL mirror of the PARG
|
|
82
|
+
# compiler's automatic skip-rule-closure exemption. Declare it
|
|
83
|
+
# for rules that manage their own trivia explicitly (expressir's
|
|
84
|
+
# remark rules): a wrapper inside them consumes text the rule
|
|
85
|
+
# itself captures, corrupting the value and double-recording it.
|
|
86
|
+
#
|
|
80
87
|
# @example
|
|
81
88
|
# class MyParser < Parsanol::Parser
|
|
82
89
|
# rule(:spaces) { match(/[ \t]/).repeat(1) }
|
data/lib/parsanol/skip.rb
CHANGED
|
@@ -41,11 +41,46 @@ module Parsanol
|
|
|
41
41
|
|
|
42
42
|
markers = capturer_markers(parser_instance, captures)
|
|
43
43
|
whitespace_kind = whitespace&.to_sym
|
|
44
|
-
exempt_names = exempt.nil? ?
|
|
44
|
+
exempt_names = Set.new(exempt.nil? ? [] : exempt.map(&:to_s))
|
|
45
|
+
exempt_names.merge(closure_names(skip_atom))
|
|
45
46
|
injector = Injector.new(skip_atom, markers, whitespace_kind, exempt_names)
|
|
46
47
|
[injector.inject(root_atom, entry: true), skip_atom]
|
|
47
48
|
end
|
|
48
49
|
|
|
50
|
+
# The skip rule's transitive rule-reference closure (parsanol-ruby#195
|
|
51
|
+
# follow-up): those rule bodies build without injection — the same
|
|
52
|
+
# exemption the PARG compiler applies to its skip declaration's
|
|
53
|
+
# closure. The docstring promised this; the code exempted only the
|
|
54
|
+
# skip atom itself. Rules the grammar manages explicitly stay
|
|
55
|
+
# declarable through +exempt:+ (their names merge with these).
|
|
56
|
+
def self.closure_names(skip_atom)
|
|
57
|
+
names = Set.new
|
|
58
|
+
seen = {}.compare_by_identity
|
|
59
|
+
queue = [skip_atom]
|
|
60
|
+
until queue.empty?
|
|
61
|
+
node = queue.shift
|
|
62
|
+
next if node.nil? || seen.key?(node)
|
|
63
|
+
|
|
64
|
+
seen[node] = true
|
|
65
|
+
case node
|
|
66
|
+
when Atoms::Entity
|
|
67
|
+
names << node.rule_name.to_s
|
|
68
|
+
begin
|
|
69
|
+
queue << node.parslet
|
|
70
|
+
rescue StandardError
|
|
71
|
+
nil
|
|
72
|
+
end
|
|
73
|
+
else
|
|
74
|
+
queue.concat(node.parslets) if node.respond_to?(:parslets)
|
|
75
|
+
queue.concat(node.alternatives) if node.respond_to?(:alternatives)
|
|
76
|
+
queue << node.parslet if node.respond_to?(:parslet)
|
|
77
|
+
queue << node.bound_parslet if node.respond_to?(:bound_parslet)
|
|
78
|
+
queue << node.wrapped_atom if node.respond_to?(:wrapped_atom)
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
names
|
|
82
|
+
end
|
|
83
|
+
|
|
49
84
|
# Derives each capturer's leading literal (the leftmost Str the
|
|
50
85
|
# rule can start with) and keys the marker table by it — the same
|
|
51
86
|
# derivation the PARG compiler applies to its skip declaration. A
|
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.91
|
|
5
5
|
platform: x86_64-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-11 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
|