Class: Attentive::Matcher
- Inherits:
-
Object
- Object
- Attentive::Matcher
- Defined in:
- lib/attentive/matcher.rb
Instance Attribute Summary collapse
-
#cursor ⇒ Object
readonly
Returns the value of attribute cursor.
-
#phrase ⇒ Object
readonly
Returns the value of attribute phrase.
-
#pos ⇒ Object
readonly
Returns the value of attribute pos.
Instance Method Summary collapse
-
#initialize(phrase, cursor, params = {}) ⇒ Matcher
constructor
A new instance of Matcher.
- #match! ⇒ Object
- #match_subphrase!(subphrases) ⇒ Object
- #matching? ⇒ Boolean
- #mismatch? ⇒ Boolean
Constructor Details
#initialize(phrase, cursor, params = {}) ⇒ Matcher
Returns a new instance of Matcher.
7 8 9 10 11 12 13 14 15 |
# File 'lib/attentive/matcher.rb', line 7 def initialize(phrase, cursor, params={}) @phrase = phrase @cursor = cursor @pos = params.fetch(:pos, 0) @match_params = params.each_with_object({}) { |(key, value), new_hash| new_hash[key] = value if %i{listener message}.member?(key) } @pos += 1 while phrase[pos] && phrase[pos].whitespace? @match_data = {} @state = :matching end |
Instance Attribute Details
#cursor ⇒ Object (readonly)
Returns the value of attribute cursor.
5 6 7 |
# File 'lib/attentive/matcher.rb', line 5 def cursor @cursor end |
#phrase ⇒ Object (readonly)
Returns the value of attribute phrase.
5 6 7 |
# File 'lib/attentive/matcher.rb', line 5 def phrase @phrase end |
#pos ⇒ Object (readonly)
Returns the value of attribute pos.
5 6 7 |
# File 'lib/attentive/matcher.rb', line 5 def pos @pos end |
Instance Method Details
#match! ⇒ Object
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
# File 'lib/attentive/matcher.rb', line 25 def match! while token = cursor.peek if token.ambiguous? unless match_subphrase!(token.possibilities) @state = :mismatch break end @pos += 1 while phrase[pos] && phrase[pos].whitespace? elsif match_data = phrase[pos].matches?(cursor) if match_data.is_a?(MatchData) new_character_index = cursor.offset + match_data.to_s.length @match_data.merge! Hash[match_data.names.zip(match_data.captures)] # Advance the cursor to the first token after the regexp match cursor_pos = cursor.tokens.index { |token| token.pos >= new_character_index } cursor_pos = cursor.tokens.length unless cursor_pos cursor.instance_variable_set :@pos, cursor_pos @pos += 1 else @match_data.merge!(match_data) unless match_data == true @pos += 1 end @pos += 1 while phrase[pos] && phrase[pos].whitespace? @state = :found # -> This is the one spot where we instantiate a Match return Attentive::Match.new(phrase, @match_params.merge(match_data: @match_data)) if pos == phrase.length elsif !token.skippable? @state = :mismatch break end cursor.pop break unless cursor.peek while cursor.peek.whitespace? cursor.pop break unless cursor.peek end end nil end |
#match_subphrase!(subphrases) ⇒ Object
71 72 73 74 75 76 77 78 79 80 81 82 |
# File 'lib/attentive/matcher.rb', line 71 def match_subphrase!(subphrases) subphrases.each do |subphrase| matcher = Matcher.new(phrase, Cursor.new(subphrase), pos: pos) matcher.match! unless matcher.mismatch? @pos = matcher.pos return true end end false end |
#matching? ⇒ Boolean
17 18 19 |
# File 'lib/attentive/matcher.rb', line 17 def matching? @state == :matching end |
#mismatch? ⇒ Boolean
21 22 23 |
# File 'lib/attentive/matcher.rb', line 21 def mismatch? @state == :mismatch end |