技术领域 本发明涉及计算机语言编译、解释、执行方法,特别涉及脚本语言的自 动机方法。 背景技术 计算机的运行都是按照计算机语言编写成的计算机程序进行的。计算机 语言的种类非常的多,可以分成机器语言,汇编语言,高级语言三大类。计 算机所能识别的语言只有机器语言,即由0和1构成的代码。但通常人们编 程时,不采用机器语言,因为它非常难于记忆和识别。汇编语言的实质和机 器语言是相同的,都是直接对硬件操作,只不过指令采用了英文缩写的标识 符,更容易识别和记忆。它同样需要编程者将每一步具体的操作用命令的形 式写出来。汇编程序的每一句指令只能对应实际操作过程中的一个很细微的 动作,例如移动、自增,因此汇编源程序一般比较冗长、复杂、容易出错, 而且使用汇编语言编程需要有更多的计算机专业知识。由于高级语言的简单 直观易于理解等优点,是目前绝大多数编程者的选择。 高级语言包括: 解释类:应用程序源代码一边由相应语言的解释器“翻译”成目标代码 (机器语言),一边执行,因此效率比较低,而且不能生成可独立执行ssss的 可执行文件,应用程序不能脱离其解释器,但这种方式比较灵活,可以动态 地调整、修改应用程序。由于解释类的灵活、平台无关等特点,当前Java等 解释类语言日渐显得重要。 编译类:在应用源程序执行之前,就将程序源代码“翻译”成目标代码 (机器语言),因此其目标程序可以脱离其语言环境独立执行,使用比较方便、 效率较高。但应用程序一旦需要修改,必须先修改源代码,再重新编译生成 新的目标文件才能执行,只有目标文件而没有源代码,修改很不方便。大多 数的编程语言都是编译型的,例如C/C++、Pascal等。 计算机语言在当前软件开发、计算机辅助工程等领域已经得到长足发 展,各类语言非常成熟。但在很多工程技术开发的独特领域,由于需求特殊, 采用通用的计算机语言进行编程开发显得过于复杂而且不够灵活。比如,在 移动通信网络维护中,经常要对底层网络消息进行反向解析,以监测网络运 行状况或进行故障定位,由于消息格式的不同,对不同消息应采用计算机程 序进行解析,这样可以大大提高效率,而若采用通用计算机语言,将会导致 开发周期长,移植不方便,修改麻烦等缺点。因此在很多小领域,尤其是有 特殊需求的地方,急切需要简单的、能定制的、可移植的专用编程工具的出 现。 脚本语言也属于计算机高级语言的一种,一般都是应用于特殊领域,具 有语法简单、功能强大、编写方便等特点。而自动机则是能编译并解释执行 脚本语言的程序实体。编译器由词法分析->语法分析->中间语言代码生成-> 机器语言代码生成等步骤完成功能,最终的输出是硬件可直接执行的机器指 令。而解释器则是直接执行语言代码。 现有的计算机语言编译器或解释器都是通过复杂的步骤实现的。传统的 编译器由词法分析->语法分析->中间语言代码生成->机器语言代码生成等步 骤完成功能,最终的输出是硬件可直接执行的机器指令。而传统的解释器则 是直接对语言进行解释并动态执行,动态分配变量空间,采用一套复杂的解 释系统来进行对语言解释过程的管理,耗用资源大,而且解释系统开发任务 量大。对于特殊领域工程开发专用的脚本语言,如果采用编译运行方法,则 显得不够灵活,如果采用解释运行方法,则所需成本高。 另外一种方法是直接对每个应用编制专门的代码来操作,这样必须对每 个问题编制专门的代码。由于软件代码强烈依赖于处理对象,处理对象的变 化,将直接导致软件的升级。而且软件代码冗余,软件代码量大,使维护工 作量很大,成本提高。另外,变化无常的软件代码还不得不依赖于具体的系 统及硬件环境,不利于移植。 在实际应用中,上述方案存在以下问题:耗用资源大,成本高;不够灵 活,可移植性不够强;代码冗余,开发效率低。 造成这种情况的主要原因在于,若采用传统的编译器或者解释器来实现 对脚本语言的编译或解释执行,都将需要耗费巨大的人力、物力资源来开发 编译器、解释器系统,而且编译器的灵活性不够强,解释器运行起来会耗费 大量硬件资源;若直接对具体的应用编制专用的代码,则代码缺乏通用性, 而且开发效率低。 发明内容 有鉴于此,本发明的主要目的在于提供一种脚本语言的自动机方法,使 得脚本语言的编译解释运行过程简单高效,降低软件开发成本,使得编译解 释自动机具有通用性、可移植性、可嵌入性的特点。 为实现上述目的,本发明提供了一种脚本语言的自动机方法,包含以下 步骤, A根据工程应用需要,制定脚本语言规范,用于规定脚本语言的语法规 则; B根据所述脚本语言规范,制定中间语言规范,用于规定从所述脚本语 言到中间语言的转换规则; C根据所述中间语言规范,将脚本语言代码编译转换为中间语言代码, 所述中间语言代码用于描述脚本语言代码的数据关系和执行关系; D解释运行所述中间语言代码。 其中,根据所述步骤B制定的所述中间语言规范,所述中间语言代码由 数据结构描述,包含头部、数据区、程序区,其中, 所述头部用于描述所述脚本语言代码的整体信息,所述数据区用于描述 所述脚本语言代码所需要的参数信息,所述程序区用于描述所述脚本语言代 码的语句执行信息。 此外,所述数据区由参数结构构成,每个所述参数结构用于描述对应参 数的相关信息,包含参数类型、常量的值、变量的地址、串的首地址。 此外,所述程序区由执行结构构成,每个所述执行结构用于描述对应语 句的相关信息,包含语句类型、下一条执行语句的索引、关联参数的索引、 关联语句的索引。 此外,所述步骤C包含以下子步骤, C1对所述脚本语言代码进行词法分析; C2对所述脚本语言代码进行语法分析; C3根据所述中间语言规范,生成所述中间语言代码。 此外,根据所述步骤A制定的所述脚本语言规范,所述脚本语言代码中 各单词由分隔字符分隔,所述步骤C1的词法分析过程包含以下子步骤:提 取当前语句的保留字;根据所述保留字判断语句类型;根据所述语句类型提 取关联参数。 此外,所述步骤C2的语法分析过程包含以下子步骤, 对于简单语句,根据所述脚本语言规范检查该语句的关联参数的个数、 类型; 对于复合语句,根据所述脚本语言规范检查该语句的关联参数的个数、 类型,检查所述程序结构块层次配对关系、语句配对关系。 此外,所述步骤C3包含以下子步骤, 在所述数据区为每个参数分配所述参数结构,并填充所述常量的值、变 量的地址、或串的首地址; 在所述程序区为每条语句分配所述执行结构,并填充所述语句类型、所 述关联参数的索引; 对于所述简单语句,按照执行顺序填充所述下一条执行语句的索引; 对于所述复合语句,解析程序结构,填充所述下一条执行语句的索引和 所述关联语句的索引。 此外,所述步骤C3的程序结构分析中,采用压栈、链表实现所述复合 语句的关联回溯。 此外,所述步骤C3中,将所述变量分配在虚拟临时变量空间中,在解 释执行时,根据所述变量在所述虚拟临时变量空间中的偏移值,在实际的临 时变量空间中分配。 此外,所述步骤D包含以下子步骤, D1根据所述程序区中当前执行结构,确定操作类型; D2根据所述关联参数的索引获得所述数据区中所述参数结构的信息; D3根据参数信息执行相应的操作; D4根据所述执行结构的执行关系信息确定下一执行结构。 此外,所述步骤D中,所述执行结构独立执行,另设置公共进程控制块, 用于保存执行上下文环境,在所述执行结构之间传递信息。 此外,编制脚本语言自动机代码嵌入工程应用中,用于提供脚本语言解 释运行功能。 此外,所述脚本语言应用于二进制消息块的反向解析。 通过比较可以发现,本发明的技术方案与现有技术的主要区别在于,针 对具体的工程应用需求,制定了简单的脚本语言规范;同时,制定了采用数 据结构表示的中间语言规范,使得该中间语言代码易于编译器转换,也易于 解释器执行;脚本语言自动机首先由编译器将脚本语言代码全部转化为中间 语言代码,然后再由解释器解释运行,通过中间语言代码综合利用了编译和 解释的优点,简化了脚本语言自动机方法;另外,还将高级语言编写的脚本 语言自动机嵌入到工程应用中,不但实现脚本语言定制功能,而且具有平台 无关特性。 这种技术方案上的区别,带来了较为明显的有益效果,即简单专用的脚 本语言规范不但满足了应用需求,而且简化了脚本语言自动机的实现,大大 降低实现复杂度;高效的中间语言规范适合于编译转换和解释执行,同时简 化了编译步骤和解释步骤,降低资源耗用和实现成本;先编译后解释的方法 实现了脚本语言自动机方法,避免了传统编译器的复杂和解释系统的庞大, 简单高效的实现了脚本语言的定制和执行;脚本语言自动机的可移植性和平 台无关性大大降低了代码开发成本,克服软件冗余性,提高软件质量。 附图说明 图1是根据本发明的一个实施例的脚本语言的自动机方法流程图; 图2是根据本发明的一个实施例的中间语言代码参数区结构示意图; 图3是根据本发明的一个实施例的中间语言代码程序区结构示意图。 具体实施方式 为使本发明的目的、技术方案和优点更加清楚,下面将结合附图对本发 明作进一步地详细描述。 本发明采用编译器加解释器的方法实现脚本自动机,综合了编译、解释 两者的优点,使得脚本语言自动机即具有高效、灵活的特点,又具有通用性 和可移植性。 首先,对自定义的简单脚本语言进行分析,比如语法分析和词法分析, 得到各类语句的运行结构;然后由编译器将脚本语言进行编译,即将脚本语 言代码转换成中间语言代码,中间语言代码是通过若干种不同数据结构类型 的变量的内存表实现的,编译器构建了这些内存表,供解释器解释运行;经 过编译的中间语言代码已经具备简单直观的数据结构、以及直接的语言运行 结构,解释器只需简单地对相应的内存区完成相应的操作,并按照相应的顺 序完成跳转即可,因此解释系统非常简单,大大降低资源利用率和开发任务 量。 其中,中间语言代码的构造是本发明的关键,对于运行中的移动脚本语 言,采用头部标识、数据区和程序区来分别实现程序信息、变量空间、程序 结构的存储,按照一定的规则将各变量安排在数据区中,而语句的操作类型 及跳转关系等信息则存放于程序区中。这样的中间语言代码结构,不但可以 简化解释系统的复杂度,降低解释维护的任务量,而且可以简化编译步骤。 所述,实现脚本语言的自动机方法首先需要有脚本语言和中间语言的规 范,然后进行语言分析、转化、运行。在本发明的一个实施例中,自动机方 法包含四个大步骤,其流程图如图1所示。 步骤101,根据工程应用需要,制定脚本语言规范,用于规定脚本语言 的语法规则。为了实现脚本语言的自动机,必须规定统一的脚本语言,以方 便之后的语言分析、中间语言规范的设计等。在本流程中,可以直接利用现 有的各种脚本语言,这样对于用户上手较为方便;也可以另外设计更加合适 具体工程应用需求的新的脚本语音的规范,这样则对于具体应用较为合适。 步骤102,根据该脚本语言规范,制定中间语言规范,用于规定从该脚 本语言到中间语言的转换规则。由于本发明是采用先转化到中间语音的方法, 因此必须根据脚本语言规范制定中间语言规范。中间语言规范包括具体实施 或者运行时各种数据结构、代码结构的设置和处理方法,是本发明的关键。 步骤103,根据该中间语言规范,将脚本语言代码编译转换为中间语言 代码,该中间语言代码用于描述该脚本语言代码的数据关系和执行关系。根 据脚本语言规范和中间语言规范,即可实现从脚本语言到中间语音的分析和 转化。 步骤104,解释运行该中间语言代码。由于本发明的中间语音代码已经 包含各种数据结构为便于描述,首先给出本发明的一个实施例中的脚本语言 规范,并基于此脚本语言给出相应的脚本语言自动机的实施例。该脚本语言 专门用于对二进制消息的反向解析,即将包含有意义内容的二进制消息块翻 译成具有相同含义内容的字符串的表现形式,以方便用户阅读。 脚本语言具有计算机语言的最低基本要求的三种语句:顺序执行语句、 条件判断语句、循环语句。在本发明的一个实施例中,用于消息反向解析的 的脚本语言定义如下(″内的符号为程序语言保留字或保留符号): 脚本语言程序基本框架为inverse语句,inverse语句的格式为:′inverse′ 常量′{′语句{语句}′}′,其中语句包含有以下几种:get语句|set语句|output 语句|skip语句|repeat语句|switch语句。所述各种语句的格式分别为: repeat语句:′repeat′变量名|常量变量名|常量′{′语句{语句}′}′,用 于实现循环结构; switch语句:′switch′变量名′{′case语句{case语句}default语句′}′, 用于实现分支结构; case语句:′case′常量′{′语句{语句}′}′,用于实现分支结构; default语句:′default″{′语句{语句}′}′,用于实现分支结构; get语句:′get′变量名值类型,按照内存地址读取变量的值; set语句:′set′变量名变量名|常量,设定变量并分配内存空间; output语句:′output′格式字符串{变量名},输出显示; skip语句:′skip′变量名|常量,跳过指定长度的消息串。 其中,上述输出语句中使用的“格式字符串”是用于定义输出格式的, 由″″{可见字符}{控制字符串}{可见字符}″″组成,其中控制字符串可以为 ′\r′\n′|′%x′|′%d′|′%c′|′%u′|′%o′,分别代表各种数据类型,定义与C语言相同, 上述“值类型”包含以下几种:U8′|′U16′|′U32′|′S8′|′S16′|′S32′,U代表无符号 数,S代表有符号数,后面的数字代表该变量所占位数,比如U16即长度为 两个字节的无符号数。所述“变量名”可以是由[_字母|字母]{字母|数字|_[字 母|数字]}组成。所述“常量“即:数字[{数字}.数字{数字}|{数字}]。字母 即:[a,z]|[A,Z],数字即:[0,9],可见字符即255个ASCII字符。 可见,这里所给出的用于消息反向解析的脚本语言规范是比较简单的, 仅仅包含了基本程序结构功能和一些能满足反向解析需求的特殊语句,这样 的脚本语言在工程开发的特殊领域中非常实用。 熟悉本领域的技术人员可以理解,在其他各种工程应用中,技术人员可 以根据具体应用需求而制定符合要求的高效、简单的脚本语音规范,既能满 足于用户编程,又能实现脚本语音自动机方法,不影响本发明的实质和范围。 在本发明的一个较佳实施例中,为便于后续的编译器编译,定义各个单 词,即编译意义上的单位,之间以回车换行符或者空格符分隔,这样即可大 大简化编译过程中词法分析步骤,大大提高编译效率。 为了进一步形象地说明该脚本语言在消息反向解析中的应用,下面给出 根据本发明的实施例的针对某种消息格式的消息反向解析脚本语言代码: inverse 0x12EF { skip 4 get ret U16 output"RETCODE=%u "ret switch ret { case 8 { output"非法参数。\r\n" } case 17 { output"单板未配置。\r\n" } default { output"\r\n" } } get len U8 set count 0 repeat len count { get temp S8 output"%c"temp } output"\r\n" } 如前所述,该段代码的主框架由inverse语句构成,inverse语句所带常 量为该段代码的标识。为了编译方便,代码中各个单词均由空格或回车换行 分隔。该段代码的主要功能即:将位于相对偏移量为4处的16位无符号数输 出,并赋给变量ret,然后根据ret的值进行分支,输出该值所代表的含义。 接着获取8位的无符号数赋给变量len,并进行以len为长度的循环结构,在 每次循环中输出下一个8位的有符号数。 由此如果所解析的二进制消息代码为: 0x12-34-FF-FF-FF-FF-00-08-0B-31-32-33-34-35-36-37-38-39-30-2E; 则该段代码经过自动机解释执行后得到的输出结果应当为: RETCODE=8非法参数。 1234567890 通过上述例子的说明,可以发现,脚本语言多用于编写为简单专用、功 能强大的代码,若采用通用计算机语言的编译或解释方法来实现脚本语言自 动机,显然效率不高,因此本发明先将脚本语言简单地编译为易于解释运行 的中间语言代码,然后由解释器简单地直序运行,即能完成脚本语言自动机 功能。 在本发明的另一个实施例中,根据脚本语言规范制定中间语言规范,由 包含各种数据结构的内存表构成,这些内存表是编译器根据脚本语言代码构 建的,直接表征了代码执行操作步骤,便于解释器解释运行。 下面先描述中间语言规范,一段用于二进制消息反向解析的脚本语言代 码所对应的中间语言的内存表结构为:头部、数据区、程序区。头部包含有: 二进制消息块的消息字,用于唯一标识一个二进制消息块;数据区包含参数 个数计数器,用以记录局部变量或静态全局变量的个数,以及所有变量的参 数结构;程序区包含语句个数计数器,用以记录程序区中该脚本所有语句的 条数,以及每句语句单元的执行结构。 在数据区中,存储有脚本语言代码所用到参数,各参数通过参数地址 wParaId唯一标识,参数地址即为参数存储空间在数据区中的相对地址,该 参数地址在程序区中将作为参数索引被引用,便于程序解释运行时读取参数。 图2示出了根据本发明的一个实施例的数据区结构示意图,数据区的各个参 数都相应包含有一个参数结构20,该数据结构20包含参数头部201、联合体 两部分,其中参数头部201信息包含参数类型、参数值类型等信息,参数类 型可以为常量、变量或格式串,参数值类型即为前述U8/U16/U32/S8/S16/S32; 联合体在各种参数类型情况下内容不同,对于常量即为有符号常量成员及无 符号常量成员的常量值202,对于变量则为该变量在临时变量空间中的地址 偏移,即变量地址203,对于格式串常量则为格式串常量在格式串静态全局 变量空间中的地址指针,即格式串首地址204。可见根据上述参数结构可以 使得解释器在解释运行时,根据参数地址访问到该参数在参数区的参数结构, 并从参数结构得到该参数的类型、值类型、地址等信息,从而获得该参数值。 程序区是一个静态全局空间,图3示出了根据本发明的一个实施例的程 序区结构意思图,对应每条脚本语言代码语句单元有一个执行结构30,用以 存放脚本语言代码的各条语句的全部信息。每条语句单元的信息包括基本信 息和相关信息:基本信息有语句类型301,下一条语句指针(pstNextFsm) 302,以及该语句所涉及的各参数的参数地址303,用于指向数据区的参数结 构20;相关信息在实现上各种类型语句不同,所以是也一个联合体,内容根 据各种不同类型的语句而不同,对于很多复合语句都包括关联语句的指针 304。 为了进一步说明中间语言代码的内存表结构组成,给出根据上述用于二 进制消息块反向解析的脚本语言规范,各种不同类型语句的执行结构中包含 的基本信息及相关信息用C语言数据结构形式表示如下: typedef struct INV_CLAUSE { U8 bFsmType; /*语句类型*/ struct INV_CLAUSE *pstNextFsm; /*下一条要执行的语句指针 */ union { struct { U16 wParaId; /*参数*/ }get; struct { U16 wParaId[2]; /*参数*/ }set; struct { U8 bParaNum; /*参数个数*/ U16 wMaxOutputLen; U16 wParaId[11]; /*参数*/ }output; struct { U16 wParaId; /*参数*/ }skip; struct { U16 wParaId[2]; /*参数*/ struct INV_CLAUSE *pstRepeatEndFsm;/*对应的循环结束 REPEAT_END语句*/ }repeat; struct { struct INV_CLAUSE *pstRepeatFsm; /*对应的循环开始 REPEAT语句*/ }repeat_end; struct { U16 wParaId; /*参数*/ }switcn_begin; struct { struct INV_FSM *pstNextCaseFsm;/*条件不成立时下一条要 执行的CASE或DEFAULT语句指针或SWITCH_END语句指针*/ U16 wParaId; /*参数*/ }case_begin; struct { struct INV_CLAUSE *pstNextCaseFsm; /*下一条要执行的 CASE语句指针或SWITCH_END语句指针*/ U16 wParaId; /*参数*/ }default_begin; }clause; }INVERSE_CLAUSE; 可见上述执行结构包含了语句类型、下一条语句指针、联合体,其中联 合体即为各种语句类型所需要的参数地址、参数个数等内容。比如,get语句 只需一个参数,因此联合体只包含一个参数地址,而output语句则包含格式 控制符、参数个数、各参数的参数地址等;而对于程序结构控制语句,比如 循环语句,则需要分为循环开始语句和循环结束语句两类,且需要包含相互 索引的指针以及计数器参数,使得循环结构可以实现。在这个实施例中,repeat 语句由repeat和repeat_end两条语句构成,其中repeat语句在循环开始处执 行,repeat_end在循环结尾处,repeat的联合体包含指向循环结束处语句的指 针和循环计数器参数地址,repeat_end的联合体包含指向循环开始处语句的 指针,由此,循环在执行时,从循环开始处先判断计数器计数是否结束,然 后顺序执行直到循环结束处,根据指针返回到循环开始处重新运行,这样便 可实现循环程序结构的解释运行。 在本发明的另一个实施例中,脚本语言自动机方法的编译步骤就是将脚 本语言代码的各条语句的相关信息解析并填入头部、数据区和程序区,其中 数据区填的是参数相关信息,程序区则为语句操作相关信息和程序结构信息, 这里程序结构信息需要编译器分析程序结构,并转化为各条执行语句单元以 及上下语句调整关系。编译的过程又是由词法分析、语法分析、中间语言生 成这三个子步骤同步工作而完成的。 其中,词法分析过程将脚本语言的字符串分析得到程序代码,在本发明 的一个较佳实施例中,由于采用的对每个编译意义上的单词进行了分隔,因 此词法分析只需简单的提取并判断保留字,然后根据保留字规则提取参数等 信息。 语法分析过程是根据语句的类型提取该语句的各个参数,并判断该语句 语法的正确性,对于简单语句(即没有涉及分支、循环结构的语句),只需 判断参数个数及类型等是否正确;对于复合语句(比如条件SWITCH、循环 REPEAT,及其嵌套),则还需要判断层次结构、配对语句,比如层次是根 据读取到的‘{’和‘}’判断的,switch语句的配对为case语句和default 语句。 中间语言生成过程是逐条处理各脚本语言语句,对每一条要处理的语句 为其在程序区中分配语句空间;对于读取到的变量参数,则在临时变量空间 分配其类型长度的空间,在参数区记录其位置指针,并在程序区相应语句的 参数信息中记录该变量参数在数据区中的位置标识wParaId;对于读取到的 常量,则在参数区中直接记录该常量值,并在程序区相应语句的参数信息中 记录该变量在数据区中的位置标识wParaId。 对于简单语句上述步骤即可完成中间语言生成过程,对于复合语句,还 需要处理关联语句信息,比如循环语句repeat需要对应的循环结束语句 repeat_end配对,填充相互索引的指针,而switch分支语句则需要配对的case、 default、switch_end语句。下面例举各种复杂的复合句的编译处理方法。 对循环REPEAT语句的编译是在处理循环语句体的结束符号’}’时进行 关联语句信息填充的,当依照‘{’和‘}’层次及配套关系读到循环语句块 的结束符’}’时,将当前结束语句的类型赋为REPEAT_END,将该循环结束 REPEAT_END语句的关联语句信息(比如循环开始语句指针pstRepeatFsm) 填充为回溯到的同一层次上的循环开始REPEAT语句的程序区位置,并将回 溯到的同一层次上的该循环开始REPEAT语句的关联语句信息(比如循环结 束语句指针pstRepeatEndFsm)填充为当前的循环结束REPEAT_END语句的 程序区位置。注意到,当循环有嵌套时,则同样地在得到循环结束符’}’时, 与离当前位置最近的循环开始语句的发生关联。 对条件SWITCH语句的编译是在处理条件语句体的结束’}’时进行关联 语句信息填充的,当依照‘{’和‘}’层次及配套关系读到条件语句块的结 束符’}’时,将回溯同层次上的CASE、DEFAULT、SWITCH语句:当回溯到 同层次上的该CASE、DEFAULT、SWITCH语句时,则将该结束语句的类型 分别赋为CASE_END、DEFAULT_END、SWITCH_END的相应类型,且当 回溯到同层次上的语句为SWITCH时,还需要在该SWITCH语句块中重新 回溯所有的CASE_END和DEFAULT_END语句,并将回溯到的这些 CASE_END和DEFAULT_END语句的下一条语句指针赋值为当前条件结束 SWITCH_END语句,并在该SWITCH语句块中重新回溯最后一条DEFAULT 语句(或无DEFAULT语句情况下的最后一条CASE语句),并将回溯到的 该DEFAULT语句(或无DEFAULT语句情况下的最后一条CASE语句)的 条件不满足时下一条要执行的语句指针(不是pstNextFsm而是 pstNextCaseFsm)赋值为当前条件结束SWITCH_END语句;在读取条件语 句块中的CASE或DEFAULT语句时,则需回溯到同于该CASE或DEFAULT 语句层次上的上一条CASE或DEFAULT语句,并将回溯到的该(上一条 CASE或DEFAULT)语句的条件不满足时下一要执行语句指针(不是 pstNextFsm而是pstNextCaseFsm)赋值为当前的CASE或DEFAULT语句。 而一般顺序执行语句的下一条要执行的语句指针均赋值为脚本语言代码位置 紧挨着的下一条语句所在的程序区位置。 从上述复合语句执行顺序关系编译方法中可见,在建议语句执行顺序 时,经常会对分支、循环语句的层次结束符号进行回溯操作,即由当前层次 结束符寻址对应层次起始符号。实现回溯的方法有很多种,比如利用压栈、 链表等操作实现。在本发明的一个较佳实施例中,为了实现回溯,在编译时 采用一个语句编译信息数据结构链表进行层次嵌套结构的记录,链表节点的 数据结构用C语言可表示如下: typedef struct INV_INIT_DATA { struct INV_INIT_DATA *pstPrev;/*上一条语句的语句编译信息数据 结构链表节点*/ struct INV_INIT_DATA *pstNext;/*下一条语句的语句编译信息数 据结构链表节点*/ U16 wIndex; /*本语句在本脚本语言代码中的 位置索引*/ U8 bCurrentLevel; /*本语句所在层次*/ INVERSE_CLAUSE *pstFsm; /*本语句的程序区位置指针*/ }INVERSE_INIT_DATA; 通过该链表进行层次分析同时,记录脚本语言代码语句的层次数,设置 初值为0,每进入一个起始符’{‘则层次数增一,每遇到一个’}’则层次数减一。 最终值应该与初值0一致,否则编译出错。 另外,在本发明的一个较佳实施例中,编译过程中对于变量参数并不进 行实际空间分配,而是在虚拟的临时变量空间(实际并不存在)中分配一个 位置的偏移值;在解释执行时,才根据编译时已分配好的各个变量参数的偏 移值,在实际的临时变量空间进行划分使用。 在由编译器完成编译步骤后,脚本语言代码即转化为中间语言代码,可 以得到程序运行的参数、运行顺序关系等信息,解释器将根据这些相关信息 将脚本语言代码解释运行。在本发明的一个实施例中,脚本语言自动机方法 的解释步骤中,解释器根据中间语言相关语句的顺序关系执行相应操作。比 如,解释器根据首语句指针开始按照每条语句的下一语句或关联语句指针的 顺序,依次执行各条语句对应的功能代码,对相应的参数进行操作。可见, 解释器的功能非常简单,耗用资源少,开发工作量少。解释器只需根据程序 区语句结构中语句类型进行相应操作,根据参数地址到数据区获得相应参数, 读取常量的值、或读取变量的值、或对变量进行相应操作,在条件判断语句 则进行相应的判断和跳转。 归纳起来,解释运行中间语言代码的过程大致上包含四个步骤:根据所 述程序区中当前执行结构,确定操作类型;根据所述关联参数的索引获得所 述数据区中所述参数结构的信息;根据参数信息执行相应的操作;根据所述 执行结构的执行关系信息确定下一执行结构。 下面详细给出根据本发明的一个实施例的解释器对上述二进制消息块 反向解析脚本语言各种语句所进行的解释运行操作。 GET语句功能,完成从输入的二进制消息当前位置处获取变量参数类型 字节数的数据到变量参数所指示的临时变量空间中存放,如果该变量参数首 次出现,则先为该变量参数在临时变量空间中分配空间; SET语句功能,对被赋值变量参数赋值为目标常量值或目标变量参数所 指示的临时变量空间中的存放值,如果被赋值变量参数首次出现,则先为其 在临时变量空间中分配空间,并将目标值赋值到该位置处存放; SKIP语句功能,将输入的二进制消息当前位置后移常量值或变量参数所 指示的临时变量空间中存放值的字节数; OUTPUT语句功能,将格式串参数所指示的格式串静态全局变量空间中 存放的格式串取出,并取出各个变量参数所指示的临时变量空间中的存放值, 按照格式串定义的格式输出各参数,比如可以直接调用C语言的库函数 printf()/sprintf()的功能,将信息打印出来; REPEAT语句功能,直接跳转到循环结束REPEAT_END语句的执行结 构; REPEAT_END语句功能,使循环计数变量参数所指示的临时变量空间 中的存放值增一,并与循环次数常量值或循环次数变量参数所指示的临时变 量空间中的存放值进行比较,如果小于等于循环次数,则跳转到循环开始处 的第一条语句,根据中间语言规范即repeat语句的下一条,否则跳转到其下 一条语句,根据中间语言规范即循环语句块之后的第一条语句; CASE、DEFAULT语句功能,直接跳转到下一条语句,根据中间语言规 范即CASE条件块内、DEFAULT语句块内的第一条语句; CASE_END、DEFAULT_END语句功能,直接跳转到下一条语句,根据 中间语言规范即SWITCH_END语句; SWITCH语句功能,从下一条语句开始遍历紧接着的语句直至 SWITCH_END语句,如果对于遍历到的DEFAULT语句,则直接跳转到该 DEFAULT语句,如果对于遍历到的CASE语句,且CASE条件满足,则直 接跳转到该CASE语句,如果对于遍历到的CASE语句,但CASE条件不满 足,则跳转到该CASE语句的关联语句,根据中间语言规范即下一CASE或 DEFAULT语句; SWITCH_END语句功能,直接跳转到下一条语句,根据中间语言规范 即条件语句块之后的第一条语句。 在本发明的一个较佳实施例中,解释器对脚本语言代码的解释执行是按 照下一条语句指针或关联语句指针指示的语句功能块顺序依次独立进行的, 另外采用了公共的进程控制块来保存解释器中语句执行上下文的环境,该进 程控制块在各条语句的功能块之间传递。比如,该进程控制块结构用C语言 可表示如下: typedef struct { U16 wScriptId; /*脚本ID*/ INVERSE_CLAUSE*fsm; /*当前执行的语句指针*/ VARIAL_DATA_STACK*pData; /*堆栈*/ U16 wInputCurrentPos; U16 wOutputCurrentPos; char *pbInput; char *pbOutput; U16 wMaxOutBufLen; U16 wMsgLen; }TRANSLATOR_PROCESS; 其中VARIAL_DATA_STACK为临时变量空间(堆栈),用C语言可表 示如下: typedef struct { U32 dwStackPoint; U8 abStack[INV_VARIAL_STACK_SIZE]; }VARIAL_DATA_STACK;/*临时变量空间(堆栈)*/ 根据上述对本发明的多个实施例的描述,实际上本发明给出的脚本语言 自动机方法由编译、解释两大步骤实现,编译步骤包含了词法分析、语法分 析、中间语言生成三个子步骤,解释步骤则根据中间语言代码进行解释执行, 在制定了脚本语言规范和中间语言规范后,脚本语言自动机首先将脚本语言 代码全部转化为中间语言代码,简化了解释器解释执行任务。 在本发明的一个实施例中,将编译器和解释器均用高级语言编写实现, 因此具有较强的可移植性,可嵌入到工程应用中,使其具有定制脚本语言并 执行的功能,从而大大提高了软件开发、工程开发的效率,而且该脚本语言 自动机不依赖于具体的系统环境及硬件,使得脚本语言具有平台无关特性。 熟悉本领域的技术人员可以理解,上述脚本语言规范、中间语言规范均 可以根据具体应用需求而制定合理的规范使得编译简单、解释方便,另外自 动机实现中的具体数据结构的实现方法也可以s采用其他方式实现,最终实 现发明目的,而不影响本发明的实质和范围。 虽然通过参照本发明的某些优选实施例,已经对本发明进行了图示和描 述,但本领域的普通技术人员应该明白,可以在形式上和细节上对其作各种 各样的改变,而不偏离所附权利要求书所限定的本发明的精神和范围。