代码处理方法及装置与流程

专利2022-06-29  80


本发明涉及计算机技术领域,具体而言,涉及一种代码处理方法及装置。



背景技术:

目前市面上有非常多的游戏项目采用python语言作为主要开发语言,这些项目通常会将游戏策划的表格数据导出为python模块文件。游戏进程会读取这些模块文件到内存里并执行相应的游戏逻辑。当表格数据变得越多的时候,表格数据占用的内存也会变多,甚至成为游戏进程的内存瓶颈。

为解决表格数据占用的问题,表格数据会被导出为python模块,模块里面包含不同类型的对象,包括字典,元组,lambda表达式,整形,长整形,浮点,字符串。对于表格数据而言,里面有很相同字面值的对象构建运算,由于这些构建运算会得到相同的对象,所以这种方式虽然在一定程度上降低了表格模块的内存占用。

但是,由于字典,元组,lambda表达式等类型是可变数据类型,python模块没有对这些类型对象使用字面值运算的优化手段。并且游戏内对于表格数据的使用是只读的,所以对于表格数据而言,字典,元组,lambda表达式等类型也是不可变数据类型,并且表格数据通常会包含多个相同值的上述类型的不同对象,这些不同对象对于表格数据来说是冗余的,会占用内存资源。

针对上述的问题,目前尚未提出有效的解决方案。



技术实现要素:

本发明实施例提供了一种代码处理方法及装置,以至少解决现有技术中存在游戏项目的表格数据较多导致占用内存资源,影响游戏进程的技术问题。

根据本发明实施例的一个方面,提供了一种代码处理方法,包括:将初始源代码转换为源抽象语法树对象;将上述源抽象语法树对象中的多个可变数据类型对象替换为自定义类型对象,并添加赋值表达式类型对象和删除表达式类型对象,得到目标抽象语法树对象;将上述目标抽象语法树对象逆向转换为目标源代码,并输出上述目标源代码。

根据本发明实施例的另一方面,还提供了一种代码处理装置,包括:转换模块,用于将初始源代码转换为源抽象语法树对象;第一处理模块,用于将上述源抽象语法树对象中的多个可变数据类型对象替换为自定义类型对象,并添加赋值表达式类型对象和删除表达式类型对象,得到目标抽象语法树对象;第二处理模块,用于将上述目标抽象语法树对象逆向转换为目标源代码,并输出上述目标源代码。

根据本发明实施例的另一方面,还提供了一种存储介质,上述存储介质包括存储的程序,其中,在上述程序运行时控制上述存储介质所在设备执行任意一项上述的代码处理方法。

根据本发明实施例的另一方面,还提供了一种处理器,上述处理器用于运行程序,其中,上述程序运行时执行任意一项上述的代码处理方法。

在本发明实施例中,采用修改表格模块源代码的方式,通过将初始源代码转换为源抽象语法树对象;将上述源抽象语法树对象中的多个可变数据类型对象替换为自定义类型对象,并添加赋值表达式类型对象和删除表达式类型对象,得到目标抽象语法树对象;将上述目标抽象语法树对象逆向转换为目标源代码,并输出上述目标源代码,达到了修改源代码以改变对象运算方式,减少表格数据的内存占用的目的,从而实现了加快游戏进程的技术效果,进而解决了现有技术中存在游戏项目的表格数据较多导致占用内存资源,影响游戏进程的技术问题。

附图说明

此处所说明的附图用来提供对本发明的进一步理解,构成本申请的一部分,本发明的示意性实施例及其说明用于解释本发明,并不构成对本发明的不当限定。在附图中:

图1是根据本发明实施例的一种代码处理方法的流程图;

图2是根据本发明实施例的一种可选的代码处理方法的流程图;

图3是根据本发明实施例的一种可选的代码处理方法的流程图;

图4是根据本发明实施例的一种代码处理装置的结构示意图。

具体实施方式

为了使本技术领域的人员更好地理解本发明方案,下面将结合本发明实施例中的附图,对本发明实施例中的技术方案进行清楚、完整地描述,显然,所描述的实施例仅仅是本发明一部分的实施例,而不是全部的实施例。基于本发明中的实施例,本领域普通技术人员在没有做出创造性劳动前提下所获得的所有其他实施例,都应当属于本发明保护的范围。

需要说明的是,本发明的说明书和权利要求书及上述附图中的术语“第一”、“第二”等是用于区别类似的对象,而不必用于描述特定的顺序或先后次序。应该理解这样使用的数据在适当情况下可以互换,以便这里描述的本发明的实施例能够以除了在这里图示或描述的那些以外的顺序实施。此外,术语“包括”和“具有”以及他们的任何变形,意图在于覆盖不排他的包含,例如,包含了一系列步骤或单元的过程、方法、系统、产品或设备不必限于清楚地列出的那些步骤或单元,而是可包括没有清楚地列出的或对于这些过程、方法、产品或设备固有的其它步骤或单元。

首先,为方便理解本发明实施例,下面将对本发明中所涉及的部分术语或名词进行解释说明:

ast模块:是指python提供的一个模块,用于帮助python程序处理python语法的抽象语法树。

tree_node:表格模块文件通过ast模块转化得到的抽象语法树对象的名称。

ast.name:ast模块提供的节点类型之一,代表名字表达式节点类型。

ast.dict:ast模块提供的节点类型之一,代表字典节点类型。

ast.tuple:ast模块提供的节点类型之一,代表元组节点类型。

ast.lambda:ast模块提供的节点类型之一,代表lambda表达式节点类型。

ast.assign:ast模块提供的节点类型之一,代表赋值表达式节点类型。

ast.delete:ast模块提供的节点类型之一,代表删除表达式节点类型。

const:自定义的节点类型,用于替换可变对象节点。

codegen:python的第三方库,用于将抽象语法树对象逆转换为代码字符串。

const_dict:有序的以const类型节点对象的name属性为键,值为包含被替换节点的信息的数据结构的表格。

node:属于某一抽象语法树的节点对象,作为输入变量。

ast.num:ast模块提供的节点类型之一,代表数字节点类型。

ast.expression:st模块提供的节点类型之一,代表表达式类型。

none,true,false:python内置的不可变对象。

repr:python内置的函数,可以将对象序列化为字符串。

source:由表格模块文件读入内存后的字符串对象。

ast.parse:ast模块提供的函数,将代码字符串对象转换为抽象语法树对象。

tree_node:转换后的抽象语法树对象的名称。

consttransformer:用于修改抽象语法树的遍历类。

visitor:consttransformer类对象。

new_body:存储算法计算得到的新的节点列表。

const_name,const_info:中间过程名称。

实施例1

根据本发明实施例,提供了一种代码处理方法的方法实施例,需要说明的是,在附图的流程图示出的步骤可以在诸如一组计算机可执行指令的计算机系统中执行,并且,虽然在流程图中示出了逻辑顺序,但是在某些情况下,可以以不同于此处的顺序执行所示出或描述的步骤。

图1是根据本发明实施例的一种代码处理方法的流程图,如图1所示,该方法包括如下步骤:

步骤s102,将初始源代码转换为源抽象语法树对象;

步骤s104,将上述源抽象语法树对象中的多个可变数据类型对象替换为自定义类型对象,并添加赋值表达式类型对象和删除表达式类型对象,得到目标抽象语法树对象;

步骤s106,将上述目标抽象语法树对象逆向转换为目标源代码,并输出上述目标源代码。

在本发明实施例中,采用修改表格模块源代码的方式,通过将初始源代码转换为源抽象语法树对象;将上述源抽象语法树对象中的多个可变数据类型对象替换为自定义类型对象,并添加赋值表达式类型对象和删除表达式类型对象,得到目标抽象语法树对象;将上述目标抽象语法树对象逆向转换为目标源代码,并输出上述目标源代码,达到了修改源代码以改变对象运算方式,减少表格数据的内存占用的目的,从而实现了加快游戏进程的技术效果,进而解决了现有技术中存在游戏项目的表格数据较多导致占用内存资源,影响游戏进程的技术问题。

在一种可选的实施例中,上述多个可变数据类型对象包括:字典类型对象、元组类型对象、预设表达式类型对象。

可选的,在本申请实施例中,上述预设表达式类型对象具体可以为lambda表达式类型对象。

在一种可选的实施例中,上述初始源代码在读入内存后从初始的表格数据形式转化为字符串对象。

可选的,在上述实施例中,上述初始源代码的初始形式为表格数据形式,在读入内存后从初始的表格数据形式转化为字符串对象。

作为一种可选的实施例,可以通过采用python内置的ast模块,将字符串对象转化为源抽象语法树对象tree_node;可选的,上述ast模块帮助python程序处理python语法的抽象语法树,ast提供节点类的定义和工具函数和类,包括遍历语法树类和修改语法树等功能,开发者可以使用该ast模块来分析和处理python源代码。

可选的,上述多个可变数据类型对象包括:ast.dict,ast.tuple,ast.lambda类型节点;上述自定义类型对象为const类型节点。

作为另一种可选的实施例,本申请实施例通过新增自定义类型对象const类型节点,继承于ast.name节点类,并提供将ast.dict,ast.tuple,ast.lambda等节点类型转化为字面值的方法,实现将上述源抽象语法树对象中的多个可变数据类型对象替换为自定义类型对象,具体的,可以通过深度遍历抽象语法树对象,将抽象语法树对象里面的ast.dict,ast.tuple,ast.lambda类型节点替换为const类型节点,其中,字面值相同的节点其对应const类型节点的name属性相同。

可选的,上述赋值表达式类型对象为ast.assign节点,上述删除表达式类型对象为ast.delete节点。

可选的,自定义节点类const(即上述const类型节点)可以但不限于为以下代码形式:

classconst(ast.name):

def__init__(self,name,origin_node,*args,**kwargs):

super(const,self).__init__(id=name,*args,**kwargs)

self.name=name

具体的,上述const类型节点继承于ast.name类型,其name属性和其id属性一致,name属性同时是一个标识,当不同的const类型节点的name属性值相等,则表明这些节点指向同一个对象;const类型节点被用于替换可变数据类型对象的节点。

在本申请实施例中,在将上述源抽象语法树对象中的多个可变数据类型对象替换为自定义类型对象之后,上述赋值表达式类型对象ast.assign节点和上述删除表达式类型对象ast.delete节点到至新创建的对象列表,得到目标抽象语法树对象;借助第三方模块codegen,将上述目标抽象语法树对象逆向转换为目标源代码,并输出上述目标源代码。

可选的,上述第三方模块codegen可以将目标抽象语法树对象逆向转换为目标源代码(python源代码),相当于ast模块的一个逆向操作。

通过本申请实施例提供的代码处理方法,通过将源抽象语法树对象中的字典类型对象、元组类型对象、预设表达式类型对象等多个可变数据类型对象,替换为自定义类型对象,并添加赋值表达式类型对象和删除表达式类型对象,得到目标抽象语法树对象;再将上述目标抽象语法树对象逆向转换为目标源代码,并输出上述目标源代码。

也即,通过借助ast模块和codegen模块,增加节点类const,通过替换源抽象语法树的ast.dict,ast.tuple,ast.lambda节点为const类型节点,增加ast.assign节点和ast.delete节点,并将修改后的抽象语法树转换为目标源代码的方式,使得表格模块里面,字面值相同的字典,元组,lambda表达式等可变类型的构建运算转化为对同一个对象的引用运算,消除了冗余的对象,减低了表格数据对内存资源的占用。

需要说明的是,本申请实施中,减少占用的内存资源的多少与表格数据重复度正相关。

在一种可选的实施例中,将上述初始源代码转换为上述源抽象语法树对象包括:

步骤s202,通过预设脚本语言中配置的解析函数将上述字符串对象转换为上述源抽象语法树对象。

作为一种可选的实施例,上述预设脚本语言可以为python语言,上述解析函数可以为ast模块,也即可以通过采用python内置的ast模块,将字符串对象转化为源抽象语法树对象tree_node。

在一种可选的实施例中,将上述源抽象语法树对象中的上述多个可变数据类型对象替换为上述自定义类型对象,并添加上述赋值表达式类型对象和上述删除表达式类型对象,得到上述目标抽象语法树对象包括:

步骤s302,将上述多个可变数据类型对象替换为上述自定义类型对象,构建采用键值对表示的数据结构;

步骤s304,基于上述数据结构,在新创建的对象列表中添加上述赋值表达式类型对象和上述删除表达式类型对象,得到上述目标抽象语法树对象。

可选的,上述键值对以上述自定义类型对象的名称属性为键,以被替换对象的信息为值。

在本申请一种可选的实施例中,在遍历过程中构建有序的以const类型节点对象的name属性为键,值为包含被替换节点的信息的数据结构const_dict。根据上述数据结构const_dict,按序添加上述赋值表达式类型对象ast.assign节点和上述删除表达式类型对象ast.delete节点到至新创建的对象列表。

作为一种可选的实施例,本申请实施例还以通过以下程序代码实现将上述多个可变数据类型对象替换为上述自定义类型对象,构建采用键值对表示的数据结构,也即,将ast.dict,ast.tuple,ast.lambda等节点类型转化为字面值:

基于上述程序代码可知,本申请实施例通过node_to_key函数将多个可变数据类型对象替换为上述自定义类型对象(例如,字符串对象或不可变类型对象),如将一个节点转化为字面值,该字面值是一个字符串对象或不可变类型对象,例如,如none,true或false。literal_eval函数将一个节点对象转化为一个非节点类的自定义类型对象,literal_eval里面的子函数_convert是实际执行转化逻辑的函数。

在一种可选的实施例中,图2是根据本发明实施例的一种可选的代码处理方法的流程图,如图2所示,基于上述数据结构,在上述新创建的对象列表中添加上述赋值表达式类型对象包括:

步骤s402,构建上述赋值表达式类型对象;

步骤s404,将上述赋值表达式类型对象添加至上述新创建的对象列表中。

可选的,上述赋值表达式类型对象的目标元素是以上述自定义类型对象的名称属性为标识构建的名字表达式类型对象,上述目标元素的值属性是与上述自定义类型对象的名称属性对应的字面值。

可选的,通过构建上述赋值表达式类型对象;并将上述赋值表达式类型对象添加至上述新创建的对象列表中,基于上述数据结构,在上述新创建的对象列表中添加上述赋值表达式类型对象。

在本申请实施例中,通过以consttransformer.add_const_node完成添加常量节点的逻辑,其接受一个源节点node作为参数,完成如下流程得到const类型节点:调用node_to_key得到node的字面值key,判断key是否存在于const_key_dict里面,如果不存在,以__const__为前缀,index为后缀创建字符串const_name,以const_name为参数创建constinfo对象const_info,以const_name为键添加到const_dict字典里面,以key为键添加到const_key_dict里面,最后index属性自增1;否则,以__const__为前缀,index为后缀创建字符串const_name,以const_name为参数创建constinfo对象const_info,以const_name为键添加到const_dict字典里面,以key为键添加到const_key_dict里面,最后index属性自增1。

通过key从const_key_dict得到const_info,以const_info.name,node作为参数构建const类型节点const_node,往const_info的node_list列表加入源节点node,往const_info.const_node_list列表加入const_node,返回const_node;const_key_dict字典保证了相同字面值的节点构建出来的constnode对象的name属性会相同,并会被加入到同一个constinfo对象。

作为一种可选的实施例,替换ast.dict节点的实现代码如下所示:

可选的,可以以consttransformer.visit_dict完成ast.dict节点替换的逻辑,采取深度遍历的方法,先将keys属性内的所有节点完成const类型节点的替换,再将values属性内的所有节点完成const类型节点的替换,最后完成自身节点的const替换。

作为一种可选的实施例,替换ast.tuple节点的实现代码如下所示:

也即,通过consttransformer.visit_tuple完成ast.tuple节点替换的逻辑,同样是深度遍历的方法,先将elts属性内的所有节点完成const的替换,最后再完成自身const类型节点的替换。

作为一种可选的实施例,替换ast.lambda节点的实现代码如下所示:

defvisit_lambda(self,node):

returnself.add_const_node(node)

也即,通过consttransformer.visit_lambda完成ast.lambda节点的替换逻辑,由于该类型节点没有子对象,完成自身const类型节点替换即可。

在一种可选的实施例中,图3是根据本发明实施例的一种可选的代码处理方法的流程图,如图3所示,基于上述数据结构,在上述新创建的对象列表中添加上述删除表达式类型对象包括:

步骤s502,构建上述删除表达式类型对象;

步骤s504,将上述删除表达式类型对象添加至上述新创建的对象列表中。

可选的,上述赋值表达式类型对象的目标元素是以上述自定义类型对象的名称属性为标识构建的名字表达式类型对象。

可选的,可以通过构建上述删除表达式类型对象;并将上述删除表达式类型对象添加至上述新创建的对象列表中。

作为一种可选的实施例中,可以通过遍历forconst_name,const_infoinnode.const_dict.iteritems();构建ast.delete节点delete_node,其targets属性只有一个元素为以const_name为id构建的ast.name节点;将delete_node往后添加到new_body;将new_body替换tree_node.body属性,即使用新的节点列表替换旧的节点列表。

作为一种可选的实施例,本申请实施例所提供的代码处理方法的整体算法流程可以但不限于如下步骤1-9所示:

1.输入表格模块的初始源代码source;

2.以source为参数,调用ast.parse函数,得到源抽象语法树对象tree_node;

3.创建consttransfromer对象visitor,以tree_node为参数调用visitor.vistor方法,完成ast.dict,ast.tuple,ast.lambda的替换,并且vistor.const_dict会存储被创建的constinfo对象;

4.创建新的节点列表new_body

5.遍历forconst_name,const_infoinvisitor.const_dict.iteritems()

5.1构建ast.assign节点assign_node,其targets只有一个元素为以const_name为id构建的ast.name节点,value属性为const_info.node_list[0],由于const_info.node_list里面每一个节点的字面值都一样,因此使用其中一个节点作为value即可;

5.2将assign_node往后添加到new_body;

6.将tree_node的子节点按序往后添加到new_body里面;

7.遍历forconst_name,const_infoinnode.const_dict.iteritems();

7.1构建ast.delete节点delete_node,其targets属性只有一个元素为以const_name为id构建的ast.name节点;

7.2将delete_node往后添加到new_body;

8.将new_body替换tree_node.body属性,即使用新的节点列表替换旧的节点列表;

9.使用codegen模块将修改后的tree_node得到目标源代码并返回。

作为一种可选的实施例,以下提供一个使用本申请实施例所提供的代码处理方法的一个实施方式:

处理前的初始源代码:

处理前的目标源代码:

作为一种可选的实施例,_convert函数可以通过执行以下流程得到自定义类型对象:

首先,输入可变数据类型对象node,并判断node的类型,如果node类型为ast.str类型,那么返回node.s属性,如果node类型为ast.num类型,以__ast_const_num_%s(%s)为格式化字符串,node.n的类型和node.n数值为格式化参数,得到一个字符串并返回;如果node类型为ast.tuple类型,借助python元组构造语法,遍历node的子节点,将每一个子节点作为参数调用_convert函数得到返回值,并将返回值地结果放到构造元组对象里,并返回构造的元组对象;如果node类型为ast.dict类型,借助python字典构造语法,遍历字典的每一个键和值,以键和值作为参数调用得到_convert函数得到键返回值和值返回值,并将键返回值和值返回值作为构造字典对象的键和值,最后返回构造的字典对象;如果node类型为ast.name并且node的id属性值等于”none”,“true”,“false”其中一个,那么返回对应的值none,true,false;如果node类型为const,返回node的name属性;如果node类型为ast.lambda,以__ast_lambda_%s作为格式字符串,借助codegen模块将node转换为python代码字符串作为格式化参数得到的字符串并返回;则抛出valueerror异常。

作为一种可选的实施例,literal_eval函数可以通过执行以下流程得到自定义类型对象:

首先,输入可变数据类型对象node,并判断node的类型,如果node的类型为ast.expression,将node的body属性作为参数调用_convert函数得到返回值并返回;否则,以node为参数调用_convert函数得到返回值并返回;node_to_key函数执行以下流程得到字面值;输入节点对象node,并以node为参数调用literal_eval函数得到自定义类型对象,判断自定义类型对象的类型,如果自定义类型对象的类型为字典类型,以__ast_const_dict_%s为格式化字符串,按键的值有序地构建一个以键值对二元元组作为元素的元组对象,并且对其调用repr函数合成一个字符串对象,并以该字符串对象作为格式化参数得到一个新的字符串并返回,如果自定义类型对象的类型为元组类型,以__ast_const_tuple_%s为格式化字符串,对中间对象调用repr函数得到的返回值作为格式化参数,得到一个新的字符串并返回自定义类型对象。

本申请一种可选的实施例中提供遍历节点类,定义constinfo的代码可以如下所示:

classconstinfo(object):

def__init__(self,name):

self.name=name

self.node_list=[]

self.const_node_list=[]

其中,上述constinfo是存储了const类型节点和被const类型节点替换的原节点的数据结构,const_node_list存储了相同name属性的const类型节点列表,node_list存储了被const_node_list里的const类型节点替换的节点列表,name属性和const_node_list里面任一节点的name属性相同,也即相同字面值的ast.dict,ast.tuple,ast.lambda节点归属于同一个constinfo对象。

本申请一种可选的实施例中定义遍历节点类的实现代码可以如下所示:

classconsttransformer(ast.nodetransformer):

def__init__(self):

self.const_dict=ordereddict()

self.const_key_dict=ordereddict()

self.index=0

具体的,上述ast模块提供工具类ast.nodetransformer,这个类用于遍历抽象语法树,开发者可以继承该类来实现自定义节点逻辑。consttransformer继承于ast.nodetransformer,其包含3个属性,const_dict是以constinfo.name为键,constinfo对象为值的有序字典,const_key_dict以constinfo.node_list里面任意一个节点的字面值作为键,值为constinfo对象的有序字典。index属性为生成const类型节点name属性的自增下标,目的是确保name属性的唯一性。

本申请一种可选的实施例中通过源节点得到一个常量节点的实现代码可以如下所示:

defadd_const_node(self,node):

try:

key=node_to_key(node)

except(valueerror,typeerror):

returnnode

ifkeynotinself.const_key_dict:

const_name='__const__%s'%self.index

const_info=self.const_dict[const_name]=constinfo(const_name)

self.const_key_dict[key]=const_info

self.index =1

else:

const_info=self.const_key_dict[key]

const_node=const(const_info.name,node)

const_info.node_list.append(node)

const_info.const_node_list.append(const_node)

ast.copy_location(const_node,node)

returnconst_node

在一种可选的实施例中,上述consttransformer.add_const_node完成添加常量节点的逻辑,其接受一个源节点node作为参数,完成如下流程得到const类型节点:调用node_to_key得到node的字面值key,判断key是否存在于const_key_dict里面,如果不存在,以__const__为前缀,index为后缀创建字符串const_name,以const_name为参数创建constinfo对象const_info,以const_name为键添加到const_dict字典里面,以key为键添加到const_key_dict里面,最后index属性自增1,否则,通过key从const_key_dict得到const_info;以const_info.name,node作为参数构建const类型节点const_node,往const_info的node_list列表加入源节点node,往const_info.const_node_list列表加入const_node,返回const_node;其中,const_key_dict字典保证了相同字面值的节点构建出来的constnode对象的name属性会相同,并会被加入到同一个constinfo对象;

本申请一种可选的实施例中,替换ast.dict节点的实现代码可以如下所示:

defvisit_dict(self,node):

keys=tuple(node.keys)

forindex,keyinenumerate(keys):

ret=self.visit(key)

ifret:

node.keys[index]=ret

ret=self.visit(node.values[index])

ifret:

node.values[index]=ret

returnself.add_const_node(node)

具体的,上述consttransformer.visit_dict完成ast.dict节点替换的逻辑,可以采用深度遍历的方法,例如,先将keys属性内的所有节点完成const类型节点的替换,再将values属性内的所有节点完成const类型节点的替换,最后完成自身节点的const替换。

本申请一种可选的实施例中,替换ast.tuple节点的实现代码可以如下所示:

defvisit_tuple(self,node):

ifnotnode.elts:

returnnode

forindex,child_nodeinenumerate(tuple(node.elts)):

ret=self.visit(child_node)

ifret:

node.elts[index]=ret

returnself.add_const_node(node)

具体的,上述consttransformer.visit_tuple完成ast.tuple节点替换的逻辑,同样是深度遍历的方法,先将elts属性内的所有节点完成const的替换,最后再完成自身const类型节点的替换。

本申请一种可选的实施例中,替换ast.lambda节点的实现代码可以如下所示:

defvisit_lambda(self,node):

returnself.add_const_node(node)

具体的,上述consttransformer.visit_lambda完成ast.lambda节点的替换逻辑,由于该类型节点没有子对象,完成自身const类型节点替换即可。

作为一种可选的实施例,上述实现方案的整体算法流程,可以但不限于如下所示:

首先,输入表格模块初始源代码source,并以source为参数,调用ast.parse函数,得到抽象语法树对象tree_node,创建consttransfromer对象visitor,以tree_node为参数调用visitor.vistor方法,此步骤会完成ast.dict,ast.tuple,ast.lambda的替换,并且vistor.const_dict会存储着被创建的constinfo对象,创建新的节点列表new_body,遍历forconst_name,const_infoinvisitor.const_dict.iteritems(),构建ast.assign节点assign_node,其targets只有一个元素为以const_name为id构建的ast.name节点,value属性为const_info.node_list[0],由于const_info.node_list里面每一个节点的字面值都一样,所以使用其中一个节点作为value即可;通过将assign_node往后添加到new_body,将tree_node的子节点按序往后添加到new_body里,遍历forconst_name,const_infoinnode.const_dict.iteritems(),构建ast.delete节点delete_node,其targets属性只有一个元素为以const_name为id构建的ast.name节点,将delete_node往后添加到new_body;将new_body替换tree_node.body属性,即是使用新的节点列表替换旧的节点列表;使用codegen模块将修改后的tree_node得到源代码并返回。

实施例2

根据本发明实施例,还提供了一种用于实施上述代码处理方法的装置实施例,图4是根据本发明实施例的一种代码处理装置的结构示意图,如图4所示,上述代码处理装置,包括:转换模块40、第一处理模块42和第二处理模块44,其中:

转换模块40,用于将初始源代码转换为源抽象语法树对象;第一处理模块42,用于将上述源抽象语法树对象中的多个可变数据类型对象替换为自定义类型对象,并添加赋值表达式类型对象和删除表达式类型对象,得到目标抽象语法树对象;第二处理模块44,用于将上述目标抽象语法树对象逆向转换为目标源代码,并输出上述目标源代码。

需要说明的是,上述各个模块是可以通过软件或硬件来实现的,例如,对于后者,可以通过以下方式实现:上述各个模块可以位于同一处理器中;或者,上述各个模块以任意组合的方式位于不同的处理器中。

此处需要说明的是,上述转换模块40、第一处理模块42和第二处理模块44对应于实施例1中的步骤s102至步骤s106,上述模块与对应的步骤所实现的实例和应用场景相同,但不限于上述实施例1所公开的内容。需要说明的是,上述模块作为装置的一部分可以运行在计算机终端中。

需要说明的是,本实施例的可选或优选实施方式可以参见实施例1中的相关描述,此处不再赘述。

上述的代码处理装置还可以包括处理器和存储器,上述转换模块40、第一处理模块42和第二处理模块44等均作为程序单元存储在存储器中,由处理器执行存储在存储器中的上述程序单元来实现相应的功能。

处理器中包含内核,由内核去存储器中调取相应的程序单元,上述内核可以设置一个或以上。存储器可能包括计算机可读介质中的非永久性存储器,随机存取存储器(ram)和/或非易失性内存等形式,如只读存储器(rom)或闪存(flashram),存储器包括至少一个存储芯片。

根据本申请实施例,还提供了一种存储介质实施例。可选地,在本实施例中,上述存储介质包括存储的程序,其中,在上述程序运行时控制上述存储介质所在设备执行上述任意一种代码处理方法。

可选地,在本实施例中,上述存储介质可以位于计算机网络中计算机终端群中的任意一个计算机终端中,或者位于移动终端群中的任意一个移动终端中,上述存储介质包括存储的程序。

可选地,在程序运行时控制存储介质所在设备执行以下功能:将初始源代码转换为源抽象语法树对象;将上述源抽象语法树对象中的多个可变数据类型对象替换为自定义类型对象,并添加赋值表达式类型对象和删除表达式类型对象,得到目标抽象语法树对象;将上述目标抽象语法树对象逆向转换为目标源代码,并输出上述目标源代码。

根据本申请实施例,还提供了一种处理器实施例。可选地,在本实施例中,上述处理器用于运行程序,其中,上述程序运行时执行上述任意一种代码处理方法。

本申请实施例提供了一种设备,设备包括处理器、存储器及存储在存储器上并可在处理器上运行的程序,处理器执行程序时实现以下步骤:将初始源代码转换为源抽象语法树对象;将上述源抽象语法树对象中的多个可变数据类型对象替换为自定义类型对象,并添加赋值表达式类型对象和删除表达式类型对象,得到目标抽象语法树对象;将上述目标抽象语法树对象逆向转换为目标源代码,并输出上述目标源代码。

本申请还提供了一种计算机程序产品,当在数据处理设备上执行时,适于执行初始化有如下方法步骤的程序:将初始源代码转换为源抽象语法树对象;将上述源抽象语法树对象中的多个可变数据类型对象替换为自定义类型对象,并添加赋值表达式类型对象和删除表达式类型对象,得到目标抽象语法树对象;将上述目标抽象语法树对象逆向转换为目标源代码,并输出上述目标源代码。

上述本发明实施例序号仅仅为了描述,不代表实施例的优劣。

在本发明的上述实施例中,对各个实施例的描述都各有侧重,某个实施例中没有详述的部分,可以参见其他实施例的相关描述。

在本申请所提供的几个实施例中,应该理解到,所揭露的技术内容,可通过其它的方式实现。其中,以上所描述的装置实施例仅仅是示意性的,例如所述单元的划分,可以为一种逻辑功能划分,实际实现时可以有另外的划分方式,例如多个单元或组件可以结合或者可以集成到另一个系统,或一些特征可以忽略,或不执行。另一点,所显示或讨论的相互之间的耦合或直接耦合或通信连接可以是通过一些接口,单元或模块的间接耦合或通信连接,可以是电性或其它的形式。

所述作为分离部件说明的单元可以是或者也可以不是物理上分开的,作为单元显示的部件可以是或者也可以不是物理单元,即可以位于一个地方,或者也可以分布到多个单元上。可以根据实际的需要选择其中的部分或者全部单元来实现本实施例方案的目的。

另外,在本发明各个实施例中的各功能单元可以集成在一个处理单元中,也可以是各个单元单独物理存在,也可以两个或两个以上单元集成在一个单元中。上述集成的单元既可以采用硬件的形式实现,也可以采用软件功能单元的形式实现。

所述集成的单元如果以软件功能单元的形式实现并作为独立的产品销售或使用时,可以存储在一个计算机可读取存储介质中。基于这样的理解,本发明的技术方案本质上或者说对现有技术做出贡献的部分或者该技术方案的全部或部分可以以软件产品的形式体现出来,该计算机软件产品存储在一个存储介质中,包括若干指令用以使得一台计算机设备(可为个人计算机、服务器或者网络设备等)执行本发明各个实施例所述方法的全部或部分步骤。而前述的存储介质包括:u盘、只读存储器(rom,read-onlymemory)、随机存取存储器(ram,randomaccessmemory)、移动硬盘、磁碟或者光盘等各种可以存储程序代码的介质。

以上所述仅是本发明的优选实施方式,应当指出,对于本技术领域的普通技术人员来说,在不脱离本发明原理的前提下,还可以做出若干改进和润饰,这些改进和润饰也应视为本发明的保护范围。


技术特征:

1.一种代码处理方法,其特征在于,包括:

将初始源代码转换为源抽象语法树对象;

将所述源抽象语法树对象中的多个可变数据类型对象替换为自定义类型对象,并添加赋值表达式类型对象和删除表达式类型对象,得到目标抽象语法树对象;

将所述目标抽象语法树对象逆向转换为目标源代码,并输出所述目标源代码。

2.根据权利要求1所述的方法,其特征在于,所述初始源代码在读入内存后从初始的表格数据形式转化为字符串对象。

3.根据权利要求2所述的方法,其特征在于,将所述初始源代码转换为所述源抽象语法树对象包括:

通过预设脚本语言中配置的解析函数将所述字符串对象转换为所述源抽象语法树对象。

4.根据权利要求1所述的方法,其特征在于,将所述源抽象语法树对象中的所述多个可变数据类型对象替换为所述自定义类型对象,并添加所述赋值表达式类型对象和所述删除表达式类型对象,得到所述目标抽象语法树对象包括:

将所述多个可变数据类型对象替换为所述自定义类型对象,构建采用键值对表示的数据结构,其中,所述键值对以所述自定义类型对象的名称属性为键,以被替换对象的信息为值;

基于所述数据结构,在新创建的对象列表中添加所述赋值表达式类型对象和所述删除表达式类型对象,得到所述目标抽象语法树对象。

5.根据权利要求4所述的方法,其特征在于,所述多个可变数据类型对象包括:

字典类型对象、元组类型对象、预设表达式类型对象。

6.根据权利要求4所述的方法,其特征在于,基于所述数据结构,在所述新创建的对象列表中添加所述赋值表达式类型对象包括:

构建所述赋值表达式类型对象,其中,所述赋值表达式类型对象的目标元素是以所述自定义类型对象的名称属性为标识构建的名字表达式类型对象,所述目标元素的值属性是与所述自定义类型对象的名称属性对应的字面值;

将所述赋值表达式类型对象添加至所述新创建的对象列表中。

7.根据权利要求4所述的方法,其特征在于,基于所述数据结构,在所述新创建的对象列表中添加所述删除表达式类型对象包括:

构建所述删除表达式类型对象,其中,所述删除表达式类型对象的目标元素是以所述自定义类型对象的名称属性为标识构建的名字表达式类型对象;

将所述删除表达式类型对象添加至所述新创建的对象列表中。

8.一种代码处理装置,其特征在于,包括:

转换模块,用于将初始源代码转换为源抽象语法树对象;

第一处理模块,用于将所述源抽象语法树对象中的多个可变数据类型对象替换为自定义类型对象,并添加赋值表达式类型对象和删除表达式类型对象,得到目标抽象语法树对象;

第二处理模块,用于将所述目标抽象语法树对象逆向转换为目标源代码,并输出所述目标源代码。

9.一种存储介质,其特征在于,所述存储介质包括存储的程序,其中,在所述程序运行时控制所述存储介质所在设备执行权利要求1至7中任意一项所述的代码处理方法。

10.一种处理器,其特征在于,所述处理器用于运行程序,其中,所述程序运行时执行权利要求1至7中任意一项所述的代码处理方法。

技术总结
本发明公开了一种代码处理方法及装置。其中,该方法包括:将初始源代码转换为源抽象语法树对象;将上述源抽象语法树对象中的多个可变数据类型对象替换为自定义类型对象,并添加赋值表达式类型对象和删除表达式类型对象,得到目标抽象语法树对象;将上述目标抽象语法树对象逆向转换为目标源代码,并输出上述目标源代码。本发明解决了现有技术中存在游戏项目的表格数据较多导致占用内存资源,影响游戏进程的技术问题。

技术研发人员:陈伟杰
受保护的技术使用者:网易(杭州)网络有限公司
技术研发日:2020.01.16
技术公布日:2020.06.09

转载请注明原文地址: https://bbs.8miu.com/read-20848.html

最新回复(0)