Rule references
You can reference grammar rules inside rule expansions, as we have already seen (in our simple yes or no grammar, the root rule referenced the yes and no rules).
Rule references work slightly differently in ABNF and GrXML.
ABNF Example
$yesorno = $yes | $no; |
In ABNF, you can simply reference a rule by the rulename as part of a rule expansion. When referencing a rule, the dollar sign character $ is used to indicate a rulename (so $yes indicates a rule reference to the "yes" rule and not the word "yes").
GrXML Example
<rule id="yesorno"> <one-of> <item><ruleref uri="#yes" /></item> <item><ruleref uri="#no" /></item> </one-of> </rule> |
In GrXML, the special element ruleref is used. It takes an attribute called uri whose value should be set to the URI of the rule you are referencing. In the event that the rule you are referencing is in the current grammar, you prefix the rule name with the pound or hash symbol # to indicate the rule is local. Note that because the ruleref element does not take any children, it must be closed with a slash / character before the closing > tag.
When either grammar is parsed, the contents of the yes and no rules are included as part of the yesorno rule. A rule is considered the child of any rule that references it.
You can also reference external grammar files -- or rules within external files -- to create more complex grammars, and re-use existing grammars. As an example, suppose you had a simple phone number grammar at the remote URI http://www.mycompany.com/phone_number.gram that looked like this:
ABNF Example
#ABNF 1.0; language en-US; mode voice; root $phone_number; $phone_number = [$area_code] $number; $digit = one | two | three | four | five | six | seven | eight | nine | zero; $area_code = [one | area code] $digit<3>; $number = $digit<7>; |
You can use this grammar in another grammar by specifying its location, inside of angle brackets, as a rulename:
#ABNF 1.0; language en-US; mode voice; root $main; $main = (my | the) [phone] number is $<http://www.mycompany.com/phone_number.gram>; |
GrXML Example
<?xml version="1.0" encoding="UTF-8" ?> |
The above grammar can be referenced in another GrXML grammar by giving the fully-qualified URI in the ruleref element:
<?xml version="1.0" encoding="UTF-8" ?> <grammar xmlns="http://www.w3.org/2001/06/grammar" xml:lang="en-US" root="phone_number" mode="voice"> <rule id="main"> <one-of> <item>my</item> <item>the</item> </one-of> <item repeat="0-1">phone</item> number is <ruleref uri="http://www.mycompany.com/phone_number.gram" /> </rule> |
In both GrXML and ABNF, the same basic logic takes place: the second grammar is using the root rule of the phone_number grammar in its main rule. You can reference grammar files using HTTP, FTP, or your operating system's local or network file descriptors. When writing grammars that use external grammar files, it's usually a good idea to specify a base URI in your grammar header.
By default, referencing an external grammar always references that grammar's root rule. It is also possible to reference a specific rule within an external grammar, by using the # symbol followed by the rule name immediately after the URI.
ABNF Example
#ABNF 1.0; language en-US; mode voice; root $main; $main = (my | the) area code is $<http://www.mycompany.com/phone_number.gram#area_code>; |
In this example, $main is referencing only the $area_code rule from the phone_number grammar.
It looks similar in GrXML:
GrXML Example
<?xml version="1.0" encoding="UTF-8" ?> <grammar xmlns="http://www.w3.org/2001/06/grammar" xml:lang="en-US" root="phone_number" mode="voice"> <rule id="main"> <one-of> <item>my</item> <item>the</item> </one-of> <item repeat="0-1">phone</item> number is <ruleref uri="http://www.mycompany.com/phone_number.gram#area_code" /> </rule> |
In addition to referencing external grammar files, you can also reference any of the LumenVox built-in grammars.
ABNF Example
Example #ABNF 1.0; language en-US; mode voice; root $main; $main = (my | the) [phone] number is $<builtin:grammar/phone>; |
GrXML Example
<?xml version="1.0" encoding="UTF-8" ?> <grammar xmlns="http://www.w3.org/2001/06/grammar" xml:lang="en-US" root="phone_number" mode="voice"> <rule id="main"> <one-of> <item>my</item> <item>the</item> </one-of> <item repeat="0-1">phone</item> number is <ruleref uri="builtin:grammar/phone" /> </rule> |
To reference a built-in grammar, provide a URI in the following format: builtin:grammar/name where name is one of the built-in types.
The next part of the grammar tutorial covers writing Special Rules.