此前做过一个c++版的网络层dsl:http://www.cnblogs.com/qianqians/p/4255034.html

现在给这个dsl加入c#的支持,并且对代码的结构做了优化,将语法解析和代码生成做了解耦

语法解析部分

class func(object):
def __init__(self):
self.keyworld = ''
self.func = []
self.argvtuple = None def clear(self):
self.keyworld = ''
self.func = []
self.argvtuple = None def push(self, ch):
if ch == ' ' or ch == '\0':
self.keyworld = deleteNoneSpacelstrip(self.keyworld)
if self.keyworld != '':
if self.argvtuple is None:
self.func.append(deleteNoneSpacelstrip(self.keyworld))
else:
if self.keyworld in ['table', 'array', 'int', 'string', 'float', 'bool']:
self.argvtuple.append(deleteNoneSpacelstrip(self.keyworld))
self.keyworld = ''
return False if ch == ',':
if self.keyworld != '' and self.keyworld in ['table', 'array', 'int', 'string', 'float', 'bool']:
self.argvtuple.append(deleteNoneSpacelstrip(self.keyworld))
self.keyworld = '' return False if ch == '(':
self.keyworld = deleteNoneSpacelstrip(self.keyworld)
if self.keyworld != '':
self.func.append(deleteNoneSpacelstrip(self.keyworld))
self.argvtuple = []
self.keyworld = ''
return False if ch == ')':
if self.keyworld != '' and self.keyworld in ['table', 'array', 'int', 'string', 'float', 'bool']:
self.argvtuple.append(deleteNoneSpacelstrip(self.keyworld)) if self.argvtuple is None:
self.func.append([])
else:
self.func.append(self.argvtuple) self.keyworld = ''
return False if ch == ';':
return True self.keyworld += ch return False class module(object):
def __init__(self):
self.keyworld = ''
self.name = ''
self.module = []
self.machine = None def push(self, ch):
if ch == '}':
self.machine = None
return True if self.machine is not None:
if self.machine.push(ch):
self.module.append(self.machine.func)
self.machine.clear()
else:
if ch == '{':
self.name = deleteNoneSpacelstrip(self.keyworld)
self.keyworld = ''
self.machine = func()
return False self.keyworld += ch return False class statemachine(object):
def __init__(self):
self.keyworld = ''
self.module = {}
self.machine = None def push(self, ch):
if self.machine is not None:
if self.machine.push(ch):
if isinstance(self.machine, module):
self.module[self.machine.name] = self.machine.module
self.machine = None
else:
if ch == ' ' or ch == '\0':
if deleteNoneSpacelstrip(self.keyworld) == 'module':
self.machine = module()
self.keyworld = ''
else:
self.keyworld += ch def getmodule(self):
return self.module def syntaxanalysis(self, genfilestr):
for str in genfilestr:
for ch in str:
self.push(ch)

解析采用状态机机制,逐字符读取代码在读取到关键字符则跳转状态,并且保持读取到的关键字。

读取的关键字采用table方式保持

module:[funcinfo, ...]

在代码生成部分,按解析获取的语法table生成module和caller代码,分别是事件的响应和调用端。

def gencaller(module_name, funcs):
code = "/*this caller file is codegen by juggle*/\n"
code += "using System;\n"
code += "using System.Collections;\n"
code += "using System.IO;\n"
code += "using MsgPack;\n"
code += "using MsgPack.Serialization;\n\n" code += "namespace caller\n"
code += "{\n"
code += " public class " + module_name + " : Icaller \n"
code += " {\n"
code += " public " + module_name + "(Ichannel _ch) : base(_ch)\n"
code += " {\n"
code += " module_name = \"" + module_name + "\";\n"
code += " }\n\n" for i in funcs:
code += " public void " + i[1] + "("
count = 0
for item in i[2]:
code += tools.gentypetocsharp(item) + " argv" + str(count)
count = count + 1
if count < len(i[2]):
code += ","
code += ")\n"
code += " {\n"
code += " ArrayList _argv = new ArrayList();\n"
for n in range(len(i[2])):
code += " _argv.Add(argv" + str(n) + ");\n"
code += " call_module_method(\"" + i[1] + "\", _argv);\n"
code += " }\n\n" code += " }\n"
code += "}\n" return code
def genmodule(module_name, funcs):
code = "/*this module file is codegen by juggle*/\n"
code += "using System;\n"
code += "using System.Collections;\n\n" code += "namespace module\n{\n"
code += " public class " + module_name + " : Imodule \n {\n" code += " public " + module_name + "()\n {\n"
code += " module_name = \"" + module_name + "\";\n"
code += " }\n\n" for i in funcs:
code += " public abstract void " + i[1] + "("
count = 0
for item in i[2]:
code += tools.gentypetocsharp(item) + " argv" + str(count)
count = count + 1
code += ");\n\n" code += " }\n"
code += "}\n" return code

和juggle的上个版本不同,为了简洁的用于开发游戏服务器,这个版本删除了同步调用功能,只保留异步调用,对同步调用感兴趣的 可以阅读darckforce里面的代码:https://github.com/qianqians/darkforce/tree/master/juggle

这个版本的代码地址在:https://github.com/qianqians/abelkhan

我将基于这个版本的juggle开发一个开源的游戏服务器框架,欢迎大家在论坛或博客给我留言提出意见

juggle添加c#版本的更多相关文章

  1. svn add 添加到版本库

    转 svn add-添加到版本库 常用操作1.添加一个文件到工作拷贝:$ svn add foo.c 2.当添加一个目录,svn add缺省的行为方式是递归的:$ svn add testdir 3. ...

  2. eclipse添加高版本tomcat问题

    eclipse添加高版本tomcat会报错,提示无法匹配高版本的容器installation is expected 解决方法: 1.找到tomcat的lib目录下的catalina.jar包,用压缩 ...

  3. [iOS Xcode8]上传AppStore无法添加构建版本

    最近升级到xcode8了,也遇到了一些问题.最近产品需要更新版本,按照以前的流程,我觉得so easy啊,万万没想到啊,这次更新版本差点让我吐血,来来回回不下七次. 首先问题是版本通过xcode上传到 ...

  4. 3.2. 添加模板版本(Core Data 应用程序实践指南)

    为了不像3.1那样崩溃,修改模型之前先创建新的模型版本.添加之后,会生成一个新的xcdatamodel文件,并且跟原来的内容完全一样,这有意思了,但是不要删除原来旧版的模型.旧的模型有助于把原来持久化 ...

  5. mac sublime切换编辑语言的方法(添加其他版本的python)

    在sublime中指定python版本,操作如下: Sublime——tools——build system——new build system 把文件中的内容替换为 { "cmd" ...

  6. wamp——添加多版本PHP

    前言 从下载到部署,手把手教学~ wamp 版本 | 3.0.4 32位 步骤 下载PHP 进入网站https://windows.php.net/download然后选择想要的版本下载 注意点: . ...

  7. Vs2013中通过Nuget添加不同版本jQuery

    vs2013中如果直接更新jQuery则是2X的版本,为了兼容IE浏览器的,一般都是希望使用jQuery1.x版本的jQuery,则可在调出Nuget的控制台,在控制台输入(此例子是下载jQuery ...

  8. 【添加最新版本的mysql的jdbc连接jar包】java.math.BigInteger cannot be cast to java.lang.Long异常

    [问题描述] 从我的电脑把项目拷贝到guo小中的win8电脑,but出现了那个错误,估计他的mysql是最新版本的. [如何下载连接jar包] 链接:https://pan.baidu.com/s/1 ...

  9. git 忽略已经添加到版本库的文件

    第一步: 指令:git rm -r --cached YOUR_PATH YOUR_PATH 即 你的文件,-r 指定了递归所有的子文件夹. 第二步: 修改项目根目录下的 .gitignore 文件, ...

随机推荐

  1. MFC入门教程01 Windows编程基础

  2. [刷题]算法竞赛入门经典(第2版) 5-12/UVa511 - Do You Know the Way to San Jose?

    题意:N张地图,查找某地点在不在某些地图上,若在,使用细节多的地图.使用哪个地图的破要求挺多,细心一点就好. 代码:(Accepted,0.000s) //UVa511 - Do You Know t ...

  3. 转:Linux中文显示乱码?如何设置centos显示中文

    怎么设置Linux系统中文语言,这是很多小伙伴在开始使用Linux的时候,都会遇到一个问题,就是终端输入命令回显的时候中文显示乱码.出现这个情况一般是由于没有安装中文语言包,或者设置的默认语言有问题导 ...

  4. 使用expect的自动化交互

    Q:利用shell脚本实现ssh自动登录远程服务器? A:expect命令 #!/usr/bin/expect spawn ssh root@172.16.11.99 expect "*pa ...

  5. 进制转换,杭电0j-2031

    进制转换,杭电0j-2031原题地址:http://acm.hdu.edu.cn/showproblem.php?pid=2031 [Problem Description] 输入一个十进制数N,将它 ...

  6. 005---query接口初步

    Query session.createQuery(String hql)方法; * hibernate的session.createQuery()方法是使用HQL(hibernate的查询语句)语句 ...

  7. 每天4亿行SQLite订单大数据测试(源码)

    SQLite单表4亿订单,大数据测试 SQLite作为嵌入式数据库的翘楚,广受欢迎!新生命团队自2010年以来,投入大量精力对SQLite进行学习研究,成功应用于各系统非致命数据场合. SQLite极 ...

  8. 简单物联网:外网访问内网路由器下树莓派Flask服务器

    最近做一个小东西,大概过程就是想在教室,宿舍控制实验室的一些设备. 已经在树莓上搭了一个轻量的flask服务器,在实验室的路由器下,任何设备都是可以访问的:但是有一些限制条件,比如我想在宿舍控制我种花 ...

  9. 使用HAL库函数建立STM32F2工程

    一.建立一个新的文件夹,新建三个文件夹User.Driver.Project,还可以加一个Doc存放工程的相关说明等等. 1.将STM32F2xx的库函数(HAL函数库)中的Drivers文件夹中的所 ...

  10. 02-2--数据库MySQL:DDL(Data Definition Language:数据库定义语言)操作数据库中的表(二)

    DDL对数据库的操作:http://blog.csdn.net/baidu_37107022/article/details/72334560 DDL对数据库中表的操作 1)方法概览 2)演示 //创 ...