machete 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,10 @@
1
+ 0.2.0 (2011-08-17)
2
+ ------------------
3
+
4
+ * Extended method name grammar to cover more Ruby method names.
5
+ * Extended symbol grammar to cover more Ruby symbols.
6
+
7
+ 0.1.0 (2011-07-27)
8
+ ------------------
9
+
10
+ * Initial release.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.0
1
+ 0.2.0
@@ -1,6 +1,6 @@
1
1
  class Machete::Parser
2
2
 
3
- token VAR_NAME
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 : VAR_NAME "=" expression { result = { val[0].to_sym => val[2] } }
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
- [:VAR_NAME, /^[a-z_][a-zA-Z0-9_]*/],
98
- [:CLASS_NAME, /^[A-Z][a-zA-Z0-9_]*/],
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
- SIMPLE_TOKENS.each do |token|
156
- if remaining_input[0...token.length] == token
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
 
@@ -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 VAR_NAME is "a".
76
- it "parses VAR_NAME" do
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
- ':a'.should be_parsed_as(LiteralMatcher.new(:a))
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: 27
4
+ hash: 23
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
- - 1
8
+ - 2
9
9
  - 0
10
- version: 0.1.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-07-27 00:00:00 +02:00
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