Class: Lox::LexicalAnalyzer

Inherits:
Object
  • Object
show all
Defined in:
lib/lox/lexical_analyzer.rb,
lib/lox/lexical_analyzer/invalid_state.rb,
lib/lox/lexical_analyzer/invalid_character.rb,
lib/lox/lexical_analyzer/unterminated_string.rb

Defined Under Namespace

Classes: InvalidCharacter, InvalidState, UnterminatedString

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(input) ⇒ LexicalAnalyzer

Returns a new instance of LexicalAnalyzer.



11
12
13
# File 'lib/lox/lexical_analyzer.rb', line 11

def initialize(input)
  @input = input
end

Instance Attribute Details

#inputObject (readonly)

Returns the value of attribute input.



9
10
11
# File 'lib/lox/lexical_analyzer.rb', line 9

def input
  @input
end

Instance Method Details

#comment(_lexeme, character) ⇒ Object

rubocop:enable Metrics/CyclomaticComplexity rubocop:enable Metrics/MethodLength



52
53
54
55
56
57
58
# File 'lib/lox/lexical_analyzer.rb', line 52

def comment(_lexeme, character)
  if character =~ /./
    :comment
  else
    :default
  end
end

#default(_lexeme, character) ⇒ Object

rubocop:disable Metrics/CyclomaticComplexity rubocop:disable Metrics/MethodLength



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/lox/lexical_analyzer.rb', line 28

def default(_lexeme, character)
  case character
  when /\s/
    :default
  when /[#]/
    :comment
  when /\d/
    [:integer, character]
  when /["]/
    [:string, character]
  when /[a-zA-Z_]/
    [:identifier, character]
  when /[!=<>]/
    [:operator, character]
  when %r{[(){},.\-+;*/]}
    yield([character])
    :default
  else
    raise(InvalidCharacter, character)
  end
end

#each_token(&block) ⇒ Object



15
16
17
18
19
20
21
22
23
24
# File 'lib/lox/lexical_analyzer.rb', line 15

def each_token(&block)
  return enum_for(:each_token) unless block_given?

  state = :default
  lexeme = nil
  input.each_char do |character|
    state, lexeme = method(state).call(lexeme, character, &block)
  end
  eof(state, lexeme, &block)
end

#eof(state, lexeme) ⇒ Object

rubocop:disable Metrics/MethodLength



98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/lox/lexical_analyzer.rb', line 98

def eof(state, lexeme)
  case state
  when :default
    nil
  when :integer
    yield([:integer, Integer(lexeme)])
  when :string
    raise(UnterminatedString, lexeme)
  when :identifier
    yield([:identifier, lexeme])
  when :operator
    yield([lexeme])
  else
    raise(InvalidState, state)
  end
  # rubocop:enable Metrics/MethodLength
end

#identifier(lexeme, character, &block) ⇒ Object



78
79
80
81
82
83
84
85
# File 'lib/lox/lexical_analyzer.rb', line 78

def identifier(lexeme, character, &block)
  if character =~ /\w/
    [:identifier, lexeme + character]
  else
    yield([:identifier, lexeme])
    default(nil, character, &block)
  end
end

#integer(lexeme, character, &block) ⇒ Object



60
61
62
63
64
65
66
67
# File 'lib/lox/lexical_analyzer.rb', line 60

def integer(lexeme, character, &block)
  if character =~ /\d/
    [:integer, lexeme + character]
  else
    yield([:integer, Integer(lexeme)])
    default(nil, character, &block)
  end
end

#operator(lexeme, character, &block) ⇒ Object



87
88
89
90
91
92
93
94
95
# File 'lib/lox/lexical_analyzer.rb', line 87

def operator(lexeme, character, &block)
  if character =~ /[=]/
    yield([lexeme + character])
    :default
  else
    yield([lexeme])
    default(nil, character, &block)
  end
end

#string(lexeme, character) ⇒ Object



69
70
71
72
73
74
75
76
# File 'lib/lox/lexical_analyzer.rb', line 69

def string(lexeme, character)
  if character =~ /["]/
    yield([:string, lexeme[1..-1]])
    :default
  else
    [:string, lexeme + character]
  end
end