首页 > 代码库 > c++的语法分析器和年终总结和骂人

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

续上篇: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.STATESECTIONENDif k == ‘defineend‘ and state.achivestate == state.STATENAMESPACEACHIVEEND:    state.achivestate = state.STATENAMESPACEDEFINEENDif 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++的语法分析器和年终总结和骂人