none
dynamic grammar generation (speech server) RRS feed

  • Question

  • Hello

     

     

    I have seen that in the workflow codebehind there area code made by the speech parser which one join activities and files with the "*.cfg" extension; I think these files are the result of grammar compilation; Is it possible build & compile (generate) these files on the fly? I mean, How can I generate "*.cfg" files dymanically (maybe througth coding)?

     

    Many thanks

    Tuesday, May 29, 2007 12:28 PM

Answers

  • Yes, grammars can be created at run time and then compiled to .cfg files. Here's some example code showing how this can be done. The following method is the code in the code-beside for a CodeActivity. It creates a grammar that can recognize a city name (Auburn or Riverside) and a state name (California, Washington, or Illinois). The grammar consists of one rule (City_State) with two items, SrgsRuleRefs that refer respectively to a simple city name grammar and a simple state name grammar.

     

    After the grammar is created it is compiled to a .cfg.

    Code Snippet

    private void codeActivity1_ExecuteCode(object sender, EventArgs e)

    {

    FileStream fs = new FileStream(cfgPath, FileMode.Create);

    SrgsDocument srgsDoc = new SrgsDocument();

    SrgsRule rootRule = new SrgsRule("City_State");

    rootRule.Scope = SrgsRuleScope.Public;

    // Forward declarations for two other rules

    SrgsRule rule1 = new SrgsRule("City");

    SrgsRule rule2 = new SrgsRule("State");

    // Create the contents of the root rule

    SrgsItem outerItem = new SrgsItem();

    rootRule.Add(outerItem);

    SrgsRuleRef ruleRef = new SrgsRuleRef(rule1);

    outerItem.Add(ruleRef);

    SrgsSemanticInterpretationTag tag = new SrgsSemanticInterpretationTag("$ = \"\"; $ = $$ + \" \"");

    outerItem.Add(tag);

    ruleRef = new SrgsRuleRef(rule2);

    outerItem.Add(ruleRef);

    tag = new SrgsSemanticInterpretationTag("$ = $ + $$");

    outerItem.Add(tag);

    // Now create the contents of the City rule

    SrgsOneOf oneOf = new SrgsOneOf();

    SrgsItem item = new SrgsItem("Auburn");

    oneOf.Add(item);

    item = new SrgsItem("Riverside");

    oneOf.Add(item);

    rule1.Add(oneOf);

    srgsDoc.Rules.Add(rule1);

    // ... and the contents of the State rule

    oneOf = new SrgsOneOf();

    item = new SrgsItem("California");

    oneOf.Add(item);

    item = new SrgsItem("Illinois");

    oneOf.Add(item);

    item = new SrgsItem("Washington");

    oneOf.Add(item);

    rule2.Add(oneOf);

    srgsDoc.Rules.Add(rule2);

    srgsDoc.Rules.Add(rootRule);

    srgsDoc.Mode = SrgsGrammarMode.Voice;

    srgsDoc.Root = rootRule;

    SrgsGrammarCompiler.Compile(srgsDoc, (Stream)fs);

    fs.Close();

    }

     

    The next method is also in the code-beside. It is the TurnStarting event handler for a QuestionAnswerActivity that asks for a city and a state. The first line in the body of this method attaches the grammar created and compiled in the previous method to the QA.

    Code Snippet

    private void askCityAndState_TurnStarting(object sender, TurnStartingEventArgs e)

    {

    Grammar city_stateGrammar = new Grammar(new Uri(cfgPath), "City_State");

    //Grammar city_stateGrammar = new Grammar(new Uri(grxmlPath), "City_State");

    this.askCityAndState.Grammars.Add(city_stateGrammar);

    this.askCityAndState.MainPrompt.SetText("Say a city and a state");

    }

     

    Hope this helps.

    Mark

    Tuesday, May 29, 2007 6:18 PM

All replies

  • Yes, grammars can be created at run time and then compiled to .cfg files. Here's some example code showing how this can be done. The following method is the code in the code-beside for a CodeActivity. It creates a grammar that can recognize a city name (Auburn or Riverside) and a state name (California, Washington, or Illinois). The grammar consists of one rule (City_State) with two items, SrgsRuleRefs that refer respectively to a simple city name grammar and a simple state name grammar.

     

    After the grammar is created it is compiled to a .cfg.

    Code Snippet

    private void codeActivity1_ExecuteCode(object sender, EventArgs e)

    {

    FileStream fs = new FileStream(cfgPath, FileMode.Create);

    SrgsDocument srgsDoc = new SrgsDocument();

    SrgsRule rootRule = new SrgsRule("City_State");

    rootRule.Scope = SrgsRuleScope.Public;

    // Forward declarations for two other rules

    SrgsRule rule1 = new SrgsRule("City");

    SrgsRule rule2 = new SrgsRule("State");

    // Create the contents of the root rule

    SrgsItem outerItem = new SrgsItem();

    rootRule.Add(outerItem);

    SrgsRuleRef ruleRef = new SrgsRuleRef(rule1);

    outerItem.Add(ruleRef);

    SrgsSemanticInterpretationTag tag = new SrgsSemanticInterpretationTag("$ = \"\"; $ = $$ + \" \"");

    outerItem.Add(tag);

    ruleRef = new SrgsRuleRef(rule2);

    outerItem.Add(ruleRef);

    tag = new SrgsSemanticInterpretationTag("$ = $ + $$");

    outerItem.Add(tag);

    // Now create the contents of the City rule

    SrgsOneOf oneOf = new SrgsOneOf();

    SrgsItem item = new SrgsItem("Auburn");

    oneOf.Add(item);

    item = new SrgsItem("Riverside");

    oneOf.Add(item);

    rule1.Add(oneOf);

    srgsDoc.Rules.Add(rule1);

    // ... and the contents of the State rule

    oneOf = new SrgsOneOf();

    item = new SrgsItem("California");

    oneOf.Add(item);

    item = new SrgsItem("Illinois");

    oneOf.Add(item);

    item = new SrgsItem("Washington");

    oneOf.Add(item);

    rule2.Add(oneOf);

    srgsDoc.Rules.Add(rule2);

    srgsDoc.Rules.Add(rootRule);

    srgsDoc.Mode = SrgsGrammarMode.Voice;

    srgsDoc.Root = rootRule;

    SrgsGrammarCompiler.Compile(srgsDoc, (Stream)fs);

    fs.Close();

    }

     

    The next method is also in the code-beside. It is the TurnStarting event handler for a QuestionAnswerActivity that asks for a city and a state. The first line in the body of this method attaches the grammar created and compiled in the previous method to the QA.

    Code Snippet

    private void askCityAndState_TurnStarting(object sender, TurnStartingEventArgs e)

    {

    Grammar city_stateGrammar = new Grammar(new Uri(cfgPath), "City_State");

    //Grammar city_stateGrammar = new Grammar(new Uri(grxmlPath), "City_State");

    this.askCityAndState.Grammars.Add(city_stateGrammar);

    this.askCityAndState.MainPrompt.SetText("Say a city and a state");

    }

     

    Hope this helps.

    Mark

    Tuesday, May 29, 2007 6:18 PM
  •  

    Hello Mark

     

    What´s the difference between grammars & dtfm grammars?, can they also be created/compiled at runtime?

    Many thanks for your help.

    Do you have a reference/sample doc for the ECMAScript argument in SrgsSemanticInterpretationTag?

     

    Many thanks

     

    Javier

     

    Tuesday, May 29, 2007 8:23 PM
  • Javier,

    A DTMF is a special kind of grammar that recognizes dial tones for 0, 1, 2, ..., 9, *, #, and a couple of other tones. The other type of grammar is a voice grammar.

     

    Our docs have some description of the ECMAScript I used in the tags. Look in

    SpeechServer->Development -> Programming Reference -> Speech Recognition Grammar References -> Semantic Interpretation Markup and the topics under that one.

     

    In a nutshell, the ECMAScript I used looks like this in XML:

    Code Snippet
    <tag>$ = ""; $ = $$ + " "</tag>

     

    and this:

    Code Snippet
    <tag>$ = $ + $$</tag>

     

    The two scripts work together to build up a city and state pair. The first script sets the rule variable ($) to an empty string, and then sets the rule variable to the value returned by the first ruleref ($$ represents that value) plus a space. The second script sets the rule variable to its previous value (which should include a city plus a space), and then appends the value returned by the second ruleref.

    Mark

    Tuesday, May 29, 2007 10:47 PM
  • Many thanks Mark

     

    It helps me a lot

     

    Javier (from Colombia!)

    Wednesday, May 30, 2007 4:28 AM