class Bytewise::Lexer
Constants
- ALLOW_ESCAPE_FOR
- ESCAPE_CHAR
- WHITESPACES
Attributes
input[R]
pos[R]
Public Class Methods
new(input)
click to toggle source
# File lib/brace_markup/lexer.rb, line 9 def initialize(input) @input = input @pos = 0 end
Public Instance Methods
escaped?(offset: 0)
click to toggle source
# File lib/brace_markup/lexer.rb, line 154 def escaped?(offset: 0) prev_char = peek(offset: offset - 1, skip_whitespace: false)[:chunk] if prev_char == ESCAPE_CHAR !escaped?(offset: offset - 1) else false end end
escapes?(offset: 0, escape: nil)
click to toggle source
Test if the current character is the escape char () and escapes another character
# File lib/brace_markup/lexer.rb, line 144 def escapes?(offset: 0, escape: nil) escape = ALLOW_ESCAPE_FOR if escape.nil? #escape << ESCAPE_CHAR unless escape.include? ESCAPE_CHAR current_char = peek(offset: offset - 1, skip_whitespace: false)[:chunk] next_char = peek(offset: offset, skip_whitespace: false)[:chunk] current_char == ESCAPE_CHAR && !escaped?(offset: offset - 1) end
expect(chars, skip_whitespace: true, offset: 0, continue: true, raise_error: false, ignore_escaped: false) { || ... }
click to toggle source
Test if the given chars are found.
If continue is set to true it will automatically run next if the given chars are found
# File lib/brace_markup/lexer.rb, line 58 def expect(chars, skip_whitespace: true, offset: 0, continue: true, raise_error: false, ignore_escaped: false, &block) result = peek(length: chars.length, skip_whitespace: skip_whitespace, offset: offset) matches = result[:chunk] == chars if ignore_escaped && escaped?(offset: result[:offset] - chars.length) matches = false end if matches && continue self.next(length: result[:offset], skip_whitespace: false) end if raise_error && !matches raise UnexpectedCharactersException.new chars, self end # Call block if block_given? && matches yield end matches end
line_and_col()
click to toggle source
# File lib/brace_markup/lexer.rb, line 164 def line_and_col buffer = @input[0...@pos] lines = buffer.split "\n" line = lines.length col = lines[-1].length "#{line}:#{col}" end
next(length: 1, skip_whitespace: true)
click to toggle source
# File lib/brace_markup/lexer.rb, line 82 def next(length: 1, skip_whitespace: true) result = peek(length: length, skip_whitespace: skip_whitespace) @pos += result[:offset] result[:chunk] end
next_loop(length: 1, skip_whitespace: true, ignore_escaped: false) { |current, current_buffer| ... }
click to toggle source
# File lib/brace_markup/lexer.rb, line 95 def next_loop(length: 1, skip_whitespace: true, ignore_escaped: false, &block) beginning = @pos last_was_escaped = false if block_given? loop do current = self.next(length: length, skip_whitespace: skip_whitespace) current_buffer = @input[beginning...@pos] if ignore_escaped.is_a?(Array) && escapes?(escape: ignore_escaped) self.next last_was_escaped = true else last_was_escaped = false yield current, current_buffer end break if @pos == @input.length || current.nil? end end end
next_nowhitespace()
click to toggle source
# File lib/brace_markup/lexer.rb, line 90 def next_nowhitespace self.next rewind 1 end
next_until(string:, skip_whitespace: true)
click to toggle source
# File lib/brace_markup/lexer.rb, line 117 def next_until(string:, skip_whitespace: true) if skip_whitespace string = string.chomp end start = @pos loop do current = peek(length: string.length, skip_whitespace: skip_whitespace) if string == current[:chunk] return @input[start...@pos] else @pos += 1 end end end
peek(length: 1, skip_whitespace: true, offset: 0)
click to toggle source
# File lib/brace_markup/lexer.rb, line 14 def peek(length: 1, skip_whitespace: true, offset: 0) buffer = '' counter = 0 loop do current_pos = @pos + offset + counter current_char = @input[current_pos] break if buffer.length >= length unless skip_whitespace && WHITESPACES.include?(current_char) buffer += current_char.to_s end break if current_pos == @input.length counter += 1 end { :chunk => buffer == '' ? nil : buffer, :offset => offset + counter } end
peek_loop(length: 1, skip_whitespace: true) { |current, current| ... }
click to toggle source
# File lib/brace_markup/lexer.rb, line 36 def peek_loop(length: 1, skip_whitespace: true, &block) if block_given? i = 0 loop do current = peek(length: length, skip_whitespace: skip_whitespace, offset: i) i = current[:offset] yield current[:chunk], current[:offset] break if current[:offset] == @input.length break if peek(length: length, skip_whitespace: skip_whitespace, offset: i)[:chunk].nil? end end end
rewind(length = 1)
click to toggle source
# File lib/brace_markup/lexer.rb, line 135 def rewind(length = 1) if @pos - length >= 0 @pos -= length else raise Exception.new('Length can\'t be below 0') end end