Class: HumanQL::QueryParser::ParseState

Inherits:
Object
  • Object
show all
Defined in:
lib/human-ql/query_parser.rb

Overview

Internal state keeping

Instance Method Summary collapse

Constructor Details

#initialize(parser) ⇒ ParseState

:nodoc:



381
382
383
384
385
386
387
388
389
390
# File 'lib/human-ql/query_parser.rb', line 381

def initialize( parser )
  @default_op = parser.default_op
  @precedence = parser.precedence
  @verbose = parser.verbose
  @node = [ @default_op ]
  @ops = []
  @has_op = true
  @index = 0
  @last_term = -1
end

Instance Method Details

#dump(fr) ⇒ Object



399
400
401
402
403
404
# File 'lib/human-ql/query_parser.rb', line 399

def dump( fr )
  if @verbose
    log( "%2d %2s ops: %-12s node: %-30s" %
         [ @index, fr, @ops.inspect, @node.inspect ] )
  end
end

#flush_treeObject



451
452
453
454
455
456
457
458
459
# File 'lib/human-ql/query_parser.rb', line 451

def flush_tree
  loop do
    n, last = @ops.pop
    break unless last
    op_to_node( n, last )
    dump 'FO'
  end
  @node
end

#log(l = nil) ⇒ Object



392
393
394
395
396
397
# File 'lib/human-ql/query_parser.rb', line 392

def log( l = nil )
  if @verbose
    l = yield if block_given?
    $stderr.puts( l )
  end
end

#op_to_node(opi, op) ⇒ Object



465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
# File 'lib/human-ql/query_parser.rb', line 465

def op_to_node( opi, op )
  if opi >= @last_term
    log { "Ignoring trailing #{op.inspect} (index #{opi})" }
    return
  end
  o1 = pop_term
  if o1
    if unary?( op )
      @node << [ op, o1 ]
    else
      o0 = pop_term
      if o0
        if @node[0] == op
          @node << o0 << o1
        else
          @node << [ op, o0, o1 ]
        end
      else
        if @node[0] == op
          @node << o1
        else
          @node = [ op, @node, o1 ]
        end
      end
    end
  else
    log { "No argument to #{op.inspect}, ignoring" }
  end
end

#pop_termObject



461
462
463
# File 'lib/human-ql/query_parser.rb', line 461

def pop_term
  @node.pop if @node.length > 1
end

#precedence_lte?(op1, op2) ⇒ Boolean

Returns:

  • (Boolean)


418
419
420
# File 'lib/human-ql/query_parser.rb', line 418

def precedence_lte?( op1, op2 )
  @precedence[op1] <= @precedence[op2]
end

#push_op(op) ⇒ Object



426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
# File 'lib/human-ql/query_parser.rb', line 426

def push_op( op )
  @index += 1
  # Possible special case implied DEFAULT_OP in front of :not or
  # :scope.
  if unary?( op )
    push_op( @default_op ) unless @has_op
  elsif @node.length < 2 # no proceeding term
    log { "Ignoring leading #{op.inspect} (index #{@index})" }
    return
  end
  loop do
    n, last = @ops.last
    if last && precedence_lte?( op, last )
      @ops.pop
      op_to_node( n, last )
      dump 'PL'
    else
      break
    end
  end
  @ops << [ @index, op ]
  @has_op = true
  dump 'PO'
end

#push_term(t) ⇒ Object



406
407
408
409
410
411
412
413
414
415
416
# File 'lib/human-ql/query_parser.rb', line 406

def push_term( t )
  if @has_op
    @index += 1
  else
    push_op( @default_op )
  end
  @node << t
  @last_term = @index
  @has_op = false
  dump 'PT'
end

#unary?(op) ⇒ Boolean

Returns:

  • (Boolean)


422
423
424
# File 'lib/human-ql/query_parser.rb', line 422

def unary?( op )
  ( op == :not || op.is_a?( String ) )
end