Module: Lexer

Included in:
SpecialGiggle
Defined in:
lib/special-giggle/lexer.rb

Defined Under Namespace

Classes: LexerError, Token

Constant Summary collapse

Patterns =
{
  :Blank          => '[ \t\r]+',
  :NewLine        => '\n+',
  :Print          => 'print',
  :Variable       => '[A-Za-z_][A-Za-z0-9_]*',
  :Number         => '-?[0-9]+',
  :Plus           => '\+',
  :Minus          => '\-',
  :Asterisk       => '\*',
  :Slash          => '\/',
  :Percent        => '\%',
  :Bar            => '\|',
  :Ampersand      => '\&',
  :Caret          => '\^',
  :Tilde          => '\~', 
  :LeftShift      => '<<',
  :RightShift     => '>>',
  :Equal          => '\=',
  :LeftBracket    => '\(',
  :RightBracket   => '\)',
  :SemiColon      => '\;',
}

Class Method Summary collapse

Class Method Details

.next_token(string, index) ⇒ Object



35
36
37
38
39
40
41
42
# File 'lib/special-giggle/lexer.rb', line 35

def self.next_token(string, index)
  Patterns.each do |type, pattern|
    res = string.match(pattern, index)
    next if res.nil?
    return [res[0], type, res.end(0)] if res.begin(0) == index
  end
  [nil, nil, nil]
end

.tokenize(string) ⇒ Object



44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/special-giggle/lexer.rb', line 44

def self.tokenize(string)
  tokens = Array.new
  index, line, column = 0, 1, 1
  while index < string.length
    rstring, rtype, index = next_token(string, index)
    case rtype
    when nil
      raise LexerError, "Unrecognized character in line #{line}, column #{column}"
    when :Blank
      next
    when :NewLine
      line, column = line + 1, 1
    else
      tokens << Token.new(rstring, rtype)
    end
  end
  tokens
end