class Oga::XPath::Parser

AST parser for XPath expressions. The AST is built using ‘AST::Node` instances.

Unlike {Oga::XML::Parser} this parser only takes String instances as input.

@api private

Constants

CACHE

@return [Oga::LRU]

CONFIG

Public Class Methods

new(data) click to toggle source

@param [String] data The input to parse.

# File lib/oga/xpath/parser.rb, line 260
def initialize(data)
  @lexer = Lexer.new(data)
end
parse_with_cache(data) click to toggle source

@param [String] data @return [AST::Node]

# File lib/oga/xpath/parser.rb, line 255
def self.parse_with_cache(data)
  CACHE.get_or_set(data) { new(data).parse }
end

Public Instance Methods

_rule_0(val) click to toggle source
# File lib/oga/xpath/parser.rb, line 308
def _rule_0(val)
  val[0]
end
_rule_1(val) click to toggle source
# File lib/oga/xpath/parser.rb, line 312
def _rule_1(val)
   combine_operators(val) 
end
_rule_10(val) click to toggle source
# File lib/oga/xpath/parser.rb, line 348
def _rule_10(val)
   [:gt, val[1]] 
end
_rule_11(val) click to toggle source
# File lib/oga/xpath/parser.rb, line 352
def _rule_11(val)
   [:lte, val[1]] 
end
_rule_12(val) click to toggle source
# File lib/oga/xpath/parser.rb, line 356
def _rule_12(val)
   [:gte, val[1]] 
end
_rule_13(val) click to toggle source
# File lib/oga/xpath/parser.rb, line 360
def _rule_13(val)
   combine_operators(val) 
end
_rule_14(val) click to toggle source
# File lib/oga/xpath/parser.rb, line 364
def _rule_14(val)
   [:add, val[1]] 
end
_rule_15(val) click to toggle source
# File lib/oga/xpath/parser.rb, line 368
def _rule_15(val)
   [:sub, val[1]] 
end
_rule_16(val) click to toggle source
# File lib/oga/xpath/parser.rb, line 372
def _rule_16(val)
   combine_optional_operator(val) 
end
_rule_17(val) click to toggle source
# File lib/oga/xpath/parser.rb, line 376
def _rule_17(val)
   [:div, val[1]] 
end
_rule_18(val) click to toggle source
# File lib/oga/xpath/parser.rb, line 380
def _rule_18(val)
   [:mod, val[1]] 
end
_rule_19(val) click to toggle source
# File lib/oga/xpath/parser.rb, line 384
def _rule_19(val)
   [:mul, val[1]] 
end
_rule_2(val) click to toggle source
# File lib/oga/xpath/parser.rb, line 316
def _rule_2(val)
   [:or, val[1]] 
end
_rule_20(val) click to toggle source
# File lib/oga/xpath/parser.rb, line 388
def _rule_20(val)
   combine_operators(val) 
end
_rule_21(val) click to toggle source
# File lib/oga/xpath/parser.rb, line 392
def _rule_21(val)
   [:pipe, val[1]] 
end
_rule_22(val) click to toggle source
# File lib/oga/xpath/parser.rb, line 396
def _rule_22(val)
  val[0]
end
_rule_23(val) click to toggle source
# File lib/oga/xpath/parser.rb, line 400
def _rule_23(val)
  val[0]
end
_rule_24(val) click to toggle source
# File lib/oga/xpath/parser.rb, line 404
def _rule_24(val)
  val[0]
end
_rule_25(val) click to toggle source
# File lib/oga/xpath/parser.rb, line 408
def _rule_25(val)
  val[0]
end
_rule_26(val) click to toggle source
# File lib/oga/xpath/parser.rb, line 412
def _rule_26(val)
  val[0]
end
_rule_27(val) click to toggle source
# File lib/oga/xpath/parser.rb, line 416
def _rule_27(val)
   val[1] 
end
_rule_28(val) click to toggle source
# File lib/oga/xpath/parser.rb, line 420
def _rule_28(val)
  
    if val[1]
      s(:absolute_path, val[1])
    else
      s(:absolute_path)
    end
  
end
_rule_29(val) click to toggle source
# File lib/oga/xpath/parser.rb, line 430
def _rule_29(val)
  val[0]
end
_rule_3(val) click to toggle source
# File lib/oga/xpath/parser.rb, line 320
def _rule_3(val)
   combine_operators(val) 
end
_rule_30(val) click to toggle source
# File lib/oga/xpath/parser.rb, line 434
def _rule_30(val)
  val[0]
end
_rule_31(val) click to toggle source
# File lib/oga/xpath/parser.rb, line 438
def _rule_31(val)
  
    type = val[1][0]
    args = val[1][1]
    pred = val[1][2]
    more = val[1][3]

    if type.equal?(:test)
      # Whenever a bare test is used (e.g. just "A") this actually means
      # "child::A". Handling this on parser level is the easiest.
      if args
        node = s(:axis, 'child', s(:test, val[0], args))
      else
        node = s(:axis, 'child', s(:test, nil, val[0]))
      end
    else
      node = s(type, val[0], *args)
    end

    if pred
      node = s(:predicate, node, pred)
    end

    if more
      node = node.updated(nil, node.children + [more])
    end

    node
  
end
_rule_32(val) click to toggle source
# File lib/oga/xpath/parser.rb, line 469
def _rule_32(val)
  
    pred = val[1]
    more = val[2]
    node = s(:axis, 'child', val[0])

    if pred
      node = s(:predicate, node, pred)
    end

    if more
      node = node.updated(nil, node.children + [more])
    end

    node
  
end
_rule_33(val) click to toggle source
# File lib/oga/xpath/parser.rb, line 487
def _rule_33(val)
   [:call, val[1]] 
end
_rule_34(val) click to toggle source
# File lib/oga/xpath/parser.rb, line 491
def _rule_34(val)
   [:test, val[1], val[2], val[3]] 
end
_rule_35(val) click to toggle source
# File lib/oga/xpath/parser.rb, line 495
def _rule_35(val)
   [:test, nil, val[0], val[1]] 
end
_rule_36(val) click to toggle source
# File lib/oga/xpath/parser.rb, line 499
def _rule_36(val)
   val[1] 
end
_rule_37(val) click to toggle source
# File lib/oga/xpath/parser.rb, line 503
def _rule_37(val)
   val[1] 
end
_rule_38(val) click to toggle source
# File lib/oga/xpath/parser.rb, line 507
def _rule_38(val)
   s(:type_test, val[0]) 
end
_rule_39(val) click to toggle source
# File lib/oga/xpath/parser.rb, line 511
def _rule_39(val)
  
    val[1] ? s(:test, val[0], val[1]) : s(:test, nil, val[0])
  
end
_rule_4(val) click to toggle source
# File lib/oga/xpath/parser.rb, line 324
def _rule_4(val)
   [:and, val[1]] 
end
_rule_40(val) click to toggle source
# File lib/oga/xpath/parser.rb, line 517
def _rule_40(val)
   val[1] 
end
_rule_41(val) click to toggle source
# File lib/oga/xpath/parser.rb, line 521
def _rule_41(val)
   [val[0], *val[1]] 
end
_rule_42(val) click to toggle source
# File lib/oga/xpath/parser.rb, line 525
def _rule_42(val)
  val
end
_rule_43(val) click to toggle source
# File lib/oga/xpath/parser.rb, line 529
def _rule_43(val)
   val[1] 
end
_rule_44(val) click to toggle source
# File lib/oga/xpath/parser.rb, line 533
def _rule_44(val)
  
    ret  = s(:axis, val[0], val[1])
    more = val[3]

    if val[2]
      ret = s(:predicate, ret, val[2])
    end

    if more
      ret = ret.updated(nil, ret.children + [more])
    end

    ret
  
end
_rule_45(val) click to toggle source
# File lib/oga/xpath/parser.rb, line 550
def _rule_45(val)
  val[0]
end
_rule_46(val) click to toggle source
# File lib/oga/xpath/parser.rb, line 554
def _rule_46(val)
  val[0]
end
_rule_47(val) click to toggle source
# File lib/oga/xpath/parser.rb, line 558
def _rule_47(val)
   s(:string, val[0]) 
end
_rule_48(val) click to toggle source
# File lib/oga/xpath/parser.rb, line 562
def _rule_48(val)
   s(:int, val[0]) 
end
_rule_49(val) click to toggle source
# File lib/oga/xpath/parser.rb, line 566
def _rule_49(val)
   s(:float, val[0]) 
end
_rule_5(val) click to toggle source
# File lib/oga/xpath/parser.rb, line 328
def _rule_5(val)
   combine_operators(val) 
end
_rule_50(val) click to toggle source
# File lib/oga/xpath/parser.rb, line 570
def _rule_50(val)
   s(:var, val[0]) 
end
_rule_51(val) click to toggle source
# File lib/oga/xpath/parser.rb, line 574
def _rule_51(val)
  val[0]
end
_rule_52(val) click to toggle source
# File lib/oga/xpath/parser.rb, line 578
def _rule_52(val)
  val[0]
end
_rule_53(val) click to toggle source
# File lib/oga/xpath/parser.rb, line 582
def _rule_53(val)
  val[0]
end
_rule_54(val) click to toggle source
# File lib/oga/xpath/parser.rb, line 586
def _rule_54(val)
  val[0]
end
_rule_55(val) click to toggle source
# File lib/oga/xpath/parser.rb, line 590
def _rule_55(val)
  val[0]
end
_rule_56(val) click to toggle source
# File lib/oga/xpath/parser.rb, line 594
def _rule_56(val)
  val[0]
end
_rule_57(val) click to toggle source
# File lib/oga/xpath/parser.rb, line 598
def _rule_57(val)
  val[0]
end
_rule_58(val) click to toggle source
# File lib/oga/xpath/parser.rb, line 602
def _rule_58(val)
  val[0]
end
_rule_59(val) click to toggle source
# File lib/oga/xpath/parser.rb, line 606
def _rule_59(val)
  val[0]
end
_rule_6(val) click to toggle source
# File lib/oga/xpath/parser.rb, line 332
def _rule_6(val)
   [:eq, val[1]] 
end
_rule_60(val) click to toggle source
# File lib/oga/xpath/parser.rb, line 610
def _rule_60(val)
  val[0]
end
_rule_61(val) click to toggle source
# File lib/oga/xpath/parser.rb, line 614
def _rule_61(val)
  val[0]
end
_rule_62(val) click to toggle source
# File lib/oga/xpath/parser.rb, line 618
def _rule_62(val)
  val[0]
end
_rule_63(val) click to toggle source
# File lib/oga/xpath/parser.rb, line 622
def _rule_63(val)
  val[0]
end
_rule_64(val) click to toggle source
# File lib/oga/xpath/parser.rb, line 626
def _rule_64(val)
  val[0]
end
_rule_65(val) click to toggle source
# File lib/oga/xpath/parser.rb, line 630
def _rule_65(val)
  val[0]
end
_rule_66(val) click to toggle source
# File lib/oga/xpath/parser.rb, line 634
def _rule_66(val)
  val[0]
end
_rule_67(val) click to toggle source
# File lib/oga/xpath/parser.rb, line 638
def _rule_67(val)
  val[0]
end
_rule_68(val) click to toggle source
# File lib/oga/xpath/parser.rb, line 642
def _rule_68(val)
  val[0]
end
_rule_69(val) click to toggle source
# File lib/oga/xpath/parser.rb, line 646
def _rule_69(val)
  val[0]
end
_rule_7(val) click to toggle source
# File lib/oga/xpath/parser.rb, line 336
def _rule_7(val)
   [:neq, val[1]] 
end
_rule_8(val) click to toggle source
# File lib/oga/xpath/parser.rb, line 340
def _rule_8(val)
   combine_operators(val) 
end
_rule_9(val) click to toggle source
# File lib/oga/xpath/parser.rb, line 344
def _rule_9(val)
   [:lt, val[1]] 
end
combine_operators(val) click to toggle source

@param [Array] val

# File lib/oga/xpath/parser.rb, line 287
def combine_operators(val)
  ret = val[0]

  val[1].each do |expr|
    ret = s(expr[0], ret, expr[1])
  end

  ret
end
combine_optional_operator(val) click to toggle source

@param [Array] val

# File lib/oga/xpath/parser.rb, line 298
def combine_optional_operator(val)
  ret = val[0]

  if val[1]
    ret = s(val[1][0], ret, val[1][1])
  end

  ret
end
each_token() { |type, value| ... } click to toggle source

Yields the next token from the lexer.

@yieldparam [Array]

# File lib/oga/xpath/parser.rb, line 276
def each_token
  @lexer.advance do |type, value, line|
    @line = line if line

    yield [type, value]
  end

  yield [-1, -1]
end
s(type, *children) click to toggle source

Creates a new XPath node.

@param [Symbol] type @param [Array] children @return [AST::Node]

# File lib/oga/xpath/parser.rb, line 269
def s(type, *children)
  AST::Node.new(type, children)
end