machete 0.4.0 → 0.5.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.
- data/.gitignore +2 -0
- data/CHANGELOG +13 -0
- data/Gemfile +4 -0
- data/README.md +85 -22
- data/Rakefile +2 -2
- data/VERSION +1 -1
- data/lib/machete.rb +87 -43
- data/lib/machete/matchers.rb +24 -14
- data/lib/machete/parser.y +99 -26
- data/machete.gemspec +2 -2
- data/spec/machete/matchers_spec.rb +69 -11
- data/spec/machete/parser_spec.rb +183 -68
- data/spec/machete_spec.rb +44 -16
- metadata +17 -15
data/lib/machete/parser.y
CHANGED
@@ -1,16 +1,17 @@
|
|
1
1
|
class Machete::Parser
|
2
2
|
|
3
|
+
token NIL
|
3
4
|
token TRUE
|
4
5
|
token FALSE
|
5
|
-
token NIL
|
6
6
|
token INTEGER
|
7
|
+
token SYMBOL
|
7
8
|
token STRING
|
9
|
+
token REGEXP
|
8
10
|
token ANY
|
9
11
|
token EVEN
|
10
12
|
token ODD
|
11
13
|
token METHOD_NAME
|
12
14
|
token CLASS_NAME
|
13
|
-
token SYMBOL
|
14
15
|
|
15
16
|
start expression
|
16
17
|
|
@@ -41,6 +42,27 @@ attrs : attr
|
|
41
42
|
| attrs "," attr { result = val[0].merge(val[2]) }
|
42
43
|
|
43
44
|
attr : method_name "=" expression { result = { val[0].to_sym => val[2] } }
|
45
|
+
| method_name "^=" SYMBOL {
|
46
|
+
result = {
|
47
|
+
val[0].to_sym => SymbolRegexpMatcher.new(
|
48
|
+
Regexp.new("^" + Regexp.escape(symbol_value(val[2]).to_s))
|
49
|
+
)
|
50
|
+
}
|
51
|
+
}
|
52
|
+
| method_name "$=" SYMBOL {
|
53
|
+
result = {
|
54
|
+
val[0].to_sym => SymbolRegexpMatcher.new(
|
55
|
+
Regexp.new(Regexp.escape(symbol_value(val[2]).to_s) + "$")
|
56
|
+
)
|
57
|
+
}
|
58
|
+
}
|
59
|
+
| method_name "*=" SYMBOL {
|
60
|
+
result = {
|
61
|
+
val[0].to_sym => SymbolRegexpMatcher.new(
|
62
|
+
Regexp.new(Regexp.escape(symbol_value(val[2]).to_s))
|
63
|
+
)
|
64
|
+
}
|
65
|
+
}
|
44
66
|
| method_name "^=" STRING {
|
45
67
|
result = {
|
46
68
|
val[0].to_sym => StringRegexpMatcher.new(
|
@@ -62,14 +84,21 @@ attr : method_name "=" expression { result = { val[0].to_sym => val[2] } }
|
|
62
84
|
)
|
63
85
|
}
|
64
86
|
}
|
87
|
+
| method_name "*=" REGEXP {
|
88
|
+
result = {
|
89
|
+
val[0].to_sym => IndifferentRegexpMatcher.new(
|
90
|
+
Regexp.new(regexp_value(val[2]))
|
91
|
+
)
|
92
|
+
}
|
93
|
+
}
|
65
94
|
|
66
95
|
# Hack to overcome the fact that some tokens will lex as simple tokens, not
|
67
96
|
# METHOD_NAME tokens, and that "reserved words" will lex as separate kinds of
|
68
97
|
# tokens.
|
69
98
|
method_name : METHOD_NAME
|
99
|
+
| NIL
|
70
100
|
| TRUE
|
71
101
|
| FALSE
|
72
|
-
| NIL
|
73
102
|
| ANY
|
74
103
|
| EVEN
|
75
104
|
| ODD
|
@@ -109,12 +138,13 @@ quantifier : "*" { result = [0, nil, 1] }
|
|
109
138
|
| "{" EVEN "}" { result = [0, nil, 2] }
|
110
139
|
| "{" ODD "}" { result = [1, nil, 2] }
|
111
140
|
|
112
|
-
literal :
|
141
|
+
literal : NIL { result = LiteralMatcher.new(nil) }
|
142
|
+
| TRUE { result = LiteralMatcher.new(true) }
|
143
|
+
| FALSE { result = LiteralMatcher.new(false) }
|
113
144
|
| INTEGER { result = LiteralMatcher.new(integer_value(val[0])) }
|
145
|
+
| SYMBOL { result = LiteralMatcher.new(symbol_value(val[0])) }
|
114
146
|
| STRING { result = LiteralMatcher.new(string_value(val[0])) }
|
115
|
-
|
|
116
|
-
| FALSE { result = LiteralMatcher.new(false) }
|
117
|
-
| NIL { result = LiteralMatcher.new(nil) }
|
147
|
+
| REGEXP { result = LiteralMatcher.new(regexp_value(val[0])) }
|
118
148
|
|
119
149
|
any : ANY { result = AnyMatcher.new }
|
120
150
|
|
@@ -143,12 +173,16 @@ def integer_value(value)
|
|
143
173
|
elsif value =~ /^0[xX]/
|
144
174
|
value[2..-1].to_i(16)
|
145
175
|
elsif value =~ /^0/
|
146
|
-
value
|
176
|
+
value.to_i(8)
|
147
177
|
else
|
148
178
|
value.to_i
|
149
179
|
end
|
150
180
|
end
|
151
181
|
|
182
|
+
def symbol_value(value)
|
183
|
+
value[1..-1].to_sym
|
184
|
+
end
|
185
|
+
|
152
186
|
def string_value(value)
|
153
187
|
quote = value[0..0]
|
154
188
|
if quote == "'"
|
@@ -173,6 +207,19 @@ def string_value(value)
|
|
173
207
|
end
|
174
208
|
end
|
175
209
|
|
210
|
+
REGEXP_OPTIONS = {
|
211
|
+
'i' => Regexp::IGNORECASE,
|
212
|
+
'm' => Regexp::MULTILINE,
|
213
|
+
'x' => Regexp::EXTENDED
|
214
|
+
}
|
215
|
+
|
216
|
+
def regexp_value(value)
|
217
|
+
/\A\/(.*)\/([imx]*)\z/ =~ value
|
218
|
+
pattern, options = $1, $2
|
219
|
+
|
220
|
+
Regexp.new(pattern, options.chars.map { |ch| REGEXP_OPTIONS[ch] }.inject(:|))
|
221
|
+
end
|
222
|
+
|
176
223
|
# "^" needs to be here because if it were among operators recognized by
|
177
224
|
# METHOD_NAME, "^=" would be recognized as two tokens.
|
178
225
|
SIMPLE_TOKENS = [
|
@@ -195,9 +242,9 @@ SIMPLE_TOKENS = [
|
|
195
242
|
]
|
196
243
|
|
197
244
|
COMPLEX_TOKENS = [
|
245
|
+
[:NIL, /^nil/],
|
198
246
|
[:TRUE, /^true/],
|
199
247
|
[:FALSE, /^false/],
|
200
|
-
[:NIL, /^nil/],
|
201
248
|
# INTEGER needs to be before METHOD_NAME, otherwise e.g. "+1" would be
|
202
249
|
# recognized as two tokens.
|
203
250
|
[
|
@@ -219,6 +266,28 @@ COMPLEX_TOKENS = [
|
|
219
266
|
)
|
220
267
|
/x
|
221
268
|
],
|
269
|
+
[
|
270
|
+
:SYMBOL,
|
271
|
+
/^
|
272
|
+
:
|
273
|
+
(
|
274
|
+
# class name
|
275
|
+
[A-Z][a-zA-Z0-9_]*
|
276
|
+
|
|
277
|
+
# regular method name
|
278
|
+
[a-z_][a-zA-Z0-9_]*[?!=]?
|
279
|
+
|
|
280
|
+
# instance variable name
|
281
|
+
@[a-zA-Z_][a-zA-Z0-9_]*
|
282
|
+
|
|
283
|
+
# class variable name
|
284
|
+
@@[a-zA-Z_][a-zA-Z0-9_]*
|
285
|
+
|
|
286
|
+
# operator (sorted by length, then alphabetically)
|
287
|
+
(<=>|===|\[\]=|\*\*|\+@|-@|<<|<=|==|=~|>=|>>|\[\]|[%&*+\-\/<>^`|~])
|
288
|
+
)
|
289
|
+
/x
|
290
|
+
],
|
222
291
|
[
|
223
292
|
:STRING,
|
224
293
|
/^
|
@@ -248,6 +317,26 @@ COMPLEX_TOKENS = [
|
|
248
317
|
)
|
249
318
|
/x
|
250
319
|
],
|
320
|
+
[
|
321
|
+
:REGEXP,
|
322
|
+
/^
|
323
|
+
\/
|
324
|
+
(
|
325
|
+
\\ # escape
|
326
|
+
(
|
327
|
+
[\\\/ntrfvaebs\(\)\[\]\{\}\-\.\?\*\+\|\^\$] # one-character escape
|
328
|
+
|
|
329
|
+
[0-7]{2,3} # octal number escape
|
330
|
+
|
|
331
|
+
x[0-9a-fA-F]{1,2} # hexadecimal number escape
|
332
|
+
)
|
333
|
+
|
|
334
|
+
[^\/] # regular character
|
335
|
+
)*
|
336
|
+
\/
|
337
|
+
[imx]*
|
338
|
+
/x
|
339
|
+
],
|
251
340
|
# ANY, EVEN and ODD need to be before METHOD_NAME, otherwise they would be
|
252
341
|
# recognized as method names.
|
253
342
|
[:ANY, /^any/],
|
@@ -268,23 +357,7 @@ COMPLEX_TOKENS = [
|
|
268
357
|
)
|
269
358
|
/x
|
270
359
|
],
|
271
|
-
[:CLASS_NAME,
|
272
|
-
[
|
273
|
-
:SYMBOL,
|
274
|
-
/^
|
275
|
-
:
|
276
|
-
(
|
277
|
-
# class name
|
278
|
-
[A-Z][a-zA-Z0-9_]*
|
279
|
-
|
|
280
|
-
# regular method name
|
281
|
-
[a-z_][a-zA-Z0-9_]*[?!=]?
|
282
|
-
|
|
283
|
-
# operator (sorted by length, then alphabetically)
|
284
|
-
(<=>|===|\[\]=|\*\*|\+@|-@|<<|<=|==|=~|>=|>>|\[\]|[%&*+\-\/<>^`|~])
|
285
|
-
)
|
286
|
-
/x
|
287
|
-
]
|
360
|
+
[:CLASS_NAME, /^[A-Z][a-zA-Z0-9_]*/]
|
288
361
|
]
|
289
362
|
|
290
363
|
def next_token
|
data/machete.gemspec
CHANGED
@@ -13,8 +13,8 @@ Gem::Specification.new do |s|
|
|
13
13
|
in the code, etc.
|
14
14
|
EOT
|
15
15
|
|
16
|
-
s.
|
17
|
-
s.email = "dmajda@suse.
|
16
|
+
s.authors = ["David Majda", "Piotr Niełacny"]
|
17
|
+
s.email = ["dmajda@suse.cz", "piotr.nielacny@gmail.com"]
|
18
18
|
s.homepage = "https://github.com/openSUSE/machete"
|
19
19
|
s.license = "MIT"
|
20
20
|
|
@@ -49,6 +49,10 @@ module Machete::Matchers
|
|
49
49
|
end
|
50
50
|
end
|
51
51
|
|
52
|
+
describe Matcher do
|
53
|
+
# Nothing to spec.
|
54
|
+
end
|
55
|
+
|
52
56
|
describe ChoiceMatcher do
|
53
57
|
before :each do
|
54
58
|
@alternatives = [
|
@@ -116,7 +120,7 @@ module Machete::Matchers
|
|
116
120
|
@matcher = NodeMatcher.new(:RegexLiteral, @attrs)
|
117
121
|
end
|
118
122
|
|
119
|
-
describe "
|
123
|
+
describe "initialize" do
|
120
124
|
describe "when passed one parameter" do
|
121
125
|
it "sets attributes correctly" do
|
122
126
|
matcher = NodeMatcher.new(:RegexLiteral)
|
@@ -409,9 +413,9 @@ module Machete::Matchers
|
|
409
413
|
end
|
410
414
|
end
|
411
415
|
|
412
|
-
describe
|
413
|
-
before
|
414
|
-
@matcher =
|
416
|
+
describe RegexpMatcher do
|
417
|
+
before do
|
418
|
+
@matcher = RegexpMatcher.new(/abcd/)
|
415
419
|
end
|
416
420
|
|
417
421
|
describe "initialize" do
|
@@ -425,27 +429,81 @@ module Machete::Matchers
|
|
425
429
|
@matcher.should == @matcher
|
426
430
|
end
|
427
431
|
|
428
|
-
it "returns true when passed a
|
429
|
-
@matcher.should ==
|
432
|
+
it "returns true when passed a RegexpMatcher initialized with the same parameters" do
|
433
|
+
@matcher.should == RegexpMatcher.new(/abcd/)
|
430
434
|
end
|
431
435
|
|
432
436
|
it "returns false when passed some random object" do
|
433
437
|
@matcher.should_not == Object.new
|
434
438
|
end
|
435
439
|
|
436
|
-
it "returns false when passed a subclass of
|
437
|
-
class
|
440
|
+
it "returns false when passed a subclass of RegexpMatcher initialized with the same parameters" do
|
441
|
+
class SubclassedRegexpMatcher < RegexpMatcher
|
438
442
|
end
|
439
443
|
|
440
|
-
@matcher.should_not ==
|
444
|
+
@matcher.should_not == SubclassedRegexpMatcher.new(/abcd/)
|
441
445
|
end
|
442
446
|
|
443
|
-
it "returns false when passed a
|
444
|
-
@matcher.should_not ==
|
447
|
+
it "returns false when passed a RegexpMatcher initialized with different parameters" do
|
448
|
+
@matcher.should_not == RegexpMatcher.new(/efgh/)
|
445
449
|
end
|
446
450
|
end
|
451
|
+
end
|
452
|
+
|
453
|
+
describe SymbolRegexpMatcher do
|
454
|
+
before do
|
455
|
+
@matcher = SymbolRegexpMatcher.new(/abcd/)
|
456
|
+
end
|
447
457
|
|
448
458
|
describe "matches?" do
|
459
|
+
it "matches a symbol matching the regexp" do
|
460
|
+
@matcher.matches?(:efghabcdijkl).should be_true
|
461
|
+
end
|
462
|
+
|
463
|
+
it "does not match a symbol not matching the regexp" do
|
464
|
+
@matcher.matches?(:efghijkl).should be_false
|
465
|
+
end
|
466
|
+
|
467
|
+
it "does not match some random object" do
|
468
|
+
@matcher.matches?(Object.new).should be_false
|
469
|
+
end
|
470
|
+
end
|
471
|
+
end
|
472
|
+
|
473
|
+
describe StringRegexpMatcher do
|
474
|
+
before :each do
|
475
|
+
@matcher = StringRegexpMatcher.new(/abcd/)
|
476
|
+
end
|
477
|
+
|
478
|
+
describe "matches?" do
|
479
|
+
it "matches a string matching the regexp" do
|
480
|
+
@matcher.matches?("efghabcdijkl").should be_true
|
481
|
+
end
|
482
|
+
|
483
|
+
it "does not match a string not matching the regexp" do
|
484
|
+
@matcher.matches?("efghijkl").should be_false
|
485
|
+
end
|
486
|
+
|
487
|
+
it "does not match some random object" do
|
488
|
+
@matcher.matches?(Object.new).should be_false
|
489
|
+
end
|
490
|
+
end
|
491
|
+
end
|
492
|
+
|
493
|
+
describe IndifferentRegexpMatcher do
|
494
|
+
before :each do
|
495
|
+
@matcher = IndifferentRegexpMatcher.new(/abcd/)
|
496
|
+
end
|
497
|
+
|
498
|
+
describe "matches?" do
|
499
|
+
it "matches a symbol matching the regexp" do
|
500
|
+
@matcher.matches?(:efghabcdijkl).should be_true
|
501
|
+
end
|
502
|
+
|
503
|
+
it "does not match a symbol not matching the regexp" do
|
504
|
+
@matcher.matches?(:efghijkl).should be_false
|
505
|
+
end
|
506
|
+
|
449
507
|
it "matches a string matching the regexp" do
|
450
508
|
@matcher.matches?("efghabcdijkl").should be_true
|
451
509
|
end
|
data/spec/machete/parser_spec.rb
CHANGED
@@ -72,7 +72,30 @@ module Machete
|
|
72
72
|
|
73
73
|
# Canonical attr is "a = 42".
|
74
74
|
it "parses attr" do
|
75
|
+
# Expressions
|
75
76
|
'Foo<a = 42 | 43>'.should be_parsed_as(NodeMatcher.new(:Foo, :a => @ch4243))
|
77
|
+
|
78
|
+
# Symbols
|
79
|
+
'Foo<a ^= :a>'.should be_parsed_as(
|
80
|
+
NodeMatcher.new(:Foo, :a => SymbolRegexpMatcher.new(/^a/))
|
81
|
+
)
|
82
|
+
'Foo<a ^= :+>'.should be_parsed_as(
|
83
|
+
NodeMatcher.new(:Foo, :a => SymbolRegexpMatcher.new(/^\+/))
|
84
|
+
)
|
85
|
+
'Foo<a $= :a>'.should be_parsed_as(
|
86
|
+
NodeMatcher.new(:Foo, :a => SymbolRegexpMatcher.new(/a$/))
|
87
|
+
)
|
88
|
+
'Foo<a $= :+>'.should be_parsed_as(
|
89
|
+
NodeMatcher.new(:Foo, :a => SymbolRegexpMatcher.new(/\+$/))
|
90
|
+
)
|
91
|
+
'Foo<a *= :a>'.should be_parsed_as(
|
92
|
+
NodeMatcher.new(:Foo, :a => SymbolRegexpMatcher.new(/a/))
|
93
|
+
)
|
94
|
+
'Foo<a *= :+>'.should be_parsed_as(
|
95
|
+
NodeMatcher.new(:Foo, :a => SymbolRegexpMatcher.new(/\+/))
|
96
|
+
)
|
97
|
+
|
98
|
+
# Strings
|
76
99
|
'Foo<a ^= "abcd">'.should be_parsed_as(
|
77
100
|
NodeMatcher.new(:Foo, :a => StringRegexpMatcher.new(/^abcd/))
|
78
101
|
)
|
@@ -97,15 +120,32 @@ module Machete
|
|
97
120
|
/\[\]\{\}\(\)\|\-\*\.\\\?\+\^\$\ \#\t\f\v\n\r/
|
98
121
|
))
|
99
122
|
)
|
123
|
+
|
124
|
+
# Regexps
|
125
|
+
'Foo<a *= /abcd/>'.should be_parsed_as(
|
126
|
+
NodeMatcher.new(:Foo, :a => IndifferentRegexpMatcher.new(/abcd/))
|
127
|
+
)
|
128
|
+
'Foo<a *= /abcd/i>'.should be_parsed_as(
|
129
|
+
NodeMatcher.new(:Foo, :a => IndifferentRegexpMatcher.new(/abcd/i))
|
130
|
+
)
|
131
|
+
'Foo<a *= /abcd/m>'.should be_parsed_as(
|
132
|
+
NodeMatcher.new(:Foo, :a => IndifferentRegexpMatcher.new(/abcd/m))
|
133
|
+
)
|
134
|
+
'Foo<a *= /abcd/x>'.should be_parsed_as(
|
135
|
+
NodeMatcher.new(:Foo, :a => IndifferentRegexpMatcher.new(/abcd/x))
|
136
|
+
)
|
137
|
+
'Foo<a *= /abcd/imx>'.should be_parsed_as(
|
138
|
+
NodeMatcher.new(:Foo, :a => IndifferentRegexpMatcher.new(/abcd/imx))
|
139
|
+
)
|
100
140
|
end
|
101
141
|
|
102
142
|
# Canonical method_name is "a".
|
103
143
|
it "parses method_name" do
|
104
144
|
'Foo<a = 42>'.should be_parsed_as(node_matcher_with_attr(:a))
|
145
|
+
'Foo<nil = 42>'.should be_parsed_as(node_matcher_with_attr(:nil))
|
105
146
|
'Foo<true = 42>'.should be_parsed_as(node_matcher_with_attr(:true))
|
106
147
|
'Foo<false = 42>'.should be_parsed_as(node_matcher_with_attr(:false))
|
107
148
|
'Foo<any = 42>'.should be_parsed_as(node_matcher_with_attr(:any))
|
108
|
-
'Foo<any = 42>'.should be_parsed_as(node_matcher_with_attr(:any))
|
109
149
|
'Foo<even = 42>'.should be_parsed_as(node_matcher_with_attr(:even))
|
110
150
|
'Foo<odd = 42>'.should be_parsed_as(node_matcher_with_attr(:odd))
|
111
151
|
'Foo<* = 42>'.should be_parsed_as(node_matcher_with_attr(:*))
|
@@ -166,12 +206,13 @@ module Machete
|
|
166
206
|
|
167
207
|
# Canonical literal is "42".
|
168
208
|
it "parses literal" do
|
169
|
-
'
|
170
|
-
'42'.should be_parsed_as(@i42)
|
171
|
-
'"abcd"'.should be_parsed_as(LiteralMatcher.new("abcd"))
|
209
|
+
'nil'.should be_parsed_as(LiteralMatcher.new(nil))
|
172
210
|
'true'.should be_parsed_as(LiteralMatcher.new(true))
|
173
211
|
'false'.should be_parsed_as(LiteralMatcher.new(false))
|
174
|
-
'
|
212
|
+
'42'.should be_parsed_as(@i42)
|
213
|
+
':a'.should be_parsed_as(LiteralMatcher.new(:a))
|
214
|
+
'"abcd"'.should be_parsed_as(LiteralMatcher.new("abcd"))
|
215
|
+
'/abcd/'.should be_parsed_as(LiteralMatcher.new(/abcd/))
|
175
216
|
end
|
176
217
|
|
177
218
|
# Canonical any is "any".
|
@@ -179,6 +220,11 @@ module Machete
|
|
179
220
|
'any'.should be_parsed_as(AnyMatcher.new)
|
180
221
|
end
|
181
222
|
|
223
|
+
# Canonical NIL is "nil".
|
224
|
+
it "parses NIL" do
|
225
|
+
'nil'.should be_parsed_as(LiteralMatcher.new(nil))
|
226
|
+
end
|
227
|
+
|
182
228
|
# Canonical TRUE is "true".
|
183
229
|
it "parses TRUE" do
|
184
230
|
'true'.should be_parsed_as(LiteralMatcher.new(true))
|
@@ -189,11 +235,6 @@ module Machete
|
|
189
235
|
'false'.should be_parsed_as(LiteralMatcher.new(false))
|
190
236
|
end
|
191
237
|
|
192
|
-
# Canonical NIL is "nil".
|
193
|
-
it "parses NIL" do
|
194
|
-
'nil'.should be_parsed_as(LiteralMatcher.new(nil))
|
195
|
-
end
|
196
|
-
|
197
238
|
# Canonical INTEGER is "42".
|
198
239
|
it "parses INTEGER" do
|
199
240
|
# Sign
|
@@ -275,6 +316,94 @@ module Machete
|
|
275
316
|
'1_2_3_4'.should be_parsed_as(LiteralMatcher.new(1234))
|
276
317
|
end
|
277
318
|
|
319
|
+
# Canonical SYMBOL is ":a".
|
320
|
+
it "parses SYMBOL" do
|
321
|
+
# Class names
|
322
|
+
':A'.should be_parsed_as(LiteralMatcher.new(:A))
|
323
|
+
':Z'.should be_parsed_as(LiteralMatcher.new(:Z))
|
324
|
+
':Aa'.should be_parsed_as(LiteralMatcher.new(:Aa))
|
325
|
+
':Az'.should be_parsed_as(LiteralMatcher.new(:Az))
|
326
|
+
':AA'.should be_parsed_as(LiteralMatcher.new(:AA))
|
327
|
+
':AZ'.should be_parsed_as(LiteralMatcher.new(:AZ))
|
328
|
+
':A0'.should be_parsed_as(LiteralMatcher.new(:A0))
|
329
|
+
':A9'.should be_parsed_as(LiteralMatcher.new(:A9))
|
330
|
+
':A_'.should be_parsed_as(LiteralMatcher.new(:A_))
|
331
|
+
':Abcd'.should be_parsed_as(LiteralMatcher.new(:Abcd))
|
332
|
+
|
333
|
+
# Regular method names
|
334
|
+
':a'.should be_parsed_as(LiteralMatcher.new(:a))
|
335
|
+
':z'.should be_parsed_as(LiteralMatcher.new(:z))
|
336
|
+
':_'.should be_parsed_as(LiteralMatcher.new(:_))
|
337
|
+
':aa'.should be_parsed_as(LiteralMatcher.new(:aa))
|
338
|
+
':az'.should be_parsed_as(LiteralMatcher.new(:az))
|
339
|
+
':aA'.should be_parsed_as(LiteralMatcher.new(:aA))
|
340
|
+
':aZ'.should be_parsed_as(LiteralMatcher.new(:aZ))
|
341
|
+
':a0'.should be_parsed_as(LiteralMatcher.new(:a0))
|
342
|
+
':a9'.should be_parsed_as(LiteralMatcher.new(:a9))
|
343
|
+
':a_'.should be_parsed_as(LiteralMatcher.new(:a_))
|
344
|
+
':abcd'.should be_parsed_as(LiteralMatcher.new(:abcd))
|
345
|
+
':a?'.should be_parsed_as(LiteralMatcher.new(:a?))
|
346
|
+
':a!'.should be_parsed_as(LiteralMatcher.new(:a!))
|
347
|
+
':a='.should be_parsed_as(LiteralMatcher.new(:a=))
|
348
|
+
|
349
|
+
# Instance variable name
|
350
|
+
':@a'.should be_parsed_as(LiteralMatcher.new(:@a))
|
351
|
+
':@z'.should be_parsed_as(LiteralMatcher.new(:@z))
|
352
|
+
':@A'.should be_parsed_as(LiteralMatcher.new(:@A))
|
353
|
+
':@Z'.should be_parsed_as(LiteralMatcher.new(:@Z))
|
354
|
+
':@_'.should be_parsed_as(LiteralMatcher.new(:@_))
|
355
|
+
':@aa'.should be_parsed_as(LiteralMatcher.new(:@aa))
|
356
|
+
':@az'.should be_parsed_as(LiteralMatcher.new(:@az))
|
357
|
+
':@aA'.should be_parsed_as(LiteralMatcher.new(:@aA))
|
358
|
+
':@aZ'.should be_parsed_as(LiteralMatcher.new(:@aZ))
|
359
|
+
':@a0'.should be_parsed_as(LiteralMatcher.new(:@a0))
|
360
|
+
':@a9'.should be_parsed_as(LiteralMatcher.new(:@a9))
|
361
|
+
':@a_'.should be_parsed_as(LiteralMatcher.new(:@a_))
|
362
|
+
':@abcd'.should be_parsed_as(LiteralMatcher.new(:@abcd))
|
363
|
+
|
364
|
+
# Class variable name
|
365
|
+
':@@a'.should be_parsed_as(LiteralMatcher.new(:@@a))
|
366
|
+
':@@z'.should be_parsed_as(LiteralMatcher.new(:@@z))
|
367
|
+
':@@A'.should be_parsed_as(LiteralMatcher.new(:@@A))
|
368
|
+
':@@Z'.should be_parsed_as(LiteralMatcher.new(:@@Z))
|
369
|
+
':@@_'.should be_parsed_as(LiteralMatcher.new(:@@_))
|
370
|
+
':@@aa'.should be_parsed_as(LiteralMatcher.new(:@@aa))
|
371
|
+
':@@az'.should be_parsed_as(LiteralMatcher.new(:@@az))
|
372
|
+
':@@aA'.should be_parsed_as(LiteralMatcher.new(:@@aA))
|
373
|
+
':@@aZ'.should be_parsed_as(LiteralMatcher.new(:@@aZ))
|
374
|
+
':@@a0'.should be_parsed_as(LiteralMatcher.new(:@@a0))
|
375
|
+
':@@a9'.should be_parsed_as(LiteralMatcher.new(:@@a9))
|
376
|
+
':@@a_'.should be_parsed_as(LiteralMatcher.new(:@@a_))
|
377
|
+
':@@abcd'.should be_parsed_as(LiteralMatcher.new(:@@abcd))
|
378
|
+
|
379
|
+
# Operators (sorted alphabetically)
|
380
|
+
':%'.should be_parsed_as(LiteralMatcher.new(:%))
|
381
|
+
':&'.should be_parsed_as(LiteralMatcher.new(:&))
|
382
|
+
':*'.should be_parsed_as(LiteralMatcher.new(:*))
|
383
|
+
':**'.should be_parsed_as(LiteralMatcher.new(:**))
|
384
|
+
':+'.should be_parsed_as(LiteralMatcher.new(:+))
|
385
|
+
':+@'.should be_parsed_as(LiteralMatcher.new(:+@))
|
386
|
+
':-'.should be_parsed_as(LiteralMatcher.new(:-))
|
387
|
+
':-@'.should be_parsed_as(LiteralMatcher.new(:-@))
|
388
|
+
':/'.should be_parsed_as(LiteralMatcher.new(:/))
|
389
|
+
':<'.should be_parsed_as(LiteralMatcher.new(:<))
|
390
|
+
':<<'.should be_parsed_as(LiteralMatcher.new(:<<))
|
391
|
+
':<='.should be_parsed_as(LiteralMatcher.new(:<=))
|
392
|
+
':<=>'.should be_parsed_as(LiteralMatcher.new(:<=>))
|
393
|
+
':=='.should be_parsed_as(LiteralMatcher.new(:==))
|
394
|
+
':==='.should be_parsed_as(LiteralMatcher.new(:===))
|
395
|
+
':=~'.should be_parsed_as(LiteralMatcher.new(:=~))
|
396
|
+
':>'.should be_parsed_as(LiteralMatcher.new(:>))
|
397
|
+
':>='.should be_parsed_as(LiteralMatcher.new(:>=))
|
398
|
+
':>>'.should be_parsed_as(LiteralMatcher.new(:>>))
|
399
|
+
':[]'.should be_parsed_as(LiteralMatcher.new(:[]))
|
400
|
+
':[]='.should be_parsed_as(LiteralMatcher.new(:[]=))
|
401
|
+
':^'.should be_parsed_as(LiteralMatcher.new(:^))
|
402
|
+
':`'.should be_parsed_as(LiteralMatcher.new(:`))
|
403
|
+
':|'.should be_parsed_as(LiteralMatcher.new(:|))
|
404
|
+
':~'.should be_parsed_as(LiteralMatcher.new(:~))
|
405
|
+
end
|
406
|
+
|
278
407
|
# Canonical STRING is "\"abcd\"".
|
279
408
|
it "parses STRING" do
|
280
409
|
"''".should be_parsed_as(LiteralMatcher.new(""))
|
@@ -309,6 +438,50 @@ module Machete
|
|
309
438
|
'"abc"'.should be_parsed_as(LiteralMatcher.new("abc"))
|
310
439
|
end
|
311
440
|
|
441
|
+
# Canonical REGEXP is /regexp/.
|
442
|
+
it "parses REGEXP" do
|
443
|
+
'//'.should be_parsed_as(LiteralMatcher.new(//))
|
444
|
+
'/a/'.should be_parsed_as(LiteralMatcher.new(/a/))
|
445
|
+
'/\\\\/'.should be_parsed_as(LiteralMatcher.new(/\\/))
|
446
|
+
'/\//'.should be_parsed_as(LiteralMatcher.new(/\//))
|
447
|
+
'/\\n/'.should be_parsed_as(LiteralMatcher.new(/\n/))
|
448
|
+
'/\\t/'.should be_parsed_as(LiteralMatcher.new(/\t/))
|
449
|
+
'/\\r/'.should be_parsed_as(LiteralMatcher.new(/\r/))
|
450
|
+
'/\\f/'.should be_parsed_as(LiteralMatcher.new(/\f/))
|
451
|
+
'/\\v/'.should be_parsed_as(LiteralMatcher.new(/\v/))
|
452
|
+
'/\\a/'.should be_parsed_as(LiteralMatcher.new(/\a/))
|
453
|
+
'/\\e/'.should be_parsed_as(LiteralMatcher.new(/\e/))
|
454
|
+
'/\\b/'.should be_parsed_as(LiteralMatcher.new(/\b/))
|
455
|
+
'/\\s/'.should be_parsed_as(LiteralMatcher.new(/\s/))
|
456
|
+
'/\\(/'.should be_parsed_as(LiteralMatcher.new(/\(/))
|
457
|
+
'/\\)/'.should be_parsed_as(LiteralMatcher.new(/\)/))
|
458
|
+
'/\\[/'.should be_parsed_as(LiteralMatcher.new(/\[/))
|
459
|
+
'/\\]/'.should be_parsed_as(LiteralMatcher.new(/\]/))
|
460
|
+
'/\\{/'.should be_parsed_as(LiteralMatcher.new(/\{/))
|
461
|
+
'/\\}/'.should be_parsed_as(LiteralMatcher.new(/\}/))
|
462
|
+
'/\\-/'.should be_parsed_as(LiteralMatcher.new(/\-/))
|
463
|
+
'/\\./'.should be_parsed_as(LiteralMatcher.new(/\./))
|
464
|
+
'/\\?/'.should be_parsed_as(LiteralMatcher.new(/\?/))
|
465
|
+
'/\\*/'.should be_parsed_as(LiteralMatcher.new(/\*/))
|
466
|
+
'/\\+/'.should be_parsed_as(LiteralMatcher.new(/\+/))
|
467
|
+
'/\\|/'.should be_parsed_as(LiteralMatcher.new(/\|/))
|
468
|
+
'/\\^/'.should be_parsed_as(LiteralMatcher.new(/\^/))
|
469
|
+
'/\\$/'.should be_parsed_as(LiteralMatcher.new(/\$/))
|
470
|
+
'/\\00/'.should be_parsed_as(LiteralMatcher.new(/\00/))
|
471
|
+
'/\\07/'.should be_parsed_as(LiteralMatcher.new(/\07/))
|
472
|
+
'/\\70/'.should be_parsed_as(LiteralMatcher.new(/\70/))
|
473
|
+
'/\\77/'.should be_parsed_as(LiteralMatcher.new(/\77/))
|
474
|
+
'/\\123/'.should be_parsed_as(LiteralMatcher.new(/\123/))
|
475
|
+
'/\\x0/'.should be_parsed_as(LiteralMatcher.new(/\x0/))
|
476
|
+
'/\\x9/'.should be_parsed_as(LiteralMatcher.new(/\x9/))
|
477
|
+
'/\\xa/'.should be_parsed_as(LiteralMatcher.new(/\xa/))
|
478
|
+
'/\\xf/'.should be_parsed_as(LiteralMatcher.new(/\xf/))
|
479
|
+
'/\\xA/'.should be_parsed_as(LiteralMatcher.new(/\xA/))
|
480
|
+
'/\\xF/'.should be_parsed_as(LiteralMatcher.new(/\xF/))
|
481
|
+
'/\\x12/'.should be_parsed_as(LiteralMatcher.new(/\x12/))
|
482
|
+
'/abc/'.should be_parsed_as(LiteralMatcher.new(/abc/))
|
483
|
+
end
|
484
|
+
|
312
485
|
# Canonical ANY is "any".
|
313
486
|
it "parses ANY" do
|
314
487
|
'any'.should be_parsed_as(AnyMatcher.new)
|
@@ -382,64 +555,6 @@ module Machete
|
|
382
555
|
'Abcd'.should be_parsed_as(NodeMatcher.new(:Abcd))
|
383
556
|
end
|
384
557
|
|
385
|
-
# Canonical SYMBOL is ":a".
|
386
|
-
it "parses SYMBOL" do
|
387
|
-
# Class names
|
388
|
-
':A'.should be_parsed_as(LiteralMatcher.new(:A))
|
389
|
-
':Z'.should be_parsed_as(LiteralMatcher.new(:Z))
|
390
|
-
':Aa'.should be_parsed_as(LiteralMatcher.new(:Aa))
|
391
|
-
':Az'.should be_parsed_as(LiteralMatcher.new(:Az))
|
392
|
-
':AA'.should be_parsed_as(LiteralMatcher.new(:AA))
|
393
|
-
':AZ'.should be_parsed_as(LiteralMatcher.new(:AZ))
|
394
|
-
':A0'.should be_parsed_as(LiteralMatcher.new(:A0))
|
395
|
-
':A9'.should be_parsed_as(LiteralMatcher.new(:A9))
|
396
|
-
':A_'.should be_parsed_as(LiteralMatcher.new(:A_))
|
397
|
-
':Abcd'.should be_parsed_as(LiteralMatcher.new(:Abcd))
|
398
|
-
|
399
|
-
# Regular method names
|
400
|
-
':a'.should be_parsed_as(LiteralMatcher.new(:a))
|
401
|
-
':z'.should be_parsed_as(LiteralMatcher.new(:z))
|
402
|
-
':_'.should be_parsed_as(LiteralMatcher.new(:_))
|
403
|
-
':aa'.should be_parsed_as(LiteralMatcher.new(:aa))
|
404
|
-
':az'.should be_parsed_as(LiteralMatcher.new(:az))
|
405
|
-
':aA'.should be_parsed_as(LiteralMatcher.new(:aA))
|
406
|
-
':aZ'.should be_parsed_as(LiteralMatcher.new(:aZ))
|
407
|
-
':a0'.should be_parsed_as(LiteralMatcher.new(:a0))
|
408
|
-
':a9'.should be_parsed_as(LiteralMatcher.new(:a9))
|
409
|
-
':a_'.should be_parsed_as(LiteralMatcher.new(:a_))
|
410
|
-
':abcd'.should be_parsed_as(LiteralMatcher.new(:abcd))
|
411
|
-
':a?'.should be_parsed_as(LiteralMatcher.new(:a?))
|
412
|
-
':a!'.should be_parsed_as(LiteralMatcher.new(:a!))
|
413
|
-
':a='.should be_parsed_as(LiteralMatcher.new(:a=))
|
414
|
-
|
415
|
-
# Operators (sorted alphabetically)
|
416
|
-
':%'.should be_parsed_as(LiteralMatcher.new(:%))
|
417
|
-
':&'.should be_parsed_as(LiteralMatcher.new(:&))
|
418
|
-
':*'.should be_parsed_as(LiteralMatcher.new(:*))
|
419
|
-
':**'.should be_parsed_as(LiteralMatcher.new(:**))
|
420
|
-
':+'.should be_parsed_as(LiteralMatcher.new(:+))
|
421
|
-
':+@'.should be_parsed_as(LiteralMatcher.new(:+@))
|
422
|
-
':-'.should be_parsed_as(LiteralMatcher.new(:-))
|
423
|
-
':-@'.should be_parsed_as(LiteralMatcher.new(:-@))
|
424
|
-
':/'.should be_parsed_as(LiteralMatcher.new(:/))
|
425
|
-
':<'.should be_parsed_as(LiteralMatcher.new(:<))
|
426
|
-
':<<'.should be_parsed_as(LiteralMatcher.new(:<<))
|
427
|
-
':<='.should be_parsed_as(LiteralMatcher.new(:<=))
|
428
|
-
':<=>'.should be_parsed_as(LiteralMatcher.new(:<=>))
|
429
|
-
':=='.should be_parsed_as(LiteralMatcher.new(:==))
|
430
|
-
':==='.should be_parsed_as(LiteralMatcher.new(:===))
|
431
|
-
':=~'.should be_parsed_as(LiteralMatcher.new(:=~))
|
432
|
-
':>'.should be_parsed_as(LiteralMatcher.new(:>))
|
433
|
-
':>='.should be_parsed_as(LiteralMatcher.new(:>=))
|
434
|
-
':>>'.should be_parsed_as(LiteralMatcher.new(:>>))
|
435
|
-
':[]'.should be_parsed_as(LiteralMatcher.new(:[]))
|
436
|
-
':[]='.should be_parsed_as(LiteralMatcher.new(:[]=))
|
437
|
-
':^'.should be_parsed_as(LiteralMatcher.new(:^))
|
438
|
-
':`'.should be_parsed_as(LiteralMatcher.new(:`))
|
439
|
-
':|'.should be_parsed_as(LiteralMatcher.new(:|))
|
440
|
-
':~'.should be_parsed_as(LiteralMatcher.new(:~))
|
441
|
-
end
|
442
|
-
|
443
558
|
it "skips whitespace before tokens" do
|
444
559
|
'42'.should be_parsed_as(@i42)
|
445
560
|
' 42'.should be_parsed_as(@i42)
|