Koodoo语言简明教程

前 言
第1章 Koodoo简介
第2章 Koodoo语法


前 言

本教程介绍了一些Koodoo语言及蓝星际语音普通的基本知识与概念。学习者最好有一定的程序设计基础,当然如果稍微熟悉C或JAVA更好,其实只要懂一点它们的语法结构就可以了。

本教程包含很多简短的例子,它们都可以独立运行,当然也许实际的系统要复杂许多。正式一点的语法说明请参见语法手册,完整的库函数说明请参见系统函数手册.

学习完本教程,你就可以阅读和编写Koodoo脚本程序了,你可以下载开发平台来执行你的脚本程序,开发平台是免费的,如果要开发多线路的语音运行系统,你需要购买相应的硬件和蓝星际语音运行平台版本,请与销售商联系。


第1章 Koodoo简介

欢迎进入Koodoo的世界, Koodoo是一种脚本语言, 特别擅长快速构造IVR(自动语音应答)、呼叫中心等语音方面的应用.

当然,Koodoo也是一种通用的脚本语言,除了面对语音方面的应用外,也可以进行文件操作、数据运算、网络通讯、数据库操作等各种应用,对这些问题都有简单的解决方法。而且,Koodoo语言天然地支持多线程,支持线程之间的通讯,所谓线程对应着语音应用中的线路。所以可以使用Koodoo语言开发数据服务、通讯服务、座席服务等网关应用。

Koodoo是一个设计精巧的高级语言,Koodoo很容易学习,它有类似C语言的简明、清晰语法,它又是一种高效率的动态脚本语言,借鉴了AWK, Python等脚本语言的精华,使用它进行开发是一个愉快的过程,Koodoo是一种南非条纹羚羊的名字,音Kudu--其实也写作Kudu,虽然没有python那么凶猛,却也是我们这个蓝色星球上一种美丽的动物,我们借用了它的名字。

就让我们跟随Koodoo,开始语音开发的浪漫之旅吧。


Koodoo语言的设计受到下列语言的影响:

  1. C语言
    借鉴了C语言简洁的语法
  2. Python语言
    动态数据类型, 数组(散列表或字典), 尤其是数组别名的思想
    文件操作
  3. AWK语言
    数组,字符串的分解
  4. Java语言
    字符串拼接: 将不同类型的变量拼成一个字符串

第2章 Koodoo语法

2.1 概述.一个简单的例子

让我们来看看Koodoo语言的"Hello, world!":

WaitRing(1); // 等待来电
Play("Welcome.wav"); // 播放欢迎语音
Hangup(); // 挂断

就这三行语句,构成了一个最简单的语音应答机(IVR).
当然,运行上面的例子最好有语音卡硬件或者语音猫,还需要录制那个欢迎语音Welcome.wav文件。
有朋友会说,我暂时没有语音卡也没有语音猫,怎么办呢?没关系,电脑上只要安装声卡就可以了。
如果你安装了微软的SAPI--是免费的,你也可以不录音:

WaitRing(1); // 等待来电
TxtSpeak("您好,欢迎来电!", false, false); // TTS合成欢迎语音
Hangup(); // 挂断

让我们看看别的方式输出"Hello, world!":
在第一个信息栏显示信息:

DispInfo(0, "Hello, world!");
return(0);

在日志文件记录信息:

TextFileAppend("userlog.txt", "Hello, world!", true); // 日志文件名为:"userlog.txt"
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 PAI = 3.1415926;
const BLUE_SPACE = "深圳市蓝星际公司";

"const"关键字,表示后面的符号是个常量,常量在运行时不会被改变。
注意,系统也提供了几个有用的常量:

_lineNo // 当前线路号, 整型, 从0开始
_bssFile // 本线路执行的脚本文件名, 字符串类型
true // 逻辑真, 也就是整型1
false // 逻辑假, 也就是整型0


2.3 变量

Koodoo语言支持动态的变量,如:

i = 0; // i现在是整型0
i= "Space"; // i现在是字符串"Space"
i = 19.34; // i现在是双精度浮点型值为19.34

可以进行复杂的变量运算:

a = 23;
i1 = 99*88;
v = 10 - 8*2 + a*(i1-10);

类似C/C++, 支持:

i=0;
i++;

变量分为全局变量和局部变量,在用户自定义函数里定义的变量为局部变量,在主模块里定义的变量为全局变量。其意义与C语言相同。


2.4 数组

数组的使用是很灵活的, 规则如下:

数组下标可以是任意类型, 即使是整型也可以不连续;
数组等同于字典或散列表,不存在越界的问题;
数组可以用在复杂表达式中,其含义与其它语言如C一样;
数组可以有别名,就是不带下标的赋值, 在函数调用中如果实参为数组名,函数内也将使用别名.

例如:

m[0] = 12; // m为数组类型, 下标0对应的值是12
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应用通常由多个脚本文件组成, 由主脚本文件包含其它文件。

注意: 同一个文件最多只能包含一次, 也不可以循环包含。

此外,也不能在函数定义内包含文件。


(待续...)