machete 0.1.0 → 0.2.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/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
|