标签:
此前做过一个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开发一个开源的游戏服务器框架,欢迎大家在论坛或博客给我留言提出意见
标签:
原文地址:http://www.cnblogs.com/qianqians/p/5634178.html