class Logicality::Lexer::RegexpLexer

This class is a simple lexical token analyzer based on regular expression grammer matchers.

Attributes

expression[R]
index[R]

Public Class Methods

invalid_pattern() click to toggle source
# File lib/logicality/lexer/regexp_lexer.rb, line 17
def invalid_pattern
  "#{pattern}|(\\s*)"
end
invalid_regexp() click to toggle source
# File lib/logicality/lexer/regexp_lexer.rb, line 21
def invalid_regexp
  Regexp.new(invalid_pattern)
end
new(expression) click to toggle source
# File lib/logicality/lexer/regexp_lexer.rb, line 38
def initialize(expression)
  raise ArgumentError, 'Expression is required' unless expression &&
                                                       expression.to_s.length.positive?

  @expression = expression.to_s

  if invalid_matches.length.positive?
    raise ArgumentError, "Invalid syntax: #{invalid_matches}"
  end

  reset
end
pattern() click to toggle source
# File lib/logicality/lexer/regexp_lexer.rb, line 25
def pattern
  Grammar.constants
         .map { |c| Grammar.const_get(c).source }
         .join('|')
end
regexp() click to toggle source
# File lib/logicality/lexer/regexp_lexer.rb, line 31
def regexp
  Regexp.new(pattern)
end

Public Instance Methods

next_token() click to toggle source
# File lib/logicality/lexer/regexp_lexer.rb, line 51
def next_token
  return nil if index > matches.length - 1

  increment

  scan_array = matches[index]

  return nil unless scan_array

  tokens = scan_array.map.with_index do |value, index|
    const = Grammar.constants[index]
    value ? Token.new(const, value) : nil
  end.compact

  raise ArgumentError, "Too many tokens found for: #{scan_array}" if tokens.length > 1

  raise ArgumentError, "Cannot tokenize: #{scan_array}" if tokens.length.zero?

  tokens.first
end
reset() click to toggle source
# File lib/logicality/lexer/regexp_lexer.rb, line 72
def reset
  @index = -1

  self
end

Private Instance Methods

increment() click to toggle source
# File lib/logicality/lexer/regexp_lexer.rb, line 82
def increment
  @index += 1

  nil
end
invalid_matches() click to toggle source
# File lib/logicality/lexer/regexp_lexer.rb, line 88
def invalid_matches
  @invalid_matches ||= expression.gsub(self.class.invalid_regexp, '')
end
matches() click to toggle source
# File lib/logicality/lexer/regexp_lexer.rb, line 92
def matches
  @matches ||= expression.scan(self.class.regexp)
end