Class: Melbourne::Parser

Inherits:
Object
  • Object
show all
Defined in:
lib/melbourne/parser.rb,
lib/melbourne/processor.rb

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name, line, transforms = []) ⇒ Parser

Returns a new instance of Parser.



13
14
15
16
# File 'lib/melbourne/parser.rb', line 13

def initialize(name, line, transforms=[])
  @name = name
  @line = line > 0 ? line : 1
end

Class Method Details

.parse_file(name, line = 1) ⇒ Object



9
10
11
# File 'lib/melbourne/parser.rb', line 9

def self.parse_file(name, line=1)
  new(name, line).parse_file
end

.parse_string(string, name = '(eval)', line = 1) ⇒ Object



5
6
7
# File 'lib/melbourne/parser.rb', line 5

def self.parse_string(string, name = '(eval)', line = 1)
  new(name, line).parse_string(string)
end

Instance Method Details

#parse_fileObject



27
28
29
30
31
32
33
34
# File 'lib/melbourne/parser.rb', line 27

def parse_file
  unless @name and File.exists?(@name)
    raise Errno::ENOENT, @name.inspect
  end
  
  syntax_error unless ast = file_to_ast(@name, @line)
  ast
end

#parse_string(string) ⇒ Object



22
23
24
25
# File 'lib/melbourne/parser.rb', line 22

def parse_string(string)
  syntax_error unless ast = string_to_ast(string, @name, @line)
  ast
end

#process_alias(line, to, from) ⇒ Object

Processing methods



28
29
30
# File 'lib/melbourne/processor.rb', line 28

def process_alias(line, to, from)
  AST::Alias.new line, to, from
end

#process_and(line, left, right) ⇒ Object



32
33
34
# File 'lib/melbourne/processor.rb', line 32

def process_and(line, left, right)
  AST::And.new line, left, right
end

#process_args(line, args, defaults, splat) ⇒ Object



36
37
38
# File 'lib/melbourne/processor.rb', line 36

def process_args(line, args, defaults, splat)
  AST::FormalArguments.new line, args, defaults, splat
end

#process_argscat(line, array, rest) ⇒ Object



40
41
42
# File 'lib/melbourne/processor.rb', line 40

def process_argscat(line, array, rest)
  AST::ConcatArgs.new line, array, rest
end

#process_argspush(line, arguments, value) ⇒ Object



44
45
46
# File 'lib/melbourne/processor.rb', line 44

def process_argspush(line, arguments, value)
  AST::PushArgs.new line, arguments, value
end

#process_array(line, array) ⇒ Object



48
49
50
# File 'lib/melbourne/processor.rb', line 48

def process_array(line, array)
  AST::ArrayLiteral.new line, array
end

#process_attrasgn(line, receiver, name, arguments) ⇒ Object



52
53
54
55
56
57
58
# File 'lib/melbourne/processor.rb', line 52

def process_attrasgn(line, receiver, name, arguments)
  if name == :[]=
    AST::ElementAssignment.new line, receiver, arguments
  else
    AST::AttributeAssignment.new line, receiver, name, arguments
  end
end

#process_back_ref(line, ref) ⇒ Object



60
61
62
# File 'lib/melbourne/processor.rb', line 60

def process_back_ref(line, ref)
  AST::BackRef.new line, ref
end

#process_begin(line, body) ⇒ Object



64
65
66
# File 'lib/melbourne/processor.rb', line 64

def process_begin(line, body)
  AST::Begin.new line, body
end

#process_block(line, array) ⇒ Object



68
69
70
# File 'lib/melbourne/processor.rb', line 68

def process_block(line, array)
  AST::Block.new line, array
end

#process_block_arg(line, name) ⇒ Object



72
73
74
# File 'lib/melbourne/processor.rb', line 72

def process_block_arg(line, name)
  AST::BlockArgument.new line, name
end

#process_block_pass(line, method_send, body) ⇒ Object



76
77
78
79
80
81
82
83
84
# File 'lib/melbourne/processor.rb', line 76

def process_block_pass(line, method_send, body)
  node = AST::BlockPass.new line, body
  if method_send
    method_send.block = node
    method_send
  else
    node
  end
end

#process_break(line, value) ⇒ Object



86
87
88
# File 'lib/melbourne/processor.rb', line 86

def process_break(line, value)
  AST::Break.new line, value
end

#process_call(line, receiver, name, arguments) ⇒ Object



90
91
92
93
94
95
96
# File 'lib/melbourne/processor.rb', line 90

def process_call(line, receiver, name, arguments)
  if arguments
    AST::SendWithArguments.new line, receiver, name, arguments
  else
    AST::Send.new line, receiver, name
  end
end

#process_case(line, receiver, whens, else_body) ⇒ Object



98
99
100
101
102
103
104
# File 'lib/melbourne/processor.rb', line 98

def process_case(line, receiver, whens, else_body)
  if receiver
    AST::ReceiverCase.new line, receiver, whens, else_body
  else
    AST::Case.new line, whens, else_body
  end
end

#process_cdecl(line, expr, value) ⇒ Object



106
107
108
# File 'lib/melbourne/processor.rb', line 106

def process_cdecl(line, expr, value)
  AST::ConstSet.new line, expr, value
end

#process_class(line, name, superclass, body) ⇒ Object



110
111
112
# File 'lib/melbourne/processor.rb', line 110

def process_class(line, name, superclass, body)
  AST::Class.new line, name, superclass, body
end

#process_colon2(line, outer, name) ⇒ Object



114
115
116
117
118
119
120
# File 'lib/melbourne/processor.rb', line 114

def process_colon2(line, outer, name)
  if outer
    AST::ConstAccess.new line, outer, name
  else
    AST::ConstFind.new line, name
  end
end

#process_colon3(line, name) ⇒ Object



122
123
124
# File 'lib/melbourne/processor.rb', line 122

def process_colon3(line, name)
  AST::ConstAtTop.new line, name
end

#process_const(line, name) ⇒ Object



126
127
128
# File 'lib/melbourne/processor.rb', line 126

def process_const(line, name)
  AST::ConstFind.new line, name
end

#process_cvar(line, name) ⇒ Object



130
131
132
# File 'lib/melbourne/processor.rb', line 130

def process_cvar(line, name)
  AST::ClassVariableAccess.new line, name
end

#process_cvasgn(line, name, value) ⇒ Object



134
135
136
# File 'lib/melbourne/processor.rb', line 134

def process_cvasgn(line, name, value)
  AST::ClassVariableAssignment.new line, name, value
end

#process_cvdecl(line, name, value) ⇒ Object



138
139
140
# File 'lib/melbourne/processor.rb', line 138

def process_cvdecl(line, name, value)
  AST::ClassVariableAssignment.new line, name, value
end

#process_dangling_nodeObject

Raises:



15
16
17
18
# File 'lib/melbourne/processor.rb', line 15

def process_dangling_node
  raise ParserError.new('Processing called but node was NULL')
  # TODO: output info about the current AST node
end

#process_data(line, data) ⇒ Object



142
143
144
# File 'lib/melbourne/processor.rb', line 142

def process_data(line, data)
  AST::EndData.new line, data
end

#process_defined(line, expr) ⇒ Object



146
147
148
# File 'lib/melbourne/processor.rb', line 146

def process_defined(line, expr)
  AST::Defined.new line, expr
end

#process_defn(line, name, body) ⇒ Object



150
151
152
# File 'lib/melbourne/processor.rb', line 150

def process_defn(line, name, body)
  AST::Define.new line, name, body
end

#process_defs(line, receiver, name, body) ⇒ Object



154
155
156
# File 'lib/melbourne/processor.rb', line 154

def process_defs(line, receiver, name, body)
  AST::DefineSingleton.new line, receiver, name, body
end

#process_dot2(line, start, finish) ⇒ Object



158
159
160
# File 'lib/melbourne/processor.rb', line 158

def process_dot2(line, start, finish)
  AST::Range.new line, start, finish
end

#process_dot3(line, start, finish) ⇒ Object



162
163
164
# File 'lib/melbourne/processor.rb', line 162

def process_dot3(line, start, finish)
  AST::RangeExclude.new line, start, finish
end

#process_dregx(line, str, array, flags) ⇒ Object



166
167
168
# File 'lib/melbourne/processor.rb', line 166

def process_dregx(line, str, array, flags)
  AST::DynamicRegex.new line, str, array, flags
end

#process_dregx_once(line, str, array, flags) ⇒ Object



170
171
172
# File 'lib/melbourne/processor.rb', line 170

def process_dregx_once(line, str, array, flags)
  AST::DynamicOnceRegex.new line, str, array, flags
end

#process_dstr(line, str, array) ⇒ Object



174
175
176
# File 'lib/melbourne/processor.rb', line 174

def process_dstr(line, str, array)
  AST::DynamicString.new line, str, array
end

#process_dsym(line, str, array) ⇒ Object



178
179
180
# File 'lib/melbourne/processor.rb', line 178

def process_dsym(line, str, array)
  AST::DynamicSymbol.new line, str, array
end

#process_dxstr(line, str, array) ⇒ Object



182
183
184
# File 'lib/melbourne/processor.rb', line 182

def process_dxstr(line, str, array)
  AST::DynamicExecuteString.new line, str, array
end

#process_ensure(line, body, ensr) ⇒ Object



186
187
188
# File 'lib/melbourne/processor.rb', line 186

def process_ensure(line, body, ensr)
  AST::Ensure.new line, body, ensr
end

#process_evstr(line, value) ⇒ Object



190
191
192
193
194
195
196
# File 'lib/melbourne/processor.rb', line 190

def process_evstr(line, value)
  if value
    AST::ToString.new line, value
  else
    AST::StringLiteral.new line, ""
  end
end

#process_false(line) ⇒ Object



198
199
200
# File 'lib/melbourne/processor.rb', line 198

def process_false(line)
  AST::False.new line
end

#process_fcall(line, name, arguments) ⇒ Object



202
203
204
205
206
207
208
209
210
# File 'lib/melbourne/processor.rb', line 202

def process_fcall(line, name, arguments)
  receiver = AST::Self.new line

  if arguments
    AST::SendWithArguments.new line, receiver, name, arguments, true
  else
    AST::Send.new line, receiver, name, true
  end
end

#process_file(line) ⇒ Object



212
213
214
# File 'lib/melbourne/processor.rb', line 212

def process_file(line)
  AST::File.new line
end

#process_fixnum(line, value) ⇒ Object



216
217
218
# File 'lib/melbourne/processor.rb', line 216

def process_fixnum(line, value)
  AST::FixnumLiteral.new line, value
end

#process_flip2(line, start, finish) ⇒ Object



220
221
222
# File 'lib/melbourne/processor.rb', line 220

def process_flip2(line, start, finish)
  AST::Flip2.new line, start, finish
end

#process_flip3(line, start, finish) ⇒ Object



224
225
226
# File 'lib/melbourne/processor.rb', line 224

def process_flip3(line, start, finish)
  AST::Flip3.new line, start, finish
end

#process_float(line, str) ⇒ Object



228
229
230
# File 'lib/melbourne/processor.rb', line 228

def process_float(line, str)
  AST::Float.new line, str
end

#process_for(line, iter, arguments, body) ⇒ Object



232
233
234
235
236
# File 'lib/melbourne/processor.rb', line 232

def process_for(line, iter, arguments, body)
  method_send = AST::Send.new line, iter, :each
  method_send.block = AST::For.new line, arguments, body
  method_send
end

#process_gasgn(line, name, expr) ⇒ Object



238
239
240
# File 'lib/melbourne/processor.rb', line 238

def process_gasgn(line, name, expr)
  AST::GlobalVariableAssignment.new line, name, expr
end

#process_gvar(line, name) ⇒ Object



242
243
244
# File 'lib/melbourne/processor.rb', line 242

def process_gvar(line, name)
  AST::GlobalVariableAccess.new line, name
end

#process_hash(line, array) ⇒ Object



246
247
248
# File 'lib/melbourne/processor.rb', line 246

def process_hash(line, array)
  AST::HashLiteral.new line, array
end

#process_iasgn(line, name, value) ⇒ Object



250
251
252
# File 'lib/melbourne/processor.rb', line 250

def process_iasgn(line, name, value)
  AST::InstanceVariableAssignment.new line, name, value
end

#process_if(line, cond, body, else_body) ⇒ Object



254
255
256
# File 'lib/melbourne/processor.rb', line 254

def process_if(line, cond, body, else_body)
  AST::If.new line, cond, body, else_body
end

#process_iter(line, method_send, arguments, body) ⇒ Object



258
259
260
261
# File 'lib/melbourne/processor.rb', line 258

def process_iter(line, method_send, arguments, body)
  method_send.block = AST::Iter.new line, arguments, body
  method_send
end

#process_ivar(line, name) ⇒ Object



263
264
265
# File 'lib/melbourne/processor.rb', line 263

def process_ivar(line, name)
  AST::InstanceVariableAccess.new line, name
end

#process_lasgn(line, name, value) ⇒ Object



267
268
269
# File 'lib/melbourne/processor.rb', line 267

def process_lasgn(line, name, value)
  AST::LocalVariableAssignment.new line, name, value
end

#process_lit(line, sym) ⇒ Object



271
272
273
# File 'lib/melbourne/processor.rb', line 271

def process_lit(line, sym)
  AST::SymbolLiteral.new line, sym
end

#process_lvar(line, name) ⇒ Object



275
276
277
# File 'lib/melbourne/processor.rb', line 275

def process_lvar(line, name)
  AST::LocalVariableAccess.new line, name
end

#process_masgn(line, left, right, splat) ⇒ Object



279
280
281
# File 'lib/melbourne/processor.rb', line 279

def process_masgn(line, left, right, splat)
  AST::MAsgn.new line, left, right, splat
end

#process_match(line, pattern, flags) ⇒ Object



283
284
285
# File 'lib/melbourne/processor.rb', line 283

def process_match(line, pattern, flags)
  AST::Match.new line, pattern, flags
end

#process_match2(line, pattern, value) ⇒ Object



287
288
289
# File 'lib/melbourne/processor.rb', line 287

def process_match2(line, pattern, value)
  AST::Match2.new line, pattern, value
end

#process_match3(line, pattern, value) ⇒ Object



291
292
293
# File 'lib/melbourne/processor.rb', line 291

def process_match3(line, pattern, value)
  AST::Match3.new line, pattern, value
end

#process_missing_node(line, node_name, node_type) ⇒ Object

This method is analogous to #method_missing. It is called if there is no processing method defined for a node.

Raises:



22
23
24
# File 'lib/melbourne/processor.rb', line 22

def process_missing_node(line, node_name, node_type)
  raise ParserError.new("Unhandled node #{node_name} (#{node_type})")
end

#process_module(line, name, body) ⇒ Object



295
296
297
# File 'lib/melbourne/processor.rb', line 295

def process_module(line, name, body)
  AST::Module.new line, name, body
end

#process_negate(line, value) ⇒ Object



299
300
301
# File 'lib/melbourne/processor.rb', line 299

def process_negate(line, value)
  AST::Negate.new line, value
end

#process_next(line, value) ⇒ Object



303
304
305
# File 'lib/melbourne/processor.rb', line 303

def process_next(line, value)
  AST::Next.new line, value
end

#process_nil(line) ⇒ Object



307
308
309
# File 'lib/melbourne/processor.rb', line 307

def process_nil(line)
  AST::Nil.new line
end

#process_not(line, value) ⇒ Object



311
312
313
# File 'lib/melbourne/processor.rb', line 311

def process_not(line, value)
  AST::Not.new line, value
end

#process_nth_ref(line, ref) ⇒ Object



315
316
317
# File 'lib/melbourne/processor.rb', line 315

def process_nth_ref(line, ref)
  AST::NthRef.new line, ref
end

#process_number(line, base, str) ⇒ Object



319
320
321
322
323
324
325
326
327
# File 'lib/melbourne/processor.rb', line 319

def process_number(line, base, str)
  value = str.to_i base
  case value
  when Fixnum
    AST::FixnumLiteral.new line, value
  when Bignum
    AST::NumberLiteral.new line, value
  end
end

#process_op_asgn1(line, receiver, index, op, value) ⇒ Object



329
330
331
# File 'lib/melbourne/processor.rb', line 329

def process_op_asgn1(line, receiver, index, op, value)
  AST::OpAssign1.new line, receiver, index, op, value
end

#process_op_asgn2(line, receiver, name, op, value) ⇒ Object



333
334
335
# File 'lib/melbourne/processor.rb', line 333

def process_op_asgn2(line, receiver, name, op, value)
  AST::OpAssign2.new line, receiver, name, op, value
end

#process_op_asgn_and(line, var, value) ⇒ Object



337
338
339
# File 'lib/melbourne/processor.rb', line 337

def process_op_asgn_and(line, var, value)
  AST::OpAssignAnd.new line, var, value
end

#process_op_asgn_or(line, var, value) ⇒ Object



341
342
343
# File 'lib/melbourne/processor.rb', line 341

def process_op_asgn_or(line, var, value)
  AST::OpAssignOr.new line, var, value
end

#process_or(line, left, right) ⇒ Object



345
346
347
# File 'lib/melbourne/processor.rb', line 345

def process_or(line, left, right)
  AST::Or.new line, left, right
end

#process_parse_error(message, column, line, source) ⇒ Object



11
12
13
# File 'lib/melbourne/processor.rb', line 11

def process_parse_error(message, column, line, source)
  @exc = SyntaxError.from message, column, line, source, @name
end

#process_postexe(line) ⇒ Object



349
350
351
# File 'lib/melbourne/processor.rb', line 349

def process_postexe(line)
  AST::Send.new line, AST::Self.new(line), :at_exit, true
end

#process_redo(line) ⇒ Object



353
354
355
# File 'lib/melbourne/processor.rb', line 353

def process_redo(line)
  AST::Redo.new line
end

#process_regex(line, str, flags) ⇒ Object



357
358
359
# File 'lib/melbourne/processor.rb', line 357

def process_regex(line, str, flags)
  AST::RegexLiteral.new line, str, flags
end

#process_resbody(line, conditions, body, nxt) ⇒ Object



361
362
363
# File 'lib/melbourne/processor.rb', line 361

def process_resbody(line, conditions, body, nxt)
  AST::RescueCondition.new line, conditions, body, nxt
end

#process_rescue(line, body, rescue_body, else_body) ⇒ Object



365
366
367
# File 'lib/melbourne/processor.rb', line 365

def process_rescue(line, body, rescue_body, else_body)
  AST::Rescue.new line, body, rescue_body, else_body
end

#process_retry(line) ⇒ Object



369
370
371
# File 'lib/melbourne/processor.rb', line 369

def process_retry(line)
  AST::Retry.new line
end

#process_return(line, value) ⇒ Object



373
374
375
# File 'lib/melbourne/processor.rb', line 373

def process_return(line, value)
  AST::Return.new line, value
end

#process_sclass(line, receiver, body) ⇒ Object



377
378
379
# File 'lib/melbourne/processor.rb', line 377

def process_sclass(line, receiver, body)
  AST::SClass.new line, receiver, body
end

#process_scope(line, body) ⇒ Object



381
382
383
384
385
386
387
# File 'lib/melbourne/processor.rb', line 381

def process_scope(line, body)
  if body.kind_of? AST::Block
    body
  elsif body
    AST::Block.new line, [body]
  end
end

#process_self(line) ⇒ Object



389
390
391
# File 'lib/melbourne/processor.rb', line 389

def process_self(line)
  AST::Self.new line
end

#process_splat(line, expr) ⇒ Object



393
394
395
# File 'lib/melbourne/processor.rb', line 393

def process_splat(line, expr)
  AST::SplatValue.new line, expr
end

#process_str(line, str) ⇒ Object



397
398
399
# File 'lib/melbourne/processor.rb', line 397

def process_str(line, str)
  AST::StringLiteral.new line, str
end

#process_super(line, args) ⇒ Object



401
402
403
# File 'lib/melbourne/processor.rb', line 401

def process_super(line, args)
  AST::Super.new line, args
end

#process_svalue(line, expr) ⇒ Object



405
406
407
# File 'lib/melbourne/processor.rb', line 405

def process_svalue(line, expr)
  AST::SValue.new line, expr
end

#process_to_ary(line, expr) ⇒ Object



409
410
411
# File 'lib/melbourne/processor.rb', line 409

def process_to_ary(line, expr)
  AST::ToArray.new line, expr
end

#process_true(line) ⇒ Object



413
414
415
# File 'lib/melbourne/processor.rb', line 413

def process_true(line)
  AST::True.new line
end

#process_undef(line, sym) ⇒ Object



417
418
419
# File 'lib/melbourne/processor.rb', line 417

def process_undef(line, sym)
  AST::Undef.new line, sym
end

#process_until(line, cond, body, check_first) ⇒ Object



421
422
423
# File 'lib/melbourne/processor.rb', line 421

def process_until(line, cond, body, check_first)
  AST::Until.new line, cond, body, check_first
end

#process_valias(line, to, from) ⇒ Object



431
432
433
# File 'lib/melbourne/processor.rb', line 431

def process_valias(line, to, from)
  AST::VAlias.new line, to, from
end

#process_vcall(line, name) ⇒ Object



425
426
427
428
429
# File 'lib/melbourne/processor.rb', line 425

def process_vcall(line, name)
  receiver = AST::Self.new line

  AST::Send.new line, receiver, name, true
end

#process_when(line, conditions, body) ⇒ Object



435
436
437
# File 'lib/melbourne/processor.rb', line 435

def process_when(line, conditions, body)
  AST::When.new line, conditions, body
end

#process_while(line, cond, body, check_first) ⇒ Object



439
440
441
# File 'lib/melbourne/processor.rb', line 439

def process_while(line, cond, body, check_first)
  AST::While.new line, cond, body, check_first
end

#process_xstr(line, str) ⇒ Object



443
444
445
# File 'lib/melbourne/processor.rb', line 443

def process_xstr(line, str)
  AST::ExecuteString.new line, str
end

#process_yield(line, arguments, unwrap) ⇒ Object



447
448
449
# File 'lib/melbourne/processor.rb', line 447

def process_yield(line, arguments, unwrap)
  AST::Yield.new line, arguments, unwrap
end

#process_zarray(line) ⇒ Object



451
452
453
# File 'lib/melbourne/processor.rb', line 451

def process_zarray(line)
  AST::EmptyArray.new line
end

#process_zsuper(line) ⇒ Object



455
456
457
# File 'lib/melbourne/processor.rb', line 455

def process_zsuper(line)
  AST::ZSuper.new line
end

#syntax_errorObject

Raises:

  • (@exc)


18
19
20
# File 'lib/melbourne/parser.rb', line 18

def syntax_error
  raise @exc if @exc
end