machete 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +10 -0
- data/VERSION +1 -1
- data/lib/machete/parser.y +52 -11
- data/spec/machete/parser_spec.rb +81 -4
- metadata +5 -4
data/CHANGELOG
ADDED
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.2.0
|
data/lib/machete/parser.y
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
class Machete::Parser
|
2
2
|
|
3
|
-
token
|
3
|
+
token METHOD_NAME
|
4
4
|
token CLASS_NAME
|
5
5
|
token SYMBOL
|
6
6
|
token INTEGER
|
@@ -32,7 +32,14 @@ node : CLASS_NAME {
|
|
32
32
|
attrs : attr
|
33
33
|
| attrs "," attr { result = val[0].merge(val[2]) }
|
34
34
|
|
35
|
-
attr :
|
35
|
+
attr : method_name "=" expression { result = { val[0].to_sym => val[2] } }
|
36
|
+
|
37
|
+
# Hack to overcome the fact that "<", ">" and "|" will lex as simple tokens, not
|
38
|
+
# METHOD_NAME tokens.
|
39
|
+
method_name : METHOD_NAME
|
40
|
+
| "<"
|
41
|
+
| ">"
|
42
|
+
| "|"
|
36
43
|
|
37
44
|
literal : SYMBOL { result = LiteralMatcher.new(val[0][1..-1].to_sym) }
|
38
45
|
| INTEGER {
|
@@ -94,9 +101,8 @@ private
|
|
94
101
|
SIMPLE_TOKENS = ["|", "<", ">", ",", "="]
|
95
102
|
|
96
103
|
COMPLEX_TOKENS = [
|
97
|
-
|
98
|
-
|
99
|
-
[:SYMBOL, /^:[a-zA-Z_][a-zA-Z0-9_]*/],
|
104
|
+
# INTEGER needs to be before METHOD_NAME, otherwise e.g. "+1" would be
|
105
|
+
# recognized as two tokens.
|
100
106
|
[
|
101
107
|
:INTEGER,
|
102
108
|
/^
|
@@ -144,6 +150,38 @@ COMPLEX_TOKENS = [
|
|
144
150
|
"
|
145
151
|
)
|
146
152
|
/x
|
153
|
+
],
|
154
|
+
# We exclude "<", ">" and "|" from method names since they are lexed as simple
|
155
|
+
# tokens. This is because they have also other meanings in Machette patterns
|
156
|
+
# beside Ruby method names.
|
157
|
+
[
|
158
|
+
:METHOD_NAME,
|
159
|
+
/^
|
160
|
+
(
|
161
|
+
# regular name
|
162
|
+
[a-z_][a-zA-Z0-9_]*[?!=]?
|
163
|
+
|
|
164
|
+
# operator (sorted by length, then alphabetically)
|
165
|
+
(<=>|===|\[\]=|\*\*|\+@|-@|<<|<=|==|=~|>=|>>|\[\]|[%&*+\-\/^`~])
|
166
|
+
)
|
167
|
+
/x
|
168
|
+
],
|
169
|
+
[:CLASS_NAME, /^[A-Z][a-zA-Z0-9_]*/],
|
170
|
+
[
|
171
|
+
:SYMBOL,
|
172
|
+
/^
|
173
|
+
:
|
174
|
+
(
|
175
|
+
# class name
|
176
|
+
[A-Z][a-zA-Z0-9_]*
|
177
|
+
|
|
178
|
+
# regular method name
|
179
|
+
[a-z_][a-zA-Z0-9_]*[?!=]?
|
180
|
+
|
|
181
|
+
# operator (sorted by length, then alphabetically)
|
182
|
+
(<=>|===|\[\]=|\*\*|\+@|-@|<<|<=|==|=~|>=|>>|\[\]|[%&*+\-\/<>^`|~])
|
183
|
+
)
|
184
|
+
/x
|
147
185
|
]
|
148
186
|
]
|
149
187
|
|
@@ -152,12 +190,8 @@ def next_token
|
|
152
190
|
|
153
191
|
return false if remaining_input.empty?
|
154
192
|
|
155
|
-
|
156
|
-
|
157
|
-
@pos += token.length
|
158
|
-
return [token, token]
|
159
|
-
end
|
160
|
-
end
|
193
|
+
# Complex tokens need to be before simple tokens, otherwise e.g. "<<" would be
|
194
|
+
# recognized as two tokens.
|
161
195
|
|
162
196
|
COMPLEX_TOKENS.each do |type, regexp|
|
163
197
|
if remaining_input =~ regexp
|
@@ -166,6 +200,13 @@ def next_token
|
|
166
200
|
end
|
167
201
|
end
|
168
202
|
|
203
|
+
SIMPLE_TOKENS.each do |token|
|
204
|
+
if remaining_input[0...token.length] == token
|
205
|
+
@pos += token.length
|
206
|
+
return [token, token]
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
169
210
|
raise SyntaxError, "Unexpected character: #{remaining_input[0..0].inspect}."
|
170
211
|
end
|
171
212
|
|
data/spec/machete/parser_spec.rb
CHANGED
@@ -65,6 +65,14 @@ module Machete
|
|
65
65
|
'Foo<a = 42 | 43>'.should be_parsed_as(NodeMatcher.new(:Foo, :a => @ch4243))
|
66
66
|
end
|
67
67
|
|
68
|
+
# Canonical method_name is "a".
|
69
|
+
it "parses method_name" do
|
70
|
+
'Foo<a = 42>'.should be_parsed_as(node_matcher_with_attr(:a))
|
71
|
+
'Foo< < = 42>'.should be_parsed_as(node_matcher_with_attr(:<))
|
72
|
+
'Foo<> = 42>'.should be_parsed_as(node_matcher_with_attr(:>))
|
73
|
+
'Foo<| = 42>'.should be_parsed_as(node_matcher_with_attr(:|))
|
74
|
+
end
|
75
|
+
|
68
76
|
# Canonical literal is "42".
|
69
77
|
it "parses literal" do
|
70
78
|
':a'.should be_parsed_as(LiteralMatcher.new(:a))
|
@@ -72,8 +80,9 @@ module Machete
|
|
72
80
|
'"abcd"'.should be_parsed_as(LiteralMatcher.new("abcd"))
|
73
81
|
end
|
74
82
|
|
75
|
-
# Canonical
|
76
|
-
it "parses
|
83
|
+
# Canonical METHOD_NAME is "a".
|
84
|
+
it "parses METHOD_NAME" do
|
85
|
+
# Regular names
|
77
86
|
'Foo<a = 42>'.should be_parsed_as(node_matcher_with_attr(:a))
|
78
87
|
'Foo<z = 42>'.should be_parsed_as(node_matcher_with_attr(:z))
|
79
88
|
'Foo<_ = 42>'.should be_parsed_as(node_matcher_with_attr(:_))
|
@@ -85,6 +94,33 @@ module Machete
|
|
85
94
|
'Foo<a9 = 42>'.should be_parsed_as(node_matcher_with_attr(:a9))
|
86
95
|
'Foo<a_ = 42>'.should be_parsed_as(node_matcher_with_attr(:a_))
|
87
96
|
'Foo<abcd = 42>'.should be_parsed_as(node_matcher_with_attr(:abcd))
|
97
|
+
'Foo<a? = 42>'.should be_parsed_as(node_matcher_with_attr(:a?))
|
98
|
+
'Foo<a! = 42>'.should be_parsed_as(node_matcher_with_attr(:a!))
|
99
|
+
'Foo<a= = 42>'.should be_parsed_as(node_matcher_with_attr(:a=))
|
100
|
+
|
101
|
+
# Operators (sorted alphabetically)
|
102
|
+
'Foo<% = 42>'.should be_parsed_as(node_matcher_with_attr(:%))
|
103
|
+
'Foo<& = 42>'.should be_parsed_as(node_matcher_with_attr(:&))
|
104
|
+
'Foo<* = 42>'.should be_parsed_as(node_matcher_with_attr(:*))
|
105
|
+
'Foo<** = 42>'.should be_parsed_as(node_matcher_with_attr(:**))
|
106
|
+
'Foo<+ = 42>'.should be_parsed_as(node_matcher_with_attr(:+))
|
107
|
+
'Foo<+@ = 42>'.should be_parsed_as(node_matcher_with_attr(:+@))
|
108
|
+
'Foo<- = 42>'.should be_parsed_as(node_matcher_with_attr(:-))
|
109
|
+
'Foo<-@ = 42>'.should be_parsed_as(node_matcher_with_attr(:-@))
|
110
|
+
'Foo</ = 42>'.should be_parsed_as(node_matcher_with_attr(:/))
|
111
|
+
'Foo< << = 42>'.should be_parsed_as(node_matcher_with_attr(:<<))
|
112
|
+
'Foo< <= = 42>'.should be_parsed_as(node_matcher_with_attr(:<=))
|
113
|
+
'Foo< <=> = 42>'.should be_parsed_as(node_matcher_with_attr(:<=>))
|
114
|
+
'Foo< == = 42>'.should be_parsed_as(node_matcher_with_attr(:==))
|
115
|
+
'Foo< === = 42>'.should be_parsed_as(node_matcher_with_attr(:===))
|
116
|
+
'Foo< =~ = 42>'.should be_parsed_as(node_matcher_with_attr(:=~))
|
117
|
+
'Foo<>= = 42>'.should be_parsed_as(node_matcher_with_attr(:>=))
|
118
|
+
'Foo<>> = 42>'.should be_parsed_as(node_matcher_with_attr(:>>))
|
119
|
+
'Foo<[] = 42>'.should be_parsed_as(node_matcher_with_attr(:[]))
|
120
|
+
'Foo<[]= = 42>'.should be_parsed_as(node_matcher_with_attr(:[]=))
|
121
|
+
'Foo<^ = 42>'.should be_parsed_as(node_matcher_with_attr(:^))
|
122
|
+
'Foo<` = 42>'.should be_parsed_as(node_matcher_with_attr(:`))
|
123
|
+
'Foo<~ = 42>'.should be_parsed_as(node_matcher_with_attr(:~))
|
88
124
|
end
|
89
125
|
|
90
126
|
# Canonical CLASS_NAME is "A".
|
@@ -103,10 +139,21 @@ module Machete
|
|
103
139
|
|
104
140
|
# Canonical SYMBOL is ":a".
|
105
141
|
it "parses SYMBOL" do
|
106
|
-
|
107
|
-
':z'.should be_parsed_as(LiteralMatcher.new(:z))
|
142
|
+
# Class names
|
108
143
|
':A'.should be_parsed_as(LiteralMatcher.new(:A))
|
109
144
|
':Z'.should be_parsed_as(LiteralMatcher.new(:Z))
|
145
|
+
':Aa'.should be_parsed_as(LiteralMatcher.new(:Aa))
|
146
|
+
':Az'.should be_parsed_as(LiteralMatcher.new(:Az))
|
147
|
+
':AA'.should be_parsed_as(LiteralMatcher.new(:AA))
|
148
|
+
':AZ'.should be_parsed_as(LiteralMatcher.new(:AZ))
|
149
|
+
':A0'.should be_parsed_as(LiteralMatcher.new(:A0))
|
150
|
+
':A9'.should be_parsed_as(LiteralMatcher.new(:A9))
|
151
|
+
':A_'.should be_parsed_as(LiteralMatcher.new(:A_))
|
152
|
+
':Abcd'.should be_parsed_as(LiteralMatcher.new(:Abcd))
|
153
|
+
|
154
|
+
# Regular method names
|
155
|
+
':a'.should be_parsed_as(LiteralMatcher.new(:a))
|
156
|
+
':z'.should be_parsed_as(LiteralMatcher.new(:z))
|
110
157
|
':_'.should be_parsed_as(LiteralMatcher.new(:_))
|
111
158
|
':aa'.should be_parsed_as(LiteralMatcher.new(:aa))
|
112
159
|
':az'.should be_parsed_as(LiteralMatcher.new(:az))
|
@@ -116,6 +163,36 @@ module Machete
|
|
116
163
|
':a9'.should be_parsed_as(LiteralMatcher.new(:a9))
|
117
164
|
':a_'.should be_parsed_as(LiteralMatcher.new(:a_))
|
118
165
|
':abcd'.should be_parsed_as(LiteralMatcher.new(:abcd))
|
166
|
+
':a?'.should be_parsed_as(LiteralMatcher.new(:a?))
|
167
|
+
':a!'.should be_parsed_as(LiteralMatcher.new(:a!))
|
168
|
+
':a='.should be_parsed_as(LiteralMatcher.new(:a=))
|
169
|
+
|
170
|
+
# Operators (sorted alphabetically)
|
171
|
+
':%'.should be_parsed_as(LiteralMatcher.new(:%))
|
172
|
+
':&'.should be_parsed_as(LiteralMatcher.new(:&))
|
173
|
+
':*'.should be_parsed_as(LiteralMatcher.new(:*))
|
174
|
+
':**'.should be_parsed_as(LiteralMatcher.new(:**))
|
175
|
+
':+'.should be_parsed_as(LiteralMatcher.new(:+))
|
176
|
+
':+@'.should be_parsed_as(LiteralMatcher.new(:+@))
|
177
|
+
':-'.should be_parsed_as(LiteralMatcher.new(:-))
|
178
|
+
':-@'.should be_parsed_as(LiteralMatcher.new(:-@))
|
179
|
+
':/'.should be_parsed_as(LiteralMatcher.new(:/))
|
180
|
+
':<'.should be_parsed_as(LiteralMatcher.new(:<))
|
181
|
+
':<<'.should be_parsed_as(LiteralMatcher.new(:<<))
|
182
|
+
':<='.should be_parsed_as(LiteralMatcher.new(:<=))
|
183
|
+
':<=>'.should be_parsed_as(LiteralMatcher.new(:<=>))
|
184
|
+
':=='.should be_parsed_as(LiteralMatcher.new(:==))
|
185
|
+
':==='.should be_parsed_as(LiteralMatcher.new(:===))
|
186
|
+
':=~'.should be_parsed_as(LiteralMatcher.new(:=~))
|
187
|
+
':>'.should be_parsed_as(LiteralMatcher.new(:>))
|
188
|
+
':>='.should be_parsed_as(LiteralMatcher.new(:>=))
|
189
|
+
':>>'.should be_parsed_as(LiteralMatcher.new(:>>))
|
190
|
+
':[]'.should be_parsed_as(LiteralMatcher.new(:[]))
|
191
|
+
':[]='.should be_parsed_as(LiteralMatcher.new(:[]=))
|
192
|
+
':^'.should be_parsed_as(LiteralMatcher.new(:^))
|
193
|
+
':`'.should be_parsed_as(LiteralMatcher.new(:`))
|
194
|
+
':|'.should be_parsed_as(LiteralMatcher.new(:|))
|
195
|
+
':~'.should be_parsed_as(LiteralMatcher.new(:~))
|
119
196
|
end
|
120
197
|
|
121
198
|
# Canonical INTEGER is "42".
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: machete
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 23
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
8
|
+
- 2
|
9
9
|
- 0
|
10
|
-
version: 0.
|
10
|
+
version: 0.2.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- David Majda
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-
|
18
|
+
date: 2011-08-17 00:00:00 +02:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -99,6 +99,7 @@ extra_rdoc_files: []
|
|
99
99
|
files:
|
100
100
|
- .gitignore
|
101
101
|
- .yardopts
|
102
|
+
- CHANGELOG
|
102
103
|
- LICENSE
|
103
104
|
- README.md
|
104
105
|
- Rakefile
|