A grammar files contain both terminal and nonterminal symbols. Terminals are alphabetic strings. Nonterminals are alphanumeric strings enclosed in angle brackets. For example, print, move, and select are all terminals; <commands>, <np>, and <vp> are nonterminals.
The grammar file is a set of context-free rewrite rules. Each rule contains one nonterminal symbol on the left-hand side of an equals sign ("=") and one or more terminal or nonterminal symbols on the right-hand side. Rules must end with a period ("."). Each rule must have a unique left-hand side nonterminal---no two rules can have identical left-hand sides. For example, the following grammar fragment is not allowed:
<np> = <pronoun> . <np> = <determiner> <noun> .
However, the right-hand side of a rule can contain a list of alternative rewrites delimited by the "|" character. For example, the above fragment can be rewritten as:
<np> = <pronoun> | <determiner> <noun> .(A np can be rewritten either as a pronoun or as a determiner followed by a noun)
The following symbol-final characters have special interpretations:
The left-hand-side of the first rule in your grammar defines the root nonterminal. VoiceType or other speech applications will only recognize phrases that are derived from this nonterminal. This is illustrated in the following ill-formed grammar fragment:
<move-command> = move <direction> <count> . <:select-command> = select the next <count> words . ...A speech application using this grammar will only recognize phrases derived from <move-command> (move up five, move down six, etc.). It will not recognize phrases derived from <select-command>. In fact, this grammar will generate the warning
Non-terminal defined but not referenced BNF symbol "<select-command>"when you attempt compile it. The above grammar can be corrected by adding a grammar initial root nonterminal rule as follows:
<commands> = <move-command> | <select-command> . <move-command> = move <direction> <count> . <:select-command> = select the next <count> words .
You can include an existing grammar into the grammar file you are writing by using the INCLUDE keyword on the last line of the new grammar file. For example, the line
include 'my-numbers.bnf'
will include the rules in "my-numbers.bnf" in the current grammar.
A set of commonly used integers (one through twenty, thirty, forty and fifty) can be made available to your grammar by the special command
EXTERN <Extern_counts> .
This line must be after all the grammar rules but before any include statements. The use of the of the non-terminal <Extern_counts> is explained in the section on the @count() annotation.
Comments can be included in grammar files by use of the comment marker //. All the characters from the comment marker to the end of the line are considered to be the comment.
<september> = September:9 . <subtract> = subtract:"-" . <db-query> = list all employees:"list-employees" | show all employees:"list-employees" .
If you are writing grammars that will be used by Voice Manager, these annotations can be used to define what actions to take when a given phrase is recognized. For information on writing Voice Manager annotations see the annotations guide.
<command> = set:"[alt f]" the font to courier | set:"[alt c]" the color to blue .
is not allowed. When the speech engine recognizes "set" it doesn't know which set is intended: set:"[alt f]" or set:"[alt c]". Often this problem can be eliminated by moving the annotations rightward. Thus, the above example can be rewritten:
<command> = set the font:"[alt f]" to courier | set the color:"[alt c]" to blue .
However, this is not always possible. For example, consider the following problematic grammar:
<print-command> = print:"[ctrl p]" | print:"[ctrl p][alt e]" even pages .
This is not allowed because when the speech engine recognizes "print" it doesn't know which print is intended: print:"[ctrl p]" or print:"[ctrl p][alt e]". Moving the annotation rightward does not eliminate the problem:
<print-command> = print:"[ctrl p]" | print even:"[ctrl p][alt e]" pages .
Print is still ambiguous between print:"[ctrl p]" and print.