Overview of SAPI Grammar: Solitaire Example

Microsoft Speech SDK

The Microsoft.com Speech website Microsoft Speech SDK SAPI 5.1

SAPI Grammar Example: Solitaire

Grammar rules define sentence contents and phrase elements. Each grammar and grammar element determines the speech recognition (SR) engine's ability to effectively construct phrase elements. Phrases and sub–expressions are commonly represented by a separate rule and combined into larger phrases and sentences with higher level rules. For more information, see the Grammar rules section.

The card game called Solitaire, uses semantic objects such as cards, suits, and ranks, and semantic actions, such as "move SomeCard to AnotherCard", and "new game." The following example illustrates how to implement a grammar for a game of solitaire, which supports the previously mentioned semantic objects and actions. The example also specifies the exact voice command phrases (in American English) that must be spoken in order to play the game.

<!-- The grammar tag surrounds the entire CFG description
       Specify the language of the grammar as
       English-American ('409') -->
<GRAMMAR LANGID="409">
    <!-- Specify a set of easy-to-read strings to
            represent specific values. Similar to
            constants or #define in Visual Basic or
            C/++ programming languages -->
    <DEFINE>
        <ID NAME="FROM" VAL="1"/>
        <ID NAME="TO" VAL="2"/>
        <ID NAME="SUIT" VAL="3"/>
        <ID NAME="COLOR" VAL="4"/>
        <ID NAME="RANK" VAL="5"/>
        <ID NAME="ColorRed" VAL="11101"/>
        <ID NAME="ColorBlack" VAL="10011"/>
    </DEFINE>

   <!-- Define a top-level rule for the new game
           command, called 'newgame' -->
   <!-- Make the rule 'active', by default, so
           the rule is available as soon is speech
           is activated in the application -->
   <RULE NAME="newgame" TOPLEVEL="ACTIVE">
      <!-- Require high confidence for the word,
              game, to avoid accidental recognition
              of this important rule -->
      <!-- Make the last word, please, optional,
              only require low-confidence to
              make the command phrasing more
              flexible -->
      <P>new +game</P><O>-please</O>
   </RULE>

   <!-- Define another active top-level rule,
          called 'playcard' which enables the user
          to use voice commanding to play cards -->
   <!-- Define the 'playcard' rule as exportable, so
          we can create other solitaire or card game
          grammars which can re-use the 'playcard'
          rule functionality. -->
   <RULE NAME="playcard" TOPLEVEL="ACTIVE" EXPORT="1">
      <O>please</O>
      <P>play the</P>
         <!-- Allow for extraneous garbage words
              from the user. The user could say
              "play the little ace of spades" without
              breaking the voice command -->
      <O>...</O>
         <!-- Use a rule reference to a card grammar
                 which is defined elsewhere in the
                 overall solitaire grammar. Using
                 rule references is similar to
                 reusable components in an object-
                 oriented programming language or
                 component model -->
      <RULEREF NAME="card"/>
      <O>please</O>
   </RULE>

   <!-- Define another top-level voice command for
          moving one card to another location -->
   <!-- Note that phrase structure allows for two
           types of move-commands by making to_card
           section optional. The grammar supports
           both 'move from_card to to_card' and
           simply 'move from_card'. The application
           can select the from_card when the latter
           voice command is recognized, or the
           application can perform the full move
           with the former voice command. -->
   <RULE NAME="movecard" TOPLEVEL="ACTIVE">
      <O>please</O>
      <P>
         <L>
            <P>move</P>
            <P>put</P>
         </L>
         <P>the</P>
      </P> 
      
      <!-- Use a semantic tag/property, called 'FROM'
              which represents the from_card, and
              will contain the phrase structure
              recognized in the rule reference. By
              using semantic properties, the application
              can abstract away the exact phrase text
              and build application logic based on
              the action (i.e., Action=move 
              FromCard=(Rank=Ace, Suit=Hearts) -->
      <RULEREF PROPNAME="from" PROPID="FROM" NAME="card"/>
      <O>
         <L>
            <P>on</P>
            <P>to</P>
         </L>
         <P>the</P>
         <!-- Use another semantic property for the
                 ToCard information -->
         <RULEREF PROPNAME="to" PROPID="TO" NAME="card"/>
      </O>
      <O>please</O>
   </RULE>

   <!-- Create a reusable card grammar, which contains
           the structure of a card's descriptor (e.g.,
           "red ace", "ace of hearts", or "heart").
           Note: It is not a top-level rule, since
              it is only used by other top-level
              rules and is not directly recognizable -->
   <RULE NAME="card">
      <!-- Use a phrase list to allow the descriptor
           to be one of three forms, including
           a color and rank, or a rank and
           suit, or only a suit. -->
     <!-- The application can decode the
             card by analyzing the semantic
             property structure. For example,
             the color and rank form will
             include a property called 'color'
             with a value either ColorRed or
             ColorBlack (note that these values
             are actually numeric defines).-->
      <L>
         <P><!-- color and rank form -->
            <L PROPNAME="color" PROPID="COLOR">
               <P VAL="ColorRed">red</P>
               <P VAL="ColorBlack">black</P>
            </L>
            <RULEREF NAME="rank"/>
         </P>
         <P><!-- rank and suit form -->
            <RULEREF NAME="rank"/>
            <O>
               <P>of</P>
               <L PROPNAME="suit" PROPID="SUIT">
                  <P VAL="0">clubs</P>
                  <P VAL="1">hearts</P>
                  <P VAL="2">diamonds</P>
                  <P VAL="3">spades</P>
               </L>
            </O>
         </P>
         <!-- suit only form -->
         <L PROPNAME="suit" PROPID="SUIT">
            <P VAL="0">club</P>
            <P VAL="1">heart</P>
            <P VAL="2">diamond</P>
            <P VAL="3">spade</P>
         </L>
      </L>
   </RULE>
   <!-- Create a reusable grammar component, called
           'rank' which represents the numeric rank
           of the various cards. Note that each card
           has an associated value.
        The application can use the semantic property
           called 'rank' (specified by PROPNAME), and
           the value (specified by VAL) to abstract
           itself from the phrasing, and use only the
           numeric rank values. Note that the words
           'king' and 'emperor' both refer to the
           value 13. The grammar author can change
           or update the text without breaking the
           application's semantically-dependent
           logic -->
   <RULE NAME="rank">
      <!-- Specify the property name/id in the LIST
              tag, which will be inherited by all
              of the list tag's child phrase tags.
           Specifying the name/id in the LIST tag avoids
              having to specify it multiple times, once
              for each P tag -->
      <L PROPNAME="rank" PROPID="RANK">
         <P VAL="1">ace</P>
         <P VAL="2">two</P>
         <P VAL="3">three</P>
         <P VAL="4">four</P>
         <P VAL="5">five</P>
         <P VAL="6">six</P>
         <P VAL="7">seven</P>
         <P VAL="8">eight</P>
         <P VAL="9">nine</P>
         <P VAL="10">ten</P>
         <P VAL="11">jack</P>
         <P VAL="12">queen</P>
         <P VAL="13">king</P>
         <P VAL="12">lady</P>
         <P VAL="13">emperor</P>
      </L>
   </RULE>
<!-- End of Grammar definition -->
</GRAMMAR>

return to the top of this pageBack to top