codercmp 0.9.7

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.
@@ -0,0 +1,365 @@
1
+ require 'codercompanion/common_namespace'
2
+
3
+ module CoderCompanion
4
+
5
+ module Java
6
+ # include Literals
7
+ include CoderCompanion::Common
8
+
9
+ def self.extract_privacy(member_qualifiers)
10
+ privacy = 'private'
11
+ qualifiers = member_qualifiers.split(/\s+/)
12
+ if !qualifiers.empty? and qualifiers.first.match(/(public|protected)/)
13
+ privacy = qualifiers.first
14
+ end
15
+ return privacy
16
+ end
17
+
18
+ def self.has_final_qualifier(member_qualifiers)
19
+ return true if member_qualifiers.match(/final/)
20
+ false
21
+ end
22
+
23
+ def self.has_static_qualifier(member_qualifiers)
24
+ return true if member_qualifiers.match(/static/)
25
+ false
26
+ end
27
+
28
+ def self.remove_nested_pattern(value, pattern_to_search, pattern_to_remove)
29
+ loop do
30
+ has_pattern = value.match(pattern_to_search)
31
+ if has_pattern
32
+ value = value.gsub(pattern_to_remove, '')
33
+ else
34
+ break
35
+ end
36
+ end
37
+ return value
38
+ end
39
+
40
+ def self.remove_nested_brackets(value)
41
+ return self.remove_nested_pattern(value, /[\(\)]/, /(\([^\(\)]*\))/)
42
+ end
43
+
44
+ def self.remove_generics(value)
45
+ return self.remove_nested_pattern(value, /[<>]/, /(<[^<>]*>)/)
46
+ end
47
+
48
+ class SourceFile2 < Treetop::Runtime::SyntaxNode
49
+ def build
50
+ els = []
51
+ elements.each do |e|
52
+ next unless e and e.elements
53
+ e.elements.each do |inner_e|
54
+ els.push(inner_e.elements.first.build) if inner_e.respond_to?(:class_definition)
55
+ end
56
+ end
57
+ return els
58
+ end
59
+ end
60
+
61
+ class Interface2 < Treetop::Runtime::SyntaxNode
62
+ def build
63
+ comma_separated_list = CoderCompanion::Java.remove_generics(text_value)
64
+ comma_separated_list.gsub!(/implements\s/,'')
65
+ return comma_separated_list.split(/\s*,\s*/)
66
+ end
67
+
68
+ end
69
+
70
+ class ClassDefinitions < Treetop::Runtime::SyntaxNode
71
+ def build
72
+ els = []
73
+ privacy = ''
74
+ class_name = ''
75
+ inherits_from = ''
76
+ element_type = ''
77
+ implements = []
78
+ elements.each do |e|
79
+ if e.respond_to?(:class_qualifiers)
80
+ privacy = ::CoderCompanion::Java.extract_privacy(e.text_value)
81
+ end
82
+ if e.respond_to?(:class_or_enum)
83
+ element_type = e.text_value
84
+ next
85
+ end
86
+ if e.respond_to?(:class_name)
87
+ class_name = e.text_value
88
+ next
89
+ end
90
+ if e.respond_to?(:inheritance)
91
+ inherits_from = e.text_value.gsub(/extends\s+/, '')
92
+ inherits_from = inherits_from.gsub(/<.*>/, '')
93
+ next
94
+ end
95
+ if e.respond_to?(:implements)
96
+ implements = e.elements.first.build # reach into child's elements
97
+ next
98
+ end
99
+ if e.respond_to?(:class_body)
100
+ els.concat(e.elements.first.build)
101
+ next
102
+ end
103
+ end
104
+ ret = {:type => "#{element_type}_definition", :value => class_name, :privacy => privacy, :inherits_from => inherits_from, :implements => implements, :class_elements => els}
105
+ return ret
106
+ end
107
+ end
108
+
109
+
110
+ class ClassBody2 < Treetop::Runtime::SyntaxNode
111
+ def build
112
+ els = []
113
+ elements.each do |e|
114
+ next if e.elements.nil?
115
+ e.elements.each do |inner_e|
116
+ els.concat(inner_e.build) if inner_e.respond_to?(:build)
117
+ end
118
+ end
119
+ return els
120
+ end
121
+ end
122
+
123
+ class ClassBodyDeclaration < Treetop::Runtime::SyntaxNode
124
+ def build
125
+ els = []
126
+ elements.each do |e|
127
+ if e.respond_to? :class_element
128
+ e.elements.each do |inner_e|
129
+ els.push(inner_e.build) if inner_e.respond_to? :build
130
+ end
131
+ end
132
+ els.concat(e.build) if e.respond_to?(:build)
133
+ end
134
+ return els
135
+ end
136
+ end
137
+
138
+ class ClassQualifiers < Treetop::Runtime::SyntaxNode
139
+ def build
140
+ elements.each do |e|
141
+ end
142
+ end
143
+ end
144
+
145
+ class CommaSeparatedConstants < Treetop::Runtime::SyntaxNode
146
+ def build
147
+ els = []
148
+ no_comments = text_value.gsub(/"(\\"|[^"])*"/, '')
149
+ no_comments = no_comments.gsub(/(\/\/[^\n]*\n+|\/\*(?:.|[\r\n])*?\*\/)/, '') #Remove comments
150
+ no_comments = CoderCompanion::Java.remove_nested_brackets(no_comments)
151
+ values = no_comments.split(/\s*,\s*/)
152
+ enum_constants = []
153
+ values.each do |e|
154
+ e.strip! #Trim white spaces
155
+ enum_constants.push( {:type => 'enum_constant', :value => e.gsub(/[\\n]/, '')} ) unless e.match(/;/)
156
+ end
157
+ return enum_constants
158
+ end
159
+ end
160
+
161
+ class VariableDeclarationList < Treetop::Runtime::SyntaxNode
162
+ def build
163
+ variables = []
164
+ elements.each do |e|
165
+ variables.push(e.text_value) if e.respond_to? :variable_defined
166
+ variables.concat(e.build) if e.respond_to? :build
167
+ end
168
+ return variables
169
+ end
170
+ end
171
+
172
+ class NextVariable < Treetop::Runtime::SyntaxNode
173
+ def build
174
+ variables = []
175
+ elements.each do |e|
176
+ variables.push(e.text_value) if e.respond_to? :variable_defined
177
+ variables.concat(e.build) if e.respond_to? :build
178
+ end
179
+ return variables
180
+ end
181
+ end
182
+
183
+ class MemberVariable < Treetop::Runtime::SyntaxNode
184
+ def build
185
+ variable_type = ''
186
+ privacy = ''
187
+ variable_name = ''
188
+ type = ''
189
+ qualifiers = []
190
+ variables = []
191
+ elements.each do |e|
192
+ if e.respond_to? :qualifiers
193
+ qualifiers = e.elements[0].text_value
194
+ privacy = CoderCompanion::Java.extract_privacy(qualifiers)
195
+ if CoderCompanion::Java.has_final_qualifier(qualifiers) && CoderCompanion::Java.has_static_qualifier(qualifiers)
196
+ variable_type = 'constant'
197
+ elsif !CoderCompanion::Java.has_final_qualifier(qualifiers) && CoderCompanion::Java.has_static_qualifier(qualifiers)
198
+ variable_type = 'class_variable'
199
+ else
200
+ variable_type = 'instance_variable'
201
+ end
202
+ end
203
+ variables = e.build if e.respond_to? :build
204
+ type = e.text_value if e.respond_to? :type
205
+ variable_name = e.text_value if e.respond_to? :variable_defined
206
+ end
207
+
208
+ to_return = []
209
+ variables.each do |v|
210
+ to_return.push( {:type => 'variable_definition', :value => v.gsub(/[\s]+/, ' '), :return_type => type, :privacy => privacy, :variable_type => variable_type})
211
+ end
212
+ return to_return
213
+ end
214
+ end
215
+
216
+ class ConstructorDefinition < Treetop::Runtime::SyntaxNode
217
+ def build
218
+ privacy = ''
219
+ method_text = ''
220
+ elements.each do |e|
221
+ privacy = e.text_value if e.respond_to? :privacy
222
+ method_text = e.text_value if e.respond_to? :method_defined
223
+ end
224
+ return [{:type => 'constructor_definition', :value => method_text.gsub(/[\s]+/, ' '), :privacy => privacy}]
225
+ end
226
+ end
227
+
228
+ class MethodDefinition < Treetop::Runtime::SyntaxNode
229
+ def build
230
+ class_method = false
231
+ params = []
232
+ privacy = ''
233
+ method_text = ''
234
+ return_type = ''
235
+ qualifiers = []
236
+ elements.each do |e|
237
+ if e.respond_to? :qualifiers
238
+ qualifiers = e.elements[0].text_value
239
+ privacy = CoderCompanion::Java.extract_privacy(qualifiers)
240
+ if (CoderCompanion::Java.has_static_qualifier(qualifiers) )
241
+ class_method = true
242
+ end
243
+ end
244
+ return_type = e.text_value if e.respond_to? :return_type
245
+ method_text = e.text_value if e.respond_to? :method_defined
246
+ if e.respond_to? :method_defined
247
+ e.elements[0].elements.each do |f|
248
+ s_params = CoderCompanion::Java.remove_generics(f.text_value) if f.respond_to? :params
249
+ if s_params
250
+ s_params = s_params.gsub(/@[^\s]+\s+/, '') #Remove annotation for parameters
251
+ s_params = s_params.gsub(/\sfinal\s/, '') #Remove final keyword
252
+ s_params = s_params.gsub(/\.\.\./, '') #Remove the ellipsis at the end '...'
253
+ pre_params = s_params.split(/\s*\,\s*/)
254
+ pre_params.each do |p|
255
+ val_arr = p.split(/\s+/)
256
+ params.push({:type => val_arr[0], :value => val_arr[1]})
257
+ end
258
+ end
259
+ end
260
+ end
261
+ end
262
+ return [{:type => 'method_definition', :value => method_text.gsub(/[\s]+/, ' '), :params => params, :return_type => return_type, :privacy => privacy, :class_method => class_method}]
263
+ end
264
+ end
265
+
266
+ class Qualifiers < Treetop::Runtime::SyntaxNode
267
+ def build
268
+ els = []
269
+ elements.each do |e|
270
+ els.push(e.elements[0].text_value) if e.respond_to? :qualifier
271
+ end
272
+ return els
273
+ end
274
+ end
275
+
276
+ class InterfaceDefinition < Treetop::Runtime::SyntaxNode
277
+ def build
278
+ els = []
279
+ class_name = ''
280
+ privacy = ''
281
+ inherits_from = ''
282
+ elements.each do |e|
283
+ inherits_from = e.elements[0].build if e.respond_to? :inheritance
284
+ class_name = e.text_value if e.respond_to? :class_name
285
+ privacy = e.text_value if e.respond_to? :privacy
286
+ if e.respond_to? :class_element
287
+ e.elements[0].elements.each {|f| els.push(f.build) if f.respond_to? :build }
288
+ end
289
+ end
290
+ return {:type => "interface_definition", :value => class_name, :privacy => privacy, :inherits_from => inherits_from, :class_elements => els}
291
+ end
292
+ end
293
+
294
+ class ClassDefinition < Treetop::Runtime::SyntaxNode
295
+ def build
296
+ els = []
297
+ class_name = ''
298
+ privacy = ''
299
+ inherits_from = ''
300
+ implements = []
301
+ element_type = ''
302
+ elements.each do |e|
303
+ element_type = e.text_value if e.respond_to? :class_or_enum
304
+ inherits_from = e.elements[0].build if e.respond_to? :inheritance
305
+ implements = e.elements[0].build if e.respond_to? :implements
306
+ class_name = e.text_value if e.respond_to? :class_name
307
+ privacy = e.text_value if e.respond_to? :privacy
308
+ if e.respond_to? :class_element
309
+ resp = nil
310
+ e.elements[0].elements.each do |f|
311
+ resp = f.build if f.respond_to? :build
312
+ if resp && resp.class.to_s == "Array"
313
+ els.concat(resp)
314
+ elsif resp
315
+ els.push(resp)
316
+ end
317
+ resp = nil
318
+ end
319
+ end
320
+ end
321
+ return {:type => "#{element_type}_definition", :value => class_name, :privacy => privacy, :inherits_from => inherits_from, :implements => implements, :class_elements => els}
322
+ end
323
+ end
324
+
325
+ class Inheritance < Treetop::Runtime::SyntaxNode
326
+ def build
327
+ result = ''
328
+ elements.each {|e| result = e.build if e.respond_to? :build}
329
+ return result
330
+ end
331
+ end
332
+
333
+ class Implementation < Treetop::Runtime::SyntaxNode
334
+ def build
335
+ implements = []
336
+ elements.each do |e|
337
+ val = e.build if e.respond_to? :build
338
+ if val && val.class.to_s == "Array"
339
+ implements.concat(val)
340
+ elsif val
341
+ implements.push(val)
342
+ end
343
+ end
344
+ return implements
345
+ end
346
+ end
347
+
348
+ class NextInterface < Treetop::Runtime::SyntaxNode
349
+ def build
350
+ els = []
351
+ elements.each do |e|
352
+ val = e.build if e.respond_to? :build
353
+ if val && val.class.to_s == "Array"
354
+ els.concat(val)
355
+ elsif val
356
+ els.push(val)
357
+ end
358
+ # els.push(e.text_value) if e.respond_to? :variable_defined
359
+ # els.concat(e.build) if e.respond_to? :build
360
+ end
361
+ return els
362
+ end
363
+ end
364
+ end
365
+ end
@@ -0,0 +1,283 @@
1
+ module CoderCompanion
2
+ grammar Java
3
+
4
+ rule fake_start
5
+ source_file_2
6
+ end
7
+
8
+
9
+ rule source_file_2
10
+ s? package? s? (import s)* s? multiple_annotations? s? (class_definition:class_definition_2 s?)* <SourceFile2>
11
+ end
12
+
13
+ rule package
14
+ 'package' s? !'.' identifier s? ('.' s? identifier )* s? ';'
15
+ end
16
+
17
+ rule import
18
+ 'import' s? 'static'? s? !'.' identifier s? ('.' s? ( identifier / '*') )* s? ';'
19
+ end
20
+
21
+ rule comment_2
22
+ ('/*' (!'*/' .)* '*/' ) / '//' (![\n] .)* [\n]
23
+ end
24
+
25
+ rule class_definition_2
26
+ (class_qualifiers:class_qualifiers_2*) s? (class_or_enum:('class'/'enum'/'interface'/'@' identifier)) s
27
+ (class_name:class_identifier) ( s? generics )? s? (inheritance:inheritance)? s?
28
+ (implements:interfaces_2)? s? (class_body:class_body_2) s? <ClassDefinitions>
29
+ end
30
+
31
+ rule interfaces_2
32
+ 'implements' s? qualified_name (s? generics)? (s? ',' s? qualified_name (s? generics)? )* <Interface2>
33
+ end
34
+
35
+ rule class_body_2
36
+ '{' s? class_body_declaration_2* s? '}' <ClassBody2>
37
+ end
38
+
39
+ rule class_body_declaration_2
40
+ s? ';' / ('static' s) block_2 / s? member_declaration_2 <ClassBodyDeclaration>
41
+ end
42
+
43
+ rule variable_declaration_2
44
+ (qualifiers:general_qualifiers_2*) s? (type:type) s variable_declaration_list s? <MemberVariable>
45
+ end
46
+
47
+ rule variable_declaration_list
48
+ (variable_defined:identifier) s? (array_indicator)? s? ( method_assignment / block_assignment / assignment )? s? next_variable? s? ';' s? <VariableDeclarationList>
49
+ end
50
+
51
+ rule next_variable
52
+ s? ',' s? ( variable_defined:identifier ) s? (array_indicator?) s? ( method_assignment / block_assignment / assignment )? next_variable? <NextVariable>
53
+ end
54
+
55
+ rule method_definition_2
56
+ (qualifiers:general_qualifiers_2*) s? (return_type:type) s ( method_defined:method ) s? ('throws' s qualified_name_list)? s? ( '{' s? method_body? s? '}' / 'default' s? (string / (!";" .)*) s? ';' / ';' ) <MethodDefinition>
57
+ end
58
+
59
+ rule general_qualifiers_2
60
+ class_qualifier_2 / annotation s / generics s / ( 'native' s / 'synchronized' s / 'transient' s / 'volatile' s )
61
+ end
62
+
63
+ rule generics
64
+ '<' ( !angle_bracket . )* ( s? generics array_indicator?)? additional_generics s? '>'
65
+ end
66
+
67
+
68
+ rule additional_generics
69
+ ( s? ',' s? (!angle_bracket .)* (s? generics array_indicator?)? )*
70
+ end
71
+
72
+
73
+ rule angle_bracket
74
+ '<' / '>'
75
+ end
76
+
77
+ rule class_qualifiers_2
78
+ class_qualifier_2 (s class_qualifier_2)* <ClassQualifiers>
79
+ end
80
+
81
+ rule class_qualifier_2
82
+ 'public' s / 'protected' s / 'private' s / 'static' s / 'abstract' s / 'final' s / 'strictfp' s
83
+ end
84
+
85
+ rule member_declaration_2
86
+ s
87
+ / ('static' s) block_2
88
+ / annotation
89
+ / (class_element:class_definition_2)
90
+ / method_definition_2
91
+ / variable_declaration_2
92
+ / constructor
93
+ / comma_separated_constants_2
94
+ end
95
+
96
+ rule qualified_name_list
97
+ qualified_name s? (',' s? qualified_name)*
98
+ end
99
+
100
+ rule qualified_name
101
+ identifier ('.' identifier )*
102
+ end
103
+
104
+ rule comma_separated_constants_2
105
+ identifier s? ( '(' s? method_call_params? s? ')' )? (s? ',' s? ( identifier s? ( '(' s? method_call_params? s? ')' )? / ';' / s? ) )* <CommaSeparatedConstants>
106
+ end
107
+
108
+ rule block_2
109
+ #'{' s? block_2? s? (!curly_brackets .)* s? block_2? s? (!curly_brackets .)* s? block_2? s? '}'
110
+ '{' s? (block_2 s?)* s? (anything_but_curly_brackets? s? block_2 s?)* s? anything_but_curly_brackets? s? (block_2 s?)* s? '}'
111
+ end
112
+
113
+ rule multiple_annotations
114
+ annotation (s annotation)*
115
+ end
116
+
117
+ rule annotation
118
+ '@' qualified_name ( s? '(' (!')' .)* ')' )?
119
+ end
120
+
121
+ rule interface_definition
122
+ (privacy:privacy?) s? (qualifiers:qualifiers?) s? 'interface' s (class_name:class_identifier) s? (inheritance:inheritance)? s? (interfaces)? s? '{' s? ( class_element:class_element* ) s? '}' <InterfaceDefinition>
123
+ end
124
+
125
+ rule inheritance
126
+ 'extends' s qualified_name (s? generics)? next_interface? <Inheritance>
127
+ end
128
+
129
+ rule interfaces
130
+ 'implements' s qualified_name s? (array_indicator)? next_interface? <Implementation>
131
+ end
132
+
133
+ rule next_interface
134
+ s? ',' s? qualified_name s? (array_indicator)? next_interface? <NextInterface>
135
+ end
136
+
137
+ rule constructor
138
+ (privacy:privacy?) s? (qualifiers:qualifiers?) s? ( method_defined:method ) s? ('throws' s qualified_name_list)? s? '{' s? method_body? s? '}' <ConstructorDefinition>
139
+ end
140
+
141
+ rule interface_method_definition
142
+ (privacy:privacy?) s? (qualifiers:qualifiers?) s? (return_type:type) s ( method_defined:method ) s? ';' <MethodDefinition>
143
+ end
144
+
145
+ rule method_body
146
+ method_statement (s method_statement)*
147
+ end
148
+
149
+ rule method_statement
150
+ '(' ')'
151
+ /
152
+ comment_2
153
+ /
154
+ return_statement
155
+ /
156
+ statement
157
+ /
158
+ scope
159
+ end
160
+
161
+ rule return_statement
162
+ 'return' s? ( (!'new' qualified_name) s? '(' s? method_call_params? s? ')' s? ';' s? / return_new_object s? ';' / qualified_name method_call? s? ';' )
163
+ end
164
+
165
+ rule method_call_params
166
+ ( string / number / return_new_object / cast_statement / qualified_name method_call? / identifier ) next_method_call_params?
167
+ end
168
+
169
+ rule next_method_call_params
170
+ (s? ',' s? ( string / number / return_new_object / cast_statement / qualified_name method_call? / identifier ) ) next_method_call_params?
171
+ end
172
+
173
+ rule return_new_object
174
+ 'new' s class_identifier s? generics? s? '(' (!')' .)* ')' s '{' s? method_body s? '}'
175
+ end
176
+
177
+ rule method_call
178
+ '(' s? ( string / return_new_object / qualified_name method_call / cast_statement / (!'(' !')' .)* / '' ) s? ')' ('.' qualified_name method_call)?
179
+ end
180
+
181
+ rule cast_statement
182
+ '(' (!')' .)* ')' s? qualified_name method_call?
183
+ end
184
+
185
+ rule statement
186
+ (anything_but_curly_brackets &';') ';'
187
+ end
188
+
189
+ rule anything_but_semi_colon
190
+ [^;]+
191
+ end
192
+
193
+ rule scope
194
+ ( anything_but_curly_brackets '{' s? anything_but_curly_brackets s? scope? s? anything_but_curly_brackets s? '}' anything_but_curly_brackets scope? / anything_but_curly_brackets )
195
+ end
196
+
197
+ rule anything_but_curly_brackets
198
+ ( s / comment &{|seq| seq[0].is_valid_comment} / string / [^{}] / '.' / other_values )*
199
+ end
200
+
201
+ rule other_values
202
+ ( [\@@$] / "'@'" / "'@'" / "'.'" / "':'" / "'#'" / "'#'" )
203
+ end
204
+
205
+ rule assignment
206
+ '=' s? ( string / (!';' .) )*
207
+ end
208
+
209
+ rule method_assignment
210
+ '=' s? (!'new' qualified_name) s? '(' s? method_call_params s? ')' ('.' qualified_name method_call)? s?
211
+ end
212
+
213
+ rule block_assignment
214
+ '=' s? 'new' s (!curly_brackets !';' .)* s? block_2?
215
+ end
216
+
217
+ rule curly_brackets
218
+ '{' / '}'
219
+ end
220
+
221
+ rule privacy
222
+ ( 'public' <Identifier> / 'protected' <Identifier> / 'private' <Identifier> )
223
+ end
224
+
225
+ rule qualifiers
226
+ qualifier (s qualifier)* <Qualifiers>
227
+ end
228
+
229
+ rule qualifier
230
+ 'synchronized' / 'abstract' / 'static' / 'final' / 'const' / 'transient' / 'volatile' / 'strictfp'
231
+ end
232
+
233
+ rule method
234
+ ( qualified_name s? '(' s? ( multiple_annotations? s? !',' ('final' s)? (first_type:type) s? params:(identifier s? array_indicator*) rest_of_params:(s? ',' s? annotation? s? ('final' s)? (next_type:type) s? identifier s? array_indicator* )* )? s? ')' ) <Method>
235
+ end
236
+
237
+ rule type
238
+ ( !class_qualifiers_2 !'class' !'enum' !'interface' qualified_name array_indicator?)
239
+ end
240
+
241
+ rule array_indicator
242
+ ( s? '[]' array_indicator? / s? generics array_indicator? / s? '...' )
243
+ end
244
+
245
+ rule string
246
+ (
247
+ "'" ( (!'\\\'' '\\\\') / '\\\'' / !"'" . )* "'" <StringLiteral>
248
+ /
249
+ '"' ( (!'\"' '\\\\') / '\"' / !'"' . )* '"' <StringLiteral>
250
+ )
251
+ end
252
+
253
+ rule comment
254
+ ( '/*' s? (!'*/' .)* s? '*/' / '//' s? [^\n]* )
255
+ {
256
+ def is_valid_comment
257
+ return true if text_value.match(/(\/\/[^"'\n\r]*(?:("|')[^"'\n\r]*("|')[^"'\n\r]*)*$|\/\*([^*]|\*(?!\/))*?\*\/)(?=[^"]*(?:"[^"]*"[^"]*)*$)/)
258
+ return false
259
+ end
260
+ }
261
+ end
262
+
263
+ rule s
264
+ ( comment_2 / [ \s] )+
265
+ end
266
+
267
+ rule class_identifier
268
+ [A-Za-z_] [a-zA-Z0-9_]*
269
+ end
270
+
271
+ rule identifier
272
+ [a-zA-Z_] [a-zA-Z0-9_]* <Identifier>
273
+ end
274
+
275
+ rule number
276
+ [0-9]+ 'L'?
277
+ end
278
+
279
+ rule anything
280
+ .*
281
+ end
282
+ end
283
+ end