machete 0.4.0 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- 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)
|