2008-12-26
修改:2009-8-7
目录
1.概述
该语言可以定义出用于C++, ACTION SCRIPT 3.0 ,JAVA及PHP 或其它语言的网络通信协议,这种语言的编译器可以把这种语言编写的IDL协议文件自动生成可用于C++, ACTION SCRIPT 3.0,JAVA及PHP 或其它语言的实现代码。
2.命名规则
大小写敏感.
遵守C,JAVA和C#规则.
即变量,结构,枚举或函数名只能由字母,数字,和下划线_组成, 命名的开头不能是数字,只能以字母或下划线组成.
由(),{},[]三种标志划分命名的区域.
3.保留字
C,JAVA,PHP和AS语言的保留字并集.
enum,
struct,
coclass,
interface,
dispinterface
4.数据类型
4.1简单数据类型
CHAR | 8 bit 有符号字节 |
UCHAR | 8 bit 无符号字节 |
SHORT | 16 bit 有符号整型 |
USHORT | 16 bit 无符号整型 |
INT | 32 bit 有符号整型 |
UINT | 32 bit 无符号整型 |
LONGLONG | 64 bit 有符号整型 |
ULONGLONG | 64 bit 无符号整型 |
FLOAT | 32 bit 单精度浮点数 |
DOUBLE | 64 bit 双精度浮点数 |
STRINGA | utf8 字符串 |
STRINGW | Utf16字符串 |
****不支持指针类型
目前ACTION SCRIPT 中STRINGW(Utf16字符串)尚未支持,如果涉及as代码,请不要使用STRINGW(Utf16字符串),只能使用STRINGA(utf8 字符串).
而不少语言并不支持unsigned的整型,如java,php等,在这些语言中的应用,生成代码需要模拟实现或避免使用unsigned的整形。
4.2复杂数据类型
使用struct来自行定义, 语法类似C语言的结构定义, 但不支持typedef语法。
语法:
struct 保留字;
结构名;
{ //(开括号)
成员定义
……
} //括号
例子:
struct TLOGIN_CHALLENGE
{
CHAR acc[32];
};
4.3 复杂数据类型的继承
语法定义如下:
struct A
{
INT ma;
};
struct B:public A
{
INT mb;
};
这时称为B继承了A, B拥有A的全部结构,B称为子,A为父.
由于大部分的语言都不支持多继承,这里也不支持多继承。
子类的成员命名不能和它所继承的父类重名,如上例,struct B中不能名字为ma的成员变量。
5.注释
使用 C++语言风格注释。支持转换成各种语言的注释后,还保持原来的位置及风格或形成doxygen的注释风格
6.枚举
语法类似C语言的结构定义, 但不支持typedef.
例子:
enum _ECHARACTER_RACE
{
RACE_HUMAN=0,
RACE_UNDEAD,
RACE_ELF,
RACE_BLOOD_ELF
};
7.数组
只支持一维的定长或不定长数组, 不支持多维数据
例:
固定长度数组:
CHAR s[16]; //表示这个一个长度是16的CHAR数组
不定长数组;
CHAR s[]; //对于C++生成一个XNET_ARRAY<CHAR>对象.
[]括号中表示数组的个数,支持复杂的数结构.
例:
struct TIME_ZONE_INFO
{
int TIME_ZONE;
STRINGUTF8 szDesc;
}
struct TCLIENT_PROOF
{
int acclen;
CHAR acc[acclen];
int pwdHash[40];
int clientRand[40];
TIME_ZONE_INFO timeInfo;
};
struct TSERVER_PROOF
{
int result;
int clientRand[40];
};
8.协议接口
使用coclass保留字定义
每一个coclass表示是一套完整的网络接口协议,协议是从客户端的角度出发的。
每个由coclass定义协议包括两个接口, interface和dispinterface,其中interface表示由客户端向服务器进行主动请求的接口,而dispinterface则是服务器对于客户端的请求的回应事件接口.
Interface和dispinterface的方法声明和C语言的函数声明一致,但每个方法必须是返回INT.
即语法如下:
INT foo(…..);
例子:
coclass LoginProtocol
{
interface IloginAuthServer //有且只有一个
{
INT SendClientChallenge(ClientChallenge cc);
INT SendClientProof(ClientProof cf);
INT SendGetChannelList();
};
dispinterface LoginAuthServerEvent //有且只有一个
{
INT OnServerChallenge(ServerChallenge sc);
INT OnServerProof(ServerProof sf);
INT OnChannelList(ChannelServerInfo channelList[]);
};
};
9.边效(side effect)—可序列化和XML
所有由该语言定义的复杂结构都是可序列化及反序列化的,即:
1. 可以整个类序化成一段二进制数据流或XML。
2. 类可以从一段二进制数据流或XML初始化。
10.完整语法(扩展巴科斯范式EBNF)
使用SPIRITC++语言描述
grammar= (idl_file_define=*whitespace>>+
(enum_define|struct_define|coclass_define),
comment = comment_p ("/*", "*/") | comment_p ("//","/n"),
whitespace = space_p|comment,
typedefine_ =str_p("CHAR") | "UCHAR" | "SHORT" | "USHORT" | "INT"
| "UINT" | "LONGLONG" | "ULONGLONG" | "STRINGA" | "STRINGW"
| "DOUBLE" | "FLOAT" ,
enum_keyword_ = str_p ("enum"),
struct_keyword_ = str_p("struct"),
coclass_keyword_ =str_p("coclass"),
inteface_keyword_ =str_p("interface"),
dispinterface_keyword_ =str_p("dispinterface"),
inherit_keyword_ =str_p("public"),
keyword_ = enum_keyword_
|struct_keyword_
|coclass_keyword_
|inteface_keyword_
|dispinterface_keyword_
|inherit_keyword_
|typedefine_,
keyword = keyword_ >> +whitespace,
identifer_ = ((alpha_p | '_') >> *(alnum_p | '_'))-keyword_,
identifer = identifer_>>*(whitespace),
typedefine = (typedefine_|identifer_)>>+whitespace,
assign_operate_ = ch_p('='),
inherit_operate_ = ch_p(':'),
define_start_ = ch_p('{'),
define_end_ = ch_p('}'),
define_seperator_ = ch_p(';'),
entry_seperator_ =ch_p(','),
param_decl_start_ = ch_p('('),
param_decl_end_ = ch_p(')'),
array_d_start_ = ch_p('['),
array_d_end_ = ch_p(']'),
operators =assign_operate_
|inherit_operate_
|define_start_
|define_end_
|define_seperator_
|entry_seperator_
|param_decl_start_
|param_decl_end_
|array_d_start_
|array_d_end_
,
number_ = ((str_p("0x")|str_p("0X"))>>hex_p)|int_p,
number = number_>>*(whitespace),
unsigned_int_=((str_p("0x")|str_p("0X"))>>hex_p)|uint_p,
unsigned_int =unsigned_int_>>*(whitespace),
array_d_start = array_d_start_>>*(whitespace),
array_d_end = array_d_end_>>*(whitespace),
assign_operate = assign_operate_>>*(whitespace),
inherit_operate = inherit_operate_>>*(whitespace),
define_start = define_start_>>*(whitespace),
define_end = define_end_>>*(whitespace),
define_seperator = define_seperator_>>*(whitespace),
entry_seperator =entry_seperator_>>*(whitespace),
param_decl_start = param_decl_start_>>*whitespace,
param_decl_end = param_decl_end_>>*whitespace,
//enum
enum_assign_value = assign_operate>>number,
enum_entry = identifer>>*enum_assign_value,
enum_header = enum_keyword_>>+whitespace>>identifer,
enum_define = enum_header
>>define_start
>>enum_entry
>>*(entry_seperator>>(enum_entry))
>>!entry_seperator
>>define_end
>>define_seperator,
//structure
array_define= array_d_start
>>!unsigned_int
>>array_d_end,
variable_define = typedefine
>>identifer
>>*array_define ,
member_entry = variable_define>>define_seperator
,
struct_header =struct_keyword_>>+whitespace>>identifer
,
struct_parent = inherit_operate
>>inherit_keyword_
>>+whitespace>>identifer
,
struct_define =struct_header
>>*struct_parent
>>define_start
>>+(member_entry)
>>define_end
>>define_seperator
,
//method
param_define = variable_define>>
*(entry_seperator>>variable_define),
method_header = str_p("INT")>>+whitespace>>identifer,
method_define = method_header
>>param_decl_start
>>*(param_define)
>>param_decl_end
>>define_seperator
,
//inteface
interface_header = inteface_keyword_>>+whitespace>>identifer,
interface_define = interface_header
>>define_start
>>+(method_define)
>>define_end
>>define_seperator
,
//dispinterface
dispinterface_header = dispinterface_keyword_>>+whitespace>>identifer,
dispinterface_define = dispinterface_header
>>define_start
>>+(method_define)
>>define_end
>>define_seperator
,
//coclass
coclass_header = coclass_keyword_>>+whitespace>>identifer,
coclass_define = coclass_header
>>define_start
>>interface_define
>>dispinterface_define
>>define_end
>>define_seperator
);
11.改进需求
1.目前限制了interface与dispinterface必须配对,且才一对出现在coclass中,同时生成的代码中dispinterface和interface合并到一个类中,实践发现,这个不利于程序模块划分。因此,以下几点需要改进:
a. 必须出现一个以上的interface和dispinterface,但是不限制inteface和dispactch的数量.
b.每个inteface生成一个单独的类,同样每个dispinterface也生成一个单独的类.
c.生成interface和dispinterface生成时作为coclass的成员变量.
d.所有的数据从coclass进入,由dispactch统一分配指令号并分发调用.
2. 目前生成代码只支持actionscript和c++, 需要扩展支持PHP和JAVA.
3. 目前生成的代码中没有注释,希望可以把注释带到生成的代码中,这样便于更准确地描述接口给开发人员。
4. 定长数组,因为有不定长数组的存在,事实上定长数组是不定数组的一个子集,从理论上来说是无需保留的,但它的存在对于性能上有好处,值得商榷.
5. STRINGW是UTF-16,对于大部分的脚本语言和解释语言,并不支持,需要不需要保留也值得商榷。
6. 某些协议可能需要定义些两方共用的字符串变量或其它数组型的常量,有必要引入const定义,鉴于数组在大部的语言中可以使用字符串的转义来表达,如”/x0/xf6/x78”,表示可以表示一个数组{0,0xf6,0x78}, 所以引入const保留定来表示常量的字符串即可满足上述要求。
7. 考虑对复杂的容器的支持,如MAP和SET,对应脚本语言的关联数组(Assoc Array之类)。这样可以避免cpp中传递这样的容器时候要转成一个array所造成的效率问题。