Class: Aurum::Grammar::LexicalRules::Pattern

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

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(automata, accept) ⇒ Pattern

Returns a new instance of Pattern.



42
43
44
# File 'lib/aurum/grammar/lexical_rules.rb', line 42

def initialize automata, accept
  @automata, @accept = automata, accept
end

Instance Attribute Details

#acceptObject (readonly)

Returns the value of attribute accept.



41
42
43
# File 'lib/aurum/grammar/lexical_rules.rb', line 41

def accept
  @accept
end

#automataObject (readonly)

Returns the value of attribute automata.



41
42
43
# File 'lib/aurum/grammar/lexical_rules.rb', line 41

def automata
  @automata
end

Class Method Details

.character_set(char_set) ⇒ Object



28
29
30
31
# File 'lib/aurum/grammar/lexical_rules.rb', line 28

def self.character_set(char_set)
  automata = Automata.new(2)
  Pattern.new(automata, automata.connect(0, char_set, 1))
end

.concat(patterns) ⇒ Object



33
34
35
36
37
38
39
# File 'lib/aurum/grammar/lexical_rules.rb', line 33

def self.concat patterns
  automata, index = Automata.new, 0
  for pattern in patterns
    index = automata.connect(index, Epsilon, automata.merge!(pattern.automata)) + pattern.accept
  end
  Pattern.new(automata, index)
end

.enum(literal) ⇒ Object



24
25
26
# File 'lib/aurum/grammar/lexical_rules.rb', line 24

def self.enum(literal)
  character_set(CharacterSet.enum(literal))
end

.string(literal) ⇒ Object



18
19
20
21
22
# File 'lib/aurum/grammar/lexical_rules.rb', line 18

def self.string(literal)
  automata, index = Automata.new(literal.size + 1), 0
  literal.each_byte {|byte|automata.connect(index, CharacterSet::Interval.new(byte).to_char_set, (index += 1))}
  Pattern.new(automata, index)
end

Instance Method Details

#[](least, most = least) ⇒ Object



79
80
81
# File 'lib/aurum/grammar/lexical_rules.rb', line 79

def [] least, most = least
  Pattern.concat([self] * least + [self.zero_or_one] * (most-least))
end

#notObject



65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/aurum/grammar/lexical_rules.rb', line 65

def not
  deterministic, accepts = SubsetDeterminizer.new(@automata, [@accept]).determinize
  sink = deterministic.new_state        
  deterministic.connect(sink, CharacterSet.any, sink)
  sink.times do |state|
    joint = CharacterSet.any
    deterministic.table[state].each {|tran| joint -= tran.character_set}
    deterministic.connect(state, joint, sink) unless joint.empty?
  end
  accept = deterministic.new_state
  accept.times {|state| deterministic.connect(state, Epsilon, accept) unless accepts.has_key? state }
  Pattern.new(deterministic, accept)
end

#one_or_moreObject



53
54
55
56
57
# File 'lib/aurum/grammar/lexical_rules.rb', line 53

def one_or_more
  automata = @automata.dup
  automata.connect(@accept, Epsilon, 0)
  Pattern.new(automata, @accept)
end

#zero_or_moreObject



46
47
48
49
50
51
# File 'lib/aurum/grammar/lexical_rules.rb', line 46

def zero_or_more
  automata = @automata.dup
  automata.connect(0, Epsilon, @accept)
  automata.connect(@accept, Epsilon, 0)
  Pattern.new(automata, @accept)
end

#zero_or_oneObject



59
60
61
62
63
# File 'lib/aurum/grammar/lexical_rules.rb', line 59

def zero_or_one
  automata = @automata.dup
  automata.connect(0, Epsilon, @accept)
  Pattern.new(automata, @accept)
end

#|(other) ⇒ Object



83
84
85
86
87
88
89
# File 'lib/aurum/grammar/lexical_rules.rb', line 83

def | other
  automata = Automata.new(2)
  for pattern in [self, other]
    automata.connect(automata.connect(0, Epsilon, automata.merge!(pattern.automata)) + pattern.accept, Epsilon, 1)
  end
  Pattern.new(automata, 1)
end

#~Object



91
92
93
94
# File 'lib/aurum/grammar/lexical_rules.rb', line 91

def ~
  any = Pattern.character_set(CharacterSet.any).zero_or_more
  Pattern.concat([Pattern.concat([any, self, any]).not, self])
end