Specifying NLAL grammars

Depending on the functionality the new module is supporting, you may also need to create a new configuration file for the conversation. The configuration file defines the grammar that is used to interpret the text and to allow the module to take the appropriate action.

In the configuration file for each conversation module (${QNX_TARGET}/opt/asr/conversation/locale/module/car-control.cfg), define a section with the following syntax:

section-name = NLAL {
 }

This specifies section-name as the top-level grammar rule for the module. Each line of this configuration section describes an alternate grammar that the NLAL uses to match an utterance. You can define any number of these sections, and each section can contain any number of entries. In the code for the new conversation module, you call the asrm_set_active_sections() function to set the grammar that the module uses. The top-level rules can be composed of subrules. You specify a subrule with angled brackets. For example:

time-query = {
        'what is the current time'
}
 
keys = NLAL {
        <time-query>
}

In this configuration, the <time-query> rule is expanded to the contents of the time-query subrule, which is composed of string literals. Therefore, the only utterance that will match this rule is the sentence "what is the current time". Note that you don't use the NLAL attribute for subrules; it's only required for the top-level rules.

You can also add actions to the rule. For example, the keys section could be extended as follows:

keys = NLAL {
        <time-query:id(rule, time)>
}

This has the effect that whenever an utterance matches the <time-query> rule, an intent with the field name rule and the value time will be added to the result structure (asr_result):

intents = {
        rule = time
}

If the value is omitted from the id command, the matching text is set as the field value. For example:

search-query = {
        'search for '<...:id(search-term)>
}
  
keys = NLAL {
        <search-query:id(rule,search)>
}

This rule matches utterances of the form "search for ...". The special rule <...> is a catch-all that matches anything. If the NLAL processes the utterance "Search for Starbucks" using this rule, the following intent fields will be added to the result structure:

intents = {
        rule = search
        search-term = Starbucks
}

It's also possible to optionally match items in the grammar by enclosing them in square brackets. The rule:

search-query = {
        search ['internet '] 'for ' <...:id(search-term)> }

matches the utterances:

Note that spaces must be quoted and must be described explicitly in the rule. The following rule is incorrect:

search-query = {
        search [internet] for <...:id(search-term)> }

This rule won't match either of the previously described utterances. However, it will match the following:

Items enclosed in parentheses and separated by pipe characters specify alternative matches. For example, the rule:

search-query = {
  'search ' ( internet | media ) ' for ' <...:id(search-term)> }

matches the utterances:

This has the same effect as defining a subrule with a different match grammar on each line:

search-type = {
        internet
        media
}
 
search-query = {
        'search ' <search-time> ' for ' <...:id(search-term)> }

You can add the special help-url item to the top-level NLAL section rule to define a prompt string for ASR to use to respond to user help requests. If the user utters one of the help commands (defined in the common configuration file, ${QNX_TARGET}/opt/asr/conversation/locale/common/car-control.cfg) while this section is active, ASR passes the value of the help-url to the prompt module:

keys = NLAL {
   <search-query:id(rule, search)>
   help-url = tts://"Describe the commands supported by this grammar"
}

In this example, the if the user requests help while the keys section is active, ASR passes the URL tts://"Describe the commands supported by this grammar" to the prompt module.