Class: Pegparse::ParserBase

Inherits:
ParserCore show all
Defined in:
lib/pegparse/parser_base.rb

Overview

Parser base class (reusable rules)

Direct Known Subclasses

BiopRuleChainImitation

Instance Attribute Summary

Attributes inherited from ParserCore

#start_rule_symbol

Instance Method Summary collapse

Methods inherited from ParserCore

#backtrack, #backtrack_position_to, #best_errors, #borrow_next_line, #borrowed_area, #choice, #eos?, #init_context, #one_or_more, #optional, #parse, #peek, #read, rule, #save_error, wrap_with_trace_method, #zero_or_more

Constructor Details

#initialize(scanner_or_context) ⇒ ParserBase

Returns a new instance of ParserBase.



5
6
7
# File 'lib/pegparse/parser_base.rb', line 5

def initialize(scanner_or_context)
  super(scanner_or_context)
end

Instance Method Details

#_Object

match for spaces



10
11
12
13
14
15
16
17
18
19
20
# 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

#deeper_spObject

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

Raises:

  • (StandardError)


55
56
57
58
59
60
61
62
63
64
# 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_spObject

match for spaces without newline



46
47
48
49
50
51
52
# 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

#lfObject

match for spaces (must contain newline)



67
68
69
70
71
72
73
# 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_commentObject



22
23
24
25
# File 'lib/pegparse/parser_base.rb', line 22

def line_comment
  # read(/#[^\n]*/)
  backtrack
end

#separative(separator_matcher, allow_additional_separator: false, &repeat_block) ⇒ Object

loop with separator

Parameters:

  • separator_matcher (Regexp, String, Proc)
  • allow_additional_separator (Boolean) (defaults to: false)

    Allow redundant separator at tail.



78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# 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

#spObject

match for spaces



41
42
43
# File 'lib/pegparse/parser_base.rb', line 41

def sp
  optional{ _ }
end

#string_like(end_pattern, normal_pattern, &special_process) ⇒ Array<String,Object>

string literal

Parameters:

  • end_pattern (String, Regexp)

    End of literal (e.g. “‘”, “"”)

  • normal_pattern (Regexp)

    Pattern for string without special process (e.g. /[^‘\]*/)

  • special_process (Proc)

    Process for special characters. Block should return processed result.

Returns:

  • (Array<String,Object>)

    Match result. Result has one ore more elements. If block returned non-string result, array has multiple elements.



112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
# 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