A SRGS Introduction

In a speech application, knowing what a caller said is rarely the goal — knowing what they meant is. One caller asks for "Customer Support," another for "Customer Service"; to a call router these are the same request, and the application has to treat them as such. Mapping the words a caller speaks onto the meaning your application acts on is the job of semantic interpretation.

A grammar gets you partway there. When the recognizer matches an utterance, it produces a parse tree — the structure of rules and words it matched. But the tree only tells you which words were spoken and how they nested; turning that structure into a value your application can act on usually takes real post-processing.

Consider an SRGS/ABNF grammar that recognizes spoken numbers from zero to nine hundred ninety-nine. It is deliberately incomplete — it cannot, for instance, recognize "two forty-six" for 246:

#ABNF 1.0;
language en-US;
mode voice;
root $small_number;

$base = one|two|three|four|five|six|seven|eight|nine;
$teen = ten|eleven|twelve|thirteen|fourteen|fifteen|sixteen|seventeen|eighteen|nineteen;
$twenty_to_ninetynine = (twenty|thirty|forty|fifty|sixty|seventy|eighty|ninety)[$base];

$tens = $base|$teen|$twenty_to_ninetynine;

$hundred = ([a] hundred | $base hundred);

$small_number = $hundred [[and] $tens] | $tens;

If the recognizer matches "two hundred twelve," the parse tree looks like this:

$small_number:
  $hundred:
    $base:
      "TWO"
    "HUNDRED"
  $tens:
    $teen:
      "TWELVE"

Suppose your application needs to know whether the caller said a number greater than 500. The parse tree alone cannot tell you — it is a structure of words, not a quantity. Something has to transform that tree into the integer 212.

That logic is bound tightly to the grammar's own rules. Inside $hundred, the optional $base has to be multiplied by 100; inside $twenty_to_ninetynine, the optional $base is instead added to the running total. The transformation only makes sense in terms of the rules that produced the tree.

Because the interpretation is so closely coupled to the rules, the most maintainable place to put it is often inside the grammar itself, alongside the rules it depends on.

That is exactly what Semantic Interpretation for Speech Recognition (SISR) provides. SISR lets you embed tags directly in an SRGS grammar; each tag holds a snippet of ECMAScript (JavaScript) that the recognizer executes as it matches a rule, or part of a rule.

Capacity Private Cloud implements the W3C's first approved SISR Recommendation, version 1.0 (adopted April 2007); see the complete specification for the full reference. Earlier drafts of the specification are also supported, so grammars written against older versions continue to work.

The model behind the Capacity Private Cloud implementation is straightforward:

  1. Each tag holds a snippet of ECMAScript (JavaScript).
  2. Each grammar rule behaves like a function: it executes the code in its tags from left to right and returns a value based on that code.
  3. Referenced rules are executed left to right as well, and any tag that follows a rule reference can use that rule's return value.
  4. A rule's code runs only when the recognizer actually matches that rule.

To start working with SISR, see SISR Basics. Rule Variables and SI Script by Example go deeper, and Getting the Return Value covers how to read SISR results from your application.

If you already know SISR from an earlier version of the standard, see Converting from Older SISR.


Related Articles


Was this article helpful?