标签:
续上篇: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都写不出来 就滚回家做编译原理的大作业去吧!
标签:
原文地址:http://www.cnblogs.com/qianqians/p/4184441.html