Cont.: http://www.cnblogs.com/qianqians/p/4168332.html
Now here's a clear explanation of the grammatical analysis:
In order to maintain the context context of the function declaration, such as Declaration and global, Namespace,class, I define a simple state machine
Class state (object): Statenone = 0 Statenormalfunc = 1.1 Stateclassfunc = 1.2 Statestaticclassfunc = 1.3 ST Atefuncargvpairbegin = Statefuncargvpairend = Statefuncdefine = Statefuncachivebegin = STATEFUNCAC Hiveend = Stateclass = 2 Stateclassachivebegin = Stateclassachiveend = Stateclassdefineend = Atenamespace = 6 Statenamespaceachivebegin = Statenamespaceachiveend = Statenamespacedefineend estatic = 3 Statesectionend = 4 Staterpccall = 5 Statepreprocess = 7 def __init__ (self, parentstate): s Elf.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)
This state machine preserves the context of the superior and generates a subordinate state machine when the context is transformed.
if keyword = = v[' key ': if _state.state! = state. Statenone: _state = State (_state)
As the code sees, when the context transforms, a subordinate state machine is defined (_state) _state
Then at the end of the current context, such as the end of the function declaration, the class namespace definition ends, the pop to the parent context
if s.achivestate = = Ruletable.state.STATESECTIONEND: _statemachine.state = _statemachine.state.pop () Tempkeywork = []
The context of the judgment, belongs to the scope of the grammatical analysis, I defined a simple C + + grammar rules are as follows:
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 ':p reprocessrule}
When a keyword such as defineend is checked, and the state is in the syntax context class, it switches to the context end state
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
Based on such a lexical and syntactic parsing process, the function declarations in the code can eventually be parsed as follows:
{' acceptservice.h ': {' Templateclassfunc ': {}, ' Classfunc ': {' acceptservice ': [' Std::tuple<int, std::string, float > ', ' run_network ', ' int count '], [' std::p air<int, int> ', ' run_network ', ' int count ', ' int count1 ']}, ' Globalfun C ': [[' std::string ', ' init ']], ' templateglobalfunc ': []}}
Then, based on such a set of keyword tables, you can use it for code generation.
def codegenclient (Rpcsysmbal): If not Os.path.isdir (Build_path): Os.mkdir (Build_path) for k,v in Rpcsysmbal.i TEMs (): Code = ' #include <iremoteendpoint.h>\n\n ' for Sysmbal in v[' Globalfunc ': code + = S Ysmbal[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 \ nthe ' 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].s Plit (") Funcsys + = ' _ ' + syss[0] Code + = ' value[\ ' fnargv\ '][\ ' + syss[1] + ' \ '] = ' + syss[1] + '; ' Code + = ' value[\ ' fnname\ ' = \ ' + funcsys + ' \ '; \ n ' Code + = ' S->do_push (s, value); \ n \ nthe ' Code + = ' Json::value ret = _service_handle->wait (value[\ ' suuid\ '].asstring (), 1); \ n ' Code + = ' if (ret[\ ' suuid\ ')! = Value[\ ' suuid\ ') {\nthrow std::exception (\ "Error suuid\") \n}\n ' if sysmbal[0]! = ' void ': Code + = ' \nreturn ' If Sysmbal[0].find (' std::p air ')! =-1 or sysmbal[0].find (' pair ')! = -1:ind ex = Sysmbal[0].find (' std::p air ') 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 = s Ysmbal[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 (te Mavgr[i]), \ n ' else:code + = ' ret[\ ' rpcret\ ']. ' + returnty PE (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 + ' (iremotee Ndpoint _ep) {\NEP = _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 + = ' Bo ost::shared_ptr<session> s = getsession (EP); \ n \ nthe ' 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:] F or sys in xrange (len (AVGR)): Syss = Avgr[sys].split (") Funcsys + = ' _ ' + syss[0] Code + = ' value[\ ' fnargv\ '][\ ' + syss[1] + ' \ '] = ' + syss[1] + '; \ n ' Code + = ' value[\ ' FNN ame\ '] = \ ' + Funcsys + ' \ '; \ n ' Code + = ' S->do_push (s, value); \ n \ nthe ' code + = ' json::value ret = _service_handle-& Gt;wait (value[\ ' suuid\ '].asstring (), 1); \ n ' Code + = ' if (ret[\ ' suuid\ ']! = Value[\ ' suuid\ ']) {\nthrow std::e Xception (\ "Error suuid\") \n}\n ' if func[0]! = ' void ': Code + = ' \nreturn ' If Func[0].find (' std::p air ')! =-1 or func[0].find (' pair ')! = -1:TEMAVGR = func[0][func[0].fi nd (' < ') + 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:temav GR = Func[0][func[0].find (' < ') + 1: -1].split (', ') code + = ' Std::make_tuple (' For i in Xrange (Len (TEMAVGR)): if I! = Len (temavgr)-1:co De + = ' ret[\ ' rpcret\ ' [' + str (i) + ']. ' + returntype (Deletenonespacelstrip (temavgr[i]) + ', ' Else:code + = ' ret[\ ' rpcret\ ' [' + str (i) + ']. ' + returntype (Deletenonespacelstrip (temavg R[i])) \ 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)
The last generated code for
is as follows:
#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::p air<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 ());}};
And then roughly: this time it is not required to copy the right, because it is very difficult to read:
Then began to curse:), to reward the former colleague in TX what Chen Lei (QQ 110086478, mobile phone 13524139363), what Chan Chen (cell phone 18603014436,qq 281795034) What, in order to prevent the wrong person, Attached QQ, mobile phone! Attached to the real Mingshi sex, because you are ugly, i hate you
take stock of what you've done over the years:
Https://github.com/qianqians/tstates/tree/master/symbol_analytical tstate Monitor Acquisition tool in TX
What did you do, silly B?
Https://github.com/qianqians/vchat in a frozen voice chat frame
What did you do, silly B?
Https://github.com/qianqians/Hemsleya/tree/master/Hemsleya/base/active task scheduling framework based on co-process
What did you do, silly B?
Https://github.com/qianqians/Hemsleya/tree/master/Hemsleya/base/concurrent/pool Memory Pool
What did you do, silly B?
Https://github.com/qianqians/Fossilizid/tree/master/reliably-%20transmission in frozen UDP reliability transmission
What did you do, silly B?
Https://github.com/qianqians/Fossilizid/tree/master/remote-queue a long, good-looking network library
What did you do, silly B?
Https://github.com/qianqians/Fossilizid/tree/master/reduce-rpc/service Server Framework
What did you do, silly B?
Https://github.com/qianqians/Fossilizid/tree/master/reduce-rpc/rpcmake a CodeGen
Silly B You codegen can not write out to go home to do the compiling principle of the big homework to go!
C + + parser and year-end summary and curse