Overview
JJSGF is a JSON version of JSGF (JSpeech Grammar Format). They are equivalent to GRXML grammars.
Here is an example JSGF grammar take from the W3C document:
#JSGF V1.0 ISO8859-1 en;
grammar com.acme.commands;
import <com.acme.politeness.startPolite>;
import <com.acme.politeness.endPolite>;
/**
* Basic command.
* @example please move the window
* @example open a file
*/
public <basicCmd> = <startPolite> <command> <endPolite>;
<command> = <action> <object>;
<action> = /10/ open |/2/ close |/1/ delete |/1/ move;
<object> = [the | a] (window | file | menu);
This grammar references two external grammars (startPolite and endPolite), plus it uses weights - the /10/ and so on elements.
Expressed in our JJSGF format, the JSON representing the grammar would be:
{
"type" : "JJSGF",
"grammar" : "com.acme.command",
"imports" : [
"com.acme.politeness.startPolite",
"com.acme.politeness.endPolite"
]
"public" : {
"basicCmd" : "<startPolite> <command> <endPolite>"
},
"rules" : {
"command" : "<action> <object>",
"action" : "/10/ open |/2/ close |/1/ delete |/1/ move",
"object" : "[the | a] (window | file | menu)"
}
}
In JJSGF, the names of the rules may not start with a digit and may not contain dashes.
Literal Tags
JJSGF does support JSGF tags including ECMA/javascript processing.
Below is an example of a grammar with the "semantics/1.0-literals" tag format. Note that only a single literal tag will be returned. If more than one are on a matching path, only the last one will be returned.
The value of literal tag will be returned in the "literalTag" field in the result.
{
"type": "JJSGF",
"parameters" : {"tag-format" : "semantics/1.0-literals"},
"grammar": "my-zip-code-grammar",
"public": {
"root": "<digit> <digit> <digit> <digit> <digit> {got_zip}"
},
"rules": {
"digit": "zero|one|two|three|four|five|six|seven|eight|nine"
}
}
ECMA Tags
Below is an example of grammar with "semantics/1.0" tag format. This format allows for use of javascript (ECMA Script) to manipulate and compose tags. You can read more about it int this W3C document.
Values of the tags will be returned in the "semanticTags" field of the result.
{
"type": "JJSGF",
"parameters" : {"tag-format" : "semantics/1.0"},
"grammar": "my-zip-with-tags",
"public": {
"root": "(<digit> {d1=rules.digit.d;}) (<digit> {d2=rules.digit.d;}) (<digit> {d3=rules.digit.d;}) (<digit> {d4=rules.digit.d;}) (<digit> {d5=rules.digit.d;}) {out.zip=d1+d2+d3+d4+d5;}"
},
"rules": {
"digit": "(zero {out.d='0';}) | (one {out.d='1';}) | (two {out.d='2';}) | (three {out.d='3';}) | (four {out.d='4';}) | (five {out.d='5';}) | (six {out.d='6';}) | (seven {out.d='7';}) | (eight {out.d='8';}) | (nine {out.d='9';})"
}
}
DTMF support
By specifying mode=dtmf you instruct the recognizer to process the grammar as a DTMF grammar. Here is an example of such a grammar. The rules will match only digits 0 through 9 plus * and #:
{
"type": "JJSGF",
"grammar": "my-phone",
"parameters" : {"mode" : "dtmf"}.
"public": {
"root": "(<digit> {d1=rules.digit.d;}) (<digit> {d2=rules.digit.d;}) (<digit> {d3=rules.digit.d;}) (<digit> {d4=rules.digit.d;}) (<digit> {d5=rules.digit.d;}) (<digit> {d6=rules.digit.d;}) (<digit> {d7=rules.digit.d;}) (<digit> {d8=rules.digit.d;}) (<digit> {d9=rules.digit.d;}) (<digit> {d10=rules.digit.d;}) {out.phone='+1'+d1+d2+d3+d4+d5+d6+d7+d8+d9+d10;}"
},
"rules": {
"digit": "(0 {out.d='0';}) | (1 {out.d='1';}) | (2 {out.d='2';}) | (3 {out.d='3';}) | (4 {out.d='4';}) | (5 {out.d='5';}) | (6 {out.d='6';}) | (7 {out.d='7';}) | (8 {out.d='8';}) | (9 {out.d='9';})"
}
}
Here is an example DTMF JJSGF grammar for a simple IVR menu.
{
"type": "JJSGF",
"parameters": {
"tag-format": "semantics/1.0-literals",
"mode" : "dtmf"
},
"grammar": "menu",
"public": {
"root": "<billing> | <support> | <retention> | <agent> | <main_menu>"
},
"rules": {
"billing": "(1) {billing}",
"support": "(2) {support}",
"retention": "(3) {retention}",
"agent": "(0) {agent}",
"main_menu": "(*) {main_menu}"
}
}
Complex grammar example
Here is a grammar with literal tags that comes from a food ordering application:
{
"type": "JJSGF",
"parameters": {
"tag-format": "semantics/1.0-literals"
},
"grammar": "pizza",
"public": {
"root": "<card_phrase> {card} | <cash_phrase> {cash} | <pickup_phrase> {pickup} | <delivery_phrase> {delivery} | <agent_phrase> {agent} | <yes_phrase> {yes} | <no> {no} | <hello> {hello} "
},
"rules": {
"yes_phrase": "([sure|ok] ([<yes> [<yes>]] <yes> ))",
"yes": "(yes|yeah)",
"no": "([no] no)",
"hello": "((hello) | (hell oh) | (hlo))",
"card_phrase": "[uh]( ([[i] [will] pay] [debit] <card> [at [the] store]) | (paying with [a] <card>) | (it will be <card>) )",
"card": "(card|cord|car|cart)",
"cash_phrase": "[uhm|yes] (([[(i [will]) | (i'll)] pay] <cash> [at [the] store]) | (paying <cash>) | (it will be <cash>) | (by <cash>) | (<cash> <cash>))",
"cash": "(cash | cosh | (c a s h cash))",
"pickup_phrase": "[uh|ah] (([i'll] <pickup> [at [the] store]) | (store <pickup>) | ([[(it's | order)] for] <pickup>) | ([<pickup>] <pickup> <pickup>))",
"pickup": "(pickup | (pick up) | ((curbside|curside) [pickup]) | (carryout) | (takeout))",
"delivery_phrase": "(([((it will)|(it'll)) be] [for] <delivery>) | ([[i] (want|wanna) [to]] [order] [for] <delivery>) ) [it's a robot i think]",
"deliver>": "([a | the] (delivery | delivry | dilivry | deliver | delivered))",
"agent_phrase": "([card<yes>|no|neither|none|but] (([[([i] (need|want) to) | (could i) | (i wanna) | (can i) | (canna) | (may i)] (speak|talk) to] <agent> [dude|man]) | ( transfer [me] [to] <agent>) | (i want <agent> [to talk to]) | (give me <agent>)))",
"agent": "( [a|aye|an|the] ((customer service) | (agent) | (representative|represenative) | (someone|somewa|somebody) | (someone else) | (human [being]) | ([live|lie] person) | (operator) | (store)))"
}
}
Comments
0 comments
Article is closed for comments.