class Attentive::Matcher

Attributes

cursor[R]
message[R]
phrase[R]

Public Class Methods

match!(phrase, message) click to toggle source
# File lib/attentive/matcher.rb, line 7
def self.match!(phrase, message)
  phrase = Attentive::Tokenizer.tokenize(phrase, entities: true) unless phrase.is_a?(Attentive::Phrase)
  message = Attentive::Message.new(message) unless message.is_a?(Attentive::Message)
  self.new(phrase, Attentive::Cursor.new(message)).match!
end
new(phrase, message, params={}) click to toggle source
# File lib/attentive/matcher.rb, line 13
def initialize(phrase, message, params={})
  @phrase = phrase
  @match_start = message.pos
  @cursor = Cursor.new(phrase, params.fetch(:pos, 0))
  @message = message
  self.message.pop while self.message.peek.whitespace?
  @match_params = params.merge(message: message.message, match_start: message.pos)
  @match_data = {}
  @state = :matching

  cursor.pop while cursor.peek.whitespace?
end

Public Instance Methods

match!() click to toggle source
# File lib/attentive/matcher.rb, line 38
def match!
  until (token = message.peek).eof?
    if token.ambiguous?
      unless match_any!(token.possibilities)
        @state = :mismatch
        break
      end
      message.pop
      cursor.pop while cursor.peek.whitespace?

    elsif match_data = cursor.peek.matches?(message)
      @match_data.merge!(match_data) unless match_data == true
      cursor.pop
      cursor.pop while cursor.peek.whitespace?
      @state = :found

      # -> This is the one spot where we instantiate a Match
      return Attentive::Match.new(phrase, @match_params.merge(
        match_end: message.pos,
        match_data: @match_data)) if cursor.eof?

    elsif token.skippable?
      message.pop

    else
      @state = :mismatch
      break
    end

    message.pop while message.peek.whitespace?
  end

  nil
end
match_any!(messages) click to toggle source
# File lib/attentive/matcher.rb, line 73
def match_any!(messages)
  messages.each do |message|
    matcher = Matcher.new(phrase[pos..-1], Cursor.new(message))
    matcher.match!
    unless matcher.mismatch?
      cursor.advance matcher.pos
      return true
    end
  end

  false
end
matching?() click to toggle source
# File lib/attentive/matcher.rb, line 30
def matching?
  @state == :matching
end
mismatch?() click to toggle source
# File lib/attentive/matcher.rb, line 34
def mismatch?
  @state == :mismatch
end
pos() click to toggle source
# File lib/attentive/matcher.rb, line 26
def pos
  cursor.pos
end