Class: Dhaka::LexerSupport::DFA

Inherits:
StateMachine show all
Defined in:
lib/lexer/dfa.rb

Overview

:nodoc:

Instance Attribute Summary

Attributes inherited from StateMachine

#start_state

Instance Method Summary collapse

Methods inherited from StateMachine

#to_dot

Constructor Details

#initialize(regex) ⇒ DFA

Returns a new instance of DFA.



10
11
12
13
14
15
16
17
18
19
20
21
22
23
# File 'lib/lexer/dfa.rb', line 10

def initialize(regex)
  @regex = regex

  tokenize_result = RegexTokenizer.tokenize(@regex)
  raise InvalidRegexException.new(tokenize_error_message(tokenize_result)) if tokenize_result.has_error?

  parse_result = RegexParser.parse(tokenize_result)
  raise InvalidRegexException.new(parse_error_message(parse_result)) if parse_result.has_error?

  ast = parse_result
  ast.calculate_follow_sets

  super(ItemSet.new(ast.first))
end

Instance Method Details

#dest_key_for(key, char) ⇒ Object



38
39
40
41
42
43
44
# File 'lib/lexer/dfa.rb', line 38

def dest_key_for key, char
  result = ItemSet.new
  key.each do |position|
    result.merge(position.follow_set) if position.character == char
  end
  result
end

#matches(string) ⇒ Object



59
60
61
62
63
64
65
66
67
# File 'lib/lexer/dfa.rb', line 59

def matches(string)
  curr_state = @start_state
  string.unpack("C*").each do |i|
    dest_state = curr_state.transitions[i.chr]
    return false unless dest_state
    curr_state = dest_state
  end
  return curr_state.accepting?
end

#new_state_for_key(key) ⇒ Object



46
47
48
49
# File 'lib/lexer/dfa.rb', line 46

def new_state_for_key key
   accepting = key.detect {|position| position.accepting} 
   State.new(self, accepting && @regex)
end

#parse_error_message(parse_result) ⇒ Object



29
30
31
32
33
34
35
36
# File 'lib/lexer/dfa.rb', line 29

def parse_error_message(parse_result)
  unexpected_token = parse_result.unexpected_token
  if unexpected_token.symbol_name == END_SYMBOL_NAME
    "Unexpected end of regex."
  else
    "Unexpected token #{parse_result.unexpected_token.symbol_name}: #{@regex.dup.insert(parse_result.unexpected_token.input_position, '>>>')}"
  end
end

#tokenize_error_message(tokenize_result) ⇒ Object



25
26
27
# File 'lib/lexer/dfa.rb', line 25

def tokenize_error_message(tokenize_result)
  "Invalid character #{@regex[tokenize_result.unexpected_char_index].chr}: #{@regex.dup.insert(tokenize_result.unexpected_char_index, '>>>')}"
end

#transition_characters(key) ⇒ Object



51
52
53
54
55
56
57
# File 'lib/lexer/dfa.rb', line 51

def transition_characters key
  result = Set.new
  key.each do |node|
    result << node.character unless node.accepting
  end
  result
end