juggle添加c#版本

此前做过一个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 == '':
            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 == '':
                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*/
"
        code += "using System;
"
        code += "using System.Collections;
"
        code += "using System.IO;
"
        code += "using MsgPack;
"
        code += "using MsgPack.Serialization;

"

        code += "namespace caller
"
        code += "{
"
        code += "    public class " + module_name + " : Icaller 
"
        code += "    {
"
        code += "        public " + module_name + "(Ichannel _ch) : base(_ch)
"
        code += "        {
"
        code += "            module_name = "" + module_name + "";
"
        code += "        }

"

        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 += ")
"
                code += "        {
"
                code += "            ArrayList _argv = new ArrayList();
"
                for n in range(len(i[2])):
                        code += "            _argv.Add(argv" + str(n) + ");
"
                code += "            call_module_method("" + i[1] + "", _argv);
"
                code += "        }

"

        code += "    }
"
        code += "}
"

        return code
def genmodule(module_name, funcs):
    code = "/*this module file is codegen by juggle*/
"
    code += "using System;
"
    code += "using System.Collections;

"

    code += "namespace module
{
"
    code += "    public class " + module_name + " : Imodule 
    {
"

    code += "        public " + module_name + "()
        {
"
    code += "            module_name = "" + module_name + "";
"
    code += "        }

"

    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 += ");

"

    code += "    }
"
    code += "}
"

    return code

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

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

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

原文地址:https://www.cnblogs.com/qianqians/p/5634178.html