Koodoo语言简明教程
本教程介绍了一些Koodoo语言及蓝星际语音普通的基本知识与概念。学习者最好有一定的程序设计基础,当然如果稍微熟悉C或JAVA更好,其实只要懂一点它们的语法结构就可以了。
本教程包含很多简短的例子,它们都可以独立运行,当然也许实际的系统要复杂许多。正式一点的语法说明请参见语法手册,完整的库函数说明请参见系统函数手册.
学习完本教程,你就可以阅读和编写Koodoo脚本程序了,你可以下载开发平台来执行你的脚本程序,开发平台是免费的,如果要开发多线路的语音运行系统,你需要购买相应的硬件和蓝星际语音运行平台版本,请与销售商联系。
欢迎进入Koodoo的世界, Koodoo是一种脚本语言, 特别擅长快速构造IVR(自动语音应答)、呼叫中心等语音方面的应用.
当然,Koodoo也是一种通用的脚本语言,除了面对语音方面的应用外,也可以进行文件操作、数据运算、网络通讯、数据库操作等各种应用,对这些问题都有简单的解决方法。而且,Koodoo语言天然地支持多线程,支持线程之间的通讯,所谓线程对应着语音应用中的线路。所以可以使用Koodoo语言开发数据服务、通讯服务、座席服务等网关应用。
Koodoo是一个设计精巧的高级语言,Koodoo很容易学习,它有类似C语言的简明、清晰语法,它又是一种高效率的动态脚本语言,借鉴了AWK, Python等脚本语言的精华,使用它进行开发是一个愉快的过程,Koodoo是一种南非条纹羚羊的名字,音Kudu--其实也写作Kudu,虽然没有python那么凶猛,却也是我们这个蓝色星球上一种美丽的动物,我们借用了它的名字。
就让我们跟随Koodoo,开始语音开发的浪漫之旅吧。
Koodoo语言的设计受到下列语言的影响:
- C语言
借鉴了C语言简洁的语法 - Python语言
动态数据类型, 数组(散列表或字典), 尤其是数组别名的思想
文件操作 - AWK语言
数组,字符串的分解 - Java语言
字符串拼接: 将不同类型的变量拼成一个字符串
2.1 概述.一个简单的例子
让我们来看看Koodoo语言的"Hello, world!":
Play("Welcome.wav"); // 播放欢迎语音
Hangup(); // 挂断
就这三行语句,构成了一个最简单的语音应答机(IVR).
当然,运行上面的例子最好有语音卡硬件或者语音猫,还需要录制那个欢迎语音Welcome.wav文件。
有朋友会说,我暂时没有语音卡也没有语音猫,怎么办呢?没关系,电脑上只要安装声卡就可以了。
如果你安装了微软的SAPI--是免费的,你也可以不录音:
TxtSpeak("您好,欢迎来电!", false, false); // TTS合成欢迎语音
Hangup(); // 挂断
让我们看看别的方式输出"Hello, world!":
在第一个信息栏显示信息:
return(0);
在日志文件记录信息:
return(0);
怎么样,够简单的吧?
也许你注意到前面两个脚本例子没有return语句,Koodoo语言规定,在主脚本中如果没有return语句,则脚本将循环执行。最前面的脚本,等价于下面的标准结构:
while(true) { WaitRing(1); // 等待来电 Play("Welcome.wav"); // 播放欢迎语音 Hangup(); // 挂断 OnDisconn(); // 当线路挂断时到这里,无论是自己挂断还是远端挂断 } OnSysQuit(); // 系统退出时,到这里 return(0);
主脚本流程中如果遇到return语句,则该线路的流程将终止。
在自定义函数中,在函数结尾处,不管是否有return语句,函数都将返回到调用的地方。Koodoo语言大小写敏感。
如何执行一个脚本,请参照文档: Step by Step.
2.2 常量
Koodoo语言支持常量定义,如:
const BLUE_SPACE = "深圳市蓝星际公司";
"const"关键字,表示后面的符号是个常量,常量在运行时不会被改变。
注意,系统也提供了几个有用的常量:
_bssFile // 本线路执行的脚本文件名, 字符串类型
true // 逻辑真, 也就是整型1
false // 逻辑假, 也就是整型0
2.3 变量
Koodoo语言支持动态的变量,如:
i= "Space"; // i现在是字符串"Space"
i = 19.34; // i现在是双精度浮点型值为19.34
可以进行复杂的变量运算:
i1 = 99*88;
v = 10 - 8*2 + a*(i1-10);
类似C/C++, 支持:
i++;
变量分为全局变量和局部变量,在用户自定义函数里定义的变量为局部变量,在主模块里定义的变量为全局变量。其意义与C语言相同。
2.4 数组
数组的使用是很灵活的, 规则如下:
数组下标可以是任意类型, 即使是整型也可以不连续;
数组等同于字典或散列表,不存在越界的问题;
数组可以用在复杂表达式中,其含义与其它语言如C一样;
数组可以有别名,就是不带下标的赋值, 在函数调用中如果实参为数组名,函数内也将使用别名.
例如:
m[1] = "English";
i = m[0]*100;
p = m; // 为数组m创建一个别名p
在开发平台,双击变量列表中的数组型变量,可以浏览整个数组的全部元素。例子可以参见数组示例。
2.5 注释
与C/C++相同,有两种注释方法: 单行注释,以 // 开始直到行尾; 多行注释, 以 /* 开始, 以 */ 结束.
2.6 其它语句
1. 函数调用,包括系统函数调用,用户自定义函数调用,外部动态库函数调用3种。
系统函数功能及其参数列表,参见文档<蓝星际语音平台呼叫系统函数参考手册>,随着系统功能的扩展,系统函数会增加.
用户自定义函数和外部动态库函数参见下面章节。
2. 流程控制类语句,主要有4种
1).条件语句
if(表达式或布尔变量) { 语句块 // 表达式或布尔变量为真时执行 } else { 语句块 // 表达式或布尔变量为假时执行 } 注意:else 语句块可以省略 和C语言一样, Koodoo语言还支持else if()语句: if(表达式或布尔变量) { 语句块 } else if(表达式或布尔变量) { 语句块 } else { 语句块 } 对于整个if条件语句,可以有0-n个else if()语句和0-1个else语句, else if()语句对于多分支判断非常有用,可以使逻辑更清晰,代码更简洁。 和C语言一样,如果语句块只有一句,则{和}可以省略。 注意: else if()语句必须在同一行
2).循环语句
while(表达式或布尔变量) { 语句块 // 表达式或布尔变量为真时执行 }
语句块中可以包含 break 和 continue 语句, break直接退出循环,而continue忽略下面的语句直接回到while继续
3).标准循环语句
for(初始表达式; 表达式或布尔变量; 步进表达式) { 语句块 // 表达式或布尔变量为真时执行 } // 或迭代语句,细节请参考语法手册 for(变量a in 数组或字符串变量b) { 语句块 }
与while语句相同, 语句块中可以包含 break 和 continue 语句, break直接退出循环,而continue忽略下面的语句直接回到for继续;
最常见的用法类似下面:
for(i=0; i<100; i++) { 语句块 }
4).多分支条件语句
switch(主变量) { case(变量1或常量1) // 注意case后面要小括号, 并且不用冒号, 这与C语言不同 { 语句块 // 主变量=变量1 时执行 // 语句块结束时,不需要break语句 } ... case(变量n或常量n) { 语句块 // 主变量=变量n 时执行 } default() // 看起来像一个函数调用 { 语句块 // 主变量不等于上述变量列表中的任何一个时执行 } }
注意,与C语言相比不需要break语句, default() 语句块可以省略。
特别地,当某个case()语句没有语句块时, 表示穿透到下一条case()或default()语句, 例如:
switch(i) { case(1) { // i==1时,执行的语句块 } case(2) // 穿透 case(3) { // i==2或i==3时,执行的语句块 } default() { // 其它情况下执行的语句块 } }
以上4类语句的语句块可以是空语句块, 如:
if(i=0) { // 空语句块, 即 i=0 时什么也不干 } else { Play(VocLangSele); }
注意,所有的流程控制语句下面的语句块都必须用大括号对括起来, 而且 '{' 及 '}' 都必须单独一行.
2.7 用户自定义函数
Koodoo语言支持用户自定义函数,例如:
// 函数定义 function Add(a, b, c) { c = a + b; return(c); } // 主流程 i = 10; j = 20; k = 0; Add(i, j, k); // 调用函数Add DispInfo(0, k); Add("Hell ", "world!", k); // 调用函数Add DispInfo(1, k); // 更加直观,还可以这样: ret = Add(100, 200, 0); // 直接取返回值,放置到ret DispInfo(2, ret); return(0);
注意,函数一定要在调用之前定义。
2.8 文件包含
#include或#include "fileName"
这个语句完全类似C语言,它只是在编译时使用
可以不写扩展名, 扩展名缺省为".bss"
典型应用是将参数化变量放入配置文件; 或将用户自定义函数集放在一个单独的文件, 每次使用时包含它即可,这相当于用户可以构建自己的程序库。这样可以改善程序结构,增加主程序的可读性。复杂的IVR应用通常由多个脚本文件组成, 由主脚本文件包含其它文件。
注意: 同一个文件最多只能包含一次, 也不可以循环包含。
此外,也不能在函数定义内包含文件。
(待续...)