module Pegparse::BiopRuleChain

Binary operator rule helper.

Public Class Methods

based_on(parser_class, &exec_block) click to toggle source

Create new parser class derived from passed one. If you want to customize parser behavior, override method in exec_block. @return [Class<Pegparse::BiopRuleChainImitation>]

# File lib/pegparse/biop_rule_chain.rb, line 10
def self.based_on(parser_class, &exec_block)
  raise ArgumentError unless parser_class.ancestors.include?(Pegparse::ParserBase)

  klass = Class.new(parser_class) do
    include Pegparse::BiopRuleChain
  end
  klass.class_exec(&exec_block) if exec_block

  klass
end
new(scanner_or_context) click to toggle source
Calls superclass method
# File lib/pegparse/biop_rule_chain.rb, line 21
def initialize(scanner_or_context)
  super(scanner_or_context)
  @start_rule_symbol = :start_rule
  @operators = []
  @term = nil
end

Public Instance Methods

construct_result(lhs, op, rhs) click to toggle source

Default construction of matching result. (override this if you want)

# File lib/pegparse/biop_rule_chain.rb, line 29
def construct_result(lhs, op, rhs)
  [op, lhs, rhs]
end
left_op(operator_matcher) click to toggle source

Add left-associative binary operators. Call in order of operators precedence. If you have multiple operators in same precedence, pass Array as parameter. @param operator_matcher [String, Regexp, Array, Proc] @return [Pegparse::BiopRuleChainImitation]

# File lib/pegparse/biop_rule_chain.rb, line 71
def left_op(operator_matcher)
  @operators << get_operator_matcher(operator_matcher)
  self
end
operand_sp() click to toggle source

Default matching rule of spaces before operand. (override this if you want)

# File lib/pegparse/biop_rule_chain.rb, line 40
def operand_sp
  sp()
end
operator_sp() click to toggle source

Default matching rule of spaces before operator. (override this if you want) This rule will be used when you pass string to left_op.

# File lib/pegparse/biop_rule_chain.rb, line 35
def operator_sp
  sp()
end
term(term_block) click to toggle source

Set terminal matching rule. @param term_block [Proc]

# File lib/pegparse/biop_rule_chain.rb, line 78
def term(term_block)
  @term = term_block
  nil
end

Private Instance Methods

get_operator_matcher(operator_matcher) click to toggle source

Create match proc for operator. @param operator_matcher [Array, Proc, String, Regexp] @return [Proc]

# File lib/pegparse/biop_rule_chain.rb, line 47
        def get_operator_matcher(operator_matcher)
  if operator_matcher.is_a? Array
    ops = operator_matcher.map{|x| get_operator_matcher(x)}
    return ->{
      choice(*ops)
    }
  end
  if operator_matcher.is_a? Proc
    return operator_matcher
  end
  if operator_matcher.is_a?(String) || operator_matcher.is_a?(Regexp)
    return ->{
      operator_sp()
      op = read(operator_matcher)
    }
  end
  raise ArgumentError
end
match(operator_level) click to toggle source

Match expression of the operators which have specified precedence level.

# File lib/pegparse/biop_rule_chain.rb, line 84
        def match(operator_level)
  return @term.call if operator_level >= @operators.size

  lhs = match(operator_level + 1)

  operands = zero_or_more {
    op = choice(*@operators[operator_level])
    operand_sp()
    rhs = match(operator_level + 1)

    [op, rhs]
  }

  tree = operands.inject(lhs) {|subtree, operand|
    construct_result(subtree, operand[0], operand[1])
  }
end
start_rule() click to toggle source

entry point

# File lib/pegparse/biop_rule_chain.rb, line 103
        def start_rule
  match(0)
end