Tropo is part of CiscoLearn More

Advanced Grammar (SRGS/GRXML)

While Tropo’s Simple Grammar is pretty awesome, it’s not really suited for extremely large data sets.

For example, let’s say you were writing a travel app and wanted to allow your users to speak their destination city or airport. There are hundreds, if not thousands of airports, and many more ways to actually say them. They could say “JFK”, “John F. Kennedy”, “NYC”, “New York International”, etc. These types of complex grammars are best suited for the Speech Recognition Grammar Specification (SRGS). The SRGS is a W3C standard way of controlling speech recognition engines. SRGS can take a variety of forms, with the most popular being Grammar XML (or GRXML for short).

To use GRXML from your Tropo Scripting application, simply provide the URL to an external file:

require 'tropo-webapi-ruby'
require 'sinatra'

post '/index.json' do
  
  t = Tropo::Generator.new
  
  t.ask :name => 'destinations', 
        :timeout => 60, 
        :say => {:value => "What's your destination?"},
        :choices => {:value => "http://myserver.com/destinations.grxml"}
  
  t.on :event => 'continue', :next => '/continue.json'
  
  t.response
  
end

post '/continue.json' do
  
  v = Tropo::Generator.parse request.env["rack.input"].read
  
  t = Tropo::Generator.new
  
  answer = v[:result][:actions][:destinations][:value]
  
  t.say(:value => "You said " + answer)
  
  t.response
  
end
var http = require('http');
var express = require('express');
var app = express.createServer();
var tropo_webapi = require('tropo-webapi');

// Required to process the HTTP body.
// req.body has the Object while req.rawBody has the JSON string.

app.configure(function(){
	app.use(express.bodyParser());
});

app.post('/', function(req, res){
	
    var tropo = new TropoWebAPI();
    
    var say = new Say("What's your destination?");
    var choices = new Choices("http://myserver.com/destinations.grxml");

    // (choices, attempts, bargein, minConfidence, name, recognizer, required, say, timeout, voice);
	
    tropo.ask(choices, null, null, null, "destinations", null, null, say, 60, null);
	
    tropo.on("continue", null, "/continue", true);
	
    res.send(TropoJSON(tropo));
	
});

app.post('/continue', function(req, res){
	
    var tropo = new TropoWebAPI();

    var answer = req.body['result']['actions']['value'];
	
    tropo.say("You said " + answer);
		
    res.send(TropoJSON(tropo));

});

app.listen(8000);
console.log('Server running on port :8000');
<?php

require 'tropo.class.php';
require 'lib/limonade.php';

dispatch_post('/start', 'app_start');
function app_start() {

	$tropo = new Tropo();

	$options = array("choices" => "http://myserver.com/destinations.grxml", "name" => "destination", "timeout" => 60);
 
	$tropo->ask("What's your destination?", $options);

	$tropo->on(array("event" => "continue", "next" => "hello_world.php?uri=continue"));

	$tropo->RenderJson();

}

dispatch_post('/continue', 'app_continue');
function app_continue() {

	$tropo = new Tropo();
	@$result = new Result();
	
	$answer = $result->getValue();
	
	$tropo->say("You said " . $answer);
	
	$tropo->RenderJson();

}

run();

?>
from itty import *
from tropo import Tropo, Result

@post('/index.json')
def index(request):

	t = Tropo()

	t.ask(choices = "http://myserver.com/destinations.grxml", timeout=60, name="destinations", say = "What's your destination?")	
	
	t.on(event = "continue", next ="/continue")
	
	return t.RenderJson()
	
@post("/continue")
def index(request):
	
	r = Result(request.body)
	t = Tropo()
	
	answer = r.getValue()
	
	t.say("You said " + answer)
	
	return t.RenderJson()
	
run_itty(server='wsgiref', host='0.0.0.0', port=8888)

Note that if you use PHP, the above example includes the Limonade framework, so you would need to define the end of the start URL in Tropo to include the resource name, like http://www.example.com/test.php?uri=start.

For GrXML or other advanced grammars, ensure that the "mode" attribute in the Grammar matches the mode attribute on Tropo's ask function. The default mode for the ask object is mixed DTMF and Voice, but GrXML doesn't support mixed modes. Telling Tropo to use mixed mode when the Grammar doesn't support it will have unpredictable results. With grammars that are for DTMF input only, ensure that the "mode" parameter is set to DTMF in the GrXML <grammar> element as follows: <grammar mode="dtmf">.

The Tropo docs can't cover the entire scope of all the potential advanced grammar functionality out there, as there's quite a bit, so we recommend reviewing the following resource for more information:

http://www.w3.org/TR/speech-grammar/


Example GrXML

Need a couple examples of GRXML? Here's a few options you can build on:

<?xml version="1.0"?>
<grammar xmlns="http://www.w3.org/2001/06/grammar" root="main">

    <rule id="main" scope="public">

        <item repeat="1-16">
            <ruleref uri="#digit">
                <tag>out.concept = out.concept + rules.digit;</tag>
            </ruleref>
        </item>
    </rule>

    <rule id="digit">
        <one-of>
            <item>0</item>
            <item>1</item>
            <item>2</item>
            <item>3</item>
            <item>4</item>
            <item>5</item>
            <item>6</item>
            <item>7</item>
            <item>8</item>
            <item>9</item>
        </one-of>
    </rule>
</grammar> 
<?xml version="1.0"?>
<grammar xmlns="http://www.w3.org/2001/06/grammar" root="MAINRULE">

    <rule id="MAINRULE"> 
        <item>
            <ruleref uri="#choices">
                <tag> out.concept = out.concept;</tag> 
            </ruleref>
        </item>
    </rule> 
    
    <rule id="choices">
        <one-of>
            <item>
                <item repeat="0-1"> need a </item>
                <item repeat="0-1"> i need a </item>
                <one-of> 
                    <item> clue </item>
                </one-of>
            </item>
            <item>
                <item repeat="0-1"> have an </item>
                <item repeat="0-1"> i have an </item>
                <one-of> 
                    <item> answer </item>
                </one-of>
            </item>
        </one-of>
    </rule>

</grammar>
<grammar xmlns="http://www.w3.org/2001/06/grammar" root="MAIN">
 
    <rule id="MAIN" scope="public">
 
        <one-of>
            <item repeat="1-16">
                <ruleref uri="#digit">
                    <tag>out.concept = out.concept + rules.digit;</tag>
                </ruleref>
            </item>
 
            <item>
                help <tag>out.concept="help";</tag>
            </item>
 
            <item>
                back <tag>out.concept="back";</tag>
            </item>
        </one-of>
    </rule>
 
 
    <rule id="digit">
        <one-of>
            <item>
                <one-of>
                    <item>one</item>
                    <item>dtmf-1</item>
                </one-of>
                <tag>out="1";</tag>
            </item>
            <item>
                <one-of>
                    <item>two</item>
                    <item>dtmf-2</item>
                </one-of>
                <tag>out="2";</tag>
            </item>
            <item>
                <one-of>
                    <item>three</item>
                    <item>dtmf-3</item>
                </one-of>
                <tag>out="3";</tag>
            </item>
            <item>
                <one-of>
                    <item>four</item>
                    <item>dtmf-4</item>
                </one-of>
                <tag>out="4";</tag>
            </item>
            <item>
                <one-of>
                    <item>five</item>
                    <item>dtmf-5</item>
                </one-of>
                <tag>out="5";</tag>
            </item>
            <item>
                <one-of>
                    <item>six</item>
                    <item>dtmf-6</item>
                </one-of>
                <tag>out="6";</tag>
            </item>
            <item>
                <one-of>
                    <item>seven</item>
                    <item>dtmf-7</item>
                </one-of>
                <tag>out="7";</tag>
            </item>
            <item>
                <one-of>
                    <item>eight</item>
                    <item>dtmf-8</item>
                </one-of>
                <tag>out="8";</tag>
            </item>
            <item>
                <one-of>
                    <item>nine</item>
                    <item>dtmf-9</item>
                </one-of>
                <tag>out="9";</tag>
            </item>
            <item>
                <one-of>
                    <item>zero</item>
                    <item>dtmf-0</item>
                </one-of>
                <tag>out="0";</tag>
            </item>
        </one-of>
    </rule>
 
</grammar>
<grammar xmlns="http://www.w3.org/2001/06/grammar" root="MAIN">

    <rule id="MAIN" scope="public">
        <item>
            <item>
                <ruleref uri="#MONTH"/>
                <tag>out.month = rules.MONTH.firstSubslot;</tag>
            </item>

            <item>
                <ruleref uri="#DAY"/>
                <tag>out.day = rules.DAY.secondSubslot;</tag>
            </item>

            <item>
                <ruleref uri="#BEG"/>
                <tag>out.year = rules.BEG.yearOneSubslot;</tag>
            </item>

            <item>
                <ruleref uri="#MID"/>
                <tag>out.year = out.year + rules.MID.yearTwoSubslot;</tag>
            </item>

            <item>
                <ruleref uri="#END"/>
                <tag>out.year = out.year + rules.END.yearThreeSubslot;</tag>
            </item>
        </item>
        <tag> out.F_1= out.month + " " + out.day + ", " + out.year; </tag>
    </rule>

    <rule id="MONTH" scope="public">
        <one-of>
            <item>
                <one-of>
                    <item>one</item>
                    <item>1</item>
                    <item>January</item>
                </one-of>
                <tag>out.firstSubslot="January";</tag>
            </item>
            <item>
                <one-of>
                    <item>two</item>
                    <item>2</item>
                    <item>February</item>
                </one-of>
                <tag>out.firstSubslot="February";</tag>
            </item>
            <item>
                <one-of>
                    <item>three</item>
                    <item>3</item>
                    <item>March</item>
                </one-of>
                <tag>out.firstSubslot="March";</tag>
            </item>
            <item>
                <one-of>
                    <item>four</item>
                    <item>4</item>
                    <item>April</item>
                </one-of>
                <tag>out.firstSubslot="April";</tag>
            </item>
            <item>
                <one-of>
                    <item>five</item>
                    <item>5</item>
                    <item>May</item>
                </one-of>
                <tag>out.firstSubslot="May";</tag>
            </item>
            <item>
                <one-of>
                    <item>six</item>
                    <item>6</item>
                    <item>June</item>
                </one-of>
                <tag>out.firstSubslot="June";</tag>
            </item>
            <item>
                <one-of>
                    <item>seven</item>
                    <item>7</item>
                    <item>July</item>
                </one-of>
                <tag>out.firstSubslot="July";</tag>
            </item>
            <item>
                <one-of>
                    <item>eight</item>
                    <item>8</item>
                    <item>August</item>
                </one-of>
                <tag>out.firstSubslot="August";</tag>
            </item>
            <item>
                <one-of>
                    <item>nine</item>
                    <item>9</item>
                    <item>September</item>
                </one-of>
                <tag>out.firstSubslot="September";</tag>
            </item>
            <item>
                <one-of>
                    <item>ten</item>
                    <item>10</item>
                    <item>October</item>
                </one-of>
                <tag>out.firstSubslot="October";</tag>
            </item>
            <item>
                <one-of>
                    <item>eleven</item>
                    <item>11</item>
                    <item>November</item>
                </one-of>
                <tag>out.firstSubslot="November";</tag>
            </item>
            <item>
                <one-of>
                    <item>twelve</item>
                    <item>12</item>
                    <item>December</item>
                </one-of>
                <tag>out.firstSubslot="December";</tag>
            </item>
        </one-of>
    </rule>

    <rule id="DAY" scope="public">
        <one-of>
            <item>
                <one-of>
                    <item>one</item>
                    <item>first</item>
                    <item>1</item>
                </one-of>
                <tag>out.secondSubslot="01";</tag>
            </item>
            <item>
                <one-of>
                    <item>second</item>
                    <item>two</item>
                    <item>2</item>
                </one-of>
                <tag>out.secondSubslot="02";</tag>
            </item>
            <item>
                <one-of>
                    <item>third</item>
                    <item>three</item>
                    <item>3</item>
                </one-of>
                <tag>out.secondSubslot="03";</tag>
            </item>
            <item>
                <one-of>
                    <item>forth</item>
                    <item>four</item>
                    <item>4</item>
                </one-of>
                <tag>out.secondSubslot="04";</tag>
            </item>
            <item>
                <one-of>
                    <item>fifth</item>
                    <item>five</item>
                    <item>5</item>
                </one-of>
                <tag>out.secondSubslot="05";</tag>
            </item>
            <item>
                <one-of>
                    <item>sixth</item>
                    <item>six</item>
                    <item>6</item>
                </one-of>
                <tag>out.secondSubslot="06";</tag>
            </item>
            <item>
                <one-of>
                    <item>seventh</item>
                    <item>seven</item>
                    <item>7</item>
                </one-of>
                <tag>out.secondSubslot="07";</tag>
            </item>
            <item>
                <one-of>
                    <item>eighth</item>
                    <item>eight</item>
                    <item>8</item>
                </one-of>
                <tag>out.secondSubslot="08";</tag>
            </item>
            <item>
                <one-of>
                    <item>ninth</item>
                    <item>nine</item>
                    <item>9</item>
                </one-of>
                <tag>out.secondSubslot="09";</tag>
            </item>
            <item>
                <one-of>
                    <item>tenth</item>
                    <item>ten</item>
                    <item>10</item>
                </one-of>
                <tag>out.secondSubslot="10";</tag>
            </item>
            <item>
                <one-of>
                    <item>eleventh</item>
                    <item>eleven</item>
                    <item>11</item>
                </one-of>
                <tag>out.secondSubslot="11";</tag>
            </item>
            <item>
                <one-of>
                    <item>twelfth</item>
                    <item>twelve</item>
                    <item>12</item>
                </one-of>
                <tag>out.secondSubslot="12";</tag>
            </item>
            <item>
                <one-of>
                    <item>thirteenth</item>
                    <item>thirteen</item>
                    <item>13</item>
                </one-of>
                <tag>out.secondSubslot="13";</tag>
            </item>
            <item>
                <one-of>
                    <item>fourteenth</item>
                    <item>fourteen</item>
                    <item>14</item>
                </one-of>
                <tag>out.secondSubslot="14";</tag>
            </item>
            <item>
                <one-of>
                    <item>fifteenth</item>
                    <item>fifteen</item>
                    <item>15</item>
                </one-of>
                <tag>out.secondSubslot="15";</tag>
            </item>
            <item>
                <one-of>
                    <item>sixteenth</item>
                    <item>sixteen</item>
                    <item>16</item>
                </one-of>
                <tag>out.secondSubslot="16";</tag>
            </item>
            <item>
                <one-of>
                    <item>seventeenth</item>
                    <item>seventeen</item>
                    <item>17</item>
                </one-of>
                <tag>out.secondSubslot="17";</tag>
            </item>
            <item>
                <one-of>
                    <item>eighteenth</item>
                    <item>eighteen</item>
                    <item>18</item>
                </one-of>
                <tag>out.secondSubslot="18";</tag>
            </item>
            <item>
                <one-of>
                    <item>nineteenth</item>
                    <item>nineteen</item>
                    <item>19</item>
                </one-of>
                <tag>out.secondSubslot="19";</tag>
            </item>
            <item>
                <one-of>
                    <item>twentieth</item>
                    <item>twenty</item>
                    <item>20</item>
                </one-of>
                <tag>out.secondSubslot="20";</tag>
            </item>
            <item>
                <one-of>
                    <item>twenty first</item>
                    <item>twenty one</item>
                    <item>21</item>
                </one-of>
                <tag>out.secondSubslot="21";</tag>
            </item>
            <item>
                <one-of>
                    <item>twenty second</item>
                    <item>twenty two</item>
                    <item>22</item>
                </one-of>
                <tag>out.secondSubslot="22";</tag>
            </item>
            <item>
                <one-of>
                    <item>twenty third</item>
                    <item>twenty three</item>
                    <item>23</item>
                </one-of>
                <tag>out.secondSubslot="23";</tag>
            </item>
            <item>
                <one-of>
                    <item>twenty forth</item>
                    <item>twenty four</item>
                    <item>24</item>
                </one-of>
                <tag>out.secondSubslot="24";</tag>
            </item>
            <item>
                <one-of>
                    <item>twenty fifth</item>
                    <item>twenty five</item>
                    <item>25</item>
                </one-of>
                <tag>out.secondSubslot="25";</tag>
            </item>
            <item>
                <one-of>
                    <item>twenty sixth</item>
                    <item>twenty six</item>
                    <item>26</item>
                </one-of>
                <tag>out.secondSubslot="26";</tag>
            </item>
            <item>
                <one-of>
                    <item>twenty seventh</item>
                    <item>twenty seven</item>
                    <item>27</item>
                </one-of>
                <tag>out.secondSubslot="27";</tag>
            </item>
            <item>
                <one-of>
                    <item>twenty eighth</item>
                    <item>twenty eight</item>
                    <item>28</item>
                </one-of>
                <tag>out.secondSubslot="28";</tag>
            </item>
            <item>
                <one-of>
                    <item>twenty ninth</item>
                    <item>twenty nine</item>
                    <item>29</item>
                </one-of>
                <tag>out.secondSubslot="29";</tag>
            </item>
            <item>
                <one-of>
                    <item>thirtieth</item>
                    <item>thirty</item>
                    <item>30</item>
                </one-of>
                <tag>out.secondSubslot="30";</tag>
            </item>
            <item>
                <one-of>
                    <item>thirty first</item>
                    <item>thirty one</item>
                    <item>31</item>
                </one-of>
                <tag>out.secondSubslot="31";</tag>
            </item>
        </one-of>
    </rule>


    <rule id="BEG" scope="public">
        <one-of>
            <item>
                <one-of>
                    <item>nineteen</item>
                    <item>one thousand nine hundred</item>
                </one-of>
                <tag>out.yearOneSubslot="19"</tag>
            </item>
            <item>
                <one-of>   
                    <item>two thousand</item>
                    <item>twenty</item>
                </one-of>
                <tag>out.yearOneSubslot="20"</tag>
            </item>
        </one-of>
    </rule>

    <rule id="MID" scope="public">
        <one-of>
            <item>
                <one-of>
                    <item>O</item>
                    <item>oh</item>
                    <item>0</item>
                    <item>zero</item>
                </one-of>
                <tag>out.yearTwoSubslot="0"</tag>
            </item>
            <item>
                <one-of>   
                    <item>ten</item>
                    <item>1</item>
                    <item>10</item>
                </one-of>
                <tag>out.yearTwoSubslot="1"</tag>
            </item>
            <item>
                <one-of>   
                    <item>twenty</item>
                    <item>2</item>
                    <item>20</item>
                </one-of>
                <tag>out.yearTwoSubslot="2"</tag>
            </item>
            <item>
                <one-of>   
                    <item>thirty</item>
                    <item>3</item>
                    <item>30</item>
                </one-of>
                <tag>out.yearTwoSubslot="3"</tag>
            </item>
            <item>
                <one-of>   
                    <item>forty</item>
                    <item>4</item>
                    <item>40</item>
                </one-of>
                <tag>out.yearTwoSubslot="4"</tag>
            </item>
            <item>
                <one-of>   
                    <item>fifty</item>
                    <item>5</item>
                    <item>50</item>
                </one-of>
                <tag>out.yearTwoSubslot="5"</tag>
            </item>
            <item>
                <one-of>   
                    <item>sixty</item>
                    <item>6</item>
                    <item>60</item>
                </one-of>
                <tag>out.yearTwoSubslot="6"</tag>
            </item>
            <item>
                <one-of>   
                    <item>seventy</item>
                    <item>7</item>
                    <item>70</item>
                </one-of>
                <tag>out.yearTwoSubslot="7"</tag>
            </item>
            <item>
                <one-of>   
                    <item>eighty</item>
                    <item>8</item>
                    <item>80</item>
                </one-of>
                <tag>out.yearTwoSubslot="8"</tag>
            </item>
            <item>
                <one-of>   
                    <item>ninety</item>
                    <item>9</item>
                    <item>90</item>
                </one-of>
                <tag>out.yearTwoSubslot="9"</tag>
            </item>
        </one-of>
    </rule>

    <rule id="END" scope="public">
        <one-of>
            <item>
                <one-of>
                    <item>one</item>
                    <item>1</item>
                </one-of>
                <tag>out.yearThreeSubslot="1";</tag>
            </item>
            <item>
                <one-of>
                    <item>two</item>
                    <item>2</item>
                </one-of>
                <tag>out.yearThreeSubslot="2";</tag>
            </item>
            <item>
                <one-of>
                    <item>three</item>
                    <item>3</item>
                </one-of>
                <tag>out.yearThreeSubslot="3";</tag>
            </item>
            <item>
                <one-of>
                    <item>four</item>
                    <item>4</item>
                </one-of>
                <tag>out.yearThreeSubslot="4";</tag>
            </item>
            <item>
                <one-of>
                    <item>five</item>
                    <item>5</item>
                </one-of>
                <tag>out.yearThreeSubslot="5";</tag>
            </item>
            <item>
                <one-of>
                    <item>six</item>
                    <item>6</item>
                </one-of>
                <tag>out.yearThreeSubslot="6";</tag>
            </item>
            <item>
                <one-of>
                    <item>seven</item>
                    <item>7</item>
                </one-of>
                <tag>out.yearThreeSubslot="7";</tag>
            </item>
            <item>
                <one-of>
                    <item>eight</item>
                    <item>8</item>
                </one-of>
                <tag>out.yearThreeSubslot="8";</tag>
            </item>
            <item>
                <one-of>
                    <item>nine</item>
                    <item>9</item>
                </one-of>
                <tag>out.yearThreeSubslot="9";</tag>
            </item>
        </one-of>
    </rule>
</grammar>