class Pegparse::ParserBase

Parser base class (reusable rules)

Public Class Methods

new(scanner_or_context) click to toggle source
Calls superclass method Pegparse::ParserCore::new
# File lib/pegparse/parser_base.rb, line 5
def initialize(scanner_or_context)
  super(scanner_or_context)
end

Public Instance Methods

_() click to toggle source

match for spaces

# File lib/pegparse/parser_base.rb, line 10
def _
  one_or_more {
    choice(
      ->{ read(/[ \t\r]+/) },
      ->{ read(/\n/) },
      ->{ borrowed_area() },
      ->{ line_comment() },
      ->{ block_comment() },
    )
  }
end
block_comment() click to toggle source
# File lib/pegparse/parser_base.rb, line 27
     def block_comment
  # ret = ""
  # ret << read('/*')
  # ret << zero_or_more {
  #   part = read(/[^*]*/)
  #   break if peek('*/')
  #   part << '*' if optional('*')
  # }.join
  # ret << read('*/')
  # ret
  backtrack
end
deeper_sp() click to toggle source

match for spaces (if spaces cross to the next line, it must have deeper indent than previous line)

# File lib/pegparse/parser_base.rb, line 55
def deeper_sp
  base_line, * = @context.line_counter.position(@context.scanner.pos)
  base_indent = @indent_stack.last
  raise StandardError unless base_indent
  ret = optional{ _ }
  new_line, * = @context.line_counter.position(@context.scanner.pos)
  new_indent = @context.line_counter.indent(@context.scanner.pos)
  backtrack() if base_line != new_line && base_indent >= new_indent
  ret
end
inline_sp() click to toggle source

match for spaces without newline

# File lib/pegparse/parser_base.rb, line 46
def inline_sp
  before_line, * = @context.line_counter.position(@context.scanner.pos)
  ret = optional{ _ }
  after_line, * = @context.line_counter.position(@context.scanner.pos)
  backtrack() if before_line != after_line
  ret
end
lf() click to toggle source

match for spaces (must contain newline)

# File lib/pegparse/parser_base.rb, line 67
def lf
  before_line, * = @context.line_counter.position(@context.scanner.pos)
  ret = optional{ _ }
  after_line, * = @context.line_counter.position(@context.scanner.pos)
  backtrack() if before_line == after_line
  ret
end
line_comment() click to toggle source
# File lib/pegparse/parser_base.rb, line 22
def line_comment
  # read(/#[^\n]*/)
  backtrack
end
separative(separator_matcher, allow_additional_separator: false, &repeat_block) click to toggle source

loop with separator @param separator_matcher [Regexp, String, Proc] @param allow_additional_separator [Boolean] Allow redundant separator at tail.

# File lib/pegparse/parser_base.rb, line 78
def separative(separator_matcher, allow_additional_separator: false, &repeat_block)
  if separator_matcher.is_a? Proc
    separator_proc = separator_matcher
  else
    separator_proc = ->{
      sp()
      read(separator_matcher)
      sp()
    }
  end

  ret = []
  optional {
    ret << repeat_block.call()
    rest = zero_or_more {
      separator_proc.call()
      repeat_block.call()
    }
    ret.concat(rest)
    if allow_additional_separator
      optional {
        separator_proc.call()
      }
    end
  }
  ret
end
sp() click to toggle source

match for spaces

# File lib/pegparse/parser_base.rb, line 41
def sp
  optional{ _ }
end
string_like(end_pattern, normal_pattern, &special_process) click to toggle source

string literal @param end_pattern [String, Regexp] End of literal (e.g. “‘”, “"”) @param normal_pattern [Regexp] Pattern for string without special process (e.g. /[^’\]*/) @param special_process [Proc] Process for special characters. Block should return processed result. @return [Array<String,Object>] Match result. Result has one ore more elements.

If block returned non-string result, array has multiple elements.
# File lib/pegparse/parser_base.rb, line 112
def string_like(end_pattern, normal_pattern, &special_process)
  ret = []
  str = ''
  while true
    str << read(normal_pattern)
    break if peek(end_pattern)
    break if eos?
    break unless special_process
    processed = special_process.call()
    break unless processed
    if processed.is_a? String
      str << processed
    else
      ret << str if str.size > 0
      ret << processed
      str = ''
    end
  end
  ret << str if str.size > 0

  if ret.size > 0
    ret
  else
    ['']
  end
end