I'm dynamically creating a grammar to perform basic math.
The manually created version follows, it loads in VS.NET and works fine using the grammar test tool.
<grammar xml:lang="en-US" version="1.0" xmlns="http://www.w3.org/2001/06/grammar" xmlns:sapi="http://schemas.microsoft.com/Speech/2002/06/SRGSExtensions" tag-format="semantics-ms/1.0">
<lexicon uri=""/>
<rule id="Rule1" scope="public">
<example> Hey, what is 2 plus 2 </example>
Hey, what is
<item>
<ruleref uri="LibraryV1.grxml#integer" />
<tag> $._x = $$._value </tag>
</item>
<one-of>
<item>
plus <tag> $._op = '+' </tag>
</item>
<item>
minus <tag> $._op = '-' </tag>
</item>
<item>
times <tag> $._op = '*' </tag>
</item>
<item>
divided by <tag> $._op = '/' </tag>
</item>
</one-of>
<item>
<ruleref uri="LibraryV1.grxml#integer" />
<tag> $._y = $$._value </tag>
</item>
</rule>
</grammar>
Now the hard part is trying to recreate it using System.Speech.
First, i tried using GrammarBuilder :
GrammarBuilder
gb = new GrammarBuilder(SettingsImpl.GetInstance().Settings.TriggerName);
gb.Append("What is ");
GrammarBuilder gb1 = new GrammarBuilder();
gb1.AppendRuleReference(strUri, "integer");
SemanticResultKey srkX = new SemanticResultKey("x", gb1);
gb.Append(srkX);
Choices choices = new Choices();
choices.Add("plus");
choices.Add("minus");
choices.Add("times");
choices.Add("multiplied by");
choices.Add("divided by");
SemanticResultKey srk = new SemanticResultKey("operand", choices);
gb.Append(srk);
GrammarBuilder gb2 = new GrammarBuilder();
gb2.AppendRuleReference(strUri, "integer");
SemanticResultKey srkY = new SemanticResultKey("y", gb2);
gb.Append(srkY);
Grammar grammar = new Grammar(gb);
return grammar;
That gives the exception 'a rule reference to an imported grammar cannot be resolved'. Ok, I have never been able to successfully get AppendRuleReference to work ... and I have no clue what I could be doing wrong.
Since there is no other method to combine the SRGS and GrammarBuilder world, the next step is to try and create a SrgsDocument.
string
codeBase =
Assembly.GetExecutingAssembly().GetName().CodeBase;
string strUri = Path.GetDirectoryName(codeBase);
strUri = strUri.Replace("file:\\", String.Empty);
strUri = strUri + @"\LibraryV1.grxml";
Uri uri = new Uri(strUri);
SrgsDocument sDoc = new SrgsDocument();
sDoc.Language = "en-US";
sDoc.Mode = SrgsGrammarMode.Voice;
SrgsRule sRule = new SrgsRule("default");
sRule.Scope = SrgsRuleScope.Public;
sDoc.Rules.Add(sRule);
sDoc.Root = sRule;
SrgsText text1 = new SrgsText(SettingsImpl.GetInstance().Settings.TriggerName + " What is");
SrgsItem itemX = new SrgsItem();
SrgsRuleRef ruleRefX = new SrgsRuleRef(uri, "integer");
itemX.Elements.Add(ruleRefX);
SrgsSemanticInterpretationTag tagX = new SrgsSemanticInterpretationTag("$.x = $$._value");
itemX.Elements.Add(tagX);
SrgsOneOf oneOf = new SrgsOneOf();
oneOf.Items.Add(
new SrgsItem(
"plus"));
oneOf.Items.Add(new SrgsItem("minus"));
oneOf.Items.Add(new SrgsItem("times"));
oneOf.Items.Add(new SrgsItem("multiplied by"));
oneOf.Items.Add(new SrgsItem("divided by"));
oneOf.Items.Add(new SrgsItem("to the power of"));
SrgsItem itemY = new SrgsItem();
SrgsRuleRef ruleRefY = new SrgsRuleRef(uri, "integer");
itemY.Elements.Add(ruleRefY);
SrgsSemanticInterpretationTag tagY = new SrgsSemanticInterpretationTag("$.y = $$._value");
itemY.Elements.Add(tagY);
sRule.Add(text1);
sRule.Add(itemX);
sRule.Add(oneOf);
sRule.Add(itemY);
XmlTextWriter xtw = new XmlTextWriter("srgs.xml", Encoding.Default);
xtw.Formatting = Formatting.Indented;
sDoc.WriteSrgs(xtw);
xtw.Close();
Grammar grammar= new Grammar(sDoc, "default");
return grammar;
It works fine until the semantic tags are added in, then that fails with 'the tag-format' for grammars that include NET semantics must be tag-format=properties-ms/1.0' ... and there is no property to set TagFormat.
Is there no way to get either of the scenarios above to work?
The hack I'm looking at right now is storing what works at XML, loading it in an XmlDocument, and adding the dynamic bits using XML (not the SRGS classes), and then creating a Grammar from that.
Thanks, casey