具体实施方式
在对模板文件进行数据结构的提取时,计算机可以针对每行代码的描述,分别提取出数据参数的数据结构;然而,如果代码语句复杂,比如涉及到赋值、宏调用、for循环等操作时,由于涉及到参数类型、数值等方面的变化,计算机并不能够做出有效的区分和响应。
举例而言,假定模板文件为:
{%setb=a%}
{%setc=b%}
{{c.d}}
{%sete=1%}
则基于相关技术中的处理方式,计算机直接生成的数据结构可能为:
{a:‘’,b‘’,c:{d:‘’},e:1}
然而,由于存在“=”的赋值操作,实际上期望得到的数据结构仅仅是:
{a:{d:‘’}}
换言之,上述模板文件中只需要提供a和d的数据;其中,b、c都只是作为中间值的形式参数,不需要具体的数据,而e已经被赋值为1。
为了能够对模板文件进行有效处理,使得计算机可以自动、正确地提取出模板文件的数据结构,本申请提出了相应的提取模板文件数据结构的技术方案。为对本申请进行进一步说明,提供下列实施例:
请参考图1,图1是根据本申请一示例性实施例的一种提取模板文件数据结构的方法的流程图,可以包括以下步骤:
步骤102,生成与模板文件对应的抽象语法树。
在本实施例中,通过生成模板文件对应的抽象语法树,可以表现出模板文件的抽象语法结构,以便于为数据相关节点生成对应的初始数据结构。
在本实施例中,并不限制抽象语法树的生成过程和方式。比如作为一示例性实施方式,可以依次对模板文件执行词法分析和语法分析,即可生成对应的抽象语法树。
步骤104,提取所述抽象语法树中的数据相关节点,根据所述数据相关节点的内容以及该内容的状态属性,生成对应的初始数据结构,并将所述初始数据结构添加至初始数据结构集。
在本实施例中,数据相关节点即与数据参数相关的节点。通过获取数据相关节点的内容的状态属性(即该内容指向的目标),可以根据状态属性的不同,采取不同的处理方式。
作为一示例性实施方式,当所述数据相关节点的内容的状态属性为指向一个宏调用时,为对应的宏定义中的形式参数和实际参数分别生成对应的初始数据结构;或者,当所述数据相关节点的内容的状态属性为指向一个未确定为不会继续处理的左值且该数据相关节点的类型为for语句时,为该for语句的左值参数和右值数组参数分别生成对应的初始数据结构。
作为另一示例性实施方式,当数据相关节点的内容的状态属性为指向未确定为不会继续处理的左值且该数据相关节点的类型为非for语句,或者所述数据相关节点的内容的状态属性为其他类型时,需要判断所述初始数据结构集中是否已存在对应的初始数据结构,并根据判断结果来确定如何处理。
其中,当判断结果为不存在时,可以直接生成相应的初始数据结构;当判断结果为存在时,如果相应的数据相关节点的内容的状态属性为指向一个左值参数、方法或值类型确定的变量,且所述数据相关节点的内容与已存在的初始数据结构对应的状态属性类型不同,则根据所述数据相关节点的内容更新已存在的初始数据结构,并将原本已存在的初始数据结构记录为对应的原信息。
步骤106,根据所述初始数据结构对应的状态属性,对所述初始数据结构集中的初始数据结构进行调整,得到对应于所述模板文件的数据结构集。
在本实施例中,根据初始数据结构(即相应的数据相关节点的内容)对应的状态属性,需要采用不同的调整方式,以筛除不需要或表达错误的初始数据结构,得到真正对应于模板文件的数据结构。
作为一示例性实施方式,当数据相关节点的内容的状态属性为指向一个宏调用,或者为一个未确定为不会继续处理的左值且该数据相关节点的类型为for语句时,通过对相应语句的语义分析,可以确定所有数值参数之间的数值关系,并通过对数值参数内的形式参数、左值参数的替换,可以消除形参、左值的干扰,然后移除形式参数、左值参数对应的初始数据结构,以及指向非变量或方法的初始数据结构。
作为另一示例性实施方式,当数据相关节点的内容的状态属性为指向未确定为不会继续处理的左值参数且该数据相关节点的类型为非for语句,或者所述数据相关节点的内容的状态属性为其他类型时,如果存在记录的原信息,应当首先将相应的初始数据结构按照该原信息进行恢复,然后移除状态属性为指向非变量或方法的初始数据结构。
由上述实施例可知,在本申请的技术方案中,通过为模板文件生成对应的抽象语法树以及确定数据相关节点的内容的状态属性,可以使得初始数据结构的生成过程具有针对性,并且能够根据不同情况采取对应的的方式进行处理。同时,通过对初始数据结构集的调整,可以筛除不需要或表达错误的初始数据结构,得到真正对应于模板文件的数据结构。
请参考图2,图2是根据本申请一示例性实施例的另一种提取模板文件数据结构的方法的流程图,可以包括以下步骤:
步骤202,获取需要提取数据结构的模板文件,对该模板文件进行词法分析处理,生成对应的词法流。
步骤204,对词法流进行语法分析,生成对应的抽象语法树。
步骤206,对抽象语法树中的每个节点进行处理,具体可以通过下述操作实现:
步骤206A,判断是否存在尚未处理的剩余节点,若存在则转入步骤206B,否则转入步骤208。
在本实施例中,可以采用自底向上(或者其他顺序)的方式,依次对抽象语法树中的每个节点执行处理。
步骤206B,判断当前节点是否为数据相关节点,若是则转入步骤206C,否则返回步骤206A。
步骤206C,确定数据相关节点的内容指向的目标类型,并记录为对应的状态属性。
在本实施例中,所有可能的状态属性如表1所示。
状态属性 |
指向的目标类型 |
MACRO_CALL |
宏调用 |
left |
未确定为不会继续处理的左值 |
BREAK |
不会继续处理的左值 |
UNCERTAIN |
值类型未定的变量 |
CERTAIN |
值类型确定的变量 |
CERTAIN_FUNC |
方法 |
表1
步骤206D,根据数据相关节点的内容,生成对应的初始数据结构。
在本实施例中,作为一示例性实施方式,状态属性可以直接记录于对应的初始数据结构中,则初始数据结构中包括:数据参数、该数据参数的值、状态属性等信息。
步骤208,得到初始数据结构集。
在本实施例中,初始数据结构集即所有初始数据结构的集合,比如对应于当前需要处理的模板文件的所有初始数据结构。
步骤210,调整初始数据结构集。
在本实施例中,虽然采用步骤208-步骤210的描述方式,但并不需要将所有初始数据结构均生成并添加至初始数据结构集中之后,才对初始数据结构集进行调整;实际上,在初始数据结构生成之后的任意时刻,均可以根据实际需要进行调整。
步骤212,得到调整后的初始数据结构集,即对应于当前处理的模板文件的数据结构集。
其中,对于步骤206D-步骤210,需要针对步骤206C中确定的状态属性的不同,采取不同的处理方式,下面将分别进行详细描述。
如图3所示,步骤302为图2中步骤206B的后续处理流程,获取当前数据相关节点,并根据该数据相关节点的内容指向的目标类型,转入不同的处理分支。
1)状态属性为MACRO_CALL
假定模板文件为:
{%macrom(a)%}{{a.b}}{{c}}{%endmacro%}
{{m(d)}}
其中,当分析完第1行代码时,其表示对宏m的定义;当分析完第2行代码时,确定为宏调用,因而转入步骤304处理。
步骤304,判定当前数据相关节点的内容指向的目标为宏调用,则相应的状态属性为MACRO_CALL。
步骤306,获取调用的宏的定义。
在本实施例中,宏m的定义即第1行代码“{%macrom(a)%}{{a.b}}{{c}}{%endmacro%}”,表示一个“接收一个形式参数a,内容为{{a.b}}{{c}}”的宏。
步骤308,为相关的数据参数生成初始数据结构,即为宏的定义中的形式参数和实际参数生成初始数据结构。
在本实施例中,首先对形参a和实参d生成相应的初始数据结构为:
其中,“__stats”表示状态属性,而“__value”表示参数的值。
步骤310,对宏定义的内容进行语义分析。
在本实施例中,在语义分析的开始,需要首先记录形参a的信息,比如形参a的名称、形参a指向的实参为d等信息,然后对宏的定义和内容进行语义分析。
经过语义分析得知:对于宏的内容中的打印变量{{a.b}}和{{c}},{{a.b}}中包含有形参a,而{{c}}与形参无关。然后,对于{{a.b}}需要将形参a替换为实参d,即{{a.b}}实际上即{{d.b}};而{{c}}即其自身。那么,需要相应的初始数据结构进行调整,则初始数据结构更新为:
在本实施例中,通过语义分析处理可以获知各个数据参数之间的数值关系,从而可以对初始数据结构进行正确理解,并修正对应的描述语句。
步骤312,识别并删除形式参数(即“形参”)对应的初始数据结构。
在本实施例中,基于更新后的初始数据结构,根据事先记录的形参信息,删除形参a对应的初始数据结构,则更新后的初始数据结构为:
2)状态属性为LEFT且节点类型为for语句
假定模板文件为:
{%foriteminitems%}{{item.name}}:{{item.price}}{%endfor%}
在分析完上述代码后,确定其为for语句,因而转入步骤314处理。
步骤314,判定当前数据相关节点的内容的状态属性为指向可能继续处理的左值参数,则相应的状态属性为LEFT;同时,该节点对应于for语句。
步骤316,为相关的数据参数生成初始数据结构,即为for语句中的左值参数和右值数组参数生成初始数据结构。
在本实施例中,基于for语句涉及到的item和items,相应生成的初始数据结构为:
其中,items是一个值类型为数组的变量,状态属性记录为CERTAIN,而该数组包含的子元素的状态属性记录为UNCERTAIN;同时,item的状态属性记录为LEFT,且指向items中的首个子元素items[0]。
步骤318,对for语句的内容进行语义分析。
在本实施例中,在语义分析的开始,需要首先记录左值参数item的信息,比如左值参数item的名称、左值参数item指向的右值数组参数为items等信息,然后对for语句的其他内容进行语义分析。
经过语义分析得知:对于for语句中的变量{{item.name}}和{{item.price}},由于均包含左值参数item,需要将左值参数item替换为右值数组参数中的首个子元素item[0],所以模板文件中真正用到的变量为{{item[0].name}}和{{item[0].price}},则需要初始数据结构进行调整,则初始数据结构更新为:
在本实施例中,通过语义分析处理可以获知各个数据参数之间的数值关系,从而可以对初始数据结构进行正确理解,并修正对应的描述语句。
步骤320,识别并移除左值对应的初始数据结构。
在本实施例中,基于更新后的初始数据结构,根据事先记录的左值参数信息,删除item对应的初始数据结构,则更新后的初始数据结构为:
步骤322,基于步骤312或步骤320之后的处理过程,对初始数据结构执行进一步处理:移除状态属性不为UNCERTAIN、CERTAIN或CERTAIN_FUNC的初始数据结构。
在本实施例中,实际上是对状态属性为MACRO_CALL、LEFT、BREAK的初始状态数据进行移除处理;若未将状态数据直接记录在初始数据结构中,则剩下的即为对应于模板文件的数据结构。
步骤324,若通过将状态数据直接记录在初始数据结构中的形式,需要对剩余的初始数据结构中状态属性进行移除,从而得到对应于模板文件的数据结构。
3)其他情况
如图4所示,图4是根据本申请一示例性实施例的一种提取模板文件数据结构的方法的流程图,包括以下步骤:
步骤402,获取当前数据相关节点。
步骤404,判断是否已存在对应的初始数据结构,若存在则装入步骤408,否则转入步骤406。
步骤406,根据当前数据相关节点的内容,直接生成对应的初始数据结构。
步骤408,判断是否满足:状态数据为UNCERTAIN,或与已存在的初始数据结构的状态属性一致,若满足则转入步骤410,否则转入步骤412。
步骤410,不处理。
步骤412,生成初始数据结构,并对已存在的初始数据结构进行记录,比如将其记录为相应数据参数的原信息。
在本实施例中,假定模板文件为:
{{a}}
{%seta=b%}
{{a.c}}
其中,假定开始分析前,初始数据结构为空,即intermediateData={}。
在分析完第1行代码时,由于a的状态属性为UNCERTAIN且没有已存在的初始数据结构,因而生成对应的初始数据结构(对应于步骤406):
intermediateData={
a:{__stats:UNCERTAIN,__value:‘’}
}
在分析完第2行代码时,变量a的状态属性变为LEFT;由于已经存在对应于第1行的a的初始数据结构且状态属性不同(分别为UNCERTAIN和LEFT),因而需要转入步骤412,则更新后的初始数据结构为:
其中,“__origin”表示对应于已存在的初始数据结构的原信息,即开始时为数据参数a生成的初始数据结构。
在分析第3行代码时,由于在分析第2行代码后对a的初始数据结构进行了修改,因而可以确定{{a.c}}实际上是{{b.c}},因而需要对初始数据结构进行更新为:
其中,通过上述3行代码的解析结构可知:本申请中对于数据相关节点的处理实际上是递归的,即每个节点的处理可能依托于其他节点的处理结果,从而确保了解所有的数据转换状况。
针对已生成的初始数据结构,需要执行下述调整:
步骤414,恢复所有初始数据结构的记录值,即步骤412中记录的原信息。
在本实施例中,比如对于上述实施例的初始数据结构:
通过对数据参数a的原信息的恢复,可以得到恢复后的初始数据结构为:
步骤416,移除状态属性不为UNCERTAIN、CERTAIN或CERTAIN_FUNC的初始数据结构。
在本实施例中,实际上是对状态属性为MACRO_CALL、LEFT、BREAK的初始状态数据进行移除处理;若未将状态数据直接记录在初始数据结构中,则剩下的即为对应于模板文件的数据结构。
在本实施例中,对于上述实施例:
{{a}}
{%seta=b%}
{{a.c}}
根据第1行代码可知,变量a是一个有效数据,需要在最终数据中得以保留;然而,在步骤412之后,a的状态属性被记录为“LEFT”,属于步骤416中需要被移除的类型。因此,正是通过将a最初的状态属性“UNCERTAIN”记录在原信息中,以及在步骤414中恢复记录的原信息,从而避免了对a对应的初始数据结构的误删除。
步骤418,若通过将状态数据直接记录在初始数据结构中的形式,需要对剩余的初始数据结构中状态属性进行移除,从而得到对应于模板文件的数据结构。
此外,在上述各实施例中,初始数据结构中的值均采用默认值;或者,还可以获取对应于当前需要处理的模板文件的初始业务数据,该初始业务数据可以为已完成开发的相关模板文件的输出数据、后端提供的部分业务数据等;应当理解的是,此处的初始业务数据应当是已经验证为正确的业务数据。因此,可以预先生成对应于初始业务数据的初始数据结构,并添加至初始数据结构集中,则可能获得优于默认值的处理效果。
图5示出了根据本申请的一示例性实施例的电子设备的示意结构图。请参考图5,在硬件层面,该电子设备包括处理器、内部总线、网络接口、内存以及非易失性存储器,当然还可能包括其他业务所需要的硬件。处理器从非易失性存储器中读取对应的计算机程序到内存中然后运行,在逻辑层面上形成提取模板文件数据结构的装置。当然,除了软件实现方式之外,本申请并不排除其他实现方式,比如逻辑器件抑或软硬件结合的方式等等,也就是说以下处理流程的执行主体并不限定于各个逻辑单元,也可以是硬件或逻辑器件。
请参考图6,在软件实施方式中,该提取模板文件数据结构的装置可以包括语法树生成单元、初始数据结构生成单元和初始数据结构调整单元。其中:
语法树生成单元,生成与模板文件对应的抽象语法树;
初始数据结构生成单元,提取所述抽象语法树中的数据相关节点,根据所述数据相关节点的内容以及该内容的状态属性,生成对应的初始数据结构,并将所述初始数据结构添加至初始数据结构集;
初始数据结构调整单元,根据所述初始数据结构对应的状态属性,对所述初始数据结构集中的初始数据结构进行调整,得到对应于所述模板文件的数据结构集。
可选的,所述初始数据结构生成单元用于:
当所述数据相关节点的内容的状态属性为指向一个宏调用时,为对应的宏定义中的形式参数和实际参数分别生成对应的初始数据结构。
可选的,还包括:
第一关系确定单元,当所述数据相关节点的内容的状态属性为指向一个宏调用时,记录对应的宏定义中的形式参数,并对所述数据相关节点的内容进行语义分析,以确定对应的所有数据参数之间的数值关系;
第一参数处理单元,根据所述数值关系,判断对应的宏内容中的每个数据参数是否包含所述形式参数,若包含则将所述形式参数替换为对应的实际参数,并生成对应的初始数据结构,否则直接生成对应的初始数据结构;
第一删除单元,删除所述形式参数对应的初始数据结构。
可选的,所述初始数据结构生成单元用于:
当所述数据相关节点的内容的状态属性为指向一个未确定为不会继续处理的左值且该数据相关节点的类型为for语句时,为该for语句的左值参数和右值数组参数分别生成对应的初始数据结构。
可选的,还包括:
第二关系确定单元,当所述数据相关节点的内容的状态属性为指向一个未确定为不会继续处理的左值且该数据相关节点的类型为for语句时,记录该for语句中的左值,并对所述数据相关节点的内容进行语义分析,以确定对应的所有数据参数之间的数值关系;
第二参数处理单元,根据所述数值关系,判断对应的宏内容中的每个数据参数是否包含所述左值参数,若包含则将所述左值参数替换为对应的右值数组参数的首个子元素,并生成对应的初始数据结构,否则直接生成对应的初始数据结构;
第二删除单元,删除所述左值参数对应的初始数据结构。
可选的,所述初始数据结构调整单元用于:
在所述初始数据结构集中,移除对应的状态属性为指向非变量或方法的初始数据结构。
可选的,所述初始数据结构生成单元用于:
当所述数据相关节点的内容的状态属性为指向未确定为不会继续处理的左值且该数据相关节点的类型为非for语句,或者所述数据相关节点的内容的状态属性为其他类型时,判断所述初始数据结构集中是否已存在对应的初始数据结构;
若不存在,则根据所述数据相关节点的内容生成相应的初始数据结构;
若存在,则在所述数据相关节点的内容的状态属性为指向一个左值参数、方法或值类型确定的变量,且所述数据相关节点的内容与已存在的初始数据结构对应的状态属性类型不同的情况下,根据所述数据相关节点的内容更新所述已存在的初始数据结构,并将所述已存在的初始数据结构记录为对应的原信息。
可选的,所述初始数据结构调整单元用于:
通过所述原信息恢复相应的数据相关节点的初始数据结构;
在完成所述恢复的初始数据结构集中,移除对应的状态属性为指向非变量或方法的初始数据结构。
可选的,还包括:
数据获取单元,获取对应于所述模板文件的初始业务数据;
添加单元,生成对应于所述初始业务数据的初始数据结构,并添加至所述初始数据结构集中。
因此,本申请通过生成模板文件对应的抽象语法树,可以表现出模板文件的抽象语法结构,以便于为数据相关节点生成对应的初始数据结构;同时,通过获取数据相关节点的内容的状态属性,可以了解相应的数据参数的功能和作用,从而据此对初始数据结构进行调整后,可以筛除不需要或表达错误的初始数据结构,得到真正对应于模板文件的数据结构。
在一个典型的配置中,电子设备包括一个或多个处理器(CPU)、输入/输出接口、网络接口和内存。
内存可能包括计算机可读介质中的非永久性存储器,随机存取存储器(RAM)和/或非易失性内存等形式,如只读存储器(ROM)或闪存(flashRAM)。内存是计算机可读介质的示例。
计算机可读介质包括永久性和非永久性、可移动和非可移动媒体可以由任何方法或技术来实现信息存储。信息可以是计算机可读指令、数据结构、程序的模块或其他数据。计算机的存储介质的例子包括,但不限于相变内存(PRAM)、静态随机存取存储器(SRAM)、动态随机存取存储器(DRAM)、其他类型的随机存取存储器(RAM)、只读存储器(ROM)、电可擦除可编程只读存储器(EEPROM)、快闪记忆体或其他内存技术、只读光盘只读存储器(CD-ROM)、数字多功能光盘(DVD)或其他光学存储、磁盒式磁带,磁带磁磁盘存储或其他磁性存储设备或任何其他非传输介质,可用于存储可以被计算设备访问的信息。按照本文中的界定,计算机可读介质不包括暂存电脑可读媒体(transitorymedia),如调制的数据信号和载波。
还需要说明的是,术语“包括”、“包含”或者其任何其他变体意在涵盖非排他性的包含,从而使得包括一系列要素的过程、方法、商品或者设备不仅包括那些要素,而且还包括没有明确列出的其他要素,或者是还包括为这种过程、方法、商品或者设备所固有的要素。在没有更多限制的情况下,由语句“包括一个……”限定的要素,并不排除在包括所述要素的过程、方法、商品或者设备中还存在另外的相同要素。
以上所述仅为本申请的较佳实施例而已,并不用以限制本申请,凡在本申请的精神和原则之内,所做的任何修改、等同替换、改进等,均应包含在本申请保护的范围之内。