require 'ruby_speech/ruby_speech' if RUBY_PLATFORM =~ /java/ require 'jruby' com.benlangfeld.ruby_speech.RubySpeechService.new.basicLoad(JRuby.runtime) end module RubySpeech module GRXML class Matcher attr_reader :grammar def initialize(grammar) @grammar = grammar prepare_grammar compile_regex regexp_content end ## # Checks the grammar for a match against an input string # # @param [String] other the input string to check for a match with the grammar # # @return [NoMatch, PotentialMatch, Match, MaxMatch] depending on the result of a match attempt. A potential match indicates that the buffer is valid, but incomplete. A MaxMatch is differentiated from a Match in that it cannot accept further input. If a match can be found, it will be returned with appropriate mode/confidence/utterance and interpretation attributes # # @example A grammar that takes a 4 digit pin terminated by hash, or the *9 escape sequence # ```ruby # grammar = RubySpeech::GRXML.draw :mode => :dtmf, :root => 'pin' do # rule :id => 'digit' do # one_of do # ('0'..'9').map { |d| item { d } } # end # end # # rule :id => 'pin', :scope => 'public' do # one_of do # item do # item :repeat => '4' do # ruleref :uri => '#digit' # end # "#" # end # item do # "\* 9" # end # end # end # end # # matcher = RubySpeech::GRXML::Matcher.new grammar # # >> matcher.match '*9' # => # # >> matcher.match '1234#' # => # # >> matcher.match '5678#' # => # # >> matcher.match '1111#' # => # # >> matcher.match '111' # => # # ``` # def match(buffer) find_match buffer.dup end private def regexp_content '^' + grammar.root_rule.children.map(&:regexp_content).join + '$' end def prepare_grammar grammar.inline! grammar.tokenize! grammar.normalize_whitespace end def match_for_buffer(buffer, maximal = false) match_class = maximal ? MaxMatch : Match match_class.new mode: grammar.mode, confidence: grammar.dtmf? ? 1 : 0, utterance: buffer, interpretation: interpret_utterance(buffer) end def interpret_utterance(utterance) conversion = Hash.new { |hash, key| hash[key] = key } conversion['*'] = 'star' conversion['#'] = 'pound' utterance.chars.inject [] do |array, digit| array << "dtmf-#{conversion[digit]}" end.join ' ' end end end end