网络通讯协议定义语言及代理代码生成器

2008-12-26

修改:2009-8-7


 

 

目录

1.概述... 3

2.命名规则... 3

3.保留字... 3

4.数据类型... 3

4.1简单数据类型... 3

4.2复杂数据类型... 4

4.3 复杂数据类型的继承... 4

5.注释... 4

6.枚举... 5

7.数组... 5

8.协议接口... 6

9.边效(side effect)—可序列化和XML. 6

10.完整语法(扩展巴科斯范式EBNF... 6

11.改进需求... 10

 


 

 

1.概述

该语言可以定义出用于C++, ACTION SCRIPT 3.0 ,JAVAPHP 或其它语言的网络通信协议,这种语言的编译器可以把这种语言编写的IDL协议文件自动生成可用于C++, ACTION SCRIPT 3.0,JAVAPHP 或其它语言的实现代码。

2.命名规则

大小写敏感.

遵守C,JAVAC#规则.

即变量,结构,枚举或函数名只能由字母,数字,和下划线_组成, 命名的开头不能是数字,只能以字母或下划线组成.

 

(),{},[]三种标志划分命名的区域.

 

3.保留字

C,JAVA,PHPAS语言的保留字并集.

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 STRINGWUtf16字符串)尚未支持,如果涉及as代码,请不要使用STRINGWUtf16字符串),只能使用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]; //表示这个一个长度是16CHAR数组

不定长数组;

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定义协议包括两个接口, interfacedispinterface,其中interface表示由客户端向服务器进行主动请求的接口,而dispinterface则是服务器对于客户端的请求的回应事件接口.

 

Interfacedispinterface的方法声明和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.目前限制了interfacedispinterface必须配对,且才一对出现在coclass中,同时生成的代码中dispinterfaceinterface合并到一个类中,实践发现,这个不利于程序模块划分。因此,以下几点需要改进:


a. 必须出现一个以上的interfacedispinterface,但是不限制intefacedispactch的数量.

b.每个inteface生成一个单独的类,同样每个dispinterface也生成一个单独的类.

c.生成interfacedispinterface生成时作为coclass的成员变量.

d.所有的数据从coclass进入,由dispactch统一分配指令号并分发调用.

 

2.  目前生成代码只支持actionscriptc++, 需要扩展支持PHPJAVA.

3.       目前生成的代码中没有注释,希望可以把注释带到生成的代码中,这样便于更准确地描述接口给开发人员。

4.       定长数组,因为有不定长数组的存在,事实上定长数组是不定数组的一个子集,从理论上来说是无需保留的,但它的存在对于性能上有好处,值得商榷.

5.       STRINGWUTF-16,对于大部分的脚本语言和解释语言,并不支持,需要不需要保留也值得商榷。

6.       某些协议可能需要定义些两方共用的字符串变量或其它数组型的常量,有必要引入const定义,鉴于数组在大部的语言中可以使用字符串的转义来表达,如”/x0/xf6/x78”,表示可以表示一个数组{0,0xf6,0x78}, 所以引入const保留定来表示常量的字符串即可满足上述要求。

 

7.  考虑对复杂的容器的支持,如MAPSET,对应脚本语言的关联数组(Assoc Array之类)。这样可以避免cpp中传递这样的容器时候要转成一个array所造成的效率问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值