Using the Speech Parse Tree

#include <LV_SRE_ParseTree.h>

A parse tree represents a sentence diagram of Engine output according to the SRGS grammar that was matched. Information about the tree is accessed through iterators.

Navigating the parse tree in your client application is not the most sophisticated way to retrieve information about an answer. Generally, we recommend you use semantic interpretation tags within a grammar and then use the interpretation object to obtain results.

Here are a few code examples to show how information can be accessed from the speech parse tree. In every example, the active grammar will be the following SRGS grammar:

#ABNF 1.0;
language en-US;
mode voice;
tag-format <XML>; //a made-up tag format.

root $PhoneNumber;

$Digit = one {1} | two {2} | three {3} | four {4} | five {5} |
         six {6} | seven {7} | eight {8} | nine {9} | (zero | oh) {0};         

$AreaCode = [area code | one] {<AREA_CODE>} $Digit<3> {</AREA_CODE>};

$PhoneNumber = [$AreaCode] {<PHONE>} $Digit<7> {</PHONE>};

The decoded sentence will be "area code eight five eight seven o seven o seven o seven." If you do not understand how to write an SRGS Grammar, read the tutorial now.

Example 1: Print the Tags in the tree

C++ API

#include <LV_SRE_ParseTree.h>
#include <iostream>

using namespace std;

void PrintTags(LVParseTree& Tree)
{
     LVParseTree::Iterator Itr = Tree.Begin();
     LVParseTree::Iterator End = Tree.End();

     for (; Itr != End; ++Itr)
     {
          if (Itr->IsTag())
          {
               cout << Itr->Text() << "\n";
          }
     }
}

C++

C API

#include <LV_SRE_ParseTree.h>

void PrintTags(H_PARSE_TREE Tree)
{
     H_PARSE_TREE_NODE N;
     H_PARSE_TREE_ITR Itr;

     Itr = LVParseTree_CreateIteratorBegin(Tree);


     for (; !LVParseTree_Iterator_IsPastEnd(Itr); LVParseTree_Iterator_Advance(Itr))
     {
          N = LVParseTree_Iterator_GetNode(Itr);
          if (LVParseTree_Node_IsTag(N))
          {
               printf("%s ",LVParseTree_Node_GetLabel(N));
          }
     }

     LVParseTree_Iterator_Release(Itr);
}

Result

"<AREA_CODE> 8 5 8 </AREA_CODE> <PHONE> 7 0 7 0 7 0 7 </PHONE>"

Example 2: Print a structured tree

C++ API

#include <LV_SRE_ParseTree.h>
#include <iostream>

using namespace std;

void PrintNode(LVParseTree::Node& N)
{
     for (int i = 0; i < N.Level(); ++i) cout << "     ";
     
     if (N.IsTerminal())
          cout << "\"" << N.Text() << "\"\n";
     if (N.IsTag())
          cout << "{ " << N.Text() << " }\n";
     if (N.IsRule())
     {
          cout << "$" << N.RuleName() << ":\n";
          LVParseTree::ChildrenIterator Itr = N.ChildrenBegin();
          LVParseTree::ChildrenIterator End = N.ChildrenEnd();

          for (;Itr != End; ++Itr)
               PrintNode(*Itr);
     }
}



void PrintTree(LVParseTree& Tree)
{

     PrintNode(Tree.Root());
}

C API

#include <LV_SRE_ParseTree.h>
#include <stdio.h>

void PrintNode(H_PARSE_TREE_NODE N)
{
     H_PARSE_TREE_CHILDREN_ITR I;
     int i;

     for (i = 0; i < LVParseTree_Node_GetLevel(N); ++i)
          printf("     ");
     
     if (LVParseTree_Node_IsTerminal(N))
          printf("\"%s\"\n",LVParseTree_Node_GetText(N));
     if (LVParseTree_Node_IsTag(N))
          printf("{ %s }\n",LVParseTree_Node_GetText(N));
     if (LVParseTree_Node_IsRule(N))
     {
          printf("$%s:\n",LVParseTree_Node_GetRuleName(N));
          I = LVParseTree_Node_CreateChildrenIterator(N);

          while (!LVParseTree_ChildrenIterator_IsPastEnd(I))
          {
               PrintNode(LVParseTree_ChildrenIterator_GetNode(I));
               LVParseTree_ChildrenIterator_Advance(I);
          }
          LVParseTree_ChildrenIterator_Release(I);
     }
}



void PrintTree(H_PARSE_TREE Tree)
{

     PrintNode(LVParseTree_GetRoot(Tree));
}

Result:

$PhoneNumber:
     $AreaCode:
          "AREA"
          "CODE"
          { <AREA_CODE> }
          $Digit:
               "EIGHT"
               { 8 }
          $Digit:
               "FIVE"
               { 5 }
          $Digit:
               "EIGHT"
               { 8 }
          { </AREA_CODE> }
     { <PHONE> }
     $Digit:
          "SEVEN"
          { 7 }
     $Digit:
          "OH"
          { 0 }
     $Digit:
          "SEVEN"
          { 7 }
     $Digit:
          "OH"
          { 0 }
     $Digit:
          "SEVEN"
          { 7 }
     $Digit:
          "OH"
          { 0 }
     $Digit:
          "SEVEN"
          { 7 }
     { </PHONE> }

Once you have examined the results and no longer need to perform decodes on a port, you should unload any local grammars and close that speech port.

See Also


Complete Help Topic List | Speech Engine Product Information