onigmo 0.1.0
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 +7 -0
- data/.github/workflows/main.yml +31 -0
- data/.gitignore +10 -0
- data/Gemfile +9 -0
- data/Gemfile.lock +29 -0
- data/LICENSE +7 -0
- data/README.md +101 -0
- data/Rakefile +45 -0
- data/bin/console +10 -0
- data/ext/onigmo/extconf.rb +7 -0
- data/ext/onigmo/onigmo.c +985 -0
- data/ext/onigmo/regenc.h +256 -0
- data/ext/onigmo/regint.h +945 -0
- data/ext/onigmo/regparse.h +370 -0
- data/lib/onigmo/deconstruct_visitor.rb +121 -0
- data/lib/onigmo/json_visitor.rb +123 -0
- data/lib/onigmo/node.rb +266 -0
- data/lib/onigmo/pretty_print_visitor.rb +284 -0
- data/lib/onigmo/visitor.rb +339 -0
- data/lib/onigmo.rb +11 -0
- data/onigmo.gemspec +16 -0
- metadata +64 -0
data/lib/onigmo/node.rb
ADDED
@@ -0,0 +1,266 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Onigmo
|
4
|
+
# The base class for all nodes in the tree.
|
5
|
+
class Node
|
6
|
+
def accept(visitor)
|
7
|
+
raise NoMethodError, __method__
|
8
|
+
end
|
9
|
+
|
10
|
+
def deconstruct_keys(keys)
|
11
|
+
accept(DeconstructVisitor.new)
|
12
|
+
end
|
13
|
+
|
14
|
+
def pretty_print(q)
|
15
|
+
accept(PrettyPrintVisitor.new(q))
|
16
|
+
q.flush
|
17
|
+
end
|
18
|
+
|
19
|
+
def as_json
|
20
|
+
accept(JSONVisitor.new)
|
21
|
+
end
|
22
|
+
|
23
|
+
def to_json(*opts)
|
24
|
+
as_json.to_json(*opts)
|
25
|
+
end
|
26
|
+
|
27
|
+
private_class_method :new
|
28
|
+
end
|
29
|
+
|
30
|
+
# foo|bar
|
31
|
+
# ^^^^^^^
|
32
|
+
class AlternationNode < Node
|
33
|
+
attr_reader :nodes
|
34
|
+
|
35
|
+
def initialize(nodes)
|
36
|
+
@nodes = nodes
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
# \A
|
41
|
+
# ^^
|
42
|
+
class AnchorBufferBeginNode < Node
|
43
|
+
end
|
44
|
+
|
45
|
+
# \z
|
46
|
+
# ^^
|
47
|
+
class AnchorBufferEndNode < Node
|
48
|
+
end
|
49
|
+
|
50
|
+
# \K
|
51
|
+
# ^^
|
52
|
+
class AnchorKeepNode < Node
|
53
|
+
end
|
54
|
+
|
55
|
+
# ^
|
56
|
+
# ^
|
57
|
+
class AnchorLineBeginNode < Node
|
58
|
+
end
|
59
|
+
|
60
|
+
# $
|
61
|
+
# ^
|
62
|
+
class AnchorLineEndNode < Node
|
63
|
+
end
|
64
|
+
|
65
|
+
# \G
|
66
|
+
# ^^
|
67
|
+
class AnchorPositionBeginNode < Node
|
68
|
+
end
|
69
|
+
|
70
|
+
# \Z
|
71
|
+
# ^^
|
72
|
+
class AnchorSemiEndNode < Node
|
73
|
+
end
|
74
|
+
|
75
|
+
# \b
|
76
|
+
# ^^
|
77
|
+
class AnchorWordBoundaryNode < Node
|
78
|
+
end
|
79
|
+
|
80
|
+
# \B
|
81
|
+
# ^^
|
82
|
+
class AnchorWordBoundaryInvertNode < Node
|
83
|
+
end
|
84
|
+
|
85
|
+
# .
|
86
|
+
# ^
|
87
|
+
class AnyNode < Node
|
88
|
+
end
|
89
|
+
|
90
|
+
# \k<name>
|
91
|
+
# ^^^^^^^^
|
92
|
+
class BackrefNode < Node
|
93
|
+
attr_reader :values
|
94
|
+
|
95
|
+
def initialize(values)
|
96
|
+
@values = values
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
# \g<name>
|
101
|
+
# ^^^^^^^^
|
102
|
+
class CallNode < Node
|
103
|
+
attr_reader :number, :name
|
104
|
+
|
105
|
+
def initialize(number, name)
|
106
|
+
@number = number
|
107
|
+
@name = name
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
# [a-z]
|
112
|
+
# ^^^^^
|
113
|
+
class CClassNode < Node
|
114
|
+
attr_reader :values
|
115
|
+
|
116
|
+
def initialize(values)
|
117
|
+
@values = values
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
# [^a-z]
|
122
|
+
# ^^^^^^
|
123
|
+
class CClassInvertNode < Node
|
124
|
+
attr_reader :values
|
125
|
+
|
126
|
+
def initialize(values)
|
127
|
+
@values = values
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
# (?~subexp)
|
132
|
+
# ^^^^^^^^^^
|
133
|
+
class EncloseAbsentNode < Node
|
134
|
+
attr_reader :node
|
135
|
+
|
136
|
+
def initialize(node)
|
137
|
+
@node = node
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
# (?(cond)subexp)
|
142
|
+
# ^^^^^^^^^^^^^^^
|
143
|
+
class EncloseConditionNode < Node
|
144
|
+
attr_reader :number, :node
|
145
|
+
|
146
|
+
def initialize(number, node)
|
147
|
+
@number = number
|
148
|
+
@node = node
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
# ()
|
153
|
+
# ^^
|
154
|
+
class EncloseMemoryNode < Node
|
155
|
+
attr_reader :number, :node
|
156
|
+
|
157
|
+
def initialize(number, node)
|
158
|
+
@number = number
|
159
|
+
@node = node
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
# (?options:subexp)
|
164
|
+
# ^^^^^^^^^^^^^^^^^
|
165
|
+
class EncloseOptionsNode < Node
|
166
|
+
attr_reader :options, :node
|
167
|
+
|
168
|
+
def initialize(options, node)
|
169
|
+
@options = options
|
170
|
+
@node = node
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
# (?>subexp)
|
175
|
+
# ^^^^^^^^^^
|
176
|
+
class EncloseStopBacktrackNode < Node
|
177
|
+
attr_reader :node
|
178
|
+
|
179
|
+
def initialize(node)
|
180
|
+
@node = node
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
# a.b
|
185
|
+
# ^^^
|
186
|
+
class ListNode < Node
|
187
|
+
attr_reader :nodes
|
188
|
+
|
189
|
+
def initialize(nodes)
|
190
|
+
@nodes = nodes
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
# (?=subexp)
|
195
|
+
# ^^^^^^^^^^
|
196
|
+
class LookAheadNode < Node
|
197
|
+
attr_reader :node
|
198
|
+
|
199
|
+
def initialize(node)
|
200
|
+
@node = node
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
# (?!subexp)
|
205
|
+
# ^^^^^^^^^^
|
206
|
+
class LookAheadInvertNode < Node
|
207
|
+
attr_reader :node
|
208
|
+
|
209
|
+
def initialize(node)
|
210
|
+
@node = node
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
# (?<=subexp)
|
215
|
+
# ^^^^^^^^^^
|
216
|
+
class LookBehindNode < Node
|
217
|
+
attr_reader :node
|
218
|
+
|
219
|
+
def initialize(node)
|
220
|
+
@node = node
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
# (?<!subexp)
|
225
|
+
# ^^^^^^^^^^^
|
226
|
+
class LookBehindInvertNode < Node
|
227
|
+
attr_reader :node
|
228
|
+
|
229
|
+
def initialize(node)
|
230
|
+
@node = node
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
234
|
+
# a{1,2}
|
235
|
+
# ^^^^^
|
236
|
+
class QuantifierNode < Node
|
237
|
+
attr_reader :lower, :upper, :greedy, :node
|
238
|
+
|
239
|
+
def initialize(lower, upper, greedy, node)
|
240
|
+
@lower = lower
|
241
|
+
@upper = upper
|
242
|
+
@greedy = greedy
|
243
|
+
@node = node
|
244
|
+
end
|
245
|
+
end
|
246
|
+
|
247
|
+
# abc
|
248
|
+
# ^^^
|
249
|
+
class StringNode < Node
|
250
|
+
attr_reader :value
|
251
|
+
|
252
|
+
def initialize(value)
|
253
|
+
@value = value
|
254
|
+
end
|
255
|
+
end
|
256
|
+
|
257
|
+
# \w
|
258
|
+
# ^^
|
259
|
+
class WordNode < Node
|
260
|
+
end
|
261
|
+
|
262
|
+
# \W
|
263
|
+
# ^^
|
264
|
+
class WordInvertNode < Node
|
265
|
+
end
|
266
|
+
end
|
@@ -0,0 +1,284 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "pp"
|
4
|
+
|
5
|
+
module Onigmo
|
6
|
+
class PrettyPrintVisitor < Visitor
|
7
|
+
attr_reader :q
|
8
|
+
|
9
|
+
def initialize(q)
|
10
|
+
@q = q
|
11
|
+
end
|
12
|
+
|
13
|
+
def visit_alternation_node(node)
|
14
|
+
q.group do
|
15
|
+
q.text("alternation(")
|
16
|
+
q.nest(2) do
|
17
|
+
q.breakable("")
|
18
|
+
q.seplist(node.nodes) do |child_node|
|
19
|
+
visit(child_node)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
q.breakable("")
|
23
|
+
q.text(")")
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def visit_anchor_buffer_begin_node(node)
|
28
|
+
q.text("anchorBufferBegin()")
|
29
|
+
end
|
30
|
+
|
31
|
+
def visit_anchor_buffer_end_node(node)
|
32
|
+
q.text("anchorBufferEnd()")
|
33
|
+
end
|
34
|
+
|
35
|
+
def visit_anchor_keep_node(node)
|
36
|
+
q.text("anchorKeep()")
|
37
|
+
end
|
38
|
+
|
39
|
+
def visit_anchor_line_begin_node(node)
|
40
|
+
q.text("anchorLineBegin()")
|
41
|
+
end
|
42
|
+
|
43
|
+
def visit_anchor_line_end_node(node)
|
44
|
+
q.text("anchorLineEnd()")
|
45
|
+
end
|
46
|
+
|
47
|
+
def visit_anchor_position_begin_node(node)
|
48
|
+
q.text("anchorPositionBegin()")
|
49
|
+
end
|
50
|
+
|
51
|
+
def visit_anchor_semi_end_node(node)
|
52
|
+
q.text("anchorSemiEnd()")
|
53
|
+
end
|
54
|
+
|
55
|
+
def visit_anchor_word_boundary_node(node)
|
56
|
+
q.text("anchorWordBoundary()")
|
57
|
+
end
|
58
|
+
|
59
|
+
def visit_anchor_word_boundary_invert_node(node)
|
60
|
+
q.text("anchorWordBoundaryInvert()")
|
61
|
+
end
|
62
|
+
|
63
|
+
def visit_any_node(node)
|
64
|
+
q.text("any")
|
65
|
+
end
|
66
|
+
|
67
|
+
def visit_backref_node(node)
|
68
|
+
q.group do
|
69
|
+
q.text("backref(")
|
70
|
+
q.nest(2) do
|
71
|
+
q.breakable("")
|
72
|
+
q.seplist(node.values) do |value|
|
73
|
+
q.pp(value)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
q.breakable("")
|
77
|
+
q.text(")")
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def visit_call_node(node)
|
82
|
+
q.group do
|
83
|
+
q.text("call(")
|
84
|
+
q.nest(2) do
|
85
|
+
q.breakable("")
|
86
|
+
q.seplist([node.number, node.name]) do |value|
|
87
|
+
q.pp(value)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
q.breakable("")
|
91
|
+
q.text(")")
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def visit_cclass_node(node)
|
96
|
+
q.group do
|
97
|
+
q.text("cclass(")
|
98
|
+
q.nest(2) do
|
99
|
+
q.breakable("")
|
100
|
+
q.pp(node.values)
|
101
|
+
end
|
102
|
+
q.breakable("")
|
103
|
+
q.text(")")
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def visit_cclass_invert_node(node)
|
108
|
+
q.group do
|
109
|
+
q.text("cclassInvert(")
|
110
|
+
q.nest(2) do
|
111
|
+
q.breakable("")
|
112
|
+
q.pp(node.values)
|
113
|
+
end
|
114
|
+
q.breakable("")
|
115
|
+
q.text(")")
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
def visit_enclose_absent_node(node)
|
120
|
+
q.group do
|
121
|
+
q.text("encloseAbsent(")
|
122
|
+
q.nest(2) do
|
123
|
+
q.breakable("")
|
124
|
+
visit(node.node)
|
125
|
+
end
|
126
|
+
q.breakable("")
|
127
|
+
q.text(")")
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
def visit_enclose_condition_node(node)
|
132
|
+
q.group do
|
133
|
+
q.text("encloseCondition(")
|
134
|
+
q.nest(2) do
|
135
|
+
q.breakable("")
|
136
|
+
q.pp(node.number)
|
137
|
+
q.comma_breakable
|
138
|
+
visit(node.node)
|
139
|
+
end
|
140
|
+
q.breakable("")
|
141
|
+
q.text(")")
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
def visit_enclose_memory_node(node)
|
146
|
+
q.group do
|
147
|
+
q.text("encloseMemory(")
|
148
|
+
q.nest(2) do
|
149
|
+
q.breakable("")
|
150
|
+
q.pp(node.number)
|
151
|
+
q.comma_breakable
|
152
|
+
visit(node.node)
|
153
|
+
end
|
154
|
+
q.breakable("")
|
155
|
+
q.text(")")
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
def visit_enclose_options_node(node)
|
160
|
+
q.group do
|
161
|
+
q.text("encloseOptions(")
|
162
|
+
q.nest(2) do
|
163
|
+
q.breakable("")
|
164
|
+
q.pp(node.options)
|
165
|
+
q.comma_breakable
|
166
|
+
visit(node.node)
|
167
|
+
end
|
168
|
+
q.breakable("")
|
169
|
+
q.text(")")
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
def visit_enclose_stop_backtrack_node(node)
|
174
|
+
q.group do
|
175
|
+
q.text("encloseStopBacktrack(")
|
176
|
+
q.nest(2) do
|
177
|
+
q.breakable("")
|
178
|
+
visit(node.node)
|
179
|
+
end
|
180
|
+
q.breakable("")
|
181
|
+
q.text(")")
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
def visit_list_node(node)
|
186
|
+
q.group do
|
187
|
+
q.text("list(")
|
188
|
+
q.nest(2) do
|
189
|
+
q.breakable("")
|
190
|
+
q.seplist(node.nodes) do |child_node|
|
191
|
+
visit(child_node)
|
192
|
+
end
|
193
|
+
end
|
194
|
+
q.breakable("")
|
195
|
+
q.text(")")
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
def visit_look_ahead_node(node)
|
200
|
+
q.group do
|
201
|
+
q.text("lookAhead(")
|
202
|
+
q.nest(2) do
|
203
|
+
q.breakable("")
|
204
|
+
visit(node.node)
|
205
|
+
end
|
206
|
+
q.breakable("")
|
207
|
+
q.text(")")
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
def visit_look_ahead_invert_node(node)
|
212
|
+
q.group do
|
213
|
+
q.text("lookAheadInvert(")
|
214
|
+
q.nest(2) do
|
215
|
+
q.breakable("")
|
216
|
+
visit(node.node)
|
217
|
+
end
|
218
|
+
q.breakable("")
|
219
|
+
q.text(")")
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
def visit_look_behind_node(node)
|
224
|
+
q.group do
|
225
|
+
q.text("lookBehind(")
|
226
|
+
q.nest(2) do
|
227
|
+
q.breakable("")
|
228
|
+
visit(node.node)
|
229
|
+
end
|
230
|
+
q.breakable("")
|
231
|
+
q.text(")")
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
235
|
+
def visit_look_behind_invert_node(node)
|
236
|
+
q.group do
|
237
|
+
q.text("lookBehindInvert(")
|
238
|
+
q.nest(2) do
|
239
|
+
q.breakable("")
|
240
|
+
visit(node.node)
|
241
|
+
end
|
242
|
+
q.breakable("")
|
243
|
+
q.text(")")
|
244
|
+
end
|
245
|
+
end
|
246
|
+
|
247
|
+
def visit_quantifier_node(node)
|
248
|
+
q.group do
|
249
|
+
q.text("quantifier(")
|
250
|
+
q.nest(2) do
|
251
|
+
q.breakable("")
|
252
|
+
q.seplist({ lower: node.lower, upper: node.upper, greedy: node.greedy }) do |key, value|
|
253
|
+
q.text("#{key}: ")
|
254
|
+
q.pp(value)
|
255
|
+
end
|
256
|
+
q.comma_breakable
|
257
|
+
visit(node.node)
|
258
|
+
end
|
259
|
+
q.breakable("")
|
260
|
+
q.text(")")
|
261
|
+
end
|
262
|
+
end
|
263
|
+
|
264
|
+
def visit_string_node(node)
|
265
|
+
q.group do
|
266
|
+
q.text("string(")
|
267
|
+
q.nest(2) do
|
268
|
+
q.breakable("")
|
269
|
+
q.pp(node.value)
|
270
|
+
end
|
271
|
+
q.breakable("")
|
272
|
+
q.text(")")
|
273
|
+
end
|
274
|
+
end
|
275
|
+
|
276
|
+
def visit_word_node(node)
|
277
|
+
q.text("word()")
|
278
|
+
end
|
279
|
+
|
280
|
+
def visit_word_invert_node(node)
|
281
|
+
q.text("wordInvert()")
|
282
|
+
end
|
283
|
+
end
|
284
|
+
end
|