Using the 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>;
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>
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);
}
C++ Code
#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";
}
}
}
Result
"<AREA_CODE> 8 5 8 </AREA_CODE> <PHONE> 7 0 7 0 7 0 7 </PHONE>"
Example 2: Print a structured tree
C Code
#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));
}
C++ Code
#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());
}
Result:
- $PhoneNumber:
- $AreaCode:
- "AREA"
- "CODE"
- { <AREA_CODE> }
- $Digit:
- $Digit:
- $Digit:
- { </AREA_CODE> }
- { <PHONE> }
- $Digit:
- $Digit:
- $Digit:
- $Digit:
- $Digit:
- $Digit:
- $Digit:
- </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