码迷,mamicode.com
首页 > 编程语言 > 详细

c++的语法分析器和年终总结和骂人

时间:2014-12-25 17:58:47      阅读:194      评论:0      收藏:0      [点我收藏+]

标签:

续上篇:http://www.cnblogs.com/qianqians/p/4168332.html

现在来个清晰的语法分析讲解:

为了保持函数声明的上下文语境比如声明与全局,namespace,class之中,我定义了一个简单的状态机

class state(object):
    STATENONE = 0
    STATENORMALFUNC = 1.1
    STATECLASSFUNC = 1.2
    STATESTATICCLASSFUNC = 1.3
    STATEFUNCARGVPAIRBEGIN = 11
    STATEFUNCARGVPAIREND = 13
    STATEFUNCDEFINE = 14
    STATEFUNCACHIVEBEGIN = 15
    STATEFUNCACHIVEEND = 16
    STATECLASS = 2
    STATECLASSACHIVEBEGIN = 21
    STATECLASSACHIVEEND = 22
    STATECLASSDEFINEEND = 23
    STATENAMESPACE = 6
    STATENAMESPACEACHIVEBEGIN = 61
    STATENAMESPACEACHIVEEND = 62
    STATENAMESPACEDEFINEEND = 63
    STATESTATIC = 3
    STATESECTIONEND = 4
    STATERPCCALL = 5
    STATEPREPROCESS = 7

    def __init__(self, parentstate):
        self.pairstate = 0
        self.attachstate = state.STATENONE
        self.state = state.STATENONE
        self.rpcstate = state.STATENONE
        self.achivestate = state.STATENONE
        self.statechange = False
        self.clearcache = False

        self.parentstate = parentstate

    def pop(self):
        if self.parentstate != None:
            return self.parentstate

        self.pairstate = 0
        self.state = state.STATENONE
        self.attachstate = state.STATENONE
        self.state = state.STATENONE
        self.rpcstate = state.STATENONE
        self.achivestate = state.STATENONE

        return self

    def is_need_clear(self):
        return self.clearcache

    def is_func(self):
        return self.state == state.STATECLASSFUNC or self.state == state.STATESTATICCLASSFUNC or self.state == state.STATENORMALFUNC

    def is_change(self):
        return self.statechange

    def is_pair(self):
        return self.pairstate > 0

    def is_wait_check(self):
        return self.state == state.STATENONE or (self.state == state.STATECLASS and self.achivestate == state.STATECLASSACHIVEBEGIN) or             (self.state == state.STATENAMESPACE and self.achivestate == state.STATENAMESPACEACHIVEBEGIN)
 

这个状态机就保存了上级的语境,并且在语境变换的时候,生成一个下级的状态机

if keyword == v[‘key‘]:
            if _state.state != state.STATENONE:
                _state = state(_state)

如代码所见,在语境变换的时候,定义了一个下级的状态机_state = state(_state)

然后在当前语境结束,比如函数声明结束,class namespace定义结束,则pop到上级语境

if s.achivestate == ruletable.state.STATESECTIONEND:
     _statemachine.state = _statemachine.state.pop()
     tempkeywork = []

对语境的判断,属于语法分析的范围,我定义了一个简单的c++语法规则如下:

preprocessrule = {‘key‘:‘#‘, ‘end‘:‘\n‘, ‘keyword‘:{‘include‘:{‘pairbegin‘:‘<‘, ‘pairend‘:‘>‘}, ‘pragma‘:{}, ‘if‘:{‘endkey‘:‘endif‘}, ‘endif‘:{}, ‘define‘:{}}}

pair = {‘pairbegin‘:‘<‘, ‘pairend‘:‘>‘}

rule = {‘namespace‘:{‘key‘:‘namespace‘, ‘achivebegin‘:‘{‘, ‘achiveend‘:‘}‘, ‘defineend‘:‘}‘},
        ‘class‘:{‘key‘:‘class‘, ‘achivebegin‘:‘{‘, ‘achiveend‘:‘}‘, ‘defineend‘:‘;‘},
        ‘func‘:{‘key‘:‘(‘, ‘argvbegin‘:‘(‘, ‘argvend‘:‘)‘, ‘argvsplit‘:‘,‘, ‘defineend‘:‘;‘, ‘achivebegin‘:‘{‘, ‘achiveend‘:‘}‘, ‘achivedefineend‘:‘}‘, ‘rpc‘:‘RPCCALL‘},
        ‘template‘:{‘key‘:‘template‘, ‘templateargvbegin‘:‘<‘, ‘templateargvend‘:‘>‘},
        ‘preprocessrule‘:preprocessrule}

在检查到defineend之类的关键字,且状态在该语法语境类,则切换到语境结束状态

if k == ‘defineend‘ and state.achivestate == state.STATEFUNCARGVPAIREND:
    state.achivestate = state.STATESECTIONEND

if k == ‘defineend‘ and state.achivestate == state.STATENAMESPACEACHIVEEND:
    state.achivestate = state.STATENAMESPACEDEFINEEND

if k == ‘defineend‘ and state.achivestate == state.STATECLASSACHIVEEND:
    state.achivestate = state.STATESECTIONEND

基于这样一个词法和语法分析的过程,最终可以分析出代码中的函数声明如下:

{‘acceptservice.h‘: {‘templateclassfunc‘: {}, ‘classfunc‘: {‘acceptservice‘: [[‘std::tuple<int, std::string, float>‘, ‘run_network‘, ‘int count‘], [‘std::pair<int, int>‘, ‘run_network‘, ‘int count‘, ‘int count1‘]]}, ‘globalfunc‘: [[‘std::string‘, ‘init‘]], ‘templateglobalfunc‘: []}}

然后基于这样一组关键字表,即可用于代码生成。

def codegenclient(rpcsysmbal):
    if not os.path.isdir(build_path):
        os.mkdir(build_path)

    for k,v in rpcsysmbal.items():
        code = ‘#include <IRemoteEndpoint.h>\n\n‘
        for sysmbal in v[‘globalfunc‘]:
            code += sysmbal[0] + ‘ ‘ + sysmbal[1] + ‘(IRemoteEndpoint ep‘
            funcsys = sysmbal[1]
            avgr = sysmbal[2:]
            for i in xrange(len(avgr)):
                 code += ‘, ‘ + avgr[i]
            code += ‘){\n‘
            code += ‘	boost::shared_ptr<session> s = GetSession(ep);\n\n‘
            code += ‘	Json::Value value;\n‘
            code += ‘	value[\‘epuuid\‘] = ‘ + ‘s.enppui();\n‘
            code += ‘	value[\‘suuid\‘] = UUID();\n‘
            code += ‘	value[\‘eventtype\‘] = \‘rpc_event\‘;\n‘
            code += ‘	value[\‘rpc_event_type\‘] = \‘call_rpc_mothed\‘;\n‘
            code += ‘	value[\‘fnargv\‘] = Json::Value(Json::objectValue) ;\n‘
            for sys in xrange(len(avgr)):
                syss = avgr[sys].split(‘ ‘)
                funcsys += ‘_‘ + syss[0]
                code += ‘	value[\‘fnargv\‘][\‘‘ + syss[1] + ‘\‘] = ‘ + syss[1] + ‘;‘
            code += ‘	value[\‘fnname\‘] = \‘‘ + funcsys + ‘\‘;\n‘
            code += ‘	s->do_push(s, value);\n\n‘
            code += ‘	Json::Value ret = _service_handle->wait(value[\‘suuid\‘].asString(), 1);\n‘
            code += ‘	if (ret[\‘suuid\‘] != value[\‘suuid\‘]){\n		throw std::exception(\"error suuid\")\n	}\n‘
            if sysmbal[0] != ‘void‘:
                code += ‘\n	return ‘
                if sysmbal[0].find(‘std::pair‘) != -1 or sysmbal[0].find(‘pair‘) != -1:
                    index = sysmbal[0].find(‘std::pair‘)
                    if index == -1:
                        index = sysmbal[0].find(‘pair‘)
                    temavgr = sysmbal[0][index + 6: -1].split(‘,‘)
                    code += ‘std::make_pair(‘
                    for i in xrange(len(temavgr)):
                        code += ‘ret[\‘rpcret\‘][ret‘ + str(i) + ‘].‘ + returntype(temavgr[i])
                    code += ‘);\n‘
                elif sysmbal[0] is ‘std::tuple‘ or sysmbal[0] is ‘tuple‘:
                    index = sysmbal[0].find(‘std::tuple‘)
                    if index == -1:
                        index = sysmbal[0].find(‘tuple‘)
                    temavgr = sysmbal[0][index + 6: -1].split(‘,‘)
                    code += ‘std::make_tuple(‘
                    for i in xrange(len(temavgr)):
                        code += ‘ret[\‘rpcret\‘][ret‘ + str(i) + ‘].‘ + returntype(temavgr[i])
                    code += ‘);\n‘
                else:
                    code += ‘ ret[\‘rpcret\‘].‘ + returntype(sysmbal[0]) + ‘;\n‘
            code += ‘}\n\n‘

        for classname, sysmbal in v[‘classfunc‘].items():
            code += ‘class ‘ + classname + ‘{\n‘ + ‘private:\n‘ + ‘	IRemoteEndpoint ep;\n\n‘
            code += ‘	‘ + classname + ‘(IRemoteEndpoint _ep){\n		ep = _ep;\n	}\n\n‘
            code += ‘public:\n‘
            for func in sysmbal:
                code += ‘	‘ + func[0] + ‘ ‘ + func[1] + ‘(‘
                funcsys = func[1]
                avgr = func[3:]
                code += func[2]
                for i in xrange(len(avgr)):
                    code += ‘, ‘ + avgr[i]
                code += ‘){\n‘
                code += ‘		boost::shared_ptr<session> s = GetSession(ep);\n\n‘
                code += ‘		Json::Value value;\n‘
                code += ‘		value[\‘epuuid\‘] = ‘ + ‘s.enppui();\n‘
                code += ‘		value[\‘suuid\‘] = UUID();\n‘
                code += ‘		value[\‘eventtype\‘] = \‘rpc_event\‘;\n‘
                code += ‘		value[\‘rpc_event_type\‘] = \‘call_rpc_mothed\‘;\n‘
                code += ‘		value[\‘fnargv\‘] = Json::Value(Json::objectValue) ;\n‘
                avgr = func[2:]
                for sys in xrange(len(avgr)):
                    syss = avgr[sys].split(‘ ‘)
                    funcsys += ‘_‘ + syss[0]
                    code += ‘		value[\‘fnargv\‘][\‘‘ + syss[1] + ‘\‘] = ‘ + syss[1] + ‘;\n‘
                code += ‘		value[\‘fnname\‘] = \‘‘ + funcsys + ‘\‘;\n‘
                code += ‘		s->do_push(s, value);\n\n‘
                code += ‘		Json::Value ret = _service_handle->wait(value[\‘suuid\‘].asString(), 1);\n‘
                code += ‘		if (ret[\‘suuid\‘] != value[\‘suuid\‘]){\n			throw std::exception(\"error suuid\")\n		}\n‘
                if func[0] != ‘void‘:
                    code += ‘\n		return ‘
                    if func[0].find(‘std::pair‘) != -1 or func[0].find(‘pair‘) != -1:
                        temavgr = func[0][func[0].find(‘<‘) + 1: -1].split(‘,‘)
                        code += ‘std::make_pair(‘
                        for i in xrange(len(temavgr)):
                            if i != len(temavgr) - 1:
                                 code += ‘ret[\‘rpcret\‘][ret‘ + str(i) + ‘].‘ + returntype(deleteNoneSpacelstrip(temavgr[i])) + ‘, ‘
                            else:
                                 code += ‘ret[\‘rpcret\‘][ret‘ + str(i) + ‘].‘ + returntype(deleteNoneSpacelstrip(temavgr[i]))
                        code += ‘);\n‘
                    elif func[0].find(‘std::tuple‘) != -1 or func[0].find(‘tuple‘) != -1:
                        temavgr = func[0][func[0].find(‘<‘) + 1: -1].split(‘,‘)
                        code += ‘std::make_tuple(‘
                        for i in xrange(len(temavgr)):
                            if i != len(temavgr) - 1:
                                code += ‘ret[\‘rpcret\‘][‘ + str(i) + ‘].‘ + returntype(deleteNoneSpacelstrip(temavgr[i])) + ‘, ‘
                            else:
                                code += ‘ret[\‘rpcret\‘][‘ + str(i) + ‘].‘ + returntype(deleteNoneSpacelstrip(temavgr[i]))
                        code += ‘);\n‘
                    else:
                        code += ‘ ret[\‘rpcret\‘];\n‘
                code += ‘	}\n\n‘
            code += ‘};\n\n‘

        if code != ‘#include <IRemoteEndpoint.h>\n\n‘:
            file = open(build_path + k, ‘w‘)
            file.write(code)

最后生成的代码如下:

#include <IRemoteEndpoint.h>

std::string init(IRemoteEndpoint ep){
	boost::shared_ptr<session> s = GetSession(ep);

	Json::Value value;
	value[‘epuuid‘] = s.enppui();
	value[‘suuid‘] = UUID();
	value[‘eventtype‘] = ‘rpc_event‘;
	value[‘rpc_event_type‘] = ‘call_rpc_mothed‘;
	value[‘fnargv‘] = Json::Value(Json::objectValue) ;
	value[‘fnname‘] = ‘init‘;
	s->do_push(s, value);

	Json::Value ret = _service_handle->wait(value[‘suuid‘].asString(), 1);
	if (ret[‘suuid‘] != value[‘suuid‘]){
		throw std::exception("error suuid")
	}

	return  ret[‘rpcret‘].asString();
}

class acceptservice{
private:
	IRemoteEndpoint ep;

	acceptservice(IRemoteEndpoint _ep){
		ep = _ep;
	}

public:
	std::tuple<int, std::string, float> run_network(int count){
		boost::shared_ptr<session> s = GetSession(ep);

		Json::Value value;
		value[‘epuuid‘] = s.enppui();
		value[‘suuid‘] = UUID();
		value[‘eventtype‘] = ‘rpc_event‘;
		value[‘rpc_event_type‘] = ‘call_rpc_mothed‘;
		value[‘fnargv‘] = Json::Value(Json::objectValue) ;
		value[‘fnargv‘][‘count‘] = count;
		value[‘fnname‘] = ‘run_network_int‘;
		s->do_push(s, value);

		Json::Value ret = _service_handle->wait(value[‘suuid‘].asString(), 1);
		if (ret[‘suuid‘] != value[‘suuid‘]){
			throw std::exception("error suuid")
		}

		return std::make_tuple(ret[‘rpcret‘][0].asInt(), ret[‘rpcret‘][1].asString(), ret[‘rpcret‘][2].asFloat());
	}

	std::pair<int, int> run_network(int count, int count1){
		boost::shared_ptr<session> s = GetSession(ep);

		Json::Value value;
		value[‘epuuid‘] = s.enppui();
		value[‘suuid‘] = UUID();
		value[‘eventtype‘] = ‘rpc_event‘;
		value[‘rpc_event_type‘] = ‘call_rpc_mothed‘;
		value[‘fnargv‘] = Json::Value(Json::objectValue) ;
		value[‘fnargv‘][‘count‘] = count;
		value[‘fnargv‘][‘count1‘] = count1;
		value[‘fnname‘] = ‘run_network_int_int‘;
		s->do_push(s, value);

		Json::Value ret = _service_handle->wait(value[‘suuid‘].asString(), 1);
		if (ret[‘suuid‘] != value[‘suuid‘]){
			throw std::exception("error suuid")
		}

		return std::make_pair(ret[‘rpcret‘][ret0].asInt(), ret[‘rpcret‘][ret1].asInt());
	}

};

然后大致如此: 这次就不要求抄对了,因为看懂都蛮难的:)

然后开始骂人:),赏给在tx的前同事 什么 陈磊(qq 110086478, 手机 13524139363),什么钱陈(手机 18603014436,qq 281795034)啥的,为了防搞错人,附上QQ,手机!直接附上真名实性嘛,是因为你们长的丑,我讨厌你们

盘点下这几年做的东西:

https://github.com/qianqians/tstates/tree/master/symbol_analytical tstate在tx做的监控采集工具

傻B你做了啥!

https://github.com/qianqians/vchat 在冰冻做的语音聊天框架

傻B你做了啥!

https://github.com/qianqians/Hemsleya/tree/master/Hemsleya/base/active 基于协程的任务调度框架

傻B你做了啥!

https://github.com/qianqians/Hemsleya/tree/master/Hemsleya/base/concurrent/pool 内存池

傻B你做了啥!

https://github.com/qianqians/Fossilizid/tree/master/reliably-%20transmission 在冰冻做的udp可靠性传输

傻B你做了啥!

https://github.com/qianqians/Fossilizid/tree/master/remote-queue 一个长的好看的网络库

傻B你做了啥!

https://github.com/qianqians/Fossilizid/tree/master/reduce-rpc/service 服务器框架

傻B你做了啥!

https://github.com/qianqians/Fossilizid/tree/master/reduce-rpc/rpcmake 一个codegen

傻B 你codegen都写不出来 就滚回家做编译原理的大作业去吧!

 

c++的语法分析器和年终总结和骂人

标签:

原文地址:http://www.cnblogs.com/qianqians/p/4184441.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!