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

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

语法解析部分

  1. class func(object):
  2. def __init__(self):
  3. self.keyworld = ''
  4. self.func = []
  5. self.argvtuple = None
  6.  
  7. def clear(self):
  8. self.keyworld = ''
  9. self.func = []
  10. self.argvtuple = None
  11.  
  12. def push(self, ch):
  13. if ch == ' ' or ch == '\0':
  14. self.keyworld = deleteNoneSpacelstrip(self.keyworld)
  15. if self.keyworld != '':
  16. if self.argvtuple is None:
  17. self.func.append(deleteNoneSpacelstrip(self.keyworld))
  18. else:
  19. if self.keyworld in ['table', 'array', 'int', 'string', 'float', 'bool']:
  20. self.argvtuple.append(deleteNoneSpacelstrip(self.keyworld))
  21. self.keyworld = ''
  22. return False
  23.  
  24. if ch == ',':
  25. if self.keyworld != '' and self.keyworld in ['table', 'array', 'int', 'string', 'float', 'bool']:
  26. self.argvtuple.append(deleteNoneSpacelstrip(self.keyworld))
  27. self.keyworld = ''
  28.  
  29. return False
  30.  
  31. if ch == '(':
  32. self.keyworld = deleteNoneSpacelstrip(self.keyworld)
  33. if self.keyworld != '':
  34. self.func.append(deleteNoneSpacelstrip(self.keyworld))
  35. self.argvtuple = []
  36. self.keyworld = ''
  37. return False
  38.  
  39. if ch == ')':
  40. if self.keyworld != '' and self.keyworld in ['table', 'array', 'int', 'string', 'float', 'bool']:
  41. self.argvtuple.append(deleteNoneSpacelstrip(self.keyworld))
  42.  
  43. if self.argvtuple is None:
  44. self.func.append([])
  45. else:
  46. self.func.append(self.argvtuple)
  47.  
  48. self.keyworld = ''
  49. return False
  50.  
  51. if ch == ';':
  52. return True
  53.  
  54. self.keyworld += ch
  55.  
  56. return False
  57.  
  58. class module(object):
  59. def __init__(self):
  60. self.keyworld = ''
  61. self.name = ''
  62. self.module = []
  63. self.machine = None
  64.  
  65. def push(self, ch):
  66. if ch == '}':
  67. self.machine = None
  68. return True
  69.  
  70. if self.machine is not None:
  71. if self.machine.push(ch):
  72. self.module.append(self.machine.func)
  73. self.machine.clear()
  74. else:
  75. if ch == '{':
  76. self.name = deleteNoneSpacelstrip(self.keyworld)
  77. self.keyworld = ''
  78. self.machine = func()
  79. return False
  80.  
  81. self.keyworld += ch
  82.  
  83. return False
  84.  
  85. class statemachine(object):
  86. def __init__(self):
  87. self.keyworld = ''
  88. self.module = {}
  89. self.machine = None
  90.  
  91. def push(self, ch):
  92. if self.machine is not None:
  93. if self.machine.push(ch):
  94. if isinstance(self.machine, module):
  95. self.module[self.machine.name] = self.machine.module
  96. self.machine = None
  97. else:
  98. if ch == ' ' or ch == '\0':
  99. if deleteNoneSpacelstrip(self.keyworld) == 'module':
  100. self.machine = module()
  101. self.keyworld = ''
  102. else:
  103. self.keyworld += ch
  104.  
  105. def getmodule(self):
  106. return self.module
  107.  
  108. def syntaxanalysis(self, genfilestr):
  109. for str in genfilestr:
  110. for ch in str:
  111. self.push(ch)

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

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

module:[funcinfo, ...]

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

  1. def gencaller(module_name, funcs):
  2. code = "/*this caller file is codegen by juggle*/\n"
  3. code += "using System;\n"
  4. code += "using System.Collections;\n"
  5. code += "using System.IO;\n"
  6. code += "using MsgPack;\n"
  7. code += "using MsgPack.Serialization;\n\n"
  8.  
  9. code += "namespace caller\n"
  10. code += "{\n"
  11. code += " public class " + module_name + " : Icaller \n"
  12. code += " {\n"
  13. code += " public " + module_name + "(Ichannel _ch) : base(_ch)\n"
  14. code += " {\n"
  15. code += " module_name = \"" + module_name + "\";\n"
  16. code += " }\n\n"
  17.  
  18. for i in funcs:
  19. code += " public void " + i[1] + "("
  20. count = 0
  21. for item in i[2]:
  22. code += tools.gentypetocsharp(item) + " argv" + str(count)
  23. count = count + 1
  24. if count < len(i[2]):
  25. code += ","
  26. code += ")\n"
  27. code += " {\n"
  28. code += " ArrayList _argv = new ArrayList();\n"
  29. for n in range(len(i[2])):
  30. code += " _argv.Add(argv" + str(n) + ");\n"
  31. code += " call_module_method(\"" + i[1] + "\", _argv);\n"
  32. code += " }\n\n"
  33.  
  34. code += " }\n"
  35. code += "}\n"
  36.  
  37. return code
  1. def genmodule(module_name, funcs):
  2. code = "/*this module file is codegen by juggle*/\n"
  3. code += "using System;\n"
  4. code += "using System.Collections;\n\n"
  5.  
  6. code += "namespace module\n{\n"
  7. code += " public class " + module_name + " : Imodule \n {\n"
  8.  
  9. code += " public " + module_name + "()\n {\n"
  10. code += " module_name = \"" + module_name + "\";\n"
  11. code += " }\n\n"
  12.  
  13. for i in funcs:
  14. code += " public abstract void " + i[1] + "("
  15. count = 0
  16. for item in i[2]:
  17. code += tools.gentypetocsharp(item) + " argv" + str(count)
  18. count = count + 1
  19. code += ");\n\n"
  20.  
  21. code += " }\n"
  22. code += "}\n"
  23.  
  24. 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. git学习笔记之二 -- git分支

    前面对git基础作了简单的总结,这次对git的杀手锏--分支做一总结. Git分支简介 几乎每个版本控制系统都以某种形式支持分支,可以使你的工作从开发主线上分离开来,以免影响开发主线.很多版本控制系统 ...

  2. caffe的Matlab接口安装

    参考博文:http://blog.csdn.net/thystar/article/details/50720691 0. Caffe安装及Matlab安装 1. Caffe中matcaffe配置 c ...

  3. 透过 Delphi 使用二进位金钥做 AES 加密.

    从 1994 年开始,笔者就开始接触加密与网路安全的世界,从鲁立忠老师的指导当中获益良多,后来在台湾的元智大学就读研究所的时候,也以此为研究主题. 在当时,电子商务是显学,Visa跟 Master C ...

  4. Hive 桶的分区

    (一).桶的概念: 对于每一个表(table)或者分区, Hive可以进一步组织成桶(没有分区能分桶吗?),也就是说桶是更为细粒度的数据范围划分.Hive也是 针对某一列进行桶的组织.Hive采用对列 ...

  5. protobuf 系列 ---------下载、编译与使用

    protobuf是谷歌开发并开源的二进制序列化工具,比常用的xml,json体积更小,解析速度更快. 目前,手头上的项目有涉及到这个工具,打算仔细研究一番,顺带记录遇到的问题,解决方法,时间足够的话, ...

  6. HourRank 20

    第一题略 第二题组合数学 s1 = min(cnt['a'],cnt['b']), s2 = min(cnt['c'],cnt['d']), b1 = max(cnt['a'],cnt['b']), ...

  7. MySQL主从同步报错故障处理集锦

    前言 在发生故障切换后,经常遇到的问题就是同步报错,下面是最近收集的报错信息. 记录删除失败 在master上删除一条记录,而slave上找不到 Last_SQL_Error: Could not e ...

  8. sh脚本异常,binsh^M bad interpreter No such file or directory

    错误 在Linux中执行.sh脚本,出现如下异常 /bin/sh^M: bad interpreter: No such file or directory 原因 在windows系统中编辑的.sh文 ...

  9. Unix文化--RTFM

    背景 从上个世纪70年代初unix被创建后的不久,它变得越来越流行起来,从最初的贝尔实验室,到后来的许多大学的计算机院系.这意味着越来越多的人需要学习如何使用unix. 可以预期的是,贝尔实验室的人都 ...

  10. 如何使用kali的Searchsploit查找软件漏洞

    Searchsploit Searchsploit会通过本地的exploit-db, 查找软件漏洞信息 打开kali的命令行, 输入: searchsploit 查看系统帮助 查找mssql的漏洞 如 ...