📄 ats_proj.txt
字号:
end
2. 支持的数据类型. 支持三种数据类型: int, char, string. int型予 c语言中的定义是一样的即数字类型,是一个或一串数字; char是以一对单引号拜师的字符,如 'A' 表示字母A, 它只能表示一个字符或一个按键; string表示一个或一串字符串, 以一对双引号和在双引号之间的多个字符组成, 如: "haha".
3. 关于语句格式的说明
3.1 功能函数语句必须以';'结束, 如:
open("notepad.exe", 1000);
可以支持多行编辑功能如:
open("notepad.exe",
1000);
3.2 叁数之间必须以','隔开.
3.3 main, 子函数的定义不能';'结束, 即如果定义一个自定义函数, 叁数完后只能是: 空格, '//'(注释符), 空格+begin.
3.4 关于if then 的语法如下:
if <expression> then begin //注释
...
end
4. 保留字
main, function, if, goto, function, while, begin, then, end, return, call, int, char, string.
三. 词法部分的分析及编写
词法分析部分的工作相对简单, 它的主要工作是从ats script源文档中读入每一个单词, 放入一张单词表中, 同时检查出每一个单词的类型, 因此程式必须内建一张或多张类型表, 当读入一个单词时, 在类型表中查找其类型值, 填入单词表中。
1. 类型表的建立
可以将单词分为以下几类: 保留字 = 1; 数字常数 = 2; 字符常数 = 3; 功能函数名 = 4; 标号 = 5; 符号类型 = 6; 定义类型 = 7; 字符串常数 = 8; 其它类型 = 9; 注释类型=10;
保留字: main, function, if, goto, while, begin, then, end, return, call.
数字常数: 一个或多个数字的连续串;
字符常数: 一对单引号(0)或在单引号中的字符;
字符串常数: 一对双引号(NULL)或在双引号汇中的任意字符串;
功能函数名: 在功能函数定义INI文档中定义的名称.
标号: 用户在script文档中定义的标号.
符号类型: +, -, *, /, (, ), >, <, >=, <=, <>, ==, and, or, not
定义类型: int, char, string, function;
其它类型:处理上述类型以外的类型.
2. 词法分析的执行流程如下:
2.1 读入ats script源文档到内存.
2.2 从功能函数定义INI文档中读入所有定义的功能函数名.
2.3 读入一个单词, 放入单词表中.
2.4 在类型表中查找此单词的类型号, 写入单词表中.
2.5 ats script源文档是否结束, 如果没有结束则跳到2.3.
词法分析的一个任务就是: 去掉无用的字符串和单词, 如//后的所有单词和字符串, 而且, 对予程序的分析流程来说, //对分析流程没有大的贡献, 因此,将//也可以去掉.
四. 复杂语法的替换
程式在进行语句分析转化为伪代码时, 默认的语法只有最简单的语法说明, 一种结构: if goto结构, 因此要将while, if then 转化为if goto结构.如何转化成为下一步工作顺利进行的基础.
转化的基本算法:
1. 读入一个单词, 取得其类型号
2. 如果单词的类型号是1即为保留字时, 进行如下的处理
2.1 如果单词是if, 读单词直到是then , 然后将if expression then begin <body> end 结构的语句转化为如下的结构
if not expression goto label;
<body>;
:label
//下一条语句
将转化的语句分为单词填入单词表相应的地方,注意标号的定义, 不要将转化生成的标号予script中存在的标号重复.
2.2 如果单词是while, 则将while expression begin <body> end 的结构转化为如下的结构:
:label2
if not expression goto label1
<body>
goto label2
:label1
将转化的语句分为单词填入单词表相应的地方,注意标号的定义, 不要将转化生成的标号予script中存在的标号重复.
注意: 如果body中也有嵌套的while或if then结构,则必须采用相应的算法处理方法.
3. 如果单词表没有结束, 则跳入2.1, 否则结束.
五. 语法语句转化部分的分析及编写
此模块的主要功能是将已经预编译后产生的文件进行编译成伪代码.其主要工作是:将INI文件中定义的功能函数信息读入相应的数据结构中;然后从头开始进行分析,将合法的描述语句翻译成对应的伪代码;如果有错误,则将错误信息记录下来,最后将此过程产生的信息放入一个临时文件中,以便让下一个模块能调用.
1 从功能函数INI文档中读入每一个功能函数的信息是,在内存中的数据结构是:
struct FunctionInfo{
char* name;
int paramnumber;
parameterquery *parma;
FunctionInfo* next;
}
读入所有的函数定义信息后, 形成一个链表.
2 根据所得的功能函数的结构和单词表开始分析ATS script 源文档并生生成伪代码. 分析时如果有错误则进行错误处理,如果没有错误则将正确的语句翻译成对应的伪代码.具体的算法如下:
2.1 从atsconfig.ini中得到功能函数INI的目录及数目等.
2.2 从得到的目录下将所有定义的功能函数信息读入相应的链表中.
2.3 读入一个单词, 取得其类型号.
2.4 如果类型号等于3, 即为功能函数名, 扫描功能函数链表, 找到它的信息节点, 按定义的叁数个数, 每一个叁数的类型, 每一个叁数的缺省状态从单词表中读入单词.进行处理.
2.4.1 定义一个变量number = n //n=ini中定义的函数的叁数的个数
2.4.2 读入一个单词, 单词的类型予定义的类型相同则跳入2.4.3, 不是则的、跳到2.4.5.
2.4.3 将单词放入此函数的叁数队列中, number -- ;
2.4.4 number大于0 则跳到2.4.2, 否则结束2.4
2.4.5 检查定义中的缺省状态, 如果是缺省的, 则number -- , 将此单词予定义中的下一个叁数进行匹配, 如果成功则跳到2.4.3, 否则跳到2.4.6
2.4.6 进行出错处理, 跳到语句的结尾,结束2.4
2.5 如果类型号是1即保留字则做分类处理:
2.5.1 单词是if, if也是一种处理, 叁数只有一个expression, 生成相应的伪代码, 应用expression处理算法处理expression, 然后将结果指针填入if伪代码结构中对应的单元中, 接着处理下一个单词goto. 对待if的执行, 要而后其后的goto结合在一起来考虑处理.
2.5.2 如果单词是goto, 她为执行功能之一, 将其后的标号填入对应的伪代码单元中.
2.5.3 如果单词是begin, 直接挑过.
2.5.4 如果是end , 判断是子函数, 还是主函数结束, 做相应的处理.
2.6 如果是符号类型, 因为符号也是执行函数之一, 因此把它当做函数来处理, 只不过除了not之外, 其它的符号都是二目运算, 注意情况的处理.
2.7 如果是定义类型, 则进行相应的处理
2.7.1 如果是int, 则将其后的变量写入数据段的变量队列中, 因为有以下几种情况: int a; int a=1; int a=1, b;等, 因此在实现定义算法处理时注意各种情况的发生.
2.7.2 如果是char 或string , 其处理类似于int 处理.
2.7.3 如果是function,则进行函数的定义.对函数的定义做如下的说明.
首先对函数名进行合法性检查, 将正确的函数放入数据段的自定义函数队列中, 然后对起实现部分进行编译分析, 生成伪代码list, 检查返回值的类型予函数的返回类型是否匹配, 最后将正确的危殆伪代码list的头指针地址放入自定义函数队列的相应位置. 在别的函数调用它时再将此段伪代码list插入对应的位置.
2.8 如果是其它类型, 则进行以下的分析.
在script文档中, 如果单词类型属于其它类型, 那么只有一种是合法的, 那就是变量操作, 如 : a = 2; 等, 当扫描到a时, 它的类型号是9, 此时 处理的流程是: 首先在数据段的变量队列中找看是否定义了一个变量a, 如果有则进行下一个单词的扫描和处理; 如果没有则认为是非法的字符串, 进行出错处理.
2.9 如果单词表没有结束, 则跳到2.3; 否则结束编译程序.
经过编译,最终生成的是伪代码集, 它要产生一个临时文档, 将伪代码集按照固定的格式(struct格式)写入临时文档中.
//////////////////////////////////////////////////////////////////////////
ats 自动测试软件说明书(四): 伪代码执行程序的编写.
由于定义的函数个数可能很多, 如果每一个函数都写一个调用函数, 则代码有非常多的重复, 而且如果用户或维护人员添加了一个新的功能函数, 那么这个执行程序要重新的编写,重新的编译, 可维护性不强. 因此应该想dos下的bios调用一样, 用一个统一的象int中断格式一样的函数调用格式, 当新增一个功能函数后, 编译程序自动的进行编译, 执行时, 执行程序只要把要传入的实叁通过统一的方式传入一块内存或采用压入系统堆栈的形式传递叁数, 很大的降低了代码,量, 便于维护.
此部分较容易, 因此可以迅速的完成, 大概2天左右.
//////////////////////////////////////////////////////////////////////////
ats 自动测试软件说明书(五): 功能函数库(*.dll)的编写事项.
ATS所有的函数都放在dll中,函数不是VCL特有的__fastcall类型的,而是采用通常的Pascal调用习惯,这也是Win32 API 使用的. 因此,所有的导出函数必须这样说明:
extern "C" DWORD __export __pascal Sample1(DWORD value);
同时应该注意: 不要让函数返回double或struct类型的数值, 不要使用VCL的类(如AnsiString)来作为叁数或返回值. 叁数的类型只能是int, char, char* 和 double, 如果需要使用struct, 用其地址作为叁数. 返回值的类型只能是int和指针. 当然, 如果是DLL内部使用的函数, 并不是提供给外部模块ATS使用的, 则不需要export, 也没有以上限制.
虽然可以在 DLL 中使用 VCL 的 class 及 function, 但是这里不推荐这种做法.DLL中的代码最好简洁一些.
//////////////////////////////////////////////////////////////////////////
ats 自动测试软件说明书(六): 副辅助工具IDE界面和记录器的编写.
一. IDE界面的简单说明
由于编译和执行部分分别为两个独立的EXE文件, 因此可以实现只编译不执行和实现单步执行的功能, 为了方便用户编写script, 在IDE界面中存在着即时的帮助说明, 应由基本的一些功能如: 读入一个文件, 存入一个文件等.
二. 关于记录器
记录器虽然是一个辅助工具, 但是在ats测试软件中的地位是特殊的, 如果没有它, 那么就没有真正的实现自动测试的功能, 因为用户可能会因要实现一个测试任务而将大量的时间花费在写script上, 如果script能够自动的生成, 那么将为测试工作节约了大量的时间.因此记录器是很重要的.
要写记录器, 必须对windows编程非常的熟悉, 对windows的消息机制非常的了解, 同时也要对shell extention编程很熟悉.工作量也相对的较大.
记录器最终要生成的script, 因此它也要将记录下的信息进行一次转化, 读入功能函数定义INI文档, 按找固定的格式生成script.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -