Class: RubySpeech::GRXML::Matcher

Inherits:
Object
  • Object
show all
Defined in:
lib/ruby_speech/grxml/matcher.rb,
ext/ruby_speech/ruby_speech.c

Constant Summary collapse

UTTERANCE_CONVERTER =
Hash.new { |hash, key| hash[key] = key }

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(grammar) ⇒ Matcher



21
22
23
24
25
# File 'lib/ruby_speech/grxml/matcher.rb', line 21

def initialize(grammar)
  @grammar = grammar
  prepare_grammar
  compile_regex regexp_content.gsub(/\?<[\w\d\s]*>/, '')
end

Instance Attribute Details

#grammarObject (readonly)

Returns the value of attribute grammar.



19
20
21
# File 'lib/ruby_speech/grxml/matcher.rb', line 19

def grammar
  @grammar
end

Instance Method Details

#compile_regex(regex_string) ⇒ Object



5
6
7
8
9
10
11
12
13
14
15
16
17
# File 'ext/ruby_speech/ruby_speech.c', line 5

static VALUE method_compile_regex(VALUE self, VALUE regex_string)
{
  int erroffset       = 0;
  const char *errptr  = "";
  int options         = 0;
  const char *regex   = StringValueCStr(regex_string);

  pcre *compiled_regex = pcre_compile(regex, options, &errptr, &erroffset, NULL);
  VALUE compiled_regex_wrapper = Data_Wrap_Struct(rb_cObject, 0, pcre_free, compiled_regex);
  rb_iv_set(self, "@regex", compiled_regex_wrapper);

  return Qnil;
}

#find_match(buffer) ⇒ Object



58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'ext/ruby_speech/ruby_speech.c', line 58

static VALUE method_find_match(VALUE self, VALUE buffer)
{
  VALUE RubySpeech  = rb_const_get(rb_cObject, rb_intern("RubySpeech"));
  VALUE GRXML       = rb_const_get(RubySpeech, rb_intern("GRXML"));
  VALUE NoMatch     = rb_const_get(GRXML, rb_intern("NoMatch"));
  pcre *compiled_regex;
  int result = 0;
  int ovector[OVECTOR_SIZE];
  int workspace[WORKSPACE_SIZE];
  char *input = StringValueCStr(buffer);

  Data_Get_Struct(rb_iv_get(self, "@regex"), pcre, compiled_regex);

  if (!compiled_regex) {
    return rb_class_new_instance(0, NULL, NoMatch);
  }

  result = pcre_dfa_exec(compiled_regex, NULL, input, (int)strlen(input), 0, PCRE_PARTIAL,
    ovector, sizeof(ovector) / sizeof(ovector[0]),
    workspace, sizeof(workspace) / sizeof(workspace[0]));

  if (result > 0) {
    if (is_match_end(compiled_regex, input)) {
      return rb_funcall(self, rb_intern("match_for_buffer"), 2, buffer, Qtrue);
    }
    return rb_funcall(self, rb_intern("match_for_buffer"), 1, buffer);
  }
  if (result == PCRE_ERROR_PARTIAL || (int)strlen(input) == 0) {
    VALUE PotentialMatch = rb_const_get(GRXML, rb_intern("PotentialMatch"));
    return rb_class_new_instance(0, NULL, PotentialMatch);
  }
  return rb_class_new_instance(0, NULL, NoMatch);
}

#match(buffer) ⇒ NoMatch, ...

Checks the grammar for a match against an input string

Examples:

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'
  => #<RubySpeech::GRXML::Match:0x00000100ae5d98
        @mode = :dtmf,
        @confidence = 1,
        @utterance = "*9",
        @interpretation = "*9"
      >
  >> matcher.match '1234#'
  => #<RubySpeech::GRXML::Match:0x00000100b7e020
        @mode = :dtmf,
        @confidence = 1,
        @utterance = "1234#",
        @interpretation = "1234#"
      >
  >> matcher.match '5678#'
  => #<RubySpeech::GRXML::Match:0x00000101218688
        @mode = :dtmf,
        @confidence = 1,
        @utterance = "5678#",
        @interpretation = "5678#"
      >
  >> matcher.match '1111#'
  => #<RubySpeech::GRXML::Match:0x000001012f69d8
        @mode = :dtmf,
        @confidence = 1,
        @utterance = "1111#",
        @interpretation = "1111#"
      >
  >> matcher.match '111'
  => #<RubySpeech::GRXML::NoMatch:0x00000101371660>
  ```


92
93
94
# File 'lib/ruby_speech/grxml/matcher.rb', line 92

def match(buffer)
  find_match buffer
end