node_query 1.0.0 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +21 -0
- data/Gemfile.lock +9 -7
- data/README.md +437 -3
- data/lib/node_query/adapter.rb +6 -0
- data/lib/node_query/compiler/attribute.rb +1 -1
- data/lib/node_query/compiler/basic_selector.rb +1 -1
- data/lib/node_query/compiler/comparable.rb +26 -11
- data/lib/node_query/compiler/expression.rb +4 -10
- data/lib/node_query/compiler/expression_list.rb +11 -3
- data/lib/node_query/compiler/identifier.rb +2 -2
- data/lib/node_query/compiler/regexp.rb +7 -10
- data/lib/node_query/compiler/selector.rb +13 -4
- data/lib/node_query/compiler/string.rb +19 -0
- data/lib/node_query/compiler.rb +0 -1
- data/lib/node_query/helper.rb +47 -24
- data/lib/node_query/node_rules.rb +174 -0
- data/lib/node_query/parser_adapter.rb +6 -2
- data/lib/node_query/version.rb +1 -1
- data/lib/node_query.rb +37 -10
- data/lib/node_query_lexer.rex +2 -5
- data/lib/node_query_lexer.rex.rb +287 -0
- data/lib/node_query_parser.racc.rb +302 -0
- data/lib/node_query_parser.y +3 -4
- data/node_query.gemspec +3 -3
- data/sig/node_query/adapter.rbs +11 -0
- data/sig/node_query.rbs +6 -4
- metadata +11 -8
- data/lib/node_query/compiler/evaluated_value.rb +0 -50
@@ -0,0 +1,287 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# encoding: UTF-8
|
3
|
+
#--
|
4
|
+
# This file is automatically generated. Do not modify it.
|
5
|
+
# Generated by: oedipus_lex version 2.6.0.
|
6
|
+
# Source: lib/node_query_lexer.rex
|
7
|
+
#++
|
8
|
+
|
9
|
+
|
10
|
+
##
|
11
|
+
# The generated lexer NodeQueryLexer
|
12
|
+
|
13
|
+
class NodeQueryLexer
|
14
|
+
require 'strscan'
|
15
|
+
|
16
|
+
# :stopdoc:
|
17
|
+
OPEN_ATTRIBUTE = /\[/
|
18
|
+
CLOSE_ATTRIBUTE = /\]/
|
19
|
+
OPEN_ARRAY = /\(/
|
20
|
+
CLOSE_ARRAY = /\)/
|
21
|
+
OPEN_SELECTOR = /\(/
|
22
|
+
CLOSE_SELECTOR = /\)/
|
23
|
+
NODE_TYPE = /\.[a-z]+/
|
24
|
+
IDENTIFIER = /[@\*\.\w]*\w/
|
25
|
+
IDENTIFIER_VALUE = /[@\.\w!&:\?<>=]+/
|
26
|
+
FALSE = /false/
|
27
|
+
FLOAT = /\d+\.\d+/
|
28
|
+
INTEGER = /\d+/
|
29
|
+
NIL = /nil/
|
30
|
+
REGEXP_BODY = /(?:[^\/]|\\\/)*/
|
31
|
+
REGEXP = /\/(#{REGEXP_BODY})(?<!\\)\/([imxo]*)/
|
32
|
+
SYMBOL = /:[\w!\?<>=]+/
|
33
|
+
TRUE = /true/
|
34
|
+
SINGLE_QUOTE_STRING = /'.*?'/
|
35
|
+
DOUBLE_QUOTE_STRING = /".*?"/
|
36
|
+
# :startdoc:
|
37
|
+
# :stopdoc:
|
38
|
+
class LexerError < StandardError ; end
|
39
|
+
class ScanError < LexerError ; end
|
40
|
+
# :startdoc:
|
41
|
+
|
42
|
+
##
|
43
|
+
# The file name / path
|
44
|
+
|
45
|
+
attr_accessor :filename
|
46
|
+
|
47
|
+
##
|
48
|
+
# The StringScanner for this lexer.
|
49
|
+
|
50
|
+
attr_accessor :ss
|
51
|
+
|
52
|
+
##
|
53
|
+
# The current lexical state.
|
54
|
+
|
55
|
+
attr_accessor :state
|
56
|
+
|
57
|
+
alias :match :ss
|
58
|
+
|
59
|
+
##
|
60
|
+
# The match groups for the current scan.
|
61
|
+
|
62
|
+
def matches
|
63
|
+
m = (1..9).map { |i| ss[i] }
|
64
|
+
m.pop until m[-1] or m.empty?
|
65
|
+
m
|
66
|
+
end
|
67
|
+
|
68
|
+
##
|
69
|
+
# Yields on the current action.
|
70
|
+
|
71
|
+
def action
|
72
|
+
yield
|
73
|
+
end
|
74
|
+
|
75
|
+
|
76
|
+
##
|
77
|
+
# The current scanner class. Must be overridden in subclasses.
|
78
|
+
|
79
|
+
def scanner_class
|
80
|
+
StringScanner
|
81
|
+
end unless instance_methods(false).map(&:to_s).include?("scanner_class")
|
82
|
+
|
83
|
+
##
|
84
|
+
# Parse the given string.
|
85
|
+
|
86
|
+
def parse str
|
87
|
+
self.ss = scanner_class.new str
|
88
|
+
self.state ||= nil
|
89
|
+
|
90
|
+
do_parse
|
91
|
+
end
|
92
|
+
|
93
|
+
##
|
94
|
+
# Read in and parse the file at +path+.
|
95
|
+
|
96
|
+
def parse_file path
|
97
|
+
self.filename = path
|
98
|
+
open path do |f|
|
99
|
+
parse f.read
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
##
|
104
|
+
# The current location in the parse.
|
105
|
+
|
106
|
+
def location
|
107
|
+
[
|
108
|
+
(filename || "<input>"),
|
109
|
+
].compact.join(":")
|
110
|
+
end
|
111
|
+
|
112
|
+
##
|
113
|
+
# Lex the next token.
|
114
|
+
|
115
|
+
def next_token
|
116
|
+
|
117
|
+
token = nil
|
118
|
+
|
119
|
+
until ss.eos? or token do
|
120
|
+
token =
|
121
|
+
case state
|
122
|
+
when nil then
|
123
|
+
case
|
124
|
+
when ss.skip(/\s+/) then
|
125
|
+
# do nothing
|
126
|
+
when text = ss.scan(/,/) then
|
127
|
+
action { [:tCOMMA, text] }
|
128
|
+
when text = ss.scan(/:has/) then
|
129
|
+
action { [:tPSEUDO_CLASS, text[1..-1]] }
|
130
|
+
when text = ss.scan(/:not_has/) then
|
131
|
+
action { [:tPSEUDO_CLASS, text[1..-1]] }
|
132
|
+
when text = ss.scan(/#{NODE_TYPE}/) then
|
133
|
+
action { [:tNODE_TYPE, text[1..]] }
|
134
|
+
when text = ss.scan(/#{IDENTIFIER}/) then
|
135
|
+
action { [:tGOTO_SCOPE, text] }
|
136
|
+
when text = ss.scan(/>/) then
|
137
|
+
action { [:tRELATIONSHIP, text] }
|
138
|
+
when text = ss.scan(/~/) then
|
139
|
+
action { [:tRELATIONSHIP, text] }
|
140
|
+
when text = ss.scan(/\+/) then
|
141
|
+
action { [:tRELATIONSHIP, text] }
|
142
|
+
when text = ss.scan(/#{OPEN_SELECTOR}/) then
|
143
|
+
action { [:tOPEN_SELECTOR, text] }
|
144
|
+
when text = ss.scan(/#{CLOSE_SELECTOR}/) then
|
145
|
+
action { [:tCLOSE_SELECTOR, text] }
|
146
|
+
when text = ss.scan(/#{OPEN_ATTRIBUTE}/) then
|
147
|
+
action { @nested_count += 1; @state = :KEY; [:tOPEN_ATTRIBUTE, text] }
|
148
|
+
else
|
149
|
+
text = ss.string[ss.pos .. -1]
|
150
|
+
raise ScanError, "can not match (#{state.inspect}) at #{location}: '#{text}'"
|
151
|
+
end
|
152
|
+
when :KEY then
|
153
|
+
case
|
154
|
+
when ss.skip(/\s+/) then
|
155
|
+
# do nothing
|
156
|
+
when ss.skip(/\^=/) then
|
157
|
+
action { @state = :VALUE; [:tOPERATOR, '^='] }
|
158
|
+
when ss.skip(/\$=/) then
|
159
|
+
action { @state = :VALUE; [:tOPERATOR, '$='] }
|
160
|
+
when ss.skip(/\*=/) then
|
161
|
+
action { @state = :VALUE; [:tOPERATOR, '*='] }
|
162
|
+
when ss.skip(/!=/) then
|
163
|
+
action { @state = :VALUE; [:tOPERATOR, '!='] }
|
164
|
+
when ss.skip(/=~/) then
|
165
|
+
action { @state = :VALUE; [:tOPERATOR, '=~'] }
|
166
|
+
when ss.skip(/!~/) then
|
167
|
+
action { @state = :VALUE; [:tOPERATOR, '!~'] }
|
168
|
+
when ss.skip(/>=/) then
|
169
|
+
action { @state = :VALUE; [:tOPERATOR, '>='] }
|
170
|
+
when ss.skip(/<=/) then
|
171
|
+
action { @state = :VALUE; [:tOPERATOR, '<='] }
|
172
|
+
when ss.skip(/>/) then
|
173
|
+
action { @state = :VALUE; [:tOPERATOR, '>'] }
|
174
|
+
when ss.skip(/</) then
|
175
|
+
action { @state = :VALUE; [:tOPERATOR, '<'] }
|
176
|
+
when ss.skip(/=/) then
|
177
|
+
action { @state = :VALUE; [:tOPERATOR, '=='] }
|
178
|
+
when ss.skip(/includes/i) then
|
179
|
+
action { @state = :VALUE; [:tOPERATOR, 'includes'] }
|
180
|
+
when ss.skip(/not in/i) then
|
181
|
+
action { @state = :VALUE; [:tOPERATOR, 'not_in'] }
|
182
|
+
when ss.skip(/in/i) then
|
183
|
+
action { @state = :VALUE; [:tOPERATOR, 'in'] }
|
184
|
+
when text = ss.scan(/#{IDENTIFIER}/) then
|
185
|
+
action { [:tKEY, text] }
|
186
|
+
else
|
187
|
+
text = ss.string[ss.pos .. -1]
|
188
|
+
raise ScanError, "can not match (#{state.inspect}) at #{location}: '#{text}'"
|
189
|
+
end
|
190
|
+
when :VALUE then
|
191
|
+
case
|
192
|
+
when ss.skip(/\s+/) then
|
193
|
+
# do nothing
|
194
|
+
when text = ss.scan(/\[\]=/) then
|
195
|
+
action { [:tIDENTIFIER_VALUE, text] }
|
196
|
+
when text = ss.scan(/\[\]/) then
|
197
|
+
action { [:tIDENTIFIER_VALUE, text] }
|
198
|
+
when text = ss.scan(/:\[\]=/) then
|
199
|
+
action { [:tSYMBOL, text[1..-1].to_sym] }
|
200
|
+
when text = ss.scan(/:\[\]/) then
|
201
|
+
action { [:tSYMBOL, text[1..-1].to_sym] }
|
202
|
+
when text = ss.scan(/#{OPEN_ARRAY}/) then
|
203
|
+
action { @state = :ARRAY_VALUE; [:tOPEN_ARRAY, text] }
|
204
|
+
when text = ss.scan(/#{CLOSE_ATTRIBUTE}/) then
|
205
|
+
action { @nested_count -= 1; @state = @nested_count == 0 ? nil : :VALUE; [:tCLOSE_ATTRIBUTE, text] }
|
206
|
+
when text = ss.scan(/#{NIL}\?/) then
|
207
|
+
action { [:tIDENTIFIER_VALUE, text] }
|
208
|
+
when ss.skip(/#{NIL}/) then
|
209
|
+
action { [:tNIL, nil] }
|
210
|
+
when ss.skip(/#{TRUE}/) then
|
211
|
+
action { [:tBOOLEAN, true] }
|
212
|
+
when ss.skip(/#{FALSE}/) then
|
213
|
+
action { [:tBOOLEAN, false] }
|
214
|
+
when text = ss.scan(/#{SYMBOL}/) then
|
215
|
+
action { [:tSYMBOL, text[1..-1].to_sym] }
|
216
|
+
when text = ss.scan(/#{FLOAT}/) then
|
217
|
+
action { [:tFLOAT, text.to_f] }
|
218
|
+
when text = ss.scan(/#{INTEGER}/) then
|
219
|
+
action { [:tINTEGER, text.to_i] }
|
220
|
+
when text = ss.scan(/#{REGEXP}/) then
|
221
|
+
action { [:tREGEXP, eval(text)] }
|
222
|
+
when text = ss.scan(/#{DOUBLE_QUOTE_STRING}/) then
|
223
|
+
action { [:tSTRING, text[1...-1]] }
|
224
|
+
when text = ss.scan(/#{SINGLE_QUOTE_STRING}/) then
|
225
|
+
action { [:tSTRING, text[1...-1]] }
|
226
|
+
when text = ss.scan(/#{NODE_TYPE}/) then
|
227
|
+
action { [:tNODE_TYPE, text[1..]] }
|
228
|
+
when text = ss.scan(/#{OPEN_ATTRIBUTE}/) then
|
229
|
+
action { @nested_count += 1; @state = :KEY; [:tOPEN_ATTRIBUTE, text] }
|
230
|
+
when text = ss.scan(/#{IDENTIFIER_VALUE}/) then
|
231
|
+
action { [:tIDENTIFIER_VALUE, text] }
|
232
|
+
else
|
233
|
+
text = ss.string[ss.pos .. -1]
|
234
|
+
raise ScanError, "can not match (#{state.inspect}) at #{location}: '#{text}'"
|
235
|
+
end
|
236
|
+
when :ARRAY_VALUE then
|
237
|
+
case
|
238
|
+
when ss.skip(/\s+/) then
|
239
|
+
# do nothing
|
240
|
+
when text = ss.scan(/#{CLOSE_ARRAY}/) then
|
241
|
+
action { @state = :VALUE; [:tCLOSE_ARRAY, text] }
|
242
|
+
when text = ss.scan(/#{NIL}\?/) then
|
243
|
+
action { [:tIDENTIFIER_VALUE, text] }
|
244
|
+
when ss.skip(/#{NIL}/) then
|
245
|
+
action { [:tNIL, nil] }
|
246
|
+
when ss.skip(/#{TRUE}/) then
|
247
|
+
action { [:tBOOLEAN, true] }
|
248
|
+
when ss.skip(/#{FALSE}/) then
|
249
|
+
action { [:tBOOLEAN, false] }
|
250
|
+
when text = ss.scan(/#{SYMBOL}/) then
|
251
|
+
action { [:tSYMBOL, text[1..-1].to_sym] }
|
252
|
+
when text = ss.scan(/#{FLOAT}/) then
|
253
|
+
action { [:tFLOAT, text.to_f] }
|
254
|
+
when text = ss.scan(/#{INTEGER}/) then
|
255
|
+
action { [:tINTEGER, text.to_i] }
|
256
|
+
when text = ss.scan(/#{REGEXP}/) then
|
257
|
+
action { [:tREGEXP, eval(text)] }
|
258
|
+
when text = ss.scan(/#{DOUBLE_QUOTE_STRING}/) then
|
259
|
+
action { [:tSTRING, text[1...-1]] }
|
260
|
+
when text = ss.scan(/#{SINGLE_QUOTE_STRING}/) then
|
261
|
+
action { [:tSTRING, text[1...-1]] }
|
262
|
+
when text = ss.scan(/#{IDENTIFIER_VALUE}/) then
|
263
|
+
action { [:tIDENTIFIER_VALUE, text] }
|
264
|
+
else
|
265
|
+
text = ss.string[ss.pos .. -1]
|
266
|
+
raise ScanError, "can not match (#{state.inspect}) at #{location}: '#{text}'"
|
267
|
+
end
|
268
|
+
else
|
269
|
+
raise ScanError, "undefined state at #{location}: '#{state}'"
|
270
|
+
end # token = case state
|
271
|
+
|
272
|
+
next unless token # allow functions to trigger redo w/ nil
|
273
|
+
end # while
|
274
|
+
|
275
|
+
raise LexerError, "bad lexical result at #{location}: #{token.inspect}" unless
|
276
|
+
token.nil? || (Array === token && token.size >= 2)
|
277
|
+
|
278
|
+
# auto-switch state
|
279
|
+
self.state = token.last if token && token.first == :state
|
280
|
+
|
281
|
+
token
|
282
|
+
end # def next_token
|
283
|
+
def initialize
|
284
|
+
@nested_count = 0
|
285
|
+
end
|
286
|
+
def do_parse; end
|
287
|
+
end # class
|
@@ -0,0 +1,302 @@
|
|
1
|
+
#
|
2
|
+
# DO NOT MODIFY!!!!
|
3
|
+
# This file is automatically generated by Racc 1.6.0
|
4
|
+
# from Racc grammar file "".
|
5
|
+
#
|
6
|
+
|
7
|
+
require 'racc/parser.rb'
|
8
|
+
class NodeQueryParser < Racc::Parser
|
9
|
+
|
10
|
+
def initialize
|
11
|
+
@lexer = NodeQueryLexer.new
|
12
|
+
end
|
13
|
+
|
14
|
+
def parse string
|
15
|
+
@lexer.parse string
|
16
|
+
do_parse
|
17
|
+
end
|
18
|
+
|
19
|
+
def next_token
|
20
|
+
@lexer.next_token
|
21
|
+
end
|
22
|
+
##### State transition tables begin ###
|
23
|
+
|
24
|
+
racc_action_table = [
|
25
|
+
8, 8, 7, 9, 10, 36, 12, 5, 6, 16,
|
26
|
+
27, 17, 21, 22, 23, 24, 29, 30, 31, 32,
|
27
|
+
33, 34, 35, 8, 16, 8, 7, 40, 36, nil,
|
28
|
+
8, 5, 6, nil, 37, 36, nil, nil, nil, 29,
|
29
|
+
30, 31, 32, 33, 34, 35, 29, 30, 31, 32,
|
30
|
+
33, 34, 35, 8, 7, 8, 7, 8, 7, 5,
|
31
|
+
6, 5, 6, 5, 6, 8, 7, nil, nil, nil,
|
32
|
+
nil, 5, 6 ]
|
33
|
+
|
34
|
+
racc_action_check = [
|
35
|
+
24, 0, 0, 1, 2, 24, 5, 0, 0, 8,
|
36
|
+
24, 9, 16, 19, 20, 21, 24, 24, 24, 24,
|
37
|
+
24, 24, 24, 27, 23, 3, 3, 38, 27, nil,
|
38
|
+
39, 3, 3, nil, 27, 39, nil, nil, nil, 27,
|
39
|
+
27, 27, 27, 27, 27, 27, 39, 39, 39, 39,
|
40
|
+
39, 39, 39, 6, 6, 7, 7, 10, 10, 6,
|
41
|
+
6, 7, 7, 10, 10, 12, 12, nil, nil, nil,
|
42
|
+
nil, 12, 12 ]
|
43
|
+
|
44
|
+
racc_action_pointer = [
|
45
|
+
-2, 3, 2, 22, nil, -9, 50, 52, -2, 11,
|
46
|
+
54, nil, 62, nil, nil, nil, 6, nil, nil, -3,
|
47
|
+
2, -2, nil, 13, -3, nil, nil, 20, nil, nil,
|
48
|
+
nil, nil, nil, nil, nil, nil, nil, nil, 13, 27,
|
49
|
+
nil, nil ]
|
50
|
+
|
51
|
+
racc_action_default = [
|
52
|
+
-27, -27, -2, -4, -5, -27, -27, -27, -9, -27,
|
53
|
+
-27, -3, -27, -7, -8, -10, -27, 42, -1, -27,
|
54
|
+
-27, -27, -6, -12, -27, -11, -13, -27, -18, -19,
|
55
|
+
-20, -21, -22, -23, -24, -25, -26, -14, -27, -17,
|
56
|
+
-15, -16 ]
|
57
|
+
|
58
|
+
racc_goto_table = [
|
59
|
+
28, 15, 38, 28, 13, 14, 11, 1, 20, 26,
|
60
|
+
19, nil, nil, nil, 41, 28, 25, 18 ]
|
61
|
+
|
62
|
+
racc_goto_check = [
|
63
|
+
4, 5, 8, 4, 3, 3, 2, 1, 6, 7,
|
64
|
+
3, nil, nil, nil, 8, 4, 5, 1 ]
|
65
|
+
|
66
|
+
racc_goto_pointer = [
|
67
|
+
nil, 7, 3, -2, -24, -7, -8, -15, -25 ]
|
68
|
+
|
69
|
+
racc_goto_default = [
|
70
|
+
nil, nil, 2, 3, 4, nil, nil, 39, nil ]
|
71
|
+
|
72
|
+
racc_reduce_table = [
|
73
|
+
0, 0, :racc_error,
|
74
|
+
3, 27, :_reduce_1,
|
75
|
+
1, 27, :_reduce_2,
|
76
|
+
2, 28, :_reduce_3,
|
77
|
+
1, 28, :_reduce_4,
|
78
|
+
1, 29, :_reduce_5,
|
79
|
+
4, 29, :_reduce_6,
|
80
|
+
2, 29, :_reduce_7,
|
81
|
+
2, 29, :_reduce_8,
|
82
|
+
1, 30, :_reduce_9,
|
83
|
+
2, 30, :_reduce_10,
|
84
|
+
4, 31, :_reduce_11,
|
85
|
+
3, 31, :_reduce_12,
|
86
|
+
3, 32, :_reduce_13,
|
87
|
+
4, 32, :_reduce_14,
|
88
|
+
5, 32, :_reduce_15,
|
89
|
+
2, 34, :_reduce_16,
|
90
|
+
1, 34, :_reduce_17,
|
91
|
+
1, 33, :_reduce_none,
|
92
|
+
1, 33, :_reduce_19,
|
93
|
+
1, 33, :_reduce_20,
|
94
|
+
1, 33, :_reduce_21,
|
95
|
+
1, 33, :_reduce_22,
|
96
|
+
1, 33, :_reduce_23,
|
97
|
+
1, 33, :_reduce_24,
|
98
|
+
1, 33, :_reduce_25,
|
99
|
+
1, 33, :_reduce_26 ]
|
100
|
+
|
101
|
+
racc_reduce_n = 27
|
102
|
+
|
103
|
+
racc_shift_n = 42
|
104
|
+
|
105
|
+
racc_token_table = {
|
106
|
+
false => 0,
|
107
|
+
:error => 1,
|
108
|
+
:tCOMMA => 2,
|
109
|
+
:tNODE_TYPE => 3,
|
110
|
+
:tGOTO_SCOPE => 4,
|
111
|
+
:tATTRIBUTE => 5,
|
112
|
+
:tKEY => 6,
|
113
|
+
:tIDENTIFIER => 7,
|
114
|
+
:tIDENTIFIER_VALUE => 8,
|
115
|
+
:tPSEUDO_CLASS => 9,
|
116
|
+
:tRELATIONSHIP => 10,
|
117
|
+
:tOPEN_ATTRIBUTE => 11,
|
118
|
+
:tCLOSE_ATTRIBUTE => 12,
|
119
|
+
:tOPEN_ARRAY => 13,
|
120
|
+
:tCLOSE_ARRAY => 14,
|
121
|
+
:tOPEN_SELECTOR => 15,
|
122
|
+
:tCLOSE_SELECTOR => 16,
|
123
|
+
:tOPERATOR => 17,
|
124
|
+
:tARRAY_VALUE => 18,
|
125
|
+
:tBOOLEAN => 19,
|
126
|
+
:tFLOAT => 20,
|
127
|
+
:tINTEGER => 21,
|
128
|
+
:tNIL => 22,
|
129
|
+
:tREGEXP => 23,
|
130
|
+
:tSTRING => 24,
|
131
|
+
:tSYMBOL => 25 }
|
132
|
+
|
133
|
+
racc_nt_base = 26
|
134
|
+
|
135
|
+
racc_use_result_var = false
|
136
|
+
|
137
|
+
Racc_arg = [
|
138
|
+
racc_action_table,
|
139
|
+
racc_action_check,
|
140
|
+
racc_action_default,
|
141
|
+
racc_action_pointer,
|
142
|
+
racc_goto_table,
|
143
|
+
racc_goto_check,
|
144
|
+
racc_goto_default,
|
145
|
+
racc_goto_pointer,
|
146
|
+
racc_nt_base,
|
147
|
+
racc_reduce_table,
|
148
|
+
racc_token_table,
|
149
|
+
racc_shift_n,
|
150
|
+
racc_reduce_n,
|
151
|
+
racc_use_result_var ]
|
152
|
+
|
153
|
+
Racc_token_to_s_table = [
|
154
|
+
"$end",
|
155
|
+
"error",
|
156
|
+
"tCOMMA",
|
157
|
+
"tNODE_TYPE",
|
158
|
+
"tGOTO_SCOPE",
|
159
|
+
"tATTRIBUTE",
|
160
|
+
"tKEY",
|
161
|
+
"tIDENTIFIER",
|
162
|
+
"tIDENTIFIER_VALUE",
|
163
|
+
"tPSEUDO_CLASS",
|
164
|
+
"tRELATIONSHIP",
|
165
|
+
"tOPEN_ATTRIBUTE",
|
166
|
+
"tCLOSE_ATTRIBUTE",
|
167
|
+
"tOPEN_ARRAY",
|
168
|
+
"tCLOSE_ARRAY",
|
169
|
+
"tOPEN_SELECTOR",
|
170
|
+
"tCLOSE_SELECTOR",
|
171
|
+
"tOPERATOR",
|
172
|
+
"tARRAY_VALUE",
|
173
|
+
"tBOOLEAN",
|
174
|
+
"tFLOAT",
|
175
|
+
"tINTEGER",
|
176
|
+
"tNIL",
|
177
|
+
"tREGEXP",
|
178
|
+
"tSTRING",
|
179
|
+
"tSYMBOL",
|
180
|
+
"$start",
|
181
|
+
"expression_list",
|
182
|
+
"expression",
|
183
|
+
"selector",
|
184
|
+
"basic_selector",
|
185
|
+
"attribute_list",
|
186
|
+
"attribute",
|
187
|
+
"value",
|
188
|
+
"array_value" ]
|
189
|
+
|
190
|
+
Racc_debug_parser = false
|
191
|
+
|
192
|
+
##### State transition tables end #####
|
193
|
+
|
194
|
+
# reduce 0 omitted
|
195
|
+
|
196
|
+
def _reduce_1(val, _values)
|
197
|
+
NodeQuery::Compiler::ExpressionList.new(expression: val[0], rest: val[2])
|
198
|
+
end
|
199
|
+
|
200
|
+
def _reduce_2(val, _values)
|
201
|
+
NodeQuery::Compiler::ExpressionList.new(expression: val[0])
|
202
|
+
end
|
203
|
+
|
204
|
+
def _reduce_3(val, _values)
|
205
|
+
NodeQuery::Compiler::Expression.new(selector: val[0], rest: val[1])
|
206
|
+
end
|
207
|
+
|
208
|
+
def _reduce_4(val, _values)
|
209
|
+
NodeQuery::Compiler::Expression.new(selector: val[0])
|
210
|
+
end
|
211
|
+
|
212
|
+
def _reduce_5(val, _values)
|
213
|
+
NodeQuery::Compiler::Selector.new(basic_selector: val[0])
|
214
|
+
end
|
215
|
+
|
216
|
+
def _reduce_6(val, _values)
|
217
|
+
NodeQuery::Compiler::Selector.new(pseudo_class: val[0], pseudo_selector: val[2])
|
218
|
+
end
|
219
|
+
|
220
|
+
def _reduce_7(val, _values)
|
221
|
+
NodeQuery::Compiler::Selector.new(relationship: val[0], rest: val[1])
|
222
|
+
end
|
223
|
+
|
224
|
+
def _reduce_8(val, _values)
|
225
|
+
NodeQuery::Compiler::Selector.new(goto_scope: val[0], rest: val[1])
|
226
|
+
end
|
227
|
+
|
228
|
+
def _reduce_9(val, _values)
|
229
|
+
NodeQuery::Compiler::BasicSelector.new(node_type: val[0])
|
230
|
+
end
|
231
|
+
|
232
|
+
def _reduce_10(val, _values)
|
233
|
+
NodeQuery::Compiler::BasicSelector.new(node_type: val[0], attribute_list: val[1])
|
234
|
+
end
|
235
|
+
|
236
|
+
def _reduce_11(val, _values)
|
237
|
+
NodeQuery::Compiler::AttributeList.new(attribute: val[1], rest: val[3])
|
238
|
+
end
|
239
|
+
|
240
|
+
def _reduce_12(val, _values)
|
241
|
+
NodeQuery::Compiler::AttributeList.new(attribute: val[1])
|
242
|
+
end
|
243
|
+
|
244
|
+
def _reduce_13(val, _values)
|
245
|
+
NodeQuery::Compiler::Attribute.new(key: val[0], value: val[2], operator: val[1])
|
246
|
+
end
|
247
|
+
|
248
|
+
def _reduce_14(val, _values)
|
249
|
+
NodeQuery::Compiler::Attribute.new(key: val[0], value: NodeQuery::Compiler::ArrayValue.new, operator: val[1])
|
250
|
+
end
|
251
|
+
|
252
|
+
def _reduce_15(val, _values)
|
253
|
+
NodeQuery::Compiler::Attribute.new(key: val[0], value: val[3], operator: val[1])
|
254
|
+
end
|
255
|
+
|
256
|
+
def _reduce_16(val, _values)
|
257
|
+
NodeQuery::Compiler::ArrayValue.new(value: val[0], rest: val[1])
|
258
|
+
end
|
259
|
+
|
260
|
+
def _reduce_17(val, _values)
|
261
|
+
NodeQuery::Compiler::ArrayValue.new(value: val[0])
|
262
|
+
end
|
263
|
+
|
264
|
+
# reduce 18 omitted
|
265
|
+
|
266
|
+
def _reduce_19(val, _values)
|
267
|
+
NodeQuery::Compiler::Boolean.new(value: val[0])
|
268
|
+
end
|
269
|
+
|
270
|
+
def _reduce_20(val, _values)
|
271
|
+
NodeQuery::Compiler::Float.new(value: val[0])
|
272
|
+
end
|
273
|
+
|
274
|
+
def _reduce_21(val, _values)
|
275
|
+
NodeQuery::Compiler::Integer.new(value: val[0])
|
276
|
+
end
|
277
|
+
|
278
|
+
def _reduce_22(val, _values)
|
279
|
+
NodeQuery::Compiler::Nil.new(value: val[0])
|
280
|
+
end
|
281
|
+
|
282
|
+
def _reduce_23(val, _values)
|
283
|
+
NodeQuery::Compiler::Regexp.new(value: val[0])
|
284
|
+
end
|
285
|
+
|
286
|
+
def _reduce_24(val, _values)
|
287
|
+
NodeQuery::Compiler::String.new(value: val[0])
|
288
|
+
end
|
289
|
+
|
290
|
+
def _reduce_25(val, _values)
|
291
|
+
NodeQuery::Compiler::Symbol.new(value: val[0])
|
292
|
+
end
|
293
|
+
|
294
|
+
def _reduce_26(val, _values)
|
295
|
+
NodeQuery::Compiler::Identifier.new(value: val[0])
|
296
|
+
end
|
297
|
+
|
298
|
+
def _reduce_none(val, _values)
|
299
|
+
val[0]
|
300
|
+
end
|
301
|
+
|
302
|
+
end # class NodeQueryParser
|
data/lib/node_query_parser.y
CHANGED
@@ -2,7 +2,7 @@ class NodeQueryParser
|
|
2
2
|
options no_result_var
|
3
3
|
token tCOMMA tNODE_TYPE tGOTO_SCOPE tATTRIBUTE tKEY tIDENTIFIER tIDENTIFIER_VALUE tPSEUDO_CLASS tRELATIONSHIP
|
4
4
|
tOPEN_ATTRIBUTE tCLOSE_ATTRIBUTE tOPEN_ARRAY tCLOSE_ARRAY tOPEN_SELECTOR tCLOSE_SELECTOR
|
5
|
-
tOPERATOR tARRAY_VALUE
|
5
|
+
tOPERATOR tARRAY_VALUE tBOOLEAN tFLOAT tINTEGER tNIL tREGEXP tSTRING tSYMBOL
|
6
6
|
rule
|
7
7
|
expression_list
|
8
8
|
: expression tCOMMA expression_list { NodeQuery::Compiler::ExpressionList.new(expression: val[0], rest: val[2]) }
|
@@ -28,7 +28,7 @@ rule
|
|
28
28
|
|
29
29
|
attribute
|
30
30
|
: tKEY tOPERATOR value { NodeQuery::Compiler::Attribute.new(key: val[0], value: val[2], operator: val[1]) }
|
31
|
-
| tKEY tOPERATOR tOPEN_ARRAY tCLOSE_ARRAY { NodeQuery::Compiler::Attribute.new(key: val[0], value: NodeQuery::Compiler::
|
31
|
+
| tKEY tOPERATOR tOPEN_ARRAY tCLOSE_ARRAY { NodeQuery::Compiler::Attribute.new(key: val[0], value: NodeQuery::Compiler::ArrayValue.new, operator: val[1]) }
|
32
32
|
| tKEY tOPERATOR tOPEN_ARRAY array_value tCLOSE_ARRAY { NodeQuery::Compiler::Attribute.new(key: val[0], value: val[3], operator: val[1]) }
|
33
33
|
|
34
34
|
array_value
|
@@ -37,7 +37,6 @@ rule
|
|
37
37
|
|
38
38
|
value
|
39
39
|
: basic_selector
|
40
|
-
| tDYNAMIC_ATTRIBUTE { NodeQuery::Compiler::EvaluatedValue.new(value: val[0]) }
|
41
40
|
| tBOOLEAN { NodeQuery::Compiler::Boolean.new(value: val[0]) }
|
42
41
|
| tFLOAT { NodeQuery::Compiler::Float.new(value: val[0]) }
|
43
42
|
| tINTEGER { NodeQuery::Compiler::Integer.new(value: val[0])}
|
@@ -60,4 +59,4 @@ end
|
|
60
59
|
|
61
60
|
def next_token
|
62
61
|
@lexer.next_token
|
63
|
-
end
|
62
|
+
end
|
data/node_query.gemspec
CHANGED
@@ -15,7 +15,7 @@ Gem::Specification.new do |spec|
|
|
15
15
|
|
16
16
|
spec.metadata["homepage_uri"] = spec.homepage
|
17
17
|
spec.metadata["source_code_uri"] = "https://github.com/xinminlabs/node-query-ruby"
|
18
|
-
spec.metadata["changelog_uri"] = "https://github.com/xinminlabs/node-query-ruby/CHANGELOG.md"
|
18
|
+
spec.metadata["changelog_uri"] = "https://github.com/xinminlabs/node-query-ruby/blob/master/CHANGELOG.md"
|
19
19
|
|
20
20
|
# Specify which files should be added to the gem when it is released.
|
21
21
|
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
@@ -23,13 +23,13 @@ Gem::Specification.new do |spec|
|
|
23
23
|
`git ls-files -z`.split("\x0").reject do |f|
|
24
24
|
(f == __FILE__) || f.match(%r{\A(?:(?:bin|test|spec|features)/|\.(?:git|travis|circleci)|appveyor)})
|
25
25
|
end
|
26
|
-
end
|
26
|
+
end + %w[lib/node_query_lexer.rex.rb lib/node_query_parser.racc.rb]
|
27
27
|
spec.bindir = "exe"
|
28
28
|
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
|
29
29
|
spec.require_paths = ["lib"]
|
30
30
|
|
31
31
|
# Uncomment to register a new dependency of your gem
|
32
|
-
spec.add_dependency "activesupport"
|
32
|
+
spec.add_dependency "activesupport", "< 7.0.0"
|
33
33
|
|
34
34
|
# For more information and examples about making a new gem, check out our
|
35
35
|
# guide at: https://bundler.io/guides/creating_gem.html
|
data/sig/node_query.rbs
CHANGED
@@ -1,11 +1,13 @@
|
|
1
|
-
class NodeQuery
|
1
|
+
class NodeQuery[T]
|
2
2
|
VERSION: String
|
3
3
|
|
4
4
|
def self.configure: (options: { adapter: NodeQuery::Adapter }) -> void
|
5
5
|
|
6
|
-
def self.
|
6
|
+
def self.adapter: () -> NodeQuery::Adapter
|
7
7
|
|
8
|
-
def initialize: (
|
8
|
+
def initialize: (nqlOrRues: String | Hash) -> NodeQuery
|
9
9
|
|
10
|
-
def
|
10
|
+
def query_nodes: (node: T, including_self: boolean) -> Array[T]
|
11
|
+
|
12
|
+
def match_node?: (node: T) -> boolean
|
11
13
|
end
|