Grammar Guide


A guide to writing grammar files

The syntax of grammar rules

Symbols

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.

Grammar Rules

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:

  • ? means that the symbol is optional. For example, in change the? font the the is optional.
  • *, the Kleene Star, means that there can be zero or more occurrences of the symbol. For example, in <part-number> = <part> <digits>* there can be zero or more occurrences of <digits> .
  • +, the Kleene Plus, means that there can be one or more occurrences of the symbol.
  • The root nonterminal

    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 .
    
    

    Including a grammar within your grammar

    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

    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.

    Annotations

    Annotations can be attached to terminal symbols. When an annotated word is recognized both that word and its annotation are returned to the application. These annotations may assist the application in parsing the recognized phrases. Annotations can either be a string or a integer ranging from 0 to 65535. For example,
    <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.

    Note:

    Annotations that introduce indeterminacy are not allowed. For example,
    <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.


    Other notes


    [ Top of Page | Previous Page | Next Page | Back to Grammar Guide ]