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.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都写不出来 就滚回家做编译原理的大作业去吧!

时间: 2024-11-07 13:23:17

c++的语法分析器和年终总结和骂人的相关文章

构造可配置词法语法分析器生成器(下)

本文为笔者原创,转载请注明出处 http://blog.csdn.net/xinghongduo mylex & xparser mylex & xparser是笔者实现的类似于Lex和Yacc的词法语法分析器生成器,它接受正则表达式定义的词法规则和BNF定义的语法规则,自动构造对应的以C为宿主语言的词法分析器源程序mylex.h, mylex.c和语法分析器源程序xparser.h, xparser.c. mylex & xparser特点如下: 轻量无依赖:构造器的主要代码仅2

LL(1)语法分析器 //c++实现

#include<iostream> #include<string> #include<map> #include<vector> #include<stack> #include<set> #include<cstring> using namespace std; map<char,int>getnum; char getchar[100]; //获得对应字符 vector<string>pr

小白天堂之编写词法语法分析器何其简单(一)

写小白天堂系列的文章算是从这一篇开始吧,但是写这个词法语法分析器实在是因为编译原理老师扣啊,哎,没办法,只能直接写代码,当时正好将Javascript的语法基本撸了一边,所以就决定写一个JS的词法语法分析器,嗯,当然这个写哪种编程语法的分析器都一样,最多是在词法分析器中有点区别,他们的语法分析器几乎都是一样的,构造First集,Follow集,然后就是构建出预测分析表M基本就OK了,如果你还想增加Select集也可以,虽然这个东西可以不写,但是有些教科书上却讲了这个东西. 也许上面说的东西,有些

构造可配置词法语法分析器生成器(上)

本文为笔者原创,转载请注明出处 http://blog.csdn.net/xinghongduo 前言 源程序在被编译为目标程序需要经过如下6个过程:词法分析,语法分析,语义分析,中间代码生成,代码优化,目标代码生成.词法分析和语法分析是编译过程的初始阶段,是编译器的重要组成部分,早期相关理论和工具缺乏的环境下,编写词法语法分析器是很繁琐的事情.上世纪70年代,贝尔实验室的M. E. Lesk,E. Schmidt和Stephen C. Johnson分别为Unix系统编写了词法分析器生成器Le

构造可配置词法语法分析器生成器(中)

本文为笔者原创,转载请注明出处 http://blog.csdn.net/xinghongduo   语法分析器 语法分析器(grammar parser)是编译器的核心部分之一,它的作用是检测词法分析器返回的token序列是否符合文法定义的规则.一个完整的语法分析器除了检测语法正确性外还要包含对出错的处理以及错误恢复等功能. 文法和文法类型 文法是定义一个语言的所有规则的集合,形式上定义为四元组G={VT,VN,S,P},其中: VT是非空有限符号集合,它的每个符号称为终结符,文法产生的语言由

基于语法分析器GOLD Parser开发的数学表达式计算器

最近发现一款文法分析神器,看完官网(http://goldparser.org/)的介绍后感觉很犀利的样子,于是就拿来测试了一番,写了一个数学表达式分析的小程序,支持的数学运算符如下所示:常规运算:+ - * / ^ sqrt sqrt2(a,b) pow2(a) pow(a,b)三角函数:sin cos tan cot asin acos atan acot指数对数:log2(a) log10(a) ln(a) logn(a,b) e^最大最小:max(a,b,...) min(a,b,...

编译原理 - 实验三 - 递归下降语法分析器的调试及扩展

一. 语法分析介绍 语法分析是编译过程的核心部分,它的主要任务是按照程序语言的语法规则,从由词法分析输出的源程序符号串中识别出各类语法成分,同时进行语法检查,为语义分析和代码生成做准备.执行语法分析任务的程序叫语法分析程序或语法分析器. 二. 所实现的语义分析和代码生成程序能处理什么语句 (1)简单变量的声明语句 (2)表达式语句 (3)if语句. (4)while语句 (5)for语句 (6)write语句 (7)read语句 (8)do语句. (9)处理过程调用和返回 三.实验过程 ①用VC

语法分析器自动生成工具一览

Lex/Yacc 它生于Unix,是最经典的词法\语法分析器,是经典教材中的示例御用工具.现在它也支持在Windows上生成(安装环境),然而其所生成语法分析器的语言仅有C语言. Flex/Bison 与前者类似,Bison与Yacc有很高的兼容性.生成语言为C.C++和Java. CoCo/R 较早的一个语法分析器生成工具.其生成语法分析器的语言极其之多,包括C#. Java. C++.F#.VB.Net.Oberon等等. ANTLR 作为翻译程序的一部分,你可以使用简单的操作符和动作来参数

自己动手写编译器之Tiny语言语法分析器的实现

接着上一篇文章介绍的Tiny语言的词法分析的实现,本文将介绍Tiny语言的语法分析器的实现. 1 Tiny语言的语法 下图是Tiny在BNF中的文法, 文法的定义可以看出,INNY语言有以下特点: 1 程序共有5中语句:if语句,repea语句,read语句,write语法和assign语句. 2 if语句以end作为结束符号,if语句和repeat语句允许语句序列作为主体. 3 输入/输出由保留字read和write开始.read语句一次只读出一个变量,而write语句一次只写出一个表达式.