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>; //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

  1. #include <LV_SRE_ParseTree.h>
  2.  
  3. void PrintTags(H_PARSE_TREE Tree)
  4. {
  5. H_PARSE_TREE_NODE N;
  6. H_PARSE_TREE_ITR Itr;
  7.  
  8. Itr = LVParseTree_CreateIteratorBegin(Tree);
  9.  
  10. for (; !LVParseTree_Iterator_IsPastEnd(Itr); LVParseTree_Iterator_Advance(Itr))
  11. {
  12. N = LVParseTree_Iterator_GetNode(Itr);
  13. if (LVParseTree_Node_IsTag(N))
  14. {
  15. printf("%s ",LVParseTree_Node_GetLabel(N));
  16. }
  17. }
  18.  
  19. LVParseTree_Iterator_Release(Itr);
  20. }

C++ Code

  1. #include <LV_SRE_ParseTree.h>
  2. #include <iostream>
  3.  
  4. using namespace std;
  5.  
  6. void PrintTags(LVParseTree& Tree)
  7. {
  8. LVParseTree::Iterator Itr = Tree.Begin();
  9. LVParseTree::Iterator End = Tree.End();
  10.  
  11. for (; Itr != End; ++Itr)
  12. {
  13. if (Itr->IsTag())
  14. {
  15. cout << Itr->Text() << "\n";
  16. }
  17. }
  18. }

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

  1. #include <LV_SRE_ParseTree.h>
  2. #include <stdio.h>
  3.  
  4. void PrintNode(H_PARSE_TREE_NODE N)
  5. {
  6. H_PARSE_TREE_CHILDREN_ITR I;
  7. int i;
  8.  
  9. for (i = 0; i < LVParseTree_Node_GetLevel(N); ++i)
  10. printf("     ");
  11.  
  12. if (LVParseTree_Node_IsTerminal(N))
  13. printf("\"%s\"\n",LVParseTree_Node_GetText(N));
  14. if (LVParseTree_Node_IsTag(N))
  15. printf("{ %s }\n",LVParseTree_Node_GetText(N));
  16. if (LVParseTree_Node_IsRule(N))
  17. {
  18. printf("$%s:\n",LVParseTree_Node_GetRuleName(N));
  19. I = LVParseTree_Node_CreateChildrenIterator(N);
  20.  
  21. while (!LVParseTree_ChildrenIterator_IsPastEnd(I))
  22. {
  23. PrintNode(LVParseTree_ChildrenIterator_GetNode(I));
  24. LVParseTree_ChildrenIterator_Advance(I);
  25. }
  26. LVParseTree_ChildrenIterator_Release(I);
  27. }
  28. }
  29.  
  30. void PrintTree(H_PARSE_TREE Tree)
  31. {
  32. PrintNode(LVParseTree_GetRoot(Tree));
  33. }

C++ Code

  1. #include <LV_SRE_ParseTree.h>
  2. #include <iostream>
  3.  
  4. using namespace std;
  5.  
  6. void PrintNode(LVParseTree::Node& N)
  7. {
  8. for (int i = 0; i < N.Level(); ++i) cout << "     ";
  9.  
  10. if (N.IsTerminal())
  11. cout << "\"" << N.Text() << "\"\n";
  12. if (N.IsTag())
  13. cout << "{ " << N.Text() << " }\n";
  14. if (N.IsRule())
  15. {
  16. cout << "$" << N.RuleName() << ":\n";
  17. LVParseTree::ChildrenIterator Itr = N.ChildrenBegin();
  18. LVParseTree::ChildrenIterator End = N.ChildrenEnd();
  19.  
  20. for (;Itr != End; ++Itr)
  21. PrintNode(*Itr);
  22. }
  23. }
  24.  
  25. void PrintTree(LVParseTree& Tree)
  26. {
  27. PrintNode(Tree.Root());
  28. }

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

© 2012 LumenVox LLC. All rights reserved.