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