Class: Aurum::Builder::LexicalTableBuilder

Inherits:
Object
  • Object
show all
Defined in:
lib/aurum/grammar/builder/lexical_table_builder.rb

Instance Method Summary collapse

Constructor Details

#initialize(lexical_rules, states, literals) ⇒ LexicalTableBuilder

Returns a new instance of LexicalTableBuilder.



8
9
10
11
12
13
14
15
16
# File 'lib/aurum/grammar/builder/lexical_table_builder.rb', line 8

def initialize lexical_rules, states, literals
  @patterns, @literals = lexical_rules.patterns, literals
  @lexical_states = @patterns.keys.to_a - ['all']
  @literal_states, @literal_patterns, @common_patterns = states, {}, @patterns['all'] || {}
  for literal in literals
    pattern = Aurum::Grammar::LexicalRules::Pattern.string(literal.to_s)
    @literal_patterns[pattern] = Aurum::LexicalTable::Action.new("$literal_#{literal}")          
  end
end

Instance Method Details

#buildObject



18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/aurum/grammar/builder/lexical_table_builder.rb', line 18

def build
  automata = Aurum::Grammar::LexicalRules::Automata.new
  start, accepts, actions = automata.new_state, {}, {}
  @lexical_states.each_with_index do |lexical_state, index|
    lexical_state_start = automata.new_state
    automata.connect(start, Aurum::Grammar::LexicalRules::CharacterSet.range(-index - 1), lexical_state_start)
    [@patterns[lexical_state], @common_patterns, literals_in(lexical_state)].each do |patterns|
      for pattern, action in patterns
        pattern_start = automata.merge!(pattern.automata)
        automata.connect(lexical_state_start, Aurum::Grammar::LexicalRules::Epsilon, pattern_start)
        accepts[pattern_start + pattern.accept] = action
      end
    end
  end
  automata, dfa_accepts = Aurum::Grammar::LexicalRules::SubsetDeterminizer.new(automata, accepts.keys).determinize
  for dfa_accept, nfa_accepts in dfa_accepts
    lexical_actions = nfa_accepts.inject([]) {|result, state| result << accepts[state]}
    actions[dfa_accept] = resolve(lexical_actions.uniq)
  end
  automata, actions = Aurum::Grammar::LexicalRules::HopcroftMinimizer.new(automata, actions).minimize
  Aurum::LexicalTable.new(automata.table, @lexical_states, actions)
end